.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2014 The Linux Foundation. All rights reserved. |
---|
3 | 4 | * Copyright (C) 2013 Red Hat |
---|
4 | 5 | * Author: Rob Clark <robdclark@gmail.com> |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
8 | | - * the Free Software Foundation. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
---|
11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
13 | | - * more details. |
---|
14 | | - * |
---|
15 | | - * You should have received a copy of the GNU General Public License along with |
---|
16 | | - * this program. If not, see <http://www.gnu.org/licenses/>. |
---|
17 | 6 | */ |
---|
18 | 7 | |
---|
19 | 8 | #include <linux/of_irq.h> |
---|
20 | 9 | #include <linux/of_gpio.h> |
---|
| 10 | + |
---|
| 11 | +#include <drm/drm_bridge_connector.h> |
---|
21 | 12 | |
---|
22 | 13 | #include <sound/hdmi-codec.h> |
---|
23 | 14 | #include "hdmi.h" |
---|
.. | .. |
---|
52 | 43 | struct hdmi *hdmi = dev_id; |
---|
53 | 44 | |
---|
54 | 45 | /* Process HPD: */ |
---|
55 | | - msm_hdmi_connector_irq(hdmi->connector); |
---|
| 46 | + msm_hdmi_hpd_irq(hdmi->bridge); |
---|
56 | 47 | |
---|
57 | 48 | /* Process DDC: */ |
---|
58 | 49 | msm_hdmi_i2c_irq(hdmi->i2c); |
---|
.. | .. |
---|
98 | 89 | |
---|
99 | 90 | phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0); |
---|
100 | 91 | if (!phy_node) { |
---|
101 | | - dev_err(&pdev->dev, "cannot find phy device\n"); |
---|
| 92 | + DRM_DEV_ERROR(&pdev->dev, "cannot find phy device\n"); |
---|
102 | 93 | return -ENXIO; |
---|
103 | 94 | } |
---|
104 | 95 | |
---|
.. | .. |
---|
108 | 99 | |
---|
109 | 100 | of_node_put(phy_node); |
---|
110 | 101 | |
---|
111 | | - if (!phy_pdev || !hdmi->phy) { |
---|
112 | | - dev_err(&pdev->dev, "phy driver is not ready\n"); |
---|
| 102 | + if (!phy_pdev) { |
---|
| 103 | + DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n"); |
---|
| 104 | + return -EPROBE_DEFER; |
---|
| 105 | + } |
---|
| 106 | + if (!hdmi->phy) { |
---|
| 107 | + DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n"); |
---|
| 108 | + put_device(&phy_pdev->dev); |
---|
113 | 109 | return -EPROBE_DEFER; |
---|
114 | 110 | } |
---|
115 | 111 | |
---|
.. | .. |
---|
148 | 144 | /* HDCP needs physical address of hdmi register */ |
---|
149 | 145 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
---|
150 | 146 | config->mmio_name); |
---|
| 147 | + if (!res) { |
---|
| 148 | + ret = -EINVAL; |
---|
| 149 | + goto fail; |
---|
| 150 | + } |
---|
151 | 151 | hdmi->mmio_phy_addr = res->start; |
---|
152 | 152 | |
---|
153 | 153 | hdmi->qfprom_mmio = msm_ioremap(pdev, |
---|
154 | 154 | config->qfprom_mmio_name, "HDMI_QFPROM"); |
---|
155 | 155 | if (IS_ERR(hdmi->qfprom_mmio)) { |
---|
156 | | - dev_info(&pdev->dev, "can't find qfprom resource\n"); |
---|
| 156 | + DRM_DEV_INFO(&pdev->dev, "can't find qfprom resource\n"); |
---|
157 | 157 | hdmi->qfprom_mmio = NULL; |
---|
158 | 158 | } |
---|
159 | 159 | |
---|
.. | .. |
---|
172 | 172 | config->hpd_reg_names[i]); |
---|
173 | 173 | if (IS_ERR(reg)) { |
---|
174 | 174 | ret = PTR_ERR(reg); |
---|
175 | | - dev_err(&pdev->dev, "failed to get hpd regulator: %s (%d)\n", |
---|
| 175 | + DRM_DEV_ERROR(&pdev->dev, "failed to get hpd regulator: %s (%d)\n", |
---|
176 | 176 | config->hpd_reg_names[i], ret); |
---|
177 | 177 | goto fail; |
---|
178 | 178 | } |
---|
.. | .. |
---|
195 | 195 | config->pwr_reg_names[i]); |
---|
196 | 196 | if (IS_ERR(reg)) { |
---|
197 | 197 | ret = PTR_ERR(reg); |
---|
198 | | - dev_err(&pdev->dev, "failed to get pwr regulator: %s (%d)\n", |
---|
| 198 | + DRM_DEV_ERROR(&pdev->dev, "failed to get pwr regulator: %s (%d)\n", |
---|
199 | 199 | config->pwr_reg_names[i], ret); |
---|
200 | 200 | goto fail; |
---|
201 | 201 | } |
---|
.. | .. |
---|
217 | 217 | clk = msm_clk_get(pdev, config->hpd_clk_names[i]); |
---|
218 | 218 | if (IS_ERR(clk)) { |
---|
219 | 219 | ret = PTR_ERR(clk); |
---|
220 | | - dev_err(&pdev->dev, "failed to get hpd clk: %s (%d)\n", |
---|
| 220 | + DRM_DEV_ERROR(&pdev->dev, "failed to get hpd clk: %s (%d)\n", |
---|
221 | 221 | config->hpd_clk_names[i], ret); |
---|
222 | 222 | goto fail; |
---|
223 | 223 | } |
---|
.. | .. |
---|
239 | 239 | clk = msm_clk_get(pdev, config->pwr_clk_names[i]); |
---|
240 | 240 | if (IS_ERR(clk)) { |
---|
241 | 241 | ret = PTR_ERR(clk); |
---|
242 | | - dev_err(&pdev->dev, "failed to get pwr clk: %s (%d)\n", |
---|
| 242 | + DRM_DEV_ERROR(&pdev->dev, "failed to get pwr clk: %s (%d)\n", |
---|
243 | 243 | config->pwr_clk_names[i], ret); |
---|
244 | 244 | goto fail; |
---|
245 | 245 | } |
---|
.. | .. |
---|
247 | 247 | hdmi->pwr_clks[i] = clk; |
---|
248 | 248 | } |
---|
249 | 249 | |
---|
| 250 | + hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN); |
---|
| 251 | + /* This will catch e.g. -EPROBE_DEFER */ |
---|
| 252 | + if (IS_ERR(hdmi->hpd_gpiod)) { |
---|
| 253 | + ret = PTR_ERR(hdmi->hpd_gpiod); |
---|
| 254 | + DRM_DEV_ERROR(&pdev->dev, "failed to get hpd gpio: (%d)\n", ret); |
---|
| 255 | + goto fail; |
---|
| 256 | + } |
---|
| 257 | + |
---|
| 258 | + if (!hdmi->hpd_gpiod) |
---|
| 259 | + DBG("failed to get HPD gpio"); |
---|
| 260 | + |
---|
| 261 | + if (hdmi->hpd_gpiod) |
---|
| 262 | + gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD"); |
---|
| 263 | + |
---|
250 | 264 | pm_runtime_enable(&pdev->dev); |
---|
251 | 265 | |
---|
252 | 266 | hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0); |
---|
| 267 | + if (!hdmi->workq) { |
---|
| 268 | + ret = -ENOMEM; |
---|
| 269 | + goto fail; |
---|
| 270 | + } |
---|
253 | 271 | |
---|
254 | 272 | hdmi->i2c = msm_hdmi_i2c_init(hdmi); |
---|
255 | 273 | if (IS_ERR(hdmi->i2c)) { |
---|
256 | 274 | ret = PTR_ERR(hdmi->i2c); |
---|
257 | | - dev_err(&pdev->dev, "failed to get i2c: %d\n", ret); |
---|
| 275 | + DRM_DEV_ERROR(&pdev->dev, "failed to get i2c: %d\n", ret); |
---|
258 | 276 | hdmi->i2c = NULL; |
---|
259 | 277 | goto fail; |
---|
260 | 278 | } |
---|
261 | 279 | |
---|
262 | 280 | ret = msm_hdmi_get_phy(hdmi); |
---|
263 | 281 | if (ret) { |
---|
264 | | - dev_err(&pdev->dev, "failed to get phy\n"); |
---|
| 282 | + DRM_DEV_ERROR(&pdev->dev, "failed to get phy\n"); |
---|
265 | 283 | goto fail; |
---|
266 | 284 | } |
---|
267 | 285 | |
---|
.. | .. |
---|
295 | 313 | struct platform_device *pdev = hdmi->pdev; |
---|
296 | 314 | int ret; |
---|
297 | 315 | |
---|
| 316 | + if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) { |
---|
| 317 | + DRM_DEV_ERROR(dev->dev, "too many bridges\n"); |
---|
| 318 | + return -ENOSPC; |
---|
| 319 | + } |
---|
| 320 | + |
---|
298 | 321 | hdmi->dev = dev; |
---|
299 | 322 | hdmi->encoder = encoder; |
---|
300 | 323 | |
---|
.. | .. |
---|
303 | 326 | hdmi->bridge = msm_hdmi_bridge_init(hdmi); |
---|
304 | 327 | if (IS_ERR(hdmi->bridge)) { |
---|
305 | 328 | ret = PTR_ERR(hdmi->bridge); |
---|
306 | | - dev_err(dev->dev, "failed to create HDMI bridge: %d\n", ret); |
---|
| 329 | + DRM_DEV_ERROR(dev->dev, "failed to create HDMI bridge: %d\n", ret); |
---|
307 | 330 | hdmi->bridge = NULL; |
---|
308 | 331 | goto fail; |
---|
309 | 332 | } |
---|
310 | 333 | |
---|
311 | | - hdmi->connector = msm_hdmi_connector_init(hdmi); |
---|
| 334 | + hdmi->connector = drm_bridge_connector_init(hdmi->dev, encoder); |
---|
312 | 335 | if (IS_ERR(hdmi->connector)) { |
---|
313 | 336 | ret = PTR_ERR(hdmi->connector); |
---|
314 | | - dev_err(dev->dev, "failed to create HDMI connector: %d\n", ret); |
---|
| 337 | + DRM_DEV_ERROR(dev->dev, "failed to create HDMI connector: %d\n", ret); |
---|
315 | 338 | hdmi->connector = NULL; |
---|
316 | 339 | goto fail; |
---|
317 | 340 | } |
---|
318 | 341 | |
---|
| 342 | + drm_connector_attach_encoder(hdmi->connector, hdmi->encoder); |
---|
| 343 | + |
---|
319 | 344 | hdmi->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
---|
320 | | - if (hdmi->irq < 0) { |
---|
321 | | - ret = hdmi->irq; |
---|
322 | | - dev_err(dev->dev, "failed to get irq: %d\n", ret); |
---|
| 345 | + if (!hdmi->irq) { |
---|
| 346 | + ret = -EINVAL; |
---|
| 347 | + DRM_DEV_ERROR(dev->dev, "failed to get irq\n"); |
---|
323 | 348 | goto fail; |
---|
324 | 349 | } |
---|
325 | 350 | |
---|
326 | | - ret = devm_request_irq(&pdev->dev, hdmi->irq, |
---|
327 | | - msm_hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, |
---|
| 351 | + ret = devm_request_irq(dev->dev, hdmi->irq, |
---|
| 352 | + msm_hdmi_irq, IRQF_TRIGGER_HIGH, |
---|
328 | 353 | "hdmi_isr", hdmi); |
---|
329 | 354 | if (ret < 0) { |
---|
330 | | - dev_err(dev->dev, "failed to request IRQ%u: %d\n", |
---|
| 355 | + DRM_DEV_ERROR(dev->dev, "failed to request IRQ%u: %d\n", |
---|
331 | 356 | hdmi->irq, ret); |
---|
332 | 357 | goto fail; |
---|
333 | 358 | } |
---|
334 | 359 | |
---|
335 | | - ret = msm_hdmi_hpd_enable(hdmi->connector); |
---|
| 360 | + drm_bridge_connector_enable_hpd(hdmi->connector); |
---|
| 361 | + |
---|
| 362 | + ret = msm_hdmi_hpd_enable(hdmi->bridge); |
---|
336 | 363 | if (ret < 0) { |
---|
337 | 364 | DRM_DEV_ERROR(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret); |
---|
338 | 365 | goto fail; |
---|
339 | 366 | } |
---|
340 | | - |
---|
341 | | - encoder->bridge = hdmi->bridge; |
---|
342 | 367 | |
---|
343 | 368 | priv->bridges[priv->num_bridges++] = hdmi->bridge; |
---|
344 | 369 | priv->connectors[priv->num_connectors++] = hdmi->connector; |
---|
.. | .. |
---|
422 | 447 | .hpd_freq = hpd_clk_freq_8x74, |
---|
423 | 448 | }; |
---|
424 | 449 | |
---|
425 | | -static const struct { |
---|
426 | | - const char *name; |
---|
427 | | - const bool output; |
---|
428 | | - const int value; |
---|
429 | | - const char *label; |
---|
430 | | -} msm_hdmi_gpio_pdata[] = { |
---|
431 | | - { "qcom,hdmi-tx-ddc-clk", true, 1, "HDMI_DDC_CLK" }, |
---|
432 | | - { "qcom,hdmi-tx-ddc-data", true, 1, "HDMI_DDC_DATA" }, |
---|
433 | | - { "qcom,hdmi-tx-hpd", false, 1, "HDMI_HPD" }, |
---|
434 | | - { "qcom,hdmi-tx-mux-en", true, 1, "HDMI_MUX_EN" }, |
---|
435 | | - { "qcom,hdmi-tx-mux-sel", true, 0, "HDMI_MUX_SEL" }, |
---|
436 | | - { "qcom,hdmi-tx-mux-lpm", true, 1, "HDMI_MUX_LPM" }, |
---|
437 | | -}; |
---|
438 | | - |
---|
439 | | -static int msm_hdmi_get_gpio(struct device_node *of_node, const char *name) |
---|
440 | | -{ |
---|
441 | | - int gpio; |
---|
442 | | - |
---|
443 | | - /* try with the gpio names as in the table (downstream bindings) */ |
---|
444 | | - gpio = of_get_named_gpio(of_node, name, 0); |
---|
445 | | - if (gpio < 0) { |
---|
446 | | - char name2[32]; |
---|
447 | | - |
---|
448 | | - /* try with the gpio names as in the upstream bindings */ |
---|
449 | | - snprintf(name2, sizeof(name2), "%s-gpios", name); |
---|
450 | | - gpio = of_get_named_gpio(of_node, name2, 0); |
---|
451 | | - if (gpio < 0) { |
---|
452 | | - char name3[32]; |
---|
453 | | - |
---|
454 | | - /* |
---|
455 | | - * try again after stripping out the "qcom,hdmi-tx" |
---|
456 | | - * prefix. This is mainly to match "hpd-gpios" used |
---|
457 | | - * in the upstream bindings |
---|
458 | | - */ |
---|
459 | | - if (sscanf(name2, "qcom,hdmi-tx-%s", name3)) |
---|
460 | | - gpio = of_get_named_gpio(of_node, name3, 0); |
---|
461 | | - } |
---|
462 | | - |
---|
463 | | - if (gpio < 0) { |
---|
464 | | - DBG("failed to get gpio: %s (%d)", name, gpio); |
---|
465 | | - gpio = -1; |
---|
466 | | - } |
---|
467 | | - } |
---|
468 | | - return gpio; |
---|
469 | | -} |
---|
470 | | - |
---|
471 | 450 | /* |
---|
472 | 451 | * HDMI audio codec callbacks |
---|
473 | 452 | */ |
---|
.. | .. |
---|
482 | 461 | unsigned int level_shift = 0; /* 0dB */ |
---|
483 | 462 | bool down_mix = false; |
---|
484 | 463 | |
---|
485 | | - dev_dbg(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate, |
---|
| 464 | + DRM_DEV_DEBUG(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate, |
---|
486 | 465 | params->sample_width, params->cea.channels); |
---|
487 | 466 | |
---|
488 | 467 | switch (params->cea.channels) { |
---|
.. | .. |
---|
533 | 512 | rate = HDMI_SAMPLE_RATE_192KHZ; |
---|
534 | 513 | break; |
---|
535 | 514 | default: |
---|
536 | | - dev_err(dev, "rate[%d] not supported!\n", |
---|
| 515 | + DRM_DEV_ERROR(dev, "rate[%d] not supported!\n", |
---|
537 | 516 | params->sample_rate); |
---|
538 | 517 | return -EINVAL; |
---|
539 | 518 | } |
---|
.. | .. |
---|
577 | 556 | { |
---|
578 | 557 | struct drm_device *drm = dev_get_drvdata(master); |
---|
579 | 558 | struct msm_drm_private *priv = drm->dev_private; |
---|
580 | | - static struct hdmi_platform_config *hdmi_cfg; |
---|
| 559 | + struct hdmi_platform_config *hdmi_cfg; |
---|
581 | 560 | struct hdmi *hdmi; |
---|
582 | 561 | struct device_node *of_node = dev->of_node; |
---|
583 | | - int i, err; |
---|
| 562 | + int err; |
---|
584 | 563 | |
---|
585 | 564 | hdmi_cfg = (struct hdmi_platform_config *) |
---|
586 | 565 | of_device_get_match_data(dev); |
---|
587 | 566 | if (!hdmi_cfg) { |
---|
588 | | - dev_err(dev, "unknown hdmi_cfg: %s\n", of_node->name); |
---|
| 567 | + DRM_DEV_ERROR(dev, "unknown hdmi_cfg: %pOFn\n", of_node); |
---|
589 | 568 | return -ENXIO; |
---|
590 | 569 | } |
---|
591 | 570 | |
---|
592 | 571 | hdmi_cfg->mmio_name = "core_physical"; |
---|
593 | 572 | hdmi_cfg->qfprom_mmio_name = "qfprom_physical"; |
---|
594 | | - |
---|
595 | | - for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) { |
---|
596 | | - hdmi_cfg->gpios[i].num = msm_hdmi_get_gpio(of_node, |
---|
597 | | - msm_hdmi_gpio_pdata[i].name); |
---|
598 | | - hdmi_cfg->gpios[i].output = msm_hdmi_gpio_pdata[i].output; |
---|
599 | | - hdmi_cfg->gpios[i].value = msm_hdmi_gpio_pdata[i].value; |
---|
600 | | - hdmi_cfg->gpios[i].label = msm_hdmi_gpio_pdata[i].label; |
---|
601 | | - } |
---|
602 | 573 | |
---|
603 | 574 | dev->platform_data = hdmi_cfg; |
---|
604 | 575 | |
---|