static int mipi_dsi_on(struct platform_device *pdev) { int ret = 0; struct hisi_fb_data_type *hisifd = NULL; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); HISI_FB_DEBUG("fb%d, +.\n", hisifd->index); /* set LCD init step before LCD on*/ hisifd->panel_info.lcd_init_step = LCD_INIT_POWER_ON; ret = panel_next_on(pdev); mipi_dsi_clk_enable(hisifd); mipi_dsi_on_sub1(hisifd, hisifd->mipi_dsi0_base); if (is_dual_mipi_panel(hisifd)) mipi_dsi_on_sub1(hisifd, hisifd->mipi_dsi1_base); ret = panel_next_on(pdev); mipi_dsi_on_sub2(hisifd, hisifd->mipi_dsi0_base); if (is_dual_mipi_panel(hisifd)) mipi_dsi_on_sub2(hisifd, hisifd->mipi_dsi1_base); /* mipi hs video/command mode */ ret = panel_next_on(pdev); HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return ret; }
static int dpe_on(struct platform_device *pdev) { int ret = 0; struct k3_fb_data_type *k3fd = NULL; BUG_ON(pdev == NULL); k3fd = platform_get_drvdata(pdev); BUG_ON(k3fd == NULL); K3_FB_DEBUG("fb%d, +.\n", k3fd->index); /* dis reset DSI */ if (is_mipi_panel(k3fd)) { if (is_dual_mipi_panel(k3fd)) { outp32(k3fd->crgperi_base + PERRSTDIS3_OFFSET, 0x00030000); } else { outp32(k3fd->crgperi_base + PERRSTDIS3_OFFSET, 0x00020000); } } if (k3fd->index != PRIMARY_PANEL_IDX) { if (k3fd_list[PRIMARY_PANEL_IDX] && (k3fd_list[PRIMARY_PANEL_IDX]->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF)) { K3_FB_DEBUG("fb%d, pdp clk enable!\n", k3fd->index); dpe_clk_enable(k3fd_list[PRIMARY_PANEL_IDX]); } } dpe_regulator_enable(k3fd); dpe_init(k3fd); if (is_ldi_panel(k3fd)) { k3fd->panel_info.lcd_init_step = LCD_INIT_POWER_ON; ret = panel_next_on(pdev); } ret = panel_next_on(pdev); if (k3fd->panel_info.vsync_ctrl_type == VSYNC_CTRL_NONE) { dpe_irq_enable(k3fd); dpe_interrupt_unmask(k3fd); } #if 0 if (k3fd->index == PRIMARY_PANEL_IDX) { enable_ldi_pdp(k3fd); } else if (k3fd->index == EXTERNAL_PANEL_IDX) { enable_ldi_sdp(k3fd); } else if (k3fd->index == AUXILIARY_PANEL_IDX) { ; /* do nothing */ } else { K3_FB_ERR("fb%d, not support this device!\n", k3fd->index); } #endif K3_FB_DEBUG("fb%d, -.\n", k3fd->index); return ret; }
void enable_clk_panel(struct hisi_fb_data_type *hisifd) { char __iomem *dss_base = NULL; uint32_t val = 0; int prev_refcount = 0; BUG_ON(hisifd == NULL); dss_base = hisifd->dss_base; down(&hisi_fb_dss_panel_clk_sem); prev_refcount = panel_refcount++; if (!prev_refcount) { /* de-reset status */ val =0x0; if (is_mipi_panel(hisifd)) { val |= PDP_DSI0_DIS_RST_CFG; } if (is_dual_mipi_panel(hisifd)) { val |= PDP_DSI1_DIS_RST_CFG; } outp32(dss_base + DSS_GLB_DIS_RST_CFG, val); /* enable clk */ val = 0x0; if (is_mipi_panel(hisifd)) { val |= PDP_DSI0_EN_CLK_CFG; } if (is_dual_mipi_panel(hisifd)) { val |= PDP_DSI1_EN_CLK_CFG; if (is_ifbc_panel(hisifd)) { set_reg(dss_base + DSS_GLB_PXL0_DIV, 0xb, 4, 0); } else { set_reg(dss_base + DSS_GLB_PXL0_DIV, 0x9, 4, 0); } } if (is_ifbc_panel(hisifd)) { val |= PDP_IFBC_EN_CLK_CFG; } outp32(dss_base + DSS_GLB_EN_CLK_CFG, val); } up(&hisi_fb_dss_panel_clk_sem); }
static int dpe_off(struct platform_device *pdev) { int ret = 0; struct k3_fb_data_type *k3fd = NULL; BUG_ON(pdev == NULL); k3fd = platform_get_drvdata(pdev); BUG_ON(k3fd == NULL); K3_FB_DEBUG("fb%d, +.\n", k3fd->index); if (k3fd->panel_info.vsync_ctrl_type == VSYNC_CTRL_NONE) { dpe_interrupt_mask(k3fd); dpe_irq_disable(k3fd); } else { if (k3fd->vsync_ctrl.vsync_ctrl_enabled == 1) { if (k3fd->panel_info.vsync_ctrl_type & VSYNC_CTRL_ISR_OFF) { dpe_interrupt_mask(k3fd); dpe_irq_disable(k3fd); K3_FB_INFO("fb%d, need to disable dpe irq! vsync_ctrl_enabled=%d.\n", k3fd->index, k3fd->vsync_ctrl.vsync_ctrl_enabled); } } } ret = panel_next_off(pdev); dpe_deinit(k3fd); dpe_regulator_disable(k3fd); if (k3fd->index != PRIMARY_PANEL_IDX) { if (k3fd_list[PRIMARY_PANEL_IDX] && (k3fd_list[PRIMARY_PANEL_IDX]->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF)) { K3_FB_DEBUG("fb%d, pdp clk disable!\n", k3fd->index); dpe_clk_disable(k3fd_list[PRIMARY_PANEL_IDX]); } } /* reset DSI */ if (is_mipi_panel(k3fd)) { if (is_dual_mipi_panel(k3fd)) { outp32(k3fd->crgperi_base + PERRSTEN3_OFFSET, 0x00030000); } else { outp32(k3fd->crgperi_base + PERRSTEN3_OFFSET, 0x00020000); } } K3_FB_DEBUG("fb%d, -.\n", k3fd->index); return ret; }
void disable_clk_panel(struct hisi_fb_data_type *hisifd) { char __iomem *dss_base = NULL; uint32_t val = 0; int new_refcount = 0; BUG_ON(hisifd == NULL); dss_base = hisifd->dss_base; down(&hisi_fb_dss_panel_clk_sem); new_refcount = --panel_refcount; WARN_ON(new_refcount < 0); if (!new_refcount) { /* disable clk */ val = 0x0; if (is_mipi_panel(hisifd)) { val |= PDP_DSI0_DIS_CLK_CFG; } if (is_dual_mipi_panel(hisifd)) { val |= PDP_DSI1_DIS_CLK_CFG; } if (is_ifbc_panel(hisifd)) { val |= PDP_IFBC_DIS_CLK_CFG; } outp32(dss_base + DSS_GLB_DIS_CLK_CFG, val); /* reset status */ val = 0x0; if (is_mipi_panel(hisifd)) { val |= PDP_DSI0_EN_RST_CFG; } if (is_dual_mipi_panel(hisifd)) { val |= PDP_DSI1_EN_RST_CFG; } outp32(dss_base + DSS_GLB_EN_RST_CFG, val); } up(&hisi_fb_dss_panel_clk_sem); }
int mipi_dsi_ulps_cfg(struct hisi_fb_data_type *hisifd, int enable) { int ret = 0; BUG_ON(hisifd == NULL); HISI_FB_DEBUG("fb%d, +.\n", hisifd->index); if (enable) { mipi_dsi_ulps_exit(hisifd, hisifd->mipi_dsi0_base); if (is_dual_mipi_panel(hisifd)) mipi_dsi_ulps_exit(hisifd, hisifd->mipi_dsi1_base); } else { mipi_dsi_ulps_enter(hisifd, hisifd->mipi_dsi0_base); if (is_dual_mipi_panel(hisifd)) mipi_dsi_ulps_enter(hisifd, hisifd->mipi_dsi1_base); } HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return ret; }
int mipi_dsi_clk_enable(struct hisi_fb_data_type *hisifd) { int ret = 0; struct clk *clk_tmp = NULL; BUG_ON(hisifd == NULL); clk_tmp = hisifd->dss_dphy0_clk; if (clk_tmp) { ret = clk_prepare(clk_tmp); if (ret) { HISI_FB_ERR("fb%d dss_dphy0_clk clk_prepare failed, error=%d!\n", hisifd->index, ret); return -EINVAL; } ret = clk_enable(clk_tmp); if (ret) { HISI_FB_ERR("fb%d dss_dphy0_clk clk_enable failed, error=%d!\n", hisifd->index, ret); return -EINVAL; } } if (is_dual_mipi_panel(hisifd)) { clk_tmp = hisifd->dss_dphy1_clk; if (clk_tmp) { ret = clk_prepare(clk_tmp); if (ret) { HISI_FB_ERR("fb%d dss_dphy1_clk clk_prepare failed, error=%d!\n", hisifd->index, ret); return -EINVAL; } ret = clk_enable(clk_tmp); if (ret) { HISI_FB_ERR("fb%d dss_dphy1_clk clk_enable failed, error=%d!\n", hisifd->index, ret); return -EINVAL; } } } return 0; }
static int mipi_dsi_clk_irq_setup(struct platform_device *pdev) { struct hisi_fb_data_type *hisifd = NULL; int ret = 0; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); hisifd->dss_dphy0_clk = devm_clk_get(&pdev->dev, hisifd->dss_dphy0_clk_name); if (IS_ERR(hisifd->dss_dphy0_clk)) { ret = PTR_ERR(hisifd->dss_dphy0_clk); return ret; } else { ret = clk_set_rate(hisifd->dss_dphy0_clk, DEFAULT_MIPI_CLK_RATE); if (ret < 0) { HISI_FB_ERR("fb%d dss_dphy0_clk clk_set_rate(%lu) failed, error=%d!\n", hisifd->index, DEFAULT_MIPI_CLK_RATE, ret); return -EINVAL; } HISI_FB_INFO("dss_dphy0_clk:[%lu]->[%lu].\n", DEFAULT_MIPI_CLK_RATE, clk_get_rate(hisifd->dss_dphy0_clk)); } if (is_dual_mipi_panel(hisifd)) { hisifd->dss_dphy1_clk = devm_clk_get(&pdev->dev, hisifd->dss_dphy1_clk_name); if (IS_ERR(hisifd->dss_dphy1_clk)) { ret = PTR_ERR(hisifd->dss_dphy1_clk); return ret; } else { ret = clk_set_rate(hisifd->dss_dphy1_clk, DEFAULT_MIPI_CLK_RATE); if (ret < 0) { HISI_FB_ERR("fb%d dss_dphy1_clk clk_set_rate(%lu) failed, error=%d!\n", hisifd->index, DEFAULT_MIPI_CLK_RATE, ret); return -EINVAL; } HISI_FB_INFO("dss_dphy1_clk:[%lu]->[%lu].\n", DEFAULT_MIPI_CLK_RATE, clk_get_rate(hisifd->dss_dphy1_clk)); } } return ret; }
int mipi_dsi_clk_disable(struct hisi_fb_data_type *hisifd) { struct clk *clk_tmp = NULL; BUG_ON(hisifd == NULL); clk_tmp = hisifd->dss_dphy0_clk; if (clk_tmp) { clk_disable(clk_tmp); clk_unprepare(clk_tmp); } if (is_dual_mipi_panel(hisifd)) { clk_tmp = hisifd->dss_dphy1_clk; if (clk_tmp) { clk_disable(clk_tmp); clk_unprepare(clk_tmp); } } return 0; }
static int mipi_dsi_off(struct platform_device *pdev) { int ret = 0; struct hisi_fb_data_type *hisifd = NULL; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); HISI_FB_DEBUG("fb%d, +.\n", hisifd->index); ret = panel_next_off(pdev); mipi_dsi_off_sub(hisifd, hisifd->mipi_dsi0_base); if (is_dual_mipi_panel(hisifd)) mipi_dsi_off_sub(hisifd, hisifd->mipi_dsi1_base); mipi_dsi_clk_disable(hisifd); HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return ret; }
void init_ldi(struct hisi_fb_data_type *hisifd) { char __iomem *dss_base = 0; struct hisi_panel_info *pinfo = NULL; BUG_ON(hisifd == NULL); pinfo = &(hisifd->panel_info); dss_base = hisifd->dss_base; if (hisifd->index == PRIMARY_PANEL_IDX) { if (is_dual_mipi_panel(hisifd)) { outp32(dss_base + PDP_LDI_DPI0_HRZ_CTRL0, pinfo->ldi.h_front_porch | (pinfo->ldi.h_back_porch << 16)); outp32(dss_base + PDP_LDI_DPI0_HRZ_CTRL1, DSS_WIDTH(pinfo->xres / 2) | (DSS_WIDTH(pinfo->ldi.h_pulse_width) << 16)); outp32(dss_base + PDP_LDI_DPI1_HRZ_CTRL0, pinfo->ldi.h_back_porch << 16); outp32(dss_base + PDP_LDI_DPI1_HRZ_CTRL1, DSS_WIDTH(pinfo->xres / 2) | (DSS_WIDTH(pinfo->ldi.h_pulse_width) << 16)); outp32(dss_base + PDP_LDI_OVERLAP_SIZE, pinfo->ldi.dpi0_overlap_size | (pinfo->ldi.dpi1_overlap_size << 16)); /* dual_mode_en */ set_reg(dss_base + PDP_LDI_CTRL, 1, 1, 5); /* split mode */ set_reg(dss_base + PDP_LDI_CTRL, 0, 1, 16); } else { outp32(dss_base + PDP_LDI_DPI0_HRZ_CTRL0, pinfo->ldi.h_front_porch | (pinfo->ldi.h_back_porch << 16)); outp32(dss_base + PDP_LDI_DPI0_HRZ_CTRL1, DSS_WIDTH(pinfo->xres) | (DSS_WIDTH(pinfo->ldi.h_pulse_width) << 16)); } outp32(dss_base + PDP_LDI_VRT_CTRL0, pinfo->ldi.v_front_porch | (pinfo->ldi.v_back_porch << 16)); outp32(dss_base + PDP_LDI_VRT_CTRL1, DSS_HEIGHT(pinfo->yres) | (DSS_HEIGHT(pinfo->ldi.v_pulse_width) << 16)); outp32(dss_base + PDP_LDI_PLR_CTRL, pinfo->ldi.vsync_plr | (pinfo->ldi.hsync_plr << 1) | (pinfo->ldi.pixelclk_plr << 2) | (pinfo->ldi.data_en_plr << 3)); /* ldi disable */ set_reg(dss_base + PDP_LDI_CTRL, 0, 1, 0); /* data_gate_en: mipi command LCD open */ if (is_mipi_cmd_panel(hisifd)) { //set_reg(dss_base + PDP_LDI_CTRL, 0x1, 1, 2); set_reg(dss_base + PDP_LDI_FRM_MSK, 0x1, 1, 0); } /* bpp */ set_reg(dss_base + PDP_LDI_CTRL, pinfo->bpp, 2, 3); /* bgr */ set_reg(dss_base + PDP_LDI_CTRL, pinfo->bgr_fmt, 1, 13); /* color mode: for mipi dsi */ /*set_reg(dss_base + PDP_LDI_CTRL, 0, 1, 14);*/ /* shutdown: for mipi dsi */ /*set_reg(dss_base + PDP_LDI_CTRL, 0, 1, 15);*/ #ifdef CONFIG_HISI_FB_COLORBAR_USED /* colorbar width */ set_reg(dss_base + PDP_LDI_CTRL, DSS_WIDTH(0x3c), 7, 6); /* colorbar ort */ set_reg(dss_base + PDP_LDI_WORK_MODE, 0, 1, 1); /* colorbar enable */ set_reg(dss_base + PDP_LDI_WORK_MODE, 0, 1, 0); #else /* normal */ outp32(dss_base + PDP_LDI_WORK_MODE, 0x1); #endif /* for ddr pmqos */ outp32(dss_base + PDP_LDI_VINACT_MSK_LEN, pinfo->ldi.v_front_porch); outp32(dss_base + PDP_LDI_CG_CTRL, 0x0); /* use default value */ /*outp32(dss_base + PDP_SRAM_LP_CTRL, );*/ /* for 3D frame by frame */ /*outp32(dss_base + PDP_LDI_3D_CTRL, ); outp32(dss_base + PDP_LDI_DE_SPACE_LOW, ); set_reg(dss_base + PDP_LDI_CTRL, 1, 1, 1);*/ /* for 1Hz LCD and mipi command LCD */ /*outp32(dss_base + PDP_LDI_FRM_MSK, );*/ if (is_mipi_cmd_panel(hisifd)) { set_reg(dss_base + PDP_DSI_CMD_MOD_CTRL, 0x1, 1, 0); set_reg(dss_base + PDP_DSI_TE_CTRL, 0x4001, 32, 0); set_reg(dss_base + PDP_DSI_TE_HS_NUM, 0x0, 32, 0); set_reg(dss_base + PDP_DSI_TE_HS_WD, 0xF0F, 32, 0); set_reg(dss_base + PDP_DSI_TE_VS_WD, 0x3FC0FF, 32, 0); } /* ** for test ** 2'b00: reserved ** 2'b01: LDI0->DSI0 ** 2'b10: LDI0->DSI1 ** 2'b11: LDI1 */ #if defined(CONFIG_ARCH_HI3630FPGA) || defined(CONFIG_HISI_3635_FPGA) \ || defined(CONFIG_HISI_3650_FPGA) set_reg(dss_base + DSS_GLB_TEST_SEL, 0x1, 2, 0); #endif } else if (hisifd->index == EXTERNAL_PANEL_IDX) { outp32(dss_base + SDP_LDI_HRZ_CTRL0, pinfo->ldi.h_front_porch | (pinfo->ldi.h_back_porch << 16)); outp32(dss_base + SDP_LDI_HRZ_CTRL1, DSS_WIDTH(pinfo->xres) | (DSS_WIDTH(pinfo->ldi.h_pulse_width) << 16)); outp32(dss_base + SDP_LDI_VRT_CTRL0, pinfo->ldi.v_front_porch | (pinfo->ldi.v_back_porch << 16)); outp32(dss_base + SDP_LDI_VRT_CTRL1, DSS_HEIGHT(pinfo->yres) | (DSS_HEIGHT(pinfo->ldi.v_pulse_width) << 16)); outp32(dss_base + SDP_LDI_PLR_CTRL, pinfo->ldi.vsync_plr | (pinfo->ldi.hsync_plr << 1) | (pinfo->ldi.pixelclk_plr << 2) | (pinfo->ldi.data_en_plr << 3)); /* ldi disable */ set_reg(dss_base + SDP_LDI_CTRL, 0, 1, 0); /* data_gate_en */ /*set_reg(dss_base + PDP_LDI_CTRL, 1, 1, 2);*/ /* bpp */ set_reg(dss_base + SDP_LDI_CTRL, pinfo->bpp, 2, 3); /* bgr */ set_reg(dss_base + SDP_LDI_CTRL, pinfo->bgr_fmt, 1, 13); /* color mode */ /*set_reg(dss_base + SDP_LDI_CTRL, 0, 1, 14);*/ /* shutdown */ /*set_reg(dss_base + SDP_LDI_CTRL, 0, 1, 15);*/ #ifdef CONFIG_HISI_FB_COLORBAR_USED /* colorbar width */ set_reg(dss_base + SDP_LDI_CTRL, DSS_WIDTH(0x3c), 7, 6); /* colorbar ort */ set_reg(dss_base + SDP_LDI_WORK_MODE, 0, 1, 1); /* colorbar enable */ set_reg(dss_base + SDP_LDI_WORK_MODE, 0, 1, 0); #else /* normal */ outp32(dss_base + SDP_LDI_WORK_MODE, 0x1); #endif outp32(dss_base + SDP_LDI_VINACT_MSK_LEN, pinfo->ldi.v_front_porch); } else { HISI_FB_ERR("fb%d, not support!", hisifd->index); return ; } }
static int mipi_dsi_ulps_exit(struct hisi_fb_data_type *hisifd, char __iomem *mipi_dsi_base) { uint32_t tmp = 0; uint32_t cmp_val = 0; uint32_t try_times = 0; BUG_ON(hisifd == NULL); BUG_ON(mipi_dsi_base == NULL); HISI_FB_DEBUG("fb%d, +!\n", hisifd->index); if (hisifd->panel_info.mipi.lane_nums >= DSI_4_LANES) { cmp_val = (BIT(3) | BIT(5) | BIT(8) | BIT(10) | BIT(12)); } else if (hisifd->panel_info.mipi.lane_nums >= DSI_3_LANES) { cmp_val = (BIT(3) | BIT(5) | BIT(8) | BIT(10)); } else if (hisifd->panel_info.mipi.lane_nums >= DSI_2_LANES) { cmp_val = (BIT(3) | BIT(5) | BIT(8)); } else { cmp_val = (BIT(3) | BIT(5)); } /* enable refclk and cfgclk */ if (is_dual_mipi_panel(hisifd)) outp32(hisifd->crgperi_base + PEREN3_OFFSET, 0x500000); else outp32(hisifd->crgperi_base + PEREN3_OFFSET, 0x100000); /* Test Code @ 0x20 = 0x45 */ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010020); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00000045); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* enable DPHY PLL, force_pll = 1 */ outp32(mipi_dsi_base + MIPIDSI_PHY_RSTZ_OFFSET, 0xF); /* wait DPHY PLL Lock */ try_times = 0; tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET); while ((tmp & BIT(0)) != 0X1) { udelay(10); if (++try_times > 100) { HISI_FB_ERR("fb%d, failed to wait DPHY PLL Lock!MIPIDSI_PHY_STATUS=0x%x.\n", hisifd->index, tmp); break; } tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET); } /* request that data lane and clock lane exit ULPS */ outp32(mipi_dsi_base + MIPIDSI_PHY_ULPS_CTRL_OFFSET, 0xF); try_times= 0; tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET); while ((tmp & cmp_val) != cmp_val) { udelay(10); if (++try_times > 100) { HISI_FB_ERR("fb%d, failed to request that data lane and clock lane exit ULPS!MIPIDSI_PHY_STATUS=0x%x.\n", hisifd->index, tmp); break; } tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET); } /* mipi spec */ mdelay(1); /* clear PHY_ULPS_CTRL */ outp32(mipi_dsi_base + MIPIDSI_PHY_ULPS_CTRL_OFFSET, 0x0); /* enable DPHY clock lane's Hight Speed Clock */ set_reg(mipi_dsi_base + MIPIDSI_LPCLK_CTRL_OFFSET, 0x1, 1, 0); HISI_FB_DEBUG("fb%d, -!\n", hisifd->index); return 0; }