root/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
#ifndef _VC4_HDMI_REGS_H_
#define _VC4_HDMI_REGS_H_

#include <linux/pm_runtime.h>

#include "vc4_hdmi.h"

#define VC4_HDMI_PACKET_STRIDE                  0x24

enum vc4_hdmi_regs {
        VC4_INVALID = 0,
        VC4_HDMI,
        VC4_HD,
        VC5_CEC,
        VC5_CSC,
        VC5_DVP,
        VC5_PHY,
        VC5_RAM,
        VC5_RM,
};

enum vc4_hdmi_field {
        HDMI_AUDIO_PACKET_CONFIG,
        HDMI_CEC_CNTRL_1,
        HDMI_CEC_CNTRL_2,
        HDMI_CEC_CNTRL_3,
        HDMI_CEC_CNTRL_4,
        HDMI_CEC_CNTRL_5,
        HDMI_CEC_CPU_CLEAR,
        HDMI_CEC_CPU_MASK_CLEAR,
        HDMI_CEC_CPU_MASK_SET,
        HDMI_CEC_CPU_MASK_STATUS,
        HDMI_CEC_CPU_STATUS,
        HDMI_CEC_CPU_SET,

        /*
         * Transmit data, first byte is low byte of the 32-bit reg.
         * MSB of each byte transmitted first.
         */
        HDMI_CEC_RX_DATA_1,
        HDMI_CEC_RX_DATA_2,
        HDMI_CEC_RX_DATA_3,
        HDMI_CEC_RX_DATA_4,
        HDMI_CEC_TX_DATA_1,
        HDMI_CEC_TX_DATA_2,
        HDMI_CEC_TX_DATA_3,
        HDMI_CEC_TX_DATA_4,
        HDMI_CLOCK_STOP,
        HDMI_CORE_REV,
        HDMI_CRP_CFG,
        HDMI_CSC_12_11,
        HDMI_CSC_14_13,
        HDMI_CSC_22_21,
        HDMI_CSC_24_23,
        HDMI_CSC_32_31,
        HDMI_CSC_34_33,
        HDMI_CSC_CHANNEL_CTL,
        HDMI_CSC_CTL,

        /*
         * 20-bit fields containing CTS values to be transmitted if
         * !EXTERNAL_CTS_EN
         */
        HDMI_CTS_0,
        HDMI_CTS_1,
        HDMI_DEEP_COLOR_CONFIG_1,
        HDMI_DVP_CTL,
        HDMI_FIFO_CTL,
        HDMI_FRAME_COUNT,
        HDMI_GCP_CONFIG,
        HDMI_GCP_WORD_1,
        HDMI_HORZA,
        HDMI_HORZB,
        HDMI_HOTPLUG,
        HDMI_HOTPLUG_INT,

        /*
         * 3 bits per field, where each field maps from that
         * corresponding MAI bus channel to the given HDMI channel.
         */
        HDMI_MAI_CHANNEL_MAP,
        HDMI_MAI_CONFIG,
        HDMI_MAI_CTL,

        /*
         * Register for DMAing in audio data to be transported over
         * the MAI bus to the Falcon core.
         */
        HDMI_MAI_DATA,

        /* Format header to be placed on the MAI data. Unused. */
        HDMI_MAI_FMT,

