Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 251085
b: refs/heads/master
c: 82335c4
h: refs/heads/master
i:
  251083: 96525e5
v: v3
  • Loading branch information
Ricardo Neri authored and Tomi Valkeinen committed May 19, 2011
1 parent a1124fd commit 4bb731d
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5d8dbe4aa986526f9096bcdb27679c37f5c7b194
refs/heads/master: 82335c4cc2edf57afece9399441a7480c2a1b055
215 changes: 215 additions & 0 deletions trunk/drivers/video/omap2/dss/hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,221 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
mutex_unlock(&hdmi.lock);
}

#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
static void hdmi_wp_audio_config_format(
struct hdmi_audio_format *aud_fmt)
{
u32 r;

DSSDBG("Enter hdmi_wp_audio_config_format\n");

r = hdmi_read_reg(HDMI_WP_AUDIO_CFG);
r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
r = FLD_MOD(r, aud_fmt->type, 4, 4);
r = FLD_MOD(r, aud_fmt->justification, 3, 3);
r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
hdmi_write_reg(HDMI_WP_AUDIO_CFG, r);
}

static void hdmi_wp_audio_config_dma(struct hdmi_audio_dma *aud_dma)
{
u32 r;

DSSDBG("Enter hdmi_wp_audio_config_dma\n");

r = hdmi_read_reg(HDMI_WP_AUDIO_CFG2);
r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
r = FLD_MOD(r, aud_dma->block_size, 7, 0);
hdmi_write_reg(HDMI_WP_AUDIO_CFG2, r);

r = hdmi_read_reg(HDMI_WP_AUDIO_CTRL);
r = FLD_MOD(r, aud_dma->mode, 9, 9);
r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
hdmi_write_reg(HDMI_WP_AUDIO_CTRL, r);
}

static void hdmi_core_audio_config(struct hdmi_core_audio_config *cfg)
{
u32 r;

/* audio clock recovery parameters */
r = hdmi_read_reg(HDMI_CORE_AV_ACR_CTRL);
r = FLD_MOD(r, cfg->use_mclk, 2, 2);
r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
r = FLD_MOD(r, cfg->cts_mode, 0, 0);
hdmi_write_reg(HDMI_CORE_AV_ACR_CTRL, r);

REG_FLD_MOD(HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
REG_FLD_MOD(HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
REG_FLD_MOD(HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);

if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
} else {
/*
* HDMI IP uses this configuration to divide the MCLK to
* update CTS value.
*/
REG_FLD_MOD(HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);

/* Configure clock for audio packets */
REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
cfg->aud_par_busclk, 7, 0);
REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
(cfg->aud_par_busclk >> 8), 7, 0);
REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
(cfg->aud_par_busclk >> 16), 7, 0);
}

/* Override of SPDIF sample frequency with value in I2S_CHST4 */
REG_FLD_MOD(HDMI_CORE_AV_SPDIF_CTRL, cfg->fs_override, 1, 1);

/* I2S parameters */
REG_FLD_MOD(HDMI_CORE_AV_I2S_CHST4, cfg->freq_sample, 3, 0);

r = hdmi_read_reg(HDMI_CORE_AV_I2S_IN_CTRL);
r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7);
r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5);
r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4);
r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3);
r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
hdmi_write_reg(HDMI_CORE_AV_I2S_IN_CTRL, r);

r = hdmi_read_reg(HDMI_CORE_AV_I2S_CHST5);
r = FLD_MOD(r, cfg->freq_sample, 7, 4);
r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1);
r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0);
hdmi_write_reg(HDMI_CORE_AV_I2S_CHST5, r);

REG_FLD_MOD(HDMI_CORE_AV_I2S_IN_LEN, cfg->i2s_cfg.in_length_bits, 3, 0);

/* Audio channels and mode parameters */
REG_FLD_MOD(HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
r = hdmi_read_reg(HDMI_CORE_AV_AUD_MODE);
r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
r = FLD_MOD(r, cfg->en_spdif, 1, 1);
hdmi_write_reg(HDMI_CORE_AV_AUD_MODE, r);
}

static void hdmi_core_audio_infoframe_config(
struct hdmi_core_infoframe_audio *info_aud)
{
u8 val;
u8 sum = 0, checksum = 0;

/*
* Set audio info frame type, version and length as
* described in HDMI 1.4a Section 8.2.2 specification.
* Checksum calculation is defined in Section 5.3.5.
*/
hdmi_write_reg(HDMI_CORE_AV_AUDIO_TYPE, 0x84);
hdmi_write_reg(HDMI_CORE_AV_AUDIO_VERS, 0x01);
hdmi_write_reg(HDMI_CORE_AV_AUDIO_LEN, 0x0a);
sum += 0x84 + 0x001 + 0x00a;

val = (info_aud->db1_coding_type << 4)
| (info_aud->db1_channel_count - 1);
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(0), val);
sum += val;

val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size;
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(1), val);
sum += val;

hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(2), 0x00);

val = info_aud->db4_channel_alloc;
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(3), val);
sum += val;

val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3);
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(4), val);
sum += val;

hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(9), 0x00);

checksum = 0x100 - sum;
hdmi_write_reg(HDMI_CORE_AV_AUDIO_CHSUM, checksum);

/*
* TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
* is available.
*/
}

static int hdmi_config_audio_acr(u32 sample_freq, u32 *n, u32 *cts)
{
u32 r;
u32 deep_color = 0;
u32 pclk = hdmi.cfg.timings.timings.pixel_clock;

if (n == NULL || cts == NULL)
return -EINVAL;
/*
* Obtain current deep color configuration. This needed
* to calculate the TMDS clock based on the pixel clock.
*/
r = REG_GET(HDMI_WP_VIDEO_CFG, 1, 0);
switch (r) {
case 1: /* No deep color selected */
deep_color = 100;
break;
case 2: /* 10-bit deep color selected */
deep_color = 125;
break;
case 3: /* 12-bit deep color selected */
deep_color = 150;
break;
default:
return -EINVAL;
}

switch (sample_freq) {
case 32000:
if ((deep_color == 125) && ((pclk == 54054)
|| (pclk == 74250)))
*n = 8192;
else
*n = 4096;
break;
case 44100:
*n = 6272;
break;
case 48000:
if ((deep_color == 125) && ((pclk == 54054)
|| (pclk == 74250)))
*n = 8192;
else
*n = 6144;
break;
default:
*n = 0;
return -EINVAL;
}

/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
*cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);

return 0;
}
#endif

/* HDMI HW IP initialisation */
static int omapdss_hdmihw_probe(struct platform_device *pdev)
{
Expand Down

0 comments on commit 4bb731d

Please sign in to comment.