xref: /linux/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Panels based on the Ilitek ILI9882T display controller.
4  */
5 #include <linux/delay.h>
6 #include <linux/gpio/consumer.h>
7 #include <linux/module.h>
8 #include <linux/of.h>
9 #include <linux/regulator/consumer.h>
10 
11 #include <drm/display/drm_dsc.h>
12 #include <drm/display/drm_dsc_helper.h>
13 #include <drm/drm_connector.h>
14 #include <drm/drm_crtc.h>
15 #include <drm/drm_mipi_dsi.h>
16 #include <drm/drm_of.h>
17 #include <drm/drm_panel.h>
18 
19 #include <video/mipi_display.h>
20 
21 #define DSC_BPG_OFFSET(x)	((u8)((x) & DSC_RANGE_BPG_OFFSET_MASK))
22 
23 struct ili9882t;
24 
25 /*
26  * Use this descriptor struct to describe different panels using the
27  * Ilitek ILI9882T display controller.
28  */
29 struct panel_desc {
30 	const struct drm_display_mode *modes;
31 	const struct drm_dsc_config *dsc;
32 	unsigned int bpc;
33 
34 	/**
35 	 * @width_mm: width of the panel's active display area
36 	 * @height_mm: height of the panel's active display area
37 	 */
38 	struct {
39 		unsigned int width_mm;
40 		unsigned int height_mm;
41 	} size;
42 
43 	unsigned long mode_flags;
44 	enum mipi_dsi_pixel_format format;
45 	int (*init)(struct ili9882t *boe);
46 	unsigned int lanes;
47 };
48 
49 struct ili9882t {
50 	struct drm_panel base;
51 	struct mipi_dsi_device *dsi;
52 
53 	const struct panel_desc *desc;
54 
55 	enum drm_panel_orientation orientation;
56 	struct regulator *pp3300;
57 	struct regulator *pp1800;
58 	struct regulator *avee;
59 	struct regulator *avdd;
60 	struct gpio_desc *enable_gpio;
61 
62 	struct drm_dsc_config dsc;
63 };
64 
65 /* ILI9882-specific commands, add new commands as you decode them */
66 #define ILI9882T_DCS_SWITCH_PAGE	0xFF
67 
68 #define ili9882t_switch_page(ctx, page) \
69 	mipi_dsi_dcs_write_seq_multi(ctx, ILI9882T_DCS_SWITCH_PAGE, \
70 				     0x98, 0x82, (page))
71 
72 /* IL79900A-specific commands, add new commands as you decode them */
73 #define IL79900A_DCS_SWITCH_PAGE	0xFF
74 
75 #define il79900a_switch_page(ctx, page) \
76 	mipi_dsi_dcs_write_seq_multi(ctx, IL79900A_DCS_SWITCH_PAGE, \
77 				     0x5a, 0xa5, (page))
78 
79 static const struct drm_dsc_config tianma_il79900a_dsc = {
80 	.dsc_version_major = 1,
81 	.dsc_version_minor = 2,
82 	.slice_height = 8,
83 	.slice_width = 800,
84 	.slice_count = 2,
85 	.bits_per_component = 8,
86 	.bits_per_pixel = 8 << 4,
87 	.block_pred_enable = true,
88 	.native_420 = false,
89 	.native_422 = false,
90 	.simple_422 = false,
91 	.vbr_enable = false,
92 	.pic_width = 1600,
93 	.pic_height = 2560,
94 	.convert_rgb = 0,
95 	.rc_buf_thresh = {14, 28, 42, 56, 70, 84, 98, 105, 112, 119, 121, 123, 125, 126},
96 	.rc_model_size = DSC_RC_MODEL_SIZE_CONST,
97 	.rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST,
98 	.rc_tgt_offset_high = DSC_RC_TGT_OFFSET_HI_CONST,
99 	.rc_tgt_offset_low = DSC_RC_TGT_OFFSET_LO_CONST,
100 	.mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC,
101 	.line_buf_depth = 9,
102 	.first_line_bpg_offset = 12,
103 	.initial_xmit_delay = 512,
104 	.initial_offset = 6144,
105 	.rc_quant_incr_limit0 = 11,
106 	.rc_quant_incr_limit1 = 11,
107 	.rc_range_params = {
108 		{ 0,  4, DSC_BPG_OFFSET(2)},
109 		{ 0,  4, DSC_BPG_OFFSET(0)},
110 		{ 1,  5, DSC_BPG_OFFSET(0)},
111 		{ 1,  6, DSC_BPG_OFFSET(-2)},
112 		{ 3,  7, DSC_BPG_OFFSET(-4)},
113 		{ 3,  7, DSC_BPG_OFFSET(-6)},
114 		{ 3,  7, DSC_BPG_OFFSET(-8)},
115 		{ 3,  8, DSC_BPG_OFFSET(-8)},
116 		{ 3,  9, DSC_BPG_OFFSET(-8)},
117 		{ 3, 10, DSC_BPG_OFFSET(-10)},
118 		{ 5, 10, DSC_BPG_OFFSET(-10)},
119 		{ 5, 11, DSC_BPG_OFFSET(-12)},
120 		{ 5, 11, DSC_BPG_OFFSET(-12)},
121 		{ 9, 12, DSC_BPG_OFFSET(-12)},
122 		{12, 13, DSC_BPG_OFFSET(-12)},
123 	},
124 	.slice_chunk_size = 800,
125 	.initial_dec_delay = 657,
126 	.final_offset = 4320,
127 	.scale_increment_interval = 222,
128 	.scale_decrement_interval = 11,
129 	.initial_scale_value = 32,
130 	.nfl_bpg_offset = 3511,
131 	.slice_bpg_offset = 2179,
132 	.flatness_max_qp = 12,
133 	.flatness_min_qp = 3,
134 };
135 
136 static int starry_ili9882t_init(struct ili9882t *ili)
137 {
138 	struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi };
139 
140 	usleep_range(5000, 5100);
141 
142 	ili9882t_switch_page(&ctx, 0x01);
143 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x42);
144 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x11);
145 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x00);
146 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x00);
147 
148 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x01);
149 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x11);
150 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x00);
151 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x00);
152 
153 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x80);
154 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x81);
155 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x71);
156 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x00);
157 
158 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x00);
159 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x1a);
160 
161 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
162 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x00);
163 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x00);
164 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
165 
166 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2c, 0xd4);
167 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x40);
168 
169 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x11);
170 
171 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x32);
172 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x30);
173 
174 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x55);
175 
176 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x01);
177 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x93);
178 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x00);
179 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x80);
180 
181 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x07);
182 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x07);
183 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x07);
184 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x07);
185 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x07);
186 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x01);
187 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x00);
188 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x28);
189 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x29);
190 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x11);
191 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x13);
192 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x15);
193 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x17);
194 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x09);
195 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x0d);
196 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x02);
197 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x41, 0x02);
198 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x42, 0x02);
199 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x43, 0x02);
200 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x44, 0x02);
201 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x45, 0x02);
202 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x46, 0x02);
203 
204 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x47, 0x07);
205 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x07);
206 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x49, 0x07);
207 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0x07);
208 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4b, 0x07);
209 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4c, 0x01);
210 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x00);
211 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x28);
212 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4f, 0x29);
213 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x50, 0x10);
214 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0x12);
215 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x52, 0x14);
216 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x16);
217 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x54, 0x08);
218 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x0c);
219 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x02);
220 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x57, 0x02);
221 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x02);
222 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x02);
223 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x02);
224 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x02);
225 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x02);
226 
227 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x07);
228 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x07);
229 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x07);
230 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x07);
231 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x07);
232 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x01);
233 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x00);
234 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x28);
235 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x29);
236 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x16);
237 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6b, 0x14);
238 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x12);
239 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x10);
240 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6e, 0x0c);
241 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6f, 0x08);
242 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x02);
243 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x71, 0x02);
244 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x72, 0x02);
245 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0x02);
246 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x74, 0x02);
247 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0x02);
248 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x76, 0x02);
249 
250 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0x07);
251 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x78, 0x07);
252 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x07);
253 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x07);
254 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0x07);
255 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7c, 0x01);
256 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x00);
257 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x28);
258 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x29);
259 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x17);
260 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x15);
261 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x13);
262 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x83, 0x11);
263 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x0d);
264 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x85, 0x09);
265 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x02);
266 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x07);
267 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x07);
268 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x89, 0x07);
269 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8a, 0x07);
270 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8b, 0x07);
271 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8c, 0x07);
272 
273 	ili9882t_switch_page(&ctx, 0x02);
274 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x3a);
275 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x3b);
276 
277 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x01);
278 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x01);
279 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x0c);
280 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x44);
281 
282 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x0a);
283 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x11);
284 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x00);
285 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x0c);
286 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x44);
287 
288 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x1f);
289 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x40);
290 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x00);
291 
292 	ili9882t_switch_page(&ctx, 0x03);
293 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x01);
294 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x3c);
295 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0xfa);
296 
297 	ili9882t_switch_page(&ctx, 0x0a);
298 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x01);
299 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x01);
300 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x91);
301 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x3c);
302 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x00);
303 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe8, 0xfa);
304 
305 	ili9882t_switch_page(&ctx, 0x12);
306 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x2c);
307 
308 	ili9882t_switch_page(&ctx, 0x05);
309 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0xe5);
310 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x6b);
311 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0xa4);
312 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x54);
313 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x97);
314 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x97);
315 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0x3f);
316 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0xda);
317 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0xf1);
318 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x01);
319 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x3f);
320 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x90);
321 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x87);
322 
323 	ili9882t_switch_page(&ctx, 0x06);
324 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x80);
325 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x07);
326 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x58);
327 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x02);
328 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x58);
329 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x02);
330 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x60);
331 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x00);
332 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22);
333 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x08);
334 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x55);
335 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x38);
336 
337 	ili9882t_switch_page(&ctx, 0x08);
338 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x00, 0x10, 0x2a, 0x4d, 0x61, 0x56, 0x6a, 0x6e,
339 				     0x79, 0x76, 0x8f, 0x95, 0x98, 0xae, 0xaa, 0xb2, 0xbb, 0xce,
340 				     0xc6, 0xbd, 0xd5, 0xe2, 0xe8);
341 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x00, 0x10, 0x2a, 0x4d, 0x61, 0x56, 0x6a, 0x6e,
342 				     0x79, 0x76, 0x8f, 0x95, 0x98, 0xae, 0xaa, 0xb2, 0xbb, 0xce,
343 				     0xc6, 0xbd, 0xd5, 0xe2, 0xe8);
344 
345 	ili9882t_switch_page(&ctx, 0x04);
346 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x81);
347 
348 	ili9882t_switch_page(&ctx, 0x0c);
349 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x02);
350 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x00);
351 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x03);
352 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x01);
353 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x03);
354 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x02);
355 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x04);
356 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x03);
357 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x03);
358 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x04);
359 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x04);
360 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x05);
361 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x04);
362 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x06);
363 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x05);
364 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x07);
365 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x04);
366 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x08);
367 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x05);
368 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x09);
369 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x05);
370 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x0a);
371 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x06);
372 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x0b);
373 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x05);
374 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0c);
375 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x06);
376 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x0d);
377 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x06);
378 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x0e);
379 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x07);
380 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x0f);
381 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x06);
382 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x10);
383 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x07);
384 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x11);
385 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x07);
386 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x12);
387 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x08);
388 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x13);
389 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x07);
390 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x14);
391 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x08);
392 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x15);
393 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2c, 0x08);
394 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x16);
395 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2e, 0x09);
396 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x17);
397 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x08);
398 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x18);
399 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x09);
400 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x19);
401 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x09);
402 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x1a);
403 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x0a);
404 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x1b);
405 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x0a);
406 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x1c);
407 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x0a);
408 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x1d);
409 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x0a);
410 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x1e);
411 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x0a);
412 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x1f);
413 
414 	ili9882t_switch_page(&ctx, 0x04);
415 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x01);
416 
417 	ili9882t_switch_page(&ctx, 0x0e);
418 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x0c);
419 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x10);
420 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x16);
421 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0xe0);
422 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
423 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x71);
424 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x46);
425 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x1f);
426 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0xc7);
427 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x02);
428 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0xdf);
429 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x5a);
430 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0xc0);
431 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x5a);
432 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0xc0);
433 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x65);
434 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x3e);
435 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0xa0);
436 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
437 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0xcc);
438 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x12);
439 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xcc);
440 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcc);
441 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xcc);
442 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xcc);
443 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xcc);
444 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xcc);
445 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xcc);
446 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0xcc);
447 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x00);
448 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x81);
449 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x02);
450 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x00);
451 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x21);
452 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x10);
453 
454 	ili9882t_switch_page(&ctx, 0x1e);
455 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x00);
456 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x00);
457 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x00);
458 
459 	ili9882t_switch_page(&ctx, 0x0b);
460 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa6, 0x44);
461 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0xb6);
462 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa8, 0x03);
463 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa9, 0x03);
464 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xaa, 0x51);
465 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x51);
466 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xac, 0x04);
467 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x92);
468 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xa1);
469 
470 	ili9882t_switch_page(&ctx, 0x05);
471 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x87);
472 
473 	ili9882t_switch_page(&ctx, 0x06);
474 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22);
475 
476 	ili9882t_switch_page(&ctx, 0x00);
477 	mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
478 
479 	mipi_dsi_msleep(&ctx, 120);
480 
481 	mipi_dsi_dcs_set_display_on_multi(&ctx);
482 
483 	mipi_dsi_msleep(&ctx, 20);
484 
485 	return ctx.accum_err;
486 };
487 
488 static int tianma_il79900a_init(struct ili9882t *ili)
489 {
490 	struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi };
491 	struct drm_dsc_picture_parameter_set pps;
492 
493 	mipi_dsi_usleep_range(&ctx, 5000, 5100);
494 
495 	il79900a_switch_page(&ctx, 0x06);
496 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x62);
497 
498 	il79900a_switch_page(&ctx, 0x01);
499 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
500 
501 	il79900a_switch_page(&ctx, 0x02);
502 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x00);
503 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00);
504 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x40);
505 
506 	il79900a_switch_page(&ctx, 0x05);
507 	mipi_dsi_dcs_write_seq_multi(&ctx, 0X9e, 0xe9);
508 
509 	il79900a_switch_page(&ctx, 0x07);
510 	mipi_dsi_dcs_write_seq_multi(&ctx, 0X29, 0x01);
511 
512 	il79900a_switch_page(&ctx, 0x17);
513 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00,
514 				     0x00, 0x89, 0x30, 0x80, 0x0a, 0x00, 0x06, 0x40, 0x00,
515 				     0x08, 0x03, 0x20, 0x03, 0x20, 0x02, 0x00, 0x02, 0x91,
516 				     0x00, 0x20, 0x00, 0xde, 0x00, 0x0b, 0x00, 0x0c, 0x0d,
517 				     0xb7, 0x08, 0x83, 0x18, 0x00, 0x10, 0xe0, 0x03, 0x0c,
518 				     0x20, 0x00, 0x06, 0x0b, 0x0b, 0x33, 0x0e, 0x1c, 0x2a,
519 				     0x38, 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b,
520 				     0x7d, 0x7e, 0x01, 0x02, 0x01, 0x00, 0x09, 0x40, 0x09,
521 				     0xbe, 0x19, 0xfc, 0x19, 0xfa, 0x19, 0xf8, 0x1a, 0x38,
522 				     0x1a, 0x78, 0x1a, 0xb6, 0x2a, 0xb6, 0x2a, 0xf4, 0x2a,
523 				     0xf4, 0x4b, 0x34, 0x63, 0x74);
524 
525 	il79900a_switch_page(&ctx, 0x06);
526 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x91, 0x45);
527 
528 	il79900a_switch_page(&ctx, 0x16);
529 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x4b);
530 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x73);
531 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0xdf);
532 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x01);
533 
534 	il79900a_switch_page(&ctx, 0x10);
535 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x8c);
536 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x3c);
537 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x3d);
538 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0xfc);
539 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x9d);
540 
541 	il79900a_switch_page(&ctx, 0x0e);
542 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x18);
543 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x0e);
544 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0xcd);
545 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x53);
546 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x0e);
547 
548 	il79900a_switch_page(&ctx, 0x1e);
549 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x5c);
550 
551 	drm_dsc_pps_payload_pack(&pps, &tianma_il79900a_dsc);
552 
553 	mipi_dsi_picture_parameter_set_multi(&ctx, &pps);
554 
555 	mipi_dsi_compression_mode_ext_multi(&ctx, true,
556 					    MIPI_DSI_COMPRESSION_DSC, 1);
557 
558 	il79900a_switch_page(&ctx, 0x00);
559 	mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
560 
561 	mipi_dsi_msleep(&ctx, 120);
562 
563 	mipi_dsi_dcs_set_display_on_multi(&ctx);
564 
565 	mipi_dsi_msleep(&ctx, 20);
566 
567 	return ctx.accum_err;
568 };
569 
570 static inline struct ili9882t *to_ili9882t(struct drm_panel *panel)
571 {
572 	return container_of(panel, struct ili9882t, base);
573 }
574 
575 static int ili9882t_disable(struct drm_panel *panel)
576 {
577 	struct ili9882t *ili = to_ili9882t(panel);
578 	struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi };
579 
580 	ili9882t_switch_page(&ctx, 0x00);
581 
582 	ili->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
583 
584 	mipi_dsi_dcs_set_display_off_multi(&ctx);
585 	mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
586 
587 	mipi_dsi_msleep(&ctx, 150);
588 
589 	return ctx.accum_err;
590 }
591 
592 static int ili9882t_unprepare(struct drm_panel *panel)
593 {
594 	struct ili9882t *ili = to_ili9882t(panel);
595 
596 	gpiod_set_value_cansleep(ili->enable_gpio, 0);
597 	usleep_range(1000, 2000);
598 	regulator_disable(ili->avee);
599 	regulator_disable(ili->avdd);
600 	usleep_range(5000, 7000);
601 	regulator_disable(ili->pp1800);
602 	regulator_disable(ili->pp3300);
603 
604 	return 0;
605 }
606 
607 static int ili9882t_prepare(struct drm_panel *panel)
608 {
609 	struct ili9882t *ili = to_ili9882t(panel);
610 	int ret;
611 
612 	gpiod_set_value_cansleep(ili->enable_gpio, 0);
613 	usleep_range(1000, 1500);
614 
615 	ret = regulator_enable(ili->pp3300);
616 	if (ret < 0)
617 		return ret;
618 
619 	ret = regulator_enable(ili->pp1800);
620 	if (ret < 0)
621 		return ret;
622 
623 	usleep_range(3000, 5000);
624 
625 	ret = regulator_enable(ili->avdd);
626 	if (ret < 0)
627 		goto poweroff1v8;
628 	ret = regulator_enable(ili->avee);
629 	if (ret < 0)
630 		goto poweroffavdd;
631 
632 	usleep_range(10000, 11000);
633 
634 	// MIPI needs to keep the LP11 state before the lcm_reset pin is pulled high
635 	ret = mipi_dsi_dcs_nop(ili->dsi);
636 	if (ret < 0) {
637 		dev_err(&ili->dsi->dev, "Failed to send NOP: %d\n", ret);
638 		goto poweroff;
639 	}
640 	usleep_range(1000, 2000);
641 
642 	gpiod_set_value_cansleep(ili->enable_gpio, 1);
643 	usleep_range(1000, 2000);
644 	gpiod_set_value_cansleep(ili->enable_gpio, 0);
645 	msleep(50);
646 	gpiod_set_value_cansleep(ili->enable_gpio, 1);
647 	usleep_range(6000, 10000);
648 
649 	ret = ili->desc->init(ili);
650 	if (ret < 0)
651 		goto poweroff;
652 
653 	return 0;
654 
655 poweroff:
656 	gpiod_set_value_cansleep(ili->enable_gpio, 0);
657 	regulator_disable(ili->avee);
658 poweroffavdd:
659 	regulator_disable(ili->avdd);
660 poweroff1v8:
661 	usleep_range(5000, 7000);
662 	regulator_disable(ili->pp1800);
663 
664 	return ret;
665 }
666 
667 static int ili9882t_enable(struct drm_panel *panel)
668 {
669 	msleep(130);
670 	return 0;
671 }
672 
673 static const struct drm_display_mode starry_ili9882t_default_mode = {
674 	.clock = 165280,
675 	.hdisplay = 1200,
676 	.hsync_start = 1200 + 72,
677 	.hsync_end = 1200 + 72 + 30,
678 	.htotal = 1200 + 72 + 30 + 72,
679 	.vdisplay = 1920,
680 	.vsync_start = 1920 + 68,
681 	.vsync_end = 1920 + 68 + 2,
682 	.vtotal = 1920 + 68 + 2 + 10,
683 	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
684 };
685 
686 static const struct drm_display_mode tianma_il79900a_default_mode = {
687 	.clock = 543850,
688 	.hdisplay = 1600,
689 	.hsync_start = 1600 + 20,
690 	.hsync_end = 1600 + 20 + 2,
691 	.htotal = 1600 + 20 + 2 + 20,
692 	.vdisplay = 2560,
693 	.vsync_start = 2560 + 62,
694 	.vsync_end = 2560 + 62 + 2,
695 	.vtotal = 2560 + 62 + 2 + 136,
696 	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
697 };
698 
699 static const struct panel_desc starry_ili9882t_desc = {
700 	.modes = &starry_ili9882t_default_mode,
701 	.bpc = 8,
702 	.size = {
703 		.width_mm = 141,
704 		.height_mm = 226,
705 	},
706 	.lanes = 4,
707 	.format = MIPI_DSI_FMT_RGB888,
708 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
709 		      MIPI_DSI_MODE_LPM,
710 	.init = starry_ili9882t_init,
711 };
712 
713 static const struct panel_desc tianma_tl121bvms07_desc = {
714 	.modes = &tianma_il79900a_default_mode,
715 	.dsc = &tianma_il79900a_dsc,
716 	.bpc = 8,
717 	.size = {
718 		.width_mm = 163,
719 		.height_mm = 260,
720 	},
721 	.lanes = 3,
722 	.format = MIPI_DSI_FMT_RGB888,
723 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
724 		      MIPI_DSI_MODE_LPM,
725 	.init = tianma_il79900a_init,
726 };
727 
728 static int ili9882t_get_modes(struct drm_panel *panel,
729 			      struct drm_connector *connector)
730 {
731 	struct ili9882t *ili = to_ili9882t(panel);
732 	const struct drm_display_mode *m = ili->desc->modes;
733 	struct drm_display_mode *mode;
734 
735 	mode = drm_mode_duplicate(connector->dev, m);
736 	if (!mode) {
737 		dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
738 			m->hdisplay, m->vdisplay, drm_mode_vrefresh(m));
739 		return -ENOMEM;
740 	}
741 
742 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
743 	drm_mode_set_name(mode);
744 	drm_mode_probed_add(connector, mode);
745 
746 	connector->display_info.width_mm = ili->desc->size.width_mm;
747 	connector->display_info.height_mm = ili->desc->size.height_mm;
748 	connector->display_info.bpc = ili->desc->bpc;
749 
750 	return 1;
751 }
752 
753 static enum drm_panel_orientation ili9882t_get_orientation(struct drm_panel *panel)
754 {
755 	struct ili9882t *ili = to_ili9882t(panel);
756 
757 	return ili->orientation;
758 }
759 
760 static const struct drm_panel_funcs ili9882t_funcs = {
761 	.disable = ili9882t_disable,
762 	.unprepare = ili9882t_unprepare,
763 	.prepare = ili9882t_prepare,
764 	.enable = ili9882t_enable,
765 	.get_modes = ili9882t_get_modes,
766 	.get_orientation = ili9882t_get_orientation,
767 };
768 
769 static int ili9882t_add(struct ili9882t *ili)
770 {
771 	struct device *dev = &ili->dsi->dev;
772 	int err;
773 
774 	ili->avdd = devm_regulator_get(dev, "avdd");
775 	if (IS_ERR(ili->avdd))
776 		return PTR_ERR(ili->avdd);
777 
778 	ili->avee = devm_regulator_get(dev, "avee");
779 	if (IS_ERR(ili->avee))
780 		return PTR_ERR(ili->avee);
781 
782 	ili->pp3300 = devm_regulator_get(dev, "pp3300");
783 	if (IS_ERR(ili->pp3300))
784 		return PTR_ERR(ili->pp3300);
785 
786 	ili->pp1800 = devm_regulator_get(dev, "pp1800");
787 	if (IS_ERR(ili->pp1800))
788 		return PTR_ERR(ili->pp1800);
789 
790 	ili->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
791 	if (IS_ERR(ili->enable_gpio)) {
792 		dev_err(dev, "cannot get enable-gpios %ld\n",
793 			PTR_ERR(ili->enable_gpio));
794 		return PTR_ERR(ili->enable_gpio);
795 	}
796 
797 	gpiod_set_value_cansleep(ili->enable_gpio, 0);
798 
799 	err = drm_of_get_panel_orientation(dev->of_node, &ili->orientation);
800 	if (err < 0) {
801 		dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
802 		return err;
803 	}
804 
805 	err = drm_panel_of_backlight(&ili->base);
806 	if (err)
807 		return err;
808 
809 	ili->base.funcs = &ili9882t_funcs;
810 	ili->base.dev = &ili->dsi->dev;
811 
812 	drm_panel_add(&ili->base);
813 
814 	return 0;
815 }
816 
817 static int ili9882t_probe(struct mipi_dsi_device *dsi)
818 {
819 	struct ili9882t *ili;
820 	int ret;
821 	const struct panel_desc *desc;
822 
823 	ili = devm_drm_panel_alloc(&dsi->dev, __typeof(*ili), base,
824 				   &ili9882t_funcs, DRM_MODE_CONNECTOR_DSI);
825 
826 	if (IS_ERR(ili))
827 		return PTR_ERR(ili);
828 
829 	desc = of_device_get_match_data(&dsi->dev);
830 	dsi->lanes = desc->lanes;
831 	dsi->format = desc->format;
832 	dsi->mode_flags = desc->mode_flags;
833 	ili->desc = desc;
834 	ili->dsi = dsi;
835 
836 	if (desc->dsc) {
837 		ili->dsc = *desc->dsc;
838 		dsi->dsc = &ili->dsc;
839 	}
840 
841 	ret = ili9882t_add(ili);
842 	if (ret < 0)
843 		return ret;
844 
845 	mipi_dsi_set_drvdata(dsi, ili);
846 
847 	ret = mipi_dsi_attach(dsi);
848 	if (ret)
849 		drm_panel_remove(&ili->base);
850 
851 	return ret;
852 }
853 
854 static void ili9882t_remove(struct mipi_dsi_device *dsi)
855 {
856 	struct ili9882t *ili = mipi_dsi_get_drvdata(dsi);
857 	int ret;
858 
859 	ret = mipi_dsi_detach(dsi);
860 	if (ret < 0)
861 		dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
862 
863 	if (ili->base.dev)
864 		drm_panel_remove(&ili->base);
865 }
866 
867 static const struct of_device_id ili9882t_of_match[] = {
868 	{ .compatible = "starry,ili9882t",
869 	  .data = &starry_ili9882t_desc
870 	},
871 	{ .compatible = "tianma,tl121bvms07-00",
872 	  .data = &tianma_tl121bvms07_desc
873 	},
874 	{ /* sentinel */ }
875 };
876 MODULE_DEVICE_TABLE(of, ili9882t_of_match);
877 
878 static struct mipi_dsi_driver ili9882t_driver = {
879 	.driver = {
880 		.name = "panel-ili9882t",
881 		.of_match_table = ili9882t_of_match,
882 	},
883 	.probe = ili9882t_probe,
884 	.remove = ili9882t_remove,
885 };
886 module_mipi_dsi_driver(ili9882t_driver);
887 
888 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
889 MODULE_DESCRIPTION("Ilitek ILI9882T-based panels driver");
890 MODULE_LICENSE("GPL");
891