diff options
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 215 |
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) | ||
1279 | static 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 | |||
1298 | static 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 | |||
1315 | static 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 | |||
1385 | static 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 | |||
1435 | static 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 */ |
1278 | static int omapdss_hdmihw_probe(struct platform_device *pdev) | 1493 | static int omapdss_hdmihw_probe(struct platform_device *pdev) |
1279 | { | 1494 | { |