xref: /openbmc/linux/drivers/gpu/drm/panel/panel-boe-himax8279d.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
14b6dd3caSJerry Han // SPDX-License-Identifier: GPL-2.0
24b6dd3caSJerry Han /*
34b6dd3caSJerry Han  * Copyright (c) 2019, Huaqin Telecom Technology Co., Ltd
44b6dd3caSJerry Han  *
54b6dd3caSJerry Han  * Author: Jerry Han <jerry.han.hq@gmail.com>
64b6dd3caSJerry Han  *
74b6dd3caSJerry Han  */
84b6dd3caSJerry Han 
94b6dd3caSJerry Han #include <linux/delay.h>
104b6dd3caSJerry Han #include <linux/kernel.h>
114b6dd3caSJerry Han #include <linux/module.h>
124b6dd3caSJerry Han #include <linux/of.h>
134b6dd3caSJerry Han 
144b6dd3caSJerry Han #include <linux/gpio/consumer.h>
154b6dd3caSJerry Han #include <linux/regulator/consumer.h>
164b6dd3caSJerry Han 
174b6dd3caSJerry Han #include <drm/drm_device.h>
184b6dd3caSJerry Han #include <drm/drm_mipi_dsi.h>
194b6dd3caSJerry Han #include <drm/drm_modes.h>
204b6dd3caSJerry Han #include <drm/drm_panel.h>
214b6dd3caSJerry Han 
224b6dd3caSJerry Han #include <video/mipi_display.h>
234b6dd3caSJerry Han 
244b6dd3caSJerry Han struct panel_cmd {
254b6dd3caSJerry Han 	char cmd;
264b6dd3caSJerry Han 	char data;
274b6dd3caSJerry Han };
284b6dd3caSJerry Han 
294b6dd3caSJerry Han struct panel_desc {
304b6dd3caSJerry Han 	const struct drm_display_mode *display_mode;
314b6dd3caSJerry Han 	unsigned int bpc;
324b6dd3caSJerry Han 	unsigned int width_mm;
334b6dd3caSJerry Han 	unsigned int height_mm;
344b6dd3caSJerry Han 
354b6dd3caSJerry Han 	unsigned long mode_flags;
364b6dd3caSJerry Han 	enum mipi_dsi_pixel_format format;
374b6dd3caSJerry Han 	unsigned int lanes;
384b6dd3caSJerry Han 	const struct panel_cmd *on_cmds;
394b6dd3caSJerry Han 	unsigned int on_cmds_num;
404b6dd3caSJerry Han };
414b6dd3caSJerry Han 
424b6dd3caSJerry Han struct panel_info {
434b6dd3caSJerry Han 	struct drm_panel base;
444b6dd3caSJerry Han 	struct mipi_dsi_device *link;
454b6dd3caSJerry Han 	const struct panel_desc *desc;
464b6dd3caSJerry Han 
474b6dd3caSJerry Han 	struct gpio_desc *enable_gpio;
484b6dd3caSJerry Han 	struct gpio_desc *pp33_gpio;
494b6dd3caSJerry Han 	struct gpio_desc *pp18_gpio;
504b6dd3caSJerry Han 
514b6dd3caSJerry Han 	bool prepared;
524b6dd3caSJerry Han 	bool enabled;
534b6dd3caSJerry Han };
544b6dd3caSJerry Han 
to_panel_info(struct drm_panel * panel)554b6dd3caSJerry Han static inline struct panel_info *to_panel_info(struct drm_panel *panel)
564b6dd3caSJerry Han {
574b6dd3caSJerry Han 	return container_of(panel, struct panel_info, base);
584b6dd3caSJerry Han }
594b6dd3caSJerry Han 
disable_gpios(struct panel_info * pinfo)604b6dd3caSJerry Han static void disable_gpios(struct panel_info *pinfo)
614b6dd3caSJerry Han {
624b6dd3caSJerry Han 	gpiod_set_value(pinfo->enable_gpio, 0);
634b6dd3caSJerry Han 	gpiod_set_value(pinfo->pp33_gpio, 0);
644b6dd3caSJerry Han 	gpiod_set_value(pinfo->pp18_gpio, 0);
654b6dd3caSJerry Han }
664b6dd3caSJerry Han 
send_mipi_cmds(struct drm_panel * panel,const struct panel_cmd * cmds)674b6dd3caSJerry Han static int send_mipi_cmds(struct drm_panel *panel, const struct panel_cmd *cmds)
684b6dd3caSJerry Han {
694b6dd3caSJerry Han 	struct panel_info *pinfo = to_panel_info(panel);
704b6dd3caSJerry Han 	unsigned int i = 0;
714b6dd3caSJerry Han 	int err;
724b6dd3caSJerry Han 
734b6dd3caSJerry Han 	for (i = 0; i < pinfo->desc->on_cmds_num; i++) {
744b6dd3caSJerry Han 		err = mipi_dsi_dcs_write_buffer(pinfo->link, &cmds[i],
754b6dd3caSJerry Han 						sizeof(struct panel_cmd));
764b6dd3caSJerry Han 
774b6dd3caSJerry Han 		if (err < 0)
784b6dd3caSJerry Han 			return err;
794b6dd3caSJerry Han 	}
804b6dd3caSJerry Han 
814b6dd3caSJerry Han 	return 0;
824b6dd3caSJerry Han }
834b6dd3caSJerry Han 
boe_panel_disable(struct drm_panel * panel)844b6dd3caSJerry Han static int boe_panel_disable(struct drm_panel *panel)
854b6dd3caSJerry Han {
864b6dd3caSJerry Han 	struct panel_info *pinfo = to_panel_info(panel);
874b6dd3caSJerry Han 	int err;
884b6dd3caSJerry Han 
894b6dd3caSJerry Han 	if (!pinfo->enabled)
904b6dd3caSJerry Han 		return 0;
914b6dd3caSJerry Han 
924b6dd3caSJerry Han 	err = mipi_dsi_dcs_set_display_off(pinfo->link);
934b6dd3caSJerry Han 	if (err < 0) {
94a25b6b27SSam Ravnborg 		dev_err(panel->dev, "failed to set display off: %d\n", err);
954b6dd3caSJerry Han 		return err;
964b6dd3caSJerry Han 	}
974b6dd3caSJerry Han 
984b6dd3caSJerry Han 	pinfo->enabled = false;
994b6dd3caSJerry Han 
1004b6dd3caSJerry Han 	return 0;
1014b6dd3caSJerry Han }
1024b6dd3caSJerry Han 
boe_panel_unprepare(struct drm_panel * panel)1034b6dd3caSJerry Han static int boe_panel_unprepare(struct drm_panel *panel)
1044b6dd3caSJerry Han {
1054b6dd3caSJerry Han 	struct panel_info *pinfo = to_panel_info(panel);
1064b6dd3caSJerry Han 	int err;
1074b6dd3caSJerry Han 
1084b6dd3caSJerry Han 	if (!pinfo->prepared)
1094b6dd3caSJerry Han 		return 0;
1104b6dd3caSJerry Han 
1114b6dd3caSJerry Han 	err = mipi_dsi_dcs_set_display_off(pinfo->link);
1124b6dd3caSJerry Han 	if (err < 0)
113a25b6b27SSam Ravnborg 		dev_err(panel->dev, "failed to set display off: %d\n", err);
1144b6dd3caSJerry Han 
1154b6dd3caSJerry Han 	err = mipi_dsi_dcs_enter_sleep_mode(pinfo->link);
1164b6dd3caSJerry Han 	if (err < 0)
117a25b6b27SSam Ravnborg 		dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
1184b6dd3caSJerry Han 
1194b6dd3caSJerry Han 	/* sleep_mode_delay: 1ms - 2ms */
1204b6dd3caSJerry Han 	usleep_range(1000, 2000);
1214b6dd3caSJerry Han 
1224b6dd3caSJerry Han 	disable_gpios(pinfo);
1234b6dd3caSJerry Han 
1244b6dd3caSJerry Han 	pinfo->prepared = false;
1254b6dd3caSJerry Han 
1264b6dd3caSJerry Han 	return 0;
1274b6dd3caSJerry Han }
1284b6dd3caSJerry Han 
boe_panel_prepare(struct drm_panel * panel)1294b6dd3caSJerry Han static int boe_panel_prepare(struct drm_panel *panel)
1304b6dd3caSJerry Han {
1314b6dd3caSJerry Han 	struct panel_info *pinfo = to_panel_info(panel);
1324b6dd3caSJerry Han 	int err;
1334b6dd3caSJerry Han 
1344b6dd3caSJerry Han 	if (pinfo->prepared)
1354b6dd3caSJerry Han 		return 0;
1364b6dd3caSJerry Han 
1374b6dd3caSJerry Han 	gpiod_set_value(pinfo->pp18_gpio, 1);
1384b6dd3caSJerry Han 	/* T1: 5ms - 6ms */
1394b6dd3caSJerry Han 	usleep_range(5000, 6000);
1404b6dd3caSJerry Han 	gpiod_set_value(pinfo->pp33_gpio, 1);
1414b6dd3caSJerry Han 
1424b6dd3caSJerry Han 	/* reset sequence */
1434b6dd3caSJerry Han 	/* T2: 14ms - 15ms */
1444b6dd3caSJerry Han 	usleep_range(14000, 15000);
1454b6dd3caSJerry Han 	gpiod_set_value(pinfo->enable_gpio, 1);
1464b6dd3caSJerry Han 
1474b6dd3caSJerry Han 	/* T3: 1ms - 2ms */
1484b6dd3caSJerry Han 	usleep_range(1000, 2000);
1494b6dd3caSJerry Han 	gpiod_set_value(pinfo->enable_gpio, 0);
1504b6dd3caSJerry Han 
1514b6dd3caSJerry Han 	/* T4: 1ms - 2ms */
1524b6dd3caSJerry Han 	usleep_range(1000, 2000);
1534b6dd3caSJerry Han 	gpiod_set_value(pinfo->enable_gpio, 1);
1544b6dd3caSJerry Han 
1554b6dd3caSJerry Han 	/* T5: 5ms - 6ms */
1564b6dd3caSJerry Han 	usleep_range(5000, 6000);
1574b6dd3caSJerry Han 
1584b6dd3caSJerry Han 	/* send init code */
1594b6dd3caSJerry Han 	err = send_mipi_cmds(panel, pinfo->desc->on_cmds);
1604b6dd3caSJerry Han 	if (err < 0) {
161a25b6b27SSam Ravnborg 		dev_err(panel->dev, "failed to send DCS Init Code: %d\n", err);
1624b6dd3caSJerry Han 		goto poweroff;
1634b6dd3caSJerry Han 	}
1644b6dd3caSJerry Han 
1654b6dd3caSJerry Han 	err = mipi_dsi_dcs_exit_sleep_mode(pinfo->link);
1664b6dd3caSJerry Han 	if (err < 0) {
167a25b6b27SSam Ravnborg 		dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
1684b6dd3caSJerry Han 		goto poweroff;
1694b6dd3caSJerry Han 	}
1704b6dd3caSJerry Han 
1714b6dd3caSJerry Han 	/* T6: 120ms - 121ms */
1724b6dd3caSJerry Han 	usleep_range(120000, 121000);
1734b6dd3caSJerry Han 
1744b6dd3caSJerry Han 	err = mipi_dsi_dcs_set_display_on(pinfo->link);
1754b6dd3caSJerry Han 	if (err < 0) {
176a25b6b27SSam Ravnborg 		dev_err(panel->dev, "failed to set display on: %d\n", err);
1774b6dd3caSJerry Han 		goto poweroff;
1784b6dd3caSJerry Han 	}
1794b6dd3caSJerry Han 
1804b6dd3caSJerry Han 	/* T7: 20ms - 21ms */
1814b6dd3caSJerry Han 	usleep_range(20000, 21000);
1824b6dd3caSJerry Han 
1834b6dd3caSJerry Han 	pinfo->prepared = true;
1844b6dd3caSJerry Han 
1854b6dd3caSJerry Han 	return 0;
1864b6dd3caSJerry Han 
1874b6dd3caSJerry Han poweroff:
1884b6dd3caSJerry Han 	disable_gpios(pinfo);
1894b6dd3caSJerry Han 	return err;
1904b6dd3caSJerry Han }
1914b6dd3caSJerry Han 
boe_panel_enable(struct drm_panel * panel)1924b6dd3caSJerry Han static int boe_panel_enable(struct drm_panel *panel)
1934b6dd3caSJerry Han {
1944b6dd3caSJerry Han 	struct panel_info *pinfo = to_panel_info(panel);
1954b6dd3caSJerry Han 	int ret;
1964b6dd3caSJerry Han 
1974b6dd3caSJerry Han 	if (pinfo->enabled)
1984b6dd3caSJerry Han 		return 0;
1994b6dd3caSJerry Han 
2004b6dd3caSJerry Han 	usleep_range(120000, 121000);
2014b6dd3caSJerry Han 
2024b6dd3caSJerry Han 	ret = mipi_dsi_dcs_set_display_on(pinfo->link);
2034b6dd3caSJerry Han 	if (ret < 0) {
204a25b6b27SSam Ravnborg 		dev_err(panel->dev, "failed to set display on: %d\n", ret);
2054b6dd3caSJerry Han 		return ret;
2064b6dd3caSJerry Han 	}
2074b6dd3caSJerry Han 
2084b6dd3caSJerry Han 	pinfo->enabled = true;
2094b6dd3caSJerry Han 
2104b6dd3caSJerry Han 	return 0;
2114b6dd3caSJerry Han }
2124b6dd3caSJerry Han 
boe_panel_get_modes(struct drm_panel * panel,struct drm_connector * connector)2134b6dd3caSJerry Han static int boe_panel_get_modes(struct drm_panel *panel,
2144b6dd3caSJerry Han 			       struct drm_connector *connector)
2154b6dd3caSJerry Han {
2164b6dd3caSJerry Han 	struct panel_info *pinfo = to_panel_info(panel);
2174b6dd3caSJerry Han 	const struct drm_display_mode *m = pinfo->desc->display_mode;
2184b6dd3caSJerry Han 	struct drm_display_mode *mode;
2194b6dd3caSJerry Han 
2204b6dd3caSJerry Han 	mode = drm_mode_duplicate(connector->dev, m);
2214b6dd3caSJerry Han 	if (!mode) {
222a25b6b27SSam Ravnborg 		dev_err(pinfo->base.dev, "failed to add mode %ux%u@%u\n",
2230425662fSVille Syrjälä 			m->hdisplay, m->vdisplay, drm_mode_vrefresh(m));
2244b6dd3caSJerry Han 		return -ENOMEM;
2254b6dd3caSJerry Han 	}
2264b6dd3caSJerry Han 
2274b6dd3caSJerry Han 	drm_mode_set_name(mode);
2284b6dd3caSJerry Han 
2294b6dd3caSJerry Han 	drm_mode_probed_add(connector, mode);
2304b6dd3caSJerry Han 
2314b6dd3caSJerry Han 	connector->display_info.width_mm = pinfo->desc->width_mm;
2324b6dd3caSJerry Han 	connector->display_info.height_mm = pinfo->desc->height_mm;
2334b6dd3caSJerry Han 	connector->display_info.bpc = pinfo->desc->bpc;
2344b6dd3caSJerry Han 
2354b6dd3caSJerry Han 	return 1;
2364b6dd3caSJerry Han }
2374b6dd3caSJerry Han 
2384b6dd3caSJerry Han static const struct drm_panel_funcs panel_funcs = {
2394b6dd3caSJerry Han 	.disable = boe_panel_disable,
2404b6dd3caSJerry Han 	.unprepare = boe_panel_unprepare,
2414b6dd3caSJerry Han 	.prepare = boe_panel_prepare,
2424b6dd3caSJerry Han 	.enable = boe_panel_enable,
2434b6dd3caSJerry Han 	.get_modes = boe_panel_get_modes,
2444b6dd3caSJerry Han };
2454b6dd3caSJerry Han 
2464b6dd3caSJerry Han static const struct drm_display_mode default_display_mode = {
2474b6dd3caSJerry Han 	.clock = 159420,
2484b6dd3caSJerry Han 	.hdisplay = 1200,
2494b6dd3caSJerry Han 	.hsync_start = 1200 + 80,
2504b6dd3caSJerry Han 	.hsync_end = 1200 + 80 + 60,
2514b6dd3caSJerry Han 	.htotal = 1200 + 80 + 60 + 24,
2524b6dd3caSJerry Han 	.vdisplay = 1920,
2534b6dd3caSJerry Han 	.vsync_start = 1920 + 10,
2544b6dd3caSJerry Han 	.vsync_end = 1920 + 10 + 14,
2554b6dd3caSJerry Han 	.vtotal = 1920 + 10 + 14 + 4,
2564b6dd3caSJerry Han };
2574b6dd3caSJerry Han 
2584b6dd3caSJerry Han /* 8 inch */
2594b6dd3caSJerry Han static const struct panel_cmd boe_himax8279d8p_on_cmds[] = {
2604b6dd3caSJerry Han 	{ 0xB0, 0x05 },
2614b6dd3caSJerry Han 	{ 0xB1, 0xE5 },
2624b6dd3caSJerry Han 	{ 0xB3, 0x52 },
2634b6dd3caSJerry Han 	{ 0xC0, 0x00 },
2644b6dd3caSJerry Han 	{ 0xC2, 0x57 },
2654b6dd3caSJerry Han 	{ 0xD9, 0x85 },
2664b6dd3caSJerry Han 	{ 0xB0, 0x01 },
2674b6dd3caSJerry Han 	{ 0xC8, 0x00 },
2684b6dd3caSJerry Han 	{ 0xC9, 0x00 },
2694b6dd3caSJerry Han 	{ 0xCC, 0x26 },
2704b6dd3caSJerry Han 	{ 0xCD, 0x26 },
2714b6dd3caSJerry Han 	{ 0xDC, 0x00 },
2724b6dd3caSJerry Han 	{ 0xDD, 0x00 },
2734b6dd3caSJerry Han 	{ 0xE0, 0x26 },
2744b6dd3caSJerry Han 	{ 0xE1, 0x26 },
2754b6dd3caSJerry Han 	{ 0xB0, 0x03 },
2764b6dd3caSJerry Han 	{ 0xC3, 0x2A },
2774b6dd3caSJerry Han 	{ 0xE7, 0x2A },
2784b6dd3caSJerry Han 	{ 0xC5, 0x2A },
2794b6dd3caSJerry Han 	{ 0xDE, 0x2A },
2804b6dd3caSJerry Han 	{ 0xBC, 0x02 },
2814b6dd3caSJerry Han 	{ 0xCB, 0x02 },
2824b6dd3caSJerry Han 	{ 0xB0, 0x00 },
2834b6dd3caSJerry Han 	{ 0xB6, 0x03 },
2844b6dd3caSJerry Han 	{ 0xBA, 0x8B },
2854b6dd3caSJerry Han 	{ 0xBF, 0x15 },
2864b6dd3caSJerry Han 	{ 0xC0, 0x18 },
2874b6dd3caSJerry Han 	{ 0xC2, 0x14 },
2884b6dd3caSJerry Han 	{ 0xC3, 0x02 },
2894b6dd3caSJerry Han 	{ 0xC4, 0x14 },
2904b6dd3caSJerry Han 	{ 0xC5, 0x02 },
2914b6dd3caSJerry Han 	{ 0xCC, 0x0A },
2924b6dd3caSJerry Han 	{ 0xB0, 0x06 },
2934b6dd3caSJerry Han 	{ 0xC0, 0xA5 },
2944b6dd3caSJerry Han 	{ 0xD5, 0x20 },
2954b6dd3caSJerry Han 	{ 0xC0, 0x00 },
2964b6dd3caSJerry Han 	{ 0xB0, 0x02 },
2974b6dd3caSJerry Han 	{ 0xC0, 0x00 },
2984b6dd3caSJerry Han 	{ 0xC1, 0x02 },
2994b6dd3caSJerry Han 	{ 0xC2, 0x06 },
3004b6dd3caSJerry Han 	{ 0xC3, 0x16 },
3014b6dd3caSJerry Han 	{ 0xC4, 0x0E },
3024b6dd3caSJerry Han 	{ 0xC5, 0x18 },
3034b6dd3caSJerry Han 	{ 0xC6, 0x26 },
3044b6dd3caSJerry Han 	{ 0xC7, 0x32 },
3054b6dd3caSJerry Han 	{ 0xC8, 0x3F },
3064b6dd3caSJerry Han 	{ 0xC9, 0x3F },
3074b6dd3caSJerry Han 	{ 0xCA, 0x3F },
3084b6dd3caSJerry Han 	{ 0xCB, 0x3F },
3094b6dd3caSJerry Han 	{ 0xCC, 0x3D },
3104b6dd3caSJerry Han 	{ 0xCD, 0x2F },
3114b6dd3caSJerry Han 	{ 0xCE, 0x2F },
3124b6dd3caSJerry Han 	{ 0xCF, 0x2F },
3134b6dd3caSJerry Han 	{ 0xD0, 0x07 },
3144b6dd3caSJerry Han 	{ 0xD2, 0x00 },
3154b6dd3caSJerry Han 	{ 0xD3, 0x02 },
3164b6dd3caSJerry Han 	{ 0xD4, 0x06 },
3174b6dd3caSJerry Han 	{ 0xD5, 0x12 },
3184b6dd3caSJerry Han 	{ 0xD6, 0x0A },
3194b6dd3caSJerry Han 	{ 0xD7, 0x14 },
3204b6dd3caSJerry Han 	{ 0xD8, 0x22 },
3214b6dd3caSJerry Han 	{ 0xD9, 0x2E },
3224b6dd3caSJerry Han 	{ 0xDA, 0x3D },
3234b6dd3caSJerry Han 	{ 0xDB, 0x3F },
3244b6dd3caSJerry Han 	{ 0xDC, 0x3F },
3254b6dd3caSJerry Han 	{ 0xDD, 0x3F },
3264b6dd3caSJerry Han 	{ 0xDE, 0x3D },
3274b6dd3caSJerry Han 	{ 0xDF, 0x2F },
3284b6dd3caSJerry Han 	{ 0xE0, 0x2F },
3294b6dd3caSJerry Han 	{ 0xE1, 0x2F },
3304b6dd3caSJerry Han 	{ 0xE2, 0x07 },
3314b6dd3caSJerry Han 	{ 0xB0, 0x07 },
3324b6dd3caSJerry Han 	{ 0xB1, 0x18 },
3334b6dd3caSJerry Han 	{ 0xB2, 0x19 },
3344b6dd3caSJerry Han 	{ 0xB3, 0x2E },
3354b6dd3caSJerry Han 	{ 0xB4, 0x52 },
3364b6dd3caSJerry Han 	{ 0xB5, 0x72 },
3374b6dd3caSJerry Han 	{ 0xB6, 0x8C },
3384b6dd3caSJerry Han 	{ 0xB7, 0xBD },
3394b6dd3caSJerry Han 	{ 0xB8, 0xEB },
3404b6dd3caSJerry Han 	{ 0xB9, 0x47 },
3414b6dd3caSJerry Han 	{ 0xBA, 0x96 },
3424b6dd3caSJerry Han 	{ 0xBB, 0x1E },
3434b6dd3caSJerry Han 	{ 0xBC, 0x90 },
3444b6dd3caSJerry Han 	{ 0xBD, 0x93 },
3454b6dd3caSJerry Han 	{ 0xBE, 0xFA },
3464b6dd3caSJerry Han 	{ 0xBF, 0x56 },
3474b6dd3caSJerry Han 	{ 0xC0, 0x8C },
3484b6dd3caSJerry Han 	{ 0xC1, 0xB7 },
3494b6dd3caSJerry Han 	{ 0xC2, 0xCC },
3504b6dd3caSJerry Han 	{ 0xC3, 0xDF },
3514b6dd3caSJerry Han 	{ 0xC4, 0xE8 },
3524b6dd3caSJerry Han 	{ 0xC5, 0xF0 },
3534b6dd3caSJerry Han 	{ 0xC6, 0xF8 },
3544b6dd3caSJerry Han 	{ 0xC7, 0xFA },
3554b6dd3caSJerry Han 	{ 0xC8, 0xFC },
3564b6dd3caSJerry Han 	{ 0xC9, 0x00 },
3574b6dd3caSJerry Han 	{ 0xCA, 0x00 },
3584b6dd3caSJerry Han 	{ 0xCB, 0x5A },
3594b6dd3caSJerry Han 	{ 0xCC, 0xAF },
3604b6dd3caSJerry Han 	{ 0xCD, 0xFF },
3614b6dd3caSJerry Han 	{ 0xCE, 0xFF },
3624b6dd3caSJerry Han 	{ 0xB0, 0x08 },
3634b6dd3caSJerry Han 	{ 0xB1, 0x04 },
3644b6dd3caSJerry Han 	{ 0xB2, 0x15 },
3654b6dd3caSJerry Han 	{ 0xB3, 0x2D },
3664b6dd3caSJerry Han 	{ 0xB4, 0x51 },
3674b6dd3caSJerry Han 	{ 0xB5, 0x72 },
3684b6dd3caSJerry Han 	{ 0xB6, 0x8D },
3694b6dd3caSJerry Han 	{ 0xB7, 0xBE },
3704b6dd3caSJerry Han 	{ 0xB8, 0xED },
3714b6dd3caSJerry Han 	{ 0xB9, 0x4A },
3724b6dd3caSJerry Han 	{ 0xBA, 0x9A },
3734b6dd3caSJerry Han 	{ 0xBB, 0x23 },
3744b6dd3caSJerry Han 	{ 0xBC, 0x95 },
3754b6dd3caSJerry Han 	{ 0xBD, 0x98 },
3764b6dd3caSJerry Han 	{ 0xBE, 0xFF },
3774b6dd3caSJerry Han 	{ 0xBF, 0x59 },
3784b6dd3caSJerry Han 	{ 0xC0, 0x8E },
3794b6dd3caSJerry Han 	{ 0xC1, 0xB9 },
3804b6dd3caSJerry Han 	{ 0xC2, 0xCD },
3814b6dd3caSJerry Han 	{ 0xC3, 0xDF },
3824b6dd3caSJerry Han 	{ 0xC4, 0xE8 },
3834b6dd3caSJerry Han 	{ 0xC5, 0xF0 },
3844b6dd3caSJerry Han 	{ 0xC6, 0xF8 },
3854b6dd3caSJerry Han 	{ 0xC7, 0xFA },
3864b6dd3caSJerry Han 	{ 0xC8, 0xFC },
3874b6dd3caSJerry Han 	{ 0xC9, 0x00 },
3884b6dd3caSJerry Han 	{ 0xCA, 0x00 },
3894b6dd3caSJerry Han 	{ 0xCB, 0x5A },
3904b6dd3caSJerry Han 	{ 0xCC, 0xAF },
3914b6dd3caSJerry Han 	{ 0xCD, 0xFF },
3924b6dd3caSJerry Han 	{ 0xCE, 0xFF },
3934b6dd3caSJerry Han 	{ 0xB0, 0x09 },
3944b6dd3caSJerry Han 	{ 0xB1, 0x04 },
3954b6dd3caSJerry Han 	{ 0xB2, 0x2C },
3964b6dd3caSJerry Han 	{ 0xB3, 0x36 },
3974b6dd3caSJerry Han 	{ 0xB4, 0x53 },
3984b6dd3caSJerry Han 	{ 0xB5, 0x73 },
3994b6dd3caSJerry Han 	{ 0xB6, 0x8E },
4004b6dd3caSJerry Han 	{ 0xB7, 0xC0 },
4014b6dd3caSJerry Han 	{ 0xB8, 0xEF },
4024b6dd3caSJerry Han 	{ 0xB9, 0x4C },
4034b6dd3caSJerry Han 	{ 0xBA, 0x9D },
4044b6dd3caSJerry Han 	{ 0xBB, 0x25 },
4054b6dd3caSJerry Han 	{ 0xBC, 0x96 },
4064b6dd3caSJerry Han 	{ 0xBD, 0x9A },
4074b6dd3caSJerry Han 	{ 0xBE, 0x01 },
4084b6dd3caSJerry Han 	{ 0xBF, 0x59 },
4094b6dd3caSJerry Han 	{ 0xC0, 0x8E },
4104b6dd3caSJerry Han 	{ 0xC1, 0xB9 },
4114b6dd3caSJerry Han 	{ 0xC2, 0xCD },
4124b6dd3caSJerry Han 	{ 0xC3, 0xDF },
4134b6dd3caSJerry Han 	{ 0xC4, 0xE8 },
4144b6dd3caSJerry Han 	{ 0xC5, 0xF0 },
4154b6dd3caSJerry Han 	{ 0xC6, 0xF8 },
4164b6dd3caSJerry Han 	{ 0xC7, 0xFA },
4174b6dd3caSJerry Han 	{ 0xC8, 0xFC },
4184b6dd3caSJerry Han 	{ 0xC9, 0x00 },
4194b6dd3caSJerry Han 	{ 0xCA, 0x00 },
4204b6dd3caSJerry Han 	{ 0xCB, 0x5A },
4214b6dd3caSJerry Han 	{ 0xCC, 0xBF },
4224b6dd3caSJerry Han 	{ 0xCD, 0xFF },
4234b6dd3caSJerry Han 	{ 0xCE, 0xFF },
4244b6dd3caSJerry Han 	{ 0xB0, 0x0A },
4254b6dd3caSJerry Han 	{ 0xB1, 0x18 },
4264b6dd3caSJerry Han 	{ 0xB2, 0x19 },
4274b6dd3caSJerry Han 	{ 0xB3, 0x2E },
4284b6dd3caSJerry Han 	{ 0xB4, 0x52 },
4294b6dd3caSJerry Han 	{ 0xB5, 0x72 },
4304b6dd3caSJerry Han 	{ 0xB6, 0x8C },
4314b6dd3caSJerry Han 	{ 0xB7, 0xBD },
4324b6dd3caSJerry Han 	{ 0xB8, 0xEB },
4334b6dd3caSJerry Han 	{ 0xB9, 0x47 },
4344b6dd3caSJerry Han 	{ 0xBA, 0x96 },
4354b6dd3caSJerry Han 	{ 0xBB, 0x1E },
4364b6dd3caSJerry Han 	{ 0xBC, 0x90 },
4374b6dd3caSJerry Han 	{ 0xBD, 0x93 },
4384b6dd3caSJerry Han 	{ 0xBE, 0xFA },
4394b6dd3caSJerry Han 	{ 0xBF, 0x56 },
4404b6dd3caSJerry Han 	{ 0xC0, 0x8C },
4414b6dd3caSJerry Han 	{ 0xC1, 0xB7 },
4424b6dd3caSJerry Han 	{ 0xC2, 0xCC },
4434b6dd3caSJerry Han 	{ 0xC3, 0xDF },
4444b6dd3caSJerry Han 	{ 0xC4, 0xE8 },
4454b6dd3caSJerry Han 	{ 0xC5, 0xF0 },
4464b6dd3caSJerry Han 	{ 0xC6, 0xF8 },
4474b6dd3caSJerry Han 	{ 0xC7, 0xFA },
4484b6dd3caSJerry Han 	{ 0xC8, 0xFC },
4494b6dd3caSJerry Han 	{ 0xC9, 0x00 },
4504b6dd3caSJerry Han 	{ 0xCA, 0x00 },
4514b6dd3caSJerry Han 	{ 0xCB, 0x5A },
4524b6dd3caSJerry Han 	{ 0xCC, 0xAF },
4534b6dd3caSJerry Han 	{ 0xCD, 0xFF },
4544b6dd3caSJerry Han 	{ 0xCE, 0xFF },
4554b6dd3caSJerry Han 	{ 0xB0, 0x0B },
4564b6dd3caSJerry Han 	{ 0xB1, 0x04 },
4574b6dd3caSJerry Han 	{ 0xB2, 0x15 },
4584b6dd3caSJerry Han 	{ 0xB3, 0x2D },
4594b6dd3caSJerry Han 	{ 0xB4, 0x51 },
4604b6dd3caSJerry Han 	{ 0xB5, 0x72 },
4614b6dd3caSJerry Han 	{ 0xB6, 0x8D },
4624b6dd3caSJerry Han 	{ 0xB7, 0xBE },
4634b6dd3caSJerry Han 	{ 0xB8, 0xED },
4644b6dd3caSJerry Han 	{ 0xB9, 0x4A },
4654b6dd3caSJerry Han 	{ 0xBA, 0x9A },
4664b6dd3caSJerry Han 	{ 0xBB, 0x23 },
4674b6dd3caSJerry Han 	{ 0xBC, 0x95 },
4684b6dd3caSJerry Han 	{ 0xBD, 0x98 },
4694b6dd3caSJerry Han 	{ 0xBE, 0xFF },
4704b6dd3caSJerry Han 	{ 0xBF, 0x59 },
4714b6dd3caSJerry Han 	{ 0xC0, 0x8E },
4724b6dd3caSJerry Han 	{ 0xC1, 0xB9 },
4734b6dd3caSJerry Han 	{ 0xC2, 0xCD },
4744b6dd3caSJerry Han 	{ 0xC3, 0xDF },
4754b6dd3caSJerry Han 	{ 0xC4, 0xE8 },
4764b6dd3caSJerry Han 	{ 0xC5, 0xF0 },
4774b6dd3caSJerry Han 	{ 0xC6, 0xF8 },
4784b6dd3caSJerry Han 	{ 0xC7, 0xFA },
4794b6dd3caSJerry Han 	{ 0xC8, 0xFC },
4804b6dd3caSJerry Han 	{ 0xC9, 0x00 },
4814b6dd3caSJerry Han 	{ 0xCA, 0x00 },
4824b6dd3caSJerry Han 	{ 0xCB, 0x5A },
4834b6dd3caSJerry Han 	{ 0xCC, 0xAF },
4844b6dd3caSJerry Han 	{ 0xCD, 0xFF },
4854b6dd3caSJerry Han 	{ 0xCE, 0xFF },
4864b6dd3caSJerry Han 	{ 0xB0, 0x0C },
4874b6dd3caSJerry Han 	{ 0xB1, 0x04 },
4884b6dd3caSJerry Han 	{ 0xB2, 0x2C },
4894b6dd3caSJerry Han 	{ 0xB3, 0x36 },
4904b6dd3caSJerry Han 	{ 0xB4, 0x53 },
4914b6dd3caSJerry Han 	{ 0xB5, 0x73 },
4924b6dd3caSJerry Han 	{ 0xB6, 0x8E },
4934b6dd3caSJerry Han 	{ 0xB7, 0xC0 },
4944b6dd3caSJerry Han 	{ 0xB8, 0xEF },
4954b6dd3caSJerry Han 	{ 0xB9, 0x4C },
4964b6dd3caSJerry Han 	{ 0xBA, 0x9D },
4974b6dd3caSJerry Han 	{ 0xBB, 0x25 },
4984b6dd3caSJerry Han 	{ 0xBC, 0x96 },
4994b6dd3caSJerry Han 	{ 0xBD, 0x9A },
5004b6dd3caSJerry Han 	{ 0xBE, 0x01 },
5014b6dd3caSJerry Han 	{ 0xBF, 0x59 },
5024b6dd3caSJerry Han 	{ 0xC0, 0x8E },
5034b6dd3caSJerry Han 	{ 0xC1, 0xB9 },
5044b6dd3caSJerry Han 	{ 0xC2, 0xCD },
5054b6dd3caSJerry Han 	{ 0xC3, 0xDF },
5064b6dd3caSJerry Han 	{ 0xC4, 0xE8 },
5074b6dd3caSJerry Han 	{ 0xC5, 0xF0 },
5084b6dd3caSJerry Han 	{ 0xC6, 0xF8 },
5094b6dd3caSJerry Han 	{ 0xC7, 0xFA },
5104b6dd3caSJerry Han 	{ 0xC8, 0xFC },
5114b6dd3caSJerry Han 	{ 0xC9, 0x00 },
5124b6dd3caSJerry Han 	{ 0xCA, 0x00 },
5134b6dd3caSJerry Han 	{ 0xCB, 0x5A },
5144b6dd3caSJerry Han 	{ 0xCC, 0xBF },
5154b6dd3caSJerry Han 	{ 0xCD, 0xFF },
5164b6dd3caSJerry Han 	{ 0xCE, 0xFF },
5174b6dd3caSJerry Han 	{ 0xB0, 0x04 },
5184b6dd3caSJerry Han 	{ 0xB5, 0x02 },
5194b6dd3caSJerry Han 	{ 0xB6, 0x01 },
5204b6dd3caSJerry Han };
5214b6dd3caSJerry Han 
5224b6dd3caSJerry Han static const struct panel_desc boe_himax8279d8p_panel_desc = {
5234b6dd3caSJerry Han 	.display_mode = &default_display_mode,
5244b6dd3caSJerry Han 	.bpc = 8,
5254b6dd3caSJerry Han 	.width_mm = 107,
5264b6dd3caSJerry Han 	.height_mm = 172,
5274b6dd3caSJerry Han 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
5284b6dd3caSJerry Han 			MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM,
5294b6dd3caSJerry Han 	.format = MIPI_DSI_FMT_RGB888,
5304b6dd3caSJerry Han 	.lanes = 4,
5314b6dd3caSJerry Han 	.on_cmds = boe_himax8279d8p_on_cmds,
5324b6dd3caSJerry Han 	.on_cmds_num = 260,
5334b6dd3caSJerry Han };
5344b6dd3caSJerry Han 
5354b6dd3caSJerry Han /* 10 inch */
5364b6dd3caSJerry Han static const struct panel_cmd boe_himax8279d10p_on_cmds[] = {
5374b6dd3caSJerry Han 	{ 0xB0, 0x05 },
5384b6dd3caSJerry Han 	{ 0xB1, 0xE5 },
5394b6dd3caSJerry Han 	{ 0xB3, 0x52 },
5404b6dd3caSJerry Han 	{ 0xB0, 0x00 },
5414b6dd3caSJerry Han 	{ 0xB6, 0x03 },
5424b6dd3caSJerry Han 	{ 0xBA, 0x8B },
5434b6dd3caSJerry Han 	{ 0xBF, 0x1A },
5444b6dd3caSJerry Han 	{ 0xC0, 0x0F },
5454b6dd3caSJerry Han 	{ 0xC2, 0x0C },
5464b6dd3caSJerry Han 	{ 0xC3, 0x02 },
5474b6dd3caSJerry Han 	{ 0xC4, 0x0C },
5484b6dd3caSJerry Han 	{ 0xC5, 0x02 },
5494b6dd3caSJerry Han 	{ 0xB0, 0x01 },
5504b6dd3caSJerry Han 	{ 0xE0, 0x26 },
5514b6dd3caSJerry Han 	{ 0xE1, 0x26 },
5524b6dd3caSJerry Han 	{ 0xDC, 0x00 },
5534b6dd3caSJerry Han 	{ 0xDD, 0x00 },
5544b6dd3caSJerry Han 	{ 0xCC, 0x26 },
5554b6dd3caSJerry Han 	{ 0xCD, 0x26 },
5564b6dd3caSJerry Han 	{ 0xC8, 0x00 },
5574b6dd3caSJerry Han 	{ 0xC9, 0x00 },
5584b6dd3caSJerry Han 	{ 0xD2, 0x03 },
5594b6dd3caSJerry Han 	{ 0xD3, 0x03 },
5604b6dd3caSJerry Han 	{ 0xE6, 0x04 },
5614b6dd3caSJerry Han 	{ 0xE7, 0x04 },
5624b6dd3caSJerry Han 	{ 0xC4, 0x09 },
5634b6dd3caSJerry Han 	{ 0xC5, 0x09 },
5644b6dd3caSJerry Han 	{ 0xD8, 0x0A },
5654b6dd3caSJerry Han 	{ 0xD9, 0x0A },
5664b6dd3caSJerry Han 	{ 0xC2, 0x0B },
5674b6dd3caSJerry Han 	{ 0xC3, 0x0B },
5684b6dd3caSJerry Han 	{ 0xD6, 0x0C },
5694b6dd3caSJerry Han 	{ 0xD7, 0x0C },
5704b6dd3caSJerry Han 	{ 0xC0, 0x05 },
5714b6dd3caSJerry Han 	{ 0xC1, 0x05 },
5724b6dd3caSJerry Han 	{ 0xD4, 0x06 },
5734b6dd3caSJerry Han 	{ 0xD5, 0x06 },
5744b6dd3caSJerry Han 	{ 0xCA, 0x07 },
5754b6dd3caSJerry Han 	{ 0xCB, 0x07 },
5764b6dd3caSJerry Han 	{ 0xDE, 0x08 },
5774b6dd3caSJerry Han 	{ 0xDF, 0x08 },
5784b6dd3caSJerry Han 	{ 0xB0, 0x02 },
5794b6dd3caSJerry Han 	{ 0xC0, 0x00 },
5804b6dd3caSJerry Han 	{ 0xC1, 0x0D },
5814b6dd3caSJerry Han 	{ 0xC2, 0x17 },
5824b6dd3caSJerry Han 	{ 0xC3, 0x26 },
5834b6dd3caSJerry Han 	{ 0xC4, 0x31 },
5844b6dd3caSJerry Han 	{ 0xC5, 0x1C },
5854b6dd3caSJerry Han 	{ 0xC6, 0x2C },
5864b6dd3caSJerry Han 	{ 0xC7, 0x33 },
5874b6dd3caSJerry Han 	{ 0xC8, 0x31 },
5884b6dd3caSJerry Han 	{ 0xC9, 0x37 },
5894b6dd3caSJerry Han 	{ 0xCA, 0x37 },
5904b6dd3caSJerry Han 	{ 0xCB, 0x37 },
5914b6dd3caSJerry Han 	{ 0xCC, 0x39 },
5924b6dd3caSJerry Han 	{ 0xCD, 0x2E },
5934b6dd3caSJerry Han 	{ 0xCE, 0x2F },
5944b6dd3caSJerry Han 	{ 0xCF, 0x2F },
5954b6dd3caSJerry Han 	{ 0xD0, 0x07 },
5964b6dd3caSJerry Han 	{ 0xD2, 0x00 },
5974b6dd3caSJerry Han 	{ 0xD3, 0x0D },
5984b6dd3caSJerry Han 	{ 0xD4, 0x17 },
5994b6dd3caSJerry Han 	{ 0xD5, 0x26 },
6004b6dd3caSJerry Han 	{ 0xD6, 0x31 },
6014b6dd3caSJerry Han 	{ 0xD7, 0x3F },
6024b6dd3caSJerry Han 	{ 0xD8, 0x3F },
6034b6dd3caSJerry Han 	{ 0xD9, 0x3F },
6044b6dd3caSJerry Han 	{ 0xDA, 0x3F },
6054b6dd3caSJerry Han 	{ 0xDB, 0x37 },
6064b6dd3caSJerry Han 	{ 0xDC, 0x37 },
6074b6dd3caSJerry Han 	{ 0xDD, 0x37 },
6084b6dd3caSJerry Han 	{ 0xDE, 0x39 },
6094b6dd3caSJerry Han 	{ 0xDF, 0x2E },
6104b6dd3caSJerry Han 	{ 0xE0, 0x2F },
6114b6dd3caSJerry Han 	{ 0xE1, 0x2F },
6124b6dd3caSJerry Han 	{ 0xE2, 0x07 },
6134b6dd3caSJerry Han 	{ 0xB0, 0x03 },
6144b6dd3caSJerry Han 	{ 0xC8, 0x0B },
6154b6dd3caSJerry Han 	{ 0xC9, 0x07 },
6164b6dd3caSJerry Han 	{ 0xC3, 0x00 },
6174b6dd3caSJerry Han 	{ 0xE7, 0x00 },
6184b6dd3caSJerry Han 	{ 0xC5, 0x2A },
6194b6dd3caSJerry Han 	{ 0xDE, 0x2A },
6204b6dd3caSJerry Han 	{ 0xCA, 0x43 },
6214b6dd3caSJerry Han 	{ 0xC9, 0x07 },
6224b6dd3caSJerry Han 	{ 0xE4, 0xC0 },
6234b6dd3caSJerry Han 	{ 0xE5, 0x0D },
6244b6dd3caSJerry Han 	{ 0xCB, 0x01 },
6254b6dd3caSJerry Han 	{ 0xBC, 0x01 },
6264b6dd3caSJerry Han 	{ 0xB0, 0x06 },
6274b6dd3caSJerry Han 	{ 0xB8, 0xA5 },
6284b6dd3caSJerry Han 	{ 0xC0, 0xA5 },
6294b6dd3caSJerry Han 	{ 0xC7, 0x0F },
6304b6dd3caSJerry Han 	{ 0xD5, 0x32 },
6314b6dd3caSJerry Han 	{ 0xB8, 0x00 },
6324b6dd3caSJerry Han 	{ 0xC0, 0x00 },
6334b6dd3caSJerry Han 	{ 0xBC, 0x00 },
6344b6dd3caSJerry Han 	{ 0xB0, 0x07 },
6354b6dd3caSJerry Han 	{ 0xB1, 0x00 },
6364b6dd3caSJerry Han 	{ 0xB2, 0x05 },
6374b6dd3caSJerry Han 	{ 0xB3, 0x10 },
6384b6dd3caSJerry Han 	{ 0xB4, 0x22 },
6394b6dd3caSJerry Han 	{ 0xB5, 0x36 },
6404b6dd3caSJerry Han 	{ 0xB6, 0x4A },
6414b6dd3caSJerry Han 	{ 0xB7, 0x6C },
6424b6dd3caSJerry Han 	{ 0xB8, 0x9A },
6434b6dd3caSJerry Han 	{ 0xB9, 0xD7 },
6444b6dd3caSJerry Han 	{ 0xBA, 0x17 },
6454b6dd3caSJerry Han 	{ 0xBB, 0x92 },
6464b6dd3caSJerry Han 	{ 0xBC, 0x15 },
6474b6dd3caSJerry Han 	{ 0xBD, 0x18 },
6484b6dd3caSJerry Han 	{ 0xBE, 0x8C },
6494b6dd3caSJerry Han 	{ 0xBF, 0x00 },
6504b6dd3caSJerry Han 	{ 0xC0, 0x3A },
6514b6dd3caSJerry Han 	{ 0xC1, 0x72 },
6524b6dd3caSJerry Han 	{ 0xC2, 0x8C },
6534b6dd3caSJerry Han 	{ 0xC3, 0xA5 },
6544b6dd3caSJerry Han 	{ 0xC4, 0xB1 },
6554b6dd3caSJerry Han 	{ 0xC5, 0xBE },
6564b6dd3caSJerry Han 	{ 0xC6, 0xCA },
6574b6dd3caSJerry Han 	{ 0xC7, 0xD1 },
6584b6dd3caSJerry Han 	{ 0xC8, 0xD4 },
6594b6dd3caSJerry Han 	{ 0xC9, 0x00 },
6604b6dd3caSJerry Han 	{ 0xCA, 0x00 },
6614b6dd3caSJerry Han 	{ 0xCB, 0x16 },
6624b6dd3caSJerry Han 	{ 0xCC, 0xAF },
6634b6dd3caSJerry Han 	{ 0xCD, 0xFF },
6644b6dd3caSJerry Han 	{ 0xCE, 0xFF },
6654b6dd3caSJerry Han 	{ 0xB0, 0x08 },
6664b6dd3caSJerry Han 	{ 0xB1, 0x04 },
6674b6dd3caSJerry Han 	{ 0xB2, 0x05 },
6684b6dd3caSJerry Han 	{ 0xB3, 0x11 },
6694b6dd3caSJerry Han 	{ 0xB4, 0x24 },
6704b6dd3caSJerry Han 	{ 0xB5, 0x39 },
6714b6dd3caSJerry Han 	{ 0xB6, 0x4E },
6724b6dd3caSJerry Han 	{ 0xB7, 0x72 },
6734b6dd3caSJerry Han 	{ 0xB8, 0xA3 },
6744b6dd3caSJerry Han 	{ 0xB9, 0xE1 },
6754b6dd3caSJerry Han 	{ 0xBA, 0x25 },
6764b6dd3caSJerry Han 	{ 0xBB, 0xA8 },
6774b6dd3caSJerry Han 	{ 0xBC, 0x2E },
6784b6dd3caSJerry Han 	{ 0xBD, 0x32 },
6794b6dd3caSJerry Han 	{ 0xBE, 0xAD },
6804b6dd3caSJerry Han 	{ 0xBF, 0x28 },
6814b6dd3caSJerry Han 	{ 0xC0, 0x63 },
6824b6dd3caSJerry Han 	{ 0xC1, 0x9B },
6834b6dd3caSJerry Han 	{ 0xC2, 0xB5 },
6844b6dd3caSJerry Han 	{ 0xC3, 0xCF },
6854b6dd3caSJerry Han 	{ 0xC4, 0xDB },
6864b6dd3caSJerry Han 	{ 0xC5, 0xE8 },
6874b6dd3caSJerry Han 	{ 0xC6, 0xF5 },
6884b6dd3caSJerry Han 	{ 0xC7, 0xFA },
6894b6dd3caSJerry Han 	{ 0xC8, 0xFC },
6904b6dd3caSJerry Han 	{ 0xC9, 0x00 },
6914b6dd3caSJerry Han 	{ 0xCA, 0x00 },
6924b6dd3caSJerry Han 	{ 0xCB, 0x16 },
6934b6dd3caSJerry Han 	{ 0xCC, 0xAF },
6944b6dd3caSJerry Han 	{ 0xCD, 0xFF },
6954b6dd3caSJerry Han 	{ 0xCE, 0xFF },
6964b6dd3caSJerry Han 	{ 0xB0, 0x09 },
6974b6dd3caSJerry Han 	{ 0xB1, 0x04 },
6984b6dd3caSJerry Han 	{ 0xB2, 0x04 },
6994b6dd3caSJerry Han 	{ 0xB3, 0x0F },
7004b6dd3caSJerry Han 	{ 0xB4, 0x22 },
7014b6dd3caSJerry Han 	{ 0xB5, 0x37 },
7024b6dd3caSJerry Han 	{ 0xB6, 0x4D },
7034b6dd3caSJerry Han 	{ 0xB7, 0x71 },
7044b6dd3caSJerry Han 	{ 0xB8, 0xA2 },
7054b6dd3caSJerry Han 	{ 0xB9, 0xE1 },
7064b6dd3caSJerry Han 	{ 0xBA, 0x26 },
7074b6dd3caSJerry Han 	{ 0xBB, 0xA9 },
7084b6dd3caSJerry Han 	{ 0xBC, 0x2F },
7094b6dd3caSJerry Han 	{ 0xBD, 0x33 },
7104b6dd3caSJerry Han 	{ 0xBE, 0xAC },
7114b6dd3caSJerry Han 	{ 0xBF, 0x24 },
7124b6dd3caSJerry Han 	{ 0xC0, 0x5D },
7134b6dd3caSJerry Han 	{ 0xC1, 0x94 },
7144b6dd3caSJerry Han 	{ 0xC2, 0xAC },
7154b6dd3caSJerry Han 	{ 0xC3, 0xC5 },
7164b6dd3caSJerry Han 	{ 0xC4, 0xD1 },
7174b6dd3caSJerry Han 	{ 0xC5, 0xDC },
7184b6dd3caSJerry Han 	{ 0xC6, 0xE8 },
7194b6dd3caSJerry Han 	{ 0xC7, 0xED },
7204b6dd3caSJerry Han 	{ 0xC8, 0xF0 },
7214b6dd3caSJerry Han 	{ 0xC9, 0x00 },
7224b6dd3caSJerry Han 	{ 0xCA, 0x00 },
7234b6dd3caSJerry Han 	{ 0xCB, 0x16 },
7244b6dd3caSJerry Han 	{ 0xCC, 0xAF },
7254b6dd3caSJerry Han 	{ 0xCD, 0xFF },
7264b6dd3caSJerry Han 	{ 0xCE, 0xFF },
7274b6dd3caSJerry Han 	{ 0xB0, 0x0A },
7284b6dd3caSJerry Han 	{ 0xB1, 0x00 },
7294b6dd3caSJerry Han 	{ 0xB2, 0x05 },
7304b6dd3caSJerry Han 	{ 0xB3, 0x10 },
7314b6dd3caSJerry Han 	{ 0xB4, 0x22 },
7324b6dd3caSJerry Han 	{ 0xB5, 0x36 },
7334b6dd3caSJerry Han 	{ 0xB6, 0x4A },
7344b6dd3caSJerry Han 	{ 0xB7, 0x6C },
7354b6dd3caSJerry Han 	{ 0xB8, 0x9A },
7364b6dd3caSJerry Han 	{ 0xB9, 0xD7 },
7374b6dd3caSJerry Han 	{ 0xBA, 0x17 },
7384b6dd3caSJerry Han 	{ 0xBB, 0x92 },
7394b6dd3caSJerry Han 	{ 0xBC, 0x15 },
7404b6dd3caSJerry Han 	{ 0xBD, 0x18 },
7414b6dd3caSJerry Han 	{ 0xBE, 0x8C },
7424b6dd3caSJerry Han 	{ 0xBF, 0x00 },
7434b6dd3caSJerry Han 	{ 0xC0, 0x3A },
7444b6dd3caSJerry Han 	{ 0xC1, 0x72 },
7454b6dd3caSJerry Han 	{ 0xC2, 0x8C },
7464b6dd3caSJerry Han 	{ 0xC3, 0xA5 },
7474b6dd3caSJerry Han 	{ 0xC4, 0xB1 },
7484b6dd3caSJerry Han 	{ 0xC5, 0xBE },
7494b6dd3caSJerry Han 	{ 0xC6, 0xCA },
7504b6dd3caSJerry Han 	{ 0xC7, 0xD1 },
7514b6dd3caSJerry Han 	{ 0xC8, 0xD4 },
7524b6dd3caSJerry Han 	{ 0xC9, 0x00 },
7534b6dd3caSJerry Han 	{ 0xCA, 0x00 },
7544b6dd3caSJerry Han 	{ 0xCB, 0x16 },
7554b6dd3caSJerry Han 	{ 0xCC, 0xAF },
7564b6dd3caSJerry Han 	{ 0xCD, 0xFF },
7574b6dd3caSJerry Han 	{ 0xCE, 0xFF },
7584b6dd3caSJerry Han 	{ 0xB0, 0x0B },
7594b6dd3caSJerry Han 	{ 0xB1, 0x04 },
7604b6dd3caSJerry Han 	{ 0xB2, 0x05 },
7614b6dd3caSJerry Han 	{ 0xB3, 0x11 },
7624b6dd3caSJerry Han 	{ 0xB4, 0x24 },
7634b6dd3caSJerry Han 	{ 0xB5, 0x39 },
7644b6dd3caSJerry Han 	{ 0xB6, 0x4E },
7654b6dd3caSJerry Han 	{ 0xB7, 0x72 },
7664b6dd3caSJerry Han 	{ 0xB8, 0xA3 },
7674b6dd3caSJerry Han 	{ 0xB9, 0xE1 },
7684b6dd3caSJerry Han 	{ 0xBA, 0x25 },
7694b6dd3caSJerry Han 	{ 0xBB, 0xA8 },
7704b6dd3caSJerry Han 	{ 0xBC, 0x2E },
7714b6dd3caSJerry Han 	{ 0xBD, 0x32 },
7724b6dd3caSJerry Han 	{ 0xBE, 0xAD },
7734b6dd3caSJerry Han 	{ 0xBF, 0x28 },
7744b6dd3caSJerry Han 	{ 0xC0, 0x63 },
7754b6dd3caSJerry Han 	{ 0xC1, 0x9B },
7764b6dd3caSJerry Han 	{ 0xC2, 0xB5 },
7774b6dd3caSJerry Han 	{ 0xC3, 0xCF },
7784b6dd3caSJerry Han 	{ 0xC4, 0xDB },
7794b6dd3caSJerry Han 	{ 0xC5, 0xE8 },
7804b6dd3caSJerry Han 	{ 0xC6, 0xF5 },
7814b6dd3caSJerry Han 	{ 0xC7, 0xFA },
7824b6dd3caSJerry Han 	{ 0xC8, 0xFC },
7834b6dd3caSJerry Han 	{ 0xC9, 0x00 },
7844b6dd3caSJerry Han 	{ 0xCA, 0x00 },
7854b6dd3caSJerry Han 	{ 0xCB, 0x16 },
7864b6dd3caSJerry Han 	{ 0xCC, 0xAF },
7874b6dd3caSJerry Han 	{ 0xCD, 0xFF },
7884b6dd3caSJerry Han 	{ 0xCE, 0xFF },
7894b6dd3caSJerry Han 	{ 0xB0, 0x0C },
7904b6dd3caSJerry Han 	{ 0xB1, 0x04 },
7914b6dd3caSJerry Han 	{ 0xB2, 0x04 },
7924b6dd3caSJerry Han 	{ 0xB3, 0x0F },
7934b6dd3caSJerry Han 	{ 0xB4, 0x22 },
7944b6dd3caSJerry Han 	{ 0xB5, 0x37 },
7954b6dd3caSJerry Han 	{ 0xB6, 0x4D },
7964b6dd3caSJerry Han 	{ 0xB7, 0x71 },
7974b6dd3caSJerry Han 	{ 0xB8, 0xA2 },
7984b6dd3caSJerry Han 	{ 0xB9, 0xE1 },
7994b6dd3caSJerry Han 	{ 0xBA, 0x26 },
8004b6dd3caSJerry Han 	{ 0xBB, 0xA9 },
8014b6dd3caSJerry Han 	{ 0xBC, 0x2F },
8024b6dd3caSJerry Han 	{ 0xBD, 0x33 },
8034b6dd3caSJerry Han 	{ 0xBE, 0xAC },
8044b6dd3caSJerry Han 	{ 0xBF, 0x24 },
8054b6dd3caSJerry Han 	{ 0xC0, 0x5D },
8064b6dd3caSJerry Han 	{ 0xC1, 0x94 },
8074b6dd3caSJerry Han 	{ 0xC2, 0xAC },
8084b6dd3caSJerry Han 	{ 0xC3, 0xC5 },
8094b6dd3caSJerry Han 	{ 0xC4, 0xD1 },
8104b6dd3caSJerry Han 	{ 0xC5, 0xDC },
8114b6dd3caSJerry Han 	{ 0xC6, 0xE8 },
8124b6dd3caSJerry Han 	{ 0xC7, 0xED },
8134b6dd3caSJerry Han 	{ 0xC8, 0xF0 },
8144b6dd3caSJerry Han 	{ 0xC9, 0x00 },
8154b6dd3caSJerry Han 	{ 0xCA, 0x00 },
8164b6dd3caSJerry Han 	{ 0xCB, 0x16 },
8174b6dd3caSJerry Han 	{ 0xCC, 0xAF },
8184b6dd3caSJerry Han 	{ 0xCD, 0xFF },
8194b6dd3caSJerry Han 	{ 0xCE, 0xFF },
8204b6dd3caSJerry Han };
8214b6dd3caSJerry Han 
8224b6dd3caSJerry Han static const struct panel_desc boe_himax8279d10p_panel_desc = {
8234b6dd3caSJerry Han 	.display_mode = &default_display_mode,
8244b6dd3caSJerry Han 	.bpc = 8,
8254b6dd3caSJerry Han 	.width_mm = 135,
8264b6dd3caSJerry Han 	.height_mm = 216,
8274b6dd3caSJerry Han 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
8284b6dd3caSJerry Han 			MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM,
8294b6dd3caSJerry Han 	.format = MIPI_DSI_FMT_RGB888,
8304b6dd3caSJerry Han 	.lanes = 4,
8314b6dd3caSJerry Han 	.on_cmds = boe_himax8279d10p_on_cmds,
8324b6dd3caSJerry Han 	.on_cmds_num = 283,
8334b6dd3caSJerry Han };
8344b6dd3caSJerry Han 
8354b6dd3caSJerry Han static const struct of_device_id panel_of_match[] = {
8364b6dd3caSJerry Han 	{
8374b6dd3caSJerry Han 		.compatible = "boe,himax8279d8p",
8384b6dd3caSJerry Han 		.data = &boe_himax8279d8p_panel_desc,
8394b6dd3caSJerry Han 	},
8404b6dd3caSJerry Han 	{
8414b6dd3caSJerry Han 		.compatible = "boe,himax8279d10p",
8424b6dd3caSJerry Han 		.data = &boe_himax8279d10p_panel_desc,
8434b6dd3caSJerry Han 	},
8444b6dd3caSJerry Han 	{
8454b6dd3caSJerry Han 		/* sentinel */
8464b6dd3caSJerry Han 	}
8474b6dd3caSJerry Han };
8484b6dd3caSJerry Han MODULE_DEVICE_TABLE(of, panel_of_match);
8494b6dd3caSJerry Han 
panel_add(struct panel_info * pinfo)8504b6dd3caSJerry Han static int panel_add(struct panel_info *pinfo)
8514b6dd3caSJerry Han {
8524b6dd3caSJerry Han 	struct device *dev = &pinfo->link->dev;
8534b6dd3caSJerry Han 	int ret;
8544b6dd3caSJerry Han 
8554b6dd3caSJerry Han 	pinfo->pp18_gpio = devm_gpiod_get(dev, "pp18", GPIOD_OUT_HIGH);
8564b6dd3caSJerry Han 	if (IS_ERR(pinfo->pp18_gpio)) {
8574b6dd3caSJerry Han 		ret = PTR_ERR(pinfo->pp18_gpio);
8584b6dd3caSJerry Han 		if (ret != -EPROBE_DEFER)
859a25b6b27SSam Ravnborg 			dev_err(dev, "failed to get pp18 gpio: %d\n", ret);
8604b6dd3caSJerry Han 		return ret;
8614b6dd3caSJerry Han 	}
8624b6dd3caSJerry Han 
8634b6dd3caSJerry Han 	pinfo->pp33_gpio = devm_gpiod_get(dev, "pp33", GPIOD_OUT_HIGH);
8644b6dd3caSJerry Han 	if (IS_ERR(pinfo->pp33_gpio)) {
8654b6dd3caSJerry Han 		ret = PTR_ERR(pinfo->pp33_gpio);
8664b6dd3caSJerry Han 		if (ret != -EPROBE_DEFER)
867a25b6b27SSam Ravnborg 			dev_err(dev, "failed to get pp33 gpio: %d\n", ret);
8684b6dd3caSJerry Han 		return ret;
8694b6dd3caSJerry Han 	}
8704b6dd3caSJerry Han 
8714b6dd3caSJerry Han 	pinfo->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
8724b6dd3caSJerry Han 	if (IS_ERR(pinfo->enable_gpio)) {
8734b6dd3caSJerry Han 		ret = PTR_ERR(pinfo->enable_gpio);
8744b6dd3caSJerry Han 		if (ret != -EPROBE_DEFER)
875a25b6b27SSam Ravnborg 			dev_err(dev, "failed to get enable gpio: %d\n", ret);
8764b6dd3caSJerry Han 		return ret;
8774b6dd3caSJerry Han 	}
8784b6dd3caSJerry Han 
8794b6dd3caSJerry Han 	drm_panel_init(&pinfo->base, dev, &panel_funcs,
8804b6dd3caSJerry Han 		       DRM_MODE_CONNECTOR_DSI);
8814b6dd3caSJerry Han 
8824b6dd3caSJerry Han 	ret = drm_panel_of_backlight(&pinfo->base);
8834b6dd3caSJerry Han 	if (ret)
8844b6dd3caSJerry Han 		return ret;
8854b6dd3caSJerry Han 
886c3ee8c65SBernard Zhao 	drm_panel_add(&pinfo->base);
887c3ee8c65SBernard Zhao 
888c3ee8c65SBernard Zhao 	return 0;
8894b6dd3caSJerry Han }
8904b6dd3caSJerry Han 
panel_probe(struct mipi_dsi_device * dsi)8914b6dd3caSJerry Han static int panel_probe(struct mipi_dsi_device *dsi)
8924b6dd3caSJerry Han {
8934b6dd3caSJerry Han 	struct panel_info *pinfo;
8944b6dd3caSJerry Han 	const struct panel_desc *desc;
8954b6dd3caSJerry Han 	int err;
8964b6dd3caSJerry Han 
8974b6dd3caSJerry Han 	pinfo = devm_kzalloc(&dsi->dev, sizeof(*pinfo), GFP_KERNEL);
8984b6dd3caSJerry Han 	if (!pinfo)
8994b6dd3caSJerry Han 		return -ENOMEM;
9004b6dd3caSJerry Han 
9014b6dd3caSJerry Han 	desc = of_device_get_match_data(&dsi->dev);
9024b6dd3caSJerry Han 	dsi->mode_flags = desc->mode_flags;
9034b6dd3caSJerry Han 	dsi->format = desc->format;
9044b6dd3caSJerry Han 	dsi->lanes = desc->lanes;
9054b6dd3caSJerry Han 	pinfo->desc = desc;
9064b6dd3caSJerry Han 
9074b6dd3caSJerry Han 	pinfo->link = dsi;
9084b6dd3caSJerry Han 	mipi_dsi_set_drvdata(dsi, pinfo);
9094b6dd3caSJerry Han 
9104b6dd3caSJerry Han 	err = panel_add(pinfo);
9114b6dd3caSJerry Han 	if (err < 0)
9124b6dd3caSJerry Han 		return err;
9134b6dd3caSJerry Han 
9144b6dd3caSJerry Han 	err = mipi_dsi_attach(dsi);
9154b6dd3caSJerry Han 	if (err < 0)
9164b6dd3caSJerry Han 		drm_panel_remove(&pinfo->base);
9174b6dd3caSJerry Han 
9184b6dd3caSJerry Han 	return err;
9194b6dd3caSJerry Han }
9204b6dd3caSJerry Han 
panel_remove(struct mipi_dsi_device * dsi)921*79abca2bSUwe Kleine-König static void panel_remove(struct mipi_dsi_device *dsi)
9224b6dd3caSJerry Han {
9234b6dd3caSJerry Han 	struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi);
9244b6dd3caSJerry Han 	int err;
9254b6dd3caSJerry Han 
9264b6dd3caSJerry Han 	err = boe_panel_disable(&pinfo->base);
9274b6dd3caSJerry Han 	if (err < 0)
928a25b6b27SSam Ravnborg 		dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
9294b6dd3caSJerry Han 
9304b6dd3caSJerry Han 	err = boe_panel_unprepare(&pinfo->base);
9314b6dd3caSJerry Han 	if (err < 0)
932a25b6b27SSam Ravnborg 		dev_err(&dsi->dev, "failed to unprepare panel: %d\n", err);
9334b6dd3caSJerry Han 
9344b6dd3caSJerry Han 	err = mipi_dsi_detach(dsi);
9354b6dd3caSJerry Han 	if (err < 0)
936a25b6b27SSam Ravnborg 		dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
9374b6dd3caSJerry Han 
9384b6dd3caSJerry Han 	drm_panel_remove(&pinfo->base);
9394b6dd3caSJerry Han }
9404b6dd3caSJerry Han 
panel_shutdown(struct mipi_dsi_device * dsi)9414b6dd3caSJerry Han static void panel_shutdown(struct mipi_dsi_device *dsi)
9424b6dd3caSJerry Han {
9434b6dd3caSJerry Han 	struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi);
9444b6dd3caSJerry Han 
9454b6dd3caSJerry Han 	boe_panel_disable(&pinfo->base);
9464b6dd3caSJerry Han 	boe_panel_unprepare(&pinfo->base);
9474b6dd3caSJerry Han }
9484b6dd3caSJerry Han 
9494b6dd3caSJerry Han static struct mipi_dsi_driver panel_driver = {
9504b6dd3caSJerry Han 	.driver = {
9514b6dd3caSJerry Han 		.name = "panel-boe-himax8279d",
9524b6dd3caSJerry Han 		.of_match_table = panel_of_match,
9534b6dd3caSJerry Han 	},
9544b6dd3caSJerry Han 	.probe = panel_probe,
9554b6dd3caSJerry Han 	.remove = panel_remove,
9564b6dd3caSJerry Han 	.shutdown = panel_shutdown,
9574b6dd3caSJerry Han };
9584b6dd3caSJerry Han module_mipi_dsi_driver(panel_driver);
9594b6dd3caSJerry Han 
9604b6dd3caSJerry Han MODULE_AUTHOR("Jerry Han <jerry.han.hq@gmail.com>");
9614b6dd3caSJerry Han MODULE_DESCRIPTION("Boe Himax8279d driver");
9624b6dd3caSJerry Han MODULE_LICENSE("GPL v2");
963