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