        /* Last received format word on the MAI bus. */
        HDMI_MAI_FORMAT,
        HDMI_MAI_SMP,
        HDMI_MAI_THR,
        HDMI_M_CTL,
        HDMI_RAM_PACKET_CONFIG,
        HDMI_RAM_PACKET_START,
        HDMI_RAM_PACKET_STATUS,
        HDMI_RM_CONTROL,
        HDMI_RM_FORMAT,
        HDMI_RM_OFFSET,
        HDMI_SCHEDULER_CONTROL,
        HDMI_SCRAMBLER_CTL,
        HDMI_SW_RESET_CONTROL,
        HDMI_TX_PHY_CHANNEL_SWAP,
        HDMI_TX_PHY_CLK_DIV,
        HDMI_TX_PHY_CTL_0,
        HDMI_TX_PHY_CTL_1,
        HDMI_TX_PHY_CTL_2,
        HDMI_TX_PHY_CTL_3,
        HDMI_TX_PHY_CTL_CK,
        HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
        HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
        HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
        HDMI_TX_PHY_PLL_CFG,
        HDMI_TX_PHY_PLL_CFG_PDIV,
        HDMI_TX_PHY_PLL_CTL_0,
        HDMI_TX_PHY_PLL_CTL_1,
        HDMI_TX_PHY_PLL_MISC_0,
        HDMI_TX_PHY_PLL_MISC_1,
        HDMI_TX_PHY_PLL_MISC_2,
        HDMI_TX_PHY_PLL_MISC_3,
        HDMI_TX_PHY_PLL_MISC_4,
        HDMI_TX_PHY_PLL_MISC_5,
        HDMI_TX_PHY_PLL_MISC_6,
        HDMI_TX_PHY_PLL_MISC_7,
        HDMI_TX_PHY_PLL_MISC_8,
        HDMI_TX_PHY_PLL_POST_KDIV,
        HDMI_TX_PHY_PLL_POWERUP_CTL,
        HDMI_TX_PHY_PLL_REFCLK,
        HDMI_TX_PHY_PLL_RESET_CTL,
        HDMI_TX_PHY_PLL_VCOCLK_DIV,
        HDMI_TX_PHY_POWERDOWN_CTL,
        HDMI_TX_PHY_POWERUP_CTL,
        HDMI_TX_PHY_RESET_CTL,
        HDMI_TX_PHY_TMDS_CLK_WORD_SEL,
        HDMI_VEC_INTERFACE_CFG,
        HDMI_VEC_INTERFACE_XBAR,
        HDMI_VERTA0,
        HDMI_VERTA1,
        HDMI_VERTB0,
        HDMI_VERTB1,
        HDMI_VID_CTL,
        HDMI_MISC_CONTROL,
        HDMI_FORMAT_DET_1,
        HDMI_FORMAT_DET_2,
        HDMI_FORMAT_DET_3,
        HDMI_FORMAT_DET_4,
        HDMI_FORMAT_DET_5,
        HDMI_FORMAT_DET_6,
        HDMI_FORMAT_DET_7,
        HDMI_FORMAT_DET_8,
        HDMI_FORMAT_DET_9,
        HDMI_FORMAT_DET_10,
};

struct vc4_hdmi_register {
        char *name;
        enum vc4_hdmi_regs reg;
        unsigned int offset;
};

#define _VC4_REG(_base, _reg, _offset)  \
        [_reg] = {                              \
                .name = #_reg,                  \
                .reg = _base,                   \
                .offset = _offset,              \
        }

#define VC4_HD_REG(reg, offset)         _VC4_REG(VC4_HD, reg, offset)
#define VC4_HDMI_REG(reg, offset)       _VC4_REG(VC4_HDMI, reg, offset)
#define VC5_CEC_REG(reg, offset)        _VC4_REG(VC5_CEC, reg, offset)
#define VC5_CSC_REG(reg, offset)        _VC4_REG(VC5_CSC, reg, offset)
#define VC5_DVP_REG(reg, offset)        _VC4_REG(VC5_DVP, reg, offset)
#define VC5_PHY_REG(reg, offset)        _VC4_REG(VC5_PHY, reg, offset)
#define VC5_RAM_REG(reg, offset)        _VC4_REG(VC5_RAM, reg, offset)
#define VC5_RM_REG(reg, offset)         _VC4_REG(VC5_RM, reg, offset)

