1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2014 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 * Author: Vinay Simha <vinaysimha@inforcecomputing.com> 6 */ 7 8 #include <drm/drm_crtc.h> 9 #include <drm/drm_probe_helper.h> 10 11 #include "mdp4_kms.h" 12 13 struct mdp4_lcdc_encoder { 14 struct drm_encoder base; 15 struct device_node *panel_node; 16 struct drm_panel *panel; 17 struct clk *lcdc_clk; 18 unsigned long int pixclock; 19 struct regulator *regs[3]; 20 bool enabled; 21 uint32_t bsc; 22 }; 23 #define to_mdp4_lcdc_encoder(x) container_of(x, struct mdp4_lcdc_encoder, base) 24 25 static struct mdp4_kms *get_kms(struct drm_encoder *encoder) 26 { 27 struct msm_drm_private *priv = encoder->dev->dev_private; 28 return to_mdp4_kms(to_mdp_kms(priv->kms)); 29 } 30 31 #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING 32 #include <mach/board.h> 33 static void bs_init(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) 34 { 35 struct drm_device *dev = mdp4_lcdc_encoder->base.dev; 36 struct lcdc_platform_data *lcdc_pdata = mdp4_find_pdata("lvds.0"); 37 38 if (!lcdc_pdata) { 39 DRM_DEV_ERROR(dev->dev, "could not find lvds pdata\n"); 40 return; 41 } 42 43 if (lcdc_pdata->bus_scale_table) { 44 mdp4_lcdc_encoder->bsc = msm_bus_scale_register_client( 45 lcdc_pdata->bus_scale_table); 46 DBG("lvds : bus scale client: %08x", mdp4_lcdc_encoder->bsc); 47 } 48 } 49 50 static void bs_fini(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) 51 { 52 if (mdp4_lcdc_encoder->bsc) { 53 msm_bus_scale_unregister_client(mdp4_lcdc_encoder->bsc); 54 mdp4_lcdc_encoder->bsc = 0; 55 } 56 } 57 58 static void bs_set(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder, int idx) 59 { 60 if (mdp4_lcdc_encoder->bsc) { 61 DBG("set bus scaling: %d", idx); 62 msm_bus_scale_client_update_request(mdp4_lcdc_encoder->bsc, idx); 63 } 64 } 65 #else 66 static void bs_init(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) {} 67 static void bs_fini(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) {} 68 static void bs_set(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder, int idx) {} 69 #endif 70 71 static void mdp4_lcdc_encoder_destroy(struct drm_encoder *encoder) 72 { 73 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = 74 to_mdp4_lcdc_encoder(encoder); 75 bs_fini(mdp4_lcdc_encoder); 76 drm_encoder_cleanup(encoder); 77 kfree(mdp4_lcdc_encoder); 78 } 79 80 static const struct drm_encoder_funcs mdp4_lcdc_encoder_funcs = { 81 .destroy = mdp4_lcdc_encoder_destroy, 82 }; 83 84 /* this should probably be a helper: */ 85 static struct drm_connector *get_connector(struct drm_encoder *encoder) 86 { 87 struct drm_device *dev = encoder->dev; 88 struct drm_connector *connector; 89 90 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 91 if (connector->encoder == encoder) 92 return connector; 93 94 return NULL; 95 } 96 97 static void setup_phy(struct drm_encoder *encoder) 98 { 99 struct drm_device *dev = encoder->dev; 100 struct drm_connector *connector = get_connector(encoder); 101 struct mdp4_kms *mdp4_kms = get_kms(encoder); 102 uint32_t lvds_intf = 0, lvds_phy_cfg0 = 0; 103 int bpp, nchan, swap; 104 105 if (!connector) 106 return; 107 108 bpp = 3 * connector->display_info.bpc; 109 110 if (!bpp) 111 bpp = 18; 112 113 /* TODO, these should come from panel somehow: */ 114 nchan = 1; 115 swap = 0; 116 117 switch (bpp) { 118 case 24: 119 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(0), 120 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x08) | 121 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x05) | 122 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x04) | 123 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x03)); 124 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(0), 125 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x02) | 126 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x01) | 127 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x00)); 128 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(1), 129 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x11) | 130 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x10) | 131 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x0d) | 132 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0c)); 133 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(1), 134 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0b) | 135 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x0a) | 136 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x09)); 137 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(2), 138 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1a) | 139 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x19) | 140 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x18) | 141 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x15)); 142 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(2), 143 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x14) | 144 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x13) | 145 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x12)); 146 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(3), 147 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1b) | 148 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x17) | 149 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x16) | 150 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0f)); 151 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(3), 152 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0e) | 153 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x07) | 154 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x06)); 155 if (nchan == 2) { 156 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE3_EN | 157 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE2_EN | 158 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE1_EN | 159 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE0_EN | 160 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE3_EN | 161 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN | 162 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN | 163 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN; 164 } else { 165 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE3_EN | 166 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN | 167 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN | 168 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN; 169 } 170 break; 171 172 case 18: 173 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(0), 174 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x0a) | 175 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x07) | 176 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x06) | 177 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x05)); 178 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(0), 179 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x04) | 180 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x03) | 181 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x02)); 182 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(1), 183 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x13) | 184 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x12) | 185 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x0f) | 186 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0e)); 187 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(1), 188 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0d) | 189 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x0c) | 190 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x0b)); 191 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(2), 192 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1a) | 193 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x19) | 194 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x18) | 195 MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x17)); 196 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(2), 197 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x16) | 198 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x15) | 199 MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x14)); 200 if (nchan == 2) { 201 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE2_EN | 202 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE1_EN | 203 MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE0_EN | 204 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN | 205 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN | 206 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN; 207 } else { 208 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN | 209 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN | 210 MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN; 211 } 212 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_RGB_OUT; 213 break; 214 215 default: 216 DRM_DEV_ERROR(dev->dev, "unknown bpp: %d\n", bpp); 217 return; 218 } 219 220 switch (nchan) { 221 case 1: 222 lvds_phy_cfg0 = MDP4_LVDS_PHY_CFG0_CHANNEL0; 223 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN | 224 MDP4_LCDC_LVDS_INTF_CTL_MODE_SEL; 225 break; 226 case 2: 227 lvds_phy_cfg0 = MDP4_LVDS_PHY_CFG0_CHANNEL0 | 228 MDP4_LVDS_PHY_CFG0_CHANNEL1; 229 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_CLK_LANE_EN | 230 MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN; 231 break; 232 default: 233 DRM_DEV_ERROR(dev->dev, "unknown # of channels: %d\n", nchan); 234 return; 235 } 236 237 if (swap) 238 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH_SWAP; 239 240 lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_ENABLE; 241 242 mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0); 243 mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_INTF_CTL, lvds_intf); 244 mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG2, 0x30); 245 246 mb(); 247 udelay(1); 248 lvds_phy_cfg0 |= MDP4_LVDS_PHY_CFG0_SERIALIZATION_ENBLE; 249 mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0); 250 } 251 252 static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder, 253 struct drm_display_mode *mode, 254 struct drm_display_mode *adjusted_mode) 255 { 256 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = 257 to_mdp4_lcdc_encoder(encoder); 258 struct mdp4_kms *mdp4_kms = get_kms(encoder); 259 uint32_t lcdc_hsync_skew, vsync_period, vsync_len, ctrl_pol; 260 uint32_t display_v_start, display_v_end; 261 uint32_t hsync_start_x, hsync_end_x; 262 263 mode = adjusted_mode; 264 265 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode)); 266 267 mdp4_lcdc_encoder->pixclock = mode->clock * 1000; 268 269 DBG("pixclock=%lu", mdp4_lcdc_encoder->pixclock); 270 271 ctrl_pol = 0; 272 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 273 ctrl_pol |= MDP4_LCDC_CTRL_POLARITY_HSYNC_LOW; 274 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 275 ctrl_pol |= MDP4_LCDC_CTRL_POLARITY_VSYNC_LOW; 276 /* probably need to get DATA_EN polarity from panel.. */ 277 278 lcdc_hsync_skew = 0; /* get this from panel? */ 279 280 hsync_start_x = (mode->htotal - mode->hsync_start); 281 hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1; 282 283 vsync_period = mode->vtotal * mode->htotal; 284 vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal; 285 display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + lcdc_hsync_skew; 286 display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + lcdc_hsync_skew - 1; 287 288 mdp4_write(mdp4_kms, REG_MDP4_LCDC_HSYNC_CTRL, 289 MDP4_LCDC_HSYNC_CTRL_PULSEW(mode->hsync_end - mode->hsync_start) | 290 MDP4_LCDC_HSYNC_CTRL_PERIOD(mode->htotal)); 291 mdp4_write(mdp4_kms, REG_MDP4_LCDC_VSYNC_PERIOD, vsync_period); 292 mdp4_write(mdp4_kms, REG_MDP4_LCDC_VSYNC_LEN, vsync_len); 293 mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_HCTRL, 294 MDP4_LCDC_DISPLAY_HCTRL_START(hsync_start_x) | 295 MDP4_LCDC_DISPLAY_HCTRL_END(hsync_end_x)); 296 mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_VSTART, display_v_start); 297 mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_VEND, display_v_end); 298 mdp4_write(mdp4_kms, REG_MDP4_LCDC_BORDER_CLR, 0); 299 mdp4_write(mdp4_kms, REG_MDP4_LCDC_UNDERFLOW_CLR, 300 MDP4_LCDC_UNDERFLOW_CLR_ENABLE_RECOVERY | 301 MDP4_LCDC_UNDERFLOW_CLR_COLOR(0xff)); 302 mdp4_write(mdp4_kms, REG_MDP4_LCDC_HSYNC_SKEW, lcdc_hsync_skew); 303 mdp4_write(mdp4_kms, REG_MDP4_LCDC_CTRL_POLARITY, ctrl_pol); 304 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_HCTL, 305 MDP4_LCDC_ACTIVE_HCTL_START(0) | 306 MDP4_LCDC_ACTIVE_HCTL_END(0)); 307 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VSTART, 0); 308 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VEND, 0); 309 } 310 311 static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) 312 { 313 struct drm_device *dev = encoder->dev; 314 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = 315 to_mdp4_lcdc_encoder(encoder); 316 struct mdp4_kms *mdp4_kms = get_kms(encoder); 317 struct drm_panel *panel; 318 int i, ret; 319 320 if (WARN_ON(!mdp4_lcdc_encoder->enabled)) 321 return; 322 323 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); 324 325 panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); 326 if (!IS_ERR(panel)) { 327 drm_panel_disable(panel); 328 drm_panel_unprepare(panel); 329 } 330 331 /* 332 * Wait for a vsync so we know the ENABLE=0 latched before 333 * the (connector) source of the vsync's gets disabled, 334 * otherwise we end up in a funny state if we re-enable 335 * before the disable latches, which results that some of 336 * the settings changes for the new modeset (like new 337 * scanout buffer) don't latch properly.. 338 */ 339 mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_PRIMARY_VSYNC); 340 341 clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk); 342 343 for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { 344 ret = regulator_disable(mdp4_lcdc_encoder->regs[i]); 345 if (ret) 346 DRM_DEV_ERROR(dev->dev, "failed to disable regulator: %d\n", ret); 347 } 348 349 bs_set(mdp4_lcdc_encoder, 0); 350 351 mdp4_lcdc_encoder->enabled = false; 352 } 353 354 static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) 355 { 356 struct drm_device *dev = encoder->dev; 357 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = 358 to_mdp4_lcdc_encoder(encoder); 359 unsigned long pc = mdp4_lcdc_encoder->pixclock; 360 struct mdp4_kms *mdp4_kms = get_kms(encoder); 361 struct drm_panel *panel; 362 uint32_t config; 363 int i, ret; 364 365 if (WARN_ON(mdp4_lcdc_encoder->enabled)) 366 return; 367 368 /* TODO: hard-coded for 18bpp: */ 369 config = 370 MDP4_DMA_CONFIG_R_BPC(BPC6) | 371 MDP4_DMA_CONFIG_G_BPC(BPC6) | 372 MDP4_DMA_CONFIG_B_BPC(BPC6) | 373 MDP4_DMA_CONFIG_PACK(0x21) | 374 MDP4_DMA_CONFIG_DEFLKR_EN | 375 MDP4_DMA_CONFIG_DITHER_EN; 376 377 if (!of_property_read_bool(dev->dev->of_node, "qcom,lcdc-align-lsb")) 378 config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB; 379 380 mdp4_crtc_set_config(encoder->crtc, config); 381 mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); 382 383 bs_set(mdp4_lcdc_encoder, 1); 384 385 for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { 386 ret = regulator_enable(mdp4_lcdc_encoder->regs[i]); 387 if (ret) 388 DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret); 389 } 390 391 DBG("setting lcdc_clk=%lu", pc); 392 ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc); 393 if (ret) 394 DRM_DEV_ERROR(dev->dev, "failed to configure lcdc_clk: %d\n", ret); 395 ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk); 396 if (ret) 397 DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret); 398 399 panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); 400 if (!IS_ERR(panel)) { 401 drm_panel_prepare(panel); 402 drm_panel_enable(panel); 403 } 404 405 setup_phy(encoder); 406 407 mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1); 408 409 mdp4_lcdc_encoder->enabled = true; 410 } 411 412 static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = { 413 .mode_set = mdp4_lcdc_encoder_mode_set, 414 .disable = mdp4_lcdc_encoder_disable, 415 .enable = mdp4_lcdc_encoder_enable, 416 }; 417 418 long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate) 419 { 420 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = 421 to_mdp4_lcdc_encoder(encoder); 422 return clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, rate); 423 } 424 425 /* initialize encoder */ 426 struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, 427 struct device_node *panel_node) 428 { 429 struct drm_encoder *encoder = NULL; 430 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder; 431 struct regulator *reg; 432 int ret; 433 434 mdp4_lcdc_encoder = kzalloc(sizeof(*mdp4_lcdc_encoder), GFP_KERNEL); 435 if (!mdp4_lcdc_encoder) { 436 ret = -ENOMEM; 437 goto fail; 438 } 439 440 mdp4_lcdc_encoder->panel_node = panel_node; 441 442 encoder = &mdp4_lcdc_encoder->base; 443 444 drm_encoder_init(dev, encoder, &mdp4_lcdc_encoder_funcs, 445 DRM_MODE_ENCODER_LVDS, NULL); 446 drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs); 447 448 /* TODO: do we need different pll in other cases? */ 449 mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev); 450 if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) { 451 DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n"); 452 ret = PTR_ERR(mdp4_lcdc_encoder->lcdc_clk); 453 goto fail; 454 } 455 456 /* TODO: different regulators in other cases? */ 457 reg = devm_regulator_get(dev->dev, "lvds-vccs-3p3v"); 458 if (IS_ERR(reg)) { 459 ret = PTR_ERR(reg); 460 DRM_DEV_ERROR(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret); 461 goto fail; 462 } 463 mdp4_lcdc_encoder->regs[0] = reg; 464 465 reg = devm_regulator_get(dev->dev, "lvds-pll-vdda"); 466 if (IS_ERR(reg)) { 467 ret = PTR_ERR(reg); 468 DRM_DEV_ERROR(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret); 469 goto fail; 470 } 471 mdp4_lcdc_encoder->regs[1] = reg; 472 473 reg = devm_regulator_get(dev->dev, "lvds-vdda"); 474 if (IS_ERR(reg)) { 475 ret = PTR_ERR(reg); 476 DRM_DEV_ERROR(dev->dev, "failed to get lvds-vdda: %d\n", ret); 477 goto fail; 478 } 479 mdp4_lcdc_encoder->regs[2] = reg; 480 481 bs_init(mdp4_lcdc_encoder); 482 483 return encoder; 484 485 fail: 486 if (encoder) 487 mdp4_lcdc_encoder_destroy(encoder); 488 489 return ERR_PTR(ret); 490 } 491