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_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; }
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; }
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_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; }