forked from Minki/linux
drm/vc4: add HDMI CEC support
This patch adds support to VC4 for CEC. It is under a separate Kconfig option to keep everyone using VC4 from needing to pull in the CEC core. Thanks to Eric Anholt for providing me with the CEC register information. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Eric Anholt <eric@anholt.net> Link: https://patchwork.freedesktop.org/patch/msgid/20170716104804.48308-4-hverkuil@xs4all.nl
This commit is contained in:
parent
10ee275cb1
commit
15b4511a4a
@ -19,3 +19,11 @@ config DRM_VC4
|
||||
This driver requires that "avoid_warnings=2" be present in
|
||||
the config.txt for the firmware, to keep it from smashing
|
||||
our display setup.
|
||||
|
||||
config DRM_VC4_HDMI_CEC
|
||||
bool "Broadcom VC4 HDMI CEC Support"
|
||||
depends on DRM_VC4
|
||||
select CEC_CORE
|
||||
help
|
||||
Choose this option if you have a Broadcom VC4 GPU
|
||||
and want to use CEC.
|
||||
|
@ -57,9 +57,14 @@
|
||||
#include <sound/pcm_drm_eld.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include "media/cec.h"
|
||||
#include "vc4_drv.h"
|
||||
#include "vc4_regs.h"
|
||||
|
||||
#define HSM_CLOCK_FREQ 163682864
|
||||
#define CEC_CLOCK_FREQ 40000
|
||||
#define CEC_CLOCK_DIV (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
|
||||
|
||||
/* HDMI audio information */
|
||||
struct vc4_hdmi_audio {
|
||||
struct snd_soc_card card;
|
||||
@ -85,6 +90,11 @@ struct vc4_hdmi {
|
||||
int hpd_gpio;
|
||||
bool hpd_active_low;
|
||||
|
||||
struct cec_adapter *cec_adap;
|
||||
struct cec_msg cec_rx_msg;
|
||||
bool cec_tx_ok;
|
||||
bool cec_irq_was_rx;
|
||||
|
||||
struct clk *pixel_clock;
|
||||
struct clk *hsm_clock;
|
||||
};
|
||||
@ -149,6 +159,23 @@ static const struct {
|
||||
HDMI_REG(VC4_HDMI_VERTB1),
|
||||
HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL),
|
||||
HDMI_REG(VC4_HDMI_TX_PHY_CTL0),
|
||||
|
||||
HDMI_REG(VC4_HDMI_CEC_CNTRL_1),
|
||||
HDMI_REG(VC4_HDMI_CEC_CNTRL_2),
|
||||
HDMI_REG(VC4_HDMI_CEC_CNTRL_3),
|
||||
HDMI_REG(VC4_HDMI_CEC_CNTRL_4),
|
||||
HDMI_REG(VC4_HDMI_CEC_CNTRL_5),
|
||||
HDMI_REG(VC4_HDMI_CPU_STATUS),
|
||||
HDMI_REG(VC4_HDMI_CPU_MASK_STATUS),
|
||||
|
||||
HDMI_REG(VC4_HDMI_CEC_RX_DATA_1),
|
||||
HDMI_REG(VC4_HDMI_CEC_RX_DATA_2),
|
||||
HDMI_REG(VC4_HDMI_CEC_RX_DATA_3),
|
||||
HDMI_REG(VC4_HDMI_CEC_RX_DATA_4),
|
||||
HDMI_REG(VC4_HDMI_CEC_TX_DATA_1),
|
||||
HDMI_REG(VC4_HDMI_CEC_TX_DATA_2),
|
||||
HDMI_REG(VC4_HDMI_CEC_TX_DATA_3),
|
||||
HDMI_REG(VC4_HDMI_CEC_TX_DATA_4),
|
||||
};
|
||||
|
||||
static const struct {
|
||||
@ -216,8 +243,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
|
||||
if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
|
||||
vc4->hdmi->hpd_active_low)
|
||||
return connector_status_connected;
|
||||
else
|
||||
return connector_status_disconnected;
|
||||
cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
if (drm_probe_ddc(vc4->hdmi->ddc))
|
||||
@ -225,8 +252,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
|
||||
|
||||
if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
|
||||
return connector_status_connected;
|
||||
else
|
||||
return connector_status_disconnected;
|
||||
cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
|
||||
@ -247,6 +274,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
|
||||
struct edid *edid;
|
||||
|
||||
edid = drm_get_edid(connector, vc4->hdmi->ddc);
|
||||
cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid);
|
||||
if (!edid)
|
||||
return -ENODEV;
|
||||
|
||||
@ -1121,6 +1149,159 @@ static void vc4_hdmi_audio_cleanup(struct vc4_hdmi *hdmi)
|
||||
snd_soc_unregister_codec(dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_VC4_HDMI_CEC
|
||||
static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
|
||||
{
|
||||
struct vc4_dev *vc4 = priv;
|
||||
struct vc4_hdmi *hdmi = vc4->hdmi;
|
||||
|
||||
if (hdmi->cec_irq_was_rx) {
|
||||
if (hdmi->cec_rx_msg.len)
|
||||
cec_received_msg(hdmi->cec_adap, &hdmi->cec_rx_msg);
|
||||
} else if (hdmi->cec_tx_ok) {
|
||||
cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_OK,
|
||||
0, 0, 0, 0);
|
||||
} else {
|
||||
/*
|
||||
* This CEC implementation makes 1 retry, so if we
|
||||
* get a NACK, then that means it made 2 attempts.
|
||||
*/
|
||||
cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_NACK,
|
||||
0, 2, 0, 0);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void vc4_cec_read_msg(struct vc4_dev *vc4, u32 cntrl1)
|
||||
{
|
||||
struct cec_msg *msg = &vc4->hdmi->cec_rx_msg;
|
||||
unsigned int i;
|
||||
|
||||
msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
|
||||
VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
|
||||
for (i = 0; i < msg->len; i += 4) {
|
||||
u32 val = HDMI_READ(VC4_HDMI_CEC_RX_DATA_1 + i);
|
||||
|
||||
msg->msg[i] = val & 0xff;
|
||||
msg->msg[i + 1] = (val >> 8) & 0xff;
|
||||
msg->msg[i + 2] = (val >> 16) & 0xff;
|
||||
msg->msg[i + 3] = (val >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
|
||||
{
|
||||
struct vc4_dev *vc4 = priv;
|
||||
struct vc4_hdmi *hdmi = vc4->hdmi;
|
||||
u32 stat = HDMI_READ(VC4_HDMI_CPU_STATUS);
|
||||
u32 cntrl1, cntrl5;
|
||||
|
||||
if (!(stat & VC4_HDMI_CPU_CEC))
|
||||
return IRQ_NONE;
|
||||
hdmi->cec_rx_msg.len = 0;
|
||||
cntrl1 = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
|
||||
cntrl5 = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
|
||||
hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
|
||||
if (hdmi->cec_irq_was_rx) {
|
||||
vc4_cec_read_msg(vc4, cntrl1);
|
||||
cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
|
||||
cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
|
||||
} else {
|
||||
hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
|
||||
cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
|
||||
}
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
|
||||
HDMI_WRITE(VC4_HDMI_CPU_CLEAR, VC4_HDMI_CPU_CEC);
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
|
||||
{
|
||||
struct vc4_dev *vc4 = cec_get_drvdata(adap);
|
||||
/* clock period in microseconds */
|
||||
const u32 usecs = 1000000 / CEC_CLOCK_FREQ;
|
||||
u32 val = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
|
||||
|
||||
val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET |
|
||||
VC4_HDMI_CEC_CNT_TO_4700_US_MASK |
|
||||
VC4_HDMI_CEC_CNT_TO_4500_US_MASK);
|
||||
val |= ((4700 / usecs) << VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT) |
|
||||
((4500 / usecs) << VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT);
|
||||
|
||||
if (enable) {
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
|
||||
VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val);
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_2,
|
||||
((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) |
|
||||
((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) |
|
||||
((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) |
|
||||
((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) |
|
||||
((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT));
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_3,
|
||||
((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) |
|
||||
((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) |
|
||||
((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) |
|
||||
((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT));
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_4,
|
||||
((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) |
|
||||
((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) |
|
||||
((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
|
||||
((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
|
||||
|
||||
HDMI_WRITE(VC4_HDMI_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
|
||||
} else {
|
||||
HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
|
||||
VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
|
||||
{
|
||||
struct vc4_dev *vc4 = cec_get_drvdata(adap);
|
||||
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1,
|
||||
(HDMI_READ(VC4_HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
|
||||
(log_addr & 0xf) << VC4_HDMI_CEC_ADDR_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vc4_hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
|
||||
u32 signal_free_time, struct cec_msg *msg)
|
||||
{
|
||||
struct vc4_dev *vc4 = cec_get_drvdata(adap);
|
||||
u32 val;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < msg->len; i += 4)
|
||||
HDMI_WRITE(VC4_HDMI_CEC_TX_DATA_1 + i,
|
||||
(msg->msg[i]) |
|
||||
(msg->msg[i + 1] << 8) |
|
||||
(msg->msg[i + 2] << 16) |
|
||||
(msg->msg[i + 3] << 24));
|
||||
|
||||
val = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
|
||||
val &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
|
||||
val &= ~VC4_HDMI_CEC_MESSAGE_LENGTH_MASK;
|
||||
val |= (msg->len - 1) << VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT;
|
||||
val |= VC4_HDMI_CEC_START_XMIT_BEGIN;
|
||||
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
|
||||
.adap_enable = vc4_hdmi_cec_adap_enable,
|
||||
.adap_log_addr = vc4_hdmi_cec_adap_log_addr,
|
||||
.adap_transmit = vc4_hdmi_cec_adap_transmit,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
@ -1180,7 +1361,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
|
||||
* needs to be a bit higher than the pixel clock rate
|
||||
* (generally 148.5Mhz).
|
||||
*/
|
||||
ret = clk_set_rate(hdmi->hsm_clock, 163682864);
|
||||
ret = clk_set_rate(hdmi->hsm_clock, HSM_CLOCK_FREQ);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
|
||||
goto err_put_i2c;
|
||||
@ -1231,6 +1412,37 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
|
||||
ret = PTR_ERR(hdmi->connector);
|
||||
goto err_destroy_encoder;
|
||||
}
|
||||
#ifdef CONFIG_DRM_VC4_HDMI_CEC
|
||||
hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
|
||||
vc4, "vc4",
|
||||
CEC_CAP_TRANSMIT |
|
||||
CEC_CAP_LOG_ADDRS |
|
||||
CEC_CAP_PASSTHROUGH |
|
||||
CEC_CAP_RC, 1);
|
||||
ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
|
||||
if (ret < 0)
|
||||
goto err_destroy_conn;
|
||||
HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
|
||||
value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
|
||||
value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
|
||||
/*
|
||||
* Set the logical address to Unregistered and set the clock
|
||||
* divider: the hsm_clock rate and this divider setting will
|
||||
* give a 40 kHz CEC clock.
|
||||
*/
|
||||
value |= VC4_HDMI_CEC_ADDR_MASK |
|
||||
(4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
|
||||
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, value);
|
||||
ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
|
||||
vc4_cec_irq_handler,
|
||||
vc4_cec_irq_handler_thread, 0,
|
||||
"vc4 hdmi cec", vc4);
|
||||
if (ret)
|
||||
goto err_delete_cec_adap;
|
||||
ret = cec_register_adapter(hdmi->cec_adap, dev);
|
||||
if (ret < 0)
|
||||
goto err_delete_cec_adap;
|
||||
#endif
|
||||
|
||||
ret = vc4_hdmi_audio_init(hdmi);
|
||||
if (ret)
|
||||
@ -1238,6 +1450,12 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_DRM_VC4_HDMI_CEC
|
||||
err_delete_cec_adap:
|
||||
cec_delete_adapter(hdmi->cec_adap);
|
||||
err_destroy_conn:
|
||||
vc4_hdmi_connector_destroy(hdmi->connector);
|
||||
#endif
|
||||
err_destroy_encoder:
|
||||
vc4_hdmi_encoder_destroy(hdmi->encoder);
|
||||
err_unprepare_hsm:
|
||||
@ -1257,7 +1475,7 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
|
||||
struct vc4_hdmi *hdmi = vc4->hdmi;
|
||||
|
||||
vc4_hdmi_audio_cleanup(hdmi);
|
||||
|
||||
cec_unregister_adapter(hdmi->cec_adap);
|
||||
vc4_hdmi_connector_destroy(hdmi->connector);
|
||||
vc4_hdmi_encoder_destroy(hdmi->encoder);
|
||||
|
||||
|
@ -561,16 +561,129 @@
|
||||
# define VC4_HDMI_VERTB_VBP_MASK VC4_MASK(8, 0)
|
||||
# define VC4_HDMI_VERTB_VBP_SHIFT 0
|
||||
|
||||
#define VC4_HDMI_CEC_CNTRL_1 0x0e8
|
||||
/* Set when the transmission has ended. */
|
||||
# define VC4_HDMI_CEC_TX_EOM BIT(31)
|
||||
/* If set, transmission was acked on the 1st or 2nd attempt (only one
|
||||
* retry is attempted). If in continuous mode, this means TX needs to
|
||||
* be filled if !TX_EOM.
|
||||
*/
|
||||
# define VC4_HDMI_CEC_TX_STATUS_GOOD BIT(30)
|
||||
# define VC4_HDMI_CEC_RX_EOM BIT(29)
|
||||
# define VC4_HDMI_CEC_RX_STATUS_GOOD BIT(28)
|
||||
/* Number of bytes received for the message. */
|
||||
# define VC4_HDMI_CEC_REC_WRD_CNT_MASK VC4_MASK(27, 24)
|
||||
# define VC4_HDMI_CEC_REC_WRD_CNT_SHIFT 24
|
||||
/* Sets continuous receive mode. Generates interrupt after each 8
|
||||
* bytes to signal that RX_DATA should be consumed, and at RX_EOM.
|
||||
*
|
||||
* If disabled, maximum 16 bytes will be received (including header),
|
||||
* and interrupt at RX_EOM. Later bytes will be acked but not put
|
||||
* into the RX_DATA.
|
||||
*/
|
||||
# define VC4_HDMI_CEC_RX_CONTINUE BIT(23)
|
||||
# define VC4_HDMI_CEC_TX_CONTINUE BIT(22)
|
||||
/* Set this after a CEC interrupt. */
|
||||
# define VC4_HDMI_CEC_CLEAR_RECEIVE_OFF BIT(21)
|
||||
/* Starts a TX. Will wait for appropriate idel time before CEC
|
||||
* activity. Must be cleared in between transmits.
|
||||
*/
|
||||
# define VC4_HDMI_CEC_START_XMIT_BEGIN BIT(20)
|
||||
# define VC4_HDMI_CEC_MESSAGE_LENGTH_MASK VC4_MASK(19, 16)
|
||||
# define VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT 16
|
||||
/* Device's CEC address */
|
||||
# define VC4_HDMI_CEC_ADDR_MASK VC4_MASK(15, 12)
|
||||
# define VC4_HDMI_CEC_ADDR_SHIFT 12
|
||||
/* Divides off of HSM clock to generate CEC bit clock. */
|
||||
/* With the current defaults the CEC bit clock is 40 kHz = 25 usec */
|
||||
# define VC4_HDMI_CEC_DIV_CLK_CNT_MASK VC4_MASK(11, 0)
|
||||
# define VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT 0
|
||||
|
||||
/* Set these fields to how many bit clock cycles get to that many
|
||||
* microseconds.
|
||||
*/
|
||||
#define VC4_HDMI_CEC_CNTRL_2 0x0ec
|
||||
# define VC4_HDMI_CEC_CNT_TO_1500_US_MASK VC4_MASK(30, 24)
|
||||
# define VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT 24
|
||||
# define VC4_HDMI_CEC_CNT_TO_1300_US_MASK VC4_MASK(23, 17)
|
||||
# define VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT 17
|
||||
# define VC4_HDMI_CEC_CNT_TO_800_US_MASK VC4_MASK(16, 11)
|
||||
# define VC4_HDMI_CEC_CNT_TO_800_US_SHIFT 11
|
||||
# define VC4_HDMI_CEC_CNT_TO_600_US_MASK VC4_MASK(10, 5)
|
||||
# define VC4_HDMI_CEC_CNT_TO_600_US_SHIFT 5
|
||||
# define VC4_HDMI_CEC_CNT_TO_400_US_MASK VC4_MASK(4, 0)
|
||||
# define VC4_HDMI_CEC_CNT_TO_400_US_SHIFT 0
|
||||
|
||||
#define VC4_HDMI_CEC_CNTRL_3 0x0f0
|
||||
# define VC4_HDMI_CEC_CNT_TO_2750_US_MASK VC4_MASK(31, 24)
|
||||
# define VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT 24
|
||||
# define VC4_HDMI_CEC_CNT_TO_2400_US_MASK VC4_MASK(23, 16)
|
||||
# define VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT 16
|
||||
# define VC4_HDMI_CEC_CNT_TO_2050_US_MASK VC4_MASK(15, 8)
|
||||
# define VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT 8
|
||||
# define VC4_HDMI_CEC_CNT_TO_1700_US_MASK VC4_MASK(7, 0)
|
||||
# define VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT 0
|
||||
|
||||
#define VC4_HDMI_CEC_CNTRL_4 0x0f4
|
||||
# define VC4_HDMI_CEC_CNT_TO_4300_US_MASK VC4_MASK(31, 24)
|
||||
# define VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT 24
|
||||
# define VC4_HDMI_CEC_CNT_TO_3900_US_MASK VC4_MASK(23, 16)
|
||||
# define VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT 16
|
||||
# define VC4_HDMI_CEC_CNT_TO_3600_US_MASK VC4_MASK(15, 8)
|
||||
# define VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT 8
|
||||
# define VC4_HDMI_CEC_CNT_TO_3500_US_MASK VC4_MASK(7, 0)
|
||||
# define VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT 0
|
||||
|
||||
#define VC4_HDMI_CEC_CNTRL_5 0x0f8
|
||||
# define VC4_HDMI_CEC_TX_SW_RESET BIT(27)
|
||||
# define VC4_HDMI_CEC_RX_SW_RESET BIT(26)
|
||||
# define VC4_HDMI_CEC_PAD_SW_RESET BIT(25)
|
||||
# define VC4_HDMI_CEC_MUX_TP_OUT_CEC BIT(24)
|
||||
# define VC4_HDMI_CEC_RX_CEC_INT BIT(23)
|
||||
# define VC4_HDMI_CEC_CLK_PRELOAD_MASK VC4_MASK(22, 16)
|
||||
# define VC4_HDMI_CEC_CLK_PRELOAD_SHIFT 16
|
||||
# define VC4_HDMI_CEC_CNT_TO_4700_US_MASK VC4_MASK(15, 8)
|
||||
# define VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT 8
|
||||
# define VC4_HDMI_CEC_CNT_TO_4500_US_MASK VC4_MASK(7, 0)
|
||||
# define VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT 0
|
||||
|
||||
/* Transmit data, first byte is low byte of the 32-bit reg. MSB of
|
||||
* each byte transmitted first.
|
||||
*/
|
||||
#define VC4_HDMI_CEC_TX_DATA_1 0x0fc
|
||||
#define VC4_HDMI_CEC_TX_DATA_2 0x100
|
||||
#define VC4_HDMI_CEC_TX_DATA_3 0x104
|
||||
#define VC4_HDMI_CEC_TX_DATA_4 0x108
|
||||
#define VC4_HDMI_CEC_RX_DATA_1 0x10c
|
||||
#define VC4_HDMI_CEC_RX_DATA_2 0x110
|
||||
#define VC4_HDMI_CEC_RX_DATA_3 0x114
|
||||
#define VC4_HDMI_CEC_RX_DATA_4 0x118
|
||||
|
||||
#define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0
|
||||
|
||||
#define VC4_HDMI_TX_PHY_CTL0 0x2c4
|
||||
# define VC4_HDMI_TX_PHY_RNG_PWRDN BIT(25)
|
||||
|
||||
/* Interrupt status bits */
|
||||
#define VC4_HDMI_CPU_STATUS 0x340
|
||||
#define VC4_HDMI_CPU_SET 0x344
|
||||
#define VC4_HDMI_CPU_CLEAR 0x348
|
||||
# define VC4_HDMI_CPU_CEC BIT(6)
|
||||
# define VC4_HDMI_CPU_HOTPLUG BIT(0)
|
||||
|
||||
#define VC4_HDMI_CPU_MASK_STATUS 0x34c
|
||||
#define VC4_HDMI_CPU_MASK_SET 0x350
|
||||
#define VC4_HDMI_CPU_MASK_CLEAR 0x354
|
||||
|
||||
#define VC4_HDMI_GCP(x) (0x400 + ((x) * 0x4))
|
||||
#define VC4_HDMI_RAM_PACKET(x) (0x400 + ((x) * 0x24))
|
||||
#define VC4_HDMI_PACKET_STRIDE 0x24
|
||||
|
||||
#define VC4_HD_M_CTL 0x00c
|
||||
/* Debug: Current receive value on the CEC pad. */
|
||||
# define VC4_HD_CECRXD BIT(9)
|
||||
/* Debug: Override CEC output to 0. */
|
||||
# define VC4_HD_CECOVR BIT(8)
|
||||
# define VC4_HD_M_REGISTER_FILE_STANDBY (3 << 6)
|
||||
# define VC4_HD_M_RAM_STANDBY (3 << 4)
|
||||
# define VC4_HD_M_SW_RST BIT(2)
|
||||
|
Loading…
Reference in New Issue
Block a user