1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2014, The Linux Foundation. All rights reserved. 4 * Copyright (C) 2013 Red Hat 5 * Author: Rob Clark <robdclark@gmail.com> 6 */ 7 8 #include <drm/drm_crtc.h> 9 #include <drm/drm_probe_helper.h> 10 11 #include "mdp5_kms.h" 12 13 static struct mdp5_kms *get_kms(struct drm_encoder *encoder) 14 { 15 struct msm_drm_private *priv = encoder->dev->dev_private; 16 return to_mdp5_kms(to_mdp_kms(priv->kms)); 17 } 18 19 static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, 20 struct drm_display_mode *mode, 21 struct drm_display_mode *adjusted_mode) 22 { 23 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 24 struct mdp5_kms *mdp5_kms = get_kms(encoder); 25 struct drm_device *dev = encoder->dev; 26 struct drm_connector *connector; 27 int intf = mdp5_encoder->intf->num; 28 uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol; 29 uint32_t display_v_start, display_v_end; 30 uint32_t hsync_start_x, hsync_end_x; 31 uint32_t format = 0x2100; 32 unsigned long flags; 33 34 mode = adjusted_mode; 35 36 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode)); 37 38 ctrl_pol = 0; 39 40 /* DSI controller cannot handle active-low sync signals. */ 41 if (mdp5_encoder->intf->type != INTF_DSI) { 42 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 43 ctrl_pol |= MDP5_INTF_POLARITY_CTL_HSYNC_LOW; 44 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 45 ctrl_pol |= MDP5_INTF_POLARITY_CTL_VSYNC_LOW; 46 } 47 /* probably need to get DATA_EN polarity from panel.. */ 48 49 dtv_hsync_skew = 0; /* get this from panel? */ 50 51 /* Get color format from panel, default is 8bpc */ 52 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 53 if (connector->encoder == encoder) { 54 switch (connector->display_info.bpc) { 55 case 4: 56 format |= 0; 57 break; 58 case 5: 59 format |= 0x15; 60 break; 61 case 6: 62 format |= 0x2A; 63 break; 64 case 8: 65 default: 66 format |= 0x3F; 67 break; 68 } 69 break; 70 } 71 } 72 73 hsync_start_x = (mode->htotal - mode->hsync_start); 74 hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1; 75 76 vsync_period = mode->vtotal * mode->htotal; 77 vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal; 78 display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew; 79 display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1; 80 81 /* 82 * For edp only: 83 * DISPLAY_V_START = (VBP * HCYCLE) + HBP 84 * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP 85 */ 86 if (mdp5_encoder->intf->type == INTF_eDP) { 87 display_v_start += mode->htotal - mode->hsync_start; 88 display_v_end -= mode->hsync_start - mode->hdisplay; 89 } 90 91 spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); 92 93 mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_CTL(intf), 94 MDP5_INTF_HSYNC_CTL_PULSEW(mode->hsync_end - mode->hsync_start) | 95 MDP5_INTF_HSYNC_CTL_PERIOD(mode->htotal)); 96 mdp5_write(mdp5_kms, REG_MDP5_INTF_VSYNC_PERIOD_F0(intf), vsync_period); 97 mdp5_write(mdp5_kms, REG_MDP5_INTF_VSYNC_LEN_F0(intf), vsync_len); 98 mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_HCTL(intf), 99 MDP5_INTF_DISPLAY_HCTL_START(hsync_start_x) | 100 MDP5_INTF_DISPLAY_HCTL_END(hsync_end_x)); 101 mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_VSTART_F0(intf), display_v_start); 102 mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_VEND_F0(intf), display_v_end); 103 mdp5_write(mdp5_kms, REG_MDP5_INTF_BORDER_COLOR(intf), 0); 104 mdp5_write(mdp5_kms, REG_MDP5_INTF_UNDERFLOW_COLOR(intf), 0xff); 105 mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_SKEW(intf), dtv_hsync_skew); 106 mdp5_write(mdp5_kms, REG_MDP5_INTF_POLARITY_CTL(intf), ctrl_pol); 107 mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_HCTL(intf), 108 MDP5_INTF_ACTIVE_HCTL_START(0) | 109 MDP5_INTF_ACTIVE_HCTL_END(0)); 110 mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_VSTART_F0(intf), 0); 111 mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_VEND_F0(intf), 0); 112 mdp5_write(mdp5_kms, REG_MDP5_INTF_PANEL_FORMAT(intf), format); 113 mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(intf), 0x3); /* frame+line? */ 114 115 spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); 116 117 mdp5_crtc_set_pipeline(encoder->crtc); 118 } 119 120 static void mdp5_vid_encoder_disable(struct drm_encoder *encoder) 121 { 122 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 123 struct mdp5_kms *mdp5_kms = get_kms(encoder); 124 struct mdp5_ctl *ctl = mdp5_encoder->ctl; 125 struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc); 126 struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc); 127 struct mdp5_interface *intf = mdp5_encoder->intf; 128 int intfn = mdp5_encoder->intf->num; 129 unsigned long flags; 130 131 if (WARN_ON(!mdp5_encoder->enabled)) 132 return; 133 134 mdp5_ctl_set_encoder_state(ctl, pipeline, false); 135 136 spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); 137 mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0); 138 spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); 139 mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true); 140 141 /* 142 * Wait for a vsync so we know the ENABLE=0 latched before 143 * the (connector) source of the vsync's gets disabled, 144 * otherwise we end up in a funny state if we re-enable 145 * before the disable latches, which results that some of 146 * the settings changes for the new modeset (like new 147 * scanout buffer) don't latch properly.. 148 */ 149 mdp_irq_wait(&mdp5_kms->base, intf2vblank(mixer, intf)); 150 151 mdp5_encoder->enabled = false; 152 } 153 154 static void mdp5_vid_encoder_enable(struct drm_encoder *encoder) 155 { 156 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 157 struct mdp5_kms *mdp5_kms = get_kms(encoder); 158 struct mdp5_ctl *ctl = mdp5_encoder->ctl; 159 struct mdp5_interface *intf = mdp5_encoder->intf; 160 struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc); 161 int intfn = intf->num; 162 unsigned long flags; 163 164 if (WARN_ON(mdp5_encoder->enabled)) 165 return; 166 167 spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); 168 mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1); 169 spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); 170 mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true); 171 172 mdp5_ctl_set_encoder_state(ctl, pipeline, true); 173 174 mdp5_encoder->enabled = true; 175 } 176 177 static void mdp5_encoder_mode_set(struct drm_encoder *encoder, 178 struct drm_display_mode *mode, 179 struct drm_display_mode *adjusted_mode) 180 { 181 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 182 struct mdp5_interface *intf = mdp5_encoder->intf; 183 184 if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) 185 mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode); 186 else 187 mdp5_vid_encoder_mode_set(encoder, mode, adjusted_mode); 188 } 189 190 static void mdp5_encoder_disable(struct drm_encoder *encoder) 191 { 192 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 193 struct mdp5_interface *intf = mdp5_encoder->intf; 194 195 if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) 196 mdp5_cmd_encoder_disable(encoder); 197 else 198 mdp5_vid_encoder_disable(encoder); 199 } 200 201 static void mdp5_encoder_enable(struct drm_encoder *encoder) 202 { 203 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 204 struct mdp5_interface *intf = mdp5_encoder->intf; 205 /* this isn't right I think */ 206 struct drm_crtc_state *cstate = encoder->crtc->state; 207 208 mdp5_encoder_mode_set(encoder, &cstate->mode, &cstate->adjusted_mode); 209 210 if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND) 211 mdp5_cmd_encoder_enable(encoder); 212 else 213 mdp5_vid_encoder_enable(encoder); 214 } 215 216 static int mdp5_encoder_atomic_check(struct drm_encoder *encoder, 217 struct drm_crtc_state *crtc_state, 218 struct drm_connector_state *conn_state) 219 { 220 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 221 struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc_state); 222 struct mdp5_interface *intf = mdp5_encoder->intf; 223 struct mdp5_ctl *ctl = mdp5_encoder->ctl; 224 225 mdp5_cstate->ctl = ctl; 226 mdp5_cstate->pipeline.intf = intf; 227 228 /* 229 * This is a bit awkward, but we want to flush the CTL and hit the 230 * START bit at most once for an atomic update. In the non-full- 231 * modeset case, this is done from crtc->atomic_flush(), but that 232 * is too early in the case of full modeset, in which case we 233 * defer to encoder->enable(). But we need to *know* whether 234 * encoder->enable() will be called to do this: 235 */ 236 if (drm_atomic_crtc_needs_modeset(crtc_state)) 237 mdp5_cstate->defer_start = true; 238 239 return 0; 240 } 241 242 static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = { 243 .disable = mdp5_encoder_disable, 244 .enable = mdp5_encoder_enable, 245 .atomic_check = mdp5_encoder_atomic_check, 246 }; 247 248 int mdp5_encoder_get_linecount(struct drm_encoder *encoder) 249 { 250 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 251 struct mdp5_kms *mdp5_kms = get_kms(encoder); 252 int intf = mdp5_encoder->intf->num; 253 254 return mdp5_read(mdp5_kms, REG_MDP5_INTF_LINE_COUNT(intf)); 255 } 256 257 u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder) 258 { 259 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 260 struct mdp5_kms *mdp5_kms = get_kms(encoder); 261 int intf = mdp5_encoder->intf->num; 262 263 return mdp5_read(mdp5_kms, REG_MDP5_INTF_FRAME_COUNT(intf)); 264 } 265 266 void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode) 267 { 268 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); 269 struct mdp5_interface *intf = mdp5_encoder->intf; 270 271 /* TODO: Expand this to set writeback modes too */ 272 if (cmd_mode) { 273 WARN_ON(intf->type != INTF_DSI); 274 intf->mode = MDP5_INTF_DSI_MODE_COMMAND; 275 } else { 276 if (intf->type == INTF_DSI) 277 intf->mode = MDP5_INTF_DSI_MODE_VIDEO; 278 else 279 intf->mode = MDP5_INTF_MODE_NONE; 280 } 281 } 282 283 /* initialize encoder */ 284 struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, 285 struct mdp5_interface *intf, 286 struct mdp5_ctl *ctl) 287 { 288 struct drm_encoder *encoder = NULL; 289 struct mdp5_encoder *mdp5_encoder; 290 int enc_type = (intf->type == INTF_DSI) ? 291 DRM_MODE_ENCODER_DSI : DRM_MODE_ENCODER_TMDS; 292 293 mdp5_encoder = drmm_encoder_alloc(dev, struct mdp5_encoder, base, 294 NULL, enc_type, NULL); 295 if (IS_ERR(mdp5_encoder)) 296 return ERR_CAST(mdp5_encoder); 297 298 encoder = &mdp5_encoder->base; 299 mdp5_encoder->ctl = ctl; 300 mdp5_encoder->intf = intf; 301 302 spin_lock_init(&mdp5_encoder->intf_lock); 303 304 drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs); 305 306 return encoder; 307 } 308