From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c | 494 +++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 389 insertions(+), 105 deletions(-) diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c index 38b76f0..b8c9f7b 100644 --- a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c +++ b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_panel.c @@ -21,21 +21,159 @@ #include <drm/drm_crtc.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_panel.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_atomic_state_helper.h> +#include <drm/drm_probe_helper.h> #include "rkx110_x120.h" #include "rkx120_dsi_tx.h" -static inline struct rk_serdes_panel *to_serdes_panel(struct drm_panel *panel) +static inline struct rk_serdes_panel *drm_panel_to_serdes_panel(struct drm_panel *panel) { return container_of(panel, struct rk_serdes_panel, panel); } -static int serdes_panel_prepare(struct drm_panel *panel) +static inline struct rk_serdes_panel *drm_bridge_to_serdes_panel(struct drm_bridge *bridge) { - struct rk_serdes_panel *sd_panel = to_serdes_panel(panel); - struct rk_serdes_route *route = &sd_panel->route; - struct rk_serdes *serdes = sd_panel->parent; + return container_of(bridge, struct rk_serdes_panel, bridge); +} +static inline struct rk_serdes_panel *drm_connector_to_serdes_panel(struct drm_connector *connector) +{ + return container_of(connector, struct rk_serdes_panel, connector); +} + +static int serdes_connector_get_modes(struct drm_connector *connector) +{ + struct rk_serdes_panel *sd_panel = drm_connector_to_serdes_panel(connector); + + return drm_panel_get_modes(&sd_panel->panel, connector); +} + +static const struct drm_connector_helper_funcs +rk_serdes_connector_helper_funcs = { + .get_modes = serdes_connector_get_modes, +}; + +static enum drm_connector_status +serdes_connector_detect(struct drm_connector *connector, bool force) +{ + struct rk_serdes_panel *sd_panel = drm_connector_to_serdes_panel(connector); + + return drm_bridge_detect(&sd_panel->bridge); +} + +static const struct drm_connector_funcs rk_serdes_connector_funcs = { + .detect = serdes_connector_detect, + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int rk_serdes_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge); + struct drm_connector *connector = &sd_panel->connector; + int ret; + + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) + return 0; + + if (!bridge->encoder) { + dev_err(sd_panel->dev, "Missing encoder\n"); + return -ENODEV; + } + + connector->polled |= DRM_CONNECTOR_POLL_HPD; + drm_connector_helper_add(connector, + &rk_serdes_connector_helper_funcs); + + ret = drm_connector_init(bridge->dev, connector, + &rk_serdes_connector_funcs, + sd_panel->connector_type); + if (ret) { + dev_err(sd_panel->dev, "Failed to initialize connector\n"); + return ret; + } + + drm_connector_attach_encoder(&sd_panel->connector, bridge->encoder); + + return 0; +} + +static void rk_serdes_bridge_detach(struct drm_bridge *bridge) +{ + struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge); + struct drm_connector *connector = &sd_panel->connector; + + /* + * Cleanup the connector if we know it was initialized. + */ + if (connector->dev) + drm_connector_cleanup(connector); +} + +static void rk_serdes_bridge_pre_enable(struct drm_bridge *bridge) +{ + struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge); + + drm_panel_prepare(&sd_panel->panel); +} + +static void rk_serdes_bridge_enable(struct drm_bridge *bridge) +{ + struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge); + + drm_panel_enable(&sd_panel->panel); +} + +static void rk_serdes_bridge_disable(struct drm_bridge *bridge) +{ + struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge); + + drm_panel_disable(&sd_panel->panel); +} + +static void rk_serdes_bridge_post_disable(struct drm_bridge *bridge) +{ + struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge); + + drm_panel_unprepare(&sd_panel->panel); +} + +static int rk_serdes_bridge_get_modes(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + struct rk_serdes_panel *sd_panel = drm_bridge_to_serdes_panel(bridge); + + return drm_panel_get_modes(&sd_panel->panel, connector); +} + +static enum drm_connector_status rk_serdes_bridge_detect(struct drm_bridge *bridge) +{ + return connector_status_connected; +} + +static const struct drm_bridge_funcs panel_bridge_bridge_funcs = { + .attach = rk_serdes_bridge_attach, + .detach = rk_serdes_bridge_detach, + .pre_enable = rk_serdes_bridge_pre_enable, + .enable = rk_serdes_bridge_enable, + .disable = rk_serdes_bridge_disable, + .post_disable = rk_serdes_bridge_post_disable, + .get_modes = rk_serdes_bridge_get_modes, + .detect = rk_serdes_bridge_detect, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt, +}; + +static int serdes_panel_hw_prepare(struct rk_serdes_panel *sd_panel) +{ if (sd_panel->supply) { int err; @@ -58,36 +196,84 @@ mdelay(20); } + return 0; +} + +static int serdes_panel_dsi_prepare(struct rk_serdes_panel *sd_panel) +{ + struct rk_serdes *serdes = sd_panel->parent; + + if (sd_panel->id == 0 && sd_panel->route.remote0_port0 == RK_SERDES_DSI_TX0 && + !!(sd_panel->on_cmds)) + rkx120_dsi_tx_cmd_seq_xfer(serdes, &sd_panel->dsi_tx, DEVICE_REMOTE0, + sd_panel->on_cmds); + + if (sd_panel->id == 1 && sd_panel->route.remote1_port0 == RK_SERDES_DSI_TX0 && + !!(sd_panel->on_cmds)) + rkx120_dsi_tx_cmd_seq_xfer(serdes, &sd_panel->dsi_tx, DEVICE_REMOTE1, + sd_panel->on_cmds); + + return 0; +} + +static int serdes_panel_prepare(struct drm_panel *panel) +{ + struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel); + struct rk_serdes *serdes = sd_panel->parent; + int ret; + + ret = serdes_panel_hw_prepare(sd_panel); + if (ret) + return ret; + if (sd_panel->secondary) { + ret = serdes_panel_hw_prepare(sd_panel->secondary); + if (ret) + return ret; + } + if (serdes->route_prepare) serdes->route_prepare(serdes, &sd_panel->route); - if (route->remote0_port0 == RK_SERDES_DSI_TX0 && !!(sd_panel->on_cmds)) - rkx120_dsi_tx_cmd_seq_xfer(serdes, DEVICE_REMOTE0, - sd_panel->on_cmds); - - if (route->remote1_port0 == RK_SERDES_DSI_TX0 && !!(sd_panel->on_cmds)) - rkx120_dsi_tx_cmd_seq_xfer(serdes, DEVICE_REMOTE1, - sd_panel->on_cmds); + serdes_panel_dsi_prepare(sd_panel); + if (sd_panel->secondary) + serdes_panel_dsi_prepare(sd_panel->secondary); return 0; } static int serdes_panel_enable(struct drm_panel *panel) { - struct rk_serdes_panel *sd_panel = to_serdes_panel(panel); + struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel); struct rk_serdes *serdes = sd_panel->parent; + int ret; if (serdes->route_enable) serdes->route_enable(serdes, &sd_panel->route); + + if (sd_panel->secondary) { + ret = backlight_enable(sd_panel->secondary->panel.backlight); + if (ret < 0) { + dev_err(sd_panel->dev, "failed to enable backlight: %d\n", ret); + return ret; + } + } return 0; } static int serdes_panel_disable(struct drm_panel *panel) { - struct rk_serdes_panel *sd_panel = to_serdes_panel(panel); + struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel); struct rk_serdes *serdes = sd_panel->parent; + int ret; + if (sd_panel->secondary) { + ret = backlight_disable(sd_panel->secondary->panel.backlight); + if (ret < 0) { + dev_err(sd_panel->dev, "failed to disable backlight: %d\n", ret); + return ret; + } + } if (serdes->route_disable) serdes->route_disable(serdes, &sd_panel->route); @@ -95,22 +281,8 @@ return 0; } -static int serdes_panel_unprepare(struct drm_panel *panel) +static int serdes_panel_hw_unprepare(struct rk_serdes_panel *sd_panel) { - struct rk_serdes_panel *sd_panel = to_serdes_panel(panel); - struct rk_serdes_route *route = &sd_panel->route; - struct rk_serdes *serdes = sd_panel->parent; - - if (route->remote0_port0 == RK_SERDES_DSI_TX0 && !!(sd_panel->on_cmds)) - rkx120_dsi_tx_cmd_seq_xfer(serdes, DEVICE_REMOTE0, - sd_panel->off_cmds); - - if (route->remote1_port0 == RK_SERDES_DSI_TX0 && !!(sd_panel->on_cmds)) - rkx120_dsi_tx_cmd_seq_xfer(serdes, DEVICE_REMOTE1, - sd_panel->off_cmds); - if (serdes->route_unprepare) - serdes->route_unprepare(serdes, &sd_panel->route); - if (sd_panel->reset_gpio) { gpiod_set_value_cansleep(sd_panel->reset_gpio, 0); mdelay(20); @@ -123,6 +295,42 @@ if (sd_panel->supply) regulator_disable(sd_panel->supply); + + return 0; +} + +static int serdes_panel_dsi_unprepare(struct rk_serdes_panel *sd_panel) +{ + struct rk_serdes *serdes = sd_panel->parent; + + if (sd_panel->id == 0 && sd_panel->route.remote0_port0 == RK_SERDES_DSI_TX0 && + !!(sd_panel->off_cmds)) + rkx120_dsi_tx_cmd_seq_xfer(serdes, &sd_panel->dsi_tx, DEVICE_REMOTE0, + sd_panel->off_cmds); + + if (sd_panel->id == 1 && sd_panel->route.remote1_port0 == RK_SERDES_DSI_TX0 && + !!(sd_panel->off_cmds)) + rkx120_dsi_tx_cmd_seq_xfer(serdes, &sd_panel->dsi_tx, DEVICE_REMOTE1, + sd_panel->off_cmds); + + return 0; +} + +static int serdes_panel_unprepare(struct drm_panel *panel) +{ + struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel); + struct rk_serdes *serdes = sd_panel->parent; + + serdes_panel_dsi_unprepare(sd_panel); + if (sd_panel->secondary) + serdes_panel_dsi_unprepare(sd_panel->secondary); + + if (serdes->route_unprepare) + serdes->route_unprepare(serdes, &sd_panel->route); + + serdes_panel_hw_unprepare(sd_panel); + if (sd_panel->secondary) + serdes_panel_hw_unprepare(sd_panel->secondary); return 0; } @@ -184,7 +392,7 @@ static int serdes_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { - struct rk_serdes_panel *sd_panel = to_serdes_panel(panel); + struct rk_serdes_panel *sd_panel = drm_panel_to_serdes_panel(panel); int num = 0; num += serdes_panel_of_get_native_mode(sd_panel, connector); @@ -201,6 +409,52 @@ .unprepare = serdes_panel_unprepare, .get_modes = serdes_panel_get_modes, }; + +static void rk_serdes_panel_get_connector_type(struct rk_serdes_panel *sd_panel) +{ + struct rk_serdes_route *route = &sd_panel->route; + u32 local_port; + + if (route->local_port0) + local_port = route->local_port0; + else + local_port = route->local_port1; + + if ((local_port == RK_SERDES_DSI_RX0) || + (local_port == RK_SERDES_DSI_RX1)) + sd_panel->connector_type = DRM_MODE_CONNECTOR_DSI; + else if (local_port == RK_SERDES_RGB_RX) + sd_panel->connector_type = DRM_MODE_CONNECTOR_DPI; + else + sd_panel->connector_type = DRM_MODE_CONNECTOR_LVDS; +} + +static int rk_serdes_panel_bridge_add(struct rk_serdes_panel *sd_panel) +{ + int ret; + + rk_serdes_panel_get_connector_type(sd_panel); + + sd_panel->bridge.funcs = &panel_bridge_bridge_funcs; + sd_panel->bridge.of_node = sd_panel->dev->of_node; + sd_panel->bridge.ops = DRM_BRIDGE_OP_MODES | DRM_BRIDGE_OP_DETECT; + sd_panel->bridge.type = sd_panel->connector_type; + + drm_panel_init(&sd_panel->panel, sd_panel->dev, &serdes_panel_funcs, 0); + + ret = drm_panel_of_backlight(&sd_panel->panel); + if (ret) + return ret; + + drm_bridge_add(&sd_panel->bridge); + + return 0; +} + +static void rk_serdes_panel_bridge_remove(struct rk_serdes_panel *sd_panel) +{ + drm_bridge_remove(&sd_panel->bridge); +} static int dsi_panel_parse_cmds(struct device *dev, const u8 *data, @@ -336,11 +590,10 @@ return dsi; } -static int rkx120_dsi_rx_parse(struct rk_serdes_panel *sd_panel) +static int rkx110_dsi_rx_parse(struct rk_serdes_panel *sd_panel) { struct device_node *np = sd_panel->dev->of_node; - struct rk_serdes *serdes = sd_panel->parent; - struct rkx110_dsi_rx *dsi_rx = &serdes->dsi_rx; + struct rkx110_dsi_rx *dsi_rx = &sd_panel->dsi_rx; struct mipi_dsi_device *dsi; struct device_node *dsi_node; u32 val; @@ -370,11 +623,12 @@ static int rkx120_dsi_tx_parse(struct rk_serdes_panel *sd_panel) { struct device_node *np = sd_panel->dev->of_node; - struct rk_serdes *serdes = sd_panel->parent; - struct rkx120_dsi_tx *dsi_tx = &serdes->dsi_tx; + struct rkx120_dsi_tx *dsi_tx = &sd_panel->dsi_tx; const char *string; int ret; u32 val; + + dsi_tx->combtxphy = &sd_panel->combtxphy; if (of_property_read_u32(np, "dsi-tx,lanes", &val)) dsi_tx->lanes = 4; @@ -418,12 +672,9 @@ return 0; } -static int serdes_panel_parse_dt(struct rk_serdes_panel *sd_panel) +static int serdes_panel_parse_route(struct rk_serdes_panel *sd_panel) { struct rk_serdes_route *route = &sd_panel->route; - struct rk_serdes *serdes = sd_panel->parent; - u32 lanes; - int ret; device_property_read_u32(sd_panel->dev, "local-port0", &route->local_port0); device_property_read_u32(sd_panel->dev, "local-port1", &route->local_port1); @@ -431,17 +682,19 @@ device_property_read_u32(sd_panel->dev, "remote0-port1", &route->remote0_port1); device_property_read_u32(sd_panel->dev, "remote1-port0", &route->remote1_port0); device_property_read_u32(sd_panel->dev, "remote1-port1", &route->remote1_port1); - device_property_read_u32(sd_panel->dev, "num-lanes", &lanes); - serdes->route_flag = 0; - - if (!route->local_port0) { - dev_err(sd_panel->dev, "local_port0 should set\n"); + if (!route->local_port0 && !route->local_port1) { + dev_err(sd_panel->dev, "local port should set\n"); return -EINVAL; } - if (!route->remote0_port0) { + if (route->local_port0 && !route->remote0_port0) { dev_err(sd_panel->dev, "remote0_port0 should set\n"); + return -EINVAL; + } + + if (route->local_port1 && !route->remote1_port0) { + dev_err(sd_panel->dev, "remote1_port0 should set\n"); return -EINVAL; } @@ -451,48 +704,28 @@ } route->frame_mode = SERDES_FRAME_NORMAL_MODE; + route->route_flag = 0; - /* 2 video stream output */ - if (route->remote1_port0 || route->remote0_port1) { + /* 2 video stream output in a route */ + if (route->local_port0 && (route->remote1_port0 || route->remote0_port1)) { if (route->remote1_port0) - serdes->route_flag |= ROUTE_MULTI_REMOTE | ROUTE_MULTI_CHANNEL | + route->route_flag |= ROUTE_MULTI_REMOTE | ROUTE_MULTI_CHANNEL| ROUTE_MULTI_LANE; if (route->remote0_port1) { if ((route->remote0_port0 == RK_SERDES_LVDS_TX0) && (route->remote0_port1 == RK_SERDES_LVDS_TX1)) { - serdes->route_flag |= ROUTE_MULTI_CHANNEL; + route->route_flag |= ROUTE_MULTI_CHANNEL; } else if ((route->remote0_port0 == RK_SERDES_LVDS_TX1) && (route->remote0_port1 == RK_SERDES_LVDS_TX0)) { - serdes->route_flag |= ROUTE_MULTI_CHANNEL; + route->route_flag |= ROUTE_MULTI_CHANNEL; } else { dev_err(sd_panel->dev, "invalid multi output type\n"); return -EINVAL; } - - if (lanes == 2) - serdes->route_flag |= ROUTE_MULTI_LANE; } - if (route->local_port1) { - if ((route->local_port0 == RK_SERDES_DSI_RX0) && - (route->local_port1 == RK_SERDES_DSI_RX1)) - serdes->route_flag |= ROUTE_MULTI_DSI_INPUT; - else if ((route->local_port0 == RK_SERDES_DSI_RX1) && - (route->local_port1 == RK_SERDES_DSI_RX0)) - serdes->route_flag |= ROUTE_MULTI_DSI_INPUT; - else if ((route->local_port0 == RK_SERDES_LVDS_RX0) && - (route->local_port1 == RK_SERDES_LVDS_RX1)) - serdes->route_flag |= ROUTE_MULTI_LVDS_INPUT; - else if ((route->local_port0 == RK_SERDES_LVDS_RX1) && - (route->local_port1 == RK_SERDES_LVDS_RX0)) - serdes->route_flag |= ROUTE_MULTI_LVDS_INPUT; - else { - dev_err(sd_panel->dev, "invalid multi input type\n"); - return -EINVAL; - } - serdes->route_flag |= ROUTE_MULTI_SOURCE; - } else { + if (route->local_port0) { if (device_property_read_bool(sd_panel->dev, "split-mode")) { /* only dsi input support split mode */ if ((route->local_port0 != RK_SERDES_DSI_RX0) && @@ -510,41 +743,43 @@ else route->frame_mode = SERDES_SP_LEFT_RIGHT_SPLIT; - serdes->route_flag |= ROUTE_MULTI_SPLIT; + route->route_flag |= ROUTE_MULTI_SPLIT; } else { - serdes->route_flag |= ROUTE_MULTI_MIRROR; + route->route_flag |= ROUTE_MULTI_MIRROR; } } - } else { - if (lanes == 2) - serdes->route_flag |= ROUTE_MULTI_LANE; - } - - if (route->remote0_port0 & RK_SERDES_DSI_TX0 || - route->remote1_port0 & RK_SERDES_DSI_TX0) { - ret = rkx120_dsi_tx_parse(sd_panel); - if (ret) { - dev_err(sd_panel->dev, "failed to get cmds\n"); - return ret; - } - } - - if (route->local_port0 & RK_SERDES_DSI_RX0 || - route->local_port0 & RK_SERDES_DSI_TX1) { - ret = rkx120_dsi_rx_parse(sd_panel); - if (ret < 0) - return ret; } return 0; } +static int serdes_panel_match_by_id(struct device *dev, const void *data) +{ + struct rk_serdes_panel *sd_panel = dev_get_drvdata(dev); + unsigned int *id = (unsigned int *)data; + + return sd_panel->id == *id; +} + +static struct rk_serdes_panel *serdes_panel_find_by_id(struct device_driver *drv, + unsigned int id) +{ + struct device *dev; + + dev = driver_find_device(drv, NULL, &id, serdes_panel_match_by_id); + if (!dev) + return NULL; + + return dev_get_drvdata(dev); +} + static int serdes_panel_probe(struct platform_device *pdev) { struct rk_serdes *serdes = dev_get_drvdata(pdev->dev.parent); - struct rk_serdes_panel *sd_panel; + struct rk_serdes_panel *sd_panel, *secondary; int ret; + u32 reg; sd_panel = devm_kzalloc(&pdev->dev, sizeof(*sd_panel), GFP_KERNEL); if (!sd_panel) @@ -553,7 +788,20 @@ sd_panel->dev = &pdev->dev; sd_panel->parent = serdes; sd_panel->route.stream_type = STREAM_DISPLAY; - serdes->vm = &sd_panel->route.vm; + + ret = of_property_read_u32(sd_panel->dev->of_node, "reg", ®); + if (ret) + sd_panel->id = 0; + sd_panel->id = reg; + + sd_panel->multi_panel = device_property_read_bool(sd_panel->dev, "multi-panel"); + if (sd_panel->multi_panel) { + secondary = serdes_panel_find_by_id(sd_panel->dev->driver, 1); + if (!secondary) + return -EPROBE_DEFER; + sd_panel->secondary = secondary; + dev_info(sd_panel->dev, "%s get secondary panel\n", __func__); + } sd_panel->supply = devm_regulator_get_optional(sd_panel->dev, "power"); if (IS_ERR(sd_panel->supply)) { @@ -588,22 +836,58 @@ return ret; } - /* Register the panel. */ - drm_panel_init(&sd_panel->panel, sd_panel->dev, &serdes_panel_funcs, 0); + ret = serdes_panel_parse_route(sd_panel); + if (ret < 0) + return ret; - ret = drm_panel_of_backlight(&sd_panel->panel); + if (sd_panel->route.remote0_port0 & RK_SERDES_DSI_TX0 || + sd_panel->route.remote1_port0 & RK_SERDES_DSI_TX0) { + ret = rkx120_dsi_tx_parse(sd_panel); + if (ret) { + dev_err(sd_panel->dev, "failed to get cmds\n"); + return ret; + } + } + + ret = rk_serdes_panel_bridge_add(sd_panel); if (ret) return ret; - drm_panel_add(&sd_panel->panel); + if ((sd_panel->route.local_port0 & RK_SERDES_DSI_RX0 || + sd_panel->route.local_port0 & RK_SERDES_DSI_RX1) && sd_panel->id == 0) { + ret = rkx110_dsi_rx_parse(sd_panel); + if (ret < 0) { + rk_serdes_panel_bridge_remove(sd_panel); + return ret; + } + } + + if ((sd_panel->route.local_port1 & RK_SERDES_DSI_RX0 || + sd_panel->route.local_port1 & RK_SERDES_DSI_RX1) && sd_panel->id == 1) { + ret = rkx110_dsi_rx_parse(sd_panel); + if (ret < 0) { + rk_serdes_panel_bridge_remove(sd_panel); + return ret; + } + } dev_set_drvdata(sd_panel->dev, sd_panel); - ret = serdes_panel_parse_dt(sd_panel); - if (ret < 0) { - drm_panel_remove(&sd_panel->panel); - return ret; + if (sd_panel->route.route_flag & ROUTE_MULTI_CHANNEL) + serdes->channel_nr = 2; + + if (sd_panel->route.local_port0 && sd_panel->id == 0) { + serdes->route[0] = &sd_panel->route; + serdes->route_nr++; } + + if (sd_panel->route.local_port1 && sd_panel->id == 1) { + serdes->route[1] = &sd_panel->route; + serdes->route_nr++; + } + + if (serdes->route_nr == 2) + serdes->channel_nr = 2; return 0; } @@ -612,7 +896,7 @@ { struct rk_serdes_panel *sd_panel = dev_get_drvdata(&pdev->dev); - drm_panel_remove(&sd_panel->panel); + rk_serdes_panel_bridge_remove(sd_panel); drm_panel_disable(&sd_panel->panel); @@ -630,7 +914,7 @@ .probe = serdes_panel_probe, .remove = serdes_panel_remove, .driver = { - .name = "serdes-panel", + .name = "rockchip-serdes-panel", .of_match_table = serdes_panel_of_table, }, }; -- Gitblit v1.6.2