1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. 4 */ 5 6#include "edp.h" 7 8struct edp_bridge { 9 struct drm_bridge base; 10 struct msm_edp *edp; 11}; 12#define to_edp_bridge(x) container_of(x, struct edp_bridge, base) 13 14void edp_bridge_destroy(struct drm_bridge *bridge) 15{ 16} 17 18static void edp_bridge_pre_enable(struct drm_bridge *bridge) 19{ 20 struct edp_bridge *edp_bridge = to_edp_bridge(bridge); 21 struct msm_edp *edp = edp_bridge->edp; 22 23 DBG(""); 24 msm_edp_ctrl_power(edp->ctrl, true); 25} 26 27static void edp_bridge_enable(struct drm_bridge *bridge) 28{ 29 DBG(""); 30} 31 32static void edp_bridge_disable(struct drm_bridge *bridge) 33{ 34 DBG(""); 35} 36 37static void edp_bridge_post_disable(struct drm_bridge *bridge) 38{ 39 struct edp_bridge *edp_bridge = to_edp_bridge(bridge); 40 struct msm_edp *edp = edp_bridge->edp; 41 42 DBG(""); 43 msm_edp_ctrl_power(edp->ctrl, false); 44} 45 46static void edp_bridge_mode_set(struct drm_bridge *bridge, 47 const struct drm_display_mode *mode, 48 const struct drm_display_mode *adjusted_mode) 49{ 50 struct drm_device *dev = bridge->dev; 51 struct drm_connector *connector; 52 struct edp_bridge *edp_bridge = to_edp_bridge(bridge); 53 struct msm_edp *edp = edp_bridge->edp; 54 55 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode)); 56 57 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 58 struct drm_encoder *encoder = connector->encoder; 59 struct drm_bridge *first_bridge; 60 61 if (!connector->encoder) 62 continue; 63 64 first_bridge = drm_bridge_chain_get_first_bridge(encoder); 65 if (bridge == first_bridge) { 66 msm_edp_ctrl_timing_cfg(edp->ctrl, 67 adjusted_mode, &connector->display_info); 68 break; 69 } 70 } 71} 72 73static const struct drm_bridge_funcs edp_bridge_funcs = { 74 .pre_enable = edp_bridge_pre_enable, 75 .enable = edp_bridge_enable, 76 .disable = edp_bridge_disable, 77 .post_disable = edp_bridge_post_disable, 78 .mode_set = edp_bridge_mode_set, 79}; 80 81/* initialize bridge */ 82struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp) 83{ 84 struct drm_bridge *bridge = NULL; 85 struct edp_bridge *edp_bridge; 86 int ret; 87 88 edp_bridge = devm_kzalloc(edp->dev->dev, 89 sizeof(*edp_bridge), GFP_KERNEL); 90 if (!edp_bridge) { 91 ret = -ENOMEM; 92 goto fail; 93 } 94 95 edp_bridge->edp = edp; 96 97 bridge = &edp_bridge->base; 98 bridge->funcs = &edp_bridge_funcs; 99 100 ret = drm_bridge_attach(edp->encoder, bridge, NULL, 0); 101 if (ret) 102 goto fail; 103 104 return bridge; 105 106fail: 107 if (bridge) 108 edp_bridge_destroy(bridge); 109 110 return ERR_PTR(ret); 111} 112