static const struct vc4_hdmi_register __maybe_unused vc4_hdmi_fields[] = {
        VC4_HD_REG(HDMI_M_CTL, 0x000c),
        VC4_HD_REG(HDMI_MAI_CTL, 0x0014),
        VC4_HD_REG(HDMI_MAI_THR, 0x0018),
        VC4_HD_REG(HDMI_MAI_FMT, 0x001c),
        VC4_HD_REG(HDMI_MAI_DATA, 0x0020),
        VC4_HD_REG(HDMI_MAI_SMP, 0x002c),
        VC4_HD_REG(HDMI_VID_CTL, 0x0038),
        VC4_HD_REG(HDMI_CSC_CTL, 0x0040),
        VC4_HD_REG(HDMI_CSC_12_11, 0x0044),
        VC4_HD_REG(HDMI_CSC_14_13, 0x0048),
        VC4_HD_REG(HDMI_CSC_22_21, 0x004c),
        VC4_HD_REG(HDMI_CSC_24_23, 0x0050),
        VC4_HD_REG(HDMI_CSC_32_31, 0x0054),
        VC4_HD_REG(HDMI_CSC_34_33, 0x0058),
        VC4_HD_REG(HDMI_FRAME_COUNT, 0x0068),

        VC4_HDMI_REG(HDMI_CORE_REV, 0x0000),
        VC4_HDMI_REG(HDMI_SW_RESET_CONTROL, 0x0004),
        VC4_HDMI_REG(HDMI_HOTPLUG_INT, 0x0008),
        VC4_HDMI_REG(HDMI_HOTPLUG, 0x000c),
        VC4_HDMI_REG(HDMI_FIFO_CTL, 0x005c),
        VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x0090),
        VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0094),
        VC4_HDMI_REG(HDMI_MAI_FORMAT, 0x0098),
        VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x009c),
        VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x00a0),
        VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x00a4),
        VC4_HDMI_REG(HDMI_CRP_CFG, 0x00a8),
        VC4_HDMI_REG(HDMI_CTS_0, 0x00ac),
        VC4_HDMI_REG(HDMI_CTS_1, 0x00b0),
        VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x00c0),
        VC4_HDMI_REG(HDMI_HORZA, 0x00c4),
        VC4_HDMI_REG(HDMI_HORZB, 0x00c8),
        VC4_HDMI_REG(HDMI_VERTA0, 0x00cc),
        VC4_HDMI_REG(HDMI_VERTB0, 0x00d0),
        VC4_HDMI_REG(HDMI_VERTA1, 0x00d4),
        VC4_HDMI_REG(HDMI_VERTB1, 0x00d8),
        VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x00e4),
        VC4_HDMI_REG(HDMI_CEC_CNTRL_1, 0x00e8),
        VC4_HDMI_REG(HDMI_CEC_CNTRL_2, 0x00ec),
        VC4_HDMI_REG(HDMI_CEC_CNTRL_3, 0x00f0),
        VC4_HDMI_REG(HDMI_CEC_CNTRL_4, 0x00f4),
        VC4_HDMI_REG(HDMI_CEC_CNTRL_5, 0x00f8),
        VC4_HDMI_REG(HDMI_CEC_TX_DATA_1, 0x00fc),
        VC4_HDMI_REG(HDMI_CEC_TX_DATA_2, 0x0100),
        VC4_HDMI_REG(HDMI_CEC_TX_DATA_3, 0x0104),
        VC4_HDMI_REG(HDMI_CEC_TX_DATA_4, 0x0108),
        VC4_HDMI_REG(HDMI_CEC_RX_DATA_1, 0x010c),
        VC4_HDMI_REG(HDMI_CEC_RX_DATA_2, 0x0110),
        VC4_HDMI_REG(HDMI_CEC_RX_DATA_3, 0x0114),
        VC4_HDMI_REG(HDMI_CEC_RX_DATA_4, 0x0118),
        VC4_HDMI_REG(HDMI_TX_PHY_RESET_CTL, 0x02c0),
        VC4_HDMI_REG(HDMI_TX_PHY_CTL_0, 0x02c4),
        VC4_HDMI_REG(HDMI_CEC_CPU_STATUS, 0x0340),
        VC4_HDMI_REG(HDMI_CEC_CPU_SET, 0x0344),
        VC4_HDMI_REG(HDMI_CEC_CPU_CLEAR, 0x0348),
        VC4_HDMI_REG(HDMI_CEC_CPU_MASK_STATUS, 0x034c),
        VC4_HDMI_REG(HDMI_CEC_CPU_MASK_SET, 0x0350),
        VC4_HDMI_REG(HDMI_CEC_CPU_MASK_CLEAR, 0x0354),
        VC4_HDMI_REG(HDMI_RAM_PACKET_START, 0x0400),
};

