1 From 4137b49989ce710305e476d0bd1086d7d906ff50 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Fri, 20 Oct 2023 17:09:54 +0100
4 Subject: [PATCH] drm/vc4_fkms: Fix up interrupt handler for both 2835/2711 and
7 2712 has switched from using the SMI peripheral to another interrupt
8 source for the vsync interrupt, so handle both sources cleanly.
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
12 drivers/gpu/drm/vc4/vc4_firmware_kms.c | 48 ++++++++++++++++++++------
13 1 file changed, 38 insertions(+), 10 deletions(-)
15 --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
16 +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
17 @@ -47,9 +47,15 @@ struct get_display_cfg {
18 u32 max_pixel_clock[2]; //Max pixel clock for each display
21 +enum vc4_fkms_revision {
28 struct get_display_cfg cfg;
30 + enum vc4_fkms_revision revision;
33 #define PLANES_PER_CRTC 8
34 @@ -1149,7 +1155,7 @@ vc4_crtc_mode_valid(struct drm_crtc *crt
35 /* Pi4 can't generate odd horizontal timings on HDMI, so reject modes
36 * that would set them.
38 - if (fkms->bcm2711 &&
39 + if (fkms->revision >= BCM2711 &&
40 (vc4_crtc->display_number == 2 || vc4_crtc->display_number == 7) &&
41 !(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
42 ((mode->hdisplay | /* active */
43 @@ -1267,6 +1273,20 @@ static irqreturn_t vc4_crtc_irq_handler(
47 +static irqreturn_t vc4_crtc2712_irq_handler(int irq, void *data)
49 + struct vc4_crtc **crtc_list = data;
52 + for (i = 0; crtc_list[i]; i++) {
53 + if (crtc_list[i]->vblank_enabled)
54 + drm_crtc_handle_vblank(&crtc_list[i]->base);
55 + vc4_crtc_handle_page_flip(crtc_list[i]);
61 static int vc4_fkms_page_flip(struct drm_crtc *crtc,
62 struct drm_framebuffer *fb,
63 struct drm_pending_vblank_event *event,
64 @@ -1352,9 +1372,12 @@ static const struct drm_crtc_helper_func
67 static const struct of_device_id vc4_firmware_kms_dt_match[] = {
68 - { .compatible = "raspberrypi,rpi-firmware-kms" },
69 + { .compatible = "raspberrypi,rpi-firmware-kms",
70 + .data = (void *)BCM2835_6_7 },
71 { .compatible = "raspberrypi,rpi-firmware-kms-2711",
72 - .data = (void *)1 },
73 + .data = (void *)BCM2711 },
74 + { .compatible = "raspberrypi,rpi-firmware-kms-2712",
75 + .data = (void *)BCM2712 },
79 @@ -1924,8 +1947,7 @@ static int vc4_fkms_bind(struct device *
80 match = of_match_device(vc4_firmware_kms_dt_match, dev);
84 - fkms->bcm2711 = true;
85 + fkms->revision = (enum vc4_fkms_revision)match->data;
87 firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0);
88 vc4->firmware = devm_rpi_firmware_get(&pdev->dev, firmware_node);
89 @@ -1992,10 +2014,16 @@ static int vc4_fkms_bind(struct device *
90 if (IS_ERR(crtc_list[0]->regs))
91 DRM_ERROR("Oh dear, failed to map registers\n");
93 - writel(0, crtc_list[0]->regs + SMICS);
94 - ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
95 - vc4_crtc_irq_handler, 0,
96 - "vc4 firmware kms", crtc_list);
97 + if (fkms->revision >= BCM2712) {
98 + ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
99 + vc4_crtc2712_irq_handler, 0,
100 + "vc4 firmware kms", crtc_list);
102 + writel(0, crtc_list[0]->regs + SMICS);
103 + ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
104 + vc4_crtc_irq_handler, 0,
105 + "vc4 firmware kms", crtc_list);
108 DRM_ERROR("Oh dear, failed to register IRQ\n");