linux/drivers/gpu/drm/vc4/vc4_hdmi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2015 Broadcom
   4 * Copyright (c) 2014 The Linux Foundation. All rights reserved.
   5 * Copyright (C) 2013 Red Hat
   6 * Author: Rob Clark <robdclark@gmail.com>
   7 */
   8
   9/**
  10 * DOC: VC4 Falcon HDMI module
  11 *
  12 * The HDMI core has a state machine and a PHY.  On BCM2835, most of
  13 * the unit operates off of the HSM clock from CPRMAN.  It also
  14 * internally uses the PLLH_PIX clock for the PHY.
  15 *
  16 * HDMI infoframes are kept within a small packet ram, where each
  17 * packet can be individually enabled for including in a frame.
  18 *
  19 * HDMI audio is implemented entirely within the HDMI IP block.  A
  20 * register in the HDMI encoder takes SPDIF frames from the DMA engine
  21 * and transfers them over an internal MAI (multi-channel audio
  22 * interconnect) bus to the encoder side for insertion into the video
  23 * blank regions.
  24 *
  25 * The driver's HDMI encoder does not yet support power management.
  26 * The HDMI encoder's power domain and the HSM/pixel clocks are kept
  27 * continuously running, and only the HDMI logic and packet ram are
  28 * powered off/on at disable/enable time.
  29 *
  30 * The driver does not yet support CEC control, though the HDMI
  31 * encoder block has CEC support.
  32 */
  33
  34#include <drm/drm_atomic_helper.h>
  35#include <drm/drm_edid.h>
  36#include <drm/drm_probe_helper.h>
  37#include <drm/drm_simple_kms_helper.h>
  38#include <linux/clk.h>
  39#include <linux/component.h>
  40#include <linux/i2c.h>
  41#include <linux/of_address.h>
  42#include <linux/of_gpio.h>
  43#include <linux/of_platform.h>
  44#include <linux/pm_runtime.h>
  45#include <linux/rational.h>
  46#include <linux/reset.h>
  47#include <sound/dmaengine_pcm.h>
  48#include <sound/pcm_drm_eld.h>
  49#include <sound/pcm_params.h>
  50#include <sound/soc.h>
  51#include "media/cec.h"
  52#include "vc4_drv.h"
  53#include "vc4_hdmi.h"
  54#include "vc4_hdmi_regs.h"
  55#include "vc4_regs.h"
  56
  57#define VC5_HDMI_HORZA_HFP_SHIFT                16
  58#define VC5_HDMI_HORZA_HFP_MASK                 VC4_MASK(28, 16)
  59#define VC5_HDMI_HORZA_VPOS                     BIT(15)
  60#define VC5_HDMI_HORZA_HPOS                     BIT(14)
  61#define VC5_HDMI_HORZA_HAP_SHIFT                0
  62#define VC5_HDMI_HORZA_HAP_MASK                 VC4_MASK(13, 0)
  63
  64#define VC5_HDMI_HORZB_HBP_SHIFT                16
  65#define VC5_HDMI_HORZB_HBP_MASK                 VC4_MASK(26, 16)
  66#define VC5_HDMI_HORZB_HSP_SHIFT                0
  67#define VC5_HDMI_HORZB_HSP_MASK                 VC4_MASK(10, 0)
  68
  69#define VC5_HDMI_VERTA_VSP_SHIFT                24
  70#define VC5_HDMI_VERTA_VSP_MASK                 VC4_MASK(28, 24)
  71#define VC5_HDMI_VERTA_VFP_SHIFT                16
  72#define VC5_HDMI_VERTA_VFP_MASK                 VC4_MASK(22, 16)
  73#define VC5_HDMI_VERTA_VAL_SHIFT                0
  74#define VC5_HDMI_VERTA_VAL_MASK                 VC4_MASK(12, 0)
  75
  76#define VC5_HDMI_VERTB_VSPO_SHIFT               16
  77#define VC5_HDMI_VERTB_VSPO_MASK                VC4_MASK(29, 16)
  78
  79# define VC4_HD_M_SW_RST                        BIT(2)
  80# define VC4_HD_M_ENABLE                        BIT(0)
  81
  82#define CEC_CLOCK_FREQ 40000
  83#define VC4_HSM_MID_CLOCK 149985000
  84
  85static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
  86{
  87        struct drm_info_node *node = (struct drm_info_node *)m->private;
  88        struct vc4_hdmi *vc4_hdmi = node->info_ent->data;
  89        struct drm_printer p = drm_seq_file_printer(m);
  90
  91        drm_print_regset32(&p, &vc4_hdmi->hdmi_regset);
  92        drm_print_regset32(&p, &vc4_hdmi->hd_regset);
  93
  94        return 0;
  95}
  96
  97static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
  98{
  99        HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_SW_RST);
 100        udelay(1);
 101        HDMI_WRITE(HDMI_M_CTL, 0);
 102
 103        HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_ENABLE);
 104
 105        HDMI_WRITE(HDMI_SW_RESET_CONTROL,
 106                   VC4_HDMI_SW_RESET_HDMI |
 107                   VC4_HDMI_SW_RESET_FORMAT_DETECT);
 108
 109        HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
 110}
 111
 112static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
 113{
 114        reset_control_reset(vc4_hdmi->reset);
 115
 116        HDMI_WRITE(HDMI_DVP_CTL, 0);
 117
 118        HDMI_WRITE(HDMI_CLOCK_STOP,
 119                   HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
 120}
 121
 122static enum drm_connector_status
 123vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
 124{
 125        struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 126
 127        if (vc4_hdmi->hpd_gpio) {
 128                if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
 129                    vc4_hdmi->hpd_active_low)
 130                        return connector_status_connected;
 131                cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
 132                return connector_status_disconnected;
 133        }
 134
 135        if (drm_probe_ddc(vc4_hdmi->ddc))
 136                return connector_status_connected;
 137
 138        if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
 139                return connector_status_connected;
 140        cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
 141        return connector_status_disconnected;
 142}
 143
 144static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
 145{
 146        drm_connector_unregister(connector);
 147        drm_connector_cleanup(connector);
 148}
 149
 150static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 151{
 152        struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 153        struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder;
 154        int ret = 0;
 155        struct edid *edid;
 156
 157        edid = drm_get_edid(connector, vc4_hdmi->ddc);
 158        cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid);
 159        if (!edid)
 160                return -ENODEV;
 161
 162        vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
 163
 164        drm_connector_update_edid_property(connector, edid);
 165        ret = drm_add_edid_modes(connector, edid);
 166        kfree(edid);
 167
 168        return ret;
 169}
 170
 171static void vc4_hdmi_connector_reset(struct drm_connector *connector)
 172{
 173        drm_atomic_helper_connector_reset(connector);
 174        drm_atomic_helper_connector_tv_reset(connector);
 175}
 176
 177static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
 178        .detect = vc4_hdmi_connector_detect,
 179        .fill_modes = drm_helper_probe_single_connector_modes,
 180        .destroy = vc4_hdmi_connector_destroy,
 181        .reset = vc4_hdmi_connector_reset,
 182        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 183        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 184};
 185
 186static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
 187        .get_modes = vc4_hdmi_connector_get_modes,
 188};
 189
 190static int vc4_hdmi_connector_init(struct drm_device *dev,
 191                                   struct vc4_hdmi *vc4_hdmi)
 192{
 193        struct drm_connector *connector = &vc4_hdmi->connector;
 194        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 195        int ret;
 196
 197        drm_connector_init_with_ddc(dev, connector,
 198                                    &vc4_hdmi_connector_funcs,
 199                                    DRM_MODE_CONNECTOR_HDMIA,
 200                                    vc4_hdmi->ddc);
 201        drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
 202
 203        /* Create and attach TV margin props to this connector. */
 204        ret = drm_mode_create_tv_margin_properties(dev);
 205        if (ret)
 206                return ret;
 207
 208        drm_connector_attach_tv_margin_properties(connector);
 209
 210        connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
 211                             DRM_CONNECTOR_POLL_DISCONNECT);
 212
 213        connector->interlace_allowed = 1;
 214        connector->doublescan_allowed = 0;
 215
 216        drm_connector_attach_encoder(connector, encoder);
 217
 218        return 0;
 219}
 220
 221static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
 222                                enum hdmi_infoframe_type type)
 223{
 224        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 225        u32 packet_id = type - 0x80;
 226
 227        HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
 228                   HDMI_READ(HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
 229
 230        return wait_for(!(HDMI_READ(HDMI_RAM_PACKET_STATUS) &
 231                          BIT(packet_id)), 100);
 232}
 233
 234static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
 235                                     union hdmi_infoframe *frame)
 236{
 237        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 238        u32 packet_id = frame->any.type - 0x80;
 239        const struct vc4_hdmi_register *ram_packet_start =
 240                &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START];
 241        u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id;
 242        void __iomem *base = __vc4_hdmi_get_field_base(vc4_hdmi,
 243                                                       ram_packet_start->reg);
 244        uint8_t buffer[VC4_HDMI_PACKET_STRIDE];
 245        ssize_t len, i;
 246        int ret;
 247
 248        WARN_ONCE(!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
 249                    VC4_HDMI_RAM_PACKET_ENABLE),
 250                  "Packet RAM has to be on to store the packet.");
 251
 252        len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
 253        if (len < 0)
 254                return;
 255
 256        ret = vc4_hdmi_stop_packet(encoder, frame->any.type);
 257        if (ret) {
 258                DRM_ERROR("Failed to wait for infoframe to go idle: %d\n", ret);
 259                return;
 260        }
 261
 262        for (i = 0; i < len; i += 7) {
 263                writel(buffer[i + 0] << 0 |
 264                       buffer[i + 1] << 8 |
 265                       buffer[i + 2] << 16,
 266                       base + packet_reg);
 267                packet_reg += 4;
 268
 269                writel(buffer[i + 3] << 0 |
 270                       buffer[i + 4] << 8 |
 271                       buffer[i + 5] << 16 |
 272                       buffer[i + 6] << 24,
 273                       base + packet_reg);
 274                packet_reg += 4;
 275        }
 276
 277        HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
 278                   HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id));
 279        ret = wait_for((HDMI_READ(HDMI_RAM_PACKET_STATUS) &
 280                        BIT(packet_id)), 100);
 281        if (ret)
 282                DRM_ERROR("Failed to wait for infoframe to start: %d\n", ret);
 283}
 284
 285static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
 286{
 287        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 288        struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
 289        struct drm_connector *connector = &vc4_hdmi->connector;
 290        struct drm_connector_state *cstate = connector->state;
 291        struct drm_crtc *crtc = encoder->crtc;
 292        const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 293        union hdmi_infoframe frame;
 294        int ret;
 295
 296        ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
 297                                                       connector, mode);
 298        if (ret < 0) {
 299                DRM_ERROR("couldn't fill AVI infoframe\n");
 300                return;
 301        }
 302
 303        drm_hdmi_avi_infoframe_quant_range(&frame.avi,
 304                                           connector, mode,
 305                                           vc4_encoder->limited_rgb_range ?
 306                                           HDMI_QUANTIZATION_RANGE_LIMITED :
 307                                           HDMI_QUANTIZATION_RANGE_FULL);
 308
 309        drm_hdmi_avi_infoframe_bars(&frame.avi, cstate);
 310
 311        vc4_hdmi_write_infoframe(encoder, &frame);
 312}
 313
 314static void vc4_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
 315{
 316        union hdmi_infoframe frame;
 317        int ret;
 318
 319        ret = hdmi_spd_infoframe_init(&frame.spd, "Broadcom", "Videocore");
 320        if (ret < 0) {
 321                DRM_ERROR("couldn't fill SPD infoframe\n");
 322                return;
 323        }
 324
 325        frame.spd.sdi = HDMI_SPD_SDI_PC;
 326
 327        vc4_hdmi_write_infoframe(encoder, &frame);
 328}
 329
 330static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder)
 331{
 332        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 333        union hdmi_infoframe frame;
 334
 335        hdmi_audio_infoframe_init(&frame.audio);
 336
 337        frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
 338        frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
 339        frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
 340        frame.audio.channels = vc4_hdmi->audio.channels;
 341
 342        vc4_hdmi_write_infoframe(encoder, &frame);
 343}
 344
 345static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
 346{
 347        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 348
 349        vc4_hdmi_set_avi_infoframe(encoder);
 350        vc4_hdmi_set_spd_infoframe(encoder);
 351        /*
 352         * If audio was streaming, then we need to reenabled the audio
 353         * infoframe here during encoder_enable.
 354         */
 355        if (vc4_hdmi->audio.streaming)
 356                vc4_hdmi_set_audio_infoframe(encoder);
 357}
 358
 359static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder)
 360{
 361        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 362
 363        HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
 364
 365        HDMI_WRITE(HDMI_VID_CTL, HDMI_READ(HDMI_VID_CTL) |
 366                   VC4_HD_VID_CTL_CLRRGB | VC4_HD_VID_CTL_CLRSYNC);
 367
 368        HDMI_WRITE(HDMI_VID_CTL,
 369                   HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_BLANKPIX);
 370}
 371
 372static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder)
 373{
 374        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 375        int ret;
 376
 377        if (vc4_hdmi->variant->phy_disable)
 378                vc4_hdmi->variant->phy_disable(vc4_hdmi);
 379
 380        HDMI_WRITE(HDMI_VID_CTL,
 381                   HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
 382
 383        clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
 384        clk_disable_unprepare(vc4_hdmi->hsm_clock);
 385        clk_disable_unprepare(vc4_hdmi->pixel_clock);
 386
 387        ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
 388        if (ret < 0)
 389                DRM_ERROR("Failed to release power domain: %d\n", ret);
 390}
 391
 392static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
 393{
 394}
 395
 396static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
 397{
 398        u32 csc_ctl;
 399
 400        csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
 401                                VC4_HD_CSC_CTL_ORDER);
 402
 403        if (enable) {
 404                /* CEA VICs other than #1 requre limited range RGB
 405                 * output unless overridden by an AVI infoframe.
 406                 * Apply a colorspace conversion to squash 0-255 down
 407                 * to 16-235.  The matrix here is:
 408                 *
 409                 * [ 0      0      0.8594 16]
 410                 * [ 0      0.8594 0      16]
 411                 * [ 0.8594 0      0      16]
 412                 * [ 0      0      0       1]
 413                 */
 414                csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
 415                csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
 416                csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
 417                                         VC4_HD_CSC_CTL_MODE);
 418
 419                HDMI_WRITE(HDMI_CSC_12_11, (0x000 << 16) | 0x000);
 420                HDMI_WRITE(HDMI_CSC_14_13, (0x100 << 16) | 0x6e0);
 421                HDMI_WRITE(HDMI_CSC_22_21, (0x6e0 << 16) | 0x000);
 422                HDMI_WRITE(HDMI_CSC_24_23, (0x100 << 16) | 0x000);
 423                HDMI_WRITE(HDMI_CSC_32_31, (0x000 << 16) | 0x6e0);
 424                HDMI_WRITE(HDMI_CSC_34_33, (0x100 << 16) | 0x000);
 425        }
 426
 427        /* The RGB order applies even when CSC is disabled. */
 428        HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
 429}
 430
 431static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
 432{
 433        u32 csc_ctl;
 434
 435        csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */
 436
 437        if (enable) {
 438                /* CEA VICs other than #1 requre limited range RGB
 439                 * output unless overridden by an AVI infoframe.
 440                 * Apply a colorspace conversion to squash 0-255 down
 441                 * to 16-235.  The matrix here is:
 442                 *
 443                 * [ 0.8594 0      0      16]
 444                 * [ 0      0.8594 0      16]
 445                 * [ 0      0      0.8594 16]
 446                 * [ 0      0      0       1]
 447                 * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 448                 */
 449                HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80);
 450                HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000);
 451                HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000);
 452                HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000);
 453                HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
 454                HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
 455        } else {
 456                /* Still use the matrix for full range, but make it unity.
 457                 * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 458                 */
 459                HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000);
 460                HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000);
 461                HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000);
 462                HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000);
 463                HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
 464                HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000);
 465        }
 466
 467        HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
 468}
 469
 470static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 471                                 struct drm_display_mode *mode)
 472{
 473        bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
 474        bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 475        bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
 476        u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
 477        u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
 478                                   VC4_HDMI_VERTA_VSP) |
 479                     VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
 480                                   VC4_HDMI_VERTA_VFP) |
 481                     VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL));
 482        u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
 483                     VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
 484                                   VC4_HDMI_VERTB_VBP));
 485        u32 vertb_even = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
 486                          VC4_SET_FIELD(mode->crtc_vtotal -
 487                                        mode->crtc_vsync_end -
 488                                        interlaced,
 489                                        VC4_HDMI_VERTB_VBP));
 490
 491        HDMI_WRITE(HDMI_HORZA,
 492                   (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
 493                   (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
 494                   VC4_SET_FIELD(mode->hdisplay * pixel_rep,
 495                                 VC4_HDMI_HORZA_HAP));
 496
 497        HDMI_WRITE(HDMI_HORZB,
 498                   VC4_SET_FIELD((mode->htotal -
 499                                  mode->hsync_end) * pixel_rep,
 500                                 VC4_HDMI_HORZB_HBP) |
 501                   VC4_SET_FIELD((mode->hsync_end -
 502                                  mode->hsync_start) * pixel_rep,
 503                                 VC4_HDMI_HORZB_HSP) |
 504                   VC4_SET_FIELD((mode->hsync_start -
 505                                  mode->hdisplay) * pixel_rep,
 506                                 VC4_HDMI_HORZB_HFP));
 507
 508        HDMI_WRITE(HDMI_VERTA0, verta);
 509        HDMI_WRITE(HDMI_VERTA1, verta);
 510
 511        HDMI_WRITE(HDMI_VERTB0, vertb_even);
 512        HDMI_WRITE(HDMI_VERTB1, vertb);
 513}
 514static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 515                                 struct drm_display_mode *mode)
 516{
 517        bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
 518        bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 519        bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
 520        u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
 521        u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
 522                                   VC5_HDMI_VERTA_VSP) |
 523                     VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
 524                                   VC5_HDMI_VERTA_VFP) |
 525                     VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
 526        u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
 527                     VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
 528                                   VC4_HDMI_VERTB_VBP));
 529        u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
 530                          VC4_SET_FIELD(mode->crtc_vtotal -
 531                                        mode->crtc_vsync_end -
 532                                        interlaced,
 533                                        VC4_HDMI_VERTB_VBP));
 534
 535        HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
 536        HDMI_WRITE(HDMI_HORZA,
 537                   (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) |
 538                   (hsync_pos ? VC5_HDMI_HORZA_HPOS : 0) |
 539                   VC4_SET_FIELD(mode->hdisplay * pixel_rep,
 540                                 VC5_HDMI_HORZA_HAP) |
 541                   VC4_SET_FIELD((mode->hsync_start -
 542                                  mode->hdisplay) * pixel_rep,
 543                                 VC5_HDMI_HORZA_HFP));
 544
 545        HDMI_WRITE(HDMI_HORZB,
 546                   VC4_SET_FIELD((mode->htotal -
 547                                  mode->hsync_end) * pixel_rep,
 548                                 VC5_HDMI_HORZB_HBP) |
 549                   VC4_SET_FIELD((mode->hsync_end -
 550                                  mode->hsync_start) * pixel_rep,
 551                                 VC5_HDMI_HORZB_HSP));
 552
 553        HDMI_WRITE(HDMI_VERTA0, verta);
 554        HDMI_WRITE(HDMI_VERTA1, verta);
 555
 556        HDMI_WRITE(HDMI_VERTB0, vertb_even);
 557        HDMI_WRITE(HDMI_VERTB1, vertb);
 558
 559        HDMI_WRITE(HDMI_CLOCK_STOP, 0);
 560}
 561
 562static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
 563{
 564        u32 drift;
 565        int ret;
 566
 567        drift = HDMI_READ(HDMI_FIFO_CTL);
 568        drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
 569
 570        HDMI_WRITE(HDMI_FIFO_CTL,
 571                   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
 572        HDMI_WRITE(HDMI_FIFO_CTL,
 573                   drift | VC4_HDMI_FIFO_CTL_RECENTER);
 574        usleep_range(1000, 1100);
 575        HDMI_WRITE(HDMI_FIFO_CTL,
 576                   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
 577        HDMI_WRITE(HDMI_FIFO_CTL,
 578                   drift | VC4_HDMI_FIFO_CTL_RECENTER);
 579
 580        ret = wait_for(HDMI_READ(HDMI_FIFO_CTL) &
 581                       VC4_HDMI_FIFO_CTL_RECENTER_DONE, 1);
 582        WARN_ONCE(ret, "Timeout waiting for "
 583                  "VC4_HDMI_FIFO_CTL_RECENTER_DONE");
 584}
 585
 586static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder)
 587{
 588        struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 589        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 590        unsigned long pixel_rate, hsm_rate;
 591        int ret;
 592
 593        ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
 594        if (ret < 0) {
 595                DRM_ERROR("Failed to retain power domain: %d\n", ret);
 596                return;
 597        }
 598
 599        pixel_rate = mode->clock * 1000 * ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1);
 600        ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
 601        if (ret) {
 602                DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
 603                return;
 604        }
 605
 606        ret = clk_prepare_enable(vc4_hdmi->pixel_clock);
 607        if (ret) {
 608                DRM_ERROR("Failed to turn on pixel clock: %d\n", ret);
 609                return;
 610        }
 611
 612        /*
 613         * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must
 614         * be faster than pixel clock, infinitesimally faster, tested in
 615         * simulation. Otherwise, exact value is unimportant for HDMI
 616         * operation." This conflicts with bcm2835's vc4 documentation, which
 617         * states HSM's clock has to be at least 108% of the pixel clock.
 618         *
 619         * Real life tests reveal that vc4's firmware statement holds up, and
 620         * users are able to use pixel clocks closer to HSM's, namely for
 621         * 1920x1200@60Hz. So it was decided to have leave a 1% margin between
 622         * both clocks. Which, for RPi0-3 implies a maximum pixel clock of
 623         * 162MHz.
 624         *
 625         * Additionally, the AXI clock needs to be at least 25% of
 626         * pixel clock, but HSM ends up being the limiting factor.
 627         */
 628        hsm_rate = max_t(unsigned long, 120000000, (pixel_rate / 100) * 101);
 629        ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate);
 630        if (ret) {
 631                DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
 632                return;
 633        }
 634
 635        ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
 636        if (ret) {
 637                DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
 638                clk_disable_unprepare(vc4_hdmi->pixel_clock);
 639                return;
 640        }
 641
 642        /*
 643         * FIXME: When the pixel freq is 594MHz (4k60), this needs to be setup
 644         * at 300MHz.
 645         */
 646        ret = clk_set_min_rate(vc4_hdmi->pixel_bvb_clock,
 647                               (hsm_rate > VC4_HSM_MID_CLOCK ? 150000000 : 75000000));
 648        if (ret) {
 649                DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret);
 650                clk_disable_unprepare(vc4_hdmi->hsm_clock);
 651                clk_disable_unprepare(vc4_hdmi->pixel_clock);
 652                return;
 653        }
 654
 655        ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
 656        if (ret) {
 657                DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret);
 658                clk_disable_unprepare(vc4_hdmi->hsm_clock);
 659                clk_disable_unprepare(vc4_hdmi->pixel_clock);
 660                return;
 661        }
 662
 663        if (vc4_hdmi->variant->reset)
 664                vc4_hdmi->variant->reset(vc4_hdmi);
 665
 666        if (vc4_hdmi->variant->phy_init)
 667                vc4_hdmi->variant->phy_init(vc4_hdmi, mode);
 668
 669        HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
 670                   HDMI_READ(HDMI_SCHEDULER_CONTROL) |
 671                   VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
 672                   VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
 673
 674        if (vc4_hdmi->variant->set_timings)
 675                vc4_hdmi->variant->set_timings(vc4_hdmi, mode);
 676}
 677
 678static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder)
 679{
 680        struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 681        struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
 682        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 683
 684        if (vc4_encoder->hdmi_monitor &&
 685            drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) {
 686                if (vc4_hdmi->variant->csc_setup)
 687                        vc4_hdmi->variant->csc_setup(vc4_hdmi, true);
 688
 689                vc4_encoder->limited_rgb_range = true;
 690        } else {
 691                if (vc4_hdmi->variant->csc_setup)
 692                        vc4_hdmi->variant->csc_setup(vc4_hdmi, false);
 693
 694                vc4_encoder->limited_rgb_range = false;
 695        }
 696
 697        HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
 698}
 699
 700static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder)
 701{
 702        struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 703        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 704        struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
 705        bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
 706        bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 707        int ret;
 708
 709        HDMI_WRITE(HDMI_VID_CTL,
 710                   VC4_HD_VID_CTL_ENABLE |
 711                   VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
 712                   VC4_HD_VID_CTL_FRAME_COUNTER_RESET |
 713                   (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
 714                   (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
 715
 716        HDMI_WRITE(HDMI_VID_CTL,
 717                   HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_BLANKPIX);
 718
 719        if (vc4_encoder->hdmi_monitor) {
 720                HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
 721                           HDMI_READ(HDMI_SCHEDULER_CONTROL) |
 722                           VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
 723
 724                ret = wait_for(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
 725                               VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1000);
 726                WARN_ONCE(ret, "Timeout waiting for "
 727                          "VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
 728        } else {
 729                HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
 730                           HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
 731                           ~(VC4_HDMI_RAM_PACKET_ENABLE));
 732                HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
 733                           HDMI_READ(HDMI_SCHEDULER_CONTROL) &
 734                           ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
 735
 736                ret = wait_for(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
 737                                 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1000);
 738                WARN_ONCE(ret, "Timeout waiting for "
 739                          "!VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
 740        }
 741
 742        if (vc4_encoder->hdmi_monitor) {
 743                WARN_ON(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
 744                          VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
 745                HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
 746                           HDMI_READ(HDMI_SCHEDULER_CONTROL) |
 747                           VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT);
 748
 749                HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
 750                           VC4_HDMI_RAM_PACKET_ENABLE);
 751
 752                vc4_hdmi_set_infoframes(encoder);
 753        }
 754
 755        vc4_hdmi_recenter_fifo(vc4_hdmi);
 756}
 757
 758static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
 759{
 760}
 761
 762#define WIFI_2_4GHz_CH1_MIN_FREQ        2400000000ULL
 763#define WIFI_2_4GHz_CH1_MAX_FREQ        2422000000ULL
 764
 765static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 766                                         struct drm_crtc_state *crtc_state,
 767                                         struct drm_connector_state *conn_state)
 768{
 769        struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 770        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 771        unsigned long long pixel_rate = mode->clock * 1000;
 772        unsigned long long tmds_rate;
 773
 774        if (vc4_hdmi->variant->unsupported_odd_h_timings &&
 775            ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
 776             (mode->hsync_end % 2) || (mode->htotal % 2)))
 777                return -EINVAL;
 778
 779        /*
 780         * The 1440p@60 pixel rate is in the same range than the first
 781         * WiFi channel (between 2.4GHz and 2.422GHz with 22MHz
 782         * bandwidth). Slightly lower the frequency to bring it out of
 783         * the WiFi range.
 784         */
 785        tmds_rate = pixel_rate * 10;
 786        if (vc4_hdmi->disable_wifi_frequencies &&
 787            (tmds_rate >= WIFI_2_4GHz_CH1_MIN_FREQ &&
 788             tmds_rate <= WIFI_2_4GHz_CH1_MAX_FREQ)) {
 789                mode->clock = 238560;
 790                pixel_rate = mode->clock * 1000;
 791        }
 792
 793        if (pixel_rate > vc4_hdmi->variant->max_pixel_clock)
 794                return -EINVAL;
 795
 796        return 0;
 797}
 798
 799static enum drm_mode_status
 800vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
 801                            const struct drm_display_mode *mode)
 802{
 803        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 804
 805        if (vc4_hdmi->variant->unsupported_odd_h_timings &&
 806            ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
 807             (mode->hsync_end % 2) || (mode->htotal % 2)))
 808                return MODE_H_ILLEGAL;
 809
 810        if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock)
 811                return MODE_CLOCK_HIGH;
 812
 813        return MODE_OK;
 814}
 815
 816static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
 817        .atomic_check = vc4_hdmi_encoder_atomic_check,
 818        .mode_valid = vc4_hdmi_encoder_mode_valid,
 819        .disable = vc4_hdmi_encoder_disable,
 820        .enable = vc4_hdmi_encoder_enable,
 821};
 822
 823static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
 824{
 825        int i;
 826        u32 channel_map = 0;
 827
 828        for (i = 0; i < 8; i++) {
 829                if (channel_mask & BIT(i))
 830                        channel_map |= i << (3 * i);
 831        }
 832        return channel_map;
 833}
 834
 835static u32 vc5_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
 836{
 837        int i;
 838        u32 channel_map = 0;
 839
 840        for (i = 0; i < 8; i++) {
 841                if (channel_mask & BIT(i))
 842                        channel_map |= i << (4 * i);
 843        }
 844        return channel_map;
 845}
 846
 847/* HDMI audio codec callbacks */
 848static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
 849{
 850        u32 hsm_clock = clk_get_rate(vc4_hdmi->audio_clock);
 851        unsigned long n, m;
 852
 853        rational_best_approximation(hsm_clock, vc4_hdmi->audio.samplerate,
 854                                    VC4_HD_MAI_SMP_N_MASK >>
 855                                    VC4_HD_MAI_SMP_N_SHIFT,
 856                                    (VC4_HD_MAI_SMP_M_MASK >>
 857                                     VC4_HD_MAI_SMP_M_SHIFT) + 1,
 858                                    &n, &m);
 859
 860        HDMI_WRITE(HDMI_MAI_SMP,
 861                   VC4_SET_FIELD(n, VC4_HD_MAI_SMP_N) |
 862                   VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M));
 863}
 864
 865static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi)
 866{
 867        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 868        struct drm_crtc *crtc = encoder->crtc;
 869        const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 870        u32 samplerate = vc4_hdmi->audio.samplerate;
 871        u32 n, cts;
 872        u64 tmp;
 873
 874        n = 128 * samplerate / 1000;
 875        tmp = (u64)(mode->clock * 1000) * n;
 876        do_div(tmp, 128 * samplerate);
 877        cts = tmp;
 878
 879        HDMI_WRITE(HDMI_CRP_CFG,
 880                   VC4_HDMI_CRP_CFG_EXTERNAL_CTS_EN |
 881                   VC4_SET_FIELD(n, VC4_HDMI_CRP_CFG_N));
 882
 883        /*
 884         * We could get slightly more accurate clocks in some cases by
 885         * providing a CTS_1 value.  The two CTS values are alternated
 886         * between based on the period fields
 887         */
 888        HDMI_WRITE(HDMI_CTS_0, cts);
 889        HDMI_WRITE(HDMI_CTS_1, cts);
 890}
 891
 892static inline struct vc4_hdmi *dai_to_hdmi(struct snd_soc_dai *dai)
 893{
 894        struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai);
 895
 896        return snd_soc_card_get_drvdata(card);
 897}
 898
 899static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
 900                                  struct snd_soc_dai *dai)
 901{
 902        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
 903        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 904        struct drm_connector *connector = &vc4_hdmi->connector;
 905        int ret;
 906
 907        if (vc4_hdmi->audio.substream && vc4_hdmi->audio.substream != substream)
 908                return -EINVAL;
 909
 910        vc4_hdmi->audio.substream = substream;
 911
 912        /*
 913         * If the HDMI encoder hasn't probed, or the encoder is
 914         * currently in DVI mode, treat the codec dai as missing.
 915         */
 916        if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
 917                                VC4_HDMI_RAM_PACKET_ENABLE))
 918                return -ENODEV;
 919
 920        ret = snd_pcm_hw_constraint_eld(substream->runtime, connector->eld);
 921        if (ret)
 922                return ret;
 923
 924        return 0;
 925}
 926
 927static int vc4_hdmi_audio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 928{
 929        return 0;
 930}
 931
 932static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 933{
 934        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 935        struct device *dev = &vc4_hdmi->pdev->dev;
 936        int ret;
 937
 938        vc4_hdmi->audio.streaming = false;
 939        ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO);
 940        if (ret)
 941                dev_err(dev, "Failed to stop audio infoframe: %d\n", ret);
 942
 943        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_RESET);
 944        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_ERRORF);
 945        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_FLUSH);
 946}
 947
 948static void vc4_hdmi_audio_shutdown(struct snd_pcm_substream *substream,
 949                                    struct snd_soc_dai *dai)
 950{
 951        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
 952
 953        if (substream != vc4_hdmi->audio.substream)
 954                return;
 955
 956        vc4_hdmi_audio_reset(vc4_hdmi);
 957
 958        vc4_hdmi->audio.substream = NULL;
 959}
 960
 961/* HDMI audio codec callbacks */
 962static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
 963                                    struct snd_pcm_hw_params *params,
 964                                    struct snd_soc_dai *dai)
 965{
 966        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
 967        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 968        struct device *dev = &vc4_hdmi->pdev->dev;
 969        u32 audio_packet_config, channel_mask;
 970        u32 channel_map;
 971
 972        if (substream != vc4_hdmi->audio.substream)
 973                return -EINVAL;
 974
 975        dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
 976                params_rate(params), params_width(params),
 977                params_channels(params));
 978
 979        vc4_hdmi->audio.channels = params_channels(params);
 980        vc4_hdmi->audio.samplerate = params_rate(params);
 981
 982        HDMI_WRITE(HDMI_MAI_CTL,
 983                   VC4_HD_MAI_CTL_RESET |
 984                   VC4_HD_MAI_CTL_FLUSH |
 985                   VC4_HD_MAI_CTL_DLATE |
 986                   VC4_HD_MAI_CTL_ERRORE |
 987                   VC4_HD_MAI_CTL_ERRORF);
 988
 989        vc4_hdmi_audio_set_mai_clock(vc4_hdmi);
 990
 991        /* The B frame identifier should match the value used by alsa-lib (8) */
 992        audio_packet_config =
 993                VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_SAMPLE_FLAT |
 994                VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_INACTIVE_CHANNELS |
 995                VC4_SET_FIELD(0x8, VC4_HDMI_AUDIO_PACKET_B_FRAME_IDENTIFIER);
 996
 997        channel_mask = GENMASK(vc4_hdmi->audio.channels - 1, 0);
 998        audio_packet_config |= VC4_SET_FIELD(channel_mask,
 999                                             VC4_HDMI_AUDIO_PACKET_CEA_MASK);
