diff options
author | Hai Li | 2015-01-08 00:47:44 +0100 |
---|---|---|
committer | Rob Clark | 2015-02-01 21:30:37 +0100 |
commit | ab5b0107ccf3821a6837b0f2819270d6fa0b278f (patch) | |
tree | 87422469e4f1afaac11592f967ce246163cf7bf3 /drivers/gpu/drm/msm/edp/edp_bridge.c | |
parent | drm/msm/mdp4: add YUV format support (diff) | |
download | kernel-qcow2-linux-ab5b0107ccf3821a6837b0f2819270d6fa0b278f.tar.gz kernel-qcow2-linux-ab5b0107ccf3821a6837b0f2819270d6fa0b278f.tar.xz kernel-qcow2-linux-ab5b0107ccf3821a6837b0f2819270d6fa0b278f.zip |
drm/msm: Initial add eDP support in msm drm driver (v5)
This change adds a new eDP connector in msm drm driver. With this
change, eDP panel can work with msm platform under drm framework.
v1: Initial change
v2: Address Rob's comments
Use generated header file for register definitions
Change to devm_* APIs
v3: Address Thierry's comments and rebase on top of atomic changes
Remove edp_bridge_mode_fixup
Remove backlight control code and rely on pwm-backlight
Remove continuous splash screen support for now
Change to gpiod_* APIs
v4: Fix kbuild test issue
Signed-off-by: Hai Li <hali@codeaurora.org>
[robclark: v5: rebase on drm_bridge changes in drm-next]
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/edp/edp_bridge.c')
-rw-r--r-- | drivers/gpu/drm/msm/edp/edp_bridge.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/edp/edp_bridge.c b/drivers/gpu/drm/msm/edp/edp_bridge.c new file mode 100644 index 000000000000..2bc73f82f3f5 --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp_bridge.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "edp.h" + +struct edp_bridge { + struct drm_bridge base; + struct msm_edp *edp; +}; +#define to_edp_bridge(x) container_of(x, struct edp_bridge, base) + +void edp_bridge_destroy(struct drm_bridge *bridge) +{ +} + +static void edp_bridge_pre_enable(struct drm_bridge *bridge) +{ + struct edp_bridge *edp_bridge = to_edp_bridge(bridge); + struct msm_edp *edp = edp_bridge->edp; + + DBG(""); + msm_edp_ctrl_power(edp->ctrl, true); +} + +static void edp_bridge_enable(struct drm_bridge *bridge) +{ + DBG(""); +} + +static void edp_bridge_disable(struct drm_bridge *bridge) +{ + DBG(""); +} + +static void edp_bridge_post_disable(struct drm_bridge *bridge) +{ + struct edp_bridge *edp_bridge = to_edp_bridge(bridge); + struct msm_edp *edp = edp_bridge->edp; + + DBG(""); + msm_edp_ctrl_power(edp->ctrl, false); +} + +static void edp_bridge_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = bridge->dev; + struct drm_connector *connector; + struct edp_bridge *edp_bridge = to_edp_bridge(bridge); + struct msm_edp *edp = edp_bridge->edp; + + DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", + mode->base.id, mode->name, + mode->vrefresh, mode->clock, + mode->hdisplay, mode->hsync_start, + mode->hsync_end, mode->htotal, + mode->vdisplay, mode->vsync_start, + mode->vsync_end, mode->vtotal, + mode->type, mode->flags); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if ((connector->encoder != NULL) && + (connector->encoder->bridge == bridge)) { + msm_edp_ctrl_timing_cfg(edp->ctrl, + adjusted_mode, &connector->display_info); + break; + } + } +} + +static const struct drm_bridge_funcs edp_bridge_funcs = { + .pre_enable = edp_bridge_pre_enable, + .enable = edp_bridge_enable, + .disable = edp_bridge_disable, + .post_disable = edp_bridge_post_disable, + .mode_set = edp_bridge_mode_set, +}; + +/* initialize bridge */ +struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp) +{ + struct drm_bridge *bridge = NULL; + struct edp_bridge *edp_bridge; + int ret; + + edp_bridge = devm_kzalloc(edp->dev->dev, + sizeof(*edp_bridge), GFP_KERNEL); + if (!edp_bridge) { + ret = -ENOMEM; + goto fail; + } + + edp_bridge->edp = edp; + + bridge = &edp_bridge->base; + bridge->funcs = &edp_bridge_funcs; + + ret = drm_bridge_attach(edp->dev, bridge); + if (ret) + goto fail; + + return bridge; + +fail: + if (bridge) + edp_bridge_destroy(bridge); + + return ERR_PTR(ret); +} |