__s32 LCD_PWM_EN(__u32 sel, __bool b_en) { if (gdisp.screen[sel].lcd_cfg.lcd_pwm_used) { user_gpio_set_t gpio_info[1]; __hdle hdl; memcpy(gpio_info, &(gdisp.screen[sel].lcd_cfg.lcd_pwm), sizeof(user_gpio_set_t)); if (!sunxi_is_version_A() && (gpanel_info[sel].lcd_pwm_not_used == 0)) { if (b_en) pwm_enable(gpanel_info[sel].lcd_pwm_ch, b_en); else { gpio_info->mul_sel = 0; hdl = OSAL_GPIO_Request(gpio_info, 1); OSAL_GPIO_Release(hdl, 2); } } else { if (b_en != gpanel_info[sel].lcd_pwm_pol) { gpio_info->mul_sel = 1; gpio_info->data = 1; hdl = OSAL_GPIO_Request(gpio_info, 1); OSAL_GPIO_Release(hdl, 2); } else { gpio_info->mul_sel = 1; gpio_info->data = 0; hdl = OSAL_GPIO_Request(gpio_info, 1); OSAL_GPIO_Release(hdl, 2); } } } return 0; }
__s32 Disp_lcdc_init(__u32 sel) { irqreturn_t ret; LCD_get_sys_config(sel, &(gdisp.screen[sel].lcd_cfg)); lcdc_clk_init(sel); lvds_clk_init(); lcdc_clk_on(sel); /* ??need to be open */ LCDC_init(sel); lcdc_clk_off(sel); if (sel == 0) ret = request_irq(INTC_IRQNO_LCDC0, Disp_lcdc_event_proc, IRQF_DISABLED, "sunxi lcd0", (void *)sel); else ret = request_irq(INTC_IRQNO_LCDC1, Disp_lcdc_event_proc, IRQF_DISABLED, "sunxi lcd1", (void *)sel); if (gdisp.screen[sel].lcd_cfg.lcd_used) { if (lcd_panel_fun[sel].cfg_panel_info) lcd_panel_fun[sel].cfg_panel_info(&gpanel_info[sel]); else LCD_get_panel_para(sel, &gpanel_info[sel]); gpanel_info[sel].tcon_index = 0; if (!sunxi_is_version_A() && (gpanel_info[sel].lcd_pwm_not_used == 0)) { __pwm_info_t pwm_info; pwm_info.enable = 0; pwm_info.active_state = 1; pwm_info.period_ns = 1000000 / gpanel_info[sel].lcd_pwm_freq; if (gpanel_info[sel].lcd_pwm_pol == 0) pwm_info.duty_ns = (gdisp.screen[sel].lcd_cfg.init_bright * pwm_info.period_ns) / 256; else pwm_info.duty_ns = ((256 - gdisp.screen[sel].lcd_cfg.init_bright) * pwm_info.period_ns) / 256; pwm_set_para(gpanel_info[sel].lcd_pwm_ch, &pwm_info); } LCD_GPIO_init(sel); } return DIS_SUCCESS; }
/* * sun4i: 0-16 * sun5i: 0-256 */ __s32 BSP_disp_lcd_set_bright(__u32 sel, __u32 bright #ifdef CONFIG_ARCH_SUN5I , __u32 from_iep #endif ) { __u32 duty_ns; if (!sunxi_is_version_A() && (gpanel_info[sel].lcd_pwm_not_used == 0)) { #ifdef CONFIG_ARCH_SUN4I if (bright != 0) bright += 1; #endif #ifdef CONFIG_ARCH_SUN4I if (gpanel_info[sel].lcd_pwm_pol == 0) duty_ns = (bright * gdisp.pwm[gpanel_info[sel].lcd_pwm_ch].period_ns + 128) / 256; else duty_ns = ((256 - bright) * gdisp.pwm[gpanel_info[sel].lcd_pwm_ch].period_ns + 128) / 256; #else if (gpanel_info[sel].lcd_pwm_pol == 0) duty_ns = (bright * gdisp.screen[sel].lcd_bright_dimming * gdisp.pwm[gpanel_info[sel].lcd_pwm_ch].period_ns / 256 + 128) / 256; else duty_ns = ((256 - bright * gdisp.screen[sel].lcd_bright_dimming / 256) * gdisp.pwm[gpanel_info[sel].lcd_pwm_ch].period_ns + 128) / 256; #endif pwm_set_duty_ns(gpanel_info[sel].lcd_pwm_ch, duty_ns); } #ifdef CONFIG_ARCH_SUN5I if (!from_iep) #endif gdisp.screen[sel].lcd_bright = bright; return DIS_SUCCESS; }
/* * Calculate PLL frequence and divider depend on all kinds of lcd panel * * 1. support hv/cpu/ttl panels which pixel frequence between 2MHz~297MHz * 2. support all lvds panels, when pll can't reach (pixel clk x7), * set pll to 381MHz(pllx1), which will depress the frame rate. */ static __s32 LCD_PLL_Calc(__u32 sel, __panel_para_t *info, __u32 *divider) { __u32 lcd_dclk_freq; /* Hz */ __s32 pll_freq = -1; lcd_dclk_freq = info->lcd_dclk_freq * 1000000; /* hv panel, CPU panel and ttl panel */ if (info->lcd_if == 0 || info->lcd_if == 1 || info->lcd_if == 2) { /* MHz */ if (lcd_dclk_freq > 2000000 && lcd_dclk_freq <= 297000000) { /* divider for dclk in tcon0 */ *divider = 297000000 / (lcd_dclk_freq); pll_freq = lcd_dclk_freq * (*divider); } else { return -1; } } else if (info->lcd_if == 3) { /* lvds panel */ __u32 clk_max; if (!sunxi_is_version_A()) clk_max = 150000000; else /* * pixel clock can't be larger than 108MHz, * limited by Video pll frequency */ clk_max = 108000000; if (lcd_dclk_freq > clk_max) lcd_dclk_freq = clk_max; if (lcd_dclk_freq > 4000000) { /* pixel clk */ pll_freq = lcd_dclk_freq * 7; *divider = 7; } else return -1; } return pll_freq; }
static __s32 disp_pll_assign(__u32 sel, __u32 pll_clk) { __u32 another_lcdc, another_pll_use_status; __s32 ret = -1; another_lcdc = (sel == 0) ? 1 : 0; another_pll_use_status = gdisp.screen[another_lcdc].pll_use_status; if (pll_clk >= 250000000 && pll_clk <= 300000000) { if ((!(another_pll_use_status & VIDEO_PLL1_USED)) || (OSAL_CCMU_GetSrcFreq(AW_SYS_CLK_PLL7) == pll_clk)) ret = 1; else if ((!(another_pll_use_status & VIDEO_PLL0_USED)) || (OSAL_CCMU_GetSrcFreq(AW_SYS_CLK_PLL3) == pll_clk)) ret = 0; } else if (pll_clk <= (381000000 * 2)) { if ((!(another_pll_use_status & VIDEO_PLL0_USED)) || (OSAL_CCMU_GetSrcFreq(AW_SYS_CLK_PLL3) == pll_clk)) ret = 0; else if ((!(another_pll_use_status & VIDEO_PLL1_USED)) || (OSAL_CCMU_GetSrcFreq(AW_SYS_CLK_PLL7) == pll_clk)) ret = 1; } else if (pll_clk <= 1200000000) { if (!sunxi_is_version_A()) ret = 2; /* sata pll */ } if (ret == -1) DE_WRN("Can't assign PLL for screen%d, pll_clk:%d\n", sel, pll_clk); DE_INF("====disp_pll_assign====: sel:%d,pll_clk:%d,pll_sel:%d\n", sel, pll_clk, ret); return ret; }