static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi0_fields[] = {
        VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
        VC4_HD_REG(HDMI_MAI_CTL, 0x0010),
        VC4_HD_REG(HDMI_MAI_THR, 0x0014),
        VC4_HD_REG(HDMI_MAI_FMT, 0x0018),
        VC4_HD_REG(HDMI_MAI_DATA, 0x001c),
        VC4_HD_REG(HDMI_MAI_SMP, 0x0020),
        VC4_HD_REG(HDMI_VID_CTL, 0x0044),
        VC4_HD_REG(HDMI_FRAME_COUNT, 0x0060),

        VC4_HDMI_REG(HDMI_FIFO_CTL, 0x074),
        VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0b8),
        VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0bc),
        VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0c4),
        VC4_HDMI_REG(HDMI_CRP_CFG, 0x0c8),
        VC4_HDMI_REG(HDMI_CTS_0, 0x0cc),
        VC4_HDMI_REG(HDMI_CTS_1, 0x0d0),
        VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e0),
        VC4_HDMI_REG(HDMI_HORZA, 0x0e4),
        VC4_HDMI_REG(HDMI_HORZB, 0x0e8),
        VC4_HDMI_REG(HDMI_VERTA0, 0x0ec),
        VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
        VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
        VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
        VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x100),
        VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
        VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
        VC4_HDMI_REG(HDMI_FORMAT_DET_1, 0x134),
        VC4_HDMI_REG(HDMI_FORMAT_DET_2, 0x138),
        VC4_HDMI_REG(HDMI_FORMAT_DET_3, 0x13c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_4, 0x140),
        VC4_HDMI_REG(HDMI_FORMAT_DET_5, 0x144),
        VC4_HDMI_REG(HDMI_FORMAT_DET_6, 0x148),
        VC4_HDMI_REG(HDMI_FORMAT_DET_7, 0x14c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_8, 0x150),
        VC4_HDMI_REG(HDMI_FORMAT_DET_9, 0x154),
        VC4_HDMI_REG(HDMI_FORMAT_DET_10, 0x158),
        VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
        VC4_HDMI_REG(HDMI_GCP_CONFIG, 0x178),
        VC4_HDMI_REG(HDMI_GCP_WORD_1, 0x17c),
        VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
        VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1c4),

        VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
        VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0ec),
        VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),

        VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
        VC5_PHY_REG(HDMI_TX_PHY_POWERDOWN_CTL, 0x004),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_3, 0x014),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_0, 0x01c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_1, 0x020),
        VC5_PHY_REG(HDMI_TX_PHY_CLK_DIV, 0x028),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x034),
        VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x044),
        VC5_PHY_REG(HDMI_TX_PHY_CHANNEL_SWAP, 0x04c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 0x050),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 0x054),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 0x05c),

        VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
        VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
        VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),

        VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),

        VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
        VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
        VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
        VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
        VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),

        VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
        VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
        VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
        VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
        VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
        VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
        VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
        VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c),
};

static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = {
        VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
        VC4_HD_REG(HDMI_MAI_CTL, 0x0030),
        VC4_HD_REG(HDMI_MAI_THR, 0x0034),
        VC4_HD_REG(HDMI_MAI_FMT, 0x0038),
        VC4_HD_REG(HDMI_MAI_DATA, 0x003c),
        VC4_HD_REG(HDMI_MAI_SMP, 0x0040),
        VC4_HD_REG(HDMI_VID_CTL, 0x0048),
        VC4_HD_REG(HDMI_FRAME_COUNT, 0x0064),

        VC4_HDMI_REG(HDMI_FIFO_CTL, 0x074),
        VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0b8),
        VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0bc),
        VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0c4),
        VC4_HDMI_REG(HDMI_CRP_CFG, 0x0c8),
        VC4_HDMI_REG(HDMI_CTS_0, 0x0cc),
        VC4_HDMI_REG(HDMI_CTS_1, 0x0d0),
        VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e0),
        VC4_HDMI_REG(HDMI_HORZA, 0x0e4),
        VC4_HDMI_REG(HDMI_HORZB, 0x0e8),
        VC4_HDMI_REG(HDMI_VERTA0, 0x0ec),
        VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
        VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
        VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
        VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x100),
        VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
        VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
        VC4_HDMI_REG(HDMI_FORMAT_DET_1, 0x134),
        VC4_HDMI_REG(HDMI_FORMAT_DET_2, 0x138),
        VC4_HDMI_REG(HDMI_FORMAT_DET_3, 0x13c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_4, 0x140),
        VC4_HDMI_REG(HDMI_FORMAT_DET_5, 0x144),
        VC4_HDMI_REG(HDMI_FORMAT_DET_6, 0x148),
        VC4_HDMI_REG(HDMI_FORMAT_DET_7, 0x14c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_8, 0x150),
        VC4_HDMI_REG(HDMI_FORMAT_DET_9, 0x154),
        VC4_HDMI_REG(HDMI_FORMAT_DET_10, 0x158),
        VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
        VC4_HDMI_REG(HDMI_GCP_CONFIG, 0x178),
        VC4_HDMI_REG(HDMI_GCP_WORD_1, 0x17c),
        VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
        VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1c4),

        VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
        VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0ec),
        VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),

        VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
        VC5_PHY_REG(HDMI_TX_PHY_POWERDOWN_CTL, 0x004),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_3, 0x014),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_0, 0x01c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CTL_1, 0x020),
        VC5_PHY_REG(HDMI_TX_PHY_CLK_DIV, 0x028),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x034),
        VC5_PHY_REG(HDMI_TX_PHY_CHANNEL_SWAP, 0x04c),
        VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x044),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 0x050),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 0x054),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 0x05c),

        VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
        VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
        VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),

        VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),

        VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
        VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
        VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
        VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
        VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),

        VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
        VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
        VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
        VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
        VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
        VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
        VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
        VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c),
};

