Re: [PATCH v2 2/2] drm/panel: add Raydium RM67200 panel driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Feb 07, 2025 at 05:21:48PM +0100, Sebastian Reichel wrote:
> The Rockchip W552793DBA-V10 display/touchscreen board contains a
> Wanchanglong W552793BAA panel, which in turn is using a Raydium
> RM67200 MIPI-DSI controller. Add a DSI panel driver for it.
> 
> The W552793BAA panel init sequence has been taken from the RK3588
> EVB1 vendor kernel devicetree.
> 
> Reviewed-by: Jessica Zhang <quic_jesszhan@xxxxxxxxxxx>
> Reviewed-by: Andy Yan <andyshrk@xxxxxxx>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx>
> ---
>  drivers/gpu/drm/panel/Kconfig                 |  10 +
>  drivers/gpu/drm/panel/Makefile                |   1 +
>  drivers/gpu/drm/panel/panel-raydium-rm67200.c | 503 ++++++++++++++++++++++++++
>  3 files changed, 514 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index d7469c565d1db8b8e974dd6c45d03d9352d99d63..ab962c7d572827774dabd2cdf329367a102c43de 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -573,6 +573,16 @@ config DRM_PANEL_RAYDIUM_RM67191
>  	  Say Y here if you want to enable support for Raydium RM67191 FHD
>  	  (1080x1920) DSI panel.
>  
> +config DRM_PANEL_RAYDIUM_RM67200
> +	tristate "Raydium RM67200-based DSI panel"
> +	depends on OF
> +	depends on DRM_MIPI_DSI
> +	help
> +	  Say Y here if you want to enable support for Raydium RM67200-based
> +	  DSI video mode panels. This panel controller can be found in the
> +	  Wanchanglong W552793BAA panel found on the Rockchip RK3588 EVB1
> +	  evaluation boards.
> +
>  config DRM_PANEL_RAYDIUM_RM68200
>  	tristate "Raydium RM68200 720x1280 DSI video mode panel"
>  	depends on OF
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index 7dcf72646cacff11bab90c78e3b8b1f357e5f14a..f7b7cd1794927401cab1930402ef5c5df9e4c1c5 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -58,6 +58,7 @@ obj-$(CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS) += panel-osd-osd101t2587-53ts.o
>  obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
>  obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o
>  obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o
> +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
> diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67200.c b/drivers/gpu/drm/panel/panel-raydium-rm67200.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..1a7201ce6c9825d3c91661f612723306be1c7981
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-raydium-rm67200.c
> @@ -0,0 +1,503 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2024 Collabora
> +
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/property.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_modes.h>
> +#include <drm/drm_panel.h>
> +
> +struct raydium_rm67200_panel_info {
> +	struct drm_display_mode mode;
> +	const struct regulator_bulk_data *regulators;
> +	int num_regulators;
> +	void (*panel_setup)(struct mipi_dsi_multi_context *ctx);
> +};
> +
> +struct raydium_rm67200 {
> +	struct drm_panel panel;
> +	const struct raydium_rm67200_panel_info *panel_info;
> +	struct mipi_dsi_device *dsi;
> +	struct gpio_desc *reset_gpio;
> +	struct regulator_bulk_data *supplies;
> +	int num_supplies;
> +};
> +
> +static inline struct raydium_rm67200 *to_raydium_rm67200(struct drm_panel *panel)
> +{
> +	return container_of(panel, struct raydium_rm67200, 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);
> +}
> +
> +static void raydium_rm67200_write(struct mipi_dsi_multi_context *ctx,
> +				  u8 arg1, u8 arg2)
> +{
> +	u8 d[] = { arg1, arg2 };
> +
> +	mipi_dsi_generic_write_multi(ctx, d, ARRAY_SIZE(d));
> +}
> +
> +static void w552793baa_setup(struct mipi_dsi_multi_context *ctx)
> +{
> +	raydium_rm67200_write(ctx, 0xFE, 0x21);

Nit: Lowercase hex, please.

> +	raydium_rm67200_write(ctx, 0x04, 0x00);
> +	raydium_rm67200_write(ctx, 0x00, 0x64);
> +	raydium_rm67200_write(ctx, 0x2A, 0x00);

[...]

> +}
> +
> +static int raydium_rm67200_prepare(struct drm_panel *panel)
> +{
> +	struct raydium_rm67200 *ctx = to_raydium_rm67200(panel);
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ctx->num_supplies, ctx->supplies);
> +	if (ret < 0)
> +		return ret;
> +
> +	raydium_rm67200_reset(ctx);
> +
> +	msleep(60);
> +
> +	return 0;
> +}
> +
> +static int raydium_rm67200_unprepare(struct drm_panel *panel)
> +{
> +	struct raydium_rm67200 *ctx = to_raydium_rm67200(panel);
> +
> +	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
> +	regulator_bulk_disable(ctx->num_supplies, ctx->supplies);
> +
> +	msleep(60);
> +
> +	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);
> +
> +	msleep(60);

So, this function will sleep for 30 msec and then for 60 more. Is that
expected? Granted that the first line uses msi_dsi_multi() and the
second one is just msleep() I can assume that this is some debugging
lefrover or a  rebase issues.

> +
> +	return ctx.accum_err;
> +}
> +
> +static int raydium_rm67200_disable(struct drm_panel *panel)
> +{
> +	struct raydium_rm67200 *rm67200 = to_raydium_rm67200(panel);
> +	struct mipi_dsi_multi_context ctx = { .dsi = rm67200->dsi };
> +
> +	mipi_dsi_dcs_set_display_off_multi(&ctx);
> +	mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
> +
> +	msleep(60);
> +
> +	return ctx.accum_err;
> +}
> +
> +static int raydium_rm67200_get_modes(struct drm_panel *panel,
> +				    struct drm_connector *connector)
> +{
> +	struct raydium_rm67200 *ctx = to_raydium_rm67200(panel);
> +
> +	drm_connector_helper_get_modes_fixed(connector, &ctx->panel_info->mode);
> +	return 1;

return drm_connector_helper_get_modes_fixed().

> +}
> +

-- 
With best wishes
Dmitry



[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux