From e0eb7db49764306a969183e0ed16659b24be89c1 Mon Sep 17 00:00:00 2001 From: Ian Ray Date: Thu, 21 Sep 2023 13:47:50 +0300 Subject: drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid() Migrate away from custom EDID parsing and validity checks. Note: This is a follow-up to the original RFC by Jani [1]. The first submission in this series should have been marked v2. [1] https://patchwork.freedesktop.org/patch/msgid/20230901102400.552254-1-jani.nikula@intel.com Co-developed-by: Jani Nikula Signed-off-by: Jani Nikula Signed-off-by: Ian Ray Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230921104751.56544-1-ian.ray@ge.com --- .../drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 57 ++++------------------ 1 file changed, 9 insertions(+), 48 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c index 460db3c8a08c..e93083bbec9d 100644 --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c @@ -65,12 +65,11 @@ struct ge_b850v3_lvds { static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr; -static u8 *stdp2690_get_edid(struct i2c_client *client) +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len) { + struct i2c_client *client = context; struct i2c_adapter *adapter = client->adapter; - unsigned char start = 0x00; - unsigned int total_size; - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL); + unsigned char start = block * EDID_LENGTH; struct i2c_msg msgs[] = { { @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client) }, { .addr = client->addr, .flags = I2C_M_RD, - .len = EDID_LENGTH, - .buf = block, + .len = len, + .buf = buf, } }; - if (!block) - return NULL; + if (i2c_transfer(adapter, msgs, 2) != 2) + return -1; - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID.\n"); - goto err; - } - - if (!drm_edid_block_valid(block, 0, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH; - if (total_size > EDID_LENGTH) { - kfree(block); - block = kmalloc(total_size, GFP_KERNEL); - if (!block) - return NULL; - - /* Yes, read the entire buffer, and do not skip the first - * EDID_LENGTH bytes. - */ - start = 0x00; - msgs[1].len = total_size; - msgs[1].buf = block; - - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID extension blocks.\n"); - goto err; - } - if (!drm_edid_block_valid(block, 1, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - } - - return block; - -err: - kfree(block); - return NULL; + return 0; } static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, @@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, client = ge_b850v3_lvds_ptr->stdp2690_i2c; - return (struct edid *)stdp2690_get_edid(client); + return drm_do_get_edid(connector, stdp2690_read_block, client); } static int ge_b850v3_lvds_get_modes(struct drm_connector *connector) -- cgit From a48e2cc92835fa1d9b373b804b2173c779387b8e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 9 Oct 2023 16:06:35 +0200 Subject: drm/ssd130x: Fix atomic_check for disabled planes The plane's atomic_check returns -EINVAL if the CRTC has not been set. This is the case for disabled planes, for which atomic_check should return 0. For disabled planes, it also omits the mandatory call to drm_atomic_helper_check_plane_state(). Replace the test with the boiler-plate code that first invokes drm_atomic_helper_check_plane_state() and then tests for the plane to be visible. Return early for non-visible planes. Signed-off-by: Thomas Zimmermann Fixes: d51f9fbd98b6 ("drm/ssd130x: Store the HW buffer in the driver-private CRTC state") Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas Cc: Geert Uytterhoeven Cc: Javier Martinez Canillas Cc: Maxime Ripard Signed-off-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20231009141018.11291-7-tzimmermann@suse.de --- drivers/gpu/drm/solomon/ssd130x.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 6dcf3e041113..0c716136c538 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -638,21 +638,22 @@ static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); struct drm_crtc *crtc = plane_state->crtc; - struct drm_crtc_state *crtc_state; + struct drm_crtc_state *crtc_state = NULL; const struct drm_format_info *fi; unsigned int pitch; int ret; - if (!crtc) - return -EINVAL; - - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); - ret = drm_plane_helper_atomic_check(plane, state); + ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); if (ret) return ret; + else if (!plane_state->visible) + return 0; fi = drm_format_info(DRM_FORMAT_R1); if (!fi) -- cgit From d12d635bb03c7cb4830acb641eb176ee9ff2aa89 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Sat, 11 Feb 2023 18:17:48 +0100 Subject: drm/panel: st7703: Pick different reset sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switching to a different reset sequence, enabling IOVCC before enabling VCC. There also needs to be a delay after enabling the supplies and before deasserting the reset. The datasheet specifies 1ms after the supplies reach the required voltage. Use 10-20ms to also give the power supplies some time to reach the required voltage, too. This fixes intermittent panel initialization failures and screen corruption during resume from sleep on panel xingbangda,xbd599 (e.g. used in PinePhone). Signed-off-by: Ondrej Jirman Signed-off-by: Frank Oltmanns Reported-by: Samuel Holland Reviewed-by: Guido Günther Tested-by: Guido Günther Signed-off-by: Guido Günther Link: https://patchwork.freedesktop.org/patch/msgid/20230211171748.36692-2-frank@oltmanns.dev --- drivers/gpu/drm/panel/panel-sitronix-st7703.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 6a3945639535..7bb723d445ad 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -506,29 +506,30 @@ static int st7703_prepare(struct drm_panel *panel) return 0; dev_dbg(ctx->dev, "Resetting the panel\n"); - ret = regulator_enable(ctx->vcc); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + + ret = regulator_enable(ctx->iovcc); if (ret < 0) { - dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); + dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); return ret; } - ret = regulator_enable(ctx->iovcc); + + ret = regulator_enable(ctx->vcc); if (ret < 0) { - dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); - goto disable_vcc; + dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); + regulator_disable(ctx->iovcc); + return ret; } - gpiod_set_value_cansleep(ctx->reset_gpio, 1); - usleep_range(20, 40); + /* Give power supplies time to stabilize before deasserting reset. */ + usleep_range(10000, 20000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); - msleep(20); + usleep_range(15000, 20000); ctx->prepared = true; return 0; - -disable_vcc: - regulator_disable(ctx->vcc); - return ret; } static const u32 mantix_bus_formats[] = { -- cgit From 0ddd30471a5dd78ff762ffb9eeae1d573283243a Mon Sep 17 00:00:00 2001 From: Frank Oltmanns Date: Mon, 13 Feb 2023 13:32:38 +0100 Subject: drm/panel: st7703: Fix timings when entering/exiting sleep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix flickering of the pinephone's XDB599 panel that happens after resume. Extend the delay after issuing the command to exit sleep mode from 60 to 120 msec as per the controller's specification. Introduce a 120 msec delay after issuing the command to enter sleep mode. This is needed in order for the controller to reliably finalize the sleep in sequence before switching of power supply. In contrast to the JH057N panel, the XBD599 panel does not require a 20 msec delay after initialization and exiting sleep mode. Therefore, move the delay into the already existing device specific initialization function. The XDB599 does not require a 20 msec delay between the SETBGP and SETVCOM commands. Therefore, remove the delay from the device specific initialization function. Signed-off-by: Frank Oltmanns Cc: Ondrej Jirman Reported-by: Samuel Holland Reviewed-by: Guido Günther Tested-by: Guido Günther Signed-off-by: Guido Günther Link: https://patchwork.freedesktop.org/patch/msgid/20230213123238.76889-2-frank@oltmanns.dev --- drivers/gpu/drm/panel/panel-sitronix-st7703.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 7bb723d445ad..79d56725b010 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -130,6 +130,7 @@ static int jh057n_init_sequence(struct st7703 *ctx) 0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 0x11, 0x18); + msleep(20); return 0; } @@ -276,7 +277,6 @@ static int xbd599_init_sequence(struct st7703 *ctx) mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x07, /* VREF_SEL = 4.2V */ 0x07 /* NVREF_SEL = 4.2V */); - msleep(20); mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x2C, /* VCOMDC_F = -0.67V */ @@ -445,16 +445,14 @@ static int st7703_enable(struct drm_panel *panel) return ret; } - msleep(20); - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); if (ret < 0) { dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret); return ret; } - /* Panel is operational 120 msec after reset */ - msleep(60); + /* It takes the controller 120 msec to wake up after sleep. */ + msleep(120); ret = mipi_dsi_dcs_set_display_on(dsi); if (ret) @@ -479,6 +477,9 @@ static int st7703_disable(struct drm_panel *panel) if (ret < 0) dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret); + /* It takes the controller 120 msec to enter sleep mode. */ + msleep(120); + return 0; } -- cgit From 19e77c7aef5754e680ac77013538e2a3c0c173e4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:51 +0100 Subject: drm: adv7511: Add struct adv7511_chip_info and use i2c_get_match_data() Add struct adv7511_chip_info to handle hw differences between various chips rather checking against the 'type' variable in various places. Replace 'adv->type'->'info->type' by moving variable 'type' from struct adv7511 to struct adv7511_chip_info and add adv7511_chip_info as device data for both OF and ID tables instead of the device type. Simplify the probe() by replacing of_device_get_match_data() and ID lookup for retrieving match data with i2c_get_match_data(). Signed-off-by: Biju Das Tested-by: Fabio Estevam Reviewed-by: Adam Ford Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-2-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 6 ++- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 65 +++++++++++++++------------- drivers/gpu/drm/bridge/adv7511/adv7533.c | 4 +- 3 files changed, 43 insertions(+), 32 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 17445800248d..59e8ef10d72e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -333,6 +333,10 @@ enum adv7511_type { #define ADV7511_MAX_ADDRS 3 +struct adv7511_chip_info { + enum adv7511_type type; +}; + struct adv7511 { struct i2c_client *i2c_main; struct i2c_client *i2c_edid; @@ -377,7 +381,7 @@ struct adv7511 { u8 num_dsi_lanes; bool use_timing_gen; - enum adv7511_type type; + const struct adv7511_chip_info *info; struct platform_device *audio_pdev; struct cec_adapter *cec_adap; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index d518de88b5c3..a8508e86b391 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511) * first few seconds after enabling the output. On the other hand * adv7535 require to enable HPD Override bit for proper HPD. */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) */ regcache_sync(adv7511->regmap); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) adv7533_dsi_power_on(adv7511); adv7511->powered = true; } @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) static void __adv7511_power_off(struct adv7511 *adv7511) { /* TODO: setup additional power down modes */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, 0); @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511) static void adv7511_power_off(struct adv7511 *adv7511) { __adv7511_power_off(adv7511); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) adv7533_dsi_power_off(adv7511); adv7511->powered = false; } @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) status = connector_status_disconnected; } else { /* Renable HPD sensing */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -786,7 +786,7 @@ static void adv7511_mode_set(struct adv7511 *adv7511, else low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) regmap_update_bits(adv7511->regmap, 0xfb, 0x6, low_refresh_rate << 1); else @@ -921,7 +921,7 @@ static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, { struct adv7511 *adv = bridge_to_adv7511(bridge); - if (adv->type == ADV7533 || adv->type == ADV7535) + if (adv->info->type == ADV7533 || adv->info->type == ADV7535) return adv7533_mode_valid(adv, mode); else return adv7511_mode_valid(adv, mode); @@ -1009,7 +1009,7 @@ static int adv7511_init_regulators(struct adv7511 *adv) unsigned int i; int ret; - if (adv->type == ADV7511) { + if (adv->info->type == ADV7511) { supply_names = adv7511_supply_names; adv->num_supplies = ARRAY_SIZE(adv7511_supply_names); } else { @@ -1093,7 +1093,7 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) goto err; } - if (adv->type == ADV7533 || adv->type == ADV7535) { + if (adv->info->type == ADV7533 || adv->info->type == ADV7535) { ret = adv7533_patch_cec_registers(adv); if (ret) goto err; @@ -1192,7 +1192,6 @@ static int adv7511_parse_dt(struct device_node *np, static int adv7511_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct adv7511_link_config link_config; struct adv7511 *adv7511; struct device *dev = &i2c->dev; @@ -1209,15 +1208,11 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511->i2c_main = i2c; adv7511->powered = false; adv7511->status = connector_status_disconnected; - - if (dev->of_node) - adv7511->type = (enum adv7511_type)of_device_get_match_data(dev); - else - adv7511->type = id->driver_data; + adv7511->info = i2c_get_match_data(i2c); memset(&link_config, 0, sizeof(link_config)); - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) ret = adv7511_parse_dt(dev->of_node, &link_config); else ret = adv7533_parse_dt(dev->of_node, adv7511); @@ -1254,7 +1249,7 @@ static int adv7511_probe(struct i2c_client *i2c) goto uninit_regulators; dev_dbg(dev, "Rev. %d\n", val); - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) ret = regmap_register_patch(adv7511->regmap, adv7511_fixed_registers, ARRAY_SIZE(adv7511_fixed_registers)); @@ -1306,7 +1301,7 @@ static int adv7511_probe(struct i2c_client *i2c) i2c_set_clientdata(i2c, adv7511); - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) adv7511_set_link_config(adv7511, &link_config); ret = adv7511_cec_init(dev, adv7511); @@ -1325,7 +1320,7 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511_audio_init(dev, adv7511); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) { + if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) { ret = adv7533_attach_dsi(adv7511); if (ret) goto err_unregister_audio; @@ -1368,22 +1363,34 @@ static void adv7511_remove(struct i2c_client *i2c) i2c_unregister_device(adv7511->i2c_edid); } +static const struct adv7511_chip_info adv7511_chip_info = { + .type = ADV7511, +}; + +static const struct adv7511_chip_info adv7533_chip_info = { + .type = ADV7533, +}; + +static const struct adv7511_chip_info adv7535_chip_info = { + .type = ADV7535, +}; + static const struct i2c_device_id adv7511_i2c_ids[] = { - { "adv7511", ADV7511 }, - { "adv7511w", ADV7511 }, - { "adv7513", ADV7511 }, - { "adv7533", ADV7533 }, - { "adv7535", ADV7535 }, + { "adv7511", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7511w", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7513", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7533", (kernel_ulong_t)&adv7533_chip_info }, + { "adv7535", (kernel_ulong_t)&adv7535_chip_info }, { } }; MODULE_DEVICE_TABLE(i2c, adv7511_i2c_ids); static const struct of_device_id adv7511_of_ids[] = { - { .compatible = "adi,adv7511", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7511w", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7513", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7533", .data = (void *)ADV7533 }, - { .compatible = "adi,adv7535", .data = (void *)ADV7535 }, + { .compatible = "adi,adv7511", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7511w", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7513", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7533", .data = &adv7533_chip_info }, + { .compatible = "adi,adv7535", .data = &adv7535_chip_info }, { } }; MODULE_DEVICE_TABLE(of, adv7511_of_ids); diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index 7e3e56441aed..c452c4dc1c3f 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -108,11 +108,11 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); /* Check max clock for either 7533 or 7535 */ - if (mode->clock > (adv->type == ADV7533 ? 80000 : 148500)) + if (mode->clock > (adv->info->type == ADV7533 ? 80000 : 148500)) return MODE_CLOCK_HIGH; /* Check max clock for each lane */ - max_lane_freq = (adv->type == ADV7533 ? 800000 : 891000); + max_lane_freq = (adv->info->type == ADV7533 ? 800000 : 891000); if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes) return MODE_CLOCK_HIGH; -- cgit From 11ae4e406dd9ab799da6f5951c3a6f8ec6b1e321 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:52 +0100 Subject: drm: adv7511: Add max_mode_clock_khz variable to struct adv7511_chip_info The ADV7533 supports a maximum pixel clock of 80MHz whereas it is 148.5MHz for ADV7535. Add max_mode_clock_khz variable to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Adam Ford Tested-by: Adam Ford #imx8mm-beacon Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-3-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 ++ drivers/gpu/drm/bridge/adv7511/adv7533.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 59e8ef10d72e..b9c6c1e8a353 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -335,6 +335,7 @@ enum adv7511_type { struct adv7511_chip_info { enum adv7511_type type; + unsigned int max_mode_clock_khz; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index a8508e86b391..4ee90a754202 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1369,10 +1369,12 @@ static const struct adv7511_chip_info adv7511_chip_info = { static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, + .max_mode_clock_khz = 80000, }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, + .max_mode_clock_khz = 148500, }; static const struct i2c_device_id adv7511_i2c_ids[] = { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index c452c4dc1c3f..1d113489754c 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -108,7 +108,7 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); /* Check max clock for either 7533 or 7535 */ - if (mode->clock > (adv->info->type == ADV7533 ? 80000 : 148500)) + if (mode->clock > adv->info->max_mode_clock_khz) return MODE_CLOCK_HIGH; /* Check max clock for each lane */ -- cgit From 399562fc02d8e782f62cfc3791269d29e0b78085 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:53 +0100 Subject: drm: adv7511: Add max_lane_freq_khz variable to struct adv7511_chip_info The ADV7533 supports a maximum lane clock of 800MHz whereas it is 891MHz for ADV7535. Add max_lane_freq_khz variable to struct adv7511_chip_info to handle this difference. While at it, drop the unused local variable max_lane_freq. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-4-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 ++ drivers/gpu/drm/bridge/adv7511/adv7533.c | 5 +---- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index b9c6c1e8a353..f8d61f2fa30e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -336,6 +336,7 @@ enum adv7511_type { struct adv7511_chip_info { enum adv7511_type type; unsigned int max_mode_clock_khz; + unsigned int max_lane_freq_khz; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 4ee90a754202..4fff3e26e3d9 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1370,11 +1370,13 @@ static const struct adv7511_chip_info adv7511_chip_info = { static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, .max_mode_clock_khz = 80000, + .max_lane_freq_khz = 800000, }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, .max_mode_clock_khz = 148500, + .max_lane_freq_khz = 891000, }; static const struct i2c_device_id adv7511_i2c_ids[] = { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index 1d113489754c..4481489aaf5e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -103,7 +103,6 @@ void adv7533_dsi_power_off(struct adv7511 *adv) enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, const struct drm_display_mode *mode) { - unsigned long max_lane_freq; struct mipi_dsi_device *dsi = adv->dsi; u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); @@ -112,9 +111,7 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, return MODE_CLOCK_HIGH; /* Check max clock for each lane */ - max_lane_freq = (adv->info->type == ADV7533 ? 800000 : 891000); - - if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes) + if (mode->clock * bpp > adv->info->max_lane_freq_khz * adv->num_dsi_lanes) return MODE_CLOCK_HIGH; return MODE_OK; -- cgit From 9ac196fb9a173dd13bf6e0cf4a7edb66fc0a3797 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:54 +0100 Subject: drm: adv7511: Add supply_names and num_supplies variables to struct adv7511_chip_info The ADV7511 has 5 power supplies compared to 7 that of ADV75{33,35}. Add supply_names and num_supplies variables to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-5-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 3 ++- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 27 +++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index f8d61f2fa30e..edf7be9c21d3 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -337,6 +337,8 @@ struct adv7511_chip_info { enum adv7511_type type; unsigned int max_mode_clock_khz; unsigned int max_lane_freq_khz; + const char * const *supply_names; + unsigned int num_supplies; }; struct adv7511 { @@ -375,7 +377,6 @@ struct adv7511 { struct gpio_desc *gpio_pd; struct regulator_bulk_data *supplies; - unsigned int num_supplies; /* ADV7533 DSI RX related params */ struct device_node *host_node; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 4fff3e26e3d9..6c223f0eb4dc 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1004,37 +1004,30 @@ static const char * const adv7533_supply_names[] = { static int adv7511_init_regulators(struct adv7511 *adv) { + const char * const *supply_names = adv->info->supply_names; + unsigned int num_supplies = adv->info->num_supplies; struct device *dev = &adv->i2c_main->dev; - const char * const *supply_names; unsigned int i; int ret; - if (adv->info->type == ADV7511) { - supply_names = adv7511_supply_names; - adv->num_supplies = ARRAY_SIZE(adv7511_supply_names); - } else { - supply_names = adv7533_supply_names; - adv->num_supplies = ARRAY_SIZE(adv7533_supply_names); - } - - adv->supplies = devm_kcalloc(dev, adv->num_supplies, + adv->supplies = devm_kcalloc(dev, num_supplies, sizeof(*adv->supplies), GFP_KERNEL); if (!adv->supplies) return -ENOMEM; - for (i = 0; i < adv->num_supplies; i++) + for (i = 0; i < num_supplies; i++) adv->supplies[i].supply = supply_names[i]; - ret = devm_regulator_bulk_get(dev, adv->num_supplies, adv->supplies); + ret = devm_regulator_bulk_get(dev, num_supplies, adv->supplies); if (ret) return ret; - return regulator_bulk_enable(adv->num_supplies, adv->supplies); + return regulator_bulk_enable(num_supplies, adv->supplies); } static void adv7511_uninit_regulators(struct adv7511 *adv) { - regulator_bulk_disable(adv->num_supplies, adv->supplies); + regulator_bulk_disable(adv->info->num_supplies, adv->supplies); } static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg) @@ -1365,18 +1358,24 @@ static void adv7511_remove(struct i2c_client *i2c) static const struct adv7511_chip_info adv7511_chip_info = { .type = ADV7511, + .supply_names = adv7511_supply_names, + .num_supplies = ARRAY_SIZE(adv7511_supply_names), }; static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, .max_mode_clock_khz = 80000, .max_lane_freq_khz = 800000, + .supply_names = adv7533_supply_names, + .num_supplies = ARRAY_SIZE(adv7533_supply_names), }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, .max_mode_clock_khz = 148500, .max_lane_freq_khz = 891000, + .supply_names = adv7533_supply_names, + .num_supplies = ARRAY_SIZE(adv7533_supply_names), }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- cgit From 8d6cf571901148d0af549f4a7ae8c5b4a0f3e996 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:55 +0100 Subject: drm: adv7511: Add reg_cec_offset variable to struct adv7511_chip_info The ADV7533 and ADV7535 have an offset(0x70) for the CEC register map compared to ADV7511. Add the reg_cec_offset variable to struct adv7511_chip_info to handle this difference and drop the reg_cec_offset variable from struct adv7511. This will avoid assigning reg_cec_offset based on chip type and also testing for multiple chip types by calling adv7533_patch_cec_registers(). Signed-off-by: Biju Das Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-6-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 2 +- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 14 +++++++------- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index edf7be9c21d3..a728bfb33d03 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -339,6 +339,7 @@ struct adv7511_chip_info { unsigned int max_lane_freq_khz; const char * const *supply_names; unsigned int num_supplies; + unsigned int reg_cec_offset; }; struct adv7511 { @@ -349,7 +350,6 @@ struct adv7511 { struct regmap *regmap; struct regmap *regmap_cec; - unsigned int reg_cec_offset; enum drm_connector_status status; bool powered; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index 2a6b91f752cb..44451a9658a3 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c @@ -33,7 +33,7 @@ static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = { static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; unsigned int val; if (regmap_read(adv7511->regmap_cec, @@ -84,7 +84,7 @@ static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; struct cec_msg msg = {}; unsigned int len; unsigned int val; @@ -121,7 +121,7 @@ static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | ADV7511_INT1_CEC_TX_RETRY_TIMEOUT; @@ -177,7 +177,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; if (adv7511->i2c_cec == NULL) return -EIO; @@ -223,7 +223,7 @@ static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; unsigned int i, free_idx = ADV7511_MAX_ADDRS; if (!adv7511->cec_enabled_adap) @@ -292,7 +292,7 @@ static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; u8 len = msg->len; unsigned int i; @@ -345,7 +345,7 @@ static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511) int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; int ret = adv7511_cec_parse_dt(dev, adv7511); if (ret) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 6c223f0eb4dc..45dcfc9d9212 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1035,7 +1035,7 @@ static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg) struct i2c_client *i2c = to_i2c_client(dev); struct adv7511 *adv7511 = i2c_get_clientdata(i2c); - reg -= adv7511->reg_cec_offset; + reg -= adv7511->info->reg_cec_offset; switch (reg) { case ADV7511_REG_CEC_RX1_FRAME_HDR: @@ -1086,12 +1086,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) goto err; } - if (adv->info->type == ADV7533 || adv->info->type == ADV7535) { + if (adv->info->reg_cec_offset == ADV7533_REG_CEC_OFFSET) { ret = adv7533_patch_cec_registers(adv); if (ret) goto err; - - adv->reg_cec_offset = ADV7533_REG_CEC_OFFSET; } return 0; @@ -1368,6 +1366,7 @@ static const struct adv7511_chip_info adv7533_chip_info = { .max_lane_freq_khz = 800000, .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), + .reg_cec_offset = ADV7533_REG_CEC_OFFSET, }; static const struct adv7511_chip_info adv7535_chip_info = { @@ -1376,6 +1375,7 @@ static const struct adv7511_chip_info adv7535_chip_info = { .max_lane_freq_khz = 891000, .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), + .reg_cec_offset = ADV7533_REG_CEC_OFFSET, }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- cgit From c75551214858384d5128cd874a0b346e0a624b56 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:56 +0100 Subject: drm: adv7511: Add has_dsi variable to struct adv7511_chip_info The ADV7533 and ADV7535 have DSI support. Add a variable has_dsi to struct adv7511_chip_info for handling configuration related to DSI. Signed-off-by: Biju Das Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-7-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index a728bfb33d03..0dd56e311039 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -340,6 +340,7 @@ struct adv7511_chip_info { const char * const *supply_names; unsigned int num_supplies; unsigned int reg_cec_offset; + bool has_dsi; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 45dcfc9d9212..5a3adaf95f0d 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) */ regcache_sync(adv7511->regmap); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) + if (adv7511->info->has_dsi) adv7533_dsi_power_on(adv7511); adv7511->powered = true; } @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511) static void adv7511_power_off(struct adv7511 *adv7511) { __adv7511_power_off(adv7511); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) + if (adv7511->info->has_dsi) adv7533_dsi_power_off(adv7511); adv7511->powered = false; } @@ -921,7 +921,7 @@ static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, { struct adv7511 *adv = bridge_to_adv7511(bridge); - if (adv->info->type == ADV7533 || adv->info->type == ADV7535) + if (adv->info->has_dsi) return adv7533_mode_valid(adv, mode); else return adv7511_mode_valid(adv, mode); @@ -1311,7 +1311,7 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511_audio_init(dev, adv7511); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) { + if (adv7511->info->has_dsi) { ret = adv7533_attach_dsi(adv7511); if (ret) goto err_unregister_audio; @@ -1367,6 +1367,7 @@ static const struct adv7511_chip_info adv7533_chip_info = { .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, }; static const struct adv7511_chip_info adv7535_chip_info = { @@ -1376,6 +1377,7 @@ static const struct adv7511_chip_info adv7535_chip_info = { .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- cgit From 7618aa3ab38e1130268cca6aab408cd4fefeba0c Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:57 +0100 Subject: drm: adv7511: Add link_config variable to struct adv7511_chip_info The ADV7511 needs link configuration whereas ADV75{33,35} does not need it. Add a variable link_config to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-8-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 0dd56e311039..0d39e32b0793 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -341,6 +341,7 @@ struct adv7511_chip_info { unsigned int num_supplies; unsigned int reg_cec_offset; bool has_dsi; + bool link_config; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 5a3adaf95f0d..d076cee05e68 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1203,7 +1203,7 @@ static int adv7511_probe(struct i2c_client *i2c) memset(&link_config, 0, sizeof(link_config)); - if (adv7511->info->type == ADV7511) + if (adv7511->info->link_config) ret = adv7511_parse_dt(dev->of_node, &link_config); else ret = adv7533_parse_dt(dev->of_node, adv7511); @@ -1292,7 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c) i2c_set_clientdata(i2c, adv7511); - if (adv7511->info->type == ADV7511) + if (adv7511->info->link_config) adv7511_set_link_config(adv7511, &link_config); ret = adv7511_cec_init(dev, adv7511); @@ -1358,6 +1358,7 @@ static const struct adv7511_chip_info adv7511_chip_info = { .type = ADV7511, .supply_names = adv7511_supply_names, .num_supplies = ARRAY_SIZE(adv7511_supply_names), + .link_config = true, }; static const struct adv7511_chip_info adv7533_chip_info = { -- cgit From e12c4703cec0f07bae2f7cd1538ba9354e92b754 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:58 +0100 Subject: drm: adv7511: Add hpd_override_enable variable to struct adv7511_chip_info As per spec, it is allowed to pulse the HPD signal to indicate that the EDID information has changed. Some monitors do this when they wake up from standby or are enabled. When the HPD goes low the adv7511 is reset and the outputs are disabled which might cause the monitor to go to standby again. To avoid this we ignore the HPD pin for the first few seconds after enabling the output. On the other hand, adv7535 require to enable HPD Override bit for proper HPD. Add hpd_override_enable variable to struct adv7511_chip_info to handle this scenario. Signed-off-by: Biju Das Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-9-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 0d39e32b0793..39c9ece373b0 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -342,6 +342,7 @@ struct adv7511_chip_info { unsigned int reg_cec_offset; bool has_dsi; bool link_config; + bool hpd_override_enable; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index d076cee05e68..8be235144f6d 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511) * first few seconds after enabling the output. On the other hand * adv7535 require to enable HPD Override bit for proper HPD. */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) static void __adv7511_power_off(struct adv7511 *adv7511) { /* TODO: setup additional power down modes */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, 0); @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) status = connector_status_disconnected; } else { /* Renable HPD sensing */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -1379,6 +1379,7 @@ static const struct adv7511_chip_info adv7535_chip_info = { .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, .has_dsi = true, + .hpd_override_enable = true, }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- cgit From ec20c510ee2d2a7f0d0a00e4bfd55c28e500d3b7 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:00 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Add dw_mipi_dsi_get_bridge() helper Add dw_mipi_dsi_get_bridge() helper so that it can be used by vendor drivers which implement vendor specific extensions to Synopsys DW MIPI DSI. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-2-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index a8dd2a2e7c7b..591a75f59150 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -1209,6 +1209,12 @@ void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave) } EXPORT_SYMBOL_GPL(dw_mipi_dsi_set_slave); +struct drm_bridge *dw_mipi_dsi_get_bridge(struct dw_mipi_dsi *dsi) +{ + return &dsi->bridge; +} +EXPORT_SYMBOL_GPL(dw_mipi_dsi_get_bridge); + /* * Probe/remove API, used from platforms based on the DRM bridge API. */ -- cgit From 0de852d4c23a39d3ebff73d0c0c1b488eac6c5a8 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:01 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Add input bus format negotiation support Introduce ->get_input_bus_fmts() callback to struct dw_mipi_dsi_plat_data so that vendor drivers can implement specific methods to get input bus formats for Synopsys DW MIPI DSI. While at it, implement a generic callback for ->atomic_get_input_bus_fmts(), where we try to get the input bus formats through pdata->get_input_bus_fmts() first. If it's unavailable, fall back to the only format - MEDIA_BUS_FMT_FIXED, which matches the default behavior if ->atomic_get_input_bus_fmts() is not implemented as ->atomic_get_input_bus_fmts()'s kerneldoc indicates. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-3-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 591a75f59150..fbd0ae58a951 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -538,6 +539,34 @@ static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = { .transfer = dw_mipi_dsi_host_transfer, }; +static u32 * +dw_mipi_dsi_bridge_atomic_get_input_bus_fmts(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) +{ + struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; + u32 *input_fmts; + + if (pdata->get_input_bus_fmts) + return pdata->get_input_bus_fmts(pdata->priv_data, + bridge, bridge_state, + crtc_state, conn_state, + output_fmt, num_input_fmts); + + /* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */ + input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) + return NULL; + input_fmts[0] = MEDIA_BUS_FMT_FIXED; + *num_input_fmts = 1; + + return input_fmts; +} + static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) { u32 val; @@ -1006,6 +1035,7 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge, static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_get_input_bus_fmts = dw_mipi_dsi_bridge_atomic_get_input_bus_fmts, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_pre_enable = dw_mipi_dsi_bridge_atomic_pre_enable, .atomic_enable = dw_mipi_dsi_bridge_atomic_enable, -- cgit From d5116fb29dc09bd4b9d9175f4f571e6eac539c93 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:02 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Force input bus flags The DATAEN_ACTIVE_LOW bit in DSI_DPI_CFG_POL register is set to zero, so set the DRM_BUS_FLAG_DE_HIGH flag in input_bus_cfg.flags. It appears that the DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE flag also makes sense, so set it in input_bus_cfg.flags too. With this patch, the flags set by drm_atomic_bridge_propagate_bus_flags() are overridden (see comment in that function) in case any downstream bridges propagates invalid flags to this bridge. A real problematic case is to connect a RM67191 MIPI DSI panel whose driver sets DRM_BUS_FLAG_DE_LOW and DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE bus flags. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-4-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index fbd0ae58a951..4e5171b5978a 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -567,6 +568,17 @@ dw_mipi_dsi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, return input_fmts; } +static int dw_mipi_dsi_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + bridge_state->input_bus_cfg.flags = + DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE; + + return 0; +} + static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) { u32 val; @@ -1036,6 +1048,7 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_get_input_bus_fmts = dw_mipi_dsi_bridge_atomic_get_input_bus_fmts, + .atomic_check = dw_mipi_dsi_bridge_atomic_check, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_pre_enable = dw_mipi_dsi_bridge_atomic_pre_enable, .atomic_enable = dw_mipi_dsi_bridge_atomic_enable, -- cgit From 5a67ec8c64ec88b5c34060b347ccec4a31af3369 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:03 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Add mode fixup support Vendor drivers may need to fixup mode due to pixel clock tree limitation, so introduce the ->mode_fixup() callcack to struct dw_mipi_dsi_plat_data and call it at atomic check stage if available. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-5-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 4e5171b5978a..40d699428b1b 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -573,9 +573,23 @@ static int dw_mipi_dsi_bridge_atomic_check(struct drm_bridge *bridge, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; + bool ret; + bridge_state->input_bus_cfg.flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE; + if (pdata->mode_fixup) { + ret = pdata->mode_fixup(pdata->priv_data, &crtc_state->mode, + &crtc_state->adjusted_mode); + if (!ret) { + DRM_DEBUG_DRIVER("failed to fixup mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(&crtc_state->mode)); + return -EINVAL; + } + } + return 0; } -- cgit From ac87d23694f44af44a98d21dd77016f2756b6b1b Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:04 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Use pixel clock rate to calculate lbcc To get better accuration, use pixel clock rate to calculate lbcc instead of lane_mbps since the pixel clock rate is in KHz while lane_mbps is in MHz. Without this, distorted image can be seen on a HDMI monitor connected with i.MX93 11x11 EVK through ADV7535 DSI to HDMI bridge in 1920x1080p@60 video mode. Signed-off-by: Liu Ying Reviewed-by: Neil Armstrong Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-6-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 40d699428b1b..b21ad4ea9dca 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -764,8 +765,15 @@ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, u32 hcomponent) { u32 frac, lbcc; + int bpp; - lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8; + bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); + if (bpp < 0) { + dev_err(dsi->dev, "failed to get bpp\n"); + return 0; + } + + lbcc = div_u64((u64)hcomponent * mode->clock * bpp, dsi->lanes * 8); frac = lbcc % mode->clock; lbcc = lbcc / mode->clock; -- cgit From d22e9a6df2db6a5b0ab7ff9123831e05c3e77899 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:05 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Set minimum lane byte clock cycles for HSA and HBP According to Synopsys support channel, each region of HSA, HBP and HFP must have minimum number of 10 bytes where constant 4 bytes are for HSS or HSE and 6 bytes are for blanking packet(header + CRC). Hence, the below table comes in. +------------+----------+-------+ | data lanes | min lbcc | bytes | +------------+----------+-------+ | 1 | 10 | 1*10 | +------------+----------+-------+ | 2 | 5 | 2*5 | +------------+----------+-------+ | 3 | 4 | 3*4 | +------------+----------+-------+ | 4 | 3 | 4*3 | +------------+----------+-------+ Implement the minimum lbcc numbers to make sure that the values programmed into DSI_VID_HSA_TIME and DSI_VID_HBP_TIME registers meet the minimum number requirement. For DSI_VID_HLINE_TIME register, it seems that the value programmed should be based on mode->htotal as-is, instead of sum up HSA, HBP, HFP and HDISPLAY. This helps the case where Raydium RM67191 DSI panel is connected, since it's video timing for hsync length is only 2 pixels and without this patch the programmed value for DSI_VID_HSA_TIME is only 2 with 4 data lanes. Signed-off-by: Liu Ying Reviewed-by: Neil Armstrong Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-7-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index b21ad4ea9dca..2fd01b299f73 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -759,12 +759,19 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); } +static const u32 minimum_lbccs[] = {10, 5, 4, 3}; + +static inline u32 dw_mipi_dsi_get_minimum_lbcc(struct dw_mipi_dsi *dsi) +{ + return minimum_lbccs[dsi->lanes - 1]; +} + /* Get lane byte clock cycles. */ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, const struct drm_display_mode *mode, u32 hcomponent) { - u32 frac, lbcc; + u32 frac, lbcc, minimum_lbcc; int bpp; bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); @@ -780,6 +787,11 @@ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, if (frac) lbcc++; + minimum_lbcc = dw_mipi_dsi_get_minimum_lbcc(dsi); + + if (lbcc < minimum_lbcc) + lbcc = minimum_lbcc; + return lbcc; } -- cgit From 743bf594a3b1903a93f21f2060e3cdc5514e066c Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:06 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Disable HSTX and LPRX timeout check According to Synopsys DW MIPI DSI host databook, HSTX and LPRX timeout contention detections are measured in TO_CLK_DIVISION cycles. However, the current driver programs magic values to TO_CLK_DIVISION, HSTX_TO_CNT and LPRX_TO_CNT register fields, which makes timeout error event wrongly happen for some video modes, at least for the typical 1920x1080p@60 video mode read from a HDMI monitor driven by ADV7535 DSI to HDMI bridge. While at it, the current driver doesn't enable interrupt to handle or complain about the error status, so true error just happens silently except for display distortions by visual check. Disable the timeout check by setting those timeout register fields to zero for now until someone comes along with better computations for the timeout values. Although the databook doesn't mention what happens when they are set to zero, it turns out the false error doesn't happen for the 1920x1080p@60 video mode at least. Signed-off-by: Liu Ying Reviewed-by: Neil Armstrong Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-8-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 2fd01b299f73..8789eca26188 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -686,7 +686,7 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) * timeout clock division should be computed with the * high speed transmission counter timeout and byte lane... */ - dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) | + dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(0) | TX_ESC_CLK_DIVISION(esc_clk_division)); } @@ -749,7 +749,7 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) * compute high speed transmission counter timeout according * to the timeout clock division (TO_CLK_DIVISION) and byte lane... */ - dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000)); + dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(0) | LPRX_TO_CNT(0)); /* * TODO dw drv improvements * the Bus-Turn-Around Timeout Counter should be computed -- cgit From ce62f8ea7e3f8a8e788c3b5ea0195f1224575b66 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:08 +0800 Subject: drm/bridge: imx: Add i.MX93 MIPI DSI support Freescale i.MX93 SoC embeds a Synopsys Designware MIPI DSI host controller and a Synopsys Designware MIPI DPHY. Some configurations and extensions to them are controlled by i.MX93 media blk-ctrl. Add a DRM bridge for i.MX93 MIPI DSI by using existing DW MIPI DSI bridge helpers and implementing i.MX93 MIPI DSI specific extensions. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-10-victor.liu@nxp.com --- drivers/gpu/drm/bridge/imx/Kconfig | 11 + drivers/gpu/drm/bridge/imx/Makefile | 1 + drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 917 ++++++++++++++++++++++++++++ 3 files changed, 929 insertions(+) create mode 100644 drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig index 9fae28db6aa7..5a4f3d58501e 100644 --- a/drivers/gpu/drm/bridge/imx/Kconfig +++ b/drivers/gpu/drm/bridge/imx/Kconfig @@ -49,4 +49,15 @@ config DRM_IMX8QXP_PIXEL_LINK_TO_DPI Choose this to enable pixel link to display pixel interface(PXL2DPI) found in Freescale i.MX8qxp processor. +config DRM_IMX93_MIPI_DSI + tristate "Freescale i.MX93 specific extensions for Synopsys DW MIPI DSI" + depends on OF + depends on COMMON_CLK + select DRM_DW_MIPI_DSI + select GENERIC_PHY + select GENERIC_PHY_MIPI_DPHY + help + Choose this to enable MIPI DSI controller found in Freescale i.MX93 + processor. + endif # ARCH_MXC || COMPILE_TEST diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile index 8e2ebf3399a1..2b0c2e44aa1b 100644 --- a/drivers/gpu/drm/bridge/imx/Makefile +++ b/drivers/gpu/drm/bridge/imx/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_IMX8QXP_LDB) += imx8qxp-ldb.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o +obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c new file mode 100644 index 000000000000..3ff30ce80c5b --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c @@ -0,0 +1,917 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright 2022,2023 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* DPHY PLL configuration registers */ +#define DSI_REG 0x4c +#define CFGCLKFREQRANGE_MASK GENMASK(5, 0) +#define CFGCLKFREQRANGE(x) FIELD_PREP(CFGCLKFREQRANGE_MASK, (x)) +#define CLKSEL_MASK GENMASK(7, 6) +#define CLKSEL_STOP FIELD_PREP(CLKSEL_MASK, 0) +#define CLKSEL_GEN FIELD_PREP(CLKSEL_MASK, 1) +#define CLKSEL_EXT FIELD_PREP(CLKSEL_MASK, 2) +#define HSFREQRANGE_MASK GENMASK(14, 8) +#define HSFREQRANGE(x) FIELD_PREP(HSFREQRANGE_MASK, (x)) +#define UPDATE_PLL BIT(17) +#define SHADOW_CLR BIT(18) +#define CLK_EXT BIT(19) + +#define DSI_WRITE_REG0 0x50 +#define M_MASK GENMASK(9, 0) +#define M(x) FIELD_PREP(M_MASK, ((x) - 2)) +#define N_MASK GENMASK(13, 10) +#define N(x) FIELD_PREP(N_MASK, ((x) - 1)) +#define VCO_CTRL_MASK GENMASK(19, 14) +#define VCO_CTRL(x) FIELD_PREP(VCO_CTRL_MASK, (x)) +#define PROP_CTRL_MASK GENMASK(25, 20) +#define PROP_CTRL(x) FIELD_PREP(PROP_CTRL_MASK, (x)) +#define INT_CTRL_MASK GENMASK(31, 26) +#define INT_CTRL(x) FIELD_PREP(INT_CTRL_MASK, (x)) + +#define DSI_WRITE_REG1 0x54 +#define GMP_CTRL_MASK GENMASK(1, 0) +#define GMP_CTRL(x) FIELD_PREP(GMP_CTRL_MASK, (x)) +#define CPBIAS_CTRL_MASK GENMASK(8, 2) +#define CPBIAS_CTRL(x) FIELD_PREP(CPBIAS_CTRL_MASK, (x)) +#define PLL_SHADOW_CTRL BIT(9) + +/* display mux control register */ +#define DISPLAY_MUX 0x60 +#define MIPI_DSI_RGB666_MAP_CFG GENMASK(7, 6) +#define RGB666_CONFIG1 FIELD_PREP(MIPI_DSI_RGB666_MAP_CFG, 0) +#define RGB666_CONFIG2 FIELD_PREP(MIPI_DSI_RGB666_MAP_CFG, 1) +#define MIPI_DSI_RGB565_MAP_CFG GENMASK(5, 4) +#define RGB565_CONFIG1 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 0) +#define RGB565_CONFIG2 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 1) +#define RGB565_CONFIG3 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 2) +#define LCDIF_CROSS_LINE_PATTERN GENMASK(3, 0) +#define RGB888_TO_RGB888 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 0) +#define RGB888_TO_RGB666 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 6) +#define RGB565_TO_RGB565 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 7) + +#define MHZ(x) ((x) * 1000000UL) + +#define REF_CLK_RATE_MAX MHZ(64) +#define REF_CLK_RATE_MIN MHZ(2) +#define FOUT_MAX MHZ(1250) +#define FOUT_MIN MHZ(40) +#define FVCO_DIV_FACTOR MHZ(80) + +#define MBPS(x) ((x) * 1000000UL) + +#define DATA_RATE_MAX_SPEED MBPS(2500) +#define DATA_RATE_MIN_SPEED MBPS(80) + +#define M_MAX 625UL +#define M_MIN 64UL + +#define N_MAX 16U +#define N_MIN 1U + +struct imx93_dsi { + struct device *dev; + struct regmap *regmap; + struct clk *clk_pixel; + struct clk *clk_ref; + struct clk *clk_cfg; + struct dw_mipi_dsi *dmd; + struct dw_mipi_dsi_plat_data pdata; + union phy_configure_opts phy_cfg; + unsigned long ref_clk_rate; + u32 format; +}; + +struct dphy_pll_cfg { + u32 m; /* PLL Feedback Multiplication Ratio */ + u32 n; /* PLL Input Frequency Division Ratio */ +}; + +struct dphy_pll_vco_prop { + unsigned long max_fout; + u8 vco_cntl; + u8 prop_cntl; +}; + +struct dphy_pll_hsfreqrange { + unsigned long max_mbps; + u8 hsfreqrange; +}; + +/* DPHY Databook Table 3-13 Charge-pump Programmability */ +static const struct dphy_pll_vco_prop vco_prop_map[] = { + { 55, 0x3f, 0x0d }, + { 82, 0x37, 0x0d }, + { 110, 0x2f, 0x0d }, + { 165, 0x27, 0x0d }, + { 220, 0x1f, 0x0d }, + { 330, 0x17, 0x0d }, + { 440, 0x0f, 0x0d }, + { 660, 0x07, 0x0d }, + { 1149, 0x03, 0x0d }, + { 1152, 0x01, 0x0d }, + { 1250, 0x01, 0x0e }, +}; + +/* DPHY Databook Table 5-7 Frequency Ranges and Defaults */ +static const struct dphy_pll_hsfreqrange hsfreqrange_map[] = { + { 89, 0x00 }, + { 99, 0x10 }, + { 109, 0x20 }, + { 119, 0x30 }, + { 129, 0x01 }, + { 139, 0x11 }, + { 149, 0x21 }, + { 159, 0x31 }, + { 169, 0x02 }, + { 179, 0x12 }, + { 189, 0x22 }, + { 204, 0x32 }, + { 219, 0x03 }, + { 234, 0x13 }, + { 249, 0x23 }, + { 274, 0x33 }, + { 299, 0x04 }, + { 324, 0x14 }, + { 349, 0x25 }, + { 399, 0x35 }, + { 449, 0x05 }, + { 499, 0x16 }, + { 549, 0x26 }, + { 599, 0x37 }, + { 649, 0x07 }, + { 699, 0x18 }, + { 749, 0x28 }, + { 799, 0x39 }, + { 849, 0x09 }, + { 899, 0x19 }, + { 949, 0x29 }, + { 999, 0x3a }, + { 1049, 0x0a }, + { 1099, 0x1a }, + { 1149, 0x2a }, + { 1199, 0x3b }, + { 1249, 0x0b }, + { 1299, 0x1b }, + { 1349, 0x2b }, + { 1399, 0x3c }, + { 1449, 0x0c }, + { 1499, 0x1c }, + { 1549, 0x2c }, + { 1599, 0x3d }, + { 1649, 0x0d }, + { 1699, 0x1d }, + { 1749, 0x2e }, + { 1799, 0x3e }, + { 1849, 0x0e }, + { 1899, 0x1e }, + { 1949, 0x2f }, + { 1999, 0x3f }, + { 2049, 0x0f }, + { 2099, 0x40 }, + { 2149, 0x41 }, + { 2199, 0x42 }, + { 2249, 0x43 }, + { 2299, 0x44 }, + { 2349, 0x45 }, + { 2399, 0x46 }, + { 2449, 0x47 }, + { 2499, 0x48 }, + { 2500, 0x49 }, +}; + +static void dphy_pll_write(struct imx93_dsi *dsi, unsigned int reg, u32 value) +{ + int ret; + + ret = regmap_write(dsi->regmap, reg, value); + if (ret < 0) + dev_err(dsi->dev, "failed to write 0x%08x to pll reg 0x%x: %d\n", + value, reg, ret); +} + +static inline unsigned long data_rate_to_fout(unsigned long data_rate) +{ + /* Fout is half of data rate */ + return data_rate / 2; +} + +static int +dphy_pll_get_configure_from_opts(struct imx93_dsi *dsi, + struct phy_configure_opts_mipi_dphy *dphy_opts, + struct dphy_pll_cfg *cfg) +{ + struct device *dev = dsi->dev; + unsigned long fin = dsi->ref_clk_rate; + unsigned long fout; + unsigned long best_fout = 0; + unsigned int fvco_div; + unsigned int min_n, max_n, n, best_n; + unsigned long m, best_m; + unsigned long min_delta = ULONG_MAX; + unsigned long delta; + u64 tmp; + + if (dphy_opts->hs_clk_rate < DATA_RATE_MIN_SPEED || + dphy_opts->hs_clk_rate > DATA_RATE_MAX_SPEED) { + dev_dbg(dev, "invalid data rate per lane: %lu\n", + dphy_opts->hs_clk_rate); + return -EINVAL; + } + + fout = data_rate_to_fout(dphy_opts->hs_clk_rate); + + /* DPHY Databook 3.3.6.1 Output Frequency */ + /* Fout = Fvco / Fvco_div = (Fin * M) / (Fvco_div * N) */ + /* Fvco_div could be 1/2/4/8 according to Fout range. */ + fvco_div = 8UL / min(DIV_ROUND_UP(fout, FVCO_DIV_FACTOR), 8UL); + + /* limitation: 2MHz <= Fin / N <= 8MHz */ + min_n = DIV_ROUND_UP_ULL((u64)fin, MHZ(8)); + max_n = DIV_ROUND_DOWN_ULL((u64)fin, MHZ(2)); + + /* clamp possible N(s) */ + min_n = clamp(min_n, N_MIN, N_MAX); + max_n = clamp(max_n, N_MIN, N_MAX); + + dev_dbg(dev, "Fout = %lu, Fvco_div = %u, n_range = [%u, %u]\n", + fout, fvco_div, min_n, max_n); + + for (n = min_n; n <= max_n; n++) { + /* M = (Fout * N * Fvco_div) / Fin */ + m = DIV_ROUND_CLOSEST(fout * n * fvco_div, fin); + + /* check M range */ + if (m < M_MIN || m > M_MAX) + continue; + + /* calculate temporary Fout */ + tmp = m * fin; + do_div(tmp, n * fvco_div); + if (tmp < FOUT_MIN || tmp > FOUT_MAX) + continue; + + delta = abs(fout - tmp); + if (delta < min_delta) { + best_n = n; + best_m = m; + min_delta = delta; + best_fout = tmp; + } + } + + if (best_fout) { + cfg->m = best_m; + cfg->n = best_n; + dev_dbg(dev, "best Fout = %lu, m = %u, n = %u\n", + best_fout, cfg->m, cfg->n); + } else { + dev_dbg(dev, "failed to find best Fout\n"); + return -EINVAL; + } + + return 0; +} + +static void dphy_pll_clear_shadow(struct imx93_dsi *dsi) +{ + /* Reference DPHY Databook Figure 3-3 Initialization Timing Diagram. */ + /* Select clock generation first. */ + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN); + + /* Clear shadow after clock selection is done a while. */ + fsleep(1); + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN | SHADOW_CLR); + + /* A minimum pulse of 5ns on shadow_clear signal. */ + fsleep(1); + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN); +} + +static unsigned long dphy_pll_get_cfgclkrange(struct imx93_dsi *dsi) +{ + /* + * DPHY Databook Table 4-4 System Control Signals mentions an equation + * for cfgclkfreqrange[5:0]. + */ + return (clk_get_rate(dsi->clk_cfg) / MHZ(1) - 17) * 4; +} + +static u8 +dphy_pll_get_hsfreqrange(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long mbps = dphy_opts->hs_clk_rate / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(hsfreqrange_map); i++) + if (mbps <= hsfreqrange_map[i].max_mbps) + return hsfreqrange_map[i].hsfreqrange; + + return 0; +} + +static u8 dphy_pll_get_vco(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long fout = data_rate_to_fout(dphy_opts->hs_clk_rate) / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(vco_prop_map); i++) + if (fout <= vco_prop_map[i].max_fout) + return vco_prop_map[i].vco_cntl; + + return 0; +} + +static u8 dphy_pll_get_prop(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long fout = data_rate_to_fout(dphy_opts->hs_clk_rate) / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(vco_prop_map); i++) + if (fout <= vco_prop_map[i].max_fout) + return vco_prop_map[i].prop_cntl; + + return 0; +} + +static int dphy_pll_update(struct imx93_dsi *dsi) +{ + int ret; + + ret = regmap_update_bits(dsi->regmap, DSI_REG, UPDATE_PLL, UPDATE_PLL); + if (ret < 0) { + dev_err(dsi->dev, "failed to set UPDATE_PLL: %d\n", ret); + return ret; + } + + /* + * The updatepll signal should be asserted for a minimum of four clkin + * cycles, according to DPHY Databook Figure 3-3 Initialization Timing + * Diagram. + */ + fsleep(10); + + ret = regmap_update_bits(dsi->regmap, DSI_REG, UPDATE_PLL, 0); + if (ret < 0) { + dev_err(dsi->dev, "failed to clear UPDATE_PLL: %d\n", ret); + return ret; + } + + return 0; +} + +static int dphy_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *opts) +{ + struct dphy_pll_cfg cfg = { 0 }; + u32 val; + int ret; + + ret = dphy_pll_get_configure_from_opts(dsi, &opts->mipi_dphy, &cfg); + if (ret) { + dev_err(dsi->dev, "failed to get phy pll cfg %d\n", ret); + return ret; + } + + dphy_pll_clear_shadow(dsi); + + /* DSI_REG */ + val = CLKSEL_GEN | + CFGCLKFREQRANGE(dphy_pll_get_cfgclkrange(dsi)) | + HSFREQRANGE(dphy_pll_get_hsfreqrange(&opts->mipi_dphy)); + dphy_pll_write(dsi, DSI_REG, val); + + /* DSI_WRITE_REG0 */ + val = M(cfg.m) | N(cfg.n) | INT_CTRL(0) | + VCO_CTRL(dphy_pll_get_vco(&opts->mipi_dphy)) | + PROP_CTRL(dphy_pll_get_prop(&opts->mipi_dphy)); + dphy_pll_write(dsi, DSI_WRITE_REG0, val); + + /* DSI_WRITE_REG1 */ + dphy_pll_write(dsi, DSI_WRITE_REG1, GMP_CTRL(1) | CPBIAS_CTRL(0x10)); + + ret = clk_prepare_enable(dsi->clk_ref); + if (ret < 0) { + dev_err(dsi->dev, "failed to enable ref clock: %d\n", ret); + return ret; + } + + /* + * At least 10 refclk cycles are required before updatePLL assertion, + * according to DPHY Databook Figure 3-3 Initialization Timing Diagram. + */ + fsleep(10); + + ret = dphy_pll_update(dsi); + if (ret < 0) { + clk_disable_unprepare(dsi->clk_ref); + return ret; + } + + return 0; +} + +static void dphy_pll_clear_reg(struct imx93_dsi *dsi) +{ + dphy_pll_write(dsi, DSI_REG, 0); + dphy_pll_write(dsi, DSI_WRITE_REG0, 0); + dphy_pll_write(dsi, DSI_WRITE_REG1, 0); +} + +static int dphy_pll_init(struct imx93_dsi *dsi) +{ + int ret; + + ret = clk_prepare_enable(dsi->clk_cfg); + if (ret < 0) { + dev_err(dsi->dev, "failed to enable config clock: %d\n", ret); + return ret; + } + + dphy_pll_clear_reg(dsi); + + return 0; +} + +static void dphy_pll_uninit(struct imx93_dsi *dsi) +{ + dphy_pll_clear_reg(dsi); + clk_disable_unprepare(dsi->clk_cfg); +} + +static void dphy_pll_power_off(struct imx93_dsi *dsi) +{ + dphy_pll_clear_reg(dsi); + clk_disable_unprepare(dsi->clk_ref); +} + +static int imx93_dsi_get_phy_configure_opts(struct imx93_dsi *dsi, + const struct drm_display_mode *mode, + union phy_configure_opts *phy_cfg, + u32 lanes, u32 format) +{ + struct device *dev = dsi->dev; + int bpp; + int ret; + + bpp = mipi_dsi_pixel_format_to_bpp(format); + if (bpp < 0) { + dev_dbg(dev, "failed to get bpp for pixel format %d\n", format); + return -EINVAL; + } + + ret = phy_mipi_dphy_get_default_config(mode->clock * MSEC_PER_SEC, bpp, + lanes, &phy_cfg->mipi_dphy); + if (ret < 0) { + dev_dbg(dev, "failed to get default phy cfg %d\n", ret); + return ret; + } + + return 0; +} + +static enum drm_mode_status +imx93_dsi_validate_mode(struct imx93_dsi *dsi, const struct drm_display_mode *mode) +{ + struct drm_bridge *bridge = dw_mipi_dsi_get_bridge(dsi->dmd); + + /* Get the last bridge */ + while (drm_bridge_get_next_bridge(bridge)) + bridge = drm_bridge_get_next_bridge(bridge); + + if ((bridge->ops & DRM_BRIDGE_OP_DETECT) && + (bridge->ops & DRM_BRIDGE_OP_EDID)) { + unsigned long pixel_clock_rate = mode->clock * 1000; + unsigned long rounded_rate; + + /* Allow +/-0.5% pixel clock rate deviation */ + rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate); + if (rounded_rate < pixel_clock_rate * 995 / 1000 || + rounded_rate > pixel_clock_rate * 1005 / 1000) { + dev_dbg(dsi->dev, "failed to round clock for mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return MODE_NOCLOCK; + } + } + + return MODE_OK; +} + +static enum drm_mode_status +imx93_dsi_validate_phy(struct imx93_dsi *dsi, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format) +{ + union phy_configure_opts phy_cfg; + struct dphy_pll_cfg cfg = { 0 }; + struct device *dev = dsi->dev; + int ret; + + ret = imx93_dsi_get_phy_configure_opts(dsi, mode, &phy_cfg, lanes, + format); + if (ret < 0) { + dev_dbg(dev, "failed to get phy cfg opts %d\n", ret); + return MODE_ERROR; + } + + ret = dphy_pll_get_configure_from_opts(dsi, &phy_cfg.mipi_dphy, &cfg); + if (ret < 0) { + dev_dbg(dev, "failed to get phy pll cfg %d\n", ret); + return MODE_NOCLOCK; + } + + return MODE_OK; +} + +static enum drm_mode_status +imx93_dsi_mode_valid(void *priv_data, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format) +{ + struct imx93_dsi *dsi = priv_data; + struct device *dev = dsi->dev; + enum drm_mode_status ret; + + ret = imx93_dsi_validate_mode(dsi, mode); + if (ret != MODE_OK) { + dev_dbg(dev, "failed to validate mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return ret; + } + + ret = imx93_dsi_validate_phy(dsi, mode, mode_flags, lanes, format); + if (ret != MODE_OK) { + dev_dbg(dev, "failed to validate phy for mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return ret; + } + + return MODE_OK; +} + +static bool imx93_dsi_mode_fixup(void *priv_data, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct imx93_dsi *dsi = priv_data; + unsigned long pixel_clock_rate; + unsigned long rounded_rate; + + pixel_clock_rate = mode->clock * 1000; + rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate); + + memcpy(adjusted_mode, mode, sizeof(*mode)); + adjusted_mode->clock = rounded_rate / 1000; + + dev_dbg(dsi->dev, "adj clock %d for mode " DRM_MODE_FMT "\n", + adjusted_mode->clock, DRM_MODE_ARG(mode)); + + return true; +} + +static u32 *imx93_dsi_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) +{ + u32 *input_fmts, input_fmt; + + *num_input_fmts = 0; + + switch (output_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB666_1X18: + case MEDIA_BUS_FMT_FIXED: + input_fmt = MEDIA_BUS_FMT_RGB888_1X24; + break; + case MEDIA_BUS_FMT_RGB565_1X16: + input_fmt = output_fmt; + break; + default: + return NULL; + } + + input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) + return NULL; + input_fmts[0] = input_fmt; + *num_input_fmts = 1; + + return input_fmts; +} + +static int imx93_dsi_phy_init(void *priv_data) +{ + struct imx93_dsi *dsi = priv_data; + unsigned int fmt = 0; + int ret; + + switch (dsi->format) { + case MIPI_DSI_FMT_RGB888: + fmt = RGB888_TO_RGB888; + break; + case MIPI_DSI_FMT_RGB666: + fmt = RGB888_TO_RGB666; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB666_MAP_CFG, RGB666_CONFIG2); + break; + case MIPI_DSI_FMT_RGB666_PACKED: + fmt = RGB888_TO_RGB666; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB666_MAP_CFG, RGB666_CONFIG1); + break; + case MIPI_DSI_FMT_RGB565: + fmt = RGB565_TO_RGB565; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB565_MAP_CFG, RGB565_CONFIG1); + break; + } + + regmap_update_bits(dsi->regmap, DISPLAY_MUX, LCDIF_CROSS_LINE_PATTERN, fmt); + + ret = dphy_pll_init(dsi); + if (ret < 0) { + dev_err(dsi->dev, "failed to init phy pll: %d\n", ret); + return ret; + } + + ret = dphy_pll_configure(dsi, &dsi->phy_cfg); + if (ret < 0) { + dev_err(dsi->dev, "failed to configure phy pll: %d\n", ret); + dphy_pll_uninit(dsi); + return ret; + } + + return 0; +} + +static void imx93_dsi_phy_power_off(void *priv_data) +{ + struct imx93_dsi *dsi = priv_data; + + dphy_pll_power_off(dsi); + dphy_pll_uninit(dsi); +} + +static int +imx93_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format, + unsigned int *lane_mbps) +{ + struct imx93_dsi *dsi = priv_data; + union phy_configure_opts phy_cfg; + struct device *dev = dsi->dev; + int ret; + + ret = imx93_dsi_get_phy_configure_opts(dsi, mode, &phy_cfg, lanes, + format); + if (ret < 0) { + dev_dbg(dev, "failed to get phy cfg opts %d\n", ret); + return ret; + } + + *lane_mbps = DIV_ROUND_UP(phy_cfg.mipi_dphy.hs_clk_rate, USEC_PER_SEC); + + memcpy(&dsi->phy_cfg, &phy_cfg, sizeof(phy_cfg)); + + dev_dbg(dev, "get lane_mbps %u for mode " DRM_MODE_FMT "\n", + *lane_mbps, DRM_MODE_ARG(mode)); + + return 0; +} + +/* High-Speed Transition Times */ +struct hstt { + unsigned int maxfreq; + struct dw_mipi_dsi_dphy_timing timing; +}; + +#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \ +{ \ + .maxfreq = (_maxfreq), \ + .timing = { \ + .clk_lp2hs = (_c_lp2hs), \ + .clk_hs2lp = (_c_hs2lp), \ + .data_lp2hs = (_d_lp2hs), \ + .data_hs2lp = (_d_hs2lp), \ + } \ +} + +/* DPHY Databook Table A-4 High-Speed Transition Times */ +static const struct hstt hstt_table[] = { + HSTT(80, 21, 17, 15, 10), + HSTT(90, 23, 17, 16, 10), + HSTT(100, 22, 17, 16, 10), + HSTT(110, 25, 18, 17, 11), + HSTT(120, 26, 20, 18, 11), + HSTT(130, 27, 19, 19, 11), + HSTT(140, 27, 19, 19, 11), + HSTT(150, 28, 20, 20, 12), + HSTT(160, 30, 21, 22, 13), + HSTT(170, 30, 21, 23, 13), + HSTT(180, 31, 21, 23, 13), + HSTT(190, 32, 22, 24, 13), + HSTT(205, 35, 22, 25, 13), + HSTT(220, 37, 26, 27, 15), + HSTT(235, 38, 28, 27, 16), + HSTT(250, 41, 29, 30, 17), + HSTT(275, 43, 29, 32, 18), + HSTT(300, 45, 32, 35, 19), + HSTT(325, 48, 33, 36, 18), + HSTT(350, 51, 35, 40, 20), + HSTT(400, 59, 37, 44, 21), + HSTT(450, 65, 40, 49, 23), + HSTT(500, 71, 41, 54, 24), + HSTT(550, 77, 44, 57, 26), + HSTT(600, 82, 46, 64, 27), + HSTT(650, 87, 48, 67, 28), + HSTT(700, 94, 52, 71, 29), + HSTT(750, 99, 52, 75, 31), + HSTT(800, 105, 55, 82, 32), + HSTT(850, 110, 58, 85, 32), + HSTT(900, 115, 58, 88, 35), + HSTT(950, 120, 62, 93, 36), + HSTT(1000, 128, 63, 99, 38), + HSTT(1050, 132, 65, 102, 38), + HSTT(1100, 138, 67, 106, 39), + HSTT(1150, 146, 69, 112, 42), + HSTT(1200, 151, 71, 117, 43), + HSTT(1250, 153, 74, 120, 45), + HSTT(1300, 160, 73, 124, 46), + HSTT(1350, 165, 76, 130, 47), + HSTT(1400, 172, 78, 134, 49), + HSTT(1450, 177, 80, 138, 49), + HSTT(1500, 183, 81, 143, 52), + HSTT(1550, 191, 84, 147, 52), + HSTT(1600, 194, 85, 152, 52), + HSTT(1650, 201, 86, 155, 53), + HSTT(1700, 208, 88, 161, 53), + HSTT(1750, 212, 89, 165, 53), + HSTT(1800, 220, 90, 171, 54), + HSTT(1850, 223, 92, 175, 54), + HSTT(1900, 231, 91, 180, 55), + HSTT(1950, 236, 95, 185, 56), + HSTT(2000, 243, 97, 190, 56), + HSTT(2050, 248, 99, 194, 58), + HSTT(2100, 252, 100, 199, 59), + HSTT(2150, 259, 102, 204, 61), + HSTT(2200, 266, 105, 210, 62), + HSTT(2250, 269, 109, 213, 63), + HSTT(2300, 272, 109, 217, 65), + HSTT(2350, 281, 112, 225, 66), + HSTT(2400, 283, 115, 226, 66), + HSTT(2450, 282, 115, 226, 67), + HSTT(2500, 281, 118, 227, 67), +}; + +static int imx93_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps, + struct dw_mipi_dsi_dphy_timing *timing) +{ + struct imx93_dsi *dsi = priv_data; + struct device *dev = dsi->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(hstt_table); i++) + if (lane_mbps <= hstt_table[i].maxfreq) + break; + + if (i == ARRAY_SIZE(hstt_table)) { + dev_err(dev, "failed to get phy timing for lane_mbps %u\n", + lane_mbps); + return -EINVAL; + } + + *timing = hstt_table[i].timing; + + dev_dbg(dev, "get phy timing for %u <= %u (lane_mbps)\n", + lane_mbps, hstt_table[i].maxfreq); + + return 0; +} + +static const struct dw_mipi_dsi_phy_ops imx93_dsi_phy_ops = { + .init = imx93_dsi_phy_init, + .power_off = imx93_dsi_phy_power_off, + .get_lane_mbps = imx93_dsi_get_lane_mbps, + .get_timing = imx93_dsi_phy_get_timing, +}; + +static int imx93_dsi_host_attach(void *priv_data, struct mipi_dsi_device *device) +{ + struct imx93_dsi *dsi = priv_data; + + dsi->format = device->format; + + return 0; +} + +static const struct dw_mipi_dsi_host_ops imx93_dsi_host_ops = { + .attach = imx93_dsi_host_attach, +}; + +static int imx93_dsi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct imx93_dsi *dsi; + int ret; + + dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); + if (!dsi) + return -ENOMEM; + + dsi->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,media-blk-ctrl"); + if (IS_ERR(dsi->regmap)) { + ret = PTR_ERR(dsi->regmap); + dev_err(dev, "failed to get block ctrl regmap: %d\n", ret); + return ret; + } + + dsi->clk_pixel = devm_clk_get(dev, "pix"); + if (IS_ERR(dsi->clk_pixel)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_pixel), + "failed to get pixel clock\n"); + + dsi->clk_cfg = devm_clk_get(dev, "phy_cfg"); + if (IS_ERR(dsi->clk_cfg)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_cfg), + "failed to get phy cfg clock\n"); + + dsi->clk_ref = devm_clk_get(dev, "phy_ref"); + if (IS_ERR(dsi->clk_ref)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_ref), + "failed to get phy ref clock\n"); + + dsi->ref_clk_rate = clk_get_rate(dsi->clk_ref); + if (dsi->ref_clk_rate < REF_CLK_RATE_MIN || + dsi->ref_clk_rate > REF_CLK_RATE_MAX) { + dev_err(dev, "invalid phy ref clock rate %lu\n", + dsi->ref_clk_rate); + return -EINVAL; + } + dev_dbg(dev, "phy ref clock rate: %lu\n", dsi->ref_clk_rate); + + dsi->dev = dev; + dsi->pdata.max_data_lanes = 4; + dsi->pdata.mode_valid = imx93_dsi_mode_valid; + dsi->pdata.mode_fixup = imx93_dsi_mode_fixup; + dsi->pdata.get_input_bus_fmts = imx93_dsi_get_input_bus_fmts; + dsi->pdata.phy_ops = &imx93_dsi_phy_ops; + dsi->pdata.host_ops = &imx93_dsi_host_ops; + dsi->pdata.priv_data = dsi; + platform_set_drvdata(pdev, dsi); + + dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); + if (IS_ERR(dsi->dmd)) + return dev_err_probe(dev, PTR_ERR(dsi->dmd), + "failed to probe dw_mipi_dsi\n"); + + return 0; +} + +static void imx93_dsi_remove(struct platform_device *pdev) +{ + struct imx93_dsi *dsi = platform_get_drvdata(pdev); + + dw_mipi_dsi_remove(dsi->dmd); +} + +static const struct of_device_id imx93_dsi_dt_ids[] = { + { .compatible = "fsl,imx93-mipi-dsi", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx93_dsi_dt_ids); + +static struct platform_driver imx93_dsi_driver = { + .probe = imx93_dsi_probe, + .remove_new = imx93_dsi_remove, + .driver = { + .of_match_table = imx93_dsi_dt_ids, + .name = "imx93_mipi_dsi", + }, +}; +module_platform_driver(imx93_dsi_driver); + +MODULE_DESCRIPTION("Freescale i.MX93 MIPI DSI driver"); +MODULE_AUTHOR("Liu Ying "); +MODULE_LICENSE("GPL"); -- cgit From 15fe53be46eaf4f6339cd433972ecc90513e3076 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 12 Oct 2023 01:00:02 +0300 Subject: drm/bridge: lt9611uxc: fix the race in the error path If DSI host attachment fails, the LT9611UXC driver will remove the bridge without ensuring that there is no outstanding HPD work being done. In rare cases this can result in the warnings regarding the mutex being incorrect. Fix this by forcebly freing IRQ and flushing the work. DEBUG_LOCKS_WARN_ON(lock->magic != lock) WARNING: CPU: 0 PID: 10 at kernel/locking/mutex.c:582 __mutex_lock+0x468/0x77c Modules linked in: CPU: 0 PID: 10 Comm: kworker/0:1 Tainted: G U 6.6.0-rc5-next-20231011-gd81f81c2b682-dirty #1206 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Workqueue: events lt9611uxc_hpd_work pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __mutex_lock+0x468/0x77c lr : __mutex_lock+0x468/0x77c sp : ffff8000800a3c70 x29: ffff8000800a3c70 x28: 0000000000000000 x27: ffffd595fe333000 x26: ffff7c2f0002c005 x25: ffffd595ff1b3000 x24: ffffd595fccda5a0 x23: 0000000000000000 x22: 0000000000000002 x21: ffff7c2f056d91c8 x20: 0000000000000000 x19: ffff7c2f056d91c8 x18: fffffffffffe8db0 x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000000 x14: 000000000006efb8 x13: 0000000000000000 x12: 0000000000000037 x11: 0000000000000001 x10: 0000000000001470 x9 : ffff8000800a3ae0 x8 : ffff7c2f0027f8d0 x7 : ffff7c2f0027e400 x6 : ffffd595fc702b54 x5 : 0000000000000000 x4 : ffff8000800a0000 x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff7c2f0027e400 Call trace: __mutex_lock+0x468/0x77c mutex_lock_nested+0x24/0x30 drm_bridge_hpd_notify+0x2c/0x5c lt9611uxc_hpd_work+0x6c/0x80 process_one_work+0x1ec/0x51c worker_thread+0x1ec/0x3e4 kthread+0x120/0x124 ret_from_fork+0x10/0x20 irq event stamp: 15799 hardirqs last enabled at (15799): [] finish_task_switch.isra.0+0xa8/0x278 hardirqs last disabled at (15798): [] __schedule+0x7b8/0xbd8 softirqs last enabled at (15794): [] __do_softirq+0x498/0x4e0 softirqs last disabled at (15771): [] ____do_softirq+0x10/0x1c Fixes: bc6fa8676ebb ("drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler") Signed-off-by: Dmitry Baryshkov Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20231011220002.382422-1-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 7835738a532e..e971b75e90ad 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -929,9 +929,9 @@ retry: init_waitqueue_head(<9611uxc->wq); INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work); - ret = devm_request_threaded_irq(dev, client->irq, NULL, - lt9611uxc_irq_thread_handler, - IRQF_ONESHOT, "lt9611uxc", lt9611uxc); + ret = request_threaded_irq(client->irq, NULL, + lt9611uxc_irq_thread_handler, + IRQF_ONESHOT, "lt9611uxc", lt9611uxc); if (ret) { dev_err(dev, "failed to request irq\n"); goto err_disable_regulators; @@ -967,6 +967,8 @@ retry: return lt9611uxc_audio_init(dev, lt9611uxc); err_remove_bridge: + free_irq(client->irq, lt9611uxc); + cancel_work_sync(<9611uxc->work); drm_bridge_remove(<9611uxc->bridge); err_disable_regulators: @@ -983,7 +985,7 @@ static void lt9611uxc_remove(struct i2c_client *client) { struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client); - disable_irq(client->irq); + free_irq(client->irq, lt9611uxc); cancel_work_sync(<9611uxc->work); lt9611uxc_audio_exit(lt9611uxc); drm_bridge_remove(<9611uxc->bridge); -- cgit From 6471da5ee311d53ef46eebcb7725bc94266cc0cf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 11 Oct 2023 11:01:48 +0300 Subject: drm/rockchip: Fix type promotion bug in rockchip_gem_iommu_map() The "ret" variable is declared as ssize_t and it can hold negative error codes but the "rk_obj->base.size" variable is type size_t. This means that when we compare them, they are both type promoted to size_t and the negative error code becomes a high unsigned value and is treated as success. Add a cast to fix this. Fixes: 38f993b7c59e ("drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain") Signed-off-by: Dan Carpenter Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/2bfa28b5-145d-4b9e-a18a-98819dd686ce@moroto.mountain --- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index b8f8b45ebf59..93ed841f5dce 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -40,7 +40,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt, prot); - if (ret < rk_obj->base.size) { + if (ret < (ssize_t)rk_obj->base.size) { DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n", ret, rk_obj->base.size); ret = -ENOMEM; -- cgit From ac1c11c23fc51c1ba51a3ed586df40ffe6b1de35 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 13 Oct 2023 20:20:36 +0800 Subject: drm/rockchip: remove unused struct in vop2 These structs are undefined and un used. Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") Signed-off-by: Andy Yan Reviewed-by: Sascha Hauer Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20231013122036.1594090-1-andyshrk@163.com --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 -- drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 3 --- 2 files changed, 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index ec7e0e6149af..c5b8d716e493 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -160,7 +160,6 @@ struct vop2_video_port { struct vop2 *vop2; struct clk *dclk; unsigned int id; - const struct vop2_video_port_regs *regs; const struct vop2_video_port_data *data; struct completion dsp_hold_completion; @@ -2273,7 +2272,6 @@ static int vop2_create_crtcs(struct vop2 *vop2) vp = &vop2->vps[i]; vp->vop2 = vop2; vp->id = vp_data->id; - vp->regs = vp_data->regs; vp->data = vp_data; snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h index f1234a151130..56fd31e05238 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -134,16 +134,13 @@ struct vop2_video_port_data { u16 cubic_lut_len; struct vop_rect max_output; const u8 pre_scan_max_dly[4]; - const struct vop2_video_port_regs *regs; unsigned int offset; }; struct vop2_data { u8 nr_vps; - const struct vop2_ctrl *ctrl; const struct vop2_win_data *win; const struct vop2_video_port_data *vp; - const struct vop_csc_table *csc_table; struct vop_rect max_input; struct vop_rect max_output; -- cgit From dc00748adcf03d754bf43035c668bc5b20fb6597 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 13 Oct 2023 20:20:51 +0800 Subject: drm/rockchip: remove NR_LAYERS macro on vop2 There are 8 layers on rk3588, so a fix defined macro is not appropriate. Signed-off-by: Andy Yan Reviewed-by: Sascha Hauer Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20231013122051.1594164-1-andyshrk@163.com --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index c5b8d716e493..cce9183d750d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -2250,8 +2250,6 @@ static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2) return NULL; } -#define NR_LAYERS 6 - static int vop2_create_crtcs(struct vop2 *vop2) { const struct vop2_data *vop2_data = vop2->data; @@ -2370,7 +2368,7 @@ static int vop2_create_crtcs(struct vop2 *vop2) struct vop2_video_port *vp = &vop2->vps[i]; if (vp->crtc.port) - vp->nlayers = NR_LAYERS / nvps; + vp->nlayers = vop2_data->win_size / nvps; } return 0; -- cgit From 636a989eb4d022e1756009592445aedaaf7424d8 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Fri, 13 Oct 2023 13:39:16 -0500 Subject: drm/panel: st7703: Add Powkiddy RGB30 Panel Support The Powkiddy RGB30 4 inch panel is a 4 inch 720x720 DSI panel used in the Powkiddy RGB30 handheld gaming device. Add support for it. Signed-off-by: Chris Morgan Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20231013183918.225666-4-macroalpha82@gmail.com --- drivers/gpu/drm/panel/panel-sitronix-st7703.c | 89 +++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 79d56725b010..b55bafd1a8be 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -433,6 +433,94 @@ static const struct st7703_panel_desc rg353v2_desc = { .init_sequence = rg353v2_init_sequence, }; +static int rgb30panel_init_sequence(struct st7703 *ctx) +{ + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); + + /* Init sequence extracted from Powkiddy RGB30 BSP kernel. */ + + /* + * For some reason this specific panel must be taken out of sleep + * before the full init sequence, or else it will not display. + */ + mipi_dsi_dcs_exit_sleep_mode(dsi); + msleep(250); + + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, 0xf9, + 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, 0x00, + 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25, 0x22, 0xf0, + 0x63); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28, + 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50, + 0x00, 0x00, 0x12, 0x70, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x46); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x3c, 0x12, 0x30); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b, + 0x03, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xc0, 0x10); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x36, 0x00, 0x32, + 0x32, 0x77, 0xf1, 0xcc, 0xcc, 0x77, 0x77, 0x33, + 0x33); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x0a, 0x0a); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x88, 0x88); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x0a, 0x10, + 0x0f, 0xa1, 0x80, 0x12, 0x31, 0x23, 0x47, 0x86, + 0xa1, 0x80, 0x47, 0x08, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x48, 0x02, 0x8b, 0xaf, 0x46, 0x02, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x48, 0x13, 0x8b, 0xaf, 0x57, + 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x96, 0x12, 0x01, 0x01, + 0x01, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0x31, 0x8b, 0xa8, 0x31, 0x75, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x4f, 0x20, 0x8b, 0xa8, 0x20, + 0x64, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00, + 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0xa1, 0x80, 0x00, 0x00, 0x00, + 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x0a, 0x0f, + 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, 0x10, + 0x13, 0x15, 0x14, 0x15, 0x10, 0x17, 0x00, 0x0a, + 0x0f, 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, + 0x10, 0x13, 0x15, 0x14, 0x15, 0x10, 0x17); + + return 0; +} + +static const struct drm_display_mode rgb30panel_mode = { + .hdisplay = 720, + .hsync_start = 720 + 45, + .hsync_end = 720 + 45 + 4, + .htotal = 720 + 45 + 4 + 45, + .vdisplay = 720, + .vsync_start = 720 + 15, + .vsync_end = 720 + 15 + 3, + .vtotal = 720 + 15 + 3 + 11, + .clock = 36570, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, + .width_mm = 76, + .height_mm = 76, +}; + +static const struct st7703_panel_desc rgb30panel_desc = { + .mode = &rgb30panel_mode, + .lanes = 4, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM, + .format = MIPI_DSI_FMT_RGB888, + .init_sequence = rgb30panel_init_sequence, +}; + static int st7703_enable(struct drm_panel *panel) { struct st7703 *ctx = panel_to_st7703(panel); @@ -696,6 +784,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi) static const struct of_device_id st7703_of_match[] = { { .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc }, + { .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc }, { .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc }, { .compatible = "xingbangda,xbd599", .data = &xbd599_desc }, { /* sentinel */ } -- cgit From f7749a549b4f4db0c02e6b3d3800ea400dd76c12 Mon Sep 17 00:00:00 2001 From: Thomas Hellström Date: Tue, 10 Oct 2023 16:27:24 +0200 Subject: drm/gpuvm: Dual-licence the drm_gpuvm code GPL-2.0 OR MIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dual-licence in order to make it possible for other non-GPL os'es to re-implement the code. The use of EXPORT_SYMBOL_GPL() is intentionally left untouched to prevent use of drm_gpuvm as a proxy for non-GPL drivers to access GPL-only kernel symbols. Much of the ideas and algorithms used in the drm_gpuvm code is already present in one way or another in MIT-licensed code. Cc: Danilo Krummrich Cc: airlied@gmail.com Cc: daniel@ffwll.ch Cc: linux-kernel@vger.kernel.org Signed-off-by: Thomas Hellström Acked-by: Danilo Krummrich Reviewed-by: Francois Dugast Link: https://patchwork.freedesktop.org/patch/msgid/20231010142725.8920-1-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/drm_gpuvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index 02ce6baacdad..08c088319652 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0-only +// SPDX-License-Identifier: GPL-2.0 OR MIT /* * Copyright (c) 2022 Red Hat. * -- cgit From ec5dceb8180f0cb110dc7029d55d6a83d0583015 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:03 +0200 Subject: drm/ssd130x: Replace .page_height field in device info with a constant This deemed useful to avoid hardcoding a page height and allow to support other Solomon controller families, but dividing the screen in pages seems to be something that is specific to the SSD130x chip family. For example, SSD132x chip family divides the screen in segments (columns) and common outputs (rows), so the concept of screen pages does not exist for the SSD132x family. Let's drop this field from the device info struct and just use a constant SSD130X_PAGE_HEIGHT macro to define the page height. While being there, replace hardcoded 8 values in places where it is used as the page height. Signed-off-by: Javier Martinez Canillas Reviewed-by: Geert Uytterhoeven Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-2-javierm@redhat.com --- drivers/gpu/drm/solomon/ssd130x.c | 37 ++++++++++++++++++------------------- drivers/gpu/drm/solomon/ssd130x.h | 1 - 2 files changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 0c716136c538..d530d13eef5a 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -42,6 +42,8 @@ #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 +#define SSD130X_PAGE_HEIGHT 8 + #define SSD130X_PAGE_COL_START_LOW 0x00 #define SSD130X_PAGE_COL_START_HIGH 0x10 #define SSD130X_SET_ADDRESS_MODE 0x20 @@ -102,7 +104,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_width = 132, .default_height = 64, .page_mode_only = 1, - .page_height = 8, }, [SSD1305_ID] = { .default_vcomh = 0x34, @@ -110,7 +111,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 7, .default_width = 132, .default_height = 64, - .page_height = 8, }, [SSD1306_ID] = { .default_vcomh = 0x20, @@ -119,7 +119,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_chargepump = 1, .default_width = 128, .default_height = 64, - .page_height = 8, }, [SSD1307_ID] = { .default_vcomh = 0x20, @@ -128,7 +127,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_pwm = 1, .default_width = 128, .default_height = 39, - .page_height = 8, }, [SSD1309_ID] = { .default_vcomh = 0x34, @@ -136,7 +134,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 10, .default_width = 128, .default_height = 64, - .page_height = 8, } }; EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); @@ -465,13 +462,13 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, unsigned int width = drm_rect_width(rect); unsigned int height = drm_rect_height(rect); unsigned int line_length = DIV_ROUND_UP(width, 8); - unsigned int page_height = ssd130x->device_info->page_height; + unsigned int page_height = SSD130X_PAGE_HEIGHT; unsigned int pages = DIV_ROUND_UP(height, page_height); struct drm_device *drm = &ssd130x->drm; u32 array_idx = 0; int ret, i, j, k; - drm_WARN_ONCE(drm, y % 8 != 0, "y must be aligned to screen page\n"); + drm_WARN_ONCE(drm, y % page_height != 0, "y must be aligned to screen page\n"); /* * The screen is divided in pages, each having a height of 8 @@ -503,27 +500,32 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, */ if (!ssd130x->page_address_mode) { + u8 page_start; + /* Set address range for horizontal addressing mode */ ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width); if (ret < 0) return ret; - ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset + y / 8, pages); + page_start = ssd130x->page_offset + y / page_height; + ret = ssd130x_set_page_range(ssd130x, page_start, pages); if (ret < 0) return ret; } for (i = 0; i < pages; i++) { - int m = 8; + int m = page_height; /* Last page may be partial */ - if (8 * (y / 8 + i + 1) > ssd130x->height) - m = ssd130x->height % 8; + if (page_height * (y / page_height + i + 1) > ssd130x->height) + m = ssd130x->height % page_height; + for (j = 0; j < width; j++) { u8 data = 0; for (k = 0; k < m; k++) { - u8 byte = buf[(8 * i + k) * line_length + j / 8]; + u32 idx = (page_height * i + k) * line_length + j / 8; + u8 byte = buf[idx]; u8 bit = (byte >> (j % 8)) & 1; data |= bit << k; @@ -559,8 +561,7 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) { - unsigned int page_height = ssd130x->device_info->page_height; - unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height); + unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT); unsigned int width = ssd130x->width; int ret, i; @@ -605,14 +606,13 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, u8 *buf, u8 *data_array) { struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); - unsigned int page_height = ssd130x->device_info->page_height; struct iosys_map dst; unsigned int dst_pitch; int ret = 0; /* Align y to display page boundaries */ - rect->y1 = round_down(rect->y1, page_height); - rect->y2 = min_t(unsigned int, round_up(rect->y2, page_height), ssd130x->height); + rect->y1 = round_down(rect->y1, SSD130X_PAGE_HEIGHT); + rect->y2 = min_t(unsigned int, round_up(rect->y2, SSD130X_PAGE_HEIGHT), ssd130x->height); dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8); @@ -815,8 +815,7 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc, struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state); - unsigned int page_height = ssd130x->device_info->page_height; - unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height); + unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT); int ret; ret = drm_crtc_helper_atomic_check(crtc, state); diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index aa39b13615eb..bbe374453605 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -39,7 +39,6 @@ struct ssd130x_deviceinfo { u32 default_dclk_frq; u32 default_width; u32 default_height; - u32 page_height; bool need_pwm; bool need_chargepump; bool page_mode_only; -- cgit From e6663dd42a79a8d0440530ce91dd8667fe41ff03 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:04 +0200 Subject: drm/ssd130x: Add a controller family id to the device info data To allow the driver to have a per Solomon display controller modesetting pipeline and support aother controller families besides SSD130x. Signed-off-by: Javier Martinez Canillas Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-3-javierm@redhat.com --- drivers/gpu/drm/solomon/ssd130x-i2c.c | 1 + drivers/gpu/drm/solomon/ssd130x-spi.c | 2 ++ drivers/gpu/drm/solomon/ssd130x.c | 5 +++++ drivers/gpu/drm/solomon/ssd130x.h | 7 +++++++ 4 files changed, 15 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c index b4eb2d64bf6e..8f89b89d553f 100644 --- a/drivers/gpu/drm/solomon/ssd130x-i2c.c +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -54,6 +54,7 @@ static void ssd130x_i2c_shutdown(struct i2c_client *client) } static const struct of_device_id ssd130x_of_match[] = { + /* ssd130x family */ { .compatible = "sinowealth,sh1106", .data = &ssd130x_variants[SH1106_ID], diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 19ab4942cb33..257819bccbc8 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -108,6 +108,7 @@ static void ssd130x_spi_shutdown(struct spi_device *spi) } static const struct of_device_id ssd130x_of_match[] = { + /* ssd130x family */ { .compatible = "sinowealth,sh1106", .data = &ssd130x_variants[SH1106_ID], @@ -142,6 +143,7 @@ MODULE_DEVICE_TABLE(of, ssd130x_of_match); * not be needed for this driver to match the registered SPI devices. */ static const struct spi_device_id ssd130x_spi_table[] = { + /* ssd130x family */ { "sh1106", SH1106_ID }, { "ssd1305", SSD1305_ID }, { "ssd1306", SSD1306_ID }, diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index d530d13eef5a..84093bcc8584 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -104,6 +104,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_width = 132, .default_height = 64, .page_mode_only = 1, + .family_id = SSD130X_FAMILY, }, [SSD1305_ID] = { .default_vcomh = 0x34, @@ -111,6 +112,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 7, .default_width = 132, .default_height = 64, + .family_id = SSD130X_FAMILY, }, [SSD1306_ID] = { .default_vcomh = 0x20, @@ -119,6 +121,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_chargepump = 1, .default_width = 128, .default_height = 64, + .family_id = SSD130X_FAMILY, }, [SSD1307_ID] = { .default_vcomh = 0x20, @@ -127,6 +130,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_pwm = 1, .default_width = 128, .default_height = 39, + .family_id = SSD130X_FAMILY, }, [SSD1309_ID] = { .default_vcomh = 0x34, @@ -134,6 +138,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 10, .default_width = 128, .default_height = 64, + .family_id = SSD130X_FAMILY, } }; EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index bbe374453605..c562c2d00c16 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -24,7 +24,12 @@ #define SSD130X_DATA 0x40 #define SSD130X_COMMAND 0x80 +enum ssd130x_family_ids { + SSD130X_FAMILY +}; + enum ssd130x_variants { + /* ssd130x family */ SH1106_ID, SSD1305_ID, SSD1306_ID, @@ -42,6 +47,8 @@ struct ssd130x_deviceinfo { bool need_pwm; bool need_chargepump; bool page_mode_only; + + enum ssd130x_family_ids family_id; }; struct ssd130x_device { -- cgit From 9081d21a5a6b575551bfd6281981537140b55338 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:05 +0200 Subject: drm/ssd130x: Rename commands that are shared across chip families There are some commands that are shared between the SSD130x and SSD132x controller families, define these as a common SSD13XX set of commands. Signed-off-by: Javier Martinez Canillas Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-4-javierm@redhat.com --- drivers/gpu/drm/solomon/ssd130x-spi.c | 4 +-- drivers/gpu/drm/solomon/ssd130x.c | 47 +++++++++++++++++++---------------- drivers/gpu/drm/solomon/ssd130x.h | 4 +-- 3 files changed, 30 insertions(+), 25 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 257819bccbc8..89989da705d7 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -34,10 +34,10 @@ static int ssd130x_spi_write(void *context, const void *data, size_t count) struct spi_device *spi = t->spi; const u8 *reg = data; - if (*reg == SSD130X_COMMAND) + if (*reg == SSD13XX_COMMAND) gpiod_set_value_cansleep(t->dc, 0); - if (*reg == SSD130X_DATA) + if (*reg == SSD13XX_DATA) gpiod_set_value_cansleep(t->dc, 1); /* Remove control byte since is not used in a 4-wire SPI interface */ diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 84093bcc8584..e11f16bf795e 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -44,18 +44,24 @@ #define SSD130X_PAGE_HEIGHT 8 +/* ssd13xx commands */ +#define SSD13XX_CONTRAST 0x81 +#define SSD13XX_SET_SEG_REMAP 0xa0 +#define SSD13XX_SET_MULTIPLEX_RATIO 0xa8 +#define SSD13XX_DISPLAY_OFF 0xae +#define SSD13XX_DISPLAY_ON 0xaf + +#define SSD13XX_SET_SEG_REMAP_MASK GENMASK(0, 0) +#define SSD13XX_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD13XX_SET_SEG_REMAP_MASK, (val)) + +/* ssd130x commands */ #define SSD130X_PAGE_COL_START_LOW 0x00 #define SSD130X_PAGE_COL_START_HIGH 0x10 #define SSD130X_SET_ADDRESS_MODE 0x20 #define SSD130X_SET_COL_RANGE 0x21 #define SSD130X_SET_PAGE_RANGE 0x22 -#define SSD130X_CONTRAST 0x81 #define SSD130X_SET_LOOKUP_TABLE 0x91 #define SSD130X_CHARGE_PUMP 0x8d -#define SSD130X_SET_SEG_REMAP 0xa0 -#define SSD130X_DISPLAY_OFF 0xae -#define SSD130X_SET_MULTIPLEX_RATIO 0xa8 -#define SSD130X_DISPLAY_ON 0xaf #define SSD130X_START_PAGE_ADDRESS 0xb0 #define SSD130X_SET_COM_SCAN_DIR 0xc0 #define SSD130X_SET_DISPLAY_OFFSET 0xd3 @@ -65,13 +71,12 @@ #define SSD130X_SET_COM_PINS_CONFIG 0xda #define SSD130X_SET_VCOMH 0xdb +/* ssd130x commands accessors */ #define SSD130X_PAGE_COL_START_MASK GENMASK(3, 0) #define SSD130X_PAGE_COL_START_HIGH_SET(val) FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val) >> 4) #define SSD130X_PAGE_COL_START_LOW_SET(val) FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val)) #define SSD130X_START_PAGE_ADDRESS_MASK GENMASK(2, 0) #define SSD130X_START_PAGE_ADDRESS_SET(val) FIELD_PREP(SSD130X_START_PAGE_ADDRESS_MASK, (val)) -#define SSD130X_SET_SEG_REMAP_MASK GENMASK(0, 0) -#define SSD130X_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD130X_SET_SEG_REMAP_MASK, (val)) #define SSD130X_SET_COM_SCAN_DIR_MASK GENMASK(3, 3) #define SSD130X_SET_COM_SCAN_DIR_SET(val) FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val)) #define SSD130X_SET_CLOCK_DIV_MASK GENMASK(3, 0) @@ -171,20 +176,20 @@ static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm) } /* - * Helper to write data (SSD130X_DATA) to the device. + * Helper to write data (SSD13XX_DATA) to the device. */ static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count) { - return regmap_bulk_write(ssd130x->regmap, SSD130X_DATA, values, count); + return regmap_bulk_write(ssd130x->regmap, SSD13XX_DATA, values, count); } /* - * Helper to write command (SSD130X_COMMAND). The fist variadic argument + * Helper to write command (SSD13XX_COMMAND). The fist variadic argument * is the command to write and the following are the command options. * - * Note that the ssd130x protocol requires each command and option to be - * written as a SSD130X_COMMAND device register value. That is why a call - * to regmap_write(..., SSD130X_COMMAND, ...) is done for each argument. + * Note that the ssd13xx protocol requires each command and option to be + * written as a SSD13XX_COMMAND device register value. That is why a call + * to regmap_write(..., SSD13XX_COMMAND, ...) is done for each argument. */ static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count, /* u8 cmd, u8 option, ... */...) @@ -197,7 +202,7 @@ static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count, do { value = va_arg(ap, int); - ret = regmap_write(ssd130x->regmap, SSD130X_COMMAND, value); + ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, value); if (ret) goto out_end; } while (--count); @@ -341,13 +346,13 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) int ret; /* Set initial contrast */ - ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CONTRAST, ssd130x->contrast); + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, ssd130x->contrast); if (ret < 0) return ret; /* Set segment re-map */ - seg_remap = (SSD130X_SET_SEG_REMAP | - SSD130X_SET_SEG_REMAP_SET(ssd130x->seg_remap)); + seg_remap = (SSD13XX_SET_SEG_REMAP | + SSD13XX_SET_SEG_REMAP_SET(ssd130x->seg_remap)); ret = ssd130x_write_cmd(ssd130x, 1, seg_remap); if (ret < 0) return ret; @@ -360,7 +365,7 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) return ret; /* Set multiplex ratio value */ - ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_MULTIPLEX_RATIO, ssd130x->height - 1); + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1); if (ret < 0) return ret; @@ -915,7 +920,7 @@ static void ssd130x_encoder_atomic_enable(struct drm_encoder *encoder, if (ret) goto power_off; - ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_ON); + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); backlight_enable(ssd130x->bl_dev); @@ -934,7 +939,7 @@ static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, backlight_disable(ssd130x->bl_dev); - ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_OFF); + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_OFF); ssd130x_power_off(ssd130x); } @@ -1010,7 +1015,7 @@ static int ssd130x_update_bl(struct backlight_device *bdev) ssd130x->contrast = brightness; - ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_CONTRAST); + ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index c562c2d00c16..a5a25e054d2f 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -21,8 +21,8 @@ #include -#define SSD130X_DATA 0x40 -#define SSD130X_COMMAND 0x80 +#define SSD13XX_DATA 0x40 +#define SSD13XX_COMMAND 0x80 enum ssd130x_family_ids { SSD130X_FAMILY -- cgit From fdd591e00a9c9d64a5f1d74779b72218c22bf15d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:06 +0200 Subject: drm/ssd130x: Add support for the SSD132x OLED controller family The Solomon SSD132x controllers (such as the SSD1322, SSD1325 and SSD1327) are used by 16 grayscale dot matrix OLED panels, extend the driver to also support this chip family. Instead adding an indirection level to allow the same modesetting pipeline to be used by both controller families, add another pipeline for SSD132x. This leads to some code duplication but it makes the driver easier to read and reason about. Once other controller families are added (e.g: SSD133x), some common code can be factored out in driver helpers to be shared by the different families. But that can be done later once these patterns emerge. Signed-off-by: Javier Martinez Canillas Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-5-javierm@redhat.com --- drivers/gpu/drm/solomon/Kconfig | 12 +- drivers/gpu/drm/solomon/ssd130x-i2c.c | 17 +- drivers/gpu/drm/solomon/ssd130x-spi.c | 21 +- drivers/gpu/drm/solomon/ssd130x.c | 419 ++++++++++++++++++++++++++++++++-- drivers/gpu/drm/solomon/ssd130x.h | 7 +- 5 files changed, 449 insertions(+), 27 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index e170716d976b..c3ee956c2bb9 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -1,31 +1,31 @@ config DRM_SSD130X - tristate "DRM support for Solomon SSD130x OLED displays" + tristate "DRM support for Solomon SSD13xx OLED displays" depends on DRM && MMU select BACKLIGHT_CLASS_DEVICE select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help - DRM driver for the SSD130x Solomon and SINO WEALTH SH110x OLED + DRM driver for the SSD13xx Solomon and SINO WEALTH SH110x OLED controllers. This is only for the core driver, a driver for the appropriate bus transport in your chip also must be selected. If M is selected the module will be called ssd130x. config DRM_SSD130X_I2C - tristate "DRM support for Solomon SSD130x OLED displays (I2C bus)" + tristate "DRM support for Solomon SSD13xx OLED displays (I2C bus)" depends on DRM_SSD130X && I2C select REGMAP_I2C help - Say Y here if the SSD130x or SH110x OLED display is connected via + Say Y here if the SSD13xx or SH110x OLED display is connected via I2C bus. If M is selected the module will be called ssd130x-i2c. config DRM_SSD130X_SPI - tristate "DRM support for Solomon SSD130X OLED displays (SPI bus)" + tristate "DRM support for Solomon SSD13xx OLED displays (SPI bus)" depends on DRM_SSD130X && SPI select REGMAP help - Say Y here if the SSD130x OLED display is connected via SPI bus. + Say Y here if the SSD13xx OLED display is connected via SPI bus. If M is selected the module will be called ssd130x-spi. diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c index 8f89b89d553f..f2ccab9c06d9 100644 --- a/drivers/gpu/drm/solomon/ssd130x-i2c.c +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130x OLED displays (I2C bus) + * DRM driver for Solomon SSD13xx OLED displays (I2C bus) * * Copyright 2022 Red Hat Inc. * Author: Javier Martinez Canillas @@ -14,7 +14,7 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x-i2c" -#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays (I2C)" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (I2C)" static const struct regmap_config ssd130x_i2c_regmap_config = { .reg_bits = 8, @@ -92,6 +92,19 @@ static const struct of_device_id ssd130x_of_match[] = { .compatible = "solomon,ssd1309fb-i2c", .data = &ssd130x_variants[SSD1309_ID], }, + /* ssd132x family */ + { + .compatible = "solomon,ssd1322", + .data = &ssd130x_variants[SSD1322_ID], + }, + { + .compatible = "solomon,ssd1325", + .data = &ssd130x_variants[SSD1325_ID], + }, + { + .compatible = "solomon,ssd1327", + .data = &ssd130x_variants[SSD1327_ID], + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ssd130x_of_match); diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 89989da705d7..84e035a7ab3f 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130X OLED displays (SPI bus) + * DRM driver for Solomon SSD13xx OLED displays (SPI bus) * * Copyright 2022 Red Hat Inc. * Authors: Javier Martinez Canillas @@ -11,7 +11,7 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x-spi" -#define DRIVER_DESC "DRM driver for Solomon SSD130X OLED displays (SPI)" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (SPI)" struct ssd130x_spi_transport { struct spi_device *spi; @@ -129,6 +129,19 @@ static const struct of_device_id ssd130x_of_match[] = { .compatible = "solomon,ssd1309", .data = &ssd130x_variants[SSD1309_ID], }, + /* ssd132x family */ + { + .compatible = "solomon,ssd1322", + .data = &ssd130x_variants[SSD1322_ID], + }, + { + .compatible = "solomon,ssd1325", + .data = &ssd130x_variants[SSD1325_ID], + }, + { + .compatible = "solomon,ssd1327", + .data = &ssd130x_variants[SSD1327_ID], + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ssd130x_of_match); @@ -149,6 +162,10 @@ static const struct spi_device_id ssd130x_spi_table[] = { { "ssd1306", SSD1306_ID }, { "ssd1307", SSD1307_ID }, { "ssd1309", SSD1309_ID }, + /* ssd132x family */ + { "ssd1322", SSD1322_ID }, + { "ssd1325", SSD1325_ID }, + { "ssd1327", SSD1327_ID }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, ssd130x_spi_table); diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index e11f16bf795e..32f0857aec9f 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130x OLED displays + * DRM driver for Solomon SSD13xx OLED displays * * Copyright 2022 Red Hat Inc. * Author: Javier Martinez Canillas @@ -37,13 +37,15 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x" -#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays" #define DRIVER_DATE "20220131" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 #define SSD130X_PAGE_HEIGHT 8 +#define SSD132X_SEGMENT_WIDTH 2 + /* ssd13xx commands */ #define SSD13XX_CONTRAST 0x81 #define SSD13XX_SET_SEG_REMAP 0xa0 @@ -99,6 +101,24 @@ #define SSD130X_SET_AREA_COLOR_MODE_ENABLE 0x1e #define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER 0x05 +/* ssd132x commands */ +#define SSD132X_SET_COL_RANGE 0x15 +#define SSD132X_SET_DEACTIVATE_SCROLL 0x2e +#define SSD132X_SET_ROW_RANGE 0x75 +#define SSD132X_SET_DISPLAY_START 0xa1 +#define SSD132X_SET_DISPLAY_OFFSET 0xa2 +#define SSD132X_SET_DISPLAY_NORMAL 0xa4 +#define SSD132X_SET_FUNCTION_SELECT_A 0xab +#define SSD132X_SET_PHASE_LENGTH 0xb1 +#define SSD132X_SET_CLOCK_FREQ 0xb3 +#define SSD132X_SET_GPIO 0xb5 +#define SSD132X_SET_PRECHARGE_PERIOD 0xb6 +#define SSD132X_SET_GRAY_SCALE_TABLE 0xb8 +#define SSD132X_SELECT_DEFAULT_TABLE 0xb9 +#define SSD132X_SET_PRECHARGE_VOLTAGE 0xbc +#define SSD130X_SET_VCOMH_VOLTAGE 0xbe +#define SSD132X_SET_FUNCTION_SELECT_B 0xd5 + #define MAX_CONTRAST 255 const struct ssd130x_deviceinfo ssd130x_variants[] = { @@ -144,6 +164,22 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_width = 128, .default_height = 64, .family_id = SSD130X_FAMILY, + }, + /* ssd132x family */ + [SSD1322_ID] = { + .default_width = 480, + .default_height = 128, + .family_id = SSD132X_FAMILY, + }, + [SSD1325_ID] = { + .default_width = 128, + .default_height = 80, + .family_id = SSD132X_FAMILY, + }, + [SSD1327_ID] = { + .default_width = 128, + .default_height = 128, + .family_id = SSD132X_FAMILY, } }; EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); @@ -463,6 +499,96 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) SSD130X_SET_ADDRESS_MODE_HORIZONTAL); } +static int ssd132x_init(struct ssd130x_device *ssd130x) +{ + int ret; + + /* Set initial contrast */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, 0x80); + if (ret < 0) + return ret; + + /* Set column start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, 0x00, + ssd130x->width / SSD132X_SEGMENT_WIDTH - 1); + if (ret < 0) + return ret; + + /* Set row start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, 0x00, ssd130x->height - 1); + if (ret < 0) + return ret; + /* + * Horizontal Address Increment + * Re-map for Column Address, Nibble and COM + * COM Split Odd Even + */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_SEG_REMAP, 0x53); + if (ret < 0) + return ret; + + /* Set display start and offset */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_START, 0x00); + if (ret < 0) + return ret; + + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_OFFSET, 0x00); + if (ret < 0) + return ret; + + /* Set display mode normal */ + ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SET_DISPLAY_NORMAL); + if (ret < 0) + return ret; + + /* Set multiplex ratio value */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1); + if (ret < 0) + return ret; + + /* Set phase length */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PHASE_LENGTH, 0x55); + if (ret < 0) + return ret; + + /* Select default linear gray scale table */ + ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SELECT_DEFAULT_TABLE); + if (ret < 0) + return ret; + + /* Set clock frequency */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_CLOCK_FREQ, 0x01); + if (ret < 0) + return ret; + + /* Enable internal VDD regulator */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_A, 0x1); + if (ret < 0) + return ret; + + /* Set pre-charge period */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_PERIOD, 0x01); + if (ret < 0) + return ret; + + /* Set pre-charge voltage */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_VOLTAGE, 0x08); + if (ret < 0) + return ret; + + /* Set VCOMH voltage */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH_VOLTAGE, 0x07); + if (ret < 0) + return ret; + + /* Enable second pre-charge and internal VSL */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_B, 0x62); + if (ret < 0) + return ret; + + return 0; +} + static int ssd130x_update_rect(struct ssd130x_device *ssd130x, struct drm_rect *rect, u8 *buf, u8 *data_array) @@ -569,6 +695,64 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, return ret; } +static int ssd132x_update_rect(struct ssd130x_device *ssd130x, + struct drm_rect *rect, u8 *buf, + u8 *data_array) +{ + unsigned int x = rect->x1; + unsigned int y = rect->y1; + unsigned int segment_width = SSD132X_SEGMENT_WIDTH; + unsigned int width = drm_rect_width(rect); + unsigned int height = drm_rect_height(rect); + unsigned int columns = DIV_ROUND_UP(width, segment_width); + unsigned int rows = height; + struct drm_device *drm = &ssd130x->drm; + u32 array_idx = 0; + unsigned int i, j; + int ret; + + drm_WARN_ONCE(drm, x % segment_width != 0, "x must be aligned to screen segment\n"); + + /* + * The screen is divided in Segment and Common outputs, where + * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are + * the columns. + * + * Each Segment has a 4-bit pixel and each Common output has a + * row of pixels. When using the (default) horizontal address + * increment mode, each byte of data sent to the controller has + * two Segments (e.g: SEG0 and SEG1) that are stored in the lower + * and higher nibbles of a single byte representing one column. + * That is, the first byte are SEG0 (D0[3:0]) and SEG1 (D0[7:4]), + * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on. + */ + + /* Set column start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, x / segment_width, columns - 1); + if (ret < 0) + return ret; + + /* Set row start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, y, rows - 1); + if (ret < 0) + return ret; + + for (i = 0; i < height; i++) { + /* Process pair of pixels and combine them into a single byte */ + for (j = 0; j < width; j += segment_width) { + u8 n1 = buf[i * width + j]; + u8 n2 = buf[i * width + j + 1]; + + data_array[array_idx++] = (n2 << 4) | n1; + } + } + + /* Write out update in one go since horizontal addressing mode is used */ + ret = ssd130x_write_data(ssd130x, data_array, columns * rows); + + return ret; +} + static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) { unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT); @@ -610,6 +794,17 @@ static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) } } +static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) +{ + unsigned int columns = DIV_ROUND_UP(ssd130x->height, SSD132X_SEGMENT_WIDTH); + unsigned int height = ssd130x->height; + + memset(data_array, 0, columns * height); + + /* Write out update in one go since horizontal addressing mode is used */ + ssd130x_write_data(ssd130x, data_array, columns * height); +} + static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_map *vmap, struct drm_rect *rect, @@ -640,6 +835,35 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, return ret; } +static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb, + const struct iosys_map *vmap, + struct drm_rect *rect, u8 *buf, + u8 *data_array) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); + unsigned int dst_pitch = drm_rect_width(rect); + struct iosys_map dst; + int ret = 0; + + /* Align x to display segment boundaries */ + rect->x1 = round_down(rect->x1, SSD132X_SEGMENT_WIDTH); + rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH), + ssd130x->width); + + ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); + if (ret) + return ret; + + iosys_map_set_vaddr(&dst, buf); + drm_fb_xrgb8888_to_gray8(&dst, &dst_pitch, vmap, fb, rect); + + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); + + ssd132x_update_rect(ssd130x, rect, buf, data_array); + + return ret; +} + static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -678,6 +902,44 @@ static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane, return 0; } +static int ssd132x_primary_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_device *drm = plane->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); + struct drm_crtc *crtc = plane_state->crtc; + struct drm_crtc_state *crtc_state; + const struct drm_format_info *fi; + unsigned int pitch; + int ret; + + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + + ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); + if (ret) + return ret; + else if (!plane_state->visible) + return 0; + + fi = drm_format_info(DRM_FORMAT_R8); + if (!fi) + return -EINVAL; + + pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width); + + ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL); + if (!ssd130x_state->buffer) + return -ENOMEM; + + return 0; +} + static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -712,6 +974,40 @@ static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane, drm_dev_exit(idx); } +static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); + struct ssd130x_crtc_state *ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state); + struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; + struct drm_atomic_helper_damage_iter iter; + struct drm_device *drm = plane->dev; + struct drm_rect dst_clip; + struct drm_rect damage; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); + drm_atomic_for_each_plane_damage(&iter, &damage) { + dst_clip = plane_state->dst; + + if (!drm_rect_intersect(&dst_clip, &damage)) + continue; + + ssd132x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip, + ssd130x_plane_state->buffer, + ssd130x_crtc_state->data_array); + } + + drm_dev_exit(idx); +} + static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -736,6 +1032,30 @@ static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane, drm_dev_exit(idx); } +static void ssd132x_primary_plane_atomic_disable(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_device *drm = plane->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_crtc_state *crtc_state; + struct ssd130x_crtc_state *ssd130x_crtc_state; + int idx; + + if (!plane_state->crtc) + return; + + crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); + ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state); + + if (!drm_dev_enter(drm, &idx)) + return; + + ssd132x_clear_screen(ssd130x, ssd130x_crtc_state->data_array); + + drm_dev_exit(idx); +} + /* Called during init to allocate the plane's atomic state. */ static void ssd130x_primary_plane_reset(struct drm_plane *plane) { @@ -786,11 +1106,19 @@ static void ssd130x_primary_plane_destroy_state(struct drm_plane *plane, kfree(ssd130x_state); } -static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs = { - DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, - .atomic_check = ssd130x_primary_plane_atomic_check, - .atomic_update = ssd130x_primary_plane_atomic_update, - .atomic_disable = ssd130x_primary_plane_atomic_disable, +static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs[] = { + [SSD130X_FAMILY] = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = ssd130x_primary_plane_atomic_check, + .atomic_update = ssd130x_primary_plane_atomic_update, + .atomic_disable = ssd130x_primary_plane_atomic_disable, + }, + [SSD132X_FAMILY] = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = ssd132x_primary_plane_atomic_check, + .atomic_update = ssd132x_primary_plane_atomic_update, + .atomic_disable = ssd132x_primary_plane_atomic_disable, + } }; static const struct drm_plane_funcs ssd130x_primary_plane_funcs = { @@ -839,6 +1167,27 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc, return 0; } +static int ssd132x_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct drm_device *drm = crtc->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state); + unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH); + int ret; + + ret = drm_crtc_helper_atomic_check(crtc, state); + if (ret) + return ret; + + ssd130x_state->data_array = kmalloc(columns * ssd130x->height, GFP_KERNEL); + if (!ssd130x_state->data_array) + return -ENOMEM; + + return 0; +} + /* Called during init to allocate the CRTC's atomic state. */ static void ssd130x_crtc_reset(struct drm_crtc *crtc) { @@ -891,9 +1240,15 @@ static void ssd130x_crtc_destroy_state(struct drm_crtc *crtc, * the primary plane's atomic_update function. Disabling clears * the screen in the primary plane's atomic_disable function. */ -static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs = { - .mode_valid = ssd130x_crtc_mode_valid, - .atomic_check = ssd130x_crtc_atomic_check, +static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs[] = { + [SSD130X_FAMILY] = { + .mode_valid = ssd130x_crtc_mode_valid, + .atomic_check = ssd130x_crtc_atomic_check, + }, + [SSD132X_FAMILY] = { + .mode_valid = ssd130x_crtc_mode_valid, + .atomic_check = ssd132x_crtc_atomic_check, + }, }; static const struct drm_crtc_funcs ssd130x_crtc_funcs = { @@ -931,6 +1286,31 @@ power_off: return; } +static void ssd132x_encoder_atomic_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) +{ + struct drm_device *drm = encoder->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + int ret; + + ret = ssd130x_power_on(ssd130x); + if (ret) + return; + + ret = ssd132x_init(ssd130x); + if (ret) + goto power_off; + + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); + + backlight_enable(ssd130x->bl_dev); + + return; + +power_off: + ssd130x_power_off(ssd130x); +} + static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { @@ -944,9 +1324,15 @@ static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, ssd130x_power_off(ssd130x); } -static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs = { - .atomic_enable = ssd130x_encoder_atomic_enable, - .atomic_disable = ssd130x_encoder_atomic_disable, +static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs[] = { + [SSD130X_FAMILY] = { + .atomic_enable = ssd130x_encoder_atomic_enable, + .atomic_disable = ssd130x_encoder_atomic_disable, + }, + [SSD132X_FAMILY] = { + .atomic_enable = ssd132x_encoder_atomic_enable, + .atomic_disable = ssd130x_encoder_atomic_disable, + } }; static const struct drm_encoder_funcs ssd130x_encoder_funcs = { @@ -1080,6 +1466,7 @@ static void ssd130x_parse_properties(struct ssd130x_device *ssd130x) static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) { + enum ssd130x_family_ids family_id = ssd130x->device_info->family_id; struct drm_display_mode *mode = &ssd130x->mode; struct device *dev = ssd130x->dev; struct drm_device *drm = &ssd130x->drm; @@ -1130,7 +1517,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs); + drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs[family_id]); drm_plane_enable_fb_damage_clips(primary_plane); @@ -1144,7 +1531,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs); + drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs[family_id]); /* Encoder */ @@ -1156,7 +1543,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs); + drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs[family_id]); encoder->possible_crtcs = drm_crtc_mask(crtc); diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index a5a25e054d2f..acf7cedf0c1a 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -25,7 +25,8 @@ #define SSD13XX_COMMAND 0x80 enum ssd130x_family_ids { - SSD130X_FAMILY + SSD130X_FAMILY, + SSD132X_FAMILY }; enum ssd130x_variants { @@ -35,6 +36,10 @@ enum ssd130x_variants { SSD1306_ID, SSD1307_ID, SSD1309_ID, + /* ssd132x family */ + SSD1322_ID, + SSD1325_ID, + SSD1327_ID, NR_SSD130X_VARIANTS }; -- cgit From 53f410d3698fc96eb657b80e1758ba9b71d96628 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:31:57 +0200 Subject: drm/ast: Rename AST_IO_AR_PORT_WRITE to AST_IO_VGAARI_W Rename AST_IO_AR_PORT_WRITE to AST_IO_VGAARI_W to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-2-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 848a9f1403e8..3d64dc356d69 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -259,7 +259,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define IS_AST_GEN6(__ast) __ast_gen_is_eq(__ast, 6) #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7) -#define AST_IO_AR_PORT_WRITE (0x40) +#define AST_IO_VGAARI_W (0x40) #define AST_IO_MISC_PORT_WRITE (0x42) #define AST_IO_VGA_ENABLE_PORT (0x43) #define AST_IO_SEQ_PORT (0x44) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 32f04ec6c386..1ccbfdf27356 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -321,14 +321,14 @@ static void ast_set_std_reg(struct ast_device *ast, jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); for (i = 0; i < 20; i++) { jreg = stdtable->ar[i]; - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAARI_W, (u8)i); + ast_io_write8(ast, AST_IO_VGAARI_W, jreg); } - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x14); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x00); jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x20); /* Set GR */ for (i = 0; i < 9; i++) -- cgit From b3945edd707289191d483c930ab7961c1bd0dc0e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:31:58 +0200 Subject: drm/ast: Rename AST_IO_MISC_PORT_WRITE to AST_IO_VGAMR_W Rename AST_IO_MISC_PORT_WRITE to AST_IO_VGAMR_W to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-3-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_main.c | 2 +- drivers/gpu/drm/ast/ast_mode.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 3d64dc356d69..ff86db3604cd 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -260,7 +260,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7) #define AST_IO_VGAARI_W (0x40) -#define AST_IO_MISC_PORT_WRITE (0x42) +#define AST_IO_VGAMR_W (0x42) #define AST_IO_VGA_ENABLE_PORT (0x43) #define AST_IO_SEQ_PORT (0x44) #define AST_IO_DAC_INDEX_READ (0x47) diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index dae365ed3969..f8a682c4cbd0 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -50,7 +50,7 @@ static void ast_enable_vga(struct drm_device *dev) struct ast_device *ast = to_ast_device(dev); ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01); - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01); + ast_io_write8(ast, AST_IO_VGAMR_W, 0x01); } /* diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 1ccbfdf27356..3f52648c20a0 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -298,7 +298,7 @@ static void ast_set_std_reg(struct ast_device *ast, stdtable = vbios_mode->std_table; jreg = stdtable->misc; - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAMR_W, jreg); /* Set SEQ; except Screen Disable field */ ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03); @@ -537,7 +537,7 @@ static void ast_set_sync_reg(struct ast_device *ast, jreg |= 0x80; if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40; - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAMR_W, jreg); } static void ast_set_start_address_crt1(struct ast_device *ast, -- cgit From ba51b3ed170dabc34a1356c12302d33dc25d83e7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:31:59 +0200 Subject: drm/ast: Rename AST_IO_VGA_ENABLE_PORT to AST_IO_VGAER Rename AST_IO_VGA_ENABLE_PORT to AST_IO_VGAER to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-4-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_main.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index ff86db3604cd..e31ba929f18d 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -261,7 +261,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAARI_W (0x40) #define AST_IO_VGAMR_W (0x42) -#define AST_IO_VGA_ENABLE_PORT (0x43) +#define AST_IO_VGAER (0x43) #define AST_IO_SEQ_PORT (0x44) #define AST_IO_DAC_INDEX_READ (0x47) #define AST_IO_DAC_INDEX_WRITE (0x48) diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index f8a682c4cbd0..7db1f5004454 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -40,7 +40,7 @@ static bool ast_is_vga_enabled(struct drm_device *dev) struct ast_device *ast = to_ast_device(dev); u8 ch; - ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); + ch = ast_io_read8(ast, AST_IO_VGAER); return !!(ch & 0x01); } @@ -49,7 +49,7 @@ static void ast_enable_vga(struct drm_device *dev) { struct ast_device *ast = to_ast_device(dev); - ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01); + ast_io_write8(ast, AST_IO_VGAER, 0x01); ast_io_write8(ast, AST_IO_VGAMR_W, 0x01); } -- cgit From 2a5481e3d35c378bf2523b307e948756f8d3e5de Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:00 +0200 Subject: drm/ast: Rename AST_IO_SEQ_PORT to AST_IO_VGASRI Rename AST_IO_VGA_SEQ_PORT to AST_IO_VGASRI to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-5-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index e31ba929f18d..dc8b4d86ca9a 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -262,7 +262,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAARI_W (0x40) #define AST_IO_VGAMR_W (0x42) #define AST_IO_VGAER (0x43) -#define AST_IO_SEQ_PORT (0x44) +#define AST_IO_VGASRI (0x44) #define AST_IO_DAC_INDEX_READ (0x47) #define AST_IO_DAC_INDEX_WRITE (0x48) #define AST_IO_DAC_DATA (0x49) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 3f52648c20a0..6f8375dd80a3 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -56,13 +56,13 @@ static inline void ast_load_palette_index(struct ast_device *ast, u8 blue) { ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_read8(ast, AST_IO_VGASRI); ast_io_write8(ast, AST_IO_DAC_DATA, red); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_read8(ast, AST_IO_VGASRI); ast_io_write8(ast, AST_IO_DAC_DATA, green); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_read8(ast, AST_IO_VGASRI); ast_io_write8(ast, AST_IO_DAC_DATA, blue); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_read8(ast, AST_IO_VGASRI); } static void ast_crtc_set_gamma_linear(struct ast_device *ast, @@ -301,11 +301,11 @@ static void ast_set_std_reg(struct ast_device *ast, ast_io_write8(ast, AST_IO_VGAMR_W, jreg); /* Set SEQ; except Screen Disable field */ - ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]); + ast_set_index_reg(ast, AST_IO_VGASRI, 0x00, 0x03); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, stdtable->seq[0]); for (i = 1; i < 4; i++) { jreg = stdtable->seq[i]; - ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg); + ast_set_index_reg(ast, AST_IO_VGASRI, (i + 1), jreg); } /* Set CRTC; except base address and offset */ @@ -689,7 +689,7 @@ static void ast_primary_plane_helper_atomic_enable(struct drm_plane *plane, * Therefore only reprogram the address after enabling the plane. */ ast_set_start_address_crt1(ast, (u32)ast_plane->offset); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x00); } static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, @@ -697,7 +697,7 @@ static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, { struct ast_device *ast = to_ast_device(plane->dev); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x20); } static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = { @@ -1014,7 +1014,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) */ switch (mode) { case DRM_MODE_DPMS_ON: - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0); if (ast->tx_chip_types & AST_TX_DP501_BIT) ast_set_dp501_video_output(crtc->dev, 1); @@ -1051,7 +1051,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF); } - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0x20); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x20); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch); break; } -- cgit From 9f662e1edecdadb770e0f1cb8ec1edbc68f62a5f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:01 +0200 Subject: drm/ast: Rename AST_IO_DAC_INDEX_READ to AST_IO_VGADRR Rename AST_IO_DAC_INDEX_READ to AST_IO_VGADRR to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-6-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index dc8b4d86ca9a..ff95b8f088f8 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -263,7 +263,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAMR_W (0x42) #define AST_IO_VGAER (0x43) #define AST_IO_VGASRI (0x44) -#define AST_IO_DAC_INDEX_READ (0x47) +#define AST_IO_VGADRR (0x47) #define AST_IO_DAC_INDEX_WRITE (0x48) #define AST_IO_DAC_DATA (0x49) #define AST_IO_GR_PORT (0x4E) -- cgit From 7b0be4b94b693bc2d32a6f27d534995735bd8c95 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:02 +0200 Subject: drm/ast: Rename AST_IO_DAC_INDEX_WRITE to AST_IO_VGADWR Rename AST_IO_DAC_INDEX_WRITE to AST_IO_VGADWR to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-7-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index ff95b8f088f8..2b46fafd3467 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -264,7 +264,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAER (0x43) #define AST_IO_VGASRI (0x44) #define AST_IO_VGADRR (0x47) -#define AST_IO_DAC_INDEX_WRITE (0x48) +#define AST_IO_VGADWR (0x48) #define AST_IO_DAC_DATA (0x49) #define AST_IO_GR_PORT (0x4E) #define AST_IO_CRTC_PORT (0x54) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 6f8375dd80a3..a719f6c9493d 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -55,7 +55,7 @@ static inline void ast_load_palette_index(struct ast_device *ast, u8 index, u8 red, u8 green, u8 blue) { - ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index); + ast_io_write8(ast, AST_IO_VGADWR, index); ast_io_read8(ast, AST_IO_VGASRI); ast_io_write8(ast, AST_IO_DAC_DATA, red); ast_io_read8(ast, AST_IO_VGASRI); -- cgit From a075e1682fdeffdab80fa1cfb2f5f781f3c7c62a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:03 +0200 Subject: drm/ast: Rename AST_IO_DAC_DATA to AST_IO_VGAPDR Rename AST_IO_DAC_DATA to AST_IO_VGAPDR to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-8-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 2b46fafd3467..43d1861d6262 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -265,7 +265,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGASRI (0x44) #define AST_IO_VGADRR (0x47) #define AST_IO_VGADWR (0x48) -#define AST_IO_DAC_DATA (0x49) +#define AST_IO_VGAPDR (0x49) #define AST_IO_GR_PORT (0x4E) #define AST_IO_CRTC_PORT (0x54) #define AST_IO_INPUT_STATUS1_READ (0x5A) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index a719f6c9493d..fa21cdfd6c4f 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -57,11 +57,11 @@ static inline void ast_load_palette_index(struct ast_device *ast, { ast_io_write8(ast, AST_IO_VGADWR, index); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_DAC_DATA, red); + ast_io_write8(ast, AST_IO_VGAPDR, red); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_DAC_DATA, green); + ast_io_write8(ast, AST_IO_VGAPDR, green); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_DAC_DATA, blue); + ast_io_write8(ast, AST_IO_VGAPDR, blue); ast_io_read8(ast, AST_IO_VGASRI); } -- cgit From 272bfa3a18c5ded5a12068fe0cf041275a00db66 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:04 +0200 Subject: drm/ast: Rename AST_IO_GR_PORT to AST_IO_VGAGRI Rename AST_IO_GR_PORT to AST_IO_VGAGRI to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-9-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 43d1861d6262..86860ab54711 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -266,7 +266,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGADRR (0x47) #define AST_IO_VGADWR (0x48) #define AST_IO_VGAPDR (0x49) -#define AST_IO_GR_PORT (0x4E) +#define AST_IO_VGAGRI (0x4E) #define AST_IO_CRTC_PORT (0x54) #define AST_IO_INPUT_STATUS1_READ (0x5A) #define AST_IO_MISC_PORT_READ (0x4C) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index fa21cdfd6c4f..19dc050d6e81 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -332,7 +332,7 @@ static void ast_set_std_reg(struct ast_device *ast, /* Set GR */ for (i = 0; i < 9; i++) - ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]); + ast_set_index_reg(ast, AST_IO_VGAGRI, i, stdtable->gr[i]); } static void ast_set_crtc_reg(struct ast_device *ast, -- cgit From c79479fa215c56b4bf59add12e1a92ca6310e611 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:05 +0200 Subject: drm/ast: Rename AST_IO_CRTC_PORT to AST_IO_VGACRI Rename AST_IO_CRTC_PORT to AST_IO_VGACRI to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-10-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp.c | 70 +++++++++---------- drivers/gpu/drm/ast/ast_dp501.c | 38 +++++------ drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_i2c.c | 20 +++--- drivers/gpu/drm/ast/ast_main.c | 18 ++--- drivers/gpu/drm/ast/ast_mm.c | 4 +- drivers/gpu/drm/ast/ast_mode.c | 146 ++++++++++++++++++++-------------------- drivers/gpu/drm/ast/ast_post.c | 26 +++---- 8 files changed, 162 insertions(+), 162 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index fdd9a493aa9c..ebb6d8ebd44e 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -9,11 +9,11 @@ bool ast_astdp_is_connected(struct ast_device *ast) { - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING)) return false; - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD)) return false; - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS)) return false; return true; } @@ -29,22 +29,22 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) * CRDF[b0]: DP HPD * CRE5[b0]: Host reading EDID process is done */ - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) { goto err_astdp_edid_not_ready; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, 0x00); for (i = 0; i < 32; i++) { /* * CRE4[7:0]: Read-Pointer for EDID (Unit: 4bytes); valid range: 0~64 */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE4, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE4, ASTDP_AND_CLEAR_MASK, (u8)i); j = 0; @@ -52,9 +52,9 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) * CRD7[b0]: valid flag for EDID * CRD6[b0]: mirror read pointer for EDID */ - while ((ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD7, + while ((ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD7, ASTDP_EDID_VALID_FLAG_MASK) != 0x01) || - (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD6, + (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD6, ASTDP_EDID_READ_POINTER_MASK) != i)) { /* * Delay are getting longer with each retry. @@ -64,11 +64,11 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) */ mdelay(j+1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) { + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD))) { goto err_astdp_jump_out_loop_of_edid; } @@ -77,13 +77,13 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) goto err_astdp_jump_out_loop_of_edid; } - *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, + *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD8, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD9, + *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD9, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDA, + *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDA, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDB, + *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDB, ASTDP_EDID_READ_DATA_MASK); if (i == 31) { @@ -103,25 +103,25 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) ediddata += 4; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); return 0; err_astdp_jump_out_loop_of_edid: - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); return (~(j+256) + 1); err_astdp_edid_not_ready: - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING))) return (~0xD1 + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS))) return (~0xDC + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD))) return (~0xDF + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) return (~0xE5 + 1); return 0; @@ -137,7 +137,7 @@ void ast_dp_launch(struct drm_device *dev) struct ast_device *ast = to_ast_device(dev); // Wait one second then timeout. - while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) != + while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) != ASTDP_MCU_FW_EXECUTING) { i++; // wait 100 ms @@ -153,7 +153,7 @@ void ast_dp_launch(struct drm_device *dev) if (!bDPExecute) drm_err(dev, "Wait DPMCU executing timeout\n"); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); } @@ -164,14 +164,14 @@ void ast_dp_power_on_off(struct drm_device *dev, bool on) { struct ast_device *ast = to_ast_device(dev); // Read and Turn off DP PHY sleep - u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, AST_DP_VIDEO_ENABLE); + u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, AST_DP_VIDEO_ENABLE); // Turn on DP PHY sleep if (!on) bE3 |= AST_DP_PHY_SLEEP; // DP Power on/off - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3); } @@ -182,13 +182,13 @@ void ast_dp_set_on_off(struct drm_device *dev, bool on) u8 video_on_off = on; // Video On/Off - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); // If DP plug in and link successful then check video on / off status - if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) { + if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD)) { video_on_off <<= 4; - while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, + while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) { // wait 1 ms mdelay(1); @@ -264,8 +264,8 @@ void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mo * CRE1[7:0]: MISC1 (default: 0x00) * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE0, ASTDP_AND_CLEAR_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE0, ASTDP_AND_CLEAR_MASK, ASTDP_MISC0_24bpp); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx); } diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index f10d53b0c94f..9a4c3a0963f9 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -31,17 +31,17 @@ static int ast_load_dp501_microcode(struct drm_device *dev) static void send_ack(struct ast_device *ast) { u8 sendack; - sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); + sendack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0xff); sendack |= 0x80; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0x00, sendack); } static void send_nack(struct ast_device *ast) { u8 sendack; - sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); + sendack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0xff); sendack &= ~0x80; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0x00, sendack); } static bool wait_ack(struct ast_device *ast) @@ -49,7 +49,7 @@ static bool wait_ack(struct ast_device *ast) u8 waitack; u32 retry = 0; do { - waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitack &= 0x80; udelay(100); } while ((!waitack) && (retry++ < 1000)); @@ -65,7 +65,7 @@ static bool wait_nack(struct ast_device *ast) u8 waitack; u32 retry = 0; do { - waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitack &= 0x80; udelay(100); } while ((waitack) && (retry++ < 1000)); @@ -78,12 +78,12 @@ static bool wait_nack(struct ast_device *ast) static void set_cmd_trigger(struct ast_device *ast) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, ~0x40, 0x40); } static void clear_cmd_trigger(struct ast_device *ast) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, ~0x40, 0x00); } #if 0 @@ -92,7 +92,7 @@ static bool wait_fw_ready(struct ast_device *ast) u8 waitready; u32 retry = 0; do { - waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitready = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitready &= 0x40; udelay(100); } while ((!waitready) && (retry++ < 1000)); @@ -110,7 +110,7 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data) int retry = 0; if (wait_nack(ast)) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); send_ack(ast); set_cmd_trigger(ast); do { @@ -132,7 +132,7 @@ static bool ast_write_data(struct drm_device *dev, u8 data) if (wait_nack(ast)) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); send_ack(ast); if (wait_ack(ast)) { send_nack(ast); @@ -153,7 +153,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data) if (wait_ack(ast) == false) return false; - tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff); + tmp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd3, 0xff); *data = tmp; if (wait_nack(ast) == false) { send_nack(ast); @@ -166,7 +166,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data) static void clear_cmd(struct ast_device *ast) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, 0x00); } #endif @@ -265,9 +265,9 @@ static bool ast_launch_m68k(struct drm_device *dev) data |= 0x800; ast_moutdwm(ast, 0x1e6e2040, data); - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */ + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */ jreg |= 0x02; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x99, jreg); } return true; } @@ -354,7 +354,7 @@ static bool ast_init_dvo(struct drm_device *dev) ast_write32(ast, 0xf000, 0x1); ast_write32(ast, 0x12000, 0x1688a8a8); - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if (!(jreg & 0x80)) { /* Init SCU DVO Settings */ data = ast_read32(ast, 0x12008); @@ -413,7 +413,7 @@ static bool ast_init_dvo(struct drm_device *dev) ast_write32(ast, 0x1202c, data); /* Init VGA DVO Settings */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); return true; } @@ -442,7 +442,7 @@ static void ast_init_analog(struct drm_device *dev) ast_write32(ast, 0, data); /* Disable DVO */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x00); } void ast_init_3rdtx(struct drm_device *dev) @@ -451,7 +451,7 @@ void ast_init_3rdtx(struct drm_device *dev) u8 jreg; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) { - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); switch (jreg & 0x0e) { case 0x04: ast_init_dvo(dev); diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 86860ab54711..a8bcb1903294 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -267,7 +267,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGADWR (0x48) #define AST_IO_VGAPDR (0x49) #define AST_IO_VGAGRI (0x4E) -#define AST_IO_CRTC_PORT (0x54) +#define AST_IO_VGACRI (0x54) #define AST_IO_INPUT_STATUS1_READ (0x5A) #define AST_IO_MISC_PORT_READ (0x4C) diff --git a/drivers/gpu/drm/ast/ast_i2c.c b/drivers/gpu/drm/ast/ast_i2c.c index d64045c0b849..0e845e7acd9b 100644 --- a/drivers/gpu/drm/ast/ast_i2c.c +++ b/drivers/gpu/drm/ast/ast_i2c.c @@ -35,8 +35,8 @@ static void ast_i2c_setsda(void *i2c_priv, int data) for (i = 0; i < 0x10000; i++) { ujcrb7 = ((data & 0x01) ? 0 : 1) << 2; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf1, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x04); if (ujcrb7 == jtemp) break; } @@ -51,8 +51,8 @@ static void ast_i2c_setscl(void *i2c_priv, int clock) for (i = 0; i < 0x10000; i++) { ujcrb7 = ((clock & 0x01) ? 0 : 1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf4, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x01); if (ujcrb7 == jtemp) break; } @@ -66,14 +66,14 @@ static int ast_i2c_getsda(void *i2c_priv) count = 0; pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; do { - val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val2 = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; if (val == val2) { pass++; } else { pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; } } while ((pass < 5) && (count++ < 0x10000)); @@ -88,14 +88,14 @@ static int ast_i2c_getscl(void *i2c_priv) count = 0; pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; do { - val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val2 = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; if (val == val2) { pass++; } else { pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; } } while ((pass < 5) && (count++ < 0x10000)); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 7db1f5004454..f4ab40e22cea 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -62,21 +62,21 @@ static void ast_enable_mmio_release(void *data) struct ast_device *ast = data; /* enable standard VGA decode */ - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x04); } static int ast_enable_mmio(struct ast_device *ast) { struct drm_device *dev = &ast->base; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); return devm_add_action_or_reset(dev->dev, ast_enable_mmio_release, ast); } static void ast_open_key(struct ast_device *ast) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x80, 0xA8); } static int ast_device_config_init(struct ast_device *ast) @@ -105,8 +105,8 @@ static int ast_device_config_init(struct ast_device *ast) * is disabled. We force using P2A if VGA only mode bit * is set D[7] */ - jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); - jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jregd0 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); + jregd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) { /* @@ -219,7 +219,7 @@ static void ast_detect_widescreen(struct ast_device *ast) ast->support_wide_screen = false; break; default: - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if (!(jreg & 0x80)) ast->support_wide_screen = true; else if (jreg & 0x01) @@ -256,7 +256,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) * SIL164 when there is none. */ if (!need_post) { - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xff); if (jreg & 0x80) ast->tx_chip_types = AST_TX_SIL164_BIT; } @@ -267,7 +267,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) * the SOC scratch register #1 bits 11:8 (interestingly marked * as "reserved" in the spec) */ - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); switch (jreg) { case 0x04: ast->tx_chip_types = AST_TX_SIL164_BIT; @@ -286,7 +286,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) ast->tx_chip_types = AST_TX_DP501_BIT; } } else if (IS_AST_GEN7(ast)) { - if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK) == + if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, TX_TYPE_MASK) == ASTDP_DPMCU_TX) { ast->tx_chip_types = AST_TX_ASTDP_BIT; ast_dp_launch(&ast->base); diff --git a/drivers/gpu/drm/ast/ast_mm.c b/drivers/gpu/drm/ast/ast_mm.c index bc174bd933b9..6dfe6d9777d4 100644 --- a/drivers/gpu/drm/ast/ast_mm.c +++ b/drivers/gpu/drm/ast/ast_mm.c @@ -39,7 +39,7 @@ static u32 ast_get_vram_size(struct ast_device *ast) u32 vram_size; vram_size = AST_VIDMEM_DEFAULT_SIZE; - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xaa, 0xff); switch (jreg & 3) { case 0: vram_size = AST_VIDMEM_SIZE_8M; @@ -55,7 +55,7 @@ static u32 ast_get_vram_size(struct ast_device *ast) break; } - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x99, 0xff); switch (jreg & 0x03) { case 1: vram_size -= 0x100000; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 19dc050d6e81..c4381342af04 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -253,13 +253,13 @@ static void ast_set_vbios_color_reg(struct ast_device *ast, return; } - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8c, (u8)((color_index & 0x0f) << 4)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0x00); if (vbios_mode->enh_table->flags & NewModeInfo) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0xa8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x92, format->cpp[0] * 8); } } @@ -272,18 +272,18 @@ static void ast_set_vbios_mode_reg(struct ast_device *ast, refresh_rate_index = vbios_mode->enh_table->refresh_rate_index; mode_id = vbios_mode->enh_table->mode_id; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8d, refresh_rate_index & 0xff); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8e, mode_id & 0xff); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0x00); if (vbios_mode->enh_table->flags & NewModeInfo) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0xa8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x93, adjusted_mode->clock / 1000); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x94, adjusted_mode->crtc_hdisplay); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x95, adjusted_mode->crtc_hdisplay >> 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x96, adjusted_mode->crtc_vdisplay); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x97, adjusted_mode->crtc_vdisplay >> 8); } } @@ -309,13 +309,13 @@ static void ast_set_std_reg(struct ast_device *ast, } /* Set CRTC; except base address and offset */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00); for (i = 0; i < 12; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); for (i = 14; i < 19; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); for (i = 20; i < 25; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); /* set AR */ jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); @@ -346,48 +346,48 @@ static void ast_set_crtc_reg(struct ast_device *ast, (vbios_mode->enh_table->flags & AST2500PreCatchCRT)) precache = 40; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00); temp = (mode->crtc_htotal >> 3) - 5; if (temp & 0x100) jregAC |= 0x01; /* HT D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x00, 0x00, temp); temp = (mode->crtc_hdisplay >> 3) - 1; if (temp & 0x100) jregAC |= 0x04; /* HDE D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x01, 0x00, temp); temp = (mode->crtc_hblank_start >> 3) - 1; if (temp & 0x100) jregAC |= 0x10; /* HBS D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x02, 0x00, temp); temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f; if (temp & 0x20) jreg05 |= 0x80; /* HBE D[5] */ if (temp & 0x40) jregAD |= 0x01; /* HBE D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x03, 0xE0, (temp & 0x1f)); temp = ((mode->crtc_hsync_start-precache) >> 3) - 1; if (temp & 0x100) jregAC |= 0x40; /* HRS D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x04, 0x00, temp); temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f; if (temp & 0x20) jregAD |= 0x04; /* HRE D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAC, 0x00, jregAC); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAD, 0x00, jregAD); // Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels); if (IS_AST_GEN7(ast) && (mode->crtc_vdisplay == 1080)) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x02); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x02); else - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x00); /* vert timings */ temp = (mode->crtc_vtotal) - 2; @@ -397,7 +397,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x20; if (temp & 0x400) jregAE |= 0x01; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x06, 0x00, temp); temp = (mode->crtc_vsync_start) - 1; if (temp & 0x100) @@ -406,14 +406,14 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x80; if (temp & 0x400) jregAE |= 0x08; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x10, 0x00, temp); temp = (mode->crtc_vsync_end - 1) & 0x3f; if (temp & 0x10) jregAE |= 0x20; if (temp & 0x20) jregAE |= 0x40; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x70, temp & 0xf); temp = mode->crtc_vdisplay - 1; if (temp & 0x100) @@ -422,7 +422,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x40; if (temp & 0x400) jregAE |= 0x02; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x12, 0x00, temp); temp = mode->crtc_vblank_start - 1; if (temp & 0x100) @@ -431,23 +431,23 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg09 |= 0x20; if (temp & 0x400) jregAE |= 0x04; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x15, 0x00, temp); temp = mode->crtc_vblank_end - 1; if (temp & 0x100) jregAE |= 0x10; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x16, 0x00, temp); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x07, 0x00, jreg07); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x09, 0xdf, jreg09); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAE, 0x00, (jregAE | 0x80)); if (precache) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x80); else - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x00); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x80); } static void ast_set_offset_reg(struct ast_device *ast, @@ -456,8 +456,8 @@ static void ast_set_offset_reg(struct ast_device *ast, u16 offset; offset = fb->pitches[0] >> 3; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x13, (offset & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xb0, (offset >> 8) & 0x3f); } static void ast_set_dclk_reg(struct ast_device *ast, @@ -471,9 +471,9 @@ static void ast_set_dclk_reg(struct ast_device *ast, else clk_info = &dclk_table[vbios_mode->enh_table->dclk_index]; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc0, 0x00, clk_info->param1); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc1, 0x00, clk_info->param2); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xbb, 0x0f, (clk_info->param3 & 0xc0) | ((clk_info->param3 & 0x3) << 4)); } @@ -502,26 +502,26 @@ static void ast_set_color_reg(struct ast_device *ast, break; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa0, 0x8f, jregA0); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xf0, jregA3); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa8, 0xfd, jregA8); } static void ast_set_crtthd_reg(struct ast_device *ast) { /* Set Threshold */ if (IS_AST_GEN7(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0xe0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0xa0); } else if (IS_AST_GEN6(ast) || IS_AST_GEN5(ast) || IS_AST_GEN4(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x78); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x60); } else if (IS_AST_GEN3(ast) || IS_AST_GEN2(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x3f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x2f); } else { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x2f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x1f); } } @@ -546,9 +546,9 @@ static void ast_set_start_address_crt1(struct ast_device *ast, u32 addr; addr = offset >> 2; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x0d, (u8)(addr & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x0c, (u8)((addr >> 8) & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xaf, (u8)((addr >> 16) & 0xff)); } @@ -814,9 +814,9 @@ static void ast_set_cursor_base(struct ast_device *ast, u64 address) u8 addr1 = (address >> 11) & 0xff; u8 addr2 = (address >> 19) & 0xff; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc8, addr0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc9, addr1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xca, addr2); } static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y, @@ -827,12 +827,12 @@ static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y, u8 y0 = (y & 0x00ff); u8 y1 = (y & 0x0700) >> 8; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc2, x_offset); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc3, y_offset); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc4, x0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc5, x1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc6, y0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc7, y1); } static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled) @@ -845,7 +845,7 @@ static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled) if (enabled) vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xcb, mask, vgacrcb); } static const uint32_t ast_cursor_plane_formats[] = { @@ -1015,7 +1015,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) switch (mode) { case DRM_MODE_DPMS_ON: ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0); if (ast->tx_chip_types & AST_TX_DP501_BIT) ast_set_dp501_video_output(crtc->dev, 1); @@ -1052,7 +1052,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) } ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x20); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, ch); break; } } @@ -1086,7 +1086,7 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode return MODE_OK; if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); if (jtemp & 0x01) return MODE_NOMODE; else @@ -1219,7 +1219,7 @@ static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atom struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 13e15173f2c5..7a993a384314 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -49,7 +49,7 @@ ast_set_def_ext_reg(struct drm_device *dev) /* reset scratch */ for (i = 0x81; i <= 0x9f; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00); if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast)) ext_reg_info = extreginfo_ast2300; @@ -58,23 +58,23 @@ ast_set_def_ext_reg(struct drm_device *dev) index = 0xa0; while (*ext_reg_info != 0xff) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info); index++; ext_reg_info++; } /* disable standard IO/MEM decode if secondary */ - /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */ + /* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */ /* Set Ext. Default */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00); /* Enable RAMDAC for A1 */ reg = 0x04; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast)) reg |= 0x20; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg); } u32 ast_mindwm(struct ast_device *ast, u32 r) @@ -245,7 +245,7 @@ static void ast_init_dram_reg(struct drm_device *dev) u32 data, temp, i; const struct ast_dramstruct *dram_reg_info; - j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((j & 0x80) == 0) { /* VGA only */ if (IS_AST_GEN1(ast)) { @@ -325,7 +325,7 @@ static void ast_init_dram_reg(struct drm_device *dev) /* wait ready */ do { - j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((j & 0x40) == 0); } @@ -349,7 +349,7 @@ void ast_post_gpu(struct drm_device *dev) ast_init_3rdtx(dev); } else { if (ast->tx_chip_types & AST_TX_SIL164_BIT) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */ + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); /* Enable DVO */ } } @@ -1562,7 +1562,7 @@ static void ast_post_chip_2300(struct drm_device *dev) u32 temp; u8 reg; - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((reg & 0x80) == 0) {/* vga only */ ast_write32(ast, 0xf004, 0x1e6e0000); ast_write32(ast, 0xf000, 0x1); @@ -1634,7 +1634,7 @@ static void ast_post_chip_2300(struct drm_device *dev) /* wait ready */ do { - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((reg & 0x40) == 0); } @@ -2027,7 +2027,7 @@ void ast_post_chip_2500(struct drm_device *dev) u32 temp; u8 reg; - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */ /* Clear bus lock condition */ ast_patch_ahb_2500(ast); @@ -2075,6 +2075,6 @@ void ast_post_chip_2500(struct drm_device *dev) /* wait ready */ do { - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((reg & 0x40) == 0); } -- cgit From 224bf236ca6d6d49e559565c5eba65f7acc6bbd9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:06 +0200 Subject: drm/ast: Rename AST_IO_INPUT_STATUS1_READ to AST_IO_VGAIR1_R Rename AST_IO_INPUT_STATUS1_READ to AST_IO_VGAIR1_R to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-11-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index a8bcb1903294..03f1edf95e73 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -268,7 +268,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAPDR (0x49) #define AST_IO_VGAGRI (0x4E) #define AST_IO_VGACRI (0x54) -#define AST_IO_INPUT_STATUS1_READ (0x5A) +#define AST_IO_VGAIR1_R (0x5A) #define AST_IO_MISC_PORT_READ (0x4C) #define AST_IO_MM_OFFSET (0x380) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index c4381342af04..289e32227f6b 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -318,7 +318,7 @@ static void ast_set_std_reg(struct ast_device *ast, ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); /* set AR */ - jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); + jreg = ast_io_read8(ast, AST_IO_VGAIR1_R); for (i = 0; i < 20; i++) { jreg = stdtable->ar[i]; ast_io_write8(ast, AST_IO_VGAARI_W, (u8)i); @@ -327,7 +327,7 @@ static void ast_set_std_reg(struct ast_device *ast, ast_io_write8(ast, AST_IO_VGAARI_W, 0x14); ast_io_write8(ast, AST_IO_VGAARI_W, 0x00); - jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); + jreg = ast_io_read8(ast, AST_IO_VGAIR1_R); ast_io_write8(ast, AST_IO_VGAARI_W, 0x20); /* Set GR */ @@ -558,7 +558,7 @@ static void ast_wait_for_vretrace(struct ast_device *ast) u8 vgair1; do { - vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); + vgair1 = ast_io_read8(ast, AST_IO_VGAIR1_R); } while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout)); } -- cgit From 8811bcbf28cc270aba8d0067bdb8f44c5cc5fad7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:07 +0200 Subject: drm/ast: Rename AST_IO_MISC_PORT_READ to AST_IO_VGAMR_R Rename AST_IO_MISC_PORT_READ to AST_IO_VGAMR_R to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-12-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 03f1edf95e73..214bfac0798a 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -269,7 +269,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAGRI (0x4E) #define AST_IO_VGACRI (0x54) #define AST_IO_VGAIR1_R (0x5A) -#define AST_IO_MISC_PORT_READ (0x4C) +#define AST_IO_VGAMR_R (0x4C) #define AST_IO_MM_OFFSET (0x380) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 289e32227f6b..cb9614984285 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -531,7 +531,7 @@ static void ast_set_sync_reg(struct ast_device *ast, { u8 jreg; - jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ); + jreg = ast_io_read8(ast, AST_IO_VGAMR_R); jreg &= ~0xC0; if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80; -- cgit From 6c73f1dbd9bf91130c2ee0b9c65afb7c3c90bf23 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:08 +0200 Subject: drm/ast: Move register constants to ast_reg.h Improve readability by putting all register constants into a separate header file. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-13-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 83 +----------------------------------- drivers/gpu/drm/ast/ast_reg.h | 99 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 81 deletions(-) create mode 100644 drivers/gpu/drm/ast/ast_reg.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 214bfac0798a..2aee32344f4a 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -39,6 +39,8 @@ #include #include +#include "ast_reg.h" + #define DRIVER_AUTHOR "Dave Airlie" #define DRIVER_NAME "ast" @@ -259,25 +261,6 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define IS_AST_GEN6(__ast) __ast_gen_is_eq(__ast, 6) #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7) -#define AST_IO_VGAARI_W (0x40) -#define AST_IO_VGAMR_W (0x42) -#define AST_IO_VGAER (0x43) -#define AST_IO_VGASRI (0x44) -#define AST_IO_VGADRR (0x47) -#define AST_IO_VGADWR (0x48) -#define AST_IO_VGAPDR (0x49) -#define AST_IO_VGAGRI (0x4E) -#define AST_IO_VGACRI (0x54) -#define AST_IO_VGAIR1_R (0x5A) -#define AST_IO_VGAMR_R (0x4C) - -#define AST_IO_MM_OFFSET (0x380) - -#define AST_IO_VGAIR1_VREFRESH BIT(3) - -#define AST_IO_VGACRCB_HWC_ENABLED BIT(1) -#define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ - static inline u32 ast_read32(struct ast_device *ast, u32 reg) { return ioread32(ast->regs + reg); @@ -399,71 +382,9 @@ int ast_mode_config_init(struct ast_device *ast); #define AST_DP501_LINKRATE 0xf014 #define AST_DP501_EDID_DATA 0xf020 -/* - * Display Transmitter Type: - */ -#define TX_TYPE_MASK GENMASK(3, 1) -#define NO_TX (0 << 1) -#define ITE66121_VBIOS_TX (1 << 1) -#define SI164_VBIOS_TX (2 << 1) -#define CH7003_VBIOS_TX (3 << 1) -#define DP501_VBIOS_TX (4 << 1) -#define ANX9807_VBIOS_TX (5 << 1) -#define TX_FW_EMBEDDED_FW_TX (6 << 1) -#define ASTDP_DPMCU_TX (7 << 1) - -#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) -//#define AST_VRAM_INIT_BY_BMC BIT(7) -//#define AST_VRAM_INIT_READY BIT(6) - -/* Define for Soc scratched reg used on ASTDP */ -#define AST_DP_PHY_SLEEP BIT(4) -#define AST_DP_VIDEO_ENABLE BIT(0) - #define AST_DP_POWER_ON true #define AST_DP_POWER_OFF false -/* - * CRD1[b5]: DP MCU FW is executing - * CRDC[b0]: DP link success - * CRDF[b0]: DP HPD - * CRE5[b0]: Host reading EDID process is done - */ -#define ASTDP_MCU_FW_EXECUTING BIT(5) -#define ASTDP_LINK_SUCCESS BIT(0) -#define ASTDP_HPD BIT(0) -#define ASTDP_HOST_EDID_READ_DONE BIT(0) -#define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0) - -/* - * CRB8[b1]: Enable VSYNC off - * CRB8[b0]: Enable HSYNC off - */ -#define AST_DPMS_VSYNC_OFF BIT(1) -#define AST_DPMS_HSYNC_OFF BIT(0) - -/* - * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE - * Precondition: A. ~AST_DP_PHY_SLEEP && - * B. DP_HPD && - * C. DP_LINK_SUCCESS - */ -#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4) - -#define ASTDP_EDID_READ_POINTER_MASK GENMASK(7, 0) -#define ASTDP_EDID_VALID_FLAG_MASK GENMASK(0, 0) -#define ASTDP_EDID_READ_DATA_MASK GENMASK(7, 0) - -/* - * ASTDP setmode registers: - * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp) - * CRE1[7:0]: MISC1 (default: 0x00) - * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) - */ -#define ASTDP_MISC0_24bpp BIT(5) -#define ASTDP_MISC1 0 -#define ASTDP_AND_CLEAR_MASK 0x00 - /* * ASTDP resoultion table: * EX: ASTDP_A_B_C: diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h new file mode 100644 index 000000000000..555286ecf520 --- /dev/null +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef __AST_REG_H__ +#define __AST_REG_H__ + +#include + +/* + * Modesetting + */ + +#define AST_IO_MM_OFFSET (0x380) + +#define AST_IO_VGAARI_W (0x40) +#define AST_IO_VGAMR_W (0x42) +#define AST_IO_VGAER (0x43) +#define AST_IO_VGASRI (0x44) +#define AST_IO_VGADRR (0x47) +#define AST_IO_VGADWR (0x48) +#define AST_IO_VGAPDR (0x49) +#define AST_IO_VGAGRI (0x4E) + +#define AST_IO_VGACRI (0x54) +#define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ +#define AST_IO_VGACRCB_HWC_ENABLED BIT(1) + +#define AST_IO_VGAIR1_R (0x5A) +#define AST_IO_VGAIR1_VREFRESH BIT(3) + +#define AST_IO_VGAMR_R (0x4C) + +/* + * Display Transmitter Type + */ + +#define TX_TYPE_MASK GENMASK(3, 1) +#define NO_TX (0 << 1) +#define ITE66121_VBIOS_TX (1 << 1) +#define SI164_VBIOS_TX (2 << 1) +#define CH7003_VBIOS_TX (3 << 1) +#define DP501_VBIOS_TX (4 << 1) +#define ANX9807_VBIOS_TX (5 << 1) +#define TX_FW_EMBEDDED_FW_TX (6 << 1) +#define ASTDP_DPMCU_TX (7 << 1) + +#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) +//#define AST_VRAM_INIT_BY_BMC BIT(7) +//#define AST_VRAM_INIT_READY BIT(6) + +/* + * AST DisplayPort + */ + +/* Define for Soc scratched reg used on ASTDP */ +#define AST_DP_PHY_SLEEP BIT(4) +#define AST_DP_VIDEO_ENABLE BIT(0) + +/* + * CRD1[b5]: DP MCU FW is executing + * CRDC[b0]: DP link success + * CRDF[b0]: DP HPD + * CRE5[b0]: Host reading EDID process is done + */ +#define ASTDP_MCU_FW_EXECUTING BIT(5) +#define ASTDP_LINK_SUCCESS BIT(0) +#define ASTDP_HPD BIT(0) +#define ASTDP_HOST_EDID_READ_DONE BIT(0) +#define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0) + +/* + * CRB8[b1]: Enable VSYNC off + * CRB8[b0]: Enable HSYNC off + */ +#define AST_DPMS_VSYNC_OFF BIT(1) +#define AST_DPMS_HSYNC_OFF BIT(0) + +/* + * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE + * Precondition: A. ~AST_DP_PHY_SLEEP && + * B. DP_HPD && + * C. DP_LINK_SUCCESS + */ +#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4) + +#define ASTDP_EDID_READ_POINTER_MASK GENMASK(7, 0) +#define ASTDP_EDID_VALID_FLAG_MASK GENMASK(0, 0) +#define ASTDP_EDID_READ_DATA_MASK GENMASK(7, 0) + +/* + * ASTDP setmode registers: + * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp) + * CRE1[7:0]: MISC1 (default: 0x00) + * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) + */ +#define ASTDP_MISC0_24bpp BIT(5) +#define ASTDP_MISC1 0 +#define ASTDP_AND_CLEAR_MASK 0x00 + +#endif -- cgit From e2450d32e5fb5f89bf93e52f4ce694ad655cdc66 Mon Sep 17 00:00:00 2001 From: Cong Yang Date: Fri, 13 Oct 2023 17:18:42 +0800 Subject: drm/panel: ili9882t: Break out as separate driver The Starry ILI9882t-based panel should never have been part of the boe tv101wum driver, it is clearly based on the Ilitek ILI9882t display controller and if you look at the custom command sequences for the panel these clearly contain the signature Ilitek page switch (0xff) commands. The hardware has nothing in common with the other panels supported by this driver. Break this out into a separate driver and config symbol instead. If the placement here is out of convenience for using similar code, we should consider creating a helper library instead. Co-developed-by: Linus Walleij Signed-off-by: Linus Walleij Reviewed-by: Linus Walleij Reviewed-by: Douglas Anderson Signed-off-by: Cong Yang Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20231013091844.804310-2-yangcong5@huaqin.corp-partner.google.com --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 371 ------------ drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 759 +++++++++++++++++++++++++ 4 files changed, 769 insertions(+), 371 deletions(-) create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index ecb22ea326cb..99e14dc212ec 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -203,6 +203,15 @@ config DRM_PANEL_ILITEK_ILI9881C Say Y if you want to enable support for panels based on the Ilitek ILI9881c controller. +config DRM_PANEL_ILITEK_ILI9882T + tristate "Ilitek ILI9882t-based panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y if you want to enable support for panels based on the + Ilitek ILI9882t controller. + config DRM_PANEL_INNOLUX_EJ030NA tristate "Innolux EJ030NA 320x480 LCD panel" depends on OF && SPI diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index e14ce55a0875..d10c3de51c6d 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9882T) += panel-ilitek-ili9882t.o obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o obj-$(CONFIG_DRM_PANEL_JADARD_JD9365DA_H3) += panel-jadard-jd9365da-h3.o diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index 5ac926281d2c..4f370bc6dca8 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -1370,346 +1370,6 @@ static const struct panel_init_cmd starry_himax83102_j02_init_cmd[] = { {}, }; -static const struct panel_init_cmd starry_ili9882t_init_cmd[] = { - _INIT_DELAY_CMD(5), - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x01), - _INIT_DCS_CMD(0x00, 0x42), - _INIT_DCS_CMD(0x01, 0x11), - _INIT_DCS_CMD(0x02, 0x00), - _INIT_DCS_CMD(0x03, 0x00), - - _INIT_DCS_CMD(0x04, 0x01), - _INIT_DCS_CMD(0x05, 0x11), - _INIT_DCS_CMD(0x06, 0x00), - _INIT_DCS_CMD(0x07, 0x00), - - _INIT_DCS_CMD(0x08, 0x80), - _INIT_DCS_CMD(0x09, 0x81), - _INIT_DCS_CMD(0x0A, 0x71), - _INIT_DCS_CMD(0x0B, 0x00), - - _INIT_DCS_CMD(0x0C, 0x00), - _INIT_DCS_CMD(0x0E, 0x1A), - - _INIT_DCS_CMD(0x24, 0x00), - _INIT_DCS_CMD(0x25, 0x00), - _INIT_DCS_CMD(0x26, 0x00), - _INIT_DCS_CMD(0x27, 0x00), - - _INIT_DCS_CMD(0x2C, 0xD4), - _INIT_DCS_CMD(0xB9, 0x40), - - _INIT_DCS_CMD(0xB0, 0x11), - - _INIT_DCS_CMD(0xE6, 0x32), - _INIT_DCS_CMD(0xD1, 0x30), - - _INIT_DCS_CMD(0xD6, 0x55), - - _INIT_DCS_CMD(0xD0, 0x01), - _INIT_DCS_CMD(0xE3, 0x93), - _INIT_DCS_CMD(0xE4, 0x00), - _INIT_DCS_CMD(0xE5, 0x80), - - _INIT_DCS_CMD(0x31, 0x07), - _INIT_DCS_CMD(0x32, 0x07), - _INIT_DCS_CMD(0x33, 0x07), - _INIT_DCS_CMD(0x34, 0x07), - _INIT_DCS_CMD(0x35, 0x07), - _INIT_DCS_CMD(0x36, 0x01), - _INIT_DCS_CMD(0x37, 0x00), - _INIT_DCS_CMD(0x38, 0x28), - _INIT_DCS_CMD(0x39, 0x29), - _INIT_DCS_CMD(0x3A, 0x11), - _INIT_DCS_CMD(0x3B, 0x13), - _INIT_DCS_CMD(0x3C, 0x15), - _INIT_DCS_CMD(0x3D, 0x17), - _INIT_DCS_CMD(0x3E, 0x09), - _INIT_DCS_CMD(0x3F, 0x0D), - _INIT_DCS_CMD(0x40, 0x02), - _INIT_DCS_CMD(0x41, 0x02), - _INIT_DCS_CMD(0x42, 0x02), - _INIT_DCS_CMD(0x43, 0x02), - _INIT_DCS_CMD(0x44, 0x02), - _INIT_DCS_CMD(0x45, 0x02), - _INIT_DCS_CMD(0x46, 0x02), - - _INIT_DCS_CMD(0x47, 0x07), - _INIT_DCS_CMD(0x48, 0x07), - _INIT_DCS_CMD(0x49, 0x07), - _INIT_DCS_CMD(0x4A, 0x07), - _INIT_DCS_CMD(0x4B, 0x07), - _INIT_DCS_CMD(0x4C, 0x01), - _INIT_DCS_CMD(0x4D, 0x00), - _INIT_DCS_CMD(0x4E, 0x28), - _INIT_DCS_CMD(0x4F, 0x29), - _INIT_DCS_CMD(0x50, 0x10), - _INIT_DCS_CMD(0x51, 0x12), - _INIT_DCS_CMD(0x52, 0x14), - _INIT_DCS_CMD(0x53, 0x16), - _INIT_DCS_CMD(0x54, 0x08), - _INIT_DCS_CMD(0x55, 0x0C), - _INIT_DCS_CMD(0x56, 0x02), - _INIT_DCS_CMD(0x57, 0x02), - _INIT_DCS_CMD(0x58, 0x02), - _INIT_DCS_CMD(0x59, 0x02), - _INIT_DCS_CMD(0x5A, 0x02), - _INIT_DCS_CMD(0x5B, 0x02), - _INIT_DCS_CMD(0x5C, 0x02), - - _INIT_DCS_CMD(0x61, 0x07), - _INIT_DCS_CMD(0x62, 0x07), - _INIT_DCS_CMD(0x63, 0x07), - _INIT_DCS_CMD(0x64, 0x07), - _INIT_DCS_CMD(0x65, 0x07), - _INIT_DCS_CMD(0x66, 0x01), - _INIT_DCS_CMD(0x67, 0x00), - _INIT_DCS_CMD(0x68, 0x28), - _INIT_DCS_CMD(0x69, 0x29), - _INIT_DCS_CMD(0x6A, 0x16), - _INIT_DCS_CMD(0x6B, 0x14), - _INIT_DCS_CMD(0x6C, 0x12), - _INIT_DCS_CMD(0x6D, 0x10), - _INIT_DCS_CMD(0x6E, 0x0C), - _INIT_DCS_CMD(0x6F, 0x08), - _INIT_DCS_CMD(0x70, 0x02), - _INIT_DCS_CMD(0x71, 0x02), - _INIT_DCS_CMD(0x72, 0x02), - _INIT_DCS_CMD(0x73, 0x02), - _INIT_DCS_CMD(0x74, 0x02), - _INIT_DCS_CMD(0x75, 0x02), - _INIT_DCS_CMD(0x76, 0x02), - - _INIT_DCS_CMD(0x77, 0x07), - _INIT_DCS_CMD(0x78, 0x07), - _INIT_DCS_CMD(0x79, 0x07), - _INIT_DCS_CMD(0x7A, 0x07), - _INIT_DCS_CMD(0x7B, 0x07), - _INIT_DCS_CMD(0x7C, 0x01), - _INIT_DCS_CMD(0x7D, 0x00), - _INIT_DCS_CMD(0x7E, 0x28), - _INIT_DCS_CMD(0x7F, 0x29), - _INIT_DCS_CMD(0x80, 0x17), - _INIT_DCS_CMD(0x81, 0x15), - _INIT_DCS_CMD(0x82, 0x13), - _INIT_DCS_CMD(0x83, 0x11), - _INIT_DCS_CMD(0x84, 0x0D), - _INIT_DCS_CMD(0x85, 0x09), - _INIT_DCS_CMD(0x86, 0x02), - _INIT_DCS_CMD(0x87, 0x07), - _INIT_DCS_CMD(0x88, 0x07), - _INIT_DCS_CMD(0x89, 0x07), - _INIT_DCS_CMD(0x8A, 0x07), - _INIT_DCS_CMD(0x8B, 0x07), - _INIT_DCS_CMD(0x8C, 0x07), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x02), - _INIT_DCS_CMD(0x29, 0x3A), - _INIT_DCS_CMD(0x2A, 0x3B), - - _INIT_DCS_CMD(0x06, 0x01), - _INIT_DCS_CMD(0x07, 0x01), - _INIT_DCS_CMD(0x08, 0x0C), - _INIT_DCS_CMD(0x09, 0x44), - - _INIT_DCS_CMD(0x3C, 0x0A), - _INIT_DCS_CMD(0x39, 0x11), - _INIT_DCS_CMD(0x3D, 0x00), - _INIT_DCS_CMD(0x3A, 0x0C), - _INIT_DCS_CMD(0x3B, 0x44), - - _INIT_DCS_CMD(0x53, 0x1F), - _INIT_DCS_CMD(0x5E, 0x40), - _INIT_DCS_CMD(0x84, 0x00), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x03), - _INIT_DCS_CMD(0x20, 0x01), - _INIT_DCS_CMD(0x21, 0x3C), - _INIT_DCS_CMD(0x22, 0xFA), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0A), - _INIT_DCS_CMD(0xE0, 0x01), - _INIT_DCS_CMD(0xE2, 0x01), - _INIT_DCS_CMD(0xE5, 0x91), - _INIT_DCS_CMD(0xE6, 0x3C), - _INIT_DCS_CMD(0xE7, 0x00), - _INIT_DCS_CMD(0xE8, 0xFA), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x12), - _INIT_DCS_CMD(0x87, 0x2C), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x05), - _INIT_DCS_CMD(0x73, 0xE5), - _INIT_DCS_CMD(0x7F, 0x6B), - _INIT_DCS_CMD(0x6D, 0xA4), - _INIT_DCS_CMD(0x79, 0x54), - _INIT_DCS_CMD(0x69, 0x97), - _INIT_DCS_CMD(0x6A, 0x97), - _INIT_DCS_CMD(0xA5, 0x3F), - _INIT_DCS_CMD(0x61, 0xDA), - _INIT_DCS_CMD(0xA7, 0xF1), - _INIT_DCS_CMD(0x5F, 0x01), - _INIT_DCS_CMD(0x62, 0x3F), - _INIT_DCS_CMD(0x1D, 0x90), - _INIT_DCS_CMD(0x86, 0x87), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06), - _INIT_DCS_CMD(0xC0, 0x80), - _INIT_DCS_CMD(0xC1, 0x07), - _INIT_DCS_CMD(0xCA, 0x58), - _INIT_DCS_CMD(0xCB, 0x02), - _INIT_DCS_CMD(0xCE, 0x58), - _INIT_DCS_CMD(0xCF, 0x02), - _INIT_DCS_CMD(0x67, 0x60), - _INIT_DCS_CMD(0x10, 0x00), - _INIT_DCS_CMD(0x92, 0x22), - _INIT_DCS_CMD(0xD3, 0x08), - _INIT_DCS_CMD(0xD6, 0x55), - _INIT_DCS_CMD(0xDC, 0x38), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x08), - _INIT_DCS_CMD(0xE0, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), - _INIT_DCS_CMD(0xE1, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x04), - _INIT_DCS_CMD(0xBA, 0x81), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0C), - _INIT_DCS_CMD(0x00, 0x02), - _INIT_DCS_CMD(0x01, 0x00), - _INIT_DCS_CMD(0x02, 0x03), - _INIT_DCS_CMD(0x03, 0x01), - _INIT_DCS_CMD(0x04, 0x03), - _INIT_DCS_CMD(0x05, 0x02), - _INIT_DCS_CMD(0x06, 0x04), - _INIT_DCS_CMD(0x07, 0x03), - _INIT_DCS_CMD(0x08, 0x03), - _INIT_DCS_CMD(0x09, 0x04), - _INIT_DCS_CMD(0x0A, 0x04), - _INIT_DCS_CMD(0x0B, 0x05), - _INIT_DCS_CMD(0x0C, 0x04), - _INIT_DCS_CMD(0x0D, 0x06), - _INIT_DCS_CMD(0x0E, 0x05), - _INIT_DCS_CMD(0x0F, 0x07), - _INIT_DCS_CMD(0x10, 0x04), - _INIT_DCS_CMD(0x11, 0x08), - _INIT_DCS_CMD(0x12, 0x05), - _INIT_DCS_CMD(0x13, 0x09), - _INIT_DCS_CMD(0x14, 0x05), - _INIT_DCS_CMD(0x15, 0x0A), - _INIT_DCS_CMD(0x16, 0x06), - _INIT_DCS_CMD(0x17, 0x0B), - _INIT_DCS_CMD(0x18, 0x05), - _INIT_DCS_CMD(0x19, 0x0C), - _INIT_DCS_CMD(0x1A, 0x06), - _INIT_DCS_CMD(0x1B, 0x0D), - _INIT_DCS_CMD(0x1C, 0x06), - _INIT_DCS_CMD(0x1D, 0x0E), - _INIT_DCS_CMD(0x1E, 0x07), - _INIT_DCS_CMD(0x1F, 0x0F), - _INIT_DCS_CMD(0x20, 0x06), - _INIT_DCS_CMD(0x21, 0x10), - _INIT_DCS_CMD(0x22, 0x07), - _INIT_DCS_CMD(0x23, 0x11), - _INIT_DCS_CMD(0x24, 0x07), - _INIT_DCS_CMD(0x25, 0x12), - _INIT_DCS_CMD(0x26, 0x08), - _INIT_DCS_CMD(0x27, 0x13), - _INIT_DCS_CMD(0x28, 0x07), - _INIT_DCS_CMD(0x29, 0x14), - _INIT_DCS_CMD(0x2A, 0x08), - _INIT_DCS_CMD(0x2B, 0x15), - _INIT_DCS_CMD(0x2C, 0x08), - _INIT_DCS_CMD(0x2D, 0x16), - _INIT_DCS_CMD(0x2E, 0x09), - _INIT_DCS_CMD(0x2F, 0x17), - _INIT_DCS_CMD(0x30, 0x08), - _INIT_DCS_CMD(0x31, 0x18), - _INIT_DCS_CMD(0x32, 0x09), - _INIT_DCS_CMD(0x33, 0x19), - _INIT_DCS_CMD(0x34, 0x09), - _INIT_DCS_CMD(0x35, 0x1A), - _INIT_DCS_CMD(0x36, 0x0A), - _INIT_DCS_CMD(0x37, 0x1B), - _INIT_DCS_CMD(0x38, 0x0A), - _INIT_DCS_CMD(0x39, 0x1C), - _INIT_DCS_CMD(0x3A, 0x0A), - _INIT_DCS_CMD(0x3B, 0x1D), - _INIT_DCS_CMD(0x3C, 0x0A), - _INIT_DCS_CMD(0x3D, 0x1E), - _INIT_DCS_CMD(0x3E, 0x0A), - _INIT_DCS_CMD(0x3F, 0x1F), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x04), - _INIT_DCS_CMD(0xBA, 0x01), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0E), - _INIT_DCS_CMD(0x02, 0x0C), - _INIT_DCS_CMD(0x20, 0x10), - _INIT_DCS_CMD(0x25, 0x16), - _INIT_DCS_CMD(0x26, 0xE0), - _INIT_DCS_CMD(0x27, 0x00), - _INIT_DCS_CMD(0x29, 0x71), - _INIT_DCS_CMD(0x2A, 0x46), - _INIT_DCS_CMD(0x2B, 0x1F), - _INIT_DCS_CMD(0x2D, 0xC7), - _INIT_DCS_CMD(0x31, 0x02), - _INIT_DCS_CMD(0x32, 0xDF), - _INIT_DCS_CMD(0x33, 0x5A), - _INIT_DCS_CMD(0x34, 0xC0), - _INIT_DCS_CMD(0x35, 0x5A), - _INIT_DCS_CMD(0x36, 0xC0), - _INIT_DCS_CMD(0x38, 0x65), - _INIT_DCS_CMD(0x80, 0x3E), - _INIT_DCS_CMD(0x81, 0xA0), - _INIT_DCS_CMD(0xB0, 0x01), - _INIT_DCS_CMD(0xB1, 0xCC), - _INIT_DCS_CMD(0xC0, 0x12), - _INIT_DCS_CMD(0xC2, 0xCC), - _INIT_DCS_CMD(0xC3, 0xCC), - _INIT_DCS_CMD(0xC4, 0xCC), - _INIT_DCS_CMD(0xC5, 0xCC), - _INIT_DCS_CMD(0xC6, 0xCC), - _INIT_DCS_CMD(0xC7, 0xCC), - _INIT_DCS_CMD(0xC8, 0xCC), - _INIT_DCS_CMD(0xC9, 0xCC), - _INIT_DCS_CMD(0x30, 0x00), - _INIT_DCS_CMD(0x00, 0x81), - _INIT_DCS_CMD(0x08, 0x02), - _INIT_DCS_CMD(0x09, 0x00), - _INIT_DCS_CMD(0x07, 0x21), - _INIT_DCS_CMD(0x04, 0x10), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x1E), - _INIT_DCS_CMD(0x60, 0x00), - _INIT_DCS_CMD(0x64, 0x00), - _INIT_DCS_CMD(0x6D, 0x00), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0B), - _INIT_DCS_CMD(0xA6, 0x44), - _INIT_DCS_CMD(0xA7, 0xB6), - _INIT_DCS_CMD(0xA8, 0x03), - _INIT_DCS_CMD(0xA9, 0x03), - _INIT_DCS_CMD(0xAA, 0x51), - _INIT_DCS_CMD(0xAB, 0x51), - _INIT_DCS_CMD(0xAC, 0x04), - _INIT_DCS_CMD(0xBD, 0x92), - _INIT_DCS_CMD(0xBE, 0xA1), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x05), - _INIT_DCS_CMD(0x86, 0x87), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06), - _INIT_DCS_CMD(0x92, 0x22), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x00), - _INIT_DCS_CMD(0x11), - _INIT_DELAY_CMD(120), - _INIT_DCS_CMD(0x29), - _INIT_DELAY_CMD(20), - {}, -}; - static inline struct boe_panel *to_boe_panel(struct drm_panel *panel) { return container_of(panel, struct boe_panel, base); @@ -2135,34 +1795,6 @@ static const struct panel_desc starry_himax83102_j02_desc = { .lp11_before_reset = true, }; -static const struct drm_display_mode starry_ili9882t_default_mode = { - .clock = 165280, - .hdisplay = 1200, - .hsync_start = 1200 + 72, - .hsync_end = 1200 + 72 + 30, - .htotal = 1200 + 72 + 30 + 72, - .vdisplay = 1920, - .vsync_start = 1920 + 68, - .vsync_end = 1920 + 68 + 2, - .vtotal = 1920 + 68 + 2 + 10, - .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, -}; - -static const struct panel_desc starry_ili9882t_desc = { - .modes = &starry_ili9882t_default_mode, - .bpc = 8, - .size = { - .width_mm = 141, - .height_mm = 226, - }, - .lanes = 4, - .format = MIPI_DSI_FMT_RGB888, - .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_LPM, - .init_cmds = starry_ili9882t_init_cmd, - .lp11_before_reset = true, -}; - static int boe_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -2339,9 +1971,6 @@ static const struct of_device_id boe_of_match[] = { { .compatible = "starry,himax83102-j02", .data = &starry_himax83102_j02_desc }, - { .compatible = "starry,ili9882t", - .data = &starry_ili9882t_desc - }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, boe_of_match); diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c new file mode 100644 index 000000000000..93a40c2f1483 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c @@ -0,0 +1,759 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Panels based on the Ilitek ILI9882T display controller. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include