Linux Audio

Check our new training course

Loading...
v5.4
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright (C) 2019, Amarula Solutions.
  4 * Author: Jagan Teki <jagan@amarulasolutions.com>
  5 */
  6
  7#include <drm/drm_mipi_dsi.h>
  8#include <drm/drm_modes.h>
  9#include <drm/drm_panel.h>
 10#include <drm/drm_print.h>
 11
 12#include <linux/backlight.h>
 13#include <linux/gpio/consumer.h>
 14#include <linux/delay.h>
 15#include <linux/module.h>
 16#include <linux/of_device.h>
 17#include <linux/regulator/consumer.h>
 18
 19#include <video/mipi_display.h>
 20
 21/* Command2 BKx selection command */
 22#define DSI_CMD2BKX_SEL			0xFF
 23
 24/* Command2, BK0 commands */
 25#define DSI_CMD2_BK0_PVGAMCTRL		0xB0 /* Positive Voltage Gamma Control */
 26#define DSI_CMD2_BK0_NVGAMCTRL		0xB1 /* Negative Voltage Gamma Control */
 27#define DSI_CMD2_BK0_LNESET		0xC0 /* Display Line setting */
 28#define DSI_CMD2_BK0_PORCTRL		0xC1 /* Porch control */
 29#define DSI_CMD2_BK0_INVSEL		0xC2 /* Inversion selection, Frame Rate Control */
 30
 31/* Command2, BK1 commands */
 32#define DSI_CMD2_BK1_VRHS		0xB0 /* Vop amplitude setting */
 33#define DSI_CMD2_BK1_VCOM		0xB1 /* VCOM amplitude setting */
 34#define DSI_CMD2_BK1_VGHSS		0xB2 /* VGH Voltage setting */
 35#define DSI_CMD2_BK1_TESTCMD		0xB3 /* TEST Command Setting */
 36#define DSI_CMD2_BK1_VGLS		0xB5 /* VGL Voltage setting */
 37#define DSI_CMD2_BK1_PWCTLR1		0xB7 /* Power Control 1 */
 38#define DSI_CMD2_BK1_PWCTLR2		0xB8 /* Power Control 2 */
 39#define DSI_CMD2_BK1_SPD1		0xC1 /* Source pre_drive timing set1 */
 40#define DSI_CMD2_BK1_SPD2		0xC2 /* Source EQ2 Setting */
 41#define DSI_CMD2_BK1_MIPISET1		0xD0 /* MIPI Setting 1 */
 42
 43/**
 44 * Command2 with BK function selection.
 45 *
 46 * BIT[4, 0]: [CN2, BKXSEL]
 47 * 10 = CMD2BK0, Command2 BK0
 48 * 11 = CMD2BK1, Command2 BK1
 49 * 00 = Command2 disable
 50 */
 51#define DSI_CMD2BK1_SEL			0x11
 52#define DSI_CMD2BK0_SEL			0x10
 53#define DSI_CMD2BKX_SEL_NONE		0x00
 54
 55/* Command2, BK0 bytes */
 56#define DSI_LINESET_LINE		0x69
 57#define DSI_LINESET_LDE_EN		BIT(7)
 58#define DSI_LINESET_LINEDELTA		GENMASK(1, 0)
 59#define DSI_CMD2_BK0_LNESET_B1		DSI_LINESET_LINEDELTA
 60#define DSI_CMD2_BK0_LNESET_B0		(DSI_LINESET_LDE_EN | DSI_LINESET_LINE)
 61#define DSI_INVSEL_DEFAULT		GENMASK(5, 4)
 62#define DSI_INVSEL_NLINV		GENMASK(2, 0)
 63#define DSI_INVSEL_RTNI			GENMASK(2, 1)
 64#define DSI_CMD2_BK0_INVSEL_B1		DSI_INVSEL_RTNI
 65#define DSI_CMD2_BK0_INVSEL_B0		(DSI_INVSEL_DEFAULT | DSI_INVSEL_NLINV)
 66#define DSI_CMD2_BK0_PORCTRL_B0(m)	((m)->vtotal - (m)->vsync_end)
 67#define DSI_CMD2_BK0_PORCTRL_B1(m)	((m)->vsync_start - (m)->vdisplay)
 68
 69/* Command2, BK1 bytes */
 70#define DSI_CMD2_BK1_VRHA_SET		0x45
 71#define DSI_CMD2_BK1_VCOM_SET		0x13
 72#define DSI_CMD2_BK1_VGHSS_SET		GENMASK(2, 0)
 73#define DSI_CMD2_BK1_TESTCMD_VAL	BIT(7)
 74#define DSI_VGLS_DEFAULT		BIT(6)
 75#define DSI_VGLS_SEL			GENMASK(2, 0)
 76#define DSI_CMD2_BK1_VGLS_SET		(DSI_VGLS_DEFAULT | DSI_VGLS_SEL)
 77#define DSI_PWCTLR1_AP			BIT(7) /* Gamma OP bias, max */
 78#define DSI_PWCTLR1_APIS		BIT(2) /* Source OP input bias, min */
 79#define DSI_PWCTLR1_APOS		BIT(0) /* Source OP output bias, min */
 80#define DSI_CMD2_BK1_PWCTLR1_SET	(DSI_PWCTLR1_AP | DSI_PWCTLR1_APIS | \
 81					DSI_PWCTLR1_APOS)
 82#define DSI_PWCTLR2_AVDD		BIT(5) /* AVDD 6.6v */
 83#define DSI_PWCTLR2_AVCL		0x0    /* AVCL -4.4v */
 84#define DSI_CMD2_BK1_PWCTLR2_SET	(DSI_PWCTLR2_AVDD | DSI_PWCTLR2_AVCL)
 85#define DSI_SPD1_T2D			BIT(3)
 86#define DSI_CMD2_BK1_SPD1_SET		(GENMASK(6, 4) | DSI_SPD1_T2D)
 87#define DSI_CMD2_BK1_SPD2_SET		DSI_CMD2_BK1_SPD1_SET
 88#define DSI_MIPISET1_EOT_EN		BIT(3)
 89#define DSI_CMD2_BK1_MIPISET1_SET	(BIT(7) | DSI_MIPISET1_EOT_EN)
 90
 91struct st7701_panel_desc {
 92	const struct drm_display_mode *mode;
 93	unsigned int lanes;
 94	unsigned long flags;
 95	enum mipi_dsi_pixel_format format;
 96	const char *const *supply_names;
 97	unsigned int num_supplies;
 98	unsigned int panel_sleep_delay;
 99};
