Commit 696029eb authored by Joel Stanley's avatar Joel Stanley

drm/aspeed: Add sysfs for output settings

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: default avatarJoel Stanley <joel@jms.id.au>
Reviewed-by: default avatarAndrew Jeffery <andrew@aj.id.au>
Link: https://patchwork.freedesktop.org/patch/msgid/20200916083413.777307-1-joel@jms.id.au
parent 82e1b93a
...@@ -212,6 +212,69 @@ static const struct of_device_id aspeed_gfx_match[] = { ...@@ -212,6 +212,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 > 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, &reg);
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, &reg);
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) static int aspeed_gfx_probe(struct platform_device *pdev)
{ {
struct aspeed_gfx *priv; struct aspeed_gfx *priv;
...@@ -226,6 +289,12 @@ static int aspeed_gfx_probe(struct platform_device *pdev) ...@@ -226,6 +289,12 @@ static int aspeed_gfx_probe(struct platform_device *pdev)
if (ret) if (ret)
return 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); ret = drm_dev_register(&priv->drm, 0);
if (ret) if (ret)
goto err_unload; goto err_unload;
...@@ -234,6 +303,7 @@ static int aspeed_gfx_probe(struct platform_device *pdev) ...@@ -234,6 +303,7 @@ static int aspeed_gfx_probe(struct platform_device *pdev)
return 0; return 0;
err_unload: err_unload:
sysfs_remove_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group);
aspeed_gfx_unload(&priv->drm); aspeed_gfx_unload(&priv->drm);
return ret; return ret;
...@@ -243,6 +313,7 @@ static int aspeed_gfx_remove(struct platform_device *pdev) ...@@ -243,6 +313,7 @@ static int aspeed_gfx_remove(struct platform_device *pdev)
{ {
struct drm_device *drm = platform_get_drvdata(pdev); struct drm_device *drm = platform_get_drvdata(pdev);
sysfs_remove_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group);
drm_dev_unregister(drm); drm_dev_unregister(drm);
aspeed_gfx_unload(drm); aspeed_gfx_unload(drm);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment