diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0562-drm-vc4-dsi-Introduce-a-variant-structure.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.10/950-0562-drm-vc4-dsi-Introduce-a-variant-structure.patch | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0562-drm-vc4-dsi-Introduce-a-variant-structure.patch b/target/linux/bcm27xx/patches-5.10/950-0562-drm-vc4-dsi-Introduce-a-variant-structure.patch new file mode 100644 index 0000000000..c24bb4417e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.10/950-0562-drm-vc4-dsi-Introduce-a-variant-structure.patch @@ -0,0 +1,191 @@ +From 4dd1101f3e16e6202132ae34a8da2a7d78043d56 Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Thu, 3 Dec 2020 14:25:39 +0100 +Subject: [PATCH] drm/vc4: dsi: Introduce a variant structure + +Commit d1d195ce26a14ec0a87816c09ae514e1c40e97f7 upstream. + +Most of the differences between DSI0 and DSI1 are handled through the +ID. However, the BCM2711 DSI is going to introduce one more variable to +the mix and will break some expectations of the earlier, simpler, test. + +Let's add a variant structure that will address most of the differences +between those three controllers. + +Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-5-maxime@cerno.tech +--- + drivers/gpu/drm/vc4/vc4_dsi.c | 63 ++++++++++++++++++++--------------- + 1 file changed, 37 insertions(+), 26 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_dsi.c ++++ b/drivers/gpu/drm/vc4/vc4_dsi.c +@@ -493,6 +493,18 @@ + */ + #define DSI1_ID 0x8c + ++struct vc4_dsi_variant { ++ /* Whether we're on bcm2835's DSI0 or DSI1. */ ++ unsigned int port; ++ ++ bool broken_axi_workaround; ++ ++ const char *debugfs_name; ++ const struct debugfs_reg32 *regs; ++ size_t nregs; ++ ++}; ++ + /* General DSI hardware state. */ + struct vc4_dsi { + struct platform_device *pdev; +@@ -509,8 +521,7 @@ struct vc4_dsi { + u32 *reg_dma_mem; + dma_addr_t reg_paddr; + +- /* Whether we're on bcm2835's DSI0 or DSI1. */ +- int port; ++ const struct vc4_dsi_variant *variant; + + /* DSI channel for the panel we're connected to. */ + u32 channel; +@@ -586,10 +597,10 @@ dsi_dma_workaround_write(struct vc4_dsi + #define DSI_READ(offset) readl(dsi->regs + (offset)) + #define DSI_WRITE(offset, val) dsi_dma_workaround_write(dsi, offset, val) + #define DSI_PORT_READ(offset) \ +- DSI_READ(dsi->port ? DSI1_##offset : DSI0_##offset) ++ DSI_READ(dsi->variant->port ? DSI1_##offset : DSI0_##offset) + #define DSI_PORT_WRITE(offset, val) \ +- DSI_WRITE(dsi->port ? DSI1_##offset : DSI0_##offset, val) +-#define DSI_PORT_BIT(bit) (dsi->port ? DSI1_##bit : DSI0_##bit) ++ DSI_WRITE(dsi->variant->port ? DSI1_##offset : DSI0_##offset, val) ++#define DSI_PORT_BIT(bit) (dsi->variant->port ? DSI1_##bit : DSI0_##bit) + + /* VC4 DSI encoder KMS struct */ + struct vc4_dsi_encoder { +@@ -837,7 +848,7 @@ static void vc4_dsi_encoder_enable(struc + + ret = pm_runtime_get_sync(dev); + if (ret) { +- DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->port); ++ DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->variant->port); + return; + } + +@@ -871,7 +882,7 @@ static void vc4_dsi_encoder_enable(struc + DSI_PORT_WRITE(STAT, DSI_PORT_READ(STAT)); + + /* Set AFE CTR00/CTR1 to release powerdown of analog. */ +- if (dsi->port == 0) { ++ if (dsi->variant->port == 0) { + u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) | + VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ)); + +@@ -1017,7 +1028,7 @@ static void vc4_dsi_encoder_enable(struc + DSI_PORT_BIT(PHYC_CLANE_ENABLE) | + ((dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? + 0 : DSI_PORT_BIT(PHYC_HS_CLK_CONTINUOUS)) | +- (dsi->port == 0 ? ++ (dsi->variant->port == 0 ? + VC4_SET_FIELD(lpx - 1, DSI0_PHYC_ESC_CLK_LPDT) : + VC4_SET_FIELD(lpx - 1, DSI1_PHYC_ESC_CLK_LPDT))); + +@@ -1043,13 +1054,13 @@ static void vc4_dsi_encoder_enable(struc + DSI_DISP1_ENABLE); + + /* Ungate the block. */ +- if (dsi->port == 0) ++ if (dsi->variant->port == 0) + DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI0_CTRL_CTRL0); + else + DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN); + + /* Bring AFE out of reset. */ +- if (dsi->port == 0) { ++ if (dsi->variant->port == 0) { + } else { + DSI_PORT_WRITE(PHY_AFEC0, + DSI_PORT_READ(PHY_AFEC0) & +@@ -1305,8 +1316,16 @@ static const struct drm_encoder_helper_f + .mode_fixup = vc4_dsi_encoder_mode_fixup, + }; + ++static const struct vc4_dsi_variant bcm2835_dsi1_variant = { ++ .port = 1, ++ .broken_axi_workaround = true, ++ .debugfs_name = "dsi1_regs", ++ .regs = dsi1_regs, ++ .nregs = ARRAY_SIZE(dsi1_regs), ++}; ++ + static const struct of_device_id vc4_dsi_dt_match[] = { +- { .compatible = "brcm,bcm2835-dsi1", (void *)(uintptr_t)1 }, ++ { .compatible = "brcm,bcm2835-dsi1", &bcm2835_dsi1_variant }, + {} + }; + +@@ -1317,7 +1336,7 @@ static void dsi_handle_error(struct vc4_ + if (!(stat & bit)) + return; + +- DRM_ERROR("DSI%d: %s error\n", dsi->port, type); ++ DRM_ERROR("DSI%d: %s error\n", dsi->variant->port, type); + *ret = IRQ_HANDLED; + } + +@@ -1415,7 +1434,7 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi * + int ret; + + snprintf(clk_name, sizeof(clk_name), +- "dsi%u_%s", dsi->port, phy_clocks[i].name); ++ "dsi%u_%s", dsi->variant->port, phy_clocks[i].name); + + /* We just use core fixed factor clock ops for the PHY + * clocks. The clocks are actually gated by the +@@ -1463,7 +1482,7 @@ static int vc4_dsi_bind(struct device *d + if (!match) + return -ENODEV; + +- dsi->port = (uintptr_t)match->data; ++ dsi->variant = match->data; + + vc4_dsi_encoder = devm_kzalloc(dev, sizeof(*vc4_dsi_encoder), + GFP_KERNEL); +@@ -1480,13 +1499,8 @@ static int vc4_dsi_bind(struct device *d + return PTR_ERR(dsi->regs); + + dsi->regset.base = dsi->regs; +- if (dsi->port == 0) { +- dsi->regset.regs = dsi0_regs; +- dsi->regset.nregs = ARRAY_SIZE(dsi0_regs); +- } else { +- dsi->regset.regs = dsi1_regs; +- dsi->regset.nregs = ARRAY_SIZE(dsi1_regs); +- } ++ dsi->regset.regs = dsi->variant->regs; ++ dsi->regset.nregs = dsi->variant->nregs; + + if (DSI_PORT_READ(ID) != DSI_ID_VALUE) { + dev_err(dev, "Port returned 0x%08x for ID instead of 0x%08x\n", +@@ -1498,7 +1512,7 @@ static int vc4_dsi_bind(struct device *d + * from the ARM. It does handle writes from the DMA engine, + * so set up a channel for talking to it. + */ +- if (dsi->port == 1) { ++ if (dsi->variant->broken_axi_workaround) { + dsi->reg_dma_mem = dma_alloc_coherent(dev, 4, + &dsi->reg_dma_paddr, + GFP_KERNEL); +@@ -1619,10 +1633,7 @@ static int vc4_dsi_bind(struct device *d + */ + list_splice_init(&dsi->encoder->bridge_chain, &dsi->bridge_chain); + +- if (dsi->port == 0) +- vc4_debugfs_add_regset32(drm, "dsi0_regs", &dsi->regset); +- else +- vc4_debugfs_add_regset32(drm, "dsi1_regs", &dsi->regset); ++ vc4_debugfs_add_regset32(drm, dsi->variant->debugfs_name, &dsi->regset); + + pm_runtime_enable(dev); + |