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