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 (connector->display_info.max_tmds_clock && 635 mode->clock > connector->display_info.max_tmds_clock) 636 return MODE_BAD; 637 638 /* Check against non-VIC supported modes */ 639 if (!vic) { 640 status = meson_venc_hdmi_supported_mode(mode); 641 if (status != MODE_OK) 642 return status; 643 644 return meson_vclk_dmt_supported_freq(priv, mode->clock); 645 /* Check against supported VIC modes */ 646 } else if (!meson_venc_hdmi_supported_vic(vic)) 647 return MODE_BAD; 648 649 vclk_freq = mode->clock; 650 651 /* 480i/576i needs global pixel doubling */ 652 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 653 vclk_freq *= 2; 654 655 venc_freq = vclk_freq; 656 hdmi_freq = vclk_freq; 657 658 /* VENC double pixels for 1080i and 720p modes */ 659 if (meson_venc_hdmi_venc_repeat(vic)) 660 venc_freq *= 2; 661 662 vclk_freq = max(venc_freq, hdmi_freq); 663 664 if (mode->flags & DRM_MODE_FLAG_DBLCLK) 665 venc_freq /= 2; 666 667 dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__, 668 vclk_freq, venc_freq, hdmi_freq); 669 670 return meson_vclk_vic_supported_freq(vclk_freq); 671 } 672 673 /* Encoder */ 674 675 static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder) 676 { 677 drm_encoder_cleanup(encoder); 678 } 679 680 static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = { 681 .destroy = meson_venc_hdmi_encoder_destroy, 682 }; 683 684 static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder, 685 struct drm_crtc_state *crtc_state, 686 struct drm_connector_state *conn_state) 687 { 688 return 0; 689 } 690 691 static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder) 692 { 693 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); 694 struct meson_drm *priv = dw_hdmi->priv; 695 696 DRM_DEBUG_DRIVER("\n"); 697 698 writel_bits_relaxed(0x3, 0, 699 priv->io_base + _REG(VPU_HDMI_SETTING)); 700 701 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 702 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); 703 } 704 705 static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder) 706 { 707 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); 708 struct meson_drm *priv = dw_hdmi->priv; 709 710 DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); 711 712 if (priv->venc.hdmi_use_enci) 713 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); 714 else 715 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); 716 } 717 718 static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder, 719 struct drm_display_mode *mode, 720 struct drm_display_mode *adjusted_mode) 721 { 722 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); 723 struct meson_drm *priv = dw_hdmi->priv; 724 int vic = drm_match_cea_mode(mode); 725 726 DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic); 727 728 /* VENC + VENC-DVI Mode setup */ 729 meson_venc_hdmi_mode_set(priv, vic, mode); 730 731 /* VCLK Set clock */ 732 dw_hdmi_set_vclk(dw_hdmi, mode); 733 734 /* Setup YUV444 to HDMI-TX, no 10bit diphering */ 735 writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); 736 } 737 738 static const struct drm_encoder_helper_funcs 739 meson_venc_hdmi_encoder_helper_funcs = { 740 .atomic_check = meson_venc_hdmi_encoder_atomic_check, 741 .disable = meson_venc_hdmi_encoder_disable, 742 .enable = meson_venc_hdmi_encoder_enable, 743 .mode_set = meson_venc_hdmi_encoder_mode_set, 744 }; 745 746 /* DW HDMI Regmap */ 747 748 static int meson_dw_hdmi_reg_read(void *context, unsigned int reg, 749 unsigned int *result) 750 { 751 struct meson_dw_hdmi *dw_hdmi = context; 752 753 *result = dw_hdmi->data->dwc_read(dw_hdmi, reg); 754 755 return 0; 756 757 } 758 759 static int meson_dw_hdmi_reg_write(void *context, unsigned int reg, 760 unsigned int val) 761 { 762 struct meson_dw_hdmi *dw_hdmi = context; 763 764 dw_hdmi->data->dwc_write(dw_hdmi, reg, val); 765 766 return 0; 767 } 768 769 static const struct regmap_config meson_dw_hdmi_regmap_config = { 770 .reg_bits = 32, 771 .val_bits = 8, 772 .reg_read = meson_dw_hdmi_reg_read, 773 .reg_write = meson_dw_hdmi_reg_write, 774 .max_register = 0x10000, 775 .fast_io = true, 776 }; 777 778 static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = { 779 .top_read = dw_hdmi_top_read, 780 .top_write = dw_hdmi_top_write, 781 .dwc_read = dw_hdmi_dwc_read, 782 .dwc_write = dw_hdmi_dwc_write, 783 }; 784 785 static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = { 786 .top_read = dw_hdmi_g12a_top_read, 787 .top_write = dw_hdmi_g12a_top_write, 788 .dwc_read = dw_hdmi_g12a_dwc_read, 789 .dwc_write = dw_hdmi_g12a_dwc_write, 790 }; 791 792 static bool meson_hdmi_connector_is_available(struct device *dev) 793 { 794 struct device_node *ep, *remote; 795 796 /* HDMI Connector is on the second port, first endpoint */ 797 ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0); 798 if (!ep) 799 return false; 800 801 /* If the endpoint node exists, consider it enabled */ 802 remote = of_graph_get_remote_port(ep); 803 if (remote) { 804 of_node_put(ep); 805 return true; 806 } 807 808 of_node_put(ep); 809 of_node_put(remote); 810 811 return false; 812 } 813 814 static int meson_dw_hdmi_bind(struct device *dev, struct device *master, 815 void *data) 816 { 817 struct platform_device *pdev = to_platform_device(dev); 818 const struct meson_dw_hdmi_data *match; 819 struct meson_dw_hdmi *meson_dw_hdmi; 820 struct drm_device *drm = data; 821 struct meson_drm *priv = drm->dev_private; 822 struct dw_hdmi_plat_data *dw_plat_data; 823 struct drm_encoder *encoder; 824 struct resource *res; 825 int irq; 826 int ret; 827 828 DRM_DEBUG_DRIVER("\n"); 829 830 if (!meson_hdmi_connector_is_available(dev)) { 831 dev_info(drm->dev, "HDMI Output connector not available\n"); 832 return -ENODEV; 833 } 834 835 match = of_device_get_match_data(&pdev->dev); 836 if (!match) { 837 dev_err(&pdev->dev, "failed to get match data\n"); 838 return -ENODEV; 839 } 840 841 meson_dw_hdmi = devm_kzalloc(dev, sizeof(*meson_dw_hdmi), 842 GFP_KERNEL); 843 if (!meson_dw_hdmi) 844 return -ENOMEM; 845 846 meson_dw_hdmi->priv = priv; 847 meson_dw_hdmi->dev = dev; 848 meson_dw_hdmi->data = match; 849 dw_plat_data = &meson_dw_hdmi->dw_plat_data; 850 encoder = &meson_dw_hdmi->encoder; 851 852 meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi"); 853 if (IS_ERR(meson_dw_hdmi->hdmi_supply)) { 854 if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER) 855 return -EPROBE_DEFER; 856 meson_dw_hdmi->hdmi_supply = NULL; 857 } else { 858 ret = regulator_enable(meson_dw_hdmi->hdmi_supply); 859 if (ret) 860 return ret; 861 } 862 863 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, 864 "hdmitx_apb"); 865 if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { 866 dev_err(dev, "Failed to get hdmitx_apb reset\n"); 867 return PTR_ERR(meson_dw_hdmi->hdmitx_apb); 868 } 869 870 meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev, 871 "hdmitx"); 872 if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) { 873 dev_err(dev, "Failed to get hdmitx reset\n"); 874 return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl); 875 } 876 877 meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev, 878 "hdmitx_phy"); 879 if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) { 880 dev_err(dev, "Failed to get hdmitx_phy reset\n"); 881 return PTR_ERR(meson_dw_hdmi->hdmitx_phy); 882 } 883 884 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 885 meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res); 886 if (IS_ERR(meson_dw_hdmi->hdmitx)) 887 return PTR_ERR(meson_dw_hdmi->hdmitx); 888 889 meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr"); 890 if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) { 891 dev_err(dev, "Unable to get HDMI pclk\n"); 892 return PTR_ERR(meson_dw_hdmi->hdmi_pclk); 893 } 894 clk_prepare_enable(meson_dw_hdmi->hdmi_pclk); 895 896 meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci"); 897 if (IS_ERR(meson_dw_hdmi->venci_clk)) { 898 dev_err(dev, "Unable to get venci clk\n"); 899 return PTR_ERR(meson_dw_hdmi->venci_clk); 900 } 901 clk_prepare_enable(meson_dw_hdmi->venci_clk); 902 903 dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, 904 &meson_dw_hdmi_regmap_config); 905 if (IS_ERR(dw_plat_data->regm)) 906 return PTR_ERR(dw_plat_data->regm); 907 908 irq = platform_get_irq(pdev, 0); 909 if (irq < 0) { 910 dev_err(dev, "Failed to get hdmi top irq\n"); 911 return irq; 912 } 913 914 ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq, 915 dw_hdmi_top_thread_irq, IRQF_SHARED, 916 "dw_hdmi_top_irq", meson_dw_hdmi); 917 if (ret) { 918 dev_err(dev, "Failed to request hdmi top irq\n"); 919 return ret; 920 } 921 922 /* Encoder */ 923 924 drm_encoder_helper_add(encoder, &meson_venc_hdmi_encoder_helper_funcs); 925 926 ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs, 927 DRM_MODE_ENCODER_TMDS, "meson_hdmi"); 928 if (ret) { 929 dev_err(priv->dev, "Failed to init HDMI encoder\n"); 930 return ret; 931 } 932 933 encoder->possible_crtcs = BIT(0); 934 935 DRM_DEBUG_DRIVER("encoder initialized\n"); 936 937 /* Enable clocks */ 938 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); 939 940 /* Bring HDMITX MEM output of power down */ 941 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); 942 943 /* Reset HDMITX APB & TX & PHY */ 944 reset_control_reset(meson_dw_hdmi->hdmitx_apb); 945 reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); 946 reset_control_reset(meson_dw_hdmi->hdmitx_phy); 947 948 /* Enable APB3 fail on error */ 949 if (!meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) { 950 writel_bits_relaxed(BIT(15), BIT(15), 951 meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG); 952 writel_bits_relaxed(BIT(15), BIT(15), 953 meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG); 954 } 955 956 /* Bring out of reset */ 957 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 958 HDMITX_TOP_SW_RESET, 0); 959 960 msleep(20); 961 962 meson_dw_hdmi->data->top_write(meson_dw_hdmi, 963 HDMITX_TOP_CLK_CNTL, 0xff); 964 965 /* Enable HDMI-TX Interrupt */ 966 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, 967 HDMITX_TOP_INTR_CORE); 968 969 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN, 970 HDMITX_TOP_INTR_CORE); 971 972 /* Bridge / Connector */ 973 974 dw_plat_data->mode_valid = dw_hdmi_mode_valid; 975 dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; 976 dw_plat_data->phy_name = "meson_dw_hdmi_phy"; 977 dw_plat_data->phy_data = meson_dw_hdmi; 978 dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; 979 dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; 980 981 platform_set_drvdata(pdev, meson_dw_hdmi); 982 983 meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder, 984 &meson_dw_hdmi->dw_plat_data); 985 if (IS_ERR(meson_dw_hdmi->hdmi)) 986 return PTR_ERR(meson_dw_hdmi->hdmi); 987 988 DRM_DEBUG_DRIVER("HDMI controller initialized\n"); 989 990 return 0; 991 } 992 993 static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, 994 void *data) 995 { 996 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 997 998 dw_hdmi_unbind(meson_dw_hdmi->hdmi); 999 } 1000 1001 static const struct component_ops meson_dw_hdmi_ops = { 1002 .bind = meson_dw_hdmi_bind, 1003 .unbind = meson_dw_hdmi_unbind, 1004 }; 1005 1006 static int meson_dw_hdmi_probe(struct platform_device *pdev) 1007 { 1008 return component_add(&pdev->dev, &meson_dw_hdmi_ops); 1009 } 1010 1011 static int meson_dw_hdmi_remove(struct platform_device *pdev) 1012 { 1013 component_del(&pdev->dev, &meson_dw_hdmi_ops); 1014 1015 return 0; 1016 } 1017 1018 static const struct of_device_id meson_dw_hdmi_of_table[] = { 1019 { .compatible = "amlogic,meson-gxbb-dw-hdmi", 1020 .data = &meson_dw_hdmi_gx_data }, 1021 { .compatible = "amlogic,meson-gxl-dw-hdmi", 1022 .data = &meson_dw_hdmi_gx_data }, 1023 { .compatible = "amlogic,meson-gxm-dw-hdmi", 1024 .data = &meson_dw_hdmi_gx_data }, 1025 { .compatible = "amlogic,meson-g12a-dw-hdmi", 1026 .data = &meson_dw_hdmi_g12a_data }, 1027 { } 1028 }; 1029 MODULE_DEVICE_TABLE(of, meson_dw_hdmi_of_table); 1030 1031 static struct platform_driver meson_dw_hdmi_platform_driver = { 1032 .probe = meson_dw_hdmi_probe, 1033 .remove = meson_dw_hdmi_remove, 1034 .driver = { 1035 .name = DRIVER_NAME, 1036 .of_match_table = meson_dw_hdmi_of_table, 1037 }, 1038 }; 1039 module_platform_driver(meson_dw_hdmi_platform_driver); 1040 1041 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 1042 MODULE_DESCRIPTION(DRIVER_DESC); 1043 MODULE_LICENSE("GPL"); 1044