static const struct vc4_hdmi_register __maybe_unused vc6_hdmi_hdmi0_fields[] = {
        VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
        VC4_HD_REG(HDMI_MAI_CTL, 0x0010),
        VC4_HD_REG(HDMI_MAI_THR, 0x0014),
        VC4_HD_REG(HDMI_MAI_FMT, 0x0018),
        VC4_HD_REG(HDMI_MAI_DATA, 0x001c),
        VC4_HD_REG(HDMI_MAI_SMP, 0x0020),
        VC4_HD_REG(HDMI_VID_CTL, 0x0044),
        VC4_HD_REG(HDMI_FRAME_COUNT, 0x0060),

        VC4_HDMI_REG(HDMI_FIFO_CTL, 0x07c),
        VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0c0),
        VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0c4),
        VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0cc),
        VC4_HDMI_REG(HDMI_CRP_CFG, 0x0d0),
        VC4_HDMI_REG(HDMI_CTS_0, 0x0d4),
        VC4_HDMI_REG(HDMI_CTS_1, 0x0d8),
        VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e8),
        VC4_HDMI_REG(HDMI_HORZA, 0x0ec),
        VC4_HDMI_REG(HDMI_HORZB, 0x0f0),
        VC4_HDMI_REG(HDMI_VERTA0, 0x0f4),
        VC4_HDMI_REG(HDMI_VERTB0, 0x0f8),
        VC4_HDMI_REG(HDMI_VERTA1, 0x100),
        VC4_HDMI_REG(HDMI_VERTB1, 0x104),
        VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x114),
        VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x0a4),
        VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a8),
        VC4_HDMI_REG(HDMI_FORMAT_DET_1, 0x148),
        VC4_HDMI_REG(HDMI_FORMAT_DET_2, 0x14c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_3, 0x150),
        VC4_HDMI_REG(HDMI_FORMAT_DET_4, 0x158),
        VC4_HDMI_REG(HDMI_FORMAT_DET_5, 0x15c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_6, 0x160),
        VC4_HDMI_REG(HDMI_FORMAT_DET_7, 0x164),
        VC4_HDMI_REG(HDMI_FORMAT_DET_8, 0x168),
        VC4_HDMI_REG(HDMI_FORMAT_DET_9, 0x16c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_10, 0x170),
        VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x18c),
        VC4_HDMI_REG(HDMI_GCP_CONFIG, 0x194),
        VC4_HDMI_REG(HDMI_GCP_WORD_1, 0x198),
        VC4_HDMI_REG(HDMI_HOTPLUG, 0x1c8),
        VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1e4),

        VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
        VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0f0),
        VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f4),

        VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
        VC5_PHY_REG(HDMI_TX_PHY_POWERUP_CTL, 0x004),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_CK, 0x014),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_REFCLK, 0x01c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_POST_KDIV, 0x028),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_VCOCLK_DIV, 0x02c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x044),
        VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x054),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_0, 0x060),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_1, 0x064),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_2, 0x068),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_3, 0x06c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_4, 0x070),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_5, 0x074),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_6, 0x078),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_7, 0x07c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_8, 0x080),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_RESET_CTL, 0x190),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_POWERUP_CTL, 0x194),

        VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
        VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
        VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),

        VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),

        VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
        VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
        VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
        VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
        VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),

        VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
        VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
        VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
        VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
        VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
        VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
        VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
        VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c),
};

