These settings are used by an ASPEED BMC to determine when the host is trying to drive the display over PCIe (vga_pw) and to switch the output between PCIe and the internal graphics device (dac_mux). The valid values for the dac mux are: 00: VGA mode (default, aka PCIe) 01: Graphics CRT (aka BMC internal graphics, this driver) 10: Pass through mode from video input port A 11: Pass through mode from video input port B Values for the read-only vga password register are: 1: Host driving the display 0: Host not driving the display Signed-off-by: Joel Stanley <joel@xxxxxxxxx> --- drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index 903f4f304647..9e06a3683f8a 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -205,6 +205,69 @@ static const struct of_device_id aspeed_gfx_match[] = { { } }; +#define ASPEED_SCU_VGA0 0x50 +#define ASPEED_SCU_MISC_CTRL 0x2c + +static ssize_t dac_mux_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aspeed_gfx *priv = dev_get_drvdata(dev); + u32 val; + int rc; + + rc = kstrtou32(buf, 0, &val); + if (rc) + return rc; + + if (val < 0 || val > 3) + return -EINVAL; + + rc = regmap_update_bits(priv->scu, ASPEED_SCU_MISC_CTRL, 0x30000, val << 16); + if (rc < 0) + return 0; + + return count; +} + +static ssize_t dac_mux_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aspeed_gfx *priv = dev_get_drvdata(dev); + u32 reg; + int rc; + + rc = regmap_read(priv->scu, ASPEED_SCU_MISC_CTRL, ®); + if (rc) + return rc; + + return sprintf(buf, "%u\n", (reg >> 16) & 0x3); +} +static DEVICE_ATTR_RW(dac_mux); + +static ssize_t +vga_pw_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aspeed_gfx *priv = dev_get_drvdata(dev); + u32 reg; + int rc; + + rc = regmap_read(priv->scu, ASPEED_SCU_VGA0, ®); + if (rc) + return rc; + + return sprintf(buf, "%u\n", reg & 1); +} +static DEVICE_ATTR_RO(vga_pw); + +static struct attribute *aspeed_sysfs_entries[] = { + &dev_attr_vga_pw.attr, + &dev_attr_dac_mux.attr, + NULL, +}; + +static struct attribute_group aspeed_sysfs_attr_group = { + .attrs = aspeed_sysfs_entries, +}; + static int aspeed_gfx_probe(struct platform_device *pdev) { struct aspeed_gfx *priv; @@ -219,6 +282,12 @@ static int aspeed_gfx_probe(struct platform_device *pdev) if (ret) return ret; + dev_set_drvdata(&pdev->dev, priv); + + ret = sysfs_create_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group); + if (ret) + return ret; + ret = drm_dev_register(&priv->drm, 0); if (ret) goto err_unload; @@ -227,6 +296,7 @@ static int aspeed_gfx_probe(struct platform_device *pdev) return 0; err_unload: + sysfs_remove_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group); aspeed_gfx_unload(&priv->drm); return ret; @@ -236,6 +306,7 @@ static int aspeed_gfx_remove(struct platform_device *pdev) { struct drm_device *drm = platform_get_drvdata(pdev); + sysfs_remove_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group); drm_dev_unregister(drm); aspeed_gfx_unload(drm); -- 2.28.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel