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