diff options
Diffstat (limited to 'drivers/gpu/drm/panel')
98 files changed, 2246 insertions, 602 deletions
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index cfebb08e8a62..09b9f7ff9340 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -193,6 +193,16 @@ config DRM_PANEL_HIMAX_HX83112A Say Y here if you want to enable support for Himax HX83112A-based display panels, such as the one found in the Fairphone 4 smartphone. +config DRM_PANEL_HIMAX_HX83112B + tristate "Himax HX83112B-based DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select DRM_KMS_HELPER + help + Say Y here if you want to enable support for Himax HX83112B-based + display panels, such as the one found in the Fairphone 3 smartphone. + config DRM_PANEL_HIMAX_HX8394 tristate "HIMAX HX8394 MIPI-DSI LCD panels" depends on OF @@ -647,6 +657,32 @@ config DRM_PANEL_RAYDIUM_RM69380 This panel controller can be found in the Lenovo Xiaoxin Pad Pro 2021 in combination with an EDO OLED panel. +config DRM_PANEL_RENESAS_R61307 + tristate "Renesas R61307 DSI video mode panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for KOE tx13d100vm0eaa + IPS-LCD module with Renesas R69328 IC. The panel has a 1024x768 + resolution and uses 24 bit RGB per pixel. + + This panel controller can be found in LG Optimus Vu P895 smartphone + in combination with LCD panel. + +config DRM_PANEL_RENESAS_R69328 + tristate "Renesas R69328 720x1280 DSI video mode panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI dx12d100vm0eaa + IPS-LCD module with Renesas R69328 IC. The panel has a 720x1280 + resolution and uses 24 bit RGB per pixel. + + This panel controller can be found in LG Optimus 4X P895 smartphone + in combination with LCD panel. + config DRM_PANEL_RONBO_RB070D30 tristate "Ronbo Electronics RB070D30 panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 714cbac830e3..957555b49996 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d obj-$(CONFIG_DRM_PANEL_HIMAX_HX8279) += panel-himax-hx8279.o obj-$(CONFIG_DRM_PANEL_HIMAX_HX83102) += panel-himax-hx83102.o obj-$(CONFIG_DRM_PANEL_HIMAX_HX83112A) += panel-himax-hx83112a.o +obj-$(CONFIG_DRM_PANEL_HIMAX_HX83112B) += panel-himax-hx83112b.o obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o @@ -65,6 +66,8 @@ obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67200) += panel-raydium-rm67200.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM69380) += panel-raydium-rm69380.o +obj-$(CONFIG_DRM_PANEL_RENESAS_R61307) += panel-renesas-r61307.o +obj-$(CONFIG_DRM_PANEL_RENESAS_R69328) += panel-renesas-r69328.o obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS581VF01) += panel-samsung-ams581vf01.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS639RQ08) += panel-samsung-ams639rq08.o diff --git a/drivers/gpu/drm/panel/panel-boe-himax8279d.c b/drivers/gpu/drm/panel/panel-boe-himax8279d.c index df746baae301..4a8560b4b899 100644 --- a/drivers/gpu/drm/panel/panel-boe-himax8279d.c +++ b/drivers/gpu/drm/panel/panel-boe-himax8279d.c @@ -847,9 +847,6 @@ static int panel_add(struct panel_info *pinfo) "failed to get enable gpio\n"); } - drm_panel_init(&pinfo->base, dev, &panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&pinfo->base); if (ret) return ret; @@ -865,9 +862,11 @@ static int panel_probe(struct mipi_dsi_device *dsi) const struct panel_desc *desc; int err; - pinfo = devm_kzalloc(&dsi->dev, sizeof(*pinfo), GFP_KERNEL); - if (!pinfo) - return -ENOMEM; + pinfo = devm_drm_panel_alloc(&dsi->dev, __typeof(*pinfo), base, + &panel_funcs, DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(pinfo)) + return PTR_ERR(pinfo); desc = of_device_get_match_data(&dsi->dev); dsi->mode_flags = desc->mode_flags; diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index 3e5b0d8636d0..d5fe105bdbdd 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -1720,8 +1720,6 @@ static int boe_panel_add(struct boe_panel *boe) boe->base.prepare_prev_first = true; - drm_panel_init(&boe->base, dev, &boe_panel_funcs, - DRM_MODE_CONNECTOR_DSI); err = of_drm_get_panel_orientation(dev->of_node, &boe->orientation); if (err < 0) { dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err); @@ -1746,9 +1744,11 @@ static int boe_panel_probe(struct mipi_dsi_device *dsi) int ret; const struct panel_desc *desc; - boe = devm_kzalloc(&dsi->dev, sizeof(*boe), GFP_KERNEL); - if (!boe) - return -ENOMEM; + boe = devm_drm_panel_alloc(&dsi->dev, __typeof(*boe), base, + &boe_panel_funcs, DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(boe)) + return PTR_ERR(boe); desc = of_device_get_match_data(&dsi->dev); dsi->lanes = desc->lanes; diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 90e8c154a978..9a56e208cbdd 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -113,7 +113,7 @@ struct panel_delay { * // do fixed enable delay * // enforce prepare_to_enable min time * - * This is not specified in a standard way on eDP timing diagrams. + * This is usually (T4+T5+T6+T8)-min on eDP timing diagrams. * It is effectively the time from HPD going high till you can * turn on the backlight. */ @@ -1869,6 +1869,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02.3"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x239b, &delay_200_500_e50, "B116XAN06.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x255c, &delay_200_500_e50, "B116XTN02.5"), + EDP_PANEL_ENTRY('A', 'U', 'O', 0x30ed, &delay_200_500_e50, "G156HAN03.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x403d, &delay_200_500_e50, "B140HAN04.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAN04.0"), EDP_PANEL_ENTRY2('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01.0", @@ -1923,6 +1924,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('B', 'O', 'E', 0x094b, &delay_200_500_e50, "NT116WHM-N21"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0951, &delay_200_500_e80, "NV116WHM-N47"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x095f, &delay_200_500_e50, "NE135FBM-N41 v8.1"), + EDP_PANEL_ENTRY('B', 'O', 'E', 0x0964, &delay_200_500_e50, "NV133WUM-N61"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x096e, &delay_200_500_e50_po2e200, "NV116WHM-T07 V8.0"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0979, &delay_200_500_e50, "NV116WHM-N49 V8.0"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x098d, &boe_nv110wtm_n61.delay, "NV110WTM-N61"), @@ -1937,6 +1939,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('B', 'O', 'E', 0x0ac5, &delay_200_500_e50, "NV116WHM-N4C"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0ae8, &delay_200_500_e50_p2e80, "NV140WUM-N41"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b09, &delay_200_500_e50_po2e200, "NV140FHM-NZ"), + EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b1e, &delay_200_500_e80, "NE140QDM-N6A"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b34, &delay_200_500_e80, "NV122WUM-N41"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b43, &delay_200_500_e200, "NV140FHM-T09"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b56, &delay_200_500_e80, "NT140FHM-N47"), @@ -1965,6 +1968,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('C', 'M', 'N', 0x115e, &delay_200_500_e80_d50, "N116BCA-EA1"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1160, &delay_200_500_e80_d50, "N116BCJ-EAK"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1161, &delay_200_500_e80, "N116BCP-EA2"), + EDP_PANEL_ENTRY('C', 'M', 'N', 0x1163, &delay_200_500_e80_d50, "N116BCJ-EAK"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1247, &delay_200_500_e80_d50, "N120ACA-EA1"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x142b, &delay_200_500_e80_d50, "N140HCA-EAC"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x142e, &delay_200_500_e80_d50, "N140BGA-EA4"), @@ -1973,6 +1977,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('C', 'M', 'N', 0x14d4, &delay_200_500_e80_d50, "N140HCA-EAC"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x14d6, &delay_200_500_e80_d50, "N140BGA-EA4"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x14e5, &delay_200_500_e80_d50, "N140HGA-EA1"), + EDP_PANEL_ENTRY('C', 'M', 'N', 0x162b, &delay_200_500_e80_d50, "N160JCE-ELL"), EDP_PANEL_ENTRY('C', 'S', 'O', 0x1200, &delay_200_500_e50_p2e200, "MNC207QS1-1"), EDP_PANEL_ENTRY('C', 'S', 'O', 0x1413, &delay_200_500_e50_p2e200, "MNE007JA1-2"), @@ -2005,6 +2010,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('K', 'D', 'C', 0x044f, &delay_200_500_e50, "KD116N9-30NH-F3"), EDP_PANEL_ENTRY('K', 'D', 'C', 0x05f1, &delay_200_500_e80_d50, "KD116N5-30NV-G7"), EDP_PANEL_ENTRY('K', 'D', 'C', 0x0809, &delay_200_500_e50, "KD116N2930A15"), + EDP_PANEL_ENTRY('K', 'D', 'C', 0x1220, &delay_200_500_e50, "KD116N3730A05"), EDP_PANEL_ENTRY('L', 'G', 'D', 0x0000, &delay_200_500_e200_d200, "Unknown"), EDP_PANEL_ENTRY('L', 'G', 'D', 0x048d, &delay_200_500_e200_d200, "Unknown"), diff --git a/drivers/gpu/drm/panel/panel-elida-kd35t133.c b/drivers/gpu/drm/panel/panel-elida-kd35t133.c index b904d5437444..1f177834d629 100644 --- a/drivers/gpu/drm/panel/panel-elida-kd35t133.c +++ b/drivers/gpu/drm/panel/panel-elida-kd35t133.c @@ -206,9 +206,10 @@ static int kd35t133_probe(struct mipi_dsi_device *dsi) struct kd35t133 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct kd35t133, panel, + &kd35t133_funcs, DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->reset_gpio)) { @@ -248,9 +249,6 @@ static int kd35t133_probe(struct mipi_dsi_device *dsi) MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, &dsi->dev, &kd35t133_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c b/drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c index 986e3e192881..6225501cb174 100644 --- a/drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c +++ b/drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c @@ -443,9 +443,11 @@ static int k101_im2ba02_dsi_probe(struct mipi_dsi_device *dsi) unsigned int i; int ret; - ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&dsi->dev, struct k101_im2ba02, panel, + &k101_im2ba02_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; @@ -463,9 +465,6 @@ static int k101_im2ba02_dsi_probe(struct mipi_dsi_device *dsi) return dev_err_probe(&dsi->dev, PTR_ERR(ctx->reset), "Couldn't get our reset GPIO\n"); - drm_panel_init(&ctx->panel, &dsi->dev, &k101_im2ba02_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c index 48e3acaecdf3..4f8d6d8c07e4 100644 --- a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c +++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c @@ -189,16 +189,14 @@ static int feiyang_dsi_probe(struct mipi_dsi_device *dsi) struct feiyang *ctx; int ret; - ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&dsi->dev, struct feiyang, panel, + &feiyang_funcs, DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; - drm_panel_init(&ctx->panel, &dsi->dev, &feiyang_funcs, - DRM_MODE_CONNECTOR_DSI); - ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd"); if (IS_ERR(ctx->dvdd)) return dev_err_probe(&dsi->dev, PTR_ERR(ctx->dvdd), diff --git a/drivers/gpu/drm/panel/panel-himax-hx83102.c b/drivers/gpu/drm/panel/panel-himax-hx83102.c index 66abfc44e424..4c432d207634 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx83102.c +++ b/drivers/gpu/drm/panel/panel-himax-hx83102.c @@ -989,8 +989,6 @@ static int hx83102_panel_add(struct hx83102 *ctx) ctx->base.prepare_prev_first = true; - drm_panel_init(&ctx->base, dev, &hx83102_drm_funcs, - DRM_MODE_CONNECTOR_DSI); err = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation); if (err < 0) return dev_err_probe(dev, err, "failed to get orientation\n"); @@ -1013,9 +1011,11 @@ static int hx83102_probe(struct mipi_dsi_device *dsi) int ret; const struct hx83102_panel_desc *desc; - ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&dsi->dev, __typeof(*ctx), base, + &hx83102_drm_funcs, DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(ctx)) + return PTR_ERR(ctx); desc = of_device_get_match_data(&dsi->dev); dsi->lanes = 4; diff --git a/drivers/gpu/drm/panel/panel-himax-hx83112a.c b/drivers/gpu/drm/panel/panel-himax-hx83112a.c index 47bce087e339..142cb1cc067a 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx83112a.c +++ b/drivers/gpu/drm/panel/panel-himax-hx83112a.c @@ -269,9 +269,11 @@ static int hx83112a_probe(struct mipi_dsi_device *dsi) struct hx83112a_panel *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct hx83112a_panel, panel, + &hx83112a_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->supplies[0].supply = "vdd1"; ctx->supplies[1].supply = "vsn"; @@ -295,8 +297,6 @@ static int hx83112a_probe(struct mipi_dsi_device *dsi) MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &hx83112a_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ret = drm_panel_of_backlight(&ctx->panel); diff --git a/drivers/gpu/drm/panel/panel-himax-hx83112b.c b/drivers/gpu/drm/panel/panel-himax-hx83112b.c new file mode 100644 index 000000000000..263f79a967de --- /dev/null +++ b/drivers/gpu/drm/panel/panel-himax-hx83112b.c @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree. + * Copyright (c) 2025 Luca Weiss <luca@lucaweiss.eu> + */ + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +/* Manufacturer specific DSI commands */ +#define HX83112B_SETPOWER1 0xb1 +#define HX83112B_SETDISP 0xb2 +#define HX83112B_SETDRV 0xb4 +#define HX83112B_SETEXTC 0xb9 +#define HX83112B_SETBANK 0xbd +#define HX83112B_SETDGCLUT 0xc1 +#define HX83112B_SETDISMO 0xc2 +#define HX83112B_UNKNOWN1 0xc6 +#define HX83112B_SETPANEL 0xcc +#define HX83112B_UNKNOWN2 0xd1 +#define HX83112B_SETPOWER2 0xd2 +#define HX83112B_SETGIP0 0xd3 +#define HX83112B_SETGIP1 0xd5 +#define HX83112B_SETGIP2 0xd6 +#define HX83112B_SETGIP3 0xd8 +#define HX83112B_SETIDLE 0xdd +#define HX83112B_UNKNOWN3 0xe7 +#define HX83112B_UNKNOWN4 0xe9 + +struct hx83112b_panel { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; +}; + +static const struct regulator_bulk_data hx83112b_supplies[] = { + { .supply = "iovcc" }, + { .supply = "vsn" }, + { .supply = "vsp" }, +}; + +static inline struct hx83112b_panel *to_hx83112b_panel(struct drm_panel *panel) +{ + return container_of(panel, struct hx83112b_panel, panel); +} + +static void hx83112b_reset(struct hx83112b_panel *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); +} + +static int hx83112b_on(struct hx83112b_panel *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETEXTC, 0x83, 0x11, 0x2b); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDISMO, 0x08, 0x70); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDISP, 0x04, 0x38, 0x08, 0x70); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETPOWER1, + 0xf8, 0x27, 0x27, 0x00, 0x00, 0x0b, 0x0e, + 0x0b, 0x0e, 0x33); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETPOWER2, 0x2d, 0x2d); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDISP, + 0x80, 0x02, 0x18, 0x80, 0x70, 0x00, 0x08, + 0x1c, 0x08, 0x11, 0x05); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0xd1); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDISP, 0x00, 0x08); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDISP, 0xb5, 0x0a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETIDLE, + 0x00, 0x00, 0x08, 0x1c, 0x08, 0x34, 0x34, + 0x88); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDRV, + 0x65, 0x6b, 0x00, 0x00, 0xd0, 0xd4, 0x36, + 0xcf, 0x06, 0xce, 0x00, 0xce, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x2a, 0x07, 0x01, 0x07, + 0x00, 0x00, 0x2a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0xc3); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDRV, 0x01, 0x67, 0x2a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDGCLUT, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDGCLUT, + 0xff, 0xfb, 0xf9, 0xf6, 0xf4, 0xf1, 0xef, + 0xea, 0xe7, 0xe5, 0xe2, 0xdf, 0xdd, 0xda, + 0xd8, 0xd5, 0xd2, 0xcf, 0xcc, 0xc5, 0xbe, + 0xb7, 0xb0, 0xa8, 0xa0, 0x98, 0x8e, 0x85, + 0x7b, 0x72, 0x69, 0x5e, 0x53, 0x48, 0x3e, + 0x35, 0x2b, 0x22, 0x17, 0x0d, 0x09, 0x07, + 0x05, 0x01, 0x00, 0x26, 0xf0, 0x86, 0x25, + 0x6e, 0xb6, 0xdd, 0xf3, 0xd8, 0xcc, 0x9b, + 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDGCLUT, + 0xff, 0xfb, 0xf9, 0xf6, 0xf4, 0xf1, 0xef, + 0xea, 0xe7, 0xe5, 0xe2, 0xdf, 0xdd, 0xda, + 0xd8, 0xd5, 0xd2, 0xcf, 0xcc, 0xc5, 0xbe, + 0xb7, 0xb0, 0xa8, 0xa0, 0x98, 0x8e, 0x85, + 0x7b, 0x72, 0x69, 0x5e, 0x53, 0x48, 0x3e, + 0x35, 0x2b, 0x22, 0x17, 0x0d, 0x09, 0x07, + 0x05, 0x01, 0x00, 0x26, 0xf0, 0x86, 0x25, + 0x6e, 0xb6, 0xdd, 0xf3, 0xd8, 0xcc, 0x9b, + 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDGCLUT, + 0xff, 0xfb, 0xf9, 0xf6, 0xf4, 0xf1, 0xef, + 0xea, 0xe7, 0xe5, 0xe2, 0xdf, 0xdd, 0xda, + 0xd8, 0xd5, 0xd2, 0xcf, 0xcc, 0xc5, 0xbe, + 0xb7, 0xb0, 0xa8, 0xa0, 0x98, 0x8e, 0x85, + 0x7b, 0x72, 0x69, 0x5e, 0x53, 0x48, 0x3e, + 0x35, 0x2b, 0x22, 0x17, 0x0d, 0x09, 0x07, + 0x05, 0x01, 0x00, 0x26, 0xf0, 0x86, 0x25, + 0x6e, 0xb6, 0xdd, 0xf3, 0xd8, 0xcc, 0x9b, + 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETDISMO, 0xc8); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETPANEL, 0x08); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP0, + 0x81, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x04, 0x00, 0x01, 0x13, 0x40, 0x04, 0x09, + 0x09, 0x0b, 0x0b, 0x32, 0x10, 0x08, 0x00, + 0x08, 0x32, 0x10, 0x08, 0x00, 0x08, 0x32, + 0x10, 0x08, 0x00, 0x08, 0x00, 0x00, 0x0a, + 0x08, 0x7b); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0xc5); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN1, 0xf7); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0xd4); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN1, 0x6e); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0xef); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP0, 0x0c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0xc8); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP0, 0xa1); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP1, + 0x18, 0x18, 0x19, 0x18, 0x18, 0x20, 0x18, + 0x18, 0x18, 0x10, 0x10, 0x18, 0x18, 0x00, + 0x00, 0x18, 0x18, 0x01, 0x01, 0x18, 0x18, + 0x28, 0x28, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x35, + 0x35, 0x36, 0x36, 0x37, 0x37, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xfc, + 0xfc, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP2, + 0x18, 0x18, 0x19, 0x18, 0x18, 0x20, 0x19, + 0x18, 0x18, 0x10, 0x10, 0x18, 0x18, 0x00, + 0x00, 0x18, 0x18, 0x01, 0x01, 0x18, 0x18, + 0x28, 0x28, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x35, + 0x35, 0x36, 0x36, 0x37, 0x37, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP3, + 0xaa, 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xaa, + 0xab, 0xaf, 0xef, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaf, 0xea, 0xaa); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP3, + 0xaa, 0xaa, 0xab, 0xaf, 0xea, 0xaa, 0xaa, + 0xaa, 0xae, 0xaf, 0xea, 0xaa); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP3, + 0xaa, 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaf, 0xea, 0xaa); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETGIP3, + 0xba, 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xba, 0xaa, + 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaf, 0xea, 0xaa); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0xe4); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN3, 0x17, 0x69); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN3, + 0x09, 0x09, 0x00, 0x07, 0xe8, 0x00, 0x26, + 0x00, 0x07, 0x00, 0x00, 0xe8, 0x32, 0x00, + 0xe9, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x12, 0x04); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN3, + 0x02, 0x00, 0x01, 0x20, 0x01, 0x18, 0x08, + 0xa8, 0x09); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN3, 0x20, 0x20, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN3, + 0x00, 0xdc, 0x11, 0x70, 0x00, 0x20); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0xc9); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN3, + 0x2a, 0xce, 0x02, 0x70, 0x01, 0x04); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN4, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112B_UNKNOWN2, 0x27); + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx, 0x0000); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, + 0x24); + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + + return dsi_ctx.accum_err; +} + +static int hx83112b_off(struct hx83112b_panel *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + + return dsi_ctx.accum_err; +} + +static int hx83112b_prepare(struct drm_panel *panel) +{ + struct hx83112b_panel *ctx = to_hx83112b_panel(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(hx83112b_supplies), ctx->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + + hx83112b_reset(ctx); + + ret = hx83112b_on(ctx); + if (ret < 0) { + dev_err(dev, "Failed to initialize panel: %d\n", ret); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(hx83112b_supplies), ctx->supplies); + return ret; + } + + return 0; +} + +static int hx83112b_unprepare(struct drm_panel *panel) +{ + struct hx83112b_panel *ctx = to_hx83112b_panel(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = hx83112b_off(ctx); + if (ret < 0) + dev_err(dev, "Failed to un-initialize panel: %d\n", ret); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(hx83112b_supplies), ctx->supplies); + + return 0; +} + +static const struct drm_display_mode hx83112b_mode = { + .clock = (1080 + 40 + 4 + 12) * (2160 + 32 + 2 + 2) * 60 / 1000, + .hdisplay = 1080, + .hsync_start = 1080 + 40, + .hsync_end = 1080 + 40 + 4, + .htotal = 1080 + 40 + 4 + 12, + .vdisplay = 2160, + .vsync_start = 2160 + 32, + .vsync_end = 2160 + 32 + 2, + .vtotal = 2160 + 32 + 2 + 2, + .width_mm = 65, + .height_mm = 128, + .type = DRM_MODE_TYPE_DRIVER, +}; + +static int hx83112b_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &hx83112b_mode); +} + +static const struct drm_panel_funcs hx83112b_panel_funcs = { + .prepare = hx83112b_prepare, + .unprepare = hx83112b_unprepare, + .get_modes = hx83112b_get_modes, +}; + +static int hx83112b_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static const struct backlight_ops hx83112b_bl_ops = { + .update_status = hx83112b_bl_update_status, +}; + +static struct backlight_device * +hx83112b_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 4095, + .max_brightness = 4095, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &hx83112b_bl_ops, &props); +} + +static int hx83112b_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct hx83112b_panel *ctx; + int ret; + + ctx = devm_drm_panel_alloc(dev, struct hx83112b_panel, panel, + &hx83112b_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ret = devm_regulator_bulk_get_const(dev, + ARRAY_SIZE(hx83112b_supplies), + hx83112b_supplies, + &ctx->supplies); + if (ret < 0) + return ret; + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_CLOCK_NON_CONTINUOUS | + MIPI_DSI_MODE_VIDEO_NO_HSA | MIPI_DSI_MODE_LPM; + + ctx->panel.prepare_prev_first = true; + + ctx->panel.backlight = hx83112b_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + + drm_panel_add(&ctx->panel); + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); + } + + return 0; +} + +static void hx83112b_remove(struct mipi_dsi_device *dsi) +{ + struct hx83112b_panel *ctx = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id hx83112b_of_match[] = { + { .compatible = "djn,98-03057-6598b-i" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, hx83112b_of_match); + +static struct mipi_dsi_driver hx83112b_driver = { + .probe = hx83112b_probe, + .remove = hx83112b_remove, + .driver = { + .name = "panel-himax-hx83112b", + .of_match_table = hx83112b_of_match, + }, +}; +module_mipi_dsi_driver(hx83112b_driver); + +MODULE_DESCRIPTION("DRM driver for hx83112b-equipped DSI panels"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c index ff994bf0e3cc..c4d3e09a228d 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx8394.c +++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c @@ -477,6 +477,147 @@ static const struct hx8394_panel_desc mchp_ac40t08a_desc = { .init_sequence = mchp_ac40t08a_init_sequence, }; +/* + * HL055FHAV028C is based on Himax HX8399, so datasheet pages are + * slightly different than HX8394 based panels. + */ +static void hl055fhav028c_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) +{ + /* 6.3.6 SETEXTC: Set extension command (B9h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETEXTC, + 0xff, 0x83, 0x99); + + /* 6.3.17 SETOFFSET: Set offset voltage (D2h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETOFFSET, + 0x77); + + /* 6.3.1 SETPOWER: Set power (B1h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETPOWER, + 0x02, 0x04, 0x74, 0x94, 0x01, 0x32, + 0x33, 0x11, 0x11, 0xab, 0x4d, 0x56, + 0x73, 0x02, 0x02); + + /* 6.3.2 SETDISP: Set display related register (B2h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETDISP, + 0x00, 0x80, 0x80, 0xae, 0x05, 0x07, + 0x5a, 0x11, 0x00, 0x00, 0x10, 0x1e, + 0x70, 0x03, 0xd4); + + /* 6.3.3 SETCYC: Set display waveform cycles (B4h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETCYC, + 0x00, 0xff, 0x02, 0xc0, 0x02, 0xc0, + 0x00, 0x00, 0x08, 0x00, 0x04, 0x06, + 0x00, 0x32, 0x04, 0x0a, 0x08, 0x21, + 0x03, 0x01, 0x00, 0x0f, 0xb8, 0x8b, + 0x02, 0xc0, 0x02, 0xc0, 0x00, 0x00, + 0x08, 0x00, 0x04, 0x06, 0x00, 0x32, + 0x04, 0x0a, 0x08, 0x01, 0x00, 0x0f, + 0xb8, 0x01); + + /* 6.3.18 SETGIP0: Set GIP Option0 (D3h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x05, 0x05, 0x07, 0x00, 0x00, + 0x00, 0x05, 0x40); + + /* 6.3.19 Set GIP Option1 (D5h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP1, + 0x18, 0x18, 0x19, 0x19, 0x18, 0x18, + 0x21, 0x20, 0x01, 0x00, 0x07, 0x06, + 0x05, 0x04, 0x03, 0x02, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x2f, 0x2f, + 0x30, 0x30, 0x31, 0x31, 0x18, 0x18, + 0x18, 0x18); + + /* 6.3.20 Set GIP Option2 (D6h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGIP2, + 0x18, 0x18, 0x19, 0x19, 0x40, 0x40, + 0x20, 0x21, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x00, 0x01, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x2f, 0x2f, + 0x30, 0x30, 0x31, 0x31, 0x40, 0x40, + 0x40, 0x40); + + /* 6.3.21 Set GIP Option3 (D8h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN4, + 0xa2, 0xaa, 0x02, 0xa0, 0xa2, 0xa8, + 0x02, 0xa0, 0xb0, 0x00, 0x00, 0x00, + 0xb0, 0x00, 0x00, 0x00); + + /* 6.3.9 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x01); + + /* 6.3.21 Set GIP Option3 (D8h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN4, + 0xb0, 0x00, 0x00, 0x00, 0xb0, 0x00, + 0x00, 0x00, 0xe2, 0xaa, 0x03, 0xf0, + 0xe2, 0xaa, 0x03, 0xf0); + + /* 6.3.9 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x02); + + /* 6.3.21 Set GIP Option3 (D8h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN4, + 0xe2, 0xaa, 0x03, 0xf0, 0xe2, 0xaa, + 0x03, 0xf0); + + /* 6.3.9 Set register bank (BDh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETREGBANK, + 0x00); + + /* 6.3.4 SETVCOM: Set VCOM voltage (B6h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETVCOM, + 0x7a, 0x7a); + + /* 6.3.26 SETGAMMA: Set gamma curve related setting (E0h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETGAMMA, + 0x00, 0x18, 0x27, 0x24, 0x5a, 0x68, + 0x79, 0x78, 0x81, 0x8a, 0x92, 0x99, + 0x9e, 0xa7, 0xaf, 0xb4, 0xb9, 0xc3, + 0xc7, 0xd1, 0xc6, 0xd4, 0xd5, 0x6c, + 0x67, 0x71, 0x77, 0x00, 0x00, 0x18, + 0x27, 0x24, 0x5a, 0x68, 0x79, 0x78, + 0x81, 0x8a, 0x92, 0x99, 0x9e, 0xa7, + 0xaf, 0xb4, 0xb9, 0xc3, 0xc7, 0xd1, + 0xc6, 0xd4, 0xd5, 0x6c, 0x67, 0x77); + + /* Unknown command, not listed in the HX8399-C datasheet (C6h) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_UNKNOWN2, + 0xff, 0xf9); + + /* 6.3.16 SETPANEL (CCh) */ + mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX8394_CMD_SETPANEL, + 0x08); +} + +static const struct drm_display_mode hl055fhav028c_mode = { + .hdisplay = 1080, + .hsync_start = 1080 + 32, + .hsync_end = 1080 + 32 + 8, + .htotal = 1080 + 32 + 8 + 32, + .vdisplay = 1920, + .vsync_start = 1920 + 16, + .vsync_end = 1920 + 16 + 2, + .vtotal = 1920 + 16 + 2 + 14, + .clock = 134920, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, + .width_mm = 70, + .height_mm = 127, +}; + +static const struct hx8394_panel_desc hl055fhav028c_desc = { + .mode = &hl055fhav028c_mode, + .lanes = 4, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST, + .format = MIPI_DSI_FMT_RGB888, + .init_sequence = hl055fhav028c_init_sequence, +}; + static int hx8394_enable(struct drm_panel *panel) { struct hx8394 *ctx = panel_to_hx8394(panel); @@ -611,9 +752,11 @@ static int hx8394_probe(struct mipi_dsi_device *dsi) struct hx8394 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct hx8394, panel, + &hx8394_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ctx->reset_gpio)) @@ -645,9 +788,6 @@ static int hx8394_probe(struct mipi_dsi_device *dsi) return dev_err_probe(dev, PTR_ERR(ctx->iovcc), "Failed to request iovcc regulator\n"); - drm_panel_init(&ctx->panel, dev, &hx8394_drm_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; @@ -683,6 +823,7 @@ static void hx8394_remove(struct mipi_dsi_device *dsi) static const struct of_device_id hx8394_of_match[] = { { .compatible = "hannstar,hsd060bhw4", .data = &hsd060bhw4_desc }, + { .compatible = "huiling,hl055fhav028c", .data = &hl055fhav028c_desc }, { .compatible = "powkiddy,x55-panel", .data = &powkiddy_x55_desc }, { .compatible = "microchip,ac40t08a-mipi-panel", .data = &mchp_ac40t08a_desc }, { /* sentinel */ } diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c index 94b7dfef3b5e..6ed544a83bdd 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c @@ -722,9 +722,10 @@ static int ili9322_probe(struct spi_device *spi) int ret; int i; - ili = devm_kzalloc(dev, sizeof(struct ili9322), GFP_KERNEL); - if (!ili) - return -ENOMEM; + ili = devm_drm_panel_alloc(dev, struct ili9322, panel, + &ili9322_drm_funcs, DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(ili)) + return PTR_ERR(ili); spi_set_drvdata(spi, ili); @@ -883,9 +884,6 @@ static int ili9322_probe(struct spi_device *spi) ili->input = ili->conf->input; } - drm_panel_init(&ili->panel, dev, &ili9322_drm_funcs, - DRM_MODE_CONNECTOR_DPI); - drm_panel_add(&ili->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index ff39f5dd4097..f7425dfaa50d 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -173,7 +173,6 @@ struct ili9341_config { }; struct ili9341 { - struct device *dev; const struct ili9341_config *conf; struct drm_panel panel; struct gpio_desc *reset_gpio; @@ -490,9 +489,11 @@ static int ili9341_dpi_probe(struct spi_device *spi, struct gpio_desc *dc, struct ili9341 *ili; int ret; - ili = devm_kzalloc(dev, sizeof(struct ili9341), GFP_KERNEL); - if (!ili) - return -ENOMEM; + ili = devm_drm_panel_alloc(dev, struct ili9341, panel, + &ili9341_dpi_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(ili)) + return PTR_ERR(ili); ili->dbi = devm_kzalloc(dev, sizeof(struct mipi_dbi), GFP_KERNEL); @@ -526,8 +527,6 @@ static int ili9341_dpi_probe(struct spi_device *spi, struct gpio_desc *dc, } ili->max_spi_speed = ili->conf->max_spi_speed; - drm_panel_init(&ili->panel, dev, &ili9341_dpi_funcs, - DRM_MODE_CONNECTOR_DPI); drm_panel_add(&ili->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9805.c b/drivers/gpu/drm/panel/panel-ilitek-ili9805.c index 1cbc25758bd2..e6c483851f1f 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9805.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9805.c @@ -307,9 +307,12 @@ static int ili9805_dsi_probe(struct mipi_dsi_device *dsi) struct ili9805 *ctx; int ret; - ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&dsi->dev, struct ili9805, panel, + &ili9805_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; ctx->desc = of_device_get_match_data(&dsi->dev); @@ -320,9 +323,6 @@ static int ili9805_dsi_probe(struct mipi_dsi_device *dsi) MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET; dsi->lanes = 2; - drm_panel_init(&ctx->panel, &dsi->dev, &ili9805_funcs, - DRM_MODE_CONNECTOR_DSI); - ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd"); if (IS_ERR(ctx->dvdd)) return PTR_ERR(ctx->dvdd); diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c index a3c79ad99d0b..18aa6222b0c5 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c @@ -166,9 +166,10 @@ static int ili9806e_dsi_probe(struct mipi_dsi_device *dsi) struct ili9806e_panel *ctx; int i, ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct ili9806e_panel, panel, &ili9806e_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->desc = device_get_match_data(dev); @@ -192,9 +193,6 @@ static int ili9806e_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = ctx->desc->format; dsi->lanes = ctx->desc->lanes; - drm_panel_init(&ctx->panel, dev, &ili9806e_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation); if (ret) return dev_err_probe(dev, ret, "Failed to get orientation\n"); diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c index 28cd7560e5db..ac433345a179 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -43,6 +43,7 @@ struct ili9881c_desc { const struct drm_display_mode *mode; const unsigned long mode_flags; u8 default_address_mode; + unsigned int lanes; }; struct ili9881c { @@ -1223,6 +1224,199 @@ static const struct ili9881c_instr am8001280g_init[] = { ILI9881C_COMMAND_INSTR(MIPI_DCS_WRITE_POWER_SAVE, 0x00), }; +static const struct ili9881c_instr rpi_7inch_init[] = { + ILI9881C_SWITCH_PAGE_INSTR(3), + ILI9881C_COMMAND_INSTR(0x01, 0x00), + ILI9881C_COMMAND_INSTR(0x02, 0x00), + ILI9881C_COMMAND_INSTR(0x03, 0x73), + ILI9881C_COMMAND_INSTR(0x04, 0x00), + ILI9881C_COMMAND_INSTR(0x05, 0x00), + ILI9881C_COMMAND_INSTR(0x06, 0x0a), + ILI9881C_COMMAND_INSTR(0x07, 0x00), + ILI9881C_COMMAND_INSTR(0x08, 0x00), + ILI9881C_COMMAND_INSTR(0x09, 0x61), + ILI9881C_COMMAND_INSTR(0x0a, 0x00), + ILI9881C_COMMAND_INSTR(0x0b, 0x00), + ILI9881C_COMMAND_INSTR(0x0c, 0x01), + ILI9881C_COMMAND_INSTR(0x0d, 0x00), + ILI9881C_COMMAND_INSTR(0x0e, 0x00), + ILI9881C_COMMAND_INSTR(0x0f, 0x61), + ILI9881C_COMMAND_INSTR(0x10, 0x61), + ILI9881C_COMMAND_INSTR(0x11, 0x00), + ILI9881C_COMMAND_INSTR(0x12, 0x00), + ILI9881C_COMMAND_INSTR(0x13, 0x00), + ILI9881C_COMMAND_INSTR(0x14, 0x00), + ILI9881C_COMMAND_INSTR(0x15, 0x00), + ILI9881C_COMMAND_INSTR(0x16, 0x00), + ILI9881C_COMMAND_INSTR(0x17, 0x00), + ILI9881C_COMMAND_INSTR(0x18, 0x00), + ILI9881C_COMMAND_INSTR(0x19, 0x00), + ILI9881C_COMMAND_INSTR(0x1a, 0x00), + ILI9881C_COMMAND_INSTR(0x1b, 0x00), + ILI9881C_COMMAND_INSTR(0x1c, 0x00), + ILI9881C_COMMAND_INSTR(0x1d, 0x00), + ILI9881C_COMMAND_INSTR(0x1e, 0x40), + ILI9881C_COMMAND_INSTR(0x1f, 0x80), + ILI9881C_COMMAND_INSTR(0x20, 0x06), + ILI9881C_COMMAND_INSTR(0x21, 0x01), + ILI9881C_COMMAND_INSTR(0x22, 0x00), + ILI9881C_COMMAND_INSTR(0x23, 0x00), + ILI9881C_COMMAND_INSTR(0x24, 0x00), + ILI9881C_COMMAND_INSTR(0x25, 0x00), + ILI9881C_COMMAND_INSTR(0x26, 0x00), + ILI9881C_COMMAND_INSTR(0x27, 0x00), + ILI9881C_COMMAND_INSTR(0x28, 0x33), + ILI9881C_COMMAND_INSTR(0x29, 0x03), + ILI9881C_COMMAND_INSTR(0x2a, 0x00), + ILI9881C_COMMAND_INSTR(0x2b, 0x00), + ILI9881C_COMMAND_INSTR(0x2c, 0x00), + ILI9881C_COMMAND_INSTR(0x2d, 0x00), + ILI9881C_COMMAND_INSTR(0x2e, 0x00), + ILI9881C_COMMAND_INSTR(0x2f, 0x00), + ILI9881C_COMMAND_INSTR(0x30, 0x00), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x32, 0x00), + ILI9881C_COMMAND_INSTR(0x33, 0x00), + ILI9881C_COMMAND_INSTR(0x34, 0x04), + ILI9881C_COMMAND_INSTR(0x35, 0x00), + ILI9881C_COMMAND_INSTR(0x36, 0x00), + ILI9881C_COMMAND_INSTR(0x37, 0x00), + ILI9881C_COMMAND_INSTR(0x38, 0x3c), + ILI9881C_COMMAND_INSTR(0x39, 0x00), + ILI9881C_COMMAND_INSTR(0x3a, 0x00), + ILI9881C_COMMAND_INSTR(0x3b, 0x00), + ILI9881C_COMMAND_INSTR(0x3c, 0x00), + ILI9881C_COMMAND_INSTR(0x3d, 0x00), + ILI9881C_COMMAND_INSTR(0x3e, 0x00), + ILI9881C_COMMAND_INSTR(0x3f, 0x00), + ILI9881C_COMMAND_INSTR(0x40, 0x00), + ILI9881C_COMMAND_INSTR(0x41, 0x00), + ILI9881C_COMMAND_INSTR(0x42, 0x00), + ILI9881C_COMMAND_INSTR(0x43, 0x00), + ILI9881C_COMMAND_INSTR(0x44, 0x00), + ILI9881C_COMMAND_INSTR(0x50, 0x10), + ILI9881C_COMMAND_INSTR(0x51, 0x32), + ILI9881C_COMMAND_INSTR(0x52, 0x54), + ILI9881C_COMMAND_INSTR(0x53, 0x76), + ILI9881C_COMMAND_INSTR(0x54, 0x98), + ILI9881C_COMMAND_INSTR(0x55, 0xba), + ILI9881C_COMMAND_INSTR(0x56, 0x10), + ILI9881C_COMMAND_INSTR(0x57, 0x32), + ILI9881C_COMMAND_INSTR(0x58, 0x54), + ILI9881C_COMMAND_INSTR(0x59, 0x76), + ILI9881C_COMMAND_INSTR(0x5a, 0x98), + ILI9881C_COMMAND_INSTR(0x5b, 0xba), + ILI9881C_COMMAND_INSTR(0x5c, 0xdc), + ILI9881C_COMMAND_INSTR(0x5d, 0xfe), + ILI9881C_COMMAND_INSTR(0x5e, 0x00), + ILI9881C_COMMAND_INSTR(0x5f, 0x0e), + ILI9881C_COMMAND_INSTR(0x60, 0x0f), + ILI9881C_COMMAND_INSTR(0x61, 0x0c), + ILI9881C_COMMAND_INSTR(0x62, 0x0d), + ILI9881C_COMMAND_INSTR(0x63, 0x06), + ILI9881C_COMMAND_INSTR(0x64, 0x07), + ILI9881C_COMMAND_INSTR(0x65, 0x02), + ILI9881C_COMMAND_INSTR(0x66, 0x02), + ILI9881C_COMMAND_INSTR(0x67, 0x02), + ILI9881C_COMMAND_INSTR(0x68, 0x02), + ILI9881C_COMMAND_INSTR(0x69, 0x01), + ILI9881C_COMMAND_INSTR(0x6a, 0x00), + ILI9881C_COMMAND_INSTR(0x6b, 0x02), + ILI9881C_COMMAND_INSTR(0x6c, 0x15), + ILI9881C_COMMAND_INSTR(0x6d, 0x14), + ILI9881C_COMMAND_INSTR(0x6e, 0x02), + ILI9881C_COMMAND_INSTR(0x6f, 0x02), + ILI9881C_COMMAND_INSTR(0x70, 0x02), + ILI9881C_COMMAND_INSTR(0x71, 0x02), + ILI9881C_COMMAND_INSTR(0x72, 0x02), + ILI9881C_COMMAND_INSTR(0x73, 0x02), + ILI9881C_COMMAND_INSTR(0x74, 0x02), + ILI9881C_COMMAND_INSTR(0x75, 0x0e), + ILI9881C_COMMAND_INSTR(0x76, 0x0f), + ILI9881C_COMMAND_INSTR(0x77, 0x0c), + ILI9881C_COMMAND_INSTR(0x78, 0x0d), + ILI9881C_COMMAND_INSTR(0x79, 0x06), + ILI9881C_COMMAND_INSTR(0x7a, 0x07), + ILI9881C_COMMAND_INSTR(0x7b, 0x02), + ILI9881C_COMMAND_INSTR(0x7c, 0x02), + ILI9881C_COMMAND_INSTR(0x7d, 0x02), + ILI9881C_COMMAND_INSTR(0x7e, 0x02), + ILI9881C_COMMAND_INSTR(0x7f, 0x01), + ILI9881C_COMMAND_INSTR(0x80, 0x00), + ILI9881C_COMMAND_INSTR(0x81, 0x02), + ILI9881C_COMMAND_INSTR(0x82, 0x14), + ILI9881C_COMMAND_INSTR(0x83, 0x15), + ILI9881C_COMMAND_INSTR(0x84, 0x02), + ILI9881C_COMMAND_INSTR(0x85, 0x02), + ILI9881C_COMMAND_INSTR(0x86, 0x02), + ILI9881C_COMMAND_INSTR(0x87, 0x02), + ILI9881C_COMMAND_INSTR(0x88, 0x02), + ILI9881C_COMMAND_INSTR(0x89, 0x02), + ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_SWITCH_PAGE_INSTR(4), + ILI9881C_COMMAND_INSTR(0x6C, 0x15), + ILI9881C_COMMAND_INSTR(0x6E, 0x2A), + ILI9881C_COMMAND_INSTR(0x6F, 0x33), + ILI9881C_COMMAND_INSTR(0x3B, 0x98), + ILI9881C_COMMAND_INSTR(0x3a, 0x94), + ILI9881C_COMMAND_INSTR(0x8D, 0x14), + ILI9881C_COMMAND_INSTR(0x87, 0xBA), + ILI9881C_COMMAND_INSTR(0x26, 0x76), + ILI9881C_COMMAND_INSTR(0xB2, 0xD1), + ILI9881C_COMMAND_INSTR(0xB5, 0x06), + ILI9881C_COMMAND_INSTR(0x38, 0x01), + ILI9881C_COMMAND_INSTR(0x39, 0x00), + ILI9881C_SWITCH_PAGE_INSTR(1), + ILI9881C_COMMAND_INSTR(0x22, 0x0A), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x53, 0x7d), + ILI9881C_COMMAND_INSTR(0x55, 0x8f), + ILI9881C_COMMAND_INSTR(0x40, 0x33), + ILI9881C_COMMAND_INSTR(0x50, 0x96), + ILI9881C_COMMAND_INSTR(0x51, 0x96), + ILI9881C_COMMAND_INSTR(0x60, 0x23), + ILI9881C_COMMAND_INSTR(0xA0, 0x08), + ILI9881C_COMMAND_INSTR(0xA1, 0x1d), + ILI9881C_COMMAND_INSTR(0xA2, 0x2a), + ILI9881C_COMMAND_INSTR(0xA3, 0x10), + ILI9881C_COMMAND_INSTR(0xA4, 0x15), + ILI9881C_COMMAND_INSTR(0xA5, 0x28), + ILI9881C_COMMAND_INSTR(0xA6, 0x1c), + ILI9881C_COMMAND_INSTR(0xA7, 0x1d), + ILI9881C_COMMAND_INSTR(0xA8, 0x7e), + ILI9881C_COMMAND_INSTR(0xA9, 0x1d), + ILI9881C_COMMAND_INSTR(0xAA, 0x29), + ILI9881C_COMMAND_INSTR(0xAB, 0x6b), + ILI9881C_COMMAND_INSTR(0xAC, 0x1a), + ILI9881C_COMMAND_INSTR(0xAD, 0x18), + ILI9881C_COMMAND_INSTR(0xAE, 0x4b), + ILI9881C_COMMAND_INSTR(0xAF, 0x20), + ILI9881C_COMMAND_INSTR(0xB0, 0x27), + ILI9881C_COMMAND_INSTR(0xB1, 0x50), + ILI9881C_COMMAND_INSTR(0xB2, 0x64), + ILI9881C_COMMAND_INSTR(0xB3, 0x39), + ILI9881C_COMMAND_INSTR(0xC0, 0x08), + ILI9881C_COMMAND_INSTR(0xC1, 0x1d), + ILI9881C_COMMAND_INSTR(0xC2, 0x2a), + ILI9881C_COMMAND_INSTR(0xC3, 0x10), + ILI9881C_COMMAND_INSTR(0xC4, 0x15), + ILI9881C_COMMAND_INSTR(0xC5, 0x28), + ILI9881C_COMMAND_INSTR(0xC6, 0x1c), + ILI9881C_COMMAND_INSTR(0xC7, 0x1d), + ILI9881C_COMMAND_INSTR(0xC8, 0x7e), + ILI9881C_COMMAND_INSTR(0xC9, 0x1d), + ILI9881C_COMMAND_INSTR(0xCA, 0x29), + ILI9881C_COMMAND_INSTR(0xCB, 0x6b), + ILI9881C_COMMAND_INSTR(0xCC, 0x1a), + ILI9881C_COMMAND_INSTR(0xCD, 0x18), + ILI9881C_COMMAND_INSTR(0xCE, 0x4b), + ILI9881C_COMMAND_INSTR(0xCF, 0x20), + ILI9881C_COMMAND_INSTR(0xD0, 0x27), + ILI9881C_COMMAND_INSTR(0xD1, 0x50), + ILI9881C_COMMAND_INSTR(0xD2, 0x64), + ILI9881C_COMMAND_INSTR(0xD3, 0x39), +}; + static inline struct ili9881c *panel_to_ili9881c(struct drm_panel *panel) { return container_of(panel, struct ili9881c, panel); @@ -1449,6 +1643,23 @@ static const struct drm_display_mode am8001280g_default_mode = { .height_mm = 151, }; +static const struct drm_display_mode rpi_7inch_default_mode = { + .clock = 83330, + + .hdisplay = 720, + .hsync_start = 720 + 239, + .hsync_end = 720 + 239 + 33, + .htotal = 720 + 239 + 33 + 50, + + .vdisplay = 1280, + .vsync_start = 1280 + 20, + .vsync_end = 1280 + 20 + 2, + .vtotal = 1280 + 20 + 2 + 30, + + .width_mm = 90, + .height_mm = 151, +}; + static int ili9881c_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -1506,16 +1717,15 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi) struct ili9881c *ctx; int ret; - ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&dsi->dev, struct ili9881c, panel, &ili9881c_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; ctx->desc = of_device_get_match_data(&dsi->dev); - drm_panel_init(&ctx->panel, &dsi->dev, &ili9881c_funcs, - DRM_MODE_CONNECTOR_DSI); - ctx->power = devm_regulator_get(&dsi->dev, "power"); if (IS_ERR(ctx->power)) return dev_err_probe(&dsi->dev, PTR_ERR(ctx->power), @@ -1549,7 +1759,7 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = ctx->desc->mode_flags; dsi->format = MIPI_DSI_FMT_RGB888; - dsi->lanes = 4; + dsi->lanes = ctx->desc->lanes; return mipi_dsi_attach(dsi); } @@ -1567,6 +1777,7 @@ static const struct ili9881c_desc lhr050h41_desc = { .init_length = ARRAY_SIZE(lhr050h41_init), .mode = &lhr050h41_default_mode, .mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE, + .lanes = 4, }; static const struct ili9881c_desc k101_im2byl02_desc = { @@ -1574,6 +1785,7 @@ static const struct ili9881c_desc k101_im2byl02_desc = { .init_length = ARRAY_SIZE(k101_im2byl02_init), .mode = &k101_im2byl02_default_mode, .mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE, + .lanes = 4, }; static const struct ili9881c_desc kd050hdfia020_desc = { @@ -1599,6 +1811,7 @@ static const struct ili9881c_desc w552946aba_desc = { .mode = &w552946aba_default_mode, .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET, + .lanes = 4, }; static const struct ili9881c_desc am8001280g_desc = { @@ -1609,6 +1822,14 @@ static const struct ili9881c_desc am8001280g_desc = { MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM, }; +static const struct ili9881c_desc rpi_7inch_desc = { + .init = rpi_7inch_init, + .init_length = ARRAY_SIZE(rpi_7inch_init), + .mode = &rpi_7inch_default_mode, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM, + .lanes = 2, +}; + static const struct of_device_id ili9881c_of_match[] = { { .compatible = "bananapi,lhr050h41", .data = &lhr050h41_desc }, { .compatible = "feixin,k101-im2byl02", .data = &k101_im2byl02_desc }, @@ -1616,6 +1837,7 @@ static const struct of_device_id ili9881c_of_match[] = { { .compatible = "tdo,tl050hdv35", .data = &tl050hdv35_desc }, { .compatible = "wanchanglong,w552946aba", .data = &w552946aba_desc }, { .compatible = "ampire,am8001280g", .data = &am8001280g_desc }, + { .compatible = "raspberrypi,dsi-7inch", &rpi_7inch_desc }, { } }; MODULE_DEVICE_TABLE(of, ili9881c_of_match); diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c index 3c24a63b6be8..85c7059be214 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c @@ -614,8 +614,6 @@ static int ili9882t_add(struct ili9882t *ili) gpiod_set_value(ili->enable_gpio, 0); - drm_panel_init(&ili->base, dev, &ili9882t_funcs, - DRM_MODE_CONNECTOR_DSI); err = of_drm_get_panel_orientation(dev->of_node, &ili->orientation); if (err < 0) { dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err); @@ -640,9 +638,11 @@ static int ili9882t_probe(struct mipi_dsi_device *dsi) int ret; const struct panel_desc *desc; - ili = devm_kzalloc(&dsi->dev, sizeof(*ili), GFP_KERNEL); - if (!ili) - return -ENOMEM; + ili = devm_drm_panel_alloc(&dsi->dev, __typeof(*ili), base, + &ili9882t_funcs, DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(ili)) + return PTR_ERR(ili); desc = of_device_get_match_data(&dsi->dev); dsi->lanes = desc->lanes; diff --git a/drivers/gpu/drm/panel/panel-innolux-ej030na.c b/drivers/gpu/drm/panel/panel-innolux-ej030na.c index f85b7a4cbb42..b2309900873b 100644 --- a/drivers/gpu/drm/panel/panel-innolux-ej030na.c +++ b/drivers/gpu/drm/panel/panel-innolux-ej030na.c @@ -204,9 +204,11 @@ static int ej030na_probe(struct spi_device *spi) struct ej030na *priv; int err; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = devm_drm_panel_alloc(dev, struct ej030na, panel, + &ej030na_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(priv)) + return PTR_ERR(priv); priv->spi = spi; spi_set_drvdata(spi, priv); @@ -231,9 +233,6 @@ static int ej030na_probe(struct spi_device *spi) return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), "Failed to get reset GPIO\n"); - drm_panel_init(&priv->panel, dev, &ej030na_funcs, - DRM_MODE_CONNECTOR_DPI); - err = drm_panel_of_backlight(&priv->panel); if (err) return err; diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c index d95c0d4f3e35..80afeeab9475 100644 --- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c +++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c @@ -382,9 +382,11 @@ static int innolux_panel_add(struct mipi_dsi_device *dsi, struct device *dev = &dsi->dev; int err, i; - innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL); - if (!innolux) - return -ENOMEM; + innolux = devm_drm_panel_alloc(dev, struct innolux_panel, base, + &innolux_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(innolux)) + return PTR_ERR(innolux); innolux->desc = desc; @@ -410,9 +412,6 @@ static int innolux_panel_add(struct mipi_dsi_device *dsi, innolux->enable_gpio = NULL; } - drm_panel_init(&innolux->base, dev, &innolux_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - err = drm_panel_of_backlight(&innolux->base); if (err) return err; diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index eb0f8373258c..5c2530598ddb 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -1120,9 +1120,10 @@ static int jadard_dsi_probe(struct mipi_dsi_device *dsi) struct jadard *jadard; int ret; - jadard = devm_kzalloc(&dsi->dev, sizeof(*jadard), GFP_KERNEL); - if (!jadard) - return -ENOMEM; + jadard = devm_drm_panel_alloc(dev, struct jadard, panel, &jadard_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(jadard)) + return PTR_ERR(jadard); desc = of_device_get_match_data(dev); dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | @@ -1148,9 +1149,6 @@ static int jadard_dsi_probe(struct mipi_dsi_device *dsi) return PTR_ERR(jadard->vccio); } - drm_panel_init(&jadard->panel, dev, &jadard_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = of_drm_get_panel_orientation(dev->of_node, &jadard->orientation); if (ret < 0) return dev_err_probe(dev, ret, "failed to get orientation\n"); diff --git a/drivers/gpu/drm/panel/panel-jdi-fhd-r63452.c b/drivers/gpu/drm/panel/panel-jdi-fhd-r63452.c index 4eb71e85e9e9..cbe354b51bce 100644 --- a/drivers/gpu/drm/panel/panel-jdi-fhd-r63452.c +++ b/drivers/gpu/drm/panel/panel-jdi-fhd-r63452.c @@ -175,9 +175,11 @@ static int jdi_fhd_r63452_probe(struct mipi_dsi_device *dsi) struct jdi_fhd_r63452 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct jdi_fhd_r63452, panel, + &jdi_fhd_r63452_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ctx->reset_gpio)) @@ -192,8 +194,6 @@ static int jdi_fhd_r63452_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &jdi_fhd_r63452_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ret = drm_panel_of_backlight(&ctx->panel); diff --git a/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c b/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c index 5b5082efb282..5f897e143758 100644 --- a/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c +++ b/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c @@ -435,9 +435,6 @@ static int jdi_panel_add(struct jdi_panel *jdi) return dev_err_probe(dev, PTR_ERR(jdi->backlight), "failed to create backlight\n"); - drm_panel_init(&jdi->base, &jdi->link1->dev, &jdi_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - drm_panel_add(&jdi->base); return 0; @@ -475,10 +472,13 @@ static int jdi_panel_dsi_probe(struct mipi_dsi_device *dsi) /* register a panel for only the DSI-LINK1 interface */ if (secondary) { - jdi = devm_kzalloc(&dsi->dev, sizeof(*jdi), GFP_KERNEL); - if (!jdi) { + jdi = devm_drm_panel_alloc(&dsi->dev, __typeof(*jdi), + base, &jdi_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(jdi)) { put_device(&secondary->dev); - return -ENOMEM; + return PTR_ERR(jdi); } mipi_dsi_set_drvdata(dsi, jdi); diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c index b1ce186de261..3513e5c4dd8c 100644 --- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c +++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c @@ -402,9 +402,6 @@ static int jdi_panel_add(struct jdi_panel *jdi) return dev_err_probe(dev, PTR_ERR(jdi->backlight), "failed to register backlight %d\n", ret); - drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - drm_panel_add(&jdi->base); return 0; @@ -426,9 +423,11 @@ static int jdi_panel_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS; - jdi = devm_kzalloc(&dsi->dev, sizeof(*jdi), GFP_KERNEL); - if (!jdi) - return -ENOMEM; + jdi = devm_drm_panel_alloc(&dsi->dev, __typeof(*jdi), base, + &jdi_panel_funcs, DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(jdi)) + return PTR_ERR(jdi); mipi_dsi_set_drvdata(dsi, jdi); diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c b/drivers/gpu/drm/panel/panel-khadas-ts050.c index 0e5e8e57bd1e..67ca055f06f3 100644 --- a/drivers/gpu/drm/panel/panel-khadas-ts050.c +++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c @@ -821,9 +821,6 @@ static int khadas_ts050_panel_add(struct khadas_ts050_panel *khadas_ts050) return dev_err_probe(dev, PTR_ERR(khadas_ts050->enable_gpio), "failed to get enable gpio"); - drm_panel_init(&khadas_ts050->base, &khadas_ts050->link->dev, - &khadas_ts050_panel_funcs, DRM_MODE_CONNECTOR_DSI); - err = drm_panel_of_backlight(&khadas_ts050->base); if (err) return err; @@ -850,10 +847,12 @@ static int khadas_ts050_panel_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET; - khadas_ts050 = devm_kzalloc(&dsi->dev, sizeof(*khadas_ts050), - GFP_KERNEL); - if (!khadas_ts050) - return -ENOMEM; + khadas_ts050 = devm_drm_panel_alloc(&dsi->dev, __typeof(*khadas_ts050), + base, &khadas_ts050_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(khadas_ts050)) + return PTR_ERR(khadas_ts050); khadas_ts050->panel_data = (struct khadas_ts050_panel_data *)data; mipi_dsi_set_drvdata(dsi, khadas_ts050); diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c index d6b912277196..2fc7b0779b37 100644 --- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c +++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c @@ -337,9 +337,6 @@ static int kingdisplay_panel_add(struct kingdisplay_panel *kingdisplay) kingdisplay->enable_gpio = NULL; } - drm_panel_init(&kingdisplay->base, &kingdisplay->link->dev, - &kingdisplay_panel_funcs, DRM_MODE_CONNECTOR_DSI); - err = drm_panel_of_backlight(&kingdisplay->base); if (err) return err; @@ -364,9 +361,12 @@ static int kingdisplay_panel_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM; - kingdisplay = devm_kzalloc(&dsi->dev, sizeof(*kingdisplay), GFP_KERNEL); - if (!kingdisplay) - return -ENOMEM; + kingdisplay = devm_drm_panel_alloc(&dsi->dev, __typeof(*kingdisplay), base, + &kingdisplay_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(kingdisplay)) + return PTR_ERR(kingdisplay); mipi_dsi_set_drvdata(dsi, kingdisplay); kingdisplay->link = dsi; diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c index 77f74e6c467e..0856df5a6ee2 100644 --- a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c +++ b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c @@ -548,9 +548,11 @@ static int ltk050h3146w_probe(struct mipi_dsi_device *dsi) struct ltk050h3146w *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct ltk050h3146w, panel, + <k050h3146w_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->panel_desc = of_device_get_match_data(dev); if (!ctx->panel_desc) @@ -577,9 +579,6 @@ static int ltk050h3146w_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = ctx->panel_desc->mode_flags; - drm_panel_init(&ctx->panel, &dsi->dev, <k050h3146w_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c index 6b18cf00fd4a..7f19fd5b8060 100644 --- a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c +++ b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c @@ -604,9 +604,11 @@ static int ltk500hd1829_probe(struct mipi_dsi_device *dsi) struct device *dev = &dsi->dev; int ret; - ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct ltk500hd1829, panel, + <k500hd1829_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->panel_desc = of_device_get_match_data(dev); if (!ctx->panel_desc) @@ -643,9 +645,6 @@ static int ltk500hd1829_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET; - drm_panel_init(&ctx->panel, &dsi->dev, <k500hd1829_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-lg-lb035q02.c b/drivers/gpu/drm/panel/panel-lg-lb035q02.c index 9d0d4faa3f58..b2be6727bf73 100644 --- a/drivers/gpu/drm/panel/panel-lg-lb035q02.c +++ b/drivers/gpu/drm/panel/panel-lg-lb035q02.c @@ -178,9 +178,10 @@ static int lb035q02_probe(struct spi_device *spi) struct lb035q02_device *lcd; int ret; - lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); - if (!lcd) - return -ENOMEM; + lcd = devm_drm_panel_alloc(&spi->dev, struct lb035q02_device, panel, + &lb035q02_funcs, DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(lcd)) + return PTR_ERR(lcd); spi_set_drvdata(spi, lcd); lcd->spi = spi; @@ -195,9 +196,6 @@ static int lb035q02_probe(struct spi_device *spi) if (ret < 0) return ret; - drm_panel_init(&lcd->panel, &lcd->spi->dev, &lb035q02_funcs, - DRM_MODE_CONNECTOR_DPI); - drm_panel_add(&lcd->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-lg-lg4573.c b/drivers/gpu/drm/panel/panel-lg-lg4573.c index cf246d15b7b6..dec619902c15 100644 --- a/drivers/gpu/drm/panel/panel-lg-lg4573.c +++ b/drivers/gpu/drm/panel/panel-lg-lg4573.c @@ -243,9 +243,11 @@ static int lg4573_probe(struct spi_device *spi) struct lg4573 *ctx; int ret; - ctx = devm_kzalloc(&spi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&spi->dev, struct lg4573, panel, + &lg4573_drm_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->spi = spi; @@ -258,9 +260,6 @@ static int lg4573_probe(struct spi_device *spi) return ret; } - drm_panel_init(&ctx->panel, &spi->dev, &lg4573_drm_funcs, - DRM_MODE_CONNECTOR_DPI); - drm_panel_add(&ctx->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c index f3dcc39670ea..46a56ea92ad9 100644 --- a/drivers/gpu/drm/panel/panel-lg-sw43408.c +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c @@ -246,8 +246,6 @@ static int sw43408_add(struct sw43408_panel *ctx) ctx->base.prepare_prev_first = true; - drm_panel_init(&ctx->base, dev, &sw43408_funcs, DRM_MODE_CONNECTOR_DSI); - drm_panel_add(&ctx->base); return ret; } @@ -257,9 +255,11 @@ static int sw43408_probe(struct mipi_dsi_device *dsi) struct sw43408_panel *ctx; int ret; - ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&dsi->dev, __typeof(*ctx), base, + &sw43408_funcs, DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(ctx)) + return PTR_ERR(ctx); dsi->mode_flags = MIPI_DSI_MODE_LPM; dsi->format = MIPI_DSI_FMT_RGB888; diff --git a/drivers/gpu/drm/panel/panel-lincolntech-lcd197.c b/drivers/gpu/drm/panel/panel-lincolntech-lcd197.c index 032c542aab0f..24b34443ace0 100644 --- a/drivers/gpu/drm/panel/panel-lincolntech-lcd197.c +++ b/drivers/gpu/drm/panel/panel-lincolntech-lcd197.c @@ -190,9 +190,11 @@ static int lincoln_lcd197_panel_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = (MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST); - lcd = devm_kzalloc(&dsi->dev, sizeof(*lcd), GFP_KERNEL); - if (!lcd) - return -ENOMEM; + lcd = devm_drm_panel_alloc(dev, struct lincoln_lcd197_panel, panel, + &lincoln_lcd197_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(lcd)) + return PTR_ERR(lcd); mipi_dsi_set_drvdata(dsi, lcd); lcd->dsi = dsi; @@ -214,9 +216,6 @@ static int lincoln_lcd197_panel_probe(struct mipi_dsi_device *dsi) return dev_err_probe(dev, PTR_ERR(lcd->reset_gpio), "failed to get reset gpio"); - drm_panel_init(&lcd->panel, dev, - &lincoln_lcd197_panel_funcs, DRM_MODE_CONNECTOR_DSI); - err = drm_panel_of_backlight(&lcd->panel); if (err) return err; diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c index ba6c015aabba..23fd535d8f47 100644 --- a/drivers/gpu/drm/panel/panel-lvds.c +++ b/drivers/gpu/drm/panel/panel-lvds.c @@ -164,9 +164,11 @@ static int panel_lvds_probe(struct platform_device *pdev) struct panel_lvds *lvds; int ret; - lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); - if (!lvds) - return -ENOMEM; + lvds = devm_drm_panel_alloc(&pdev->dev, struct panel_lvds, panel, + &panel_lvds_funcs, + DRM_MODE_CONNECTOR_LVDS); + if (IS_ERR(lvds)) + return PTR_ERR(lvds); lvds->dev = &pdev->dev; @@ -214,10 +216,6 @@ static int panel_lvds_probe(struct platform_device *pdev) * driver. */ - /* Register the panel. */ - drm_panel_init(&lvds->panel, lvds->dev, &panel_lvds_funcs, - DRM_MODE_CONNECTOR_LVDS); - ret = drm_panel_of_backlight(&lvds->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c b/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c index 799c2161fc85..cde168ec631c 100644 --- a/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c +++ b/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c @@ -370,9 +370,11 @@ static int d53e6ea8966_probe(struct spi_device *spi) .node = NULL, }; - db = devm_kzalloc(dev, sizeof(*db), GFP_KERNEL); - if (!db) - return -ENOMEM; + db = devm_drm_panel_alloc(dev, struct d53e6ea8966, panel, + &d53e6ea8966_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(db)) + return PTR_ERR(db); spi_set_drvdata(spi, db); @@ -425,9 +427,6 @@ static int d53e6ea8966_probe(struct spi_device *spi) db->dsi_dev->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET; - drm_panel_init(&db->panel, dev, &d53e6ea8966_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - if (db->panel_info->backlight_register) { ret = db->panel_info->backlight_register(db); if (ret < 0) diff --git a/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c b/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c index 4db852ffb0f6..55664f5d5aa5 100644 --- a/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c +++ b/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c @@ -234,9 +234,11 @@ static int mantix_probe(struct mipi_dsi_device *dsi) struct mantix *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct mantix, panel, &mantix_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + ctx->default_mode = of_device_get_match_data(dev); ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); @@ -271,9 +273,6 @@ static int mantix_probe(struct mipi_dsi_device *dsi) if (IS_ERR(ctx->vddi)) return dev_err_probe(dev, PTR_ERR(ctx->vddi), "Failed to request vddi regulator\n"); - drm_panel_init(&ctx->panel, dev, &mantix_drm_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c b/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c index 81c5c541a351..d5c7210de4af 100644 --- a/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c +++ b/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c @@ -178,9 +178,10 @@ static int nl8048_probe(struct spi_device *spi) struct nl8048_panel *lcd; int ret; - lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); - if (!lcd) - return -ENOMEM; + lcd = devm_drm_panel_alloc(&spi->dev, struct nl8048_panel, panel, + &nl8048_funcs, DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(lcd)) + return PTR_ERR(lcd); spi_set_drvdata(spi, lcd); lcd->spi = spi; @@ -204,9 +205,6 @@ static int nl8048_probe(struct spi_device *spi) if (ret < 0) return ret; - drm_panel_init(&lcd->panel, &lcd->spi->dev, &nl8048_funcs, - DRM_MODE_CONNECTOR_DPI); - drm_panel_add(&lcd->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c index b6429795e8f5..22560384e48e 100644 --- a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c +++ b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c @@ -361,9 +361,11 @@ static int panel_nv3051d_probe(struct mipi_dsi_device *dsi) struct panel_nv3051d *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct panel_nv3051d, panel, + &panel_nv3051d_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->dev = dev; @@ -391,9 +393,6 @@ static int panel_nv3051d_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = ctx->panel_info->mode_flags; - drm_panel_init(&ctx->panel, &dsi->dev, &panel_nv3051d_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c index 06e16a7c14a7..0db9cadd868e 100644 --- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c @@ -777,9 +777,10 @@ static int nv3052c_probe(struct spi_device *spi) struct nv3052c *priv; int err; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = devm_drm_panel_alloc(dev, struct nv3052c, panel, &nv3052c_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(priv)) + return PTR_ERR(priv); priv->dev = dev; @@ -803,9 +804,6 @@ static int nv3052c_probe(struct spi_device *spi) spi_set_drvdata(spi, priv); - drm_panel_init(&priv->panel, dev, &nv3052c_funcs, - DRM_MODE_CONNECTOR_DPI); - err = drm_panel_of_backlight(&priv->panel); if (err) return dev_err_probe(dev, err, "Failed to attach backlight\n"); diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35510.c b/drivers/gpu/drm/panel/panel-novatek-nt35510.c index 549b86f2cc28..3189d89c7ca0 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35510.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35510.c @@ -1087,9 +1087,12 @@ static int nt35510_probe(struct mipi_dsi_device *dsi) struct nt35510 *nt; int ret; - nt = devm_kzalloc(dev, sizeof(struct nt35510), GFP_KERNEL); - if (!nt) - return -ENOMEM; + nt = devm_drm_panel_alloc(dev, struct nt35510, panel, + &nt35510_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(nt)) + return PTR_ERR(nt); + mipi_dsi_set_drvdata(dsi, nt); nt->dev = dev; @@ -1142,9 +1145,6 @@ static int nt35510_probe(struct mipi_dsi_device *dsi) return PTR_ERR(nt->reset_gpio); } - drm_panel_init(&nt->panel, dev, &nt35510_drm_funcs, - DRM_MODE_CONNECTOR_DSI); - /* * First, try to locate an external backlight (such as on GPIO) * if this fails, assume we will want to use the internal backlight diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35560.c b/drivers/gpu/drm/panel/panel-novatek-nt35560.c index 5bbea734123b..98f0782c8411 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35560.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35560.c @@ -456,9 +456,12 @@ static int nt35560_probe(struct mipi_dsi_device *dsi) struct nt35560 *nt; int ret; - nt = devm_kzalloc(dev, sizeof(struct nt35560), GFP_KERNEL); - if (!nt) - return -ENOMEM; + nt = devm_drm_panel_alloc(dev, struct nt35560, panel, + &nt35560_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(nt)) + return PTR_ERR(nt); + nt->video_mode = of_property_read_bool(dev->of_node, "enforce-video-mode"); @@ -502,9 +505,6 @@ static int nt35560_probe(struct mipi_dsi_device *dsi) return dev_err_probe(dev, PTR_ERR(nt->reset_gpio), "failed to request GPIO\n"); - drm_panel_init(&nt->panel, dev, &nt35560_drm_funcs, - DRM_MODE_CONNECTOR_DSI); - nt->panel.backlight = devm_backlight_device_register(dev, "nt35560", dev, nt, &nt35560_bl_ops, &nt35560_bl_props); if (IS_ERR(nt->panel.backlight)) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35950.c b/drivers/gpu/drm/panel/panel-novatek-nt35950.c index 08b22b592ab0..94aa6489d99f 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35950.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35950.c @@ -449,9 +449,10 @@ static int nt35950_probe(struct mipi_dsi_device *dsi) const struct mipi_dsi_device_info *info; int i, num_dsis = 1, ret; - nt = devm_kzalloc(dev, sizeof(*nt), GFP_KERNEL); - if (!nt) - return -ENOMEM; + nt = devm_drm_panel_alloc(dev, struct nt35950, panel, &nt35950_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(nt)) + return PTR_ERR(nt); ret = nt35950_sharp_init_vregs(nt, dev); if (ret) @@ -491,9 +492,6 @@ static int nt35950_probe(struct mipi_dsi_device *dsi) nt->dsi[0] = dsi; mipi_dsi_set_drvdata(dsi, nt); - drm_panel_init(&nt->panel, dev, &nt35950_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&nt->panel); if (ret) { if (num_dsis == 2) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index 116d67bfa114..32cf64c7c18b 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -1171,9 +1171,11 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) const struct mipi_dsi_device_info *info; int i, ret; - pinfo = devm_kzalloc(dev, sizeof(*pinfo), GFP_KERNEL); - if (!pinfo) - return -ENOMEM; + pinfo = devm_drm_panel_alloc(dev, struct panel_info, panel, + &nt36523_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(pinfo)) + return PTR_ERR(pinfo); pinfo->vddio = devm_regulator_get(dev, "vddio"); if (IS_ERR(pinfo->vddio)) @@ -1211,7 +1213,6 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) pinfo->dsi[0] = dsi; mipi_dsi_set_drvdata(dsi, pinfo); - drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI); ret = of_drm_get_panel_orientation(dev->of_node, &pinfo->orientation); if (ret < 0) { diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c index c2abd20e0734..29e1f6aea480 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c @@ -608,8 +608,6 @@ static int nt36672a_panel_add(struct nt36672a_panel *pinfo) return dev_err_probe(dev, PTR_ERR(pinfo->reset_gpio), "failed to get reset gpio from DT\n"); - drm_panel_init(&pinfo->base, dev, &panel_funcs, DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&pinfo->base); if (ret) return dev_err_probe(dev, ret, "Failed to get backlight\n"); @@ -625,9 +623,11 @@ static int nt36672a_panel_probe(struct mipi_dsi_device *dsi) const struct nt36672a_panel_desc *desc; int err; - pinfo = devm_kzalloc(&dsi->dev, sizeof(*pinfo), GFP_KERNEL); - if (!pinfo) - return -ENOMEM; + pinfo = devm_drm_panel_alloc(&dsi->dev, __typeof(*pinfo), base, + &panel_funcs, DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(pinfo)) + return PTR_ERR(pinfo); desc = of_device_get_match_data(&dsi->dev); dsi->mode_flags = desc->mode_flags; diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c index 8c9e04207ba9..c5e00eb55722 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c @@ -522,9 +522,11 @@ static int nt36672e_panel_probe(struct mipi_dsi_device *dsi) struct nt36672e_panel *ctx; int i, ret = 0; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct nt36672e_panel, panel, + &nt36672e_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->desc = of_device_get_match_data(dev); if (!ctx->desc) { @@ -553,8 +555,6 @@ static int nt36672e_panel_probe(struct mipi_dsi_device *dsi) dsi->format = ctx->desc->format; dsi->mode_flags = ctx->desc->mode_flags; - drm_panel_init(&ctx->panel, dev, &nt36672e_drm_funcs, DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return dev_err_probe(dev, ret, "Failed to get backlight\n"); diff --git a/drivers/gpu/drm/panel/panel-novatek-nt39016.c b/drivers/gpu/drm/panel/panel-novatek-nt39016.c index 9fa7654e2b67..a629976bae54 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt39016.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt39016.c @@ -246,9 +246,10 @@ static int nt39016_probe(struct spi_device *spi) struct nt39016 *panel; int err; - panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); - if (!panel) - return -ENOMEM; + panel = devm_drm_panel_alloc(dev, struct nt39016, drm_panel, &nt39016_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(panel)) + return PTR_ERR(panel); spi_set_drvdata(spi, panel); @@ -279,9 +280,6 @@ static int nt39016_probe(struct spi_device *spi) return PTR_ERR(panel->map); } - drm_panel_init(&panel->drm_panel, dev, &nt39016_funcs, - DRM_MODE_CONNECTOR_DPI); - err = drm_panel_of_backlight(&panel->drm_panel); if (err) return dev_err_probe(dev, err, "Failed to get backlight handle\n"); diff --git a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c index 94ae8c8270b8..66f99982f360 100644 --- a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c +++ b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c @@ -175,9 +175,11 @@ static int lcd_olinuxino_probe(struct i2c_client *client) I2C_FUNC_SMBUS_READ_I2C_BLOCK)) return -ENODEV; - lcd = devm_kzalloc(dev, sizeof(*lcd), GFP_KERNEL); - if (!lcd) - return -ENOMEM; + lcd = devm_drm_panel_alloc(dev, struct lcd_olinuxino, panel, + &lcd_olinuxino_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(lcd)) + return PTR_ERR(lcd); i2c_set_clientdata(client, lcd); lcd->dev = dev; @@ -234,9 +236,6 @@ static int lcd_olinuxino_probe(struct i2c_client *client) if (IS_ERR(lcd->enable_gpio)) return PTR_ERR(lcd->enable_gpio); - drm_panel_init(&lcd->panel, dev, &lcd_olinuxino_funcs, - DRM_MODE_CONNECTOR_DPI); - ret = drm_panel_of_backlight(&lcd->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c b/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c index fc87f61d4400..3231e84dc66c 100644 --- a/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c +++ b/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c @@ -237,9 +237,11 @@ static int ota5601a_probe(struct spi_device *spi) struct ota5601a *panel; int err; - panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); - if (!panel) - return -ENOMEM; + panel = devm_drm_panel_alloc(dev, struct ota5601a, drm_panel, + &ota5601a_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(panel)) + return PTR_ERR(panel); spi_set_drvdata(spi, panel); @@ -273,9 +275,6 @@ static int ota5601a_probe(struct spi_device *spi) return PTR_ERR(panel->map); } - drm_panel_init(&panel->drm_panel, dev, &ota5601a_funcs, - DRM_MODE_CONNECTOR_DPI); - err = drm_panel_of_backlight(&panel->drm_panel); if (err) { if (err != -EPROBE_DEFER) diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c index 87bbb25d119a..a0f58c3b73f6 100644 --- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c +++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c @@ -424,9 +424,11 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi) struct otm8009a *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct otm8009a, panel, + &otm8009a_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->reset_gpio)) { @@ -451,9 +453,6 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &otm8009a_drm_funcs, - DRM_MODE_CONNECTOR_DSI); - ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev), dev, ctx, &otm8009a_backlight_ops, diff --git a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c index dbea84f51514..2334b77f348c 100644 --- a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c +++ b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c @@ -132,9 +132,6 @@ static int osd101t2587_panel_add(struct osd101t2587_panel *osd101t2587) if (IS_ERR(osd101t2587->supply)) return PTR_ERR(osd101t2587->supply); - drm_panel_init(&osd101t2587->base, &osd101t2587->dsi->dev, - &osd101t2587_panel_funcs, DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&osd101t2587->base); if (ret) return ret; @@ -161,9 +158,12 @@ static int osd101t2587_panel_probe(struct mipi_dsi_device *dsi) MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET; - osd101t2587 = devm_kzalloc(&dsi->dev, sizeof(*osd101t2587), GFP_KERNEL); - if (!osd101t2587) - return -ENOMEM; + osd101t2587 = devm_drm_panel_alloc(&dsi->dev, __typeof(*osd101t2587), base, + &osd101t2587_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(osd101t2587)) + return PTR_ERR(osd101t2587); mipi_dsi_set_drvdata(dsi, osd101t2587); diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c index d1c5c9bc3c56..3c3308fc55df 100644 --- a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c +++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c @@ -166,9 +166,6 @@ static int wuxga_nt_panel_add(struct wuxga_nt_panel *wuxga_nt) if (IS_ERR(wuxga_nt->supply)) return PTR_ERR(wuxga_nt->supply); - drm_panel_init(&wuxga_nt->base, &wuxga_nt->dsi->dev, - &wuxga_nt_panel_funcs, DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&wuxga_nt->base); if (ret) return ret; @@ -196,9 +193,12 @@ static int wuxga_nt_panel_probe(struct mipi_dsi_device *dsi) MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; - wuxga_nt = devm_kzalloc(&dsi->dev, sizeof(*wuxga_nt), GFP_KERNEL); - if (!wuxga_nt) - return -ENOMEM; + wuxga_nt = devm_drm_panel_alloc(&dsi->dev, __typeof(*wuxga_nt), base, + &wuxga_nt_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(wuxga_nt)) + return PTR_ERR(wuxga_nt); mipi_dsi_set_drvdata(dsi, wuxga_nt); diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c index e10e469aa7a6..dc4bb8ad9131 100644 --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c @@ -373,9 +373,12 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c) .node = NULL, }; - ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); - if (!ts) - return -ENOMEM; + ts = devm_drm_panel_alloc(dev, __typeof(*ts), base, + &rpi_touchscreen_funcs, + DRM_MODE_CONNECTOR_DSI); + + if (IS_ERR(ts)) + return PTR_ERR(ts); i2c_set_clientdata(i2c, ts); @@ -428,9 +431,6 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c) return PTR_ERR(ts->dsi); } - drm_panel_init(&ts->base, dev, &rpi_touchscreen_funcs, - DRM_MODE_CONNECTOR_DSI); - /* This appears last, as it's what will unblock the DSI host * driver's component bind function. */ diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67191.c b/drivers/gpu/drm/panel/panel-raydium-rm67191.c index b2029e035635..2af6aa47a551 100644 --- a/drivers/gpu/drm/panel/panel-raydium-rm67191.c +++ b/drivers/gpu/drm/panel/panel-raydium-rm67191.c @@ -527,9 +527,11 @@ static int rad_panel_probe(struct mipi_dsi_device *dsi) int ret; u32 video_mode; - panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL); - if (!panel) - return -ENOMEM; + panel = devm_drm_panel_alloc(dev, struct rad_panel, panel, + &rad_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(panel)) + return PTR_ERR(panel); mipi_dsi_set_drvdata(dsi, panel); @@ -586,8 +588,6 @@ static int rad_panel_probe(struct mipi_dsi_device *dsi) if (ret) return ret; - drm_panel_init(&panel->panel, dev, &rad_panel_funcs, - DRM_MODE_CONNECTOR_DSI); dev_set_drvdata(dev, panel); drm_panel_add(&panel->panel); diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67200.c b/drivers/gpu/drm/panel/panel-raydium-rm67200.c index 64b685dc11f6..333faed62da7 100644 --- a/drivers/gpu/drm/panel/panel-raydium-rm67200.c +++ b/drivers/gpu/drm/panel/panel-raydium-rm67200.c @@ -36,12 +36,14 @@ static inline struct raydium_rm67200 *to_raydium_rm67200(struct drm_panel *panel static void raydium_rm67200_reset(struct raydium_rm67200 *ctx) { - gpiod_set_value_cansleep(ctx->reset_gpio, 0); - msleep(60); - gpiod_set_value_cansleep(ctx->reset_gpio, 1); - msleep(60); - gpiod_set_value_cansleep(ctx->reset_gpio, 0); - msleep(60); + if (ctx->reset_gpio) { + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + msleep(60); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + msleep(60); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + msleep(60); + } } static void raydium_rm67200_write(struct mipi_dsi_multi_context *ctx, @@ -318,6 +320,7 @@ static void w552793baa_setup(struct mipi_dsi_multi_context *ctx) static int raydium_rm67200_prepare(struct drm_panel *panel) { struct raydium_rm67200 *ctx = to_raydium_rm67200(panel); + struct mipi_dsi_multi_context mctx = { .dsi = ctx->dsi }; int ret; ret = regulator_bulk_enable(ctx->num_supplies, ctx->supplies); @@ -328,6 +331,12 @@ static int raydium_rm67200_prepare(struct drm_panel *panel) msleep(60); + ctx->panel_info->panel_setup(&mctx); + mipi_dsi_dcs_exit_sleep_mode_multi(&mctx); + mipi_dsi_msleep(&mctx, 120); + mipi_dsi_dcs_set_display_on_multi(&mctx); + mipi_dsi_msleep(&mctx, 30); + return 0; } @@ -343,20 +352,6 @@ static int raydium_rm67200_unprepare(struct drm_panel *panel) return 0; } -static int raydium_rm67200_enable(struct drm_panel *panel) -{ - struct raydium_rm67200 *rm67200 = to_raydium_rm67200(panel); - struct mipi_dsi_multi_context ctx = { .dsi = rm67200->dsi }; - - rm67200->panel_info->panel_setup(&ctx); - mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); - mipi_dsi_msleep(&ctx, 120); - mipi_dsi_dcs_set_display_on_multi(&ctx); - mipi_dsi_msleep(&ctx, 30); - - return ctx.accum_err; -} - static int raydium_rm67200_disable(struct drm_panel *panel) { struct raydium_rm67200 *rm67200 = to_raydium_rm67200(panel); @@ -381,7 +376,6 @@ static const struct drm_panel_funcs raydium_rm67200_funcs = { .prepare = raydium_rm67200_prepare, .unprepare = raydium_rm67200_unprepare, .get_modes = raydium_rm67200_get_modes, - .enable = raydium_rm67200_enable, .disable = raydium_rm67200_disable, }; @@ -391,9 +385,11 @@ static int raydium_rm67200_probe(struct mipi_dsi_device *dsi) struct raydium_rm67200 *ctx; int ret = 0; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct raydium_rm67200, panel, + &raydium_rm67200_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->panel_info = device_get_match_data(dev); if (!ctx->panel_info) @@ -407,7 +403,7 @@ static int raydium_rm67200_probe(struct mipi_dsi_device *dsi) if (ret < 0) return ret; - ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->reset_gpio)) return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "Failed to get reset-gpios\n"); @@ -421,9 +417,6 @@ static int raydium_rm67200_probe(struct mipi_dsi_device *dsi) MIPI_DSI_MODE_LPM; ctx->panel.prepare_prev_first = true; - drm_panel_init(&ctx->panel, dev, &raydium_rm67200_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; @@ -471,6 +464,7 @@ static const struct raydium_rm67200_panel_info w552793baa_info = { .vtotal = 1952, .width_mm = 68, /* 68.04mm */ .height_mm = 121, /* 120.96mm */ + .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, .type = DRM_MODE_TYPE_DRIVER, }, .regulators = w552793baa_regulators, diff --git a/drivers/gpu/drm/panel/panel-raydium-rm68200.c b/drivers/gpu/drm/panel/panel-raydium-rm68200.c index 7b7fe987e292..669b5f5c1ad9 100644 --- a/drivers/gpu/drm/panel/panel-raydium-rm68200.c +++ b/drivers/gpu/drm/panel/panel-raydium-rm68200.c @@ -327,9 +327,11 @@ static int rm68200_probe(struct mipi_dsi_device *dsi) struct rm68200 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct rm68200, panel, + &rm68200_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->reset_gpio)) { @@ -355,9 +357,6 @@ static int rm68200_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &rm68200_drm_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-raydium-rm692e5.c b/drivers/gpu/drm/panel/panel-raydium-rm692e5.c index ea1b728e85a2..8e9484768657 100644 --- a/drivers/gpu/drm/panel/panel-raydium-rm692e5.c +++ b/drivers/gpu/drm/panel/panel-raydium-rm692e5.c @@ -281,9 +281,11 @@ static int rm692e5_probe(struct mipi_dsi_device *dsi) struct rm692e5_panel *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct rm692e5_panel, panel, + &rm692e5_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->supplies[0].supply = "vddio"; ctx->supplies[1].supply = "dvdd"; @@ -306,8 +308,6 @@ static int rm692e5_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &rm692e5_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ctx->panel.backlight = rm692e5_create_backlight(dsi); diff --git a/drivers/gpu/drm/panel/panel-raydium-rm69380.c b/drivers/gpu/drm/panel/panel-raydium-rm69380.c index d3071c01aaea..86769cadec97 100644 --- a/drivers/gpu/drm/panel/panel-raydium-rm69380.c +++ b/drivers/gpu/drm/panel/panel-raydium-rm69380.c @@ -208,9 +208,11 @@ static int rm69380_probe(struct mipi_dsi_device *dsi) struct device_node *dsi_sec; int ret, i; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct rm69380_panel, panel, + &rm69380_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->supplies[0].supply = "vddio"; ctx->supplies[1].supply = "avdd"; @@ -248,8 +250,6 @@ static int rm69380_probe(struct mipi_dsi_device *dsi) ctx->dsi[0] = dsi; mipi_dsi_set_drvdata(dsi, ctx); - drm_panel_init(&ctx->panel, dev, &rm69380_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ctx->panel.backlight = rm69380_create_backlight(dsi); diff --git a/drivers/gpu/drm/panel/panel-renesas-r61307.c b/drivers/gpu/drm/panel/panel-renesas-r61307.c new file mode 100644 index 000000000000..319415194839 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-renesas-r61307.c @@ -0,0 +1,325 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/array_size.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> + +#define R61307_MACP 0xb0 /* Manufacturer CMD Protect */ +#define R61307_MACP_ON 0x03 +#define R61307_MACP_OFF 0x04 + +#define R61307_INVERSION 0xc1 +#define R61307_GAMMA_SET_A 0xc8 /* Gamma Setting A */ +#define R61307_GAMMA_SET_B 0xc9 /* Gamma Setting B */ +#define R61307_GAMMA_SET_C 0xca /* Gamma Setting C */ +#define R61307_CONTRAST_SET 0xcc + +struct renesas_r61307 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + + struct regulator *vcc_supply; + struct regulator *iovcc_supply; + + struct gpio_desc *reset_gpio; + + bool prepared; + + bool dig_cont_adj; + bool inversion; + u32 gamma; +}; + +static const u8 gamma_setting[][25] = { + { /* sentinel */ }, + { + R61307_GAMMA_SET_A, + 0x00, 0x06, 0x0a, 0x0f, + 0x14, 0x1f, 0x1f, 0x17, + 0x12, 0x0c, 0x09, 0x06, + 0x00, 0x06, 0x0a, 0x0f, + 0x14, 0x1f, 0x1f, 0x17, + 0x12, 0x0c, 0x09, 0x06 + }, + { + R61307_GAMMA_SET_A, + 0x00, 0x05, 0x0b, 0x0f, + 0x11, 0x1d, 0x20, 0x18, + 0x18, 0x09, 0x07, 0x06, + 0x00, 0x05, 0x0b, 0x0f, + 0x11, 0x1d, 0x20, 0x18, + 0x18, 0x09, 0x07, 0x06 + }, + { + R61307_GAMMA_SET_A, + 0x0b, 0x0d, 0x10, 0x14, + 0x13, 0x1d, 0x20, 0x18, + 0x12, 0x09, 0x07, 0x06, + 0x0a, 0x0c, 0x10, 0x14, + 0x13, 0x1d, 0x20, 0x18, + 0x12, 0x09, 0x07, 0x06 + }, +}; + +static inline struct renesas_r61307 *to_renesas_r61307(struct drm_panel *panel) +{ + return container_of(panel, struct renesas_r61307, panel); +} + +static void renesas_r61307_reset(struct renesas_r61307 *priv) +{ + gpiod_set_value_cansleep(priv->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(priv->reset_gpio, 0); + usleep_range(2000, 3000); +} + +static int renesas_r61307_prepare(struct drm_panel *panel) +{ + struct renesas_r61307 *priv = to_renesas_r61307(panel); + struct device *dev = &priv->dsi->dev; + int ret; + + if (priv->prepared) + return 0; + + ret = regulator_enable(priv->vcc_supply); + if (ret) { + dev_err(dev, "failed to enable vcc power supply\n"); + return ret; + } + + usleep_range(2000, 3000); + + ret = regulator_enable(priv->iovcc_supply); + if (ret) { + dev_err(dev, "failed to enable iovcc power supply\n"); + return ret; + } + + usleep_range(2000, 3000); + + renesas_r61307_reset(priv); + + priv->prepared = true; + return 0; +} + +static int renesas_r61307_enable(struct drm_panel *panel) +{ + struct renesas_r61307 *priv = to_renesas_r61307(panel); + struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi }; + + mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); + mipi_dsi_msleep(&ctx, 80); + + mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00); + mipi_dsi_msleep(&ctx, 20); + + mipi_dsi_dcs_set_pixel_format_multi(&ctx, MIPI_DCS_PIXEL_FMT_24BIT << 4); + + /* MACP Off */ + mipi_dsi_generic_write_seq_multi(&ctx, R61307_MACP, R61307_MACP_OFF); + + if (priv->dig_cont_adj) + mipi_dsi_generic_write_seq_multi(&ctx, R61307_CONTRAST_SET, + 0xdc, 0xb4, 0xff); + + if (priv->gamma) + mipi_dsi_generic_write_multi(&ctx, gamma_setting[priv->gamma], + sizeof(gamma_setting[priv->gamma])); + + if (priv->inversion) + mipi_dsi_generic_write_seq_multi(&ctx, R61307_INVERSION, + 0x00, 0x50, 0x03, 0x22, + 0x16, 0x06, 0x60, 0x11); + else + mipi_dsi_generic_write_seq_multi(&ctx, R61307_INVERSION, + 0x00, 0x10, 0x03, 0x22, + 0x16, 0x06, 0x60, 0x01); + + /* MACP On */ + mipi_dsi_generic_write_seq_multi(&ctx, R61307_MACP, R61307_MACP_ON); + + mipi_dsi_dcs_set_display_on_multi(&ctx); + mipi_dsi_msleep(&ctx, 50); + + return 0; +} + +static int renesas_r61307_disable(struct drm_panel *panel) +{ + struct renesas_r61307 *priv = to_renesas_r61307(panel); + struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi }; + + mipi_dsi_dcs_set_display_off_multi(&ctx); + mipi_dsi_msleep(&ctx, 100); + mipi_dsi_dcs_enter_sleep_mode_multi(&ctx); + + return 0; +} + +static int renesas_r61307_unprepare(struct drm_panel *panel) +{ + struct renesas_r61307 *priv = to_renesas_r61307(panel); + + if (!priv->prepared) + return 0; + + usleep_range(10000, 11000); + + gpiod_set_value_cansleep(priv->reset_gpio, 1); + usleep_range(5000, 6000); + + regulator_disable(priv->iovcc_supply); + usleep_range(2000, 3000); + regulator_disable(priv->vcc_supply); + + priv->prepared = false; + return 0; +} + +static const struct drm_display_mode renesas_r61307_mode = { + .clock = (768 + 116 + 81 + 5) * (1024 + 24 + 8 + 2) * 60 / 1000, + .hdisplay = 768, + .hsync_start = 768 + 116, + .hsync_end = 768 + 116 + 81, + .htotal = 768 + 116 + 81 + 5, + .vdisplay = 1024, + .vsync_start = 1024 + 24, + .vsync_end = 1024 + 24 + 8, + .vtotal = 1024 + 24 + 8 + 2, + .width_mm = 76, + .height_mm = 101, +}; + +static int renesas_r61307_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, &renesas_r61307_mode); + if (!mode) + return -ENOMEM; + + drm_mode_set_name(mode); + + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; + drm_mode_probed_add(connector, mode); + + return 1; +} + +static const struct drm_panel_funcs renesas_r61307_panel_funcs = { + .prepare = renesas_r61307_prepare, + .enable = renesas_r61307_enable, + .disable = renesas_r61307_disable, + .unprepare = renesas_r61307_unprepare, + .get_modes = renesas_r61307_get_modes, +}; + +static int renesas_r61307_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct renesas_r61307 *priv; + int ret; + + priv = devm_drm_panel_alloc(dev, struct renesas_r61307, panel, + &renesas_r61307_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(priv)) + return PTR_ERR(priv); + + priv->vcc_supply = devm_regulator_get(dev, "vcc"); + if (IS_ERR(priv->vcc_supply)) + return dev_err_probe(dev, PTR_ERR(priv->vcc_supply), + "Failed to get vcc-supply\n"); + + priv->iovcc_supply = devm_regulator_get(dev, "iovcc"); + if (IS_ERR(priv->iovcc_supply)) + return dev_err_probe(dev, PTR_ERR(priv->iovcc_supply), + "Failed to get iovcc-supply\n"); + + priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(priv->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), + "Failed to get reset gpios\n"); + + if (device_property_read_bool(dev, "renesas,inversion")) + priv->inversion = true; + + if (device_property_read_bool(dev, "renesas,contrast")) + priv->dig_cont_adj = true; + + priv->gamma = 0; + device_property_read_u32(dev, "renesas,gamma", &priv->gamma); + + priv->dsi = dsi; + mipi_dsi_set_drvdata(dsi, priv); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; + + ret = drm_panel_of_backlight(&priv->panel); + if (ret) + return dev_err_probe(dev, ret, "Failed to get backlight\n"); + + drm_panel_add(&priv->panel); + + ret = mipi_dsi_attach(dsi); + if (ret) { + drm_panel_remove(&priv->panel); + return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); + } + + return 0; +} + +static void renesas_r61307_remove(struct mipi_dsi_device *dsi) +{ + struct renesas_r61307 *priv = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&priv->panel); +} + +static const struct of_device_id renesas_r61307_of_match[] = { + { .compatible = "hit,tx13d100vm0eaa" }, + { .compatible = "koe,tx13d100vm0eaa" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, renesas_r61307_of_match); + +static struct mipi_dsi_driver renesas_r61307_driver = { + .probe = renesas_r61307_probe, + .remove = renesas_r61307_remove, + .driver = { + .name = "panel-renesas-r61307", + .of_match_table = renesas_r61307_of_match, + }, +}; +module_mipi_dsi_driver(renesas_r61307_driver); + +MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>"); +MODULE_DESCRIPTION("Renesas R61307-based panel driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-renesas-r69328.c b/drivers/gpu/drm/panel/panel-renesas-r69328.c new file mode 100644 index 000000000000..46287ab04c30 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-renesas-r69328.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/array_size.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> + +#define R69328_MACP 0xb0 /* Manufacturer Access CMD Protect */ +#define R69328_MACP_ON 0x03 +#define R69328_MACP_OFF 0x04 + +#define R69328_GAMMA_SET_A 0xc8 /* Gamma Setting A */ +#define R69328_GAMMA_SET_B 0xc9 /* Gamma Setting B */ +#define R69328_GAMMA_SET_C 0xca /* Gamma Setting C */ + +#define R69328_POWER_SET 0xd1 + +struct renesas_r69328 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + + struct regulator *vdd_supply; + struct regulator *vddio_supply; + struct gpio_desc *reset_gpio; + + bool prepared; +}; + +static inline struct renesas_r69328 *to_renesas_r69328(struct drm_panel *panel) +{ + return container_of(panel, struct renesas_r69328, panel); +} + +static void renesas_r69328_reset(struct renesas_r69328 *priv) +{ + gpiod_set_value_cansleep(priv->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(priv->reset_gpio, 0); + usleep_range(2000, 3000); +} + +static int renesas_r69328_prepare(struct drm_panel *panel) +{ + struct renesas_r69328 *priv = to_renesas_r69328(panel); + struct device *dev = &priv->dsi->dev; + int ret; + + if (priv->prepared) + return 0; + + ret = regulator_enable(priv->vdd_supply); + if (ret) { + dev_err(dev, "failed to enable vdd power supply\n"); + return ret; + } + + usleep_range(10000, 11000); + + ret = regulator_enable(priv->vddio_supply); + if (ret < 0) { + dev_err(dev, "failed to enable vddio power supply\n"); + return ret; + } + + usleep_range(10000, 11000); + + renesas_r69328_reset(priv); + + priv->prepared = true; + return 0; +} + +static int renesas_r69328_enable(struct drm_panel *panel) +{ + struct renesas_r69328 *priv = to_renesas_r69328(panel); + struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi }; + + /* Set address mode */ + mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00); + mipi_dsi_dcs_set_pixel_format_multi(&ctx, MIPI_DCS_PIXEL_FMT_24BIT << 4); + mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); + + mipi_dsi_msleep(&ctx, 100); + + /* MACP Off */ + mipi_dsi_generic_write_seq_multi(&ctx, R69328_MACP, R69328_MACP_OFF); + + mipi_dsi_generic_write_seq_multi(&ctx, R69328_POWER_SET, 0x14, 0x1d, + 0x21, 0x67, 0x11, 0x9a); + + mipi_dsi_generic_write_seq_multi(&ctx, R69328_GAMMA_SET_A, 0x00, 0x1a, + 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1e, 0x1c, 0x00, 0x00, 0x1a, + 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1e, 0x1c, 0x00); + + mipi_dsi_generic_write_seq_multi(&ctx, R69328_GAMMA_SET_B, 0x00, 0x1a, + 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1e, 0x1c, 0x00, 0x00, 0x1a, + 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1e, 0x1c, 0x00); + + mipi_dsi_generic_write_seq_multi(&ctx, R69328_GAMMA_SET_C, 0x00, 0x1a, + 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1e, 0x1c, 0x00, 0x00, 0x1a, + 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1e, 0x1c, 0x00); + + /* MACP On */ + mipi_dsi_generic_write_seq_multi(&ctx, R69328_MACP, R69328_MACP_ON); + + mipi_dsi_dcs_set_display_on_multi(&ctx); + mipi_dsi_msleep(&ctx, 50); + + return 0; +} + +static int renesas_r69328_disable(struct drm_panel *panel) +{ + struct renesas_r69328 *priv = to_renesas_r69328(panel); + struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi }; + + mipi_dsi_dcs_set_display_off_multi(&ctx); + mipi_dsi_msleep(&ctx, 60); + mipi_dsi_dcs_enter_sleep_mode_multi(&ctx); + + return 0; +} + +static int renesas_r69328_unprepare(struct drm_panel *panel) +{ + struct renesas_r69328 *priv = to_renesas_r69328(panel); + + if (!priv->prepared) + return 0; + + gpiod_set_value_cansleep(priv->reset_gpio, 1); + + usleep_range(5000, 6000); + + regulator_disable(priv->vddio_supply); + regulator_disable(priv->vdd_supply); + + priv->prepared = false; + return 0; +} + +static const struct drm_display_mode renesas_r69328_mode = { + .clock = (720 + 92 + 62 + 4) * (1280 + 6 + 3 + 1) * 60 / 1000, + .hdisplay = 720, + .hsync_start = 720 + 92, + .hsync_end = 720 + 92 + 62, + .htotal = 720 + 92 + 62 + 4, + .vdisplay = 1280, + .vsync_start = 1280 + 6, + .vsync_end = 1280 + 6 + 3, + .vtotal = 1280 + 6 + 3 + 1, + .width_mm = 59, + .height_mm = 105, +}; + +static int renesas_r69328_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, &renesas_r69328_mode); + if (!mode) + return -ENOMEM; + + drm_mode_set_name(mode); + + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; + drm_mode_probed_add(connector, mode); + + return 1; +} + +static const struct drm_panel_funcs renesas_r69328_panel_funcs = { + .prepare = renesas_r69328_prepare, + .enable = renesas_r69328_enable, + .disable = renesas_r69328_disable, + .unprepare = renesas_r69328_unprepare, + .get_modes = renesas_r69328_get_modes, +}; + +static int renesas_r69328_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct renesas_r69328 *priv; + int ret; + + priv = devm_drm_panel_alloc(dev, struct renesas_r69328, panel, + &renesas_r69328_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(priv)) + return PTR_ERR(priv); + + priv->vdd_supply = devm_regulator_get(dev, "vdd"); + if (IS_ERR(priv->vdd_supply)) + return dev_err_probe(dev, PTR_ERR(priv->vdd_supply), + "Failed to get vdd-supply\n"); + + priv->vddio_supply = devm_regulator_get(dev, "vddio"); + if (IS_ERR(priv->vddio_supply)) + return dev_err_probe(dev, PTR_ERR(priv->vddio_supply), + "Failed to get vddio-supply\n"); + + priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(priv->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), + "Failed to get reset-gpios\n"); + + priv->dsi = dsi; + mipi_dsi_set_drvdata(dsi, priv); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; + + ret = drm_panel_of_backlight(&priv->panel); + if (ret) + return dev_err_probe(dev, ret, "Failed to get backlight\n"); + + drm_panel_add(&priv->panel); + + ret = mipi_dsi_attach(dsi); + if (ret) { + drm_panel_remove(&priv->panel); + return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); + } + + return 0; +} + +static void renesas_r69328_remove(struct mipi_dsi_device *dsi) +{ + struct renesas_r69328 *priv = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&priv->panel); +} + +static const struct of_device_id renesas_r69328_of_match[] = { + { .compatible = "jdi,dx12d100vm0eaa" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, renesas_r69328_of_match); + +static struct mipi_dsi_driver renesas_r69328_driver = { + .probe = renesas_r69328_probe, + .remove = renesas_r69328_remove, + .driver = { + .name = "panel-renesas-r69328", + .of_match_table = renesas_r69328_of_match, + }, +}; +module_mipi_dsi_driver(renesas_r69328_driver); + +MODULE_AUTHOR("Maxim Schwalm <maxim.schwalm@gmail.com>"); +MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>"); +MODULE_DESCRIPTION("Renesas R69328-based panel driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c b/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c index 2ef5ea5eaeeb..ad35d0fb0a16 100644 --- a/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c +++ b/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c @@ -143,9 +143,11 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi) struct rb070d30_panel *ctx; int ret; - ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&dsi->dev, struct rb070d30_panel, panel, + &rb070d30_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->supply = devm_regulator_get(&dsi->dev, "vcc-lcd"); if (IS_ERR(ctx->supply)) @@ -154,9 +156,6 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi) mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; - drm_panel_init(&ctx->panel, &dsi->dev, &rb070d30_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ctx->gpios.reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->gpios.reset)) { dev_err(&dsi->dev, "Couldn't get our reset GPIO\n"); diff --git a/drivers/gpu/drm/panel/panel-samsung-ams581vf01.c b/drivers/gpu/drm/panel/panel-samsung-ams581vf01.c index cf6186312252..188dd7cf0297 100644 --- a/drivers/gpu/drm/panel/panel-samsung-ams581vf01.c +++ b/drivers/gpu/drm/panel/panel-samsung-ams581vf01.c @@ -211,9 +211,11 @@ static int ams581vf01_probe(struct mipi_dsi_device *dsi) struct ams581vf01 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(&dsi->dev, struct ams581vf01, panel, + &ams581vf01_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ret = devm_regulator_bulk_get_const(&dsi->dev, ARRAY_SIZE(ams581vf01_supplies), @@ -235,8 +237,6 @@ static int ams581vf01_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; - drm_panel_init(&ctx->panel, dev, &ams581vf01_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ctx->panel.backlight = ams581vf01_create_backlight(dsi); diff --git a/drivers/gpu/drm/panel/panel-samsung-ams639rq08.c b/drivers/gpu/drm/panel/panel-samsung-ams639rq08.c index 817365cb5e46..f8ebbd4a530b 100644 --- a/drivers/gpu/drm/panel/panel-samsung-ams639rq08.c +++ b/drivers/gpu/drm/panel/panel-samsung-ams639rq08.c @@ -257,9 +257,11 @@ static int ams639rq08_probe(struct mipi_dsi_device *dsi) struct ams639rq08 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct ams639rq08, panel, + &ams639rq08_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ret = devm_regulator_bulk_get_const(&dsi->dev, ARRAY_SIZE(ams639rq08_supplies), @@ -281,8 +283,6 @@ static int ams639rq08_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; - drm_panel_init(&ctx->panel, dev, &ams639rq08_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ctx->panel.backlight = ams639rq08_create_backlight(dsi); diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c index 9a482a744b8c..20ec27d2d6c2 100644 --- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c +++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c @@ -266,9 +266,12 @@ static int atana33xc20_probe(struct dp_aux_ep_device *aux_ep) struct device *dev = &aux_ep->dev; int ret; - panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); - if (!panel) - return -ENOMEM; + panel = devm_drm_panel_alloc(dev, struct atana33xc20_panel, base, + &atana33xc20_funcs, + DRM_MODE_CONNECTOR_eDP); + if (IS_ERR(panel)) + return PTR_ERR(panel); + dev_set_drvdata(dev, panel); panel->aux = aux_ep->aux; @@ -301,8 +304,6 @@ static int atana33xc20_probe(struct dp_aux_ep_device *aux_ep) if (ret) return ret; - drm_panel_init(&panel->base, dev, &atana33xc20_funcs, DRM_MODE_CONNECTOR_eDP); - pm_runtime_get_sync(dev); ret = drm_panel_dp_aux_backlight(&panel->base, aux_ep->aux); pm_runtime_mark_last_busy(dev); diff --git a/drivers/gpu/drm/panel/panel-samsung-db7430.c b/drivers/gpu/drm/panel/panel-samsung-db7430.c index 14c6700e37b3..a97182f3c990 100644 --- a/drivers/gpu/drm/panel/panel-samsung-db7430.c +++ b/drivers/gpu/drm/panel/panel-samsung-db7430.c @@ -267,9 +267,11 @@ static int db7430_probe(struct spi_device *spi) struct db7430 *db; int ret; - db = devm_kzalloc(dev, sizeof(*db), GFP_KERNEL); - if (!db) - return -ENOMEM; + db = devm_drm_panel_alloc(dev, struct db7430, panel, &db7430_drm_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(db)) + return PTR_ERR(db); + db->dev = dev; /* @@ -294,9 +296,6 @@ static int db7430_probe(struct spi_device *spi) if (ret) return dev_err_probe(dev, ret, "MIPI DBI init failed\n"); - drm_panel_init(&db->panel, dev, &db7430_drm_funcs, - DRM_MODE_CONNECTOR_DPI); - /* FIXME: if no external backlight, use internal backlight */ ret = drm_panel_of_backlight(&db->panel); if (ret) diff --git a/drivers/gpu/drm/panel/panel-samsung-ld9040.c b/drivers/gpu/drm/panel/panel-samsung-ld9040.c index 9f438683a6f6..c7f2241523a0 100644 --- a/drivers/gpu/drm/panel/panel-samsung-ld9040.c +++ b/drivers/gpu/drm/panel/panel-samsung-ld9040.c @@ -339,9 +339,11 @@ static int ld9040_probe(struct spi_device *spi) struct ld9040 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(struct ld9040), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct ld9040, panel, + &ld9040_drm_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); spi_set_drvdata(spi, ctx); @@ -373,9 +375,6 @@ static int ld9040_probe(struct spi_device *spi) return ret; } - drm_panel_init(&ctx->panel, dev, &ld9040_drm_funcs, - DRM_MODE_CONNECTOR_DPI); - bldev = devm_backlight_device_register(dev, dev_name(dev), dev, ctx, &ld9040_bl_ops, &ld9040_bl_props); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c b/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c index 79f611963c61..ba1a02000bb9 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c @@ -166,9 +166,11 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi) struct s6d16d0 *s6; int ret; - s6 = devm_kzalloc(dev, sizeof(struct s6d16d0), GFP_KERNEL); - if (!s6) - return -ENOMEM; + s6 = devm_drm_panel_alloc(dev, struct s6d16d0, panel, + &s6d16d0_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(s6)) + return PTR_ERR(s6); mipi_dsi_set_drvdata(dsi, s6); s6->dev = dev; @@ -200,9 +202,6 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi) return ret; } - drm_panel_init(&s6->panel, dev, &s6d16d0_drm_funcs, - DRM_MODE_CONNECTOR_DSI); - drm_panel_add(&s6->panel); ret = mipi_dsi_attach(dsi); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d27a1.c b/drivers/gpu/drm/panel/panel-samsung-s6d27a1.c index 2adb223a895c..300dc19bd9d1 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6d27a1.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6d27a1.c @@ -247,9 +247,11 @@ static int s6d27a1_probe(struct spi_device *spi) struct s6d27a1 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6d27a1, panel, + &s6d27a1_drm_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->dev = dev; @@ -277,9 +279,6 @@ static int s6d27a1_probe(struct spi_device *spi) ctx->dbi.read_commands = s6d27a1_dbi_read_commands; - drm_panel_init(&ctx->panel, dev, &s6d27a1_drm_funcs, - DRM_MODE_CONNECTOR_DPI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return dev_err_probe(dev, ret, "failed to add backlight\n"); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c index 93f11e2e9398..692020081524 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c @@ -244,7 +244,7 @@ static const struct s6d7aa0_panel_desc s6d7aa0_lsl080al02_desc = { .init_func = s6d7aa0_lsl080al02_init, .off_func = s6d7aa0_lsl080al02_off, .drm_mode = &s6d7aa0_lsl080al02_mode, - .mode_flags = MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_NO_HFP, + .mode_flags = MIPI_DSI_MODE_VIDEO_NO_HFP, .bus_flags = 0, .has_backlight = false, @@ -392,9 +392,11 @@ static int s6d7aa0_probe(struct mipi_dsi_device *dsi) struct s6d7aa0 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6d7aa0, panel, + &s6d7aa0_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->desc = of_device_get_match_data(dev); if (!ctx->desc) @@ -420,8 +422,6 @@ static int s6d7aa0_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | ctx->desc->mode_flags; - drm_panel_init(&ctx->panel, dev, &s6d7aa0_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ret = drm_panel_of_backlight(&ctx->panel); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c b/drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c index 27a059b55ae5..f4d75eca3cdf 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c @@ -185,9 +185,11 @@ static int s6e3fa7_panel_probe(struct mipi_dsi_device *dsi) struct s6e3fa7_panel *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6e3fa7_panel, panel, + &s6e3fa7_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ctx->reset_gpio)) @@ -202,8 +204,6 @@ static int s6e3fa7_panel_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; - drm_panel_init(&ctx->panel, dev, &s6e3fa7_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ctx->panel.backlight = s6e3fa7_panel_create_backlight(dsi); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c index ab8b58545284..1db0c63b1131 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c @@ -681,9 +681,11 @@ static int s6e3ha2_probe(struct mipi_dsi_device *dsi) struct s6e3ha2 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6e3ha2, panel, + &s6e3ha2_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); mipi_dsi_set_drvdata(dsi, ctx); @@ -731,8 +733,6 @@ static int s6e3ha2_probe(struct mipi_dsi_device *dsi) ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS; ctx->bl_dev->props.power = BACKLIGHT_POWER_OFF; - drm_panel_init(&ctx->panel, dev, &s6e3ha2_drm_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; drm_panel_add(&ctx->panel); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c index 64c6f7d45bed..550e9ef9bb71 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c @@ -253,9 +253,11 @@ static int s6e3ha8_amb577px01_wqhd_probe(struct mipi_dsi_device *dsi) struct s6e3ha8 *priv; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + priv = devm_drm_panel_alloc(dev, struct s6e3ha8, panel, + &s6e3ha8_amb577px01_wqhd_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(priv)) + return PTR_ERR(priv); ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(s6e3ha8_supplies), s6e3ha8_supplies, @@ -279,8 +281,6 @@ static int s6e3ha8_amb577px01_wqhd_probe(struct mipi_dsi_device *dsi) MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | MIPI_DSI_MODE_VIDEO_NO_HSA | MIPI_DSI_MODE_NO_EOT_PACKET; - drm_panel_init(&priv->panel, dev, &s6e3ha8_amb577px01_wqhd_panel_funcs, - DRM_MODE_CONNECTOR_DSI); priv->panel.prepare_prev_first = true; drm_panel_add(&priv->panel); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c b/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c index 364f1c9a16d9..6f3d39556f92 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c @@ -437,9 +437,11 @@ static int s6e63j0x03_probe(struct mipi_dsi_device *dsi) struct s6e63j0x03 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(struct s6e63j0x03), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6e63j0x03, panel, + &s6e63j0x03_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); mipi_dsi_set_drvdata(dsi, ctx); @@ -462,8 +464,6 @@ static int s6e63j0x03_probe(struct mipi_dsi_device *dsi) return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "cannot get reset-gpio\n"); - drm_panel_init(&ctx->panel, dev, &s6e63j0x03_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx, diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c index 6917ffda5b2b..ea241c89593b 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c @@ -13,6 +13,7 @@ #include <linux/backlight.h> #include <linux/delay.h> +#include <linux/export.h> #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/property.h> diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams427ap24.c b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams427ap24.c index e92e95158d1f..e91f50662997 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams427ap24.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams427ap24.c @@ -687,9 +687,11 @@ static int s6e88a0_ams427ap24_probe(struct mipi_dsi_device *dsi) struct s6e88a0_ams427ap24 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6e88a0_ams427ap24, panel, + &s6e88a0_ams427ap24_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(s6e88a0_ams427ap24_supplies), @@ -711,8 +713,6 @@ static int s6e88a0_ams427ap24_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_VIDEO_NO_HFP; - drm_panel_init(&ctx->panel, dev, &s6e88a0_ams427ap24_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ctx->flip_horizontal = device_property_read_bool(dev, "flip-horizontal"); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c index 57b1a899bbdc..ca5cad41ff1d 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c @@ -165,9 +165,11 @@ static int s6e88a0_ams452ef01_probe(struct mipi_dsi_device *dsi) struct s6e88a0_ams452ef01 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6e88a0_ams452ef01, panel, + &s6e88a0_ams452ef01_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->supplies[0].supply = "vdd3"; ctx->supplies[1].supply = "vci"; @@ -192,9 +194,6 @@ static int s6e88a0_ams452ef01_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; - drm_panel_init(&ctx->panel, dev, &s6e88a0_ams452ef01_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - drm_panel_add(&ctx->panel); ret = mipi_dsi_attach(dsi); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c b/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c index c51d07ec1529..1b5c500d4f4e 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c @@ -979,9 +979,11 @@ static int s6e8aa0_probe(struct mipi_dsi_device *dsi) struct s6e8aa0 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(struct s6e8aa0), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6e8aa0, panel, + &s6e8aa0_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); mipi_dsi_set_drvdata(dsi, ctx); @@ -990,7 +992,7 @@ static int s6e8aa0_probe(struct mipi_dsi_device *dsi) dsi->lanes = 4; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST - | MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_AUTO_VERT; + | MIPI_DSI_MODE_VIDEO_AUTO_VERT; ret = s6e8aa0_parse_dt(ctx); if (ret < 0) @@ -1014,8 +1016,6 @@ static int s6e8aa0_probe(struct mipi_dsi_device *dsi) ctx->brightness = GAMMA_LEVEL_NUM - 1; - drm_panel_init(&ctx->panel, dev, &s6e8aa0_drm_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; drm_panel_add(&ctx->panel); diff --git a/drivers/gpu/drm/panel/panel-samsung-sofef00.c b/drivers/gpu/drm/panel/panel-samsung-sofef00.c index d92ae6b6100f..064258217d50 100644 --- a/drivers/gpu/drm/panel/panel-samsung-sofef00.c +++ b/drivers/gpu/drm/panel/panel-samsung-sofef00.c @@ -191,9 +191,11 @@ static int sofef00_panel_probe(struct mipi_dsi_device *dsi) struct sofef00_panel *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct sofef00_panel, panel, + &sofef00_panel_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->supply = devm_regulator_get(dev, "vddio"); if (IS_ERR(ctx->supply)) @@ -211,9 +213,6 @@ static int sofef00_panel_probe(struct mipi_dsi_device *dsi) dsi->lanes = 4; dsi->format = MIPI_DSI_FMT_RGB888; - drm_panel_init(&ctx->panel, dev, &sofef00_panel_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ctx->panel.backlight = sofef00_create_backlight(dsi); if (IS_ERR(ctx->panel.backlight)) return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c index 7d1b421ea9dd..0935d83ee2db 100644 --- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c +++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c @@ -204,9 +204,11 @@ static int seiko_panel_probe(struct device *dev, struct seiko_panel *panel; int err; - panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); - if (!panel) - return -ENOMEM; + panel = devm_drm_panel_alloc(dev, struct seiko_panel, base, + &seiko_panel_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(panel)) + return PTR_ERR(panel); panel->desc = desc; @@ -224,9 +226,6 @@ static int seiko_panel_probe(struct device *dev, return dev_err_probe(dev, PTR_ERR(panel->enable_gpio), "failed to request GPIO\n"); - drm_panel_init(&panel->base, dev, &seiko_panel_funcs, - DRM_MODE_CONNECTOR_DPI); - err = drm_panel_of_backlight(&panel->base); if (err) return err; diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c index a0d76d588da1..d159b0e4fdb6 100644 --- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c +++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c @@ -279,9 +279,6 @@ static int sharp_panel_add(struct sharp_panel *sharp) if (IS_ERR(sharp->supply)) return PTR_ERR(sharp->supply); - drm_panel_init(&sharp->base, &sharp->link1->dev, &sharp_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&sharp->base); if (ret) return ret; @@ -323,10 +320,12 @@ static int sharp_panel_probe(struct mipi_dsi_device *dsi) /* register a panel for only the DSI-LINK1 interface */ if (secondary) { - sharp = devm_kzalloc(&dsi->dev, sizeof(*sharp), GFP_KERNEL); - if (!sharp) { + sharp = devm_drm_panel_alloc(&dsi->dev, __typeof(*sharp), base, + &sharp_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(sharp)) { put_device(&secondary->dev); - return -ENOMEM; + return PTR_ERR(sharp); } mipi_dsi_set_drvdata(dsi, sharp); diff --git a/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c index a9673a52b861..938beac4655d 100644 --- a/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c +++ b/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c @@ -138,9 +138,10 @@ static int ls037v7dw01_probe(struct platform_device *pdev) { struct ls037v7dw01_panel *lcd; - lcd = devm_kzalloc(&pdev->dev, sizeof(*lcd), GFP_KERNEL); - if (!lcd) - return -ENOMEM; + lcd = devm_drm_panel_alloc(&pdev->dev, struct ls037v7dw01_panel, panel, + &ls037v7dw01_funcs, DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(lcd)) + return PTR_ERR(lcd); platform_set_drvdata(pdev, lcd); lcd->pdev = pdev; @@ -181,9 +182,6 @@ static int ls037v7dw01_probe(struct platform_device *pdev) return PTR_ERR(lcd->ud_gpio); } - drm_panel_init(&lcd->panel, &pdev->dev, &ls037v7dw01_funcs, - DRM_MODE_CONNECTOR_DPI); - drm_panel_add(&lcd->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-sharp-ls060t1sx01.c b/drivers/gpu/drm/panel/panel-sharp-ls060t1sx01.c index 0b4e0983639b..0456f3d705e7 100644 --- a/drivers/gpu/drm/panel/panel-sharp-ls060t1sx01.c +++ b/drivers/gpu/drm/panel/panel-sharp-ls060t1sx01.c @@ -193,9 +193,11 @@ static int sharp_ls060_probe(struct mipi_dsi_device *dsi) struct sharp_ls060 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct sharp_ls060, panel, + &sharp_ls060_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->vddi_supply = devm_regulator_get(dev, "vddi"); if (IS_ERR(ctx->vddi_supply)) @@ -227,9 +229,6 @@ static int sharp_ls060_probe(struct mipi_dsi_device *dsi) MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &sharp_ls060_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return dev_err_probe(dev, ret, "Failed to get backlight\n"); diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 9f81fa960b46..3333d4a07504 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1305,6 +1305,30 @@ static const struct panel_desc auo_g190ean01 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct display_timing auo_p238han01_timings = { + .pixelclock = { 107400000, 142400000, 180000000 }, + .hactive = { 1920, 1920, 1920 }, + .hfront_porch = { 30, 70, 650 }, + .hback_porch = { 30, 70, 650 }, + .hsync_len = { 20, 40, 136 }, + .vactive = { 1080, 1080, 1080 }, + .vfront_porch = { 5, 19, 318 }, + .vback_porch = { 5, 19, 318 }, + .vsync_len = { 4, 12, 120 }, +}; + +static const struct panel_desc auo_p238han01 = { + .timings = &auo_p238han01_timings, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 527, + .height = 296, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct display_timing auo_p320hvn03_timings = { .pixelclock = { 106000000, 148500000, 164000000 }, .hactive = { 1920, 1920, 1920 }, @@ -4976,6 +5000,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "auo,g190ean01", .data = &auo_g190ean01, }, { + .compatible = "auo,p238han01", + .data = &auo_p238han01, + }, { .compatible = "auo,p320hvn03", .data = &auo_p320hvn03, }, { diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/drivers/gpu/drm/panel/panel-sitronix-st7701.c index 1f72ef7ca74c..2f79ec4a2063 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7701.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7701.c @@ -520,6 +520,28 @@ static void rg28xx_gip_sequence(struct st7701 *st7701) st7701_switch_cmd_bkx(st7701, false, 0); } +static void wf40eswaa6mnn0_gip_sequence(struct st7701 *st7701) +{ + ST7701_WRITE(st7701, 0xE0, 0x00, 0x28, 0x02); + ST7701_WRITE(st7701, 0xE1, 0x08, 0xA0, 0x00, 0x00, 0x07, 0xA0, 0x00, + 0x00, 0x00, 0x44, 0x44); + ST7701_WRITE(st7701, 0xE2, 0x11, 0x11, 0x44, 0x44, 0xED, 0xA0, 0x00, + 0x00, 0xEC, 0xA0, 0x00, 0x00); + ST7701_WRITE(st7701, 0xE3, 0x00, 0x00, 0x11, 0x11); + ST7701_WRITE(st7701, 0xE4, 0x44, 0x44); + ST7701_WRITE(st7701, 0xE5, 0x0A, 0xE9, 0xD8, 0xA0, 0x0C, 0xEB, 0xD8, + 0xA0, 0x0E, 0xED, 0xD8, 0xA0, 0x10, 0xEF, 0xD8, 0xA0); + ST7701_WRITE(st7701, 0xE6, 0x00, 0x00, 0x11, 0x11); + ST7701_WRITE(st7701, 0xE7, 0x44, 0x44); + ST7701_WRITE(st7701, 0xE8, 0x09, 0xE8, 0xD8, 0xA0, 0x0B, 0xEA, 0xD8, + 0xA0, 0x0D, 0xEC, 0xD8, 0xA0, 0x0F, 0xEE, 0xD8, 0xA0); + ST7701_WRITE(st7701, 0xEB, 0x00, 0x00, 0xE4, 0xE4, 0x88, 0x00, 0x40); + ST7701_WRITE(st7701, 0xEC, 0x3C, 0x00); + ST7701_WRITE(st7701, 0xED, 0xAB, 0x89, 0x76, 0x54, 0x02, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x45, 0x67, 0x98, 0xBA); + ST7701_WRITE(st7701, MIPI_DCS_SET_ADDRESS_MODE, 0); +} + static int st7701_prepare(struct drm_panel *panel) { struct st7701 *st7701 = panel_to_st7701(panel); @@ -1135,6 +1157,107 @@ static const struct st7701_panel_desc rg28xx_desc = { .gip_sequence = rg28xx_gip_sequence, }; +static const struct drm_display_mode wf40eswaa6mnn0_mode = { + .clock = 18306, + + .hdisplay = 480, + .hsync_start = 480 + 2, + .hsync_end = 480 + 2 + 45, + .htotal = 480 + 2 + 45 + 13, + + .vdisplay = 480, + .vsync_start = 480 + 2, + .vsync_end = 480 + 2 + 70, + .vtotal = 480 + 2 + 70 + 13, + + .width_mm = 72, + .height_mm = 70, + + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, + + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + +static const struct st7701_panel_desc wf40eswaa6mnn0_desc = { + .mode = &wf40eswaa6mnn0_mode, + .lanes = 2, + .format = MIPI_DSI_FMT_RGB888, + .panel_sleep_delay = 0, + + .pv_gamma = { + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC0_MASK, 0x1), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x08), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x10), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0c), + + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x10), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x08), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x10), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x0c), + + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x08), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x22), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x04), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0x14), + + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x12), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0xb3), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x3a), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x1f) + }, + .nv_gamma = { + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x13), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC4_MASK, 0x19), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC8_MASK, 0x1f), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC16_MASK, 0x0f), + + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC24_MASK, 0x14), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC52_MASK, 0x07), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC80_MASK, 0x07), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC108_MASK, 0x08), + + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC147_MASK, 0x07), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC175_MASK, 0x22), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC203_MASK, 0x02), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC231_MASK, 0xf), + + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC239_MASK, 0x0f), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC247_MASK, 0xa3), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC251_MASK, 0x29), + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_AJ_MASK, 0) | + CFIELD_PREP(ST7701_CMD2_BK0_GAMCTRL_VC255_MASK, 0x0d) + }, + .nlinv = 3, + .vop_uv = 4737500, + .vcom_uv = 662500, + .vgh_mv = 15000, + .vgl_mv = -10170, + .avdd_mv = 6600, + .avcl_mv = -4600, + .gamma_op_bias = OP_BIAS_MIDDLE, + .input_op_bias = OP_BIAS_MIDDLE, + .output_op_bias = OP_BIAS_MIN, + .t2d_ns = 1600, + .t3d_ns = 10400, + .eot_en = true, + .gip_sequence = wf40eswaa6mnn0_gip_sequence, +}; + static void st7701_cleanup(void *data) { struct st7701 *st7701 = (struct st7701 *)data; @@ -1150,9 +1273,10 @@ static int st7701_probe(struct device *dev, int connector_type) struct st7701 *st7701; int ret; - st7701 = devm_kzalloc(dev, sizeof(*st7701), GFP_KERNEL); - if (!st7701) - return -ENOMEM; + st7701 = devm_drm_panel_alloc(dev, struct st7701, panel, &st7701_funcs, + connector_type); + if (IS_ERR(st7701)) + return PTR_ERR(st7701); desc = of_device_get_match_data(dev); if (!desc) @@ -1176,7 +1300,6 @@ static int st7701_probe(struct device *dev, int connector_type) if (ret < 0) return dev_err_probe(dev, ret, "Failed to get orientation\n"); - drm_panel_init(&st7701->panel, dev, &st7701_funcs, connector_type); st7701->panel.prepare_prev_first = true; /** @@ -1265,6 +1388,7 @@ static const struct of_device_id st7701_dsi_of_match[] = { { .compatible = "densitron,dmt028vghmcmi-1a", .data = &dmt028vghmcmi_1a_desc }, { .compatible = "elida,kd50t048a", .data = &kd50t048a_desc }, { .compatible = "techstar,ts8550b", .data = &ts8550b_desc }, + { .compatible = "winstar,wf40eswaa6mnn0", .data = &wf40eswaa6mnn0_desc }, { } }; MODULE_DEVICE_TABLE(of, st7701_dsi_of_match); diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 67e8e45498cb..1a007a244d84 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -846,9 +846,11 @@ static int st7703_probe(struct mipi_dsi_device *dsi) struct st7703 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct st7703, panel, + &st7703_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->reset_gpio)) @@ -876,9 +878,6 @@ static int st7703_probe(struct mipi_dsi_device *dsi) if (ret < 0) return dev_err_probe(&dsi->dev, ret, "Failed to get orientation\n"); - drm_panel_init(&ctx->panel, dev, &st7703_drm_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7789v.c b/drivers/gpu/drm/panel/panel-sitronix-st7789v.c index 28bfc48a9127..04d91929eedd 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7789v.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7789v.c @@ -612,9 +612,10 @@ static int st7789v_probe(struct spi_device *spi) struct st7789v *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct st7789v, panel, + &st7789v_drm_funcs, DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); spi_set_drvdata(spi, ctx); ctx->spi = spi; @@ -626,9 +627,6 @@ static int st7789v_probe(struct spi_device *spi) ctx->info = device_get_match_data(&spi->dev); - drm_panel_init(&ctx->panel, dev, &st7789v_drm_funcs, - DRM_MODE_CONNECTOR_DPI); - ctx->power = devm_regulator_get(dev, "power"); ret = PTR_ERR_OR_ZERO(ctx->power); if (ret) diff --git a/drivers/gpu/drm/panel/panel-sony-acx565akm.c b/drivers/gpu/drm/panel/panel-sony-acx565akm.c index d437f5c84f5f..fe043de791b0 100644 --- a/drivers/gpu/drm/panel/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/panel/panel-sony-acx565akm.c @@ -607,9 +607,10 @@ static int acx565akm_probe(struct spi_device *spi) struct acx565akm_panel *lcd; int ret; - lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); - if (!lcd) - return -ENOMEM; + lcd = devm_drm_panel_alloc(&spi->dev, struct acx565akm_panel, panel, + &acx565akm_funcs, DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(lcd)) + return PTR_ERR(lcd); spi_set_drvdata(spi, lcd); spi->mode = SPI_MODE_3; @@ -635,9 +636,6 @@ static int acx565akm_probe(struct spi_device *spi) return ret; } - drm_panel_init(&lcd->panel, &lcd->spi->dev, &acx565akm_funcs, - DRM_MODE_CONNECTOR_DPI); - drm_panel_add(&lcd->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c b/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c index 97f4bb4e1029..7c989b70ab51 100644 --- a/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c +++ b/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c @@ -175,9 +175,11 @@ static int sony_td4353_jdi_probe(struct mipi_dsi_device *dsi) struct sony_td4353_jdi *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct sony_td4353_jdi, panel, + &sony_td4353_jdi_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->type = (uintptr_t)of_device_get_match_data(dev); @@ -206,9 +208,6 @@ static int sony_td4353_jdi_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &sony_td4353_jdi_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return dev_err_probe(dev, ret, "Failed to get backlight\n"); diff --git a/drivers/gpu/drm/panel/panel-sony-tulip-truly-nt35521.c b/drivers/gpu/drm/panel/panel-sony-tulip-truly-nt35521.c index 104b2290560e..216a6ad8696e 100644 --- a/drivers/gpu/drm/panel/panel-sony-tulip-truly-nt35521.c +++ b/drivers/gpu/drm/panel/panel-sony-tulip-truly-nt35521.c @@ -433,9 +433,11 @@ static int truly_nt35521_probe(struct mipi_dsi_device *dsi) struct truly_nt35521 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct truly_nt35521, panel, + &truly_nt35521_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->supplies[0].supply = "positive5"; ctx->supplies[1].supply = "negative5"; @@ -465,9 +467,6 @@ static int truly_nt35521_probe(struct mipi_dsi_device *dsi) MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &truly_nt35521_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ctx->panel.backlight = truly_nt35521_create_backlight(dsi); if (IS_ERR(ctx->panel.backlight)) return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), diff --git a/drivers/gpu/drm/panel/panel-summit.c b/drivers/gpu/drm/panel/panel-summit.c index e780faee1857..4854437e2899 100644 --- a/drivers/gpu/drm/panel/panel-summit.c +++ b/drivers/gpu/drm/panel/panel-summit.c @@ -68,9 +68,11 @@ static int summit_probe(struct mipi_dsi_device *dsi) struct summit_data *s_data; int ret; - s_data = devm_kzalloc(dev, sizeof(*s_data), GFP_KERNEL); - if (!s_data) - return -ENOMEM; + s_data = devm_drm_panel_alloc(dev, struct summit_data, panel, + &summit_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(s_data)) + return PTR_ERR(s_data); mipi_dsi_set_drvdata(dsi, s_data); s_data->dsi = dsi; @@ -85,8 +87,6 @@ static int summit_probe(struct mipi_dsi_device *dsi) if (IS_ERR(s_data->bl)) return PTR_ERR(s_data->bl); - drm_panel_init(&s_data->panel, dev, &summit_panel_funcs, - DRM_MODE_CONNECTOR_DSI); drm_panel_add(&s_data->panel); return mipi_dsi_attach(dsi); diff --git a/drivers/gpu/drm/panel/panel-synaptics-r63353.c b/drivers/gpu/drm/panel/panel-synaptics-r63353.c index b148e6cba9bd..3a74d48753d9 100644 --- a/drivers/gpu/drm/panel/panel-synaptics-r63353.c +++ b/drivers/gpu/drm/panel/panel-synaptics-r63353.c @@ -229,9 +229,11 @@ static int r63353_panel_probe(struct mipi_dsi_device *dsi) struct device *dev = &dsi->dev; struct r63353_panel *panel; - panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL); - if (!panel) - return -ENOMEM; + panel = devm_drm_panel_alloc(dev, struct r63353_panel, base, + &r63353_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(panel)) + return PTR_ERR(panel); mipi_dsi_set_drvdata(dsi, panel); panel->dsi = dsi; @@ -258,9 +260,6 @@ static int r63353_panel_probe(struct mipi_dsi_device *dsi) return PTR_ERR(panel->reset_gpio); } - drm_panel_init(&panel->base, dev, &r63353_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - panel->base.prepare_prev_first = true; ret = drm_panel_of_backlight(&panel->base); if (ret) diff --git a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c index 11d460d2ea19..ee86ff20c1bd 100644 --- a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c +++ b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c @@ -318,9 +318,11 @@ static int td028ttec1_probe(struct spi_device *spi) struct td028ttec1_panel *lcd; int ret; - lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); - if (!lcd) - return -ENOMEM; + lcd = devm_drm_panel_alloc(&spi->dev, struct td028ttec1_panel, panel, + &td028ttec1_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(lcd)) + return PTR_ERR(lcd); spi_set_drvdata(spi, lcd); lcd->spi = spi; @@ -334,9 +336,6 @@ static int td028ttec1_probe(struct spi_device *spi) return ret; } - drm_panel_init(&lcd->panel, &lcd->spi->dev, &td028ttec1_funcs, - DRM_MODE_CONNECTOR_DPI); - ret = drm_panel_of_backlight(&lcd->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c index cf4609bb9b1d..b18af526b54c 100644 --- a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c @@ -421,9 +421,10 @@ static int td043mtea1_probe(struct spi_device *spi) struct td043mtea1_panel *lcd; int ret; - lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); - if (lcd == NULL) - return -ENOMEM; + lcd = devm_drm_panel_alloc(&spi->dev, struct td043mtea1_panel, panel, + &td043mtea1_funcs, DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(lcd)) + return PTR_ERR(lcd); spi_set_drvdata(spi, lcd); lcd->spi = spi; @@ -455,9 +456,6 @@ static int td043mtea1_probe(struct spi_device *spi) return ret; } - drm_panel_init(&lcd->panel, &lcd->spi->dev, &td043mtea1_funcs, - DRM_MODE_CONNECTOR_DPI); - drm_panel_add(&lcd->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-tpo-tpg110.c b/drivers/gpu/drm/panel/panel-tpo-tpg110.c index f6a212e542cb..0beba5c08956 100644 --- a/drivers/gpu/drm/panel/panel-tpo-tpg110.c +++ b/drivers/gpu/drm/panel/panel-tpo-tpg110.c @@ -405,9 +405,11 @@ static int tpg110_probe(struct spi_device *spi) struct tpg110 *tpg; int ret; - tpg = devm_kzalloc(dev, sizeof(*tpg), GFP_KERNEL); - if (!tpg) - return -ENOMEM; + tpg = devm_drm_panel_alloc(dev, struct tpg110, panel, + &tpg110_drm_funcs, DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(tpg)) + return PTR_ERR(tpg); + tpg->dev = dev; /* We get the physical display dimensions from the DT */ @@ -438,9 +440,6 @@ static int tpg110_probe(struct spi_device *spi) if (ret) return ret; - drm_panel_init(&tpg->panel, dev, &tpg110_drm_funcs, - DRM_MODE_CONNECTOR_DPI); - ret = drm_panel_of_backlight(&tpg->panel); if (ret) return ret; diff --git a/drivers/gpu/drm/panel/panel-visionox-r66451.c b/drivers/gpu/drm/panel/panel-visionox-r66451.c index 3ea0a86f6e69..690cccedd438 100644 --- a/drivers/gpu/drm/panel/panel-visionox-r66451.c +++ b/drivers/gpu/drm/panel/panel-visionox-r66451.c @@ -255,9 +255,11 @@ static int visionox_r66451_probe(struct mipi_dsi_device *dsi) struct drm_dsc_config *dsc; int ret = 0; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct visionox_r66451, panel, + &visionox_r66451_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); dsc = devm_kzalloc(dev, sizeof(*dsc), GFP_KERNEL); if (!dsc) @@ -297,7 +299,6 @@ static int visionox_r66451_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; ctx->panel.prepare_prev_first = true; - drm_panel_init(&ctx->panel, dev, &visionox_r66451_funcs, DRM_MODE_CONNECTOR_DSI); ctx->panel.backlight = visionox_r66451_create_backlight(dsi); if (IS_ERR(ctx->panel.backlight)) return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c index be3a9797fbce..909c280eab1f 100644 --- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c +++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c @@ -5,6 +5,7 @@ #include <linux/delay.h> #include <linux/module.h> +#include <linux/property.h> #include <linux/mod_devicetable.h> #include <linux/gpio/consumer.h> #include <linux/regulator/consumer.h> @@ -15,11 +16,138 @@ #include <drm/drm_modes.h> #include <drm/drm_panel.h> +struct visionox_rm69299_panel_desc { + const struct drm_display_mode *mode; + const u8 *init_seq; + unsigned int init_seq_len; +}; + struct visionox_rm69299 { struct drm_panel panel; - struct regulator_bulk_data supplies[2]; + struct regulator_bulk_data *supplies; struct gpio_desc *reset_gpio; struct mipi_dsi_device *dsi; + const struct visionox_rm69299_panel_desc *desc; +}; + +static const struct regulator_bulk_data visionox_rm69299_supplies[] = { + { .supply = "vdda", .init_load_uA = 32000 }, + { .supply = "vdd3p3", .init_load_uA = 13200 }, +}; + +static const u8 visionox_rm69299_1080x2248_60hz_init_seq[][2] = { + { 0xfe, 0x00 }, { 0xc2, 0x08 }, { 0x35, 0x00 }, { 0x51, 0xff }, +}; + +static const u8 visionox_rm69299_1080x2160_60hz_init_seq[][2] = { + { 0xfe, 0x40 }, { 0x05, 0x04 }, { 0x06, 0x08 }, { 0x08, 0x04 }, + { 0x09, 0x08 }, { 0x0a, 0x07 }, { 0x0b, 0xcc }, { 0x0c, 0x07 }, + { 0x0d, 0x90 }, { 0x0f, 0x87 }, { 0x20, 0x8d }, { 0x21, 0x8d }, + { 0x24, 0x05 }, { 0x26, 0x05 }, { 0x28, 0x05 }, { 0x2a, 0x05 }, + { 0x2d, 0x28 }, { 0x2f, 0x28 }, { 0x30, 0x32 }, { 0x31, 0x32 }, + { 0x37, 0x80 }, { 0x38, 0x30 }, { 0x39, 0xa8 }, { 0x46, 0x48 }, + { 0x47, 0x48 }, { 0x6b, 0x10 }, { 0x6f, 0x02 }, { 0x74, 0x2b }, + { 0x80, 0x1a }, { 0xfe, 0x40 }, { 0x93, 0x10 }, { 0x16, 0x00 }, + { 0x85, 0x07 }, { 0x84, 0x01 }, { 0x86, 0x0f }, { 0x87, 0x05 }, + { 0x8c, 0x00 }, { 0x88, 0x2e }, { 0x89, 0x2e }, { 0x8b, 0x09 }, + { 0x95, 0x00 }, { 0x91, 0x00 }, { 0x90, 0x00 }, { 0x8d, 0xd0 }, + { 0x8a, 0x03 }, { 0xfe, 0xa0 }, { 0x13, 0x00 }, { 0x33, 0x00 }, + { 0x0b, 0x33 }, { 0x36, 0x1e }, { 0x31, 0x88 }, { 0x32, 0x88 }, + { 0x37, 0xf1 }, { 0xfe, 0x50 }, { 0x00, 0x00 }, { 0x01, 0x00 }, + { 0x02, 0x00 }, { 0x03, 0xe9 }, { 0x04, 0x00 }, { 0x05, 0xf6 }, + { 0x06, 0x01 }, { 0x07, 0x2c }, { 0x08, 0x01 }, { 0x09, 0x62 }, + { 0x0a, 0x01 }, { 0x0b, 0x98 }, { 0x0c, 0x01 }, { 0x0d, 0xbf }, + { 0x0e, 0x01 }, { 0x0f, 0xf6 }, { 0x10, 0x02 }, { 0x11, 0x24 }, + { 0x12, 0x02 }, { 0x13, 0x4e }, { 0x14, 0x02 }, { 0x15, 0x70 }, + { 0x16, 0x02 }, { 0x17, 0xaf }, { 0x18, 0x02 }, { 0x19, 0xe2 }, + { 0x1a, 0x03 }, { 0x1b, 0x1f }, { 0x1c, 0x03 }, { 0x1d, 0x52 }, + { 0x1e, 0x03 }, { 0x1f, 0x82 }, { 0x20, 0x03 }, { 0x21, 0xb6 }, + { 0x22, 0x03 }, { 0x23, 0xf0 }, { 0x24, 0x04 }, { 0x25, 0x1f }, + { 0x26, 0x04 }, { 0x27, 0x37 }, { 0x28, 0x04 }, { 0x29, 0x59 }, + { 0x2a, 0x04 }, { 0x2b, 0x68 }, { 0x30, 0x04 }, { 0x31, 0x85 }, + { 0x32, 0x04 }, { 0x33, 0xa2 }, { 0x34, 0x04 }, { 0x35, 0xbc }, + { 0x36, 0x04 }, { 0x37, 0xd8 }, { 0x38, 0x04 }, { 0x39, 0xf4 }, + { 0x3a, 0x05 }, { 0x3b, 0x0e }, { 0x40, 0x05 }, { 0x41, 0x13 }, + { 0x42, 0x05 }, { 0x43, 0x1f }, { 0x44, 0x05 }, { 0x45, 0x1f }, + { 0x46, 0x00 }, { 0x47, 0x00 }, { 0x48, 0x01 }, { 0x49, 0x43 }, + { 0x4a, 0x01 }, { 0x4b, 0x4c }, { 0x4c, 0x01 }, { 0x4d, 0x6f }, + { 0x4e, 0x01 }, { 0x4f, 0x92 }, { 0x50, 0x01 }, { 0x51, 0xb5 }, + { 0x52, 0x01 }, { 0x53, 0xd4 }, { 0x58, 0x02 }, { 0x59, 0x06 }, + { 0x5a, 0x02 }, { 0x5b, 0x33 }, { 0x5c, 0x02 }, { 0x5d, 0x59 }, + { 0x5e, 0x02 }, { 0x5f, 0x7d }, { 0x60, 0x02 }, { 0x61, 0xbd }, + { 0x62, 0x02 }, { 0x63, 0xf7 }, { 0x64, 0x03 }, { 0x65, 0x31 }, + { 0x66, 0x03 }, { 0x67, 0x63 }, { 0x68, 0x03 }, { 0x69, 0x9d }, + { 0x6a, 0x03 }, { 0x6b, 0xd2 }, { 0x6c, 0x04 }, { 0x6d, 0x05 }, + { 0x6e, 0x04 }, { 0x6f, 0x38 }, { 0x70, 0x04 }, { 0x71, 0x51 }, + { 0x72, 0x04 }, { 0x73, 0x70 }, { 0x74, 0x04 }, { 0x75, 0x85 }, + { 0x76, 0x04 }, { 0x77, 0xa1 }, { 0x78, 0x04 }, { 0x79, 0xc0 }, + { 0x7a, 0x04 }, { 0x7b, 0xd8 }, { 0x7c, 0x04 }, { 0x7d, 0xf2 }, + { 0x7e, 0x05 }, { 0x7f, 0x10 }, { 0x80, 0x05 }, { 0x81, 0x21 }, + { 0x82, 0x05 }, { 0x83, 0x2e }, { 0x84, 0x05 }, { 0x85, 0x3a }, + { 0x86, 0x05 }, { 0x87, 0x3e }, { 0x88, 0x00 }, { 0x89, 0x00 }, + { 0x8a, 0x01 }, { 0x8b, 0x86 }, { 0x8c, 0x01 }, { 0x8d, 0x8f }, + { 0x8e, 0x01 }, { 0x8f, 0xb3 }, { 0x90, 0x01 }, { 0x91, 0xd7 }, + { 0x92, 0x01 }, { 0x93, 0xfb }, { 0x94, 0x02 }, { 0x95, 0x18 }, + { 0x96, 0x02 }, { 0x97, 0x4f }, { 0x98, 0x02 }, { 0x99, 0x7e }, + { 0x9a, 0x02 }, { 0x9b, 0xa6 }, { 0x9c, 0x02 }, { 0x9d, 0xcf }, + { 0x9e, 0x03 }, { 0x9f, 0x14 }, { 0xa4, 0x03 }, { 0xa5, 0x52 }, + { 0xa6, 0x03 }, { 0xa7, 0x93 }, { 0xac, 0x03 }, { 0xad, 0xcf }, + { 0xae, 0x04 }, { 0xaf, 0x08 }, { 0xb0, 0x04 }, { 0xb1, 0x42 }, + { 0xb2, 0x04 }, { 0xb3, 0x7f }, { 0xb4, 0x04 }, { 0xb5, 0xb4 }, + { 0xb6, 0x04 }, { 0xb7, 0xcc }, { 0xb8, 0x04 }, { 0xb9, 0xf2 }, + { 0xba, 0x05 }, { 0xbb, 0x0c }, { 0xbc, 0x05 }, { 0xbd, 0x26 }, + { 0xbe, 0x05 }, { 0xbf, 0x4b }, { 0xc0, 0x05 }, { 0xc1, 0x64 }, + { 0xc2, 0x05 }, { 0xc3, 0x83 }, { 0xc4, 0x05 }, { 0xc5, 0xa1 }, + { 0xc6, 0x05 }, { 0xc7, 0xba }, { 0xc8, 0x05 }, { 0xc9, 0xc4 }, + { 0xca, 0x05 }, { 0xcb, 0xd5 }, { 0xcc, 0x05 }, { 0xcd, 0xd5 }, + { 0xce, 0x00 }, { 0xcf, 0xce }, { 0xd0, 0x00 }, { 0xd1, 0xdb }, + { 0xd2, 0x01 }, { 0xd3, 0x32 }, { 0xd4, 0x01 }, { 0xd5, 0x3b }, + { 0xd6, 0x01 }, { 0xd7, 0x74 }, { 0xd8, 0x01 }, { 0xd9, 0x7d }, + { 0xfe, 0x60 }, { 0x00, 0xcc }, { 0x01, 0x0f }, { 0x02, 0xff }, + { 0x03, 0x01 }, { 0x04, 0x00 }, { 0x05, 0x02 }, { 0x06, 0x00 }, + { 0x07, 0x00 }, { 0x09, 0xc4 }, { 0x0a, 0x00 }, { 0x0b, 0x04 }, + { 0x0c, 0x01 }, { 0x0d, 0x00 }, { 0x0e, 0x04 }, { 0x0f, 0x00 }, + { 0x10, 0x71 }, { 0x12, 0xc4 }, { 0x13, 0x00 }, { 0x14, 0x04 }, + { 0x15, 0x01 }, { 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, + { 0x19, 0x71 }, { 0x1b, 0xc4 }, { 0x1c, 0x00 }, { 0x1d, 0x02 }, + { 0x1e, 0x00 }, { 0x1f, 0x00 }, { 0x20, 0x08 }, { 0x21, 0x66 }, + { 0x22, 0xb4 }, { 0x24, 0xc4 }, { 0x25, 0x00 }, { 0x26, 0x02 }, + { 0x27, 0x00 }, { 0x28, 0x00 }, { 0x29, 0x07 }, { 0x2a, 0x66 }, + { 0x2b, 0xb4 }, { 0x2f, 0xc4 }, { 0x30, 0x00 }, { 0x31, 0x04 }, + { 0x32, 0x01 }, { 0x33, 0x00 }, { 0x34, 0x03 }, { 0x35, 0x00 }, + { 0x36, 0x71 }, { 0x38, 0xc4 }, { 0x39, 0x00 }, { 0x3a, 0x04 }, + { 0x3b, 0x01 }, { 0x3d, 0x00 }, { 0x3f, 0x05 }, { 0x40, 0x00 }, + { 0x41, 0x71 }, { 0x83, 0xce }, { 0x84, 0x02 }, { 0x85, 0x20 }, + { 0x86, 0xdc }, { 0x87, 0x00 }, { 0x88, 0x04 }, { 0x89, 0x00 }, + { 0x8a, 0xbb }, { 0x8b, 0x80 }, { 0xc7, 0x0e }, { 0xc8, 0x05 }, + { 0xc9, 0x1f }, { 0xca, 0x06 }, { 0xcb, 0x00 }, { 0xcc, 0x03 }, + { 0xcd, 0x04 }, { 0xce, 0x1f }, { 0xcf, 0x1f }, { 0xd0, 0x1f }, + { 0xd1, 0x1f }, { 0xd2, 0x1f }, { 0xd3, 0x1f }, { 0xd4, 0x1f }, + { 0xd5, 0x1f }, { 0xd6, 0x1f }, { 0xd7, 0x17 }, { 0xd8, 0x1f }, + { 0xd9, 0x16 }, { 0xda, 0x1f }, { 0xdb, 0x0e }, { 0xdc, 0x01 }, + { 0xdd, 0x1f }, { 0xde, 0x02 }, { 0xdf, 0x00 }, { 0xe0, 0x03 }, + { 0xe1, 0x04 }, { 0xe2, 0x1f }, { 0xe3, 0x1f }, { 0xe4, 0x1f }, + { 0xe5, 0x1f }, { 0xe6, 0x1f }, { 0xe7, 0x1f }, { 0xe8, 0x1f }, + { 0xe9, 0x1f }, { 0xea, 0x1f }, { 0xeb, 0x17 }, { 0xec, 0x1f }, + { 0xed, 0x16 }, { 0xee, 0x1f }, { 0xef, 0x03 }, { 0xfe, 0x70 }, + { 0x5a, 0x0b }, { 0x5b, 0x0b }, { 0x5c, 0x55 }, { 0x5d, 0x24 }, + { 0xfe, 0x90 }, { 0x12, 0x24 }, { 0x13, 0x49 }, { 0x14, 0x92 }, + { 0x15, 0x86 }, { 0x16, 0x61 }, { 0x17, 0x18 }, { 0x18, 0x24 }, + { 0x19, 0x49 }, { 0x1a, 0x92 }, { 0x1b, 0x86 }, { 0x1c, 0x61 }, + { 0x1d, 0x18 }, { 0x1e, 0x24 }, { 0x1f, 0x49 }, { 0x20, 0x92 }, + { 0x21, 0x86 }, { 0x22, 0x61 }, { 0x23, 0x18 }, { 0xfe, 0x40 }, + { 0x0e, 0x10 }, { 0xfe, 0xa0 }, { 0x04, 0x80 }, { 0x16, 0x00 }, + { 0x26, 0x10 }, { 0x2f, 0x37 }, { 0xfe, 0xd0 }, { 0x06, 0x0f }, + { 0x4b, 0x00 }, { 0x56, 0x4a }, { 0xfe, 0x00 }, { 0xc2, 0x09 }, + { 0x35, 0x00 }, { 0xfe, 0x70 }, { 0x7d, 0x61 }, { 0x7f, 0x00 }, + { 0x7e, 0x4e }, { 0x52, 0x2c }, { 0x49, 0x00 }, { 0x4a, 0x00 }, + { 0x4b, 0x00 }, { 0x4c, 0x00 }, { 0x4d, 0xe8 }, { 0x4e, 0x25 }, + { 0x4f, 0x6e }, { 0x50, 0xae }, { 0x51, 0x2f }, { 0xad, 0xf4 }, + { 0xae, 0x8f }, { 0xaf, 0x00 }, { 0xb0, 0x54 }, { 0xb1, 0x3a }, + { 0xb2, 0x00 }, { 0xb3, 0x00 }, { 0xb4, 0x00 }, { 0xb5, 0x00 }, + { 0xb6, 0x18 }, { 0xb7, 0x30 }, { 0xb8, 0x4a }, { 0xb9, 0x98 }, + { 0xba, 0x30 }, { 0xbb, 0x60 }, { 0xbc, 0x50 }, { 0xbd, 0x00 }, + { 0xbe, 0x00 }, { 0xbf, 0x39 }, { 0xfe, 0x00 }, { 0x51, 0x66 }, }; static inline struct visionox_rm69299 *panel_to_ctx(struct drm_panel *panel) @@ -31,7 +159,8 @@ static int visionox_rm69299_power_on(struct visionox_rm69299 *ctx) { int ret; - ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + ret = regulator_bulk_enable(ARRAY_SIZE(visionox_rm69299_supplies), + ctx->supplies); if (ret < 0) return ret; @@ -54,37 +183,32 @@ static int visionox_rm69299_power_off(struct visionox_rm69299 *ctx) { gpiod_set_value(ctx->reset_gpio, 0); - return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + return regulator_bulk_disable(ARRAY_SIZE(visionox_rm69299_supplies), + ctx->supplies); } static int visionox_rm69299_unprepare(struct drm_panel *panel) { struct visionox_rm69299 *ctx = panel_to_ctx(panel); - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; ctx->dsi->mode_flags = 0; - ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); - if (ret < 0) - dev_err(ctx->panel.dev, "set_display_off cmd failed ret = %d\n", ret); + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); /* 120ms delay required here as per DCS spec */ - msleep(120); - - ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); - if (ret < 0) { - dev_err(ctx->panel.dev, "enter_sleep cmd failed ret = %d\n", ret); - } + mipi_dsi_msleep(&dsi_ctx, 120); - ret = visionox_rm69299_power_off(ctx); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); - return ret; + return visionox_rm69299_power_off(ctx); } static int visionox_rm69299_prepare(struct drm_panel *panel) { struct visionox_rm69299 *ctx = panel_to_ctx(panel); - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + int ret, i; ret = visionox_rm69299_power_on(ctx); if (ret < 0) @@ -92,52 +216,20 @@ static int visionox_rm69299_prepare(struct drm_panel *panel) ctx->dsi->mode_flags |= MIPI_DSI_MODE_LPM; - ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0xfe, 0x00 }, 2); - if (ret < 0) { - dev_err(ctx->panel.dev, "cmd set tx 0 failed, ret = %d\n", ret); - goto power_off; - } - - ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0xc2, 0x08 }, 2); - if (ret < 0) { - dev_err(ctx->panel.dev, "cmd set tx 1 failed, ret = %d\n", ret); - goto power_off; - } + for (i = 0; i < ctx->desc->init_seq_len; i++) + mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, &ctx->desc->init_seq[i * 2], 2); - ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0x35, 0x00 }, 2); - if (ret < 0) { - dev_err(ctx->panel.dev, "cmd set tx 2 failed, ret = %d\n", ret); - goto power_off; - } - - ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0x51, 0xff }, 2); - if (ret < 0) { - dev_err(ctx->panel.dev, "cmd set tx 3 failed, ret = %d\n", ret); - goto power_off; - } - - ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); - if (ret < 0) { - dev_err(ctx->panel.dev, "exit_sleep_mode cmd failed ret = %d\n", ret); - goto power_off; - } + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); /* Per DSI spec wait 120ms after sending exit sleep DCS command */ - msleep(120); + mipi_dsi_msleep(&dsi_ctx, 120); - ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); - if (ret < 0) { - dev_err(ctx->panel.dev, "set_display_on cmd failed ret = %d\n", ret); - goto power_off; - } + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); /* Per DSI spec wait 120ms after sending set_display_on DCS command */ - msleep(120); + mipi_dsi_msleep(&dsi_ctx, 120); - return 0; - -power_off: - return ret; + return dsi_ctx.accum_err; } static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = { @@ -154,14 +246,26 @@ static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = { .flags = 0, }; +static const struct drm_display_mode visionox_rm69299_1080x2160_60hz = { + .clock = 158695, + .hdisplay = 1080, + .hsync_start = 1080 + 26, + .hsync_end = 1080 + 26 + 2, + .htotal = 1080 + 26 + 2 + 36, + .vdisplay = 2160, + .vsync_start = 2160 + 8, + .vsync_end = 2160 + 8 + 4, + .vtotal = 2160 + 8 + 4 + 4, + .flags = 0, +}; + static int visionox_rm69299_get_modes(struct drm_panel *panel, struct drm_connector *connector) { struct visionox_rm69299 *ctx = panel_to_ctx(panel); struct drm_display_mode *mode; - mode = drm_mode_duplicate(connector->dev, - &visionox_rm69299_1080x2248_60hz); + mode = drm_mode_duplicate(connector->dev, ctx->desc->mode); if (!mode) { dev_err(ctx->panel.dev, "failed to create a new display mode\n"); return 0; @@ -187,20 +291,22 @@ static int visionox_rm69299_probe(struct mipi_dsi_device *dsi) struct visionox_rm69299 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct visionox_rm69299, panel, + &visionox_rm69299_drm_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ctx->desc = device_get_match_data(dev); + if (!ctx->desc) + return -EINVAL; mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; - ctx->supplies[0].supply = "vdda"; - ctx->supplies[0].init_load_uA = 32000; - ctx->supplies[1].supply = "vdd3p3"; - ctx->supplies[1].init_load_uA = 13200; - - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies), ctx->supplies); + ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(visionox_rm69299_supplies), + visionox_rm69299_supplies, &ctx->supplies); if (ret < 0) return ret; @@ -210,8 +316,6 @@ static int visionox_rm69299_probe(struct mipi_dsi_device *dsi) return PTR_ERR(ctx->reset_gpio); } - drm_panel_init(&ctx->panel, dev, &visionox_rm69299_drm_funcs, - DRM_MODE_CONNECTOR_DSI); drm_panel_add(&ctx->panel); dsi->lanes = 4; @@ -239,8 +343,23 @@ static void visionox_rm69299_remove(struct mipi_dsi_device *dsi) drm_panel_remove(&ctx->panel); } +const struct visionox_rm69299_panel_desc visionox_rm69299_1080p_display_desc = { + .mode = &visionox_rm69299_1080x2248_60hz, + .init_seq = (const u8 *)visionox_rm69299_1080x2248_60hz_init_seq, + .init_seq_len = ARRAY_SIZE(visionox_rm69299_1080x2248_60hz_init_seq), +}; + +const struct visionox_rm69299_panel_desc visionox_rm69299_shift_desc = { + .mode = &visionox_rm69299_1080x2160_60hz, + .init_seq = (const u8 *)visionox_rm69299_1080x2160_60hz_init_seq, + .init_seq_len = ARRAY_SIZE(visionox_rm69299_1080x2160_60hz_init_seq), +}; + static const struct of_device_id visionox_rm69299_of_match[] = { - { .compatible = "visionox,rm69299-1080p-display", }, + { .compatible = "visionox,rm69299-1080p-display", + .data = &visionox_rm69299_1080p_display_desc }, + { .compatible = "visionox,rm69299-shift", + .data = &visionox_rm69299_shift_desc }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, visionox_rm69299_of_match); diff --git a/drivers/gpu/drm/panel/panel-visionox-rm692e5.c b/drivers/gpu/drm/panel/panel-visionox-rm692e5.c index 4db7fa8d74c4..e53645d59413 100644 --- a/drivers/gpu/drm/panel/panel-visionox-rm692e5.c +++ b/drivers/gpu/drm/panel/panel-visionox-rm692e5.c @@ -360,9 +360,11 @@ static int visionox_rm692e5_probe(struct mipi_dsi_device *dsi) struct visionox_rm692e5 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct visionox_rm692e5, panel, + &visionox_rm692e5_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ret = devm_regulator_bulk_get_const(&dsi->dev, ARRAY_SIZE(visionox_rm692e5_supplies), @@ -383,8 +385,6 @@ static int visionox_rm692e5_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS; - drm_panel_init(&ctx->panel, dev, &visionox_rm692e5_panel_funcs, - DRM_MODE_CONNECTOR_DSI); ctx->panel.prepare_prev_first = true; ctx->panel.backlight = visionox_rm692e5_create_backlight(dsi); diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c index 17b8defe79c1..97a79411e1ec 100644 --- a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c +++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c @@ -248,9 +248,11 @@ static int visionox_vtdr6130_probe(struct mipi_dsi_device *dsi) struct visionox_vtdr6130 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct visionox_vtdr6130, panel, + &visionox_vtdr6130_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ret = devm_regulator_bulk_get_const(&dsi->dev, ARRAY_SIZE(visionox_vtdr6130_supplies), @@ -273,9 +275,6 @@ static int visionox_vtdr6130_probe(struct mipi_dsi_device *dsi) MIPI_DSI_CLOCK_NON_CONTINUOUS; ctx->panel.prepare_prev_first = true; - drm_panel_init(&ctx->panel, dev, &visionox_vtdr6130_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - ctx->panel.backlight = visionox_vtdr6130_create_backlight(dsi); if (IS_ERR(ctx->panel.backlight)) return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), diff --git a/drivers/gpu/drm/panel/panel-widechips-ws2401.c b/drivers/gpu/drm/panel/panel-widechips-ws2401.c index 2591ff8f0d4e..dd74610bd2eb 100644 --- a/drivers/gpu/drm/panel/panel-widechips-ws2401.c +++ b/drivers/gpu/drm/panel/panel-widechips-ws2401.c @@ -347,9 +347,11 @@ static int ws2401_probe(struct spi_device *spi) struct ws2401 *ws; int ret; - ws = devm_kzalloc(dev, sizeof(*ws), GFP_KERNEL); - if (!ws) - return -ENOMEM; + ws = devm_drm_panel_alloc(dev, struct ws2401, panel, &ws2401_drm_funcs, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(ws)) + return PTR_ERR(ws); + ws->dev = dev; /* @@ -379,9 +381,6 @@ static int ws2401_probe(struct spi_device *spi) ws2401_read_mtp_id(ws); ws2401_power_off(ws); - drm_panel_init(&ws->panel, dev, &ws2401_drm_funcs, - DRM_MODE_CONNECTOR_DPI); - ret = drm_panel_of_backlight(&ws->panel); if (ret) return dev_err_probe(dev, ret, diff --git a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c index 2b91414c2829..fc6516373b5d 100644 --- a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c +++ b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c @@ -241,9 +241,10 @@ static int xpp055c272_probe(struct mipi_dsi_device *dsi) struct xpp055c272 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct xpp055c272, panel, + &xpp055c272_funcs, DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->reset_gpio)) @@ -269,9 +270,6 @@ static int xpp055c272_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET; - drm_panel_init(&ctx->panel, &dsi->dev, &xpp055c272_funcs, - DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&ctx->panel); if (ret) return ret; |