1 /*
2 * Allwinner SoCs display driver.
3 *
4 * Copyright (C) 2016 Allwinner.
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11 /*******************************************************************************
12 * All Winner Tech, All Right Reserved. 2014-2015 Copyright (c)
13 *
14 * File name : de_fcc.c
15 *
16 * Description : display engine 2.0 fcc base functions implement
17 *
18 * History : 2014/03/28 iptang v0.1 Initial version
19 *
20 ******************************************************************************/
21
22 #ifdef CONFIG_DISP2_SUNXI_SUPPORT_ENAHNCE
23 #include "de_fcc_type.h"
24 #include "de_rtmx.h"
25 #include "de_vep_table.h"
26 #include "de_enhance.h"
27
28 static volatile struct __fcc_reg_t *fcc_dev[DE_NUM][CHN_NUM];
29 static struct de_reg_blocks fcc_para_block[DE_NUM][CHN_NUM];
30
31 /*******************************************************************************
32 * function : de_fcc_set_reg_base
33 * description : set fcc reg base
34 * parameters :
35 * sel <rtmx select>
36 * chno <overlay select>
37 * base <reg base>
38 * return :
39 * success
40 ******************************************************************************/
de_fcc_set_reg_base(unsigned int sel,unsigned int chno,void * base)41 int de_fcc_set_reg_base(unsigned int sel, unsigned int chno, void *base)
42 {
43 fcc_dev[sel][chno] = (struct __fcc_reg_t *) base;
44
45 return 0;
46 }
47
de_fcc_init(unsigned int sel,unsigned int chno,uintptr_t reg_base)48 int de_fcc_init(unsigned int sel, unsigned int chno, uintptr_t reg_base)
49 {
50 uintptr_t fcc_base;
51 void *memory;
52
53 fcc_base = reg_base + (sel + 1) * 0x00100000 + FCC_OFST;
54 #if defined(CONFIG_ARCH_SUN50IW10)
55 if (sel)
56 fcc_base = fcc_base - 0x00100000;
57 #endif
58 /* FIXME display path offset should be defined */
59
60 memory = disp_sys_malloc(sizeof(struct __fcc_reg_t));
61 if (memory == NULL) {
62 DE_WRN("disp_sys_malloc vep fcc[%d][%d] memory fail! size=0x%x\n", sel,
63 chno, (unsigned int)sizeof(struct __fcc_reg_t));
64 return -1;
65 }
66
67 fcc_para_block[sel][chno].off = fcc_base;
68 fcc_para_block[sel][chno].val = memory;
69 fcc_para_block[sel][chno].size = 0x48;
70 fcc_para_block[sel][chno].dirty = 0;
71
72 de_fcc_set_reg_base(sel, chno, memory);
73
74 return 0;
75 }
76
de_fcc_exit(unsigned int sel,unsigned int chno)77 int de_fcc_exit(unsigned int sel, unsigned int chno)
78 {
79 disp_sys_free(fcc_para_block[sel][chno].val);
80
81 return 0;
82 }
83
de_fcc_update_regs(unsigned int sel,unsigned int chno)84 int de_fcc_update_regs(unsigned int sel, unsigned int chno)
85 {
86 if (fcc_para_block[sel][chno].dirty == 0x1) {
87 regwrite((void *)fcc_para_block[sel][chno].off,
88 fcc_para_block[sel][chno].val,
89 fcc_para_block[sel][chno].size);
90 fcc_para_block[sel][chno].dirty = 0x0;
91 }
92
93 return 0;
94 }
95
96 /*******************************************************************************
97 * function : de_fcc_enable(unsigned int sel, unsigned int chno,
98 * unsigned int en)
99 * description : enable/disable fcc
100 * parameters :
101 * sel <rtmx select>
102 * chno <overlay select>
103 * en <enable: 0-disable; 1-enable>
104 * return :
105 * success
106 ******************************************************************************/
de_fcc_enable(unsigned int sel,unsigned int chno,unsigned int en)107 int de_fcc_enable(unsigned int sel, unsigned int chno, unsigned int en)
108 {
109 fcc_dev[sel][chno]->fcc_ctl.bits.en = en;
110 fcc_para_block[sel][chno].dirty = 1;
111
112 return 0;
113 }
114
115 /*******************************************************************************
116 * function : de_fcc_set_size(unsigned int sel, unsigned int chno,
117 * unsigned int width, unsigned int height)
118 * description : set fcc size
119 * parameters :
120 * sel <rtmx select>
121 * chno <overlay select>
122 * width <input width>
123 * height <input height>
124 * return :
125 * success
126 ******************************************************************************/
de_fcc_set_size(unsigned int sel,unsigned int chno,unsigned int width,unsigned int height)127 int de_fcc_set_size(unsigned int sel, unsigned int chno, unsigned int width,
128 unsigned int height)
129 {
130 fcc_dev[sel][chno]->fcc_size.bits.width = width == 0 ? 0 : width - 1;
131 fcc_dev[sel][chno]->fcc_size.bits.height = height == 0 ? 0 : height - 1;
132
133 fcc_para_block[sel][chno].dirty = 1;
134
135 return 0;
136 }
137
138 /*******************************************************************************
139 * function : de_fcc_set_window(unsigned int sel, unsigned int chno,
140 * unsigned int win_en, struct de_rect window)
141 * description : set fcc window
142 * parameters :
143 * sel <rtmx select>
144 * chno <overlay select>
145 * win_en <enable: 0-window mode disable;
146 * 1-window mode enable>
147 * window <window rectangle>
148 * return :
149 * success
150 ******************************************************************************/
de_fcc_set_window(unsigned int sel,unsigned int chno,unsigned int win_en,struct de_rect window)151 int de_fcc_set_window(unsigned int sel, unsigned int chno, unsigned int win_en,
152 struct de_rect window)
153 {
154 fcc_dev[sel][chno]->fcc_ctl.bits.win_en = win_en & 0x1;
155
156 if (win_en) {
157 fcc_dev[sel][chno]->fcc_win0.bits.left = window.x;
158 fcc_dev[sel][chno]->fcc_win0.bits.top = window.y;
159 fcc_dev[sel][chno]->fcc_win1.bits.right =
160 window.x + window.w - 1;
161 fcc_dev[sel][chno]->fcc_win1.bits.bot = window.y + window.h - 1;
162 }
163
164 fcc_para_block[sel][chno].dirty = 1;
165
166 return 0;
167 }
168
169 /*******************************************************************************
170 * function : de_fcc_set_para(unsigned int sel, unsigned int chno,
171 * unsigned int mode)
172 * description : set fcc para
173 * parameters :
174 * sel <rtmx select>
175 * chno <overlay select>
176 * sgain
177 * return :
178 * success
179 ******************************************************************************/
de_fcc_set_para(unsigned int sel,unsigned int chno,unsigned int sgain[6])180 int de_fcc_set_para(unsigned int sel, unsigned int chno, unsigned int sgain[6])
181 {
182 regwrite((void *)fcc_dev[sel][chno]->fcc_range,
183 (void *)&fcc_range_gain[0], sizeof(int) * 6);
184 regwrite((void *)fcc_dev[sel][chno]->fcc_gain, (void *)&sgain[0],
185 sizeof(int) * 6);
186
187 fcc_para_block[sel][chno].dirty = 1;
188
189 return 0;
190 }
191
192 /*******************************************************************************
193 * function : de_fcc_info2para(unsigned int gain, struct de_rect window,
194 * struct __fcc_config_data *para)
195 * description : info->para conversion
196 * parameters :
197 * gain <gain info from user>
198 * window <window info>
199 * para <bsp para>
200 * return :
201 * success
202 ******************************************************************************/
de_fcc_info2para(unsigned int sgain0,unsigned int sgain1,unsigned int sgain2,unsigned int sgain3,unsigned int sgain4,unsigned int sgain5,struct de_rect window,struct __fcc_config_data * para)203 int de_fcc_info2para(unsigned int sgain0, unsigned int sgain1,
204 unsigned int sgain2, unsigned int sgain3,
205 unsigned int sgain4, unsigned int sgain5,
206 struct de_rect window, struct __fcc_config_data *para)
207 {
208 int fcc_para[FCC_PARA_NUM][FCC_MODE_NUM] = {
209 {0, 5, 10}, /* sgain0 */
210 {0, 12, 24}, /* sgain1 */
211 {0, 4, 8}, /* sgain2 */
212 {0, 0, 0}, /* sgain3 */
213 {0, 0, 0}, /* sgain4 */
214 {0, 0, 0}, /* sgain5 */
215 };
216
217 /* parameters */
218 para->fcc_en =
219 ((sgain0 | sgain1 | sgain2 | sgain3 | sgain4 | sgain5) == 0) ?
220 0 : 1;
221
222 para->sgain[0] = fcc_para[0][sgain0];
223 para->sgain[1] = fcc_para[1][sgain1];
224 para->sgain[2] = fcc_para[2][sgain2];
225 para->sgain[3] = fcc_para[3][sgain3];
226 para->sgain[4] = fcc_para[4][sgain4];
227 para->sgain[5] = fcc_para[5][sgain5];
228
229 return 0;
230 }
231 #endif
232