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