static void lcdc_overlay_start(void *priv, uint32_t addr, uint32_t stride, uint32_t width, uint32_t height, uint32_t x, uint32_t y) { struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); struct mdp4_overlay_pipe *pipe; pipe = lcdc_pipe; pipe->srcp0_addr = addr; if (mdp->dma_config_dirty) { if(mdp->dma_format == DMA_IBUF_FORMAT_RGB565) { pipe->src_format = MDP_RGB_565; pipe->srcp0_ystride = pipe->src_width * 2; } else if(mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888) { pipe->src_format = MDP_RGBA_8888; pipe->srcp0_ystride = pipe->src_width * 4; } mdp4_overlay_format2pipe(pipe); mdp_writel(pipe->mdp, 0, MDP_LCDC_EN); mdelay(30); mdp4_overlay_dmap_xy(pipe); mdp4_overlay_dmap_cfg(pipe, 1); mdp4_overlayproc_cfg(pipe); mdp4_overlay_rgb_setup(pipe); mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */ mdp_writel(pipe->mdp, 1, MDP_LCDC_EN); mdp->dma_config_dirty = false; } else { mdp4_overlay_rgb_setup(pipe); mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */ } }
static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, uint32_t width, uint32_t height, uint32_t x, uint32_t y) { struct mdp_info *mdp = priv; uint32_t dma2_cfg; uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */ dma2_cfg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB; dma2_cfg |= mdp->dma_format; dma2_cfg |= mdp->dma_pack_pattern; dma2_cfg |= DMA_DITHER_EN; /* 666 18BPP */ dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; /* setup size, address, and stride */ mdp_writel(mdp, (height << 16) | (width), MDP_DMA_P_SIZE); mdp_writel(mdp, addr, MDP_DMA_P_IBUF_ADDR); mdp_writel(mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE); /* set y & x offset and MDDI transaction parameters */ mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY); mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL); mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM, MDP_MDDI_PARAM); mdp_writel(mdp, 0x1, MDP_MDDI_DATA_XFR); mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG); mdp_writel(mdp, 0, MDP_DMA_P_START); }
static int icm_thread(void *data) { struct mdp_lcdc_info *lcdc; struct msm_lcdc_panel_ops *panel_ops; int rc; unsigned long irq_flags = 0; lcdc = data; panel_ops = lcdc->pdata->panel_ops; while (1) { rc = wait_event_timeout(panel_update_wait_queue, icm_check_panel_update() == 1, PANEL_ENTER_IDLE_TIMEOUT); ICM_DBG("ICM Thread:wake up rc=%d \n", rc); mutex_lock(&panel_icm->icm_lock); if (rc == 0 && icm_check_panel_update() != 1) {/* wait_timeout */ ICM_DBG("EnterICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable); if (panel_icm->icm_mode == false && panel_icm->icm_doable == true) { if (panel_ops->refresh_enable) panel_ops->refresh_enable(panel_ops); panel_icm->icm_mode = true; msleep(PANEL_IDLE_STABLE_TIMEOUT); mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); clk_disable(lcdc->pad_pclk); clk_disable(lcdc->pclk); clk_disable(lcdc->mdp_clk); panel_icm->clock_enabled = false; PR_DISP_DEBUG("EnterICM: enter ICM MODE done!!!\n"); } } else {/* get update event, no timeout */ ICM_DBG("Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable); if (panel_icm->icm_mode == true && panel_icm->icm_doable == true) { clk_enable(lcdc->mdp_clk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); panel_icm->clock_enabled = true; if (panel_ops->refresh_disable) panel_ops->refresh_disable(panel_ops); panel_icm->icm_mode = false; PR_DISP_DEBUG("LeaveICM: leave ICM MODE done !!!\n"); } spin_lock_irqsave(&panel_icm->lock, irq_flags); panel_icm->panel_update = 0; spin_unlock_irqrestore(&panel_icm->lock, irq_flags); } mutex_unlock(&panel_icm->icm_lock); } /* end while */ return 0; }
void mdp4_lcdc_overlay_blt(ulong addr) { unsigned long flag; spin_lock_irqsave(&mdp_spin_lock, flag); lcdc_pipe->blt_addr = addr; lcdc_pipe->blt_cnt = 0; spin_unlock_irqrestore(&mdp_spin_lock, flag); mdp_writel(lcdc_pipe->mdp,0x0,0xc0000); mdelay(100); mdp4_overlayproc_cfg(lcdc_pipe); mdp4_overlay_dmap_xy(lcdc_pipe); mdelay(100); mdp_writel(lcdc_pipe->mdp,0x1,0xc0000); }
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 void lcdc_dma_start(void *priv, uint32_t addr, uint32_t stride, uint32_t width, uint32_t height, uint32_t x, uint32_t y) { struct mdp_lcdc_info *lcdc = priv; struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); if (mdp->dma_config_dirty) { mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); mdelay(30); mdp_dev->configure_dma(mdp_dev); mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); } mdp_writel(lcdc->mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE); mdp_writel(lcdc->mdp, addr, MDP_DMA_P_IBUF_ADDR); }
static void icm_force_leave(void) { struct msm_lcdc_panel_ops *panel_ops; unsigned long irq_flags = 0; panel_ops = panel_icm->lcdc->pdata->panel_ops; mutex_lock(&panel_icm->icm_lock); ICM_DBG("Force Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable); if (panel_icm->icm_mode == true) { clk_enable(panel_icm->lcdc->mdp_clk); clk_enable(panel_icm->lcdc->pclk); clk_enable(panel_icm->lcdc->pad_pclk); mdp_writel(panel_icm->lcdc->mdp, 1, MDP_LCDC_EN); panel_icm->clock_enabled = true; if (panel_ops->refresh_disable) panel_ops->refresh_disable(panel_ops); panel_icm->icm_mode = false; panel_icm->icm_doable = true; PR_DISP_INFO("ForceLeaveICM: leave ICM MODE done !!!\n"); } spin_lock_irqsave(&panel_icm->lock, irq_flags); panel_icm->panel_update = 0; spin_unlock_irqrestore(&panel_icm->lock, irq_flags); mutex_unlock(&panel_icm->icm_lock); }
/* FIXME: arrange the clock manipulating to proper place, integrate with the counter of fb_hdmi */ int lcdc_enable_video(void) { //struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct mdp_lcdc_info *lcdc = _lcdc; struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; mutex_lock(&lcdc->blank_lock); if (atomic_read(&lcdc->blank_count)) goto end_enable_video; HDMI_DBG("%s: enable clocks\n", __func__); clk_enable(lcdc->mdp_clk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); /* TODO: need pre-test to see if it make any influence to HDCP, * if ebi1_clk doesn't enabled here. */ //panel_ops->unblank(panel_ops); mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); atomic_inc(&lcdc->blank_count); HDMI_DBG("%s, blank_count=%d\n", __func__, atomic_read(&lcdc->blank_count)); end_enable_video: mutex_unlock(&lcdc->blank_lock); return 0; }
void mdp4_mddi_overlay_kickoff(struct mdp_info *mdp, struct mdp4_overlay_pipe *pipe) { #ifdef MDP4_NONBLOCKING mdp_writel(mdp, 0, 0x0004); #endif }
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 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_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_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_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); pr_info("%s: suspending\n", __func__); mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); <<<<<<< HEAD
void mdp4_blt_xy_update(struct mdp4_overlay_pipe *pipe) { uint32_t off, addr; if (pipe->blt_addr == 0) return; /* overlay ouput is RG565 */ off = 0; if (pipe->blt_cnt & 0x01) off = pipe->src_height * pipe->src_width * 2; addr = pipe->blt_addr+ off; /* dmap */ mdp_writel(pipe->mdp, addr, 0x90008); /* overlay 0 */ mdp_writel(pipe->mdp, addr, MDP4_OVERLAYPROC0_BASE + 0x000c); mdp_writel(pipe->mdp, addr, MDP4_OVERLAYPROC0_BASE + 0x001c); }
/* * mdp4_dmap_done_mddi: called from isr */ void mdp4_dma_p_done_mddi(void) { if (mddi_pipe->blt_end) { mddi_pipe->blt_addr = 0; mdp_intr_mask &= ~INTR_DMA_P_DONE; mdp_writel(mddi_pipe->mdp,mdp_intr_mask,MDP_INTR_ENABLE); mdp4_overlayproc_cfg(mddi_pipe); mdp4_overlay_dmap_xy(mddi_pipe); return; } }
void mdp4_dma_s_update_lcd(struct mdp_info *mdp) { uint32_t mddi_ld_param = 1; uint16_t mddi_vdo_packet_reg = MDDI_VDO_PACKET_PRIM; struct mdp4_overlay_pipe *pipe = NULL; mddi_mdp = mdp; /* keep it */ pipe = mddi_pipe; /*config PIXELSIZE*/ mdp4_overlay_dmas_xy(pipe); /*config for dma_s_cfg_reg*/ mdp4_overlay_dmas_cfg(pipe, 0); mdp_writel(mdp, mddi_ld_param, 0x00090); mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | mddi_vdo_packet_reg, 0x00094); mdp_writel(mdp, 1, 0x00098); }
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); 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; }
/* * mdp4_overlay0_done_mddi: called from isr */ void mdp4_overlay0_done_mddi(void) { if (mddi_pipe->blt_addr) { if (mddi_pipe->blt_cnt == 0) { mdp4_overlayproc_cfg(mddi_pipe); mdp4_overlay_dmap_xy(mddi_pipe); mddi_pipe->blt_cnt++; /* BLT start from next frame */ } else { mdp4_blt_xy_update(mddi_pipe); mddi_pipe->blt_cnt++; /* start DMAP */ mdp_writel(mddi_pipe->mdp,0x0,0x000c); } } }
int mdp_hw_init(struct mdp_info *mdp) { int ret; ret = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_P_DONE, mdp_dma_to_mddi); if (ret) return ret; mdp_writel(mdp, 0, MDP_INTR_ENABLE); mdp_writel(mdp, 0, MDP_DMA_P_HIST_INTR_ENABLE); /* XXX: why set this? QCT says it should be > mdp_pclk, * but they never set the clkrate of pclk */ mdp_set_core_clk(4); pr_info("%s: mdp_clk=%lu\n", __func__, clk_get_rate(mdp->clk)); /* TODO: Configure the VG/RGB pipes fetch data */ /* this should work for any mdp_clk freq. * TODO: use different value for mdp_clk freqs >= 90Mhz */ mdp_writel(mdp, 0x27, MDP_DMA_P_FETCH_CFG); /* 8 bytes-burst x 8 req */ mdp_writel(mdp, 0x3, MDP_EBI2_PORTMAP_MODE); /* 3 pending requests */ mdp_writel(mdp, 0x02222, MDP_MAX_RD_PENDING_CMD_CONFIG); /* no overlay processing, sw controls everything */ mdp_writel(mdp, 0, MDP_LAYERMIXER_IN_CFG); mdp_writel(mdp, 1 << 3, MDP_OVERLAYPROC0_CFG); mdp_writel(mdp, 1 << 3, MDP_OVERLAYPROC1_CFG); /* XXX: HACK! hardcode to do mddi on primary */ mdp_writel(mdp, 0x2, MDP_DISP_INTF_SEL); 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; }
void mdp4_mddi_overlay_blt(ulong addr) { unsigned long flag; spin_lock_irqsave(&mdp_spin_lock, flag); if (addr) { mdp_intr_mask |= INTR_DMA_P_DONE; if(mddi_pipe!=NULL){ mdp_writel(mddi_pipe->mdp,mdp_intr_mask,MDP_INTR_ENABLE); mddi_pipe->blt_cnt = 0; mddi_pipe->blt_end = 0; mddi_pipe->blt_addr = addr; } blt_addr = addr; } else { mddi_pipe->blt_end = 1; /* mark as end */ mdp4_dma_p_done_mddi(); } spin_unlock_irqrestore(&mdp_spin_lock, flag); }
int lcdc_disable_video(void) { struct mdp_lcdc_info *lcdc = _lcdc; struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; mutex_lock(&lcdc->blank_lock); if (atomic_read(&lcdc->blank_count) == 0) goto disable_video_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); } disable_video_done: mutex_unlock(&lcdc->blank_lock); HDMI_DBG("%s, blank_count=%d\n", __func__, atomic_read(&lcdc->blank_count)); return 0; }
static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) { struct msm_panel_data *fb_panel = &lcdc->fb_panel_data; uint32_t dma_cfg; unsigned int clk_id, clk_rate; clk_enable(lcdc->mdp_clk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate); clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate); printk(KERN_DEBUG "pclk = %ld, pad_pclk = %ld\n", clk_get_rate(lcdc->pclk), clk_get_rate(lcdc->pad_pclk)); /* write the lcdc params */ 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, 0, 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, (((fb_panel->fb_data->yres & 0x7ff) << 16) | (fb_panel->fb_data->xres & 0x7ff)), MDP_DMA_P_SIZE); /* TODO: pull in the bpp info from somewhere else? */ mdp_writel(lcdc->mdp, fb_panel->fb_data->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); /* Send customized command to ARM9 for escalating DMA_P as tier-1 * of AXI bus. * Ref: SR#272509 */ clk_id = P_USB_PHY_CLK; clk_rate = 0x1; msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &clk_id, &clk_rate); return 0; }
static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) { struct msm_panel_data *fb_panel = &lcdc->fb_panel_data; uint32_t dma_cfg; clk_prepare_enable(lcdc->mdp_clk); clk_prepare_enable(lcdc->pclk); clk_prepare_enable(lcdc->pad_pclk); clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate); clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate); /* write the lcdc params */ 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, 0xff, 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); /* 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, (((fb_panel->fb_data->yres & 0x7ff) << 16) | (fb_panel->fb_data->xres & 0x7ff)), MDP_DMA_P_SIZE); mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY); dma_cfg = mdp_readl(lcdc->mdp, MDP_DMA_P_CONFIG); dma_cfg |= (DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB | DMA_DITHER_EN); dma_cfg |= DMA_OUT_SEL_LCDC; dma_cfg &= ~DMA_DST_BITS_MASK; if (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB666) dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; else dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG); /* enable the lcdc timing generation */ mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); return 0; }
void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata) { mdp_writel(mdp, pdata->sync_config, MDP_SYNC_CONFIG_0); mdp_writel(mdp, 1, MDP_TEAR_CHECK_EN); mdp_writel(mdp, pdata->sync_thresh, MDP_SYNC_THRESH_0); mdp_writel(mdp, pdata->sync_start_pos, MDP_PRIM_START_POS); }
static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, uint32_t width, uint32_t height, uint32_t x, uint32_t y) { struct mdp_info *mdp = priv; uint32_t dma2_cfg; uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */ dma2_cfg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS; dma2_cfg |= mdp->dma_format; dma2_cfg |= mdp->dma_pack_pattern; dma2_cfg |= DMA_OUT_SEL_MDDI; dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; dma2_cfg |= DMA_DITHER_EN; /* 666 18BPP */ dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; #ifdef CONFIG_MSM_MDP22 /* setup size, address, and stride */ mdp_writel(mdp, (height << 16) | (width), MDP_CMD_DEBUG_ACCESS_BASE + 0x0184); mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188); mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C); /* set y & x offset and MDDI transaction parameters */ mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194); mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0); if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | MDDI_VDO_PACKET_PRIM, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4); else mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB666 << 16) | MDDI_VDO_PACKET_PRIM, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4); mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180); /* start DMA2 */ mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044); #else /* setup size, address, and stride */ mdp_writel(mdp, (height << 16) | (width), MDP_DMA_P_SIZE); mdp_writel(mdp, addr, MDP_DMA_P_IBUF_ADDR); mdp_writel(mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE); /* set y & x offset and MDDI transaction parameters */ mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY); mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL); if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | MDDI_VDO_PACKET_PRIM, MDP_MDDI_PARAM); else mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB666 << 16) | MDDI_VDO_PACKET_PRIM, MDP_MDDI_PARAM); mdp_writel(mdp, 0x1, MDP_MDDI_DATA_XFR); mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG); mdp_writel(mdp, 0, MDP_DMA_P_START); #endif }
int mdp_hw_init(struct mdp_info *mdp) { int n; int lcdc_enabled; mdp_irq_mask = 0; mdp_writel(mdp, 0, MDP_INTR_ENABLE); /* debug interface write access */ mdp_writel(mdp, 1, 0x60); mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE); #ifndef CONFIG_MSM_MDP22 lcdc_enabled = mdp_readl(mdp, MDP_LCDC_EN); /* disable lcdc */ mdp_writel(mdp, 0, MDP_LCDC_EN); /* enable auto clock gating for all blocks by default */ mdp_writel(mdp, 0xffffffff, MDP_CGC_EN); /* reset color/gamma correct parms */ mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG); #endif mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc); mdp_writel(mdp, 1, 0x60); for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++) mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg); /* clear up unused fg/main registers */ /* comp.plane 2&3 ystride */ mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120); /* unpacked pattern */ mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c); /* comp.plane 2 & 3 */ mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118); /* clear unused bg registers */ mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0); mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4); for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++) mdp_writel(mdp, csc_matrix_config_table[n].val, csc_matrix_config_table[n].reg); mdp_ppp_init_scale(mdp); #ifndef CONFIG_MSM_MDP31 mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG); #endif #ifndef CONFIG_MSM_MDP22 if (lcdc_enabled) mdp_writel(mdp, 1, MDP_LCDC_EN); #endif return 0; }