brintos

brintos / linux-shallow public Read only

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