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_peak.c
15 *
16 * Description : display engine 2.0 peaking basic function definition
17 *
18 * History : 2014/03/27 vito cheng v0.1 Initial version
19 *
20 ******************************************************************************/
21
22 #ifdef CONFIG_DISP2_SUNXI_SUPPORT_ENAHNCE
23 #include "de_peak_type.h"
24 #include "de_rtmx.h"
25 #include "de_enhance.h"
26
27 static volatile struct __peak_reg_t *peak_dev[DE_NUM][CHN_NUM];
28 static struct de_reg_blocks peak_block[DE_NUM][CHN_NUM];
29 static struct de_reg_blocks peak_gain_block[DE_NUM][CHN_NUM];
30
31 /*******************************************************************************
32 * function : de_peak_set_reg_base(unsigned int sel, unsigned int chno,
33 * unsigned int base)
34 * description : set peak reg base
35 * parameters :
36 * sel <rtmx select>
37 * chno <overlay select>
38 * base <reg base>
39 * return :
40 * success
41 ******************************************************************************/
de_peak_set_reg_base(unsigned int sel,unsigned int chno,void * base)42 int de_peak_set_reg_base(unsigned int sel, unsigned int chno, void *base)
43 {
44 DE_INF("sel=%d, chno=%d, base=0x%p\n", sel, chno, base);
45 peak_dev[sel][chno] = (struct __peak_reg_t *) base;
46
47 return 0;
48 }
49
de_peak_update_regs(unsigned int sel,unsigned int chno)50 int de_peak_update_regs(unsigned int sel, unsigned int chno)
51 {
52 if (peak_block[sel][chno].dirty == 0x1) {
53 regwrite((void *)peak_block[sel][chno].off,
54 peak_block[sel][chno].val, peak_block[sel][chno].size);
55 peak_block[sel][chno].dirty = 0x0;
56 }
57
58 if (peak_gain_block[sel][chno].dirty == 0x1) {
59 regwrite((void *)peak_gain_block[sel][chno].off,
60 peak_gain_block[sel][chno].val,
61 peak_gain_block[sel][chno].size);
62 peak_gain_block[sel][chno].dirty = 0x0;
63 }
64
65 return 0;
66 }
67
de_peak_init(unsigned int sel,unsigned int chno,uintptr_t reg_base)68 int de_peak_init(unsigned int sel, unsigned int chno, uintptr_t reg_base)
69 {
70 uintptr_t base;
71 void *memory;
72
73 /* FIXME: chno is not considered */
74 base = reg_base + (sel + 1) * 0x00100000 + PEAK_OFST;
75 #if defined(CONFIG_ARCH_SUN50IW10)
76 if (sel)
77 base = base - 0x00100000;
78 #endif
79 DE_INF("sel %d, peak_base[%d]=0x%p\n", sel, chno, (void *)base);
80
81 memory = disp_sys_malloc(sizeof(struct __peak_reg_t));
82 if (memory == NULL) {
83 DE_WRN("disp_sys_malloc peak[%d][%d] memory fail! size=0x%x\n", sel, chno,
84 (unsigned int)sizeof(struct __peak_reg_t));
85 return -1;
86 }
87
88 peak_block[sel][chno].off = base;
89 peak_block[sel][chno].val = memory;
90 peak_block[sel][chno].size = 0x10;
91 peak_block[sel][chno].dirty = 0;
92
93 peak_gain_block[sel][chno].off = base + 0x10;
94 peak_gain_block[sel][chno].val = memory + 0x10;
95 peak_gain_block[sel][chno].size = 0x20;
96 peak_gain_block[sel][chno].dirty = 0;
97
98 de_peak_set_reg_base(sel, chno, memory);
99
100 return 0;
101 }
102
de_peak_exit(unsigned int sel,unsigned int chno)103 int de_peak_exit(unsigned int sel, unsigned int chno)
104 {
105 disp_sys_free(peak_block[sel][chno].val);
106
107 return 0;
108 }
109
110 /*******************************************************************************
111 * function : de_peak_enable(unsigned int sel, unsigned int chno,
112 * unsigned int en)
113 * description : enable/disable peak
114 * parameters :
115 * sel <rtmx select>
116 * chno <overlay select>
117 * en <enable: 0-disable; 1-enable>
118 * return :
119 * success
120 ******************************************************************************/
de_peak_enable(unsigned int sel,unsigned int chno,unsigned int en)121 int de_peak_enable(unsigned int sel, unsigned int chno, unsigned int en)
122 {
123 DE_INF("sel=%d, chno=%d, en=%d\n", sel, chno, en);
124 peak_dev[sel][chno]->ctrl.bits.en = en;
125 peak_block[sel][chno].dirty = 1;
126 return 0;
127 }
128
129 /*******************************************************************************
130 * function : de_peak_set_size(unsigned int sel, unsigned int chno,
131 * unsigned int width, unsigned int height)
132 * description : set peak size
133 * parameters :
134 * sel <rtmx select>
135 * chno <overlay select>
136 * width <input width>
137 * height <input height>
138 * return :
139 * success
140 ******************************************************************************/
de_peak_set_size(unsigned int sel,unsigned int chno,unsigned int width,unsigned int height)141 int de_peak_set_size(unsigned int sel, unsigned int chno, unsigned int width,
142 unsigned int height)
143 {
144 peak_dev[sel][chno]->size.bits.width = width - 1;
145 peak_dev[sel][chno]->size.bits.height = height - 1;
146 peak_block[sel][chno].dirty = 1;
147 return 0;
148 }
149
150 /*******************************************************************************
151 * function : de_peak_set_window(unsigned int sel, unsigned int chno,
152 * unsigned int win_enable, struct de_rect window)
153 * description : set peak window
154 * parameters :
155 * sel <rtmx select>
156 * chno <overlay select>
157 * win_enable <enable: 0-window mode disable;
158 * 1-window mode enable>
159 * window <window rectangle>
160 * return :
161 * success
162 ******************************************************************************/
de_peak_set_window(unsigned int sel,unsigned int chno,unsigned int win_enable,struct de_rect window)163 int de_peak_set_window(unsigned int sel, unsigned int chno,
164 unsigned int win_enable, struct de_rect window)
165 {
166 peak_dev[sel][chno]->ctrl.bits.win_en = win_enable;
167
168 if (win_enable) {
169 peak_dev[sel][chno]->win0.bits.win_left = window.x;
170 peak_dev[sel][chno]->win0.bits.win_top = window.y;
171 peak_dev[sel][chno]->win1.bits.win_right =
172 window.x + window.w - 1;
173 peak_dev[sel][chno]->win1.bits.win_bot =
174 window.y + window.h - 1;
175 }
176 peak_block[sel][chno].dirty = 1;
177 return 0;
178 }
179
180 /*******************************************************************************
181 * function : de_peak_set_para(unsigned int sel, unsigned int chno,
182 * unsigned int gain,unsigned int hp_ratio,
183 * unsigned int bp0_ratio)
184 * description : set peak para
185 * parameters :
186 * sel <rtmx select>
187 * chno <overlay select>
188 * gain <peak gain: normal setting 36-42>
189 * hp_ratio<high pass filter ratio>
190 * bp0_ratio<band pass filter 0 ratio>
191 * return :
192 * success
193 * note : 14/09/01 add hp_ratio and bp0_ratio
194 ******************************************************************************/
de_peak_set_para(unsigned int sel,unsigned int chno,unsigned int gain,unsigned int hp_ratio,unsigned int bp0_ratio)195 int de_peak_set_para(unsigned int sel, unsigned int chno, unsigned int gain,
196 unsigned int hp_ratio, unsigned int bp0_ratio)
197 {
198 peak_dev[sel][chno]->gain.bits.gain = gain;
199 peak_dev[sel][chno]->filter.bits.filter_sel = 0;
200 peak_dev[sel][chno]->filter.bits.hp_ratio = hp_ratio;
201 peak_dev[sel][chno]->filter.bits.bp0_ratio = bp0_ratio;
202
203 peak_dev[sel][chno]->filter.bits.bp1_ratio = 0;
204 peak_dev[sel][chno]->gainctrl.bits.beta = 0;
205 peak_dev[sel][chno]->gainctrl.bits.dif_up = 128;
206 peak_dev[sel][chno]->shootctrl.bits.neg_gain = 31;
207 peak_dev[sel][chno]->coring.bits.corthr = 4;
208
209 peak_gain_block[sel][chno].dirty = 1;
210 return 0;
211 }
212
213 /*******************************************************************************
214 * function : de_peak_info2para(unsigned int sharp, struct de_rect window,
215 * struct __peak_config_data *para)
216 * description : info->para conversion
217 * parameters :
218 * sharp <info from user>
219 * window <window info>
220 * para <bsp para>
221 * return :
222 * success
223 ******************************************************************************/
de_peak_info2para(unsigned int sharp,struct de_rect window,struct __peak_config_data * para)224 int de_peak_info2para(unsigned int sharp, struct de_rect window,
225 struct __peak_config_data *para)
226 {
227 int mode;
228 int peak_para[PEAK_PARA_NUM][PEAK_MODE_NUM] = {
229 {0, 36, 48}, /* gain */
230 {0, 0x4, 0xe}, /* hp_ratio */
231 {0, 0xc, 0x2}, /* bp0_ratio */
232 };
233
234 /* parameters */
235 mode = (sharp >> 4) & 0xf;
236 para->peak_en = mode ? 1 : 0;
237
238 para->gain = peak_para[0][mode];
239 para->hp_ratio = peak_para[1][mode];
240 para->bp0_ratio = peak_para[2][mode];
241
242 return 0;
243 }
244 #endif
245