Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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");