diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:35:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:39:31 +0000 |
commit | 85c675d0d09a45a135bddd15d7b385f8758c32fb (patch) | |
tree | 76267dbc9b9a130337be3640948fe397b04ac629 /drivers/gpu/drm/bridge/adv7511 | |
parent | Adding upstream version 6.6.15. (diff) | |
download | linux-85c675d0d09a45a135bddd15d7b385f8758c32fb.tar.xz linux-85c675d0d09a45a135bddd15d7b385f8758c32fb.zip |
Adding upstream version 6.7.7.upstream/6.7.7
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/gpu/drm/bridge/adv7511')
-rw-r--r-- | drivers/gpu/drm/bridge/adv7511/adv7511.h | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 108 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/adv7511/adv7533.c | 7 |
4 files changed, 83 insertions, 62 deletions
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 1744580024..39c9ece373 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -333,6 +333,18 @@ enum adv7511_type { #define ADV7511_MAX_ADDRS 3 +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; + unsigned int reg_cec_offset; + bool has_dsi; + bool link_config; + bool hpd_override_enable; +}; + struct adv7511 { struct i2c_client *i2c_main; struct i2c_client *i2c_edid; @@ -341,7 +353,6 @@ struct adv7511 { struct regmap *regmap; struct regmap *regmap_cec; - unsigned int reg_cec_offset; enum drm_connector_status status; bool powered; @@ -369,7 +380,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; @@ -377,7 +387,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_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index 2a6b91f752..44451a9658 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 2611afd2c1..8be235144f 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -121,7 +121,7 @@ static const struct regmap_config adv7511_regmap_config = { .val_bits = 8, .max_register = 0xff, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .reg_defaults_raw = adv7511_register_defaults, .num_reg_defaults_raw = ARRAY_SIZE(adv7511_register_defaults), @@ -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->hpd_override_enable) 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->has_dsi) 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->hpd_override_enable) 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->has_dsi) 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->hpd_override_enable) 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->has_dsi) return adv7533_mode_valid(adv, mode); else return adv7511_mode_valid(adv, mode); @@ -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->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) @@ -1042,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: @@ -1068,7 +1061,7 @@ static const struct regmap_config adv7511_cec_regmap_config = { .val_bits = 8, .max_register = 0xff, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .volatile_reg = adv7511_cec_register_volatile, }; @@ -1093,12 +1086,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) goto err; } - if (adv->type == ADV7533 || adv->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; @@ -1192,7 +1183,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 +1199,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->link_config) ret = adv7511_parse_dt(dev->of_node, &link_config); else ret = adv7533_parse_dt(dev->of_node, adv7511); @@ -1254,7 +1240,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 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c) i2c_set_clientdata(i2c, adv7511); - if (adv7511->type == ADV7511) + if (adv7511->info->link_config) adv7511_set_link_config(adv7511, &link_config); ret = adv7511_cec_init(dev, adv7511); @@ -1325,7 +1311,7 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511_audio_init(dev, adv7511); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) { + if (adv7511->info->has_dsi) { ret = adv7533_attach_dsi(adv7511); if (ret) goto err_unregister_audio; @@ -1368,22 +1354,50 @@ 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, + .supply_names = adv7511_supply_names, + .num_supplies = ARRAY_SIZE(adv7511_supply_names), + .link_config = true, +}; + +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), + .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, +}; + +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), + .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, + .hpd_override_enable = true, +}; + 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 7e3e56441a..4481489aaf 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -103,18 +103,15 @@ 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); /* Check max clock for either 7533 or 7535 */ - if (mode->clock > (adv->type == ADV7533 ? 80000 : 148500)) + if (mode->clock > adv->info->max_mode_clock_khz) return MODE_CLOCK_HIGH; /* Check max clock for each lane */ - max_lane_freq = (adv->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; |