summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/bridge/adv7511
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/bridge/adv7511')
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511.h3
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c24
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7533.c45
3 files changed, 39 insertions, 33 deletions
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 94de73cbeb2d..17445800248d 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -402,7 +402,8 @@ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
void adv7533_dsi_power_on(struct adv7511 *adv);
void adv7533_dsi_power_off(struct adv7511 *adv);
-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode);
+enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
+ const struct drm_display_mode *mode);
int adv7533_patch_registers(struct adv7511 *adv);
int adv7533_patch_cec_registers(struct adv7511 *adv);
int adv7533_attach_dsi(struct adv7511 *adv);
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index f887200e8abc..e7a6e456ed0d 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -697,7 +697,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
}
static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
- struct drm_display_mode *mode)
+ const struct drm_display_mode *mode)
{
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
@@ -791,9 +791,6 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
regmap_update_bits(adv7511->regmap, 0x17,
0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
- if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
- adv7533_mode_set(adv7511, adj_mode);
-
drm_mode_copy(&adv7511->curr_mode, adj_mode);
/*
@@ -913,6 +910,18 @@ static void adv7511_bridge_mode_set(struct drm_bridge *bridge,
adv7511_mode_set(adv, mode, adj_mode);
}
+static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode)
+{
+ struct adv7511 *adv = bridge_to_adv7511(bridge);
+
+ if (adv->type == ADV7533 || adv->type == ADV7535)
+ return adv7533_mode_valid(adv, mode);
+ else
+ return adv7511_mode_valid(adv, mode);
+}
+
static int adv7511_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
@@ -960,6 +969,7 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = {
.enable = adv7511_bridge_enable,
.disable = adv7511_bridge_disable,
.mode_set = adv7511_bridge_mode_set,
+ .mode_valid = adv7511_bridge_mode_valid,
.attach = adv7511_bridge_attach,
.detect = adv7511_bridge_detect,
.get_edid = adv7511_bridge_get_edid,
@@ -1209,10 +1219,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
return ret;
ret = adv7511_init_regulators(adv7511);
- if (ret) {
- dev_err(dev, "failed to init regulators\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to init regulators\n");
/*
* The power down GPIO is optional. If present, toggle it from active to
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c
index ef6270806d1d..fdfeadcefe80 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -100,26 +100,27 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
regmap_write(adv->regmap_cec, 0x27, 0x0b);
}
-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode)
+enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
+ const struct drm_display_mode *mode)
{
+ int lanes;
struct mipi_dsi_device *dsi = adv->dsi;
- int lanes, ret;
-
- if (adv->num_dsi_lanes != 4)
- return;
if (mode->clock > 80000)
lanes = 4;
else
lanes = 3;
- if (lanes != dsi->lanes) {
- mipi_dsi_detach(dsi);
- dsi->lanes = lanes;
- ret = mipi_dsi_attach(dsi);
- if (ret)
- dev_err(&dsi->dev, "failed to change host lanes\n");
- }
+ /*
+ * TODO: add support for dynamic switching of lanes
+ * by using the bridge pre_enable() op . Till then filter
+ * out the modes which shall need different number of lanes
+ * than what was configured in the device tree.
+ */
+ if (lanes != dsi->lanes)
+ return MODE_BAD;
+
+ return MODE_OK;
}
int adv7533_patch_registers(struct adv7511 *adv)
@@ -148,16 +149,14 @@ int adv7533_attach_dsi(struct adv7511 *adv)
};
host = of_find_mipi_dsi_host_by_node(adv->host_node);
- if (!host) {
- dev_err(dev, "failed to find dsi host\n");
- return -EPROBE_DEFER;
- }
+ if (!host)
+ return dev_err_probe(dev, -EPROBE_DEFER,
+ "failed to find dsi host\n");
dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
- if (IS_ERR(dsi)) {
- dev_err(dev, "failed to create dsi device\n");
- return PTR_ERR(dsi);
- }
+ if (IS_ERR(dsi))
+ return dev_err_probe(dev, PTR_ERR(dsi),
+ "failed to create dsi device\n");
adv->dsi = dsi;
@@ -167,10 +166,8 @@ int adv7533_attach_dsi(struct adv7511 *adv)
MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE;
ret = devm_mipi_dsi_attach(dev, dsi);
- if (ret < 0) {
- dev_err(dev, "failed to attach dsi to host\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "failed to attach dsi to host\n");
return 0;
}