static void lcdc_request_vsync(struct msm_panel_data *fb_panel, struct msmfb_callback *vsync_cb) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); /* the vsync callback will start the dma */ vsync_cb->func(vsync_cb); // CotullaFIX start // F**K, who make calls from console with disabled interrupts, F**K THEM! if (irqs_disabled()) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); uint32_t status; uint32_t i; // do it via polling for (i = 0; i < 20; i++) { status = mdp_readl(lcdc->mdp, MDP_INTR_STATUS); if (status & MDP_LCDC_FRAME_START) break; mdelay(1); } // clear intr at the end mdp_writel(lcdc->mdp, MDP_LCDC_FRAME_START, MDP_INTR_CLEAR); // vsync_cb->func(vsync_cb); } else { lcdc->got_vsync = 0; mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, MDP_LCDC_FRAME_START, &lcdc->frame_start_cb); lcdc_wait_vsync(fb_panel); } // CotullaFIX end }
static int lcdc_blank(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); //struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; #if 0 mutex_lock(&lcdc->blank_lock); if (atomic_read(&lcdc->blank_count) == 0) goto blank_done; if (atomic_dec_return(&lcdc->blank_count) == 0) { HDMI_DBG("%s: disable clocks\n", __func__); panel_ops->blank(panel_ops); mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); clk_disable(lcdc->pclk); clk_disable(lcdc->pad_pclk); clk_disable(lcdc->mdp_clk); } blank_done: mutex_unlock(&lcdc->blank_lock); HDMI_DBG("%s, blank_count=%d\n", __func__, atomic_read(&lcdc->blank_count)); #else lcdc_disable_video(); #endif return 0; }
static int lcdc_unblank(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; HDMI_DBG("%s\n", __func__); #if 0 HDMI_DBG("%s: enable clocks\n", __func__); clk_enable(lcdc->mdp_clk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); panel_ops->unblank(panel_ops); mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); atomic_set(&lcdc->blank_count, 1); #else lcdc_enable_video(); /* TODO: need pre-test to see if it make any influence to HDCP, * if ebi1_clk enabled here. */ panel_ops->unblank(panel_ops); #endif return 0; }
static int lcdc_resume(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; PR_DISP_INFO("%s: resuming\n", __func__); if (panel_ops->init) { if (panel_ops->init(panel_ops) < 0) PR_DISP_ERR("LCD init fail!\n"); } clk_enable(lcdc->mdp_clk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); #if defined(CONFIG_ARCH_MSM7227) writel(0x1, LCDC_MUX_CTL); D("resume_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL)); #endif mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); #ifdef CONFIG_PANEL_SELF_REFRESH if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) { mutex_lock(&panel_icm->icm_lock); panel_icm->icm_doable = true; panel_icm->clock_enabled = true; panel_icm->icm_suspend = false; mutex_unlock(&panel_icm->icm_lock); } #endif return 0; }
static int lcdc_suspend(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: suspending\n", __func__); #if defined(CONFIG_ARCH_MSM7227) writel(0x0, LCDC_MUX_CTL); D("suspend_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL)); #endif #ifdef CONFIG_PANEL_SELF_REFRESH if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) { mutex_lock(&panel_icm->icm_lock); panel_icm->icm_doable = false; pr_info("[ICM %s]: icm mode=%d\n", __func__, panel_icm->icm_mode); if (panel_icm->icm_mode == false) { #endif mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); clk_disable(lcdc->pad_pclk); clk_disable(lcdc->pclk); clk_disable(lcdc->mdp_clk); #ifdef CONFIG_PANEL_SELF_REFRESH } mutex_unlock(&panel_icm->icm_lock); } #endif if (panel_ops->uninit) panel_ops->uninit(panel_ops); return 0; }
static int lcdc_resume(struct msm_panel_data *fb_panel) { // unsigned int status; struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: resuming\n", __func__); if (panel_ops->init) { if (panel_ops->init(panel_ops) < 0) printk(KERN_ERR "LCD init fail!\n"); } clk_enable(lcdc->mdp_clk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); #if defined(CONFIG_ARCH_MSM7227) writel(0x1, LCDC_MUX_CTL); status = readl(LCDC_MUX_CTL); D("resume_lcdc_mux_ctl = %x\n",status); #endif mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); return 0; }
static int lcdc_suspend(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); pr_info("%s: suspending\n", __func__); mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); <<<<<<< HEAD
static void lcdc_wait_vsync(struct msm_panel_data *panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(panel); int ret; ret = wait_event_timeout(lcdc->vsync_waitq, lcdc->got_vsync, HZ / 2); if (!ret && !lcdc->got_vsync) pr_err("%s: timeout waiting for VSYNC\n", __func__); lcdc->got_vsync = 0; }
static int lcdc_blank(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: ()\n", __func__); panel_ops->blank(panel_ops); return 0; }
static void lcdc_request_vsync(struct msm_panel_data *fb_panel, struct msmfb_callback *vsync_cb) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); /* the vsync callback will start the dma */ vsync_cb->func(vsync_cb); lcdc->got_vsync = 0; mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, MDP_LCDC_FRAME_START, &lcdc->frame_start_cb); lcdc_wait_vsync(fb_panel); }
static int lcdc_shutdown(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: ()\n", __func__); if (panel_ops->shutdown) panel_ops->shutdown(panel_ops); return 0; }
static int lcdc_unblank(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; PR_DISP_INFO("%s: ()\n", __func__); if (panel_ops->unblank) panel_ops->unblank(panel_ops); return 0; }
static int lcdc_suspend(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); pr_info("%s: suspending\n", __func__); mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); clk_disable_unprepare(lcdc->pad_pclk); clk_disable_unprepare(lcdc->pclk); clk_disable_unprepare(lcdc->mdp_clk); return 0; }
static int lcdc_resume(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); pr_info("%s: resuming\n", __func__); clk_prepare_enable(lcdc->mdp_clk); clk_prepare_enable(lcdc->pclk); clk_prepare_enable(lcdc->pad_pclk); mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); return 0; }
static int lcdc_suspend(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; //pr_info("%s: suspending\n", __func__); HDMI_DBG("%s\n", __func__); if (panel_ops->uninit) panel_ops->uninit(panel_ops); lcdc_disable_video(); return 0; }
static int lcdc_resume(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; //pr_info("%s: resuming\n", __func__); HDMI_DBG("%s\n", __func__); if (panel_ops->init) { if (panel_ops->init(panel_ops) < 0) printk(KERN_ERR "LCD init fail!\n"); } return 0; }
static int lcdc_suspend(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: suspending\n", __func__); #if defined(CONFIG_ARCH_MSM7227) writel(0x0, LCDC_MUX_CTL); D("suspend_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL)); #endif mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); clk_disable(lcdc->pad_pclk); clk_disable(lcdc->pclk); clk_disable(lcdc->mdp_clk); if (panel_ops->uninit) panel_ops->uninit(panel_ops); return 0; }
static void lcdc_clear_vsync(struct msm_panel_data *fb_panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); lcdc->got_vsync = 0; mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, 0, NULL); }
static int lcdc_adjust_timing(struct msm_panel_data *fb_panel, struct msm_lcdc_timing *timing, u32 xres, u32 yres) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); unsigned int hsync_period; unsigned int hsync_start_x; unsigned int hsync_end_x; unsigned int vsync_period; unsigned int display_vstart; unsigned int display_vend; uint32_t dma_cfg; clk_set_rate(lcdc->pclk, timing->clk_rate); clk_set_rate(lcdc->pad_pclk, timing->clk_rate); HDMI_DBG("%s, clk=%d, xres=%d, yres=%d,\n", __func__, clk_get_rate(lcdc->pclk), xres, yres); hsync_period = (timing->hsync_pulse_width + timing->hsync_back_porch + xres + timing->hsync_front_porch); hsync_start_x = (timing->hsync_pulse_width + timing->hsync_back_porch); hsync_end_x = hsync_period - timing->hsync_front_porch - 1; vsync_period = (timing->vsync_pulse_width + timing->vsync_back_porch + yres + timing->vsync_front_porch); vsync_period *= hsync_period; display_vstart = timing->vsync_pulse_width + timing->vsync_back_porch; display_vstart *= hsync_period; display_vstart += timing->hsync_skew; display_vend = timing->vsync_front_porch * hsync_period; display_vend = vsync_period - display_vend + timing->hsync_skew - 1; /* register values we pre-compute at init time from the timing * information in the panel info */ lcdc->parms.hsync_ctl = (((hsync_period & 0xfff) << 16) | (timing->hsync_pulse_width & 0xfff)); lcdc->parms.vsync_period = vsync_period & 0xffffff; lcdc->parms.vsync_pulse_width = (timing->vsync_pulse_width * hsync_period) & 0xffffff; lcdc->parms.display_hctl = (((hsync_end_x & 0xfff) << 16) | (hsync_start_x & 0xfff)); lcdc->parms.display_vstart = display_vstart & 0xffffff; lcdc->parms.display_vend = display_vend & 0xffffff; lcdc->parms.hsync_skew = timing->hsync_skew & 0xfff; lcdc->parms.polarity = ((timing->hsync_act_low << 0) | (timing->vsync_act_low << 1) | (timing->den_act_low << 2)); lcdc->parms.clk_rate = timing->clk_rate; mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL); mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD); mdp_writel(lcdc->mdp, lcdc->parms.vsync_pulse_width, MDP_LCDC_VSYNC_PULSE_WIDTH); mdp_writel(lcdc->mdp, lcdc->parms.display_hctl, MDP_LCDC_DISPLAY_HCTL); mdp_writel(lcdc->mdp, lcdc->parms.display_vstart, MDP_LCDC_DISPLAY_V_START); mdp_writel(lcdc->mdp, lcdc->parms.display_vend, MDP_LCDC_DISPLAY_V_END); mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW); mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR); mdp_writel(lcdc->mdp, 0x0, MDP_LCDC_UNDERFLOW_CTL); mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL); mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START); mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END); mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY); printk("solomon: polarity=%04x\n", mdp_readl(lcdc->mdp, MDP_LCDC_CTL_POLARITY)); /* config the dma_p block that drives the lcdc data */ mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR); mdp_writel(lcdc->mdp, (((yres & 0x7ff) << 16) | (xres & 0x7ff)), MDP_DMA_P_SIZE); /* TODO: pull in the bpp info from somewhere else? */ mdp_writel(lcdc->mdp, xres * 2, MDP_DMA_P_IBUF_Y_STRIDE); mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY); dma_cfg = (DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB | DMA_DITHER_EN); dma_cfg |= DMA_OUT_SEL_LCDC; dma_cfg |= DMA_IBUF_FORMAT_RGB565; dma_cfg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG); return 0; }