Hi Eric,

On 16/07/17 12:48, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verk...@cisco.com>
> 
> This patch adds support to VC4 for CEC.
> 
> Thanks to Eric Anholt for providing me with the CEC register information.
> 
> To prevent the firmware from eating the CEC interrupts you need to add this to
> your config.txt:
> 
> mask_gpu_interrupt1=0x100

I put this text in the commit log, but I think it should also go into the 
source.
Do you agree?

Should I also mention this in the kernel log via a 'dev_info'? It's not an 
obvious
config option, after all.

Or do you have other ideas regarding this?

Regards,

        Hans

> 
> Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>
> Signed-off-by: Eric Anholt <e...@anholt.net>
> ---
>  drivers/gpu/drm/vc4/Kconfig    |   8 ++
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 227 
> +++++++++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/vc4/vc4_regs.h | 113 ++++++++++++++++++++
>  3 files changed, 342 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
> index 4361bdcfd28a..fdae18aeab4f 100644
> --- a/drivers/gpu/drm/vc4/Kconfig
> +++ b/drivers/gpu/drm/vc4/Kconfig
> @@ -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.
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index e0104f96011e..761b95f5deed 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -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,34 @@ 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 +1447,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 +1472,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);
>  
> diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
> index d382c34c1b9e..55677bd50f66 100644
> --- a/drivers/gpu/drm/vc4/vc4_regs.h
> +++ b/drivers/gpu/drm/vc4/vc4_regs.h
> @@ -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)
> 

Reply via email to