From: Petr Hodina <[email protected]> rk_vop.c only looks for its encoder in UCLASS_DISPLAY and knows nothing about UCLASS_VIDEO_BRIDGE. Bind a thin display device on the DSI node that forwards read_timing to the panel and enable to the bridge. Enable goes through video_bridge_set_backlight() so that dsi_host_enable() also runs and the controller leaves command mode.
Signed-off-by: Petr Hodina <[email protected]> --- drivers/video/rockchip/dw_mipi_dsi_rockchip.c | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/drivers/video/rockchip/dw_mipi_dsi_rockchip.c b/drivers/video/rockchip/dw_mipi_dsi_rockchip.c index 49835587aaf..9d0dda86726 100644 --- a/drivers/video/rockchip/dw_mipi_dsi_rockchip.c +++ b/drivers/video/rockchip/dw_mipi_dsi_rockchip.c @@ -10,6 +10,7 @@ #define LOG_CATEGORY UCLASS_VIDEO_BRIDGE #include <clk.h> +#include <display.h> #include <dm.h> #include <div64.h> #include <dsi_host.h> @@ -798,6 +799,18 @@ static int dw_mipi_dsi_rockchip_bind(struct udevice *dev) return ret; } + /* + * Bind a thin UCLASS_DISPLAY adapter at the same node so legacy + * rk_vop.c can drive this bridge without either side needing to + * know about the other's op table. + */ + ret = device_bind_driver_to_node(dev, "dw-mipi-dsi-rockchip-display", + "display", dev_ofnode(dev), NULL); + if (ret) { + dev_err(dev, "failed to bind display shim to node\n"); + return ret; + } + return dm_scan_fdt_dev(dev); } @@ -997,3 +1010,57 @@ U_BOOT_DRIVER(dw_mipi_dsi_rockchip) = { .ops = &dw_mipi_dsi_rockchip_ops, .priv_auto = sizeof(struct dw_rockchip_dsi_priv), }; + +/* + * Forwards the two ops rk_vop.c actually calls (read_timing, enable) onto + * the real UCLASS_VIDEO_BRIDGE bridge and its UCLASS_PANEL child, which is + * where this hardware's own panel.c-based driver (e.g. himax-hx8394.c) + * already does the real work + */ +static int dw_mipi_dsi_rockchip_display_read_timing(struct udevice *dev, + struct display_timing *timing) +{ + struct udevice *panel; + int ret; + + ret = uclass_first_device_err(UCLASS_PANEL, &panel); + if (ret) + return ret; + + ret = panel_get_display_timing(panel, timing); + if (ret) + ret = ofnode_decode_display_timing(dev_ofnode(panel), 0, timing); + + return ret; +} + +static int dw_mipi_dsi_rockchip_display_enable(struct udevice *dev, + int panel_bpp, + const struct display_timing *timing) +{ + struct udevice *bridge; + int ret; + + ret = uclass_first_device_err(UCLASS_VIDEO_BRIDGE, &bridge); + if (ret) + return ret; + + ret = video_bridge_attach(bridge); + if (ret) + return ret; + + ret = video_bridge_set_backlight(bridge, 100); + + return ret; +} + +static const struct dm_display_ops dw_mipi_dsi_rockchip_display_ops = { + .read_timing = dw_mipi_dsi_rockchip_display_read_timing, + .enable = dw_mipi_dsi_rockchip_display_enable, +}; + +U_BOOT_DRIVER(dw_mipi_dsi_rockchip_display) = { + .name = "dw-mipi-dsi-rockchip-display", + .id = UCLASS_DISPLAY, + .ops = &dw_mipi_dsi_rockchip_display_ops, +}; -- 2.55.0