100
101struct st7701 {
102	struct drm_panel panel;
103	struct mipi_dsi_device *dsi;
104	const struct st7701_panel_desc *desc;
105
106	struct backlight_device *backlight;
107	struct regulator_bulk_data *supplies;
108	struct gpio_desc *reset;
109	unsigned int sleep_delay;
110};
111
112static inline struct st7701 *panel_to_st7701(struct drm_panel *panel)
113{
114	return container_of(panel, struct st7701, panel);
115}
116
117static inline int st7701_dsi_write(struct st7701 *st7701, const void *seq,
118				   size_t len)
119{
120	return mipi_dsi_dcs_write_buffer(st7701->dsi, seq, len);
121}
122
123#define ST7701_DSI(st7701, seq...)				\
124	{							\
125		const u8 d[] = { seq };				\
126		st7701_dsi_write(st7701, d, ARRAY_SIZE(d));	\
127	}
128
129static void st7701_init_sequence(struct st7701 *st7701)
130{
131	const struct drm_display_mode *mode = st7701->desc->mode;
132
133	ST7701_DSI(st7701, MIPI_DCS_SOFT_RESET, 0x00);
134
135	/* We need to wait 5ms before sending new commands */
136	msleep(5);
137
138	ST7701_DSI(st7701, MIPI_DCS_EXIT_SLEEP_MODE, 0x00);
139
140	msleep(st7701->sleep_delay);
141
142	/* Command2, BK0 */
143	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
144		   0x77, 0x01, 0x00, 0x00, DSI_CMD2BK0_SEL);
145	ST7701_DSI(st7701, DSI_CMD2_BK0_PVGAMCTRL, 0x00, 0x0E, 0x15, 0x0F,
146		   0x11, 0x08, 0x08, 0x08, 0x08, 0x23, 0x04, 0x13, 0x12,
147		   0x2B, 0x34, 0x1F);
148	ST7701_DSI(st7701, DSI_CMD2_BK0_NVGAMCTRL, 0x00, 0x0E, 0x95, 0x0F,
149		   0x13, 0x07, 0x09, 0x08, 0x08, 0x22, 0x04, 0x10, 0x0E,
150		   0x2C, 0x34, 0x1F);
151	ST7701_DSI(st7701, DSI_CMD2_BK0_LNESET,
152		   DSI_CMD2_BK0_LNESET_B0, DSI_CMD2_BK0_LNESET_B1);
153	ST7701_DSI(st7701, DSI_CMD2_BK0_PORCTRL,
154		   DSI_CMD2_BK0_PORCTRL_B0(mode),
155		   DSI_CMD2_BK0_PORCTRL_B1(mode));
156	ST7701_DSI(st7701, DSI_CMD2_BK0_INVSEL,
157		   DSI_CMD2_BK0_INVSEL_B0, DSI_CMD2_BK0_INVSEL_B1);
158
159	/* Command2, BK1 */
160	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
161			0x77, 0x01, 0x00, 0x00, DSI_CMD2BK1_SEL);
162	ST7701_DSI(st7701, DSI_CMD2_BK1_VRHS, DSI_CMD2_BK1_VRHA_SET);
163	ST7701_DSI(st7701, DSI_CMD2_BK1_VCOM, DSI_CMD2_BK1_VCOM_SET);
164	ST7701_DSI(st7701, DSI_CMD2_BK1_VGHSS, DSI_CMD2_BK1_VGHSS_SET);
165	ST7701_DSI(st7701, DSI_CMD2_BK1_TESTCMD, DSI_CMD2_BK1_TESTCMD_VAL);
166	ST7701_DSI(st7701, DSI_CMD2_BK1_VGLS, DSI_CMD2_BK1_VGLS_SET);
167	ST7701_DSI(st7701, DSI_CMD2_BK1_PWCTLR1, DSI_CMD2_BK1_PWCTLR1_SET);
168	ST7701_DSI(st7701, DSI_CMD2_BK1_PWCTLR2, DSI_CMD2_BK1_PWCTLR2_SET);
169	ST7701_DSI(st7701, DSI_CMD2_BK1_SPD1, DSI_CMD2_BK1_SPD1_SET);
170	ST7701_DSI(st7701, DSI_CMD2_BK1_SPD2, DSI_CMD2_BK1_SPD2_SET);
171	ST7701_DSI(st7701, DSI_CMD2_BK1_MIPISET1, DSI_CMD2_BK1_MIPISET1_SET);
172
173	/**
174	 * ST7701_SPEC_V1.2 is unable to provide enough information above this
175	 * specific command sequence, so grab the same from vendor BSP driver.
176	 */
177	ST7701_DSI(st7701, 0xE0, 0x00, 0x00, 0x02);
178	ST7701_DSI(st7701, 0xE1, 0x0B, 0x00, 0x0D, 0x00, 0x0C, 0x00, 0x0E,
179		   0x00, 0x00, 0x44, 0x44);
180	ST7701_DSI(st7701, 0xE2, 0x33, 0x33, 0x44, 0x44, 0x64, 0x00, 0x66,
181		   0x00, 0x65, 0x00, 0x67, 0x00, 0x00);
182	ST7701_DSI(st7701, 0xE3, 0x00, 0x00, 0x33, 0x33);
183	ST7701_DSI(st7701, 0xE4, 0x44, 0x44);
184	ST7701_DSI(st7701, 0xE5, 0x0C, 0x78, 0x3C, 0xA0, 0x0E, 0x78, 0x3C,
185		   0xA0, 0x10, 0x78, 0x3C, 0xA0, 0x12, 0x78, 0x3C, 0xA0);
186	ST7701_DSI(st7701, 0xE6, 0x00, 0x00, 0x33, 0x33);
187	ST7701_DSI(st7701, 0xE7, 0x44, 0x44);
188	ST7701_DSI(st7701, 0xE8, 0x0D, 0x78, 0x3C, 0xA0, 0x0F, 0x78, 0x3C,
189		   0xA0, 0x11, 0x78, 0x3C, 0xA0, 0x13, 0x78, 0x3C, 0xA0);
190	ST7701_DSI(st7701, 0xEB, 0x02, 0x02, 0x39, 0x39, 0xEE, 0x44, 0x00);
191	ST7701_DSI(st7701, 0xEC, 0x00, 0x00);
192	ST7701_DSI(st7701, 0xED, 0xFF, 0xF1, 0x04, 0x56, 0x72, 0x3F, 0xFF,
193		   0xFF, 0xFF, 0xFF, 0xF3, 0x27, 0x65, 0x40, 0x1F, 0xFF);
194
195	/* disable Command2 */
196	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
197		   0x77, 0x01, 0x00, 0x00, DSI_CMD2BKX_SEL_NONE);
198}
199
200static int st7701_prepare(struct drm_panel *panel)
201{
202	struct st7701 *st7701 = panel_to_st7701(panel);
203	int ret;
204
205	gpiod_set_value(st7701->reset, 0);
206
207	ret = regulator_bulk_enable(st7701->desc->num_supplies,
208				    st7701->supplies);
209	if (ret < 0)
210		return ret;
211	msleep(20);
212
213	gpiod_set_value(st7701->reset, 1);
214	msleep(150);
215
216	st7701_init_sequence(st7701);
217
218	return 0;
219}
220
221static int st7701_enable(struct drm_panel *panel)
222{
223	struct st7701 *st7701 = panel_to_st7701(panel);
224
225	ST7701_DSI(st7701, MIPI_DCS_SET_DISPLAY_ON, 0x00);
226	backlight_enable(st7701->backlight);
227
228	return 0;
229}
230
231static int st7701_disable(struct drm_panel *panel)
232{
233	struct st7701 *st7701 = panel_to_st7701(panel);
234
235	backlight_disable(st7701->backlight);
236	ST7701_DSI(st7701, MIPI_DCS_SET_DISPLAY_OFF, 0x00);
237
238	return 0;
239}
240
241static int st7701_unprepare(struct drm_panel *panel)
242{
243	struct st7701 *st7701 = panel_to_st7701(panel);
244
245	ST7701_DSI(st7701, MIPI_DCS_ENTER_SLEEP_MODE, 0x00);
246
247	msleep(st7701->sleep_delay);
248
249	gpiod_set_value(st7701->reset, 0);
250
251	/**
252	 * During the Resetting period, the display will be blanked
253	 * (The display is entering blanking sequence, which maximum
254	 * time is 120 ms, when Reset Starts in Sleep Out –mode. The
255	 * display remains the blank state in Sleep In –mode.) and
256	 * then return to Default condition for Hardware Reset.
257	 *
258	 * So we need wait sleep_delay time to make sure reset completed.
259	 */
260	msleep(st7701->sleep_delay);
261
262	regulator_bulk_disable(st7701->desc->num_supplies, st7701->supplies);
263
264	return 0;
265}
266
267static int st7701_get_modes(struct drm_panel *panel)
 
