riscv:linux:drm
[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         if (enable) {
1492                 if (hw->out[1] == OUT_DPI)
1493                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(1), BIT(3));
1494
1495                 hi_write(hw, AQ_INTR_ENBL, 0xFFFFFFFF);
1496         } else {
1497                 hi_write(hw, AQ_INTR_ENBL, 0);
1498         }
1499 }
1500
1501 u32 dc_hw_get_interrupt(struct dc_hw *hw)
1502 {
1503         return hi_read(hw, AQ_INTR_ACKNOWLEDGE);
1504 }
1505
1506 bool dc_hw_check_underflow(struct dc_hw *hw)
1507 {
1508         return dc_read(hw, DC_FRAMEBUFFER_CONFIG) & BIT(5);
1509 }
1510
1511 void dc_hw_enable_shadow_register(struct dc_hw *hw, bool enable)
1512 {
1513         u32 i, offset;
1514         u8 id, layer_num = hw->info->layer_num;
1515         u8 panel_num = hw->info->panel_num;
1516
1517         for (i = 0; i < layer_num; i++) {
1518                 id = hw->info->planes[i].id;
1519                 offset = get_addr_offset(id);
1520                 if (enable) {
1521                         if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1)
1522                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset, BIT(12), 0);
1523                         else
1524                                 dc_set_clear(hw, DC_OVERLAY_CONFIG + offset, BIT(31), 0);
1525                 } else {
1526                         if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1)
1527                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset, 0, BIT(12));
1528                         else
1529                                 dc_set_clear(hw, DC_OVERLAY_CONFIG + offset, 0, BIT(31));
1530                 }
1531         }
1532
1533         for (i = 0; i < panel_num; i++) {
1534                 offset = i << 2;
1535                 if (enable)
1536                         dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG_EX + offset, 0, BIT(0));
1537                 else
1538                         dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG_EX + offset, BIT(0), 0);
1539         }
1540 }
1541
1542 void dc_hw_set_out(struct dc_hw *hw, enum dc_hw_out out, u8 id)
1543 {
1544         if (out <= OUT_DP)
1545                 hw->out[id] = out;
1546 }
1547
1548 static void gamma_ex_commit(struct dc_hw *hw)
1549 {
1550         u8 panel_num = hw->info->panel_num;
1551         u16 i, j;
1552         u32 value;
1553
1554         for (j = 0; j < panel_num; j++) {
1555                 if (hw->gamma[j].dirty) {
1556                         if (hw->gamma[j].enable) {
1557                                 dc_write(hw, DC_DISPLAY_GAMMA_EX_INDEX + (j << 2), 0x00);
1558                                 for (i = 0; i < GAMMA_EX_SIZE; i++) {
1559                                         value = hw->gamma[j].gamma[i][2] |
1560                                                 (hw->gamma[j].gamma[i][1] << 12);
1561                                         dc_write(hw, DC_DISPLAY_GAMMA_EX_DATA + (j << 2), value);
1562                                         dc_write(hw, DC_DISPLAY_GAMMA_EX_ONE_DATA + (j << 2),
1563                                                  hw->gamma[j].gamma[i][0]);
1564                                 }
1565                                 dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + (j << 2),
1566                                                          BIT(13), 0);
1567                         } else {
1568                                 dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + (j << 2),
1569                                                          0, BIT(13));
1570                         }
1571                         hw->gamma[j].dirty = false;
1572                 }
1573         }
1574 }
1575
1576 static void plane_commit(struct dc_hw *hw)
1577 {
1578         struct dc_hw_plane *plane;
1579         const struct dc_hw_plane_reg *reg;
1580         bool primary = false;
1581         u8 id, layer_num = hw->info->layer_num;
1582         u32 i, offset;
1583
1584         for (i = 0; i < layer_num; i++) {
1585                 plane = &hw->plane[i];
1586                 id = hw->info->planes[i].id;
1587                 offset = get_addr_offset(id);
1588                 if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1) {
1589                         reg = &dc_plane_reg[0];
1590                         primary = true;
1591                 } else {
1592                         reg = &dc_plane_reg[1];
1593                         primary = false;
1594                 }
1595
1596                 if (plane->fb.dirty) {
1597                         if (plane->fb.enable) {
1598                                 dc_write(hw, reg->y_address + offset,
1599                                          plane->fb.y_address);
1600                                 dc_write(hw, reg->u_address + offset,
1601                                          plane->fb.u_address);
1602                                 dc_write(hw, reg->v_address + offset,
1603                                          plane->fb.v_address);
1604                                 dc_write(hw, reg->y_stride + offset,
1605                                          plane->fb.y_stride);
1606                                 dc_write(hw, reg->u_stride + offset,
1607                                          plane->fb.u_stride);
1608                                 dc_write(hw, reg->v_stride + offset,
1609                                          plane->fb.v_stride);
1610                                 dc_write(hw, reg->size + offset,
1611                                          plane->fb.width |
1612                                          (plane->fb.height << 15));
1613                                 dc_write(hw, reg->water_mark + offset,
1614                                          plane->fb.water_mark);
1615
1616                                 if (plane->fb.clear_enable)
1617                                         dc_write(hw, reg->clear_value + offset,
1618                                                 plane->fb.clear_value);
1619                         }
1620
1621                         if (primary) {
1622                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG + offset,
1623                                                  (plane->fb.format << 26) |
1624                                                  (plane->fb.uv_swizzle << 25) |
1625                                                  (plane->fb.swizzle << 23) |
1626                                                  (plane->fb.tile_mode << 17) |
1627                                                  (plane->fb.yuv_color_space << 14) |
1628                                                  (plane->fb.rotation << 11) |
1629                                                  (plane->fb.clear_enable << 8),
1630                                                  (0x1F << 26) |
1631                                                  BIT(25) |
1632                                                  (0x03 << 23) |
1633                                                  (0x1F << 17) |
1634                                                  (0x07 << 14) |
1635                                                  (0x07 << 11) |
1636                                                  BIT(8));
1637                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset,
1638                                         (plane->fb.dec_enable << 1) |
1639                                         (plane->fb.enable << 13) |
1640                                         (plane->fb.zpos << 16) |
1641                                         (plane->fb.display_id << 19),
1642                                         BIT(1) | BIT(13) | (0x07 << 16) | BIT(19));
1643                         } else {
1644                                 dc_set_clear(hw, DC_OVERLAY_CONFIG + offset,
1645                                                  (plane->fb.dec_enable << 27) |
1646                                                  (plane->fb.clear_enable << 25) |
1647                                                  (plane->fb.enable << 24) |
1648                                                  (plane->fb.format << 16) |
1649                                                  (plane->fb.uv_swizzle << 15) |
1650                                                  (plane->fb.swizzle << 13) |
1651                                                  (plane->fb.tile_mode << 8) |
1652                                                  (plane->fb.yuv_color_space << 5) |
1653                                                  (plane->fb.rotation << 2),
1654                                                  BIT(27) |
1655                                                  BIT(25) |
1656                                                  BIT(24) |
1657                                                  (0x1F << 16) |
1658                                                  BIT(15) |
1659                                                  (0x03 << 13) |
1660                                                  (0x1F << 8) |
1661                                                  (0x07 << 5) |
1662                                                  (0x07 << 2));
1663                                 dc_set_clear(hw, DC_OVERLAY_CONFIG_EX + offset,
1664                                                  plane->fb.zpos | (plane->fb.display_id << 3),
1665                                                  0x07 | BIT(3));
1666                         }
1667                         plane->fb.dirty = false;
1668                 }
1669
1670                 if (plane->scale.dirty) {
1671                         if (plane->scale.enable) {
1672                                 dc_write(hw, reg->scale_factor_x + offset,
1673                                         plane->scale.scale_factor_x);
1674                                 dc_write(hw, reg->scale_factor_y + offset,
1675                                         plane->scale.scale_factor_y);
1676                                 if (primary)
1677                                         dc_set_clear(hw,
1678                                                          DC_FRAMEBUFFER_CONFIG + offset,
1679                                                          BIT(22), 0);
1680                                 else
1681                                         dc_set_clear(hw,
1682                                                          DC_OVERLAY_SCALE_CONFIG + offset,
1683                                                          BIT(8), 0);
1684                         } else {
1685                                 if (primary)
1686                                         dc_set_clear(hw,
1687                                                          DC_FRAMEBUFFER_CONFIG + offset,
1688                                                          0, BIT(22));
1689                                 else
1690                                         dc_set_clear(hw,
1691                                                          DC_OVERLAY_SCALE_CONFIG + offset,
1692                                                          0, BIT(8));
1693                         }
1694                         plane->scale.dirty = false;
1695                 }
1696
1697                 if (plane->pos.dirty) {
1698                         dc_write(hw, reg->top_left + offset,
1699                                 plane->pos.start_x |
1700                                 (plane->pos.start_y << 15));
1701                         dc_write(hw, reg->bottom_right + offset,
1702                                 plane->pos.end_x |
1703                                 (plane->pos.end_y << 15));
1704                         plane->pos.dirty = false;
1705                 }
1706
1707                 if (plane->blend.dirty) {
1708                         dc_write(hw, reg->src_global_color + offset,
1709                                          plane->blend.alpha << 24);
1710                         dc_write(hw, reg->dst_global_color + offset,
1711                                          plane->blend.alpha << 24);
1712                         switch (plane->blend.blend_mode) {
1713                         case BLEND_PREMULTI:
1714                                 dc_write(hw, reg->blend_config + offset, 0x3450);
1715                                 break;
1716                         case BLEND_COVERAGE:
1717                                 dc_write(hw, reg->blend_config + offset, 0x3950);
1718                                 break;
1719                         case BLEND_PIXEL_NONE:
1720                                 dc_write(hw, reg->blend_config + offset, 0x3548);
1721                                 break;
1722                         default:
1723                                 break;
1724                         }
1725                         plane->blend.dirty = false;
1726                 }
1727
1728                 if (plane->colorkey.dirty) {
1729                         dc_write(hw, reg->color_key + offset, plane->colorkey.colorkey);
1730                         dc_write(hw, reg->color_key_high + offset,
1731                                          plane->colorkey.colorkey_high);
1732
1733                         if (primary)
1734                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG + offset,
1735                                                          plane->colorkey.transparency << 9, 0x03 << 9);
1736                         else
1737                                 dc_set_clear(hw, DC_OVERLAY_CONFIG + offset,
1738                                                          plane->colorkey.transparency, 0x03);
1739
1740                         plane->colorkey.dirty = false;
1741                 }
1742
1743                 if (plane->roi.dirty) {
1744                         if (plane->roi.enable) {
1745                                 dc_write(hw, reg->roi_origin + offset,
1746                                                  plane->roi.x | (plane->roi.y << 16));
1747                                 dc_write(hw, reg->roi_size + offset,
1748                                                  plane->roi.width | (plane->roi.height << 16));
1749                                 if (primary)
1750                                         dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset,
1751                                                                  BIT(0), 0);
1752                                 else
1753                                         dc_set_clear(hw, DC_OVERLAY_CONFIG + offset,
1754                                                                  BIT(22), 0);
1755                         } else {
1756                                 if (primary)
1757                                         dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX + offset,
1758                                                                  0, BIT(0));
1759                                 else
1760                                         dc_set_clear(hw, DC_OVERLAY_CONFIG + offset,
1761                                                                  0, BIT(22));
1762                         }
1763                         plane->roi.dirty = false;
1764                 }
1765         }
1766 }
1767
1768 static void plane_ex_commit(struct dc_hw *hw)
1769 {
1770         struct dc_hw_plane *plane;
1771         const struct dc_hw_plane_reg *reg;
1772         bool primary = false;
1773         u8 id, layer_num = hw->info->layer_num;
1774         u32 i, offset;
1775
1776         for (i = 0; i < layer_num; i++) {
1777                 plane = &hw->plane[i];
1778                 id = hw->info->planes[i].id;
1779                 offset = get_addr_offset(id);
1780                 if (id == PRIMARY_PLANE_0 || id == PRIMARY_PLANE_1) {
1781                         reg = &dc_plane_reg[0];
1782                         primary = true;
1783                 } else {
1784                         reg = &dc_plane_reg[1];
1785                         primary = false;
1786                 }
1787
1788                 if (plane->fb.dirty) {
1789                         if (is_rgb(plane->fb.format)) {
1790                                 if (primary)
1791                                         dc_set_clear(hw,
1792                                                          DC_FRAMEBUFFER_CONFIG_EX + offset,
1793                                                          BIT(6), BIT(8));
1794                                 else
1795                                         dc_set_clear(hw,
1796                                                          DC_OVERLAY_CONFIG + offset,
1797                                                          BIT(29), BIT(30));
1798                         } else {
1799                                 if (primary)
1800                                         dc_set_clear(hw,
1801                                                          DC_FRAMEBUFFER_CONFIG_EX + offset,
1802                                                          BIT(8), BIT(6));
1803                                 else
1804                                         dc_set_clear(hw,
1805                                                          DC_OVERLAY_CONFIG + offset,
1806                                                          BIT(30), BIT(29));
1807                                 switch (plane->fb.yuv_color_space) {
1808                                 case COLOR_SPACE_601:
1809                                         load_yuv_to_rgb(hw, reg, offset, YUV601_2RGB);
1810                                         break;
1811                                 case COLOR_SPACE_709:
1812                                         load_yuv_to_rgb(hw, reg, offset, YUV709_2RGB);
1813                                         break;
1814                                 case COLOR_SPACE_2020:
1815                                         load_yuv_to_rgb(hw, reg, offset, YUV2020_2RGB);
1816                                         break;
1817                                 default:
1818                                         break;
1819                                 }
1820                         }
1821                 }
1822                 if (plane->degamma.dirty) {
1823                         switch (plane->degamma.mode) {
1824                         case VS_DEGAMMA_DISABLE:
1825                                 if (primary)
1826                                         dc_set_clear(hw,
1827                                                  DC_FRAMEBUFFER_CONFIG_EX + offset,
1828                                                  0, BIT(5));
1829                                 else
1830                                         dc_set_clear(hw,
1831                                                  DC_OVERLAY_CONFIG + offset,
1832                                                  0, BIT(28));
1833                                 break;
1834                         case VS_DEGAMMA_BT709:
1835                                 load_degamma_table(hw, reg, offset, DEGAMMA_709);
1836                                 if (primary)
1837                                         dc_set_clear(hw,
1838                                                  DC_FRAMEBUFFER_CONFIG_EX + offset,
1839                                                  BIT(5), 0);
1840                                 else
1841                                         dc_set_clear(hw,
1842                                                  DC_OVERLAY_CONFIG + offset,
1843                                                  BIT(28), 0);
1844                                 break;
1845                         case VS_DEGAMMA_BT2020:
1846                                 load_degamma_table(hw, reg, offset, DEGAMMA_2020);
1847                                 if (primary)
1848                                         dc_set_clear(hw,
1849                                                  DC_FRAMEBUFFER_CONFIG_EX + offset,
1850                                                  BIT(5), 0);
1851                                 else
1852                                         dc_set_clear(hw,
1853                                                  DC_OVERLAY_CONFIG + offset,
1854                                                  BIT(28), 0);
1855                                 break;
1856                         default:
1857                                 break;
1858                         }
1859                         plane->degamma.dirty = false;
1860                 }
1861         }
1862         plane_commit(hw);
1863 }
1864
1865 static void setup_display(struct dc_hw *hw, struct dc_hw_display *display)
1866 {
1867         u8 id = display->id;
1868         u32 dpi_cfg, offset = id << 2;
1869
1870         if (hw->display[id].enable) {
1871                 switch (display->bus_format) {
1872                 case MEDIA_BUS_FMT_RGB565_1X16:
1873                         dpi_cfg = 0;
1874                         break;
1875                 case MEDIA_BUS_FMT_RGB666_1X18:
1876                         dpi_cfg = 3;
1877                         break;
1878                 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
1879                         dpi_cfg = 4;
1880                         break;
1881                 case MEDIA_BUS_FMT_RGB888_1X24:
1882                         dpi_cfg = 5;
1883                         break;
1884                 case MEDIA_BUS_FMT_RGB101010_1X30:
1885                         dpi_cfg = 6;
1886                         break;
1887                 default:
1888                         dpi_cfg = 5;
1889                         break;
1890                 }
1891                 dc_write(hw, DC_DISPLAY_DPI_CONFIG + offset, dpi_cfg);
1892
1893                 if (id == 0)
1894                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(0) | BIT(2));
1895                 else
1896                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(1) | BIT(2));
1897
1898                 dc_write(hw, DC_DISPLAY_H + offset, hw->display[id].h_active |
1899                                 (hw->display[id].h_total << 16));
1900                 dc_write(hw, DC_DISPLAY_H_SYNC + offset,
1901                                 hw->display[id].h_sync_start |
1902                                 (hw->display[id].h_sync_end << 15) |
1903                                 (hw->display[id].h_sync_polarity ? 0 : BIT(31)) |
1904                                 BIT(30));
1905                 dc_write(hw, DC_DISPLAY_V + offset, hw->display[id].v_active |
1906                                 (hw->display[id].v_total << 16));
1907                 dc_write(hw, DC_DISPLAY_V_SYNC + offset,
1908                                 hw->display[id].v_sync_start |
1909                                 (hw->display[id].v_sync_end << 15) |
1910                                 (hw->display[id].v_sync_polarity ? 0 : BIT(31)) |
1911                                 BIT(30));
1912
1913                 if (hw->info->pipe_sync) {
1914                         switch (display->sync_mode) {
1915                         case VS_SINGLE_DC:
1916                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX,
1917                                                  0, BIT(3) | BIT(4));
1918                                 break;
1919                         case VS_MULTI_DC_PRIMARY:
1920                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX,
1921                                                  BIT(3) | BIT(4), 0);
1922                                 break;
1923                         case VS_MULTI_DC_SECONDARY:
1924                                 dc_set_clear(hw, DC_FRAMEBUFFER_CONFIG_EX,
1925                                                  BIT(3), BIT(4));
1926                                 break;
1927                         default:
1928                                 break;
1929                         }
1930                 }
1931
1932                 if (hw->info->background)
1933                         dc_write(hw, DC_FRAMEBUFFER_BG_COLOR + offset,
1934                                          hw->display[id].bg_color);
1935
1936                 if (hw->display[id].dither_enable) {
1937                         dc_write(hw, DC_DISPLAY_DITHER_TABLE_LOW + offset,
1938                                          DC_DISPLAY_DITHERTABLE_LOW);
1939                         dc_write(hw, DC_DISPLAY_DITHER_TABLE_HIGH + offset,
1940                                          DC_DISPLAY_DITHERTABLE_HIGH);
1941                         dc_write(hw, DC_DISPLAY_DITHER_CONFIG + offset, BIT(31));
1942                 } else {
1943                         dc_write(hw, DC_DISPLAY_DITHER_CONFIG + offset, 0);
1944                 }
1945
1946                 dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, BIT(12), 0);
1947                 if (hw->display[id].sync_enable)
1948                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(2) | BIT(3), 0);
1949                 else if (id == 0)
1950                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(0), BIT(3));
1951                 else
1952                         if (hw->out[id] != OUT_DPI)
1953                                 dc_set_clear(hw, DC_DISPLAY_PANEL_START, BIT(1), BIT(3));
1954         } else {
1955                 dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, 0, BIT(12));
1956                 if (id == 0)
1957                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(0) | BIT(2));
1958                 else
1959                         dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(1) | BIT(2));
1960
1961                 dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x0, 0x0, BIT(24));
1962                 dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x4, 0x0, BIT(24));
1963                 dc_set_clear(hw, DC_OVERLAY_CONFIG + 0x8, 0x0, BIT(24));
1964                 dc_set_clear(hw, DC_OVERLAY_CONFIG + 0xc, 0x0, BIT(24));
1965
1966                 dc_set_clear(hw, DC_CURSOR_CONFIG + 0x0, BIT(3), 0x03);
1967                 dc_set_clear(hw, DC_CURSOR_CONFIG + DC_CURSOR_OFFSET, BIT(3), 0x03);
1968         }
1969 }
1970
1971 static void setup_display_ex(struct dc_hw *hw, struct dc_hw_display *display)
1972 {
1973         u8 id = display->id;
1974         u32 dp_cfg, offset = id << 2;
1975         bool is_yuv = false;
1976
1977         if (hw->display[id].enable && hw->out[id] == OUT_DP) {
1978                 switch (display->bus_format) {
1979                 case MEDIA_BUS_FMT_RGB565_1X16:
1980                         dp_cfg = 0;
1981                         break;
1982                 case MEDIA_BUS_FMT_RGB666_1X18:
1983                         dp_cfg = 1;
1984                         break;
1985                 case MEDIA_BUS_FMT_RGB888_1X24:
1986                         dp_cfg = 2;
1987                         break;
1988                 case MEDIA_BUS_FMT_RGB101010_1X30:
1989                         dp_cfg = 3;
1990                         break;
1991                 case MEDIA_BUS_FMT_UYVY8_1X16:
1992                         dp_cfg = 2 << 4;
1993                         is_yuv = true;
1994                         break;
1995                 case MEDIA_BUS_FMT_YUV8_1X24:
1996                         dp_cfg = 4 << 4;
1997                         is_yuv = true;
1998                         break;
1999                 case MEDIA_BUS_FMT_UYVY10_1X20:
2000                         dp_cfg = 8 << 4;
2001                         is_yuv = true;
2002                         break;
2003                 case MEDIA_BUS_FMT_YUV10_1X30:
2004                         dp_cfg = 10 << 4;
2005                         is_yuv = true;
2006                         break;
2007                 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
2008                         dp_cfg = 12 << 4;
2009                         is_yuv = true;
2010                         break;
2011                 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
2012                         dp_cfg = 13 << 4;
2013                         is_yuv = true;
2014                         break;
2015                 default:
2016                         dp_cfg = 2;
2017                         break;
2018                 }
2019                 if (is_yuv)
2020                         dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, BIT(16), 0);
2021                 else
2022                         dc_set_clear(hw, DC_DISPLAY_PANEL_CONFIG + offset, 0, BIT(16));
2023                 dc_write(hw, DC_DISPLAY_DP_CONFIG + offset, dp_cfg | BIT(3));
2024         }
2025
2026         if (hw->out[id] == OUT_DPI)
2027                 dc_set_clear(hw, DC_DISPLAY_DP_CONFIG + offset, 0, BIT(3));
2028
2029         setup_display(hw, display);
2030 }
2031
2032 static const struct dc_hw_funcs hw_func = {
2033         .gamma = &gamma_ex_commit,
2034         .plane = &plane_ex_commit,
2035         .display = setup_display_ex,
2036 };
2037
2038 void dc_hw_commit(struct dc_hw *hw)
2039 {
2040         u32 i, offset = 0;
2041         u8 plane_num = hw->info->plane_num;
2042         u8 layer_num = hw->info->layer_num;
2043         u8 cursor_num = plane_num - layer_num;
2044
2045         hw->func->gamma(hw);
2046         hw->func->plane(hw);
2047
2048         for (i = 0; i < cursor_num; i++) {
2049                 if (hw->cursor[i].dirty) {
2050                         offset = hw->cursor[i].display_id ? DC_CURSOR_OFFSET : 0;
2051                         if (hw->cursor[i].enable) {
2052                                 dc_write(hw, DC_CURSOR_ADDRESS + offset,
2053                                                  hw->cursor[i].address);
2054                                 dc_write(hw, DC_CURSOR_LOCATION + offset, hw->cursor[i].x |
2055                                          (hw->cursor[i].y << 16));
2056                                 dc_set_clear(hw, DC_CURSOR_CONFIG + offset,
2057                                                  (hw->cursor[i].hot_x << 16) |
2058                                                  (hw->cursor[i].hot_y << 8) |
2059                                                  (hw->cursor[i].size << 5) |
2060                                                  BIT(3) | BIT(2) | 0x02,
2061                                                  (0xFF << 16) |
2062                                                  (0xFF << 8) |
2063                                                  (0x07 << 5) | 0x1F);
2064                         } else {
2065                                 dc_set_clear(hw, DC_CURSOR_CONFIG + offset, BIT(3), 0x03);
2066                         }
2067                         hw->cursor[i].dirty = false;
2068                 }
2069         }
2070
2071         if (hw->qos.dirty) {
2072                 dc_set_clear(hw, DC_QOS_CONFIG, (hw->qos.high_value << 4) |
2073                                          hw->qos.low_value, 0xFF);
2074                 hw->qos.dirty = false;
2075         }
2076 }
2077
2078 #ifdef CONFIG_VERISILICON_DEC
2079 void dc_hw_dec_init(struct dc_hw *hw)
2080 {
2081         u32 config = 0;
2082
2083         config = DEC_CONTROL_RESET & (~COMPRESSION_DISABLE);
2084         dc_write(hw, DEC_CONTROL, config | FLUSH_ENABLE);
2085
2086         config = DEC_CONTROL_EX2_RESET &
2087                          (~TILE_STATUS_READ_ID_MASK) &
2088                          (~TILE_STATUS_READ_ID_H_MASK) &
2089                          (~DISABLE_HW_DEC_FLUSH);
2090         dc_write(hw, DEC_CONTROL_EX2,
2091                          config | (TILE_STATUS_READ_ID_H << 22) |
2092                          TILE_STATUS_READ_ID);
2093
2094         config = DEC_CONTROL_EX_RESET &
2095                          (~WRITE_MISS_POLICY_MASK) &
2096                          (~READ_MISS_POLICY_MASK);
2097         dc_write(hw, DEC_CONTROL_EX, config | (WRITE_MISS_POLICY1 << 19));
2098 }
2099
2100 void dc_hw_dec_stream_set(struct dc_hw *hw, u32 main_base_addr,
2101                                                   u32 ts_base_addr, u8 tile_mode, u8 align_mode,
2102                                                   u8 format, u8 depth, u8 stream_id)
2103 {
2104         u32 offset = stream_id << 2;
2105
2106         dc_set_clear(hw, DEC_READ_CONFIG + offset,
2107                                  (tile_mode << 25) |
2108                                  (align_mode << 16) |
2109                                  (format << 3) |
2110                                  COMPRESSION_EN,
2111                                  TILE_MODE_MASK |
2112                                  COMPRESSION_ALIGN_MODE_MASK |
2113                                  COMPRESSION_FORMAT_MASK);
2114
2115         dc_set_clear(hw, DEC_READ_EX_CONFIG + offset,
2116                                  (depth << 16), BIT_DEPTH_MASK);
2117
2118         dc_write(hw, DEC_READ_BUFFER_BASE + offset, main_base_addr);
2119         dc_write(hw, DEC_READ_BUFFER_END + offset, ts_base_addr - 128);
2120         dc_write(hw, DEC_READ_CACHE_BASE + offset, ts_base_addr);
2121 }
2122
2123 void dc_hw_dec_stream_disable(struct dc_hw *hw, u8 stream_id)
2124 {
2125         u32 offset = stream_id << 2;
2126
2127         dc_write(hw, DEC_READ_CONFIG + offset, DEC_READ_CONFIG_RESET);
2128         dc_write(hw, DEC_READ_BUFFER_BASE + offset, 0xFFFFFFFF);
2129         dc_write(hw, DEC_READ_BUFFER_END + offset, 0xFFFFFFFF);
2130 }
2131 #endif
2132
2133 #ifdef CONFIG_VERISILICON_MMU
2134 static u32 mmu_read(struct dc_hw *hw, u32 reg)
2135 {
2136         return readl(hw->mmu_base + reg - mmu_reg_base);
2137 }
2138
2139 static void mmu_write(struct dc_hw *hw, u32 reg, u32 value)
2140 {
2141         writel(value, hw->mmu_base + reg - mmu_reg_base);
2142 }
2143
2144 static void mmu_set_clear(struct dc_hw *hw, u32 reg, u32 set, u32 clear)
2145 {
2146         u32 value = mmu_read(hw, reg);
2147
2148         value &= ~clear;
2149         value |= set;
2150         mmu_write(hw, reg, value);
2151 }
2152
2153 int dc_hw_mmu_init(struct dc_hw *hw, dc_mmu_pt mmu)
2154 {
2155         const struct dc_hw_mmu_reg *reg;
2156         u32 mtlb = 0, ext_mtlb = 0;
2157         u32 safe_addr = 0, ext_safe_addr = 0;
2158         u32 config = 0;
2159
2160         reg = &dc_mmu_reg;
2161
2162         mtlb = (u32)(mmu->mtlb_physical & 0xFFFFFFFF);
2163         ext_mtlb = (u32)(mmu->mtlb_physical >> 32);
2164
2165         /* more than 40bit physical address */
2166         if (ext_mtlb & 0xFFFFFF00) {
2167                 pr_err("Mtlb address out of range.\n");
2168                 return -EFAULT;
2169         }
2170
2171         config = (ext_mtlb << 20) | (mtlb >> 12);
2172         if (mmu->mode == MMU_MODE_1K)
2173                 mmu_set_clear(hw, reg->context_pd_entry,
2174                                   (config << 4) | BIT(0),
2175                                   (0xFFFFFFF << 4) | (0x07));
2176         else
2177                 mmu_set_clear(hw, reg->context_pd_entry,
2178                                   (config << 4),
2179                                   (0xFFFFFFF << 4) | (0x07));
2180
2181         safe_addr = (u32)(mmu->safe_page_physical & 0xFFFFFFFF);
2182         ext_safe_addr = (u32)(mmu->safe_page_physical >> 32);
2183
2184         if ((safe_addr & 0x3F) || (ext_safe_addr & 0xFFFFFF00)) {
2185                 pr_err("Invalid safe_address.\n");
2186                 return -EFAULT;
2187         }
2188
2189         mmu_write(hw, reg->table_array_size, 1);
2190         mmu_write(hw, reg->safe_secure, safe_addr);
2191         mmu_write(hw, reg->safe_non_secure, safe_addr);
2192
2193         mmu_set_clear(hw, reg->safe_ex,
2194                           (ext_safe_addr << 16) | ext_safe_addr,
2195                           BIT(31) | (0xFF << 16) | BIT(15) | 0xFF);
2196
2197         /* mmu configuration for ree driver */
2198         mmu_write(hw, reg->mmu_control, BIT(5) | BIT(0));
2199
2200         mmu_write(hw, SE_MMU_REG_INTR_ENBL, 0xFFFFFFFF);
2201
2202         return 0;
2203 }
2204
2205 void dc_hw_enable_mmu_prefetch(struct dc_hw *hw, bool enable)
2206 {
2207         if (!hw->info->mmu_prefetch)
2208                 return;
2209
2210         if (enable)
2211                 dc_write(hw, DC_MMU_PREFETCH, BIT(0));
2212         else
2213                 dc_write(hw, DC_MMU_PREFETCH, 0);
2214 }
2215
2216 void dc_hw_mmu_flush(struct dc_hw *hw)
2217 {
2218         const struct dc_hw_mmu_reg *reg = &dc_mmu_reg;
2219         u32 value = mmu_read(hw, reg->mmu_config);
2220
2221         mmu_write(hw, reg->mmu_config, value | BIT(4));
2222         mmu_write(hw, reg->mmu_config, value);
2223 }
2224 #endif