aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/bridge/Kconfig13
-rw-r--r--drivers/gpu/drm/bridge/dw_hdmi.c13
-rw-r--r--drivers/gpu/drm/bridge/ptn3460.c310
-rw-r--r--drivers/gpu/drm/drm_bridge.c91
-rw-r--r--drivers/gpu/drm/drm_crtc.c72
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c53
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.h1
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c4
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.h1
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_bridge.c7
-rw-r--r--drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c33
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c57
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c29
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c11
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c11
17 files changed, 436 insertions, 278 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index cf0eed8208b5..2c239b99de64 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
14 drm_info.o drm_debugfs.o drm_encoder_slave.o \ 14 drm_info.o drm_debugfs.o drm_encoder_slave.o \
15 drm_trace_points.o drm_global.o drm_prime.o \ 15 drm_trace_points.o drm_global.o drm_prime.o \
16 drm_rect.o drm_vma_manager.o drm_flip_work.o \ 16 drm_rect.o drm_vma_manager.o drm_flip_work.o \
17 drm_modeset_lock.o drm_atomic.o 17 drm_modeset_lock.o drm_atomic.o drm_bridge.o
18 18
19drm-$(CONFIG_COMPAT) += drm_ioc32.o 19drm-$(CONFIG_COMPAT) += drm_ioc32.o
20drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o 20drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index b70f3c8d4e8a..f38bbcdf929b 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -1,10 +1,13 @@
1config DRM_PTN3460 1config DRM_DW_HDMI
2 tristate "PTN3460 DP/LVDS bridge" 2 tristate
3 depends on DRM 3 depends on DRM
4 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
5 ---help---
6 5
7config DRM_DW_HDMI 6config DRM_PTN3460
8 tristate 7 tristate "PTN3460 DP/LVDS bridge"
9 depends on DRM 8 depends on DRM
9 depends on OF
10 select DRM_KMS_HELPER 10 select DRM_KMS_HELPER
11 select DRM_PANEL
12 ---help---
13 ptn3460 eDP-LVDS bridge chip driver.
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 6ea000504173..cd6a70647e32 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1373,12 +1373,6 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
1373 dw_hdmi_poweron(hdmi); 1373 dw_hdmi_poweron(hdmi);
1374} 1374}
1375 1375
1376static void dw_hdmi_bridge_destroy(struct drm_bridge *bridge)
1377{
1378 drm_bridge_cleanup(bridge);
1379 kfree(bridge);
1380}
1381
1382static void dw_hdmi_bridge_nop(struct drm_bridge *bridge) 1376static void dw_hdmi_bridge_nop(struct drm_bridge *bridge)
1383{ 1377{
1384 /* do nothing */ 1378 /* do nothing */
@@ -1468,7 +1462,6 @@ struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
1468 .post_disable = dw_hdmi_bridge_nop, 1462 .post_disable = dw_hdmi_bridge_nop,
1469 .mode_set = dw_hdmi_bridge_mode_set, 1463 .mode_set = dw_hdmi_bridge_mode_set,
1470 .mode_fixup = dw_hdmi_bridge_mode_fixup, 1464 .mode_fixup = dw_hdmi_bridge_mode_fixup,
1471 .destroy = dw_hdmi_bridge_destroy,
1472}; 1465};
1473 1466
1474static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id) 1467static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
@@ -1531,8 +1524,8 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
1531 1524
1532 hdmi->bridge = bridge; 1525 hdmi->bridge = bridge;
1533 bridge->driver_private = hdmi; 1526 bridge->driver_private = hdmi;
1534 1527 bridge->funcs = &dw_hdmi_bridge_funcs;
1535 ret = drm_bridge_init(drm, bridge, &dw_hdmi_bridge_funcs); 1528 ret = drm_bridge_attach(drm, bridge);
1536 if (ret) { 1529 if (ret) {
1537 DRM_ERROR("Failed to initialize bridge with drm\n"); 1530 DRM_ERROR("Failed to initialize bridge with drm\n");
1538 return -EINVAL; 1531 return -EINVAL;
@@ -1649,7 +1642,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
1649 dw_hdmi_irq, IRQF_SHARED, 1642 dw_hdmi_irq, IRQF_SHARED,
1650 dev_name(dev), hdmi); 1643 dev_name(dev), hdmi);
1651 if (ret) 1644 if (ret)
1652 return ret; 1645 goto err_iahb;
1653 1646
1654 /* 1647 /*
1655 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator 1648 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c
index d466696ed5e8..826833e396f0 100644
--- a/drivers/gpu/drm/bridge/ptn3460.c
+++ b/drivers/gpu/drm/bridge/ptn3460.c
@@ -13,20 +13,23 @@
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 */ 14 */
15 15
16#include <linux/delay.h>
17#include <linux/gpio.h>
18#include <linux/i2c.h>
16#include <linux/module.h> 19#include <linux/module.h>
17#include <linux/of.h> 20#include <linux/of.h>
18#include <linux/of_gpio.h> 21#include <linux/of_gpio.h>
19#include <linux/i2c.h> 22#include <linux/of_graph.h>
20#include <linux/gpio.h>
21#include <linux/delay.h>
22 23
23#include "drmP.h" 24#include <drm/drm_panel.h>
24#include "drm_edid.h"
25#include "drm_crtc.h"
26#include "drm_crtc_helper.h"
27 25
28#include "bridge/ptn3460.h" 26#include "bridge/ptn3460.h"
29 27
28#include "drm_crtc.h"
29#include "drm_crtc_helper.h"
30#include "drm_edid.h"
31#include "drmP.h"
32
30#define PTN3460_EDID_ADDR 0x0 33#define PTN3460_EDID_ADDR 0x0
31#define PTN3460_EDID_EMULATION_ADDR 0x84 34#define PTN3460_EDID_EMULATION_ADDR 0x84
32#define PTN3460_EDID_ENABLE_EMULATION 0 35#define PTN3460_EDID_ENABLE_EMULATION 0
@@ -36,15 +39,27 @@
36struct ptn3460_bridge { 39struct ptn3460_bridge {
37 struct drm_connector connector; 40 struct drm_connector connector;
38 struct i2c_client *client; 41 struct i2c_client *client;
39 struct drm_encoder *encoder; 42 struct drm_bridge bridge;
40 struct drm_bridge *bridge;
41 struct edid *edid; 43 struct edid *edid;
42 int gpio_pd_n; 44 struct drm_panel *panel;
43 int gpio_rst_n; 45 struct gpio_desc *gpio_pd_n;
46 struct gpio_desc *gpio_rst_n;
44 u32 edid_emulation; 47 u32 edid_emulation;
45 bool enabled; 48 bool enabled;
46}; 49};
47 50
51static inline struct ptn3460_bridge *
52 bridge_to_ptn3460(struct drm_bridge *bridge)
53{
54 return container_of(bridge, struct ptn3460_bridge, bridge);
55}
56
57static inline struct ptn3460_bridge *
58 connector_to_ptn3460(struct drm_connector *connector)
59{
60 return container_of(connector, struct ptn3460_bridge, connector);
61}
62
48static int ptn3460_read_bytes(struct ptn3460_bridge *ptn_bridge, char addr, 63static int ptn3460_read_bytes(struct ptn3460_bridge *ptn_bridge, char addr,
49 u8 *buf, int len) 64 u8 *buf, int len)
50{ 65{
@@ -92,7 +107,7 @@ static int ptn3460_select_edid(struct ptn3460_bridge *ptn_bridge)
92 ret = ptn3460_write_byte(ptn_bridge, PTN3460_EDID_SRAM_LOAD_ADDR, 107 ret = ptn3460_write_byte(ptn_bridge, PTN3460_EDID_SRAM_LOAD_ADDR,
93 ptn_bridge->edid_emulation); 108 ptn_bridge->edid_emulation);
94 if (ret) { 109 if (ret) {
95 DRM_ERROR("Failed to transfer edid to sram, ret=%d\n", ret); 110 DRM_ERROR("Failed to transfer EDID to sram, ret=%d\n", ret);
96 return ret; 111 return ret;
97 } 112 }
98 113
@@ -102,7 +117,7 @@ static int ptn3460_select_edid(struct ptn3460_bridge *ptn_bridge)
102 117
103 ret = ptn3460_write_byte(ptn_bridge, PTN3460_EDID_EMULATION_ADDR, val); 118 ret = ptn3460_write_byte(ptn_bridge, PTN3460_EDID_EMULATION_ADDR, val);
104 if (ret) { 119 if (ret) {
105 DRM_ERROR("Failed to write edid value, ret=%d\n", ret); 120 DRM_ERROR("Failed to write EDID value, ret=%d\n", ret);
106 return ret; 121 return ret;
107 } 122 }
108 123
@@ -111,19 +126,21 @@ static int ptn3460_select_edid(struct ptn3460_bridge *ptn_bridge)
111 126
112static void ptn3460_pre_enable(struct drm_bridge *bridge) 127static void ptn3460_pre_enable(struct drm_bridge *bridge)
113{ 128{
114 struct ptn3460_bridge *ptn_bridge = bridge->driver_private; 129 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
115 int ret; 130 int ret;
116 131
117 if (ptn_bridge->enabled) 132 if (ptn_bridge->enabled)
118 return; 133 return;
119 134
120 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) 135 gpiod_set_value(ptn_bridge->gpio_pd_n, 1);
121 gpio_set_value(ptn_bridge->gpio_pd_n, 1); 136
137 gpiod_set_value(ptn_bridge->gpio_rst_n, 0);
138 usleep_range(10, 20);
139 gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
122 140
123 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) { 141 if (drm_panel_prepare(ptn_bridge->panel)) {
124 gpio_set_value(ptn_bridge->gpio_rst_n, 0); 142 DRM_ERROR("failed to prepare panel\n");
125 udelay(10); 143 return;
126 gpio_set_value(ptn_bridge->gpio_rst_n, 1);
127 } 144 }
128 145
129 /* 146 /*
@@ -135,73 +152,67 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge)
135 152
136 ret = ptn3460_select_edid(ptn_bridge); 153 ret = ptn3460_select_edid(ptn_bridge);
137 if (ret) 154 if (ret)
138 DRM_ERROR("Select edid failed ret=%d\n", ret); 155 DRM_ERROR("Select EDID failed ret=%d\n", ret);
139 156
140 ptn_bridge->enabled = true; 157 ptn_bridge->enabled = true;
141} 158}
142 159
143static void ptn3460_enable(struct drm_bridge *bridge) 160static void ptn3460_enable(struct drm_bridge *bridge)
144{ 161{
162 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
163
164 if (drm_panel_enable(ptn_bridge->panel)) {
165 DRM_ERROR("failed to enable panel\n");
166 return;
167 }
145} 168}
146 169
147static void ptn3460_disable(struct drm_bridge *bridge) 170static void ptn3460_disable(struct drm_bridge *bridge)
148{ 171{
149 struct ptn3460_bridge *ptn_bridge = bridge->driver_private; 172 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
150 173
151 if (!ptn_bridge->enabled) 174 if (!ptn_bridge->enabled)
152 return; 175 return;
153 176
154 ptn_bridge->enabled = false; 177 ptn_bridge->enabled = false;
155 178
156 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) 179 if (drm_panel_disable(ptn_bridge->panel)) {
157 gpio_set_value(ptn_bridge->gpio_rst_n, 1); 180 DRM_ERROR("failed to disable panel\n");
181 return;
182 }
158 183
159 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) 184 gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
160 gpio_set_value(ptn_bridge->gpio_pd_n, 0); 185 gpiod_set_value(ptn_bridge->gpio_pd_n, 0);
161} 186}
162 187
163static void ptn3460_post_disable(struct drm_bridge *bridge) 188static void ptn3460_post_disable(struct drm_bridge *bridge)
164{ 189{
165} 190 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
166 191
167void ptn3460_bridge_destroy(struct drm_bridge *bridge) 192 if (drm_panel_unprepare(ptn_bridge->panel)) {
168{ 193 DRM_ERROR("failed to unprepare panel\n");
169 struct ptn3460_bridge *ptn_bridge = bridge->driver_private; 194 return;
170 195 }
171 drm_bridge_cleanup(bridge);
172 if (gpio_is_valid(ptn_bridge->gpio_pd_n))
173 gpio_free(ptn_bridge->gpio_pd_n);
174 if (gpio_is_valid(ptn_bridge->gpio_rst_n))
175 gpio_free(ptn_bridge->gpio_rst_n);
176 /* Nothing else to free, we've got devm allocated memory */
177} 196}
178 197
179struct drm_bridge_funcs ptn3460_bridge_funcs = { 198static int ptn3460_get_modes(struct drm_connector *connector)
180 .pre_enable = ptn3460_pre_enable,
181 .enable = ptn3460_enable,
182 .disable = ptn3460_disable,
183 .post_disable = ptn3460_post_disable,
184 .destroy = ptn3460_bridge_destroy,
185};
186
187int ptn3460_get_modes(struct drm_connector *connector)
188{ 199{
189 struct ptn3460_bridge *ptn_bridge; 200 struct ptn3460_bridge *ptn_bridge;
190 u8 *edid; 201 u8 *edid;
191 int ret, num_modes; 202 int ret, num_modes = 0;
192 bool power_off; 203 bool power_off;
193 204
194 ptn_bridge = container_of(connector, struct ptn3460_bridge, connector); 205 ptn_bridge = connector_to_ptn3460(connector);
195 206
196 if (ptn_bridge->edid) 207 if (ptn_bridge->edid)
197 return drm_add_edid_modes(connector, ptn_bridge->edid); 208 return drm_add_edid_modes(connector, ptn_bridge->edid);
198 209
199 power_off = !ptn_bridge->enabled; 210 power_off = !ptn_bridge->enabled;
200 ptn3460_pre_enable(ptn_bridge->bridge); 211 ptn3460_pre_enable(&ptn_bridge->bridge);
201 212
202 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 213 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
203 if (!edid) { 214 if (!edid) {
204 DRM_ERROR("Failed to allocate edid\n"); 215 DRM_ERROR("Failed to allocate EDID\n");
205 return 0; 216 return 0;
206 } 217 }
207 218
@@ -209,7 +220,6 @@ int ptn3460_get_modes(struct drm_connector *connector)
209 EDID_LENGTH); 220 EDID_LENGTH);
210 if (ret) { 221 if (ret) {
211 kfree(edid); 222 kfree(edid);
212 num_modes = 0;
213 goto out; 223 goto out;
214 } 224 }
215 225
@@ -220,124 +230,188 @@ int ptn3460_get_modes(struct drm_connector *connector)
220 230
221out: 231out:
222 if (power_off) 232 if (power_off)
223 ptn3460_disable(ptn_bridge->bridge); 233 ptn3460_disable(&ptn_bridge->bridge);
224 234
225 return num_modes; 235 return num_modes;
226} 236}
227 237
228struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector) 238static struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
229{ 239{
230 struct ptn3460_bridge *ptn_bridge; 240 struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector);
231
232 ptn_bridge = container_of(connector, struct ptn3460_bridge, connector);
233 241
234 return ptn_bridge->encoder; 242 return ptn_bridge->bridge.encoder;
235} 243}
236 244
237struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = { 245static struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
238 .get_modes = ptn3460_get_modes, 246 .get_modes = ptn3460_get_modes,
239 .best_encoder = ptn3460_best_encoder, 247 .best_encoder = ptn3460_best_encoder,
240}; 248};
241 249
242enum drm_connector_status ptn3460_detect(struct drm_connector *connector, 250static enum drm_connector_status ptn3460_detect(struct drm_connector *connector,
243 bool force) 251 bool force)
244{ 252{
245 return connector_status_connected; 253 return connector_status_connected;
246} 254}
247 255
248void ptn3460_connector_destroy(struct drm_connector *connector) 256static void ptn3460_connector_destroy(struct drm_connector *connector)
249{ 257{
250 drm_connector_cleanup(connector); 258 drm_connector_cleanup(connector);
251} 259}
252 260
253struct drm_connector_funcs ptn3460_connector_funcs = { 261static struct drm_connector_funcs ptn3460_connector_funcs = {
254 .dpms = drm_helper_connector_dpms, 262 .dpms = drm_helper_connector_dpms,
255 .fill_modes = drm_helper_probe_single_connector_modes, 263 .fill_modes = drm_helper_probe_single_connector_modes,
256 .detect = ptn3460_detect, 264 .detect = ptn3460_detect,
257 .destroy = ptn3460_connector_destroy, 265 .destroy = ptn3460_connector_destroy,
258}; 266};
259 267
260int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, 268int ptn3460_bridge_attach(struct drm_bridge *bridge)
261 struct i2c_client *client, struct device_node *node)
262{ 269{
270 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
263 int ret; 271 int ret;
264 struct drm_bridge *bridge;
265 struct ptn3460_bridge *ptn_bridge;
266 272
267 bridge = devm_kzalloc(dev->dev, sizeof(*bridge), GFP_KERNEL); 273 if (!bridge->encoder) {
268 if (!bridge) { 274 DRM_ERROR("Parent encoder object not found");
269 DRM_ERROR("Failed to allocate drm bridge\n"); 275 return -ENODEV;
270 return -ENOMEM; 276 }
277
278 ptn_bridge->connector.polled = DRM_CONNECTOR_POLL_HPD;
279 ret = drm_connector_init(bridge->dev, &ptn_bridge->connector,
280 &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
281 if (ret) {
282 DRM_ERROR("Failed to initialize connector with drm\n");
283 return ret;
271 } 284 }
285 drm_connector_helper_add(&ptn_bridge->connector,
286 &ptn3460_connector_helper_funcs);
287 drm_connector_register(&ptn_bridge->connector);
288 drm_mode_connector_attach_encoder(&ptn_bridge->connector,
289 bridge->encoder);
272 290
273 ptn_bridge = devm_kzalloc(dev->dev, sizeof(*ptn_bridge), GFP_KERNEL); 291 if (ptn_bridge->panel)
292 drm_panel_attach(ptn_bridge->panel, &ptn_bridge->connector);
293
294 drm_helper_hpd_irq_event(ptn_bridge->connector.dev);
295
296 return ret;
297}
298
299static struct drm_bridge_funcs ptn3460_bridge_funcs = {
300 .pre_enable = ptn3460_pre_enable,
301 .enable = ptn3460_enable,
302 .disable = ptn3460_disable,
303 .post_disable = ptn3460_post_disable,
304 .attach = ptn3460_bridge_attach,
305};
306
307static int ptn3460_probe(struct i2c_client *client,
308 const struct i2c_device_id *id)
309{
310 struct device *dev = &client->dev;
311 struct ptn3460_bridge *ptn_bridge;
312 struct device_node *endpoint, *panel_node;
313 int ret;
314
315 ptn_bridge = devm_kzalloc(dev, sizeof(*ptn_bridge), GFP_KERNEL);
274 if (!ptn_bridge) { 316 if (!ptn_bridge) {
275 DRM_ERROR("Failed to allocate ptn bridge\n");
276 return -ENOMEM; 317 return -ENOMEM;
277 } 318 }
278 319
279 ptn_bridge->client = client; 320 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
280 ptn_bridge->encoder = encoder; 321 if (endpoint) {
281 ptn_bridge->bridge = bridge; 322 panel_node = of_graph_get_remote_port_parent(endpoint);
282 ptn_bridge->gpio_pd_n = of_get_named_gpio(node, "powerdown-gpio", 0); 323 if (panel_node) {
283 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) { 324 ptn_bridge->panel = of_drm_find_panel(panel_node);
284 ret = gpio_request_one(ptn_bridge->gpio_pd_n, 325 of_node_put(panel_node);
285 GPIOF_OUT_INIT_HIGH, "PTN3460_PD_N"); 326 if (!ptn_bridge->panel)
286 if (ret) { 327 return -EPROBE_DEFER;
287 DRM_ERROR("Request powerdown-gpio failed (%d)\n", ret);
288 return ret;
289 } 328 }
290 } 329 }
291 330
292 ptn_bridge->gpio_rst_n = of_get_named_gpio(node, "reset-gpio", 0); 331 ptn_bridge->client = client;
293 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) { 332
294 /* 333 ptn_bridge->gpio_pd_n = devm_gpiod_get(&client->dev, "powerdown");
295 * Request the reset pin low to avoid the bridge being 334 if (IS_ERR(ptn_bridge->gpio_pd_n)) {
296 * initialized prematurely 335 ret = PTR_ERR(ptn_bridge->gpio_pd_n);
297 */ 336 dev_err(dev, "cannot get gpio_pd_n %d\n", ret);
298 ret = gpio_request_one(ptn_bridge->gpio_rst_n, 337 return ret;
299 GPIOF_OUT_INIT_LOW, "PTN3460_RST_N");
300 if (ret) {
301 DRM_ERROR("Request reset-gpio failed (%d)\n", ret);
302 gpio_free(ptn_bridge->gpio_pd_n);
303 return ret;
304 }
305 } 338 }
306 339
307 ret = of_property_read_u32(node, "edid-emulation", 340 ret = gpiod_direction_output(ptn_bridge->gpio_pd_n, 1);
308 &ptn_bridge->edid_emulation);
309 if (ret) { 341 if (ret) {
310 DRM_ERROR("Can't read edid emulation value\n"); 342 DRM_ERROR("cannot configure gpio_pd_n\n");
311 goto err; 343 return ret;
312 } 344 }
313 345
314 ret = drm_bridge_init(dev, bridge, &ptn3460_bridge_funcs); 346 ptn_bridge->gpio_rst_n = devm_gpiod_get(&client->dev, "reset");
347 if (IS_ERR(ptn_bridge->gpio_rst_n)) {
348 ret = PTR_ERR(ptn_bridge->gpio_rst_n);
349 DRM_ERROR("cannot get gpio_rst_n %d\n", ret);
350 return ret;
351 }
352 /*
353 * Request the reset pin low to avoid the bridge being
354 * initialized prematurely
355 */
356 ret = gpiod_direction_output(ptn_bridge->gpio_rst_n, 0);
315 if (ret) { 357 if (ret) {
316 DRM_ERROR("Failed to initialize bridge with drm\n"); 358 DRM_ERROR("cannot configure gpio_rst_n\n");
317 goto err; 359 return ret;
318 } 360 }
319 361
320 bridge->driver_private = ptn_bridge; 362 ret = of_property_read_u32(dev->of_node, "edid-emulation",
321 encoder->bridge = bridge; 363 &ptn_bridge->edid_emulation);
364 if (ret) {
365 dev_err(dev, "Can't read EDID emulation value\n");
366 return ret;
367 }
322 368
323 ret = drm_connector_init(dev, &ptn_bridge->connector, 369 ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
324 &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS); 370 ptn_bridge->bridge.of_node = dev->of_node;
371 ret = drm_bridge_add(&ptn_bridge->bridge);
325 if (ret) { 372 if (ret) {
326 DRM_ERROR("Failed to initialize connector with drm\n"); 373 DRM_ERROR("Failed to add bridge\n");
327 goto err; 374 return ret;
328 } 375 }
329 drm_connector_helper_add(&ptn_bridge->connector, 376
330 &ptn3460_connector_helper_funcs); 377 i2c_set_clientdata(client, ptn_bridge);
331 drm_connector_register(&ptn_bridge->connector);
332 drm_mode_connector_attach_encoder(&ptn_bridge->connector, encoder);
333 378
334 return 0; 379 return 0;
380}
335 381
336err: 382static int ptn3460_remove(struct i2c_client *client)
337 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) 383{
338 gpio_free(ptn_bridge->gpio_pd_n); 384 struct ptn3460_bridge *ptn_bridge = i2c_get_clientdata(client);
339 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) 385
340 gpio_free(ptn_bridge->gpio_rst_n); 386 drm_bridge_remove(&ptn_bridge->bridge);
341 return ret; 387
388 return 0;
342} 389}
343EXPORT_SYMBOL(ptn3460_init); 390
391static const struct i2c_device_id ptn3460_i2c_table[] = {
392 {"nxp,ptn3460", 0},
393 {},
394};
395MODULE_DEVICE_TABLE(i2c, ptn3460_i2c_table);
396
397static const struct of_device_id ptn3460_match[] = {
398 { .compatible = "nxp,ptn3460" },
399 {},
400};
401MODULE_DEVICE_TABLE(of, ptn3460_match);
402
403static struct i2c_driver ptn3460_driver = {
404 .id_table = ptn3460_i2c_table,
405 .probe = ptn3460_probe,
406 .remove = ptn3460_remove,
407 .driver = {
408 .name = "nxp,ptn3460",
409 .owner = THIS_MODULE,
410 .of_match_table = ptn3460_match,
411 },
412};
413module_i2c_driver(ptn3460_driver);
414
415MODULE_AUTHOR("Sean Paul <seanpaul@chromium.org>");
416MODULE_DESCRIPTION("NXP ptn3460 eDP-LVDS converter driver");
417MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
new file mode 100644
index 000000000000..d1187e571c6d
--- /dev/null
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <linux/err.h>
25#include <linux/module.h>
26
27#include <drm/drm_crtc.h>
28
29#include "drm/drmP.h"
30
31static DEFINE_MUTEX(bridge_lock);
32static LIST_HEAD(bridge_list);
33
34int drm_bridge_add(struct drm_bridge *bridge)
35{
36 mutex_lock(&bridge_lock);
37 list_add_tail(&bridge->list, &bridge_list);
38 mutex_unlock(&bridge_lock);
39
40 return 0;
41}
42EXPORT_SYMBOL(drm_bridge_add);
43
44void drm_bridge_remove(struct drm_bridge *bridge)
45{
46 mutex_lock(&bridge_lock);
47 list_del_init(&bridge->list);
48 mutex_unlock(&bridge_lock);
49}
50EXPORT_SYMBOL(drm_bridge_remove);
51
52extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
53{
54 if (!dev || !bridge)
55 return -EINVAL;
56
57 if (bridge->dev)
58 return -EBUSY;
59
60 bridge->dev = dev;
61
62 if (bridge->funcs->attach)
63 return bridge->funcs->attach(bridge);
64
65 return 0;
66}
67EXPORT_SYMBOL(drm_bridge_attach);
68
69#ifdef CONFIG_OF
70struct drm_bridge *of_drm_find_bridge(struct device_node *np)
71{
72 struct drm_bridge *bridge;
73
74 mutex_lock(&bridge_lock);
75
76 list_for_each_entry(bridge, &bridge_list, list) {
77 if (bridge->of_node == np) {
78 mutex_unlock(&bridge_lock);
79 return bridge;
80 }
81 }
82
83 mutex_unlock(&bridge_lock);
84 return NULL;
85}
86EXPORT_SYMBOL(of_drm_find_bridge);
87#endif
88
89MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
90MODULE_DESCRIPTION("DRM bridge infrastructure");
91MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index b459888f6310..6b00173d1be4 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -787,7 +787,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
787 if (formats && num_formats) { 787 if (formats && num_formats) {
788 fmts = kmemdup(formats, sizeof(*formats) * num_formats, 788 fmts = kmemdup(formats, sizeof(*formats) * num_formats,
789 GFP_KERNEL); 789 GFP_KERNEL);
790 if (!formats) 790 if (!fmts)
791 return -ENOMEM; 791 return -ENOMEM;
792 } 792 }
793 793
@@ -1066,61 +1066,6 @@ void drm_connector_unplug_all(struct drm_device *dev)
1066EXPORT_SYMBOL(drm_connector_unplug_all); 1066EXPORT_SYMBOL(drm_connector_unplug_all);
1067 1067
1068/** 1068/**
1069 * drm_bridge_init - initialize a drm transcoder/bridge
1070 * @dev: drm device
1071 * @bridge: transcoder/bridge to set up
1072 * @funcs: bridge function table
1073 *
1074 * Initialises a preallocated bridge. Bridges should be
1075 * subclassed as part of driver connector objects.
1076 *
1077 * Returns:
1078 * Zero on success, error code on failure.
1079 */
1080int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge,
1081 const struct drm_bridge_funcs *funcs)
1082{
1083 int ret;
1084
1085 drm_modeset_lock_all(dev);
1086
1087 ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE);
1088 if (ret)
1089 goto out;
1090
1091 bridge->dev = dev;
1092 bridge->funcs = funcs;
1093
1094 list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
1095 dev->mode_config.num_bridge++;
1096
1097 out:
1098 drm_modeset_unlock_all(dev);
1099 return ret;
1100}
1101EXPORT_SYMBOL(drm_bridge_init);
1102
1103/**
1104 * drm_bridge_cleanup - cleans up an initialised bridge
1105 * @bridge: bridge to cleanup
1106 *
1107 * Cleans up the bridge but doesn't free the object.
1108 */
1109void drm_bridge_cleanup(struct drm_bridge *bridge)
1110{
1111 struct drm_device *dev = bridge->dev;
1112
1113 drm_modeset_lock_all(dev);
1114 drm_mode_object_put(dev, &bridge->base);
1115 list_del(&bridge->head);
1116 dev->mode_config.num_bridge--;
1117 drm_modeset_unlock_all(dev);
1118
1119 memset(bridge, 0, sizeof(*bridge));
1120}
1121EXPORT_SYMBOL(drm_bridge_cleanup);
1122
1123/**
1124 * drm_encoder_init - Init a preallocated encoder 1069 * drm_encoder_init - Init a preallocated encoder
1125 * @dev: drm device 1070 * @dev: drm device
1126 * @encoder: the encoder to init 1071 * @encoder: the encoder to init
@@ -1715,7 +1660,6 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
1715 total_objects += dev->mode_config.num_crtc; 1660 total_objects += dev->mode_config.num_crtc;
1716 total_objects += dev->mode_config.num_connector; 1661 total_objects += dev->mode_config.num_connector;
1717 total_objects += dev->mode_config.num_encoder; 1662 total_objects += dev->mode_config.num_encoder;
1718 total_objects += dev->mode_config.num_bridge;
1719 1663
1720 group->id_list = kcalloc(total_objects, sizeof(uint32_t), GFP_KERNEL); 1664 group->id_list = kcalloc(total_objects, sizeof(uint32_t), GFP_KERNEL);
1721 if (!group->id_list) 1665 if (!group->id_list)
@@ -1724,7 +1668,6 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
1724 group->num_crtcs = 0; 1668 group->num_crtcs = 0;
1725 group->num_connectors = 0; 1669 group->num_connectors = 0;
1726 group->num_encoders = 0; 1670 group->num_encoders = 0;
1727 group->num_bridges = 0;
1728 return 0; 1671 return 0;
1729} 1672}
1730 1673
@@ -1744,7 +1687,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
1744 struct drm_crtc *crtc; 1687 struct drm_crtc *crtc;
1745 struct drm_encoder *encoder; 1688 struct drm_encoder *encoder;
1746 struct drm_connector *connector; 1689 struct drm_connector *connector;
1747 struct drm_bridge *bridge;
1748 int ret; 1690 int ret;
1749 1691
1750 ret = drm_mode_group_init(dev, group); 1692 ret = drm_mode_group_init(dev, group);
@@ -1762,11 +1704,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
1762 group->id_list[group->num_crtcs + group->num_encoders + 1704 group->id_list[group->num_crtcs + group->num_encoders +
1763 group->num_connectors++] = connector->base.id; 1705 group->num_connectors++] = connector->base.id;
1764 1706
1765 list_for_each_entry(bridge, &dev->mode_config.bridge_list, head)
1766 group->id_list[group->num_crtcs + group->num_encoders +
1767 group->num_connectors + group->num_bridges++] =
1768 bridge->base.id;
1769
1770 return 0; 1707 return 0;
1771} 1708}
1772EXPORT_SYMBOL(drm_mode_group_init_legacy_group); 1709EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
@@ -5443,7 +5380,6 @@ void drm_mode_config_init(struct drm_device *dev)
5443 INIT_LIST_HEAD(&dev->mode_config.fb_list); 5380 INIT_LIST_HEAD(&dev->mode_config.fb_list);
5444 INIT_LIST_HEAD(&dev->mode_config.crtc_list); 5381 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
5445 INIT_LIST_HEAD(&dev->mode_config.connector_list); 5382 INIT_LIST_HEAD(&dev->mode_config.connector_list);
5446 INIT_LIST_HEAD(&dev->mode_config.bridge_list);
5447 INIT_LIST_HEAD(&dev->mode_config.encoder_list); 5383 INIT_LIST_HEAD(&dev->mode_config.encoder_list);
5448 INIT_LIST_HEAD(&dev->mode_config.property_list); 5384 INIT_LIST_HEAD(&dev->mode_config.property_list);
5449 INIT_LIST_HEAD(&dev->mode_config.property_blob_list); 5385 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
@@ -5483,7 +5419,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
5483 struct drm_connector *connector, *ot; 5419 struct drm_connector *connector, *ot;
5484 struct drm_crtc *crtc, *ct; 5420 struct drm_crtc *crtc, *ct;
5485 struct drm_encoder *encoder, *enct; 5421 struct drm_encoder *encoder, *enct;
5486 struct drm_bridge *bridge, *brt;
5487 struct drm_framebuffer *fb, *fbt; 5422 struct drm_framebuffer *fb, *fbt;
5488 struct drm_property *property, *pt; 5423 struct drm_property *property, *pt;
5489 struct drm_property_blob *blob, *bt; 5424 struct drm_property_blob *blob, *bt;
@@ -5494,11 +5429,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
5494 encoder->funcs->destroy(encoder); 5429 encoder->funcs->destroy(encoder);
5495 } 5430 }
5496 5431
5497 list_for_each_entry_safe(bridge, brt,
5498 &dev->mode_config.bridge_list, head) {
5499 bridge->funcs->destroy(bridge);
5500 }
5501
5502 list_for_each_entry_safe(connector, ot, 5432 list_for_each_entry_safe(connector, ot,
5503 &dev->mode_config.connector_list, head) { 5433 &dev->mode_config.connector_list, head) {
5504 connector->funcs->destroy(connector); 5434 connector->funcs->destroy(connector);
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index c0644bb865f2..2d5ca8eec13a 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -323,8 +323,6 @@ EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
323int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, 323int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
324 const struct mipi_dsi_msg *msg) 324 const struct mipi_dsi_msg *msg)
325{ 325{
326 const u8 *tx = msg->tx_buf;
327
328 if (!packet || !msg) 326 if (!packet || !msg)
329 return -EINVAL; 327 return -EINVAL;
330 328
@@ -353,8 +351,10 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
353 packet->header[2] = (msg->tx_len >> 8) & 0xff; 351 packet->header[2] = (msg->tx_len >> 8) & 0xff;
354 352
355 packet->payload_length = msg->tx_len; 353 packet->payload_length = msg->tx_len;
356 packet->payload = tx; 354 packet->payload = msg->tx_buf;
357 } else { 355 } else {
356 const u8 *tx = msg->tx_buf;
357
358 packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; 358 packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
359 packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; 359 packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
360 } 360 }
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 34d46aa75416..46f149737bc8 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/of_gpio.h> 20#include <linux/of_gpio.h>
21#include <linux/of_graph.h>
21#include <linux/gpio.h> 22#include <linux/gpio.h>
22#include <linux/component.h> 23#include <linux/component.h>
23#include <linux/phy/phy.h> 24#include <linux/phy/phy.h>
@@ -993,32 +994,20 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
993 .best_encoder = exynos_dp_best_encoder, 994 .best_encoder = exynos_dp_best_encoder,
994}; 995};
995 996
996static bool find_bridge(const char *compat, struct bridge_init *bridge)
997{
998 bridge->client = NULL;
999 bridge->node = of_find_compatible_node(NULL, NULL, compat);
1000 if (!bridge->node)
1001 return false;
1002
1003 bridge->client = of_find_i2c_device_by_node(bridge->node);
1004 if (!bridge->client)
1005 return false;
1006
1007 return true;
1008}
1009
1010/* returns the number of bridges attached */ 997/* returns the number of bridges attached */
1011static int exynos_drm_attach_lcd_bridge(struct drm_device *dev, 998static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
1012 struct drm_encoder *encoder) 999 struct drm_encoder *encoder)
1013{ 1000{
1014 struct bridge_init bridge;
1015 int ret; 1001 int ret;
1016 1002
1017 if (find_bridge("nxp,ptn3460", &bridge)) { 1003 encoder->bridge = dp->bridge;
1018 ret = ptn3460_init(dev, encoder, bridge.client, bridge.node); 1004 dp->bridge->encoder = encoder;
1019 if (!ret) 1005 ret = drm_bridge_attach(encoder->dev, dp->bridge);
1020 return 1; 1006 if (ret) {
1007 DRM_ERROR("Failed to attach bridge to drm\n");
1008 return ret;
1021 } 1009 }
1010
1022 return 0; 1011 return 0;
1023} 1012}
1024 1013
@@ -1032,9 +1021,11 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
1032 dp->encoder = encoder; 1021 dp->encoder = encoder;
1033 1022
1034 /* Pre-empt DP connector creation if there's a bridge */ 1023 /* Pre-empt DP connector creation if there's a bridge */
1035 ret = exynos_drm_attach_lcd_bridge(dp->drm_dev, encoder); 1024 if (dp->bridge) {
1036 if (ret) 1025 ret = exynos_drm_attach_lcd_bridge(dp, encoder);
1037 return 0; 1026 if (!ret)
1027 return 0;
1028 }
1038 1029
1039 connector->polled = DRM_CONNECTOR_POLL_HPD; 1030 connector->polled = DRM_CONNECTOR_POLL_HPD;
1040 1031
@@ -1241,7 +1232,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
1241 } 1232 }
1242 } 1233 }
1243 1234
1244 if (!dp->panel) { 1235 if (!dp->panel && !dp->bridge) {
1245 ret = exynos_dp_dt_parse_panel(dp); 1236 ret = exynos_dp_dt_parse_panel(dp);
1246 if (ret) 1237 if (ret)
1247 return ret; 1238 return ret;
@@ -1325,7 +1316,7 @@ static const struct component_ops exynos_dp_ops = {
1325static int exynos_dp_probe(struct platform_device *pdev) 1316static int exynos_dp_probe(struct platform_device *pdev)
1326{ 1317{
1327 struct device *dev = &pdev->dev; 1318 struct device *dev = &pdev->dev;
1328 struct device_node *panel_node; 1319 struct device_node *panel_node, *bridge_node, *endpoint;
1329 struct exynos_dp_device *dp; 1320 struct exynos_dp_device *dp;
1330 int ret; 1321 int ret;
1331 1322
@@ -1351,6 +1342,18 @@ static int exynos_dp_probe(struct platform_device *pdev)
1351 return -EPROBE_DEFER; 1342 return -EPROBE_DEFER;
1352 } 1343 }
1353 1344
1345 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
1346 if (endpoint) {
1347 bridge_node = of_graph_get_remote_port_parent(endpoint);
1348 if (bridge_node) {
1349 dp->bridge = of_drm_find_bridge(bridge_node);
1350 of_node_put(bridge_node);
1351 if (!dp->bridge)
1352 return -EPROBE_DEFER;
1353 } else
1354 return -EPROBE_DEFER;
1355 }
1356
1354 ret = component_add(&pdev->dev, &exynos_dp_ops); 1357 ret = component_add(&pdev->dev, &exynos_dp_ops);
1355 if (ret) 1358 if (ret)
1356 exynos_drm_component_del(&pdev->dev, 1359 exynos_drm_component_del(&pdev->dev,
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index 164f171168e7..a4e799679669 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -153,6 +153,7 @@ struct exynos_dp_device {
153 struct drm_connector connector; 153 struct drm_connector connector;
154 struct drm_encoder *encoder; 154 struct drm_encoder *encoder;
155 struct drm_panel *panel; 155 struct drm_panel *panel;
156 struct drm_bridge *bridge;
156 struct clk *clock; 157 struct clk *clock;
157 unsigned int irq; 158 unsigned int irq;
158 void __iomem *reg_base; 159 void __iomem *reg_base;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 062c68725376..95f7b8d0f3ef 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -247,9 +247,9 @@ int hdmi_modeset_init(struct hdmi *hdmi,
247 return 0; 247 return 0;
248 248
249fail: 249fail:
250 /* bridge/connector are normally destroyed by drm: */ 250 /* bridge is normally destroyed by drm: */
251 if (hdmi->bridge) { 251 if (hdmi->bridge) {
252 hdmi->bridge->funcs->destroy(hdmi->bridge); 252 hdmi_bridge_destroy(hdmi->bridge);
253 hdmi->bridge = NULL; 253 hdmi->bridge = NULL;
254 } 254 }
255 if (hdmi->connector) { 255 if (hdmi->connector) {
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 43e654f751b7..4d4cad42a776 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -146,6 +146,7 @@ void hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
146 */ 146 */
147 147
148struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi); 148struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi);
149void hdmi_bridge_destroy(struct drm_bridge *bridge);
149 150
150/* 151/*
151 * hdmi connector: 152 * hdmi connector:
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 6902ad6da710..d6f8d5818e18 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -23,10 +23,9 @@ struct hdmi_bridge {
23}; 23};
24#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base) 24#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
25 25
26static void hdmi_bridge_destroy(struct drm_bridge *bridge) 26void hdmi_bridge_destroy(struct drm_bridge *bridge)
27{ 27{
28 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 28 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
29 drm_bridge_cleanup(bridge);
30 kfree(hdmi_bridge); 29 kfree(hdmi_bridge);
31} 30}
32 31
@@ -200,7 +199,6 @@ static const struct drm_bridge_funcs hdmi_bridge_funcs = {
200 .disable = hdmi_bridge_disable, 199 .disable = hdmi_bridge_disable,
201 .post_disable = hdmi_bridge_post_disable, 200 .post_disable = hdmi_bridge_post_disable,
202 .mode_set = hdmi_bridge_mode_set, 201 .mode_set = hdmi_bridge_mode_set,
203 .destroy = hdmi_bridge_destroy,
204}; 202};
205 203
206 204
@@ -220,8 +218,9 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi)
220 hdmi_bridge->hdmi = hdmi; 218 hdmi_bridge->hdmi = hdmi;
221 219
222 bridge = &hdmi_bridge->base; 220 bridge = &hdmi_bridge->base;
221 bridge->funcs = &hdmi_bridge_funcs;
223 222
224 drm_bridge_init(hdmi->dev, bridge, &hdmi_bridge_funcs); 223 drm_bridge_attach(hdmi->dev, bridge);
225 224
226 return bridge; 225 return bridge;
227 226
diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 9d81759d82fc..3cce3ca19601 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -19,8 +19,6 @@
19 19
20#include <video/mipi_display.h> 20#include <video/mipi_display.h>
21 21
22#include <linux/host1x.h>
23
24struct sharp_panel { 22struct sharp_panel {
25 struct drm_panel base; 23 struct drm_panel base;
26 /* the datasheet refers to them as DSI-LINK1 and DSI-LINK2 */ 24 /* the datasheet refers to them as DSI-LINK1 and DSI-LINK2 */
@@ -41,6 +39,16 @@ static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel)
41 return container_of(panel, struct sharp_panel, base); 39 return container_of(panel, struct sharp_panel, base);
42} 40}
43 41
42static void sharp_wait_frames(struct sharp_panel *sharp, unsigned int frames)
43{
44 unsigned int refresh = drm_mode_vrefresh(sharp->mode);
45
46 if (WARN_ON(frames > refresh))
47 return;
48
49 msleep(1000 / (refresh / frames));
50}
51
44static int sharp_panel_write(struct sharp_panel *sharp, u16 offset, u8 value) 52static int sharp_panel_write(struct sharp_panel *sharp, u16 offset, u8 value)
45{ 53{
46 u8 payload[3] = { offset >> 8, offset & 0xff, value }; 54 u8 payload[3] = { offset >> 8, offset & 0xff, value };
@@ -106,6 +114,8 @@ static int sharp_panel_unprepare(struct drm_panel *panel)
106 if (!sharp->prepared) 114 if (!sharp->prepared)
107 return 0; 115 return 0;
108 116
117 sharp_wait_frames(sharp, 4);
118
109 err = mipi_dsi_dcs_set_display_off(sharp->link1); 119 err = mipi_dsi_dcs_set_display_off(sharp->link1);
110 if (err < 0) 120 if (err < 0)
111 dev_err(panel->dev, "failed to set display off: %d\n", err); 121 dev_err(panel->dev, "failed to set display off: %d\n", err);
@@ -170,15 +180,13 @@ static int sharp_panel_prepare(struct drm_panel *panel)
170 if (err < 0) 180 if (err < 0)
171 return err; 181 return err;
172 182
173 usleep_range(10000, 20000); 183 /*
174 184 * According to the datasheet, the panel needs around 10 ms to fully
175 err = mipi_dsi_dcs_soft_reset(sharp->link1); 185 * power up. At least another 120 ms is required before exiting sleep
176 if (err < 0) { 186 * mode to make sure the panel is ready. Throw in another 20 ms for
177 dev_err(panel->dev, "soft reset failed: %d\n", err); 187 * good measure.
178 goto poweroff; 188 */
179 } 189 msleep(150);
180
181 msleep(120);
182 190
183 err = mipi_dsi_dcs_exit_sleep_mode(sharp->link1); 191 err = mipi_dsi_dcs_exit_sleep_mode(sharp->link1);
184 if (err < 0) { 192 if (err < 0) {
@@ -238,6 +246,9 @@ static int sharp_panel_prepare(struct drm_panel *panel)
238 246
239 sharp->prepared = true; 247 sharp->prepared = true;
240 248
249 /* wait for 6 frames before continuing */
250 sharp_wait_frames(sharp, 6);
251
241 return 0; 252 return 0;
242 253
243poweroff: 254poweroff:
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 6049d245c20e..39806c335339 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -448,6 +448,34 @@ static const struct panel_desc auo_b133htn01 = {
448 }, 448 },
449}; 449};
450 450
451static const struct drm_display_mode avic_tm070ddh03_mode = {
452 .clock = 51200,
453 .hdisplay = 1024,
454 .hsync_start = 1024 + 160,
455 .hsync_end = 1024 + 160 + 4,
456 .htotal = 1024 + 160 + 4 + 156,
457 .vdisplay = 600,
458 .vsync_start = 600 + 17,
459 .vsync_end = 600 + 17 + 1,
460 .vtotal = 600 + 17 + 1 + 17,
461 .vrefresh = 60,
462};
463
464static const struct panel_desc avic_tm070ddh03 = {
465 .modes = &avic_tm070ddh03_mode,
466 .num_modes = 1,
467 .bpc = 8,
468 .size = {
469 .width = 154,
470 .height = 90,
471 },
472 .delay = {
473 .prepare = 20,
474 .enable = 200,
475 .disable = 200,
476 },
477};
478
451static const struct drm_display_mode chunghwa_claa101wa01a_mode = { 479static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
452 .clock = 72070, 480 .clock = 72070,
453 .hdisplay = 1366, 481 .hdisplay = 1366,
@@ -566,6 +594,29 @@ static const struct panel_desc foxlink_fl500wvr00_a0t = {
566 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 594 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
567}; 595};
568 596
597static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
598 .clock = 9000,
599 .hdisplay = 480,
600 .hsync_start = 480 + 5,
601 .hsync_end = 480 + 5 + 1,
602 .htotal = 480 + 5 + 1 + 40,
603 .vdisplay = 272,
604 .vsync_start = 272 + 8,
605 .vsync_end = 272 + 8 + 1,
606 .vtotal = 272 + 8 + 1 + 8,
607 .vrefresh = 60,
608};
609
610static const struct panel_desc giantplus_gpg482739qs5 = {
611 .modes = &giantplus_gpg482739qs5_mode,
612 .num_modes = 1,
613 .bpc = 8,
614 .size = {
615 .width = 95,
616 .height = 54,
617 },
618};
619
569static const struct drm_display_mode hannstar_hsd070pww1_mode = { 620static const struct drm_display_mode hannstar_hsd070pww1_mode = {
570 .clock = 71100, 621 .clock = 71100,
571 .hdisplay = 1280, 622 .hdisplay = 1280,
@@ -745,6 +796,9 @@ static const struct of_device_id platform_of_match[] = {
745 .compatible = "auo,b133xtn01", 796 .compatible = "auo,b133xtn01",
746 .data = &auo_b133xtn01, 797 .data = &auo_b133xtn01,
747 }, { 798 }, {
799 .compatible = "avic,tm070ddh03",
800 .data = &avic_tm070ddh03,
801 }, {
748 .compatible = "chunghwa,claa101wa01a", 802 .compatible = "chunghwa,claa101wa01a",
749 .data = &chunghwa_claa101wa01a 803 .data = &chunghwa_claa101wa01a
750 }, { 804 }, {
@@ -763,6 +817,9 @@ static const struct of_device_id platform_of_match[] = {
763 .compatible = "foxlink,fl500wvr00-a0t", 817 .compatible = "foxlink,fl500wvr00-a0t",
764 .data = &foxlink_fl500wvr00_a0t, 818 .data = &foxlink_fl500wvr00_a0t,
765 }, { 819 }, {
820 .compatible = "giantplus,gpg482739qs5",
821 .data = &giantplus_gpg482739qs5
822 }, {
766 .compatible = "hannstar,hsd070pww1", 823 .compatible = "hannstar,hsd070pww1",
767 .data = &hannstar_hsd070pww1, 824 .data = &hannstar_hsd070pww1,
768 }, { 825 }, {
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index 651afad21f92..aeb5070c8363 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -91,6 +91,7 @@ struct sti_dvo {
91 struct dvo_config *config; 91 struct dvo_config *config;
92 bool enabled; 92 bool enabled;
93 struct drm_encoder *encoder; 93 struct drm_encoder *encoder;
94 struct drm_bridge *bridge;
94}; 95};
95 96
96struct sti_dvo_connector { 97struct sti_dvo_connector {
@@ -272,19 +273,12 @@ static void sti_dvo_bridge_nope(struct drm_bridge *bridge)
272 /* do nothing */ 273 /* do nothing */
273} 274}
274 275
275static void sti_dvo_brigde_destroy(struct drm_bridge *bridge)
276{
277 drm_bridge_cleanup(bridge);
278 kfree(bridge);
279}
280
281static const struct drm_bridge_funcs sti_dvo_bridge_funcs = { 276static const struct drm_bridge_funcs sti_dvo_bridge_funcs = {
282 .pre_enable = sti_dvo_pre_enable, 277 .pre_enable = sti_dvo_pre_enable,
283 .enable = sti_dvo_bridge_nope, 278 .enable = sti_dvo_bridge_nope,
284 .disable = sti_dvo_disable, 279 .disable = sti_dvo_disable,
285 .post_disable = sti_dvo_bridge_nope, 280 .post_disable = sti_dvo_bridge_nope,
286 .mode_set = sti_dvo_set_mode, 281 .mode_set = sti_dvo_set_mode,
287 .destroy = sti_dvo_brigde_destroy,
288}; 282};
289 283
290static int sti_dvo_connector_get_modes(struct drm_connector *connector) 284static int sti_dvo_connector_get_modes(struct drm_connector *connector)
@@ -416,8 +410,21 @@ static int sti_dvo_bind(struct device *dev, struct device *master, void *data)
416 return -ENOMEM; 410 return -ENOMEM;
417 411
418 bridge->driver_private = dvo; 412 bridge->driver_private = dvo;
419 drm_bridge_init(drm_dev, bridge, &sti_dvo_bridge_funcs); 413 bridge->funcs = &sti_dvo_bridge_funcs;
414 bridge->of_node = dvo->dev.of_node;
415 err = drm_bridge_add(bridge);
416 if (err) {
417 DRM_ERROR("Failed to add bridge\n");
418 return err;
419 }
420 420
421 err = drm_bridge_attach(drm_dev, bridge);
422 if (err) {
423 DRM_ERROR("Failed to attach bridge\n");
424 return err;
425 }
426
427 dvo->bridge = bridge;
421 encoder->bridge = bridge; 428 encoder->bridge = bridge;
422 connector->encoder = encoder; 429 connector->encoder = encoder;
423 dvo->encoder = encoder; 430 dvo->encoder = encoder;
@@ -446,7 +453,7 @@ static int sti_dvo_bind(struct device *dev, struct device *master, void *data)
446err_sysfs: 453err_sysfs:
447 drm_connector_unregister(drm_connector); 454 drm_connector_unregister(drm_connector);
448err_connector: 455err_connector:
449 drm_bridge_cleanup(bridge); 456 drm_bridge_remove(bridge);
450 drm_connector_cleanup(drm_connector); 457 drm_connector_cleanup(drm_connector);
451 return -EINVAL; 458 return -EINVAL;
452} 459}
@@ -454,7 +461,9 @@ err_connector:
454static void sti_dvo_unbind(struct device *dev, 461static void sti_dvo_unbind(struct device *dev,
455 struct device *master, void *data) 462 struct device *master, void *data)
456{ 463{
457 /* do nothing */ 464 struct sti_dvo *dvo = dev_get_drvdata(dev);
465
466 drm_bridge_remove(dvo->bridge);
458} 467}
459 468
460static const struct component_ops sti_dvo_ops = { 469static const struct component_ops sti_dvo_ops = {
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index 2ae9a9b73666..a9bbb081ecad 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -508,19 +508,12 @@ static void sti_hda_bridge_nope(struct drm_bridge *bridge)
508 /* do nothing */ 508 /* do nothing */
509} 509}
510 510
511static void sti_hda_brigde_destroy(struct drm_bridge *bridge)
512{
513 drm_bridge_cleanup(bridge);
514 kfree(bridge);
515}
516
517static const struct drm_bridge_funcs sti_hda_bridge_funcs = { 511static const struct drm_bridge_funcs sti_hda_bridge_funcs = {
518 .pre_enable = sti_hda_pre_enable, 512 .pre_enable = sti_hda_pre_enable,
519 .enable = sti_hda_bridge_nope, 513 .enable = sti_hda_bridge_nope,
520 .disable = sti_hda_disable, 514 .disable = sti_hda_disable,
521 .post_disable = sti_hda_bridge_nope, 515 .post_disable = sti_hda_bridge_nope,
522 .mode_set = sti_hda_set_mode, 516 .mode_set = sti_hda_set_mode,
523 .destroy = sti_hda_brigde_destroy,
524}; 517};
525 518
526static int sti_hda_connector_get_modes(struct drm_connector *connector) 519static int sti_hda_connector_get_modes(struct drm_connector *connector)
@@ -664,7 +657,8 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
664 return -ENOMEM; 657 return -ENOMEM;
665 658
666 bridge->driver_private = hda; 659 bridge->driver_private = hda;
667 drm_bridge_init(drm_dev, bridge, &sti_hda_bridge_funcs); 660 bridge->funcs = &sti_hda_bridge_funcs;
661 drm_bridge_attach(drm_dev, bridge);
668 662
669 encoder->bridge = bridge; 663 encoder->bridge = bridge;
670 connector->encoder = encoder; 664 connector->encoder = encoder;
@@ -693,7 +687,6 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
693err_sysfs: 687err_sysfs:
694 drm_connector_unregister(drm_connector); 688 drm_connector_unregister(drm_connector);
695err_connector: 689err_connector:
696 drm_bridge_cleanup(bridge);
697 drm_connector_cleanup(drm_connector); 690 drm_connector_cleanup(drm_connector);
698 return -EINVAL; 691 return -EINVAL;
699} 692}
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index d032e024b0b8..e840ca5de401 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -463,19 +463,12 @@ static void sti_hdmi_bridge_nope(struct drm_bridge *bridge)
463 /* do nothing */ 463 /* do nothing */
464} 464}
465 465
466static void sti_hdmi_brigde_destroy(struct drm_bridge *bridge)
467{
468 drm_bridge_cleanup(bridge);
469 kfree(bridge);
470}
471
472static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = { 466static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = {
473 .pre_enable = sti_hdmi_pre_enable, 467 .pre_enable = sti_hdmi_pre_enable,
474 .enable = sti_hdmi_bridge_nope, 468 .enable = sti_hdmi_bridge_nope,
475 .disable = sti_hdmi_disable, 469 .disable = sti_hdmi_disable,
476 .post_disable = sti_hdmi_bridge_nope, 470 .post_disable = sti_hdmi_bridge_nope,
477 .mode_set = sti_hdmi_set_mode, 471 .mode_set = sti_hdmi_set_mode,
478 .destroy = sti_hdmi_brigde_destroy,
479}; 472};
480 473
481static int sti_hdmi_connector_get_modes(struct drm_connector *connector) 474static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -635,7 +628,8 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
635 goto err_adapt; 628 goto err_adapt;
636 629
637 bridge->driver_private = hdmi; 630 bridge->driver_private = hdmi;
638 drm_bridge_init(drm_dev, bridge, &sti_hdmi_bridge_funcs); 631 bridge->funcs = &sti_hdmi_bridge_funcs;
632 drm_bridge_attach(drm_dev, bridge);
639 633
640 encoder->bridge = bridge; 634 encoder->bridge = bridge;
641 connector->encoder = encoder; 635 connector->encoder = encoder;
@@ -667,7 +661,6 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
667err_sysfs: 661err_sysfs:
668 drm_connector_unregister(drm_connector); 662 drm_connector_unregister(drm_connector);
669err_connector: 663err_connector:
670 drm_bridge_cleanup(bridge);
671 drm_connector_cleanup(drm_connector); 664 drm_connector_cleanup(drm_connector);
672err_adapt: 665err_adapt:
673 put_device(&hdmi->ddc_adapt->dev); 666 put_device(&hdmi->ddc_adapt->dev);