2 * Copyright (C) 2012 Spreadtrum Communications Inc.
\r
4 * This software is licensed under the terms of the GNU General Public
\r
5 * License version 2, as published by the Free Software Foundation, and
\r
6 * may be copied, distributed, and modified under those terms.
\r
8 * This program is distributed in the hope that it will be useful,
\r
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
11 * GNU General Public License for more details.
\r
14 /**---------------------------------------------------------------------------*
\r
16 **---------------------------------------------------------------------------*/
\r
17 //#include <linux/irq.h>
\r
20 #include "gsp_config_if.h"
\r
24 /**---------------------------------------------------------------------------*
\r
26 **---------------------------------------------------------------------------*/
\r
28 /**---------------------------------------------------------------------------*
\r
29 ** Macro Definition *
\r
30 **---------------------------------------------------------------------------*/
\r
33 /**---------------------------------------------------------------------------*
\r
34 ** Function Define *
\r
35 **---------------------------------------------------------------------------*/
\r
37 LOCAL void GSP_SetLayer0Parameter(gsp_context_t *gspCtx)
\r
39 if(!gspCtx->gsp_cfg.layer0_info.layer_en) {
\r
40 GSP_L0_ENABLE_SET(0);
\r
44 GSP_L0_ADDR_SET(gspCtx->gsp_cfg.layer0_info.src_addr);
\r
45 GSP_L0_PITCH_SET(gspCtx->gsp_cfg.layer0_info.pitch);
\r
46 GSP_L0_CLIPRECT_SET(gspCtx->gsp_cfg.layer0_info.clip_rect);
\r
47 GSP_L0_DESRECT_SET(gspCtx->gsp_cfg.layer0_info.des_rect);
\r
48 GSP_L0_GREY_SET(gspCtx->gsp_cfg.layer0_info.grey);
\r
49 GSP_L0_ENDIAN_SET(gspCtx->gsp_cfg.layer0_info.endian_mode);
\r
50 GSP_L0_ALPHA_SET(gspCtx->gsp_cfg.layer0_info.alpha);
\r
51 GSP_L0_COLORKEY_SET(gspCtx->gsp_cfg.layer0_info.colorkey);
\r
52 GSP_L0_IMGFORMAT_SET(gspCtx->gsp_cfg.layer0_info.img_format);
\r
53 GSP_L0_ROTMODE_SET(gspCtx->gsp_cfg.layer0_info.rot_angle);
\r
54 GSP_L0_COLORKEYENABLE_SET(gspCtx->gsp_cfg.layer0_info.colorkey_en);
\r
55 GSP_L0_PALLETENABLE_SET(gspCtx->gsp_cfg.layer0_info.pallet_en);
\r
56 //GSP_L0_SCALETAPMODE_SET(gspCtx->gsp_cfg.layer0_info.row_tap_mode,gspCtx->gsp_cfg.layer0_info.col_tap_mode);
\r
61 LOCAL void GSP_SetLayer1Parameter(gsp_context_t *gspCtx)
\r
63 if(!gspCtx->gsp_cfg.layer1_info.layer_en) {
\r
64 GSP_L1_ENABLE_SET(0);
\r
68 GSP_L1_ADDR_SET(gspCtx->gsp_cfg.layer1_info.src_addr);
\r
69 GSP_L1_PITCH_SET(gspCtx->gsp_cfg.layer1_info.pitch);
\r
70 GSP_L1_CLIPRECT_SET(gspCtx->gsp_cfg.layer1_info.clip_rect);
\r
71 GSP_L1_DESPOS_SET(gspCtx->gsp_cfg.layer1_info.des_pos);
\r
72 GSP_L1_GREY_SET(gspCtx->gsp_cfg.layer1_info.grey);
\r
73 GSP_L1_ENDIAN_SET(gspCtx->gsp_cfg.layer1_info.endian_mode);
\r
74 GSP_L1_ALPHA_SET(gspCtx->gsp_cfg.layer1_info.alpha);
\r
75 GSP_L1_COLORKEY_SET(gspCtx->gsp_cfg.layer1_info.colorkey);
\r
76 GSP_L1_IMGFORMAT_SET(gspCtx->gsp_cfg.layer1_info.img_format);
\r
77 GSP_L1_ROTMODE_SET(gspCtx->gsp_cfg.layer1_info.rot_angle);
\r
78 GSP_L1_COLORKEYENABLE_SET(gspCtx->gsp_cfg.layer1_info.colorkey_en);
\r
79 GSP_L1_PALLETENABLE_SET(gspCtx->gsp_cfg.layer1_info.pallet_en);
\r
84 LOCAL void GSP_SetLayerDesParameter(gsp_context_t *gspCtx)
\r
86 if(!gspCtx->gsp_cfg.layer0_info.layer_en && !gspCtx->gsp_cfg.layer1_info.layer_en) {
\r
90 GSP_Ld_ADDR_SET(gspCtx->gsp_cfg.layer_des_info.src_addr);
\r
91 GSP_Ld_PITCH_SET(gspCtx->gsp_cfg.layer_des_info.pitch);
\r
92 GSP_Ld_ENDIAN_SET(gspCtx->gsp_cfg.layer_des_info.endian_mode);
\r
93 GSP_Ld_IMGFORMAT_SET(gspCtx->gsp_cfg.layer_des_info.img_format);
\r
94 GSP_Ld_COMPRESSRGB888_SET(gspCtx->gsp_cfg.layer_des_info.compress_r8_en);
\r
97 LOCAL void GSP_SetMiscParameter(gsp_context_t *gspCtx)
\r
99 if(!gspCtx->gsp_cfg.layer0_info.layer_en && !gspCtx->gsp_cfg.layer1_info.layer_en) {
\r
103 GSP_L0_ENABLE_SET(gspCtx->gsp_cfg.layer0_info.layer_en);
\r
104 GSP_L1_ENABLE_SET(gspCtx->gsp_cfg.layer1_info.layer_en);
\r
106 if(gspCtx->gsp_cfg.layer0_info.scaling_en == 1) {
\r
107 GSP_SCALESTATUS_RESET();
\r
109 GSP_SCALE_ENABLE_SET(gspCtx->gsp_cfg.layer0_info.scaling_en);
\r
112 GSP_PMARGB_ENABLE_SET(gspCtx->gsp_cfg.layer0_info.pmargb_en||gspCtx->gsp_cfg.layer1_info.pmargb_en);
\r
113 GSP_L0_PMARGBMODE_SET(gspCtx->gsp_cfg.layer0_info.pmargb_mod);
\r
114 GSP_L1_PMARGBMODE_SET(gspCtx->gsp_cfg.layer1_info.pmargb_mod);
\r
115 GSP_PAGES_BOARDER_SPLIT_SET(gspCtx->gsp_cfg.misc_info.split_pages);
\r
116 GSP_Y2R_OPT_SET(gspCtx->gsp_cfg.misc_info.y2r_opt);
\r
117 GSP_DITHER_ENABLE_SET(gspCtx->gsp_cfg.misc_info.dithering_en);
\r
118 //GSP_AHB_CLOCK_SET(gspCtx->gsp_cfg.misc_info.ahb_clock);
\r
119 GSP_CLOCK_SET(gspCtx->gsp_cfg.misc_info.gsp_clock);
\r
120 GSP_EMC_GAP_SET(gspCtx->gsp_cfg.misc_info.gsp_gap);
\r
123 PUBLIC void GSP_module_enable(gsp_context_t *gspCtx)
\r
126 //GSP_HWMODULE_ENABLE();
\r
127 if(gspCtx->gsp_clk != NULL) {
\r
128 ret = clk_prepare_enable(gspCtx->gsp_clk);
\r
130 GSP_TRACE(KERN_ERR "%s: enable clock failed!\n",__FUNCTION__);
\r
133 pr_debug(KERN_INFO "%s: enable clock ok!\n",__FUNCTION__);
\r
136 GSP_TRACE(KERN_ERR "%s: gsp_clk not init yet!\n",__FUNCTION__);
\r
139 PUBLIC void GSP_module_disable(gsp_context_t *gspCtx)
\r
141 if(gspCtx->gsp_clk != NULL) {
\r
142 //GSP_HWMODULE_DISABLE();//disable may not use the enable regiter
\r
143 clk_disable_unprepare(gspCtx->gsp_clk);
\r
145 printk(KERN_ERR "%s: gsp_clk not init yet!\n",__FUNCTION__);
\r
150 func:GSP_ClocksCheckPhase0
\r
151 desc: check all clock except iommu
\r
153 PUBLIC int GSP_ClocksCheckPhase0(void)
\r
158 if(0==(GSP_REG_READ(GSP_MOD_EN)&GSP_MOD_EN_BIT)) {
\r
159 printk(KERN_ERR "%s: err: gsp enable is not set!%lx:%08x\n",__FUNCTION__,
\r
160 (ulong)GSP_MOD_EN,GSP_REG_READ(GSP_MOD_EN));
\r
163 if(GSP_WORKSTATUS_GET() != 0) {
\r
164 printk(KERN_ERR "%s: err:busy is still on!!!!\n",__FUNCTION__);
\r
169 //check GSP clock select
\r
170 if(GSP_CLK_SEL_BIT_MASK!=(GSP_REG_READ(GSP_CLOCK_BASE)&GSP_CLK_SEL_BIT_MASK)) {
\r
171 printk(KERN_INFO "%s: info: gsp clock select is not set to hightest freq!%lx:%08x\n",__FUNCTION__,
\r
172 (ulong)GSP_CLOCK_BASE,GSP_REG_READ(GSP_CLOCK_BASE));
\r
175 //check GSP AUTO_GATE clock
\r
176 if(0==(GSP_REG_READ(GSP_AUTO_GATE_ENABLE_BASE)&GSP_AUTO_GATE_ENABLE_BIT)) {
\r
177 printk(KERN_ERR "%s: err: gsp auto gate clock is not enable!%lx:%08x\n",__FUNCTION__,
\r
178 (ulong)GSP_AUTO_GATE_ENABLE_BASE,GSP_REG_READ(GSP_AUTO_GATE_ENABLE_BASE));
\r
182 //check GSP EMC clock
\r
183 if(0==(GSP_REG_READ(GSP_EMC_MATRIX_BASE)&GSP_EMC_MATRIX_BIT)) {
\r
184 printk(KERN_ERR "%s: err: gsp emc clock is not enable!%lx:%08x\n",__FUNCTION__,
\r
185 (ulong)GSP_EMC_MATRIX_BASE,GSP_REG_READ(GSP_EMC_MATRIX_BASE));
\r
188 return (ret>0)?GSP_KERNEL_CLOCK_ERR:GSP_NO_ERR;
\r
192 func:GSP_ClocksCheckPhase1
\r
193 desc: check iommu cfg
\r
195 PUBLIC int GSP_ClocksCheckPhase1(void)
\r
198 uint32_t ctl_val = GSP_REG_READ(GSP_MMU_CTRL_BASE);
\r
199 uint32_t addr_y0 = GSP_L0_ADDRY_GET();
\r
200 uint32_t addr_uv0 = GSP_L0_ADDRUV_GET();
\r
201 uint32_t addr_va0 = GSP_L0_ADDRVA_GET();
\r
202 uint32_t addr_y1 = GSP_L1_ADDRY_GET();
\r
203 uint32_t addr_uv1 = GSP_L1_ADDRUV_GET();
\r
204 uint32_t addr_va1 = GSP_L1_ADDRVA_GET();
\r
205 uint32_t addr_yd = GSP_Ld_ADDRY_GET();
\r
206 uint32_t addr_uvd = GSP_Ld_ADDRUV_GET();
\r
207 uint32_t addr_vad = GSP_Ld_ADDRVA_GET();
\r
209 #define IOVA_CHECK(addr) (0x10000000<= (addr) && (addr) < 0x80000000)
\r
211 //check GSP IOMMU ENABLE
\r
212 if(((ctl_val & 0x1)==0 || (ctl_val & 0xF0000000)==0)/*IOMMU be disabled*/
\r
213 &&(((GSP_L0_ENABLE_GET() == 1) && (IOVA_CHECK(addr_y0) || IOVA_CHECK(addr_uv0) || IOVA_CHECK(addr_va0)))/*L0 is enabled and use iova*/
\r
214 ||((GSP_L1_ENABLE_GET() == 1) && (IOVA_CHECK(addr_y1) || IOVA_CHECK(addr_uv1) || IOVA_CHECK(addr_va1)))/*L1 is enabled and use iova*/
\r
215 ||((GSP_L0_ENABLE_GET() == 1 ||GSP_L1_ENABLE_GET() == 1 ) && (IOVA_CHECK(addr_yd) || IOVA_CHECK(addr_uvd) || IOVA_CHECK(addr_vad))))) {
\r
216 printk(KERN_ERR "%s: err: gsp iommu is not enable or iova base is null!%lx:%08x\n",__FUNCTION__,
\r
217 (ulong)GSP_MMU_CTRL_BASE,GSP_REG_READ(GSP_MMU_CTRL_BASE));
\r
220 return (ret>0)?GSP_KERNEL_CLOCK_ERR:GSP_NO_ERR;
\r
224 PUBLIC int GSP_Init(gsp_context_t *gspCtx)
\r
227 GSP_module_enable(gspCtx);
\r
228 ret = clk_prepare_enable(gspCtx->gsp_emc_clk);
\r
229 //GSP_AUTO_GATE_ENABLE();//gsp driver take charge of auto_gate bit instead of pm
\r
231 printk(KERN_ERR "%s: enable emc clock failed!\n",__FUNCTION__);
\r
232 return GSP_KERNEL_CLOCK_ERR;
\r
234 pr_debug(KERN_INFO "%s: enable emc clock ok!\n",__FUNCTION__);
\r
237 //GSP_HWMODULE_SOFTRESET();//sharkL bug 350028
\r
238 GSP_IRQMODE_SET(GSP_IRQ_MODE_LEVEL);
\r
239 ret = GSP_ClocksCheckPhase0();
\r
242 PUBLIC void GSP_Deinit(gsp_context_t *gspCtx)
\r
244 clk_disable_unprepare(gspCtx->gsp_emc_clk);
\r
245 GSP_IRQSTATUS_CLEAR();
\r
246 GSP_IRQENABLE_SET(GSP_IRQ_TYPE_DISABLE);
\r
247 GSP_module_disable(gspCtx);
\r
250 PUBLIC void GSP_ConfigLayer(GSP_MODULE_ID_E layer_id, gsp_context_t *gspCtx)
\r
253 case GSP_MODULE_LAYER0:
\r
254 GSP_SetLayer0Parameter(gspCtx);
\r
257 case GSP_MODULE_LAYER1:
\r
258 GSP_SetLayer1Parameter(gspCtx);
\r
261 case GSP_MODULE_DST:
\r
262 GSP_SetLayerDesParameter(gspCtx);
\r
266 GSP_SetMiscParameter(gspCtx);
\r
271 PUBLIC void GSP_Wait_Finish(void)
\r
273 if(GSP_WORKSTATUS_GET() != 0) {
\r
274 printk(KERN_ERR "%s: err:busy is still on!!!!\n",__FUNCTION__);
\r
279 PUBLIC uint32_t GSP_Trigger(void)
\r
281 int ret = GSP_ClocksCheckPhase1();
\r
285 if(GSP_ERRFLAG_GET()) {
\r
287 return GSP_ERRCODE_GET();
\r
290 GSP_IRQENABLE_SET(GSP_IRQ_TYPE_ENABLE);
\r
291 GSP_ENGINE_TRIGGER();
\r