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_lti.c
15 *
16 * Description : display engine 2.0 LTI basic function definition
17 *
18 * History : 2014/04/01 vito cheng v0.1 Initial version
19 *
20 ******************************************************************************/
21
22 #ifdef CONFIG_DISP2_SUNXI_SUPPORT_ENAHNCE
23 #include "de_lti_type.h"
24 #include "de_enhance.h"
25
26 static volatile struct __lti_reg_t *lti_dev[DE_NUM][CHN_NUM];
27 static struct de_reg_blocks lti_block[DE_NUM][CHN_NUM];
28
29 /*******************************************************************************
30 * function : de_lti_set_reg_base(unsigned int sel, unsigned int chno,
31 * unsigned int base)
32 * description : set lti reg base
33 * parameters :
34 * sel <rtmx select>
35 * chno <overlay select>
36 * base <reg base>
37 * return :
38 * success
39 ******************************************************************************/
de_lti_set_reg_base(unsigned int sel,unsigned int chno,void * base)40 int de_lti_set_reg_base(unsigned int sel, unsigned int chno, void *base)
41 {
42 lti_dev[sel][chno] = (struct __lti_reg_t *) base;
43
44 return 0;
45 }
46
de_lti_update_regs(unsigned int sel,unsigned int chno)47 int de_lti_update_regs(unsigned int sel, unsigned int chno)
48 {
49 if (lti_block[sel][chno].dirty == 0x1) {
50 regwrite((void *)lti_block[sel][chno].off,
51 lti_block[sel][chno].val, lti_block[sel][chno].size);
52 lti_block[sel][chno].dirty = 0x0;
53 }
54
55 return 0;
56 }
57
de_lti_init(unsigned int sel,unsigned int chno,uintptr_t reg_base)58 int de_lti_init(unsigned int sel, unsigned int chno, uintptr_t reg_base)
59 {
60 uintptr_t base;
61 void *memory;
62
63 /* FIXME display path offset should be defined */
64 base = reg_base + (sel + 1) * 0x00100000 + LTI_OFST;
65 #if defined(CONFIG_ARCH_SUN50IW10)
66 if (sel)
67 base = base - 0x00100000;
68 #endif
69 DE_INF("sel %d, lti_base[%d]=0x%p\n", sel, chno, (void *)base);
70
71 memory = disp_sys_malloc(sizeof(struct __lti_reg_t));
72 if (memory == NULL) {
73 DE_WRN("disp_sys_malloc lti[%d][%d] memory fail! size=0x%x\n", sel, chno,
74 (unsigned int)sizeof(struct __lti_reg_t));
75 return -1;
76 }
77
78 lti_block[sel][chno].off = base;
79 lti_block[sel][chno].val = memory;
80 lti_block[sel][chno].size = 0x40;
81 lti_block[sel][chno].dirty = 0;
82
83 de_lti_set_reg_base(sel, chno, memory);
84
85 return 0;
86 }
87
de_lti_exit(unsigned int sel,unsigned int chno)88 int de_lti_exit(unsigned int sel, unsigned int chno)
89 {
90 disp_sys_free(lti_block[sel][chno].val);
91
92 return 0;
93 }
94
95 /*******************************************************************************
96 * function : de_lti_enable(unsigned int sel, unsigned int chno,
97 * unsigned int en)
98 * description : enable/disable lti
99 * parameters :
100 * sel <rtmx select>
101 * chno <overlay select>
102 * en <enable: 0-disable; 1-enable>
103 * return :
104 * success
105 ******************************************************************************/
de_lti_enable(unsigned int sel,unsigned int chno,unsigned int en)106 int de_lti_enable(unsigned int sel, unsigned int chno, unsigned int en)
107 {
108 lti_dev[sel][chno]->ctrl.bits.en = en;
109 lti_block[sel][chno].dirty = 1;
110 return 0;
111 }
112
113 /*******************************************************************************
114 * function : de_lti_set_size(unsigned int sel, unsigned int chno,
115 * unsigned int width, unsigned int height)
116 * description : set lti size
117 * parameters :
118 * sel <rtmx select>
119 * chno <overlay select>
120 * width <input width>
121 * height <input height>
122 * return :
123 * success
124 ******************************************************************************/
de_lti_set_size(unsigned int sel,unsigned int chno,unsigned int width,unsigned int height)125 int de_lti_set_size(unsigned int sel, unsigned int chno, unsigned int width,
126 unsigned int height)
127 {
128 lti_dev[sel][chno]->size.bits.width = width - 1;
129 lti_dev[sel][chno]->size.bits.height = height - 1;
130 lti_block[sel][chno].dirty = 1;
131 return 0;
132 }
133
134 /*******************************************************************************
135 * function : de_lti_set_window(unsigned int sel, unsigned int chno,
136 * unsigned int win_enable, struct de_rect window)
137 * description : set lti window
138 * parameters :
139 * sel <rtmx select>
140 * chno <overlay select>
141 * win_enable <enable: 0-window mode disable;
142 * 1-window mode enable>
143 * window <window rectangle>
144 * return :
145 * success
146 ******************************************************************************/
de_lti_set_window(unsigned int sel,unsigned int chno,unsigned int win_enable,struct de_rect window)147 int de_lti_set_window(unsigned int sel, unsigned int chno,
148 unsigned int win_enable, struct de_rect window)
149 {
150 lti_dev[sel][chno]->ctrl.bits.win_en = win_enable;
151
152 if (win_enable) {
153 lti_dev[sel][chno]->win0.bits.win_left = window.x;
154 lti_dev[sel][chno]->win0.bits.win_top = window.y;
155 lti_dev[sel][chno]->win1.bits.win_right =
156 window.x + window.w - 1;
157 lti_dev[sel][chno]->win1.bits.win_bot = window.y + window.h - 1;
158 }
159 lti_block[sel][chno].dirty = 1;
160 return 0;
161 }
162
163 /*******************************************************************************
164 * function : de_lti_set_para(unsigned int sel, unsigned int chno,
165 * unsigned int gain)
166 * description : set lti para
167 * parameters :
168 * sel <rtmx select>
169 * chno <overlay select>
170 * gain <lti gain: normal setting 0-3>
171 * return :
172 * success
173 ******************************************************************************/
de_lti_set_para(unsigned int sel,unsigned int chno,unsigned int gain)174 int de_lti_set_para(unsigned int sel, unsigned int chno, unsigned int gain)
175 {
176 lti_dev[sel][chno]->gain.bits.lti_fil_gain = gain;
177
178 lti_dev[sel][chno]->ctrl.bits.sel = 0;
179 lti_dev[sel][chno]->ctrl.bits.nonl_en = 0;
180
181 lti_dev[sel][chno]->coef0.bits.c0 = 127;
182 lti_dev[sel][chno]->coef0.bits.c1 = 64;
183 lti_dev[sel][chno]->coef1.bits.c2 = 0xe0;
184 lti_dev[sel][chno]->coef1.bits.c3 = 0xc0;
185 lti_dev[sel][chno]->coef2.bits.c4 = 0xe0;
186
187 lti_dev[sel][chno]->corth.bits.lti_cor_th = 4;
188 lti_dev[sel][chno]->diff.bits.offset = 32;
189 lti_dev[sel][chno]->diff.bits.slope = 4;
190 lti_dev[sel][chno]->edge_gain.bits.edge_gain = 1;
191 lti_dev[sel][chno]->os_con.bits.core_x = 0;
192 lti_dev[sel][chno]->os_con.bits.clip = 40;
193 lti_dev[sel][chno]->os_con.bits.peak_limit = 1;
194
195 lti_dev[sel][chno]->win_range.bits.win_range = 2;
196 lti_dev[sel][chno]->elvel_th.bits.elvel_th = 32;
197
198 lti_block[sel][chno].dirty = 1;
199 return 0;
200 }
201
202 /*******************************************************************************
203 * function : de_lti_info2para(unsigned int sharp, struct de_rect window,
204 * struct __lti_config_data *para)
205 * description : info->para conversion
206 * parameters :
207 * sharp <gain info from user>
208 * window <window info>
209 * para <bsp para>
210 * return :
211 * success
212 ******************************************************************************/
de_lti_info2para(unsigned int sharp,struct de_rect window,struct __lti_config_data * para)213 int de_lti_info2para(unsigned int sharp, struct de_rect window,
214 struct __lti_config_data *para)
215 {
216 int mode;
217 int lti_para[LTI_PARA_NUM][LTI_MODE_NUM] = {
218 {0, 3}, /* gain */
219 };
220
221 /* parameters */
222 mode = sharp & 0xf;
223 para->lti_en = mode ? 1 : 0;
224 para->gain = lti_para[0][mode];
225
226 return 0;
227 }
228 #endif
229