268{
269	struct st7701 *st7701 = panel_to_st7701(panel);
270	const struct drm_display_mode *desc_mode = st7701->desc->mode;
271	struct drm_display_mode *mode;
272
273	mode = drm_mode_duplicate(panel->drm, desc_mode);
274	if (!mode) {
275		DRM_DEV_ERROR(&st7701->dsi->dev,
276			      "failed to add mode %ux%ux@%u\n",
277			      desc_mode->hdisplay, desc_mode->vdisplay,
278			      desc_mode->vrefresh);
279		return -ENOMEM;
280	}
281
282	drm_mode_set_name(mode);
283	drm_mode_probed_add(panel->connector, mode);
284
285	panel->connector->display_info.width_mm = desc_mode->width_mm;
286	panel->connector->display_info.height_mm = desc_mode->height_mm;
287
288	return 1;
289}
290
291static const struct drm_panel_funcs st7701_funcs = {
292	.disable	= st7701_disable,
293	.unprepare	= st7701_unprepare,
294	.prepare	= st7701_prepare,
295	.enable		= st7701_enable,
296	.get_modes	= st7701_get_modes,
297};
298
299static const struct drm_display_mode ts8550b_mode = {
300	.clock		= 27500,
301
302	.hdisplay	= 480,
303	.hsync_start	= 480 + 38,
304	.hsync_end	= 480 + 38 + 12,
305	.htotal		= 480 + 38 + 12 + 12,
306
307	.vdisplay	= 854,
308	.vsync_start	= 854 + 18,
309	.vsync_end	= 854 + 18 + 8,
310	.vtotal		= 854 + 18 + 8 + 4,
311
312	.width_mm	= 69,
313	.height_mm	= 139,
314
315	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
316};
317
318static const char * const ts8550b_supply_names[] = {
319	"VCC",
320	"IOVCC",
321};
322
323static const struct st7701_panel_desc ts8550b_desc = {
324	.mode = &ts8550b_mode,
325	.lanes = 2,
326	.flags = MIPI_DSI_MODE_VIDEO,
327	.format = MIPI_DSI_FMT_RGB888,
328	.supply_names = ts8550b_supply_names,
329	.num_supplies = ARRAY_SIZE(ts8550b_supply_names),
330	.panel_sleep_delay = 80, /* panel need extra 80ms for sleep out cmd */
331};
332
333static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
334{
335	const struct st7701_panel_desc *desc;
336	struct st7701 *st7701;
337	int ret, i;
338
339	st7701 = devm_kzalloc(&dsi->dev, sizeof(*st7701), GFP_KERNEL);
340	if (!st7701)
341		return -ENOMEM;
342
343	desc = of_device_get_match_data(&dsi->dev);
344	dsi->mode_flags = desc->flags;
345	dsi->format = desc->format;
346	dsi->lanes = desc->lanes;
347
348	st7701->supplies = devm_kcalloc(&dsi->dev, desc->num_supplies,
349					sizeof(*st7701->supplies),
350					GFP_KERNEL);
351	if (!st7701->supplies)
352		return -ENOMEM;
353
354	for (i = 0; i < desc->num_supplies; i++)
355		st7701->supplies[i].supply = desc->supply_names[i];
356
357	ret = devm_regulator_bulk_get(&dsi->dev, desc->num_supplies,
358				      st7701->supplies);
359	if (ret < 0)
360		return ret;
361
362	st7701->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
363	if (IS_ERR(st7701->reset)) {
364		DRM_DEV_ERROR(&dsi->dev, "Couldn't get our reset GPIO\n");
365		return PTR_ERR(st7701->reset);
366	}
367
368	st7701->backlight = devm_of_find_backlight(&dsi->dev);
369	if (IS_ERR(st7701->backlight))
370		return PTR_ERR(st7701->backlight);
371
372	drm_panel_init(&st7701->panel);
373
374	/**
375	 * Once sleep out has been issued, ST7701 IC required to wait 120ms
376	 * before initiating new commands.
377	 *
378	 * On top of that some panels might need an extra delay to wait, so
379	 * add panel specific delay for those cases. As now this panel specific
380	 * delay information is referenced from those panel BSP driver, example
381	 * ts8550b and there is no valid documentation for that.
382	 */
383	st7701->sleep_delay = 120 + desc->panel_sleep_delay;
384	st7701->panel.funcs = &st7701_funcs;
385	st7701->panel.dev = &dsi->dev;
386
387	ret = drm_panel_add(&st7701->panel);
388	if (ret < 0)
389		return ret;
 
 
390
391	mipi_dsi_set_drvdata(dsi, st7701);
392	st7701->dsi = dsi;
393	st7701->desc = desc;
394
395	return mipi_dsi_attach(dsi);
396}
397
398static int st7701_dsi_remove(struct mipi_dsi_device *dsi)
399{
400	struct st7701 *st7701 = mipi_dsi_get_drvdata(dsi);
401
402	mipi_dsi_detach(dsi);
403	drm_panel_remove(&st7701->panel);
404
405	return 0;
406}
407
408static const struct of_device_id st7701_of_match[] = {
409	{ .compatible = "techstar,ts8550b", .data = &ts8550b_desc },
410	{ }
411};
412MODULE_DEVICE_TABLE(of, st7701_of_match);
413
414static struct mipi_dsi_driver st7701_dsi_driver = {
415	.probe		= st7701_dsi_probe,
416	.remove		= st7701_dsi_remove,
417	.driver = {
418		.name		= "st7701",
419		.of_match_table	= st7701_of_match,
420	},
421};
422module_mipi_dsi_driver(st7701_dsi_driver);
423
424MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
425MODULE_DESCRIPTION("Sitronix ST7701 LCD Panel Driver");
426MODULE_LICENSE("GPL");
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright (C) 2019, Amarula Solutions.
  4 * Author: Jagan Teki <jagan@amarulasolutions.com>
  5 */
  6
  7#include <drm/drm_mipi_dsi.h>
  8#include <drm/drm_modes.h>
  9#include <drm/drm_panel.h>
 
 10
 
 11#include <linux/gpio/consumer.h>
 12#include <linux/delay.h>
 13#include <linux/module.h>
 14#include <linux/of_device.h>
 15#include <linux/regulator/consumer.h>
 16
 17#include <video/mipi_display.h>
 18
 19/* Command2 BKx selection command */
 20#define DSI_CMD2BKX_SEL			0xFF
 21
 22/* Command2, BK0 commands */
 23#define DSI_CMD2_BK0_PVGAMCTRL		0xB0 /* Positive Voltage Gamma Control */
 24#define DSI_CMD2_BK0_NVGAMCTRL		0xB1 /* Negative Voltage Gamma Control */
 25#define DSI_CMD2_BK0_LNESET		0xC0 /* Display Line setting */
 26#define DSI_CMD2_BK0_PORCTRL		0xC1 /* Porch control */
 27#define DSI_CMD2_BK0_INVSEL		0xC2 /* Inversion selection, Frame Rate Control */
 28
 29/* Command2, BK1 commands */
 30#define DSI_CMD2_BK1_VRHS		0xB0 /* Vop amplitude setting */
 31#define DSI_CMD2_BK1_VCOM		0xB1 /* VCOM amplitude setting */
 32#define DSI_CMD2_BK1_VGHSS		0xB2 /* VGH Voltage setting */
 33#define DSI_CMD2_BK1_TESTCMD		0xB3 /* TEST Command Setting */
 34#define DSI_CMD2_BK1_VGLS		0xB5 /* VGL Voltage setting */
 35#define DSI_CMD2_BK1_PWCTLR1		0xB7 /* Power Control 1 */
 36#define DSI_CMD2_BK1_PWCTLR2		0xB8 /* Power Control 2 */
 37#define DSI_CMD2_BK1_SPD1		0xC1 /* Source pre_drive timing set1 */
 38#define DSI_CMD2_BK1_SPD2		0xC2 /* Source EQ2 Setting */
 39#define DSI_CMD2_BK1_MIPISET1		0xD0 /* MIPI Setting 1 */
 40
 41/*
 42 * Command2 with BK function selection.
 43 *
 44 * BIT[4, 0]: [CN2, BKXSEL]
 45 * 10 = CMD2BK0, Command2 BK0
 46 * 11 = CMD2BK1, Command2 BK1
 47 * 00 = Command2 disable
 48 */
 49#define DSI_CMD2BK1_SEL			0x11
 50#define DSI_CMD2BK0_SEL			0x10
 51#define DSI_CMD2BKX_SEL_NONE		0x00
 52
 53/* Command2, BK0 bytes */
 54#define DSI_LINESET_LINE		0x69
 55#define DSI_LINESET_LDE_EN		BIT(7)
 56#define DSI_LINESET_LINEDELTA		GENMASK(1, 0)
 57#define DSI_CMD2_BK0_LNESET_B1		DSI_LINESET_LINEDELTA
 58#define DSI_CMD2_BK0_LNESET_B0		(DSI_LINESET_LDE_EN | DSI_LINESET_LINE)
 59#define DSI_INVSEL_DEFAULT		GENMASK(5, 4)
 60#define DSI_INVSEL_NLINV		GENMASK(2, 0)
 61#define DSI_INVSEL_RTNI			GENMASK(2, 1)
 62#define DSI_CMD2_BK0_INVSEL_B1		DSI_INVSEL_RTNI
 63#define DSI_CMD2_BK0_INVSEL_B0		(DSI_INVSEL_DEFAULT | DSI_INVSEL_NLINV)
 64#define DSI_CMD2_BK0_PORCTRL_B0(m)	((m)->vtotal - (m)->vsync_end)
 65#define DSI_CMD2_BK0_PORCTRL_B1(m)	((m)->vsync_start - (m)->vdisplay)
 66
 67/* Command2, BK1 bytes */
 68#define DSI_CMD2_BK1_VRHA_SET		0x45
 69#define DSI_CMD2_BK1_VCOM_SET		0x13
 70#define DSI_CMD2_BK1_VGHSS_SET		GENMASK(2, 0)
 71#define DSI_CMD2_BK1_TESTCMD_VAL	BIT(7)
 72#define DSI_VGLS_DEFAULT		BIT(6)
 73#define DSI_VGLS_SEL			GENMASK(2, 0)
 74#define DSI_CMD2_BK1_VGLS_SET		(DSI_VGLS_DEFAULT | DSI_VGLS_SEL)
 75#define DSI_PWCTLR1_AP			BIT(7) /* Gamma OP bias, max */
 76#define DSI_PWCTLR1_APIS		BIT(2) /* Source OP input bias, min */
 77#define DSI_PWCTLR1_APOS		BIT(0) /* Source OP output bias, min */
 78#define DSI_CMD2_BK1_PWCTLR1_SET	(DSI_PWCTLR1_AP | DSI_PWCTLR1_APIS | \
 79					DSI_PWCTLR1_APOS)
 80#define DSI_PWCTLR2_AVDD		BIT(5) /* AVDD 6.6v */
 81#define DSI_PWCTLR2_AVCL		0x0    /* AVCL -4.4v */
 82#define DSI_CMD2_BK1_PWCTLR2_SET	(DSI_PWCTLR2_AVDD | DSI_PWCTLR2_AVCL)
 83#define DSI_SPD1_T2D			BIT(3)
 84#define DSI_CMD2_BK1_SPD1_SET		(GENMASK(6, 4) | DSI_SPD1_T2D)
 85#define DSI_CMD2_BK1_SPD2_SET		DSI_CMD2_BK1_SPD1_SET
 86#define DSI_MIPISET1_EOT_EN		BIT(3)
 87#define DSI_CMD2_BK1_MIPISET1_SET	(BIT(7) | DSI_MIPISET1_EOT_EN)
 88
 89struct st7701_panel_desc {
 90	const struct drm_display_mode *mode;
 91	unsigned int lanes;
 92	unsigned long flags;
 93	enum mipi_dsi_pixel_format format;
 94	const char *const *supply_names;
 95	unsigned int num_supplies;
 96	unsigned int panel_sleep_delay;
 97};
 98
 99struct st7701 {
100	struct drm_panel panel;
101	struct mipi_dsi_device *dsi;
102	const struct st7701_panel_desc *desc;
103
 
104	struct regulator_bulk_data *supplies;
105	struct gpio_desc *reset;
106	unsigned int sleep_delay;
107};
108
109static inline struct st7701 *panel_to_st7701(struct drm_panel *panel)
110{
111	return container_of(panel, struct st7701, panel);
112}
113
114static inline int st7701_dsi_write(struct st7701 *st7701, const void *seq,
115				   size_t len)
116{
117	return mipi_dsi_dcs_write_buffer(st7701->dsi, seq, len);
118}
119
120#define ST7701_DSI(st7701, seq...)				\
121	{							\
122		const u8 d[] = { seq };				\
123		st7701_dsi_write(st7701, d, ARRAY_SIZE(d));	\
124	}
125
126static void st7701_init_sequence(struct st7701 *st7701)
127{
128	const struct drm_display_mode *mode = st7701->desc->mode;
129
130	ST7701_DSI(st7701, MIPI_DCS_SOFT_RESET, 0x00);
131
132	/* We need to wait 5ms before sending new commands */
133	msleep(5);
134
135	ST7701_DSI(st7701, MIPI_DCS_EXIT_SLEEP_MODE, 0x00);
136
137	msleep(st7701->sleep_delay);
138
139	/* Command2, BK0 */
140	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
141		   0x77, 0x01, 0x00, 0x00, DSI_CMD2BK0_SEL);
142	ST7701_DSI(st7701, DSI_CMD2_BK0_PVGAMCTRL, 0x00, 0x0E, 0x15, 0x0F,
143		   0x11, 0x08, 0x08, 0x08, 0x08, 0x23, 0x04, 0x13, 0x12,
144		   0x2B, 0x34, 0x1F);
145	ST7701_DSI(st7701, DSI_CMD2_BK0_NVGAMCTRL, 0x00, 0x0E, 0x95, 0x0F,
146		   0x13, 0x07, 0x09, 0x08, 0x08, 0x22, 0x04, 0x10, 0x0E,
147		   0x2C, 0x34, 0x1F);
148	ST7701_DSI(st7701, DSI_CMD2_BK0_LNESET,
149		   DSI_CMD2_BK0_LNESET_B0, DSI_CMD2_BK0_LNESET_B1);
150	ST7701_DSI(st7701, DSI_CMD2_BK0_PORCTRL,
151		   DSI_CMD2_BK0_PORCTRL_B0(mode),
152		   DSI_CMD2_BK0_PORCTRL_B1(mode));
153	ST7701_DSI(st7701, DSI_CMD2_BK0_INVSEL,
154		   DSI_CMD2_BK0_INVSEL_B0, DSI_CMD2_BK0_INVSEL_B1);
155
156	/* Command2, BK1 */
157	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
158			0x77, 0x01, 0x00, 0x00, DSI_CMD2BK1_SEL);
159	ST7701_DSI(st7701, DSI_CMD2_BK1_VRHS, DSI_CMD2_BK1_VRHA_SET);
160	ST7701_DSI(st7701, DSI_CMD2_BK1_VCOM, DSI_CMD2_BK1_VCOM_SET);
161	ST7701_DSI(st7701, DSI_CMD2_BK1_VGHSS, DSI_CMD2_BK1_VGHSS_SET);
162	ST7701_DSI(st7701, DSI_CMD2_BK1_TESTCMD, DSI_CMD2_BK1_TESTCMD_VAL);
163	ST7701_DSI(st7701, DSI_CMD2_BK1_VGLS, DSI_CMD2_BK1_VGLS_SET);
164	ST7701_DSI(st7701, DSI_CMD2_BK1_PWCTLR1, DSI_CMD2_BK1_PWCTLR1_SET);
165	ST7701_DSI(st7701, DSI_CMD2_BK1_PWCTLR2, DSI_CMD2_BK1_PWCTLR2_SET);
166	ST7701_DSI(st7701, DSI_CMD2_BK1_SPD1, DSI_CMD2_BK1_SPD1_SET);
167	ST7701_DSI(st7701, DSI_CMD2_BK1_SPD2, DSI_CMD2_BK1_SPD2_SET);
168	ST7701_DSI(st7701, DSI_CMD2_BK1_MIPISET1, DSI_CMD2_BK1_MIPISET1_SET);
169
170	/**
171	 * ST7701_SPEC_V1.2 is unable to provide enough information above this
172	 * specific command sequence, so grab the same from vendor BSP driver.
173	 */
174	ST7701_DSI(st7701, 0xE0, 0x00, 0x00, 0x02);
175	ST7701_DSI(st7701, 0xE1, 0x0B, 0x00, 0x0D, 0x00, 0x0C, 0x00, 0x0E,
176		   0x00, 0x00, 0x44, 0x44);
177	ST7701_DSI(st7701, 0xE2, 0x33, 0x33, 0x44, 0x44, 0x64, 0x00, 0x66,
178		   0x00, 0x65, 0x00, 0x67, 0x00, 0x00);
179	ST7701_DSI(st7701, 0xE3, 0x00, 0x00, 0x33, 0x33);
180	ST7701_DSI(st7701, 0xE4, 0x44, 0x44);
181	ST7701_DSI(st7701, 0xE5, 0x0C, 0x78, 0x3C, 0xA0, 0x0E, 0x78, 0x3C,
182		   0xA0, 0x10, 0x78, 0x3C, 0xA0, 0x12, 0x78, 0x3C, 0xA0);
183	ST7701_DSI(st7701, 0xE6, 0x00, 0x00, 0x33, 0x33);
184	ST7701_DSI(st7701, 0xE7, 0x44, 0x44);
185	ST7701_DSI(st7701, 0xE8, 0x0D, 0x78, 0x3C, 0xA0, 0x0F, 0x78, 0x3C,
186		   0xA0, 0x11, 0x78, 0x3C, 0xA0, 0x13, 0x78, 0x3C, 0xA0);
187	ST7701_DSI(st7701, 0xEB, 0x02, 0x02, 0x39, 0x39, 0xEE, 0x44, 0x00);
188	ST7701_DSI(st7701, 0xEC, 0x00, 0x00);
189	ST7701_DSI(st7701, 0xED, 0xFF, 0xF1, 0x04, 0x56, 0x72, 0x3F, 0xFF,
190		   0xFF, 0xFF, 0xFF, 0xF3, 0x27, 0x65, 0x40, 0x1F, 0xFF);
191
192	/* disable Command2 */
193	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
194		   0x77, 0x01, 0x00, 0x00, DSI_CMD2BKX_SEL_NONE);
195}
196
197static int st7701_prepare(struct drm_panel *panel)
198{
199	struct st7701 *st7701 = panel_to_st7701(panel);
200	int ret;
201
202	gpiod_set_value(st7701->reset, 0);
203
204	ret = regulator_bulk_enable(st7701->desc->num_supplies,
205				    st7701->supplies);
206	if (ret < 0)
207		return ret;
208	msleep(20);
209
210	gpiod_set_value(st7701->reset, 1);
211	msleep(150);
212
213	st7701_init_sequence(st7701);
214
215	return 0;
216}
217
218static int st7701_enable(struct drm_panel *panel)
219{
220	struct st7701 *st7701 = panel_to_st7701(panel);
221
222	ST7701_DSI(st7701, MIPI_DCS_SET_DISPLAY_ON, 0x00);
 
223
224	return 0;
225}
226
227static int st7701_disable(struct drm_panel *panel)
228{
229	struct st7701 *st7701 = panel_to_st7701(panel);
230
 
231	ST7701_DSI(st7701, MIPI_DCS_SET_DISPLAY_OFF, 0x00);
232
233	return 0;
234}
235
236static int st7701_unprepare(struct drm_panel *panel)
237{
238	struct st7701 *st7701 = panel_to_st7701(panel);
239
240	ST7701_DSI(st7701, MIPI_DCS_ENTER_SLEEP_MODE, 0x00);
241
242	msleep(st7701->sleep_delay);
243
244	gpiod_set_value(st7701->reset, 0);
245
246	/**
247	 * During the Resetting period, the display will be blanked
248	 * (The display is entering blanking sequence, which maximum
249	 * time is 120 ms, when Reset Starts in Sleep Out –mode. The
250	 * display remains the blank state in Sleep In –mode.) and
251	 * then return to Default condition for Hardware Reset.
252	 *
253	 * So we need wait sleep_delay time to make sure reset completed.
254	 */
255	msleep(st7701->sleep_delay);
256
257	regulator_bulk_disable(st7701->desc->num_supplies, st7701->supplies);
258
259	return 0;
260}
261
262static int st7701_get_modes(struct drm_panel *panel,
263			    struct drm_connector *connector)
264{
265	struct st7701 *st7701 = panel_to_st7701(panel);
266	const struct drm_display_mode *desc_mode = st7701->desc->mode;
267	struct drm_display_mode *mode;
268
269	mode = drm_mode_duplicate(connector->dev, desc_mode);
270	if (!mode) {
271		dev_err(&st7701->dsi->dev, "failed to add mode %ux%u@%u\n",
272			desc_mode->hdisplay, desc_mode->vdisplay,
273			drm_mode_vrefresh(desc_mode));
 
274		return -ENOMEM;
275	}
276
277	drm_mode_set_name(mode);
278	drm_mode_probed_add(connector, mode);
279
280	connector->display_info.width_mm = desc_mode->width_mm;
281	connector->display_info.height_mm = desc_mode->height_mm;
282
283	return 1;
284}
285
286static const struct drm_panel_funcs st7701_funcs = {
287	.disable	= st7701_disable,
288	.unprepare	= st7701_unprepare,
289	.prepare	= st7701_prepare,
290	.enable		= st7701_enable,
291	.get_modes	= st7701_get_modes,
292};
293
294static const struct drm_display_mode ts8550b_mode = {
295	.clock		= 27500,
296
297	.hdisplay	= 480,
298	.hsync_start	= 480 + 38,
299	.hsync_end	= 480 + 38 + 12,
300	.htotal		= 480 + 38 + 12 + 12,
301
302	.vdisplay	= 854,
303	.vsync_start	= 854 + 18,
304	.vsync_end	= 854 + 18 + 8,
305	.vtotal		= 854 + 18 + 8 + 4,
306
307	.width_mm	= 69,
308	.height_mm	= 139,
309
310	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
311};
312
313static const char * const ts8550b_supply_names[] = {
314	"VCC",
315	"IOVCC",
316};
317
318static const struct st7701_panel_desc ts8550b_desc = {
319	.mode = &ts8550b_mode,
320	.lanes = 2,
321	.flags = MIPI_DSI_MODE_VIDEO,
322	.format = MIPI_DSI_FMT_RGB888,
323	.supply_names = ts8550b_supply_names,
324	.num_supplies = ARRAY_SIZE(ts8550b_supply_names),
325	.panel_sleep_delay = 80, /* panel need extra 80ms for sleep out cmd */
326};
327
328static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
329{
330	const struct st7701_panel_desc *desc;
331	struct st7701 *st7701;
332	int ret, i;
333
334	st7701 = devm_kzalloc(&dsi->dev, sizeof(*st7701), GFP_KERNEL);
335	if (!st7701)
336		return -ENOMEM;
337
338	desc = of_device_get_match_data(&dsi->dev);
339	dsi->mode_flags = desc->flags;
340	dsi->format = desc->format;
341	dsi->lanes = desc->lanes;
342
343	st7701->supplies = devm_kcalloc(&dsi->dev, desc->num_supplies,
344					sizeof(*st7701->supplies),
345					GFP_KERNEL);
346	if (!st7701->supplies)
347		return -ENOMEM;
348
349	for (i = 0; i < desc->num_supplies; i++)
350		st7701->supplies[i].supply = desc->supply_names[i];
351
352	ret = devm_regulator_bulk_get(&dsi->dev, desc->num_supplies,
353				      st7701->supplies);
354	if (ret < 0)
355		return ret;
356
357	st7701->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
358	if (IS_ERR(st7701->reset)) {
359		dev_err(&dsi->dev, "Couldn't get our reset GPIO\n");
360		return PTR_ERR(st7701->reset);
361	}
362
363	drm_panel_init(&st7701->panel, &dsi->dev, &st7701_funcs,
364		       DRM_MODE_CONNECTOR_DSI);
 
 
 
365
366	/**
367	 * Once sleep out has been issued, ST7701 IC required to wait 120ms
368	 * before initiating new commands.
369	 *
370	 * On top of that some panels might need an extra delay to wait, so
371	 * add panel specific delay for those cases. As now this panel specific
372	 * delay information is referenced from those panel BSP driver, example
373	 * ts8550b and there is no valid documentation for that.
374	 */
375	st7701->sleep_delay = 120 + desc->panel_sleep_delay;
 
 
376
377	ret = drm_panel_of_backlight(&st7701->panel);
378	if (ret)
379		return ret;
380
381	drm_panel_add(&st7701->panel);
382
383	mipi_dsi_set_drvdata(dsi, st7701);
384	st7701->dsi = dsi;
385	st7701->desc = desc;
386
387	return mipi_dsi_attach(dsi);
388}
389
390static int st7701_dsi_remove(struct mipi_dsi_device *dsi)
391{
392	struct st7701 *st7701 = mipi_dsi_get_drvdata(dsi);
393
394	mipi_dsi_detach(dsi);
395	drm_panel_remove(&st7701->panel);
396
397	return 0;
398}
399
400static const struct of_device_id st7701_of_match[] = {
401	{ .compatible = "techstar,ts8550b", .data = &ts8550b_desc },
402	{ }
403};
404MODULE_DEVICE_TABLE(of, st7701_of_match);
405
406static struct mipi_dsi_driver st7701_dsi_driver = {
407	.probe		= st7701_dsi_probe,
408	.remove		= st7701_dsi_remove,
409	.driver = {
410		.name		= "st7701",
411		.of_match_table	= st7701_of_match,
412	},
413};
414module_mipi_dsi_driver(st7701_dsi_driver);
415
416MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
417MODULE_DESCRIPTION("Sitronix ST7701 LCD Panel Driver");
418MODULE_LICENSE("GPL");