static int hisi_offlinecompser_panel_off(struct platform_device *pdev) { int ret = 0; struct hisi_fb_data_type *hisifd = NULL; int i = 0; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); HISI_FB_DEBUG("index=%d, enter!\n", hisifd->index); for (i = 0; i < HISI_DSS_OFFLINE_MAX_NUM; i++) { char __iomem *ctl_base = hisifd->dss_base + DSS_GLB_WBE1_CH0_CTL + i * (DSS_GLB_WBE1_CH1_CTL - DSS_GLB_WBE1_CH0_CTL); cmdlist_config_stop(hisifd, i); hisifd->offline_wb_status[i] = e_status_idle; set_reg(ctl_base, 0x1, 1, 8); set_reg(ctl_base, 0x0, 1, 8); } HISI_FB_DEBUG("index=%d, exit!\n", hisifd->index); return ret; }
static int hisi_offlinecompser_panel_remove(struct platform_device *pdev) { int ret = 0; int i = 0; struct hisi_fb_data_type *hisifd = NULL; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); /*BUG_ON(hisifd == NULL);*/ if (!hisifd) { return 0; } HISI_FB_DEBUG("index=%d, enter!\n", hisifd->index); for (i = 0; i < HISI_DSS_OFFLINE_MAX_BLOCK; i++) { kfree(hisifd->block_rects[i]); hisifd->block_rects[i] = NULL; } if (hisifd->block_overlay) { kfree(hisifd->block_overlay); hisifd->block_overlay = NULL; } for(i = 0; i < HISI_DSS_OFFLINE_MAX_LIST; i++){ cmdlist_free_one_list(hisifd->cmdlist_node[i], hisifd->ion_client); } HISI_FB_DEBUG("index=%d, exit!\n", hisifd->index); return ret; }
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 rgb2mipi_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); hisifd->panel_info.lcd_init_step = LCD_INIT_POWER_ON; ret = panel_next_on(pdev); /* rgb2mipi bridge init */ ret = rgb2mipi_init(hisifd); /* LCDD (Peripheral) Setting */ ret = panel_next_on(pdev); /* rgb2mipi bridge prepare for receiving */ ret = rgb2mipi_prep4Rec(hisifd); ret = panel_next_on(pdev); msleep(50); HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return ret; }
static void hisifb_vsync_ctrl_workqueue_handler(struct work_struct *work) { struct hisi_fb_data_type *hisifd = NULL; struct hisifb_vsync *vsync_ctrl = NULL; struct hisi_fb_panel_data *pdata = NULL; unsigned long flags = 0; vsync_ctrl = container_of(work, typeof(*vsync_ctrl), vsync_ctrl_work); BUG_ON(vsync_ctrl == NULL); hisifd = vsync_ctrl->hisifd; BUG_ON(hisifd == NULL); pdata = dev_get_platdata(&hisifd->pdev->dev); BUG_ON(pdata == NULL); down(&(hisifd->blank_sem)); if (!hisifd->panel_power_on) { HISI_FB_DEBUG("fb%d, panel is power off!", hisifd->index); up(&(hisifd->blank_sem)); return; } mutex_lock(&(vsync_ctrl->vsync_lock)); if (vsync_ctrl->vsync_ctrl_disabled_set && (vsync_ctrl->vsync_ctrl_expire_count == 0) && vsync_ctrl->vsync_ctrl_enabled && !vsync_ctrl->vsync_enabled) { HISI_FB_DEBUG("fb%d, dss clk off!\n", hisifd->index); spin_lock_irqsave(&(vsync_ctrl->spin_lock), flags); if (pdata->vsync_ctrl) { pdata->vsync_ctrl(hisifd->pdev, 0); } else { HISI_FB_ERR("fb%d, vsync_ctrl not supported!\n", hisifd->index); } vsync_ctrl->vsync_ctrl_enabled = 0; vsync_ctrl->vsync_ctrl_disabled_set = 0; spin_unlock_irqrestore(&(vsync_ctrl->spin_lock), flags); if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_MIPI_ULPS) { mipi_dsi_ulps_cfg(hisifd, 0); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF) { dpe_clk_disable(hisifd); mipi_dsi_clk_disable(hisifd); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_VCC_OFF) { dpe_regulator_disable(hisifd); } } mutex_unlock(&(vsync_ctrl->vsync_lock)); if (vsync_ctrl->vsync_report_fnc) { vsync_ctrl->vsync_report_fnc(1); } up(&(hisifd->blank_sem)); }
static int mipi_dsi_remove(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_remove(pdev); if (hisifd->dss_dphy0_clk) { clk_put(hisifd->dss_dphy0_clk); hisifd->dss_dphy0_clk = NULL; } if (hisifd->dss_dphy1_clk) { clk_put(hisifd->dss_dphy1_clk); hisifd->dss_dphy1_clk = NULL; } HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return ret; }
static int hisi_pwm_probe(struct platform_device *pdev) { struct device_node *np = NULL; int ret = 0; HISI_FB_DEBUG("+.\n"); BUG_ON(pdev == NULL); np = of_find_compatible_node(NULL, NULL, DTS_COMP_PWM_NAME); if (!np) { HISI_FB_ERR("NOT FOUND device node %s!\n", DTS_COMP_PWM_NAME); ret = -ENXIO; goto err_return; } /* get pwm reg base */ hisifd_pwm_base = of_iomap(np, 0); #if !defined(CONFIG_ARCH_HI3630FPGA) && !defined(CONFIG_HISI_3635_FPGA) \ && !defined(CONFIG_HISI_3650_FPGA) /* pwm pinctrl init */ ret = pinctrl_cmds_tx(pdev, pwm_pinctrl_init_cmds, ARRAY_SIZE(pwm_pinctrl_init_cmds)); if (ret != 0) { HISI_FB_ERR("Init pwm pinctrl failed! ret=%d.\n", ret); goto err_return; } /* get blpwm clk resource */ g_dss_pwm_clk = of_clk_get(np, 0); if (IS_ERR(g_dss_pwm_clk)) { HISI_FB_ERR("%s clock not found: %d!\n", np->name, (int)PTR_ERR(g_dss_pwm_clk)); ret = -ENXIO; goto err_return; } ret = clk_set_rate(g_dss_pwm_clk, DEFAULT_PWM_CLK_RATE); if (ret != 0) { HISI_FB_ERR("dss_pwm_clk clk_set_rate(%lu) failed, error=%d!\n", DEFAULT_PWM_CLK_RATE, ret); ret = -EINVAL; goto err_return; } HISI_FB_INFO("dss_pwm_clk:[%lu]->[%lu].\n", DEFAULT_PWM_CLK_RATE, clk_get_rate(g_dss_pwm_clk)); #endif hisi_fb_device_set_status0(DTS_PWM_READY); HISI_FB_DEBUG("-.\n"); return 0; err_return: return ret; }
static int mipi_dsi_frc_handle(struct platform_device *pdev, int fps) { int ret = 0; #if 0 struct hisi_fb_data_type *hisifd = NULL; struct hisi_panel_info *pinfo = NULL; uint32_t hline_time = 0; uint32_t pixel_clk = 0; uint32_t vertical_timing = 0; uint32_t horizontal_timing = 0; uint32_t h_front_porch = 0; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); if (hisifd->index != PRIMARY_PANEL_IDX) { HISI_FB_ERR("fb%d, not support!", hisifd->index); return 0; } HISI_FB_DEBUG("fb%d, +.\n", hisifd->index); pinfo = &(hisifd->panel_info); /* calculate new HFP based on target_fps */ vertical_timing = pinfo->yres + pinfo->ldi.v_back_porch + pinfo->ldi.v_front_porch + pinfo->ldi.v_pulse_width; horizontal_timing = pinfo->pxl_clk_rate / (vertical_timing * fps); /* new HFP*/ /* pinfo->ldi.h_front_porch = horizontal_timing - pinfo->xres -pinfo->ldi.h_back_porch - pinfo->ldi.h_pulse_width; */ h_front_porch = horizontal_timing - pinfo->xres -pinfo->ldi.h_back_porch - pinfo->ldi.h_pulse_width; pixel_clk = pinfo->pxl_clk_rate / 1000000; /* update hline_time */ hline_time = (pinfo->ldi.h_pulse_width + pinfo->ldi.h_back_porch + pinfo->xres + h_front_porch) * (pinfo->mipi.dsi_bit_clk / 4) / pixel_clk; /* reset dsi core */ set_reg(hisifd->mipi_dsi0_base + MIPIDSI_PWR_UP_OFFSET, 0x0, 1, 0); set_reg(hisifd->mipi_dsi0_base + MIPIDSI_VID_HLINE_TIME_OFFSET, hline_time, 15, 0); outp32(hisifd->dss_base + PDP_LDI_DPI0_HRZ_CTRL0, h_front_porch | (pinfo->ldi.h_back_porch << 16)); /* power on dsi core */ set_reg(hisifd->mipi_dsi0_base + MIPIDSI_PWR_UP_OFFSET, 0x1, 1, 0); HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); #endif return ret; }
static int hisi_spi_remove(struct spi_device *spi_dev) { HISI_FB_DEBUG("+.\n"); /*spi_unregister_driver(&spi_driver);*/ HISI_FB_DEBUG("-.\n"); return 0; }
static int hisi_spi_probe (struct spi_device *spi_dev) { HISI_FB_DEBUG("+.\n"); g_spi_dev = spi_dev; spi_dev->bits_per_word = 8; spi_dev->mode = SPI_MODE_3; spi_setup(spi_dev); hisi_fb_device_set_status0(DTS_SPI_READY); HISI_FB_DEBUG("-.\n"); return 0; }
static int rgb2mipi_esd_handle(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_esd_handle(pdev); HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return ret; }
static int rgb2mipi_vsync_ctrl(struct platform_device *pdev, int enable) { 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_vsync_ctrl(pdev, enable); HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return ret; }
static int mipi_dsi_set_display_region(struct platform_device *pdev, struct dss_rect *dirty) { int ret = 0; struct hisi_fb_data_type *hisifd = NULL; BUG_ON(pdev == NULL || dirty == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); HISI_FB_DEBUG("index=%d, enter!\n", hisifd->index); ret = panel_next_set_display_region(pdev, dirty); HISI_FB_DEBUG("index=%d, exit!\n", hisifd->index); return ret; }
int hisifb_vsync_ctrl(struct fb_info *info, void __user *argp) { int ret = 0; struct hisi_fb_data_type *hisifd = NULL; struct hisi_fb_panel_data *pdata = NULL; struct hisifb_vsync *vsync_ctrl = NULL; int enable = 0; BUG_ON(info == NULL); hisifd = (struct hisi_fb_data_type *)info->par; BUG_ON(hisifd == NULL); pdata = dev_get_platdata(&hisifd->pdev->dev); BUG_ON(pdata == NULL); vsync_ctrl = &(hisifd->vsync_ctrl); BUG_ON(vsync_ctrl == NULL); ret = copy_from_user(&enable, argp, sizeof(enable)); if (ret) { HISI_FB_ERR("hisifb_vsync_ctrl ioctl failed!\n"); return ret; } enable = (enable) ? 1 : 0; mutex_lock(&(vsync_ctrl->vsync_lock)); if (vsync_ctrl->vsync_enabled == enable) { mutex_unlock(&(vsync_ctrl->vsync_lock)); return 0; } if (g_debug_online_vsync) HISI_FB_INFO("fb%d, enable=%d!\n", hisifd->index, enable); vsync_ctrl->vsync_enabled = enable; mutex_unlock(&(vsync_ctrl->vsync_lock)); down(&hisifd->blank_sem); if (!hisifd->panel_power_on) { HISI_FB_DEBUG("fb%d, panel is power off!", hisifd->index); up(&hisifd->blank_sem); return 0; } if (enable) { hisifb_activate_vsync(hisifd); } else { hisifb_deactivate_vsync(hisifd); } up(&hisifd->blank_sem); return 0; }
void hisifb_activate_vsync(struct hisi_fb_data_type *hisifd) { struct hisi_fb_panel_data *pdata = NULL; struct hisifb_vsync *vsync_ctrl = NULL; unsigned long flags = 0; int clk_enabled = 0; BUG_ON(hisifd == NULL); pdata = dev_get_platdata(&hisifd->pdev->dev); BUG_ON(pdata == NULL); vsync_ctrl = &(hisifd->vsync_ctrl); BUG_ON(vsync_ctrl == NULL); if (hisifd->panel_info.vsync_ctrl_type == VSYNC_CTRL_NONE) return; mutex_lock(&(vsync_ctrl->vsync_lock)); if (vsync_ctrl->vsync_ctrl_enabled == 0) { HISI_FB_DEBUG("fb%d, dss clk on!\n", hisifd->index); if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_VCC_OFF) { dpe_regulator_enable(hisifd); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF) { mipi_dsi_clk_enable(hisifd); dpe_clk_enable(hisifd); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_MIPI_ULPS) { mipi_dsi_ulps_cfg(hisifd, 1); } vsync_ctrl->vsync_ctrl_enabled = 1; clk_enabled = 1; } spin_lock_irqsave(&(vsync_ctrl->spin_lock), flags); vsync_ctrl->vsync_ctrl_disabled_set = 0; vsync_ctrl->vsync_ctrl_expire_count = 0; if (clk_enabled) { if (pdata->vsync_ctrl) { pdata->vsync_ctrl(hisifd->pdev, 1); } else { HISI_FB_ERR("fb%d, vsync_ctrl not supported!\n", hisifd->index); } } spin_unlock_irqrestore(&(vsync_ctrl->spin_lock), flags); mutex_unlock(&(vsync_ctrl->vsync_lock)); }
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; }
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; }
static ssize_t mipi_dsi_bit_clk_upt_store(struct platform_device *pdev, const char *buf, size_t count) { struct hisi_fb_data_type *hisifd = NULL; struct hisi_panel_info *pinfo = NULL; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); pinfo = &(hisifd->panel_info); if (!hisifd->panel_info.dsi_bit_clk_upt_support) { HISI_FB_ERR("fb%d, not support!", hisifd->index); return count; } HISI_FB_DEBUG("fb%d, +.\n", hisifd->index); if (!strncmp(buf, MIPI_DSI_BIT_CLK_STR1, count)) { pinfo->mipi.dsi_bit_clk_upt = pinfo->mipi.dsi_bit_clk_val1; } else if (!strncmp(buf, MIPI_DSI_BIT_CLK_STR2, count)) { pinfo->mipi.dsi_bit_clk_upt = pinfo->mipi.dsi_bit_clk_val2; } else if (!strncmp(buf, MIPI_DSI_BIT_CLK_STR3, count)) { pinfo->mipi.dsi_bit_clk_upt = pinfo->mipi.dsi_bit_clk_val3; } else if (!strncmp(buf, MIPI_DSI_BIT_CLK_STR4, count)) { pinfo->mipi.dsi_bit_clk_upt = pinfo->mipi.dsi_bit_clk_val4; } else if (!strncmp(buf, MIPI_DSI_BIT_CLK_STR5, count)) { pinfo->mipi.dsi_bit_clk_upt = pinfo->mipi.dsi_bit_clk_val5; } else { HISI_FB_ERR("fb%d, unknown dsi_bit_clk_index!\n", hisifd->index); } HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return count; }
static int rgb2mipi_probe(struct platform_device *pdev) { struct hisi_fb_data_type *hisifd = NULL; struct platform_device *dpe_dev = NULL; struct hisi_fb_panel_data *pdata = NULL; int ret = 0; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); BUG_ON(hisifd->panel_info.spi_dev == NULL); HISI_FB_DEBUG("fb%d, +.\n", hisifd->index); /* alloc device */ dpe_dev = platform_device_alloc(DEV_NAME_DSS_DPE, pdev->id); if (!dpe_dev) { HISI_FB_ERR("fb%d platform_device_alloc failed, error=%d!\n", hisifd->index, ret); ret = -ENOMEM; goto err_device_alloc; } /* link to the latest pdev */ hisifd->pdev = dpe_dev; /* alloc panel device data */ ret = platform_device_add_data(dpe_dev, dev_get_platdata(&pdev->dev), sizeof(struct hisi_fb_panel_data)); if (ret) { HISI_FB_ERR("fb%d platform_device_add_data failed error=%d!\n", hisifd->index, ret); goto err_device_put; } /* data chain */ pdata = dev_get_platdata(&dpe_dev->dev); pdata->set_fastboot = rgb2mipi_set_fastboot; pdata->on = rgb2mipi_on; pdata->off = rgb2mipi_off; pdata->remove = rgb2mipi_remove; pdata->set_backlight = rgb2mipi_set_backlight; pdata->vsync_ctrl = rgb2mipi_vsync_ctrl; pdata->frc_handle = rgb2mipi_frc_handle; pdata->esd_handle = rgb2mipi_esd_handle; pdata->next = pdev; /* get/set panel info */ memcpy(&hisifd->panel_info, pdata->panel_info, sizeof(struct hisi_panel_info)); /* set driver data */ platform_set_drvdata(dpe_dev, hisifd); /* device add */ ret = platform_device_add(dpe_dev); if (ret) { HISI_FB_ERR("fb%d platform_device_add failed, error=%d!\n", hisifd->index, ret); goto err_device_put; } HISI_FB_DEBUG("fb%d, -.\n", hisifd->index); return 0; err_device_put: platform_device_put(dpe_dev); err_device_alloc: return ret; }
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; }
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; }
uint32_t hisi_dss_mif_get_invalid_sel(dss_img_t *img, uint32_t transform, int v_scaling_factor, uint8_t is_tile, bool rdma_stretch_enable) { uint32_t invalid_sel_val = 0; uint32_t tlb_tag_org = 0; if (img == NULL) { HISI_FB_ERR("img is null"); return 0; } if ((transform == (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_H)) || (transform == (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_V))) { transform = HISI_FB_TRANSFORM_ROT_90; } if (isYUVSemiPlanar(img->format) || isYUVPlanar(img->format)) { if (v_scaling_factor > (2048 / (img->stride/16) - 4)) { HISI_FB_DEBUG(" v_scaling_factor out of limit !!!! \n"); return 0; } } tlb_tag_org = (transform & 0x7) | ((is_tile ? 1 : 0) << 3) | ((rdma_stretch_enable ? 1 : 0) << 4); switch (tlb_tag_org) { case MMU_TLB_TAG_ORG_0x0: invalid_sel_val = 1; break; case MMU_TLB_TAG_ORG_0x1: invalid_sel_val = 1; break; case MMU_TLB_TAG_ORG_0x2: invalid_sel_val = 2; break; case MMU_TLB_TAG_ORG_0x3: invalid_sel_val = 2; break; case MMU_TLB_TAG_ORG_0x4: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x7: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x8: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x9: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0xA: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0xB: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0xC: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0xF: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x10: invalid_sel_val = 1; break; case MMU_TLB_TAG_ORG_0x11: invalid_sel_val = 1; break; case MMU_TLB_TAG_ORG_0x12: invalid_sel_val = 2; break; case MMU_TLB_TAG_ORG_0x13: invalid_sel_val = 2; break; case MMU_TLB_TAG_ORG_0x14: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x17: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x18: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x19: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x1A: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x1B: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x1C: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x1F: invalid_sel_val = 0; break; default: invalid_sel_val = 0; HISI_FB_ERR("not support this tlb_tag_org(0x%x)!\n", tlb_tag_org); break; } return invalid_sel_val; }
static int lcdc_fake_panel_probe(struct platform_device *pdev) { int ret = 0; struct hisi_panel_info *pinfo = NULL; struct device_node *np = NULL; if (hisi_fb_device_probe_defer(PANEL_NO)) { goto err_probe_defer; } HISI_FB_DEBUG("+.\n"); np = of_find_compatible_node(NULL, NULL, DTS_COMP_LCDC_FAKE_PANEL); if (!np) { HISI_FB_ERR("NOT FOUND device node %s!\n", DTS_COMP_LCDC_FAKE_PANEL); goto err_return; } pdev->id = 1; /* init lcd info */ pinfo = fake_panel_data.panel_info; memset(pinfo, 0, sizeof(struct hisi_panel_info)); pinfo->xres = 1080; pinfo->yres = 1920; pinfo->width = 61; pinfo->height = 109; pinfo->type = PANEL_NO; pinfo->orientation = LCD_PORTRAIT; pinfo->bpp = LCD_RGB888; pinfo->bgr_fmt = LCD_RGB; pinfo->bl_min = 1; pinfo->bl_max = 255; pinfo->bl_set_type = BL_SET_BY_PWM; pinfo->ifbc_type = IFBC_TYPE_NON; pinfo->vsync_ctrl_type = 0; pinfo->frc_enable = 0; pinfo->esd_enable = 0; pinfo->dirty_region_updt_support = 0; pinfo->sbl_support = 0; pinfo->smart_bl.strength_limit = 128; pinfo->smart_bl.calibration_a = 60; pinfo->smart_bl.calibration_b = 95; pinfo->smart_bl.calibration_c = 5; pinfo->smart_bl.calibration_d = 1; pinfo->smart_bl.t_filter_control = 5; pinfo->smart_bl.backlight_min = 480; pinfo->smart_bl.backlight_max = 4096; pinfo->smart_bl.backlight_scale = 0xff; pinfo->smart_bl.ambient_light_min = 14; pinfo->smart_bl.filter_a = 1738; pinfo->smart_bl.filter_b = 6; pinfo->smart_bl.logo_left = 0; pinfo->smart_bl.logo_top = 0; pinfo->ldi.h_back_porch = 11; pinfo->ldi.h_front_porch = 4; pinfo->ldi.h_pulse_width = 4; pinfo->ldi.v_back_porch = 10; pinfo->ldi.v_front_porch = 4; pinfo->ldi.v_pulse_width = 4; pinfo->mipi.lane_nums = DSI_4_LANES; pinfo->mipi.color_mode = DSI_24BITS_1; pinfo->mipi.vc = 0; pinfo->mipi.dsi_bit_clk = 480; pinfo->pxl_clk_rate = 150*1000000; /* alloc panel device data */ ret = platform_device_add_data(pdev, &fake_panel_data, sizeof(struct hisi_fb_panel_data)); if (ret) { HISI_FB_ERR("platform_device_add_data failed!\n"); goto err_device_put; } hisi_fb_add_device(pdev); HISI_FB_DEBUG("-.\n"); return 0; err_device_put: platform_device_put(pdev); err_return: return ret; err_probe_defer: return -EPROBE_DEFER; }
static int hisi_offlinecompser_probe(struct platform_device *pdev) { int ret = 0; struct hisi_panel_info *pinfo = NULL; struct hisi_fb_data_type *hisifd = NULL; struct platform_device *reg_dev = NULL; int i = 0; if (hisi_fb_device_probe_defer(PANEL_OFFLINECOMPOSER)) { goto err_probe_defer; } HISI_FB_DEBUG("+.\n"); BUG_ON(pdev == NULL); pdev->id = 1; pinfo = hisi_offlinecomposer_panel_data.panel_info; memset(pinfo, 0, sizeof(struct hisi_panel_info)); pinfo->xres = g_primary_lcd_xres; pinfo->yres = g_primary_lcd_yres; pinfo->type = PANEL_OFFLINECOMPOSER; /* alloc panel device data */ ret = platform_device_add_data(pdev, &hisi_offlinecomposer_panel_data, sizeof(struct hisi_fb_panel_data)); if (ret) { HISI_FB_ERR("platform_device_add_data failed!\n"); goto err_device_put; } reg_dev = hisi_fb_add_device(pdev); if (!reg_dev) { HISI_FB_ERR("hisi_fb_add_device failed!\n"); goto err_device_put; } hisifd = platform_get_drvdata(reg_dev); BUG_ON(hisifd == NULL); for (i = 0; i < HISI_DSS_OFFLINE_MAX_NUM; i++) { INIT_LIST_HEAD(&hisifd->offline_cmdlist_head[i]); hisifd->offline_wb_status[i] = e_status_idle; init_waitqueue_head(&hisifd->offline_writeback_wq[i]); } for (i = 0; i < HISI_DSS_OFFLINE_MAX_BLOCK; i++) { hisifd->block_rects[i] = (dss_rect_t *)kmalloc(sizeof(dss_rect_t), GFP_ATOMIC); if (!hisifd->block_rects[i]) { HISI_FB_ERR("block_rects[%d] failed to alloc!", i); goto err_device_put; } } hisifd->block_overlay = (dss_overlay_t *)kmalloc(sizeof(dss_overlay_t), GFP_ATOMIC); if (!hisifd->block_overlay) { HISI_FB_ERR("hisifd->block_overlay no mem.\n"); goto err_device_put; } memset(hisifd->block_overlay, 0, sizeof(dss_overlay_t)); for(i = 0; i < HISI_DSS_OFFLINE_MAX_LIST; i++){ ret = cmdlist_alloc_one_list(&hisifd->cmdlist_node[i], hisifd->ion_client); if(ret < 0){ HISI_FB_ERR("cmdlist_alloc_one_list no mem.\n"); goto err_device_put; } } hisi_dss_offline_module_default(hisifd); hisifd->dss_module_resource_initialized = true; HISI_FB_DEBUG("-.\n"); return 0; err_device_put: platform_device_put(pdev); return ret; err_probe_defer: return -EPROBE_DEFER; }