Merge branches 'pm-cpuidle', 'pm-sleep' and 'pm-powercap'
[linux-block.git] / drivers / gpu / drm / panel / panel-novatek-nt36672e.c
CommitLineData
ea4f9975
RK
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
3
4#include <linux/delay.h>
5#include <linux/gpio/consumer.h>
6#include <linux/module.h>
2095d507 7#include <linux/of.h>
ea4f9975
RK
8#include <linux/regulator/consumer.h>
9
10#include <drm/drm_mipi_dsi.h>
11#include <drm/drm_modes.h>
12#include <drm/drm_panel.h>
13
14#include <video/mipi_display.h>
15
16static const char * const regulator_names[] = {
17 "vddi",
18 "avdd",
19 "avee",
20};
21
22static const unsigned long regulator_enable_loads[] = {
23 62000,
24 100000,
25 100000,
26};
27
28static const unsigned long regulator_disable_loads[] = {
29 80,
30 100,
31 100,
32};
33
34struct panel_desc {
35 const struct drm_display_mode *display_mode;
36 u32 width_mm;
37 u32 height_mm;
38 unsigned long mode_flags;
39 enum mipi_dsi_pixel_format format;
40 unsigned int lanes;
41 const char *panel_name;
42 int (*init_sequence)(struct mipi_dsi_device *dsi);
43};
44
45struct nt36672e_panel {
46 struct drm_panel panel;
47 struct mipi_dsi_device *dsi;
48 struct gpio_desc *reset_gpio;
49 struct regulator_bulk_data supplies[3];
50 const struct panel_desc *desc;
51};
52
53static inline struct nt36672e_panel *to_nt36672e_panel(struct drm_panel *panel)
54{
55 return container_of(panel, struct nt36672e_panel, panel);
56}
57
58static int nt36672e_1080x2408_60hz_init(struct mipi_dsi_device *dsi)
59{
60 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
61 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
62 mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00);
63 mipi_dsi_dcs_write_seq(dsi, 0xc0, 0x00);
64 mipi_dsi_dcs_write_seq(dsi, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 0x02,
65 0x0e, 0x00, 0x2b, 0x00, 0x07, 0x0d, 0xb7, 0x0c, 0xb7);
66
67 mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x1b, 0xa0);
68 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
69 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
70 mipi_dsi_dcs_write_seq(dsi, 0x01, 0x66);
71 mipi_dsi_dcs_write_seq(dsi, 0x06, 0x40);
72 mipi_dsi_dcs_write_seq(dsi, 0x07, 0x38);
73 mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x83);
74 mipi_dsi_dcs_write_seq(dsi, 0x69, 0x91);
75 mipi_dsi_dcs_write_seq(dsi, 0x95, 0xd1);
76 mipi_dsi_dcs_write_seq(dsi, 0x96, 0xd1);
77 mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x64);
78 mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x54);
79 mipi_dsi_dcs_write_seq(dsi, 0xf4, 0x64);
80 mipi_dsi_dcs_write_seq(dsi, 0xf5, 0x54);
81 mipi_dsi_dcs_write_seq(dsi, 0xf6, 0x64);
82 mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x54);
83 mipi_dsi_dcs_write_seq(dsi, 0xf8, 0x64);
84 mipi_dsi_dcs_write_seq(dsi, 0xf9, 0x54);
85 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24);
86 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
87 mipi_dsi_dcs_write_seq(dsi, 0x01, 0x0f);
88 mipi_dsi_dcs_write_seq(dsi, 0x03, 0x0c);
89 mipi_dsi_dcs_write_seq(dsi, 0x05, 0x1d);
90 mipi_dsi_dcs_write_seq(dsi, 0x08, 0x2f);
91 mipi_dsi_dcs_write_seq(dsi, 0x09, 0x2e);
92 mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x2d);
93 mipi_dsi_dcs_write_seq(dsi, 0x0b, 0x2c);
94 mipi_dsi_dcs_write_seq(dsi, 0x11, 0x17);
95 mipi_dsi_dcs_write_seq(dsi, 0x12, 0x13);
96 mipi_dsi_dcs_write_seq(dsi, 0x13, 0x15);
97 mipi_dsi_dcs_write_seq(dsi, 0x15, 0x14);
98 mipi_dsi_dcs_write_seq(dsi, 0x16, 0x16);
99 mipi_dsi_dcs_write_seq(dsi, 0x17, 0x18);
100 mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x01);
101 mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1d);
102 mipi_dsi_dcs_write_seq(dsi, 0x20, 0x2f);
103 mipi_dsi_dcs_write_seq(dsi, 0x21, 0x2e);
104 mipi_dsi_dcs_write_seq(dsi, 0x22, 0x2d);
105 mipi_dsi_dcs_write_seq(dsi, 0x23, 0x2c);
106 mipi_dsi_dcs_write_seq(dsi, 0x29, 0x17);
107 mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x13);
108 mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x15);
109 mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x14);
110 mipi_dsi_dcs_write_seq(dsi, 0x30, 0x16);
111 mipi_dsi_dcs_write_seq(dsi, 0x31, 0x18);
112 mipi_dsi_dcs_write_seq(dsi, 0x32, 0x04);
113 mipi_dsi_dcs_write_seq(dsi, 0x34, 0x10);
114 mipi_dsi_dcs_write_seq(dsi, 0x35, 0x1f);
115 mipi_dsi_dcs_write_seq(dsi, 0x36, 0x1f);
116 mipi_dsi_dcs_write_seq(dsi, 0x4d, 0x14);
117 mipi_dsi_dcs_write_seq(dsi, 0x4e, 0x36);
118 mipi_dsi_dcs_write_seq(dsi, 0x4f, 0x36);
119 mipi_dsi_dcs_write_seq(dsi, 0x53, 0x36);
120 mipi_dsi_dcs_write_seq(dsi, 0x71, 0x30);
121 mipi_dsi_dcs_write_seq(dsi, 0x79, 0x11);
122 mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x82);
123 mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x8f);
124 mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x04);
125 mipi_dsi_dcs_write_seq(dsi, 0x80, 0x04);
126 mipi_dsi_dcs_write_seq(dsi, 0x81, 0x04);
127 mipi_dsi_dcs_write_seq(dsi, 0x82, 0x13);
128 mipi_dsi_dcs_write_seq(dsi, 0x84, 0x31);
129 mipi_dsi_dcs_write_seq(dsi, 0x85, 0x00);
130 mipi_dsi_dcs_write_seq(dsi, 0x86, 0x00);
131 mipi_dsi_dcs_write_seq(dsi, 0x87, 0x00);
132 mipi_dsi_dcs_write_seq(dsi, 0x90, 0x13);
133 mipi_dsi_dcs_write_seq(dsi, 0x92, 0x31);
134 mipi_dsi_dcs_write_seq(dsi, 0x93, 0x00);
135 mipi_dsi_dcs_write_seq(dsi, 0x94, 0x00);
136 mipi_dsi_dcs_write_seq(dsi, 0x95, 0x00);
137 mipi_dsi_dcs_write_seq(dsi, 0x9c, 0xf4);
138 mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x01);
139 mipi_dsi_dcs_write_seq(dsi, 0xa0, 0x0f);
140 mipi_dsi_dcs_write_seq(dsi, 0xa2, 0x0f);
141 mipi_dsi_dcs_write_seq(dsi, 0xa3, 0x02);
142 mipi_dsi_dcs_write_seq(dsi, 0xa4, 0x04);
143 mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x04);
144 mipi_dsi_dcs_write_seq(dsi, 0xc6, 0xc0);
145 mipi_dsi_dcs_write_seq(dsi, 0xc9, 0x00);
146 mipi_dsi_dcs_write_seq(dsi, 0xd9, 0x80);
147 mipi_dsi_dcs_write_seq(dsi, 0xe9, 0x02);
148 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25);
149 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
150 mipi_dsi_dcs_write_seq(dsi, 0x18, 0x22);
151 mipi_dsi_dcs_write_seq(dsi, 0x19, 0xe4);
152 mipi_dsi_dcs_write_seq(dsi, 0x21, 0x40);
153 mipi_dsi_dcs_write_seq(dsi, 0x66, 0xd8);
154 mipi_dsi_dcs_write_seq(dsi, 0x68, 0x50);
155 mipi_dsi_dcs_write_seq(dsi, 0x69, 0x10);
156 mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x00);
157 mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x0d);
158 mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x48);
159 mipi_dsi_dcs_write_seq(dsi, 0x72, 0x41);
160 mipi_dsi_dcs_write_seq(dsi, 0x73, 0x4a);
161 mipi_dsi_dcs_write_seq(dsi, 0x74, 0xd0);
162 mipi_dsi_dcs_write_seq(dsi, 0x77, 0x62);
163 mipi_dsi_dcs_write_seq(dsi, 0x79, 0x7e);
164 mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x03);
165 mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x15);
166 mipi_dsi_dcs_write_seq(dsi, 0x7f, 0x00);
167 mipi_dsi_dcs_write_seq(dsi, 0x84, 0x4d);
168 mipi_dsi_dcs_write_seq(dsi, 0xcf, 0x80);
169 mipi_dsi_dcs_write_seq(dsi, 0xd6, 0x80);
170 mipi_dsi_dcs_write_seq(dsi, 0xd7, 0x80);
171 mipi_dsi_dcs_write_seq(dsi, 0xef, 0x20);
172 mipi_dsi_dcs_write_seq(dsi, 0xf0, 0x84);
173 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26);
174 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
175 mipi_dsi_dcs_write_seq(dsi, 0x81, 0x0f);
176 mipi_dsi_dcs_write_seq(dsi, 0x83, 0x01);
177 mipi_dsi_dcs_write_seq(dsi, 0x84, 0x03);
178 mipi_dsi_dcs_write_seq(dsi, 0x85, 0x01);
179 mipi_dsi_dcs_write_seq(dsi, 0x86, 0x03);
180 mipi_dsi_dcs_write_seq(dsi, 0x87, 0x01);
181 mipi_dsi_dcs_write_seq(dsi, 0x88, 0x05);
182 mipi_dsi_dcs_write_seq(dsi, 0x8a, 0x1a);
183 mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x11);
184 mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x24);
185 mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x42);
186 mipi_dsi_dcs_write_seq(dsi, 0x8f, 0x11);
187 mipi_dsi_dcs_write_seq(dsi, 0x90, 0x11);
188 mipi_dsi_dcs_write_seq(dsi, 0x91, 0x11);
189 mipi_dsi_dcs_write_seq(dsi, 0x9a, 0x80);
190 mipi_dsi_dcs_write_seq(dsi, 0x9b, 0x04);
191 mipi_dsi_dcs_write_seq(dsi, 0x9c, 0x00);
192 mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x00);
193 mipi_dsi_dcs_write_seq(dsi, 0x9e, 0x00);
194 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x27);
195 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
196 mipi_dsi_dcs_write_seq(dsi, 0x01, 0x68);
197 mipi_dsi_dcs_write_seq(dsi, 0x20, 0x81);
198 mipi_dsi_dcs_write_seq(dsi, 0x21, 0x6a);
199 mipi_dsi_dcs_write_seq(dsi, 0x25, 0x81);
200 mipi_dsi_dcs_write_seq(dsi, 0x26, 0x94);
201 mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x00);
202 mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x00);
203 mipi_dsi_dcs_write_seq(dsi, 0x70, 0x00);
204 mipi_dsi_dcs_write_seq(dsi, 0x71, 0x00);
205 mipi_dsi_dcs_write_seq(dsi, 0x72, 0x00);
206 mipi_dsi_dcs_write_seq(dsi, 0x75, 0x00);
207 mipi_dsi_dcs_write_seq(dsi, 0x76, 0x00);
208 mipi_dsi_dcs_write_seq(dsi, 0x77, 0x00);
209 mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x09);
210 mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x67);
211 mipi_dsi_dcs_write_seq(dsi, 0x80, 0x23);
212 mipi_dsi_dcs_write_seq(dsi, 0x82, 0x09);
213 mipi_dsi_dcs_write_seq(dsi, 0x83, 0x67);
214 mipi_dsi_dcs_write_seq(dsi, 0x88, 0x01);
215 mipi_dsi_dcs_write_seq(dsi, 0x89, 0x10);
216 mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x10);
217 mipi_dsi_dcs_write_seq(dsi, 0xa6, 0x23);
218 mipi_dsi_dcs_write_seq(dsi, 0xa7, 0x01);
219 mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x40);
220 mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x02);
221 mipi_dsi_dcs_write_seq(dsi, 0xe6, 0xd3);
222 mipi_dsi_dcs_write_seq(dsi, 0xeb, 0x03);
223 mipi_dsi_dcs_write_seq(dsi, 0xec, 0x28);
224 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a);
225 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
226 mipi_dsi_dcs_write_seq(dsi, 0x00, 0x91);
227 mipi_dsi_dcs_write_seq(dsi, 0x03, 0x20);
228 mipi_dsi_dcs_write_seq(dsi, 0x07, 0x50);
229 mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x70);
230 mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x04);
231 mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x40);
232 mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x01);
233 mipi_dsi_dcs_write_seq(dsi, 0x11, 0xe0);
234 mipi_dsi_dcs_write_seq(dsi, 0x15, 0x0f);
235 mipi_dsi_dcs_write_seq(dsi, 0x16, 0xa4);
236 mipi_dsi_dcs_write_seq(dsi, 0x19, 0x0f);
237 mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x78);
238 mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x23);
239 mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x36);
240 mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x3e);
241 mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x3e);
242 mipi_dsi_dcs_write_seq(dsi, 0x20, 0x3e);
243 mipi_dsi_dcs_write_seq(dsi, 0x28, 0xfd);
244 mipi_dsi_dcs_write_seq(dsi, 0x29, 0x12);
245 mipi_dsi_dcs_write_seq(dsi, 0x2a, 0xe1);
246 mipi_dsi_dcs_write_seq(dsi, 0x2d, 0x0a);
247 mipi_dsi_dcs_write_seq(dsi, 0x30, 0x49);
248 mipi_dsi_dcs_write_seq(dsi, 0x33, 0x96);
249 mipi_dsi_dcs_write_seq(dsi, 0x34, 0xff);
250 mipi_dsi_dcs_write_seq(dsi, 0x35, 0x40);
251 mipi_dsi_dcs_write_seq(dsi, 0x36, 0xde);
252 mipi_dsi_dcs_write_seq(dsi, 0x37, 0xf9);
253 mipi_dsi_dcs_write_seq(dsi, 0x38, 0x45);
254 mipi_dsi_dcs_write_seq(dsi, 0x39, 0xd9);
255 mipi_dsi_dcs_write_seq(dsi, 0x3a, 0x49);
256 mipi_dsi_dcs_write_seq(dsi, 0x4a, 0xf0);
257 mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x09);
258 mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x40);
259 mipi_dsi_dcs_write_seq(dsi, 0x7f, 0xf0);
260 mipi_dsi_dcs_write_seq(dsi, 0x83, 0x0f);
261 mipi_dsi_dcs_write_seq(dsi, 0x84, 0xa4);
262 mipi_dsi_dcs_write_seq(dsi, 0x87, 0x0f);
263 mipi_dsi_dcs_write_seq(dsi, 0x88, 0x78);
264 mipi_dsi_dcs_write_seq(dsi, 0x89, 0x23);
265 mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x36);
266 mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x7d);
267 mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x7d);
268 mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x7d);
269 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
270 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
271 mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
272 0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
273 mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
274 0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
275 mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
276 0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
277 mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
278 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
279 mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
280 0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
281 mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
282 0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
283 mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
284 0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
285 mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
286 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
287 mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
288 0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
289 mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
290 0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
291 mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
292 0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
293 mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
294 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
295 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x21);
296 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
297 mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
298 0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
299 mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
300 0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
301 mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
302 0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
303 mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
304 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
305 mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
306 0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
307 mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
308 0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
309 mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
310 0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
311 mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
312 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
313 mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
314 0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
315 mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
316 0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
317 mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
318 0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
319 mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
320 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
321 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2c);
322 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
323 mipi_dsi_dcs_write_seq(dsi, 0x61, 0x1f);
324 mipi_dsi_dcs_write_seq(dsi, 0x62, 0x1f);
325 mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x03);
326 mipi_dsi_dcs_write_seq(dsi, 0x6a, 0x14);
327 mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x36);
328 mipi_dsi_dcs_write_seq(dsi, 0x6c, 0x36);
329 mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x36);
330 mipi_dsi_dcs_write_seq(dsi, 0x53, 0x04);
331 mipi_dsi_dcs_write_seq(dsi, 0x54, 0x04);
332 mipi_dsi_dcs_write_seq(dsi, 0x55, 0x04);
333 mipi_dsi_dcs_write_seq(dsi, 0x56, 0x0f);
334 mipi_dsi_dcs_write_seq(dsi, 0x58, 0x0f);
335 mipi_dsi_dcs_write_seq(dsi, 0x59, 0x0f);
336 mipi_dsi_dcs_write_seq(dsi, 0xff, 0xf0);
337 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
338 mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x00);
339
340 mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
341 mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
342 mipi_dsi_dcs_write_seq(dsi, 0x51, 0xff);
343 mipi_dsi_dcs_write_seq(dsi, 0x53, 0x24);
344 mipi_dsi_dcs_write_seq(dsi, 0x55, 0x01);
345
346 return 0;
347}
348
349static int nt36672e_power_on(struct nt36672e_panel *ctx)
350{
351 struct mipi_dsi_device *dsi = ctx->dsi;
352 int ret, i;
353
354 for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++) {
355 ret = regulator_set_load(ctx->supplies[i].consumer,
356 regulator_enable_loads[i]);
357 if (ret) {
358 dev_err(&dsi->dev, "regulator set load failed for supply %s: %d\n",
359 ctx->supplies[i].supply, ret);
360 return ret;
361 }
362 }
363
364 ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
365 if (ret < 0) {
366 dev_err(&dsi->dev, "regulator bulk enable failed: %d\n", ret);
367 return ret;
368 }
369
370 /*
371 * Reset sequence of nt36672e panel requires the panel to be out of reset
372 * for 10ms, followed by being held in reset for 10ms and then out again.
373 */
374 gpiod_set_value(ctx->reset_gpio, 1);
375 usleep_range(10000, 20000);
376 gpiod_set_value(ctx->reset_gpio, 0);
377 usleep_range(10000, 20000);
378 gpiod_set_value(ctx->reset_gpio, 1);
379 usleep_range(10000, 20000);
380
381 return 0;
382}
383
384static int nt36672e_power_off(struct nt36672e_panel *ctx)
385{
386 struct mipi_dsi_device *dsi = ctx->dsi;
387 int ret = 0;
388 int i;
389
390 gpiod_set_value(ctx->reset_gpio, 0);
391
392 for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++) {
393 ret = regulator_set_load(ctx->supplies[i].consumer,
394 regulator_disable_loads[i]);
395 if (ret) {
396 dev_err(&dsi->dev, "regulator set load failed for supply %s: %d\n",
397 ctx->supplies[i].supply, ret);
398 return ret;
399 }
400 }
401
402 ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
403 if (ret)
404 dev_err(&dsi->dev, "regulator bulk disable failed: %d\n", ret);
405
406 return ret;
407}
408
409static int nt36672e_on(struct nt36672e_panel *ctx)
410{
411 struct mipi_dsi_device *dsi = ctx->dsi;
412 const struct panel_desc *desc = ctx->desc;
413 int ret = 0;
414
415 dsi->mode_flags |= MIPI_DSI_MODE_LPM;
416
417 if (desc->init_sequence) {
418 ret = desc->init_sequence(dsi);
419 if (ret < 0) {
420 dev_err(&dsi->dev, "panel init sequence failed: %d\n", ret);
421 return ret;
422 }
423 }
424
425 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
426 if (ret < 0) {
427 dev_err(&dsi->dev, "Failed to exit sleep mode: %d\n", ret);
428 return ret;
429 }
430 msleep(120);
431
432 ret = mipi_dsi_dcs_set_display_on(dsi);
433 if (ret < 0) {
434 dev_err(&dsi->dev, "Failed to set display on: %d\n", ret);
435 return ret;
436 }
437 msleep(100);
438
439 return 0;
440}
441
442static int nt36672e_off(struct nt36672e_panel *ctx)
443{
444 struct mipi_dsi_device *dsi = ctx->dsi;
445 int ret = 0;
446
447 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
448
449 ret = mipi_dsi_dcs_set_display_off(dsi);
450 if (ret < 0) {
451 dev_err(&dsi->dev, "Failed to set display off: %d\n", ret);
452 return ret;
453 }
454 msleep(20);
455
456 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
457 if (ret < 0) {
458 dev_err(&dsi->dev, "Failed to enter sleep mode: %d\n", ret);
459 return ret;
460 }
461 msleep(60);
462
463 return 0;
464}
465
466static int nt36672e_panel_prepare(struct drm_panel *panel)
467{
468 struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
469 struct mipi_dsi_device *dsi = ctx->dsi;
470 int ret = 0;
471
472 ret = nt36672e_power_on(ctx);
473 if (ret < 0)
474 return ret;
475
476 ret = nt36672e_on(ctx);
477 if (ret < 0) {
478 dev_err(&dsi->dev, "Failed to initialize panel: %d\n", ret);
479 if (nt36672e_power_off(ctx))
480 dev_err(&dsi->dev, "power off failed\n");
481 return ret;
482 }
483
484 return 0;
485}
486
487static int nt36672e_panel_unprepare(struct drm_panel *panel)
488{
489 struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
490 struct mipi_dsi_device *dsi = ctx->dsi;
491 int ret = 0;
492
493 ret = nt36672e_off(ctx);
494 if (ret < 0)
495 dev_err(&dsi->dev, "Failed to un-initialize panel: %d\n", ret);
496
497 ret = nt36672e_power_off(ctx);
498 if (ret < 0)
499 dev_err(&dsi->dev, "power off failed: %d\n", ret);
500
501 return 0;
502}
503
504static const struct drm_display_mode nt36672e_1080x2408_60hz = {
505 .name = "1080x2408",
506 .clock = 181690,
507 .hdisplay = 1080,
508 .hsync_start = 1080 + 76,
509 .hsync_end = 1080 + 76 + 12,
510 .htotal = 1080 + 76 + 12 + 56,
511 .vdisplay = 2408,
512 .vsync_start = 2408 + 46,
513 .vsync_end = 2408 + 46 + 10,
514 .vtotal = 2408 + 46 + 10 + 10,
515 .flags = 0,
516};
517
518static const struct panel_desc nt36672e_panel_desc = {
519 .display_mode = &nt36672e_1080x2408_60hz,
520 .width_mm = 74,
521 .height_mm = 131,
522 .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
523 .format = MIPI_DSI_FMT_RGB888,
524 .lanes = 4,
525 .panel_name = "nt36672e fhd plus panel",
526 .init_sequence = nt36672e_1080x2408_60hz_init,
527};
528
529static int nt36672e_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector)
530{
531 struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
532 struct drm_display_mode *mode;
533
534 mode = drm_mode_duplicate(connector->dev, ctx->desc->display_mode);
535 if (!mode)
536 return -ENOMEM;
537
538 drm_mode_set_name(mode);
539
540 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
541 connector->display_info.width_mm = ctx->desc->width_mm;
542 connector->display_info.height_mm = ctx->desc->height_mm;
543 drm_mode_probed_add(connector, mode);
544
545 return 1;
546}
547
548static const struct drm_panel_funcs nt36672e_drm_funcs = {
549 .prepare = nt36672e_panel_prepare,
550 .unprepare = nt36672e_panel_unprepare,
551 .get_modes = nt36672e_panel_get_modes,
552};
553
554static int nt36672e_panel_probe(struct mipi_dsi_device *dsi)
555{
556 struct device *dev = &dsi->dev;
557 struct nt36672e_panel *ctx;
558 int i, ret = 0;
559
560 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
561 if (!ctx)
562 return -ENOMEM;
563
564 ctx->desc = of_device_get_match_data(dev);
565 if (!ctx->desc) {
566 dev_err(dev, "missing device configuration\n");
567 return -ENODEV;
568 }
569
570 for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++)
571 ctx->supplies[i].supply = regulator_names[i];
572
573 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
574 ctx->supplies);
575 if (ret < 0)
576 return ret;
577
578 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
579 if (IS_ERR(ctx->reset_gpio))
580 return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "Failed to get reset-gpios\n");
581
582 ctx->dsi = dsi;
583 mipi_dsi_set_drvdata(dsi, ctx);
584
585 dsi->lanes = ctx->desc->lanes;
586 dsi->format = ctx->desc->format;
587 dsi->mode_flags = ctx->desc->mode_flags;
588
589 drm_panel_init(&ctx->panel, dev, &nt36672e_drm_funcs, DRM_MODE_CONNECTOR_DSI);
590
591 ret = drm_panel_of_backlight(&ctx->panel);
592 if (ret)
593 return dev_err_probe(dev, ret, "Failed to get backlight\n");
594
595 ctx->panel.prepare_prev_first = true;
596
597 drm_panel_add(&ctx->panel);
598
599 ret = mipi_dsi_attach(dsi);
600 if (ret < 0) {
601 dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
602 goto err_dsi_attach;
603 }
604
605 return 0;
606
607err_dsi_attach:
608 drm_panel_remove(&ctx->panel);
609 return ret;
610}
611
612static void nt36672e_panel_remove(struct mipi_dsi_device *dsi)
613{
614 struct nt36672e_panel *ctx = mipi_dsi_get_drvdata(dsi);
615
616 mipi_dsi_detach(ctx->dsi);
ea4f9975
RK
617 drm_panel_remove(&ctx->panel);
618}
619
620static const struct of_device_id nt36672e_of_match[] = {
621 {
622 .compatible = "novatek,nt36672e",
623 .data = &nt36672e_panel_desc,
624 },
625 { }
626};
627MODULE_DEVICE_TABLE(of, nt36672e_of_match);
628
629static struct mipi_dsi_driver nt36672e_panel_driver = {
630 .driver = {
631 .name = "panel-novatek-nt36672e",
632 .of_match_table = nt36672e_of_match,
633 },
634 .probe = nt36672e_panel_probe,
635 .remove = nt36672e_panel_remove,
636};
637module_mipi_dsi_driver(nt36672e_panel_driver);
638
639MODULE_AUTHOR("Ritesh Kumar <quic_riteshk@quicinc.com>");
640MODULE_DESCRIPTION("Novatek NT36672E DSI Panel Driver");
641MODULE_LICENSE("GPL");