3c5cdbf50594599bb5e7163c03bb612a9ad516e9
[platform/kernel/linux-starfive.git] / drivers / gpu / drm / verisilicon / vs_dc_hw.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020 VeriSilicon Holdings Co., Ltd.
4  */
5
6 #include <linux/io.h>
7 #include <linux/bits.h>
8 #include <linux/media-bus-format.h>
9
10 #include <drm/vs_drm.h>
11
12 #include "vs_type.h"
13 #include "vs_dc_hw.h"
14 #include "vs_dc_dec.h"
15
16 static const u32 horKernel[] = {
17         0x00000000, 0x20000000, 0x00002000, 0x00000000,
18         0x00000000, 0x00000000, 0x23fd1c03, 0x00000000,
19         0x00000000, 0x00000000, 0x181f0000, 0x000027e1,
20         0x00000000, 0x00000000, 0x00000000, 0x2b981468,
21         0x00000000, 0x00000000, 0x00000000, 0x10f00000,
22         0x00002f10, 0x00000000, 0x00000000, 0x00000000,
23         0x32390dc7, 0x00000000, 0x00000000, 0x00000000,
24         0x0af50000, 0x0000350b, 0x00000000, 0x00000000,
25         0x00000000, 0x3781087f, 0x00000000, 0x00000000,
26         0x00000000, 0x06660000, 0x0000399a, 0x00000000,
27         0x00000000, 0x00000000, 0x3b5904a7, 0x00000000,
28         0x00000000, 0x00000000, 0x033c0000, 0x00003cc4,
29         0x00000000, 0x00000000, 0x00000000, 0x3de1021f,
30         0x00000000, 0x00000000, 0x00000000, 0x01470000,
31         0x00003eb9, 0x00000000, 0x00000000, 0x00000000,
32         0x3f5300ad, 0x00000000, 0x00000000, 0x00000000,
33         0x00480000, 0x00003fb8, 0x00000000, 0x00000000,
34         0x00000000, 0x3fef0011, 0x00000000, 0x00000000,
35         0x00000000, 0x00000000, 0x00004000, 0x00000000,
36         0x00000000, 0x00000000, 0x20002000, 0x00000000,
37         0x00000000, 0x00000000, 0x1c030000, 0x000023fd,
38         0x00000000, 0x00000000, 0x00000000, 0x27e1181f,
39         0x00000000, 0x00000000, 0x00000000, 0x14680000,
40         0x00002b98, 0x00000000, 0x00000000, 0x00000000,
41         0x2f1010f0, 0x00000000, 0x00000000, 0x00000000,
42         0x0dc70000, 0x00003239, 0x00000000, 0x00000000,
43         0x00000000, 0x350b0af5, 0x00000000, 0x00000000,
44         0x00000000, 0x087f0000, 0x00003781, 0x00000000,
45         0x00000000, 0x00000000, 0x399a0666, 0x00000000,
46         0x00000000, 0x00000000, 0x04a70000, 0x00003b59,
47         0x00000000, 0x00000000, 0x00000000, 0x3cc4033c,
48         0x00000000, 0x00000000, 0x00000000, 0x021f0000,
49 };
50 #define H_COEF_SIZE (sizeof(horKernel) / sizeof(u32))
51
52 static const u32 verKernel[] = {
53         0x00000000, 0x20000000, 0x00002000, 0x00000000,
54         0x00000000, 0x00000000, 0x23fd1c03, 0x00000000,
55         0x00000000, 0x00000000, 0x181f0000, 0x000027e1,
56         0x00000000, 0x00000000, 0x00000000, 0x2b981468,
57         0x00000000, 0x00000000, 0x00000000, 0x10f00000,
58         0x00002f10, 0x00000000, 0x00000000, 0x00000000,
59         0x32390dc7, 0x00000000, 0x00000000, 0x00000000,
60         0x0af50000, 0x0000350b, 0x00000000, 0x00000000,
61         0x00000000, 0x3781087f, 0x00000000, 0x00000000,
62         0x00000000, 0x06660000, 0x0000399a, 0x00000000,
63         0x00000000, 0x00000000, 0x3b5904a7, 0x00000000,
64         0x00000000, 0x00000000, 0x033c0000, 0x00003cc4,
65         0x00000000, 0x00000000, 0x00000000, 0x3de1021f,
66         0x00000000, 0x00000000, 0x00000000, 0x01470000,
67         0x00003eb9, 0x00000000, 0x00000000, 0x00000000,
68         0x3f5300ad, 0x00000000, 0x00000000, 0x00000000,
69         0x00480000, 0x00003fb8, 0x00000000, 0x00000000,
70         0x00000000, 0x3fef0011, 0x00000000, 0x00000000,
71         0x00000000, 0x00000000, 0x00004000, 0x00000000,
72         0xcdcd0000, 0xfdfdfdfd, 0xabababab, 0xabababab,
73         0x00000000, 0x00000000, 0x5ff5f456, 0x000f5f58,
74         0x02cc6c78, 0x02cc0c28, 0xfeeefeee, 0xfeeefeee,
75         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
76         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
77         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
78         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
79         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
80         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
81         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
82         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
83         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
84         0xfeeefeee, 0xfeeefeee, 0xfeeefeee, 0xfeeefeee,
85 };
86 #define V_COEF_SIZE (sizeof(verKernel) / sizeof(u32))
87
88 /*
89  * RGB 709->2020 conversion parameters
90  */
91 static u16 RGB2RGB[RGB_TO_RGB_TABLE_SIZE] = {
92         10279,  5395,   709,
93         1132,   15065,  187,
94         269,    1442,   14674
95 };
96
97 /*
98  * YUV601 to RGB conversion parameters
99  * YUV2RGB[0]  - [8] : C0 - C8;
100  * YUV2RGB[9]  - [11]: D0 - D2;
101  * YUV2RGB[12] - [13]: Y clamp min & max calue;
102  * YUV2RGB[14] - [15]: UV clamp min & max calue;
103  */
104 static s32 YUV601_2RGB[YUV_TO_RGB_TABLE_SIZE] = {
105         1196,   0,                      1640,   1196,
106         -404,   -836,           1196,   2076,
107         0,              -916224,        558336, -1202944,
108         64,              940,           64,             960
109 };
110
111 /*
112  * YUV709 to RGB conversion parameters
113  * YUV2RGB[0]  - [8] : C0 - C8;
114  * YUV2RGB[9]  - [11]: D0 - D2;
115  * YUV2RGB[12] - [13]: Y clamp min & max calue;
116  * YUV2RGB[14] - [15]: UV clamp min & max calue;
117  */
118 static s32 YUV709_2RGB[YUV_TO_RGB_TABLE_SIZE] = {
119         1196,           0,              1844,   1196,
120         -220,           -548,   1196,   2172,
121         0,                      -1020672, 316672,  -1188608,
122         64,                     940,            64,             960
123 };
124
125 /*
126  * YUV2020 to RGB conversion parameters
127  * YUV2RGB[0]  - [8] : C0 - C8;
128  * YUV2RGB[9]  - [11]: D0 - D2;
129  * YUV2RGB[12] - [13]: Y clamp min & max calue;
130  * YUV2RGB[14] - [15]: UV clamp min & max calue;
131  */
132 static s32 YUV2020_2RGB[YUV_TO_RGB_TABLE_SIZE] = {
133         1196, 0, 1724, 1196,
134         -192, -668, 1196, 2200,
135         0, -959232, 363776, -1202944,
136         64, 940, 64, 960
137 };
138
139 /*
140  * RGB to YUV2020 conversion parameters
141  * RGB2YUV[0] - [8] : C0 - C8;
142  * RGB2YUV[9] - [11]: D0 - D2;
143  */
144 static s16 RGB2YUV[RGB_TO_YUV_TABLE_SIZE] = {
145         230,    594,    52,
146         -125,  -323,    448,
147         448,   -412,   -36,
148         64,             512,    512
149 };
150
151 /*
152  * Degamma table for 709 color space data.
153  */
154 static u16 DEGAMMA_709[DEGAMMA_SIZE] = {
155         0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0005,
156         0x0007, 0x000a, 0x000d, 0x0011, 0x0015, 0x0019, 0x001e, 0x0024,
157         0x002a, 0x0030, 0x0038, 0x003f, 0x0048, 0x0051, 0x005a, 0x0064,
158         0x006f, 0x007b, 0x0087, 0x0094, 0x00a1, 0x00af, 0x00be, 0x00ce,
159         0x00de, 0x00ef, 0x0101, 0x0114, 0x0127, 0x013b, 0x0150, 0x0166,
160         0x017c, 0x0193, 0x01ac, 0x01c4, 0x01de, 0x01f9, 0x0214, 0x0230,
161         0x024d, 0x026b, 0x028a, 0x02aa, 0x02ca, 0x02ec, 0x030e, 0x0331,
162         0x0355, 0x037a, 0x03a0, 0x03c7, 0x03ef, 0x0418, 0x0441, 0x046c,
163         0x0498, 0x04c4, 0x04f2, 0x0520, 0x0550, 0x0581, 0x05b2, 0x05e5,
164         0x0618, 0x064d, 0x0682, 0x06b9, 0x06f0, 0x0729, 0x0763, 0x079d,
165         0x07d9, 0x0816, 0x0854, 0x0893, 0x08d3, 0x0914, 0x0956, 0x0999,
166         0x09dd, 0x0a23, 0x0a69, 0x0ab1, 0x0afa, 0x0b44, 0x0b8f, 0x0bdb,
167         0x0c28, 0x0c76, 0x0cc6, 0x0d17, 0x0d69, 0x0dbb, 0x0e10, 0x0e65,
168         0x0ebb, 0x0f13, 0x0f6c, 0x0fc6, 0x1021, 0x107d, 0x10db, 0x113a,
169         0x119a, 0x11fb, 0x125d, 0x12c1, 0x1325, 0x138c, 0x13f3, 0x145b,
170         0x14c5, 0x1530, 0x159c, 0x160a, 0x1678, 0x16e8, 0x175a, 0x17cc,
171         0x1840, 0x18b5, 0x192b, 0x19a3, 0x1a1c, 0x1a96, 0x1b11, 0x1b8e,
172         0x1c0c, 0x1c8c, 0x1d0c, 0x1d8e, 0x1e12, 0x1e96, 0x1f1c, 0x1fa3,
173         0x202c, 0x20b6, 0x2141, 0x21ce, 0x225c, 0x22eb, 0x237c, 0x240e,
174         0x24a1, 0x2536, 0x25cc, 0x2664, 0x26fc, 0x2797, 0x2832, 0x28cf,
175         0x296e, 0x2a0e, 0x2aaf, 0x2b51, 0x2bf5, 0x2c9b, 0x2d41, 0x2dea,
176         0x2e93, 0x2f3e, 0x2feb, 0x3099, 0x3148, 0x31f9, 0x32ab, 0x335f,
177         0x3414, 0x34ca, 0x3582, 0x363c, 0x36f7, 0x37b3, 0x3871, 0x3930,
178         0x39f1, 0x3ab3, 0x3b77, 0x3c3c, 0x3d02, 0x3dcb, 0x3e94, 0x3f5f,
179         0x402c, 0x40fa, 0x41ca, 0x429b, 0x436d, 0x4442, 0x4517, 0x45ee,
180         0x46c7, 0x47a1, 0x487d, 0x495a, 0x4a39, 0x4b19, 0x4bfb, 0x4cde,
181         0x4dc3, 0x4eaa, 0x4f92, 0x507c, 0x5167, 0x5253, 0x5342, 0x5431,
182         0x5523, 0x5616, 0x570a, 0x5800, 0x58f8, 0x59f1, 0x5aec, 0x5be9,
183         0x5ce7, 0x5de6, 0x5ee7, 0x5fea, 0x60ef, 0x61f5, 0x62fc, 0x6406,
184         0x6510, 0x661d, 0x672b, 0x683b, 0x694c, 0x6a5f, 0x6b73, 0x6c8a,
185         0x6da2, 0x6ebb, 0x6fd6, 0x70f3, 0x7211, 0x7331, 0x7453, 0x7576,
186         0x769b, 0x77c2, 0x78ea, 0x7a14, 0x7b40, 0x7c6d, 0x7d9c, 0x7ecd,
187         0x3f65, 0x3f8c, 0x3fb2, 0x3fd8
188 };
189
190 /*
191  * Degamma table for 2020 color space data.
192  */
193 static u16 DEGAMMA_2020[DEGAMMA_SIZE] = {
194         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
195         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
196         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
197         0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
198         0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0003, 0x0003,
199         0x0003, 0x0003, 0x0004, 0x0004, 0x0004, 0x0005, 0x0005, 0x0006,
200         0x0006, 0x0006, 0x0007, 0x0007, 0x0008, 0x0008, 0x0009, 0x000a,
201         0x000a, 0x000b, 0x000c, 0x000c, 0x000d, 0x000e, 0x000f, 0x000f,
202         0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0016, 0x0017, 0x0018,
203         0x0019, 0x001b, 0x001c, 0x001e, 0x001f, 0x0021, 0x0022, 0x0024,
204         0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030, 0x0033, 0x0035,
205         0x0038, 0x003a, 0x003d, 0x0040, 0x0043, 0x0046, 0x0049, 0x004d,
206         0x0050, 0x0054, 0x0057, 0x005b, 0x005f, 0x0064, 0x0068, 0x006d,
207         0x0071, 0x0076, 0x007c, 0x0081, 0x0086, 0x008c, 0x0092, 0x0098,
208         0x009f, 0x00a5, 0x00ac, 0x00b4, 0x00bb, 0x00c3, 0x00cb, 0x00d3,
209         0x00dc, 0x00e5, 0x00ee, 0x00f8, 0x0102, 0x010c, 0x0117, 0x0123,
210         0x012e, 0x013a, 0x0147, 0x0154, 0x0161, 0x016f, 0x017e, 0x018d,
211         0x019c, 0x01ac, 0x01bd, 0x01ce, 0x01e0, 0x01f3, 0x0206, 0x021a,
212         0x022f, 0x0244, 0x025a, 0x0272, 0x0289, 0x02a2, 0x02bc, 0x02d6,
213         0x02f2, 0x030f, 0x032c, 0x034b, 0x036b, 0x038b, 0x03ae, 0x03d1,
214         0x03f5, 0x041b, 0x0443, 0x046b, 0x0495, 0x04c1, 0x04ee, 0x051d,
215         0x054e, 0x0580, 0x05b4, 0x05ea, 0x0622, 0x065c, 0x0698, 0x06d6,
216         0x0717, 0x075a, 0x079f, 0x07e7, 0x0831, 0x087e, 0x08cd, 0x0920,
217         0x0976, 0x09ce, 0x0a2a, 0x0a89, 0x0aec, 0x0b52, 0x0bbc, 0x0c2a,
218         0x0c9b, 0x0d11, 0x0d8b, 0x0e0a, 0x0e8d, 0x0f15, 0x0fa1, 0x1033,
219         0x10ca, 0x1167, 0x120a, 0x12b2, 0x1360, 0x1415, 0x14d1, 0x1593,
220         0x165d, 0x172e, 0x1806, 0x18e7, 0x19d0, 0x1ac1, 0x1bbb, 0x1cbf,
221         0x1dcc, 0x1ee3, 0x2005, 0x2131, 0x2268, 0x23ab, 0x24fa, 0x2656,
222         0x27be, 0x2934, 0x2ab8, 0x2c4a, 0x2dec, 0x2f9d, 0x315f, 0x3332,
223         0x3516, 0x370d, 0x3916, 0x3b34, 0x3d66, 0x3fad, 0x420b, 0x4480,
224         0x470d, 0x49b3, 0x4c73, 0x4f4e, 0x5246, 0x555a, 0x588e, 0x5be1,
225         0x5f55, 0x62eb, 0x66a6, 0x6a86, 0x6e8c, 0x72bb, 0x7714, 0x7b99,
226         0x3dcb, 0x3e60, 0x3ef5, 0x3f8c
227 };
228
229 /* one is for primary plane and the other is for all overlay planes */
230 static const struct dc_hw_plane_reg dc_plane_reg[] = {
231         {
232         .y_address              = DC_FRAMEBUFFER_ADDRESS,
233         .u_address              = DC_FRAMEBUFFER_U_ADDRESS,
234         .v_address              = DC_FRAMEBUFFER_V_ADDRESS,
235         .y_stride               = DC_FRAMEBUFFER_STRIDE,
236         .u_stride               = DC_FRAMEBUFFER_U_STRIDE,
237         .v_stride               = DC_FRAMEBUFFER_V_STRIDE,
238         .size                   = DC_FRAMEBUFFER_SIZE,
239         .top_left               = DC_FRAMEBUFFER_TOP_LEFT,
240         .bottom_right   = DC_FRAMEBUFFER_BOTTOM_RIGHT,
241         .scale_factor_x                 = DC_FRAMEBUFFER_SCALE_FACTOR_X,
242         .scale_factor_y                 = DC_FRAMEBUFFER_SCALE_FACTOR_Y,
243         .h_filter_coef_index    = DC_FRAMEBUFFER_H_FILTER_COEF_INDEX,
244         .h_filter_coef_data             = DC_FRAMEBUFFER_H_FILTER_COEF_DATA,
245         .v_filter_coef_index    = DC_FRAMEBUFFER_V_FILTER_COEF_INDEX,
246         .v_filter_coef_data             = DC_FRAMEBUFFER_V_FILTER_COEF_DATA,
247         .init_offset                    = DC_FRAMEBUFFER_INIT_OFFSET,
248         .color_key                              = DC_FRAMEBUFFER_COLOR_KEY,
249         .color_key_high                 = DC_FRAMEBUFFER_COLOR_KEY_HIGH,
250         .clear_value                    = DC_FRAMEBUFFER_CLEAR_VALUE,
251         .color_table_index              = DC_FRAMEBUFFER_COLOR_TABLE_INDEX,
252         .color_table_data               = DC_FRAMEBUFFER_COLOR_TABLE_DATA,
253         .scale_config                   = DC_FRAMEBUFFER_SCALE_CONFIG,
254         .water_mark                             = DC_FRAMEBUFFER_WATER_MARK,
255         .degamma_index                  = DC_FRAMEBUFFER_DEGAMMA_INDEX,
256         .degamma_data                   = DC_FRAMEBUFFER_DEGAMMA_DATA,
257         .degamma_ex_data                = DC_FRAMEBUFFER_DEGAMMA_EX_DATA,
258         .src_global_color               = DC_FRAMEBUFFER_SRC_GLOBAL_COLOR,
259         .dst_global_color               = DC_FRAMEBUFFER_DST_GLOBAL_COLOR,
260         .blend_config                   = DC_FRAMEBUFFER_BLEND_CONFIG,
261         .roi_origin                             = DC_FRAMEBUFFER_ROI_ORIGIN,
262         .roi_size                               = DC_FRAMEBUFFER_ROI_SIZE,
263         .YUVToRGBCoef0                  = DC_FRAMEBUFFER_YUVTORGB_COEF0,
264         .YUVToRGBCoef1                  = DC_FRAMEBUFFER_YUVTORGB_COEF1,
265         .YUVToRGBCoef2                  = DC_FRAMEBUFFER_YUVTORGB_COEF2,
266         .YUVToRGBCoef3                  = DC_FRAMEBUFFER_YUVTORGB_COEF3,
267         .YUVToRGBCoef4                  = DC_FRAMEBUFFER_YUVTORGB_COEF4,
268         .YUVToRGBCoefD0                 = DC_FRAMEBUFFER_YUVTORGB_COEFD0,
269         .YUVToRGBCoefD1                 = DC_FRAMEBUFFER_YUVTORGB_COEFD1,
270         .YUVToRGBCoefD2                 = DC_FRAMEBUFFER_YUVTORGB_COEFD2,
271         .YClampBound                    = DC_FRAMEBUFFER_Y_CLAMP_BOUND,
272         .UVClampBound                   = DC_FRAMEBUFFER_UV_CLAMP_BOUND,
273         .RGBToRGBCoef0                  = DC_FRAMEBUFFER_RGBTORGB_COEF0,
274         .RGBToRGBCoef1                  = DC_FRAMEBUFFER_RGBTORGB_COEF1,
275         .RGBToRGBCoef2                  = DC_FRAMEBUFFER_RGBTORGB_COEF2,
276         .RGBToRGBCoef3                  = DC_FRAMEBUFFER_RGBTORGB_COEF3,
277         .RGBToRGBCoef4                  = DC_FRAMEBUFFER_RGBTORGB_COEF4,
278         },
279         {
280         .y_address              = DC_OVERLAY_ADDRESS,
281         .u_address              = DC_OVERLAY_U_ADDRESS,
282         .v_address              = DC_OVERLAY_V_ADDRESS,
283         .y_stride               = DC_OVERLAY_STRIDE,
284         .u_stride               = DC_OVERLAY_U_STRIDE,
285         .v_stride               = DC_OVERLAY_V_STRIDE,
286         .size                   = DC_OVERLAY_SIZE,
287         .top_left               = DC_OVERLAY_TOP_LEFT,
288         .bottom_right   = DC_OVERLAY_BOTTOM_RIGHT,
289         .scale_factor_x = DC_OVERLAY_SCALE_FACTOR_X,
290         .scale_factor_y = DC_OVERLAY_SCALE_FACTOR_Y,
291         .h_filter_coef_index = DC_OVERLAY_H_FILTER_COEF_INDEX,
292         .h_filter_coef_data  = DC_OVERLAY_H_FILTER_COEF_DATA,
293         .v_filter_coef_index = DC_OVERLAY_V_FILTER_COEF_INDEX,
294         .v_filter_coef_data  = DC_OVERLAY_V_FILTER_COEF_DATA,
295         .init_offset             = DC_OVERLAY_INIT_OFFSET,
296         .color_key                       = DC_OVERLAY_COLOR_KEY,
297         .color_key_high                 = DC_OVERLAY_COLOR_KEY_HIGH,
298         .clear_value             = DC_OVERLAY_CLEAR_VALUE,
299         .color_table_index       = DC_OVERLAY_COLOR_TABLE_INDEX,
300         .color_table_data        = DC_OVERLAY_COLOR_TABLE_DATA,
301         .scale_config            = DC_OVERLAY_SCALE_CONFIG,
302         .water_mark                             = DC_OVERLAY_WATER_MARK,
303         .degamma_index           = DC_OVERLAY_DEGAMMA_INDEX,
304         .degamma_data            = DC_OVERLAY_DEGAMMA_DATA,
305         .degamma_ex_data         = DC_OVERLAY_DEGAMMA_EX_DATA,
306         .src_global_color        = DC_OVERLAY_SRC_GLOBAL_COLOR,
307         .dst_global_color        = DC_OVERLAY_DST_GLOBAL_COLOR,
308         .blend_config            = DC_OVERLAY_BLEND_CONFIG,
309         .roi_origin                             = DC_OVERLAY_ROI_ORIGIN,
310         .roi_size                               = DC_OVERLAY_ROI_SIZE,
311         .YUVToRGBCoef0           = DC_OVERLAY_YUVTORGB_COEF0,
312         .YUVToRGBCoef1           = DC_OVERLAY_YUVTORGB_COEF1,
313         .YUVToRGBCoef2           = DC_OVERLAY_YUVTORGB_COEF2,
314         .YUVToRGBCoef3           = DC_OVERLAY_YUVTORGB_COEF3,
315         .YUVToRGBCoef4                  = DC_OVERLAY_YUVTORGB_COEF4,
316         .YUVToRGBCoefD0                 = DC_OVERLAY_YUVTORGB_COEFD0,
317         .YUVToRGBCoefD1                 = DC_OVERLAY_YUVTORGB_COEFD1,
318         .YUVToRGBCoefD2                 = DC_OVERLAY_YUVTORGB_COEFD2,
319         .YClampBound             = DC_OVERLAY_Y_CLAMP_BOUND,
320         .UVClampBound            = DC_OVERLAY_UV_CLAMP_BOUND,
321         .RGBToRGBCoef0           = DC_OVERLAY_RGBTORGB_COEF0,
322         .RGBToRGBCoef1           = DC_OVERLAY_RGBTORGB_COEF1,
323         .RGBToRGBCoef2           = DC_OVERLAY_RGBTORGB_COEF2,
324         .RGBToRGBCoef3           = DC_OVERLAY_RGBTORGB_COEF3,
325         .RGBToRGBCoef4           = DC_OVERLAY_RGBTORGB_COEF4,
326         },
327 };
328
329 #ifdef CONFIG_VERISILICON_MMU
330 static const u32 mmu_reg_base = SE_MMU_REG_BASE;
331
332 static const struct dc_hw_mmu_reg dc_mmu_reg = {
333         .mmu_config = SE_MMU_REG_CONFIG,
334         .mmu_control = SE_MMU_REG_CONTROL,
335         .table_array_size = SE_MMU_REG_TABLE_ARRAY_SIZE,
336         .safe_non_secure = SE_MMU_REG_SAFE_NON_SECUR,
337         .safe_secure = SE_MMU_REG_SAFE_SECURE,
338         .safe_ex = SE_MMU_REG_SAFE_EXT_ADDRESS,
339         .context_pd_entry = SE_MMU_REG_CONTEXT_PD,
340 };
341 #endif
342
343 static const u32 primary_overlay_format0[] = {
344         DRM_FORMAT_XRGB4444,
345         DRM_FORMAT_XBGR4444,
346         DRM_FORMAT_RGBX4444,
347         DRM_FORMAT_BGRX4444,
348         DRM_FORMAT_ARGB4444,
349         DRM_FORMAT_ABGR4444,
350         DRM_FORMAT_RGBA4444,
351         DRM_FORMAT_BGRA4444,
352         DRM_FORMAT_XRGB1555,
353         DRM_FORMAT_XBGR1555,
354         DRM_FORMAT_RGBX5551,
355         DRM_FORMAT_BGRX5551,
356         DRM_FORMAT_ARGB1555,
357         DRM_FORMAT_ABGR1555,
358         DRM_FORMAT_RGBA5551,
359         DRM_FORMAT_BGRA5551,
360         DRM_FORMAT_RGB565,
361         DRM_FORMAT_BGR565,
362         DRM_FORMAT_XRGB8888,
363         DRM_FORMAT_XBGR8888,
364         DRM_FORMAT_RGBX8888,
365         DRM_FORMAT_BGRX8888,
366         DRM_FORMAT_ARGB8888,
367         DRM_FORMAT_ABGR8888,
368         DRM_FORMAT_RGBA8888,
369         DRM_FORMAT_BGRA8888,
370         DRM_FORMAT_ARGB2101010,
371         DRM_FORMAT_ABGR2101010,
372         DRM_FORMAT_RGBA1010102,
373         DRM_FORMAT_BGRA1010102,
374         DRM_FORMAT_YUYV,
375         DRM_FORMAT_YVYU,
376         DRM_FORMAT_UYVY,
377         DRM_FORMAT_VYUY,
378         DRM_FORMAT_YVU420,
379         DRM_FORMAT_YUV420,
380         DRM_FORMAT_NV12,
381         DRM_FORMAT_NV21,
382         DRM_FORMAT_NV16,
383         DRM_FORMAT_NV61,
384         DRM_FORMAT_P010,
385 };
386
387 static const u32 primary_overlay_format1[] = {
388         DRM_FORMAT_XRGB8888,
389         DRM_FORMAT_XBGR8888,
390         DRM_FORMAT_RGBX8888,
391         DRM_FORMAT_BGRX8888,
392         DRM_FORMAT_ARGB8888,
393         DRM_FORMAT_ABGR8888,
394         DRM_FORMAT_RGBA8888,
395         DRM_FORMAT_BGRA8888,
396         DRM_FORMAT_ARGB2101010,
397         DRM_FORMAT_ABGR2101010,
398         DRM_FORMAT_RGBA1010102,
399         DRM_FORMAT_BGRA1010102,
400         DRM_FORMAT_NV12,
401         DRM_FORMAT_NV21,
402         DRM_FORMAT_YUV444,
403 };
404
405 static const u32 cursor_formats[] = {
406         DRM_FORMAT_ARGB8888
407 };
408
409 static const u64 format_modifier0[] = {
410         DRM_FORMAT_MOD_LINEAR,
411         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_LINEAR),
412         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_SUPER_TILED_XMAJOR),
413         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_SUPER_TILED_YMAJOR),
414         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_TILE_8X8),
415         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_TILE_8X4),
416         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_SUPER_TILED_XMAJOR_8X4),
417         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_SUPER_TILED_YMAJOR_4X8),
418 #ifdef CONFIG_VERISILICON_DEC
419         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_TILE_8X8_XMAJOR,
420                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
421         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_TILE_8X4,
422                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
423         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_TILE_4X8,
424                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
425         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_RASTER_256X1,
426                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
427         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_RASTER_128X1,
428                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
429         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_RASTER_64X1,
430                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
431         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_TILE_16X8,
432                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
433         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_RASTER_32X1,
434                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
435         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_TILE_32X8,
436                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
437 #endif
438         DRM_FORMAT_MOD_INVALID
439 };
440
441 static const u64 format_modifier1[] = {
442         DRM_FORMAT_MOD_LINEAR,
443         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_LINEAR),
444         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_SUPER_TILED_XMAJOR),
445         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_SUPER_TILED_YMAJOR),
446         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_TILE_8X8),
447         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_TILE_8X4),
448         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_SUPER_TILED_XMAJOR_8X4),
449         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_SUPER_TILED_YMAJOR_4X8),
450         fourcc_mod_vs_norm_code(DRM_FORMAT_MOD_VS_TILE_MODE4X4),
451         fourcc_mod_vs_custom_code(DRM_FORMAT_MOD_VS_TILE_MODE4X4),
452         DRM_FORMAT_MOD_INVALID
453 };
454
455 static const u64 secondary_format_modifiers[] = {
456         DRM_FORMAT_MOD_LINEAR,
457 #ifdef CONFIG_VERISILICON_DEC
458         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_RASTER_256X1,
459                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
460         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_RASTER_128X1,
461                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
462         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_RASTER_64X1,
463                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
464         fourcc_mod_vs_dec_code(DRM_FORMAT_MOD_VS_DEC_RASTER_32X1,
465                                         DRM_FORMAT_MOD_VS_DEC_ALIGN_32),
466 #endif
467         DRM_FORMAT_MOD_INVALID
468 };
469
470 #define FRAC_16_16(mult, div)    (((mult) << 16) / (div))
471
472 static const struct vs_plane_info dc_hw_planes[][PLANE_NUM] = {
473         {
474                 /* DC_REV_0 */
475                 {
476                 .name                   = "Primary",
477                 .id                             = PRIMARY_PLANE_0,
478                 .type                   = DRM_PLANE_TYPE_PRIMARY,
479                 .num_formats    = ARRAY_SIZE(primary_overlay_format0),
480                 .formats                = primary_overlay_format0,
481                 .num_modifiers  = ARRAY_SIZE(format_modifier0),
482                 .modifiers              = format_modifier0,
483                 .min_width              = 0,
484                 .min_height             = 0,
485                 .max_width              = 4096,
486                 .max_height             = 4096,
487                 .rotation               = DRM_MODE_ROTATE_0 |
488                                                         DRM_MODE_ROTATE_90 |
489                                                         DRM_MODE_ROTATE_180 |
490                                                         DRM_MODE_ROTATE_270 |
491                                                         DRM_MODE_REFLECT_X |
492                                                         DRM_MODE_REFLECT_Y,
493                 .blend_mode             = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
494                                                         BIT(DRM_MODE_BLEND_PREMULTI) |
495                                                         BIT(DRM_MODE_BLEND_COVERAGE),
496                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
497                                                   BIT(DRM_COLOR_YCBCR_BT2020),
498                 .degamma_size   = DEGAMMA_SIZE,
499                 .min_scale       = FRAC_16_16(1, 3),
500                 .max_scale       = FRAC_16_16(10, 1),
501                 .zpos            = 0,
502                 .watermark       = true,
503                 .color_mgmt  = true,
504                 .roi             = true,
505                 },
506                 {
507                 .name                   = "Overlay",
508                 .id                             = OVERLAY_PLANE_0,
509                 .type                   = DRM_PLANE_TYPE_OVERLAY,
510                 .num_formats    = ARRAY_SIZE(primary_overlay_format0),
511                 .formats                = primary_overlay_format0,
512                 .num_modifiers  = ARRAY_SIZE(format_modifier0),
513                 .modifiers              = format_modifier0,
514                 .min_width              = 0,
515                 .min_height             = 0,
516                 .max_width              = 4096,
517                 .max_height             = 4096,
518                 .rotation        = DRM_MODE_ROTATE_0 |
519                                            DRM_MODE_ROTATE_90 |
520                                            DRM_MODE_ROTATE_180 |
521                                            DRM_MODE_ROTATE_270 |
522                                            DRM_MODE_REFLECT_X |
523                                            DRM_MODE_REFLECT_Y,
524                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
525                                            BIT(DRM_MODE_BLEND_PREMULTI) |
526                                            BIT(DRM_MODE_BLEND_COVERAGE),
527                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
528                                                   BIT(DRM_COLOR_YCBCR_BT2020),
529                 .degamma_size   = DEGAMMA_SIZE,
530                 .min_scale       = FRAC_16_16(1, 3),
531                 .max_scale       = FRAC_16_16(10, 1),
532                 .zpos            = 1,
533                 .watermark       = true,
534                 .color_mgmt  = true,
535                 .roi             = true,
536                 },
537                 {
538                 .name                   = "Overlay_1",
539                 .id                             = OVERLAY_PLANE_1,
540                 .type                   = DRM_PLANE_TYPE_OVERLAY,
541                 .num_formats    = ARRAY_SIZE(primary_overlay_format0),
542                 .formats                = primary_overlay_format0,
543                 .num_modifiers  = ARRAY_SIZE(secondary_format_modifiers),
544                 .modifiers              = secondary_format_modifiers,
545                 .min_width              = 0,
546                 .min_height             = 0,
547                 .max_width              = 4096,
548                 .max_height             = 4096,
549                 .rotation               = 0,
550                 .blend_mode             = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
551                                                         BIT(DRM_MODE_BLEND_PREMULTI) |
552                                                         BIT(DRM_MODE_BLEND_COVERAGE),
553                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
554                                                   BIT(DRM_COLOR_YCBCR_BT2020),
555                 .degamma_size   = DEGAMMA_SIZE,
556                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
557                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
558                 .zpos            = 2,
559                 .watermark       = true,
560                 .color_mgmt  = true,
561                 .roi             = true,
562                 },
563                 {
564                 .name            = "Primary_1",
565                 .id                             = PRIMARY_PLANE_1,
566                 .type            = DRM_PLANE_TYPE_PRIMARY,
567                 .num_formats = ARRAY_SIZE(primary_overlay_format0),
568                 .formats         = primary_overlay_format0,
569                 .num_modifiers = ARRAY_SIZE(format_modifier0),
570                 .modifiers       = format_modifier0,
571                 .min_width       = 0,
572                 .min_height  = 0,
573                 .max_width       = 4096,
574                 .max_height  = 4096,
575                 .rotation        = DRM_MODE_ROTATE_0 |
576                                            DRM_MODE_ROTATE_90 |
577                                            DRM_MODE_ROTATE_180 |
578                                            DRM_MODE_ROTATE_270 |
579                                            DRM_MODE_REFLECT_X |
580                                            DRM_MODE_REFLECT_Y,
581                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
582                                            BIT(DRM_MODE_BLEND_PREMULTI) |
583                                            BIT(DRM_MODE_BLEND_COVERAGE),
584                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
585                                                   BIT(DRM_COLOR_YCBCR_BT2020),
586                 .degamma_size   = DEGAMMA_SIZE,
587                 .min_scale       = FRAC_16_16(1, 3),
588                 .max_scale       = FRAC_16_16(10, 1),
589                 .zpos            = 3,
590                 .watermark       = true,
591                 .color_mgmt  = true,
592                 .roi             = true,
593                 },
594                 {
595                 .name            = "Overlay_2",
596                 .id                             = OVERLAY_PLANE_2,
597                 .type            = DRM_PLANE_TYPE_OVERLAY,
598                 .num_formats = ARRAY_SIZE(primary_overlay_format0),
599                 .formats         = primary_overlay_format0,
600                 .num_modifiers = ARRAY_SIZE(format_modifier0),
601                 .modifiers       = format_modifier0,
602                 .min_width       = 0,
603                 .min_height  = 0,
604                 .max_width       = 4096,
605                 .max_height  = 4096,
606                 .rotation        = DRM_MODE_ROTATE_0 |
607                                            DRM_MODE_ROTATE_90 |
608                                            DRM_MODE_ROTATE_180 |
609                                            DRM_MODE_ROTATE_270 |
610                                            DRM_MODE_REFLECT_X |
611                                            DRM_MODE_REFLECT_Y,
612                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
613                                            BIT(DRM_MODE_BLEND_PREMULTI) |
614                                            BIT(DRM_MODE_BLEND_COVERAGE),
615                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
616                                                   BIT(DRM_COLOR_YCBCR_BT2020),
617                 .degamma_size   = DEGAMMA_SIZE,
618                 .min_scale       = FRAC_16_16(1, 3),
619                 .max_scale       = FRAC_16_16(10, 1),
620                 .zpos            = 4,
621                 .watermark       = true,
622                 .color_mgmt  = true,
623                 .roi             = true,
624                 },
625                 {
626                 .name            = "Overlay_3",
627                 .id                     = OVERLAY_PLANE_3,
628                 .type            = DRM_PLANE_TYPE_OVERLAY,
629                 .num_formats = ARRAY_SIZE(primary_overlay_format0),
630                 .formats         = primary_overlay_format0,
631                 .num_modifiers = ARRAY_SIZE(secondary_format_modifiers),
632                 .modifiers       = secondary_format_modifiers,
633                 .min_width       = 0,
634                 .min_height  = 0,
635                 .max_width       = 4096,
636                 .max_height  = 4096,
637                 .rotation        = 0,
638                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
639                                            BIT(DRM_MODE_BLEND_PREMULTI) |
640                                            BIT(DRM_MODE_BLEND_COVERAGE),
641                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
642                                                   BIT(DRM_COLOR_YCBCR_BT2020),
643                 .degamma_size   = DEGAMMA_SIZE,
644                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
645                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
646                 .zpos            = 5,
647                 .watermark       = true,
648                 .color_mgmt  = true,
649                 .roi             = true,
650                 },
651                 {
652                 .name            = "Cursor",
653                 .id                             = CURSOR_PLANE_0,
654                 .type            = DRM_PLANE_TYPE_CURSOR,
655                 .num_formats = ARRAY_SIZE(cursor_formats),
656                 .formats         = cursor_formats,
657                 .num_modifiers = 0,
658                 .modifiers       = NULL,
659                 .min_width       = 32,
660                 .min_height  = 32,
661                 .max_width       = 64,
662                 .max_height  = 64,
663                 .rotation        = 0,
664                 .degamma_size = 0,
665                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
666                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
667                 .zpos            = 255,
668                 .watermark       = false,
669                 .color_mgmt  = false,
670                 .roi             = false,
671                 },
672                 {
673                 .name            = "Cursor_1",
674                 .id                             = CURSOR_PLANE_1,
675                 .type            = DRM_PLANE_TYPE_CURSOR,
676                 .num_formats = ARRAY_SIZE(cursor_formats),
677                 .formats         = cursor_formats,
678                 .num_modifiers = 0,
679                 .modifiers       = NULL,
680                 .min_width       = 32,
681                 .min_height  = 32,
682                 .max_width       = 64,
683                 .max_height  = 64,
684                 .rotation        = 0,
685                 .degamma_size = 0,
686                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
687                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
688                 .zpos            = 255,
689                 .watermark       = false,
690                 .color_mgmt  = false,
691                 .roi             = false,
692                 },
693         },
694         {
695                 /* DC_REV_1 */
696                 {
697                 .name            = "Primary",
698                 .id                             = PRIMARY_PLANE_0,
699                 .type            = DRM_PLANE_TYPE_PRIMARY,
700                 .num_formats = ARRAY_SIZE(primary_overlay_format0),
701                 .formats         = primary_overlay_format0,
702                 .num_modifiers = ARRAY_SIZE(format_modifier0),
703                 .modifiers       = format_modifier0,
704                 .min_width       = 0,
705                 .min_height  = 0,
706                 .max_width       = 4096,
707                 .max_height  = 4096,
708                 .rotation        = DRM_MODE_ROTATE_0 |
709                                            DRM_MODE_ROTATE_90 |
710                                            DRM_MODE_ROTATE_180 |
711                                            DRM_MODE_ROTATE_270 |
712                                            DRM_MODE_REFLECT_X |
713                                            DRM_MODE_REFLECT_Y,
714                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
715                                            BIT(DRM_MODE_BLEND_PREMULTI) |
716                                            BIT(DRM_MODE_BLEND_COVERAGE),
717                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
718                                                   BIT(DRM_COLOR_YCBCR_BT2020),
719                 .degamma_size   = DEGAMMA_SIZE,
720                 .min_scale       = FRAC_16_16(1, 3),
721                 .max_scale       = FRAC_16_16(10, 1),
722                 .zpos            = 0,
723                 .watermark       = true,
724                 .color_mgmt  = true,
725                 .roi             = true,
726                 },
727                 {
728                 .name            = "Overlay",
729                 .id                             = OVERLAY_PLANE_0,
730                 .type            = DRM_PLANE_TYPE_OVERLAY,
731                 .num_formats = ARRAY_SIZE(primary_overlay_format0),
732                 .formats         = primary_overlay_format0,
733                 .num_modifiers = ARRAY_SIZE(format_modifier0),
734                 .modifiers       = format_modifier0,
735                 .min_width       = 0,
736                 .min_height  = 0,
737                 .max_width       = 4096,
738                 .max_height  = 4096,
739                 .rotation        = DRM_MODE_ROTATE_0 |
740                                            DRM_MODE_ROTATE_90 |
741                                            DRM_MODE_ROTATE_180 |
742                                            DRM_MODE_ROTATE_270 |
743                                            DRM_MODE_REFLECT_X |
744                                            DRM_MODE_REFLECT_Y,
745                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
746                                            BIT(DRM_MODE_BLEND_PREMULTI) |
747                                            BIT(DRM_MODE_BLEND_COVERAGE),
748                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
749                                                   BIT(DRM_COLOR_YCBCR_BT2020),
750                 .degamma_size   = DEGAMMA_SIZE,
751                 .min_scale       = FRAC_16_16(1, 3),
752                 .max_scale       = FRAC_16_16(10, 1),
753                 .zpos            = 1,
754                 .watermark       = true,
755                 .color_mgmt  = true,
756                 .roi             = true,
757                 },
758                 {
759                 .name            = "Primary_1",
760                 .id                             = PRIMARY_PLANE_1,
761                 .type            = DRM_PLANE_TYPE_PRIMARY,
762                 .num_formats = ARRAY_SIZE(primary_overlay_format0),
763                 .formats         = primary_overlay_format0,
764                 .num_modifiers = ARRAY_SIZE(format_modifier0),
765                 .modifiers       = format_modifier0,
766                 .min_width       = 0,
767                 .min_height  = 0,
768                 .max_width       = 4096,
769                 .max_height  = 4096,
770                 .rotation        = DRM_MODE_ROTATE_0 |
771                                            DRM_MODE_ROTATE_90 |
772                                            DRM_MODE_ROTATE_180 |
773                                            DRM_MODE_ROTATE_270 |
774                                            DRM_MODE_REFLECT_X |
775                                            DRM_MODE_REFLECT_Y,
776                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
777                                            BIT(DRM_MODE_BLEND_PREMULTI) |
778                                            BIT(DRM_MODE_BLEND_COVERAGE),
779                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
780                                                   BIT(DRM_COLOR_YCBCR_BT2020),
781                 .degamma_size   = DEGAMMA_SIZE,
782                 .min_scale       = FRAC_16_16(1, 3),
783                 .max_scale       = FRAC_16_16(10, 1),
784                 .zpos            = 2,
785                 .watermark       = true,
786                 .color_mgmt  = true,
787                 .roi             = true,
788                 },
789                 {
790                 .name            = "Overlay_2",
791                 .id                             = OVERLAY_PLANE_2,
792                 .type            = DRM_PLANE_TYPE_OVERLAY,
793                 .num_formats = ARRAY_SIZE(primary_overlay_format0),
794                 .formats         = primary_overlay_format0,
795                 .num_modifiers = ARRAY_SIZE(format_modifier0),
796                 .modifiers       = format_modifier0,
797                 .min_width       = 0,
798                 .min_height  = 0,
799                 .max_width       = 4096,
800                 .max_height  = 4096,
801                 .rotation        = DRM_MODE_ROTATE_0 |
802                                            DRM_MODE_ROTATE_90 |
803                                            DRM_MODE_ROTATE_180 |
804                                            DRM_MODE_ROTATE_270 |
805                                            DRM_MODE_REFLECT_X |
806                                            DRM_MODE_REFLECT_Y,
807                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
808                                            BIT(DRM_MODE_BLEND_PREMULTI) |
809                                            BIT(DRM_MODE_BLEND_COVERAGE),
810                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
811                                                   BIT(DRM_COLOR_YCBCR_BT2020),
812                 .degamma_size   = DEGAMMA_SIZE,
813                 .min_scale       = FRAC_16_16(1, 3),
814                 .max_scale       = FRAC_16_16(10, 1),
815                 .zpos            = 3,
816                 .watermark       = true,
817                 .color_mgmt  = true,
818                 .roi             = true,
819                 },
820                 {
821                 .name            = "Cursor",
822                 .id                             = CURSOR_PLANE_0,
823                 .type            = DRM_PLANE_TYPE_CURSOR,
824                 .num_formats = ARRAY_SIZE(cursor_formats),
825                 .formats         = cursor_formats,
826                 .num_modifiers = 0,
827                 .modifiers       = NULL,
828                 .min_width       = 32,
829                 .min_height  = 32,
830                 .max_width       = 64,
831                 .max_height  = 64,
832                 .rotation        = 0,
833                 .degamma_size = 0,
834                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
835                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
836                 .zpos            = 255,
837                 .watermark       = false,
838                 .color_mgmt  = false,
839                 .roi             = false,
840                 },
841                 {
842                 .name            = "Cursor_1",
843                 .id                             = CURSOR_PLANE_1,
844                 .type            = DRM_PLANE_TYPE_CURSOR,
845                 .num_formats = ARRAY_SIZE(cursor_formats),
846                 .formats         = cursor_formats,
847                 .num_modifiers = 0,
848                 .modifiers       = NULL,
849                 .min_width       = 32,
850                 .min_height  = 32,
851                 .max_width       = 64,
852                 .max_height  = 64,
853                 .rotation        = 0,
854                 .degamma_size = 0,
855                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
856                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
857                 .zpos            = 255,
858                 .watermark       = false,
859                 .color_mgmt  = false,
860                 .roi             = false,
861                 },
862         },
863         {
864                 /* DC_REV_2 */
865                 {
866                 .name            = "Primary",
867                 .id                             = PRIMARY_PLANE_0,
868                 .type            = DRM_PLANE_TYPE_PRIMARY,
869                 .num_formats = ARRAY_SIZE(primary_overlay_format1),
870                 .formats         = primary_overlay_format1,
871                 .num_modifiers = ARRAY_SIZE(format_modifier1),
872                 .modifiers       = format_modifier1,
873                 .min_width       = 0,
874                 .min_height  = 0,
875                 .max_width       = 4096,
876                 .max_height  = 4096,
877                 .rotation        = DRM_MODE_ROTATE_0 |
878                                            DRM_MODE_ROTATE_90 |
879                                            DRM_MODE_ROTATE_180 |
880                                            DRM_MODE_ROTATE_270 |
881                                            DRM_MODE_REFLECT_X |
882                                            DRM_MODE_REFLECT_Y,
883                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
884                                            BIT(DRM_MODE_BLEND_PREMULTI) |
885                                            BIT(DRM_MODE_BLEND_COVERAGE),
886                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
887                                                   BIT(DRM_COLOR_YCBCR_BT2020),
888                 .degamma_size   = DEGAMMA_SIZE,
889                 .min_scale       = FRAC_16_16(1, 3),
890                 .max_scale       = FRAC_16_16(10, 1),
891                 .zpos            = 0,
892                 .watermark       = true,
893                 .color_mgmt  = true,
894                 .roi             = true,
895                 },
896                 {
897                 .name            = "Overlay",
898                 .id                             = OVERLAY_PLANE_0,
899                 .type            = DRM_PLANE_TYPE_OVERLAY,
900                 .num_formats = ARRAY_SIZE(primary_overlay_format1),
901                 .formats         = primary_overlay_format1,
902                 .num_modifiers = ARRAY_SIZE(format_modifier1),
903                 .modifiers       = format_modifier1,
904                 .min_width       = 0,
905                 .min_height  = 0,
906                 .max_width       = 4096,
907                 .max_height  = 4096,
908                 .rotation        = DRM_MODE_ROTATE_0 |
909                                            DRM_MODE_ROTATE_90 |
910                                            DRM_MODE_ROTATE_180 |
911                                            DRM_MODE_ROTATE_270 |
912                                            DRM_MODE_REFLECT_X |
913                                            DRM_MODE_REFLECT_Y,
914                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
915                                            BIT(DRM_MODE_BLEND_PREMULTI) |
916                                            BIT(DRM_MODE_BLEND_COVERAGE),
917                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
918                                                   BIT(DRM_COLOR_YCBCR_BT2020),
919                 .degamma_size   = DEGAMMA_SIZE,
920                 .min_scale       = FRAC_16_16(1, 3),
921                 .max_scale       = FRAC_16_16(10, 1),
922                 .zpos            = 1,
923                 .watermark       = true,
924                 .color_mgmt  = true,
925                 .roi             = true,
926                 },
927                 {
928                 .name            = "Overlay_1",
929                 .id                             = OVERLAY_PLANE_1,
930                 .type            = DRM_PLANE_TYPE_OVERLAY,
931                 .num_formats = ARRAY_SIZE(primary_overlay_format1),
932                 .formats         = primary_overlay_format1,
933                 .num_modifiers = ARRAY_SIZE(secondary_format_modifiers),
934                 .modifiers       = secondary_format_modifiers,
935                 .min_width       = 0,
936                 .min_height  = 0,
937                 .max_width       = 4096,
938                 .max_height  = 4096,
939                 .rotation        = 0,
940                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
941                                            BIT(DRM_MODE_BLEND_PREMULTI) |
942                                            BIT(DRM_MODE_BLEND_COVERAGE),
943                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
944                                                   BIT(DRM_COLOR_YCBCR_BT2020),
945                 .degamma_size   = DEGAMMA_SIZE,
946                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
947                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
948                 .zpos            = 2,
949                 .watermark       = true,
950                 .color_mgmt  = true,
951                 .roi             = true,
952                 },
953                 {
954                 .name            = "Primary_1",
955                 .id                             = PRIMARY_PLANE_1,
956                 .type            = DRM_PLANE_TYPE_PRIMARY,
957                 .num_formats = ARRAY_SIZE(primary_overlay_format1),
958                 .formats         = primary_overlay_format1,
959                 .num_modifiers = ARRAY_SIZE(format_modifier1),
960                 .modifiers       = format_modifier1,
961                 .min_width       = 0,
962                 .min_height  = 0,
963                 .max_width       = 4096,
964                 .max_height  = 4096,
965                 .rotation        = DRM_MODE_ROTATE_0 |
966                                            DRM_MODE_ROTATE_90 |
967                                            DRM_MODE_ROTATE_180 |
968                                            DRM_MODE_ROTATE_270 |
969                                            DRM_MODE_REFLECT_X |
970                                            DRM_MODE_REFLECT_Y,
971                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
972                                            BIT(DRM_MODE_BLEND_PREMULTI) |
973                                            BIT(DRM_MODE_BLEND_COVERAGE),
974                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
975                                                   BIT(DRM_COLOR_YCBCR_BT2020),
976                 .degamma_size   = DEGAMMA_SIZE,
977                 .min_scale       = FRAC_16_16(1, 3),
978                 .max_scale       = FRAC_16_16(10, 1),
979                 .zpos            = 3,
980                 .watermark       = true,
981                 .color_mgmt  = true,
982                 .roi             = true,
983                 },
984                 {
985                 .name            = "Overlay_2",
986                 .id                             = OVERLAY_PLANE_2,
987                 .type            = DRM_PLANE_TYPE_OVERLAY,
988                 .num_formats = ARRAY_SIZE(primary_overlay_format1),
989                 .formats         = primary_overlay_format1,
990                 .num_modifiers = ARRAY_SIZE(format_modifier1),
991                 .modifiers       = format_modifier1,
992                 .min_width       = 0,
993                 .min_height  = 0,
994                 .max_width       = 4096,
995                 .max_height  = 4096,
996                 .rotation        = DRM_MODE_ROTATE_0 |
997                                            DRM_MODE_ROTATE_90 |
998                                            DRM_MODE_ROTATE_180 |
999                                            DRM_MODE_ROTATE_270 |
1000                                            DRM_MODE_REFLECT_X |
1001                                            DRM_MODE_REFLECT_Y,
1002                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
1003                                            BIT(DRM_MODE_BLEND_PREMULTI) |
1004                                            BIT(DRM_MODE_BLEND_COVERAGE),
1005                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
1006                                                   BIT(DRM_COLOR_YCBCR_BT2020),
1007                 .degamma_size   = DEGAMMA_SIZE,
1008                 .min_scale       = FRAC_16_16(1, 3),
1009                 .max_scale       = FRAC_16_16(10, 1),
1010                 .zpos            = 4,
1011                 .watermark       = true,
1012                 .color_mgmt  = true,
1013                 .roi             = true,
1014                 },
1015                 {
1016                 .name            = "Overlay_3",
1017                 .id                             = OVERLAY_PLANE_3,
1018                 .type            = DRM_PLANE_TYPE_OVERLAY,
1019                 .num_formats = ARRAY_SIZE(primary_overlay_format1),
1020                 .formats         = primary_overlay_format1,
1021                 .num_modifiers = ARRAY_SIZE(secondary_format_modifiers),
1022                 .modifiers       = secondary_format_modifiers,
1023                 .min_width       = 0,
1024                 .min_height  = 0,
1025                 .max_width       = 4096,
1026                 .max_height  = 4096,
1027                 .rotation        = 0,
1028                 .blend_mode  = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
1029                                            BIT(DRM_MODE_BLEND_PREMULTI) |
1030                                            BIT(DRM_MODE_BLEND_COVERAGE),
1031                 .color_encoding = BIT(DRM_COLOR_YCBCR_BT709) |
1032                                                   BIT(DRM_COLOR_YCBCR_BT2020),
1033                 .degamma_size   = DEGAMMA_SIZE,
1034                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
1035                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
1036                 .zpos            = 5,
1037                 .watermark       = true,
1038                 .color_mgmt  = true,
1039                 .roi             = true,
1040                 },
1041                 {
1042                 .name            = "Cursor",
1043                 .id                             = CURSOR_PLANE_0,
1044                 .type            = DRM_PLANE_TYPE_CURSOR,
1045                 .num_formats = ARRAY_SIZE(cursor_formats),
1046                 .formats         = cursor_formats,
1047                 .num_modifiers = 0,
1048                 .modifiers       = NULL,
1049                 .min_width       = 32,
1050                 .min_height  = 32,
1051                 .max_width       = 64,
1052                 .max_height  = 64,
1053                 .rotation        = 0,
1054                 .degamma_size = 0,
1055                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
1056                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
1057                 .zpos            = 255,
1058                 .watermark       = false,
1059                 .color_mgmt  = false,
1060                 .roi             = false,
1061                 },
1062                 {
1063                 .name            = "Cursor_1",
1064                 .id                             = CURSOR_PLANE_1,
1065                 .type            = DRM_PLANE_TYPE_CURSOR,
1066                 .num_formats = ARRAY_SIZE(cursor_formats),
1067                 .formats         = cursor_formats,
1068                 .num_modifiers = 0,
1069                 .modifiers       = NULL,
1070                 .min_width       = 32,
1071                 .min_height  = 32,
1072                 .max_width       = 64,
1073                 .max_height  = 64,
1074                 .rotation        = 0,
1075                 .degamma_size = 0,
1076                 .min_scale       = DRM_PLANE_HELPER_NO_SCALING,
1077                 .max_scale       = DRM_PLANE_HELPER_NO_SCALING,
1078                 .zpos            = 255,
1079                 .watermark       = false,
1080                 .color_mgmt  = false,
1081                 .roi             = false,
1082                 },
1083         },
1084 };
1085
1086 static const struct vs_dc_info dc_info[] = {
1087         {
1088                 /* DC_REV_0 */
1089                 .name                   = "DC8200",
1090                 .panel_num              = 2,
1091                 .plane_num              = 8,
1092                 .planes                 = dc_hw_planes[DC_REV_0],
1093                 .layer_num              = 6,
1094                 .max_bpc                = 10,
1095                 .color_formats  = DRM_COLOR_FORMAT_RGB444 |
1096                                                   DRM_COLOR_FORMAT_YCRCB444 |
1097                                                   DRM_COLOR_FORMAT_YCRCB422 |
1098                                                   DRM_COLOR_FORMAT_YCRCB420,
1099                 .gamma_size             = GAMMA_EX_SIZE,
1100                 .gamma_bits             = 12,
1101                 .pitch_alignment        = 128,
1102                 .pipe_sync              = false,
1103                 .mmu_prefetch   = false,
1104                 .background             = true,
1105                 .panel_sync             = true,
1106                 .cap_dec                = true,
1107         },
1108         {
1109                 /* DC_REV_1 */
1110                 .name                   = "DC8200",
1111                 .panel_num              = 2,
1112                 .plane_num              = 6,
1113                 .planes                 = dc_hw_planes[DC_REV_1],
1114                 .layer_num              = 4,
1115                 .max_bpc                = 10,
1116                 .color_formats  = DRM_COLOR_FORMAT_RGB444 |
1117                                                   DRM_COLOR_FORMAT_YCRCB444 |
1118                                                   DRM_COLOR_FORMAT_YCRCB422 |
1119                                                   DRM_COLOR_FORMAT_YCRCB420,
1120                 .gamma_size             = GAMMA_EX_SIZE,
1121                 .gamma_bits             = 12,
1122                 .pitch_alignment        = 128,
1123                 .pipe_sync              = false,
1124                 .mmu_prefetch   = false,
1125                 .background             = true,
1126                 .panel_sync             = true,
1127                 .cap_dec                = true,
1128         },
1129         {
1130                 /* DC_REV_2 */
1131                 .name                   = "DC8200",
1132                 .panel_num              = 2,
1133                 .plane_num              = 8,
1134                 .planes                 = dc_hw_planes[DC_REV_2],
1135                 .layer_num              = 6,
1136                 .max_bpc                = 10,
1137                 .color_formats  = DRM_COLOR_FORMAT_RGB444 |
1138                                                   DRM_COLOR_FORMAT_YCRCB444 |
1139                                                   DRM_COLOR_FORMAT_YCRCB422 |
1140                                                   DRM_COLOR_FORMAT_YCRCB420,
1141                 .gamma_size             = GAMMA_EX_SIZE,
1142                 .gamma_bits             = 12,
1143                 .pitch_alignment        = 128,
1144                 .pipe_sync              = false,
1145                 .mmu_prefetch   = false,
1146                 .background             = true,
1147                 .panel_sync             = true,
1148                 .cap_dec                = false,
1149         },
1150 };
1151
1152 static const struct dc_hw_funcs hw_func;
1153
1154 static inline u32 hi_read(struct dc_hw *hw, u32 reg)
1155 {
1156         return readl(hw->hi_base + reg);
1157 }
1158
1159 static inline void hi_write(struct dc_hw *hw, u32 reg, u32 value)
1160 {
1161         writel(value, hw->hi_base + reg);
1162 }
1163
1164 static inline void dc_write(struct dc_hw *hw, u32 reg, u32 value)
1165 {
1166         writel(value, hw->reg_base + reg - DC_REG_BASE);
1167 }
1168
1169 static inline u32 dc_read(struct dc_hw *hw, u32 reg)
1170 {
1171         u32 value = readl(hw->reg_base + reg - DC_REG_BASE);
1172
1173         return value;
1174 }
1175
1176 static inline void dc_set_clear(struct dc_hw *hw, u32 reg, u32 set, u32 clear)
1177 {
1178         u32 value = dc_read(hw, reg);
1179
1180         value &= ~clear;
1181         value |= set;
1182         dc_write(hw, reg, value);
1183 }
1184
1185 static void load_default_filter(struct dc_hw *hw,
1186                                 const struct dc_hw_plane_reg *reg, u32 offset)
1187 {
1188         u8 i;
1189
1190         dc_write(hw, reg->scale_config + offset, 0x33);
1191         dc_write(hw, reg->init_offset + offset, 0x80008000);
1192         dc_write(hw, reg->h_filter_coef_index + offset, 0x00);
1193         for (i = 0; i < H_COEF_SIZE; i++)
1194                 dc_write(hw, reg->h_filter_coef_data + offset, horKernel[i]);
1195
1196         dc_write(hw, reg->v_filter_coef_index + offset, 0x00);
1197         for (i = 0; i < V_COEF_SIZE; i++)
1198                 dc_write(hw, reg->v_filter_coef_data + offset, verKernel[i]);
1199 }
1200
1201 static void load_rgb_to_rgb(struct dc_hw *hw, const struct dc_hw_plane_reg *reg,
1202                                 u32 offset, u16 *table)
1203 {
1204         dc_write(hw, reg->RGBToRGBCoef0 + offset, table[0] | (table[1] << 16));
1205         dc_write(hw, reg->RGBToRGBCoef1 + offset, table[2] | (table[3] << 16));
1206         dc_write(hw, reg->RGBToRGBCoef2 + offset, table[4] | (table[5] << 16));
1207         dc_write(hw, reg->RGBToRGBCoef3 + offset, table[6] | (table[7] << 16));
1208         dc_write(hw, reg->RGBToRGBCoef4 + offset, table[8]);
1209 }
1210
1211 static void load_yuv_to_rgb(struct dc_hw *hw, const struct dc_hw_plane_reg *reg,
1212                                                         u32 offset, s32 *table)
1213 {
1214         dc_write(hw, reg->YUVToRGBCoef0 + offset,
1215                          (0xFFFF & table[0]) | (table[1] << 16));
1216         dc_write(hw, reg->YUVToRGBCoef1 + offset,
1217                          (0xFFFF & table[2]) | (table[3] << 16));
1218         dc_write(hw, reg->YUVToRGBCoef2 + offset,
1219                          (0xFFFF & table[4]) | (table[5] << 16));
1220         dc_write(hw, reg->YUVToRGBCoef3 + offset,
1221                          (0xFFFF & table[6]) | (table[7] << 16));
1222         dc_write(hw, reg->YUVToRGBCoef4 + offset, table[8]);
1223         dc_write(hw, reg->YUVToRGBCoefD0 + offset, table[9]);
1224         dc_write(hw, reg->YUVToRGBCoefD1 + offset, table[10]);
1225         dc_write(hw, reg->YUVToRGBCoefD2 + offset, table[11]);
1226         dc_write(hw, reg->YClampBound + offset, table[12] | (table[13] << 16));
1227         dc_write(hw, reg->UVClampBound + offset, table[14] | (table[15] << 16));
1228 }
1229
1230 static void load_rgb_to_yuv(struct dc_hw *hw, u32 offset, s16 *table)
1231 {
1232         dc_write(hw, DC_DISPLAY_RGBTOYUV_COEF0 + offset,
1233                          table[0] | (table[1] << 16));
1234         dc_write(hw, DC_DISPLAY_RGBTOYUV_COEF1 + offset,
1235                          table[2] | (table[3] << 16));
1236         dc_write(hw, DC_DISPLAY_RGBTOYUV_COEF2 + offset,
1237                          table[4] | (table[5] << 16));
1238         dc_write(hw, DC_DISPLAY_RGBTOYUV_COEF3 + offset,
1239                          table[6] | (table[7] << 16));
1240         dc_write(hw, DC_DISPLAY_RGBTOYUV_COEF4 + offset, table[8]);
1241         dc_write(hw, DC_DISPLAY_RGBTOYUV_COEFD0 + offset, table[9]);
1242         dc_write(hw, DC_DISPLAY_RGBTOYUV_COEFD1 + offset, table[10]);
1243         dc_write(hw, DC_DISPLAY_RGBTOYUV_COEFD2 + offset, table[11]);
1244 }
1245
1246 static bool is_rgb(enum dc_hw_color_format format)
1247 {
1248         switch (format) {
1249         case FORMAT_X4R4G4B4:
1250         case FORMAT_A4R4G4B4:
1251         case FORMAT_X1R5G5B5:
1252         case FORMAT_A1R5G5B5:
1253         case FORMAT_R5G6B5:
1254         case FORMAT_X8R8G8B8:
1255         case FORMAT_A8R8G8B8:
1256         case FORMAT_A2R10G10B10:
1257                 return true;
1258         default:
1259                 return false;
1260         }
1261 }
1262
1263 static void load_degamma_table(struct dc_hw *hw,
1264                                    const struct dc_hw_plane_reg *reg,
1265                                    u32 offset, u16 *table)
1266 {
1267         u16 i;
1268         u32 value;
1269
1270         dc_write(hw, reg->degamma_index + offset, 0);
1271
1272         for (i = 0; i < DEGAMMA_SIZE; i++) {
1273                 value = table[i] | (table[i] << 16);
1274                 dc_write(hw, reg->degamma_data + offset, value);
1275                 dc_write(hw, reg->degamma_ex_data + offset, table[i]);
1276         }
1277 }
1278
1279 static u32 get_addr_offset(u32 id)
1280 {
1281         u32 offset = 0;
1282
1283         switch (id) {
1284         case PRIMARY_PLANE_1:
1285         case OVERLAY_PLANE_1:
1286                 offset = 0x04;
1287                 break;
1288         case OVERLAY_PLANE_2:
1289                 offset = 0x08;
1290                 break;
1291         case OVERLAY_PLANE_3:
1292                 offset = 0x0C;
1293                 break;
1294         default:
1295                 break;
1296         }
1297
1298         return offset;
1299 }
1300
1301 int dc_hw_init(struct dc_hw *hw)
1302 {
1303         u8 i, id, panel_num, layer_num;
1304         u32 offset;
1305         u32 revision = hi_read(hw, DC_HW_REVISION);
1306         u32 cid = hi_read(hw, DC_HW_CHIP_CID);
1307         const struct dc_hw_plane_reg *reg;
1308
1309         switch (revision) {
1310         case 0x5720:
1311                 hw->rev = DC_REV_0;
1312                 break;
1313         case 0x5721:
1314                 switch (cid) {
1315                 case 0x30B:
1316                         hw->rev = DC_REV_1;
1317                         break;
1318                 case 0x310:
1319                         hw->rev = DC_REV_2;
1320                         break;
1321                 default:
1322                         hw->rev = DC_REV_0;
1323                         break;
1324                 }
1325                 break;
1326         default:
1327                 return -ENXIO;
1328         }
1329
1330         hw->info = (struct vs_dc_info *)&dc_info[hw->rev];
1331         hw->func = (struct dc_hw_funcs *)&hw_func;
1332
1333         layer_num = hw->info->layer_num;
1334         for (i = 0; i < layer_num; i++) {
1335                 id = hw->info->planes[i].id;
1336                 offset = get_addr_offset(id);
1337                 if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1)
1338                         reg = &dc_plane_reg[0];
1339                 else
1340                         reg = &dc_plane_reg[1];
1341
1342                 load_default_filter(hw, reg, offset);
1343                 load_rgb_to_rgb(hw, reg, offset, RGB2RGB);
1344
1345         }
1346
1347         panel_num = hw->info->panel_num;
1348         for (i = 0; i < panel_num; i++) {
1349                 offset = i << 2;
1350
1351                 load_rgb_to_yuv(hw, offset, RGB2YUV);
1352                 dc_write(hw, DC_DISPLAY_PANEL_CONFIG + offset, 0x111);
1353
1354                 offset = i ? DC_CURSOR_OFFSET : 0;
1355                 dc_write(hw, DC_CURSOR_BACKGROUND + offset, 0x00FFFFFF);
1356                 dc_write(hw, DC_CURSOR_FOREGROUND + offset, 0x00AAAAAA);
1357
1358         }
1359
1360         return 0;
1361 }
1362
1363 void dc_hw_deinit(struct dc_hw *hw)
1364 {
1365         /* Nothing to do */
1366 }
1367
1368 void dc_hw_update_plane(struct dc_hw *hw, u8 id,
1369                         struct dc_hw_fb *fb, struct dc_hw_scale *scale,
1370                         struct dc_hw_position *pos, struct dc_hw_blend *blend)
1371 {
1372         struct dc_hw_plane *plane = &hw->plane[id];
1373
1374         if (plane) {
1375                 if (fb) {
1376                         if (fb->enable == false)
1377                                 plane->fb.enable = false;
1378                         else
1379                                 memcpy(&plane->fb, fb,
1380                                            sizeof(*fb) - sizeof(fb->dirty));
1381                         plane->fb.dirty = true;
1382                 }
1383                 if (scale) {
1384                         memcpy(&plane->scale, scale,
1385                                    sizeof(*scale) - sizeof(scale->dirty));
1386                         plane->scale.dirty = true;
1387                 }
1388                 if (pos) {
1389                         memcpy(&plane->pos, pos,
1390                                    sizeof(*pos) - sizeof(pos->dirty));
1391                         plane->pos.dirty = true;
1392                 }
1393                 if (blend) {
1394                         memcpy(&plane->blend, blend,
1395                                    sizeof(*blend) - sizeof(blend->dirty));
1396                         plane->blend.dirty = true;
1397                 }
1398         }
1399 }
1400
1401 void dc_hw_update_degamma(struct dc_hw *hw, u8 id, u32 mode)
1402 {
1403         struct dc_hw_plane *plane = &hw->plane[id];
1404
1405         if (plane) {
1406                 if (hw->info->planes[id].degamma_size) {
1407                         plane->degamma.mode = mode;
1408                         plane->degamma.dirty = true;
1409                 } else {
1410                         plane->degamma.dirty = false;
1411                 }
1412         }
1413 }
1414
1415 void dc_hw_update_roi(struct dc_hw *hw, u8 id, struct dc_hw_roi *roi)
1416 {
1417         struct dc_hw_plane *plane = &hw->plane[id];
1418
1419         if (plane) {
1420                 memcpy(&plane->roi, roi, sizeof(*roi) - sizeof(roi->dirty));
1421                 plane->roi.dirty = true;
1422         }
1423 }
1424
1425 void dc_hw_update_colorkey(struct dc_hw *hw, u8 id,
1426                                                    struct dc_hw_colorkey *colorkey)
1427 {
1428         struct dc_hw_plane *plane = &hw->plane[id];
1429
1430         if (plane) {
1431                 memcpy(&plane->colorkey, colorkey,
1432                            sizeof(*colorkey) - sizeof(colorkey->dirty));
1433                 plane->colorkey.dirty = true;
1434         }
1435 }
1436
1437 void dc_hw_update_qos(struct dc_hw *hw, struct dc_hw_qos *qos)
1438 {
1439         memcpy(&hw->qos, qos, sizeof(*qos) - sizeof(qos->dirty));
1440         hw->qos.dirty = true;
1441 }
1442
1443 void dc_hw_update_cursor(struct dc_hw *hw, u8 id, struct dc_hw_cursor *cursor)
1444 {
1445         memcpy(&hw->cursor[id], cursor, sizeof(*cursor) - sizeof(cursor->dirty));
1446         hw->cursor[id].dirty = true;
1447 }
1448
1449 void dc_hw_update_gamma(struct dc_hw *hw, u8 id, u16 index,
1450                                                 u16 r, u16 g, u16 b)
1451 {
1452         if (index >= hw->info->gamma_size)
1453                 return;
1454
1455         hw->gamma[id].gamma[index][0] = r;
1456         hw->gamma[id].gamma[index][1] = g;
1457         hw->gamma[id].gamma[index][2] = b;
1458         hw->gamma[id].dirty = true;
1459 }
1460
1461 void dc_hw_enable_gamma(struct dc_hw *hw, u8 id, bool enable)
1462 {
1463         hw->gamma[id].enable = enable;
1464         hw->gamma[id].dirty = true;
1465 }
1466
1467 void dc_hw_enable_dump(struct dc_hw *hw, u32 addr, u32 pitch)
1468 {
1469         dc_write(hw, 0x14F0, addr);
1470         dc_write(hw, 0x14E8, addr);
1471         dc_write(hw, 0x1500, pitch);
1472         dc_write(hw, 0x14F8, 0x30000);
1473 }
1474
1475 void dc_hw_disable_dump(struct dc_hw *hw)
1476 {
1477         dc_write(hw, 0x14F8, 0x00);
1478 }
1479
1480 void dc_hw_setup_display(struct dc_hw *hw, struct dc_hw_display *display)
1481 {
1482         u8 id = display->id;
1483
1484         memcpy(&hw->display[id], display, sizeof(*display));
1485
1486         hw->func->display(hw, display);
1487 }
1488
1489 void dc_hw_enable_interrupt(struct dc_hw *hw, bool enable)
1490 {
1491         u8 id = 1;//display->id;
1492
1493         if (enable) {
1494                 if (hw->display[id].sync_enable)
1495                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(2) | BIT(3), 0);
1496                 else if (id == 0)
1497                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(0), BIT(3));
1498                 else
1499                         if (hw->out[id] == OUT_DPI)
1500                                 dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(1), BIT(3));
1501
1502                 hi_write(hw, AQ_INTR_ENBL, 0xFFFFFFFF);
1503         } else {
1504                 hi_write(hw, AQ_INTR_ENBL, 0);
1505         }
1506 }
1507
1508 u32 dc_hw_get_interrupt(struct dc_hw *hw)
1509 {
1510         return hi_read(hw, AQ_INTR_ACKNOWLEDGE);
1511 }
1512
1513 bool dc_hw_check_underflow(struct dc_hw *hw)
1514 {
1515         return dc_read(hw, DC_FRAMEBUFFER_CONFIG) & BIT(5);
1516 }
1517
1518 void dc_hw_enable_shadow_register(struct dc_hw *hw, bool enable)
1519 {
1520         u32 i, offset;
1521         u8 id, layer_num = hw->info->layer_num;
1522         u8 panel_num = hw->info->panel_num;
1523
1524         for (i = 0; i < layer_num; i++) {
1525                 id = hw->info->planes[i].id;
1526                 offset = get_addr_offset(id);
1527                 if (enable) {
1528                         if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1)
1529                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset, BIT(12), 0);
1530                         else
1531                                 dc_set_clear(hw, DC_OVERLAY_CONFIG + offset, BIT(31), 0);
1532                 } else {
1533                         if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1)
1534                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset, 0, BIT(12));
1535                         else
1536                                 dc_set_clear(hw, DC_OVERLAY_CONFIG + offset, 0, BIT(31));
1537                 }
1538         }
1539
1540         for (i = 0; i < panel_num; i++) {
1541                 offset = i << 2;
1542                 if (enable)
1543                         dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG_EX + offset, 0, BIT(0));
1544                 else
1545                         dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG_EX + offset, BIT(0), 0);
1546         }
1547 }
1548
1549 void dc_hw_set_out(struct dc_hw *hw, enum dc_hw_out out, u8 id)
1550 {
1551         if (out <= OUT_DP)
1552                 hw->out[id] = out;
1553 }
1554
1555 static void gamma_ex_commit(struct dc_hw *hw)
1556 {
1557         u8 panel_num = hw->info->panel_num;
1558         u16 i, j;
1559         u32 value;
1560
1561         for (j = 0; j < panel_num; j++) {
1562                 if (hw->gamma[j].dirty) {
1563                         if (hw->gamma[j].enable) {
1564                                 dc_write(hw, DC_DISPLAY_GAMMA_EX_INDEX + (j << 2), 0x00);
1565                                 for (i = 0; i < GAMMA_EX_SIZE; i++) {
1566                                         value = hw->gamma[j].gamma[i][2] |
1567                                                 (hw->gamma[j].gamma[i][1] << 12);
1568                                         dc_write(hw, DC_DISPLAY_GAMMA_EX_DATA + (j << 2), value);
1569                                         dc_write(hw, DC_DISPLAY_GAMMA_EX_ONE_DATA + (j << 2),
1570                                                  hw->gamma[j].gamma[i][0]);
1571                                 }
1572                                 dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + (j << 2),
1573                                                          BIT(13), 0);
1574                         } else {
1575                                 dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + (j << 2),
1576                                                          0, BIT(13));
1577                         }
1578                         hw->gamma[j].dirty = false;
1579                 }
1580         }
1581 }
1582
1583 static void plane_commit(struct dc_hw *hw)
1584 {
1585         struct dc_hw_plane *plane;
1586         const struct dc_hw_plane_reg *reg;
1587         bool primary = false;
1588         u8 id, layer_num = hw->info->layer_num;
1589         u32 i, offset;
1590
1591         for (i = 0; i < layer_num; i++) {
1592                 plane = &hw->plane[i];
1593                 id = hw->info->planes[i].id;
1594                 offset = get_addr_offset(id);
1595                 if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1) {
1596                         reg = &dc_plane_reg[0];
1597                         primary = true;
1598                 } else {
1599                         reg = &dc_plane_reg[1];
1600                         primary = false;
1601                 }
1602
1603                 if (plane->fb.dirty) {
1604                         if (plane->fb.enable) {
1605                                 dc_write(hw, reg->y_address + offset,
1606                                          plane->fb.y_address);
1607                                 dc_write(hw, reg->u_address + offset,
1608                                          plane->fb.u_address);
1609                                 dc_write(hw, reg->v_address + offset,
1610                                          plane->fb.v_address);
1611                                 dc_write(hw, reg->y_stride + offset,
1612                                          plane->fb.y_stride);
1613                                 dc_write(hw, reg->u_stride + offset,
1614                                          plane->fb.u_stride);
1615                                 dc_write(hw, reg->v_stride + offset,
1616                                          plane->fb.v_stride);
1617                                 dc_write(hw, reg->size + offset,
1618                                          plane->fb.width |
1619                                          (plane->fb.height << 15));
1620                                 dc_write(hw, reg->water_mark + offset,
1621                                          plane->fb.water_mark);
1622
1623                                 if (plane->fb.clear_enable)
1624                                         dc_write(hw, reg->clear_value + offset,
1625                                                 plane->fb.clear_value);
1626                         }
1627
1628                         if (primary) {
1629                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG + offset,
1630                                                  (plane->fb.format << 26) |
1631                                                  (plane->fb.uv_swizzle << 25) |
1632                                                  (plane->fb.swizzle << 23) |
1633                                                  (plane->fb.tile_mode << 17) |
1634                                                  (plane->fb.yuv_color_space << 14) |
1635                                                  (plane->fb.rotation << 11) |
1636                                                  (plane->fb.clear_enable << 8),
1637                                                  (0x1F << 26) |
1638                                                  BIT(25) |
1639                                                  (0x03 << 23) |
1640                                                  (0x1F << 17) |
1641                                                  (0x07 << 14) |
1642                                                  (0x07 << 11) |
1643                                                  BIT(8));
1644                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset,
1645                                         (plane->fb.dec_enable << 1) |
1646                                         (plane->fb.enable << 13) |
1647                                         (plane->fb.zpos << 16) |
1648                                         (plane->fb.display_id << 19),
1649                                         BIT(1) | BIT(13) | (0x07 << 16) | BIT(19));
1650                         } else {
1651                                 dc_set_clear(hw, DC_OVERLAY_CONFIG + offset,
1652                                                  (plane->fb.dec_enable << 27) |
1653                                                  (plane->fb.clear_enable << 25) |
1654                                                  (plane->fb.enable << 24) |
1655                                                  (plane->fb.format << 16) |
1656                                                  (plane->fb.uv_swizzle << 15) |
1657                                                  (plane->fb.swizzle << 13) |
1658                                                  (plane->fb.tile_mode << 8) |
1659                                                  (plane->fb.yuv_color_space << 5) |
1660                                                  (plane->fb.rotation << 2),
1661                                                  BIT(27) |
1662                                                  BIT(25) |
1663                                                  BIT(24) |
1664                                                  (0x1F << 16) |
1665                                                  BIT(15) |
1666                                                  (0x03 << 13) |
1667                                                  (0x1F << 8) |
1668                                                  (0x07 << 5) |
1669                                                  (0x07 << 2));
1670                                 dc_set_clear(hw, DC_OVERLAY_CONFIG_EX + offset,
1671                                                  plane->fb.zpos | (plane->fb.display_id << 3),
1672                                                  0x07 | BIT(3));
1673                         }
1674                         plane->fb.dirty = false;
1675                 }
1676
1677                 if (plane->scale.dirty) {
1678                         if (plane->scale.enable) {
1679                                 dc_write(hw, reg->scale_factor_x + offset,
1680                                         plane->scale.scale_factor_x);
1681                                 dc_write(hw, reg->scale_factor_y + offset,
1682                                         plane->scale.scale_factor_y);
1683                                 if (primary)
1684                                         dc_set_clear(hw,
1685                                                          DC_FRAMEBUFFER_CONFIG + offset,
1686                                                          BIT(22), 0);
1687                                 else
1688                                         dc_set_clear(hw,
1689                                                          DC_OVERLAY_SCALE_CONFIG + offset,
1690                                                          BIT(8), 0);
1691                         } else {
1692                                 if (primary)
1693                                         dc_set_clear(hw,
1694                                                          DC_FRAMEBUFFER_CONFIG + offset,
1695                                                          0, BIT(22));
1696                                 else
1697                                         dc_set_clear(hw,
1698                                                          DC_OVERLAY_SCALE_CONFIG + offset,
1699                                                          0, BIT(8));
1700                         }
1701                         plane->scale.dirty = false;
1702                 }
1703
1704                 if (plane->pos.dirty) {
1705                         dc_write(hw, reg->top_left + offset,
1706                                 plane->pos.start_x |
1707                                 (plane->pos.start_y << 15));
1708                         dc_write(hw, reg->bottom_right + offset,
1709                                 plane->pos.end_x |
1710                                 (plane->pos.end_y << 15));
1711                         plane->pos.dirty = false;
1712                 }
1713
1714                 if (plane->blend.dirty) {
1715                         dc_write(hw, reg->src_global_color + offset,
1716                                          plane->blend.alpha << 24);
1717                         dc_write(hw, reg->dst_global_color + offset,
1718                                          plane->blend.alpha << 24);
1719                         switch (plane->blend.blend_mode) {
1720                         case BLEND_PREMULTI:
1721                                 dc_write(hw, reg->blend_config + offset, 0x3450);
1722                                 break;
1723                         case BLEND_COVERAGE:
1724                                 dc_write(hw, reg->blend_config + offset, 0x3950);
1725                                 break;
1726                         case BLEND_PIXEL_NONE:
1727                                 dc_write(hw, reg->blend_config + offset, 0x3548);
1728                                 break;
1729                         default:
1730                                 break;
1731                         }
1732                         plane->blend.dirty = false;
1733                 }
1734
1735                 if (plane->colorkey.dirty) {
1736                         dc_write(hw, reg->color_key + offset, plane->colorkey.colorkey);
1737                         dc_write(hw, reg->color_key_high + offset,
1738                                          plane->colorkey.colorkey_high);
1739
1740                         if (primary)
1741                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG + offset,
1742                                                          plane->colorkey.transparency << 9, 0x03 << 9);
1743                         else
1744                                 dc_set_clear(hw, DC_OVERLAY_CONFIG + offset,
1745                                                          plane->colorkey.transparency, 0x03);
1746
1747                         plane->colorkey.dirty = false;
1748                 }
1749
1750                 if (plane->roi.dirty) {
1751                         if (plane->roi.enable) {
1752                                 dc_write(hw, reg->roi_origin + offset,
1753                                                  plane->roi.x | (plane->roi.y << 16));
1754                                 dc_write(hw, reg->roi_size + offset,
1755                                                  plane->roi.width | (plane->roi.height << 16));
1756                                 if (primary)
1757                                         dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset,
1758                                                                  BIT(0), 0);
1759                                 else
1760                                         dc_set_clear(hw, DC_OVERLAY_CONFIG + offset,
1761                                                                  BIT(22), 0);
1762                         } else {
1763                                 if (primary)
1764                                         dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset,
1765                                                                  0, BIT(0));
1766                                 else
1767                                         dc_set_clear(hw, DC_OVERLAY_CONFIG + offset,
1768                                                                  0, BIT(22));
1769                         }
1770                         plane->roi.dirty = false;
1771                 }
1772         }
1773 }
1774
1775 static void plane_ex_commit(struct dc_hw *hw)
1776 {
1777         struct dc_hw_plane *plane;
1778         const struct dc_hw_plane_reg *reg;
1779         bool primary = false;
1780         u8 id, layer_num = hw->info->layer_num;
1781         u32 i, offset;
1782
1783         for (i = 0; i < layer_num; i++) {
1784                 plane = &hw->plane[i];
1785                 id = hw->info->planes[i].id;
1786                 offset = get_addr_offset(id);
1787                 if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1) {
1788                         reg = &dc_plane_reg[0];
1789                         primary = true;
1790                 } else {
1791                         reg = &dc_plane_reg[1];
1792                         primary = false;
1793                 }
1794
1795                 if (plane->fb.dirty) {
1796                         if (is_rgb(plane->fb.format)) {
1797                                 if (primary)
1798                                         dc_set_clear(hw,
1799                                                          DC_FRAMEBUFFER_CONFIG_EX + offset,
1800                                                          BIT(6), BIT(8));
1801                                 else
1802                                         dc_set_clear(hw,
1803                                                          DC_OVERLAY_CONFIG + offset,
1804                                                          BIT(29), BIT(30));
1805                         } else {
1806                                 if (primary)
1807                                         dc_set_clear(hw,
1808                                                          DC_FRAMEBUFFER_CONFIG_EX + offset,
1809                                                          BIT(8), BIT(6));
1810                                 else
1811                                         dc_set_clear(hw,
1812                                                          DC_OVERLAY_CONFIG + offset,
1813                                                          BIT(30), BIT(29));
1814                                 switch (plane->fb.yuv_color_space) {
1815                                 case COLOR_SPACE_601:
1816                                         load_yuv_to_rgb(hw, reg, offset, YUV601_2RGB);
1817                                         break;
1818                                 case COLOR_SPACE_709:
1819                                         load_yuv_to_rgb(hw, reg, offset, YUV709_2RGB);
1820                                         break;
1821                                 case COLOR_SPACE_2020:
1822                                         load_yuv_to_rgb(hw, reg, offset, YUV2020_2RGB);
1823                                         break;
1824                                 default:
1825                                         break;
1826                                 }
1827                         }
1828                 }
1829                 if (plane->degamma.dirty) {
1830                         switch (plane->degamma.mode) {
1831                         case VS_DEGAMMA_DISABLE:
1832                                 if (primary)
1833                                         dc_set_clear(hw,
1834                                                  DC_FRAMEBUFFER_CONFIG_EX + offset,
1835                                                  0, BIT(5));
1836                                 else
1837                                         dc_set_clear(hw,
1838                                                  DC_OVERLAY_CONFIG + offset,
1839                                                  0, BIT(28));
1840                                 break;
1841                         case VS_DEGAMMA_BT709:
1842                                 load_degamma_table(hw, reg, offset, DEGAMMA_709);
1843                                 if (primary)
1844                                         dc_set_clear(hw,
1845                                                  DC_FRAMEBUFFER_CONFIG_EX + offset,
1846                                                  BIT(5), 0);
1847                                 else
1848                                         dc_set_clear(hw,
1849                                                  DC_OVERLAY_CONFIG + offset,
1850                                                  BIT(28), 0);
1851                                 break;
1852                         case VS_DEGAMMA_BT2020:
1853                                 load_degamma_table(hw, reg, offset, DEGAMMA_2020);
1854                                 if (primary)
1855                                         dc_set_clear(hw,
1856                                                  DC_FRAMEBUFFER_CONFIG_EX + offset,
1857                                                  BIT(5), 0);
1858                                 else
1859                                         dc_set_clear(hw,
1860                                                  DC_OVERLAY_CONFIG + offset,
1861                                                  BIT(28), 0);
1862                                 break;
1863                         default:
1864                                 break;
1865                         }
1866                         plane->degamma.dirty = false;
1867                 }
1868         }
1869         plane_commit(hw);
1870 }
1871
1872 static void setup_display(struct dc_hw *hw, struct dc_hw_display *display)
1873 {
1874         u8 id = display->id;
1875         u32 dpi_cfg, offset = id << 2;
1876
1877         if (hw->display[id].enable) {
1878                 switch (display->bus_format) {
1879                 case MEDIA_BUS_FMT_RGB565_1X16:
1880                         dpi_cfg = 0;
1881                         break;
1882                 case MEDIA_BUS_FMT_RGB666_1X18:
1883                         dpi_cfg = 3;
1884                         break;
1885                 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
1886                         dpi_cfg = 4;
1887                         break;
1888                 case MEDIA_BUS_FMT_RGB888_1X24:
1889                         dpi_cfg = 5;
1890                         break;
1891                 case MEDIA_BUS_FMT_RGB101010_1X30:
1892                         dpi_cfg = 6;
1893                         break;
1894                 default:
1895                         dpi_cfg = 5;
1896                         break;
1897                 }
1898                 dc_write(hw, DC_DISPLAY_DPI_CONFIG + offset, dpi_cfg);
1899
1900                 if (id == 0)
1901                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(0) | BIT(2));
1902                 else
1903                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(1) | BIT(2));
1904
1905                 dc_write(hw, DC_DISPLAY_H + offset, hw->display[id].h_active |
1906                                 (hw->display[id].h_total << 16));
1907                 dc_write(hw, DC_DISPLAY_H_SYNC + offset,
1908                                 hw->display[id].h_sync_start |
1909                                 (hw->display[id].h_sync_end << 15) |
1910                                 (hw->display[id].h_sync_polarity ? 0 : BIT(31)) |
1911                                 BIT(30));
1912                 dc_write(hw, DC_DISPLAY_V + offset, hw->display[id].v_active |
1913                                 (hw->display[id].v_total << 16));
1914                 dc_write(hw, DC_DISPLAY_V_SYNC + offset,
1915                                 hw->display[id].v_sync_start |
1916                                 (hw->display[id].v_sync_end << 15) |
1917                                 (hw->display[id].v_sync_polarity ? 0 : BIT(31)) |
1918                                 BIT(30));
1919
1920                 if (hw->info->pipe_sync) {
1921                         switch (display->sync_mode) {
1922                         case VS_SINGLE_DC:
1923                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX,
1924                                                  0, BIT(3) | BIT(4));
1925                                 break;
1926                         case VS_MULTI_DC_PRIMARY:
1927                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX,
1928                                                  BIT(3) | BIT(4), 0);
1929                                 break;
1930                         case VS_MULTI_DC_SECONDARY:
1931                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX,
1932                                                  BIT(3), BIT(4));
1933                                 break;
1934                         default:
1935                                 break;
1936                         }
1937                 }
1938
1939                 if (hw->info->background)
1940                         dc_write(hw, DC_FRAMEBUFFER_BG_COLOR + offset,
1941                                          hw->display[id].bg_color);
1942
1943                 if (hw->display[id].dither_enable) {
1944                         dc_write(hw, DC_DISPLAY_DITHER_TABLE_LOW + offset,
1945                                          DC_DISPLAY_DITHERTABLE_LOW);
1946                         dc_write(hw, DC_DISPLAY_DITHER_TABLE_HIGH + offset,
1947                                          DC_DISPLAY_DITHERTABLE_HIGH);
1948                         dc_write(hw, DC_DISPLAY_DITHER_CONFIG + offset, BIT(31));
1949                 } else {
1950                         dc_write(hw, DC_DISPLAY_DITHER_CONFIG + offset, 0);
1951                 }
1952
1953                 dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, BIT(12), 0);
1954                 if (hw->display[id].sync_enable)
1955                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(2) | BIT(3), 0);
1956                 else if (id == 0)
1957                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(0), BIT(3));
1958                 else
1959                         if (hw->out[id] != OUT_DPI)
1960                                 dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(1), BIT(3));
1961         } else {
1962                 dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, 0, BIT(12));
1963                 if (id == 0)
1964                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(0) | BIT(2));
1965                 else
1966                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(1) | BIT(2));
1967
1968                 dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x0, 0x0, BIT(24));
1969                 dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x4, 0x0, BIT(24));
1970                 dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x8, 0x0, BIT(24));
1971                 dc_set_clear(hw, DC_OVERLAY_CONFIG + 0xc, 0x0, BIT(24));
1972
1973                 dc_set_clear(hw, DC_CURSOR_CONFIG + 0x0, BIT(3), 0x03);
1974                 dc_set_clear(hw, DC_CURSOR_CONFIG + DC_CURSOR_OFFSET, BIT(3), 0x03);
1975         }
1976 }
1977
1978 static void setup_display_ex(struct dc_hw *hw, struct dc_hw_display *display)
1979 {
1980         u8 id = display->id;
1981         u32 dp_cfg, offset = id << 2;
1982         bool is_yuv = false;
1983
1984         if (hw->display[id].enable && hw->out[id] == OUT_DP) {
1985                 switch (display->bus_format) {
1986                 case MEDIA_BUS_FMT_RGB565_1X16:
1987                         dp_cfg = 0;
1988                         break;
1989                 case MEDIA_BUS_FMT_RGB666_1X18:
1990                         dp_cfg = 1;
1991                         break;
1992                 case MEDIA_BUS_FMT_RGB888_1X24:
1993                         dp_cfg = 2;
1994                         break;
1995                 case MEDIA_BUS_FMT_RGB101010_1X30:
1996                         dp_cfg = 3;
1997                         break;
1998                 case MEDIA_BUS_FMT_UYVY8_1X16:
1999                         dp_cfg = 2 << 4;
2000                         is_yuv = true;
2001                         break;
2002                 case MEDIA_BUS_FMT_YUV8_1X24:
2003                         dp_cfg = 4 << 4;
2004                         is_yuv = true;
2005                         break;
2006                 case MEDIA_BUS_FMT_UYVY10_1X20:
2007                         dp_cfg = 8 << 4;
2008                         is_yuv = true;
2009                         break;
2010                 case MEDIA_BUS_FMT_YUV10_1X30:
2011                         dp_cfg = 10 << 4;
2012                         is_yuv = true;
2013                         break;
2014                 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
2015                         dp_cfg = 12 << 4;
2016                         is_yuv = true;
2017                         break;
2018                 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
2019                         dp_cfg = 13 << 4;
2020                         is_yuv = true;
2021                         break;
2022                 default:
2023                         dp_cfg = 2;
2024                         break;
2025                 }
2026                 if (is_yuv)
2027                         dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, BIT(16), 0);
2028                 else
2029                         dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, 0, BIT(16));
2030                 dc_write(hw, DC_DISPLAY_DP_CONFIG + offset, dp_cfg | BIT(3));
2031         }
2032
2033         if (hw->out[id] == OUT_DPI)
2034                 dc_set_clear(hw, DC_DISPLAY_DP_CONFIG + offset, 0, BIT(3));
2035
2036         setup_display(hw, display);
2037 }
2038
2039 static const struct dc_hw_funcs hw_func = {
2040         .gamma = &gamma_ex_commit,
2041         .plane = &plane_ex_commit,
2042         .display = setup_display_ex,
2043 };
2044
2045 void dc_hw_commit(struct dc_hw *hw)
2046 {
2047         u32 i, offset = 0;
2048         u8 plane_num = hw->info->plane_num;
2049         u8 layer_num = hw->info->layer_num;
2050         u8 cursor_num = plane_num - layer_num;
2051
2052         hw->func->gamma(hw);
2053         hw->func->plane(hw);
2054
2055         for (i = 0; i < cursor_num; i++) {
2056                 if (hw->cursor[i].dirty) {
2057                         offset = hw->cursor[i].display_id ? DC_CURSOR_OFFSET : 0;
2058                         if (hw->cursor[i].enable) {
2059                                 dc_write(hw, DC_CURSOR_ADDRESS + offset,
2060                                                  hw->cursor[i].address);
2061                                 dc_write(hw, DC_CURSOR_LOCATION + offset, hw->cursor[i].x |
2062                                          (hw->cursor[i].y << 16));
2063                                 dc_set_clear(hw, DC_CURSOR_CONFIG + offset,
2064                                                  (hw->cursor[i].hot_x << 16) |
2065                                                  (hw->cursor[i].hot_y << 8) |
2066                                                  (hw->cursor[i].size << 5) |
2067                                                  BIT(3) | BIT(2) | 0x02,
2068                                                  (0xFF << 16) |
2069                                                  (0xFF << 8) |
2070                                                  (0x07 << 5) | 0x1F);
2071                         } else {
2072                                 dc_set_clear(hw, DC_CURSOR_CONFIG + offset, BIT(3), 0x03);
2073                         }
2074                         hw->cursor[i].dirty = false;
2075                 }
2076         }
2077
2078         if (hw->qos.dirty) {
2079                 dc_set_clear(hw, DC_QOS_CONFIG, (hw->qos.high_value << 4) |
2080                                          hw->qos.low_value, 0xFF);
2081                 hw->qos.dirty = false;
2082         }
2083 }
2084
2085 #ifdef CONFIG_VERISILICON_DEC
2086 void dc_hw_dec_init(struct dc_hw *hw)
2087 {
2088         u32 config = 0;
2089
2090         config = DEC_CONTROL_RESET & (~COMPRESSION_DISABLE);
2091         dc_write(hw, DEC_CONTROL, config | FLUSH_ENABLE);
2092
2093         config = DEC_CONTROL_EX2_RESET &
2094                          (~TILE_STATUS_READ_ID_MASK) &
2095                          (~TILE_STATUS_READ_ID_H_MASK) &
2096                          (~DISABLE_HW_DEC_FLUSH);
2097         dc_write(hw, DEC_CONTROL_EX2,
2098                          config | (TILE_STATUS_READ_ID_H << 22) |
2099                          TILE_STATUS_READ_ID);
2100
2101         config = DEC_CONTROL_EX_RESET &
2102                          (~WRITE_MISS_POLICY_MASK) &
2103                          (~READ_MISS_POLICY_MASK);
2104         dc_write(hw, DEC_CONTROL_EX, config | (WRITE_MISS_POLICY1 << 19));
2105 }
2106
2107 void dc_hw_dec_stream_set(struct dc_hw *hw, u32 main_base_addr,
2108                                                   u32 ts_base_addr, u8 tile_mode, u8 align_mode,
2109                                                   u8 format, u8 depth, u8 stream_id)
2110 {
2111         u32 offset = stream_id << 2;
2112
2113         dc_set_clear(hw, DEC_READ_CONFIG + offset,
2114                                  (tile_mode << 25) |
2115                                  (align_mode << 16) |
2116                                  (format << 3) |
2117                                  COMPRESSION_EN,
2118                                  TILE_MODE_MASK |
2119                                  COMPRESSION_ALIGN_MODE_MASK |
2120                                  COMPRESSION_FORMAT_MASK);
2121
2122         dc_set_clear(hw, DEC_READ_EX_CONFIG + offset,
2123                                  (depth << 16), BIT_DEPTH_MASK);
2124
2125         dc_write(hw, DEC_READ_BUFFER_BASE + offset, main_base_addr);
2126         dc_write(hw, DEC_READ_BUFFER_END + offset, ts_base_addr - 128);
2127         dc_write(hw, DEC_READ_CACHE_BASE + offset, ts_base_addr);
2128 }
2129
2130 void dc_hw_dec_stream_disable(struct dc_hw *hw, u8 stream_id)
2131 {
2132         u32 offset = stream_id << 2;
2133
2134         dc_write(hw, DEC_READ_CONFIG + offset, DEC_READ_CONFIG_RESET);
2135         dc_write(hw, DEC_READ_BUFFER_BASE + offset, 0xFFFFFFFF);
2136         dc_write(hw, DEC_READ_BUFFER_END + offset, 0xFFFFFFFF);
2137 }
2138 #endif
2139
2140 #ifdef CONFIG_VERISILICON_MMU
2141 static u32 mmu_read(struct dc_hw *hw, u32 reg)
2142 {
2143         return readl(hw->mmu_base + reg - mmu_reg_base);
2144 }
2145
2146 static void mmu_write(struct dc_hw *hw, u32 reg, u32 value)
2147 {
2148         writel(value, hw->mmu_base + reg - mmu_reg_base);
2149 }
2150
2151 static void mmu_set_clear(struct dc_hw *hw, u32 reg, u32 set, u32 clear)
2152 {
2153         u32 value = mmu_read(hw, reg);
2154
2155         value &= ~clear;
2156         value |= set;
2157         mmu_write(hw, reg, value);
2158 }
2159
2160 int dc_hw_mmu_init(struct dc_hw *hw, dc_mmu_pt mmu)
2161 {
2162         const struct dc_hw_mmu_reg *reg;
2163         u32 mtlb = 0, ext_mtlb = 0;
2164         u32 safe_addr = 0, ext_safe_addr = 0;
2165         u32 config = 0;
2166
2167         reg = &dc_mmu_reg;
2168
2169         mtlb = (u32)(mmu->mtlb_physical & 0xFFFFFFFF);
2170         ext_mtlb = (u32)(mmu->mtlb_physical >> 32);
2171
2172         /* more than 40bit physical address */
2173         if (ext_mtlb & 0xFFFFFF00) {
2174                 pr_err("Mtlb address out of range.\n");
2175                 return -EFAULT;
2176         }
2177
2178         config = (ext_mtlb << 20) | (mtlb >> 12);
2179         if (mmu->mode == MMU_MODE_1K)
2180                 mmu_set_clear(hw, reg->context_pd_entry,
2181                                   (config << 4) | BIT(0),
2182                                   (0xFFFFFFF << 4) | (0x07));
2183         else
2184                 mmu_set_clear(hw, reg->context_pd_entry,
2185                                   (config << 4),
2186                                   (0xFFFFFFF << 4) | (0x07));
2187
2188         safe_addr = (u32)(mmu->safe_page_physical & 0xFFFFFFFF);
2189         ext_safe_addr = (u32)(mmu->safe_page_physical >> 32);
2190
2191         if ((safe_addr & 0x3F) || (ext_safe_addr & 0xFFFFFF00)) {
2192                 pr_err("Invalid safe_address.\n");
2193                 return -EFAULT;
2194         }
2195
2196         mmu_write(hw, reg->table_array_size, 1);
2197         mmu_write(hw, reg->safe_secure, safe_addr);
2198         mmu_write(hw, reg->safe_non_secure, safe_addr);
2199
2200         mmu_set_clear(hw, reg->safe_ex,
2201                           (ext_safe_addr << 16) | ext_safe_addr,
2202                           BIT(31) | (0xFF << 16) | BIT(15) | 0xFF);
2203
2204         /* mmu configuration for ree driver */
2205         mmu_write(hw, reg->mmu_control, BIT(5) | BIT(0));
2206
2207         mmu_write(hw, SE_MMU_REG_INTR_ENBL, 0xFFFFFFFF);
2208
2209         return 0;
2210 }
2211
2212 void dc_hw_enable_mmu_prefetch(struct dc_hw *hw, bool enable)
2213 {
2214         if (!hw->info->mmu_prefetch)
2215                 return;
2216
2217         if (enable)
2218                 dc_write(hw, DC_MMU_PREFETCH, BIT(0));
2219         else
2220                 dc_write(hw, DC_MMU_PREFETCH, 0);
2221 }
2222
2223 void dc_hw_mmu_flush(struct dc_hw *hw)
2224 {
2225         const struct dc_hw_mmu_reg *reg = &dc_mmu_reg;
2226         u32 value = mmu_read(hw, reg->mmu_config);
2227
2228         mmu_write(hw, reg->mmu_config, value | BIT(4));
2229         mmu_write(hw, reg->mmu_config, value);
2230 }
2231 #endif