mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-14 08:34:02 +08:00
drm/bridge: display-connector: add DP support
Add DP support to display-connector driver. The driver will support HPD via a GPIO and DP PWR. DP PWR will be enabled at probe, which is not optimal, but I'm not sure what would be a good place to enable and disable DP PWR. Perhaps attach/detach, but I don't know if enabling HW is something that attach is supposed to do. In any case, I don't think there's much difference in power consumption between the version in this patch and enabling the regulator later: if the driver probes, supposedly it will attach very soon afterwards, and we need to enable the DP PWR as soon as possible. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201130112919.241054-3-tomi.valkeinen@ti.com
This commit is contained in:
parent
a46c112512
commit
2e2bf3a558
@ -11,6 +11,7 @@
|
|||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/regulator/consumer.h>
|
||||||
|
|
||||||
#include <drm/drm_bridge.h>
|
#include <drm/drm_bridge.h>
|
||||||
#include <drm/drm_edid.h>
|
#include <drm/drm_edid.h>
|
||||||
@ -20,6 +21,8 @@ struct display_connector {
|
|||||||
|
|
||||||
struct gpio_desc *hpd_gpio;
|
struct gpio_desc *hpd_gpio;
|
||||||
int hpd_irq;
|
int hpd_irq;
|
||||||
|
|
||||||
|
struct regulator *dp_pwr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct display_connector *
|
static inline struct display_connector *
|
||||||
@ -172,11 +175,12 @@ static int display_connector_probe(struct platform_device *pdev)
|
|||||||
of_property_read_string(pdev->dev.of_node, "label", &label);
|
of_property_read_string(pdev->dev.of_node, "label", &label);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the HPD GPIO for DVI and HDMI connectors. If the GPIO can provide
|
* Get the HPD GPIO for DVI, HDMI and DP connectors. If the GPIO can provide
|
||||||
* edge interrupts, register an interrupt handler.
|
* edge interrupts, register an interrupt handler.
|
||||||
*/
|
*/
|
||||||
if (type == DRM_MODE_CONNECTOR_DVII ||
|
if (type == DRM_MODE_CONNECTOR_DVII ||
|
||||||
type == DRM_MODE_CONNECTOR_HDMIA) {
|
type == DRM_MODE_CONNECTOR_HDMIA ||
|
||||||
|
type == DRM_MODE_CONNECTOR_DisplayPort) {
|
||||||
conn->hpd_gpio = devm_gpiod_get_optional(&pdev->dev, "hpd",
|
conn->hpd_gpio = devm_gpiod_get_optional(&pdev->dev, "hpd",
|
||||||
GPIOD_IN);
|
GPIOD_IN);
|
||||||
if (IS_ERR(conn->hpd_gpio)) {
|
if (IS_ERR(conn->hpd_gpio)) {
|
||||||
@ -223,6 +227,38 @@ static int display_connector_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the DP PWR for DP connector. */
|
||||||
|
if (type == DRM_MODE_CONNECTOR_DisplayPort) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
conn->dp_pwr = devm_regulator_get_optional(&pdev->dev, "dp-pwr");
|
||||||
|
|
||||||
|
if (IS_ERR(conn->dp_pwr)) {
|
||||||
|
ret = PTR_ERR(conn->dp_pwr);
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case -ENODEV:
|
||||||
|
conn->dp_pwr = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -EPROBE_DEFER:
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dev_err(&pdev->dev, "failed to get DP PWR regulator: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->dp_pwr) {
|
||||||
|
ret = regulator_enable(conn->dp_pwr);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "failed to enable DP PWR regulator: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
conn->bridge.funcs = &display_connector_bridge_funcs;
|
conn->bridge.funcs = &display_connector_bridge_funcs;
|
||||||
conn->bridge.of_node = pdev->dev.of_node;
|
conn->bridge.of_node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -251,6 +287,9 @@ static int display_connector_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct display_connector *conn = platform_get_drvdata(pdev);
|
struct display_connector *conn = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
if (conn->dp_pwr)
|
||||||
|
regulator_disable(conn->dp_pwr);
|
||||||
|
|
||||||
drm_bridge_remove(&conn->bridge);
|
drm_bridge_remove(&conn->bridge);
|
||||||
|
|
||||||
if (!IS_ERR(conn->bridge.ddc))
|
if (!IS_ERR(conn->bridge.ddc))
|
||||||
@ -275,6 +314,9 @@ static const struct of_device_id display_connector_match[] = {
|
|||||||
}, {
|
}, {
|
||||||
.compatible = "vga-connector",
|
.compatible = "vga-connector",
|
||||||
.data = (void *)DRM_MODE_CONNECTOR_VGA,
|
.data = (void *)DRM_MODE_CONNECTOR_VGA,
|
||||||
|
}, {
|
||||||
|
.compatible = "dp-connector",
|
||||||
|
.data = (void *)DRM_MODE_CONNECTOR_DisplayPort,
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user