From 8cfb46089990799e3981ea67a927b1025c02a0b2 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Fri, 21 Apr 2023 01:12:46 +0000 Subject: [PATCH 01/13] drm/rockchip: dsi2: mv mode set to encoder .atomic_enable Signed-off-by: Guochun Huang Change-Id: If792fa3ee9471668023f873e147a48eef3e5b5e7 --- .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 63 +++++++++++++------ 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index 3f5d5c784d56..a17a6a083936 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -448,7 +448,8 @@ static void dw_mipi_dsi2_post_disable(struct dw_mipi_dsi2 *dsi2) dw_mipi_dsi2_post_disable(dsi2->slave); } -static void dw_mipi_dsi2_encoder_disable(struct drm_encoder *encoder) +static void dw_mipi_dsi2_encoder_atomic_disable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct dw_mipi_dsi2 *dsi2 = encoder_to_dsi2(encoder); struct drm_crtc *crtc = encoder->crtc; @@ -835,9 +836,46 @@ static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2) dw_mipi_dsi2_enable(dsi2->slave); } -static void dw_mipi_dsi2_encoder_enable(struct drm_encoder *encoder) +static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, + struct drm_atomic_state *state) +{ + struct drm_encoder *encoder = &dsi2->encoder; + struct drm_connector *connector; + struct drm_connector_state *conn_state; + struct drm_crtc_state *crtc_state; + + connector = drm_atomic_get_new_connector_for_encoder(state, encoder); + if (!connector) + return -ENODEV; + + conn_state = drm_atomic_get_new_connector_state(state, connector); + if (!conn_state) + return -ENODEV; + + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + if (!crtc_state) { + dev_err(dsi2->dev, "failed to get crtc state\n"); + return -ENODEV; + } + + drm_mode_copy(&dsi2->mode, &crtc_state->adjusted_mode); + if (dsi2->slave) + drm_mode_copy(&dsi2->slave->mode, &crtc_state->adjusted_mode); + + return 0; +} + +static void dw_mipi_dsi2_encoder_atomic_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct dw_mipi_dsi2 *dsi2 = encoder_to_dsi2(encoder); + int ret; + + ret = dw_mipi_dsi2_encoder_mode_set(dsi2, state); + if (ret) { + dev_err(dsi2->dev, "failed to set dsi2 mode\n"); + return; + } dw_mipi_dsi2_get_lane_rate(dsi2); @@ -865,8 +903,8 @@ static void dw_mipi_dsi2_encoder_enable(struct drm_encoder *encoder) static int dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); @@ -931,18 +969,6 @@ dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder, return 0; } -static void -dw_mipi_dsi2_encoder_atomic_mode_set(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *connector_state) -{ - struct dw_mipi_dsi2 *dsi2 = encoder_to_dsi2(encoder); - - drm_mode_copy(&dsi2->mode, &crtc_state->adjusted_mode); - if (dsi2->slave) - drm_mode_copy(&dsi2->slave->mode, &crtc_state->adjusted_mode); -} - static void dw_mipi_dsi2_loader_protect(struct dw_mipi_dsi2 *dsi2, bool on) { if (on) { @@ -978,10 +1004,9 @@ static int dw_mipi_dsi2_encoder_loader_protect(struct drm_encoder *encoder, static const struct drm_encoder_helper_funcs dw_mipi_dsi2_encoder_helper_funcs = { - .enable = dw_mipi_dsi2_encoder_enable, - .disable = dw_mipi_dsi2_encoder_disable, + .atomic_enable = dw_mipi_dsi2_encoder_atomic_enable, + .atomic_disable = dw_mipi_dsi2_encoder_atomic_disable, .atomic_check = dw_mipi_dsi2_encoder_atomic_check, - .atomic_mode_set = dw_mipi_dsi2_encoder_atomic_mode_set, }; static int dw_mipi_dsi2_connector_get_modes(struct drm_connector *connector) From 6ef5aaf99ed26ee0e6b202d4078c8bbac564f842 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Fri, 21 Apr 2023 08:47:18 +0000 Subject: [PATCH 02/13] drm/bridge: analogix_dp: mv mode_set to bridge .atomic_pre_enable Change-Id: I4cabcb05cb1d67df6280f601ec1c920cb42bb6ce Signed-off-by: Guochun Huang --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 1a76671e46e5..e9bf6f7fdc3a 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -52,6 +52,9 @@ struct bridge_init { struct device_node *node; }; +static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *adj_mode); + static bool analogix_dp_bandwidth_ok(struct analogix_dp_device *dp, const struct drm_display_mode *mode, unsigned int rate, unsigned int lanes) @@ -1575,13 +1578,17 @@ analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge, struct drm_atomic_state *old_state = old_bridge_state->base.state; struct analogix_dp_device *dp = bridge->driver_private; struct drm_crtc *crtc; - struct drm_crtc_state *old_crtc_state; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; crtc = analogix_dp_get_new_crtc(dp, old_state); if (!crtc) return; old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc); + + new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); + analogix_dp_bridge_mode_set(bridge, &new_crtc_state->adjusted_mode); + /* Don't touch the panel if we're coming back from PSR */ if (old_crtc_state && old_crtc_state->self_refresh_active) return; @@ -1790,7 +1797,6 @@ analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge, } static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, - const struct drm_display_mode *orig_mode, const struct drm_display_mode *adj_mode) { struct analogix_dp_device *dp = bridge->driver_private; @@ -1934,7 +1940,6 @@ static const struct drm_bridge_funcs analogix_dp_bridge_funcs = { .atomic_enable = analogix_dp_bridge_atomic_enable, .atomic_disable = analogix_dp_bridge_atomic_disable, .atomic_post_disable = analogix_dp_bridge_atomic_post_disable, - .mode_set = analogix_dp_bridge_mode_set, .attach = analogix_dp_bridge_attach, .detach = analogix_dp_bridge_detach, .mode_valid = analogix_dp_bridge_mode_valid, From 649255c0e301e74bad3a7d5719cd6cb5de47ef8c Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Sat, 3 Jun 2023 09:52:37 +0000 Subject: [PATCH 03/13] drm/rockchip: drv: Add crtc_clock convert in drm_mode_convert_to_{split,origin}_mode() Signed-off-by: Guochun Huang Change-Id: Ia8138dca964ef619f4b99d7f07b30441cb39dca9 --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index f15be91177dd..0835dd07565f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -125,6 +125,7 @@ void drm_mode_convert_to_split_mode(struct drm_display_mode *mode) hbp = mode->htotal - mode->hsync_end; mode->clock *= 2; + mode->crtc_clock *= 2; mode->hdisplay = hactive * 2; mode->hsync_start = mode->hdisplay + hfp * 2; mode->hsync_end = mode->hsync_start + hsync * 2; @@ -143,6 +144,7 @@ void drm_mode_convert_to_origin_mode(struct drm_display_mode *mode) hbp = mode->htotal - mode->hsync_end; mode->clock /= 2; + mode->crtc_clock /= 2; mode->hdisplay = hactive / 2; mode->hsync_start = mode->hdisplay + hfp / 2; mode->hsync_end = mode->hsync_start + hsync / 2; From 442df8e89b4dc7867be8bd32f6adacf99d70a4a5 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Tue, 20 Jun 2023 03:42:33 +0000 Subject: [PATCH 04/13] drm/rockchip: dsi2: support split mode with other display interface Signed-off-by: Guochun Huang Change-Id: I78623fe2be99022a2a4ea7a7d3ef27578e094432 --- .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index a17a6a083936..63bce16179a9 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -275,6 +275,10 @@ struct dw_mipi_dsi2 { struct rockchip_drm_sub_dev sub_dev; struct gpio_desc *te_gpio; + + /* split with other display interface */ + bool dual_connector_split; + bool left_display; }; static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host) @@ -843,6 +847,8 @@ static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, struct drm_connector *connector; struct drm_connector_state *conn_state; struct drm_crtc_state *crtc_state; + const struct drm_display_mode *adjusted_mode; + struct drm_display_mode *mode = &dsi2->mode; connector = drm_atomic_get_new_connector_for_encoder(state, encoder); if (!connector) @@ -858,9 +864,14 @@ static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, return -ENODEV; } - drm_mode_copy(&dsi2->mode, &crtc_state->adjusted_mode); + adjusted_mode = &crtc_state->adjusted_mode; + drm_mode_copy(mode, adjusted_mode); + + if (dsi2->dual_connector_split) + drm_mode_convert_to_origin_mode(mode); + if (dsi2->slave) - drm_mode_copy(&dsi2->slave->mode, &crtc_state->adjusted_mode); + drm_mode_copy(&dsi2->slave->mode, mode); return 0; } @@ -953,6 +964,15 @@ dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder, s->output_if |= VOP_OUTPUT_IF_MIPI1; } + if (dsi2->dual_connector_split) { + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CONNECTOR_SPLIT_MODE; + + if (dsi2->left_display) + s->output_if_left_panel |= dsi2->id ? + VOP_OUTPUT_IF_MIPI1 : + VOP_OUTPUT_IF_MIPI0; + } + if (dsi2->dsc_enable) { s->dsc_enable = 1; s->dsc_sink_cap.version_major = dsi2->version_major; @@ -1567,6 +1587,13 @@ static int dw_mipi_dsi2_probe(struct platform_device *pdev) dsi2->pdata = of_device_get_match_data(dev); platform_set_drvdata(pdev, dsi2); + if (device_property_read_bool(dev, "dual-connector-split")) { + dsi2->dual_connector_split = true; + + if (device_property_read_bool(dev, "left-display")) + dsi2->left_display = true; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(dev, res); if (IS_ERR(regs)) From a0d31a5520c5ef5bf3f4fa4bf94f7da255c215b1 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Tue, 20 Jun 2023 03:27:00 +0000 Subject: [PATCH 05/13] drm/bridge: analogix_dp: support dual connector with other display interface Signed-off-by: Guochun Huang Change-Id: Ic86b7237d7d01031ca761d557389426051c58eee --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 +- include/drm/bridge/analogix_dp.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index e9bf6f7fdc3a..455a41ac0bda 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1916,7 +1916,7 @@ analogix_dp_bridge_mode_valid(struct drm_bridge *bridge, drm_mode_copy(&m, mode); - if (dp->plat_data->split_mode) + if (dp->plat_data->split_mode || dp->plat_data->dual_connector_split) dp->plat_data->convert_to_origin_mode(&m); max_link_rate = min_t(u32, dp->video_info.max_link_rate, diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index e912503a9149..09f0dfeff6e8 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -43,6 +43,11 @@ struct analogix_dp_plat_data { bool ssc; bool split_mode; + + /* split with other display interface */ + bool dual_connector_split; + bool left_display; + struct analogix_dp_device *left; struct analogix_dp_device *right; From cf4fecc4dc71542ab10bb1c01fc1a25d5c939836 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Wed, 5 Jul 2023 12:17:20 +0000 Subject: [PATCH 06/13] drm/rockchip: analogix_dp: support split mode with other display interface Change-Id: I1a7e5215259ad669a9e6fe9dd79246b16e45d82d Signed-off-by: Guochun Huang --- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 236b0ddc0242..e15c50e7a53d 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -437,6 +437,16 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, } else { s->output_if |= dp->id ? VOP_OUTPUT_IF_eDP1 : VOP_OUTPUT_IF_eDP0; } + + if (dp->plat_data.dual_connector_split) { + s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CONNECTOR_SPLIT_MODE; + + if (dp->plat_data.left_display) + s->output_if_left_panel |= dp->id ? + VOP_OUTPUT_IF_eDP1 : + VOP_OUTPUT_IF_eDP0; + } + s->output_bpc = di->bpc; s->bus_flags = di->bus_flags; s->tv_state = &conn_state->tv; @@ -678,6 +688,12 @@ static int rockchip_dp_probe(struct platform_device *pdev) device_property_read_u32(dev, "min-refresh-rate", &dp->min_refresh_rate); device_property_read_u32(dev, "max-refresh-rate", &dp->max_refresh_rate); + if (dp->data->split_mode && device_property_read_bool(dev, "dual-connector-split")) { + dp->plat_data.dual_connector_split = true; + if (device_property_read_bool(dev, "left-display")) + dp->plat_data.left_display = true; + } + ret = component_add(dev, &rockchip_dp_component_ops); if (ret) goto err_dp_remove; From 4f58666813ddd712c10d91bbe9aac331a1ff8807 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Wed, 5 Jul 2023 12:48:38 +0000 Subject: [PATCH 07/13] drm/rockchip: dsi2: add support split area prop Change-Id: Ia96f8f40d2703865808b5cdc4e84b30a81d7c974 Signed-off-by: Guochun Huang --- .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index 63bce16179a9..b7a24e102d75 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -279,6 +279,7 @@ struct dw_mipi_dsi2 { /* split with other display interface */ bool dual_connector_split; bool left_display; + u32 split_area; }; static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host) @@ -1108,6 +1109,32 @@ static void dw_mipi_dsi2_drm_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } +static int +dw_mipi_dsi2_atomic_connector_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + struct rockchip_drm_private *private = connector->dev->dev_private; + struct dw_mipi_dsi2 *dsi2 = con_to_dsi2(connector); + + if (property == private->split_area_prop) { + switch (dsi2->split_area) { + case 1: + *val = ROCKCHIP_DRM_SPLIT_LEFT_SIDE; + break; + case 2: + *val = ROCKCHIP_DRM_SPLIT_RIGHT_SIDE; + break; + default: + *val = ROCKCHIP_DRM_SPLIT_UNSET; + break; + } + } + + return 0; +} + static const struct drm_connector_funcs dw_mipi_dsi2_atomic_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .detect = dw_mipi_dsi2_connector_detect, @@ -1115,6 +1142,7 @@ static const struct drm_connector_funcs dw_mipi_dsi2_atomic_connector_funcs = { .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .atomic_get_property = dw_mipi_dsi2_atomic_connector_get_property, }; static int dw_mipi_dsi2_dual_channel_probe(struct dw_mipi_dsi2 *dsi2) @@ -1261,8 +1289,16 @@ connector_cleanup: static int dw_mipi_dsi2_register_sub_dev(struct dw_mipi_dsi2 *dsi2, struct drm_connector *connector) { + struct rockchip_drm_private *private; struct device *dev = dsi2->dev; + private = connector->dev->dev_private; + + if (dsi2->split_area) + drm_object_attach_property(&connector->base, + private->split_area_prop, + dsi2->split_area); + dsi2->sub_dev.connector = connector; dsi2->sub_dev.of_node = dev->of_node; dsi2->sub_dev.loader_protect = dw_mipi_dsi2_encoder_loader_protect; @@ -1594,6 +1630,9 @@ static int dw_mipi_dsi2_probe(struct platform_device *pdev) dsi2->left_display = true; } + if (device_property_read_u32(dev, "split-area", &dsi2->split_area)) + dsi2->split_area = 0; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(dev, res); if (IS_ERR(regs)) From 297258e67842f13417169ef538259b14607ac01b Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Wed, 5 Jul 2023 13:12:01 +0000 Subject: [PATCH 08/13] drm/bridge: analogix_dp: add support split area prop Change-Id: I8520ee076b08ca86ae40f1fddeac2c0314eef7d1 Signed-off-by: Guochun Huang --- .../drm/bridge/analogix/analogix_dp_core.c | 39 +++++++++++++++++++ .../drm/bridge/analogix/analogix_dp_core.h | 2 + 2 files changed, 41 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 455a41ac0bda..53264c731c69 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -32,6 +32,7 @@ #include "analogix_dp_core.h" #include "analogix_dp_reg.h" +#include "../../rockchip/rockchip_drm_drv.h" #define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) @@ -1445,6 +1446,32 @@ static void analogix_dp_connector_force(struct drm_connector *connector) extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false); } +static int +analogix_dp_atomic_connector_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + struct rockchip_drm_private *private = connector->dev->dev_private; + struct analogix_dp_device *dp = to_dp(connector); + + if (property == private->split_area_prop) { + switch (dp->split_area) { + case 1: + *val = ROCKCHIP_DRM_SPLIT_LEFT_SIDE; + break; + case 2: + *val = ROCKCHIP_DRM_SPLIT_RIGHT_SIDE; + break; + default: + *val = ROCKCHIP_DRM_SPLIT_UNSET; + break; + } + } + + return 0; +} + static const struct drm_connector_funcs analogix_dp_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .detect = analogix_dp_connector_detect, @@ -1453,6 +1480,7 @@ static const struct drm_connector_funcs analogix_dp_connector_funcs = { .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .force = analogix_dp_connector_force, + .atomic_get_property = analogix_dp_atomic_connector_get_property, }; static int analogix_dp_bridge_attach(struct drm_bridge *bridge, @@ -1483,6 +1511,7 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge, if (!dp->plat_data->skip_connector) { int connector_type = DRM_MODE_CONNECTOR_eDP; + struct rockchip_drm_private *private; if (dp->plat_data->bridge && dp->plat_data->bridge->type != DRM_MODE_CONNECTOR_Unknown) @@ -1502,6 +1531,13 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge, return ret; } + private = connector->dev->dev_private; + + if (dp->split_area) + drm_object_attach_property(&connector->base, + private->split_area_prop, + dp->split_area); + drm_connector_helper_add(connector, &analogix_dp_connector_helper_funcs); drm_connector_attach_encoder(connector, encoder); @@ -2078,6 +2114,9 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp) return ret; } + if (device_property_read_u32(dp->dev, "split-area", &dp->split_area)) + dp->split_area = 0; + return 0; } diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index a843a739b76c..f744058e59a5 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -195,6 +195,8 @@ struct analogix_dp_device { struct analogix_dp_plat_data *plat_data; struct extcon_dev *extcon; struct analogix_dp_compliance compliance; + + u32 split_area; }; /* analogix_dp_reg.c */ From c931cf5e00ec228b1b1ec75f4af2346a3ac356a2 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Thu, 29 Jun 2023 11:07:19 +0800 Subject: [PATCH 09/13] mtd: spinand: fmsh: Modify incorrect information despite not used Change-Id: I69cfb5f18155c33f1d76c56d270642d5393869ef Signed-off-by: Jon Lin --- drivers/mtd/nand/spi/fmsh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/spi/fmsh.c b/drivers/mtd/nand/spi/fmsh.c index 0c5761b3b0e6..186ce828f32a 100644 --- a/drivers/mtd/nand/spi/fmsh.c +++ b/drivers/mtd/nand/spi/fmsh.c @@ -97,11 +97,11 @@ static const struct spinand_info fmsh_spinand_table[] = { SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), - 1, + SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)), SPINAND_INFO("FM25S01", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA1), - NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), NAND_ECCREQ(1, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, @@ -110,7 +110,7 @@ static const struct spinand_info fmsh_spinand_table[] = { SPINAND_ECCINFO(&fm25s01_ooblayout, NULL)), SPINAND_INFO("FM25LS01", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA5), - NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), NAND_ECCREQ(1, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, From 1f6698fe5d220549b03af3e222ebc2a6640358e5 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Thu, 29 Jun 2023 11:49:44 +0800 Subject: [PATCH 10/13] mtd: spinand: fmsh: Support new device FM25S01BI3 Change-Id: I8fdd0bdc4913c31031f2298f206ee6a6025031e1 Signed-off-by: Jon Lin --- drivers/mtd/nand/spi/fmsh.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/mtd/nand/spi/fmsh.c b/drivers/mtd/nand/spi/fmsh.c index 186ce828f32a..ef4a586ea50c 100644 --- a/drivers/mtd/nand/spi/fmsh.c +++ b/drivers/mtd/nand/spi/fmsh.c @@ -80,6 +80,31 @@ static const struct mtd_ooblayout_ops fm25s01_ooblayout = { .free = fm25s01_ooblayout_free, }; +/* + * ecc bits: 0xC0[4,6] + * [0b000], No bit errors were detected; + * [0b001] and [0b011], 1~6 Bit errors were detected and corrected. Not + * reach Flipping Bits; + * [0b101], Bit error count equals the bit flip + * detection threshold + * [0b010], Multiple bit errors were detected and + * not corrected. + * others, Reserved. + */ +static int fm25s01bi3_ecc_ecc_get_status(struct spinand_device *spinand, + u8 status) +{ + struct nand_device *nand = spinand_to_nand(spinand); + u8 eccsr = (status & GENMASK(6, 4)) >> 4; + + if (eccsr <= 1 || eccsr == 3) + return eccsr; + else if (eccsr == 5) + return nanddev_get_ecc_requirements(nand)->strength; + else + return -EBADMSG; +} + static const struct spinand_info fmsh_spinand_table[] = { SPINAND_INFO("FM25S01A", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), @@ -117,6 +142,15 @@ static const struct spinand_info fmsh_spinand_table[] = { &update_cache_variants), 0, SPINAND_ECCINFO(&fm25s01_ooblayout, NULL)), + SPINAND_INFO("FM25S01BI3", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&fm25s01_ooblayout, fm25s01bi3_ecc_ecc_get_status)), }; static const struct spinand_manufacturer_ops fmsh_spinand_manuf_ops = { From 390c4a232c583fa27abe21bea32b872c635a788a Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Thu, 6 Jul 2023 19:20:40 +0800 Subject: [PATCH 11/13] mtd: spinand: foresee: Support new device F35UQA002G-WWT Change-Id: Iff7ba4b10e477e950e11c51f4d68b7783a71075c Signed-off-by: Jon Lin --- drivers/mtd/nand/spi/foresee.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mtd/nand/spi/foresee.c b/drivers/mtd/nand/spi/foresee.c index bb2e517755fb..4af967f7ddc3 100644 --- a/drivers/mtd/nand/spi/foresee.c +++ b/drivers/mtd/nand/spi/foresee.c @@ -115,6 +115,15 @@ static const struct spinand_info foresee_spinand_table[] = { &update_cache_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)), + SPINAND_INFO("F35UQA002G-WWT", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x62), + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(1, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)), }; static const struct spinand_manufacturer_ops foresee_spinand_manuf_ops = { From 718ca57be24d11ccac15520f46ab5a114686cb48 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Thu, 6 Jul 2023 19:23:10 +0800 Subject: [PATCH 12/13] mtd: spinand: foresee: Support new device F35UQA001G-WWT Change-Id: Icf2f439e2d7e05be100c22f352ef1473a27b0d29 Signed-off-by: Jon Lin --- drivers/mtd/nand/spi/foresee.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mtd/nand/spi/foresee.c b/drivers/mtd/nand/spi/foresee.c index 4af967f7ddc3..403c33157c37 100644 --- a/drivers/mtd/nand/spi/foresee.c +++ b/drivers/mtd/nand/spi/foresee.c @@ -124,6 +124,15 @@ static const struct spinand_info foresee_spinand_table[] = { &update_cache_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)), + SPINAND_INFO("F35UQA001G-WWT", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x61), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(1, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&fsxxndxxg_ooblayout, NULL)), }; static const struct spinand_manufacturer_ops foresee_spinand_manuf_ops = { From 328145662f6d6154fbf4329a0d53f9c152673648 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Fri, 7 Jul 2023 12:06:40 +0800 Subject: [PATCH 13/13] mtd: spinand: skyhigh: The vendor requires the devices to be patched 1.Double OIP=0 after page 13H 2.The nand flash does not support 84H and 34H command Change-Id: Ie805f42a36e1a864115988087bdc43592cc94ded Signed-off-by: Jon Lin --- drivers/mtd/nand/spi/core.c | 9 ++++++++- drivers/mtd/nand/spi/skyhigh.c | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index bd18e6d0f670..24cdc9356daa 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -527,7 +527,7 @@ static int spinand_read_page(struct spinand_device *spinand, const struct nand_page_io_req *req, bool ecc_enabled) { - u8 status; + u8 status = 0; int ret; ret = spinand_load_page_op(spinand, req); @@ -535,6 +535,13 @@ static int spinand_read_page(struct spinand_device *spinand, return ret; ret = spinand_wait(spinand, &status); + /* + * When there is data outside of OIP in the status, the status data is + * inaccurate and needs to be reconfirmed + */ + if (spinand->id.data[0] == 0x01 && status && !ret) + ret = spinand_wait(spinand, &status); + if (ret < 0) return ret; diff --git a/drivers/mtd/nand/spi/skyhigh.c b/drivers/mtd/nand/spi/skyhigh.c index cda84089a5b2..3d075f12ed82 100644 --- a/drivers/mtd/nand/spi/skyhigh.c +++ b/drivers/mtd/nand/spi/skyhigh.c @@ -26,8 +26,8 @@ static SPINAND_OP_VARIANTS(write_cache_variants, SPINAND_PROG_LOAD(true, 0, NULL, 0)); static SPINAND_OP_VARIANTS(update_cache_variants, - SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), - SPINAND_PROG_LOAD(false, 0, NULL, 0)); + SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), + SPINAND_PROG_LOAD(true, 0, NULL, 0)); static int s35ml04g3_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *region)