/* * Copyright (C) 2010 Google, Inc. * Author: Dima Zavin * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include #include "mdp_hw.h" #include "mdp_ppp.h" #include "mdp_csc_table.h" #define MDP_CMD_DEBUG_ACCESS_BASE (0x10000) static unsigned int mdp_irq_mask; #if 0 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 } #endif #if defined CONFIG_MSM_MDP302 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); } #endif #if 0 int mdp_hw_init(struct mdp_info *mdp) { int n; n = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_P_DONE, mdp_dma_to_mddi); if (n) return n; 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 /* 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 return 0; } #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; }