0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <linux/clk.h>
0033 #include <linux/component.h>
0034 #include <linux/of_device.h>
0035 #include <linux/pm_runtime.h>
0036
0037 #include <drm/drm_atomic.h>
0038 #include <drm/drm_atomic_helper.h>
0039 #include <drm/drm_atomic_uapi.h>
0040 #include <drm/drm_fb_cma_helper.h>
0041 #include <drm/drm_framebuffer.h>
0042 #include <drm/drm_print.h>
0043 #include <drm/drm_probe_helper.h>
0044 #include <drm/drm_vblank.h>
0045
0046 #include "vc4_drv.h"
0047 #include "vc4_hdmi.h"
0048 #include "vc4_regs.h"
0049
0050 #define HVS_FIFO_LATENCY_PIX 6
0051
0052 #define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
0053 #define CRTC_READ(offset) readl(vc4_crtc->regs + (offset))
0054
0055 static const struct debugfs_reg32 crtc_regs[] = {
0056 VC4_REG32(PV_CONTROL),
0057 VC4_REG32(PV_V_CONTROL),
0058 VC4_REG32(PV_VSYNCD_EVEN),
0059 VC4_REG32(PV_HORZA),
0060 VC4_REG32(PV_HORZB),
0061 VC4_REG32(PV_VERTA),
0062 VC4_REG32(PV_VERTB),
0063 VC4_REG32(PV_VERTA_EVEN),
0064 VC4_REG32(PV_VERTB_EVEN),
0065 VC4_REG32(PV_INTEN),
0066 VC4_REG32(PV_INTSTAT),
0067 VC4_REG32(PV_STAT),
0068 VC4_REG32(PV_HACT_ACT),
0069 };
0070
0071 static unsigned int
0072 vc4_crtc_get_cob_allocation(struct vc4_dev *vc4, unsigned int channel)
0073 {
0074 struct vc4_hvs *hvs = vc4->hvs;
0075 u32 dispbase = HVS_READ(SCALER_DISPBASEX(channel));
0076
0077
0078
0079
0080 u32 top = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_TOP) & ~3;
0081 u32 base = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_BASE) & ~3;
0082
0083 return top - base + 4;
0084 }
0085
0086 static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc,
0087 bool in_vblank_irq,
0088 int *vpos, int *hpos,
0089 ktime_t *stime, ktime_t *etime,
0090 const struct drm_display_mode *mode)
0091 {
0092 struct drm_device *dev = crtc->dev;
0093 struct vc4_dev *vc4 = to_vc4_dev(dev);
0094 struct vc4_hvs *hvs = vc4->hvs;
0095 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
0096 struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state);
0097 unsigned int cob_size;
0098 u32 val;
0099 int fifo_lines;
0100 int vblank_lines;
0101 bool ret = false;
0102
0103
0104
0105
0106 if (stime)
0107 *stime = ktime_get();
0108
0109
0110
0111
0112
0113 val = HVS_READ(SCALER_DISPSTATX(vc4_crtc_state->assigned_channel));
0114
0115
0116 if (etime)
0117 *etime = ktime_get();
0118
0119
0120
0121
0122 *vpos = VC4_GET_FIELD(val, SCALER_DISPSTATX_LINE);
0123 *hpos = 0;
0124
0125 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
0126 *vpos /= 2;
0127
0128
0129 if (vc4_hvs_get_fifo_frame_count(hvs, vc4_crtc_state->assigned_channel) % 2)
0130 *hpos += mode->crtc_htotal / 2;
0131 }
0132
0133 cob_size = vc4_crtc_get_cob_allocation(vc4, vc4_crtc_state->assigned_channel);
0134
0135 fifo_lines = cob_size / mode->crtc_hdisplay;
0136
0137 if (fifo_lines > 0)
0138 ret = true;
0139
0140
0141 if (*vpos > fifo_lines) {
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 *vpos -= fifo_lines + 1;
0155
0156 return ret;
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 vblank_lines = mode->vtotal - mode->vdisplay;
0169
0170 if (in_vblank_irq) {
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 *vpos = -vblank_lines;
0181
0182 if (stime)
0183 *stime = vc4_crtc->t_vblank;
0184 if (etime)
0185 *etime = vc4_crtc->t_vblank;
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 } else {
0197
0198
0199
0200
0201
0202
0203 *vpos = 0;
0204 }
0205
0206 return ret;
0207 }
0208
0209 void vc4_crtc_destroy(struct drm_crtc *crtc)
0210 {
0211 drm_crtc_cleanup(crtc);
0212 }
0213
0214 static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format)
0215 {
0216 const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(vc4_crtc);
0217 const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
0218 struct vc4_dev *vc4 = to_vc4_dev(vc4_crtc->base.dev);
0219 u32 fifo_len_bytes = pv_data->fifo_depth;
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231 switch (format) {
0232 case PV_CONTROL_FORMAT_DSIV_16:
0233 case PV_CONTROL_FORMAT_DSIC_16:
0234 return fifo_len_bytes - 2 * HVS_FIFO_LATENCY_PIX;
0235 case PV_CONTROL_FORMAT_DSIV_18:
0236 return fifo_len_bytes - 14;
0237 case PV_CONTROL_FORMAT_24:
0238 case PV_CONTROL_FORMAT_DSIV_24:
0239 default:
0240
0241
0242
0243
0244 if (crtc_data->hvs_output == 5)
0245 return 32;
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 if (!vc4->is_vc5)
0261 return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1;
0262
0263 return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
0264 }
0265 }
0266
0267 static u32 vc4_crtc_get_fifo_full_level_bits(struct vc4_crtc *vc4_crtc,
0268 u32 format)
0269 {
0270 u32 level = vc4_get_fifo_full_level(vc4_crtc, format);
0271 u32 ret = 0;
0272
0273 ret |= VC4_SET_FIELD((level >> 6),
0274 PV5_CONTROL_FIFO_LEVEL_HIGH);
0275
0276 return ret | VC4_SET_FIELD(level & 0x3f,
0277 PV_CONTROL_FIFO_LEVEL);
0278 }
0279
0280
0281
0282
0283
0284
0285
0286
0287 struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
0288 struct drm_crtc_state *state)
0289 {
0290 struct drm_encoder *encoder;
0291
0292 WARN_ON(hweight32(state->encoder_mask) > 1);
0293
0294 drm_for_each_encoder_mask(encoder, crtc->dev, state->encoder_mask)
0295 return encoder;
0296
0297 return NULL;
0298 }
0299
0300 static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
0301 {
0302 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
0303
0304
0305 CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
0306 CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR);
0307 }
0308
0309 static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encoder,
0310 struct drm_atomic_state *state)
0311 {
0312 struct drm_device *dev = crtc->dev;
0313 struct vc4_dev *vc4 = to_vc4_dev(dev);
0314 struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
0315 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
0316 const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
0317 struct drm_crtc_state *crtc_state = crtc->state;
0318 struct drm_display_mode *mode = &crtc_state->adjusted_mode;
0319 bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
0320 bool is_hdmi = vc4_encoder->type == VC4_ENCODER_TYPE_HDMI0 ||
0321 vc4_encoder->type == VC4_ENCODER_TYPE_HDMI1;
0322 u32 pixel_rep = ((mode->flags & DRM_MODE_FLAG_DBLCLK) && !is_hdmi) ? 2 : 1;
0323 bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
0324 vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
0325 bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
0326 u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
0327 u8 ppc = pv_data->pixels_per_clock;
0328 bool debug_dump_regs = false;
0329
0330 if (debug_dump_regs) {
0331 struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev);
0332 dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs before:\n",
0333 drm_crtc_index(crtc));
0334 drm_print_regset32(&p, &vc4_crtc->regset);
0335 }
0336
0337 vc4_crtc_pixelvalve_reset(crtc);
0338
0339 CRTC_WRITE(PV_HORZA,
0340 VC4_SET_FIELD((mode->htotal - mode->hsync_end) * pixel_rep / ppc,
0341 PV_HORZA_HBP) |
0342 VC4_SET_FIELD((mode->hsync_end - mode->hsync_start) * pixel_rep / ppc,
0343 PV_HORZA_HSYNC));
0344
0345 CRTC_WRITE(PV_HORZB,
0346 VC4_SET_FIELD((mode->hsync_start - mode->hdisplay) * pixel_rep / ppc,
0347 PV_HORZB_HFP) |
0348 VC4_SET_FIELD(mode->hdisplay * pixel_rep / ppc,
0349 PV_HORZB_HACTIVE));
0350
0351 CRTC_WRITE(PV_VERTA,
0352 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
0353 interlace,
0354 PV_VERTA_VBP) |
0355 VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
0356 PV_VERTA_VSYNC));
0357 CRTC_WRITE(PV_VERTB,
0358 VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
0359 PV_VERTB_VFP) |
0360 VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
0361
0362 if (interlace) {
0363 CRTC_WRITE(PV_VERTA_EVEN,
0364 VC4_SET_FIELD(mode->crtc_vtotal -
0365 mode->crtc_vsync_end,
0366 PV_VERTA_VBP) |
0367 VC4_SET_FIELD(mode->crtc_vsync_end -
0368 mode->crtc_vsync_start,
0369 PV_VERTA_VSYNC));
0370 CRTC_WRITE(PV_VERTB_EVEN,
0371 VC4_SET_FIELD(mode->crtc_vsync_start -
0372 mode->crtc_vdisplay,
0373 PV_VERTB_VFP) |
0374 VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
0375
0376
0377
0378
0379
0380
0381 CRTC_WRITE(PV_V_CONTROL,
0382 PV_VCONTROL_CONTINUOUS |
0383 (is_dsi ? PV_VCONTROL_DSI : 0) |
0384 PV_VCONTROL_INTERLACE |
0385 VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc),
0386 PV_VCONTROL_ODD_DELAY));
0387 CRTC_WRITE(PV_VSYNCD_EVEN, 0);
0388 } else {
0389 CRTC_WRITE(PV_V_CONTROL,
0390 PV_VCONTROL_CONTINUOUS |
0391 (is_dsi ? PV_VCONTROL_DSI : 0));
0392 }
0393
0394 if (is_dsi)
0395 CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
0396
0397 if (vc4->is_vc5)
0398 CRTC_WRITE(PV_MUX_CFG,
0399 VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP,
0400 PV_MUX_CFG_RGB_PIXEL_MUX_MODE));
0401
0402 CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR |
0403 vc4_crtc_get_fifo_full_level_bits(vc4_crtc, format) |
0404 VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
0405 VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
0406 PV_CONTROL_CLR_AT_START |
0407 PV_CONTROL_TRIGGER_UNDERFLOW |
0408 PV_CONTROL_WAIT_HSTART |
0409 VC4_SET_FIELD(vc4_encoder->clock_select,
0410 PV_CONTROL_CLK_SELECT));
0411
0412 if (debug_dump_regs) {
0413 struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev);
0414 dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs after:\n",
0415 drm_crtc_index(crtc));
0416 drm_print_regset32(&p, &vc4_crtc->regset);
0417 }
0418 }
0419
0420 static void require_hvs_enabled(struct drm_device *dev)
0421 {
0422 struct vc4_dev *vc4 = to_vc4_dev(dev);
0423 struct vc4_hvs *hvs = vc4->hvs;
0424
0425 WARN_ON_ONCE((HVS_READ(SCALER_DISPCTRL) & SCALER_DISPCTRL_ENABLE) !=
0426 SCALER_DISPCTRL_ENABLE);
0427 }
0428
0429 static int vc4_crtc_disable(struct drm_crtc *crtc,
0430 struct drm_encoder *encoder,
0431 struct drm_atomic_state *state,
0432 unsigned int channel)
0433 {
0434 struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
0435 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
0436 struct drm_device *dev = crtc->dev;
0437 struct vc4_dev *vc4 = to_vc4_dev(dev);
0438 int ret;
0439
0440 CRTC_WRITE(PV_V_CONTROL,
0441 CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
0442 ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
0443 WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461 mdelay(20);
0462
0463 if (vc4_encoder && vc4_encoder->post_crtc_disable)
0464 vc4_encoder->post_crtc_disable(encoder, state);
0465
0466 vc4_crtc_pixelvalve_reset(crtc);
0467 vc4_hvs_stop_channel(vc4->hvs, channel);
0468
0469 if (vc4_encoder && vc4_encoder->post_crtc_powerdown)
0470 vc4_encoder->post_crtc_powerdown(encoder, state);
0471
0472 return 0;
0473 }
0474
0475 static struct drm_encoder *vc4_crtc_get_encoder_by_type(struct drm_crtc *crtc,
0476 enum vc4_encoder_type type)
0477 {
0478 struct drm_encoder *encoder;
0479
0480 drm_for_each_encoder(encoder, crtc->dev) {
0481 struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
0482
0483 if (vc4_encoder->type == type)
0484 return encoder;
0485 }
0486
0487 return NULL;
0488 }
0489
0490 int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
0491 {
0492 struct drm_device *drm = crtc->dev;
0493 struct vc4_dev *vc4 = to_vc4_dev(drm);
0494 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
0495 enum vc4_encoder_type encoder_type;
0496 const struct vc4_pv_data *pv_data;
0497 struct drm_encoder *encoder;
0498 struct vc4_hdmi *vc4_hdmi;
0499 unsigned encoder_sel;
0500 int channel;
0501 int ret;
0502
0503 if (!(of_device_is_compatible(vc4_crtc->pdev->dev.of_node,
0504 "brcm,bcm2711-pixelvalve2") ||
0505 of_device_is_compatible(vc4_crtc->pdev->dev.of_node,
0506 "brcm,bcm2711-pixelvalve4")))
0507 return 0;
0508
0509 if (!(CRTC_READ(PV_CONTROL) & PV_CONTROL_EN))
0510 return 0;
0511
0512 if (!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN))
0513 return 0;
0514
0515 channel = vc4_hvs_get_fifo_from_output(vc4->hvs, vc4_crtc->data->hvs_output);
0516 if (channel < 0)
0517 return 0;
0518
0519 encoder_sel = VC4_GET_FIELD(CRTC_READ(PV_CONTROL), PV_CONTROL_CLK_SELECT);
0520 if (WARN_ON(encoder_sel != 0))
0521 return 0;
0522
0523 pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
0524 encoder_type = pv_data->encoder_types[encoder_sel];
0525 encoder = vc4_crtc_get_encoder_by_type(crtc, encoder_type);
0526 if (WARN_ON(!encoder))
0527 return 0;
0528
0529 vc4_hdmi = encoder_to_vc4_hdmi(encoder);
0530 ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
0531 if (ret)
0532 return ret;
0533
0534 ret = vc4_crtc_disable(crtc, encoder, NULL, channel);
0535 if (ret)
0536 return ret;
0537
0538
0539
0540
0541
0542
0543
0544 return 0;
0545 }
0546
0547 static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
0548 struct drm_atomic_state *state)
0549 {
0550 struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
0551 crtc);
0552 struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state);
0553 struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, old_state);
0554 struct drm_device *dev = crtc->dev;
0555
0556 drm_dbg(dev, "Disabling CRTC %s (%u) connected to Encoder %s (%u)",
0557 crtc->name, crtc->base.id, encoder->name, encoder->base.id);
0558
0559 require_hvs_enabled(dev);
0560
0561
0562 drm_crtc_vblank_off(crtc);
0563
0564 vc4_crtc_disable(crtc, encoder, state, old_vc4_state->assigned_channel);
0565
0566
0567
0568
0569
0570 if (crtc->state->event) {
0571 unsigned long flags;
0572
0573 spin_lock_irqsave(&dev->event_lock, flags);
0574 drm_crtc_send_vblank_event(crtc, crtc->state->event);
0575 crtc->state->event = NULL;
0576 spin_unlock_irqrestore(&dev->event_lock, flags);
0577 }
0578 }
0579
0580 static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
0581 struct drm_atomic_state *state)
0582 {
0583 struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state,
0584 crtc);
0585 struct drm_device *dev = crtc->dev;
0586 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
0587 struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, new_state);
0588 struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
0589
0590 drm_dbg(dev, "Enabling CRTC %s (%u) connected to Encoder %s (%u)",
0591 crtc->name, crtc->base.id, encoder->name, encoder->base.id);
0592
0593 require_hvs_enabled(dev);
0594
0595
0596
0597
0598 drm_crtc_vblank_on(crtc);
0599
0600 vc4_hvs_atomic_enable(crtc, state);
0601
0602 if (vc4_encoder->pre_crtc_configure)
0603 vc4_encoder->pre_crtc_configure(encoder, state);
0604
0605 vc4_crtc_config_pv(crtc, encoder, state);
0606
0607 CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
0608
0609 if (vc4_encoder->pre_crtc_enable)
0610 vc4_encoder->pre_crtc_enable(encoder, state);
0611
0612
0613
0614
0615 CRTC_WRITE(PV_V_CONTROL,
0616 CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
0617
0618 if (vc4_encoder->post_crtc_enable)
0619 vc4_encoder->post_crtc_enable(encoder, state);
0620 }
0621
0622 static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
0623 const struct drm_display_mode *mode)
0624 {
0625
0626 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
0627 DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n",
0628 crtc->base.id);
0629 return MODE_NO_DBLESCAN;
0630 }
0631
0632 return MODE_OK;
0633 }
0634
0635 void vc4_crtc_get_margins(struct drm_crtc_state *state,
0636 unsigned int *left, unsigned int *right,
0637 unsigned int *top, unsigned int *bottom)
0638 {
0639 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
0640 struct drm_connector_state *conn_state;
0641 struct drm_connector *conn;
0642 int i;
0643
0644 *left = vc4_state->margins.left;
0645 *right = vc4_state->margins.right;
0646 *top = vc4_state->margins.top;
0647 *bottom = vc4_state->margins.bottom;
0648
0649
0650
0651
0652
0653
0654 for_each_new_connector_in_state(state->state, conn, conn_state, i) {
0655 if (conn_state->crtc != state->crtc)
0656 continue;
0657
0658 *left = conn_state->tv.margins.left;
0659 *right = conn_state->tv.margins.right;
0660 *top = conn_state->tv.margins.top;
0661 *bottom = conn_state->tv.margins.bottom;
0662 break;
0663 }
0664 }
0665
0666 static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
0667 struct drm_atomic_state *state)
0668 {
0669 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
0670 crtc);
0671 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state);
0672 struct drm_connector *conn;
0673 struct drm_connector_state *conn_state;
0674 struct drm_encoder *encoder;
0675 int ret, i;
0676
0677 ret = vc4_hvs_atomic_check(crtc, state);
0678 if (ret)
0679 return ret;
0680
0681 encoder = vc4_get_crtc_encoder(crtc, crtc_state);
0682 if (encoder) {
0683 const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
0684 struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
0685
0686 if (vc4_encoder->type == VC4_ENCODER_TYPE_HDMI0) {
0687 vc4_state->hvs_load = max(mode->clock * mode->hdisplay / mode->htotal + 1000,
0688 mode->clock * 9 / 10) * 1000;
0689 } else {
0690 vc4_state->hvs_load = mode->clock * 1000;
0691 }
0692 }
0693
0694 for_each_new_connector_in_state(state, conn, conn_state,
0695 i) {
0696 if (conn_state->crtc != crtc)
0697 continue;
0698
0699 vc4_state->margins.left = conn_state->tv.margins.left;
0700 vc4_state->margins.right = conn_state->tv.margins.right;
0701 vc4_state->margins.top = conn_state->tv.margins.top;
0702 vc4_state->margins.bottom = conn_state->tv.margins.bottom;
0703 break;
0704 }
0705
0706 return 0;
0707 }
0708
0709 static int vc4_enable_vblank(struct drm_crtc *crtc)
0710 {
0711 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
0712
0713 CRTC_WRITE(PV_INTEN, PV_INT_VFP_START);
0714
0715 return 0;
0716 }
0717
0718 static void vc4_disable_vblank(struct drm_crtc *crtc)
0719 {
0720 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
0721
0722 CRTC_WRITE(PV_INTEN, 0);
0723 }
0724
0725 static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
0726 {
0727 struct drm_crtc *crtc = &vc4_crtc->base;
0728 struct drm_device *dev = crtc->dev;
0729 struct vc4_dev *vc4 = to_vc4_dev(dev);
0730 struct vc4_hvs *hvs = vc4->hvs;
0731 u32 chan = vc4_crtc->current_hvs_channel;
0732 unsigned long flags;
0733
0734 spin_lock_irqsave(&dev->event_lock, flags);
0735 spin_lock(&vc4_crtc->irq_lock);
0736 if (vc4_crtc->event &&
0737 (vc4_crtc->current_dlist == HVS_READ(SCALER_DISPLACTX(chan)) ||
0738 vc4_crtc->feeds_txp)) {
0739 drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
0740 vc4_crtc->event = NULL;
0741 drm_crtc_vblank_put(crtc);
0742
0743
0744
0745
0746
0747
0748
0749 vc4_hvs_unmask_underrun(hvs, chan);
0750 }
0751 spin_unlock(&vc4_crtc->irq_lock);
0752 spin_unlock_irqrestore(&dev->event_lock, flags);
0753 }
0754
0755 void vc4_crtc_handle_vblank(struct vc4_crtc *crtc)
0756 {
0757 crtc->t_vblank = ktime_get();
0758 drm_crtc_handle_vblank(&crtc->base);
0759 vc4_crtc_handle_page_flip(crtc);
0760 }
0761
0762 static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
0763 {
0764 struct vc4_crtc *vc4_crtc = data;
0765 u32 stat = CRTC_READ(PV_INTSTAT);
0766 irqreturn_t ret = IRQ_NONE;
0767
0768 if (stat & PV_INT_VFP_START) {
0769 CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
0770 vc4_crtc_handle_vblank(vc4_crtc);
0771 ret = IRQ_HANDLED;
0772 }
0773
0774 return ret;
0775 }
0776
0777 struct vc4_async_flip_state {
0778 struct drm_crtc *crtc;
0779 struct drm_framebuffer *fb;
0780 struct drm_framebuffer *old_fb;
0781 struct drm_pending_vblank_event *event;
0782
0783 union {
0784 struct dma_fence_cb fence;
0785 struct vc4_seqno_cb seqno;
0786 } cb;
0787 };
0788
0789
0790
0791
0792 static void
0793 vc4_async_page_flip_complete(struct vc4_async_flip_state *flip_state)
0794 {
0795 struct drm_crtc *crtc = flip_state->crtc;
0796 struct drm_device *dev = crtc->dev;
0797 struct drm_plane *plane = crtc->primary;
0798
0799 vc4_plane_async_set_fb(plane, flip_state->fb);
0800 if (flip_state->event) {
0801 unsigned long flags;
0802
0803 spin_lock_irqsave(&dev->event_lock, flags);
0804 drm_crtc_send_vblank_event(crtc, flip_state->event);
0805 spin_unlock_irqrestore(&dev->event_lock, flags);
0806 }
0807
0808 drm_crtc_vblank_put(crtc);
0809 drm_framebuffer_put(flip_state->fb);
0810
0811 if (flip_state->old_fb)
0812 drm_framebuffer_put(flip_state->old_fb);
0813
0814 kfree(flip_state);
0815 }
0816
0817 static void vc4_async_page_flip_seqno_complete(struct vc4_seqno_cb *cb)
0818 {
0819 struct vc4_async_flip_state *flip_state =
0820 container_of(cb, struct vc4_async_flip_state, cb.seqno);
0821 struct vc4_bo *bo = NULL;
0822
0823 if (flip_state->old_fb) {
0824 struct drm_gem_cma_object *cma_bo =
0825 drm_fb_cma_get_gem_obj(flip_state->old_fb, 0);
0826 bo = to_vc4_bo(&cma_bo->base);
0827 }
0828
0829 vc4_async_page_flip_complete(flip_state);
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840 if (bo)
0841 vc4_bo_dec_usecnt(bo);
0842 }
0843
0844 static void vc4_async_page_flip_fence_complete(struct dma_fence *fence,
0845 struct dma_fence_cb *cb)
0846 {
0847 struct vc4_async_flip_state *flip_state =
0848 container_of(cb, struct vc4_async_flip_state, cb.fence);
0849
0850 vc4_async_page_flip_complete(flip_state);
0851 dma_fence_put(fence);
0852 }
0853
0854 static int vc4_async_set_fence_cb(struct drm_device *dev,
0855 struct vc4_async_flip_state *flip_state)
0856 {
0857 struct drm_framebuffer *fb = flip_state->fb;
0858 struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
0859 struct vc4_dev *vc4 = to_vc4_dev(dev);
0860 struct dma_fence *fence;
0861 int ret;
0862
0863 if (!vc4->is_vc5) {
0864 struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
0865
0866 return vc4_queue_seqno_cb(dev, &flip_state->cb.seqno, bo->seqno,
0867 vc4_async_page_flip_seqno_complete);
0868 }
0869
0870 ret = dma_resv_get_singleton(cma_bo->base.resv, DMA_RESV_USAGE_READ, &fence);
0871 if (ret)
0872 return ret;
0873
0874
0875 if (!fence) {
0876 vc4_async_page_flip_fence_complete(fence, &flip_state->cb.fence);
0877 return 0;
0878 }
0879
0880
0881 if (dma_fence_add_callback(fence, &flip_state->cb.fence,
0882 vc4_async_page_flip_fence_complete))
0883 vc4_async_page_flip_fence_complete(fence, &flip_state->cb.fence);
0884
0885 return 0;
0886 }
0887
0888 static int
0889 vc4_async_page_flip_common(struct drm_crtc *crtc,
0890 struct drm_framebuffer *fb,
0891 struct drm_pending_vblank_event *event,
0892 uint32_t flags)
0893 {
0894 struct drm_device *dev = crtc->dev;
0895 struct drm_plane *plane = crtc->primary;
0896 struct vc4_async_flip_state *flip_state;
0897
0898 flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
0899 if (!flip_state)
0900 return -ENOMEM;
0901
0902 drm_framebuffer_get(fb);
0903 flip_state->fb = fb;
0904 flip_state->crtc = crtc;
0905 flip_state->event = event;
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915 flip_state->old_fb = plane->state->fb;
0916 if (flip_state->old_fb)
0917 drm_framebuffer_get(flip_state->old_fb);
0918
0919 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
0920
0921
0922
0923
0924
0925 drm_atomic_set_fb_for_plane(plane->state, fb);
0926
0927 vc4_async_set_fence_cb(dev, flip_state);
0928
0929
0930 return 0;
0931 }
0932
0933
0934
0935
0936
0937
0938
0939 static int vc4_async_page_flip(struct drm_crtc *crtc,
0940 struct drm_framebuffer *fb,
0941 struct drm_pending_vblank_event *event,
0942 uint32_t flags)
0943 {
0944 struct drm_device *dev = crtc->dev;
0945 struct vc4_dev *vc4 = to_vc4_dev(dev);
0946 struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
0947 struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
0948 int ret;
0949
0950 if (WARN_ON_ONCE(vc4->is_vc5))
0951 return -ENODEV;
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962 ret = vc4_bo_inc_usecnt(bo);
0963 if (ret)
0964 return ret;
0965
0966 ret = vc4_async_page_flip_common(crtc, fb, event, flags);
0967 if (ret) {
0968 vc4_bo_dec_usecnt(bo);
0969 return ret;
0970 }
0971
0972 return 0;
0973 }
0974
0975 static int vc5_async_page_flip(struct drm_crtc *crtc,
0976 struct drm_framebuffer *fb,
0977 struct drm_pending_vblank_event *event,
0978 uint32_t flags)
0979 {
0980 return vc4_async_page_flip_common(crtc, fb, event, flags);
0981 }
0982
0983 int vc4_page_flip(struct drm_crtc *crtc,
0984 struct drm_framebuffer *fb,
0985 struct drm_pending_vblank_event *event,
0986 uint32_t flags,
0987 struct drm_modeset_acquire_ctx *ctx)
0988 {
0989 if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
0990 struct drm_device *dev = crtc->dev;
0991 struct vc4_dev *vc4 = to_vc4_dev(dev);
0992
0993 if (vc4->is_vc5)
0994 return vc5_async_page_flip(crtc, fb, event, flags);
0995 else
0996 return vc4_async_page_flip(crtc, fb, event, flags);
0997 } else {
0998 return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx);
0999 }
1000 }
1001
1002 struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
1003 {
1004 struct vc4_crtc_state *vc4_state, *old_vc4_state;
1005
1006 vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
1007 if (!vc4_state)
1008 return NULL;
1009
1010 old_vc4_state = to_vc4_crtc_state(crtc->state);
1011 vc4_state->margins = old_vc4_state->margins;
1012 vc4_state->assigned_channel = old_vc4_state->assigned_channel;
1013
1014 __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base);
1015 return &vc4_state->base;
1016 }
1017
1018 void vc4_crtc_destroy_state(struct drm_crtc *crtc,
1019 struct drm_crtc_state *state)
1020 {
1021 struct vc4_dev *vc4 = to_vc4_dev(crtc->dev);
1022 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
1023
1024 if (drm_mm_node_allocated(&vc4_state->mm)) {
1025 unsigned long flags;
1026
1027 spin_lock_irqsave(&vc4->hvs->mm_lock, flags);
1028 drm_mm_remove_node(&vc4_state->mm);
1029 spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags);
1030
1031 }
1032
1033 drm_atomic_helper_crtc_destroy_state(crtc, state);
1034 }
1035
1036 void vc4_crtc_reset(struct drm_crtc *crtc)
1037 {
1038 struct vc4_crtc_state *vc4_crtc_state;
1039
1040 if (crtc->state)
1041 vc4_crtc_destroy_state(crtc, crtc->state);
1042
1043 vc4_crtc_state = kzalloc(sizeof(*vc4_crtc_state), GFP_KERNEL);
1044 if (!vc4_crtc_state) {
1045 crtc->state = NULL;
1046 return;
1047 }
1048
1049 vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED;
1050 __drm_atomic_helper_crtc_reset(crtc, &vc4_crtc_state->base);
1051 }
1052
1053 static const struct drm_crtc_funcs vc4_crtc_funcs = {
1054 .set_config = drm_atomic_helper_set_config,
1055 .destroy = vc4_crtc_destroy,
1056 .page_flip = vc4_page_flip,
1057 .set_property = NULL,
1058 .cursor_set = NULL,
1059 .cursor_move = NULL,
1060 .reset = vc4_crtc_reset,
1061 .atomic_duplicate_state = vc4_crtc_duplicate_state,
1062 .atomic_destroy_state = vc4_crtc_destroy_state,
1063 .enable_vblank = vc4_enable_vblank,
1064 .disable_vblank = vc4_disable_vblank,
1065 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
1066 };
1067
1068 static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
1069 .mode_valid = vc4_crtc_mode_valid,
1070 .atomic_check = vc4_crtc_atomic_check,
1071 .atomic_begin = vc4_hvs_atomic_begin,
1072 .atomic_flush = vc4_hvs_atomic_flush,
1073 .atomic_enable = vc4_crtc_atomic_enable,
1074 .atomic_disable = vc4_crtc_atomic_disable,
1075 .get_scanout_position = vc4_crtc_get_scanout_position,
1076 };
1077
1078 static const struct vc4_pv_data bcm2835_pv0_data = {
1079 .base = {
1080 .hvs_available_channels = BIT(0),
1081 .hvs_output = 0,
1082 },
1083 .debugfs_name = "crtc0_regs",
1084 .fifo_depth = 64,
1085 .pixels_per_clock = 1,
1086 .encoder_types = {
1087 [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
1088 [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
1089 },
1090 };
1091
1092 static const struct vc4_pv_data bcm2835_pv1_data = {
1093 .base = {
1094 .hvs_available_channels = BIT(2),
1095 .hvs_output = 2,
1096 },
1097 .debugfs_name = "crtc1_regs",
1098 .fifo_depth = 64,
1099 .pixels_per_clock = 1,
1100 .encoder_types = {
1101 [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
1102 [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
1103 },
1104 };
1105
1106 static const struct vc4_pv_data bcm2835_pv2_data = {
1107 .base = {
1108 .hvs_available_channels = BIT(1),
1109 .hvs_output = 1,
1110 },
1111 .debugfs_name = "crtc2_regs",
1112 .fifo_depth = 64,
1113 .pixels_per_clock = 1,
1114 .encoder_types = {
1115 [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI0,
1116 [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
1117 },
1118 };
1119
1120 static const struct vc4_pv_data bcm2711_pv0_data = {
1121 .base = {
1122 .hvs_available_channels = BIT(0),
1123 .hvs_output = 0,
1124 },
1125 .debugfs_name = "crtc0_regs",
1126 .fifo_depth = 64,
1127 .pixels_per_clock = 1,
1128 .encoder_types = {
1129 [0] = VC4_ENCODER_TYPE_DSI0,
1130 [1] = VC4_ENCODER_TYPE_DPI,
1131 },
1132 };
1133
1134 static const struct vc4_pv_data bcm2711_pv1_data = {
1135 .base = {
1136 .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
1137 .hvs_output = 3,
1138 },
1139 .debugfs_name = "crtc1_regs",
1140 .fifo_depth = 64,
1141 .pixels_per_clock = 1,
1142 .encoder_types = {
1143 [0] = VC4_ENCODER_TYPE_DSI1,
1144 [1] = VC4_ENCODER_TYPE_SMI,
1145 },
1146 };
1147
1148 static const struct vc4_pv_data bcm2711_pv2_data = {
1149 .base = {
1150 .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
1151 .hvs_output = 4,
1152 },
1153 .debugfs_name = "crtc2_regs",
1154 .fifo_depth = 256,
1155 .pixels_per_clock = 2,
1156 .encoder_types = {
1157 [0] = VC4_ENCODER_TYPE_HDMI0,
1158 },
1159 };
1160
1161 static const struct vc4_pv_data bcm2711_pv3_data = {
1162 .base = {
1163 .hvs_available_channels = BIT(1),
1164 .hvs_output = 1,
1165 },
1166 .debugfs_name = "crtc3_regs",
1167 .fifo_depth = 64,
1168 .pixels_per_clock = 1,
1169 .encoder_types = {
1170 [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
1171 },
1172 };
1173
1174 static const struct vc4_pv_data bcm2711_pv4_data = {
1175 .base = {
1176 .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
1177 .hvs_output = 5,
1178 },
1179 .debugfs_name = "crtc4_regs",
1180 .fifo_depth = 64,
1181 .pixels_per_clock = 2,
1182 .encoder_types = {
1183 [0] = VC4_ENCODER_TYPE_HDMI1,
1184 },
1185 };
1186
1187 static const struct of_device_id vc4_crtc_dt_match[] = {
1188 { .compatible = "brcm,bcm2835-pixelvalve0", .data = &bcm2835_pv0_data },
1189 { .compatible = "brcm,bcm2835-pixelvalve1", .data = &bcm2835_pv1_data },
1190 { .compatible = "brcm,bcm2835-pixelvalve2", .data = &bcm2835_pv2_data },
1191 { .compatible = "brcm,bcm2711-pixelvalve0", .data = &bcm2711_pv0_data },
1192 { .compatible = "brcm,bcm2711-pixelvalve1", .data = &bcm2711_pv1_data },
1193 { .compatible = "brcm,bcm2711-pixelvalve2", .data = &bcm2711_pv2_data },
1194 { .compatible = "brcm,bcm2711-pixelvalve3", .data = &bcm2711_pv3_data },
1195 { .compatible = "brcm,bcm2711-pixelvalve4", .data = &bcm2711_pv4_data },
1196 {}
1197 };
1198
1199 static void vc4_set_crtc_possible_masks(struct drm_device *drm,
1200 struct drm_crtc *crtc)
1201 {
1202 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
1203 const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
1204 const enum vc4_encoder_type *encoder_types = pv_data->encoder_types;
1205 struct drm_encoder *encoder;
1206
1207 drm_for_each_encoder(encoder, drm) {
1208 struct vc4_encoder *vc4_encoder;
1209 int i;
1210
1211 if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
1212 continue;
1213
1214 vc4_encoder = to_vc4_encoder(encoder);
1215 for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) {
1216 if (vc4_encoder->type == encoder_types[i]) {
1217 vc4_encoder->clock_select = i;
1218 encoder->possible_crtcs |= drm_crtc_mask(crtc);
1219 break;
1220 }
1221 }
1222 }
1223 }
1224
1225 int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
1226 const struct drm_crtc_funcs *crtc_funcs,
1227 const struct drm_crtc_helper_funcs *crtc_helper_funcs)
1228 {
1229 struct vc4_dev *vc4 = to_vc4_dev(drm);
1230 struct drm_crtc *crtc = &vc4_crtc->base;
1231 struct drm_plane *primary_plane;
1232 unsigned int i;
1233
1234
1235
1236
1237
1238
1239
1240 primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
1241 if (IS_ERR(primary_plane)) {
1242 dev_err(drm->dev, "failed to construct primary plane\n");
1243 return PTR_ERR(primary_plane);
1244 }
1245
1246 spin_lock_init(&vc4_crtc->irq_lock);
1247 drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
1248 crtc_funcs, NULL);
1249 drm_crtc_helper_add(crtc, crtc_helper_funcs);
1250
1251 if (!vc4->is_vc5) {
1252 drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
1253
1254 drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
1255
1256
1257
1258
1259 drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
1260 }
1261
1262 for (i = 0; i < crtc->gamma_size; i++) {
1263 vc4_crtc->lut_r[i] = i;
1264 vc4_crtc->lut_g[i] = i;
1265 vc4_crtc->lut_b[i] = i;
1266 }
1267
1268 return 0;
1269 }
1270
1271 static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
1272 {
1273 struct platform_device *pdev = to_platform_device(dev);
1274 struct drm_device *drm = dev_get_drvdata(master);
1275 const struct vc4_pv_data *pv_data;
1276 struct vc4_crtc *vc4_crtc;
1277 struct drm_crtc *crtc;
1278 struct drm_plane *destroy_plane, *temp;
1279 int ret;
1280
1281 vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
1282 if (!vc4_crtc)
1283 return -ENOMEM;
1284 crtc = &vc4_crtc->base;
1285
1286 pv_data = of_device_get_match_data(dev);
1287 if (!pv_data)
1288 return -ENODEV;
1289 vc4_crtc->data = &pv_data->base;
1290 vc4_crtc->pdev = pdev;
1291
1292 vc4_crtc->regs = vc4_ioremap_regs(pdev, 0);
1293 if (IS_ERR(vc4_crtc->regs))
1294 return PTR_ERR(vc4_crtc->regs);
1295
1296 vc4_crtc->regset.base = vc4_crtc->regs;
1297 vc4_crtc->regset.regs = crtc_regs;
1298 vc4_crtc->regset.nregs = ARRAY_SIZE(crtc_regs);
1299
1300 ret = vc4_crtc_init(drm, vc4_crtc,
1301 &vc4_crtc_funcs, &vc4_crtc_helper_funcs);
1302 if (ret)
1303 return ret;
1304 vc4_set_crtc_possible_masks(drm, crtc);
1305
1306 CRTC_WRITE(PV_INTEN, 0);
1307 CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
1308 ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
1309 vc4_crtc_irq_handler,
1310 IRQF_SHARED,
1311 "vc4 crtc", vc4_crtc);
1312 if (ret)
1313 goto err_destroy_planes;
1314
1315 platform_set_drvdata(pdev, vc4_crtc);
1316
1317 vc4_debugfs_add_regset32(drm, pv_data->debugfs_name,
1318 &vc4_crtc->regset);
1319
1320 return 0;
1321
1322 err_destroy_planes:
1323 list_for_each_entry_safe(destroy_plane, temp,
1324 &drm->mode_config.plane_list, head) {
1325 if (destroy_plane->possible_crtcs == drm_crtc_mask(crtc))
1326 destroy_plane->funcs->destroy(destroy_plane);
1327 }
1328
1329 return ret;
1330 }
1331
1332 static void vc4_crtc_unbind(struct device *dev, struct device *master,
1333 void *data)
1334 {
1335 struct platform_device *pdev = to_platform_device(dev);
1336 struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev);
1337
1338 vc4_crtc_destroy(&vc4_crtc->base);
1339
1340 CRTC_WRITE(PV_INTEN, 0);
1341
1342 platform_set_drvdata(pdev, NULL);
1343 }
1344
1345 static const struct component_ops vc4_crtc_ops = {
1346 .bind = vc4_crtc_bind,
1347 .unbind = vc4_crtc_unbind,
1348 };
1349
1350 static int vc4_crtc_dev_probe(struct platform_device *pdev)
1351 {
1352 return component_add(&pdev->dev, &vc4_crtc_ops);
1353 }
1354
1355 static int vc4_crtc_dev_remove(struct platform_device *pdev)
1356 {
1357 component_del(&pdev->dev, &vc4_crtc_ops);
1358 return 0;
1359 }
1360
1361 struct platform_driver vc4_crtc_driver = {
1362 .probe = vc4_crtc_dev_probe,
1363 .remove = vc4_crtc_dev_remove,
1364 .driver = {
1365 .name = "vc4_crtc",
1366 .of_match_table = vc4_crtc_dt_match,
1367 },
1368 };