1 // SPDX-License-Identifier: GPL-2.0+
3 * Renesas R61307 panel driver
5 * Copyright (c) 2022 Svyatoslav Ryhel <clamor95@gmail.com>
14 #include <mipi_display.h>
17 #include <linux/delay.h>
18 #include <linux/err.h>
19 #include <power/regulator.h>
22 * The datasheet is not publicly available, all values are
23 * taken from the downstream. If you have access to datasheets,
24 * corrections are welcome.
27 #define R61307_MACP 0xB0 /* Manufacturer CMD Protect */
29 #define R61307_INVERSION 0xC1
30 #define R61307_GAMMA_SET_A 0xC8 /* Gamma Setting A */
31 #define R61307_GAMMA_SET_B 0xC9 /* Gamma Setting B */
32 #define R61307_GAMMA_SET_C 0xCA /* Gamma Setting C */
33 #define R61307_CONTRAST_SET 0xCC
35 struct renesas_r61307_priv {
37 struct udevice *iovcc;
39 struct udevice *backlight;
41 struct gpio_desc reset_gpio;
48 static const u8 macp_on[] = {
52 static const u8 macp_off[] = {
56 static const u8 address_mode[] = {
57 MIPI_DCS_SET_ADDRESS_MODE
60 static const u8 contrast_setting[] = {
65 static const u8 column_inversion[] = {
67 0x00, 0x50, 0x03, 0x22,
68 0x16, 0x06, 0x60, 0x11
71 static const u8 line_inversion[] = {
73 0x00, 0x10, 0x03, 0x22,
74 0x16, 0x06, 0x60, 0x01
77 static const u8 gamma_setting[][25] = {
81 0x00, 0x06, 0x0a, 0x0f,
82 0x14, 0x1f, 0x1f, 0x17,
83 0x12, 0x0c, 0x09, 0x06,
84 0x00, 0x06, 0x0a, 0x0f,
85 0x14, 0x1f, 0x1f, 0x17,
86 0x12, 0x0c, 0x09, 0x06
90 0x00, 0x05, 0x0b, 0x0f,
91 0x11, 0x1d, 0x20, 0x18,
92 0x18, 0x09, 0x07, 0x06,
93 0x00, 0x05, 0x0b, 0x0f,
94 0x11, 0x1d, 0x20, 0x18,
95 0x18, 0x09, 0x07, 0x06
99 0x0b, 0x0d, 0x10, 0x14,
100 0x13, 0x1d, 0x20, 0x18,
101 0x12, 0x09, 0x07, 0x06,
102 0x0a, 0x0c, 0x10, 0x14,
103 0x13, 0x1d, 0x20, 0x18,
104 0x12, 0x09, 0x07, 0x06
108 static struct display_timing default_timing = {
109 .pixelclock.typ = 62000000,
111 .hfront_porch.typ = 116,
112 .hback_porch.typ = 81,
115 .vfront_porch.typ = 24,
116 .vback_porch.typ = 8,
120 static int renesas_r61307_enable_backlight(struct udevice *dev)
122 struct renesas_r61307_priv *priv = dev_get_priv(dev);
125 ret = regulator_set_enable_if_allowed(priv->vcc, 1);
127 log_err("enabling vcc-supply failed (%d)\n", ret);
132 ret = regulator_set_enable_if_allowed(priv->iovcc, 1);
134 log_err("enabling iovcc-supply failed (%d)\n", ret);
138 ret = dm_gpio_set_value(&priv->reset_gpio, 0);
140 log_err("changing reset-gpio failed (%d)\n", ret);
145 ret = dm_gpio_set_value(&priv->reset_gpio, 1);
147 log_err("changing reset-gpio failed (%d)\n", ret);
156 static int renesas_r61307_set_backlight(struct udevice *dev, int percent)
158 struct renesas_r61307_priv *priv = dev_get_priv(dev);
159 struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
160 struct mipi_dsi_device *dsi = plat->device;
163 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
165 log_err("failed to exit sleep mode: %d\n", ret);
171 mipi_dsi_dcs_write_buffer(dsi, address_mode,
172 sizeof(address_mode));
176 ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT << 4);
178 log_err("failed to set pixel format: %d\n", ret);
183 mipi_dsi_generic_write(dsi, macp_off, sizeof(macp_off));
185 if (priv->dig_cont_adj)
186 mipi_dsi_generic_write(dsi, contrast_setting,
187 sizeof(contrast_setting));
190 mipi_dsi_generic_write(dsi, gamma_setting[priv->gamma],
191 sizeof(gamma_setting[priv->gamma]));
194 mipi_dsi_generic_write(dsi, column_inversion,
195 sizeof(column_inversion));
197 mipi_dsi_generic_write(dsi, line_inversion,
198 sizeof(line_inversion));
201 mipi_dsi_generic_write(dsi, macp_on, sizeof(macp_on));
203 ret = mipi_dsi_dcs_set_display_on(dsi);
205 log_err("failed to set display on: %d\n", ret);
211 ret = backlight_enable(priv->backlight);
215 ret = backlight_set_brightness(priv->backlight, percent);
222 static int renesas_r61307_timings(struct udevice *dev,
223 struct display_timing *timing)
225 memcpy(timing, &default_timing, sizeof(*timing));
229 static int renesas_r61307_of_to_plat(struct udevice *dev)
231 struct renesas_r61307_priv *priv = dev_get_priv(dev);
234 ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
235 "backlight", &priv->backlight);
237 log_err("Cannot get backlight: ret = %d\n", ret);
241 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
242 "vcc-supply", &priv->vcc);
244 log_err("Cannot get vcc-supply: ret = %d\n", ret);
248 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
249 "iovcc-supply", &priv->iovcc);
251 log_err("Cannot get iovcc-supply: ret = %d\n", ret);
255 ret = gpio_request_by_name(dev, "reset-gpios", 0,
256 &priv->reset_gpio, GPIOD_IS_OUT);
258 log_err("Could not decode reser-gpios (%d)\n", ret);
262 priv->dig_cont_adj = dev_read_bool(dev, "renesas,contrast");
263 priv->inversion = dev_read_bool(dev, "renesas,inversion");
264 priv->gamma = dev_read_u32_default(dev, "renesas,gamma", 0);
269 static int renesas_r61307_probe(struct udevice *dev)
271 struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
273 /* fill characteristics of DSI data link */
275 plat->format = MIPI_DSI_FMT_RGB888;
276 plat->mode_flags = MIPI_DSI_MODE_VIDEO;
281 static const struct panel_ops renesas_r61307_ops = {
282 .enable_backlight = renesas_r61307_enable_backlight,
283 .set_backlight = renesas_r61307_set_backlight,
284 .get_display_timing = renesas_r61307_timings,
287 static const struct udevice_id renesas_r61307_ids[] = {
288 { .compatible = "koe,tx13d100vm0eaa" },
289 { .compatible = "hitachi,tx13d100vm0eaa" },
293 U_BOOT_DRIVER(renesas_r61307) = {
294 .name = "renesas_r61307",
296 .of_match = renesas_r61307_ids,
297 .ops = &renesas_r61307_ops,
298 .of_to_plat = renesas_r61307_of_to_plat,
299 .probe = renesas_r61307_probe,
300 .plat_auto = sizeof(struct mipi_dsi_panel_plat),
301 .priv_auto = sizeof(struct renesas_r61307_priv),