| .. | .. |
|---|
| 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 | |
|---|