Le mer. 26 août 2026 à 23:22, David Lechner <[email protected]> a écrit : > > Add a driver for the Startek KD070FHFID078 7" DSI panel. This panel is > used on the MediaTek Genio 360 EVK board. > > The display mode and DSI mode flags follow the upstream Linux driver > panel-himax-hx8279.c, which is what the "himax,hx8279" fallback > compatible in the device tree binds to. > > Signed-off-by: David Lechner <[email protected]> > --- > Add a driver for the Startek KD070FHFID078 7" DSI panel. > > This depends on the mipi_dsi {generic,dcs}_write_seq helper macros series > for mipi_dsi_generic_write_seq(). > > Note: no defconfig enables this driver yet, since there is no MediaTek DSI > host driver in U-Boot at this point. It will be enabled together with the > display pipeline support. > --- > Changes in v2: > - Added missing BACKLIGHT and DM_REGULATOR Kconfig dependencies. > - Use the display mode and MIPI_DSI_CLOCK_NON_CONTINUOUS flag from the > upstream Linux panel-himax-hx8279.c driver instead of the MediaTek > downstream driver. > - enable-gpios is now optional, matching the binding. > - A missing backlight is now an error instead of a warning. > - Do not request reset/enable GPIOs as active, so they are not asserted > before the regulators are enabled. > - Use mipi_dsi_dcs_exit_sleep_mode()/mipi_dsi_dcs_set_display_on() instead > of raw DCS opcodes and check their return values. > - Dropped stale InforceComputing/Linaro copyright and author lines. > - Dropped the unused dev field and the unreachable mode check. > - Link to v1: > https://patch.msgid.link/20260814-mtk-video-panel-startek-078-v1-1-5f84a5724...@baylibre.com > --- > MAINTAINERS | 6 + > drivers/video/Kconfig | 10 + > drivers/video/Makefile | 1 + > drivers/video/panel-startek-kd070fhfid078.c | 283 > ++++++++++++++++++++++++++++ > 4 files changed, 300 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index fabcb8b2968..b3bf5b1f8c7 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1723,6 +1723,12 @@ R: GSS_MTK_Uboot_upstream > <[email protected]> > S: Maintained > F: drivers/video/panel-startek-kd070fhfid015.c > > +STARTEK KD070FHFID078 PANEL > +M: David Lechner <[email protected]> > +R: GSS_MTK_Uboot_upstream <[email protected]> > +S: Maintained > +F: drivers/video/panel-startek-kd070fhfid078.c > + > TARGET_BCMNS3 > M: Rayagonda Kokatanur <[email protected]> > S: Maintained > diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig > index 37ab17f0ab2..495e4382a22 100644 > --- a/drivers/video/Kconfig > +++ b/drivers/video/Kconfig > @@ -330,6 +330,16 @@ config PANEL_STARTEK_KD070FHFID015 > 1200 x 1920 pixels. It provides a MIPI DSI interface to the host, a > built-in LED backlight and touch controller. > > +config PANEL_STARTEK_KD070FHFID078 > + bool "STARTEK KD070FHFID078 panel" > + depends on PANEL && BACKLIGHT && DM_GPIO && DM_REGULATOR > + select VIDEO_MIPI_DSI > + help > + Say Y here if you want to enable support for STARTEK KD070FHFID078 > DSI panel. > + The panel is a 7-inch TFT LCD display with a resolution of 1200 x > 1920 > + pixels. It provides a MIPI DSI interface to the host, a built-in LED > + backlight and touch controller.
This looks like a copy/paste from PANEL_STARTEK_KD070FHFID015. The built-in LED backlight is wrong for this panel. drop it. > + > config VIDEO_BOCHS > bool "Enable Bochs video emulation for QEMU" > help > diff --git a/drivers/video/Makefile b/drivers/video/Makefile > index 7a54f1f290d..7a7b54e6b53 100644 > --- a/drivers/video/Makefile > +++ b/drivers/video/Makefile > @@ -23,6 +23,7 @@ obj-$(CONFIG_$(PHASE_)VIDEO) += video_bmp.o > obj-$(CONFIG_$(PHASE_)PANEL) += panel-uclass.o > obj-$(CONFIG_PANEL_HX8238D) += hx8238d.o > obj-$(CONFIG_PANEL_STARTEK_KD070FHFID015) += panel-startek-kd070fhfid015.o > +obj-$(CONFIG_PANEL_STARTEK_KD070FHFID078) += panel-startek-kd070fhfid078.o > obj-$(CONFIG_$(PHASE_)SIMPLE_PANEL) += simple_panel.o > > obj-$(CONFIG_VIDEO_LOGO) += u_boot_logo.bmp.o > diff --git a/drivers/video/panel-startek-kd070fhfid078.c > b/drivers/video/panel-startek-kd070fhfid078.c > new file mode 100644 > index 00000000000..dd5cac46267 > --- /dev/null > +++ b/drivers/video/panel-startek-kd070fhfid078.c > @@ -0,0 +1,283 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) 2025 MediaTek Inc. > + * Copyright (C) 2026 BayLibre, SAS > + * > + * Authors: > + * - Guillaume La Roque <[email protected]> > + * - Jitao Shi <[email protected]> > + * - David Lechner <[email protected]> > + */ > + > +#include <asm-generic/gpio.h> > +#include <backlight.h> > +#include <dm.h> > +#include <dm/device_compat.h> > +#include <errno.h> > +#include <linux/delay.h> > +#include <mipi_dsi.h> > +#include <panel.h> > +#include <power/regulator.h> > + > +struct stk078_panel { > + struct gpio_desc *enable_gpio; > + struct gpio_desc *reset_gpio; > + struct mipi_dsi_device *dsi; > + struct udevice *iovcc; > + struct udevice *vdd; > + struct udevice *backlight; > +}; > + > +static const struct drm_display_mode default_mode = { > + .clock = 156458, > + .hdisplay = 1200, > + .hsync_start = 1200 + 50, > + .hsync_end = 1200 + 50 + 24, > + .htotal = 1200 + 50 + 24 + 66, > + .vdisplay = 1920, > + .vsync_start = 1920 + 14, > + .vsync_end = 1920 + 14 + 2, > + .vtotal = 1920 + 14 + 2 + 10, > +}; > + > +static int stk078_panel_init(struct stk078_panel *stk) > +{ > + struct mipi_dsi_device *dsi = stk->dsi; > + int ret; > + > + mipi_dsi_generic_write_seq(dsi, 0xB0, 0x05); > + mipi_dsi_generic_write_seq(dsi, 0xB3, 0x52); > + mipi_dsi_generic_write_seq(dsi, 0xB8, 0x7F); > + mipi_dsi_generic_write_seq(dsi, 0xBC, 0x20); > + mipi_dsi_generic_write_seq(dsi, 0xD6, 0x7F); > + mipi_dsi_generic_write_seq(dsi, 0xB0, 0x01); > + mipi_dsi_generic_write_seq(dsi, 0xC0, 0x0D); > + mipi_dsi_generic_write_seq(dsi, 0xC1, 0x0D); > + mipi_dsi_generic_write_seq(dsi, 0xC2, 0x06); > + mipi_dsi_generic_write_seq(dsi, 0xC3, 0x06); > + mipi_dsi_generic_write_seq(dsi, 0xC4, 0x08); > + mipi_dsi_generic_write_seq(dsi, 0xC5, 0x08); > + mipi_dsi_generic_write_seq(dsi, 0xC6, 0x0A); > + mipi_dsi_generic_write_seq(dsi, 0xC7, 0x0A); > + mipi_dsi_generic_write_seq(dsi, 0xC8, 0x0C); > + mipi_dsi_generic_write_seq(dsi, 0xC9, 0x0C); > + mipi_dsi_generic_write_seq(dsi, 0xCA, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xCB, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xCC, 0x0E); > + mipi_dsi_generic_write_seq(dsi, 0xCD, 0x0E); > + mipi_dsi_generic_write_seq(dsi, 0xCE, 0x01); > + mipi_dsi_generic_write_seq(dsi, 0xCF, 0x01); > + mipi_dsi_generic_write_seq(dsi, 0xD0, 0x04); > + mipi_dsi_generic_write_seq(dsi, 0xD1, 0x04); > + mipi_dsi_generic_write_seq(dsi, 0xD2, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xD3, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xD4, 0x0D); > + mipi_dsi_generic_write_seq(dsi, 0xD5, 0x0D); > + mipi_dsi_generic_write_seq(dsi, 0xD6, 0x05); > + mipi_dsi_generic_write_seq(dsi, 0xD7, 0x05); > + mipi_dsi_generic_write_seq(dsi, 0xD8, 0x07); > + mipi_dsi_generic_write_seq(dsi, 0xD9, 0x07); > + mipi_dsi_generic_write_seq(dsi, 0xDA, 0x09); > + mipi_dsi_generic_write_seq(dsi, 0xDB, 0x09); > + mipi_dsi_generic_write_seq(dsi, 0xDC, 0x0B); > + mipi_dsi_generic_write_seq(dsi, 0xDD, 0x0B); > + mipi_dsi_generic_write_seq(dsi, 0xDE, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xDF, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xE0, 0x0E); > + mipi_dsi_generic_write_seq(dsi, 0xE1, 0x0E); > + mipi_dsi_generic_write_seq(dsi, 0xE2, 0x01); > + mipi_dsi_generic_write_seq(dsi, 0xE3, 0x01); > + mipi_dsi_generic_write_seq(dsi, 0xE4, 0x03); > + mipi_dsi_generic_write_seq(dsi, 0xE5, 0x03); > + mipi_dsi_generic_write_seq(dsi, 0xE6, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xE7, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xB0, 0x03); > + mipi_dsi_generic_write_seq(dsi, 0xBA, 0xF0); > + mipi_dsi_generic_write_seq(dsi, 0xC8, 0x07); > + mipi_dsi_generic_write_seq(dsi, 0xC9, 0x03); > + mipi_dsi_generic_write_seq(dsi, 0xCA, 0x41); > + mipi_dsi_generic_write_seq(dsi, 0xD2, 0x01); > + mipi_dsi_generic_write_seq(dsi, 0xD3, 0x05); > + mipi_dsi_generic_write_seq(dsi, 0xD4, 0x05); > + mipi_dsi_generic_write_seq(dsi, 0xD5, 0x8A); > + mipi_dsi_generic_write_seq(dsi, 0xE4, 0xC0); > + mipi_dsi_generic_write_seq(dsi, 0xE5, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xB0, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xBF, 0x1F); > + mipi_dsi_generic_write_seq(dsi, 0xC0, 0x12); > + mipi_dsi_generic_write_seq(dsi, 0xC2, 0x1E); > + mipi_dsi_generic_write_seq(dsi, 0xC4, 0x1E); > + mipi_dsi_generic_write_seq(dsi, 0xB0, 0x06); > + mipi_dsi_generic_write_seq(dsi, 0xB8, 0xA5); > + mipi_dsi_generic_write_seq(dsi, 0xC0, 0xA5); > + mipi_dsi_generic_write_seq(dsi, 0xBC, 0x11); > + mipi_dsi_generic_write_seq(dsi, 0xD5, 0x48); > + mipi_dsi_generic_write_seq(dsi, 0xB8, 0x00); > + mipi_dsi_generic_write_seq(dsi, 0xC0, 0x00); > + > + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); > + if (ret < 0) > + return ret; > + > + mdelay(120); > + > + ret = mipi_dsi_dcs_set_display_on(dsi); > + if (ret < 0) > + return ret; > + > + mdelay(20); > + > + return 0; > +} > + > +static int stk078_panel_enable_backlight(struct udevice *dev) > +{ > + struct stk078_panel *stk = dev_get_priv(dev); > + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); > + struct mipi_dsi_device *dsi = plat->device; > + int ret; > + > + stk->dsi = dsi; > + ret = mipi_dsi_attach(dsi); > + if (ret < 0) { > + dev_err(dev, "mipi_dsi_attach failed: %d\n", ret); > + return ret; > + } > + > + dm_gpio_set_value(stk->reset_gpio, 0); > + if (stk->enable_gpio) > + dm_gpio_set_value(stk->enable_gpio, 0); > + mdelay(10); > + > + ret = regulator_enable(stk->vdd); > + if (ret < 0) { > + dev_err(dev, "enable vdd failed: %d\n", ret); > + goto out_gpio; > + } > + > + ret = regulator_enable(stk->iovcc); > + if (ret < 0) { > + dev_err(dev, "enable iovcc failed: %d\n", ret); > + goto out_vdd; > + } > + > + mdelay(15); > + if (stk->enable_gpio) > + dm_gpio_set_value(stk->enable_gpio, 1); > + mdelay(10); > + dm_gpio_set_value(stk->reset_gpio, 1); > + mdelay(140); > + > + ret = stk078_panel_init(stk); > + if (ret < 0) { > + dev_err(dev, "panel init sequence failed: %d\n", ret); > + goto out_power; > + } > + > + ret = backlight_enable(stk->backlight); > + if (ret < 0) { > + dev_err(dev, "enable backlight failed: %d\n", ret); > + goto out_power; > + } > + > + return 0; > + > +out_power: > + regulator_disable(stk->iovcc); > +out_vdd: > + regulator_disable(stk->vdd); > +out_gpio: > + dm_gpio_set_value(stk->reset_gpio, 0); > + if (stk->enable_gpio) > + dm_gpio_set_value(stk->enable_gpio, 0); > + > + return ret; I think we are missing mipi_dsi_detach() call at the end > +} > + > +static int stk078_panel_add(struct udevice *dev) > +{ > + struct stk078_panel *stk = dev_get_priv(dev); > + int ret; > + > + ret = device_get_supply_regulator(dev, "iovcc-supply", &stk->iovcc); > + if (ret) { > + dev_err(dev, "Failed to get iovcc regulator: %d\n", ret); > + return ret; > + } > + > + ret = device_get_supply_regulator(dev, "vdd-supply", &stk->vdd); > + if (ret) { > + dev_err(dev, "Failed to get vdd regulator: %d\n", ret); > + return ret; > + } > + > + stk->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_IS_OUT); > + if (IS_ERR(stk->reset_gpio)) { > + ret = PTR_ERR(stk->reset_gpio); > + dev_err(dev, "cannot get reset-gpios %d\n", ret); > + return ret; > + } > + > + stk->enable_gpio = devm_gpiod_get_optional(dev, "enable", > GPIOD_IS_OUT); > + if (IS_ERR(stk->enable_gpio)) { > + ret = PTR_ERR(stk->enable_gpio); > + dev_err(dev, "cannot get enable-gpios %d\n", ret); > + return ret; > + } > + > + ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, > + "backlight", &stk->backlight); > + if (ret) { > + dev_err(dev, "failed to get backlight: %d\n", ret); > + return ret; > + } > + > + return 0; > +} > + > +static int stk078_panel_probe(struct udevice *dev) > +{ > + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); > + int ret; > + > + plat->lanes = 4; > + plat->format = MIPI_DSI_FMT_RGB888; > + plat->mode_flags = MIPI_DSI_MODE_VIDEO | > + MIPI_DSI_MODE_VIDEO_SYNC_PULSE | > + MIPI_DSI_MODE_LPM | > + MIPI_DSI_CLOCK_NON_CONTINUOUS; > + > + ret = stk078_panel_add(dev); > + if (ret < 0) > + return ret; > + > + return 0; can be simplified: return stk078_panel_add(dev); > +} > + > +static int stk078_panel_get_modes(struct udevice *dev, > + const struct drm_display_mode **modes) > +{ > + *modes = &default_mode; > + > + return 1; > +} > + > +static const struct panel_ops stk078_panel_ops = { > + .enable_backlight = stk078_panel_enable_backlight, > + .get_modes = stk078_panel_get_modes, > +}; > + > +static const struct udevice_id stk078_of_match[] = { > + { .compatible = "startek,kd070fhfid078" }, > + { } > +}; > + > +U_BOOT_DRIVER(stk078_panel_driver) = { > + .name = "panel-startek-kd070fhfid078", > + .id = UCLASS_PANEL, > + .of_match = stk078_of_match, > + .ops = &stk078_panel_ops, > + .probe = stk078_panel_probe, > + .plat_auto = sizeof(struct mipi_dsi_panel_plat), > + .priv_auto = sizeof(struct stk078_panel), > +}; > > --- > base-commit: f252d228be2b2d180737ad0a851f91749273cbd9 > change-id: 20260814-mtk-video-panel-startek-078-1a9ab38e89f7 > prerequisite-message-id: > <20260806-add_mipi_dsi_write_seq_helper_macros-v1-0-6b533788d...@baylibre.com> > prerequisite-patch-id: cf35ac4802976971af68bd0ce1dc0ab872fdb661 > prerequisite-patch-id: 9f6aca2bfde84a5d84329b77b3b9af8898b18e4a > prerequisite-patch-id: e7bb7ee54b88b6d6e00f74fe84b1c81d00957051 > prerequisite-patch-id: d4a530120b1a93d68e4b17c6e1fcf2878e784454 > prerequisite-patch-id: 18b1bbeab6808decceaf5117b3e999baf4495e1d > prerequisite-patch-id: d50e7e28a399c303226ff08c78e60749930a7243 > > Best regards, > -- > David Lechner <[email protected]> >
