blob: fdde9ffeb96bca7efc2897571faf8f6c2dbf8e60 [file] [log] [blame]
/*
* Copyright (C) 2010 Google, Inc.
* Author: Dima Zavin <dima@android.com>
*
* 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 <linux/io.h>
#include "mdp_hw.h"
#include "mdp_ppp.h"
#include "mdp_csc_table.h"
#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000)
#ifdef CONFIG_FB_MSM_MDDI
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);
mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 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);
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);
#endif
}
#endif
int mdp_hw_init(struct mdp_info *mdp)
{
int n;
#ifdef CONFIG_FB_MSM_MDDI
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;
#endif
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;
}