aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/omap2/dss/hdmi.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 76e1142e4b6f..0b209d38a106 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -1274,6 +1274,221 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
1274 mutex_unlock(&hdmi.lock); 1274 mutex_unlock(&hdmi.lock);
1275} 1275}
1276 1276
1277#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1278 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1279static void hdmi_wp_audio_config_format(
1280 struct hdmi_audio_format *aud_fmt)
1281{
1282 u32 r;
1283
1284 DSSDBG("Enter hdmi_wp_audio_config_format\n");
1285
1286 r = hdmi_read_reg(HDMI_WP_AUDIO_CFG);
1287 r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
1288 r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
1289 r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
1290 r = FLD_MOD(r, aud_fmt->type, 4, 4);
1291 r = FLD_MOD(r, aud_fmt->justification, 3, 3);
1292 r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
1293 r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
1294 r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
1295 hdmi_write_reg(HDMI_WP_AUDIO_CFG, r);
1296}
1297
1298static void hdmi_wp_audio_config_dma(struct hdmi_audio_dma *aud_dma)
1299{
1300 u32 r;
1301
1302 DSSDBG("Enter hdmi_wp_audio_config_dma\n");
1303
1304 r = hdmi_read_reg(HDMI_WP_AUDIO_CFG2);
1305 r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
1306 r = FLD_MOD(r, aud_dma->block_size, 7, 0);
1307 hdmi_write_reg(HDMI_WP_AUDIO_CFG2, r);
1308
1309 r = hdmi_read_reg(HDMI_WP_AUDIO_CTRL);
1310 r = FLD_MOD(r, aud_dma->mode, 9, 9);
1311 r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
1312 hdmi_write_reg(HDMI_WP_AUDIO_CTRL, r);
1313}
1314
1315static void hdmi_core_audio_config(struct hdmi_core_audio_config *cfg)
1316{
1317 u32 r;
1318
1319 /* audio clock recovery parameters */
1320 r = hdmi_read_reg(HDMI_CORE_AV_ACR_CTRL);
1321 r = FLD_MOD(r, cfg->use_mclk, 2, 2);
1322 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1323 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1324 hdmi_write_reg(HDMI_CORE_AV_ACR_CTRL, r);
1325
1326 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
1327 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
1328 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
1329
1330 if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
1331 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
1332 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
1333 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
1334 } else {
1335 /*
1336 * HDMI IP uses this configuration to divide the MCLK to
1337 * update CTS value.
1338 */
1339 REG_FLD_MOD(HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1340
1341 /* Configure clock for audio packets */
1342 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
1343 cfg->aud_par_busclk, 7, 0);
1344 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
1345 (cfg->aud_par_busclk >> 8), 7, 0);
1346 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
1347 (cfg->aud_par_busclk >> 16), 7, 0);
1348 }
1349
1350 /* Override of SPDIF sample frequency with value in I2S_CHST4 */
1351 REG_FLD_MOD(HDMI_CORE_AV_SPDIF_CTRL, cfg->fs_override, 1, 1);
1352
1353 /* I2S parameters */
1354 REG_FLD_MOD(HDMI_CORE_AV_I2S_CHST4, cfg->freq_sample, 3, 0);
1355
1356 r = hdmi_read_reg(HDMI_CORE_AV_I2S_IN_CTRL);
1357 r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7);
1358 r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
1359 r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5);
1360 r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4);
1361 r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3);
1362 r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
1363 r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
1364 r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
1365 hdmi_write_reg(HDMI_CORE_AV_I2S_IN_CTRL, r);
1366
1367 r = hdmi_read_reg(HDMI_CORE_AV_I2S_CHST5);
1368 r = FLD_MOD(r, cfg->freq_sample, 7, 4);
1369 r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1);
1370 r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0);
1371 hdmi_write_reg(HDMI_CORE_AV_I2S_CHST5, r);
1372
1373 REG_FLD_MOD(HDMI_CORE_AV_I2S_IN_LEN, cfg->i2s_cfg.in_length_bits, 3, 0);
1374
1375 /* Audio channels and mode parameters */
1376 REG_FLD_MOD(HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
1377 r = hdmi_read_reg(HDMI_CORE_AV_AUD_MODE);
1378 r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
1379 r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
1380 r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
1381 r = FLD_MOD(r, cfg->en_spdif, 1, 1);
1382 hdmi_write_reg(HDMI_CORE_AV_AUD_MODE, r);
1383}
1384
1385static void hdmi_core_audio_infoframe_config(
1386 struct hdmi_core_infoframe_audio *info_aud)
1387{
1388 u8 val;
1389 u8 sum = 0, checksum = 0;
1390
1391 /*
1392 * Set audio info frame type, version and length as
1393 * described in HDMI 1.4a Section 8.2.2 specification.
1394 * Checksum calculation is defined in Section 5.3.5.
1395 */
1396 hdmi_write_reg(HDMI_CORE_AV_AUDIO_TYPE, 0x84);
1397 hdmi_write_reg(HDMI_CORE_AV_AUDIO_VERS, 0x01);
1398 hdmi_write_reg(HDMI_CORE_AV_AUDIO_LEN, 0x0a);
1399 sum += 0x84 + 0x001 + 0x00a;
1400
1401 val = (info_aud->db1_coding_type << 4)
1402 | (info_aud->db1_channel_count - 1);
1403 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(0), val);
1404 sum += val;
1405
1406 val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size;
1407 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(1), val);
1408 sum += val;
1409
1410 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(2), 0x00);
1411
1412 val = info_aud->db4_channel_alloc;
1413 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(3), val);
1414 sum += val;
1415
1416 val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3);
1417 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(4), val);
1418 sum += val;
1419
1420 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
1421 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
1422 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
1423 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
1424 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
1425
1426 checksum = 0x100 - sum;
1427 hdmi_write_reg(HDMI_CORE_AV_AUDIO_CHSUM, checksum);
1428
1429 /*
1430 * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
1431 * is available.
1432 */
1433}
1434
1435static int hdmi_config_audio_acr(u32 sample_freq, u32 *n, u32 *cts)
1436{
1437 u32 r;
1438 u32 deep_color = 0;
1439 u32 pclk = hdmi.cfg.timings.timings.pixel_clock;
1440
1441 if (n == NULL || cts == NULL)
1442 return -EINVAL;
1443 /*
1444 * Obtain current deep color configuration. This needed
1445 * to calculate the TMDS clock based on the pixel clock.
1446 */
1447 r = REG_GET(HDMI_WP_VIDEO_CFG, 1, 0);
1448 switch (r) {
1449 case 1: /* No deep color selected */
1450 deep_color = 100;
1451 break;
1452 case 2: /* 10-bit deep color selected */
1453 deep_color = 125;
1454 break;
1455 case 3: /* 12-bit deep color selected */
1456 deep_color = 150;
1457 break;
1458 default:
1459 return -EINVAL;
1460 }
1461
1462 switch (sample_freq) {
1463 case 32000:
1464 if ((deep_color == 125) && ((pclk == 54054)
1465 || (pclk == 74250)))
1466 *n = 8192;
1467 else
1468 *n = 4096;
1469 break;
1470 case 44100:
1471 *n = 6272;
1472 break;
1473 case 48000:
1474 if ((deep_color == 125) && ((pclk == 54054)
1475 || (pclk == 74250)))
1476 *n = 8192;
1477 else
1478 *n = 6144;
1479 break;
1480 default:
1481 *n = 0;
1482 return -EINVAL;
1483 }
1484
1485 /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
1486 *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
1487
1488 return 0;
1489}
1490#endif
1491
1277/* HDMI HW IP initialisation */ 1492/* HDMI HW IP initialisation */
1278static int omapdss_hdmihw_probe(struct platform_device *pdev) 1493static int omapdss_hdmihw_probe(struct platform_device *pdev)
1279{ 1494{