Revert "vc4/fkms: Remove use of SMI peripheral"
authorDave Stevenson <dave.stevenson@raspberrypi.com>
Fri, 20 Oct 2023 14:21:34 +0000 (15:21 +0100)
committerDom Cobley <popcornmix@gmail.com>
Mon, 19 Feb 2024 11:35:08 +0000 (11:35 +0000)
This reverts commit 3fb20da9f3bff93f20b1a1fe2c950c6c8f4d1e1e.

drivers/gpu/drm/vc4/vc4_firmware_kms.c

index a02f3c7..439bac0 100644 (file)
@@ -255,6 +255,13 @@ static const struct vc_image_format *vc4_get_vc_image_fmt(u32 drm_format)
 /* The firmware delivers a vblank interrupt to us through the SMI
  * hardware, which has only this one register.
  */
+#define SMICS 0x0
+#define SMIDSW0 0x14
+#define SMIDSW1 0x1C
+#define SMICS_INTERRUPTS (BIT(9) | BIT(10) | BIT(11))
+
+/* Flag to denote that the firmware is giving multiple display callbacks */
+#define SMI_NEW 0xabcd0000
 
 struct vc4_fkms_crtc {
        struct drm_crtc base;
@@ -1212,13 +1219,16 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
 {
        struct vc4_fkms_crtc **crtc_list = data;
        int i;
+       u32 stat = readl(crtc_list[0]->regs + SMICS);
        irqreturn_t ret = IRQ_NONE;
        u32 chan;
-       if (1) {
 
-               chan = 0;
+       if (stat & SMICS_INTERRUPTS) {
+               writel(0, crtc_list[0]->regs + SMICS);
+
+               chan = readl(crtc_list[0]->regs + SMIDSW0);
 
-               if (1) {
+               if ((chan & 0xFFFF0000) != SMI_NEW) {
                        /* Older firmware. Treat the one interrupt as vblank/
                         * complete for all crtcs.
                         */
@@ -1229,7 +1239,7 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
                        }
                } else {
                        if (chan & 1) {
-                               //writel(SMI_NEW, crtc_list[0]->regs + SMIDSW0);
+                               writel(SMI_NEW, crtc_list[0]->regs + SMIDSW0);
                                if (crtc_list[0]->vblank_enabled)
                                        drm_crtc_handle_vblank(&crtc_list[0]->base);
                                vc4_crtc_handle_page_flip(crtc_list[0]);
@@ -1237,10 +1247,10 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
 
                        if (crtc_list[1]) {
                                /* Check for the secondary display too */
-                               //chan = readl(crtc_list[0]->regs + SMIDSW1);
+                               chan = readl(crtc_list[0]->regs + SMIDSW1);
 
                                if (chan & 1) {
-                                       //writel(SMI_NEW, crtc_list[0]->regs + SMIDSW1);
+                                       writel(SMI_NEW, crtc_list[0]->regs + SMIDSW1);
 
                                        if (crtc_list[1]->vblank_enabled)
                                                drm_crtc_handle_vblank(&crtc_list[1]->base);
@@ -1980,7 +1990,7 @@ static int vc4_fkms_bind(struct device *dev, struct device *master, void *data)
                if (IS_ERR(crtc_list[0]->regs))
                        DRM_ERROR("Oh dear, failed to map registers\n");
 
-               //writel(0, crtc_list[0]->regs + SMICS);
+               writel(0, crtc_list[0]->regs + SMICS);
                ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
                                       vc4_crtc_irq_handler, 0,
                                       "vc4 firmware kms", crtc_list);