drm/bridge/synopsys: Add MIPI DSI2 host controller bridge

Add a Synopsys Designware MIPI DSI host DRM bridge driver for their
DSI2 host controller, based on the Rockchip version from the driver
rockchip/dw-mipi-dsi2.c in their vendor-kernel with phy & bridge APIs.

While the driver is heavily modelled after the previous IP, the register
set of this DSI2 controller is completely different and there are also
additional properties like the variable-width phy interface.

Tested-by: Daniel Semkowicz <dse@thaumatec.com>
Tested-by: Dmitry Yashin <dmt.yashin@gmail.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
Reviewed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20241209231021.2180582-2-heiko@sntech.de
This commit is contained in:
Heiko Stuebner 2024-12-10 00:10:19 +01:00 committed by Heiko Stuebner
parent 8a4b913df4
commit 0d6d86253f
4 changed files with 1132 additions and 0 deletions

View file

@ -59,3 +59,9 @@ config DRM_DW_MIPI_DSI
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL_BRIDGE
config DRM_DW_MIPI_DSI2
tristate
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL_BRIDGE

View file

@ -8,3 +8,4 @@ obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
obj-$(CONFIG_DRM_DW_HDMI_QP) += dw-hdmi-qp.o
obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
obj-$(CONFIG_DRM_DW_MIPI_DSI2) += dw-mipi-dsi2.o

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,95 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2024, Fuzhou Rockchip Electronics Co., Ltd
*
* Authors: Guochun Huang <hero.huang@rock-chips.com>
* Heiko Stuebner <heiko.stuebner@cherry.de>
*/
#ifndef __DW_MIPI_DSI2__
#define __DW_MIPI_DSI2__
#include <linux/regmap.h>
#include <linux/types.h>
#include <drm/drm_atomic.h>
#include <drm/drm_bridge.h>
#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_modes.h>
struct drm_display_mode;
struct drm_encoder;
struct dw_mipi_dsi2;
struct mipi_dsi_device;
struct platform_device;
enum dw_mipi_dsi2_phy_type {
DW_MIPI_DSI2_DPHY,
DW_MIPI_DSI2_CPHY,
};
struct dw_mipi_dsi2_phy_iface {
int ppi_width;
enum dw_mipi_dsi2_phy_type phy_type;
};
struct dw_mipi_dsi2_phy_timing {
u32 data_hs2lp;
u32 data_lp2hs;
};
struct dw_mipi_dsi2_phy_ops {
int (*init)(void *priv_data);
void (*power_on)(void *priv_data);
void (*power_off)(void *priv_data);
void (*get_interface)(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface);
int (*get_lane_mbps)(void *priv_data,
const struct drm_display_mode *mode,
unsigned long mode_flags, u32 lanes, u32 format,
unsigned int *lane_mbps);
int (*get_timing)(void *priv_data, unsigned int lane_mbps,
struct dw_mipi_dsi2_phy_timing *timing);
int (*get_esc_clk_rate)(void *priv_data, unsigned int *esc_clk_rate);
};
struct dw_mipi_dsi2_host_ops {
int (*attach)(void *priv_data,
struct mipi_dsi_device *dsi);
int (*detach)(void *priv_data,
struct mipi_dsi_device *dsi);
};
struct dw_mipi_dsi2_plat_data {
struct regmap *regmap;
unsigned int max_data_lanes;
enum drm_mode_status (*mode_valid)(void *priv_data,
const struct drm_display_mode *mode,
unsigned long mode_flags,
u32 lanes, u32 format);
bool (*mode_fixup)(void *priv_data, const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
u32 *(*get_input_bus_fmts)(void *priv_data,
struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state,
u32 output_fmt,
unsigned int *num_input_fmts);
const struct dw_mipi_dsi2_phy_ops *phy_ops;
const struct dw_mipi_dsi2_host_ops *host_ops;
void *priv_data;
};
struct dw_mipi_dsi2 *dw_mipi_dsi2_probe(struct platform_device *pdev,
const struct dw_mipi_dsi2_plat_data *plat_data);
void dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2);
int dw_mipi_dsi2_bind(struct dw_mipi_dsi2 *dsi2, struct drm_encoder *encoder);
void dw_mipi_dsi2_unbind(struct dw_mipi_dsi2 *dsi2);
#endif /* __DW_MIPI_DSI2__ */