From 4bf24b47175bd55813612f0d162defcb65b94d13 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Wed, 16 Aug 2023 21:30:56 +0800 Subject: video: starfive: Add StarFive JH7110 Devkits board support Make the code be compatible with the StarFive Devkits board. The code is ported from tag JH7110_DVK_515_v3.9.3 of Devkits repo. Signed-off-by: Keith Zhao Signed-off-by: Shengyang Chen Signed-off-by: Hal Feng --- drivers/video/starfive/mipi_dsi_host.c | 51 ++++++++---- drivers/video/starfive/sf_mipi.c | 38 ++++++--- drivers/video/starfive/sf_mipi.h | 1 + drivers/video/starfive/sf_vop.c | 137 ++++++++++++++++++++++++++++++++- 4 files changed, 199 insertions(+), 28 deletions(-) diff --git a/drivers/video/starfive/mipi_dsi_host.c b/drivers/video/starfive/mipi_dsi_host.c index 2736eb329f..4960a22ee5 100644 --- a/drivers/video/starfive/mipi_dsi_host.c +++ b/drivers/video/starfive/mipi_dsi_host.c @@ -220,7 +220,7 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host, ret = wait_for_send_done(dsi, MIPI_FIFO_TIMEOUT); if (!ret) { - printf("wait tx done timeout!\n"); + debug("wait tx done timeout!\n"); return -ETIMEDOUT; } udelay(10); @@ -285,7 +285,7 @@ static int mipi_dsi_northwest_init(struct udevice *dev, priv->phy_base = (void *)dev_read_addr_name(device->dev, "phy"); if ((fdt_addr_t)priv->dsi_base == FDT_ADDR_T_NONE || (fdt_addr_t)priv->phy_base == FDT_ADDR_T_NONE) { - printf("dsi dt register address error\n"); + debug("dsi dt register address error\n"); return -EINVAL; } priv->link_initialized = false; @@ -300,21 +300,38 @@ static int mipi_dsi_enable(struct udevice *dev) priv->phy_ops->init(priv->device); priv->phy_ops->post_set_mode(priv->device, MIPI_DSI_MODE_VIDEO); cdns_dsi_init_link(priv, priv->device); - - writel(0x00670067, priv->dsi_base + 0x000000c0); - writel(0x00cb0960, priv->dsi_base + 0x000000c4); - writel(0x0003b145, priv->dsi_base + 0x000000b4); - writel(0x000001e0, priv->dsi_base + 0x000000b8); - writel(0x00000a9e, priv->dsi_base + 0x000000d0); - writel(0x0a980000, priv->dsi_base + 0x000000f8); - writel(0x00000b0f, priv->dsi_base + 0x000000cc); - writel(0x7c3c0aae, priv->dsi_base + 0x000000dc); - writel(0x0032dcd3, priv->dsi_base + 0x00000014); - writel(0x00032dcd, priv->dsi_base + 0x00000018); - writel(0x80b8fe00, priv->dsi_base + 0x000000b0); - writel(0x00020027, priv->dsi_base + 0x00000004); - writel(0x00004018, priv->dsi_base + 0x0000000c); - + debug("priv->timings.hactive.typ %d----\n",priv->timings.hactive.typ); + debug("priv->timings.vactive.typ %d----\n",priv->timings.vactive.typ); + if (priv->timings.hactive.typ == 800) + { + writel(0x00670067, priv->dsi_base + 0x000000c0); + writel(0x00cb0960, priv->dsi_base + 0x000000c4); + writel(0x0003b145, priv->dsi_base + 0x000000b4); + writel(0x000001e0, priv->dsi_base + 0x000000b8); + writel(0x00000a9e, priv->dsi_base + 0x000000d0); + writel(0x0a980000, priv->dsi_base + 0x000000f8); + writel(0x00000b0f, priv->dsi_base + 0x000000cc); + writel(0x7c3c0aae, priv->dsi_base + 0x000000dc); + writel(0x0032dcd3, priv->dsi_base + 0x00000014); + writel(0x00032dcd, priv->dsi_base + 0x00000018); + writel(0x80b8fe00, priv->dsi_base + 0x000000b0); + writel(0x00020027, priv->dsi_base + 0x00000004); + writel(0x00004018, priv->dsi_base + 0x0000000c); + }else if (priv->timings.hactive.typ == 1920){ + writel(0x01d30081, priv->dsi_base + 0x000000c0); + writel(0x01171680, priv->dsi_base + 0x000000c4); + writel(0x00003905, priv->dsi_base + 0x000000b4); + writel(0x00000438, priv->dsi_base + 0x000000b8); + writel(0x00001976, priv->dsi_base + 0x000000d0); + writel(0x19700000, priv->dsi_base + 0x000000f8); + writel(0x00001a01, priv->dsi_base + 0x000000cc); + writel(0x98900661, priv->dsi_base + 0x000000dc); + writel(0x003f9403, priv->dsi_base + 0x00000014); + writel(0x0003f940, priv->dsi_base + 0x00000018); + writel(0x80b8fe00, priv->dsi_base + 0x000000b0); + writel(0x00020027, priv->dsi_base + 0x00000004); + writel(0x000040f8, priv->dsi_base + 0x0000000c); + } return 0; } diff --git a/drivers/video/starfive/sf_mipi.c b/drivers/video/starfive/sf_mipi.c index ee5fbe7359..d9300c5879 100644 --- a/drivers/video/starfive/sf_mipi.c +++ b/drivers/video/starfive/sf_mipi.c @@ -114,7 +114,13 @@ static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags) if (!priv) return; - bitrate = 750000000;//1188M 60fps + // bitrate = 750000000;//1188M 60fps + debug("dsi_phy_post_set_mode priv->timings.hactive.typ %d----\n",priv->timings.hactive.typ); + debug("dsi_phy_post_set_mode priv->timings.vactive.typ %d----\n",priv->timings.vactive.typ); + if (priv->timings.hactive.typ == 800) + bitrate = 750000000; + else if(priv->timings.hactive.typ == 1920) + bitrate = 900000000;//1188M 60fps sf_dphy_set_reg(priv->phy_reg + 0x8, 0x10, RG_CDTX_L0N_HSTX_RES_SHIFT, RG_CDTX_L0N_HSTX_RES_MASK); @@ -255,11 +261,24 @@ static int dsi_sf_attach(struct udevice *dev) struct display_timing timings; int ret; +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS) + ret = uclass_get_device_by_name(UCLASS_PANEL, "seeed_panel@45", &priv->panel); + if (ret) { + debug("Could not get seeed_panel@45: %d\n", ret); + ret = uclass_get_device_by_name(UCLASS_PANEL, "lt8911exb_i2c@29", &priv->panel); + if (ret) { + debug("Could not get lt8911exb_i2c@29: %d\n", ret); + return ret; + } + } +#else ret = uclass_first_device(UCLASS_PANEL, &priv->panel); if (ret) { debug("panel device error %d\n", ret); return ret; } +#endif + debug("%s,priv->panel->name = %s\n", __func__,priv->panel->name); mplat = dev_get_plat(priv->panel); @@ -273,14 +292,15 @@ static int dsi_sf_attach(struct udevice *dev) ret = ofnode_decode_display_timing(dev_ofnode(priv->panel), 0, &timings); if (ret) { - printf("decode display timing error %d\n", ret); + debug("decode display timing error %d\n", ret); return ret; } } + priv->timings = timings; ret = uclass_get_device(UCLASS_DSI_HOST, 0, &priv->dsi_host); if (ret) { - printf("No video dsi host detected %d\n", ret); + debug("No video dsi host detected %d\n", ret); return ret; } @@ -288,7 +308,7 @@ static int dsi_sf_attach(struct udevice *dev) mplat->lanes, &dsi_stm_phy_ops); if (ret) { - printf("failed to initialize mipi dsi host\n"); + debug("failed to initialize mipi dsi host\n"); return ret; } @@ -302,13 +322,13 @@ static int dsi_sf_set_backlight(struct udevice *dev, int percent) ret = dsi_host_enable(priv->dsi_host); if (ret) { - printf("failed to enable mipi dsi host\n"); + debug("failed to enable mipi dsi host\n"); return ret; } ret = panel_enable_backlight(priv->panel); if (ret) { - printf("panel %s enable backlight error %d\n", + debug("panel %s enable backlight error %d\n", priv->panel->name, ret); return ret; } @@ -442,7 +462,7 @@ static int dsi_sf_probe(struct udevice *dev) ret = dev_read_u32(dev, "data-lanes-num", &priv->data_lanes); if (ret) { - printf("fail to get data lanes property %d\n", ret); + debug("fail to get data lanes property %d\n", ret); return 0; } @@ -508,13 +528,13 @@ static int dsi_sf_probe(struct udevice *dev) debug("%s ok: ID_REG val = %08x\n", __func__, val); if (REV_VENDOR_ID(val) != 0xcad) { - printf("invalid vendor id\n"); + debug("invalid vendor id\n"); ret = -EINVAL; } ret = cdns_check_register_access(dev); if (ret) { - printf("error: r/w test generic reg failed\n"); + debug("error: r/w test generic reg failed\n"); } val = readl(priv->dsi_reg + IP_CONF); diff --git a/drivers/video/starfive/sf_mipi.h b/drivers/video/starfive/sf_mipi.h index 21c82340ba..dbf7f0d246 100644 --- a/drivers/video/starfive/sf_mipi.h +++ b/drivers/video/starfive/sf_mipi.h @@ -786,6 +786,7 @@ struct dsi_sf_priv { struct udevice *panel; struct udevice *dsi_host; unsigned int data_lanes; + struct display_timing timings; struct clk dsi_sys_clk; struct clk apb_clk; diff --git a/drivers/video/starfive/sf_vop.c b/drivers/video/starfive/sf_vop.c index 5f91ed7bde..a167341cd9 100644 --- a/drivers/video/starfive/sf_vop.c +++ b/drivers/video/starfive/sf_vop.c @@ -29,6 +29,7 @@ #include #include "sf_vop.h" +#include "sf_mipi.h" DECLARE_GLOBAL_DATA_PTR; @@ -398,7 +399,9 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) debug("%s(%s, 0x%lx, %s)\n", __func__, dev_read_name(dev), fbbase, ofnode_get_name(ep_node)); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) struct udevice *panel = NULL; +#endif ret = ofnode_read_u32(ep_node, "remote-endpoint", &remote_phandle); if (ret) @@ -579,6 +582,7 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) return ret; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) ret = uclass_first_device_err(UCLASS_PANEL, &panel); if (ret) { if (ret != -ENODEV) @@ -595,6 +599,7 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) return ret; } } +#endif int err = clk_set_parent(&priv->dc_pix0, &priv->dc_pix_src); if (err) { @@ -603,17 +608,40 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) return err; } +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) ulong new_rate = clk_set_rate(&priv->dc_pix_src, timing.pixelclock.typ); debug("new_rate %ld\n", new_rate); +#endif dc_hw_init(dev); +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) uc_priv->xsize = timing.hactive.typ; uc_priv->ysize = timing.vactive.typ; if (IS_ENABLED(CONFIG_VIDEO_COPY)) uc_plat->copy_base = uc_plat->base - uc_plat->size / 2; +#else + struct dsi_sf_priv *private = dev_get_priv(disp); + + uc_priv->xsize = private->timings.hactive.typ; + uc_priv->ysize = private->timings.vactive.typ; + debug("uc_priv->xsize %d\n", uc_priv->xsize); + debug("uc_priv->ysize %d\n", uc_priv->ysize); + + if(uc_priv->xsize == 800) + { + ulong new_rate = clk_set_rate(&priv->dc_pix_src, 29700000); + debug("new_rate %ld\n", new_rate); + } + if(uc_priv->xsize == 1920) + { + ulong new_rate = clk_set_rate(&priv->dc_pix_src, 148500000); + debug("new_rate %ld\n", new_rate); + } +#endif +#if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB) || CONFIG_IS_ENABLED(TARGET_STARFIVE_VISIONFIVE2) writel(0xc0001fff, priv->regs_hi+0x00000014); //csr_reg writel(0x000000e8, priv->regs_hi+0x00001a38); //csr_reg writel(0x00002000, priv->regs_hi+0x00001cc0); //csr_reg @@ -663,10 +691,115 @@ static int sf_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node) writel(0x00000000, priv->regs_hi+0x000024fc); //csr_reg writel(0x00011b25, priv->regs_hi+0x000024e8); //csr_reg writel(0x00000001, priv->regs_hi+0x00001ccc); //csr_reg - priv->mipi_logo = true; - return 0; +#else + if(uc_priv->xsize == 800) + { + writel(0xc0001fff, priv->regs_hi+0x00000014); //csr_reg + writel(0x000000e8, priv->regs_hi+0x00001a38); //csr_reg + writel(0x00002000, priv->regs_hi+0x00001cc0); //csr_reg + writel(0x00000000, priv->regs_hi+0x000024d8); //csr_reg + writel(0x03c00438, priv->regs_hi+0x000024e0); //csr_reg + writel(0x03c00438, priv->regs_hi+0x00001810); //csr_reg + writel(uc_plat->base, priv->regs_hi+0x00001400); + writel(0x000010e0, priv->regs_hi+0x00001408); //csr_reg + writel(0x000fb00b, priv->regs_hi+0x00001ce8); //csr_reg + writel(0x0000a9a3, priv->regs_hi+0x00002510); //csr_reg + writel(0x2c4e6f06, priv->regs_hi+0x00002508); //csr_reg + writel(0xe6daec4f, priv->regs_hi+0x00002500); //csr_reg + writel(0x18220000, priv->regs_hi+0x00001518); //csr_reg + writel(0x00003000, priv->regs_hi+0x00001cc0); //csr_reg + writel(0x00030000, priv->regs_hi+0x00001cc4); //csr_reg + writel(0x00030000, priv->regs_hi+0x00001cc4); //csr_reg + writel(0x00050c1a, priv->regs_hi+0x00001540); //csr_reg + writel(0x00000001, priv->regs_hi+0x00002540); //csr_reg + writel(0x00050c1a, priv->regs_hi+0x00001540); //csr_reg + writel(0x4016120c, priv->regs_hi+0x00001544); //csr_reg + writel(0x00000002, priv->regs_hi+0x00002544); //csr_reg + writel(0x4016120c, priv->regs_hi+0x00001544); //csr_reg + writel(0x001b1208, priv->regs_hi+0x00001548); //csr_reg + writel(0x00000004, priv->regs_hi+0x00002548); //csr_reg + writel(0x001b1208, priv->regs_hi+0x00001548); //csr_reg + writel(0x0016110e, priv->regs_hi+0x0000154c); //csr_reg + writel(0x00000005, priv->regs_hi+0x0000254c); //csr_reg + writel(0x0016110e, priv->regs_hi+0x0000154c); //csr_reg + writel(0x00000001, priv->regs_hi+0x00002518); //csr_reg + writel(0x00000000, priv->regs_hi+0x00001a28); //csr_reg + writel(0x03840320, priv->regs_hi+0x00001430); //csr_reg, hsize, htotal + writel(0xc1bf837a, priv->regs_hi+0x00001438); //csr_reg, hsize blanking + writel(0x022601e0, priv->regs_hi+0x00001440); //csr_reg, vsize + writel(0xc110021c, priv->regs_hi+0x00001448); //csr_reg, vsize blanking + writel(0x00000000, priv->regs_hi+0x000014b0); //csr_reg + writel(0x000000e2, priv->regs_hi+0x00001cd0); //csr_reg + writel(0x000000af, priv->regs_hi+0x000014d0); //csr_reg + writel(0x00000005, priv->regs_hi+0x000014b8); //csr_reg + writel(0x8dd0b774, priv->regs_hi+0x00001528); //csr_reg + writel(0x00001111, priv->regs_hi+0x00001418); //csr_reg + writel(0x00000000, priv->regs_hi+0x00001410); //csr_reg + writel(0x00000000, priv->regs_hi+0x00002518); //csr_reg + writel(0x00000006, priv->regs_hi+0x00001468); //csr_reg + writel(0x00000000, priv->regs_hi+0x00001484); //csr_reg + writel(0x00000006, priv->regs_hi+0x00001468); //csr_reg + writel(0x00011b25, priv->regs_hi+0x000024e8); //csr_reg + writel(0x00000000, priv->regs_hi+0x000024fc); //csr_reg + writel(0x00011b25, priv->regs_hi+0x000024e8); //csr_reg + writel(0x00000001, priv->regs_hi+0x00001ccc); //csr_reg + } + if(uc_priv->xsize == 1920) + { + writel(0xc0001fff, priv->regs_hi+0x00000014); + writel(0x000000e8, priv->regs_hi+0x00001a38); + writel(0x00002000, priv->regs_hi+0x00001cc0); + writel(0x00000000, priv->regs_hi+0x000024d8); + writel(0x04380780, priv->regs_hi+0x000024e0); + writel(0x04380780, priv->regs_hi+0x00001810); + writel(uc_plat->base, priv->regs_hi+0x00001400); + writel(0x00001e00, priv->regs_hi+0x00001408); + writel(0x00000000, priv->regs_hi+0x00001ce8); + writel(0x0000a9a3, priv->regs_hi+0x00002510); + writel(0x2c4e6f06, priv->regs_hi+0x00002508); + writel(0xe6daec4f, priv->regs_hi+0x00002500); + writel(0x18220000, priv->regs_hi+0x00001518); + writel(0x00003000, priv->regs_hi+0x00001cc0); + writel(0x00030000, priv->regs_hi+0x00001cc4); + writel(0x00030000, priv->regs_hi+0x00001cc4); + writel(0x00050c1a, priv->regs_hi+0x00001540); + writel(0x00000001, priv->regs_hi+0x00002540); + writel(0x00050c1a, priv->regs_hi+0x00001540); + writel(0x4016120c, priv->regs_hi+0x00001544); + writel(0x00000002, priv->regs_hi+0x00002544); + writel(0x4016120c, priv->regs_hi+0x00001544); + writel(0x001b1208, priv->regs_hi+0x00001548); + writel(0x00000004, priv->regs_hi+0x00002548); + writel(0x001b1208, priv->regs_hi+0x00001548); + writel(0x0016110e, priv->regs_hi+0x0000154c); + writel(0x00000005, priv->regs_hi+0x0000254c); + writel(0x0016110e, priv->regs_hi+0x0000154c); + writel(0x00000001, priv->regs_hi+0x00002518); + writel(0x00000000, priv->regs_hi+0x00001a28); + writel(0x08980780, priv->regs_hi+0x00001430); + writel(0xc40207d8, priv->regs_hi+0x00001438); + writel(0x04650438, priv->regs_hi+0x00001440); + writel(0xc220843c, priv->regs_hi+0x00001448); + writel(0x00000000, priv->regs_hi+0x000014b0); + writel(0x000000e2, priv->regs_hi+0x00001cd0); + writel(0x000000af, priv->regs_hi+0x000014d0); + writel(0x00000005, priv->regs_hi+0x000014b8); + writel(0x8dd0b774, priv->regs_hi+0x00001528); + writel(0x00001111, priv->regs_hi+0x00001418); + writel(0x00000000, priv->regs_hi+0x00001410); + writel(0x00000000, priv->regs_hi+0x00002518); + writel(0x00000006, priv->regs_hi+0x00001468); + writel(0x00000000, priv->regs_hi+0x00001484); + writel(0x00000006, priv->regs_hi+0x00001468); + writel(0x00011b25, priv->regs_hi+0x000024e8); + writel(0x00000000, priv->regs_hi+0x000024fc); + writel(0x00011b25, priv->regs_hi+0x000024e8); + writel(0x00000001, priv->regs_hi+0x00001ccc); + } +#endif } + priv->mipi_logo = true; return 0; } -- cgit v1.2.3