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/kernel.h> 9 #include <linux/module.h> 10 #include <linux/component.h> 11 #include <linux/of_device.h> 12 #include <linux/of_graph.h> 13 #include <linux/reset.h> 14 #include <linux/clk.h> 15 #include <linux/regulator/consumer.h> 16 17 #include <drm/drmP.h> 18 #include <drm/drm_atomic_helper.h> 19 #include <drm/drm_edid.h> 20 #include <drm/drm_probe_helper.h> 21 #include <drm/bridge/dw_hdmi.h> 22 23 #include <uapi/linux/media-bus-format.h> 24 #include <uapi/linux/videodev2.h> 25 26 #include "meson_drv.h" 27 #include "meson_venc.h" 28 #include "meson_vclk.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 HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */ 110 #define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */ 111 #define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */ 112 #define HHI_HDMI_PHY_CNTL5 0x3b4 /* 0xed */ 113 114 static DEFINE_SPINLOCK(reg_lock); 115 116 enum meson_venc_source { 117 MESON_VENC_SOURCE_NONE = 0, 118 MESON_VENC_SOURCE_ENCI = 1, 119 MESON_VENC_SOURCE_ENCP = 2, 120 }; 121 122 struct meson_dw_hdmi; 123 124 struct meson_dw_hdmi_data { 125 unsigned int (*top_read)(struct meson_dw_hdmi *dw_hdmi, 126 unsigned int addr); 127 void (*top_write)(struct meson_dw_hdmi *dw_hdmi, 128 unsigned int addr, unsigned int data); 129 unsigned int (*dwc_read)(struct meson_dw_hdmi *dw_hdmi, 130 unsigned int addr); 131 void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi, 132 unsigned int addr, unsigned int data); 133 }; 134 135 struct meson_dw_hdmi { 136 struct drm_encoder encoder; 137 struct dw_hdmi_plat_data dw_plat_data; 138 struct meson_drm *priv; 139 struct device *dev; 140 void __iomem *hdmitx; 141 const struct meson_dw_hdmi_data *data; 142 struct reset_control *hdmitx_apb; 143 struct reset_control *hdmitx_ctrl; 144 struct reset_control *hdmitx_phy; 145 struct clk *hdmi_pclk; 146 struct clk *venci_clk; 147 struct regulator *hdmi_supply; 148 u32 irq_stat; 149 struct dw_hdmi *hdmi; 150 }; 151 #define encoder_to_meson_dw_hdmi(x) \ 152 container_of(x, struct meson_dw_hdmi, encoder) 153 154 static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi, 155 const char *compat) 156 { 157 return of_device_is_compatible(dw_hdmi->dev->of_node, compat); 158 } 159 160 /* PHY (via TOP bridge) and Controller dedicated register interface */ 161 162 static unsigned int dw_hdmi_top_read(struct meson_dw_hdmi *dw_hdmi, 163 unsigned int addr) 164 { 165 unsigned long flags; 166 unsigned int data; 167 168 spin_lock_irqsave(®_lock, flags); 169 170 /* ADDR must be written twice */ 171 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 172 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 173 174 /* Read needs a second DATA read */ 175 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 176 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 177 178 spin_unlock_irqrestore(®_lock, flags); 179 180 return data; 181 } 182 183 static unsigned int dw_hdmi_g12a_top_read(struct meson_dw_hdmi *dw_hdmi, 184 unsigned int addr) 185 { 186 return readl(dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2)); 187 } 188 189 static inline void dw_hdmi_top_write(struct meson_dw_hdmi *dw_hdmi, 190 unsigned int addr, unsigned int data) 191 { 192 unsigned long flags; 193 194 spin_lock_irqsave(®_lock, flags); 195 196 /* ADDR must be written twice */ 197 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 198 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); 199 200 /* Write needs single DATA write */ 201 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); 202 203 spin_unlock_irqrestore(®_lock, flags); 204 } 205 206 static inline void dw_hdmi_g12a_top_write(struct meson_dw_hdmi *dw_hdmi, 207 unsigned int addr, unsigned int data) 208 { 209 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2)); 210 } 211 212 /* Helper to change specific bits in PHY registers */ 213 static inline void dw_hdmi_top_write_bits(struct meson_dw_hdmi *dw_hdmi, 214 unsigned int addr, 215 unsigned int mask, 216 unsigned int val) 217 { 218 unsigned int data = dw_hdmi->data->top_read(dw_hdmi, addr); 219 220 data &= ~mask; 221 data |= val; 222 223 dw_hdmi->data->top_write(dw_hdmi, addr, data); 224 } 225 226 static unsigned int dw_hdmi_dwc_read(struct meson_dw_hdmi *dw_hdmi, 227 unsigned int addr) 228 { 229 unsigned long flags; 230 unsigned int data; 231 232 spin_lock_irqsave(®_lock, flags); 233 234 /* ADDR must be written twice */ 235 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 236 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 237 238 /* Read needs a second DATA read */ 239 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 240 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 241 242 spin_unlock_irqrestore(®_lock, flags); 243 244 return data; 245 } 246 247 static unsigned int dw_hdmi_g12a_dwc_read(struct meson_dw_hdmi *dw_hdmi, 248 unsigned int addr) 249 { 250 return readb(dw_hdmi->hdmitx + addr); 251 } 252 253 static inline void dw_hdmi_dwc_write(struct meson_dw_hdmi *dw_hdmi, 254 unsigned int addr, unsigned int data) 255 { 256 unsigned long flags; 257 258 spin_lock_irqsave(®_lock, flags); 259 260 /* ADDR must be written twice */ 261 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 262 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); 263 264 /* Write needs single DATA write */ 265 writel(data, dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); 266 267 spin_unlock_irqrestore(®_lock, flags); 268 } 269 270 static inline void dw_hdmi_g12a_dwc_write(struct meson_dw_hdmi *dw_hdmi, 271 unsigned int addr, unsigned int data) 272 { 273 writeb(data, dw_hdmi->hdmitx + addr); 274 } 275 276 /* Helper to change specific bits in controller registers */ 277 static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi, 278 unsigned int addr, 279 unsigned int mask, 280 unsigned int val) 281 { 282 unsigned int data = dw_hdmi->data->dwc_read(dw_hdmi, addr); 283 284 data &= ~mask; 285 data |= val; 286 287 dw_hdmi->data->dwc_write(dw_hdmi, addr, data); 288 } 289 290 /* Bridge */ 291 292 /* Setup PHY bandwidth modes */ 293 static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, 294 struct drm_display_mode *mode) 295 { 296 struct meson_drm *priv = dw_hdmi->priv; 297 unsigned int pixel_clock = mode->clock; 298 299 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || 300 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { 301 if (pixel_clock >= 371250) { 302 /* 5.94Gbps, 3.7125Gbps */ 303 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x333d3282); 304 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b); 305 } else if (pixel_clock >= 297000) { 306 /* 2.97Gbps */ 307 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382); 308 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b); 309 } else if (pixel_clock >= 148500) { 310 /* 1.485Gbps */ 311 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303362); 312 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2016315b); 313 } else { 314 /* 742.5Mbps, and below */ 315 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33604142); 316 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x0016315b); 317 } 318 } else if (dw_hdmi_is_compatible(dw_hdmi, 319 "amlogic,meson-gxbb-dw-hdmi")) { 320 if (pixel_clock >= 371250) { 321 /* 5.94Gbps, 3.7125Gbps */ 322 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33353245); 323 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2100115b); 324 } else if (pixel_clock >= 297000) { 325 /* 2.97Gbps */ 326 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33634283); 327 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0xb000115b); 328 } else { 329 /* 1.485Gbps, and below */ 330 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33632122); 331 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2000115b); 332 } 333 } else if (dw_hdmi_is_compatible(dw_hdmi, 334 "amlogic,meson-g12a-dw-hdmi")) { 335 if (pixel_clock >= 371250) { 336 /* 5.94Gbps, 3.7125Gbps */ 337 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x37eb65c4); 338 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 339 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x0000080b); 340 } else if (pixel_clock >= 297000) { 341 /* 2.97Gbps */ 342 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb6262); 343 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 344 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003); 345 } else { 346 /* 1.485Gbps, and below */ 347 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb4242); 348 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); 349 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003); 350 } 351 } 352 } 353 354 static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) 355 { 356 struct meson_drm *priv = dw_hdmi->priv; 357 358 /* Enable and software reset */ 359 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xf); 360 361 mdelay(2); 362 363 /* Enable and unreset */ 364 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xe); 365 366 mdelay(2); 367 } 368 369 static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, 370 struct drm_display_mode *mode) 371 { 372 struct meson_drm *priv = dw_hdmi->priv; 373 int vic = drm_match_cea_mode(mode); 374 unsigned int vclk_freq; 375 unsigned int venc_freq; 376 unsigned int hdmi_freq; 377 378 vclk_freq = mode->clock; 379 380 if (!vic) { 381 meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq, 382 vclk_freq, vclk_freq, false); 383 return; 384 } 385 386 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 387 vclk_freq *= 2; 388 389 venc_freq = vclk_freq; 390 hdmi_freq = vclk_freq; 391 392 if (meson_venc_hdmi_venc_repeat(vic)) 393 venc_freq *= 2; 394 395 vclk_freq = max(venc_freq, hdmi_freq); 396 397 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 398 venc_freq /= 2; 399 400 DRM_DEBUG_DRIVER("vclk:%d venc=%d hdmi=%d enci=%d\n", 401 vclk_freq, venc_freq, hdmi_freq, 402 priv->venc.hdmi_use_enci); 403 404 meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, vclk_freq, 405 venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); 406 } 407 408 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, 409 struct drm_display_mode *mode) 410 { 411 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 412 struct meson_drm *priv = dw_hdmi->priv; 413 unsigned int wr_clk = 414 readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING)); 415 416 DRM_DEBUG_DRIVER("\"%s\" div%d\n", mode->name, 417 mode->clock > 340000 ? 40 : 10); 418 419 /* Enable clocks */ 420 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); 421 422 /* Bring HDMITX MEM output of power down */ 423 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); 424 425 /* Bring out of reset */ 426 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0); 427 428 /* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */ 429 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL, 430 0x3, 0x3); 431 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL, 432 0x3 << 4, 0x3 << 4); 433 434 /* Enable normal output to PHY */ 435 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); 436 437 /* TMDS pattern setup (TOFIX Handle the YUV420 case) */ 438 if (mode->clock > 340000) { 439 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 440 0); 441 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 442 0x03ff03ff); 443 } else { 444 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 445 0x001f001f); 446 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 447 0x001f001f); 448 } 449 450 /* Load TMDS pattern */ 451 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1); 452 msleep(20); 453 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); 454 455 /* Setup PHY parameters */ 456 meson_hdmi_phy_setup_mode(dw_hdmi, mode); 457 458 /* Setup PHY */ 459 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 460 0xffff << 16, 0x0390 << 16); 461 462 /* BIT_INVERT */ 463 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || 464 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || 465 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi")) 466 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 467 BIT(17), 0); 468 else 469 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 470 BIT(17), BIT(17)); 471 472 /* Disable clock, fifo, fifo_wr */ 473 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0); 474 475 dw_hdmi_set_high_tmds_clock_ratio(hdmi); 476 477 msleep(100); 478 479 /* Reset PHY 3 times in a row */ 480 meson_dw_hdmi_phy_reset(dw_hdmi); 481 meson_dw_hdmi_phy_reset(dw_hdmi); 482 meson_dw_hdmi_phy_reset(dw_hdmi); 483 484 /* Temporary Disable VENC video stream */ 485 if (priv->venc.hdmi_use_enci) 486 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 487 else 488 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 489 490 /* Temporary Disable HDMI video stream to HDMI-TX */ 491 writel_bits_relaxed(0x3, 0, 492 priv->io_base + _REG(VPU_HDMI_SETTING)); 493 writel_bits_relaxed(0xf << 8, 0, 494 priv->io_base + _REG(VPU_HDMI_SETTING)); 495 496 /* Re-Enable VENC video stream */ 497 if (priv->venc.hdmi_use_enci) 498 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 499 else 500 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); 501 502 /* Push back HDMI clock settings */ 503 writel_bits_relaxed(0xf << 8, wr_clk & (0xf << 8), 504 priv->io_base + _REG(VPU_HDMI_SETTING)); 505 506 /* Enable and Select HDMI video source for HDMI-TX */ 507 if (priv->venc.hdmi_use_enci) 508 writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCI, 509 priv->io_base + _REG(VPU_HDMI_SETTING)); 510 else 511 writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCP, 512 priv->io_base + _REG(VPU_HDMI_SETTING)); 513 514 return 0; 515 } 516 517 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, 518 void *data) 519 { 520 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 521 struct meson_drm *priv = dw_hdmi->priv; 522 523 DRM_DEBUG_DRIVER("\n"); 524 525 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); 526 } 527 528 static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi, 529 void *data) 530 { 531 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 532 533 return !!dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_STAT0) ? 534 connector_status_connected : connector_status_disconnected; 535 } 536 537 static void dw_hdmi_setup_hpd(struct dw_hdmi *hdmi, 538 void *data) 539 { 540 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; 541 542 /* Setup HPD Filter */ 543 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_HPD_FILTER, 544 (0xa << 12) | 0xa0); 545 546 /* Clear interrupts */ 547 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, 548 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL); 549 550 /* Unmask interrupts */ 551 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_INTR_MASKN, 552 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL, 553 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL); 554 } 555 556 static const struct dw_hdmi_phy_ops meson_dw_hdmi_phy_ops = { 557 .init = dw_hdmi_phy_init, 558 .disable = dw_hdmi_phy_disable, 559 .read_hpd = dw_hdmi_read_hpd, 560 .setup_hpd = dw_hdmi_setup_hpd, 561 }; 562 563 static irqreturn_t dw_hdmi_top_irq(int irq, void *dev_id) 564 { 565 struct meson_dw_hdmi *dw_hdmi = dev_id; 566 u32 stat; 567 568 stat = dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_INTR_STAT); 569 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, stat); 570 571 /* HPD Events, handle in the threaded interrupt handler */ 572 if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) { 573 dw_hdmi->irq_stat = stat; 574 return IRQ_WAKE_THREAD; 575 } 576 577 /* HDMI Controller Interrupt */ 578 if (stat & 1) 579 return IRQ_NONE; 580 581 /* TOFIX Handle HDCP Interrupts */ 582 583 return IRQ_HANDLED; 584 } 585 586 /* Threaded interrupt handler to manage HPD events */ 587 static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) 588 { 589 struct meson_dw_hdmi *dw_hdmi = dev_id; 590 u32 stat = dw_hdmi->irq_stat; 591 592 /* HPD Events */ 593 if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) { 594 bool hpd_connected = false; 595 596 if (stat & HDMITX_TOP_INTR_HPD_RISE) 597 hpd_connected = true; 598 599 dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected, 600 hpd_connected); 601 602 drm_helper_hpd_irq_event(dw_hdmi->encoder.dev); 603 } 604 605 return IRQ_HANDLED; 606 } 607 608 static enum drm_mode_status 609 dw_hdmi_mode_valid(struct drm_connector *connector, 610 const struct drm_display_mode *mode) 611 { 612 struct meson_drm *priv = connector->dev->dev_private; 613 unsigned int vclk_freq; 614 unsigned int venc_freq; 615 unsigned int hdmi_freq; 616 int vic = drm_match_cea_mode(mode); 617 enum drm_mode_status status; 618 619 DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); 620 621 /* If sink max TMDS clock, we reject the mode */ 622 if (connector->display_info.max_tmds_clock && 623 mode->clock > connector->display_info.max_tmds_clock) 624 return MODE_BAD; 625 626 /* Check against non-VIC supported modes */ 627 if (!vic) { 628 status = meson_venc_hdmi_supported_mode(mode); 629 if (status != MODE_OK) 630 return status; 631 632 return meson_vclk_dmt_supported_freq(priv, mode->clock); 633 /* Check against supported VIC modes */ 634 } else if (!meson_venc_hdmi_supported_vic(vic)) 635 return MODE_BAD; 636 637 vclk_freq = mode->clock; 638 639 /* 480i/576i needs global pixel doubling */ 640 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 641 vclk_freq *= 2; 642 643 venc_freq = vclk_freq; 644 hdmi_freq = vclk_freq; 645 646 /* VENC double pixels for 1080i and 720p modes */ 647 if (meson_venc_hdmi_venc_repeat(vic)) 648 venc_freq *= 2; 649 650 vclk_freq = max(venc_freq, hdmi_freq); 651 652 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 653 venc_freq /= 2; 654 655 dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__, 656 vclk_freq, venc_freq, hdmi_freq); 657 658 return meson_vclk_vic_supported_freq(vclk_freq); 659 } 660 661 /* Encoder */ 662 663 static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder) 664 { 665 drm_encoder_cleanup(encoder); 666 } 667 668 static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = { 669 .destroy = meson_venc_hdmi_encoder_destroy, 670 }; 671 672 static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder, 673 struct drm_crtc_state *crtc_state, 674 struct drm_connector_state *conn_state) 675 { 676 return 0; 677 } 678 679 static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder) 680 { 681 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); 682 struct meson_drm *priv = dw_hdmi->priv; 683 684 DRM_DEBUG_DRIVER("\n"); 685 686 writel_bits_relaxed(0x3, 0, 687 priv->io_base + _REG(VPU_HDMI_SETTING)); 688 689 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 690 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 691 } 692 693 static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder) 694 { 695 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); 696 struct meson_drm *priv = dw_hdmi->priv; 697 698 DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); 699 700 if (priv->venc.hdmi_use_enci) 701 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 702 else 703 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); 704 } 705 706 static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder, 707 struct drm_display_mode *mode, 708 struct drm_display_mode *adjusted_mode) 709 { 710 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); 711 struct meson_drm *priv = dw_hdmi->priv; 712 int vic = drm_match_cea_mode(mode); 713 714 DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic); 715 716 /* VENC + VENC-DVI Mode setup */ 717 meson_venc_hdmi_mode_set(priv, vic, mode); 718 719 /* VCLK Set clock */ 720 dw_hdmi_set_vclk(dw_hdmi, mode); 721 722 /* Setup YUV444 to HDMI-TX, no 10bit diphering */ 723 writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); 724 } 725 726 static const struct drm_encoder_helper_funcs 727 meson_venc_hdmi_encoder_helper_funcs = { 728 .atomic_check = meson_venc_hdmi_encoder_atomic_check, 729 .disable = meson_venc_hdmi_encoder_disable, 730 .enable = meson_venc_hdmi_encoder_enable, 731 .mode_set = meson_venc_hdmi_encoder_mode_set, 732 }; 733 734 /* DW HDMI Regmap */ 735 736 static int meson_dw_hdmi_reg_read(void *context, unsigned int reg, 737 unsigned int *result) 738 { 739 struct meson_dw_hdmi *dw_hdmi = context; 740 741 *result = dw_hdmi->data->dwc_read(dw_hdmi, reg); 742 743 return 0; 744 745 } 746 747 static int meson_dw_hdmi_reg_write(void *context, unsigned int reg, 748 unsigned int val) 749 { 750 struct meson_dw_hdmi *dw_hdmi = context; 751 752 dw_hdmi->data->dwc_write(dw_hdmi, reg, val); 753 754 return 0; 755 } 756 757 static const struct regmap_config meson_dw_hdmi_regmap_config = { 758 .reg_bits = 32, 759 .val_bits = 8, 760 .reg_read = meson_dw_hdmi_reg_read, 761 .reg_write = meson_dw_hdmi_reg_write, 762 .max_register = 0x10000, 763 .fast_io = true, 764 }; 765 766 static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = { 767 .top_read = dw_hdmi_top_read, 768 .top_write = dw_hdmi_top_write, 769 .dwc_read = dw_hdmi_dwc_read, 770 .dwc_write = dw_hdmi_dwc_write, 771 }; 772 773 static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = { 774 .top_read = dw_hdmi_g12a_top_read, 775 .top_write = dw_hdmi_g12a_top_write, 776 .dwc_read = dw_hdmi_g12a_dwc_read, 777 .dwc_write = dw_hdmi_g12a_dwc_write, 778 }; 779 780 static bool meson_hdmi_connector_is_available(struct device *dev) 781 { 782 struct device_node *ep, *remote; 783 784 /* HDMI Connector is on the second port, first endpoint */ 785 ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0); 786 if (!ep) 787 return false; 788 789 /* If the endpoint node exists, consider it enabled */ 790 remote = of_graph_get_remote_port(ep); 791 if (remote) { 792 of_node_put(ep); 793 return true; 794 } 795 796 of_node_put(ep); 797 of_node_put(remote); 798 799 return false; 800 } 801 802 static int meson_dw_hdmi_bind(struct device *dev, struct device *master, 803 void *data) 804 { 805 struct platform_device *pdev = to_platform_device(dev); 806 const struct meson_dw_hdmi_data *match; 807 struct meson_dw_hdmi *meson_dw_hdmi; 808 struct drm_device *drm = data; 809 struct meson_drm *priv = drm->dev_private; 810 struct dw_hdmi_plat_data *dw_plat_data; 811 struct drm_encoder *encoder; 812 struct resource *res; 813 int irq; 814 int ret; 815 816 DRM_DEBUG_DRIVER("\n"); 817 818 if (!meson_hdmi_connector_is_available(dev)) { 819 dev_info(drm->dev, "HDMI Output connector not available\n"); 820 return -ENODEV; 821 } 822 823 match = of_device_get_match_data(&pdev->dev); 824 if (!match) { 825 dev_err(&pdev->dev, "failed to get match data\n"); 826 return -ENODEV; 827 } 828 829 meson_dw_hdmi = devm_kzalloc(dev, sizeof(*meson_dw_hdmi), 830 GFP_KERNEL); 831 if (!meson_dw_hdmi) 832 return -ENOMEM; 833 834 meson_dw_hdmi->priv = priv; 835 meson_dw_hdmi->dev = dev; 836 meson_dw_hdmi->data = match; 837 dw_plat_data = &meson_dw_hdmi->dw_plat_data; 838 encoder = &meson_dw_hdmi->encoder; 839 840 meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi"); 841 if (IS_ERR(meson_dw_hdmi->hdmi_supply)) { 842 if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER) 843 return -EPROBE_DEFER; 844 meson_dw_hdmi->hdmi_supply = NULL; 845 } else { 846 ret = regulator_enable(meson_dw_hdmi->hdmi_supply); 847 if (ret) 848 return ret; 849 } 850 851 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, 852 "hdmitx_apb"); 853 if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { 854 dev_err(dev, "Failed to get hdmitx_apb reset\n"); 855 return PTR_ERR(meson_dw_hdmi->hdmitx_apb); 856 } 857 858 meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev, 859 "hdmitx"); 860 if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) { 861 dev_err(dev, "Failed to get hdmitx reset\n"); 862 return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl); 863 } 864 865 meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev, 866 "hdmitx_phy"); 867 if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) { 868 dev_err(dev, "Failed to get hdmitx_phy reset\n"); 869 return PTR_ERR(meson_dw_hdmi->hdmitx_phy); 870 } 871 872 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 873 meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res); 874 if (IS_ERR(meson_dw_hdmi->hdmitx)) 875 return PTR_ERR(meson_dw_hdmi->hdmitx); 876 877 meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr"); 878 if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) { 879 dev_err(dev, "Unable to get HDMI pclk\n"); 880 return PTR_ERR(meson_dw_hdmi->hdmi_pclk); 881 } 882 clk_prepare_enable(meson_dw_hdmi->hdmi_pclk); 883 884 meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci"); 885 if (IS_ERR(meson_dw_hdmi->venci_clk)) { 886 dev_err(dev, "Unable to get venci clk\n"); 887 return PTR_ERR(meson_dw_hdmi->venci_clk); 888 } 889 clk_prepare_enable(meson_dw_hdmi->venci_clk); 890 891 dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, 892 &meson_dw_hdmi_regmap_config); 893 if (IS_ERR(dw_plat_data->regm)) 894 return PTR_ERR(dw_plat_data->regm); 895 896 irq = platform_get_irq(pdev, 0); 897 if (irq < 0) { 898 dev_err(dev, "Failed to get hdmi top irq\n"); 899 return irq; 900 } 901 902 ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq, 903 dw_hdmi_top_thread_irq, IRQF_SHARED, 904 "dw_hdmi_top_irq", meson_dw_hdmi); 905 if (ret) { 906 dev_err(dev, "Failed to request hdmi top irq\n"); 907 return ret; 908 } 909 910 /* Encoder */ 911 912 drm_encoder_helper_add(encoder, &meson_venc_hdmi_encoder_helper_funcs); 913 914 ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs, 915 DRM_MODE_ENCODER_TMDS, "meson_hdmi"); 916 if (ret) { 917 dev_err(priv->dev, "Failed to init HDMI encoder\n"); 918 return ret; 919 } 920 921 encoder->possible_crtcs = BIT(0); 922 923 DRM_DEBUG_DRIVER("encoder initialized\n"); 924 925 /* Enable clocks */ 926 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); 927 928 /* Bring HDMITX MEM output of power down */ 929 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); 930 931 /* Reset HDMITX APB & TX & PHY */ 932 reset_control_reset(meson_dw_hdmi->hdmitx_apb); 933 reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); 934 reset_control_reset(meson_dw_hdmi->hdmitx_phy); 935 936 /* Enable APB3 fail on error */ 937 if (!meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) { 938 writel_bits_relaxed(BIT(15), BIT(15), 939 meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG); 940 writel_bits_relaxed(BIT(15), BIT(15), 941 meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG); 942 } 943 944 /* Bring out of reset */ 945 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 946 HDMITX_TOP_SW_RESET, 0); 947 948 msleep(20); 949 950 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 951 HDMITX_TOP_CLK_CNTL, 0xff); 952 953 /* Enable HDMI-TX Interrupt */ 954 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, 955 HDMITX_TOP_INTR_CORE); 956 957 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN, 958 HDMITX_TOP_INTR_CORE); 959 960 /* Bridge / Connector */ 961 962 dw_plat_data->mode_valid = dw_hdmi_mode_valid; 963 dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; 964 dw_plat_data->phy_name = "meson_dw_hdmi_phy"; 965 dw_plat_data->phy_data = meson_dw_hdmi; 966 dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; 967 dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; 968 969 platform_set_drvdata(pdev, meson_dw_hdmi); 970 971 meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder, 972 &meson_dw_hdmi->dw_plat_data); 973 if (IS_ERR(meson_dw_hdmi->hdmi)) 974 return PTR_ERR(meson_dw_hdmi->hdmi); 975 976 DRM_DEBUG_DRIVER("HDMI controller initialized\n"); 977 978 return 0; 979 } 980 981 static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, 982 void *data) 983 { 984 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 985 986 dw_hdmi_unbind(meson_dw_hdmi->hdmi); 987 } 988 989 static const struct component_ops meson_dw_hdmi_ops = { 990 .bind = meson_dw_hdmi_bind, 991 .unbind = meson_dw_hdmi_unbind, 992 }; 993 994 static int meson_dw_hdmi_probe(struct platform_device *pdev) 995 { 996 return component_add(&pdev->dev, &meson_dw_hdmi_ops); 997 } 998 999 static int meson_dw_hdmi_remove(struct platform_device *pdev) 1000 { 1001 component_del(&pdev->dev, &meson_dw_hdmi_ops); 1002 1003 return 0; 1004 } 1005 1006 static const struct of_device_id meson_dw_hdmi_of_table[] = { 1007 { .compatible = "amlogic,meson-gxbb-dw-hdmi", 1008 .data = &meson_dw_hdmi_gx_data }, 1009 { .compatible = "amlogic,meson-gxl-dw-hdmi", 1010 .data = &meson_dw_hdmi_gx_data }, 1011 { .compatible = "amlogic,meson-gxm-dw-hdmi", 1012 .data = &meson_dw_hdmi_gx_data }, 1013 { .compatible = "amlogic,meson-g12a-dw-hdmi", 1014 .data = &meson_dw_hdmi_g12a_data }, 1015 { } 1016 }; 1017 MODULE_DEVICE_TABLE(of, meson_dw_hdmi_of_table); 1018 1019 static struct platform_driver meson_dw_hdmi_platform_driver = { 1020 .probe = meson_dw_hdmi_probe, 1021 .remove = meson_dw_hdmi_remove, 1022 .driver = { 1023 .name = DRIVER_NAME, 1024 .of_match_table = meson_dw_hdmi_of_table, 1025 }, 1026 }; 1027 module_platform_driver(meson_dw_hdmi_platform_driver); 1028 1029 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 1030 MODULE_DESCRIPTION(DRIVER_DESC); 1031 MODULE_LICENSE("GPL"); 1032