static const struct vc4_hdmi_register __maybe_unused vc6_hdmi_hdmi1_fields[] = {
        VC4_HD_REG(HDMI_DVP_CTL, 0x0000),
        VC4_HD_REG(HDMI_MAI_CTL, 0x0030),
        VC4_HD_REG(HDMI_MAI_THR, 0x0034),
        VC4_HD_REG(HDMI_MAI_FMT, 0x0038),
        VC4_HD_REG(HDMI_MAI_DATA, 0x003c),
        VC4_HD_REG(HDMI_MAI_SMP, 0x0040),
        VC4_HD_REG(HDMI_VID_CTL, 0x0048),
        VC4_HD_REG(HDMI_FRAME_COUNT, 0x0064),

        VC4_HDMI_REG(HDMI_FIFO_CTL, 0x07c),
        VC4_HDMI_REG(HDMI_AUDIO_PACKET_CONFIG, 0x0c0),
        VC4_HDMI_REG(HDMI_RAM_PACKET_CONFIG, 0x0c4),
        VC4_HDMI_REG(HDMI_RAM_PACKET_STATUS, 0x0cc),
        VC4_HDMI_REG(HDMI_CRP_CFG, 0x0d0),
        VC4_HDMI_REG(HDMI_CTS_0, 0x0d4),
        VC4_HDMI_REG(HDMI_CTS_1, 0x0d8),
        VC4_HDMI_REG(HDMI_SCHEDULER_CONTROL, 0x0e8),
        VC4_HDMI_REG(HDMI_HORZA, 0x0ec),
        VC4_HDMI_REG(HDMI_HORZB, 0x0f0),
        VC4_HDMI_REG(HDMI_VERTA0, 0x0f4),
        VC4_HDMI_REG(HDMI_VERTB0, 0x0f8),
        VC4_HDMI_REG(HDMI_VERTA1, 0x100),
        VC4_HDMI_REG(HDMI_VERTB1, 0x104),
        VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x114),
        VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x0a4),
        VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a8),
        VC4_HDMI_REG(HDMI_FORMAT_DET_1, 0x148),
        VC4_HDMI_REG(HDMI_FORMAT_DET_2, 0x14c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_3, 0x150),
        VC4_HDMI_REG(HDMI_FORMAT_DET_4, 0x158),
        VC4_HDMI_REG(HDMI_FORMAT_DET_5, 0x15c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_6, 0x160),
        VC4_HDMI_REG(HDMI_FORMAT_DET_7, 0x164),
        VC4_HDMI_REG(HDMI_FORMAT_DET_8, 0x168),
        VC4_HDMI_REG(HDMI_FORMAT_DET_9, 0x16c),
        VC4_HDMI_REG(HDMI_FORMAT_DET_10, 0x170),
        VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x18c),
        VC4_HDMI_REG(HDMI_GCP_CONFIG, 0x194),
        VC4_HDMI_REG(HDMI_GCP_WORD_1, 0x198),
        VC4_HDMI_REG(HDMI_HOTPLUG, 0x1c8),
        VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1e4),

        VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
        VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0f0),
        VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f4),

        VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
        VC5_PHY_REG(HDMI_TX_PHY_POWERUP_CTL, 0x004),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_0, 0x008),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_1, 0x00c),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_2, 0x010),
        VC5_PHY_REG(HDMI_TX_PHY_CTL_CK, 0x014),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_REFCLK, 0x01c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_POST_KDIV, 0x028),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_VCOCLK_DIV, 0x02c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_CFG, 0x044),
        VC5_PHY_REG(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, 0x054),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_0, 0x060),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_1, 0x064),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_2, 0x068),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_3, 0x06c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_4, 0x070),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_5, 0x074),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_6, 0x078),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_7, 0x07c),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_MISC_8, 0x080),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_RESET_CTL, 0x190),
        VC5_PHY_REG(HDMI_TX_PHY_PLL_POWERUP_CTL, 0x194),

        VC5_RM_REG(HDMI_RM_CONTROL, 0x000),
        VC5_RM_REG(HDMI_RM_OFFSET, 0x018),
        VC5_RM_REG(HDMI_RM_FORMAT, 0x01c),

        VC5_RAM_REG(HDMI_RAM_PACKET_START, 0x000),

        VC5_CEC_REG(HDMI_CEC_CNTRL_1, 0x010),
        VC5_CEC_REG(HDMI_CEC_CNTRL_2, 0x014),
        VC5_CEC_REG(HDMI_CEC_CNTRL_3, 0x018),
        VC5_CEC_REG(HDMI_CEC_CNTRL_4, 0x01c),
        VC5_CEC_REG(HDMI_CEC_CNTRL_5, 0x020),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_1, 0x028),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_2, 0x02c),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_3, 0x030),
        VC5_CEC_REG(HDMI_CEC_TX_DATA_4, 0x034),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_1, 0x038),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_2, 0x03c),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_3, 0x040),
        VC5_CEC_REG(HDMI_CEC_RX_DATA_4, 0x044),

        VC5_CSC_REG(HDMI_CSC_CTL, 0x000),
        VC5_CSC_REG(HDMI_CSC_12_11, 0x004),
        VC5_CSC_REG(HDMI_CSC_14_13, 0x008),
        VC5_CSC_REG(HDMI_CSC_22_21, 0x00c),
        VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
        VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
        VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
        VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c),
};

