0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/delay.h>
0009
0010 #include <drm/drm_crtc.h>
0011 #include <drm/drm_probe_helper.h>
0012
0013 #include "mdp4_kms.h"
0014
0015 struct mdp4_lcdc_encoder {
0016 struct drm_encoder base;
0017 struct device_node *panel_node;
0018 struct drm_panel *panel;
0019 struct clk *lcdc_clk;
0020 unsigned long int pixclock;
0021 struct regulator *regs[3];
0022 bool enabled;
0023 uint32_t bsc;
0024 };
0025 #define to_mdp4_lcdc_encoder(x) container_of(x, struct mdp4_lcdc_encoder, base)
0026
0027 static struct mdp4_kms *get_kms(struct drm_encoder *encoder)
0028 {
0029 struct msm_drm_private *priv = encoder->dev->dev_private;
0030 return to_mdp4_kms(to_mdp_kms(priv->kms));
0031 }
0032
0033 static void mdp4_lcdc_encoder_destroy(struct drm_encoder *encoder)
0034 {
0035 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
0036 to_mdp4_lcdc_encoder(encoder);
0037 drm_encoder_cleanup(encoder);
0038 kfree(mdp4_lcdc_encoder);
0039 }
0040
0041 static const struct drm_encoder_funcs mdp4_lcdc_encoder_funcs = {
0042 .destroy = mdp4_lcdc_encoder_destroy,
0043 };
0044
0045
0046 static struct drm_connector *get_connector(struct drm_encoder *encoder)
0047 {
0048 struct drm_device *dev = encoder->dev;
0049 struct drm_connector *connector;
0050
0051 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
0052 if (connector->encoder == encoder)
0053 return connector;
0054
0055 return NULL;
0056 }
0057
0058 static void setup_phy(struct drm_encoder *encoder)
0059 {
0060 struct drm_device *dev = encoder->dev;
0061 struct drm_connector *connector = get_connector(encoder);
0062 struct mdp4_kms *mdp4_kms = get_kms(encoder);
0063 uint32_t lvds_intf = 0, lvds_phy_cfg0 = 0;
0064 int bpp, nchan, swap;
0065
0066 if (!connector)
0067 return;
0068
0069 bpp = 3 * connector->display_info.bpc;
0070
0071 if (!bpp)
0072 bpp = 18;
0073
0074
0075 nchan = 1;
0076 swap = 0;
0077
0078 switch (bpp) {
0079 case 24:
0080 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(0),
0081 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x08) |
0082 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x05) |
0083 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x04) |
0084 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x03));
0085 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(0),
0086 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x02) |
0087 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x01) |
0088 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x00));
0089 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(1),
0090 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x11) |
0091 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x10) |
0092 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x0d) |
0093 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0c));
0094 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(1),
0095 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0b) |
0096 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x0a) |
0097 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x09));
0098 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(2),
0099 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1a) |
0100 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x19) |
0101 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x18) |
0102 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x15));
0103 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(2),
0104 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x14) |
0105 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x13) |
0106 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x12));
0107 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(3),
0108 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1b) |
0109 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x17) |
0110 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x16) |
0111 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0f));
0112 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(3),
0113 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0e) |
0114 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x07) |
0115 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x06));
0116 if (nchan == 2) {
0117 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE3_EN |
0118 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE2_EN |
0119 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE1_EN |
0120 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE0_EN |
0121 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE3_EN |
0122 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN |
0123 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN |
0124 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN;
0125 } else {
0126 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE3_EN |
0127 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN |
0128 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN |
0129 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN;
0130 }
0131 break;
0132
0133 case 18:
0134 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(0),
0135 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x0a) |
0136 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x07) |
0137 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x06) |
0138 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x05));
0139 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(0),
0140 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x04) |
0141 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x03) |
0142 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x02));
0143 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(1),
0144 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x13) |
0145 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x12) |
0146 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x0f) |
0147 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0e));
0148 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(1),
0149 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0d) |
0150 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x0c) |
0151 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x0b));
0152 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(2),
0153 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1a) |
0154 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x19) |
0155 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x18) |
0156 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x17));
0157 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(2),
0158 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x16) |
0159 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x15) |
0160 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x14));
0161 if (nchan == 2) {
0162 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE2_EN |
0163 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE1_EN |
0164 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE0_EN |
0165 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN |
0166 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN |
0167 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN;
0168 } else {
0169 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN |
0170 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN |
0171 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN;
0172 }
0173 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_RGB_OUT;
0174 break;
0175
0176 default:
0177 DRM_DEV_ERROR(dev->dev, "unknown bpp: %d\n", bpp);
0178 return;
0179 }
0180
0181 switch (nchan) {
0182 case 1:
0183 lvds_phy_cfg0 = MDP4_LVDS_PHY_CFG0_CHANNEL0;
0184 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN |
0185 MDP4_LCDC_LVDS_INTF_CTL_MODE_SEL;
0186 break;
0187 case 2:
0188 lvds_phy_cfg0 = MDP4_LVDS_PHY_CFG0_CHANNEL0 |
0189 MDP4_LVDS_PHY_CFG0_CHANNEL1;
0190 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_CLK_LANE_EN |
0191 MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN;
0192 break;
0193 default:
0194 DRM_DEV_ERROR(dev->dev, "unknown # of channels: %d\n", nchan);
0195 return;
0196 }
0197
0198 if (swap)
0199 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH_SWAP;
0200
0201 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_ENABLE;
0202
0203 mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0);
0204 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_INTF_CTL, lvds_intf);
0205 mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG2, 0x30);
0206
0207 mb();
0208 udelay(1);
0209 lvds_phy_cfg0 |= MDP4_LVDS_PHY_CFG0_SERIALIZATION_ENBLE;
0210 mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0);
0211 }
0212
0213 static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder,
0214 struct drm_display_mode *mode,
0215 struct drm_display_mode *adjusted_mode)
0216 {
0217 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
0218 to_mdp4_lcdc_encoder(encoder);
0219 struct mdp4_kms *mdp4_kms = get_kms(encoder);
0220 uint32_t lcdc_hsync_skew, vsync_period, vsync_len, ctrl_pol;
0221 uint32_t display_v_start, display_v_end;
0222 uint32_t hsync_start_x, hsync_end_x;
0223
0224 mode = adjusted_mode;
0225
0226 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
0227
0228 mdp4_lcdc_encoder->pixclock = mode->clock * 1000;
0229
0230 DBG("pixclock=%lu", mdp4_lcdc_encoder->pixclock);
0231
0232 ctrl_pol = 0;
0233 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
0234 ctrl_pol |= MDP4_LCDC_CTRL_POLARITY_HSYNC_LOW;
0235 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
0236 ctrl_pol |= MDP4_LCDC_CTRL_POLARITY_VSYNC_LOW;
0237
0238
0239 lcdc_hsync_skew = 0;
0240
0241 hsync_start_x = (mode->htotal - mode->hsync_start);
0242 hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
0243
0244 vsync_period = mode->vtotal * mode->htotal;
0245 vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal;
0246 display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + lcdc_hsync_skew;
0247 display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + lcdc_hsync_skew - 1;
0248
0249 mdp4_write(mdp4_kms, REG_MDP4_LCDC_HSYNC_CTRL,
0250 MDP4_LCDC_HSYNC_CTRL_PULSEW(mode->hsync_end - mode->hsync_start) |
0251 MDP4_LCDC_HSYNC_CTRL_PERIOD(mode->htotal));
0252 mdp4_write(mdp4_kms, REG_MDP4_LCDC_VSYNC_PERIOD, vsync_period);
0253 mdp4_write(mdp4_kms, REG_MDP4_LCDC_VSYNC_LEN, vsync_len);
0254 mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_HCTRL,
0255 MDP4_LCDC_DISPLAY_HCTRL_START(hsync_start_x) |
0256 MDP4_LCDC_DISPLAY_HCTRL_END(hsync_end_x));
0257 mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_VSTART, display_v_start);
0258 mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_VEND, display_v_end);
0259 mdp4_write(mdp4_kms, REG_MDP4_LCDC_BORDER_CLR, 0);
0260 mdp4_write(mdp4_kms, REG_MDP4_LCDC_UNDERFLOW_CLR,
0261 MDP4_LCDC_UNDERFLOW_CLR_ENABLE_RECOVERY |
0262 MDP4_LCDC_UNDERFLOW_CLR_COLOR(0xff));
0263 mdp4_write(mdp4_kms, REG_MDP4_LCDC_HSYNC_SKEW, lcdc_hsync_skew);
0264 mdp4_write(mdp4_kms, REG_MDP4_LCDC_CTRL_POLARITY, ctrl_pol);
0265 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_HCTL,
0266 MDP4_LCDC_ACTIVE_HCTL_START(0) |
0267 MDP4_LCDC_ACTIVE_HCTL_END(0));
0268 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VSTART, 0);
0269 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VEND, 0);
0270 }
0271
0272 static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)
0273 {
0274 struct drm_device *dev = encoder->dev;
0275 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
0276 to_mdp4_lcdc_encoder(encoder);
0277 struct mdp4_kms *mdp4_kms = get_kms(encoder);
0278 struct drm_panel *panel;
0279 int i, ret;
0280
0281 if (WARN_ON(!mdp4_lcdc_encoder->enabled))
0282 return;
0283
0284 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
0285
0286 panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
0287 if (!IS_ERR(panel)) {
0288 drm_panel_disable(panel);
0289 drm_panel_unprepare(panel);
0290 }
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_PRIMARY_VSYNC);
0301
0302 clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk);
0303
0304 for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
0305 ret = regulator_disable(mdp4_lcdc_encoder->regs[i]);
0306 if (ret)
0307 DRM_DEV_ERROR(dev->dev, "failed to disable regulator: %d\n", ret);
0308 }
0309
0310 mdp4_lcdc_encoder->enabled = false;
0311 }
0312
0313 static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
0314 {
0315 struct drm_device *dev = encoder->dev;
0316 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
0317 to_mdp4_lcdc_encoder(encoder);
0318 unsigned long pc = mdp4_lcdc_encoder->pixclock;
0319 struct mdp4_kms *mdp4_kms = get_kms(encoder);
0320 struct drm_panel *panel;
0321 uint32_t config;
0322 int i, ret;
0323
0324 if (WARN_ON(mdp4_lcdc_encoder->enabled))
0325 return;
0326
0327
0328 config =
0329 MDP4_DMA_CONFIG_R_BPC(BPC6) |
0330 MDP4_DMA_CONFIG_G_BPC(BPC6) |
0331 MDP4_DMA_CONFIG_B_BPC(BPC6) |
0332 MDP4_DMA_CONFIG_PACK(0x21) |
0333 MDP4_DMA_CONFIG_DEFLKR_EN |
0334 MDP4_DMA_CONFIG_DITHER_EN;
0335
0336 if (!of_property_read_bool(dev->dev->of_node, "qcom,lcdc-align-lsb"))
0337 config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB;
0338
0339 mdp4_crtc_set_config(encoder->crtc, config);
0340 mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);
0341
0342 for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
0343 ret = regulator_enable(mdp4_lcdc_encoder->regs[i]);
0344 if (ret)
0345 DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret);
0346 }
0347
0348 DBG("setting lcdc_clk=%lu", pc);
0349 ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc);
0350 if (ret)
0351 DRM_DEV_ERROR(dev->dev, "failed to configure lcdc_clk: %d\n", ret);
0352 ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk);
0353 if (ret)
0354 DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret);
0355
0356 panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
0357 if (!IS_ERR(panel)) {
0358 drm_panel_prepare(panel);
0359 drm_panel_enable(panel);
0360 }
0361
0362 setup_phy(encoder);
0363
0364 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1);
0365
0366 mdp4_lcdc_encoder->enabled = true;
0367 }
0368
0369 static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = {
0370 .mode_set = mdp4_lcdc_encoder_mode_set,
0371 .disable = mdp4_lcdc_encoder_disable,
0372 .enable = mdp4_lcdc_encoder_enable,
0373 };
0374
0375 long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
0376 {
0377 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
0378 to_mdp4_lcdc_encoder(encoder);
0379 return clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, rate);
0380 }
0381
0382
0383 struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
0384 struct device_node *panel_node)
0385 {
0386 struct drm_encoder *encoder = NULL;
0387 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder;
0388 struct regulator *reg;
0389 int ret;
0390
0391 mdp4_lcdc_encoder = kzalloc(sizeof(*mdp4_lcdc_encoder), GFP_KERNEL);
0392 if (!mdp4_lcdc_encoder) {
0393 ret = -ENOMEM;
0394 goto fail;
0395 }
0396
0397 mdp4_lcdc_encoder->panel_node = panel_node;
0398
0399 encoder = &mdp4_lcdc_encoder->base;
0400
0401 drm_encoder_init(dev, encoder, &mdp4_lcdc_encoder_funcs,
0402 DRM_MODE_ENCODER_LVDS, NULL);
0403 drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs);
0404
0405
0406 mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev);
0407 if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) {
0408 DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n");
0409 ret = PTR_ERR(mdp4_lcdc_encoder->lcdc_clk);
0410 goto fail;
0411 }
0412
0413
0414 reg = devm_regulator_get(dev->dev, "lvds-vccs-3p3v");
0415 if (IS_ERR(reg)) {
0416 ret = PTR_ERR(reg);
0417 DRM_DEV_ERROR(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret);
0418 goto fail;
0419 }
0420 mdp4_lcdc_encoder->regs[0] = reg;
0421
0422 reg = devm_regulator_get(dev->dev, "lvds-pll-vdda");
0423 if (IS_ERR(reg)) {
0424 ret = PTR_ERR(reg);
0425 DRM_DEV_ERROR(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret);
0426 goto fail;
0427 }
0428 mdp4_lcdc_encoder->regs[1] = reg;
0429
0430 reg = devm_regulator_get(dev->dev, "lvds-vdda");
0431 if (IS_ERR(reg)) {
0432 ret = PTR_ERR(reg);
0433 DRM_DEV_ERROR(dev->dev, "failed to get lvds-vdda: %d\n", ret);
0434 goto fail;
0435 }
0436 mdp4_lcdc_encoder->regs[2] = reg;
0437
0438 return encoder;
0439
0440 fail:
0441 if (encoder)
0442 mdp4_lcdc_encoder_destroy(encoder);
0443
0444 return ERR_PTR(ret);
0445 }