Commit 83239891 authored by Maxime Ripard's avatar Maxime Ripard

drm/vc4: hdmi: Support the BCM2711 HDMI controllers

Now that the driver is ready for it, let's bring in the HDMI controllers
variants for the BCM2711.
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Tested-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Tested-by: default avatarHoegeun Kwon <hoegeun.kwon@samsung.com>
Tested-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Reviewed-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://patchwork.freedesktop.org/patch/msgid/b540c7a9ebb7ad51da39271a8388b69c7e27e582.1599120059.git-series.maxime@cerno.tech
parent 37387429
This diff is collapsed.
...@@ -26,6 +26,13 @@ struct drm_display_mode; ...@@ -26,6 +26,13 @@ struct drm_display_mode;
struct vc4_hdmi; struct vc4_hdmi;
struct vc4_hdmi_register; struct vc4_hdmi_register;
enum vc4_hdmi_phy_channel {
PHY_LANE_0 = 0,
PHY_LANE_1,
PHY_LANE_2,
PHY_LANE_CK,
};
struct vc4_hdmi_variant { struct vc4_hdmi_variant {
/* Encoder Type for that controller */ /* Encoder Type for that controller */
enum vc4_encoder_type encoder_type; enum vc4_encoder_type encoder_type;
...@@ -48,6 +55,13 @@ struct vc4_hdmi_variant { ...@@ -48,6 +55,13 @@ struct vc4_hdmi_variant {
/* Number of registers on that variant */ /* Number of registers on that variant */
unsigned int num_registers; unsigned int num_registers;
/* BCM2711 Only.
* The variants don't map the lane in the same order in the
* PHY, so this is an array mapping the HDMI channel (index)
* to the PHY lane (value).
*/
enum vc4_hdmi_phy_channel phy_lane_mapping[4];
/* Callback to get the resources (memory region, interrupts, /* Callback to get the resources (memory region, interrupts,
* clocks, etc) for that variant. * clocks, etc) for that variant.
*/ */
...@@ -108,6 +122,20 @@ struct vc4_hdmi { ...@@ -108,6 +122,20 @@ struct vc4_hdmi {
struct i2c_adapter *ddc; struct i2c_adapter *ddc;
void __iomem *hdmicore_regs; void __iomem *hdmicore_regs;
void __iomem *hd_regs; void __iomem *hd_regs;
/* VC5 Only */
void __iomem *cec_regs;
/* VC5 Only */
void __iomem *csc_regs;
/* VC5 Only */
void __iomem *dvp_regs;
/* VC5 Only */
void __iomem *phy_regs;
/* VC5 Only */
void __iomem *ram_regs;
/* VC5 Only */
void __iomem *rm_regs;
int hpd_gpio; int hpd_gpio;
bool hpd_active_low; bool hpd_active_low;
...@@ -121,6 +149,8 @@ struct vc4_hdmi { ...@@ -121,6 +149,8 @@ struct vc4_hdmi {
struct clk *audio_clock; struct clk *audio_clock;
struct clk *pixel_bvb_clock; struct clk *pixel_bvb_clock;
struct reset_control *reset;
struct debugfs_regset32 hdmi_regset; struct debugfs_regset32 hdmi_regset;
struct debugfs_regset32 hd_regset; struct debugfs_regset32 hd_regset;
}; };
...@@ -145,4 +175,10 @@ void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi); ...@@ -145,4 +175,10 @@ void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi); void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi); void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
struct drm_display_mode *mode);
void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
#endif /* _VC4_HDMI_H_ */ #endif /* _VC4_HDMI_H_ */
This diff is collapsed.
...@@ -9,6 +9,12 @@ enum vc4_hdmi_regs { ...@@ -9,6 +9,12 @@ enum vc4_hdmi_regs {
VC4_INVALID = 0, VC4_INVALID = 0,
VC4_HDMI, VC4_HDMI,
VC4_HD, VC4_HD,
VC5_CEC,
VC5_CSC,
VC5_DVP,
VC5_PHY,
VC5_RAM,
VC5_RM,
}; };
enum vc4_hdmi_field { enum vc4_hdmi_field {
...@@ -36,6 +42,7 @@ enum vc4_hdmi_field { ...@@ -36,6 +42,7 @@ enum vc4_hdmi_field {
HDMI_CEC_TX_DATA_2, HDMI_CEC_TX_DATA_2,
HDMI_CEC_TX_DATA_3, HDMI_CEC_TX_DATA_3,
HDMI_CEC_TX_DATA_4, HDMI_CEC_TX_DATA_4,
HDMI_CLOCK_STOP,
HDMI_CORE_REV, HDMI_CORE_REV,
HDMI_CRP_CFG, HDMI_CRP_CFG,
HDMI_CSC_12_11, HDMI_CSC_12_11,
...@@ -52,6 +59,7 @@ enum vc4_hdmi_field { ...@@ -52,6 +59,7 @@ enum vc4_hdmi_field {
*/ */
HDMI_CTS_0, HDMI_CTS_0,
HDMI_CTS_1, HDMI_CTS_1,
HDMI_DVP_CTL,
HDMI_FIFO_CTL, HDMI_FIFO_CTL,
HDMI_FRAME_COUNT, HDMI_FRAME_COUNT,
HDMI_HORZA, HDMI_HORZA,
...@@ -84,10 +92,27 @@ enum vc4_hdmi_field { ...@@ -84,10 +92,27 @@ enum vc4_hdmi_field {
HDMI_RAM_PACKET_CONFIG, HDMI_RAM_PACKET_CONFIG,
HDMI_RAM_PACKET_START, HDMI_RAM_PACKET_START,
HDMI_RAM_PACKET_STATUS, HDMI_RAM_PACKET_STATUS,
HDMI_RM_CONTROL,
HDMI_RM_FORMAT,
HDMI_RM_OFFSET,
HDMI_SCHEDULER_CONTROL, HDMI_SCHEDULER_CONTROL,
HDMI_SW_RESET_CONTROL, HDMI_SW_RESET_CONTROL,
HDMI_TX_PHY_CHANNEL_SWAP,
HDMI_TX_PHY_CLK_DIV,
HDMI_TX_PHY_CTL_0, HDMI_TX_PHY_CTL_0,
HDMI_TX_PHY_CTL_1,
HDMI_TX_PHY_CTL_2,
HDMI_TX_PHY_CTL_3,
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_CTL_0,
HDMI_TX_PHY_PLL_CTL_1,
HDMI_TX_PHY_POWERDOWN_CTL,
HDMI_TX_PHY_RESET_CTL, HDMI_TX_PHY_RESET_CTL,
HDMI_TX_PHY_TMDS_CLK_WORD_SEL,
HDMI_VEC_INTERFACE_XBAR,
HDMI_VERTA0, HDMI_VERTA0,
HDMI_VERTA1, HDMI_VERTA1,
HDMI_VERTB0, HDMI_VERTB0,
...@@ -110,6 +135,12 @@ struct vc4_hdmi_register { ...@@ -110,6 +135,12 @@ struct vc4_hdmi_register {
#define VC4_HD_REG(reg, offset) _VC4_REG(VC4_HD, reg, 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 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 vc4_hdmi_fields[] = { static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
VC4_HD_REG(HDMI_M_CTL, 0x000c), VC4_HD_REG(HDMI_M_CTL, 0x000c),
...@@ -172,6 +203,158 @@ static const struct vc4_hdmi_register vc4_hdmi_fields[] = { ...@@ -172,6 +203,158 @@ static const struct vc4_hdmi_register vc4_hdmi_fields[] = {
VC4_HDMI_REG(HDMI_RAM_PACKET_START, 0x0400), VC4_HDMI_REG(HDMI_RAM_PACKET_START, 0x0400),
}; };
static const struct vc4_hdmi_register 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_MAI_CHANNEL_MAP, 0x09c),
VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
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),
};
static const struct vc4_hdmi_register 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_MAI_CHANNEL_MAP, 0x09c),
VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
VC4_HDMI_REG(HDMI_HOTPLUG, 0x1a8),
VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
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),
};
static inline static inline
void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi, void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
enum vc4_hdmi_regs reg) enum vc4_hdmi_regs reg)
...@@ -183,6 +366,24 @@ void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi, ...@@ -183,6 +366,24 @@ void __iomem *__vc4_hdmi_get_field_base(struct vc4_hdmi *hdmi,
case VC4_HDMI: case VC4_HDMI:
return hdmi->hdmicore_regs; 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: default:
return NULL; return NULL;
} }
......
...@@ -744,6 +744,8 @@ ...@@ -744,6 +744,8 @@
# define VC4_HD_CSC_CTL_RGB2YCC BIT(1) # define VC4_HD_CSC_CTL_RGB2YCC BIT(1)
# define VC4_HD_CSC_CTL_ENABLE BIT(0) # define VC4_HD_CSC_CTL_ENABLE BIT(0)
# define VC4_DVP_HT_CLOCK_STOP_PIXEL BIT(1)
/* HVS display list information. */ /* HVS display list information. */
#define HVS_BOOTLOADER_DLIST_END 32 #define HVS_BOOTLOADER_DLIST_END 32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment