0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk.h>
0011 #include <linux/mutex.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/sys_soc.h>
0014
0015 #include <drm/drm_atomic.h>
0016 #include <drm/drm_atomic_helper.h>
0017 #include <drm/drm_bridge.h>
0018 #include <drm/drm_crtc.h>
0019 #include <drm/drm_device.h>
0020 #include <drm/drm_fb_cma_helper.h>
0021 #include <drm/drm_gem_cma_helper.h>
0022 #include <drm/drm_plane_helper.h>
0023 #include <drm/drm_vblank.h>
0024
0025 #include "rcar_cmm.h"
0026 #include "rcar_du_crtc.h"
0027 #include "rcar_du_drv.h"
0028 #include "rcar_du_encoder.h"
0029 #include "rcar_du_kms.h"
0030 #include "rcar_du_plane.h"
0031 #include "rcar_du_regs.h"
0032 #include "rcar_du_vsp.h"
0033 #include "rcar_lvds.h"
0034
0035 static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
0036 {
0037 struct rcar_du_device *rcdu = rcrtc->dev;
0038
0039 return rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
0040 }
0041
0042 static void rcar_du_crtc_write(struct rcar_du_crtc *rcrtc, u32 reg, u32 data)
0043 {
0044 struct rcar_du_device *rcdu = rcrtc->dev;
0045
0046 rcar_du_write(rcdu, rcrtc->mmio_offset + reg, data);
0047 }
0048
0049 static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr)
0050 {
0051 struct rcar_du_device *rcdu = rcrtc->dev;
0052
0053 rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
0054 rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
0055 }
0056
0057 static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
0058 {
0059 struct rcar_du_device *rcdu = rcrtc->dev;
0060
0061 rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
0062 rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
0063 }
0064
0065 void rcar_du_crtc_dsysr_clr_set(struct rcar_du_crtc *rcrtc, u32 clr, u32 set)
0066 {
0067 struct rcar_du_device *rcdu = rcrtc->dev;
0068
0069 rcrtc->dsysr = (rcrtc->dsysr & ~clr) | set;
0070 rcar_du_write(rcdu, rcrtc->mmio_offset + DSYSR, rcrtc->dsysr);
0071 }
0072
0073
0074
0075
0076
0077 struct dpll_info {
0078 unsigned int output;
0079 unsigned int fdpll;
0080 unsigned int n;
0081 unsigned int m;
0082 };
0083
0084 static void rcar_du_dpll_divider(struct rcar_du_crtc *rcrtc,
0085 struct dpll_info *dpll,
0086 unsigned long input,
0087 unsigned long target)
0088 {
0089 unsigned long best_diff = (unsigned long)-1;
0090 unsigned long diff;
0091 unsigned int fdpll;
0092 unsigned int m;
0093 unsigned int n;
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 for (m = 0; m < 4; m++) {
0124 for (n = 119; n > 38; n--) {
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 unsigned long fout = input * (n + 1) / (m + 1);
0135
0136 if (fout < 1000 || fout > 2048 * 1000 * 1000U)
0137 continue;
0138
0139 for (fdpll = 1; fdpll < 32; fdpll++) {
0140 unsigned long output;
0141
0142 output = fout / (fdpll + 1);
0143 if (output >= 400 * 1000 * 1000)
0144 continue;
0145
0146 diff = abs((long)output - (long)target);
0147 if (best_diff > diff) {
0148 best_diff = diff;
0149 dpll->n = n;
0150 dpll->m = m;
0151 dpll->fdpll = fdpll;
0152 dpll->output = output;
0153 }
0154
0155 if (diff == 0)
0156 goto done;
0157 }
0158 }
0159 }
0160
0161 done:
0162 dev_dbg(rcrtc->dev->dev,
0163 "output:%u, fdpll:%u, n:%u, m:%u, diff:%lu\n",
0164 dpll->output, dpll->fdpll, dpll->n, dpll->m, best_diff);
0165 }
0166
0167 struct du_clk_params {
0168 struct clk *clk;
0169 unsigned long rate;
0170 unsigned long diff;
0171 u32 escr;
0172 };
0173
0174 static void rcar_du_escr_divider(struct clk *clk, unsigned long target,
0175 u32 escr, struct du_clk_params *params)
0176 {
0177 unsigned long rate;
0178 unsigned long diff;
0179 u32 div;
0180
0181
0182
0183
0184
0185 if (params->diff == 0)
0186 return;
0187
0188
0189
0190
0191
0192 rate = clk_round_rate(clk, target);
0193 div = clamp(DIV_ROUND_CLOSEST(rate, target), 1UL, 64UL) - 1;
0194 diff = abs(rate / (div + 1) - target);
0195
0196
0197
0198
0199
0200 if (diff < params->diff) {
0201 params->clk = clk;
0202 params->rate = rate;
0203 params->diff = diff;
0204 params->escr = escr | div;
0205 }
0206 }
0207
0208 static const struct soc_device_attribute rcar_du_r8a7795_es1[] = {
0209 { .soc_id = "r8a7795", .revision = "ES1.*" },
0210 { }
0211 };
0212
0213 static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
0214 {
0215 const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
0216 struct rcar_du_device *rcdu = rcrtc->dev;
0217 unsigned long mode_clock = mode->clock * 1000;
0218 unsigned int hdse_offset;
0219 u32 dsmr;
0220 u32 escr;
0221
0222 if (rcdu->info->dpll_mask & (1 << rcrtc->index)) {
0223 unsigned long target = mode_clock;
0224 struct dpll_info dpll = { 0 };
0225 unsigned long extclk;
0226 u32 dpllcr;
0227 u32 div = 0;
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 if (soc_device_match(rcar_du_r8a7795_es1)) {
0243 target *= 2;
0244 div = 1;
0245 }
0246
0247 extclk = clk_get_rate(rcrtc->extclock);
0248 rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
0249
0250 dpllcr = DPLLCR_CODE | DPLLCR_CLKE
0251 | DPLLCR_FDPLL(dpll.fdpll)
0252 | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
0253 | DPLLCR_STBY;
0254
0255 if (rcrtc->index == 1)
0256 dpllcr |= DPLLCR_PLCS1
0257 | DPLLCR_INCS_DOTCLKIN1;
0258 else
0259 dpllcr |= DPLLCR_PLCS0
0260 | DPLLCR_INCS_DOTCLKIN0;
0261
0262 rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
0263
0264 escr = ESCR_DCLKSEL_DCLKIN | div;
0265 } else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) ||
0266 rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) {
0267
0268
0269
0270
0271
0272
0273 escr = ESCR_DCLKSEL_DCLKIN;
0274 } else {
0275 struct du_clk_params params = { .diff = (unsigned long)-1 };
0276
0277 rcar_du_escr_divider(rcrtc->clock, mode_clock,
0278 ESCR_DCLKSEL_CLKS, ¶ms);
0279 if (rcrtc->extclock)
0280 rcar_du_escr_divider(rcrtc->extclock, mode_clock,
0281 ESCR_DCLKSEL_DCLKIN, ¶ms);
0282
0283 dev_dbg(rcrtc->dev->dev, "mode clock %lu %s rate %lu\n",
0284 mode_clock, params.clk == rcrtc->clock ? "cpg" : "ext",
0285 params.rate);
0286
0287 clk_set_rate(params.clk, params.rate);
0288 escr = params.escr;
0289 }
0290
0291 dev_dbg(rcrtc->dev->dev, "%s: ESCR 0x%08x\n", __func__, escr);
0292
0293 rcar_du_crtc_write(rcrtc, rcrtc->index % 2 ? ESCR13 : ESCR02, escr);
0294 rcar_du_crtc_write(rcrtc, rcrtc->index % 2 ? OTAR13 : OTAR02, 0);
0295
0296
0297 dsmr = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
0298 | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
0299 | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0)
0300 | DSMR_DIPM_DISP | DSMR_CSPM;
0301 rcar_du_crtc_write(rcrtc, DSMR, dsmr);
0302
0303
0304
0305
0306
0307
0308 hdse_offset = 19;
0309 if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2))
0310 hdse_offset += 25;
0311
0312
0313 rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start -
0314 hdse_offset);
0315 rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start +
0316 mode->hdisplay - hdse_offset);
0317 rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end -
0318 mode->hsync_start - 1);
0319 rcar_du_crtc_write(rcrtc, HCR, mode->htotal - 1);
0320
0321 rcar_du_crtc_write(rcrtc, VDSR, mode->crtc_vtotal -
0322 mode->crtc_vsync_end - 2);
0323 rcar_du_crtc_write(rcrtc, VDER, mode->crtc_vtotal -
0324 mode->crtc_vsync_end +
0325 mode->crtc_vdisplay - 2);
0326 rcar_du_crtc_write(rcrtc, VSPR, mode->crtc_vtotal -
0327 mode->crtc_vsync_end +
0328 mode->crtc_vsync_start - 1);
0329 rcar_du_crtc_write(rcrtc, VCR, mode->crtc_vtotal - 1);
0330
0331 rcar_du_crtc_write(rcrtc, DESR, mode->htotal - mode->hsync_start - 1);
0332 rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay);
0333 }
0334
0335 static unsigned int plane_zpos(struct rcar_du_plane *plane)
0336 {
0337 return plane->plane.state->normalized_zpos;
0338 }
0339
0340 static const struct rcar_du_format_info *
0341 plane_format(struct rcar_du_plane *plane)
0342 {
0343 return to_rcar_plane_state(plane->plane.state)->format;
0344 }
0345
0346 static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
0347 {
0348 struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
0349 struct rcar_du_device *rcdu = rcrtc->dev;
0350 unsigned int num_planes = 0;
0351 unsigned int dptsr_planes;
0352 unsigned int hwplanes = 0;
0353 unsigned int prio = 0;
0354 unsigned int i;
0355 u32 dspr = 0;
0356
0357 for (i = 0; i < rcrtc->group->num_planes; ++i) {
0358 struct rcar_du_plane *plane = &rcrtc->group->planes[i];
0359 unsigned int j;
0360
0361 if (plane->plane.state->crtc != &rcrtc->crtc ||
0362 !plane->plane.state->visible)
0363 continue;
0364
0365
0366 for (j = num_planes++; j > 0; --j) {
0367 if (plane_zpos(planes[j-1]) <= plane_zpos(plane))
0368 break;
0369 planes[j] = planes[j-1];
0370 }
0371
0372 planes[j] = plane;
0373 prio += plane_format(plane)->planes * 4;
0374 }
0375
0376 for (i = 0; i < num_planes; ++i) {
0377 struct rcar_du_plane *plane = planes[i];
0378 struct drm_plane_state *state = plane->plane.state;
0379 unsigned int index = to_rcar_plane_state(state)->hwindex;
0380
0381 prio -= 4;
0382 dspr |= (index + 1) << prio;
0383 hwplanes |= 1 << index;
0384
0385 if (plane_format(plane)->planes == 2) {
0386 index = (index + 1) % 8;
0387
0388 prio -= 4;
0389 dspr |= (index + 1) << prio;
0390 hwplanes |= 1 << index;
0391 }
0392 }
0393
0394
0395 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
0396 if (rcdu->info->gen < 3) {
0397 dspr = (rcrtc->index % 2) + 1;
0398 hwplanes = 1 << (rcrtc->index % 2);
0399 } else {
0400 dspr = (rcrtc->index % 2) ? 3 : 1;
0401 hwplanes = 1 << ((rcrtc->index % 2) ? 2 : 0);
0402 }
0403 }
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 mutex_lock(&rcrtc->group->lock);
0415
0416 dptsr_planes = rcrtc->index % 2 ? rcrtc->group->dptsr_planes | hwplanes
0417 : rcrtc->group->dptsr_planes & ~hwplanes;
0418
0419 if (dptsr_planes != rcrtc->group->dptsr_planes) {
0420 rcar_du_group_write(rcrtc->group, DPTSR,
0421 (dptsr_planes << 16) | dptsr_planes);
0422 rcrtc->group->dptsr_planes = dptsr_planes;
0423
0424 if (rcrtc->group->used_crtcs)
0425 rcar_du_group_restart(rcrtc->group);
0426 }
0427
0428
0429 if (rcrtc->group->need_restart)
0430 rcar_du_group_restart(rcrtc->group);
0431
0432 mutex_unlock(&rcrtc->group->lock);
0433
0434 rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
0435 dspr);
0436 }
0437
0438
0439
0440
0441
0442 void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc)
0443 {
0444 struct drm_pending_vblank_event *event;
0445 struct drm_device *dev = rcrtc->crtc.dev;
0446 unsigned long flags;
0447
0448 spin_lock_irqsave(&dev->event_lock, flags);
0449 event = rcrtc->event;
0450 rcrtc->event = NULL;
0451 spin_unlock_irqrestore(&dev->event_lock, flags);
0452
0453 if (event == NULL)
0454 return;
0455
0456 spin_lock_irqsave(&dev->event_lock, flags);
0457 drm_crtc_send_vblank_event(&rcrtc->crtc, event);
0458 wake_up(&rcrtc->flip_wait);
0459 spin_unlock_irqrestore(&dev->event_lock, flags);
0460
0461 drm_crtc_vblank_put(&rcrtc->crtc);
0462 }
0463
0464 static bool rcar_du_crtc_page_flip_pending(struct rcar_du_crtc *rcrtc)
0465 {
0466 struct drm_device *dev = rcrtc->crtc.dev;
0467 unsigned long flags;
0468 bool pending;
0469
0470 spin_lock_irqsave(&dev->event_lock, flags);
0471 pending = rcrtc->event != NULL;
0472 spin_unlock_irqrestore(&dev->event_lock, flags);
0473
0474 return pending;
0475 }
0476
0477 static void rcar_du_crtc_wait_page_flip(struct rcar_du_crtc *rcrtc)
0478 {
0479 struct rcar_du_device *rcdu = rcrtc->dev;
0480
0481 if (wait_event_timeout(rcrtc->flip_wait,
0482 !rcar_du_crtc_page_flip_pending(rcrtc),
0483 msecs_to_jiffies(50)))
0484 return;
0485
0486 dev_warn(rcdu->dev, "page flip timeout\n");
0487
0488 rcar_du_crtc_finish_page_flip(rcrtc);
0489 }
0490
0491
0492
0493
0494
0495 static int rcar_du_cmm_check(struct drm_crtc *crtc,
0496 struct drm_crtc_state *state)
0497 {
0498 struct drm_property_blob *drm_lut = state->gamma_lut;
0499 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
0500 struct device *dev = rcrtc->dev->dev;
0501
0502 if (!drm_lut)
0503 return 0;
0504
0505
0506 if (drm_color_lut_size(drm_lut) != CM2_LUT_SIZE) {
0507 dev_err(dev, "invalid gamma lut size: %zu bytes\n",
0508 drm_lut->length);
0509 return -EINVAL;
0510 }
0511
0512 return 0;
0513 }
0514
0515 static void rcar_du_cmm_setup(struct drm_crtc *crtc)
0516 {
0517 struct drm_property_blob *drm_lut = crtc->state->gamma_lut;
0518 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
0519 struct rcar_cmm_config cmm_config = {};
0520
0521 if (!rcrtc->cmm)
0522 return;
0523
0524 if (drm_lut)
0525 cmm_config.lut.table = (struct drm_color_lut *)drm_lut->data;
0526
0527 rcar_cmm_setup(rcrtc->cmm, &cmm_config);
0528 }
0529
0530
0531
0532
0533
0534 static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
0535 {
0536
0537 rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
0538 rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0));
0539
0540
0541 rcar_du_crtc_set_display_timing(rcrtc);
0542 rcar_du_group_set_routing(rcrtc->group);
0543
0544
0545 rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
0546
0547
0548 if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
0549 rcar_du_vsp_enable(rcrtc);
0550
0551
0552 drm_crtc_vblank_on(&rcrtc->crtc);
0553 }
0554
0555 static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
0556 {
0557 int ret;
0558
0559
0560
0561
0562
0563 if (rcrtc->initialized)
0564 return 0;
0565
0566 ret = clk_prepare_enable(rcrtc->clock);
0567 if (ret < 0)
0568 return ret;
0569
0570 ret = clk_prepare_enable(rcrtc->extclock);
0571 if (ret < 0)
0572 goto error_clock;
0573
0574 ret = rcar_du_group_get(rcrtc->group);
0575 if (ret < 0)
0576 goto error_group;
0577
0578 rcar_du_crtc_setup(rcrtc);
0579 rcrtc->initialized = true;
0580
0581 return 0;
0582
0583 error_group:
0584 clk_disable_unprepare(rcrtc->extclock);
0585 error_clock:
0586 clk_disable_unprepare(rcrtc->clock);
0587 return ret;
0588 }
0589
0590 static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
0591 {
0592 rcar_du_group_put(rcrtc->group);
0593
0594 clk_disable_unprepare(rcrtc->extclock);
0595 clk_disable_unprepare(rcrtc->clock);
0596
0597 rcrtc->initialized = false;
0598 }
0599
0600 static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
0601 {
0602 bool interlaced;
0603
0604
0605
0606
0607
0608
0609 interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE;
0610 rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
0611 (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
0612 DSYSR_TVM_MASTER);
0613
0614 rcar_du_group_start_stop(rcrtc->group, true);
0615 }
0616
0617 static void rcar_du_crtc_disable_planes(struct rcar_du_crtc *rcrtc)
0618 {
0619 struct rcar_du_device *rcdu = rcrtc->dev;
0620 struct drm_crtc *crtc = &rcrtc->crtc;
0621 u32 status;
0622
0623
0624 drm_crtc_vblank_get(crtc);
0625
0626
0627
0628
0629
0630
0631
0632
0633 spin_lock_irq(&rcrtc->vblank_lock);
0634 rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
0635 status = rcar_du_crtc_read(rcrtc, DSSR);
0636 rcrtc->vblank_count = status & DSSR_VBK ? 2 : 1;
0637 spin_unlock_irq(&rcrtc->vblank_lock);
0638
0639 if (!wait_event_timeout(rcrtc->vblank_wait, rcrtc->vblank_count == 0,
0640 msecs_to_jiffies(100)))
0641 dev_warn(rcdu->dev, "vertical blanking timeout\n");
0642
0643 drm_crtc_vblank_put(crtc);
0644 }
0645
0646 static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
0647 {
0648 struct drm_crtc *crtc = &rcrtc->crtc;
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661 rcar_du_crtc_disable_planes(rcrtc);
0662
0663
0664
0665
0666
0667
0668 rcar_du_crtc_wait_page_flip(rcrtc);
0669 drm_crtc_vblank_off(crtc);
0670
0671
0672 if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
0673 rcar_du_vsp_disable(rcrtc);
0674
0675 if (rcrtc->cmm)
0676 rcar_cmm_disable(rcrtc->cmm);
0677
0678
0679
0680
0681
0682
0683
0684
0685 if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_TVM_SYNC))
0686 rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_TVM_MASK,
0687 DSYSR_TVM_SWITCH);
0688
0689 rcar_du_group_start_stop(rcrtc->group, false);
0690 }
0691
0692
0693
0694
0695
0696 static int rcar_du_crtc_atomic_check(struct drm_crtc *crtc,
0697 struct drm_atomic_state *state)
0698 {
0699 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
0700 crtc);
0701 struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc_state);
0702 struct drm_encoder *encoder;
0703 int ret;
0704
0705 ret = rcar_du_cmm_check(crtc, crtc_state);
0706 if (ret)
0707 return ret;
0708
0709
0710 rstate->outputs = 0;
0711
0712 drm_for_each_encoder_mask(encoder, crtc->dev,
0713 crtc_state->encoder_mask) {
0714 struct rcar_du_encoder *renc;
0715
0716
0717 if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
0718 continue;
0719
0720 renc = to_rcar_encoder(encoder);
0721 rstate->outputs |= BIT(renc->output);
0722 }
0723
0724 return 0;
0725 }
0726
0727 static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
0728 struct drm_atomic_state *state)
0729 {
0730 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
0731 struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc->state);
0732 struct rcar_du_device *rcdu = rcrtc->dev;
0733
0734 if (rcrtc->cmm)
0735 rcar_cmm_enable(rcrtc->cmm);
0736 rcar_du_crtc_get(rcrtc);
0737
0738
0739
0740
0741
0742
0743 if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
0744 rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
0745 struct drm_bridge *bridge = rcdu->lvds[rcrtc->index];
0746 const struct drm_display_mode *mode =
0747 &crtc->state->adjusted_mode;
0748
0749 rcar_lvds_clk_enable(bridge, mode->clock * 1000);
0750 }
0751
0752 rcar_du_crtc_start(rcrtc);
0753
0754
0755
0756
0757
0758
0759 rcar_du_cmm_setup(crtc);
0760 }
0761
0762 static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
0763 struct drm_atomic_state *state)
0764 {
0765 struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
0766 crtc);
0767 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
0768 struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(old_state);
0769 struct rcar_du_device *rcdu = rcrtc->dev;
0770
0771 rcar_du_crtc_stop(rcrtc);
0772 rcar_du_crtc_put(rcrtc);
0773
0774 if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
0775 rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
0776 struct drm_bridge *bridge = rcdu->lvds[rcrtc->index];
0777
0778
0779
0780
0781
0782 rcar_lvds_clk_disable(bridge);
0783 }
0784
0785 spin_lock_irq(&crtc->dev->event_lock);
0786 if (crtc->state->event) {
0787 drm_crtc_send_vblank_event(crtc, crtc->state->event);
0788 crtc->state->event = NULL;
0789 }
0790 spin_unlock_irq(&crtc->dev->event_lock);
0791 }
0792
0793 static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
0794 struct drm_atomic_state *state)
0795 {
0796 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
0797
0798 WARN_ON(!crtc->state->enable);
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812 rcar_du_crtc_get(rcrtc);
0813
0814
0815 if (crtc->state->color_mgmt_changed && !crtc->state->active_changed)
0816 rcar_du_cmm_setup(crtc);
0817
0818 if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
0819 rcar_du_vsp_atomic_begin(rcrtc);
0820 }
0821
0822 static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
0823 struct drm_atomic_state *state)
0824 {
0825 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
0826 struct drm_device *dev = rcrtc->crtc.dev;
0827 unsigned long flags;
0828
0829 rcar_du_crtc_update_planes(rcrtc);
0830
0831 if (crtc->state->event) {
0832 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
0833
0834 spin_lock_irqsave(&dev->event_lock, flags);
0835 rcrtc->event = crtc->state->event;
0836 crtc->state->event = NULL;
0837 spin_unlock_irqrestore(&dev->event_lock, flags);
0838 }
0839
0840 if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
0841 rcar_du_vsp_atomic_flush(rcrtc);
0842 }
0843
0844 static enum drm_mode_status
0845 rcar_du_crtc_mode_valid(struct drm_crtc *crtc,
0846 const struct drm_display_mode *mode)
0847 {
0848 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
0849 struct rcar_du_device *rcdu = rcrtc->dev;
0850 bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
0851 unsigned int min_sync_porch;
0852 unsigned int vbp;
0853
0854 if (interlaced && !rcar_du_has(rcdu, RCAR_DU_FEATURE_INTERLACED))
0855 return MODE_NO_INTERLACE;
0856
0857
0858
0859
0860
0861
0862 min_sync_porch = 20;
0863 if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2))
0864 min_sync_porch += 25;
0865
0866 if (mode->htotal - mode->hsync_start < min_sync_porch)
0867 return MODE_HBLANK_NARROW;
0868
0869 vbp = (mode->vtotal - mode->vsync_end) / (interlaced ? 2 : 1);
0870 if (vbp < 3)
0871 return MODE_VBLANK_NARROW;
0872
0873 return MODE_OK;
0874 }
0875
0876 static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
0877 .atomic_check = rcar_du_crtc_atomic_check,
0878 .atomic_begin = rcar_du_crtc_atomic_begin,
0879 .atomic_flush = rcar_du_crtc_atomic_flush,
0880 .atomic_enable = rcar_du_crtc_atomic_enable,
0881 .atomic_disable = rcar_du_crtc_atomic_disable,
0882 .mode_valid = rcar_du_crtc_mode_valid,
0883 };
0884
0885 static void rcar_du_crtc_crc_init(struct rcar_du_crtc *rcrtc)
0886 {
0887 struct rcar_du_device *rcdu = rcrtc->dev;
0888 const char **sources;
0889 unsigned int count;
0890 int i = -1;
0891
0892
0893 if (rcdu->info->gen < 3)
0894 return;
0895
0896
0897 count = rcrtc->vsp->num_planes + 1;
0898
0899 sources = kmalloc_array(count, sizeof(*sources), GFP_KERNEL);
0900 if (!sources)
0901 return;
0902
0903 sources[0] = kstrdup("auto", GFP_KERNEL);
0904 if (!sources[0])
0905 goto error;
0906
0907 for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
0908 struct drm_plane *plane = &rcrtc->vsp->planes[i].plane;
0909 char name[16];
0910
0911 sprintf(name, "plane%u", plane->base.id);
0912 sources[i + 1] = kstrdup(name, GFP_KERNEL);
0913 if (!sources[i + 1])
0914 goto error;
0915 }
0916
0917 rcrtc->sources = sources;
0918 rcrtc->sources_count = count;
0919 return;
0920
0921 error:
0922 while (i >= 0) {
0923 kfree(sources[i]);
0924 i--;
0925 }
0926 kfree(sources);
0927 }
0928
0929 static void rcar_du_crtc_crc_cleanup(struct rcar_du_crtc *rcrtc)
0930 {
0931 unsigned int i;
0932
0933 if (!rcrtc->sources)
0934 return;
0935
0936 for (i = 0; i < rcrtc->sources_count; i++)
0937 kfree(rcrtc->sources[i]);
0938 kfree(rcrtc->sources);
0939
0940 rcrtc->sources = NULL;
0941 rcrtc->sources_count = 0;
0942 }
0943
0944 static struct drm_crtc_state *
0945 rcar_du_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
0946 {
0947 struct rcar_du_crtc_state *state;
0948 struct rcar_du_crtc_state *copy;
0949
0950 if (WARN_ON(!crtc->state))
0951 return NULL;
0952
0953 state = to_rcar_crtc_state(crtc->state);
0954 copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
0955 if (copy == NULL)
0956 return NULL;
0957
0958 __drm_atomic_helper_crtc_duplicate_state(crtc, ©->state);
0959
0960 return ©->state;
0961 }
0962
0963 static void rcar_du_crtc_atomic_destroy_state(struct drm_crtc *crtc,
0964 struct drm_crtc_state *state)
0965 {
0966 __drm_atomic_helper_crtc_destroy_state(state);
0967 kfree(to_rcar_crtc_state(state));
0968 }
0969
0970 static void rcar_du_crtc_cleanup(struct drm_crtc *crtc)
0971 {
0972 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
0973
0974 rcar_du_crtc_crc_cleanup(rcrtc);
0975
0976 return drm_crtc_cleanup(crtc);
0977 }
0978
0979 static void rcar_du_crtc_reset(struct drm_crtc *crtc)
0980 {
0981 struct rcar_du_crtc_state *state;
0982
0983 if (crtc->state) {
0984 rcar_du_crtc_atomic_destroy_state(crtc, crtc->state);
0985 crtc->state = NULL;
0986 }
0987
0988 state = kzalloc(sizeof(*state), GFP_KERNEL);
0989 if (state == NULL)
0990 return;
0991
0992 state->crc.source = VSP1_DU_CRC_NONE;
0993 state->crc.index = 0;
0994
0995 __drm_atomic_helper_crtc_reset(crtc, &state->state);
0996 }
0997
0998 static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
0999 {
1000 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
1001
1002 rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
1003 rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
1004 rcrtc->vblank_enable = true;
1005
1006 return 0;
1007 }
1008
1009 static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
1010 {
1011 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
1012
1013 rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE);
1014 rcrtc->vblank_enable = false;
1015 }
1016
1017 static int rcar_du_crtc_parse_crc_source(struct rcar_du_crtc *rcrtc,
1018 const char *source_name,
1019 enum vsp1_du_crc_source *source)
1020 {
1021 unsigned int index;
1022 int ret;
1023
1024
1025
1026
1027
1028
1029
1030 if (!source_name) {
1031 *source = VSP1_DU_CRC_NONE;
1032 return 0;
1033 } else if (!strcmp(source_name, "auto")) {
1034 *source = VSP1_DU_CRC_OUTPUT;
1035 return 0;
1036 } else if (strstarts(source_name, "plane")) {
1037 unsigned int i;
1038
1039 *source = VSP1_DU_CRC_PLANE;
1040
1041 ret = kstrtouint(source_name + strlen("plane"), 10, &index);
1042 if (ret < 0)
1043 return ret;
1044
1045 for (i = 0; i < rcrtc->vsp->num_planes; ++i) {
1046 if (index == rcrtc->vsp->planes[i].plane.base.id)
1047 return i;
1048 }
1049 }
1050
1051 return -EINVAL;
1052 }
1053
1054 static int rcar_du_crtc_verify_crc_source(struct drm_crtc *crtc,
1055 const char *source_name,
1056 size_t *values_cnt)
1057 {
1058 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
1059 enum vsp1_du_crc_source source;
1060
1061 if (rcar_du_crtc_parse_crc_source(rcrtc, source_name, &source) < 0) {
1062 DRM_DEBUG_DRIVER("unknown source %s\n", source_name);
1063 return -EINVAL;
1064 }
1065
1066 *values_cnt = 1;
1067 return 0;
1068 }
1069
1070 static const char *const *
1071 rcar_du_crtc_get_crc_sources(struct drm_crtc *crtc, size_t *count)
1072 {
1073 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
1074
1075 *count = rcrtc->sources_count;
1076 return rcrtc->sources;
1077 }
1078
1079 static int rcar_du_crtc_set_crc_source(struct drm_crtc *crtc,
1080 const char *source_name)
1081 {
1082 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
1083 struct drm_modeset_acquire_ctx ctx;
1084 struct drm_crtc_state *crtc_state;
1085 struct drm_atomic_state *state;
1086 enum vsp1_du_crc_source source;
1087 unsigned int index;
1088 int ret;
1089
1090 ret = rcar_du_crtc_parse_crc_source(rcrtc, source_name, &source);
1091 if (ret < 0)
1092 return ret;
1093
1094 index = ret;
1095
1096
1097 drm_modeset_acquire_init(&ctx, 0);
1098
1099 state = drm_atomic_state_alloc(crtc->dev);
1100 if (!state) {
1101 ret = -ENOMEM;
1102 goto unlock;
1103 }
1104
1105 state->acquire_ctx = &ctx;
1106
1107 retry:
1108 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1109 if (!IS_ERR(crtc_state)) {
1110 struct rcar_du_crtc_state *rcrtc_state;
1111
1112 rcrtc_state = to_rcar_crtc_state(crtc_state);
1113 rcrtc_state->crc.source = source;
1114 rcrtc_state->crc.index = index;
1115
1116 ret = drm_atomic_commit(state);
1117 } else {
1118 ret = PTR_ERR(crtc_state);
1119 }
1120
1121 if (ret == -EDEADLK) {
1122 drm_atomic_state_clear(state);
1123 drm_modeset_backoff(&ctx);
1124 goto retry;
1125 }
1126
1127 drm_atomic_state_put(state);
1128
1129 unlock:
1130 drm_modeset_drop_locks(&ctx);
1131 drm_modeset_acquire_fini(&ctx);
1132
1133 return ret;
1134 }
1135
1136 static const struct drm_crtc_funcs crtc_funcs_gen2 = {
1137 .reset = rcar_du_crtc_reset,
1138 .destroy = drm_crtc_cleanup,
1139 .set_config = drm_atomic_helper_set_config,
1140 .page_flip = drm_atomic_helper_page_flip,
1141 .atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
1142 .atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
1143 .enable_vblank = rcar_du_crtc_enable_vblank,
1144 .disable_vblank = rcar_du_crtc_disable_vblank,
1145 };
1146
1147 static const struct drm_crtc_funcs crtc_funcs_gen3 = {
1148 .reset = rcar_du_crtc_reset,
1149 .destroy = rcar_du_crtc_cleanup,
1150 .set_config = drm_atomic_helper_set_config,
1151 .page_flip = drm_atomic_helper_page_flip,
1152 .atomic_duplicate_state = rcar_du_crtc_atomic_duplicate_state,
1153 .atomic_destroy_state = rcar_du_crtc_atomic_destroy_state,
1154 .enable_vblank = rcar_du_crtc_enable_vblank,
1155 .disable_vblank = rcar_du_crtc_disable_vblank,
1156 .set_crc_source = rcar_du_crtc_set_crc_source,
1157 .verify_crc_source = rcar_du_crtc_verify_crc_source,
1158 .get_crc_sources = rcar_du_crtc_get_crc_sources,
1159 };
1160
1161
1162
1163
1164
1165 static irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
1166 {
1167 struct rcar_du_crtc *rcrtc = arg;
1168 struct rcar_du_device *rcdu = rcrtc->dev;
1169 irqreturn_t ret = IRQ_NONE;
1170 u32 status;
1171
1172 spin_lock(&rcrtc->vblank_lock);
1173
1174 status = rcar_du_crtc_read(rcrtc, DSSR);
1175 rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
1176
1177 if (status & DSSR_VBK) {
1178
1179
1180
1181
1182
1183 if (rcrtc->vblank_count) {
1184 if (--rcrtc->vblank_count == 0)
1185 wake_up(&rcrtc->vblank_wait);
1186 }
1187 }
1188
1189 spin_unlock(&rcrtc->vblank_lock);
1190
1191 if (status & DSSR_VBK) {
1192 if (rcdu->info->gen < 3) {
1193 drm_crtc_handle_vblank(&rcrtc->crtc);
1194 rcar_du_crtc_finish_page_flip(rcrtc);
1195 }
1196
1197 ret = IRQ_HANDLED;
1198 }
1199
1200 return ret;
1201 }
1202
1203
1204
1205
1206
1207 int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
1208 unsigned int hwindex)
1209 {
1210 static const unsigned int mmio_offsets[] = {
1211 DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET, DU3_REG_OFFSET
1212 };
1213
1214 struct rcar_du_device *rcdu = rgrp->dev;
1215 struct platform_device *pdev = to_platform_device(rcdu->dev);
1216 struct rcar_du_crtc *rcrtc = &rcdu->crtcs[swindex];
1217 struct drm_crtc *crtc = &rcrtc->crtc;
1218 struct drm_plane *primary;
1219 unsigned int irqflags;
1220 struct clk *clk;
1221 char clk_name[9];
1222 char *name;
1223 int irq;
1224 int ret;
1225
1226
1227 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_CLOCK)) {
1228 sprintf(clk_name, "du.%u", hwindex);
1229 name = clk_name;
1230 } else {
1231 name = NULL;
1232 }
1233
1234 rcrtc->clock = devm_clk_get(rcdu->dev, name);
1235 if (IS_ERR(rcrtc->clock)) {
1236 dev_err(rcdu->dev, "no clock for DU channel %u\n", hwindex);
1237 return PTR_ERR(rcrtc->clock);
1238 }
1239
1240 sprintf(clk_name, "dclkin.%u", hwindex);
1241 clk = devm_clk_get(rcdu->dev, clk_name);
1242 if (!IS_ERR(clk)) {
1243 rcrtc->extclock = clk;
1244 } else if (PTR_ERR(clk) == -EPROBE_DEFER) {
1245 return -EPROBE_DEFER;
1246 } else if (rcdu->info->dpll_mask & BIT(hwindex)) {
1247
1248
1249
1250
1251 ret = PTR_ERR(clk);
1252 dev_err(rcdu->dev, "can't get dclkin.%u: %d\n", hwindex, ret);
1253 return ret;
1254 }
1255
1256 init_waitqueue_head(&rcrtc->flip_wait);
1257 init_waitqueue_head(&rcrtc->vblank_wait);
1258 spin_lock_init(&rcrtc->vblank_lock);
1259
1260 rcrtc->dev = rcdu;
1261 rcrtc->group = rgrp;
1262 rcrtc->mmio_offset = mmio_offsets[hwindex];
1263 rcrtc->index = hwindex;
1264 rcrtc->dsysr = rcrtc->index % 2 ? 0 : DSYSR_DRES;
1265
1266 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_TVM_SYNC))
1267 rcrtc->dsysr |= DSYSR_TVM_TVSYNC;
1268
1269 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
1270 primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
1271 else
1272 primary = &rgrp->planes[swindex % 2].plane;
1273
1274 ret = drm_crtc_init_with_planes(&rcdu->ddev, crtc, primary, NULL,
1275 rcdu->info->gen <= 2 ?
1276 &crtc_funcs_gen2 : &crtc_funcs_gen3,
1277 NULL);
1278 if (ret < 0)
1279 return ret;
1280
1281
1282 if (rcdu->cmms[swindex]) {
1283 rcrtc->cmm = rcdu->cmms[swindex];
1284 rgrp->cmms_mask |= BIT(hwindex % 2);
1285
1286 drm_mode_crtc_set_gamma_size(crtc, CM2_LUT_SIZE);
1287 drm_crtc_enable_color_mgmt(crtc, 0, false, CM2_LUT_SIZE);
1288 }
1289
1290 drm_crtc_helper_add(crtc, &crtc_helper_funcs);
1291
1292
1293 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ)) {
1294
1295 irq = platform_get_irq(pdev, swindex);
1296 irqflags = 0;
1297 } else {
1298 irq = platform_get_irq(pdev, 0);
1299 irqflags = IRQF_SHARED;
1300 }
1301
1302 if (irq < 0) {
1303 dev_err(rcdu->dev, "no IRQ for CRTC %u\n", swindex);
1304 return irq;
1305 }
1306
1307 ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags,
1308 dev_name(rcdu->dev), rcrtc);
1309 if (ret < 0) {
1310 dev_err(rcdu->dev,
1311 "failed to register IRQ for CRTC %u\n", swindex);
1312 return ret;
1313 }
1314
1315 rcar_du_crtc_crc_init(rcrtc);
1316
1317 return 0;
1318 }