Merge commit '328145662f6d6154fbf4329a0d53f9c152673648'

* commit '328145662f6d6154fbf4329a0d53f9c152673648':
  mtd: spinand: skyhigh: The vendor requires the devices to be patched
  mtd: spinand: foresee: Support new device F35UQA001G-WWT
  mtd: spinand: foresee: Support new device F35UQA002G-WWT
  mtd: spinand: fmsh: Support new device FM25S01BI3
  mtd: spinand: fmsh: Modify incorrect information despite not used
  drm/bridge: analogix_dp: add support split area prop
  drm/rockchip: dsi2: add support split area prop
  drm/rockchip: analogix_dp: support split mode with other display interface
  drm/bridge: analogix_dp: support dual connector with other display interface
  drm/rockchip: dsi2: support split mode with other display interface
  drm/rockchip: drv: Add crtc_clock convert in drm_mode_convert_to_{split,origin}_mode()
  drm/bridge: analogix_dp: mv mode_set to bridge .atomic_pre_enable
  drm/rockchip: dsi2: mv mode set to encoder .atomic_enable

Change-Id: Ie34682a12a9877c582fc95803edcf527ccdae98e

Conflicts:
	drivers/mtd/nand/spi/core.c

Ignore:
commit 328145662f ("mtd: spinand: skyhigh: The vendor requires the devices to be patched")

Change-Id: I5baf8f1296e43b3491994529cb8b4ac1f08b3cf4
This commit is contained in:
Tao Huang
2023-08-21 16:45:42 +08:00
8 changed files with 238 additions and 26 deletions

View File

@@ -33,6 +33,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)
@@ -53,6 +54,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)
@@ -1443,6 +1447,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,
@@ -1451,6 +1481,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,
@@ -1481,6 +1512,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)
@@ -1500,6 +1532,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);
@@ -1576,13 +1615,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;
@@ -1791,7 +1834,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;
@@ -1911,7 +1953,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,
@@ -1935,7 +1977,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,
@@ -2074,6 +2115,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;
}

View File

@@ -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 */

View File

@@ -447,6 +447,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;
@@ -688,6 +698,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;

View File

@@ -274,6 +274,11 @@ 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;
u32 split_area;
};
static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host)
@@ -447,7 +452,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;
@@ -834,9 +840,53 @@ 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;
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)
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;
}
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, 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);
@@ -864,8 +914,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);
@@ -914,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;
@@ -930,18 +989,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) {
@@ -977,10 +1024,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)
@@ -1062,6 +1108,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,
@@ -1069,6 +1141,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)
@@ -1215,8 +1288,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;
@@ -1541,6 +1622,16 @@ 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;
}
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))

View File

@@ -140,6 +140,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;
@@ -158,6 +159,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;

View File

@@ -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),
@@ -97,11 +122,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,13 +135,22 @@ 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,
&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 = {

View File

@@ -115,6 +115,24 @@ 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)),
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 = {

View File

@@ -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;