Loading...
1/*
2 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include "edp.h"
15
16struct edp_bridge {
17 struct drm_bridge base;
18 struct msm_edp *edp;
19};
20#define to_edp_bridge(x) container_of(x, struct edp_bridge, base)
21
22void edp_bridge_destroy(struct drm_bridge *bridge)
23{
24}
25
26static void edp_bridge_pre_enable(struct drm_bridge *bridge)
27{
28 struct edp_bridge *edp_bridge = to_edp_bridge(bridge);
29 struct msm_edp *edp = edp_bridge->edp;
30
31 DBG("");
32 msm_edp_ctrl_power(edp->ctrl, true);
33}
34
35static void edp_bridge_enable(struct drm_bridge *bridge)
36{
37 DBG("");
38}
39
40static void edp_bridge_disable(struct drm_bridge *bridge)
41{
42 DBG("");
43}
44
45static void edp_bridge_post_disable(struct drm_bridge *bridge)
46{
47 struct edp_bridge *edp_bridge = to_edp_bridge(bridge);
48 struct msm_edp *edp = edp_bridge->edp;
49
50 DBG("");
51 msm_edp_ctrl_power(edp->ctrl, false);
52}
53
54static void edp_bridge_mode_set(struct drm_bridge *bridge,
55 struct drm_display_mode *mode,
56 struct drm_display_mode *adjusted_mode)
57{
58 struct drm_device *dev = bridge->dev;
59 struct drm_connector *connector;
60 struct edp_bridge *edp_bridge = to_edp_bridge(bridge);
61 struct msm_edp *edp = edp_bridge->edp;
62
63 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
64 mode->base.id, mode->name,
65 mode->vrefresh, mode->clock,
66 mode->hdisplay, mode->hsync_start,
67 mode->hsync_end, mode->htotal,
68 mode->vdisplay, mode->vsync_start,
69 mode->vsync_end, mode->vtotal,
70 mode->type, mode->flags);
71
72 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
73 if ((connector->encoder != NULL) &&
74 (connector->encoder->bridge == bridge)) {
75 msm_edp_ctrl_timing_cfg(edp->ctrl,
76 adjusted_mode, &connector->display_info);
77 break;
78 }
79 }
80}
81
82static const struct drm_bridge_funcs edp_bridge_funcs = {
83 .pre_enable = edp_bridge_pre_enable,
84 .enable = edp_bridge_enable,
85 .disable = edp_bridge_disable,
86 .post_disable = edp_bridge_post_disable,
87 .mode_set = edp_bridge_mode_set,
88};
89
90/* initialize bridge */
91struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp)
92{
93 struct drm_bridge *bridge = NULL;
94 struct edp_bridge *edp_bridge;
95 int ret;
96
97 edp_bridge = devm_kzalloc(edp->dev->dev,
98 sizeof(*edp_bridge), GFP_KERNEL);
99 if (!edp_bridge) {
100 ret = -ENOMEM;
101 goto fail;
102 }
103
104 edp_bridge->edp = edp;
105
106 bridge = &edp_bridge->base;
107 bridge->funcs = &edp_bridge_funcs;
108
109 ret = drm_bridge_attach(edp->dev, bridge);
110 if (ret)
111 goto fail;
112
113 return bridge;
114
115fail:
116 if (bridge)
117 edp_bridge_destroy(bridge);
118
119 return ERR_PTR(ret);
120}
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 if ((connector->encoder != NULL) &&
59 (connector->encoder->bridge == bridge)) {
60 msm_edp_ctrl_timing_cfg(edp->ctrl,
61 adjusted_mode, &connector->display_info);
62 break;
63 }
64 }
65}
66
67static const struct drm_bridge_funcs edp_bridge_funcs = {
68 .pre_enable = edp_bridge_pre_enable,
69 .enable = edp_bridge_enable,
70 .disable = edp_bridge_disable,
71 .post_disable = edp_bridge_post_disable,
72 .mode_set = edp_bridge_mode_set,
73};
74
75/* initialize bridge */
76struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp)
77{
78 struct drm_bridge *bridge = NULL;
79 struct edp_bridge *edp_bridge;
80 int ret;
81
82 edp_bridge = devm_kzalloc(edp->dev->dev,
83 sizeof(*edp_bridge), GFP_KERNEL);
84 if (!edp_bridge) {
85 ret = -ENOMEM;
86 goto fail;
87 }
88
89 edp_bridge->edp = edp;
90
91 bridge = &edp_bridge->base;
92 bridge->funcs = &edp_bridge_funcs;
93
94 ret = drm_bridge_attach(edp->encoder, bridge, NULL);
95 if (ret)
96 goto fail;
97
98 return bridge;
99
100fail:
101 if (bridge)
102 edp_bridge_destroy(bridge);
103
104 return ERR_PTR(ret);
105}