Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,82 @@
# SPDX-License-Identifier: GPL-2.0-only
config DRM_DW_DP
tristate
select DRM_DISPLAY_HELPER
select DRM_DISPLAY_DP_HELPER
select DRM_KMS_HELPER
select REGMAP_MMIO
config DRM_DW_HDMI
tristate
select DRM_DISPLAY_HDMI_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select REGMAP_MMIO
select CEC_CORE if CEC_NOTIFIER
config DRM_DW_HDMI_AHB_AUDIO
tristate "Synopsys Designware AHB Audio interface"
depends on DRM_DW_HDMI && SND
select SND_PCM
select SND_PCM_ELD
select SND_PCM_IEC958
help
Support the AHB Audio interface which is part of the Synopsys
Designware HDMI block. This is used in conjunction with
the i.MX6 HDMI driver.
config DRM_DW_HDMI_I2S_AUDIO
tristate "Synopsys Designware I2S Audio interface"
depends on SND_SOC
depends on DRM_DW_HDMI
select SND_SOC_HDMI_CODEC
help
Support the I2S Audio interface which is part of the Synopsys
Designware HDMI block.
config DRM_DW_HDMI_GP_AUDIO
tristate "Synopsys Designware GP Audio interface"
depends on DRM_DW_HDMI && SND
select SND_PCM
select SND_PCM_ELD
select SND_PCM_IEC958
help
Support the GP Audio interface which is part of the Synopsys
Designware HDMI block.
config DRM_DW_HDMI_CEC
tristate "Synopsis Designware CEC interface"
depends on DRM_DW_HDMI
select CEC_CORE
select CEC_NOTIFIER
help
Support the CE interface which is part of the Synopsys
Designware HDMI block.
config DRM_DW_HDMI_QP
tristate
select DRM_DISPLAY_HDMI_HELPER
select DRM_DISPLAY_HDMI_STATE_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select REGMAP_MMIO
config DRM_DW_HDMI_QP_CEC
bool "Synopsis Designware QP CEC interface"
depends on DRM_DW_HDMI_QP
select DRM_DISPLAY_HDMI_CEC_HELPER
help
Support the CEC interface which is part of the Synopsys
Designware HDMI QP block.
config DRM_DW_MIPI_DSI
tristate
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL_BRIDGE
config DRM_DW_MIPI_DSI2
tristate
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL_BRIDGE
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_DRM_DW_DP) += dw-dp.o
obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
obj-$(CONFIG_DRM_DW_HDMI_GP_AUDIO) += dw-hdmi-gp-audio.o
obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
obj-$(CONFIG_DRM_DW_HDMI_QP) += dw-hdmi-qp.o
obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
obj-$(CONFIG_DRM_DW_MIPI_DSI2) += dw-mipi-dsi2.o
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,660 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* DesignWare HDMI audio driver
*
* Written and tested against the Designware HDMI Tx found in iMX6.
*/
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/vmalloc.h>
#include <drm/bridge/dw_hdmi.h>
#include <drm/drm_edid.h>
#include <sound/asoundef.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_drm_eld.h>
#include <sound/pcm_iec958.h>
#include "dw-hdmi-audio.h"
#define DRIVER_NAME "dw-hdmi-ahb-audio"
/* Provide some bits rather than bit offsets */
enum {
HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
HDMI_AHB_DMA_START_START = BIT(0),
HDMI_AHB_DMA_STOP_STOP = BIT(0),
HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
HDMI_IH_AHBDMAAUD_STAT0_ALL =
HDMI_IH_AHBDMAAUD_STAT0_ERROR |
HDMI_IH_AHBDMAAUD_STAT0_LOST |
HDMI_IH_AHBDMAAUD_STAT0_RETRY |
HDMI_IH_AHBDMAAUD_STAT0_DONE |
HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
HDMI_AHB_DMA_CONF0_INCR4 = 0,
HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
HDMI_AHB_DMA_MASK_DONE = BIT(7),
HDMI_REVISION_ID = 0x0001,
HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
HDMI_AHB_DMA_CONF0 = 0x3600,
HDMI_AHB_DMA_START = 0x3601,
HDMI_AHB_DMA_STOP = 0x3602,
HDMI_AHB_DMA_THRSLD = 0x3603,
HDMI_AHB_DMA_STRADDR0 = 0x3604,
HDMI_AHB_DMA_STPADDR0 = 0x3608,
HDMI_AHB_DMA_MASK = 0x3614,
HDMI_AHB_DMA_POL = 0x3615,
HDMI_AHB_DMA_CONF1 = 0x3616,
HDMI_AHB_DMA_BUFFPOL = 0x361a,
};
struct dw_hdmi_channel_conf {
u8 conf1;
u8 ca;
};
/*
* The default mapping of ALSA channels to HDMI channels and speaker
* allocation bits. Note that we can't do channel remapping here -
* channels must be in the same order.
*
* Mappings for alsa-lib pcm/surround*.conf files:
*
* Front Sur4.0 Sur4.1 Sur5.0 Sur5.1 Sur7.1
* Channels 2 4 6 6 6 8
*
* Our mapping from ALSA channel to CEA686D speaker name and HDMI channel:
*
* Number of ALSA channels
* ALSA Channel 2 3 4 5 6 7 8
* 0 FL:0 = = = = = =
* 1 FR:1 = = = = = =
* 2 FC:3 RL:4 LFE:2 = = =
* 3 RR:5 RL:4 FC:3 = =
* 4 RR:5 RL:4 = =
* 5 RR:5 = =
* 6 RC:6 =
* 7 RLC/FRC RLC/FRC
*/
static struct dw_hdmi_channel_conf default_hdmi_channel_config[7] = {
{ 0x03, 0x00 }, /* FL,FR */
{ 0x0b, 0x02 }, /* FL,FR,FC */
{ 0x33, 0x08 }, /* FL,FR,RL,RR */
{ 0x37, 0x09 }, /* FL,FR,LFE,RL,RR */
{ 0x3f, 0x0b }, /* FL,FR,LFE,FC,RL,RR */
{ 0x7f, 0x0f }, /* FL,FR,LFE,FC,RL,RR,RC */
{ 0xff, 0x13 }, /* FL,FR,LFE,FC,RL,RR,[FR]RC,[FR]LC */
};
struct snd_dw_hdmi {
struct snd_card *card;
struct snd_pcm *pcm;
spinlock_t lock;
struct dw_hdmi_audio_data data;
struct snd_pcm_substream *substream;
void (*reformat)(struct snd_dw_hdmi *, size_t, size_t);
void *buf_src;
void *buf_dst;
dma_addr_t buf_addr;
unsigned buf_offset;
unsigned buf_period;
unsigned buf_size;
unsigned channels;
u8 revision;
u8 iec_offset;
u8 cs[192][8];
};
static void dw_hdmi_writel(u32 val, void __iomem *ptr)
{
writeb_relaxed(val, ptr);
writeb_relaxed(val >> 8, ptr + 1);
writeb_relaxed(val >> 16, ptr + 2);
writeb_relaxed(val >> 24, ptr + 3);
}
/*
* Convert to hardware format: The userspace buffer contains IEC958 samples,
* with the PCUV bits in bits 31..28 and audio samples in bits 27..4. We
* need these to be in bits 27..24, with the IEC B bit in bit 28, and audio
* samples in 23..0.
*
* Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd
*
* Ideally, we could do with having the data properly formatted in userspace.
*/
static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
size_t offset, size_t bytes)
{
u32 *src = dw->buf_src + offset;
u32 *dst = dw->buf_dst + offset;
u32 *end = dw->buf_src + offset + bytes;
do {
u32 b, sample = *src++;
b = (sample & 8) << (28 - 3);
sample >>= 4;
*dst++ = sample | b;
} while (src < end);
}
static u32 parity(u32 sample)
{
sample ^= sample >> 16;
sample ^= sample >> 8;
sample ^= sample >> 4;
sample ^= sample >> 2;
sample ^= sample >> 1;
return (sample & 1) << 27;
}
static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
size_t offset, size_t bytes)
{
u32 *src = dw->buf_src + offset;
u32 *dst = dw->buf_dst + offset;
u32 *end = dw->buf_src + offset + bytes;
do {
unsigned i;
u8 *cs;
cs = dw->cs[dw->iec_offset++];
if (dw->iec_offset >= 192)
dw->iec_offset = 0;
i = dw->channels;
do {
u32 sample = *src++;
sample &= ~0xff000000;
sample |= *cs++ << 24;
sample |= parity(sample & ~0xf8000000);
*dst++ = sample;
} while (--i);
} while (src < end);
}
static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
struct snd_pcm_runtime *runtime)
{
u8 cs[4];
unsigned ch, i, j;
snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs));
memset(dw->cs, 0, sizeof(dw->cs));
for (ch = 0; ch < 8; ch++) {
cs[2] &= ~IEC958_AES2_CON_CHANNEL;
cs[2] |= (ch + 1) << 4;
for (i = 0; i < ARRAY_SIZE(cs); i++) {
unsigned c = cs[i];
for (j = 0; j < 8; j++, c >>= 1)
dw->cs[i * 8 + j][ch] = (c & 1) << 2;
}
}
dw->cs[0][0] |= BIT(4);
}
static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
{
void __iomem *base = dw->data.base;
unsigned offset = dw->buf_offset;
unsigned period = dw->buf_period;
u32 start, stop;
dw->reformat(dw, offset, period);
/* Clear all irqs before enabling irqs and starting DMA */
writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
base + HDMI_IH_AHBDMAAUD_STAT0);
start = dw->buf_addr + offset;
stop = start + period - 1;
/* Setup the hardware start/stop addresses */
dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0);
dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0);
writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK);
writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START);
offset += period;
if (offset >= dw->buf_size)
offset = 0;
dw->buf_offset = offset;
}
static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
{
/* Disable interrupts before disabling DMA */
writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK);
writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP);
}
static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
{
struct snd_dw_hdmi *dw = data;
struct snd_pcm_substream *substream;
unsigned stat;
stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
if (!stat)
return IRQ_NONE;
writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
substream = dw->substream;
if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
snd_pcm_period_elapsed(substream);
spin_lock(&dw->lock);
if (dw->substream)
dw_hdmi_start_dma(dw);
spin_unlock(&dw->lock);
}
return IRQ_HANDLED;
}
static const struct snd_pcm_hardware dw_hdmi_hw = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE |
SNDRV_PCM_FMTBIT_S24_LE,
.rates = SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_176400 |
SNDRV_PCM_RATE_192000,
.channels_min = 2,
.channels_max = 8,
.buffer_bytes_max = 1024 * 1024,
.period_bytes_min = 256,
.period_bytes_max = 8192, /* ERR004323: must limit to 8k */
.periods_min = 2,
.periods_max = 16,
.fifo_size = 0,
};
static int dw_hdmi_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dw_hdmi *dw = substream->private_data;
void __iomem *base = dw->data.base;
u8 *eld;
int ret;
runtime->hw = dw_hdmi_hw;
eld = dw->data.get_eld(dw->data.hdmi);
if (eld) {
ret = snd_pcm_hw_constraint_eld(runtime, eld);
if (ret < 0)
return ret;
}
ret = snd_pcm_limit_hw_rates(runtime);
if (ret < 0)
return ret;
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0)
return ret;
/* Limit the buffer size to the size of the preallocated buffer */
ret = snd_pcm_hw_constraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
0, substream->dma_buffer.bytes);
if (ret < 0)
return ret;
/* Clear FIFO */
writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
base + HDMI_AHB_DMA_CONF0);
/* Configure interrupt polarities */
writeb_relaxed(~0, base + HDMI_AHB_DMA_POL);
writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL);
/* Keep interrupts masked, and clear any pending */
writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK);
writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0);
ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
"dw-hdmi-audio", dw);
if (ret)
return ret;
/* Un-mute done interrupt */
writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
return 0;
}
static int dw_hdmi_close(struct snd_pcm_substream *substream)
{
struct snd_dw_hdmi *dw = substream->private_data;
/* Mute all interrupts */
writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
free_irq(dw->data.irq, dw);
return 0;
}
static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
vfree(runtime->dma_area);
runtime->dma_area = NULL;
return 0;
}
static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
size_t size = params_buffer_bytes(params);
/* Allocate the PCM runtime buffer, which is exposed to userspace. */
if (runtime->dma_area) {
if (runtime->dma_bytes >= size)
return 0; /* already large enough */
vfree(runtime->dma_area);
}
runtime->dma_area = vzalloc(size);
if (!runtime->dma_area)
return -ENOMEM;
runtime->dma_bytes = size;
return 1;
}
static struct page *dw_hdmi_get_page(struct snd_pcm_substream *substream,
unsigned long offset)
{
return vmalloc_to_page(substream->runtime->dma_area + offset);
}
static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dw_hdmi *dw = substream->private_data;
u8 threshold, conf0, conf1, ca;
/* Setup as per 3.0.5 FSL 4.1.0 BSP */
switch (dw->revision) {
case 0x0a:
conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
HDMI_AHB_DMA_CONF0_INCR4;
if (runtime->channels == 2)
threshold = 126;
else
threshold = 124;
break;
case 0x1a:
conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
HDMI_AHB_DMA_CONF0_INCR8;
threshold = 128;
break;
default:
/* NOTREACHED */
return -EINVAL;
}
dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate);
/* Minimum number of bytes in the fifo. */
runtime->hw.fifo_size = threshold * 32;
conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK;
conf1 = default_hdmi_channel_config[runtime->channels - 2].conf1;
ca = default_hdmi_channel_config[runtime->channels - 2].ca;
writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
dw_hdmi_set_channel_count(dw->data.hdmi, runtime->channels);
dw_hdmi_set_channel_allocation(dw->data.hdmi, ca);
switch (runtime->format) {
case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
dw->reformat = dw_hdmi_reformat_iec958;
break;
case SNDRV_PCM_FORMAT_S24_LE:
dw_hdmi_create_cs(dw, runtime);
dw->reformat = dw_hdmi_reformat_s24;
break;
}
dw->iec_offset = 0;
dw->channels = runtime->channels;
dw->buf_src = runtime->dma_area;
dw->buf_dst = substream->dma_buffer.area;
dw->buf_addr = substream->dma_buffer.addr;
dw->buf_period = snd_pcm_lib_period_bytes(substream);
dw->buf_size = snd_pcm_lib_buffer_bytes(substream);
return 0;
}
static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_dw_hdmi *dw = substream->private_data;
unsigned long flags;
int ret = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
spin_lock_irqsave(&dw->lock, flags);
dw->buf_offset = 0;
dw->substream = substream;
dw_hdmi_start_dma(dw);
dw_hdmi_audio_enable(dw->data.hdmi);
spin_unlock_irqrestore(&dw->lock, flags);
substream->runtime->delay = substream->runtime->period_size;
break;
case SNDRV_PCM_TRIGGER_STOP:
spin_lock_irqsave(&dw->lock, flags);
dw->substream = NULL;
dw_hdmi_stop_dma(dw);
dw_hdmi_audio_disable(dw->data.hdmi);
spin_unlock_irqrestore(&dw->lock, flags);
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dw_hdmi *dw = substream->private_data;
/*
* We are unable to report the exact hardware position as
* reading the 32-bit DMA position using 8-bit reads is racy.
*/
return bytes_to_frames(runtime, dw->buf_offset);
}
static const struct snd_pcm_ops snd_dw_hdmi_ops = {
.open = dw_hdmi_open,
.close = dw_hdmi_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = dw_hdmi_hw_params,
.hw_free = dw_hdmi_hw_free,
.prepare = dw_hdmi_prepare,
.trigger = dw_hdmi_trigger,
.pointer = dw_hdmi_pointer,
.page = dw_hdmi_get_page,
};
static int snd_dw_hdmi_probe(struct platform_device *pdev)
{
const struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
struct device *dev = pdev->dev.parent;
struct snd_dw_hdmi *dw;
struct snd_card *card;
struct snd_pcm *pcm;
unsigned revision;
int ret;
writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
revision = readb_relaxed(data->base + HDMI_REVISION_ID);
if (revision != 0x0a && revision != 0x1a) {
dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n",
revision);
return -ENXIO;
}
ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
THIS_MODULE, sizeof(struct snd_dw_hdmi), &card);
if (ret < 0)
return ret;
strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
strscpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
snprintf(card->longname, sizeof(card->longname),
"%s rev 0x%02x, irq %d", card->shortname, revision,
data->irq);
dw = card->private_data;
dw->card = card;
dw->data = *data;
dw->revision = revision;
spin_lock_init(&dw->lock);
ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm);
if (ret < 0)
goto err;
dw->pcm = pcm;
pcm->private_data = dw;
strscpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
/*
* To support 8-channel 96kHz audio reliably, we need 512k
* to satisfy alsa with our restricted period (ERR004323).
*/
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
dev, 128 * 1024, 1024 * 1024);
ret = snd_card_register(card);
if (ret < 0)
goto err;
platform_set_drvdata(pdev, dw);
return 0;
err:
snd_card_free(card);
return ret;
}
static void snd_dw_hdmi_remove(struct platform_device *pdev)
{
struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
snd_card_free(dw->card);
}
#if defined(CONFIG_PM_SLEEP) && defined(IS_NOT_BROKEN)
/*
* This code is fine, but requires implementation in the dw_hdmi_trigger()
* method which is currently missing as I have no way to test this.
*/
static int snd_dw_hdmi_suspend(struct device *dev)
{
struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);
return 0;
}
static int snd_dw_hdmi_resume(struct device *dev)
{
struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0);
return 0;
}
static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend,
snd_dw_hdmi_resume);
#define PM_OPS &snd_dw_hdmi_pm
#else
#define PM_OPS NULL
#endif
static struct platform_driver snd_dw_hdmi_driver = {
.probe = snd_dw_hdmi_probe,
.remove = snd_dw_hdmi_remove,
.driver = {
.name = DRIVER_NAME,
.pm = PM_OPS,
},
};
module_platform_driver(snd_dw_hdmi_driver);
MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRIVER_NAME);
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef DW_HDMI_AUDIO_H
#define DW_HDMI_AUDIO_H
struct dw_hdmi;
struct dw_hdmi_audio_data {
phys_addr_t phys;
void __iomem *base;
int irq;
struct dw_hdmi *hdmi;
u8 *(*get_eld)(struct dw_hdmi *hdmi);
};
struct dw_hdmi_i2s_audio_data {
struct dw_hdmi *hdmi;
void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
u8 (*read)(struct dw_hdmi *hdmi, int offset);
u8 *(*get_eld)(struct dw_hdmi *hdmi);
};
#endif
@@ -0,0 +1,360 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Designware HDMI CEC driver
*
* Copyright (C) 2015-2017 Russell King.
*/
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <drm/drm_edid.h>
#include <media/cec.h>
#include <media/cec-notifier.h>
#include "dw-hdmi-cec.h"
enum {
HDMI_IH_CEC_STAT0 = 0x0106,
HDMI_IH_MUTE_CEC_STAT0 = 0x0186,
HDMI_CEC_CTRL = 0x7d00,
CEC_CTRL_START = BIT(0),
CEC_CTRL_FRAME_TYP = 3 << 1,
CEC_CTRL_RETRY = 0 << 1,
CEC_CTRL_NORMAL = 1 << 1,
CEC_CTRL_IMMED = 2 << 1,
HDMI_CEC_STAT = 0x7d01,
CEC_STAT_DONE = BIT(0),
CEC_STAT_EOM = BIT(1),
CEC_STAT_NACK = BIT(2),
CEC_STAT_ARBLOST = BIT(3),
CEC_STAT_ERROR_INIT = BIT(4),
CEC_STAT_ERROR_FOLL = BIT(5),
CEC_STAT_WAKEUP = BIT(6),
HDMI_CEC_MASK = 0x7d02,
HDMI_CEC_POLARITY = 0x7d03,
HDMI_CEC_INT = 0x7d04,
HDMI_CEC_ADDR_L = 0x7d05,
HDMI_CEC_ADDR_H = 0x7d06,
HDMI_CEC_TX_CNT = 0x7d07,
HDMI_CEC_RX_CNT = 0x7d08,
HDMI_CEC_TX_DATA0 = 0x7d10,
HDMI_CEC_RX_DATA0 = 0x7d20,
HDMI_CEC_LOCK = 0x7d30,
HDMI_CEC_WKUPCTRL = 0x7d31,
};
struct dw_hdmi_cec {
struct dw_hdmi *hdmi;
const struct dw_hdmi_cec_ops *ops;
u32 addresses;
struct cec_adapter *adap;
struct cec_msg rx_msg;
unsigned int tx_status;
bool tx_done;
bool rx_done;
struct cec_notifier *notify;
int irq;
u8 regs_polarity;
u8 regs_mask;
u8 regs_mute_stat0;
};
static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
{
cec->ops->write(cec->hdmi, val, offset);
}
static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
{
return cec->ops->read(cec->hdmi, offset);
}
static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
{
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
if (logical_addr == CEC_LOG_ADDR_INVALID)
cec->addresses = 0;
else
cec->addresses |= BIT(logical_addr) | BIT(15);
dw_hdmi_write(cec, cec->addresses & 255, HDMI_CEC_ADDR_L);
dw_hdmi_write(cec, cec->addresses >> 8, HDMI_CEC_ADDR_H);
return 0;
}
static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg)
{
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
unsigned int i, ctrl;
switch (signal_free_time) {
case CEC_SIGNAL_FREE_TIME_RETRY:
ctrl = CEC_CTRL_RETRY;
break;
case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
default:
ctrl = CEC_CTRL_NORMAL;
break;
case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
ctrl = CEC_CTRL_IMMED;
break;
}
for (i = 0; i < msg->len; i++)
dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
dw_hdmi_write(cec, ctrl | CEC_CTRL_START, HDMI_CEC_CTRL);
return 0;
}
static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
{
struct cec_adapter *adap = data;
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
unsigned int stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
irqreturn_t ret = IRQ_HANDLED;
if (stat == 0)
return IRQ_NONE;
dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
if (stat & CEC_STAT_ERROR_INIT) {
cec->tx_status = CEC_TX_STATUS_ERROR;
cec->tx_done = true;
ret = IRQ_WAKE_THREAD;
} else if (stat & CEC_STAT_DONE) {
cec->tx_status = CEC_TX_STATUS_OK;
cec->tx_done = true;
ret = IRQ_WAKE_THREAD;
} else if (stat & CEC_STAT_NACK) {
cec->tx_status = CEC_TX_STATUS_NACK;
cec->tx_done = true;
ret = IRQ_WAKE_THREAD;
} else if (stat & CEC_STAT_ARBLOST) {
cec->tx_status = CEC_TX_STATUS_ARB_LOST;
cec->tx_done = true;
ret = IRQ_WAKE_THREAD;
}
if (stat & CEC_STAT_EOM) {
unsigned int len, i;
len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
if (len > sizeof(cec->rx_msg.msg))
len = sizeof(cec->rx_msg.msg);
for (i = 0; i < len; i++)
cec->rx_msg.msg[i] =
dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
cec->rx_msg.len = len;
smp_wmb();
cec->rx_done = true;
ret = IRQ_WAKE_THREAD;
}
return ret;
}
static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
{
struct cec_adapter *adap = data;
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
if (cec->tx_done) {
cec->tx_done = false;
cec_transmit_attempt_done(adap, cec->tx_status);
}
if (cec->rx_done) {
cec->rx_done = false;
smp_rmb();
cec_received_msg(adap, &cec->rx_msg);
}
return IRQ_HANDLED;
}
static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
{
struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
if (!enable) {
dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
cec->ops->disable(cec->hdmi);
} else {
unsigned int irqs;
dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
cec->ops->enable(cec->hdmi);
irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
CEC_STAT_ARBLOST | CEC_STAT_DONE;
dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
}
return 0;
}
static const struct cec_adap_ops dw_hdmi_cec_ops = {
.adap_enable = dw_hdmi_cec_enable,
.adap_log_addr = dw_hdmi_cec_log_addr,
.adap_transmit = dw_hdmi_cec_transmit,
};
static void dw_hdmi_cec_del(void *data)
{
struct dw_hdmi_cec *cec = data;
cec_delete_adapter(cec->adap);
}
static int dw_hdmi_cec_probe(struct platform_device *pdev)
{
struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
struct dw_hdmi_cec *cec;
int ret;
if (!data)
return -ENXIO;
/*
* Our device is just a convenience - we want to link to the real
* hardware device here, so that userspace can see the association
* between the HDMI hardware and its associated CEC chardev.
*/
cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
if (!cec)
return -ENOMEM;
cec->irq = data->irq;
cec->ops = data->ops;
cec->hdmi = data->hdmi;
platform_set_drvdata(pdev, cec);
dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
CEC_CAP_DEFAULTS |
CEC_CAP_CONNECTOR_INFO,
CEC_MAX_LOG_ADDRS);
if (IS_ERR(cec->adap))
return PTR_ERR(cec->adap);
/* override the module pointer */
cec->adap->owner = THIS_MODULE;
ret = devm_add_action_or_reset(&pdev->dev, dw_hdmi_cec_del, cec);
if (ret)
return ret;
ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
dw_hdmi_cec_hardirq,
dw_hdmi_cec_thread, IRQF_SHARED,
"dw-hdmi-cec", cec->adap);
if (ret < 0)
return ret;
cec->notify = cec_notifier_cec_adap_register(pdev->dev.parent,
NULL, cec->adap);
if (!cec->notify)
return -ENOMEM;
ret = cec_register_adapter(cec->adap, pdev->dev.parent);
if (ret < 0) {
cec_notifier_cec_adap_unregister(cec->notify, cec->adap);
return ret;
}
/*
* CEC documentation says we must not call cec_delete_adapter
* after a successful call to cec_register_adapter().
*/
devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
return 0;
}
static void dw_hdmi_cec_remove(struct platform_device *pdev)
{
struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
cec_notifier_cec_adap_unregister(cec->notify, cec->adap);
cec_unregister_adapter(cec->adap);
}
static int dw_hdmi_cec_resume(struct device *dev)
{
struct dw_hdmi_cec *cec = dev_get_drvdata(dev);
/* Restore logical address */
dw_hdmi_write(cec, cec->addresses & 255, HDMI_CEC_ADDR_L);
dw_hdmi_write(cec, cec->addresses >> 8, HDMI_CEC_ADDR_H);
/* Restore interrupt status/mask registers */
dw_hdmi_write(cec, cec->regs_polarity, HDMI_CEC_POLARITY);
dw_hdmi_write(cec, cec->regs_mask, HDMI_CEC_MASK);
dw_hdmi_write(cec, cec->regs_mute_stat0, HDMI_IH_MUTE_CEC_STAT0);
return 0;
}
static int dw_hdmi_cec_suspend(struct device *dev)
{
struct dw_hdmi_cec *cec = dev_get_drvdata(dev);
/* store interrupt status/mask registers */
cec->regs_polarity = dw_hdmi_read(cec, HDMI_CEC_POLARITY);
cec->regs_mask = dw_hdmi_read(cec, HDMI_CEC_MASK);
cec->regs_mute_stat0 = dw_hdmi_read(cec, HDMI_IH_MUTE_CEC_STAT0);
return 0;
}
static const struct dev_pm_ops dw_hdmi_cec_pm = {
SYSTEM_SLEEP_PM_OPS(dw_hdmi_cec_suspend, dw_hdmi_cec_resume)
};
static struct platform_driver dw_hdmi_cec_driver = {
.probe = dw_hdmi_cec_probe,
.remove = dw_hdmi_cec_remove,
.driver = {
.name = "dw-hdmi-cec",
.pm = pm_ptr(&dw_hdmi_cec_pm),
},
};
module_platform_driver(dw_hdmi_cec_driver);
MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
MODULE_DESCRIPTION("Synopsys Designware HDMI CEC driver for i.MX");
MODULE_LICENSE("GPL");
MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
@@ -0,0 +1,19 @@
#ifndef DW_HDMI_CEC_H
#define DW_HDMI_CEC_H
struct dw_hdmi;
struct dw_hdmi_cec_ops {
void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
u8 (*read)(struct dw_hdmi *hdmi, int offset);
void (*enable)(struct dw_hdmi *hdmi);
void (*disable)(struct dw_hdmi *hdmi);
};
struct dw_hdmi_cec_data {
struct dw_hdmi *hdmi;
const struct dw_hdmi_cec_ops *ops;
int irq;
};
#endif
@@ -0,0 +1,200 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* dw-hdmi-gp-audio.c
*
* Copyright 2020-2022 NXP
*/
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <drm/bridge/dw_hdmi.h>
#include <drm/drm_edid.h>
#include <drm/drm_connector.h>
#include <sound/hdmi-codec.h>
#include <sound/asoundef.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_drm_eld.h>
#include <sound/pcm_iec958.h>
#include <sound/dmaengine_pcm.h>
#include "dw-hdmi-audio.h"
#define DRIVER_NAME "dw-hdmi-gp-audio"
#define DRV_NAME "hdmi-gp-audio"
struct snd_dw_hdmi {
struct dw_hdmi_audio_data data;
struct platform_device *audio_pdev;
unsigned int pos;
};
struct dw_hdmi_channel_conf {
u8 conf1;
u8 ca;
};
/*
* The default mapping of ALSA channels to HDMI channels and speaker
* allocation bits. Note that we can't do channel remapping here -
* channels must be in the same order.
*
* Mappings for alsa-lib pcm/surround*.conf files:
*
* Front Sur4.0 Sur4.1 Sur5.0 Sur5.1 Sur7.1
* Channels 2 4 6 6 6 8
*
* Our mapping from ALSA channel to CEA686D speaker name and HDMI channel:
*
* Number of ALSA channels
* ALSA Channel 2 3 4 5 6 7 8
* 0 FL:0 = = = = = =
* 1 FR:1 = = = = = =
* 2 FC:3 RL:4 LFE:2 = = =
* 3 RR:5 RL:4 FC:3 = =
* 4 RR:5 RL:4 = =
* 5 RR:5 = =
* 6 RC:6 =
* 7 RLC/FRC RLC/FRC
*/
static struct dw_hdmi_channel_conf default_hdmi_channel_config[7] = {
{ 0x03, 0x00 }, /* FL,FR */
{ 0x0b, 0x02 }, /* FL,FR,FC */
{ 0x33, 0x08 }, /* FL,FR,RL,RR */
{ 0x37, 0x09 }, /* FL,FR,LFE,RL,RR */
{ 0x3f, 0x0b }, /* FL,FR,LFE,FC,RL,RR */
{ 0x7f, 0x0f }, /* FL,FR,LFE,FC,RL,RR,RC */
{ 0xff, 0x13 }, /* FL,FR,LFE,FC,RL,RR,[FR]RC,[FR]LC */
};
static int audio_hw_params(struct device *dev, void *data,
struct hdmi_codec_daifmt *daifmt,
struct hdmi_codec_params *params)
{
struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
u8 ca;
dw_hdmi_set_sample_rate(dw->data.hdmi, params->sample_rate);
ca = default_hdmi_channel_config[params->channels - 2].ca;
dw_hdmi_set_channel_count(dw->data.hdmi, params->channels);
dw_hdmi_set_channel_allocation(dw->data.hdmi, ca);
dw_hdmi_set_sample_non_pcm(dw->data.hdmi,
params->iec.status[0] & IEC958_AES0_NONAUDIO);
dw_hdmi_set_sample_width(dw->data.hdmi, params->sample_width);
if (daifmt->bit_fmt == SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE)
dw_hdmi_set_sample_iec958(dw->data.hdmi, 1);
else
dw_hdmi_set_sample_iec958(dw->data.hdmi, 0);
return 0;
}
static void audio_shutdown(struct device *dev, void *data)
{
}
static int audio_mute_stream(struct device *dev, void *data,
bool enable, int direction)
{
struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
if (!enable)
dw_hdmi_audio_enable(dw->data.hdmi);
else
dw_hdmi_audio_disable(dw->data.hdmi);
return 0;
}
static int audio_get_eld(struct device *dev, void *data,
u8 *buf, size_t len)
{
struct dw_hdmi_audio_data *audio = data;
u8 *eld;
eld = audio->get_eld(audio->hdmi);
if (eld)
memcpy(buf, eld, min_t(size_t, MAX_ELD_BYTES, len));
else
/* Pass en empty ELD if connector not available */
memset(buf, 0, len);
return 0;
}
static int audio_hook_plugged_cb(struct device *dev, void *data,
hdmi_codec_plugged_cb fn,
struct device *codec_dev)
{
struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
return dw_hdmi_set_plugged_cb(dw->data.hdmi, fn, codec_dev);
}
static const struct hdmi_codec_ops audio_codec_ops = {
.hw_params = audio_hw_params,
.audio_shutdown = audio_shutdown,
.mute_stream = audio_mute_stream,
.get_eld = audio_get_eld,
.hook_plugged_cb = audio_hook_plugged_cb,
};
static int snd_dw_hdmi_probe(struct platform_device *pdev)
{
struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
struct snd_dw_hdmi *dw;
const struct hdmi_codec_pdata codec_data = {
.i2s = 1,
.spdif = 0,
.ops = &audio_codec_ops,
.max_i2s_channels = 8,
.data = data,
};
dw = devm_kzalloc(&pdev->dev, sizeof(*dw), GFP_KERNEL);
if (!dw)
return -ENOMEM;
dw->data = *data;
platform_set_drvdata(pdev, dw);
dw->audio_pdev = platform_device_register_data(&pdev->dev,
HDMI_CODEC_DRV_NAME, 1,
&codec_data,
sizeof(codec_data));
return PTR_ERR_OR_ZERO(dw->audio_pdev);
}
static void snd_dw_hdmi_remove(struct platform_device *pdev)
{
struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
platform_device_unregister(dw->audio_pdev);
}
static struct platform_driver snd_dw_hdmi_driver = {
.probe = snd_dw_hdmi_probe,
.remove = snd_dw_hdmi_remove,
.driver = {
.name = DRIVER_NAME,
},
};
module_platform_driver(snd_dw_hdmi_driver);
MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");
MODULE_DESCRIPTION("Synopsys Designware HDMI GPA ALSA interface");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRIVER_NAME);
@@ -0,0 +1,239 @@
// SPDX-License-Identifier: GPL-2.0
/*
* dw-hdmi-i2s-audio.c
*
* Copyright (c) 2017 Renesas Solutions Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*/
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <drm/bridge/dw_hdmi.h>
#include <drm/drm_crtc.h>
#include <sound/hdmi-codec.h>
#include "dw-hdmi.h"
#include "dw-hdmi-audio.h"
#define DRIVER_NAME "dw-hdmi-i2s-audio"
static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio,
u8 val, int offset)
{
struct dw_hdmi *hdmi = audio->hdmi;
audio->write(hdmi, val, offset);
}
static inline u8 hdmi_read(struct dw_hdmi_i2s_audio_data *audio, int offset)
{
struct dw_hdmi *hdmi = audio->hdmi;
return audio->read(hdmi, offset);
}
static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
struct hdmi_codec_daifmt *fmt,
struct hdmi_codec_params *hparms)
{
struct dw_hdmi_i2s_audio_data *audio = data;
struct dw_hdmi *hdmi = audio->hdmi;
u8 conf0 = 0;
u8 conf1 = 0;
u8 inputclkfs = 0;
/* it cares I2S only */
if (fmt->bit_clk_provider | fmt->frame_clk_provider) {
dev_err(dev, "unsupported clock settings\n");
return -EINVAL;
}
/* Reset the FIFOs before applying new params */
hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
hdmi_write(audio, (u8)~HDMI_MC_SWRSTZ_I2SSWRST_REQ, HDMI_MC_SWRSTZ);
inputclkfs = HDMI_AUD_INPUTCLKFS_64FS;
conf0 = (HDMI_AUD_CONF0_I2S_SELECT | HDMI_AUD_CONF0_I2S_EN0);
/* Enable the required i2s lanes */
switch (hparms->channels) {
case 7 ... 8:
conf0 |= HDMI_AUD_CONF0_I2S_EN3;
fallthrough;
case 5 ... 6:
conf0 |= HDMI_AUD_CONF0_I2S_EN2;
fallthrough;
case 3 ... 4:
conf0 |= HDMI_AUD_CONF0_I2S_EN1;
/* Fall-thru */
}
switch (hparms->sample_width) {
case 16:
conf1 = HDMI_AUD_CONF1_WIDTH_16;
break;
case 24:
case 32:
conf1 = HDMI_AUD_CONF1_WIDTH_24;
break;
}
switch (fmt->fmt) {
case HDMI_I2S:
conf1 |= HDMI_AUD_CONF1_MODE_I2S;
break;
case HDMI_RIGHT_J:
conf1 |= HDMI_AUD_CONF1_MODE_RIGHT_J;
break;
case HDMI_LEFT_J:
conf1 |= HDMI_AUD_CONF1_MODE_LEFT_J;
break;
case HDMI_DSP_A:
conf1 |= HDMI_AUD_CONF1_MODE_BURST_1;
break;
case HDMI_DSP_B:
conf1 |= HDMI_AUD_CONF1_MODE_BURST_2;
break;
default:
dev_err(dev, "unsupported format\n");
return -EINVAL;
}
dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
dw_hdmi_set_channel_count(hdmi, hparms->channels);
dw_hdmi_set_channel_allocation(hdmi, hparms->cea.channel_allocation);
hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS);
hdmi_write(audio, conf0, HDMI_AUD_CONF0);
hdmi_write(audio, conf1, HDMI_AUD_CONF1);
return 0;
}
static int dw_hdmi_i2s_audio_startup(struct device *dev, void *data)
{
struct dw_hdmi_i2s_audio_data *audio = data;
struct dw_hdmi *hdmi = audio->hdmi;
dw_hdmi_audio_enable(hdmi);
return 0;
}
static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data)
{
struct dw_hdmi_i2s_audio_data *audio = data;
struct dw_hdmi *hdmi = audio->hdmi;
dw_hdmi_audio_disable(hdmi);
}
static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf,
size_t len)
{
struct dw_hdmi_i2s_audio_data *audio = data;
u8 *eld;
eld = audio->get_eld(audio->hdmi);
if (eld)
memcpy(buf, eld, min_t(size_t, MAX_ELD_BYTES, len));
else
/* Pass en empty ELD if connector not available */
memset(buf, 0, len);
return 0;
}
static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
struct device_node *endpoint,
void *data)
{
struct of_endpoint of_ep;
int ret;
ret = of_graph_parse_endpoint(endpoint, &of_ep);
if (ret < 0)
return ret;
/*
* HDMI sound should be located as reg = <2>
* Then, it is sound port 0
*/
if (of_ep.port == 2)
return 0;
return -EINVAL;
}
static int dw_hdmi_i2s_hook_plugged_cb(struct device *dev, void *data,
hdmi_codec_plugged_cb fn,
struct device *codec_dev)
{
struct dw_hdmi_i2s_audio_data *audio = data;
struct dw_hdmi *hdmi = audio->hdmi;
return dw_hdmi_set_plugged_cb(hdmi, fn, codec_dev);
}
static const struct hdmi_codec_ops dw_hdmi_i2s_ops = {
.hw_params = dw_hdmi_i2s_hw_params,
.audio_startup = dw_hdmi_i2s_audio_startup,
.audio_shutdown = dw_hdmi_i2s_audio_shutdown,
.get_eld = dw_hdmi_i2s_get_eld,
.get_dai_id = dw_hdmi_i2s_get_dai_id,
.hook_plugged_cb = dw_hdmi_i2s_hook_plugged_cb,
};
static int snd_dw_hdmi_probe(struct platform_device *pdev)
{
struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data;
struct platform_device_info pdevinfo;
struct hdmi_codec_pdata pdata;
struct platform_device *platform;
memset(&pdata, 0, sizeof(pdata));
pdata.ops = &dw_hdmi_i2s_ops;
pdata.i2s = 1;
pdata.max_i2s_channels = 8;
pdata.data = audio;
memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo.parent = pdev->dev.parent;
pdevinfo.id = PLATFORM_DEVID_AUTO;
pdevinfo.name = HDMI_CODEC_DRV_NAME;
pdevinfo.data = &pdata;
pdevinfo.size_data = sizeof(pdata);
pdevinfo.dma_mask = DMA_BIT_MASK(32);
platform = platform_device_register_full(&pdevinfo);
if (IS_ERR(platform))
return PTR_ERR(platform);
dev_set_drvdata(&pdev->dev, platform);
return 0;
}
static void snd_dw_hdmi_remove(struct platform_device *pdev)
{
struct platform_device *platform = dev_get_drvdata(&pdev->dev);
platform_device_unregister(platform);
}
static struct platform_driver snd_dw_hdmi_driver = {
.probe = snd_dw_hdmi_probe,
.remove = snd_dw_hdmi_remove,
.driver = {
.name = DRIVER_NAME,
},
};
module_platform_driver(snd_dw_hdmi_driver);
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
MODULE_DESCRIPTION("Synopsis Designware HDMI I2S ALSA SoC interface");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRIVER_NAME);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,851 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) Rockchip Electronics Co., Ltd.
* Author:
* Algea Cao <algea.cao@rock-chips.com>
*/
#ifndef __DW_HDMI_QP_H__
#define __DW_HDMI_QP_H__
#include <linux/bits.h>
/* Main Unit Registers */
#define CORE_ID 0x0
#define VER_NUMBER 0x4
#define VER_TYPE 0x8
#define CONFIG_REG 0xc
#define CONFIG_CEC BIT(28)
#define CONFIG_AUD_UD BIT(23)
#define CORE_TIMESTAMP_HHMM 0x14
#define CORE_TIMESTAMP_MMDD 0x18
#define CORE_TIMESTAMP_YYYY 0x1c
/* Reset Manager Registers */
#define GLOBAL_SWRESET_REQUEST 0x40
#define EARCRX_CMDC_SWINIT_P BIT(27)
#define AVP_DATAPATH_PACKET_AUDIO_SWINIT_P BIT(10)
#define GLOBAL_SWDISABLE 0x44
#define CEC_SWDISABLE BIT(17)
#define AVP_DATAPATH_PACKET_AUDIO_SWDISABLE BIT(10)
#define AVP_DATAPATH_VIDEO_SWDISABLE BIT(6)
#define RESET_MANAGER_CONFIG0 0x48
#define RESET_MANAGER_STATUS0 0x50
#define RESET_MANAGER_STATUS1 0x54
#define RESET_MANAGER_STATUS2 0x58
/* Timer Base Registers */
#define TIMER_BASE_CONFIG0 0x80
#define TIMER_BASE_STATUS0 0x84
/* CMU Registers */
#define CMU_CONFIG0 0xa0
#define CMU_CONFIG1 0xa4
#define CMU_CONFIG2 0xa8
#define CMU_CONFIG3 0xac
#define CMU_STATUS 0xb0
#define DISPLAY_CLK_MONITOR 0x3f
#define DISPLAY_CLK_LOCKED 0X15
#define EARC_BPCLK_OFF BIT(9)
#define AUDCLK_OFF BIT(7)
#define LINKQPCLK_OFF BIT(5)
#define VIDQPCLK_OFF BIT(3)
#define IPI_CLK_OFF BIT(1)
#define CMU_IPI_CLK_FREQ 0xb4
#define CMU_VIDQPCLK_FREQ 0xb8
#define CMU_LINKQPCLK_FREQ 0xbc
#define CMU_AUDQPCLK_FREQ 0xc0
#define CMU_EARC_BPCLK_FREQ 0xc4
/* I2CM Registers */
#define I2CM_SM_SCL_CONFIG0 0xe0
#define I2CM_FM_SCL_CONFIG0 0xe4
#define I2CM_CONFIG0 0xe8
#define I2CM_CONTROL0 0xec
#define I2CM_STATUS0 0xf0
#define I2CM_INTERFACE_CONTROL0 0xf4
#define I2CM_ADDR 0xff000
#define I2CM_SLVADDR 0xfe0
#define I2CM_WR_MASK 0x1e
#define I2CM_EXT_READ BIT(4)
#define I2CM_SHORT_READ BIT(3)
#define I2CM_FM_READ BIT(2)
#define I2CM_FM_WRITE BIT(1)
#define I2CM_FM_EN BIT(0)
#define I2CM_INTERFACE_CONTROL1 0xf8
#define I2CM_SEG_PTR 0x7f80
#define I2CM_SEG_ADDR 0x7f
#define I2CM_INTERFACE_WRDATA_0_3 0xfc
#define I2CM_INTERFACE_WRDATA_4_7 0x100
#define I2CM_INTERFACE_WRDATA_8_11 0x104
#define I2CM_INTERFACE_WRDATA_12_15 0x108
#define I2CM_INTERFACE_RDDATA_0_3 0x10c
#define I2CM_INTERFACE_RDDATA_4_7 0x110
#define I2CM_INTERFACE_RDDATA_8_11 0x114
#define I2CM_INTERFACE_RDDATA_12_15 0x118
/* SCDC Registers */
#define SCDC_CONFIG0 0x140
#define SCDC_I2C_FM_EN BIT(12)
#define SCDC_UPD_FLAGS_AUTO_CLR BIT(6)
#define SCDC_UPD_FLAGS_POLL_EN BIT(4)
#define SCDC_CONTROL0 0x148
#define SCDC_STATUS0 0x150
#define STATUS_UPDATE BIT(0)
#define FRL_START BIT(4)
#define FLT_UPDATE BIT(5)
/* FLT Registers */
#define FLT_CONFIG0 0x160
#define FLT_CONFIG1 0x164
#define FLT_CONFIG2 0x168
#define FLT_CONTROL0 0x170
/* Main Unit 2 Registers */
#define MAINUNIT_STATUS0 0x180
/* Video Interface Registers */
#define VIDEO_INTERFACE_CONFIG0 0x800
#define VIDEO_INTERFACE_CONFIG1 0x804
#define VIDEO_INTERFACE_CONFIG2 0x808
#define VIDEO_INTERFACE_CONTROL0 0x80c
#define VIDEO_INTERFACE_STATUS0 0x814
/* Video Packing Registers */
#define VIDEO_PACKING_CONFIG0 0x81c
/* Audio Interface Registers */
#define AUDIO_INTERFACE_CONFIG0 0x820
#define AUD_IF_SEL_MSK 0x3
#define AUD_IF_SPDIF 0x2
#define AUD_IF_I2S 0x1
#define AUD_IF_PAI 0x0
#define AUD_FIFO_INIT_ON_OVF_MSK BIT(2)
#define AUD_FIFO_INIT_ON_OVF_EN BIT(2)
#define I2S_LINES_EN_MSK GENMASK(7, 4)
#define I2S_LINES_EN(x) BIT((x) + 4)
#define I2S_BPCUV_RCV_MSK BIT(12)
#define I2S_BPCUV_RCV_EN BIT(12)
#define I2S_BPCUV_RCV_DIS 0
#define SPDIF_LINES_EN GENMASK(19, 16)
#define AUD_FORMAT_MSK GENMASK(26, 24)
#define AUD_3DOBA (0x7 << 24)
#define AUD_3DASP (0x6 << 24)
#define AUD_MSOBA (0x5 << 24)
#define AUD_MSASP (0x4 << 24)
#define AUD_HBR (0x3 << 24)
#define AUD_DST (0x2 << 24)
#define AUD_OBA (0x1 << 24)
#define AUD_ASP (0x0 << 24)
#define AUDIO_INTERFACE_CONFIG1 0x824
#define AUDIO_INTERFACE_CONTROL0 0x82c
#define AUDIO_FIFO_CLR_P BIT(0)
#define AUDIO_INTERFACE_STATUS0 0x834
/* Frame Composer Registers */
#define FRAME_COMPOSER_CONFIG0 0x840
#define FRAME_COMPOSER_CONFIG1 0x844
#define FRAME_COMPOSER_CONFIG2 0x848
#define FRAME_COMPOSER_CONFIG3 0x84c
#define FRAME_COMPOSER_CONFIG4 0x850
#define FRAME_COMPOSER_CONFIG5 0x854
#define FRAME_COMPOSER_CONFIG6 0x858
#define FRAME_COMPOSER_CONFIG7 0x85c
#define FRAME_COMPOSER_CONFIG8 0x860
#define FRAME_COMPOSER_CONFIG9 0x864
#define FRAME_COMPOSER_CONTROL0 0x86c
/* Video Monitor Registers */
#define VIDEO_MONITOR_CONFIG0 0x880
#define VIDEO_MONITOR_STATUS0 0x884
#define VIDEO_MONITOR_STATUS1 0x888
#define VIDEO_MONITOR_STATUS2 0x88c
#define VIDEO_MONITOR_STATUS3 0x890
#define VIDEO_MONITOR_STATUS4 0x894
#define VIDEO_MONITOR_STATUS5 0x898
#define VIDEO_MONITOR_STATUS6 0x89c
/* HDCP2 Logic Registers */
#define HDCP2LOGIC_CONFIG0 0x8e0
#define HDCP2_BYPASS BIT(0)
#define HDCP2LOGIC_ESM_GPIO_IN 0x8e4
#define HDCP2LOGIC_ESM_GPIO_OUT 0x8e8
/* HDCP14 Registers */
#define HDCP14_CONFIG0 0x900
#define HDCP14_CONFIG1 0x904
#define HDCP14_CONFIG2 0x908
#define HDCP14_CONFIG3 0x90c
#define HDCP14_KEY_SEED 0x914
#define HDCP14_KEY_H 0x918
#define HDCP14_KEY_L 0x91c
#define HDCP14_KEY_STATUS 0x920
#define HDCP14_AKSV_H 0x924
#define HDCP14_AKSV_L 0x928
#define HDCP14_AN_H 0x92c
#define HDCP14_AN_L 0x930
#define HDCP14_STATUS0 0x934
#define HDCP14_STATUS1 0x938
/* Scrambler Registers */
#define SCRAMB_CONFIG0 0x960
/* Video Configuration Registers */
#define LINK_CONFIG0 0x968
#define OPMODE_FRL_4LANES BIT(8)
#define OPMODE_DVI BIT(4)
#define OPMODE_FRL BIT(0)
/* TMDS FIFO Registers */
#define TMDS_FIFO_CONFIG0 0x970
#define TMDS_FIFO_CONTROL0 0x974
/* FRL RSFEC Registers */
#define FRL_RSFEC_CONFIG0 0xa20
#define FRL_RSFEC_STATUS0 0xa30
/* FRL Packetizer Registers */
#define FRL_PKTZ_CONFIG0 0xa40
#define FRL_PKTZ_CONTROL0 0xa44
#define FRL_PKTZ_CONTROL1 0xa50
#define FRL_PKTZ_STATUS1 0xa54
/* Packet Scheduler Registers */
#define PKTSCHED_CONFIG0 0xa80
#define PKTSCHED_PRQUEUE0_CONFIG0 0xa84
#define PKTSCHED_PRQUEUE1_CONFIG0 0xa88
#define PKTSCHED_PRQUEUE2_CONFIG0 0xa8c
#define PKTSCHED_PRQUEUE2_CONFIG1 0xa90
#define PKTSCHED_PRQUEUE2_CONFIG2 0xa94
#define PKTSCHED_PKT_CONFIG0 0xa98
#define PKTSCHED_PKT_CONFIG1 0xa9c
#define PKTSCHED_VSI_FIELDRATE BIT(14)
#define PKTSCHED_DRMI_FIELDRATE BIT(13)
#define PKTSCHED_AVI_FIELDRATE BIT(12)
#define PKTSCHED_PKT_CONFIG2 0xaa0
#define PKTSCHED_PKT_CONFIG3 0xaa4
#define PKTSCHED_PKT_EN 0xaa8
#define PKTSCHED_DRMI_TX_EN BIT(17)
#define PKTSCHED_AUDI_TX_EN BIT(15)
#define PKTSCHED_SPDI_TX_EN BIT(14)
#define PKTSCHED_AVI_TX_EN BIT(13)
#define PKTSCHED_VSI_TX_EN BIT(12)
#define PKTSCHED_EMP_CVTEM_TX_EN BIT(10)
#define PKTSCHED_AMD_TX_EN BIT(8)
#define PKTSCHED_GCP_TX_EN BIT(3)
#define PKTSCHED_AUDS_TX_EN BIT(2)
#define PKTSCHED_ACR_TX_EN BIT(1)
#define PKTSCHED_NULL_TX_EN BIT(0)
#define PKTSCHED_PKT_CONTROL0 0xaac
#define PKTSCHED_PKT_SEND 0xab0
#define PKTSCHED_PKT_STATUS0 0xab4
#define PKTSCHED_PKT_STATUS1 0xab8
#define PKT_NULL_CONTENTS0 0xb00
#define PKT_NULL_CONTENTS1 0xb04
#define PKT_NULL_CONTENTS2 0xb08
#define PKT_NULL_CONTENTS3 0xb0c
#define PKT_NULL_CONTENTS4 0xb10
#define PKT_NULL_CONTENTS5 0xb14
#define PKT_NULL_CONTENTS6 0xb18
#define PKT_NULL_CONTENTS7 0xb1c
#define PKT_ACP_CONTENTS0 0xb20
#define PKT_ACP_CONTENTS1 0xb24
#define PKT_ACP_CONTENTS2 0xb28
#define PKT_ACP_CONTENTS3 0xb2c
#define PKT_ACP_CONTENTS4 0xb30
#define PKT_ACP_CONTENTS5 0xb34
#define PKT_ACP_CONTENTS6 0xb38
#define PKT_ACP_CONTENTS7 0xb3c
#define PKT_ISRC1_CONTENTS0 0xb40
#define PKT_ISRC1_CONTENTS1 0xb44
#define PKT_ISRC1_CONTENTS2 0xb48
#define PKT_ISRC1_CONTENTS3 0xb4c
#define PKT_ISRC1_CONTENTS4 0xb50
#define PKT_ISRC1_CONTENTS5 0xb54
#define PKT_ISRC1_CONTENTS6 0xb58
#define PKT_ISRC1_CONTENTS7 0xb5c
#define PKT_ISRC2_CONTENTS0 0xb60
#define PKT_ISRC2_CONTENTS1 0xb64
#define PKT_ISRC2_CONTENTS2 0xb68
#define PKT_ISRC2_CONTENTS3 0xb6c
#define PKT_ISRC2_CONTENTS4 0xb70
#define PKT_ISRC2_CONTENTS5 0xb74
#define PKT_ISRC2_CONTENTS6 0xb78
#define PKT_ISRC2_CONTENTS7 0xb7c
#define PKT_GMD_CONTENTS0 0xb80
#define PKT_GMD_CONTENTS1 0xb84
#define PKT_GMD_CONTENTS2 0xb88
#define PKT_GMD_CONTENTS3 0xb8c
#define PKT_GMD_CONTENTS4 0xb90
#define PKT_GMD_CONTENTS5 0xb94
#define PKT_GMD_CONTENTS6 0xb98
#define PKT_GMD_CONTENTS7 0xb9c
#define PKT_AMD_CONTENTS0 0xba0
#define PKT_AMD_CONTENTS1 0xba4
#define PKT_AMD_CONTENTS2 0xba8
#define PKT_AMD_CONTENTS3 0xbac
#define PKT_AMD_CONTENTS4 0xbb0
#define PKT_AMD_CONTENTS5 0xbb4
#define PKT_AMD_CONTENTS6 0xbb8
#define PKT_AMD_CONTENTS7 0xbbc
#define PKT_VSI_CONTENTS0 0xbc0
#define PKT_VSI_CONTENTS1 0xbc4
#define PKT_VSI_CONTENTS2 0xbc8
#define PKT_VSI_CONTENTS3 0xbcc
#define PKT_VSI_CONTENTS4 0xbd0
#define PKT_VSI_CONTENTS5 0xbd4
#define PKT_VSI_CONTENTS6 0xbd8
#define PKT_VSI_CONTENTS7 0xbdc
#define PKT_AVI_CONTENTS0 0xbe0
#define HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT BIT(4)
#define HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR 0x04
#define HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR 0x08
#define HDMI_FC_AVICONF2_IT_CONTENT_VALID 0x80
#define PKT_AVI_CONTENTS1 0xbe4
#define PKT_AVI_CONTENTS2 0xbe8
#define PKT_AVI_CONTENTS3 0xbec
#define PKT_AVI_CONTENTS4 0xbf0
#define PKT_AVI_CONTENTS5 0xbf4
#define PKT_AVI_CONTENTS6 0xbf8
#define PKT_AVI_CONTENTS7 0xbfc
#define PKT_SPDI_CONTENTS0 0xc00
#define PKT_SPDI_CONTENTS1 0xc04
#define PKT_SPDI_CONTENTS2 0xc08
#define PKT_SPDI_CONTENTS3 0xc0c
#define PKT_SPDI_CONTENTS4 0xc10
#define PKT_SPDI_CONTENTS5 0xc14
#define PKT_SPDI_CONTENTS6 0xc18
#define PKT_SPDI_CONTENTS7 0xc1c
#define PKT_AUDI_CONTENTS0 0xc20
#define PKT_AUDI_CONTENTS1 0xc24
#define PKT_AUDI_CONTENTS2 0xc28
#define PKT_AUDI_CONTENTS3 0xc2c
#define PKT_AUDI_CONTENTS4 0xc30
#define PKT_AUDI_CONTENTS5 0xc34
#define PKT_AUDI_CONTENTS6 0xc38
#define PKT_AUDI_CONTENTS7 0xc3c
#define PKT_NVI_CONTENTS0 0xc40
#define PKT_NVI_CONTENTS1 0xc44
#define PKT_NVI_CONTENTS2 0xc48
#define PKT_NVI_CONTENTS3 0xc4c
#define PKT_NVI_CONTENTS4 0xc50
#define PKT_NVI_CONTENTS5 0xc54
#define PKT_NVI_CONTENTS6 0xc58
#define PKT_NVI_CONTENTS7 0xc5c
#define PKT_DRMI_CONTENTS0 0xc60
#define PKT_DRMI_CONTENTS1 0xc64
#define PKT_DRMI_CONTENTS2 0xc68
#define PKT_DRMI_CONTENTS3 0xc6c
#define PKT_DRMI_CONTENTS4 0xc70
#define PKT_DRMI_CONTENTS5 0xc74
#define PKT_DRMI_CONTENTS6 0xc78
#define PKT_DRMI_CONTENTS7 0xc7c
#define PKT_GHDMI1_CONTENTS0 0xc80
#define PKT_GHDMI1_CONTENTS1 0xc84
#define PKT_GHDMI1_CONTENTS2 0xc88
#define PKT_GHDMI1_CONTENTS3 0xc8c
#define PKT_GHDMI1_CONTENTS4 0xc90
#define PKT_GHDMI1_CONTENTS5 0xc94
#define PKT_GHDMI1_CONTENTS6 0xc98
#define PKT_GHDMI1_CONTENTS7 0xc9c
#define PKT_GHDMI2_CONTENTS0 0xca0
#define PKT_GHDMI2_CONTENTS1 0xca4
#define PKT_GHDMI2_CONTENTS2 0xca8
#define PKT_GHDMI2_CONTENTS3 0xcac
#define PKT_GHDMI2_CONTENTS4 0xcb0
#define PKT_GHDMI2_CONTENTS5 0xcb4
#define PKT_GHDMI2_CONTENTS6 0xcb8
#define PKT_GHDMI2_CONTENTS7 0xcbc
/* EMP Packetizer Registers */
#define PKT_EMP_CONFIG0 0xce0
#define PKT_EMP_CONTROL0 0xcec
#define PKT_EMP_CONTROL1 0xcf0
#define PKT_EMP_CONTROL2 0xcf4
#define PKT_EMP_VTEM_CONTENTS0 0xd00
#define PKT_EMP_VTEM_CONTENTS1 0xd04
#define PKT_EMP_VTEM_CONTENTS2 0xd08
#define PKT_EMP_VTEM_CONTENTS3 0xd0c
#define PKT_EMP_VTEM_CONTENTS4 0xd10
#define PKT_EMP_VTEM_CONTENTS5 0xd14
#define PKT_EMP_VTEM_CONTENTS6 0xd18
#define PKT_EMP_VTEM_CONTENTS7 0xd1c
#define PKT0_EMP_CVTEM_CONTENTS0 0xd20
#define PKT0_EMP_CVTEM_CONTENTS1 0xd24
#define PKT0_EMP_CVTEM_CONTENTS2 0xd28
#define PKT0_EMP_CVTEM_CONTENTS3 0xd2c
#define PKT0_EMP_CVTEM_CONTENTS4 0xd30
#define PKT0_EMP_CVTEM_CONTENTS5 0xd34
#define PKT0_EMP_CVTEM_CONTENTS6 0xd38
#define PKT0_EMP_CVTEM_CONTENTS7 0xd3c
#define PKT1_EMP_CVTEM_CONTENTS0 0xd40
#define PKT1_EMP_CVTEM_CONTENTS1 0xd44
#define PKT1_EMP_CVTEM_CONTENTS2 0xd48
#define PKT1_EMP_CVTEM_CONTENTS3 0xd4c
#define PKT1_EMP_CVTEM_CONTENTS4 0xd50
#define PKT1_EMP_CVTEM_CONTENTS5 0xd54
#define PKT1_EMP_CVTEM_CONTENTS6 0xd58
#define PKT1_EMP_CVTEM_CONTENTS7 0xd5c
#define PKT2_EMP_CVTEM_CONTENTS0 0xd60
#define PKT2_EMP_CVTEM_CONTENTS1 0xd64
#define PKT2_EMP_CVTEM_CONTENTS2 0xd68
#define PKT2_EMP_CVTEM_CONTENTS3 0xd6c
#define PKT2_EMP_CVTEM_CONTENTS4 0xd70
#define PKT2_EMP_CVTEM_CONTENTS5 0xd74
#define PKT2_EMP_CVTEM_CONTENTS6 0xd78
#define PKT2_EMP_CVTEM_CONTENTS7 0xd7c
#define PKT3_EMP_CVTEM_CONTENTS0 0xd80
#define PKT3_EMP_CVTEM_CONTENTS1 0xd84
#define PKT3_EMP_CVTEM_CONTENTS2 0xd88
#define PKT3_EMP_CVTEM_CONTENTS3 0xd8c
#define PKT3_EMP_CVTEM_CONTENTS4 0xd90
#define PKT3_EMP_CVTEM_CONTENTS5 0xd94
#define PKT3_EMP_CVTEM_CONTENTS6 0xd98
#define PKT3_EMP_CVTEM_CONTENTS7 0xd9c
#define PKT4_EMP_CVTEM_CONTENTS0 0xda0
#define PKT4_EMP_CVTEM_CONTENTS1 0xda4
#define PKT4_EMP_CVTEM_CONTENTS2 0xda8
#define PKT4_EMP_CVTEM_CONTENTS3 0xdac
#define PKT4_EMP_CVTEM_CONTENTS4 0xdb0
#define PKT4_EMP_CVTEM_CONTENTS5 0xdb4
#define PKT4_EMP_CVTEM_CONTENTS6 0xdb8
#define PKT4_EMP_CVTEM_CONTENTS7 0xdbc
#define PKT5_EMP_CVTEM_CONTENTS0 0xdc0
#define PKT5_EMP_CVTEM_CONTENTS1 0xdc4
#define PKT5_EMP_CVTEM_CONTENTS2 0xdc8
#define PKT5_EMP_CVTEM_CONTENTS3 0xdcc
#define PKT5_EMP_CVTEM_CONTENTS4 0xdd0
#define PKT5_EMP_CVTEM_CONTENTS5 0xdd4
#define PKT5_EMP_CVTEM_CONTENTS6 0xdd8
#define PKT5_EMP_CVTEM_CONTENTS7 0xddc
/* Audio Packetizer Registers */
#define AUDPKT_CONTROL0 0xe20
#define AUDPKT_PBIT_FORCE_EN_MASK BIT(12)
#define AUDPKT_PBIT_FORCE_EN BIT(12)
#define AUDPKT_CHSTATUS_OVR_EN_MASK BIT(0)
#define AUDPKT_CHSTATUS_OVR_EN BIT(0)
#define AUDPKT_CONTROL1 0xe24
#define AUDPKT_ACR_CONTROL0 0xe40
#define AUDPKT_ACR_N_VALUE 0xfffff
#define AUDPKT_ACR_CONTROL1 0xe44
#define AUDPKT_ACR_CTS_OVR_VAL_MSK GENMASK(23, 4)
#define AUDPKT_ACR_CTS_OVR_VAL(x) ((x) << 4)
#define AUDPKT_ACR_CTS_OVR_EN_MSK BIT(1)
#define AUDPKT_ACR_CTS_OVR_EN BIT(1)
#define AUDPKT_ACR_STATUS0 0xe4c
#define AUDPKT_CHSTATUS_OVR0 0xe60
#define AUDPKT_CHSTATUS_OVR1 0xe64
/* IEC60958 Byte 3: Sampleing frenuency Bits 24 to 27 */
#define AUDPKT_CHSTATUS_SR_MASK GENMASK(3, 0)
#define AUDPKT_CHSTATUS_SR_22050 0x4
#define AUDPKT_CHSTATUS_SR_24000 0x6
#define AUDPKT_CHSTATUS_SR_32000 0x3
#define AUDPKT_CHSTATUS_SR_44100 0x0
#define AUDPKT_CHSTATUS_SR_48000 0x2
#define AUDPKT_CHSTATUS_SR_88200 0x8
#define AUDPKT_CHSTATUS_SR_96000 0xa
#define AUDPKT_CHSTATUS_SR_176400 0xc
#define AUDPKT_CHSTATUS_SR_192000 0xe
#define AUDPKT_CHSTATUS_SR_768000 0x9
#define AUDPKT_CHSTATUS_SR_NOT_INDICATED 0x1
/* IEC60958 Byte 4: Original Sampleing frenuency Bits 36 to 39 */
#define AUDPKT_CHSTATUS_0SR_MASK GENMASK(15, 12)
#define AUDPKT_CHSTATUS_OSR_8000 0x6
#define AUDPKT_CHSTATUS_OSR_11025 0xa
#define AUDPKT_CHSTATUS_OSR_12000 0x2
#define AUDPKT_CHSTATUS_OSR_16000 0x8
#define AUDPKT_CHSTATUS_OSR_22050 0xb
#define AUDPKT_CHSTATUS_OSR_24000 0x9
#define AUDPKT_CHSTATUS_OSR_32000 0xc
#define AUDPKT_CHSTATUS_OSR_44100 0xf
#define AUDPKT_CHSTATUS_OSR_48000 0xd
#define AUDPKT_CHSTATUS_OSR_88200 0x7
#define AUDPKT_CHSTATUS_OSR_96000 0x5
#define AUDPKT_CHSTATUS_OSR_176400 0x3
#define AUDPKT_CHSTATUS_OSR_192000 0x1
#define AUDPKT_CHSTATUS_OSR_NOT_INDICATED 0x0
#define AUDPKT_CHSTATUS_OVR2 0xe68
#define AUDPKT_CHSTATUS_OVR3 0xe6c
#define AUDPKT_CHSTATUS_OVR4 0xe70
#define AUDPKT_CHSTATUS_OVR5 0xe74
#define AUDPKT_CHSTATUS_OVR6 0xe78
#define AUDPKT_CHSTATUS_OVR7 0xe7c
#define AUDPKT_CHSTATUS_OVR8 0xe80
#define AUDPKT_CHSTATUS_OVR9 0xe84
#define AUDPKT_CHSTATUS_OVR10 0xe88
#define AUDPKT_CHSTATUS_OVR11 0xe8c
#define AUDPKT_CHSTATUS_OVR12 0xe90
#define AUDPKT_CHSTATUS_OVR13 0xe94
#define AUDPKT_CHSTATUS_OVR14 0xe98
#define AUDPKT_USRDATA_OVR_MSG_GENERIC0 0xea0
#define AUDPKT_USRDATA_OVR_MSG_GENERIC1 0xea4
#define AUDPKT_USRDATA_OVR_MSG_GENERIC2 0xea8
#define AUDPKT_USRDATA_OVR_MSG_GENERIC3 0xeac
#define AUDPKT_USRDATA_OVR_MSG_GENERIC4 0xeb0
#define AUDPKT_USRDATA_OVR_MSG_GENERIC5 0xeb4
#define AUDPKT_USRDATA_OVR_MSG_GENERIC6 0xeb8
#define AUDPKT_USRDATA_OVR_MSG_GENERIC7 0xebc
#define AUDPKT_USRDATA_OVR_MSG_GENERIC8 0xec0
#define AUDPKT_USRDATA_OVR_MSG_GENERIC9 0xec4
#define AUDPKT_USRDATA_OVR_MSG_GENERIC10 0xec8
#define AUDPKT_USRDATA_OVR_MSG_GENERIC11 0xecc
#define AUDPKT_USRDATA_OVR_MSG_GENERIC12 0xed0
#define AUDPKT_USRDATA_OVR_MSG_GENERIC13 0xed4
#define AUDPKT_USRDATA_OVR_MSG_GENERIC14 0xed8
#define AUDPKT_USRDATA_OVR_MSG_GENERIC15 0xedc
#define AUDPKT_USRDATA_OVR_MSG_GENERIC16 0xee0
#define AUDPKT_USRDATA_OVR_MSG_GENERIC17 0xee4
#define AUDPKT_USRDATA_OVR_MSG_GENERIC18 0xee8
#define AUDPKT_USRDATA_OVR_MSG_GENERIC19 0xeec
#define AUDPKT_USRDATA_OVR_MSG_GENERIC20 0xef0
#define AUDPKT_USRDATA_OVR_MSG_GENERIC21 0xef4
#define AUDPKT_USRDATA_OVR_MSG_GENERIC22 0xef8
#define AUDPKT_USRDATA_OVR_MSG_GENERIC23 0xefc
#define AUDPKT_USRDATA_OVR_MSG_GENERIC24 0xf00
#define AUDPKT_USRDATA_OVR_MSG_GENERIC25 0xf04
#define AUDPKT_USRDATA_OVR_MSG_GENERIC26 0xf08
#define AUDPKT_USRDATA_OVR_MSG_GENERIC27 0xf0c
#define AUDPKT_USRDATA_OVR_MSG_GENERIC28 0xf10
#define AUDPKT_USRDATA_OVR_MSG_GENERIC29 0xf14
#define AUDPKT_USRDATA_OVR_MSG_GENERIC30 0xf18
#define AUDPKT_USRDATA_OVR_MSG_GENERIC31 0xf1c
#define AUDPKT_USRDATA_OVR_MSG_GENERIC32 0xf20
#define AUDPKT_VBIT_OVR0 0xf24
/* CEC Registers */
#define CEC_TX_CONTROL 0x1000
#define CEC_CTRL_CLEAR BIT(0)
#define CEC_CTRL_START BIT(0)
#define CEC_STATUS 0x1004
#define CEC_STAT_DONE BIT(0)
#define CEC_STAT_NACK BIT(1)
#define CEC_STAT_ARBLOST BIT(2)
#define CEC_STAT_LINE_ERR BIT(3)
#define CEC_STAT_RETRANS_FAIL BIT(4)
#define CEC_STAT_DISCARD BIT(5)
#define CEC_STAT_TX_BUSY BIT(8)
#define CEC_STAT_RX_BUSY BIT(9)
#define CEC_STAT_DRIVE_ERR BIT(10)
#define CEC_STAT_EOM BIT(11)
#define CEC_STAT_NOTIFY_ERR BIT(12)
#define CEC_CONFIG 0x1008
#define CEC_ADDR 0x100c
#define CEC_ADDR_BROADCAST BIT(15)
#define CEC_TX_COUNT 0x1020
#define CEC_TX_DATA3_0 0x1024
#define CEC_TX_DATA7_4 0x1028
#define CEC_TX_DATA11_8 0x102c
#define CEC_TX_DATA15_12 0x1030
#define CEC_RX_COUNT_STATUS 0x1040
#define CEC_RX_DATA3_0 0x1044
#define CEC_RX_DATA7_4 0x1048
#define CEC_RX_DATA11_8 0x104c
#define CEC_RX_DATA15_12 0x1050
#define CEC_LOCK_CONTROL 0x1054
#define CEC_RXQUAL_BITTIME_CONFIG 0x1060
#define CEC_RX_BITTIME_CONFIG 0x1064
#define CEC_TX_BITTIME_CONFIG 0x1068
/* eARC RX CMDC Registers */
#define EARCRX_CMDC_CONFIG0 0x1800
#define EARCRX_XACTREAD_STOP_CFG BIT(26)
#define EARCRX_XACTREAD_RETRY_CFG BIT(25)
#define EARCRX_CMDC_DSCVR_EARCVALID0_TO_DISC1 BIT(24)
#define EARCRX_CMDC_XACT_RESTART_EN BIT(18)
#define EARCRX_CMDC_CONFIG1 0x1804
#define EARCRX_CMDC_CONTROL 0x1808
#define EARCRX_CMDC_HEARTBEAT_LOSS_EN BIT(4)
#define EARCRX_CMDC_DISCOVERY_EN BIT(3)
#define EARCRX_CONNECTOR_HPD BIT(1)
#define EARCRX_CMDC_WHITELIST0_CONFIG 0x180c
#define EARCRX_CMDC_WHITELIST1_CONFIG 0x1810
#define EARCRX_CMDC_WHITELIST2_CONFIG 0x1814
#define EARCRX_CMDC_WHITELIST3_CONFIG 0x1818
#define EARCRX_CMDC_STATUS 0x181c
#define EARCRX_CMDC_XACT_INFO 0x1820
#define EARCRX_CMDC_XACT_ACTION 0x1824
#define EARCRX_CMDC_HEARTBEAT_RXSTAT_SE 0x1828
#define EARCRX_CMDC_HEARTBEAT_STATUS 0x182c
#define EARCRX_CMDC_XACT_WR0 0x1840
#define EARCRX_CMDC_XACT_WR1 0x1844
#define EARCRX_CMDC_XACT_WR2 0x1848
#define EARCRX_CMDC_XACT_WR3 0x184c
#define EARCRX_CMDC_XACT_WR4 0x1850
#define EARCRX_CMDC_XACT_WR5 0x1854
#define EARCRX_CMDC_XACT_WR6 0x1858
#define EARCRX_CMDC_XACT_WR7 0x185c
#define EARCRX_CMDC_XACT_WR8 0x1860
#define EARCRX_CMDC_XACT_WR9 0x1864
#define EARCRX_CMDC_XACT_WR10 0x1868
#define EARCRX_CMDC_XACT_WR11 0x186c
#define EARCRX_CMDC_XACT_WR12 0x1870
#define EARCRX_CMDC_XACT_WR13 0x1874
#define EARCRX_CMDC_XACT_WR14 0x1878
#define EARCRX_CMDC_XACT_WR15 0x187c
#define EARCRX_CMDC_XACT_WR16 0x1880
#define EARCRX_CMDC_XACT_WR17 0x1884
#define EARCRX_CMDC_XACT_WR18 0x1888
#define EARCRX_CMDC_XACT_WR19 0x188c
#define EARCRX_CMDC_XACT_WR20 0x1890
#define EARCRX_CMDC_XACT_WR21 0x1894
#define EARCRX_CMDC_XACT_WR22 0x1898
#define EARCRX_CMDC_XACT_WR23 0x189c
#define EARCRX_CMDC_XACT_WR24 0x18a0
#define EARCRX_CMDC_XACT_WR25 0x18a4
#define EARCRX_CMDC_XACT_WR26 0x18a8
#define EARCRX_CMDC_XACT_WR27 0x18ac
#define EARCRX_CMDC_XACT_WR28 0x18b0
#define EARCRX_CMDC_XACT_WR29 0x18b4
#define EARCRX_CMDC_XACT_WR30 0x18b8
#define EARCRX_CMDC_XACT_WR31 0x18bc
#define EARCRX_CMDC_XACT_WR32 0x18c0
#define EARCRX_CMDC_XACT_WR33 0x18c4
#define EARCRX_CMDC_XACT_WR34 0x18c8
#define EARCRX_CMDC_XACT_WR35 0x18cc
#define EARCRX_CMDC_XACT_WR36 0x18d0
#define EARCRX_CMDC_XACT_WR37 0x18d4
#define EARCRX_CMDC_XACT_WR38 0x18d8
#define EARCRX_CMDC_XACT_WR39 0x18dc
#define EARCRX_CMDC_XACT_WR40 0x18e0
#define EARCRX_CMDC_XACT_WR41 0x18e4
#define EARCRX_CMDC_XACT_WR42 0x18e8
#define EARCRX_CMDC_XACT_WR43 0x18ec
#define EARCRX_CMDC_XACT_WR44 0x18f0
#define EARCRX_CMDC_XACT_WR45 0x18f4
#define EARCRX_CMDC_XACT_WR46 0x18f8
#define EARCRX_CMDC_XACT_WR47 0x18fc
#define EARCRX_CMDC_XACT_WR48 0x1900
#define EARCRX_CMDC_XACT_WR49 0x1904
#define EARCRX_CMDC_XACT_WR50 0x1908
#define EARCRX_CMDC_XACT_WR51 0x190c
#define EARCRX_CMDC_XACT_WR52 0x1910
#define EARCRX_CMDC_XACT_WR53 0x1914
#define EARCRX_CMDC_XACT_WR54 0x1918
#define EARCRX_CMDC_XACT_WR55 0x191c
#define EARCRX_CMDC_XACT_WR56 0x1920
#define EARCRX_CMDC_XACT_WR57 0x1924
#define EARCRX_CMDC_XACT_WR58 0x1928
#define EARCRX_CMDC_XACT_WR59 0x192c
#define EARCRX_CMDC_XACT_WR60 0x1930
#define EARCRX_CMDC_XACT_WR61 0x1934
#define EARCRX_CMDC_XACT_WR62 0x1938
#define EARCRX_CMDC_XACT_WR63 0x193c
#define EARCRX_CMDC_XACT_WR64 0x1940
#define EARCRX_CMDC_XACT_RD0 0x1960
#define EARCRX_CMDC_XACT_RD1 0x1964
#define EARCRX_CMDC_XACT_RD2 0x1968
#define EARCRX_CMDC_XACT_RD3 0x196c
#define EARCRX_CMDC_XACT_RD4 0x1970
#define EARCRX_CMDC_XACT_RD5 0x1974
#define EARCRX_CMDC_XACT_RD6 0x1978
#define EARCRX_CMDC_XACT_RD7 0x197c
#define EARCRX_CMDC_XACT_RD8 0x1980
#define EARCRX_CMDC_XACT_RD9 0x1984
#define EARCRX_CMDC_XACT_RD10 0x1988
#define EARCRX_CMDC_XACT_RD11 0x198c
#define EARCRX_CMDC_XACT_RD12 0x1990
#define EARCRX_CMDC_XACT_RD13 0x1994
#define EARCRX_CMDC_XACT_RD14 0x1998
#define EARCRX_CMDC_XACT_RD15 0x199c
#define EARCRX_CMDC_XACT_RD16 0x19a0
#define EARCRX_CMDC_XACT_RD17 0x19a4
#define EARCRX_CMDC_XACT_RD18 0x19a8
#define EARCRX_CMDC_XACT_RD19 0x19ac
#define EARCRX_CMDC_XACT_RD20 0x19b0
#define EARCRX_CMDC_XACT_RD21 0x19b4
#define EARCRX_CMDC_XACT_RD22 0x19b8
#define EARCRX_CMDC_XACT_RD23 0x19bc
#define EARCRX_CMDC_XACT_RD24 0x19c0
#define EARCRX_CMDC_XACT_RD25 0x19c4
#define EARCRX_CMDC_XACT_RD26 0x19c8
#define EARCRX_CMDC_XACT_RD27 0x19cc
#define EARCRX_CMDC_XACT_RD28 0x19d0
#define EARCRX_CMDC_XACT_RD29 0x19d4
#define EARCRX_CMDC_XACT_RD30 0x19d8
#define EARCRX_CMDC_XACT_RD31 0x19dc
#define EARCRX_CMDC_XACT_RD32 0x19e0
#define EARCRX_CMDC_XACT_RD33 0x19e4
#define EARCRX_CMDC_XACT_RD34 0x19e8
#define EARCRX_CMDC_XACT_RD35 0x19ec
#define EARCRX_CMDC_XACT_RD36 0x19f0
#define EARCRX_CMDC_XACT_RD37 0x19f4
#define EARCRX_CMDC_XACT_RD38 0x19f8
#define EARCRX_CMDC_XACT_RD39 0x19fc
#define EARCRX_CMDC_XACT_RD40 0x1a00
#define EARCRX_CMDC_XACT_RD41 0x1a04
#define EARCRX_CMDC_XACT_RD42 0x1a08
#define EARCRX_CMDC_XACT_RD43 0x1a0c
#define EARCRX_CMDC_XACT_RD44 0x1a10
#define EARCRX_CMDC_XACT_RD45 0x1a14
#define EARCRX_CMDC_XACT_RD46 0x1a18
#define EARCRX_CMDC_XACT_RD47 0x1a1c
#define EARCRX_CMDC_XACT_RD48 0x1a20
#define EARCRX_CMDC_XACT_RD49 0x1a24
#define EARCRX_CMDC_XACT_RD50 0x1a28
#define EARCRX_CMDC_XACT_RD51 0x1a2c
#define EARCRX_CMDC_XACT_RD52 0x1a30
#define EARCRX_CMDC_XACT_RD53 0x1a34
#define EARCRX_CMDC_XACT_RD54 0x1a38
#define EARCRX_CMDC_XACT_RD55 0x1a3c
#define EARCRX_CMDC_XACT_RD56 0x1a40
#define EARCRX_CMDC_XACT_RD57 0x1a44
#define EARCRX_CMDC_XACT_RD58 0x1a48
#define EARCRX_CMDC_XACT_RD59 0x1a4c
#define EARCRX_CMDC_XACT_RD60 0x1a50
#define EARCRX_CMDC_XACT_RD61 0x1a54
#define EARCRX_CMDC_XACT_RD62 0x1a58
#define EARCRX_CMDC_XACT_RD63 0x1a5c
#define EARCRX_CMDC_XACT_RD64 0x1a60
#define EARCRX_CMDC_SYNC_CONFIG 0x1b00
/* eARC RX DMAC Registers */
#define EARCRX_DMAC_PHY_CONTROL 0x1c00
#define EARCRX_DMAC_CONFIG 0x1c08
#define EARCRX_DMAC_CONTROL0 0x1c0c
#define EARCRX_DMAC_AUDIO_EN BIT(1)
#define EARCRX_DMAC_EN BIT(0)
#define EARCRX_DMAC_CONTROL1 0x1c10
#define EARCRX_DMAC_STATUS 0x1c14
#define EARCRX_DMAC_CHSTATUS0 0x1c18
#define EARCRX_DMAC_CHSTATUS1 0x1c1c
#define EARCRX_DMAC_CHSTATUS2 0x1c20
#define EARCRX_DMAC_CHSTATUS3 0x1c24
#define EARCRX_DMAC_CHSTATUS4 0x1c28
#define EARCRX_DMAC_CHSTATUS5 0x1c2c
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC0 0x1c30
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC1 0x1c34
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC2 0x1c38
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC3 0x1c3c
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC4 0x1c40
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC5 0x1c44
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC6 0x1c48
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC7 0x1c4c
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC8 0x1c50
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC9 0x1c54
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC10 0x1c58
#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC11 0x1c5c
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT0 0x1c60
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT1 0x1c64
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT2 0x1c68
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT3 0x1c6c
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT4 0x1c70
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT5 0x1c74
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT6 0x1c78
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT7 0x1c7c
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT8 0x1c80
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT9 0x1c84
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT10 0x1c88
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT11 0x1c8c
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT0 0x1c90
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT1 0x1c94
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT2 0x1c98
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT3 0x1c9c
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT4 0x1ca0
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT5 0x1ca4
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT6 0x1ca8
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT7 0x1cac
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT8 0x1cb0
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT9 0x1cb4
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT10 0x1cb8
#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT11 0x1cbc
#define EARCRX_DMAC_USRDATA_MSG_GENERIC0 0x1cc0
#define EARCRX_DMAC_USRDATA_MSG_GENERIC1 0x1cc4
#define EARCRX_DMAC_USRDATA_MSG_GENERIC2 0x1cc8
#define EARCRX_DMAC_USRDATA_MSG_GENERIC3 0x1ccc
#define EARCRX_DMAC_USRDATA_MSG_GENERIC4 0x1cd0
#define EARCRX_DMAC_USRDATA_MSG_GENERIC5 0x1cd4
#define EARCRX_DMAC_USRDATA_MSG_GENERIC6 0x1cd8
#define EARCRX_DMAC_USRDATA_MSG_GENERIC7 0x1cdc
#define EARCRX_DMAC_USRDATA_MSG_GENERIC8 0x1ce0
#define EARCRX_DMAC_USRDATA_MSG_GENERIC9 0x1ce4
#define EARCRX_DMAC_USRDATA_MSG_GENERIC10 0x1ce8
#define EARCRX_DMAC_USRDATA_MSG_GENERIC11 0x1cec
#define EARCRX_DMAC_USRDATA_MSG_GENERIC12 0x1cf0
#define EARCRX_DMAC_USRDATA_MSG_GENERIC13 0x1cf4
#define EARCRX_DMAC_USRDATA_MSG_GENERIC14 0x1cf8
#define EARCRX_DMAC_USRDATA_MSG_GENERIC15 0x1cfc
#define EARCRX_DMAC_USRDATA_MSG_GENERIC16 0x1d00
#define EARCRX_DMAC_USRDATA_MSG_GENERIC17 0x1d04
#define EARCRX_DMAC_USRDATA_MSG_GENERIC18 0x1d08
#define EARCRX_DMAC_USRDATA_MSG_GENERIC19 0x1d0c
#define EARCRX_DMAC_USRDATA_MSG_GENERIC20 0x1d10
#define EARCRX_DMAC_USRDATA_MSG_GENERIC21 0x1d14
#define EARCRX_DMAC_USRDATA_MSG_GENERIC22 0x1d18
#define EARCRX_DMAC_USRDATA_MSG_GENERIC23 0x1d1c
#define EARCRX_DMAC_USRDATA_MSG_GENERIC24 0x1d20
#define EARCRX_DMAC_USRDATA_MSG_GENERIC25 0x1d24
#define EARCRX_DMAC_USRDATA_MSG_GENERIC26 0x1d28
#define EARCRX_DMAC_USRDATA_MSG_GENERIC27 0x1d2c
#define EARCRX_DMAC_USRDATA_MSG_GENERIC28 0x1d30
#define EARCRX_DMAC_USRDATA_MSG_GENERIC29 0x1d34
#define EARCRX_DMAC_USRDATA_MSG_GENERIC30 0x1d38
#define EARCRX_DMAC_USRDATA_MSG_GENERIC31 0x1d3c
#define EARCRX_DMAC_USRDATA_MSG_GENERIC32 0x1d40
#define EARCRX_DMAC_CHSTATUS_STREAMER0 0x1d44
#define EARCRX_DMAC_CHSTATUS_STREAMER1 0x1d48
#define EARCRX_DMAC_CHSTATUS_STREAMER2 0x1d4c
#define EARCRX_DMAC_CHSTATUS_STREAMER3 0x1d50
#define EARCRX_DMAC_CHSTATUS_STREAMER4 0x1d54
#define EARCRX_DMAC_CHSTATUS_STREAMER5 0x1d58
#define EARCRX_DMAC_CHSTATUS_STREAMER6 0x1d5c
#define EARCRX_DMAC_CHSTATUS_STREAMER7 0x1d60
#define EARCRX_DMAC_CHSTATUS_STREAMER8 0x1d64
#define EARCRX_DMAC_CHSTATUS_STREAMER9 0x1d68
#define EARCRX_DMAC_CHSTATUS_STREAMER10 0x1d6c
#define EARCRX_DMAC_CHSTATUS_STREAMER11 0x1d70
#define EARCRX_DMAC_CHSTATUS_STREAMER12 0x1d74
#define EARCRX_DMAC_CHSTATUS_STREAMER13 0x1d78
#define EARCRX_DMAC_CHSTATUS_STREAMER14 0x1d7c
#define EARCRX_DMAC_USRDATA_STREAMER0 0x1d80
/* Main Unit Interrupt Registers */
#define MAIN_INTVEC_INDEX 0x3000
#define MAINUNIT_0_INT_STATUS 0x3010
#define MAINUNIT_0_INT_MASK_N 0x3014
#define MAINUNIT_0_INT_CLEAR 0x3018
#define MAINUNIT_0_INT_FORCE 0x301c
#define MAINUNIT_1_INT_STATUS 0x3020
#define FLT_EXIT_TO_LTSL_IRQ BIT(22)
#define FLT_EXIT_TO_LTS4_IRQ BIT(21)
#define FLT_EXIT_TO_LTSP_IRQ BIT(20)
#define SCDC_NACK_RCVD_IRQ BIT(12)
#define SCDC_RR_REPLY_STOP_IRQ BIT(11)
#define SCDC_UPD_FLAGS_CLR_IRQ BIT(10)
#define SCDC_UPD_FLAGS_CHG_IRQ BIT(9)
#define SCDC_UPD_FLAGS_RD_IRQ BIT(8)
#define I2CM_NACK_RCVD_IRQ BIT(2)
#define I2CM_READ_REQUEST_IRQ BIT(1)
#define I2CM_OP_DONE_IRQ BIT(0)
#define MAINUNIT_1_INT_MASK_N 0x3024
#define I2CM_NACK_RCVD_MASK_N BIT(2)
#define I2CM_READ_REQUEST_MASK_N BIT(1)
#define I2CM_OP_DONE_MASK_N BIT(0)
#define MAINUNIT_1_INT_CLEAR 0x3028
#define I2CM_NACK_RCVD_CLEAR BIT(2)
#define I2CM_READ_REQUEST_CLEAR BIT(1)
#define I2CM_OP_DONE_CLEAR BIT(0)
#define MAINUNIT_1_INT_FORCE 0x302c
/* AVPUNIT Interrupt Registers */
#define AVP_INTVEC_INDEX 0x3800
#define AVP_0_INT_STATUS 0x3810
#define AVP_0_INT_MASK_N 0x3814
#define AVP_0_INT_CLEAR 0x3818
#define AVP_0_INT_FORCE 0x381c
#define AVP_1_INT_STATUS 0x3820
#define AVP_1_INT_MASK_N 0x3824
#define HDCP14_AUTH_CHG_MASK_N BIT(6)
#define AVP_1_INT_CLEAR 0x3828
#define AVP_1_INT_FORCE 0x382c
#define AVP_2_INT_STATUS 0x3830
#define AVP_2_INT_MASK_N 0x3834
#define AVP_2_INT_CLEAR 0x3838
#define AVP_2_INT_FORCE 0x383c
#define AVP_3_INT_STATUS 0x3840
#define AVP_3_INT_MASK_N 0x3844
#define AVP_3_INT_CLEAR 0x3848
#define AVP_3_INT_FORCE 0x384c
#define AVP_4_INT_STATUS 0x3850
#define AVP_4_INT_MASK_N 0x3854
#define AVP_4_INT_CLEAR 0x3858
#define AVP_4_INT_FORCE 0x385c
#define AVP_5_INT_STATUS 0x3860
#define AVP_5_INT_MASK_N 0x3864
#define AVP_5_INT_CLEAR 0x3868
#define AVP_5_INT_FORCE 0x386c
#define AVP_6_INT_STATUS 0x3870
#define AVP_6_INT_MASK_N 0x3874
#define AVP_6_INT_CLEAR 0x3878
#define AVP_6_INT_FORCE 0x387c
/* CEC Interrupt Registers */
#define CEC_INT_STATUS 0x4000
#define CEC_INT_MASK_N 0x4004
#define CEC_INT_CLEAR 0x4008
#define CEC_INT_FORCE 0x400c
/* eARC RX Interrupt Registers */
#define EARCRX_INTVEC_INDEX 0x4800
#define EARCRX_0_INT_STATUS 0x4810
#define EARCRX_CMDC_DISCOVERY_TIMEOUT_IRQ BIT(9)
#define EARCRX_CMDC_DISCOVERY_DONE_IRQ BIT(8)
#define EARCRX_0_INT_MASK_N 0x4814
#define EARCRX_0_INT_CLEAR 0x4818
#define EARCRX_0_INT_FORCE 0x481c
#define EARCRX_1_INT_STATUS 0x4820
#define EARCRX_1_INT_MASK_N 0x4824
#define EARCRX_1_INT_CLEAR 0x4828
#define EARCRX_1_INT_FORCE 0x482c
#endif /* __DW_HDMI_QP_H__ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff