• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Allwinner SoCs vdpo lowlevel driver.
3  *
4  * Copyright (C) 2017 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 #include "drv_vdpo_lowlevel.h"
11 
12 volatile struct __vdpo_dev *vdpo_dev[VDPO_NUM];
13 
__vdpo_module_en(u32 dev_sel,u32 module_en,u32 sepa_sync_en)14 void __vdpo_module_en(u32 dev_sel, u32 module_en, u32 sepa_sync_en)
15 {
16 	vdpo_dev[dev_sel]->module_ctrl.bits.separate_sync_en = sepa_sync_en;
17 	vdpo_dev[dev_sel]->module_ctrl.bits.vdpo_mudule_en = module_en;
18 }
19 
__vdpo_fmt_set(u32 dev_sel,u32 data_seq_sel,u32 sync_fmt,u32 data_width,u32 interlace)20 void __vdpo_fmt_set(u32 dev_sel, u32 data_seq_sel, u32 sync_fmt, u32 data_width,
21 		    u32 interlace)
22 {
23 	vdpo_dev[dev_sel]->fmt_ctrl.bits.data_seq_sel = data_seq_sel;
24 	vdpo_dev[dev_sel]->fmt_ctrl.bits.embedded_sync_fmt = sync_fmt;
25 	vdpo_dev[dev_sel]->fmt_ctrl.bits.output_data_width = data_width;
26 	vdpo_dev[dev_sel]->fmt_ctrl.bits.interlace_mode = interlace;
27 }
28 
__vdpo_chroma_spl_set(u32 dev_sel,u8 cr_type,u8 cb_type)29 void __vdpo_chroma_spl_set(u32 dev_sel, u8 cr_type, u8 cb_type)
30 {
31 	vdpo_dev[dev_sel]->hor_spl_ctrl.bits.cb_hori_spl_type = cb_type;
32 	vdpo_dev[dev_sel]->hor_spl_ctrl.bits.cr_hori_spl_type = cr_type;
33 }
34 
__vdpo_clamp_set(u32 dev_sel,u16 y_min,u16 y_max,u16 cb_min,u16 cb_max,u16 cr_min,u16 cr_max)35 void __vdpo_clamp_set(u32 dev_sel, u16 y_min, u16 y_max, u16 cb_min, u16 cb_max,
36 		      u16 cr_min, u16 cr_max)
37 {
38 	vdpo_dev[dev_sel]->clamp0.bits.y_val_range_min = y_min;
39 	vdpo_dev[dev_sel]->clamp0.bits.y_val_range_max = y_max;
40 	vdpo_dev[dev_sel]->clamp1.bits.cb_val_range_min = cb_min;
41 	vdpo_dev[dev_sel]->clamp1.bits.cb_val_range_max = cb_max;
42 	vdpo_dev[dev_sel]->clamp2.bits.cr_val_range_min = cr_min;
43 	vdpo_dev[dev_sel]->clamp2.bits.cr_val_range_max = cr_max;
44 }
45 
__vdpo_sync_pol_set(u32 dev_sel,u8 hb_pol,u8 vb_pol,u8 field_pol)46 void __vdpo_sync_pol_set(u32 dev_sel, u8 hb_pol, u8 vb_pol, u8 field_pol)
47 {
48 	vdpo_dev[dev_sel]->sync_ctrl.bits.h_blank_pol = hb_pol;
49 	vdpo_dev[dev_sel]->sync_ctrl.bits.v_blank_pol = vb_pol;
50 	vdpo_dev[dev_sel]->sync_ctrl.bits.field_pol = field_pol;
51 }
52 
__vdpo_dclk_adjust(u32 dev_sel,u8 dclk_invt,u8 dly_en,u8 dly_num)53 void __vdpo_dclk_adjust(u32 dev_sel, u8 dclk_invt, u8 dly_en, u8 dly_num)
54 {
55 	vdpo_dev[dev_sel]->sync_ctrl.bits.dclk_invert = dclk_invt;
56 	vdpo_dev[dev_sel]->sync_ctrl.bits.dclk_dly_num = dly_num;
57 	vdpo_dev[dev_sel]->sync_ctrl.bits.dclk_dly_en = dly_en;
58 }
59 
__vdpo_get_curline(u32 sel)60 u32 __vdpo_get_curline(u32 sel)
61 {
62 	u32 line = vdpo_dev[sel]->status.bits.current_line;
63 
64 	return line;
65 }
66 
__vdpo_get_field(u32 sel)67 u32 __vdpo_get_field(u32 sel)
68 {
69 	u32 field = vdpo_dev[sel]->status.bits.field_pol_sta;
70 
71 	return field;
72 }
73 
__vdpo_irq_en(u32 sel,u32 int_type,u32 line)74 s32 __vdpo_irq_en(u32 sel, u32 int_type, u32 line)
75 {
76 	s32 ret = 0;
77 
78 	if (int_type == V_INT) {
79 		vdpo_dev[sel]->int_ctrl.bits.vb_int_en = 1;
80 	} else if (int_type == L_INT) {
81 		vdpo_dev[sel]->line_int_num.bits.int_line_num = line;
82 		vdpo_dev[sel]->int_ctrl.bits.line_match_int_en = 1;
83 	} else
84 		ret = -1;
85 	return ret;
86 }
87 
__vdpo_irq_disable(u32 sel,u32 int_type)88 s32 __vdpo_irq_disable(u32 sel, u32 int_type)
89 {
90 	s32 ret = 0;
91 
92 	if (int_type == V_INT)
93 		vdpo_dev[sel]->int_ctrl.bits.vb_int_en = 0;
94 	else if (int_type == L_INT)
95 		vdpo_dev[sel]->int_ctrl.bits.line_match_int_en = 0;
96 	else
97 		ret = -1;
98 	return ret;
99 }
100 
__vdpo_irq_process(u32 sel)101 u32 __vdpo_irq_process(u32 sel)
102 {
103 	if ((vdpo_dev[sel]->int_ctrl.bits.vb_int_flag) &&
104 	    (vdpo_dev[sel]->int_ctrl.bits.vb_int_en))
105 		return V_INT;
106 	else if ((vdpo_dev[sel]->int_ctrl.bits.line_match_int_flag) &&
107 		 (vdpo_dev[sel]->int_ctrl.bits.line_match_int_en))
108 		return L_INT;
109 	else
110 		return 0;
111 }
112 
__vdpo_clr_irq(u32 sel,u32 int_type)113 u32 __vdpo_clr_irq(u32 sel, u32 int_type)
114 {
115 	if (int_type == V_INT)
116 		vdpo_dev[sel]->int_ctrl.bits.vb_int_flag = 0;
117 	else if (int_type == L_INT)
118 		vdpo_dev[sel]->int_ctrl.bits.line_match_int_flag = 0;
119 	return 0;
120 }
121 
__vdpo_timing_set(u32 sel,u32 h_active,u32 h_bp,u32 v_active,u32 v_bp,u32 v_total,u32 interlace,u32 itl_mode)122 void __vdpo_timing_set(u32 sel, u32 h_active, u32 h_bp, u32 v_active, u32 v_bp,
123 		       u32 v_total, u32 interlace, u32 itl_mode)
124 {
125 	vdpo_dev[sel]->h_timing.bits.h_active = h_active - 1;
126 	vdpo_dev[sel]->h_timing.bits.h_bp = h_bp - 1;
127 	vdpo_dev[sel]->v_timing.bits.v_active = v_active / (interlace + 1) - 1;
128 	vdpo_dev[sel]->v_timing.bits.v_bp = v_bp - 1;
129 	vdpo_dev[sel]->v_timing1.bits.v_total = v_total * 2 / (interlace + 1);
130 	if (interlace)
131 		vdpo_dev[sel]->v_timing1.bits.itl_mode = itl_mode;
132 }
133 
134 #if 0
135 u32 __vdpo_reg_default_test(u32 sel, u32 addr_offset, u32 exp_value)
136 {
137 	u32 base_addr;
138 
139 	base_addr = VDPO_BASE;
140 	if (exp_value != get_wvalue(base_addr + addr_offset))
141 		return RET_FAIL;
142 	else
143 		return RET_OK;
144 }
145 
146 u32 __vdpo_reg_wr_test(u32 sel, u32 addr_offset, u32 mask, u32 wr_value)
147 {
148 	u32 base_addr, rd_value;
149 
150 	base_addr = VDPO_BASE;
151 	wr_value &= mask;
152 	put_wvalue(base_addr + addr_offset, wr_value);
153 	rd_value = get_wvalue(base_addr + addr_offset);
154 	rd_value &= mask;
155 	if (wr_value != rd_value)
156 		return RET_FAIL;
157 	else
158 		return RET_OK;
159 }
160 #endif
161 
__vdpo_set_reg_base(u32 sel,void __iomem * base_addr)162 void __vdpo_set_reg_base(u32 sel, void __iomem *base_addr)
163 {
164 	vdpo_dev[sel] = (struct __vdpo_dev *)base_addr;
165 }
166