drm/exynos: do not start enabling DP at bind() phase
The DP device will be properly enabled at the enable() call just after the bind call finishes. Changelog v2: - no change Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
663a233eef
commit
07c4270302
@ -1009,9 +1009,9 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
encoder->bridge = dp->bridge;
|
encoder->bridge->next = dp->ptn_bridge;
|
||||||
dp->bridge->encoder = encoder;
|
dp->ptn_bridge->encoder = encoder;
|
||||||
ret = drm_bridge_attach(encoder->dev, dp->bridge);
|
ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("Failed to attach bridge to drm\n");
|
DRM_ERROR("Failed to attach bridge to drm\n");
|
||||||
return ret;
|
return ret;
|
||||||
@ -1020,14 +1020,15 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exynos_dp_create_connector(struct drm_encoder *encoder)
|
static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
|
||||||
{
|
{
|
||||||
struct exynos_dp_device *dp = encoder_to_dp(encoder);
|
struct exynos_dp_device *dp = bridge->driver_private;
|
||||||
|
struct drm_encoder *encoder = &dp->encoder;
|
||||||
struct drm_connector *connector = &dp->connector;
|
struct drm_connector *connector = &dp->connector;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Pre-empt DP connector creation if there's a bridge */
|
/* Pre-empt DP connector creation if there's a bridge */
|
||||||
if (dp->bridge) {
|
if (dp->ptn_bridge) {
|
||||||
ret = exynos_drm_attach_lcd_bridge(dp, encoder);
|
ret = exynos_drm_attach_lcd_bridge(dp, encoder);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1052,22 +1053,9 @@ static int exynos_dp_create_connector(struct drm_encoder *encoder)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
|
static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
|
||||||
const struct drm_display_mode *mode,
|
|
||||||
struct drm_display_mode *adjusted_mode)
|
|
||||||
{
|
{
|
||||||
return true;
|
struct exynos_dp_device *dp = bridge->driver_private;
|
||||||
}
|
|
||||||
|
|
||||||
static void exynos_dp_mode_set(struct drm_encoder *encoder,
|
|
||||||
struct drm_display_mode *mode,
|
|
||||||
struct drm_display_mode *adjusted_mode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exynos_dp_enable(struct drm_encoder *encoder)
|
|
||||||
{
|
|
||||||
struct exynos_dp_device *dp = encoder_to_dp(encoder);
|
|
||||||
struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
|
struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
|
||||||
|
|
||||||
if (dp->dpms_mode == DRM_MODE_DPMS_ON)
|
if (dp->dpms_mode == DRM_MODE_DPMS_ON)
|
||||||
@ -1092,9 +1080,9 @@ static void exynos_dp_enable(struct drm_encoder *encoder)
|
|||||||
dp->dpms_mode = DRM_MODE_DPMS_ON;
|
dp->dpms_mode = DRM_MODE_DPMS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exynos_dp_disable(struct drm_encoder *encoder)
|
static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
|
||||||
{
|
{
|
||||||
struct exynos_dp_device *dp = encoder_to_dp(encoder);
|
struct exynos_dp_device *dp = bridge->driver_private;
|
||||||
struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
|
struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
|
||||||
|
|
||||||
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
|
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
|
||||||
@ -1123,6 +1111,69 @@ static void exynos_dp_disable(struct drm_encoder *encoder)
|
|||||||
dp->dpms_mode = DRM_MODE_DPMS_OFF;
|
dp->dpms_mode = DRM_MODE_DPMS_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
|
||||||
|
{
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
|
||||||
|
.enable = exynos_dp_bridge_enable,
|
||||||
|
.disable = exynos_dp_bridge_disable,
|
||||||
|
.pre_enable = exynos_dp_bridge_nop,
|
||||||
|
.post_disable = exynos_dp_bridge_nop,
|
||||||
|
.attach = exynos_dp_bridge_attach,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int exynos_dp_create_connector(struct drm_encoder *encoder)
|
||||||
|
{
|
||||||
|
struct exynos_dp_device *dp = encoder_to_dp(encoder);
|
||||||
|
struct drm_device *drm_dev = dp->drm_dev;
|
||||||
|
struct drm_bridge *bridge;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
|
||||||
|
if (!bridge) {
|
||||||
|
DRM_ERROR("failed to allocate for drm bridge\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
dp->bridge = bridge;
|
||||||
|
|
||||||
|
encoder->bridge = bridge;
|
||||||
|
bridge->driver_private = dp;
|
||||||
|
bridge->encoder = encoder;
|
||||||
|
bridge->funcs = &exynos_dp_bridge_funcs;
|
||||||
|
|
||||||
|
ret = drm_bridge_attach(drm_dev, bridge);
|
||||||
|
if (ret) {
|
||||||
|
DRM_ERROR("failed to attach drm bridge\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
|
||||||
|
const struct drm_display_mode *mode,
|
||||||
|
struct drm_display_mode *adjusted_mode)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exynos_dp_mode_set(struct drm_encoder *encoder,
|
||||||
|
struct drm_display_mode *mode,
|
||||||
|
struct drm_display_mode *adjusted_mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exynos_dp_enable(struct drm_encoder *encoder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exynos_dp_disable(struct drm_encoder *encoder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
|
static struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
|
||||||
.mode_fixup = exynos_dp_mode_fixup,
|
.mode_fixup = exynos_dp_mode_fixup,
|
||||||
.mode_set = exynos_dp_mode_set,
|
.mode_set = exynos_dp_mode_set,
|
||||||
@ -1238,7 +1289,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dp->panel && !dp->bridge) {
|
if (!dp->panel && !dp->ptn_bridge) {
|
||||||
ret = exynos_dp_dt_parse_panel(dp);
|
ret = exynos_dp_dt_parse_panel(dp);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1289,10 +1340,6 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
|
|||||||
|
|
||||||
INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
|
INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
|
||||||
|
|
||||||
phy_power_on(dp->phy);
|
|
||||||
|
|
||||||
exynos_dp_init_dp(dp);
|
|
||||||
|
|
||||||
ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
|
ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
|
||||||
irq_flags, "exynos-dp", dp);
|
irq_flags, "exynos-dp", dp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -1365,9 +1412,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
|
|||||||
if (endpoint) {
|
if (endpoint) {
|
||||||
bridge_node = of_graph_get_remote_port_parent(endpoint);
|
bridge_node = of_graph_get_remote_port_parent(endpoint);
|
||||||
if (bridge_node) {
|
if (bridge_node) {
|
||||||
dp->bridge = of_drm_find_bridge(bridge_node);
|
dp->ptn_bridge = of_drm_find_bridge(bridge_node);
|
||||||
of_node_put(bridge_node);
|
of_node_put(bridge_node);
|
||||||
if (!dp->bridge)
|
if (!dp->ptn_bridge)
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
} else
|
} else
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
@ -153,6 +153,7 @@ struct exynos_dp_device {
|
|||||||
struct drm_connector connector;
|
struct drm_connector connector;
|
||||||
struct drm_panel *panel;
|
struct drm_panel *panel;
|
||||||
struct drm_bridge *bridge;
|
struct drm_bridge *bridge;
|
||||||
|
struct drm_bridge *ptn_bridge;
|
||||||
struct clk *clock;
|
struct clk *clock;
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
void __iomem *reg_base;
|
void __iomem *reg_base;
|
||||||
|
Loading…
Reference in New Issue
Block a user