1000
1001        /* Set the MAI threshold.  This logic mimics the firmware's. */
1002        if (vc4_hdmi->audio.samplerate > 96000) {
1003                HDMI_WRITE(HDMI_MAI_THR,
1004                           VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQHIGH) |
1005                           VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
1006        } else if (vc4_hdmi->audio.samplerate > 48000) {
1007                HDMI_WRITE(HDMI_MAI_THR,
1008                           VC4_SET_FIELD(0x14, VC4_HD_MAI_THR_DREQHIGH) |
1009                           VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
1010        } else {
1011                HDMI_WRITE(HDMI_MAI_THR,
1012                           VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) |
1013                           VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) |
1014                           VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) |
1015                           VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW));
1016        }
1017
1018        HDMI_WRITE(HDMI_MAI_CONFIG,
1019                   VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
1020                   VC4_SET_FIELD(channel_mask, VC4_HDMI_MAI_CHANNEL_MASK));
1021
1022        channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask);
1023        HDMI_WRITE(HDMI_MAI_CHANNEL_MAP, channel_map);
1024        HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
1025        vc4_hdmi_set_n_cts(vc4_hdmi);
1026
1027        vc4_hdmi_set_audio_infoframe(encoder);
1028
1029        return 0;
1030}
1031
1032static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
1033                                  struct snd_soc_dai *dai)
1034{
1035        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
1036
1037        switch (cmd) {
1038        case SNDRV_PCM_TRIGGER_START:
1039                vc4_hdmi->audio.streaming = true;
1040
1041                if (vc4_hdmi->variant->phy_rng_enable)
1042                        vc4_hdmi->variant->phy_rng_enable(vc4_hdmi);
1043
1044                HDMI_WRITE(HDMI_MAI_CTL,
1045                           VC4_SET_FIELD(vc4_hdmi->audio.channels,
1046                                         VC4_HD_MAI_CTL_CHNUM) |
1047                           VC4_HD_MAI_CTL_ENABLE);
1048                break;
1049        case SNDRV_PCM_TRIGGER_STOP:
1050                HDMI_WRITE(HDMI_MAI_CTL,
1051                           VC4_HD_MAI_CTL_DLATE |
1052                           VC4_HD_MAI_CTL_ERRORE |
1053                           VC4_HD_MAI_CTL_ERRORF);
1054
1055                if (vc4_hdmi->variant->phy_rng_disable)
1056                        vc4_hdmi->variant->phy_rng_disable(vc4_hdmi);
1057
1058                vc4_hdmi->audio.streaming = false;
1059
1060                break;
1061        default:
1062                break;
1063        }
1064
1065        return 0;
1066}
1067
1068static inline struct vc4_hdmi *
1069snd_component_to_hdmi(struct snd_soc_component *component)
1070{
1071        struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
1072
1073        return snd_soc_card_get_drvdata(card);
1074}
1075
1076static int vc4_hdmi_audio_eld_ctl_info(struct snd_kcontrol *kcontrol,
1077                                       struct snd_ctl_elem_info *uinfo)
1078{
1079        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1080        struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
1081        struct drm_connector *connector = &vc4_hdmi->connector;
1082
1083        uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1084        uinfo->count = sizeof(connector->eld);
1085
1086        return 0;
1087}
1088
1089static int vc4_hdmi_audio_eld_ctl_get(struct snd_kcontrol *kcontrol,
1090                                      struct snd_ctl_elem_value *ucontrol)
1091{
1092        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1093        struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
1094        struct drm_connector *connector = &vc4_hdmi->connector;
1095
1096        memcpy(ucontrol->value.bytes.data, connector->eld,
1097               sizeof(connector->eld));
1098
1099        return 0;
1100}
1101
1102static const struct snd_kcontrol_new vc4_hdmi_audio_controls[] = {
1103        {
1104                .access = SNDRV_CTL_ELEM_ACCESS_READ |
1105                          SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1106                .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1107                .name = "ELD",
1108                .info = vc4_hdmi_audio_eld_ctl_info,
1109                .get = vc4_hdmi_audio_eld_ctl_get,
1110        },
1111};
1112
1113static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = {
1114        SND_SOC_DAPM_OUTPUT("TX"),
1115};
1116
1117static const struct snd_soc_dapm_route vc4_hdmi_audio_routes[] = {
1118        { "TX", NULL, "Playback" },
1119};
1120
1121static const struct snd_soc_component_driver vc4_hdmi_audio_component_drv = {
1122        .name                   = "vc4-hdmi-codec-dai-component",
1123        .controls               = vc4_hdmi_audio_controls,
1124        .num_controls           = ARRAY_SIZE(vc4_hdmi_audio_controls),
1125        .dapm_widgets           = vc4_hdmi_audio_widgets,
1126        .num_dapm_widgets       = ARRAY_SIZE(vc4_hdmi_audio_widgets),
1127        .dapm_routes            = vc4_hdmi_audio_routes,
1128        .num_dapm_routes        = ARRAY_SIZE(vc4_hdmi_audio_routes),
1129        .idle_bias_on           = 1,
1130        .use_pmdown_time        = 1,
1131        .endianness             = 1,
1132        .non_legacy_dai_naming  = 1,
1133};
1134
1135static const struct snd_soc_dai_ops vc4_hdmi_audio_dai_ops = {
1136        .startup = vc4_hdmi_audio_startup,
1137        .shutdown = vc4_hdmi_audio_shutdown,
1138        .hw_params = vc4_hdmi_audio_hw_params,
1139        .set_fmt = vc4_hdmi_audio_set_fmt,
1140        .trigger = vc4_hdmi_audio_trigger,
1141};
1142
1143static struct snd_soc_dai_driver vc4_hdmi_audio_codec_dai_drv = {
1144        .name = "vc4-hdmi-hifi",
1145        .playback = {
1146                .stream_name = "Playback",
1147                .channels_min = 2,
1148                .channels_max = 8,
1149                .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
1150                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
1151                         SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
1152                         SNDRV_PCM_RATE_192000,
1153                .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
1154        },
1155};
1156
1157static const struct snd_soc_component_driver vc4_hdmi_audio_cpu_dai_comp = {
1158        .name = "vc4-hdmi-cpu-dai-component",
1159};
1160
1161static int vc4_hdmi_audio_cpu_dai_probe(struct snd_soc_dai *dai)
1162{
1163        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
1164
1165        snd_soc_dai_init_dma_data(dai, &vc4_hdmi->audio.dma_data, NULL);
1166
1167        return 0;
1168}
1169
1170static struct snd_soc_dai_driver vc4_hdmi_audio_cpu_dai_drv = {
1171        .name = "vc4-hdmi-cpu-dai",
1172        .probe  = vc4_hdmi_audio_cpu_dai_probe,
1173        .playback = {
1174                .stream_name = "Playback",
1175                .channels_min = 1,
1176                .channels_max = 8,
1177                .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
1178                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
1179                         SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
1180                         SNDRV_PCM_RATE_192000,
1181                .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
1182        },
1183        .ops = &vc4_hdmi_audio_dai_ops,
1184};
1185
1186static const struct snd_dmaengine_pcm_config pcm_conf = {
1187        .chan_names[SNDRV_PCM_STREAM_PLAYBACK] = "audio-rx",
1188        .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
1189};
1190
1191static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
1192{
1193        const struct vc4_hdmi_register *mai_data =
1194                &vc4_hdmi->variant->registers[HDMI_MAI_DATA];
1195        struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
1196        struct snd_soc_card *card = &vc4_hdmi->audio.card;
1197        struct device *dev = &vc4_hdmi->pdev->dev;
1198        const __be32 *addr;
1199        int index;
1200        int ret;
1201
1202        if (!of_find_property(dev->of_node, "dmas", NULL)) {
1203                dev_warn(dev,
1204                         "'dmas' DT property is missing, no HDMI audio\n");
1205                return 0;
1206        }
1207
1208        if (mai_data->reg != VC4_HD) {
1209                WARN_ONCE(true, "MAI isn't in the HD block\n");
1210                return -EINVAL;
1211        }
1212
1213        /*
1214         * Get the physical address of VC4_HD_MAI_DATA. We need to retrieve
1215         * the bus address specified in the DT, because the physical address
1216         * (the one returned by platform_get_resource()) is not appropriate
1217         * for DMA transfers.
1218         * This VC/MMU should probably be exposed to avoid this kind of hacks.
1219         */
1220        index = of_property_match_string(dev->of_node, "reg-names", "hd");
1221        /* Before BCM2711, we don't have a named register range */
1222        if (index < 0)
1223                index = 1;
1224
1225        addr = of_get_address(dev->of_node, index, NULL, NULL);
1226
1227        vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset;
1228        vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
1229        vc4_hdmi->audio.dma_data.maxburst = 2;
1230
1231        ret = devm_snd_dmaengine_pcm_register(dev, &pcm_conf, 0);
1232        if (ret) {
1233                dev_err(dev, "Could not register PCM component: %d\n", ret);
1234                return ret;
1235        }
1236
1237        ret = devm_snd_soc_register_component(dev, &vc4_hdmi_audio_cpu_dai_comp,
1238                                              &vc4_hdmi_audio_cpu_dai_drv, 1);
1239        if (ret) {
1240                dev_err(dev, "Could not register CPU DAI: %d\n", ret);
1241                return ret;
1242        }
1243
1244        /* register component and codec dai */
1245        ret = devm_snd_soc_register_component(dev, &vc4_hdmi_audio_component_drv,
1246                                     &vc4_hdmi_audio_codec_dai_drv, 1);
1247        if (ret) {
1248                dev_err(dev, "Could not register component: %d\n", ret);
1249                return ret;
1250        }
1251
1252        dai_link->cpus          = &vc4_hdmi->audio.cpu;
1253        dai_link->codecs        = &vc4_hdmi->audio.codec;
1254        dai_link->platforms     = &vc4_hdmi->audio.platform;
1255
1256        dai_link->num_cpus      = 1;
1257        dai_link->num_codecs    = 1;
1258        dai_link->num_platforms = 1;
1259
1260        dai_link->name = "MAI";
1261        dai_link->stream_name = "MAI PCM";
1262        dai_link->codecs->dai_name = vc4_hdmi_audio_codec_dai_drv.name;
1263        dai_link->cpus->dai_name = dev_name(dev);
1264        dai_link->codecs->name = dev_name(dev);
1265        dai_link->platforms->name = dev_name(dev);
1266
1267        card->dai_link = dai_link;
1268        card->num_links = 1;
1269        card->name = vc4_hdmi->variant->card_name;
1270        card->driver_name = "vc4-hdmi";
1271        card->dev = dev;
1272        card->owner = THIS_MODULE;
1273
1274        /*
1275         * Be careful, snd_soc_register_card() calls dev_set_drvdata() and
1276         * stores a pointer to the snd card object in dev->driver_data. This
1277         * means we cannot use it for something else. The hdmi back-pointer is
1278         * now stored in card->drvdata and should be retrieved with
1279         * snd_soc_card_get_drvdata() if needed.
1280         */
1281        snd_soc_card_set_drvdata(card, vc4_hdmi);
1282        ret = devm_snd_soc_register_card(dev, card);
1283        if (ret)
1284                dev_err(dev, "Could not register sound card: %d\n", ret);
1285
1286        return ret;
1287
1288}
1289
1290#ifdef CONFIG_DRM_VC4_HDMI_CEC
1291static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
1292{
1293        struct vc4_hdmi *vc4_hdmi = priv;
1294
1295        if (vc4_hdmi->cec_irq_was_rx) {
1296                if (vc4_hdmi->cec_rx_msg.len)
1297                        cec_received_msg(vc4_hdmi->cec_adap,
1298                                         &vc4_hdmi->cec_rx_msg);
1299        } else if (vc4_hdmi->cec_tx_ok) {
1300                cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_OK,
1301                                  0, 0, 0, 0);
1302        } else {
1303                /*
1304                 * This CEC implementation makes 1 retry, so if we
1305                 * get a NACK, then that means it made 2 attempts.
1306                 */
1307                cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_NACK,
1308                                  0, 2, 0, 0);
1309        }
1310        return IRQ_HANDLED;
1311}
1312
1313static void vc4_cec_read_msg(struct vc4_hdmi *vc4_hdmi, u32 cntrl1)
1314{
1315        struct cec_msg *msg = &vc4_hdmi->cec_rx_msg;
1316        unsigned int i;
1317
1318        msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
1319                                        VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
1320        for (i = 0; i < msg->len; i += 4) {
1321                u32 val = HDMI_READ(HDMI_CEC_RX_DATA_1 + i);
1322
1323                msg->msg[i] = val & 0xff;
1324                msg->msg[i + 1] = (val >> 8) & 0xff;
1325                msg->msg[i + 2] = (val >> 16) & 0xff;
1326                msg->msg[i + 3] = (val >> 24) & 0xff;
1327        }
1328}
1329
1330static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
1331{
1332        struct vc4_hdmi *vc4_hdmi = priv;
1333        u32 stat = HDMI_READ(HDMI_CEC_CPU_STATUS);
1334        u32 cntrl1, cntrl5;
1335
1336        if (!(stat & VC4_HDMI_CPU_CEC))
1337                return IRQ_NONE;
1338        vc4_hdmi->cec_rx_msg.len = 0;
1339        cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1);
1340        cntrl5 = HDMI_READ(HDMI_CEC_CNTRL_5);
1341        vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
1342        if (vc4_hdmi->cec_irq_was_rx) {
1343                vc4_cec_read_msg(vc4_hdmi, cntrl1);
1344                cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
1345                HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1);
1346                cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
1347        } else {
1348                vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
1349                cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
1350        }
1351        HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1);
1352        HDMI_WRITE(HDMI_CEC_CPU_CLEAR, VC4_HDMI_CPU_CEC);
1353
1354        return IRQ_WAKE_THREAD;
1355}
1356
1357static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
1358{
1359        struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
1360        /* clock period in microseconds */
1361        const u32 usecs = 1000000 / CEC_CLOCK_FREQ;
1362        u32 val = HDMI_READ(HDMI_CEC_CNTRL_5);
1363
1364        val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET |
1365                 VC4_HDMI_CEC_CNT_TO_4700_US_MASK |
1366                 VC4_HDMI_CEC_CNT_TO_4500_US_MASK);
1367        val |= ((4700 / usecs) << VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT) |
1368               ((4500 / usecs) << VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT);
1369
1370        if (enable) {
1371                HDMI_WRITE(HDMI_CEC_CNTRL_5, val |
1372                           VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
1373                HDMI_WRITE(HDMI_CEC_CNTRL_5, val);
1374                HDMI_WRITE(HDMI_CEC_CNTRL_2,
1375                           ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) |
1376                           ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) |
1377                           ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) |
1378                           ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) |
1379                           ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT));
1380                HDMI_WRITE(HDMI_CEC_CNTRL_3,
1381                           ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) |
1382                           ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) |
1383                           ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) |
1384                           ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT));
1385                HDMI_WRITE(HDMI_CEC_CNTRL_4,
1386                           ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) |
1387                           ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) |
1388                           ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
1389                           ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
1390
1391                HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
1392        } else {
1393                HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
1394                HDMI_WRITE(HDMI_CEC_CNTRL_5, val |
1395                           VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
1396        }
1397        return 0;
1398}
1399
1400static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
1401{
1402        struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
1403
1404        HDMI_WRITE(HDMI_CEC_CNTRL_1,
1405                   (HDMI_READ(HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
1406                   (log_addr & 0xf) << VC4_HDMI_CEC_ADDR_SHIFT);
1407        return 0;
1408}
1409
1410static int vc4_hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
1411                                      u32 signal_free_time, struct cec_msg *msg)
1412{
1413        struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
1414        u32 val;
1415        unsigned int i;
1416
1417        for (i = 0; i < msg->len; i += 4)
1418                HDMI_WRITE(HDMI_CEC_TX_DATA_1 + i,
1419                           (msg->msg[i]) |
1420                           (msg->msg[i + 1] << 8) |
1421                           (msg->msg[i + 2] << 16) |
1422                           (msg->msg[i + 3] << 24));
1423
1424        val = HDMI_READ(HDMI_CEC_CNTRL_1);
1425        val &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
1426        HDMI_WRITE(HDMI_CEC_CNTRL_1, val);
1427        val &= ~VC4_HDMI_CEC_MESSAGE_LENGTH_MASK;
1428        val |= (msg->len - 1) << VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT;
1429        val |= VC4_HDMI_CEC_START_XMIT_BEGIN;
1430
1431        HDMI_WRITE(HDMI_CEC_CNTRL_1, val);
1432        return 0;
1433}
1434
1435static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
1436        .adap_enable = vc4_hdmi_cec_adap_enable,
1437        .adap_log_addr = vc4_hdmi_cec_adap_log_addr,
1438        .adap_transmit = vc4_hdmi_cec_adap_transmit,
1439};
1440
1441static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
1442{
1443        struct cec_connector_info conn_info;
1444        struct platform_device *pdev = vc4_hdmi->pdev;
1445        u32 value;
1446        int ret;
1447
1448        if (!vc4_hdmi->variant->cec_available)
1449                return 0;
1450
1451        vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
1452                                                  vc4_hdmi, "vc4",
1453                                                  CEC_CAP_DEFAULTS |
1454                                                  CEC_CAP_CONNECTOR_INFO, 1);
1455        ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
1456        if (ret < 0)
1457                return ret;
1458
1459        cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector);
1460        cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
1461
1462        HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
1463        value = HDMI_READ(HDMI_CEC_CNTRL_1);
1464        value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
1465        /*
1466         * Set the logical address to Unregistered and set the clock
1467         * divider: the hsm_clock rate and this divider setting will
1468         * give a 40 kHz CEC clock.
1469         */
1470        value |= VC4_HDMI_CEC_ADDR_MASK |
1471                 (4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
1472        HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
1473        ret = devm_request_threaded_irq(&pdev->dev, platform_get_irq(pdev, 0),
1474                                        vc4_cec_irq_handler,
1475                                        vc4_cec_irq_handler_thread, 0,
1476                                        "vc4 hdmi cec", vc4_hdmi);
1477        if (ret)
1478                goto err_delete_cec_adap;
1479
1480        ret = cec_register_adapter(vc4_hdmi->cec_adap, &pdev->dev);
1481        if (ret < 0)
1482                goto err_delete_cec_adap;
1483
1484        return 0;
1485
1486err_delete_cec_adap:
1487        cec_delete_adapter(vc4_hdmi->cec_adap);
1488
1489        return ret;
1490}
1491
1492static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi)
1493{
1494        cec_unregister_adapter(vc4_hdmi->cec_adap);
1495}
1496#else
1497static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
1498{
1499        return 0;
1500}
1501
1502static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) {};
1503
1504#endif
1505
1506static int vc4_hdmi_build_regset(struct vc4_hdmi *vc4_hdmi,
1507                                 struct debugfs_regset32 *regset,
1508                                 enum vc4_hdmi_regs reg)
1509{
1510        const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
1511        struct debugfs_reg32 *regs, *new_regs;
1512        unsigned int count = 0;
1513        unsigned int i;
1514
1515        regs = kcalloc(variant->num_registers, sizeof(*regs),
1516                       GFP_KERNEL);
1517        if (!regs)
1518                return -ENOMEM;
1519
1520        for (i = 0; i < variant->num_registers; i++) {
1521                const struct vc4_hdmi_register *field = &variant->registers[i];
1522
1523                if (field->reg != reg)
1524                        continue;
1525
1526                regs[count].name = field->name;
1527                regs[count].offset = field->offset;
1528                count++;
1529        }
1530
1531        new_regs = krealloc(regs, count * sizeof(*regs), GFP_KERNEL);
1532        if (!new_regs)
1533                return -ENOMEM;
1534
1535        regset->base = __vc4_hdmi_get_field_base(vc4_hdmi, reg);
1536        regset->regs = new_regs;
1537        regset->nregs = count;
1538
1539        return 0;
1540}
1541
1542static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
1543{
1544        struct platform_device *pdev = vc4_hdmi->pdev;
1545        struct device *dev = &pdev->dev;
1546        int ret;
1547
1548        vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
1549        if (IS_ERR(vc4_hdmi->hdmicore_regs))
1550                return PTR_ERR(vc4_hdmi->hdmicore_regs);
1551
1552        vc4_hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
1553        if (IS_ERR(vc4_hdmi->hd_regs))
1554                return PTR_ERR(vc4_hdmi->hd_regs);
1555
1556        ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hd_regset, VC4_HD);
1557        if (ret)
1558                return ret;
1559
1560        ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hdmi_regset, VC4_HDMI);
1561        if (ret)
1562                return ret;
1563
1564        vc4_hdmi->pixel_clock = devm_clk_get(dev, "pixel");
1565        if (IS_ERR(vc4_hdmi->pixel_clock)) {
1566                ret = PTR_ERR(vc4_hdmi->pixel_clock);
1567                if (ret != -EPROBE_DEFER)
1568                        DRM_ERROR("Failed to get pixel clock\n");
1569                return ret;
1570        }
1571
1572        vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
1573        if (IS_ERR(vc4_hdmi->hsm_clock)) {
1574                DRM_ERROR("Failed to get HDMI state machine clock\n");
1575                return PTR_ERR(vc4_hdmi->hsm_clock);
1576        }
1577        vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock;
1578
1579        return 0;
1580}
1581
1582static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
1583{
1584        struct platform_device *pdev = vc4_hdmi->pdev;
1585        struct device *dev = &pdev->dev;
1586        struct resource *res;
1587
1588        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi");
1589        if (!res)
1590                return -ENODEV;
1591
1592        vc4_hdmi->hdmicore_regs = devm_ioremap(dev, res->start,
1593                                               resource_size(res));
1594        if (!vc4_hdmi->hdmicore_regs)
1595                return -ENOMEM;
1596
1597        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hd");
1598        if (!res)
1599                return -ENODEV;
1600
1601        vc4_hdmi->hd_regs = devm_ioremap(dev, res->start, resource_size(res));
1602        if (!vc4_hdmi->hd_regs)
1603                return -ENOMEM;
1604
1605        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cec");
1606        if (!res)
1607                return -ENODEV;
1608
1609        vc4_hdmi->cec_regs = devm_ioremap(dev, res->start, resource_size(res));
1610        if (!vc4_hdmi->cec_regs)
1611                return -ENOMEM;
1612
1613        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csc");
1614        if (!res)
1615                return -ENODEV;
1616
1617        vc4_hdmi->csc_regs = devm_ioremap(dev, res->start, resource_size(res));
1618        if (!vc4_hdmi->csc_regs)
1619                return -ENOMEM;
1620
1621        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dvp");
1622        if (!res)
1623                return -ENODEV;
1624
1625        vc4_hdmi->dvp_regs = devm_ioremap(dev, res->start, resource_size(res));
1626        if (!vc4_hdmi->dvp_regs)
1627                return -ENOMEM;
1628
1629        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
1630        if (!res)
1631                return -ENODEV;
1632
1633        vc4_hdmi->phy_regs = devm_ioremap(dev, res->start, resource_size(res));
1634        if (!vc4_hdmi->phy_regs)
1635                return -ENOMEM;
1636
1637        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "packet");
1638        if (!res)
1639                return -ENODEV;
1640
1641        vc4_hdmi->ram_regs = devm_ioremap(dev, res->start, resource_size(res));
1642        if (!vc4_hdmi->ram_regs)
1643                return -ENOMEM;
1644
1645        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rm");
1646        if (!res)
1647                return -ENODEV;
1648
1649        vc4_hdmi->rm_regs = devm_ioremap(dev, res->start, resource_size(res));
1650        if (!vc4_hdmi->rm_regs)
1651                return -ENOMEM;
1652
1653        vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
1654        if (IS_ERR(vc4_hdmi->hsm_clock)) {
1655                DRM_ERROR("Failed to get HDMI state machine clock\n");
1656                return PTR_ERR(vc4_hdmi->hsm_clock);
1657        }
1658
1659        vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb");
1660        if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) {
1661                DRM_ERROR("Failed to get pixel bvb clock\n");
1662                return PTR_ERR(vc4_hdmi->pixel_bvb_clock);
1663        }
1664
1665        vc4_hdmi->audio_clock = devm_clk_get(dev, "audio");
1666        if (IS_ERR(vc4_hdmi->audio_clock)) {
1667                DRM_ERROR("Failed to get audio clock\n");
1668                return PTR_ERR(vc4_hdmi->audio_clock);
1669        }
1670
1671        vc4_hdmi->reset = devm_reset_control_get(dev, NULL);
1672        if (IS_ERR(vc4_hdmi->reset)) {
1673                DRM_ERROR("Failed to get HDMI reset line\n");
1674                return PTR_ERR(vc4_hdmi->reset);
1675        }
1676
1677        return 0;
1678}
1679
1680static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1681{
1682        const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
1683        struct platform_device *pdev = to_platform_device(dev);
1684        struct drm_device *drm = dev_get_drvdata(master);
1685        struct vc4_hdmi *vc4_hdmi;
1686        struct drm_encoder *encoder;
1687        struct device_node *ddc_node;
1688        u32 value;
1689        int ret;
1690
1691        vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
1692        if (!vc4_hdmi)
1693                return -ENOMEM;
1694
1695        dev_set_drvdata(dev, vc4_hdmi);
1696        encoder = &vc4_hdmi->encoder.base.base;
1697        vc4_hdmi->encoder.base.type = variant->encoder_type;
1698        vc4_hdmi->encoder.base.pre_crtc_configure = vc4_hdmi_encoder_pre_crtc_configure;
1699        vc4_hdmi->encoder.base.pre_crtc_enable = vc4_hdmi_encoder_pre_crtc_enable;
1700        vc4_hdmi->encoder.base.post_crtc_enable = vc4_hdmi_encoder_post_crtc_enable;
1701        vc4_hdmi->encoder.base.post_crtc_disable = vc4_hdmi_encoder_post_crtc_disable;
1702        vc4_hdmi->encoder.base.post_crtc_powerdown = vc4_hdmi_encoder_post_crtc_powerdown;
1703        vc4_hdmi->pdev = pdev;
1704        vc4_hdmi->variant = variant;
1705
1706        ret = variant->init_resources(vc4_hdmi);
1707        if (ret)
1708                return ret;
1709
1710        ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
1711        if (!ddc_node) {
1712                DRM_ERROR("Failed to find ddc node in device tree\n");
1713                return -ENODEV;
1714        }
1715
1716        vc4_hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
1717        of_node_put(ddc_node);
1718        if (!vc4_hdmi->ddc) {
1719                DRM_DEBUG("Failed to get ddc i2c adapter by node\n");
1720                return -EPROBE_DEFER;
1721        }
1722
1723        /* Only use the GPIO HPD pin if present in the DT, otherwise
1724         * we'll use the HDMI core's register.
1725         */
1726        if (of_find_property(dev->of_node, "hpd-gpios", &value)) {
1727                enum of_gpio_flags hpd_gpio_flags;
1728
1729                vc4_hdmi->hpd_gpio = of_get_named_gpio_flags(dev->of_node,
1730                                                             "hpd-gpios", 0,
1731                                                             &hpd_gpio_flags);
1732                if (vc4_hdmi->hpd_gpio < 0) {
1733                        ret = vc4_hdmi->hpd_gpio;
1734                        goto err_unprepare_hsm;
1735                }
1736
1737                vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
1738        }
1739
1740        vc4_hdmi->disable_wifi_frequencies =
1741                of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
1742
1743        pm_runtime_enable(dev);
1744
1745        drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
1746        drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
1747
1748        ret = vc4_hdmi_connector_init(drm, vc4_hdmi);
1749        if (ret)
1750                goto err_destroy_encoder;
1751
1752        ret = vc4_hdmi_cec_init(vc4_hdmi);
1753        if (ret)
1754                goto err_destroy_conn;
1755
1756        ret = vc4_hdmi_audio_init(vc4_hdmi);
1757        if (ret)
1758                goto err_free_cec;
1759
1760        vc4_debugfs_add_file(drm, variant->debugfs_name,
1761                             vc4_hdmi_debugfs_regs,
1762                             vc4_hdmi);
1763
1764        return 0;
1765
1766err_free_cec:
1767        vc4_hdmi_cec_exit(vc4_hdmi);
1768err_destroy_conn:
1769        vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
1770err_destroy_encoder:
1771        drm_encoder_cleanup(encoder);
1772err_unprepare_hsm:
1773        pm_runtime_disable(dev);
1774        put_device(&vc4_hdmi->ddc->dev);
1775
1776        return ret;
1777}
1778
1779static void vc4_hdmi_unbind(struct device *dev, struct device *master,
1780                            void *data)
1781{
1782        struct vc4_hdmi *vc4_hdmi;
1783
1784        /*
1785         * ASoC makes it a bit hard to retrieve a pointer to the
1786         * vc4_hdmi structure. Registering the card will overwrite our
1787         * device drvdata with a pointer to the snd_soc_card structure,
1788         * which can then be used to retrieve whatever drvdata we want
1789         * to associate.
1790         *
1791         * However, that doesn't fly in the case where we wouldn't
1792         * register an ASoC card (because of an old DT that is missing
1793         * the dmas properties for example), then the card isn't
1794         * registered and the device drvdata wouldn't be set.
1795         *
1796         * We can deal with both cases by making sure a snd_soc_card
1797         * pointer and a vc4_hdmi structure are pointing to the same
1798         * memory address, so we can treat them indistinctly without any
1799         * issue.
1800         */
1801        BUILD_BUG_ON(offsetof(struct vc4_hdmi_audio, card) != 0);
1802        BUILD_BUG_ON(offsetof(struct vc4_hdmi, audio) != 0);
1803        vc4_hdmi = dev_get_drvdata(dev);
1804
1805        kfree(vc4_hdmi->hdmi_regset.regs);
1806        kfree(vc4_hdmi->hd_regset.regs);
1807
1808        vc4_hdmi_cec_exit(vc4_hdmi);
1809        vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
1810        drm_encoder_cleanup(&vc4_hdmi->encoder.base.base);
1811
1812        pm_runtime_disable(dev);
1813
1814        put_device(&vc4_hdmi->ddc->dev);
1815}
1816
1817static const struct component_ops vc4_hdmi_ops = {
1818        .bind   = vc4_hdmi_bind,
1819        .unbind = vc4_hdmi_unbind,
1820};
1821
1822static int vc4_hdmi_dev_probe(struct platform_device *pdev)
1823{
1824        return component_add(&pdev->dev, &vc4_hdmi_ops);
1825}
1826
1827static int vc4_hdmi_dev_remove(struct platform_device *pdev)
1828{
1829        component_del(&pdev->dev, &vc4_hdmi_ops);
1830        return 0;
1831}
1832
1833static const struct vc4_hdmi_variant bcm2835_variant = {
1834        .encoder_type           = VC4_ENCODER_TYPE_HDMI0,
1835        .debugfs_name           = "hdmi_regs",
1836        .card_name              = "vc4-hdmi",
1837        .max_pixel_clock        = 162000000,
1838        .cec_available          = true,
1839        .registers              = vc4_hdmi_fields,
1840        .num_registers          = ARRAY_SIZE(vc4_hdmi_fields),
1841
1842        .init_resources         = vc4_hdmi_init_resources,
1843        .csc_setup              = vc4_hdmi_csc_setup,
1844        .reset                  = vc4_hdmi_reset,
1845        .set_timings            = vc4_hdmi_set_timings,
1846        .phy_init               = vc4_hdmi_phy_init,
1847        .phy_disable            = vc4_hdmi_phy_disable,
1848        .phy_rng_enable         = vc4_hdmi_phy_rng_enable,
1849        .phy_rng_disable        = vc4_hdmi_phy_rng_disable,
1850        .channel_map            = vc4_hdmi_channel_map,
1851};
1852
1853static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = {
1854        .encoder_type           = VC4_ENCODER_TYPE_HDMI0,
1855        .debugfs_name           = "hdmi0_regs",
1856        .card_name              = "vc4-hdmi-0",
1857        .max_pixel_clock        = 297000000,
1858        .registers              = vc5_hdmi_hdmi0_fields,
1859        .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi0_fields),
1860        .phy_lane_mapping       = {
1861                PHY_LANE_0,
1862                PHY_LANE_1,
1863                PHY_LANE_2,
1864                PHY_LANE_CK,
1865        },
1866        .unsupported_odd_h_timings      = true,
1867
1868        .init_resources         = vc5_hdmi_init_resources,
1869        .csc_setup              = vc5_hdmi_csc_setup,
1870        .reset                  = vc5_hdmi_reset,
1871        .set_timings            = vc5_hdmi_set_timings,
1872        .phy_init               = vc5_hdmi_phy_init,
1873        .phy_disable            = vc5_hdmi_phy_disable,
1874        .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
1875        .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
1876        .channel_map            = vc5_hdmi_channel_map,
1877};
1878
1879static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
1880        .encoder_type           = VC4_ENCODER_TYPE_HDMI1,
1881        .debugfs_name           = "hdmi1_regs",
1882        .card_name              = "vc4-hdmi-1",
1883        .max_pixel_clock        = 297000000,
1884        .registers              = vc5_hdmi_hdmi1_fields,
1885        .num_registers          = ARRAY_SIZE(vc5_hdmi_hdmi1_fields),
1886        .phy_lane_mapping       = {
1887                PHY_LANE_1,
1888                PHY_LANE_0,
1889                PHY_LANE_CK,
1890                PHY_LANE_2,
1891        },
1892        .unsupported_odd_h_timings      = true,
1893
1894        .init_resources         = vc5_hdmi_init_resources,
1895        .csc_setup              = vc5_hdmi_csc_setup,
1896        .reset                  = vc5_hdmi_reset,
1897        .set_timings            = vc5_hdmi_set_timings,
1898        .phy_init               = vc5_hdmi_phy_init,
1899        .phy_disable            = vc5_hdmi_phy_disable,
1900        .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
1901        .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
1902        .channel_map            = vc5_hdmi_channel_map,
1903};
1904
1905static const struct of_device_id vc4_hdmi_dt_match[] = {
1906        { .compatible = "brcm,bcm2835-hdmi", .data = &bcm2835_variant },
1907        { .compatible = "brcm,bcm2711-hdmi0", .data = &bcm2711_hdmi0_variant },
1908        { .compatible = "brcm,bcm2711-hdmi1", .data = &bcm2711_hdmi1_variant },
1909        {}
1910};
1911
1912struct platform_driver vc4_hdmi_driver = {
1913        .probe = vc4_hdmi_dev_probe,
1914        .remove = vc4_hdmi_dev_remove,
1915        .driver = {
1916                .name = "vc4_hdmi",
1917                .of_match_table = vc4_hdmi_dt_match,
1918        },
1919};
1920