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