static inline
void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
                                        enum vc4_hdmi_regs reg)
{
        switch (reg) {
        case VC4_HD:
                return hdmi->hd_regs;

        case VC4_HDMI:
                return hdmi->hdmicore_regs;

        case VC5_CSC:
                return hdmi->csc_regs;

        case VC5_CEC:
                return hdmi->cec_regs;

        case VC5_DVP:
                return hdmi->dvp_regs;

        case VC5_PHY:
                return hdmi->phy_regs;

        case VC5_RAM:
                return hdmi->ram_regs;

        case VC5_RM:
                return hdmi->rm_regs;

        default:
                return NULL;
        }

        return NULL;
}

static inline u32 vc4_hdmi_read(struct vc4_hdmi *hdmi,
                                enum vc4_hdmi_field reg)
{
        const struct vc4_hdmi_register *field;
        const struct vc4_hdmi_variant *variant = hdmi->variant;
        void __iomem *base;

        WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev));

        kunit_fail_current_test("Accessing an HDMI register in a unit test!\n");

        if (reg >= variant->num_registers) {
                dev_warn(&hdmi->pdev->dev,
                         "Invalid register ID %u\n", reg);
                return 0;
        }

        field = &variant->registers[reg];
        base = __vc4_hdmi_get_field_base(hdmi, field->reg);
        if (!base) {
                dev_warn(&hdmi->pdev->dev,
                         "Unknown register ID %u\n", reg);
                return 0;
        }

        return readl(base + field->offset);
}
#define HDMI_READ(reg)          vc4_hdmi_read(vc4_hdmi, reg)

static inline void vc4_hdmi_write(struct vc4_hdmi *hdmi,
                                  enum vc4_hdmi_field reg,
                                  u32 value)
{
        const struct vc4_hdmi_register *field;
        const struct vc4_hdmi_variant *variant = hdmi->variant;
        void __iomem *base;

        lockdep_assert_held(&hdmi->hw_lock);

        WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev));

        kunit_fail_current_test("Accessing an HDMI register in a unit test!\n");

        if (reg >= variant->num_registers) {
                dev_warn(&hdmi->pdev->dev,
                         "Invalid register ID %u\n", reg);
                return;
        }

        field = &variant->registers[reg];
        base = __vc4_hdmi_get_field_base(hdmi, field->reg);
        if (!base) {
                dev_warn(&hdmi->pdev->dev,
                         "Unknown register ID %u\n", reg);
                return;
        }

        writel(value, base + field->offset);
}
#define HDMI_WRITE(reg, val)    vc4_hdmi_write(vc4_hdmi, reg, val)

#endif /* _VC4_HDMI_REGS_H_ */