/* * Copyright (C) 2010 Google, Inc. * Author: Dima Zavin * * Based on code from Code Aurora Forum. * * 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 #include "mdp_hw.h" 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); } 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 */ clk_set_rate(mdp->clk, 122880000); /* 122.88 Mhz */ 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; }