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.h> 13 #include <linux/of_graph.h> 14 #include <linux/platform_device.h> 15 #include <linux/regulator/consumer.h> 16 #include <linux/reset.h> 17 18 #include <drm/bridge/dw_hdmi.h> 19 #include <drm/drm_atomic_helper.h> 20 #include <drm/drm_bridge.h> 21 #include <drm/drm_device.h> 22 #include <drm/drm_edid.h> 23 #include <drm/drm_probe_helper.h> 24 #include <drm/drm_print.h> 25 26 #include <linux/videodev2.h> 27 28 #include "meson_drv.h" 29 #include "meson_dw_hdmi.h" 30 #include "meson_registers.h" 31 32 #define DRIVER_NAME "meson-dw-hdmi" 33 #define DRIVER_DESC "Amlogic Meson HDMI-TX DRM driver" 34 35 /** 36 * DOC: HDMI Output 37 * 38 * HDMI Output is composed of : 39 * 40 * - A Synopsys DesignWare HDMI Controller IP 41 * - A TOP control block controlling the Clocks and PHY 42 * - A custom HDMI PHY in order convert video to TMDS signal 43 * 44 * .. code:: 45 * 46 * ___________________________________ 47 * | HDMI TOP |<= HPD 48 * |___________________________________| 49 * | | | 50 * | Synopsys HDMI | HDMI PHY |=> TMDS 51 * | Controller |________________| 52 * |___________________________________|<=> DDC 53 * 54 * 55 * The HDMI TOP block only supports HPD sensing. 56 * The Synopsys HDMI Controller interrupt is routed 57 * through the TOP Block interrupt. 58 * Communication to the TOP Block and the Synopsys 59 * HDMI Controller is done a pair of addr+read/write 60 * registers. 61 * The HDMI PHY is configured by registers in the 62 * HHI register block. 63 * 64 * Pixel data arrives in 4:4:4 format from the VENC 65 * block and the VPU HDMI mux selects either the ENCI 66 * encoder for the 576i or 480i formats or the ENCP 67 * encoder for all the other formats including 68 * interlaced HD formats. 69 * The VENC uses a DVI encoder on top of the ENCI 70 * or ENCP encoders to generate DVI timings for the 71 * HDMI controller. 72 * 73 * GXBB, GXL and GXM embeds the Synopsys DesignWare 74 * HDMI TX IP version 2.01a with HDCP and I2C & S/PDIF 75 * audio source interfaces. 76 * 77 * We handle the following features : 78 * 79 * - HPD Rise & Fall interrupt 80 * - HDMI Controller Interrupt 81 * - HDMI PHY Init for 480i to 1080p60 82 * - VENC & HDMI Clock setup for 480i to 1080p60 83 * - VENC Mode setup for 480i to 1080p60 84 * 85 * What is missing : 86 * 87 * - PHY, Clock and Mode setup for 2k && 4k modes 88 * - SDDC Scrambling mode for HDMI 2.0a 89 * - HDCP Setup 90 * - CEC Management 91 */ 92 93 /* TOP Block Communication Channel */ 94 #define HDMITX_TOP_ADDR_REG 0x0 95 #define HDMITX_TOP_DATA_REG 0x4 96 #define HDMITX_TOP_CTRL_REG 0x8 97 #define HDMITX_TOP_G12A_OFFSET 0x8000 98 99 /* Controller Communication Channel */ 100 #define HDMITX_DWC_ADDR_REG 0x10 101 #define HDMITX_DWC_DATA_REG 0x14 102 #define HDMITX_DWC_CTRL_REG 0x18 103 104 /* HHI Registers */ 105 #define HHI_MEM_PD_REG0 0x100 /* 0x40 */ 106 #define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */ 107 #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */ 108 #define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */ 109 #define PHY_CNTL1_INIT 0x03900000 110 #define PHY_INVERT BIT(17) 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 u32 cntl0_init; 136 u32 cntl1_init; 137 }; 138 139 struct meson_dw_hdmi { 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 u32 irq_stat; 149 struct dw_hdmi *hdmi; 150 struct drm_bridge *bridge; 151 }; 152 153 static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi, 154 const char *compat) 155 { 156 return of_device_is_compatible(dw_hdmi->dev->of_node, compat); 157 } 158 159 /* PHY (via TOP bridge) and Controller dedicated register interface */ 160 161 static unsigned int dw_hdmi_top_read(struct meson_dw_hdmi *dw_hdmi, 162 unsigned int addr) 163 { 164 unsigned long flags; 165 unsigned int data; 166 167 spin_lock_irqsave(®_lock, flags); 168 169 /* ADDR must be written twice */ 170 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 171 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 172 173 /* Read needs a second DATA read */ 174 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 175 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 176 177 spin_unlock_irqrestore(®_lock, flags); 178 179 return data; 180 } 181 182 static unsigned int dw_hdmi_g12a_top_read(struct meson_dw_hdmi *dw_hdmi, 183 unsigned int addr) 184 { 185 return readl(dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2)); 186 } 187 188 static inline void dw_hdmi_top_write(struct meson_dw_hdmi *dw_hdmi, 189 unsigned int addr, unsigned int data) 190 { 191 unsigned long flags; 192 193 spin_lock_irqsave(®_lock, flags); 194 195 /* ADDR must be written twice */ 196 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 197 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 198 199 /* Write needs single DATA write */ 200 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 201 202 spin_unlock_irqrestore(®_lock, flags); 203 } 204 205 static inline void dw_hdmi_g12a_top_write(struct meson_dw_hdmi *dw_hdmi, 206 unsigned int addr, unsigned int data) 207 { 208 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2)); 209 } 210 211 /* Helper to change specific bits in PHY registers */ 212 static inline void dw_hdmi_top_write_bits(struct meson_dw_hdmi *dw_hdmi, 213 unsigned int addr, 214 unsigned int mask, 215 unsigned int val) 216 { 217 unsigned int data = dw_hdmi->data->top_read(dw_hdmi, addr); 218 219 data &= ~mask; 220 data |= val; 221 222 dw_hdmi->data->top_write(dw_hdmi, addr, data); 223 } 224 225 static unsigned int dw_hdmi_dwc_read(struct meson_dw_hdmi *dw_hdmi, 226 unsigned int addr) 227 { 228 unsigned long flags; 229 unsigned int data; 230 231 spin_lock_irqsave(®_lock, flags); 232 233 /* ADDR must be written twice */ 234 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 235 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 236 237 /* Read needs a second DATA read */ 238 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 239 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 240 241 spin_unlock_irqrestore(®_lock, flags); 242 243 return data; 244 } 245 246 static unsigned int dw_hdmi_g12a_dwc_read(struct meson_dw_hdmi *dw_hdmi, 247 unsigned int addr) 248 { 249 return readb(dw_hdmi->hdmitx + addr); 250 } 251 252 static inline void dw_hdmi_dwc_write(struct meson_dw_hdmi *dw_hdmi, 253 unsigned int addr, unsigned int data) 254 { 255 unsigned long flags; 256 257 spin_lock_irqsave(®_lock, flags); 258 259 /* ADDR must be written twice */ 260 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 261 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 262 263 /* Write needs single DATA write */ 264 writel(data, dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 265 266 spin_unlock_irqrestore(®_lock, flags); 267 } 268 269 static inline void dw_hdmi_g12a_dwc_write(struct meson_dw_hdmi *dw_hdmi, 270 unsigned int addr, unsigned int data) 271 { 272 writeb(data, dw_hdmi->hdmitx + addr); 273 } 274 275 /* Helper to change specific bits in controller registers */ 276 static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi, 277 unsigned int addr, 278 unsigned int mask, 279 unsigned int val) 280 { 281 unsigned int data = dw_hdmi->data->dwc_read(dw_hdmi, addr); 282 283 data &= ~mask; 284 data |= val; 285 286 dw_hdmi->data->dwc_write(dw_hdmi, addr, data); 287 } 288 289 /* Bridge */ 290 291 /* Setup PHY bandwidth modes */ 292 static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, 293 const struct drm_display_mode *mode, 294 bool mode_is_420) 295 { 296 struct meson_drm *priv = dw_hdmi->priv; 297 unsigned int pixel_clock = mode->clock; 298 299 /* For 420, pixel clock is half unlike venc clock */ 300 if (mode_is_420) pixel_clock /= 2; 301 302 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || 303 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { 304 if (pixel_clock >= 371250) { 305 /* 5.94Gbps, 3.7125Gbps */ 306 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x333d3282); 307 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b); 308 } else if (pixel_clock >= 297000) { 309 /* 2.97Gbps */ 310 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382); 311 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b); 312 } else if (pixel_clock >= 148500) { 313 /* 1.485Gbps */ 314 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303362); 315 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2016315b); 316 } else { 317 /* 742.5Mbps, and below */ 318 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33604142); 319 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x0016315b); 320 } 321 } else if (dw_hdmi_is_compatible(dw_hdmi, 322 "amlogic,meson-gxbb-dw-hdmi")) { 323 if (pixel_clock >= 371250) { 324 /* 5.94Gbps, 3.7125Gbps */ 325 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33353245); 326 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2100115b); 327 } else if (pixel_clock >= 297000) { 328 /* 2.97Gbps */ 329 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33634283); 330 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0xb000115b); 331 } else { 332 /* 1.485Gbps, and below */ 333 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33632122); 334 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2000115b); 335 } 336 } else if (dw_hdmi_is_compatible(dw_hdmi, 337 "amlogic,meson-g12a-dw-hdmi")) { 338 if (pixel_clock >= 371250) { 339 /* 5.94Gbps, 3.7125Gbps */ 340 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x37eb65c4); 341 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 342 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x0000080b); 343 } else if (pixel_clock >= 297000) { 344 /* 2.97Gbps */ 345 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb6262); 346 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 347 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003); 348 } else { 349 /* 1.485Gbps, and below */ 350 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb4242); 351 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 352 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003); 353 } 354 } 355 } 356 357 static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) 358 { 359 struct meson_drm *priv = dw_hdmi->priv; 360 361 /* Enable and software reset */ 362 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xf); 363 364 mdelay(2); 365 366 /* Enable and unreset */ 367 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xe); 368 369 mdelay(2); 370 } 371 372 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, 373 const struct drm_display_info *display, 374 const struct drm_display_mode *mode) 375 { 376 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 377 bool is_hdmi2_sink = display->hdmi.scdc.supported; 378 struct meson_drm *priv = dw_hdmi->priv; 379 unsigned int wr_clk = 380 readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING)); 381 bool mode_is_420 = false; 382 383 DRM_DEBUG_DRIVER("\"%s\" div%d\n", mode->name, 384 mode->clock > 340000 ? 40 : 10); 385 386 if (drm_mode_is_420_only(display, mode) || 387 (!is_hdmi2_sink && drm_mode_is_420_also(display, mode)) || 388 dw_hdmi_bus_fmt_is_420(hdmi)) 389 mode_is_420 = true; 390 391 /* TMDS pattern setup */ 392 if (mode->clock > 340000 && !mode_is_420) { 393 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 394 0); 395 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 396 0x03ff03ff); 397 } else { 398 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 399 0x001f001f); 400 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 401 0x001f001f); 402 } 403 404 /* Load TMDS pattern */ 405 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1); 406 msleep(20); 407 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); 408 409 /* Setup PHY parameters */ 410 meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420); 411 412 /* Disable clock, fifo, fifo_wr */ 413 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0); 414 415 dw_hdmi_set_high_tmds_clock_ratio(hdmi, display); 416 417 msleep(100); 418 419 /* Reset PHY 3 times in a row */ 420 meson_dw_hdmi_phy_reset(dw_hdmi); 421 meson_dw_hdmi_phy_reset(dw_hdmi); 422 meson_dw_hdmi_phy_reset(dw_hdmi); 423 424 /* Temporary Disable VENC video stream */ 425 if (priv->venc.hdmi_use_enci) 426 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 427 else 428 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 429 430 /* Temporary Disable HDMI video stream to HDMI-TX */ 431 writel_bits_relaxed(0x3, 0, 432 priv->io_base + _REG(VPU_HDMI_SETTING)); 433 writel_bits_relaxed(0xf << 8, 0, 434 priv->io_base + _REG(VPU_HDMI_SETTING)); 435 436 /* Re-Enable VENC video stream */ 437 if (priv->venc.hdmi_use_enci) 438 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 439 else 440 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); 441 442 /* Push back HDMI clock settings */ 443 writel_bits_relaxed(0xf << 8, wr_clk & (0xf << 8), 444 priv->io_base + _REG(VPU_HDMI_SETTING)); 445 446 /* Enable and Select HDMI video source for HDMI-TX */ 447 if (priv->venc.hdmi_use_enci) 448 writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCI, 449 priv->io_base + _REG(VPU_HDMI_SETTING)); 450 else 451 writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCP, 452 priv->io_base + _REG(VPU_HDMI_SETTING)); 453 454 return 0; 455 } 456 457 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, 458 void *data) 459 { 460 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 461 struct meson_drm *priv = dw_hdmi->priv; 462 463 DRM_DEBUG_DRIVER("\n"); 464 465 /* Fallback to init mode */ 466 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, dw_hdmi->data->cntl1_init); 467 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, dw_hdmi->data->cntl0_init); 468 } 469 470 static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi, 471 void *data) 472 { 473 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 474 475 return !!dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_STAT0) ? 476 connector_status_connected : connector_status_disconnected; 477 } 478 479 static void dw_hdmi_setup_hpd(struct dw_hdmi *hdmi, 480 void *data) 481 { 482 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 483 484 /* Setup HPD Filter */ 485 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_HPD_FILTER, 486 (0xa << 12) | 0xa0); 487 488 /* Clear interrupts */ 489 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, 490 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL); 491 492 /* Unmask interrupts */ 493 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_INTR_MASKN, 494 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL, 495 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL); 496 } 497 498 static const struct dw_hdmi_phy_ops meson_dw_hdmi_phy_ops = { 499 .init = dw_hdmi_phy_init, 500 .disable = dw_hdmi_phy_disable, 501 .read_hpd = dw_hdmi_read_hpd, 502 .setup_hpd = dw_hdmi_setup_hpd, 503 }; 504 505 static irqreturn_t dw_hdmi_top_irq(int irq, void *dev_id) 506 { 507 struct meson_dw_hdmi *dw_hdmi = dev_id; 508 u32 stat; 509 510 stat = dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_INTR_STAT); 511 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, stat); 512 513 /* HPD Events, handle in the threaded interrupt handler */ 514 if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) { 515 dw_hdmi->irq_stat = stat; 516 return IRQ_WAKE_THREAD; 517 } 518 519 /* HDMI Controller Interrupt */ 520 if (stat & 1) 521 return IRQ_NONE; 522 523 /* TOFIX Handle HDCP Interrupts */ 524 525 return IRQ_HANDLED; 526 } 527 528 /* Threaded interrupt handler to manage HPD events */ 529 static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) 530 { 531 struct meson_dw_hdmi *dw_hdmi = dev_id; 532 u32 stat = dw_hdmi->irq_stat; 533 534 /* HPD Events */ 535 if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) { 536 bool hpd_connected = false; 537 538 if (stat & HDMITX_TOP_INTR_HPD_RISE) 539 hpd_connected = true; 540 541 dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected, 542 hpd_connected); 543 544 drm_helper_hpd_irq_event(dw_hdmi->bridge->dev); 545 drm_bridge_hpd_notify(dw_hdmi->bridge, 546 hpd_connected ? connector_status_connected 547 : connector_status_disconnected); 548 } 549 550 return IRQ_HANDLED; 551 } 552 553 /* DW HDMI Regmap */ 554 555 static int meson_dw_hdmi_reg_read(void *context, unsigned int reg, 556 unsigned int *result) 557 { 558 struct meson_dw_hdmi *dw_hdmi = context; 559 560 *result = dw_hdmi->data->dwc_read(dw_hdmi, reg); 561 562 return 0; 563 564 } 565 566 static int meson_dw_hdmi_reg_write(void *context, unsigned int reg, 567 unsigned int val) 568 { 569 struct meson_dw_hdmi *dw_hdmi = context; 570 571 dw_hdmi->data->dwc_write(dw_hdmi, reg, val); 572 573 return 0; 574 } 575 576 static const struct regmap_config meson_dw_hdmi_regmap_config = { 577 .reg_bits = 32, 578 .val_bits = 8, 579 .reg_read = meson_dw_hdmi_reg_read, 580 .reg_write = meson_dw_hdmi_reg_write, 581 .max_register = 0x10000, 582 .fast_io = true, 583 }; 584 585 static const struct meson_dw_hdmi_data meson_dw_hdmi_gxbb_data = { 586 .top_read = dw_hdmi_top_read, 587 .top_write = dw_hdmi_top_write, 588 .dwc_read = dw_hdmi_dwc_read, 589 .dwc_write = dw_hdmi_dwc_write, 590 .cntl0_init = 0x0, 591 .cntl1_init = PHY_CNTL1_INIT | PHY_INVERT, 592 }; 593 594 static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = { 595 .top_read = dw_hdmi_top_read, 596 .top_write = dw_hdmi_top_write, 597 .dwc_read = dw_hdmi_dwc_read, 598 .dwc_write = dw_hdmi_dwc_write, 599 .cntl0_init = 0x0, 600 .cntl1_init = PHY_CNTL1_INIT, 601 }; 602 603 static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = { 604 .top_read = dw_hdmi_g12a_top_read, 605 .top_write = dw_hdmi_g12a_top_write, 606 .dwc_read = dw_hdmi_g12a_dwc_read, 607 .dwc_write = dw_hdmi_g12a_dwc_write, 608 .cntl0_init = 0x000b4242, /* Bandgap */ 609 .cntl1_init = PHY_CNTL1_INIT, 610 }; 611 612 static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) 613 { 614 struct meson_drm *priv = meson_dw_hdmi->priv; 615 616 /* Enable clocks */ 617 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); 618 619 /* Bring HDMITX MEM output of power down */ 620 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); 621 622 /* Reset HDMITX APB & TX & PHY */ 623 reset_control_reset(meson_dw_hdmi->hdmitx_apb); 624 reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); 625 reset_control_reset(meson_dw_hdmi->hdmitx_phy); 626 627 /* Enable APB3 fail on error */ 628 if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { 629 writel_bits_relaxed(BIT(15), BIT(15), 630 meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG); 631 writel_bits_relaxed(BIT(15), BIT(15), 632 meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG); 633 } 634 635 /* Bring out of reset */ 636 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 637 HDMITX_TOP_SW_RESET, 0); 638 639 msleep(20); 640 641 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 642 HDMITX_TOP_CLK_CNTL, 0xff); 643 644 /* Enable normal output to PHY */ 645 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); 646 647 /* Setup PHY */ 648 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, meson_dw_hdmi->data->cntl1_init); 649 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, meson_dw_hdmi->data->cntl0_init); 650 651 /* Enable HDMI-TX Interrupt */ 652 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, 653 HDMITX_TOP_INTR_CORE); 654 655 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN, 656 HDMITX_TOP_INTR_CORE); 657 658 } 659 660 static void meson_disable_clk(void *data) 661 { 662 clk_disable_unprepare(data); 663 } 664 665 static int meson_enable_clk(struct device *dev, char *name) 666 { 667 struct clk *clk; 668 int ret; 669 670 clk = devm_clk_get(dev, name); 671 if (IS_ERR(clk)) { 672 dev_err(dev, "Unable to get %s pclk\n", name); 673 return PTR_ERR(clk); 674 } 675 676 ret = clk_prepare_enable(clk); 677 if (!ret) 678 ret = devm_add_action_or_reset(dev, meson_disable_clk, clk); 679 680 return ret; 681 } 682 683 static int meson_dw_hdmi_bind(struct device *dev, struct device *master, 684 void *data) 685 { 686 struct platform_device *pdev = to_platform_device(dev); 687 const struct meson_dw_hdmi_data *match; 688 struct meson_dw_hdmi *meson_dw_hdmi; 689 struct drm_device *drm = data; 690 struct meson_drm *priv = drm->dev_private; 691 struct dw_hdmi_plat_data *dw_plat_data; 692 int irq; 693 int ret; 694 695 DRM_DEBUG_DRIVER("\n"); 696 697 match = of_device_get_match_data(&pdev->dev); 698 if (!match) { 699 dev_err(&pdev->dev, "failed to get match data\n"); 700 return -ENODEV; 701 } 702 703 meson_dw_hdmi = devm_kzalloc(dev, sizeof(*meson_dw_hdmi), 704 GFP_KERNEL); 705 if (!meson_dw_hdmi) 706 return -ENOMEM; 707 708 meson_dw_hdmi->priv = priv; 709 meson_dw_hdmi->dev = dev; 710 meson_dw_hdmi->data = match; 711 dw_plat_data = &meson_dw_hdmi->dw_plat_data; 712 713 ret = devm_regulator_get_enable_optional(dev, "hdmi"); 714 if (ret < 0 && ret != -ENODEV) 715 return ret; 716 717 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, 718 "hdmitx_apb"); 719 if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { 720 dev_err(dev, "Failed to get hdmitx_apb reset\n"); 721 return PTR_ERR(meson_dw_hdmi->hdmitx_apb); 722 } 723 724 meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev, 725 "hdmitx"); 726 if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) { 727 dev_err(dev, "Failed to get hdmitx reset\n"); 728 return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl); 729 } 730 731 meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev, 732 "hdmitx_phy"); 733 if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) { 734 dev_err(dev, "Failed to get hdmitx_phy reset\n"); 735 return PTR_ERR(meson_dw_hdmi->hdmitx_phy); 736 } 737 738 meson_dw_hdmi->hdmitx = devm_platform_ioremap_resource(pdev, 0); 739 if (IS_ERR(meson_dw_hdmi->hdmitx)) 740 return PTR_ERR(meson_dw_hdmi->hdmitx); 741 742 ret = meson_enable_clk(dev, "isfr"); 743 if (ret) 744 return ret; 745 746 ret = meson_enable_clk(dev, "iahb"); 747 if (ret) 748 return ret; 749 750 ret = meson_enable_clk(dev, "venci"); 751 if (ret) 752 return ret; 753 754 dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, 755 &meson_dw_hdmi_regmap_config); 756 if (IS_ERR(dw_plat_data->regm)) 757 return PTR_ERR(dw_plat_data->regm); 758 759 irq = platform_get_irq(pdev, 0); 760 if (irq < 0) 761 return irq; 762 763 ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq, 764 dw_hdmi_top_thread_irq, IRQF_SHARED, 765 "dw_hdmi_top_irq", meson_dw_hdmi); 766 if (ret) { 767 dev_err(dev, "Failed to request hdmi top irq\n"); 768 return ret; 769 } 770 771 meson_dw_hdmi_init(meson_dw_hdmi); 772 773 /* Bridge / Connector */ 774 775 dw_plat_data->priv_data = meson_dw_hdmi; 776 dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; 777 dw_plat_data->phy_name = "meson_dw_hdmi_phy"; 778 dw_plat_data->phy_data = meson_dw_hdmi; 779 dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; 780 dw_plat_data->ycbcr_420_allowed = true; 781 dw_plat_data->disable_cec = true; 782 dw_plat_data->output_port = 1; 783 784 if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || 785 dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || 786 dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-g12a-dw-hdmi")) 787 dw_plat_data->use_drm_infoframe = true; 788 789 platform_set_drvdata(pdev, meson_dw_hdmi); 790 791 meson_dw_hdmi->hdmi = dw_hdmi_probe(pdev, &meson_dw_hdmi->dw_plat_data); 792 if (IS_ERR(meson_dw_hdmi->hdmi)) 793 return PTR_ERR(meson_dw_hdmi->hdmi); 794 795 meson_dw_hdmi->bridge = of_drm_find_bridge(pdev->dev.of_node); 796 797 DRM_DEBUG_DRIVER("HDMI controller initialized\n"); 798 799 return 0; 800 } 801 802 static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, 803 void *data) 804 { 805 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 806 807 dw_hdmi_unbind(meson_dw_hdmi->hdmi); 808 } 809 810 static const struct component_ops meson_dw_hdmi_ops = { 811 .bind = meson_dw_hdmi_bind, 812 .unbind = meson_dw_hdmi_unbind, 813 }; 814 815 static int __maybe_unused meson_dw_hdmi_pm_suspend(struct device *dev) 816 { 817 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 818 819 if (!meson_dw_hdmi) 820 return 0; 821 822 /* Reset TOP */ 823 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 824 HDMITX_TOP_SW_RESET, 0); 825 826 return 0; 827 } 828 829 static int __maybe_unused meson_dw_hdmi_pm_resume(struct device *dev) 830 { 831 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 832 833 if (!meson_dw_hdmi) 834 return 0; 835 836 meson_dw_hdmi_init(meson_dw_hdmi); 837 838 dw_hdmi_resume(meson_dw_hdmi->hdmi); 839 840 return 0; 841 } 842 843 static int meson_dw_hdmi_probe(struct platform_device *pdev) 844 { 845 return component_add(&pdev->dev, &meson_dw_hdmi_ops); 846 } 847 848 static void meson_dw_hdmi_remove(struct platform_device *pdev) 849 { 850 component_del(&pdev->dev, &meson_dw_hdmi_ops); 851 } 852 853 static const struct dev_pm_ops meson_dw_hdmi_pm_ops = { 854 SET_SYSTEM_SLEEP_PM_OPS(meson_dw_hdmi_pm_suspend, 855 meson_dw_hdmi_pm_resume) 856 }; 857 858 static const struct of_device_id meson_dw_hdmi_of_table[] = { 859 { .compatible = "amlogic,meson-gxbb-dw-hdmi", 860 .data = &meson_dw_hdmi_gxbb_data }, 861 { .compatible = "amlogic,meson-gxl-dw-hdmi", 862 .data = &meson_dw_hdmi_gxl_data }, 863 { .compatible = "amlogic,meson-gxm-dw-hdmi", 864 .data = &meson_dw_hdmi_gxl_data }, 865 { .compatible = "amlogic,meson-g12a-dw-hdmi", 866 .data = &meson_dw_hdmi_g12a_data }, 867 { } 868 }; 869 MODULE_DEVICE_TABLE(of, meson_dw_hdmi_of_table); 870 871 static struct platform_driver meson_dw_hdmi_platform_driver = { 872 .probe = meson_dw_hdmi_probe, 873 .remove_new = meson_dw_hdmi_remove, 874 .driver = { 875 .name = DRIVER_NAME, 876 .of_match_table = meson_dw_hdmi_of_table, 877 .pm = &meson_dw_hdmi_pm_ops, 878 }, 879 }; 880 module_platform_driver(meson_dw_hdmi_platform_driver); 881 882 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 883 MODULE_DESCRIPTION(DRIVER_DESC); 884 MODULE_LICENSE("GPL"); 885