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        int ret;
 335
 336        ret = hdmi_audio_infoframe_init(&frame.audio);
 337
 338        frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
 339        frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
 340        frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
 341        frame.audio.channels = vc4_hdmi->audio.channels;
 342
 343        vc4_hdmi_write_infoframe(encoder, &frame);
 344}
 345
 346static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
 347{
 348        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 349
 350        vc4_hdmi_set_avi_infoframe(encoder);
 351        vc4_hdmi_set_spd_infoframe(encoder);
 352        /*
 353         * If audio was streaming, then we need to reenabled the audio
 354         * infoframe here during encoder_enable.
 355         */
 356        if (vc4_hdmi->audio.streaming)
 357                vc4_hdmi_set_audio_infoframe(encoder);
 358}
 359
 360static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder)
 361{
 362        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 363
 364        HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
 365
 366        HDMI_WRITE(HDMI_VID_CTL, HDMI_READ(HDMI_VID_CTL) |
 367                   VC4_HD_VID_CTL_CLRRGB | VC4_HD_VID_CTL_CLRSYNC);
 368
 369        HDMI_WRITE(HDMI_VID_CTL,
 370                   HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_BLANKPIX);
 371}
 372
 373static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder)
 374{
 375        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 376        int ret;
 377
 378        if (vc4_hdmi->variant->phy_disable)
 379                vc4_hdmi->variant->phy_disable(vc4_hdmi);
 380
 381        HDMI_WRITE(HDMI_VID_CTL,
 382                   HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
 383
 384        clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
 385        clk_disable_unprepare(vc4_hdmi->hsm_clock);
 386        clk_disable_unprepare(vc4_hdmi->pixel_clock);
 387
 388        ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
 389        if (ret < 0)
 390                DRM_ERROR("Failed to release power domain: %d\n", ret);
 391}
 392
 393static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
 394{
 395}
 396
 397static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
 398{
 399        u32 csc_ctl;
 400
 401        csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
 402                                VC4_HD_CSC_CTL_ORDER);
 403
 404        if (enable) {
 405                /* CEA VICs other than #1 requre limited range RGB
 406                 * output unless overridden by an AVI infoframe.
 407                 * Apply a colorspace conversion to squash 0-255 down
 408                 * to 16-235.  The matrix here is:
 409                 *
 410                 * [ 0      0      0.8594 16]
 411                 * [ 0      0.8594 0      16]
 412                 * [ 0.8594 0      0      16]
 413                 * [ 0      0      0       1]
 414                 */
 415                csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
 416                csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
 417                csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
 418                                         VC4_HD_CSC_CTL_MODE);
 419
 420                HDMI_WRITE(HDMI_CSC_12_11, (0x000 << 16) | 0x000);
 421                HDMI_WRITE(HDMI_CSC_14_13, (0x100 << 16) | 0x6e0);
 422                HDMI_WRITE(HDMI_CSC_22_21, (0x6e0 << 16) | 0x000);
 423                HDMI_WRITE(HDMI_CSC_24_23, (0x100 << 16) | 0x000);
 424                HDMI_WRITE(HDMI_CSC_32_31, (0x000 << 16) | 0x6e0);
 425                HDMI_WRITE(HDMI_CSC_34_33, (0x100 << 16) | 0x000);
 426        }
 427
 428        /* The RGB order applies even when CSC is disabled. */
 429        HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
 430}
 431
 432static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
 433{
 434        u32 csc_ctl;
 435
 436        csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */
 437
 438        if (enable) {
 439                /* CEA VICs other than #1 requre limited range RGB
 440                 * output unless overridden by an AVI infoframe.
 441                 * Apply a colorspace conversion to squash 0-255 down
 442                 * to 16-235.  The matrix here is:
 443                 *
 444                 * [ 0.8594 0      0      16]
 445                 * [ 0      0.8594 0      16]
 446                 * [ 0      0      0.8594 16]
 447                 * [ 0      0      0       1]
 448                 * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 449                 */
 450                HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80);
 451                HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000);
 452                HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000);
 453                HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000);
 454                HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
 455                HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
 456        } else {
 457                /* Still use the matrix for full range, but make it unity.
 458                 * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 459                 */
 460                HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000);
 461                HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000);
 462                HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000);
 463                HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000);
 464                HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
 465                HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000);
 466        }
 467
 468        HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
 469}
 470
 471static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 472                                 struct drm_display_mode *mode)
 473{
 474        bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
 475        bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 476        bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
 477        u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
 478        u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
 479                                   VC4_HDMI_VERTA_VSP) |
 480                     VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
 481                                   VC4_HDMI_VERTA_VFP) |
 482                     VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL));
 483        u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
 484                     VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
 485                                   VC4_HDMI_VERTB_VBP));
 486        u32 vertb_even = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
 487                          VC4_SET_FIELD(mode->crtc_vtotal -
 488                                        mode->crtc_vsync_end -
 489                                        interlaced,
 490                                        VC4_HDMI_VERTB_VBP));
 491
 492        HDMI_WRITE(HDMI_HORZA,
 493                   (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
 494                   (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
 495                   VC4_SET_FIELD(mode->hdisplay * pixel_rep,
 496                                 VC4_HDMI_HORZA_HAP));
 497
 498        HDMI_WRITE(HDMI_HORZB,
 499                   VC4_SET_FIELD((mode->htotal -
 500                                  mode->hsync_end) * pixel_rep,
 501                                 VC4_HDMI_HORZB_HBP) |
 502                   VC4_SET_FIELD((mode->hsync_end -
 503                                  mode->hsync_start) * pixel_rep,
 504                                 VC4_HDMI_HORZB_HSP) |
 505                   VC4_SET_FIELD((mode->hsync_start -
 506                                  mode->hdisplay) * pixel_rep,
 507                                 VC4_HDMI_HORZB_HFP));
 508
 509        HDMI_WRITE(HDMI_VERTA0, verta);
 510        HDMI_WRITE(HDMI_VERTA1, verta);
 511
 512        HDMI_WRITE(HDMI_VERTB0, vertb_even);
 513        HDMI_WRITE(HDMI_VERTB1, vertb);
 514}
 515static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 516                                 struct drm_display_mode *mode)
 517{
 518        bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
 519        bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 520        bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
 521        u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
 522        u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
 523                                   VC5_HDMI_VERTA_VSP) |
 524                     VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
 525                                   VC5_HDMI_VERTA_VFP) |
 526                     VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
 527        u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
 528                     VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
 529                                   VC4_HDMI_VERTB_VBP));
 530        u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
 531                          VC4_SET_FIELD(mode->crtc_vtotal -
 532                                        mode->crtc_vsync_end -
 533                                        interlaced,
 534                                        VC4_HDMI_VERTB_VBP));
 535
 536        HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
 537        HDMI_WRITE(HDMI_HORZA,
 538                   (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) |
 539                   (hsync_pos ? VC5_HDMI_HORZA_HPOS : 0) |
 540                   VC4_SET_FIELD(mode->hdisplay * pixel_rep,
 541                                 VC5_HDMI_HORZA_HAP) |
 542                   VC4_SET_FIELD((mode->hsync_start -
 543                                  mode->hdisplay) * pixel_rep,
 544                                 VC5_HDMI_HORZA_HFP));
 545
 546        HDMI_WRITE(HDMI_HORZB,
 547                   VC4_SET_FIELD((mode->htotal -
 548                                  mode->hsync_end) * pixel_rep,
 549                                 VC5_HDMI_HORZB_HBP) |
 550                   VC4_SET_FIELD((mode->hsync_end -
 551                                  mode->hsync_start) * pixel_rep,
 552                                 VC5_HDMI_HORZB_HSP));
 553
 554        HDMI_WRITE(HDMI_VERTA0, verta);
 555        HDMI_WRITE(HDMI_VERTA1, verta);
 556
 557        HDMI_WRITE(HDMI_VERTB0, vertb_even);
 558        HDMI_WRITE(HDMI_VERTB1, vertb);
 559
 560        HDMI_WRITE(HDMI_CLOCK_STOP, 0);
 561}
 562
 563static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi)
 564{
 565        u32 drift;
 566        int ret;
 567
 568        drift = HDMI_READ(HDMI_FIFO_CTL);
 569        drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
 570
 571        HDMI_WRITE(HDMI_FIFO_CTL,
 572                   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
 573        HDMI_WRITE(HDMI_FIFO_CTL,
 574                   drift | VC4_HDMI_FIFO_CTL_RECENTER);
 575        usleep_range(1000, 1100);
 576        HDMI_WRITE(HDMI_FIFO_CTL,
 577                   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
 578        HDMI_WRITE(HDMI_FIFO_CTL,
 579                   drift | VC4_HDMI_FIFO_CTL_RECENTER);
 580
 581        ret = wait_for(HDMI_READ(HDMI_FIFO_CTL) &
 582                       VC4_HDMI_FIFO_CTL_RECENTER_DONE, 1);
 583        WARN_ONCE(ret, "Timeout waiting for "
 584                  "VC4_HDMI_FIFO_CTL_RECENTER_DONE");
 585}
 586
 587static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder)
 588{
 589        struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 590        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 591        unsigned long pixel_rate, hsm_rate;
 592        int ret;
 593
 594        ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
 595        if (ret < 0) {
 596                DRM_ERROR("Failed to retain power domain: %d\n", ret);
 597                return;
 598        }
 599
 600        pixel_rate = mode->clock * 1000 * ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1);
 601        ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
 602        if (ret) {
 603                DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
 604                return;
 605        }
 606
 607        ret = clk_prepare_enable(vc4_hdmi->pixel_clock);
 608        if (ret) {
 609                DRM_ERROR("Failed to turn on pixel clock: %d\n", ret);
 610                return;
 611        }
 612
 613        /*
 614         * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must
 615         * be faster than pixel clock, infinitesimally faster, tested in
 616         * simulation. Otherwise, exact value is unimportant for HDMI
 617         * operation." This conflicts with bcm2835's vc4 documentation, which
 618         * states HSM's clock has to be at least 108% of the pixel clock.
 619         *
 620         * Real life tests reveal that vc4's firmware statement holds up, and
 621         * users are able to use pixel clocks closer to HSM's, namely for
 622         * 1920x1200@60Hz. So it was decided to have leave a 1% margin between
 623         * both clocks. Which, for RPi0-3 implies a maximum pixel clock of
 624         * 162MHz.
 625         *
 626         * Additionally, the AXI clock needs to be at least 25% of
 627         * pixel clock, but HSM ends up being the limiting factor.
 628         */
 629        hsm_rate = max_t(unsigned long, 120000000, (pixel_rate / 100) * 101);
 630        ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate);
 631        if (ret) {
 632                DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
 633                return;
 634        }
 635
 636        ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
 637        if (ret) {
 638                DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
 639                clk_disable_unprepare(vc4_hdmi->pixel_clock);
 640                return;
 641        }
 642
 643        /*
 644         * FIXME: When the pixel freq is 594MHz (4k60), this needs to be setup
 645         * at 300MHz.
 646         */
 647        ret = clk_set_min_rate(vc4_hdmi->pixel_bvb_clock,
 648                               (hsm_rate > VC4_HSM_MID_CLOCK ? 150000000 : 75000000));
 649        if (ret) {
 650                DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret);
 651                clk_disable_unprepare(vc4_hdmi->hsm_clock);
 652                clk_disable_unprepare(vc4_hdmi->pixel_clock);
 653                return;
 654        }
 655
 656        ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
 657        if (ret) {
 658                DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret);
 659                clk_disable_unprepare(vc4_hdmi->hsm_clock);
 660                clk_disable_unprepare(vc4_hdmi->pixel_clock);
 661                return;
 662        }
 663
 664        if (vc4_hdmi->variant->reset)
 665                vc4_hdmi->variant->reset(vc4_hdmi);
 666
 667        if (vc4_hdmi->variant->phy_init)
 668                vc4_hdmi->variant->phy_init(vc4_hdmi, mode);
 669
 670        HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
 671                   HDMI_READ(HDMI_SCHEDULER_CONTROL) |
 672                   VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
 673                   VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
 674
 675        if (vc4_hdmi->variant->set_timings)
 676                vc4_hdmi->variant->set_timings(vc4_hdmi, mode);
 677}
 678
 679static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder)
 680{
 681        struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 682        struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
 683        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 684
 685        if (vc4_encoder->hdmi_monitor &&
 686            drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) {
 687                if (vc4_hdmi->variant->csc_setup)
 688                        vc4_hdmi->variant->csc_setup(vc4_hdmi, true);
 689
 690                vc4_encoder->limited_rgb_range = true;
 691        } else {
 692                if (vc4_hdmi->variant->csc_setup)
 693                        vc4_hdmi->variant->csc_setup(vc4_hdmi, false);
 694
 695                vc4_encoder->limited_rgb_range = false;
 696        }
 697
 698        HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
 699}
 700
 701static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder)
 702{
 703        struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 704        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 705        struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
 706        bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
 707        bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 708        int ret;
 709
 710        HDMI_WRITE(HDMI_VID_CTL,
 711                   VC4_HD_VID_CTL_ENABLE |
 712                   VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
 713                   VC4_HD_VID_CTL_FRAME_COUNTER_RESET |
 714                   (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
 715                   (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
 716
 717        HDMI_WRITE(HDMI_VID_CTL,
 718                   HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_BLANKPIX);
 719
 720        if (vc4_encoder->hdmi_monitor) {
 721                HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
 722                           HDMI_READ(HDMI_SCHEDULER_CONTROL) |
 723                           VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
 724
 725                ret = wait_for(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
 726                               VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1000);
 727                WARN_ONCE(ret, "Timeout waiting for "
 728                          "VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
 729        } else {
 730                HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
 731                           HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
 732                           ~(VC4_HDMI_RAM_PACKET_ENABLE));
 733                HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
 734                           HDMI_READ(HDMI_SCHEDULER_CONTROL) &
 735                           ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
 736
 737                ret = wait_for(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
 738                                 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1000);
 739                WARN_ONCE(ret, "Timeout waiting for "
 740                          "!VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
 741        }
 742
 743        if (vc4_encoder->hdmi_monitor) {
 744                WARN_ON(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
 745                          VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
 746                HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
 747                           HDMI_READ(HDMI_SCHEDULER_CONTROL) |
 748                           VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT);
 749
 750                HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
 751                           VC4_HDMI_RAM_PACKET_ENABLE);
 752
 753                vc4_hdmi_set_infoframes(encoder);
 754        }
 755
 756        vc4_hdmi_recenter_fifo(vc4_hdmi);
 757}
 758
 759static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
 760{
 761}
 762
 763#define WIFI_2_4GHz_CH1_MIN_FREQ        2400000000ULL
 764#define WIFI_2_4GHz_CH1_MAX_FREQ        2422000000ULL
 765
 766static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 767                                         struct drm_crtc_state *crtc_state,
 768                                         struct drm_connector_state *conn_state)
 769{
 770        struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 771        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 772        unsigned long long pixel_rate = mode->clock * 1000;
 773        unsigned long long tmds_rate;
 774
 775        if (vc4_hdmi->variant->unsupported_odd_h_timings &&
 776            ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
 777             (mode->hsync_end % 2) || (mode->htotal % 2)))
 778                return -EINVAL;
 779
 780        /*
 781         * The 1440p@60 pixel rate is in the same range than the first
 782         * WiFi channel (between 2.4GHz and 2.422GHz with 22MHz
 783         * bandwidth). Slightly lower the frequency to bring it out of
 784         * the WiFi range.
 785         */
 786        tmds_rate = pixel_rate * 10;
 787        if (vc4_hdmi->disable_wifi_frequencies &&
 788            (tmds_rate >= WIFI_2_4GHz_CH1_MIN_FREQ &&
 789             tmds_rate <= WIFI_2_4GHz_CH1_MAX_FREQ)) {
 790                mode->clock = 238560;
 791                pixel_rate = mode->clock * 1000;
 792        }
 793
 794        if (pixel_rate > vc4_hdmi->variant->max_pixel_clock)
 795                return -EINVAL;
 796
 797        return 0;
 798}
 799
 800static enum drm_mode_status
 801vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
 802                            const struct drm_display_mode *mode)
 803{
 804        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 805
 806        if (vc4_hdmi->variant->unsupported_odd_h_timings &&
 807            ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
 808             (mode->hsync_end % 2) || (mode->htotal % 2)))
 809                return MODE_H_ILLEGAL;
 810
 811        if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock)
 812                return MODE_CLOCK_HIGH;
 813
 814        return MODE_OK;
 815}
 816
 817static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
 818        .atomic_check = vc4_hdmi_encoder_atomic_check,
 819        .mode_valid = vc4_hdmi_encoder_mode_valid,
 820        .disable = vc4_hdmi_encoder_disable,
 821        .enable = vc4_hdmi_encoder_enable,
 822};
 823
 824static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
 825{
 826        int i;
 827        u32 channel_map = 0;
 828
 829        for (i = 0; i < 8; i++) {
 830                if (channel_mask & BIT(i))
 831                        channel_map |= i << (3 * i);
 832        }
 833        return channel_map;
 834}
 835
 836static u32 vc5_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
 837{
 838        int i;
 839        u32 channel_map = 0;
 840
 841        for (i = 0; i < 8; i++) {
 842                if (channel_mask & BIT(i))
 843                        channel_map |= i << (4 * i);
 844        }
 845        return channel_map;
 846}
 847
 848/* HDMI audio codec callbacks */
 849static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
 850{
 851        u32 hsm_clock = clk_get_rate(vc4_hdmi->audio_clock);
 852        unsigned long n, m;
 853
 854        rational_best_approximation(hsm_clock, vc4_hdmi->audio.samplerate,
 855                                    VC4_HD_MAI_SMP_N_MASK >>
 856                                    VC4_HD_MAI_SMP_N_SHIFT,
 857                                    (VC4_HD_MAI_SMP_M_MASK >>
 858                                     VC4_HD_MAI_SMP_M_SHIFT) + 1,
 859                                    &n, &m);
 860
 861        HDMI_WRITE(HDMI_MAI_SMP,
 862                   VC4_SET_FIELD(n, VC4_HD_MAI_SMP_N) |
 863                   VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M));
 864}
 865
 866static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi)
 867{
 868        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 869        struct drm_crtc *crtc = encoder->crtc;
 870        const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 871        u32 samplerate = vc4_hdmi->audio.samplerate;
 872        u32 n, cts;
 873        u64 tmp;
 874
 875        n = 128 * samplerate / 1000;
 876        tmp = (u64)(mode->clock * 1000) * n;
 877        do_div(tmp, 128 * samplerate);
 878        cts = tmp;
 879
 880        HDMI_WRITE(HDMI_CRP_CFG,
 881                   VC4_HDMI_CRP_CFG_EXTERNAL_CTS_EN |
 882                   VC4_SET_FIELD(n, VC4_HDMI_CRP_CFG_N));
 883
 884        /*
 885         * We could get slightly more accurate clocks in some cases by
 886         * providing a CTS_1 value.  The two CTS values are alternated
 887         * between based on the period fields
 888         */
 889        HDMI_WRITE(HDMI_CTS_0, cts);
 890        HDMI_WRITE(HDMI_CTS_1, cts);
 891}
 892
 893static inline struct vc4_hdmi *dai_to_hdmi(struct snd_soc_dai *dai)
 894{
 895        struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai);
 896
 897        return snd_soc_card_get_drvdata(card);
 898}
 899
 900static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
 901                                  struct snd_soc_dai *dai)
 902{
 903        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
 904        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 905        struct drm_connector *connector = &vc4_hdmi->connector;
 906        int ret;
 907
 908        if (vc4_hdmi->audio.substream && vc4_hdmi->audio.substream != substream)
 909                return -EINVAL;
 910
 911        vc4_hdmi->audio.substream = substream;
 912
 913        /*
 914         * If the HDMI encoder hasn't probed, or the encoder is
 915         * currently in DVI mode, treat the codec dai as missing.
 916         */
 917        if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
 918                                VC4_HDMI_RAM_PACKET_ENABLE))
 919                return -ENODEV;
 920
 921        ret = snd_pcm_hw_constraint_eld(substream->runtime, connector->eld);
 922        if (ret)
 923                return ret;
 924
 925        return 0;
 926}
 927
 928static int vc4_hdmi_audio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 929{
 930        return 0;
 931}
 932
 933static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 934{
 935        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 936        struct device *dev = &vc4_hdmi->pdev->dev;
 937        int ret;
 938
 939        vc4_hdmi->audio.streaming = false;
 940        ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO);
 941        if (ret)
 942                dev_err(dev, "Failed to stop audio infoframe: %d\n", ret);
 943
 944        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_RESET);
 945        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_ERRORF);
 946        HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_FLUSH);
 947}
 948
 949static void vc4_hdmi_audio_shutdown(struct snd_pcm_substream *substream,
 950                                    struct snd_soc_dai *dai)
 951{
 952        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
 953
 954        if (substream != vc4_hdmi->audio.substream)
 955                return;
 956
 957        vc4_hdmi_audio_reset(vc4_hdmi);
 958
 959        vc4_hdmi->audio.substream = NULL;
 960}
 961
 962/* HDMI audio codec callbacks */
 963static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
 964                                    struct snd_pcm_hw_params *params,
 965                                    struct snd_soc_dai *dai)
 966{
 967        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
 968        struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
 969        struct device *dev = &vc4_hdmi->pdev->dev;
 970        u32 audio_packet_config, channel_mask;
 971        u32 channel_map;
 972
 973        if (substream != vc4_hdmi->audio.substream)
 974                return -EINVAL;
 975
 976        dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
 977                params_rate(params), params_width(params),
 978                params_channels(params));
 979
 980        vc4_hdmi->audio.channels = params_channels(params);
 981        vc4_hdmi->audio.samplerate = params_rate(params);
 982
 983        HDMI_WRITE(HDMI_MAI_CTL,
 984                   VC4_HD_MAI_CTL_RESET |
 985                   VC4_HD_MAI_CTL_FLUSH |
 986                   VC4_HD_MAI_CTL_DLATE |
 987                   VC4_HD_MAI_CTL_ERRORE |
 988                   VC4_HD_MAI_CTL_ERRORF);
 989
 990        vc4_hdmi_audio_set_mai_clock(vc4_hdmi);
 991
 992        /* The B frame identifier should match the value used by alsa-lib (8) */
 993        audio_packet_config =
 994                VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_SAMPLE_FLAT |
 995                VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_INACTIVE_CHANNELS |
 996                VC4_SET_FIELD(0x8, VC4_HDMI_AUDIO_PACKET_B_FRAME_IDENTIFIER);
 997
 998        channel_mask = GENMASK(vc4_hdmi->audio.channels - 1, 0);
 999        audio_packet_config |= VC4_SET_FIELD(channel_mask,
1000                                             VC4_HDMI_AUDIO_PACKET_CEA_MASK);
1001
1002        /* Set the MAI threshold.  This logic mimics the firmware's. */
1003        if (vc4_hdmi->audio.samplerate > 96000) {
1004                HDMI_WRITE(HDMI_MAI_THR,
1005                           VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQHIGH) |
1006                           VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
1007        } else if (vc4_hdmi->audio.samplerate > 48000) {
1008                HDMI_WRITE(HDMI_MAI_THR,
1009                           VC4_SET_FIELD(0x14, VC4_HD_MAI_THR_DREQHIGH) |
1010                           VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
1011        } else {
1012                HDMI_WRITE(HDMI_MAI_THR,
1013                           VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) |
1014                           VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) |
1015                           VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) |
1016                           VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW));
1017        }
1018
1019        HDMI_WRITE(HDMI_MAI_CONFIG,
1020                   VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
1021                   VC4_SET_FIELD(channel_mask, VC4_HDMI_MAI_CHANNEL_MASK));
1022
1023        channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask);
1024        HDMI_WRITE(HDMI_MAI_CHANNEL_MAP, channel_map);
1025        HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
1026        vc4_hdmi_set_n_cts(vc4_hdmi);
1027
1028        vc4_hdmi_set_audio_infoframe(encoder);
1029
1030        return 0;
1031}
1032
1033static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
1034                                  struct snd_soc_dai *dai)
1035{
1036        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
1037
1038        switch (cmd) {
1039        case SNDRV_PCM_TRIGGER_START:
1040                vc4_hdmi->audio.streaming = true;
1041
1042                if (vc4_hdmi->variant->phy_rng_enable)
1043                        vc4_hdmi->variant->phy_rng_enable(vc4_hdmi);
1044
1045                HDMI_WRITE(HDMI_MAI_CTL,
1046                           VC4_SET_FIELD(vc4_hdmi->audio.channels,
1047                                         VC4_HD_MAI_CTL_CHNUM) |
1048                           VC4_HD_MAI_CTL_ENABLE);
1049                break;
1050        case SNDRV_PCM_TRIGGER_STOP:
1051                HDMI_WRITE(HDMI_MAI_CTL,
1052                           VC4_HD_MAI_CTL_DLATE |
1053                           VC4_HD_MAI_CTL_ERRORE |
1054                           VC4_HD_MAI_CTL_ERRORF);
1055
1056                if (vc4_hdmi->variant->phy_rng_disable)
1057                        vc4_hdmi->variant->phy_rng_disable(vc4_hdmi);
1058
1059                vc4_hdmi->audio.streaming = false;
1060
1061                break;
1062        default:
1063                break;
1064        }
1065
1066        return 0;
1067}
1068
1069static inline struct vc4_hdmi *
1070snd_component_to_hdmi(struct snd_soc_component *component)
1071{
1072        struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
1073
1074        return snd_soc_card_get_drvdata(card);
1075}
1076
1077static int vc4_hdmi_audio_eld_ctl_info(struct snd_kcontrol *kcontrol,
1078                                       struct snd_ctl_elem_info *uinfo)
1079{
1080        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1081        struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
1082        struct drm_connector *connector = &vc4_hdmi->connector;
1083
1084        uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1085        uinfo->count = sizeof(connector->eld);
1086
1087        return 0;
1088}
1089
1090static int vc4_hdmi_audio_eld_ctl_get(struct snd_kcontrol *kcontrol,
1091                                      struct snd_ctl_elem_value *ucontrol)
1092{
1093        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1094        struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
1095        struct drm_connector *connector = &vc4_hdmi->connector;
1096
1097        memcpy(ucontrol->value.bytes.data, connector->eld,
1098               sizeof(connector->eld));
1099
1100        return 0;
1101}
1102
1103static const struct snd_kcontrol_new vc4_hdmi_audio_controls[] = {
1104        {
1105                .access = SNDRV_CTL_ELEM_ACCESS_READ |
1106                          SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1107                .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1108                .name = "ELD",
1109                .info = vc4_hdmi_audio_eld_ctl_info,
1110                .get = vc4_hdmi_audio_eld_ctl_get,
1111        },
1112};
1113
1114static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = {
1115        SND_SOC_DAPM_OUTPUT("TX"),
1116};
1117
1118static const struct snd_soc_dapm_route vc4_hdmi_audio_routes[] = {
1119        { "TX", NULL, "Playback" },
1120};
1121
1122static const struct snd_soc_component_driver vc4_hdmi_audio_component_drv = {
1123        .name                   = "vc4-hdmi-codec-dai-component",
1124        .controls               = vc4_hdmi_audio_controls,
1125        .num_controls           = ARRAY_SIZE(vc4_hdmi_audio_controls),
1126        .dapm_widgets           = vc4_hdmi_audio_widgets,
1127        .num_dapm_widgets       = ARRAY_SIZE(vc4_hdmi_audio_widgets),
1128        .dapm_routes            = vc4_hdmi_audio_routes,
1129        .num_dapm_routes        = ARRAY_SIZE(vc4_hdmi_audio_routes),
1130        .idle_bias_on           = 1,
1131        .use_pmdown_time        = 1,
1132        .endianness             = 1,
1133        .non_legacy_dai_naming  = 1,
1134};
1135
1136static const struct snd_soc_dai_ops vc4_hdmi_audio_dai_ops = {
1137        .startup = vc4_hdmi_audio_startup,
1138        .shutdown = vc4_hdmi_audio_shutdown,
1139        .hw_params = vc4_hdmi_audio_hw_params,
1140        .set_fmt = vc4_hdmi_audio_set_fmt,
1141        .trigger = vc4_hdmi_audio_trigger,
1142};
1143
1144static struct snd_soc_dai_driver vc4_hdmi_audio_codec_dai_drv = {
1145        .name = "vc4-hdmi-hifi",
1146        .playback = {
1147                .stream_name = "Playback",
1148                .channels_min = 2,
1149                .channels_max = 8,
1150                .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
1151                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
1152                         SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
1153                         SNDRV_PCM_RATE_192000,
1154                .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
1155        },
1156};
1157
1158static const struct snd_soc_component_driver vc4_hdmi_audio_cpu_dai_comp = {
1159        .name = "vc4-hdmi-cpu-dai-component",
1160};
1161
1162static int vc4_hdmi_audio_cpu_dai_probe(struct snd_soc_dai *dai)
1163{
1164        struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
1165
1166        snd_soc_dai_init_dma_data(dai, &vc4_hdmi->audio.dma_data, NULL);
1167
1168        return 0;
1169}
1170
1171static struct snd_soc_dai_driver vc4_hdmi_audio_cpu_dai_drv = {
1172        .name = "vc4-hdmi-cpu-dai",
1173        .probe  = vc4_hdmi_audio_cpu_dai_probe,
1174        .playback = {
1175                .stream_name = "Playback",
1176                .channels_min = 1,
1177                .channels_max = 8,
1178                .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
1179                         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
1180                         SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
1181                         SNDRV_PCM_RATE_192000,
1182                .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
1183        },
1184        .ops = &vc4_hdmi_audio_dai_ops,
1185};
1186
1187static const struct snd_dmaengine_pcm_config pcm_conf = {
1188        .chan_names[SNDRV_PCM_STREAM_PLAYBACK] = "audio-rx",
1189        .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
1190};
1191
1192static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
1193{
1194        const struct vc4_hdmi_register *mai_data =
1195                &vc4_hdmi->variant->registers[HDMI_MAI_DATA];
1196        struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
1197        struct snd_soc_card *card = &vc4_hdmi->audio.card;
1198        struct device *dev = &vc4_hdmi->pdev->dev;
1199        const __be32 *addr;
1200        int index;
1201        int ret;
1202
1203        if (!of_find_property(dev->of_node, "dmas", NULL)) {
1204                dev_warn(dev,
1205                         "'dmas' DT property is missing, no HDMI audio\n");
1206                return 0;
1207        }
1208
1209        if (mai_data->reg != VC4_HD) {
1210                WARN_ONCE(true, "MAI isn't in the HD block\n");
1211                return -EINVAL;
1212        }
1213
1214        /*
1215         * Get the physical address of VC4_HD_MAI_DATA. We need to retrieve
1216         * the bus address specified in the DT, because the physical address
1217         * (the one returned by platform_get_resource()) is not appropriate
1218         * for DMA transfers.
1219         * This VC/MMU should probably be exposed to avoid this kind of hacks.
1220         */
1221        index = of_property_match_string(dev->of_node, "reg-names", "hd");
1222        /* Before BCM2711, we don't have a named register range */
1223        if (index < 0)
1224                index = 1;
1225
1226        addr = of_get_address(dev->of_node, index, NULL, NULL);
1227
1228        vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset;
1229        vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
1230        vc4_hdmi->audio.dma_data.maxburst = 2;
1231
1232        ret = devm_snd_dmaengine_pcm_register(dev, &pcm_conf, 0);
1233        if (ret) {
1234                dev_err(dev, "Could not register PCM component: %d\n", ret);
1235                return ret;
1236        }
1237
1238        ret = devm_snd_soc_register_component(dev, &vc4_hdmi_audio_cpu_dai_comp,
1239                                              &vc4_hdmi_audio_cpu_dai_drv, 1);
1240        if (ret) {
1241                dev_err(dev, "Could not register CPU DAI: %d\n", ret);
1242                return ret;
1243        }
1244
1245        /* register component and codec dai */
1246        ret = devm_snd_soc_register_component(dev, &vc4_hdmi_audio_component_drv,
1247                                     &vc4_hdmi_audio_codec_dai_drv, 1);
1248        if (ret) {
1249                dev_err(dev, "Could not register component: %d\n", ret);
1250                return ret;
1251        }
1252
1253        dai_link->cpus          = &vc4_hdmi->audio.cpu;
1254        dai_link->codecs        = &vc4_hdmi->audio.codec;
1255        dai_link->platforms     = &vc4_hdmi->audio.platform;
1256
1257        dai_link->num_cpus      = 1;
1258        dai_link->num_codecs    = 1;
1259        dai_link->num_platforms = 1;
1260
1261        dai_link->name = "MAI";
1262        dai_link->stream_name = "MAI PCM";
1263        dai_link->codecs->dai_name = vc4_hdmi_audio_codec_dai_drv.name;
1264        dai_link->cpus->dai_name = dev_name(dev);
1265        dai_link->codecs->name = dev_name(dev);
1266        dai_link->platforms->name = dev_name(dev);
1267
1268        card->dai_link = dai_link;
1269        card->num_links = 1;
1270        card->name = vc4_hdmi->variant->card_name;
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