diff --git a/drivers/video/anx98xx-edp.h b/drivers/video/anx98xx-edp.h index f7e8baa167..b6c21a399d 100644 --- a/drivers/video/anx98xx-edp.h +++ b/drivers/video/anx98xx-edp.h @@ -83,6 +83,7 @@ #define ANX9804_VID_CTRL1_REG 0x08 #define ANX9804_VID_CTRL1_VID_EN BIT(7) +#define ANX9804_VID_CTRL1_DDR_CTRL BIT(1) #define ANX9804_VID_CTRL1_EDGE BIT(0) #define ANX9804_VID_CTRL2_REG 0x09 diff --git a/drivers/video/bridge/anx6345.c b/drivers/video/bridge/anx6345.c index 0a94affb9f..5b12720b23 100644 --- a/drivers/video/bridge/anx6345.c +++ b/drivers/video/bridge/anx6345.c @@ -11,6 +11,7 @@ #include #include #include "../anx98xx-edp.h" +#include "../drm/rockchip_bridge.h" #define DP_MAX_LINK_RATE 0x001 #define DP_MAX_LANE_COUNT 0x002 @@ -19,6 +20,7 @@ DECLARE_GLOBAL_DATA_PTR; struct anx6345_priv { + u8 chipid; u8 edid[EDID_SIZE]; }; @@ -254,6 +256,13 @@ static int anx6345_read_dpcd(struct udevice *dev, u32 reg, u8 *val) static int anx6345_read_edid(struct udevice *dev, u8 *buf, int size) { struct anx6345_priv *priv = dev_get_priv(dev); + int ret; + + ret = anx6345_read_aux_i2c(dev, 0x50, 0x0, EDID_SIZE, priv->edid); + if (ret < 0) { + dev_err(dev, "failed to get edid\n"); + return ret; + } if (size > EDID_SIZE) size = EDID_SIZE; @@ -268,12 +277,11 @@ static int anx6345_attach(struct udevice *dev) return 0; } -static int anx6345_enable(struct udevice *dev) +static int anx6345_init(struct udevice *dev) { - u8 chipid, colordepth, lanes, data_rate, c; - int ret, i, bpp; - struct display_timing timing; struct anx6345_priv *priv = dev_get_priv(dev); + u8 c; + int ret, i; /* Deassert reset and enable power */ ret = video_bridge_set_active(dev, true); @@ -288,16 +296,16 @@ static int anx6345_enable(struct udevice *dev) /* Write 0 to the powerdown reg (powerup everything) */ anx6345_write_r1(dev, ANX9804_POWERD_CTRL_REG, 0); - ret = anx6345_read_r1(dev, ANX9804_DEV_IDH_REG, &chipid); + ret = anx6345_read_r1(dev, ANX9804_DEV_IDH_REG, &priv->chipid); if (ret) debug("%s: read id failed: %d\n", __func__, ret); - switch (chipid) { + switch (priv->chipid) { case 0x63: debug("ANX63xx detected.\n"); break; default: - debug("Error anx6345 chipid mismatch: %.2x\n", (int)chipid); + debug("Error anx6345 chipid mismatch: %.2x\n", priv->chipid); return -ENODEV; } @@ -339,7 +347,16 @@ static int anx6345_enable(struct udevice *dev) anx6345_write_r0(dev, ANX9804_HDCP_CONTROL_0_REG, 0x00); anx6345_write_r0(dev, 0xa7, 0x00); - anx6345_read_aux_i2c(dev, 0x50, 0x0, EDID_SIZE, priv->edid); + return 0; +} + +static int anx6345_enable(struct udevice *dev) +{ + u8 colordepth, lanes, data_rate, c; + int i, bpp; + struct display_timing timing; + struct anx6345_priv *priv = dev_get_priv(dev); + if (edid_get_timing(priv->edid, EDID_SIZE, &timing, &bpp) != 0) { debug("Failed to parse EDID\n"); return -EIO; @@ -374,7 +391,7 @@ static int anx6345_enable(struct udevice *dev) mdelay(5); for (i = 0; i < 100; i++) { anx6345_read_r0(dev, ANX9804_LINK_TRAINING_CTRL_REG, &c); - if ((chipid == 0x63) && (c & 0x80) == 0) + if ((priv->chipid == 0x63) && (c & 0x80) == 0) break; mdelay(5); @@ -385,8 +402,8 @@ static int anx6345_enable(struct udevice *dev) } /* Enable */ - anx6345_write_r1(dev, ANX9804_VID_CTRL1_REG, - ANX9804_VID_CTRL1_VID_EN | ANX9804_VID_CTRL1_EDGE); + anx6345_write_r1(dev, ANX9804_VID_CTRL1_REG, ANX9804_VID_CTRL1_VID_EN | + ANX9804_VID_CTRL1_DDR_CTRL | ANX9804_VID_CTRL1_EDGE); /* Force stream valid */ anx6345_write_r0(dev, ANX9804_SYS_CTRL3_REG, ANX9804_SYS_CTRL3_F_HPD | @@ -399,20 +416,40 @@ static int anx6345_enable(struct udevice *dev) static int anx6345_probe(struct udevice *dev) { + struct rockchip_bridge *bridge = + (struct rockchip_bridge *)dev_get_driver_data(dev); + if (device_get_uclass_id(dev->parent) != UCLASS_I2C) return -EPROTONOSUPPORT; - return anx6345_enable(dev); + bridge->dev = dev; + + return anx6345_init(dev); } -struct video_bridge_ops anx6345_ops = { +static const struct video_bridge_ops anx6345_ops = { .attach = anx6345_attach, .set_backlight = anx6345_set_backlight, .read_edid = anx6345_read_edid, }; +static void anx6345_bridge_enable(struct rockchip_bridge *bridge) +{ + anx6345_enable(bridge->dev); +} + +static const struct rockchip_bridge_funcs anx6345_bridge_funcs = { + .enable = anx6345_bridge_enable, +}; + +static struct rockchip_bridge anx6345_driver_data = { + .funcs = &anx6345_bridge_funcs, +}; + static const struct udevice_id anx6345_ids[] = { - { .compatible = "analogix,anx6345", }, + { + .compatible = "analogix,anx6345", + .data = (ulong)&anx6345_driver_data, }, { } };