1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2013 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 */ 6 7 #include <drm/drm_crtc.h> 8 #include <drm/drm_probe_helper.h> 9 10 #include "mdp4_kms.h" 11 12 struct mdp4_dtv_encoder { 13 struct drm_encoder base; 14 struct clk *hdmi_clk; 15 struct clk *mdp_clk; 16 unsigned long int pixclock; 17 bool enabled; 18 uint32_t bsc; 19 }; 20 #define to_mdp4_dtv_encoder(x) container_of(x, struct mdp4_dtv_encoder, base) 21 22 static struct mdp4_kms *get_kms(struct drm_encoder *encoder) 23 { 24 struct msm_drm_private *priv = encoder->dev->dev_private; 25 return to_mdp4_kms(to_mdp_kms(priv->kms)); 26 } 27 28 #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING 29 #include <mach/board.h> 30 /* not ironically named at all.. no, really.. */ 31 static void bs_init(struct mdp4_dtv_encoder *mdp4_dtv_encoder) 32 { 33 struct drm_device *dev = mdp4_dtv_encoder->base.dev; 34 struct lcdc_platform_data *dtv_pdata = mdp4_find_pdata("dtv.0"); 35 36 if (!dtv_pdata) { 37 DRM_DEV_ERROR(dev->dev, "could not find dtv pdata\n"); 38 return; 39 } 40 41 if (dtv_pdata->bus_scale_table) { 42 mdp4_dtv_encoder->bsc = msm_bus_scale_register_client( 43 dtv_pdata->bus_scale_table); 44 DBG("bus scale client: %08x", mdp4_dtv_encoder->bsc); 45 DBG("lcdc_power_save: %p", dtv_pdata->lcdc_power_save); 46 if (dtv_pdata->lcdc_power_save) 47 dtv_pdata->lcdc_power_save(1); 48 } 49 } 50 51 static void bs_fini(struct mdp4_dtv_encoder *mdp4_dtv_encoder) 52 { 53 if (mdp4_dtv_encoder->bsc) { 54 msm_bus_scale_unregister_client(mdp4_dtv_encoder->bsc); 55 mdp4_dtv_encoder->bsc = 0; 56 } 57 } 58 59 static void bs_set(struct mdp4_dtv_encoder *mdp4_dtv_encoder, int idx) 60 { 61 if (mdp4_dtv_encoder->bsc) { 62 DBG("set bus scaling: %d", idx); 63 msm_bus_scale_client_update_request(mdp4_dtv_encoder->bsc, idx); 64 } 65 } 66 #else 67 static void bs_init(struct mdp4_dtv_encoder *mdp4_dtv_encoder) {} 68 static void bs_fini(struct mdp4_dtv_encoder *mdp4_dtv_encoder) {} 69 static void bs_set(struct mdp4_dtv_encoder *mdp4_dtv_encoder, int idx) {} 70 #endif 71 72 static void mdp4_dtv_encoder_destroy(struct drm_encoder *encoder) 73 { 74 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); 75 bs_fini(mdp4_dtv_encoder); 76 drm_encoder_cleanup(encoder); 77 kfree(mdp4_dtv_encoder); 78 } 79 80 static const struct drm_encoder_funcs mdp4_dtv_encoder_funcs = { 81 .destroy = mdp4_dtv_encoder_destroy, 82 }; 83 84 static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder, 85 struct drm_display_mode *mode, 86 struct drm_display_mode *adjusted_mode) 87 { 88 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); 89 struct mdp4_kms *mdp4_kms = get_kms(encoder); 90 uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol; 91 uint32_t display_v_start, display_v_end; 92 uint32_t hsync_start_x, hsync_end_x; 93 94 mode = adjusted_mode; 95 96 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode)); 97 98 mdp4_dtv_encoder->pixclock = mode->clock * 1000; 99 100 DBG("pixclock=%lu", mdp4_dtv_encoder->pixclock); 101 102 ctrl_pol = 0; 103 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 104 ctrl_pol |= MDP4_DTV_CTRL_POLARITY_HSYNC_LOW; 105 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 106 ctrl_pol |= MDP4_DTV_CTRL_POLARITY_VSYNC_LOW; 107 /* probably need to get DATA_EN polarity from panel.. */ 108 109 dtv_hsync_skew = 0; /* get this from panel? */ 110 111 hsync_start_x = (mode->htotal - mode->hsync_start); 112 hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1; 113 114 vsync_period = mode->vtotal * mode->htotal; 115 vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal; 116 display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew; 117 display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1; 118 119 mdp4_write(mdp4_kms, REG_MDP4_DTV_HSYNC_CTRL, 120 MDP4_DTV_HSYNC_CTRL_PULSEW(mode->hsync_end - mode->hsync_start) | 121 MDP4_DTV_HSYNC_CTRL_PERIOD(mode->htotal)); 122 mdp4_write(mdp4_kms, REG_MDP4_DTV_VSYNC_PERIOD, vsync_period); 123 mdp4_write(mdp4_kms, REG_MDP4_DTV_VSYNC_LEN, vsync_len); 124 mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_HCTRL, 125 MDP4_DTV_DISPLAY_HCTRL_START(hsync_start_x) | 126 MDP4_DTV_DISPLAY_HCTRL_END(hsync_end_x)); 127 mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_VSTART, display_v_start); 128 mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_VEND, display_v_end); 129 mdp4_write(mdp4_kms, REG_MDP4_DTV_BORDER_CLR, 0); 130 mdp4_write(mdp4_kms, REG_MDP4_DTV_UNDERFLOW_CLR, 131 MDP4_DTV_UNDERFLOW_CLR_ENABLE_RECOVERY | 132 MDP4_DTV_UNDERFLOW_CLR_COLOR(0xff)); 133 mdp4_write(mdp4_kms, REG_MDP4_DTV_HSYNC_SKEW, dtv_hsync_skew); 134 mdp4_write(mdp4_kms, REG_MDP4_DTV_CTRL_POLARITY, ctrl_pol); 135 mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_HCTL, 136 MDP4_DTV_ACTIVE_HCTL_START(0) | 137 MDP4_DTV_ACTIVE_HCTL_END(0)); 138 mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VSTART, 0); 139 mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VEND, 0); 140 } 141 142 static void mdp4_dtv_encoder_disable(struct drm_encoder *encoder) 143 { 144 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); 145 struct mdp4_kms *mdp4_kms = get_kms(encoder); 146 147 if (WARN_ON(!mdp4_dtv_encoder->enabled)) 148 return; 149 150 mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0); 151 152 /* 153 * Wait for a vsync so we know the ENABLE=0 latched before 154 * the (connector) source of the vsync's gets disabled, 155 * otherwise we end up in a funny state if we re-enable 156 * before the disable latches, which results that some of 157 * the settings changes for the new modeset (like new 158 * scanout buffer) don't latch properly.. 159 */ 160 mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_EXTERNAL_VSYNC); 161 162 clk_disable_unprepare(mdp4_dtv_encoder->hdmi_clk); 163 clk_disable_unprepare(mdp4_dtv_encoder->mdp_clk); 164 165 bs_set(mdp4_dtv_encoder, 0); 166 167 mdp4_dtv_encoder->enabled = false; 168 } 169 170 static void mdp4_dtv_encoder_enable(struct drm_encoder *encoder) 171 { 172 struct drm_device *dev = encoder->dev; 173 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); 174 struct mdp4_kms *mdp4_kms = get_kms(encoder); 175 unsigned long pc = mdp4_dtv_encoder->pixclock; 176 int ret; 177 178 if (WARN_ON(mdp4_dtv_encoder->enabled)) 179 return; 180 181 mdp4_crtc_set_config(encoder->crtc, 182 MDP4_DMA_CONFIG_R_BPC(BPC8) | 183 MDP4_DMA_CONFIG_G_BPC(BPC8) | 184 MDP4_DMA_CONFIG_B_BPC(BPC8) | 185 MDP4_DMA_CONFIG_PACK(0x21)); 186 mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 1); 187 188 bs_set(mdp4_dtv_encoder, 1); 189 190 DBG("setting mdp_clk=%lu", pc); 191 192 ret = clk_set_rate(mdp4_dtv_encoder->mdp_clk, pc); 193 if (ret) 194 DRM_DEV_ERROR(dev->dev, "failed to set mdp_clk to %lu: %d\n", 195 pc, ret); 196 197 ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk); 198 if (ret) 199 DRM_DEV_ERROR(dev->dev, "failed to enabled mdp_clk: %d\n", ret); 200 201 ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk); 202 if (ret) 203 DRM_DEV_ERROR(dev->dev, "failed to enable hdmi_clk: %d\n", ret); 204 205 mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1); 206 207 mdp4_dtv_encoder->enabled = true; 208 } 209 210 static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = { 211 .mode_set = mdp4_dtv_encoder_mode_set, 212 .enable = mdp4_dtv_encoder_enable, 213 .disable = mdp4_dtv_encoder_disable, 214 }; 215 216 long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate) 217 { 218 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); 219 return clk_round_rate(mdp4_dtv_encoder->mdp_clk, rate); 220 } 221 222 /* initialize encoder */ 223 struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev) 224 { 225 struct drm_encoder *encoder = NULL; 226 struct mdp4_dtv_encoder *mdp4_dtv_encoder; 227 int ret; 228 229 mdp4_dtv_encoder = kzalloc(sizeof(*mdp4_dtv_encoder), GFP_KERNEL); 230 if (!mdp4_dtv_encoder) { 231 ret = -ENOMEM; 232 goto fail; 233 } 234 235 encoder = &mdp4_dtv_encoder->base; 236 237 drm_encoder_init(dev, encoder, &mdp4_dtv_encoder_funcs, 238 DRM_MODE_ENCODER_TMDS, NULL); 239 drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs); 240 241 mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk"); 242 if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) { 243 DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n"); 244 ret = PTR_ERR(mdp4_dtv_encoder->hdmi_clk); 245 goto fail; 246 } 247 248 mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk"); 249 if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) { 250 DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n"); 251 ret = PTR_ERR(mdp4_dtv_encoder->mdp_clk); 252 goto fail; 253 } 254 255 bs_init(mdp4_dtv_encoder); 256 257 return encoder; 258 259 fail: 260 if (encoder) 261 mdp4_dtv_encoder_destroy(encoder); 262 263 return ERR_PTR(ret); 264 } 265