0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/clk.h>
0009 #include <linux/component.h>
0010 #include <linux/device.h>
0011 #include <linux/dma-mapping.h>
0012 #include <linux/errno.h>
0013 #include <linux/export.h>
0014 #include <linux/module.h>
0015 #include <linux/platform_device.h>
0016
0017 #include <video/imx-ipu-v3.h>
0018
0019 #include <drm/drm_atomic.h>
0020 #include <drm/drm_atomic_helper.h>
0021 #include <drm/drm_fb_cma_helper.h>
0022 #include <drm/drm_gem_cma_helper.h>
0023 #include <drm/drm_managed.h>
0024 #include <drm/drm_probe_helper.h>
0025 #include <drm/drm_vblank.h>
0026
0027 #include "imx-drm.h"
0028 #include "ipuv3-plane.h"
0029
0030 #define DRIVER_DESC "i.MX IPUv3 Graphics"
0031
0032 struct ipu_crtc {
0033 struct device *dev;
0034 struct drm_crtc base;
0035
0036
0037 struct ipu_plane *plane[2];
0038
0039 struct ipu_dc *dc;
0040 struct ipu_di *di;
0041 int irq;
0042 struct drm_pending_vblank_event *event;
0043 };
0044
0045 static inline struct ipu_crtc *to_ipu_crtc(struct drm_crtc *crtc)
0046 {
0047 return container_of(crtc, struct ipu_crtc, base);
0048 }
0049
0050 static void ipu_crtc_atomic_enable(struct drm_crtc *crtc,
0051 struct drm_atomic_state *state)
0052 {
0053 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
0054 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
0055
0056 ipu_prg_enable(ipu);
0057 ipu_dc_enable(ipu);
0058 ipu_dc_enable_channel(ipu_crtc->dc);
0059 ipu_di_enable(ipu_crtc->di);
0060 }
0061
0062 static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc,
0063 struct drm_crtc_state *old_crtc_state)
0064 {
0065 bool disable_partial = false;
0066 bool disable_full = false;
0067 struct drm_plane *plane;
0068
0069 drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) {
0070 if (plane == &ipu_crtc->plane[0]->base)
0071 disable_full = true;
0072 if (ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base)
0073 disable_partial = true;
0074 }
0075
0076 if (disable_partial)
0077 ipu_plane_disable(ipu_crtc->plane[1], true);
0078 if (disable_full)
0079 ipu_plane_disable(ipu_crtc->plane[0], true);
0080 }
0081
0082 static void ipu_crtc_atomic_disable(struct drm_crtc *crtc,
0083 struct drm_atomic_state *state)
0084 {
0085 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
0086 crtc);
0087 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
0088 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
0089
0090 ipu_dc_disable_channel(ipu_crtc->dc);
0091 ipu_di_disable(ipu_crtc->di);
0092
0093
0094
0095
0096
0097 ipu_crtc_disable_planes(ipu_crtc, old_crtc_state);
0098 ipu_dc_disable(ipu);
0099 ipu_prg_disable(ipu);
0100
0101 drm_crtc_vblank_off(crtc);
0102
0103 spin_lock_irq(&crtc->dev->event_lock);
0104 if (crtc->state->event && !crtc->state->active) {
0105 drm_crtc_send_vblank_event(crtc, crtc->state->event);
0106 crtc->state->event = NULL;
0107 }
0108 spin_unlock_irq(&crtc->dev->event_lock);
0109 }
0110
0111 static void imx_drm_crtc_reset(struct drm_crtc *crtc)
0112 {
0113 struct imx_crtc_state *state;
0114
0115 if (crtc->state)
0116 __drm_atomic_helper_crtc_destroy_state(crtc->state);
0117
0118 kfree(to_imx_crtc_state(crtc->state));
0119 crtc->state = NULL;
0120
0121 state = kzalloc(sizeof(*state), GFP_KERNEL);
0122 if (state)
0123 __drm_atomic_helper_crtc_reset(crtc, &state->base);
0124 }
0125
0126 static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc)
0127 {
0128 struct imx_crtc_state *state;
0129
0130 state = kzalloc(sizeof(*state), GFP_KERNEL);
0131 if (!state)
0132 return NULL;
0133
0134 __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
0135
0136 WARN_ON(state->base.crtc != crtc);
0137 state->base.crtc = crtc;
0138
0139 return &state->base;
0140 }
0141
0142 static void imx_drm_crtc_destroy_state(struct drm_crtc *crtc,
0143 struct drm_crtc_state *state)
0144 {
0145 __drm_atomic_helper_crtc_destroy_state(state);
0146 kfree(to_imx_crtc_state(state));
0147 }
0148
0149 static int ipu_enable_vblank(struct drm_crtc *crtc)
0150 {
0151 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
0152
0153 enable_irq(ipu_crtc->irq);
0154
0155 return 0;
0156 }
0157
0158 static void ipu_disable_vblank(struct drm_crtc *crtc)
0159 {
0160 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
0161
0162 disable_irq_nosync(ipu_crtc->irq);
0163 }
0164
0165 static const struct drm_crtc_funcs ipu_crtc_funcs = {
0166 .set_config = drm_atomic_helper_set_config,
0167 .page_flip = drm_atomic_helper_page_flip,
0168 .reset = imx_drm_crtc_reset,
0169 .atomic_duplicate_state = imx_drm_crtc_duplicate_state,
0170 .atomic_destroy_state = imx_drm_crtc_destroy_state,
0171 .enable_vblank = ipu_enable_vblank,
0172 .disable_vblank = ipu_disable_vblank,
0173 };
0174
0175 static irqreturn_t ipu_irq_handler(int irq, void *dev_id)
0176 {
0177 struct ipu_crtc *ipu_crtc = dev_id;
0178 struct drm_crtc *crtc = &ipu_crtc->base;
0179 unsigned long flags;
0180 int i;
0181
0182 drm_crtc_handle_vblank(crtc);
0183
0184 if (ipu_crtc->event) {
0185 for (i = 0; i < ARRAY_SIZE(ipu_crtc->plane); i++) {
0186 struct ipu_plane *plane = ipu_crtc->plane[i];
0187
0188 if (!plane)
0189 continue;
0190
0191 if (ipu_plane_atomic_update_pending(&plane->base))
0192 break;
0193 }
0194
0195 if (i == ARRAY_SIZE(ipu_crtc->plane)) {
0196 spin_lock_irqsave(&crtc->dev->event_lock, flags);
0197 drm_crtc_send_vblank_event(crtc, ipu_crtc->event);
0198 ipu_crtc->event = NULL;
0199 drm_crtc_vblank_put(crtc);
0200 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
0201 }
0202 }
0203
0204 return IRQ_HANDLED;
0205 }
0206
0207 static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc,
0208 const struct drm_display_mode *mode,
0209 struct drm_display_mode *adjusted_mode)
0210 {
0211 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
0212 struct videomode vm;
0213 int ret;
0214
0215 drm_display_mode_to_videomode(adjusted_mode, &vm);
0216
0217 ret = ipu_di_adjust_videomode(ipu_crtc->di, &vm);
0218 if (ret)
0219 return false;
0220
0221 if ((vm.vsync_len == 0) || (vm.hsync_len == 0))
0222 return false;
0223
0224 drm_display_mode_from_videomode(&vm, adjusted_mode);
0225
0226 return true;
0227 }
0228
0229 static int ipu_crtc_atomic_check(struct drm_crtc *crtc,
0230 struct drm_atomic_state *state)
0231 {
0232 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
0233 crtc);
0234 u32 primary_plane_mask = drm_plane_mask(crtc->primary);
0235
0236 if (crtc_state->active && (primary_plane_mask & crtc_state->plane_mask) == 0)
0237 return -EINVAL;
0238
0239 return 0;
0240 }
0241
0242 static void ipu_crtc_atomic_begin(struct drm_crtc *crtc,
0243 struct drm_atomic_state *state)
0244 {
0245 drm_crtc_vblank_on(crtc);
0246 }
0247
0248 static void ipu_crtc_atomic_flush(struct drm_crtc *crtc,
0249 struct drm_atomic_state *state)
0250 {
0251 spin_lock_irq(&crtc->dev->event_lock);
0252 if (crtc->state->event) {
0253 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
0254
0255 WARN_ON(drm_crtc_vblank_get(crtc));
0256 ipu_crtc->event = crtc->state->event;
0257 crtc->state->event = NULL;
0258 }
0259 spin_unlock_irq(&crtc->dev->event_lock);
0260 }
0261
0262 static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc)
0263 {
0264 struct drm_device *dev = crtc->dev;
0265 struct drm_encoder *encoder;
0266 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
0267 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
0268 struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state);
0269 struct ipu_di_signal_cfg sig_cfg = {};
0270 unsigned long encoder_types = 0;
0271
0272 dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
0273 mode->hdisplay);
0274 dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
0275 mode->vdisplay);
0276
0277 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
0278 if (encoder->crtc == crtc)
0279 encoder_types |= BIT(encoder->encoder_type);
0280 }
0281
0282 dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n",
0283 __func__, encoder_types);
0284
0285
0286
0287
0288
0289
0290 if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) |
0291 BIT(DRM_MODE_ENCODER_LVDS)))
0292 sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT;
0293 else if (encoder_types & BIT(DRM_MODE_ENCODER_TVDAC))
0294 sig_cfg.clkflags = IPU_DI_CLKMODE_EXT;
0295 else
0296 sig_cfg.clkflags = 0;
0297
0298 sig_cfg.enable_pol = !(imx_crtc_state->bus_flags & DRM_BUS_FLAG_DE_LOW);
0299
0300 sig_cfg.clk_pol = !!(imx_crtc_state->bus_flags &
0301 DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE);
0302 sig_cfg.bus_format = imx_crtc_state->bus_format;
0303 sig_cfg.v_to_h_sync = 0;
0304 sig_cfg.hsync_pin = imx_crtc_state->di_hsync_pin;
0305 sig_cfg.vsync_pin = imx_crtc_state->di_vsync_pin;
0306
0307 drm_display_mode_to_videomode(mode, &sig_cfg.mode);
0308 if (!IS_ALIGNED(sig_cfg.mode.hactive, 8)) {
0309 unsigned int new_hactive = ALIGN(sig_cfg.mode.hactive, 8);
0310
0311 dev_warn(ipu_crtc->dev, "8-pixel align hactive %d -> %d\n",
0312 sig_cfg.mode.hactive, new_hactive);
0313
0314 sig_cfg.mode.hfront_porch = new_hactive - sig_cfg.mode.hactive;
0315 sig_cfg.mode.hactive = new_hactive;
0316 }
0317
0318 ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di,
0319 mode->flags & DRM_MODE_FLAG_INTERLACE,
0320 imx_crtc_state->bus_format, sig_cfg.mode.hactive);
0321 ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg);
0322 }
0323
0324 static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
0325 .mode_fixup = ipu_crtc_mode_fixup,
0326 .mode_set_nofb = ipu_crtc_mode_set_nofb,
0327 .atomic_check = ipu_crtc_atomic_check,
0328 .atomic_begin = ipu_crtc_atomic_begin,
0329 .atomic_flush = ipu_crtc_atomic_flush,
0330 .atomic_disable = ipu_crtc_atomic_disable,
0331 .atomic_enable = ipu_crtc_atomic_enable,
0332 };
0333
0334 static void ipu_put_resources(struct drm_device *dev, void *ptr)
0335 {
0336 struct ipu_crtc *ipu_crtc = ptr;
0337
0338 if (!IS_ERR_OR_NULL(ipu_crtc->dc))
0339 ipu_dc_put(ipu_crtc->dc);
0340 if (!IS_ERR_OR_NULL(ipu_crtc->di))
0341 ipu_di_put(ipu_crtc->di);
0342 }
0343
0344 static int ipu_get_resources(struct drm_device *dev, struct ipu_crtc *ipu_crtc,
0345 struct ipu_client_platformdata *pdata)
0346 {
0347 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
0348 int ret;
0349
0350 ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc);
0351 if (IS_ERR(ipu_crtc->dc))
0352 return PTR_ERR(ipu_crtc->dc);
0353
0354 ret = drmm_add_action_or_reset(dev, ipu_put_resources, ipu_crtc);
0355 if (ret)
0356 return ret;
0357
0358 ipu_crtc->di = ipu_di_get(ipu, pdata->di);
0359 if (IS_ERR(ipu_crtc->di))
0360 return PTR_ERR(ipu_crtc->di);
0361
0362 return 0;
0363 }
0364
0365 static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
0366 {
0367 struct ipu_client_platformdata *pdata = dev->platform_data;
0368 struct ipu_soc *ipu = dev_get_drvdata(dev->parent);
0369 struct drm_device *drm = data;
0370 struct ipu_plane *primary_plane;
0371 struct ipu_crtc *ipu_crtc;
0372 struct drm_crtc *crtc;
0373 int dp = -EINVAL;
0374 int ret;
0375
0376 if (pdata->dp >= 0)
0377 dp = IPU_DP_FLOW_SYNC_BG;
0378 primary_plane = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0,
0379 DRM_PLANE_TYPE_PRIMARY);
0380 if (IS_ERR(primary_plane))
0381 return PTR_ERR(primary_plane);
0382
0383 ipu_crtc = drmm_crtc_alloc_with_planes(drm, struct ipu_crtc, base,
0384 &primary_plane->base, NULL,
0385 &ipu_crtc_funcs, NULL);
0386 if (IS_ERR(ipu_crtc))
0387 return PTR_ERR(ipu_crtc);
0388
0389 ipu_crtc->dev = dev;
0390 ipu_crtc->plane[0] = primary_plane;
0391
0392 crtc = &ipu_crtc->base;
0393 crtc->port = pdata->of_node;
0394 drm_crtc_helper_add(crtc, &ipu_helper_funcs);
0395
0396 ret = ipu_get_resources(drm, ipu_crtc, pdata);
0397 if (ret) {
0398 dev_err(ipu_crtc->dev, "getting resources failed with %d.\n",
0399 ret);
0400 return ret;
0401 }
0402
0403
0404 if (pdata->dp >= 0 && pdata->dma[1] > 0) {
0405 ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1],
0406 IPU_DP_FLOW_SYNC_FG,
0407 drm_crtc_mask(&ipu_crtc->base),
0408 DRM_PLANE_TYPE_OVERLAY);
0409 if (IS_ERR(ipu_crtc->plane[1]))
0410 ipu_crtc->plane[1] = NULL;
0411 }
0412
0413 ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
0414 ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
0415 "imx_drm", ipu_crtc);
0416 if (ret < 0) {
0417 dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
0418 return ret;
0419 }
0420
0421 disable_irq(ipu_crtc->irq);
0422
0423 return 0;
0424 }
0425
0426 static const struct component_ops ipu_crtc_ops = {
0427 .bind = ipu_drm_bind,
0428 };
0429
0430 static int ipu_drm_probe(struct platform_device *pdev)
0431 {
0432 struct device *dev = &pdev->dev;
0433 int ret;
0434
0435 if (!dev->platform_data)
0436 return -EINVAL;
0437
0438 ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
0439 if (ret)
0440 return ret;
0441
0442 return component_add(dev, &ipu_crtc_ops);
0443 }
0444
0445 static int ipu_drm_remove(struct platform_device *pdev)
0446 {
0447 component_del(&pdev->dev, &ipu_crtc_ops);
0448 return 0;
0449 }
0450
0451 struct platform_driver ipu_drm_driver = {
0452 .driver = {
0453 .name = "imx-ipuv3-crtc",
0454 },
0455 .probe = ipu_drm_probe,
0456 .remove = ipu_drm_remove,
0457 };