1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2016 BayLibre, SAS 4 * Author: Neil Armstrong <narmstrong@baylibre.com> 5 * Copyright (C) 2015 Amlogic, Inc. All rights reserved. 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/component.h> 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/of_device.h> 13 #include <linux/of_graph.h> 14 #include <linux/regulator/consumer.h> 15 #include <linux/reset.h> 16 17 #include <drm/bridge/dw_hdmi.h> 18 #include <drm/drm_atomic_helper.h> 19 #include <drm/drm_bridge.h> 20 #include <drm/drm_device.h> 21 #include <drm/drm_edid.h> 22 #include <drm/drm_probe_helper.h> 23 #include <drm/drm_print.h> 24 25 #include <linux/media-bus-format.h> 26 #include <linux/videodev2.h> 27 28 #include "meson_drv.h" 29 #include "meson_dw_hdmi.h" 30 #include "meson_registers.h" 31 #include "meson_vclk.h" 32 #include "meson_venc.h" 33 34 #define DRIVER_NAME "meson-dw-hdmi" 35 #define DRIVER_DESC "Amlogic Meson HDMI-TX DRM driver" 36 37 /** 38 * DOC: HDMI Output 39 * 40 * HDMI Output is composed of : 41 * 42 * - A Synopsys DesignWare HDMI Controller IP 43 * - A TOP control block controlling the Clocks and PHY 44 * - A custom HDMI PHY in order convert video to TMDS signal 45 * 46 * .. code:: 47 * 48 * ___________________________________ 49 * | HDMI TOP |<= HPD 50 * |___________________________________| 51 * | | | 52 * | Synopsys HDMI | HDMI PHY |=> TMDS 53 * | Controller |________________| 54 * |___________________________________|<=> DDC 55 * 56 * 57 * The HDMI TOP block only supports HPD sensing. 58 * The Synopsys HDMI Controller interrupt is routed 59 * through the TOP Block interrupt. 60 * Communication to the TOP Block and the Synopsys 61 * HDMI Controller is done a pair of addr+read/write 62 * registers. 63 * The HDMI PHY is configured by registers in the 64 * HHI register block. 65 * 66 * Pixel data arrives in 4:4:4 format from the VENC 67 * block and the VPU HDMI mux selects either the ENCI 68 * encoder for the 576i or 480i formats or the ENCP 69 * encoder for all the other formats including 70 * interlaced HD formats. 71 * The VENC uses a DVI encoder on top of the ENCI 72 * or ENCP encoders to generate DVI timings for the 73 * HDMI controller. 74 * 75 * GXBB, GXL and GXM embeds the Synopsys DesignWare 76 * HDMI TX IP version 2.01a with HDCP and I2C & S/PDIF 77 * audio source interfaces. 78 * 79 * We handle the following features : 80 * 81 * - HPD Rise & Fall interrupt 82 * - HDMI Controller Interrupt 83 * - HDMI PHY Init for 480i to 1080p60 84 * - VENC & HDMI Clock setup for 480i to 1080p60 85 * - VENC Mode setup for 480i to 1080p60 86 * 87 * What is missing : 88 * 89 * - PHY, Clock and Mode setup for 2k && 4k modes 90 * - SDDC Scrambling mode for HDMI 2.0a 91 * - HDCP Setup 92 * - CEC Management 93 */ 94 95 /* TOP Block Communication Channel */ 96 #define HDMITX_TOP_ADDR_REG 0x0 97 #define HDMITX_TOP_DATA_REG 0x4 98 #define HDMITX_TOP_CTRL_REG 0x8 99 #define HDMITX_TOP_G12A_OFFSET 0x8000 100 101 /* Controller Communication Channel */ 102 #define HDMITX_DWC_ADDR_REG 0x10 103 #define HDMITX_DWC_DATA_REG 0x14 104 #define HDMITX_DWC_CTRL_REG 0x18 105 106 /* HHI Registers */ 107 #define HHI_MEM_PD_REG0 0x100 /* 0x40 */ 108 #define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */ 109 #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */ 110 #define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */ 111 #define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */ 112 #define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */ 113 #define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */ 114 #define HHI_HDMI_PHY_CNTL5 0x3b4 /* 0xed */ 115 116 static DEFINE_SPINLOCK(reg_lock); 117 118 enum meson_venc_source { 119 MESON_VENC_SOURCE_NONE = 0, 120 MESON_VENC_SOURCE_ENCI = 1, 121 MESON_VENC_SOURCE_ENCP = 2, 122 }; 123 124 struct meson_dw_hdmi; 125 126 struct meson_dw_hdmi_data { 127 unsigned int (*top_read)(struct meson_dw_hdmi *dw_hdmi, 128 unsigned int addr); 129 void (*top_write)(struct meson_dw_hdmi *dw_hdmi, 130 unsigned int addr, unsigned int data); 131 unsigned int (*dwc_read)(struct meson_dw_hdmi *dw_hdmi, 132 unsigned int addr); 133 void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi, 134 unsigned int addr, unsigned int data); 135 }; 136 137 struct meson_dw_hdmi { 138 struct drm_encoder encoder; 139 struct drm_bridge bridge; 140 struct dw_hdmi_plat_data dw_plat_data; 141 struct meson_drm *priv; 142 struct device *dev; 143 void __iomem *hdmitx; 144 const struct meson_dw_hdmi_data *data; 145 struct reset_control *hdmitx_apb; 146 struct reset_control *hdmitx_ctrl; 147 struct reset_control *hdmitx_phy; 148 struct clk *hdmi_pclk; 149 struct clk *venci_clk; 150 struct regulator *hdmi_supply; 151 u32 irq_stat; 152 struct dw_hdmi *hdmi; 153 unsigned long output_bus_fmt; 154 }; 155 #define encoder_to_meson_dw_hdmi(x) \ 156 container_of(x, struct meson_dw_hdmi, encoder) 157 #define bridge_to_meson_dw_hdmi(x) \ 158 container_of(x, struct meson_dw_hdmi, bridge) 159 160 static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi, 161 const char *compat) 162 { 163 return of_device_is_compatible(dw_hdmi->dev->of_node, compat); 164 } 165 166 /* PHY (via TOP bridge) and Controller dedicated register interface */ 167 168 static unsigned int dw_hdmi_top_read(struct meson_dw_hdmi *dw_hdmi, 169 unsigned int addr) 170 { 171 unsigned long flags; 172 unsigned int data; 173 174 spin_lock_irqsave(®_lock, flags); 175 176 /* ADDR must be written twice */ 177 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 178 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 179 180 /* Read needs a second DATA read */ 181 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 182 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 183 184 spin_unlock_irqrestore(®_lock, flags); 185 186 return data; 187 } 188 189 static unsigned int dw_hdmi_g12a_top_read(struct meson_dw_hdmi *dw_hdmi, 190 unsigned int addr) 191 { 192 return readl(dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2)); 193 } 194 195 static inline void dw_hdmi_top_write(struct meson_dw_hdmi *dw_hdmi, 196 unsigned int addr, unsigned int data) 197 { 198 unsigned long flags; 199 200 spin_lock_irqsave(®_lock, flags); 201 202 /* ADDR must be written twice */ 203 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 204 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 205 206 /* Write needs single DATA write */ 207 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 208 209 spin_unlock_irqrestore(®_lock, flags); 210 } 211 212 static inline void dw_hdmi_g12a_top_write(struct meson_dw_hdmi *dw_hdmi, 213 unsigned int addr, unsigned int data) 214 { 215 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2)); 216 } 217 218 /* Helper to change specific bits in PHY registers */ 219 static inline void dw_hdmi_top_write_bits(struct meson_dw_hdmi *dw_hdmi, 220 unsigned int addr, 221 unsigned int mask, 222 unsigned int val) 223 { 224 unsigned int data = dw_hdmi->data->top_read(dw_hdmi, addr); 225 226 data &= ~mask; 227 data |= val; 228 229 dw_hdmi->data->top_write(dw_hdmi, addr, data); 230 } 231 232 static unsigned int dw_hdmi_dwc_read(struct meson_dw_hdmi *dw_hdmi, 233 unsigned int addr) 234 { 235 unsigned long flags; 236 unsigned int data; 237 238 spin_lock_irqsave(®_lock, flags); 239 240 /* ADDR must be written twice */ 241 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 242 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 243 244 /* Read needs a second DATA read */ 245 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 246 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 247 248 spin_unlock_irqrestore(®_lock, flags); 249 250 return data; 251 } 252 253 static unsigned int dw_hdmi_g12a_dwc_read(struct meson_dw_hdmi *dw_hdmi, 254 unsigned int addr) 255 { 256 return readb(dw_hdmi->hdmitx + addr); 257 } 258 259 static inline void dw_hdmi_dwc_write(struct meson_dw_hdmi *dw_hdmi, 260 unsigned int addr, unsigned int data) 261 { 262 unsigned long flags; 263 264 spin_lock_irqsave(®_lock, flags); 265 266 /* ADDR must be written twice */ 267 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 268 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 269 270 /* Write needs single DATA write */ 271 writel(data, dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 272 273 spin_unlock_irqrestore(®_lock, flags); 274 } 275 276 static inline void dw_hdmi_g12a_dwc_write(struct meson_dw_hdmi *dw_hdmi, 277 unsigned int addr, unsigned int data) 278 { 279 writeb(data, dw_hdmi->hdmitx + addr); 280 } 281 282 /* Helper to change specific bits in controller registers */ 283 static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi, 284 unsigned int addr, 285 unsigned int mask, 286 unsigned int val) 287 { 288 unsigned int data = dw_hdmi->data->dwc_read(dw_hdmi, addr); 289 290 data &= ~mask; 291 data |= val; 292 293 dw_hdmi->data->dwc_write(dw_hdmi, addr, data); 294 } 295 296 /* Bridge */ 297 298 /* Setup PHY bandwidth modes */ 299 static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, 300 struct drm_display_mode *mode) 301 { 302 struct meson_drm *priv = dw_hdmi->priv; 303 unsigned int pixel_clock = mode->clock; 304 305 /* For 420, pixel clock is half unlike venc clock */ 306 if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) 307 pixel_clock /= 2; 308 309 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || 310 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { 311 if (pixel_clock >= 371250) { 312 /* 5.94Gbps, 3.7125Gbps */ 313 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x333d3282); 314 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b); 315 } else if (pixel_clock >= 297000) { 316 /* 2.97Gbps */ 317 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382); 318 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b); 319 } else if (pixel_clock >= 148500) { 320 /* 1.485Gbps */ 321 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303362); 322 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2016315b); 323 } else { 324 /* 742.5Mbps, and below */ 325 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33604142); 326 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x0016315b); 327 } 328 } else if (dw_hdmi_is_compatible(dw_hdmi, 329 "amlogic,meson-gxbb-dw-hdmi")) { 330 if (pixel_clock >= 371250) { 331 /* 5.94Gbps, 3.7125Gbps */ 332 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33353245); 333 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2100115b); 334 } else if (pixel_clock >= 297000) { 335 /* 2.97Gbps */ 336 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33634283); 337 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0xb000115b); 338 } else { 339 /* 1.485Gbps, and below */ 340 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33632122); 341 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2000115b); 342 } 343 } else if (dw_hdmi_is_compatible(dw_hdmi, 344 "amlogic,meson-g12a-dw-hdmi")) { 345 if (pixel_clock >= 371250) { 346 /* 5.94Gbps, 3.7125Gbps */ 347 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x37eb65c4); 348 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 349 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x0000080b); 350 } else if (pixel_clock >= 297000) { 351 /* 2.97Gbps */ 352 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb6262); 353 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 354 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003); 355 } else { 356 /* 1.485Gbps, and below */ 357 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb4242); 358 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 359 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003); 360 } 361 } 362 } 363 364 static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) 365 { 366 struct meson_drm *priv = dw_hdmi->priv; 367 368 /* Enable and software reset */ 369 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xf); 370 371 mdelay(2); 372 373 /* Enable and unreset */ 374 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xe); 375 376 mdelay(2); 377 } 378 379 static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, 380 const struct drm_display_mode *mode) 381 { 382 struct meson_drm *priv = dw_hdmi->priv; 383 int vic = drm_match_cea_mode(mode); 384 unsigned int phy_freq; 385 unsigned int vclk_freq; 386 unsigned int venc_freq; 387 unsigned int hdmi_freq; 388 389 vclk_freq = mode->clock; 390 391 /* For 420, pixel clock is half unlike venc clock */ 392 if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) 393 vclk_freq /= 2; 394 395 /* TMDS clock is pixel_clock * 10 */ 396 phy_freq = vclk_freq * 10; 397 398 if (!vic) { 399 meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, phy_freq, 400 vclk_freq, vclk_freq, vclk_freq, false); 401 return; 402 } 403 404 /* 480i/576i needs global pixel doubling */ 405 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 406 vclk_freq *= 2; 407 408 venc_freq = vclk_freq; 409 hdmi_freq = vclk_freq; 410 411 /* VENC double pixels for 1080i, 720p and YUV420 modes */ 412 if (meson_venc_hdmi_venc_repeat(vic) || 413 dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) 414 venc_freq *= 2; 415 416 vclk_freq = max(venc_freq, hdmi_freq); 417 418 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 419 venc_freq /= 2; 420 421 DRM_DEBUG_DRIVER("vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", 422 phy_freq, vclk_freq, venc_freq, hdmi_freq, 423 priv->venc.hdmi_use_enci); 424 425 meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, phy_freq, vclk_freq, 426 venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); 427 } 428 429 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, 430 struct drm_display_mode *mode) 431 { 432 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 433 struct meson_drm *priv = dw_hdmi->priv; 434 unsigned int wr_clk = 435 readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING)); 436 437 DRM_DEBUG_DRIVER("\"%s\" div%d\n", mode->name, 438 mode->clock > 340000 ? 40 : 10); 439 440 /* Enable clocks */ 441 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); 442 443 /* Bring HDMITX MEM output of power down */ 444 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); 445 446 /* Bring out of reset */ 447 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0); 448 449 /* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */ 450 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL, 451 0x3, 0x3); 452 453 /* Enable cec_clk and hdcp22_tmdsclk_en */ 454 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL, 455 0x3 << 4, 0x3 << 4); 456 457 /* Enable normal output to PHY */ 458 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); 459 460 /* TMDS pattern setup */ 461 if (mode->clock > 340000 && 462 dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_YUV8_1X24) { 463 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 464 0); 465 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 466 0x03ff03ff); 467 } else { 468 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 469 0x001f001f); 470 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 471 0x001f001f); 472 } 473 474 /* Load TMDS pattern */ 475 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1); 476 msleep(20); 477 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); 478 479 /* Setup PHY parameters */ 480 meson_hdmi_phy_setup_mode(dw_hdmi, mode); 481 482 /* Setup PHY */ 483 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 484 0xffff << 16, 0x0390 << 16); 485 486 /* BIT_INVERT */ 487 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || 488 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || 489 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi")) 490 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 491 BIT(17), 0); 492 else 493 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 494 BIT(17), BIT(17)); 495 496 /* Disable clock, fifo, fifo_wr */ 497 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0); 498 499 dw_hdmi_set_high_tmds_clock_ratio(hdmi); 500 501 msleep(100); 502 503 /* Reset PHY 3 times in a row */ 504 meson_dw_hdmi_phy_reset(dw_hdmi); 505 meson_dw_hdmi_phy_reset(dw_hdmi); 506 meson_dw_hdmi_phy_reset(dw_hdmi); 507 508 /* Temporary Disable VENC video stream */ 509 if (priv->venc.hdmi_use_enci) 510 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 511 else 512 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 513 514 /* Temporary Disable HDMI video stream to HDMI-TX */ 515 writel_bits_relaxed(0x3, 0, 516 priv->io_base + _REG(VPU_HDMI_SETTING)); 517 writel_bits_relaxed(0xf << 8, 0, 518 priv->io_base + _REG(VPU_HDMI_SETTING)); 519 520 /* Re-Enable VENC video stream */ 521 if (priv->venc.hdmi_use_enci) 522 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 523 else 524 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); 525 526 /* Push back HDMI clock settings */ 527 writel_bits_relaxed(0xf << 8, wr_clk & (0xf << 8), 528 priv->io_base + _REG(VPU_HDMI_SETTING)); 529 530 /* Enable and Select HDMI video source for HDMI-TX */ 531 if (priv->venc.hdmi_use_enci) 532 writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCI, 533 priv->io_base + _REG(VPU_HDMI_SETTING)); 534 else 535 writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCP, 536 priv->io_base + _REG(VPU_HDMI_SETTING)); 537 538 return 0; 539 } 540 541 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, 542 void *data) 543 { 544 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 545 struct meson_drm *priv = dw_hdmi->priv; 546 547 DRM_DEBUG_DRIVER("\n"); 548 549 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); 550 } 551 552 static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi, 553 void *data) 554 { 555 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 556 557 return !!dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_STAT0) ? 558 connector_status_connected : connector_status_disconnected; 559 } 560 561 static void dw_hdmi_setup_hpd(struct dw_hdmi *hdmi, 562 void *data) 563 { 564 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 565 566 /* Setup HPD Filter */ 567 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_HPD_FILTER, 568 (0xa << 12) | 0xa0); 569 570 /* Clear interrupts */ 571 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, 572 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL); 573 574 /* Unmask interrupts */ 575 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_INTR_MASKN, 576 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL, 577 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL); 578 } 579 580 static const struct dw_hdmi_phy_ops meson_dw_hdmi_phy_ops = { 581 .init = dw_hdmi_phy_init, 582 .disable = dw_hdmi_phy_disable, 583 .read_hpd = dw_hdmi_read_hpd, 584 .setup_hpd = dw_hdmi_setup_hpd, 585 }; 586 587 static irqreturn_t dw_hdmi_top_irq(int irq, void *dev_id) 588 { 589 struct meson_dw_hdmi *dw_hdmi = dev_id; 590 u32 stat; 591 592 stat = dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_INTR_STAT); 593 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, stat); 594 595 /* HPD Events, handle in the threaded interrupt handler */ 596 if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) { 597 dw_hdmi->irq_stat = stat; 598 return IRQ_WAKE_THREAD; 599 } 600 601 /* HDMI Controller Interrupt */ 602 if (stat & 1) 603 return IRQ_NONE; 604 605 /* TOFIX Handle HDCP Interrupts */ 606 607 return IRQ_HANDLED; 608 } 609 610 /* Threaded interrupt handler to manage HPD events */ 611 static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) 612 { 613 struct meson_dw_hdmi *dw_hdmi = dev_id; 614 u32 stat = dw_hdmi->irq_stat; 615 616 /* HPD Events */ 617 if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) { 618 bool hpd_connected = false; 619 620 if (stat & HDMITX_TOP_INTR_HPD_RISE) 621 hpd_connected = true; 622 623 dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected, 624 hpd_connected); 625 626 drm_helper_hpd_irq_event(dw_hdmi->encoder.dev); 627 } 628 629 return IRQ_HANDLED; 630 } 631 632 static enum drm_mode_status 633 dw_hdmi_mode_valid(struct drm_connector *connector, 634 const struct drm_display_mode *mode) 635 { 636 struct meson_drm *priv = connector->dev->dev_private; 637 bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported; 638 unsigned int phy_freq; 639 unsigned int vclk_freq; 640 unsigned int venc_freq; 641 unsigned int hdmi_freq; 642 int vic = drm_match_cea_mode(mode); 643 enum drm_mode_status status; 644 645 DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); 646 647 /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */ 648 if (connector->display_info.max_tmds_clock && 649 mode->clock > connector->display_info.max_tmds_clock && 650 !drm_mode_is_420_only(&connector->display_info, mode) && 651 !drm_mode_is_420_also(&connector->display_info, mode)) 652 return MODE_BAD; 653 654 /* Check against non-VIC supported modes */ 655 if (!vic) { 656 status = meson_venc_hdmi_supported_mode(mode); 657 if (status != MODE_OK) 658 return status; 659 660 return meson_vclk_dmt_supported_freq(priv, mode->clock); 661 /* Check against supported VIC modes */ 662 } else if (!meson_venc_hdmi_supported_vic(vic)) 663 return MODE_BAD; 664 665 vclk_freq = mode->clock; 666 667 /* For 420, pixel clock is half unlike venc clock */ 668 if (drm_mode_is_420_only(&connector->display_info, mode) || 669 (!is_hdmi2_sink && 670 drm_mode_is_420_also(&connector->display_info, mode))) 671 vclk_freq /= 2; 672 673 /* TMDS clock is pixel_clock * 10 */ 674 phy_freq = vclk_freq * 10; 675 676 /* 480i/576i needs global pixel doubling */ 677 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 678 vclk_freq *= 2; 679 680 venc_freq = vclk_freq; 681 hdmi_freq = vclk_freq; 682 683 /* VENC double pixels for 1080i, 720p and YUV420 modes */ 684 if (meson_venc_hdmi_venc_repeat(vic) || 685 drm_mode_is_420_only(&connector->display_info, mode) || 686 (!is_hdmi2_sink && 687 drm_mode_is_420_also(&connector->display_info, mode))) 688 venc_freq *= 2; 689 690 vclk_freq = max(venc_freq, hdmi_freq); 691 692 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 693 venc_freq /= 2; 694 695 dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", 696 __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); 697 698 return meson_vclk_vic_supported_freq(phy_freq, vclk_freq); 699 } 700 701 /* Encoder */ 702 703 static const u32 meson_dw_hdmi_out_bus_fmts[] = { 704 MEDIA_BUS_FMT_YUV8_1X24, 705 MEDIA_BUS_FMT_UYYVYY8_0_5X24, 706 }; 707 708 static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder) 709 { 710 drm_encoder_cleanup(encoder); 711 } 712 713 static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = { 714 .destroy = meson_venc_hdmi_encoder_destroy, 715 }; 716 717 static u32 * 718 meson_venc_hdmi_encoder_get_inp_bus_fmts(struct drm_bridge *bridge, 719 struct drm_bridge_state *bridge_state, 720 struct drm_crtc_state *crtc_state, 721 struct drm_connector_state *conn_state, 722 u32 output_fmt, 723 unsigned int *num_input_fmts) 724 { 725 u32 *input_fmts = NULL; 726 int i; 727 728 *num_input_fmts = 0; 729 730 for (i = 0 ; i < ARRAY_SIZE(meson_dw_hdmi_out_bus_fmts) ; ++i) { 731 if (output_fmt == meson_dw_hdmi_out_bus_fmts[i]) { 732 *num_input_fmts = 1; 733 input_fmts = kcalloc(*num_input_fmts, 734 sizeof(*input_fmts), 735 GFP_KERNEL); 736 if (!input_fmts) 737 return NULL; 738 739 input_fmts[0] = output_fmt; 740 741 break; 742 } 743 } 744 745 return input_fmts; 746 } 747 748 static int meson_venc_hdmi_encoder_atomic_check(struct drm_bridge *bridge, 749 struct drm_bridge_state *bridge_state, 750 struct drm_crtc_state *crtc_state, 751 struct drm_connector_state *conn_state) 752 { 753 struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); 754 755 dw_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format; 756 757 DRM_DEBUG_DRIVER("output_bus_fmt %lx\n", dw_hdmi->output_bus_fmt); 758 759 return 0; 760 } 761 762 static void meson_venc_hdmi_encoder_disable(struct drm_bridge *bridge) 763 { 764 struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); 765 struct meson_drm *priv = dw_hdmi->priv; 766 767 DRM_DEBUG_DRIVER("\n"); 768 769 writel_bits_relaxed(0x3, 0, 770 priv->io_base + _REG(VPU_HDMI_SETTING)); 771 772 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 773 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 774 } 775 776 static void meson_venc_hdmi_encoder_enable(struct drm_bridge *bridge) 777 { 778 struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); 779 struct meson_drm *priv = dw_hdmi->priv; 780 781 DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); 782 783 if (priv->venc.hdmi_use_enci) 784 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 785 else 786 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); 787 } 788 789 static void meson_venc_hdmi_encoder_mode_set(struct drm_bridge *bridge, 790 const struct drm_display_mode *mode, 791 const struct drm_display_mode *adjusted_mode) 792 { 793 struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge); 794 struct meson_drm *priv = dw_hdmi->priv; 795 int vic = drm_match_cea_mode(mode); 796 unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR; 797 bool yuv420_mode = false; 798 799 DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic); 800 801 if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { 802 ycrcb_map = VPU_HDMI_OUTPUT_CRYCB; 803 yuv420_mode = true; 804 } 805 806 /* VENC + VENC-DVI Mode setup */ 807 meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, yuv420_mode, mode); 808 809 /* VCLK Set clock */ 810 dw_hdmi_set_vclk(dw_hdmi, mode); 811 812 if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) 813 /* Setup YUV420 to HDMI-TX, no 10bit diphering */ 814 writel_relaxed(2 | (2 << 2), 815 priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); 816 else 817 /* Setup YUV444 to HDMI-TX, no 10bit diphering */ 818 writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); 819 } 820 821 static const struct drm_bridge_funcs meson_venc_hdmi_encoder_bridge_funcs = { 822 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 823 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 824 .atomic_get_input_bus_fmts = meson_venc_hdmi_encoder_get_inp_bus_fmts, 825 .atomic_reset = drm_atomic_helper_bridge_reset, 826 .atomic_check = meson_venc_hdmi_encoder_atomic_check, 827 .enable = meson_venc_hdmi_encoder_enable, 828 .disable = meson_venc_hdmi_encoder_disable, 829 .mode_set = meson_venc_hdmi_encoder_mode_set, 830 }; 831 832 /* DW HDMI Regmap */ 833 834 static int meson_dw_hdmi_reg_read(void *context, unsigned int reg, 835 unsigned int *result) 836 { 837 struct meson_dw_hdmi *dw_hdmi = context; 838 839 *result = dw_hdmi->data->dwc_read(dw_hdmi, reg); 840 841 return 0; 842 843 } 844 845 static int meson_dw_hdmi_reg_write(void *context, unsigned int reg, 846 unsigned int val) 847 { 848 struct meson_dw_hdmi *dw_hdmi = context; 849 850 dw_hdmi->data->dwc_write(dw_hdmi, reg, val); 851 852 return 0; 853 } 854 855 static const struct regmap_config meson_dw_hdmi_regmap_config = { 856 .reg_bits = 32, 857 .val_bits = 8, 858 .reg_read = meson_dw_hdmi_reg_read, 859 .reg_write = meson_dw_hdmi_reg_write, 860 .max_register = 0x10000, 861 .fast_io = true, 862 }; 863 864 static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = { 865 .top_read = dw_hdmi_top_read, 866 .top_write = dw_hdmi_top_write, 867 .dwc_read = dw_hdmi_dwc_read, 868 .dwc_write = dw_hdmi_dwc_write, 869 }; 870 871 static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = { 872 .top_read = dw_hdmi_g12a_top_read, 873 .top_write = dw_hdmi_g12a_top_write, 874 .dwc_read = dw_hdmi_g12a_dwc_read, 875 .dwc_write = dw_hdmi_g12a_dwc_write, 876 }; 877 878 static bool meson_hdmi_connector_is_available(struct device *dev) 879 { 880 struct device_node *ep, *remote; 881 882 /* HDMI Connector is on the second port, first endpoint */ 883 ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0); 884 if (!ep) 885 return false; 886 887 /* If the endpoint node exists, consider it enabled */ 888 remote = of_graph_get_remote_port(ep); 889 if (remote) { 890 of_node_put(ep); 891 return true; 892 } 893 894 of_node_put(ep); 895 of_node_put(remote); 896 897 return false; 898 } 899 900 static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) 901 { 902 struct meson_drm *priv = meson_dw_hdmi->priv; 903 904 /* Enable clocks */ 905 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); 906 907 /* Bring HDMITX MEM output of power down */ 908 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); 909 910 /* Reset HDMITX APB & TX & PHY */ 911 reset_control_reset(meson_dw_hdmi->hdmitx_apb); 912 reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); 913 reset_control_reset(meson_dw_hdmi->hdmitx_phy); 914 915 /* Enable APB3 fail on error */ 916 if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { 917 writel_bits_relaxed(BIT(15), BIT(15), 918 meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG); 919 writel_bits_relaxed(BIT(15), BIT(15), 920 meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG); 921 } 922 923 /* Bring out of reset */ 924 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 925 HDMITX_TOP_SW_RESET, 0); 926 927 msleep(20); 928 929 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 930 HDMITX_TOP_CLK_CNTL, 0xff); 931 932 /* Enable HDMI-TX Interrupt */ 933 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, 934 HDMITX_TOP_INTR_CORE); 935 936 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN, 937 HDMITX_TOP_INTR_CORE); 938 939 } 940 941 static int meson_dw_hdmi_bind(struct device *dev, struct device *master, 942 void *data) 943 { 944 struct platform_device *pdev = to_platform_device(dev); 945 const struct meson_dw_hdmi_data *match; 946 struct meson_dw_hdmi *meson_dw_hdmi; 947 struct drm_device *drm = data; 948 struct meson_drm *priv = drm->dev_private; 949 struct dw_hdmi_plat_data *dw_plat_data; 950 struct drm_bridge *next_bridge; 951 struct drm_encoder *encoder; 952 struct resource *res; 953 int irq; 954 int ret; 955 956 DRM_DEBUG_DRIVER("\n"); 957 958 if (!meson_hdmi_connector_is_available(dev)) { 959 dev_info(drm->dev, "HDMI Output connector not available\n"); 960 return -ENODEV; 961 } 962 963 match = of_device_get_match_data(&pdev->dev); 964 if (!match) { 965 dev_err(&pdev->dev, "failed to get match data\n"); 966 return -ENODEV; 967 } 968 969 meson_dw_hdmi = devm_kzalloc(dev, sizeof(*meson_dw_hdmi), 970 GFP_KERNEL); 971 if (!meson_dw_hdmi) 972 return -ENOMEM; 973 974 meson_dw_hdmi->priv = priv; 975 meson_dw_hdmi->dev = dev; 976 meson_dw_hdmi->data = match; 977 dw_plat_data = &meson_dw_hdmi->dw_plat_data; 978 encoder = &meson_dw_hdmi->encoder; 979 980 meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi"); 981 if (IS_ERR(meson_dw_hdmi->hdmi_supply)) { 982 if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER) 983 return -EPROBE_DEFER; 984 meson_dw_hdmi->hdmi_supply = NULL; 985 } else { 986 ret = regulator_enable(meson_dw_hdmi->hdmi_supply); 987 if (ret) 988 return ret; 989 } 990 991 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, 992 "hdmitx_apb"); 993 if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { 994 dev_err(dev, "Failed to get hdmitx_apb reset\n"); 995 return PTR_ERR(meson_dw_hdmi->hdmitx_apb); 996 } 997 998 meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev, 999 "hdmitx"); 1000 if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) { 1001 dev_err(dev, "Failed to get hdmitx reset\n"); 1002 return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl); 1003 } 1004 1005 meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev, 1006 "hdmitx_phy"); 1007 if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) { 1008 dev_err(dev, "Failed to get hdmitx_phy reset\n"); 1009 return PTR_ERR(meson_dw_hdmi->hdmitx_phy); 1010 } 1011 1012 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1013 meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res); 1014 if (IS_ERR(meson_dw_hdmi->hdmitx)) 1015 return PTR_ERR(meson_dw_hdmi->hdmitx); 1016 1017 meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr"); 1018 if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) { 1019 dev_err(dev, "Unable to get HDMI pclk\n"); 1020 return PTR_ERR(meson_dw_hdmi->hdmi_pclk); 1021 } 1022 clk_prepare_enable(meson_dw_hdmi->hdmi_pclk); 1023 1024 meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci"); 1025 if (IS_ERR(meson_dw_hdmi->venci_clk)) { 1026 dev_err(dev, "Unable to get venci clk\n"); 1027 return PTR_ERR(meson_dw_hdmi->venci_clk); 1028 } 1029 clk_prepare_enable(meson_dw_hdmi->venci_clk); 1030 1031 dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, 1032 &meson_dw_hdmi_regmap_config); 1033 if (IS_ERR(dw_plat_data->regm)) 1034 return PTR_ERR(dw_plat_data->regm); 1035 1036 irq = platform_get_irq(pdev, 0); 1037 if (irq < 0) 1038 return irq; 1039 1040 ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq, 1041 dw_hdmi_top_thread_irq, IRQF_SHARED, 1042 "dw_hdmi_top_irq", meson_dw_hdmi); 1043 if (ret) { 1044 dev_err(dev, "Failed to request hdmi top irq\n"); 1045 return ret; 1046 } 1047 1048 /* Encoder */ 1049 1050 ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs, 1051 DRM_MODE_ENCODER_TMDS, "meson_hdmi"); 1052 if (ret) { 1053 dev_err(priv->dev, "Failed to init HDMI encoder\n"); 1054 return ret; 1055 } 1056 1057 meson_dw_hdmi->bridge.funcs = &meson_venc_hdmi_encoder_bridge_funcs; 1058 drm_bridge_attach(encoder, &meson_dw_hdmi->bridge, NULL, 0); 1059 1060 encoder->possible_crtcs = BIT(0); 1061 1062 DRM_DEBUG_DRIVER("encoder initialized\n"); 1063 1064 meson_dw_hdmi_init(meson_dw_hdmi); 1065 1066 /* Bridge / Connector */ 1067 1068 dw_plat_data->mode_valid = dw_hdmi_mode_valid; 1069 dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; 1070 dw_plat_data->phy_name = "meson_dw_hdmi_phy"; 1071 dw_plat_data->phy_data = meson_dw_hdmi; 1072 dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; 1073 dw_plat_data->ycbcr_420_allowed = true; 1074 1075 if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || 1076 dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || 1077 dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-g12a-dw-hdmi")) 1078 dw_plat_data->use_drm_infoframe = true; 1079 1080 platform_set_drvdata(pdev, meson_dw_hdmi); 1081 1082 meson_dw_hdmi->hdmi = dw_hdmi_probe(pdev, 1083 &meson_dw_hdmi->dw_plat_data); 1084 if (IS_ERR(meson_dw_hdmi->hdmi)) 1085 return PTR_ERR(meson_dw_hdmi->hdmi); 1086 1087 next_bridge = of_drm_find_bridge(pdev->dev.of_node); 1088 if (next_bridge) 1089 drm_bridge_attach(encoder, next_bridge, 1090 &meson_dw_hdmi->bridge, 0); 1091 1092 DRM_DEBUG_DRIVER("HDMI controller initialized\n"); 1093 1094 return 0; 1095 } 1096 1097 static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, 1098 void *data) 1099 { 1100 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 1101 1102 dw_hdmi_unbind(meson_dw_hdmi->hdmi); 1103 } 1104 1105 static const struct component_ops meson_dw_hdmi_ops = { 1106 .bind = meson_dw_hdmi_bind, 1107 .unbind = meson_dw_hdmi_unbind, 1108 }; 1109 1110 static int __maybe_unused meson_dw_hdmi_pm_suspend(struct device *dev) 1111 { 1112 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 1113 1114 if (!meson_dw_hdmi) 1115 return 0; 1116 1117 /* Reset TOP */ 1118 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 1119 HDMITX_TOP_SW_RESET, 0); 1120 1121 return 0; 1122 } 1123 1124 static int __maybe_unused meson_dw_hdmi_pm_resume(struct device *dev) 1125 { 1126 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 1127 1128 if (!meson_dw_hdmi) 1129 return 0; 1130 1131 meson_dw_hdmi_init(meson_dw_hdmi); 1132 1133 dw_hdmi_resume(meson_dw_hdmi->hdmi); 1134 1135 return 0; 1136 } 1137 1138 static int meson_dw_hdmi_probe(struct platform_device *pdev) 1139 { 1140 return component_add(&pdev->dev, &meson_dw_hdmi_ops); 1141 } 1142 1143 static int meson_dw_hdmi_remove(struct platform_device *pdev) 1144 { 1145 component_del(&pdev->dev, &meson_dw_hdmi_ops); 1146 1147 return 0; 1148 } 1149 1150 static const struct dev_pm_ops meson_dw_hdmi_pm_ops = { 1151 SET_SYSTEM_SLEEP_PM_OPS(meson_dw_hdmi_pm_suspend, 1152 meson_dw_hdmi_pm_resume) 1153 }; 1154 1155 static const struct of_device_id meson_dw_hdmi_of_table[] = { 1156 { .compatible = "amlogic,meson-gxbb-dw-hdmi", 1157 .data = &meson_dw_hdmi_gx_data }, 1158 { .compatible = "amlogic,meson-gxl-dw-hdmi", 1159 .data = &meson_dw_hdmi_gx_data }, 1160 { .compatible = "amlogic,meson-gxm-dw-hdmi", 1161 .data = &meson_dw_hdmi_gx_data }, 1162 { .compatible = "amlogic,meson-g12a-dw-hdmi", 1163 .data = &meson_dw_hdmi_g12a_data }, 1164 { } 1165 }; 1166 MODULE_DEVICE_TABLE(of, meson_dw_hdmi_of_table); 1167 1168 static struct platform_driver meson_dw_hdmi_platform_driver = { 1169 .probe = meson_dw_hdmi_probe, 1170 .remove = meson_dw_hdmi_remove, 1171 .driver = { 1172 .name = DRIVER_NAME, 1173 .of_match_table = meson_dw_hdmi_of_table, 1174 .pm = &meson_dw_hdmi_pm_ops, 1175 }, 1176 }; 1177 module_platform_driver(meson_dw_hdmi_platform_driver); 1178 1179 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 1180 MODULE_DESCRIPTION(DRIVER_DESC); 1181 MODULE_LICENSE("GPL"); 1182