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