void single_frame_update(struct hisi_fb_data_type *hisifd) { char __iomem *dss_base = NULL; BUG_ON(hisifd == NULL); dss_base = hisifd->dss_base; if (hisifd->index == PRIMARY_PANEL_IDX) { if (is_mipi_cmd_panel(hisifd)) { set_reg(dss_base + PDP_LDI_FRM_MSK, 1, 1, 24); } set_reg(dss_base + PDP_LDI_CTRL, 1, 1, 0); } else if (hisifd->index == EXTERNAL_PANEL_IDX) { if (is_mipi_cmd_panel(hisifd)) { set_reg(dss_base + SDP_LDI_FRM_MSK, 1, 1, 24); } set_reg(dss_base + SDP_LDI_CTRL, 1, 1, 0); } else { ; } if (hisifd->vsync_ctrl.vsync_report_fnc) { atomic_inc(&(hisifd->vsync_ctrl.buffer_updated)); } }
static int mipi_dsi_on_sub2(struct hisi_fb_data_type *hisifd, char __iomem *mipi_dsi_base) { BUG_ON(hisifd == NULL); BUG_ON(mipi_dsi_base == NULL); if (is_mipi_video_panel(hisifd)) { /* switch to video mode */ set_reg(mipi_dsi_base + MIPIDSI_MODE_CFG_OFFSET, 0x0, 1, 0); } if (is_mipi_cmd_panel(hisifd)) { /* cmd mode: high speed mode */ set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x0, 7, 8); set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x0, 4, 16); set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x0, 1, 24); } /* enable EOTP TX */ set_reg(mipi_dsi_base + MIPIDSI_PCKHDL_CFG_OFFSET, 0x1, 1, 0); /* enable generate High Speed clock */ set_reg(mipi_dsi_base + MIPIDSI_LPCLK_CTRL_OFFSET, 0x1, 1, 0); return 0; }
void hisi_dss_mctl_ov_set_ctl_dbg_reg(struct hisi_fb_data_type *hisifd, char __iomem *mctl_dgb) { if (hisifd == NULL) { HISI_FB_ERR("hisifd is null"); return; } if (is_mipi_cmd_panel(hisifd) && (hisifd->ldi_data_gate_en == 1)) { //open underflow clear set_reg(mctl_dgb, 0x782620, 32, 0); } else { //open underflow clear set_reg(mctl_dgb, 0x70A620, 32, 0); //set_reg(mctl_dgb, 0xB02620, 32, 0); } }
void init_dpp(struct hisi_fb_data_type *hisifd) { char __iomem *dpp_base = NULL; BUG_ON(hisifd == NULL); if (hisifd->index == PRIMARY_PANEL_IDX) { dpp_base = hisifd->dss_base + DSS_DPP0_CTRL_OFFSET; } else { HISI_FB_ERR("fb%d, not support!", hisifd->index); return ; } set_reg(dpp_base + DPP_IMG_HRZ, DSS_WIDTH(hisifd->panel_info.xres), 13, 0); set_reg(dpp_base + DPP_IMG_VRT, DSS_HEIGHT(hisifd->panel_info.yres), 13, 0); #ifdef CONFIG_FIX_DIRTY_REGION_UPDT if (is_mipi_cmd_panel(hisifd)) { outp32(dpp_base + DPP_CLK_GT, 0xA); } #endif }
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 ; } }
void init_sbl(struct hisi_fb_data_type *hisifd) { char __iomem *dpp_base = NULL; char __iomem *sbl_base = NULL; uint32_t tmp = 0; BUG_ON(hisifd == NULL); if (hisifd->index == PRIMARY_PANEL_IDX) { dpp_base = hisifd->dss_base + DSS_DPP0_CTRL_OFFSET; sbl_base = hisifd->dss_base + DSS_DPP_SBL_OFFSET; } else { HISI_FB_ERR("fb%d, not support!", hisifd->index); return ; } if (is_mipi_cmd_panel(hisifd)) { outp32(sbl_base + SBL_CONFIG_BUFFER_MODE, 0x2); } else { outp32(sbl_base + SBL_CONFIG_BUFFER_MODE, 0x0); } outp32(sbl_base + SBL_AUTOMATIC_START_CALC_STRENGTH_DRC_BACKLIGHT_SEL, 0x80); tmp = hisifd->panel_info.xres; outp32(sbl_base + SBL_FRAME_WIDTH_L, (tmp & 0xff)); outp32(sbl_base + SBL_FRAME_WIDTH_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.yres; outp32(sbl_base + SBL_FRAME_HEIGHT_L, (tmp & 0xff)); outp32(sbl_base + SBL_FRAME_HEIGHT_H, ((tmp >> 8) & 0xff)); outp32(sbl_base + SBL_APICAL_DITHER, 0x0); tmp = hisifd->bl_level; outp32(sbl_base + SBL_BACKLIGHT_L, (tmp & 0xff)); outp32(sbl_base + SBL_BACKLIGHT_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.backlight_scale; outp32(sbl_base + SBL_BACKLIGHT_SCALE_L, (tmp & 0xff)); outp32(sbl_base + SBL_BACKLIGHT_SCALE_H, (tmp >> 8) & 0xff); tmp = hisifd->panel_info.smart_bl.strength_limit; outp32(sbl_base + SBL_STRENGTH_LIMIT, tmp); tmp = hisifd->panel_info.smart_bl.calibration_a; outp32(sbl_base + SBL_CALIBRATION_A_L, (tmp & 0xff)); outp32(sbl_base + SBL_CALIBRATION_A_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.calibration_b; outp32(sbl_base + SBL_CALIBRATION_B_L, (tmp & 0xff)); outp32(sbl_base + SBL_CALIBRATION_B_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.calibration_c; outp32(sbl_base + SBL_CALIBRATION_C_L, (tmp & 0xff)); outp32(sbl_base + SBL_CALIBRATION_C_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.calibration_d; outp32(sbl_base + SBL_CALIBRATION_D_L, (tmp & 0xff)); outp32(sbl_base + SBL_CALIBRATION_D_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.t_filter_control; outp32(sbl_base + SBL_T_FILTER_CONTROL, tmp); tmp = hisifd->panel_info.smart_bl.backlight_min; outp32(sbl_base + SBL_BACKLIGHT_MIN_L, (tmp & 0xff)); outp32(sbl_base + SBL_BACKLIGHT_MIN_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.backlight_max; outp32(sbl_base + SBL_BACKLIGHT_MAX_L, (tmp & 0xff)); outp32(sbl_base + SBL_BACKLIGHT_MAX_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.ambient_light_min; outp32(sbl_base + SBL_AMBIENT_LIGHT_MIN_L, (tmp & 0xff)); outp32(sbl_base + SBL_AMBIENT_LIGHT_MIN_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.filter_a; outp32(sbl_base + SBL_FILTER_A_L, (tmp & 0xff)); outp32(sbl_base + SBL_FILTER_A_H, ((tmp >> 8) & 0xff)); tmp = hisifd->panel_info.smart_bl.filter_b; outp32(sbl_base + SBL_FILTER_B, tmp); tmp = hisifd->panel_info.smart_bl.logo_left; outp32(sbl_base + SBL_LOGO_LEFT, tmp); tmp = hisifd->panel_info.smart_bl.logo_top; outp32(sbl_base + SBL_LOGO_TOP, tmp); outp32(sbl_base + SBL_ENABLE, 0x0); if (hisifd->panel_info.sbl_support == 1) { outp32(dpp_base + DPP_SBL, 0x1); } else { outp32(dpp_base + DPP_SBL, 0x0); } }
static void dpe_interrupt_unmask(struct k3_fb_data_type *k3fd) { char __iomem *dss_base = 0; u32 unmask = 0; BUG_ON(k3fd == NULL); dss_base = k3fd->dss_base; if (k3fd->index == PRIMARY_PANEL_IDX) { /* Stage 1 interrupts */ //unmask = ~0; //unmask &= ~(BIT_PDP_LDI0_IRQ_CPU | BIT_WBE0_MMU_IRQ_CPU); unmask = 0x0; outp32(dss_base + DSS_GLB_PDP_CPU_IRQ_MSK, unmask); /* ** Stage 2 interrupts ** BIT_LDI_UNFLOW_INT in k3_baselayer_init */ unmask = ~0; if (is_mipi_cmd_panel(k3fd)) unmask &= ~(BIT_BACKLIGHT_INT | BIT_VACTIVE0_START_INT | BIT_LDI_TE0_PIN_INT); else unmask &= ~(BIT_BACKLIGHT_INT | BIT_VSYNC_INT | BIT_VACTIVE0_START_INT); outp32(dss_base + PDP_LDI_CPU_IRQ_MSK, unmask); unmask = ~0; unmask &= ~(BIT_WBE0_FRAME_END_CPU_CH1 | BIT_WBE0_FRAME_END_CPU_CH0); outp32(dss_base + DSS_DPE0_OFFSET + DSS_DP_CTRL_OFFSET + PDP_WBE0_CPU_IRQ_MSK, unmask); } else if (k3fd->index == EXTERNAL_PANEL_IDX) { /* Stage 1 interrupts */ //unmask = ~0; //unmask &= ~(BIT_SDP_LDI1_IRQ_MCU | BIT_WBE0_MMU_IRQ_CPU); unmask = 0x0; outp32(dss_base + DSS_GLB_SDP_CPU_IRQ_MSK, unmask); /* Stage 2 interrupts */ unmask = ~0; unmask &= ~(BIT_VSYNC_INT | BIT_VACTIVE0_START_INT); outp32(dss_base + SDP_LDI_CPU_IRQ_MSK, unmask); unmask = ~0; unmask &= ~(BIT_WBE0_FRAME_END_CPU_CH1 | BIT_WBE0_FRAME_END_CPU_CH0); outp32(dss_base + DSS_DPE1_OFFSET + DSS_DP_CTRL_OFFSET + SDP_WBE0_CPU_IRQ_MSK, unmask); } else if (k3fd->index == AUXILIARY_PANEL_IDX) { /* Stage 1 interrupts */ //unmask = ~0; //unmask &= ~(BIT_OFFLINE_S2_IRQ_CPU_OFF | // BIT_WBE1_MMU_IRQ_CPU_OFF | BIT_WBE0_MMU_IRQ_CPU_OFF | // BIT_CMDLIST_IRQ_CPU_OFF); unmask = 0x0; outp32(dss_base + DSS_GLB_OFFLINE_CPU_IRQ_MSK, unmask); /* Stage 2 interrupts */ unmask = ~0; unmask &= ~(BIT_OFFLINE_WBE1_CH0_FRM_END_CPU | BIT_OFFLINE_WBE1_CH1_FRM_END_CPU); outp32(dss_base + DSS_DPE3_OFFSET + DSS_DP_CTRL_OFFSET + OFFLINE_WBE1_CPU_IRQ_MSK, unmask); /* enable adp irq */ //outp32(dss_base + DSS_GLB_OFFLINE_S2_CPU_IRQ_MSK, 0); /* enable cmdlist irq */ //set_reg(dss_base + DSS_CMD_LIST_OFFSET + CMDLIST_CH4_INTE, 0x3F, 6, 0); //set_reg(dss_base + DSS_CMD_LIST_OFFSET + CMDLIST_CH5_INTE, 0x3F, 6, 0); } else { K3_FB_ERR("fb%d, not support this device!\n", k3fd->index); } }
static void mipi_init(struct hisi_fb_data_type *hisifd, char __iomem *mipi_dsi_base) { uint32_t hline_time = 0; uint32_t hsa_time = 0; uint32_t hbp_time = 0; uint32_t pixel_clk = 0; unsigned long dw_jiffies = 0; struct mipi_dsi_phy_ctrl phy_ctrl = {0}; uint32_t tmp = 0; bool is_ready = false; struct hisi_panel_info *pinfo = NULL; BUG_ON(hisifd == NULL); BUG_ON(mipi_dsi_base == NULL); pinfo = &(hisifd->panel_info); get_dsi_phy_ctrl(pinfo->mipi.dsi_bit_clk, &phy_ctrl); /* config TE */ if (is_mipi_cmd_panel(hisifd)) { /* config to command mode */ set_reg(mipi_dsi_base + MIPIDSI_MODE_CFG_OFFSET, 0x1, 1, 0); /* ALLOWED_CMD_SIZE */ set_reg(mipi_dsi_base + MIPIDSI_EDPI_CMD_SIZE_OFFSET, pinfo->xres, 16, 0); /* cnt=2 in update-patial scene, cnt nees to be checked for different panels*/ set_reg(mipi_dsi_base + MIPIDSI_HS_WR_TO_CNT_OFFSET, 0x1000002, 25, 0); /* phy_stop_wait_time */ set_reg(mipi_dsi_base + MIPIDSI_PHY_IF_CFG_OFFSET, 0x30, 8, 8); /* FIXME: test tearing effect, if use gpio, no need */ /*set_reg(mipi_dsi_base + MIPIDSI_CMD_MODE_CFG_OFFSET, 0x1, 1, 0);*/ } /*--------------configuring the DPI packet transmission----------------*/ /* ** 1. Global configuration ** Configure Register PHY_IF_CFG with the correct number of lanes ** to be used by the controller. */ set_reg(mipi_dsi_base + MIPIDSI_PHY_IF_CFG_OFFSET, pinfo->mipi.lane_nums, 2, 0); /* ** 2. Configure the DPI Interface: ** This defines how the DPI interface interacts with the controller. */ set_reg(mipi_dsi_base + MIPIDSI_DPI_VCID_OFFSET, pinfo->mipi.vc, 2, 0); set_reg(mipi_dsi_base + MIPIDSI_DPI_COLOR_CODING_OFFSET, pinfo->mipi.color_mode, 4, 0); set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.data_en_plr, 1, 0); set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.vsync_plr, 1, 1); set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, pinfo->ldi.hsync_plr, 1, 2); set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, 0x0, 1, 3); set_reg(mipi_dsi_base + MIPIDSI_DPI_CFG_POL_OFFSET, 0x0, 1, 4); if (pinfo->bpp == LCD_RGB666) { set_reg(mipi_dsi_base + MIPIDSI_DPI_COLOR_CODING_OFFSET, 0x1, 1, 8); } /* ** 3. Select the Video Transmission Mode: ** This defines how the processor requires the video line to be ** transported through the DSI link. */ /* video mode: low power mode */ set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, 0x3f, 6, 8); /* set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, 0x0, 1, 14); */ /* burst mode */ set_reg(mipi_dsi_base + MIPIDSI_VID_MODE_CFG_OFFSET, phy_ctrl.burst_mode, 2, 0); set_reg(mipi_dsi_base + MIPIDSI_VID_PKT_SIZE_OFFSET, pinfo->xres, 14, 0); /* for dsi read, BTA enable*/ set_reg(mipi_dsi_base + MIPIDSI_PCKHDL_CFG_OFFSET, 0x1, 1, 2); /* ** 4. Define the DPI Horizontal timing configuration: ** ** Hsa_time = HSA*(PCLK period/Clk Lane Byte Period); ** Hbp_time = HBP*(PCLK period/Clk Lane Byte Period); ** Hline_time = (HSA+HBP+HACT+HFP)*(PCLK period/Clk Lane Byte Period); */ pixel_clk = pinfo->pxl_clk_rate / 1000000; hsa_time = pinfo->ldi.h_pulse_width * phy_ctrl.lane_byte_clk / pixel_clk; hbp_time = pinfo->ldi.h_back_porch * phy_ctrl.lane_byte_clk / pixel_clk; hline_time = (pinfo->ldi.h_pulse_width + pinfo->ldi.h_back_porch + pinfo->xres + pinfo->ldi.h_front_porch) * phy_ctrl.lane_byte_clk / pixel_clk; set_reg(mipi_dsi_base + MIPIDSI_VID_HSA_TIME_OFFSET, hsa_time, 12, 0); set_reg(mipi_dsi_base + MIPIDSI_VID_HBP_TIME_OFFSET, hbp_time, 12, 0); set_reg(mipi_dsi_base + MIPIDSI_VID_HLINE_TIME_OFFSET, hline_time, 15, 0); /* ** 5. Define the Vertical line configuration: */ set_reg(mipi_dsi_base + MIPIDSI_VID_VSA_LINES_OFFSET, pinfo->ldi.v_pulse_width, 10, 0); set_reg(mipi_dsi_base + MIPIDSI_VID_VBP_LINES_OFFSET, pinfo->ldi.v_back_porch, 10, 0); set_reg(mipi_dsi_base + MIPIDSI_VID_VFP_LINES_OFFSET, pinfo->ldi.v_front_porch, 10, 0); set_reg(mipi_dsi_base + MIPIDSI_VID_VACTIVE_LINES_OFFSET, pinfo->yres, 14, 0); set_reg(mipi_dsi_base + MIPIDSI_TO_CNT_CFG_OFFSET, 0x7FF, 16, 0); /* Configure core's phy parameters */ set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, 4095, 15, 0); set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_LPCLK_CFG_OFFSET, phy_ctrl.clk_lane_lp2hs_time, 10, 0); set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_LPCLK_CFG_OFFSET, phy_ctrl.clk_lane_hs2lp_time, 10, 16); set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, phy_ctrl.data_lane_lp2hs_time, 8, 16); set_reg(mipi_dsi_base + MIPIDSI_PHY_TMR_CFG_OFFSET, phy_ctrl.data_lane_hs2lp_time, 8, 24); /*------------DSI and D-PHY Initialization-----------------*/ /* 1. Waking up Core */ set_reg(mipi_dsi_base + MIPIDSI_PWR_UP_OFFSET, 0x1, 1, 0); /* ** 3. Configure the TX_ESC clock frequency to a frequency lower than 20 MHz ** that is the maximum allowed frequency for D-PHY ESCAPE mode. */ set_reg(mipi_dsi_base + MIPIDSI_CLKMGR_CFG_OFFSET, phy_ctrl.clk_division, 8, 0); set_reg(mipi_dsi_base + MIPIDSI_CLKMGR_CFG_OFFSET, phy_ctrl.clk_division, 8, 8); /* ** 4. Configure the DPHY PLL clock frequency through the TEST Interface to ** operate at XX Hz, */ /* Write CP current */ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010011); 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, phy_ctrl.cp_current); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Write LPF Control */ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010012); 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, phy_ctrl.lpf_ctrl); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /*Configured N and M factors effective*/ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010019); 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, phy_ctrl.factors_effective); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Write N Pll */ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010017); 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, phy_ctrl.n_pll-1); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Write M Pll part 1 */ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018); 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, phy_ctrl.m_pll_1); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Write M Pll part 2 */ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018); 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, phy_ctrl.m_pll_2); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Set hsfreqrange */ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010044); 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, phy_ctrl.hsfreqrange); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Set PLL unlocking filter */ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010016); 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, phy_ctrl.pll_unlocking_filter); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); #if 0 /* Set the phy direction*/ outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x000100b0); 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, 0x00000001); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); #endif outp32(mipi_dsi_base + MIPIDSI_PHY_RSTZ_OFFSET, 0x0000000F); is_ready = false; dw_jiffies = jiffies + HZ / 2; do { tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET); if ((tmp & 0x00000001) == 0x00000001) { is_ready = true; break; } } while (time_after(dw_jiffies, jiffies)); if (!is_ready) { HISI_FB_INFO("fb%d, phylock is not ready!MIPIDSI_PHY_STATUS_OFFSET=0x%x.\n", hisifd->index, tmp); } is_ready = false; dw_jiffies = jiffies + HZ / 2; do { tmp = inp32(mipi_dsi_base + MIPIDSI_PHY_STATUS_OFFSET); if ((tmp & 0x00000004) == 0x00000004) { is_ready = true; break; } } while (time_after(dw_jiffies, jiffies)); if (!is_ready) { HISI_FB_INFO("fb%d, phystopstateclklane is not ready! MIPIDSI_PHY_STATUS_OFFSET=0x%x.\n", hisifd->index, tmp); } }
int mipi_dsi_bit_clk_upt_isr_handler(struct hisi_fb_data_type *hisifd) { char __iomem *mipi_dsi0_base = NULL; struct mipi_dsi_phy_ctrl phy_ctrl = {0}; struct hisi_panel_info *pinfo = NULL; uint32_t dsi_bit_clk_upt = 0; uint32_t hline_time = 0; uint32_t hsa_time = 0; uint32_t hbp_time = 0; uint32_t pixel_clk = 0; uint32_t tmp = 0; bool is_ready = false; int i = 0; BUG_ON(hisifd == NULL); pinfo = &(hisifd->panel_info); dsi_bit_clk_upt = pinfo->mipi.dsi_bit_clk_upt; mipi_dsi0_base = hisifd->mipi_dsi0_base; if (hisifd->index != PRIMARY_PANEL_IDX) { HISI_FB_ERR("fb%d, not support!", hisifd->index); return 0; } if (dsi_bit_clk_upt == pinfo->mipi.dsi_bit_clk) { return 0; } HISI_FB_DEBUG("fb%d +.\n", hisifd->index); /* get new phy_ctrl value according to dsi_bit_clk_next */ get_dsi_phy_ctrl(pinfo->mipi.dsi_bit_clk_upt, &phy_ctrl); /* ** Configure the DPHY PLL clock frequency through the TEST Interface to ** operate at XX Hz, */ /* Write M Pll part 1 */ outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.m_pll_1); /*wait until dphy data lane enter into stop state*/ for (i = 0; i < 40; i++) { tmp = inp32(mipi_dsi0_base + MIPIDSI_PHY_STATUS_OFFSET); if ((tmp & 0x00000a90) == 0x00000a90) { is_ready = true; break; } udelay(1); } if (!is_ready) { HISI_FB_ERR("fb%d, phystopstatedatalane is not ready! MIPIDSI_PHY_STATUS_OFFSET=0x%x.\n", hisifd->index, tmp); return 0; } outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); pinfo->mipi.dsi_bit_clk = dsi_bit_clk_upt; /* Write M Pll part 2 */ outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010018); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.m_pll_2); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Set hsfreqrange */ outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010044); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.hsfreqrange); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Write CP current */ outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010011); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.cp_current); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); /* Write LPF Control */ outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, 0x00010012); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL1_OFFSET, phy_ctrl.lpf_ctrl); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000002); outp32(mipi_dsi0_base + MIPIDSI_PHY_TST_CTRL0_OFFSET, 0x00000000); if (!is_mipi_cmd_panel(hisifd)) { /* ** Define the DPI Horizontal timing configuration: ** ** Hsa_time = HSA*(PCLK period/Clk Lane Byte Period); ** Hbp_time = HBP*(PCLK period/Clk Lane Byte Period); ** Hline_time = (HSA+HBP+HACT+HFP)*(PCLK period/Clk Lane Byte Period); */ pixel_clk = pinfo->pxl_clk_rate / 1000000; hsa_time = pinfo->ldi.h_pulse_width * phy_ctrl.lane_byte_clk / pixel_clk; hbp_time = pinfo->ldi.h_back_porch * phy_ctrl.lane_byte_clk / pixel_clk; hline_time = (pinfo->ldi.h_pulse_width + pinfo->ldi.h_back_porch + pinfo->xres + pinfo->ldi.h_front_porch) * phy_ctrl.lane_byte_clk / pixel_clk; outp32(mipi_dsi0_base + MIPIDSI_VID_HSA_TIME_OFFSET, hsa_time); outp32(mipi_dsi0_base + MIPIDSI_VID_HBP_TIME_OFFSET, hbp_time); outp32(mipi_dsi0_base + MIPIDSI_VID_HLINE_TIME_OFFSET, hline_time); } /* Configure core's phy parameters */ outp32(mipi_dsi0_base + MIPIDSI_PHY_TMR_LPCLK_CFG_OFFSET, (phy_ctrl.clk_lane_lp2hs_time + (phy_ctrl.clk_lane_hs2lp_time << 16))); outp32(mipi_dsi0_base + MIPIDSI_PHY_TMR_CFG_OFFSET, (4095 + (phy_ctrl.data_lane_lp2hs_time << 16) + (phy_ctrl.data_lane_hs2lp_time << 24))); /* ** Configure the TX_ESC clock frequency to a frequency lower than 20 MHz ** that is the maximum allowed frequency for D-PHY ESCAPE mode. */ outp32(mipi_dsi0_base + MIPIDSI_CLKMGR_CFG_OFFSET, (phy_ctrl.clk_division + (phy_ctrl.clk_division<<8))); HISI_FB_DEBUG("fb%d -.\n", hisifd->index); return 0; }