aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRahul Sharma <rahul.sharma@samsung.com>2012-11-26 00:22:57 -0500
committerInki Dae <inki.dae@samsung.com>2012-12-05 00:39:23 -0500
commita144c2e9f17b738ac47716f1fb033cbfcfcde934 (patch)
tree8e7d0c97f1ebecf326f19de32770f868c2994522
parenta4d8de5f1b765aef577a9347f2166d61a5b0a2db (diff)
drm/exynos: sending AVI and AUI info frames
This patch adds code for composing AVI and AUI info frames and send them every VSYNC. This patch is important for hdmi certification. v3: - Moved enums, macros to exynos_hdmi.c. - Corrected hex format. - Added static to hdmi_reg_infoframe. v2: - Added few blank lines. - Corrected comments format. - Added comments for 2's Complement calculation for check sum. v1: - Remove un-necessary blank lines. - Change the case of hex constants. Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com> Signed-off-by: Fahad Kunnathadi <fahad.k@samsung.com> Signed-off-by: Shirish S <s.shirish@samsung.com> Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c165
-rw-r--r--drivers/gpu/drm/exynos/regs-hdmi.h17
2 files changed, 161 insertions, 21 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9f017748e730..bafb65389562 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -50,6 +50,29 @@
50#define MAX_HEIGHT 1080 50#define MAX_HEIGHT 1080
51#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) 51#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
52 52
53/* AVI header and aspect ratio */
54#define HDMI_AVI_VERSION 0x02
55#define HDMI_AVI_LENGTH 0x0D
56#define AVI_PIC_ASPECT_RATIO_16_9 (2 << 4)
57#define AVI_SAME_AS_PIC_ASPECT_RATIO 8
58
59/* AUI header info */
60#define HDMI_AUI_VERSION 0x01
61#define HDMI_AUI_LENGTH 0x0A
62
63/* HDMI infoframe to configure HDMI out packet header, AUI and AVI */
64enum HDMI_PACKET_TYPE {
65 /* refer to Table 5-8 Packet Type in HDMI specification v1.4a */
66 /* InfoFrame packet type */
67 HDMI_PACKET_TYPE_INFOFRAME = 0x80,
68 /* Vendor-Specific InfoFrame */
69 HDMI_PACKET_TYPE_VSI = HDMI_PACKET_TYPE_INFOFRAME + 1,
70 /* Auxiliary Video information InfoFrame */
71 HDMI_PACKET_TYPE_AVI = HDMI_PACKET_TYPE_INFOFRAME + 2,
72 /* Audio information InfoFrame */
73 HDMI_PACKET_TYPE_AUI = HDMI_PACKET_TYPE_INFOFRAME + 4
74};
75
53enum hdmi_type { 76enum hdmi_type {
54 HDMI_TYPE13, 77 HDMI_TYPE13,
55 HDMI_TYPE14, 78 HDMI_TYPE14,
@@ -182,6 +205,7 @@ struct hdmi_v13_conf {
182 int height; 205 int height;
183 int vrefresh; 206 int vrefresh;
184 bool interlace; 207 bool interlace;
208 int cea_video_id;
185 const u8 *hdmiphy_data; 209 const u8 *hdmiphy_data;
186 const struct hdmi_v13_preset_conf *conf; 210 const struct hdmi_v13_preset_conf *conf;
187}; 211};
@@ -353,15 +377,20 @@ static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
353}; 377};
354 378
355static const struct hdmi_v13_conf hdmi_v13_confs[] = { 379static const struct hdmi_v13_conf hdmi_v13_confs[] = {
356 { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 }, 380 { 1280, 720, 60, false, 4, hdmiphy_v13_conf74_25,
357 { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 }, 381 &hdmi_v13_conf_720p60 },
358 { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p }, 382 { 1280, 720, 50, false, 19, hdmiphy_v13_conf74_25,
359 { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 }, 383 &hdmi_v13_conf_720p60 },
360 { 1920, 1080, 50, false, hdmiphy_v13_conf148_5, 384 { 720, 480, 60, false, 3, hdmiphy_v13_conf27_027,
361 &hdmi_v13_conf_1080p50 }, 385 &hdmi_v13_conf_480p },
362 { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 }, 386 { 1920, 1080, 50, true, 20, hdmiphy_v13_conf74_25,
363 { 1920, 1080, 60, false, hdmiphy_v13_conf148_5, 387 &hdmi_v13_conf_1080i50 },
364 &hdmi_v13_conf_1080p60 }, 388 { 1920, 1080, 50, false, 31, hdmiphy_v13_conf148_5,
389 &hdmi_v13_conf_1080p50 },
390 { 1920, 1080, 60, true, 5, hdmiphy_v13_conf74_25,
391 &hdmi_v13_conf_1080i60 },
392 { 1920, 1080, 60, false, 16, hdmiphy_v13_conf148_5,
393 &hdmi_v13_conf_1080p60 },
365}; 394};
366 395
367/* HDMI Version 1.4 */ 396/* HDMI Version 1.4 */
@@ -479,6 +508,7 @@ struct hdmi_conf {
479 int height; 508 int height;
480 int vrefresh; 509 int vrefresh;
481 bool interlace; 510 bool interlace;
511 int cea_video_id;
482 const u8 *hdmiphy_data; 512 const u8 *hdmiphy_data;
483 const struct hdmi_preset_conf *conf; 513 const struct hdmi_preset_conf *conf;
484}; 514};
@@ -934,16 +964,21 @@ static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
934}; 964};
935 965
936static const struct hdmi_conf hdmi_confs[] = { 966static const struct hdmi_conf hdmi_confs[] = {
937 { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 }, 967 { 720, 480, 60, false, 3, hdmiphy_conf27_027, &hdmi_conf_480p60 },
938 { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 }, 968 { 1280, 720, 50, false, 19, hdmiphy_conf74_25, &hdmi_conf_720p50 },
939 { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 }, 969 { 1280, 720, 60, false, 4, hdmiphy_conf74_25, &hdmi_conf_720p60 },
940 { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 }, 970 { 1920, 1080, 50, true, 20, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
941 { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 }, 971 { 1920, 1080, 60, true, 5, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
942 { 1920, 1080, 30, false, hdmiphy_conf74_176, &hdmi_conf_1080p30 }, 972 { 1920, 1080, 30, false, 34, hdmiphy_conf74_176, &hdmi_conf_1080p30 },
943 { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 }, 973 { 1920, 1080, 50, false, 31, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
944 { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 }, 974 { 1920, 1080, 60, false, 16, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
945}; 975};
946 976
977struct hdmi_infoframe {
978 enum HDMI_PACKET_TYPE type;
979 u8 ver;
980 u8 len;
981};
947 982
948static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) 983static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
949{ 984{
@@ -1267,6 +1302,88 @@ static int hdmi_conf_index(struct hdmi_context *hdata,
1267 return hdmi_v14_conf_index(mode); 1302 return hdmi_v14_conf_index(mode);
1268} 1303}
1269 1304
1305static u8 hdmi_chksum(struct hdmi_context *hdata,
1306 u32 start, u8 len, u32 hdr_sum)
1307{
1308 int i;
1309
1310 /* hdr_sum : header0 + header1 + header2
1311 * start : start address of packet byte1
1312 * len : packet bytes - 1 */
1313 for (i = 0; i < len; ++i)
1314 hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4);
1315
1316 /* return 2's complement of 8 bit hdr_sum */
1317 return (u8)(~(hdr_sum & 0xff) + 1);
1318}
1319
1320static void hdmi_reg_infoframe(struct hdmi_context *hdata,
1321 struct hdmi_infoframe *infoframe)
1322{
1323 u32 hdr_sum;
1324 u8 chksum;
1325 u32 aspect_ratio;
1326 u32 mod;
1327 u32 vic;
1328
1329 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1330
1331 mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
1332 if (hdata->dvi_mode) {
1333 hdmi_reg_writeb(hdata, HDMI_VSI_CON,
1334 HDMI_VSI_CON_DO_NOT_TRANSMIT);
1335 hdmi_reg_writeb(hdata, HDMI_AVI_CON,
1336 HDMI_AVI_CON_DO_NOT_TRANSMIT);
1337 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
1338 return;
1339 }
1340
1341 switch (infoframe->type) {
1342 case HDMI_PACKET_TYPE_AVI:
1343 hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
1344 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->type);
1345 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, infoframe->ver);
1346 hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->len);
1347 hdr_sum = infoframe->type + infoframe->ver + infoframe->len;
1348
1349 /* Output format zero hardcoded ,RGB YBCR selection */
1350 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
1351 AVI_ACTIVE_FORMAT_VALID |
1352 AVI_UNDERSCANNED_DISPLAY_VALID);
1353
1354 aspect_ratio = AVI_PIC_ASPECT_RATIO_16_9;
1355
1356 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), aspect_ratio |
1357 AVI_SAME_AS_PIC_ASPECT_RATIO);
1358
1359 if (hdata->type == HDMI_TYPE13)
1360 vic = hdmi_v13_confs[hdata->cur_conf].cea_video_id;
1361 else
1362 vic = hdmi_confs[hdata->cur_conf].cea_video_id;
1363
1364 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic);
1365
1366 chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
1367 infoframe->len, hdr_sum);
1368 DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
1369 hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
1370 break;
1371 case HDMI_PACKET_TYPE_AUI:
1372 hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
1373 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->type);
1374 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, infoframe->ver);
1375 hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->len);
1376 hdr_sum = infoframe->type + infoframe->ver + infoframe->len;
1377 chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
1378 infoframe->len, hdr_sum);
1379 DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
1380 hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
1381 break;
1382 default:
1383 break;
1384 }
1385}
1386
1270static bool hdmi_is_connected(void *ctx) 1387static bool hdmi_is_connected(void *ctx)
1271{ 1388{
1272 struct hdmi_context *hdata = ctx; 1389 struct hdmi_context *hdata = ctx;
@@ -1542,6 +1659,8 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
1542 1659
1543static void hdmi_conf_init(struct hdmi_context *hdata) 1660static void hdmi_conf_init(struct hdmi_context *hdata)
1544{ 1661{
1662 struct hdmi_infoframe infoframe;
1663
1545 /* disable HPD interrupts */ 1664 /* disable HPD interrupts */
1546 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | 1665 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1547 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); 1666 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
@@ -1576,9 +1695,17 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
1576 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); 1695 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1577 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); 1696 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1578 } else { 1697 } else {
1698 infoframe.type = HDMI_PACKET_TYPE_AVI;
1699 infoframe.ver = HDMI_AVI_VERSION;
1700 infoframe.len = HDMI_AVI_LENGTH;
1701 hdmi_reg_infoframe(hdata, &infoframe);
1702
1703 infoframe.type = HDMI_PACKET_TYPE_AUI;
1704 infoframe.ver = HDMI_AUI_VERSION;
1705 infoframe.len = HDMI_AUI_LENGTH;
1706 hdmi_reg_infoframe(hdata, &infoframe);
1707
1579 /* enable AVI packet every vsync, fixes purple line problem */ 1708 /* enable AVI packet every vsync, fixes purple line problem */
1580 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1581 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1582 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5); 1709 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1583 } 1710 }
1584} 1711}
diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h
index 9cc7c5e9718c..970cdb518eb1 100644
--- a/drivers/gpu/drm/exynos/regs-hdmi.h
+++ b/drivers/gpu/drm/exynos/regs-hdmi.h
@@ -298,14 +298,14 @@
298#define HDMI_AVI_HEADER1 HDMI_CORE_BASE(0x0714) 298#define HDMI_AVI_HEADER1 HDMI_CORE_BASE(0x0714)
299#define HDMI_AVI_HEADER2 HDMI_CORE_BASE(0x0718) 299#define HDMI_AVI_HEADER2 HDMI_CORE_BASE(0x0718)
300#define HDMI_AVI_CHECK_SUM HDMI_CORE_BASE(0x071C) 300#define HDMI_AVI_CHECK_SUM HDMI_CORE_BASE(0x071C)
301#define HDMI_AVI_BYTE(n) HDMI_CORE_BASE(0x0720 + 4 * (n)) 301#define HDMI_AVI_BYTE(n) HDMI_CORE_BASE(0x0720 + 4 * (n-1))
302 302
303#define HDMI_AUI_CON HDMI_CORE_BASE(0x0800) 303#define HDMI_AUI_CON HDMI_CORE_BASE(0x0800)
304#define HDMI_AUI_HEADER0 HDMI_CORE_BASE(0x0810) 304#define HDMI_AUI_HEADER0 HDMI_CORE_BASE(0x0810)
305#define HDMI_AUI_HEADER1 HDMI_CORE_BASE(0x0814) 305#define HDMI_AUI_HEADER1 HDMI_CORE_BASE(0x0814)
306#define HDMI_AUI_HEADER2 HDMI_CORE_BASE(0x0818) 306#define HDMI_AUI_HEADER2 HDMI_CORE_BASE(0x0818)
307#define HDMI_AUI_CHECK_SUM HDMI_CORE_BASE(0x081C) 307#define HDMI_AUI_CHECK_SUM HDMI_CORE_BASE(0x081C)
308#define HDMI_AUI_BYTE(n) HDMI_CORE_BASE(0x0820 + 4 * (n)) 308#define HDMI_AUI_BYTE(n) HDMI_CORE_BASE(0x0820 + 4 * (n-1))
309 309
310#define HDMI_MPG_CON HDMI_CORE_BASE(0x0900) 310#define HDMI_MPG_CON HDMI_CORE_BASE(0x0900)
311#define HDMI_MPG_CHECK_SUM HDMI_CORE_BASE(0x091C) 311#define HDMI_MPG_CHECK_SUM HDMI_CORE_BASE(0x091C)
@@ -338,6 +338,19 @@
338#define HDMI_AN_SEED_2 HDMI_CORE_BASE(0x0E60) 338#define HDMI_AN_SEED_2 HDMI_CORE_BASE(0x0E60)
339#define HDMI_AN_SEED_3 HDMI_CORE_BASE(0x0E64) 339#define HDMI_AN_SEED_3 HDMI_CORE_BASE(0x0E64)
340 340
341/* AVI bit definition */
342#define HDMI_AVI_CON_DO_NOT_TRANSMIT (0 << 1)
343#define HDMI_AVI_CON_EVERY_VSYNC (1 << 1)
344
345#define AVI_ACTIVE_FORMAT_VALID (1 << 4)
346#define AVI_UNDERSCANNED_DISPLAY_VALID (1 << 1)
347
348/* AUI bit definition */
349#define HDMI_AUI_CON_NO_TRAN (0 << 0)
350
351/* VSI bit definition */
352#define HDMI_VSI_CON_DO_NOT_TRANSMIT (0 << 0)
353
341/* HDCP related registers */ 354/* HDCP related registers */
342#define HDMI_HDCP_SHA1(n) HDMI_CORE_BASE(0x7000 + 4 * (n)) 355#define HDMI_HDCP_SHA1(n) HDMI_CORE_BASE(0x7000 + 4 * (n))
343#define HDMI_HDCP_KSV_LIST(n) HDMI_CORE_BASE(0x7050 + 4 * (n)) 356#define HDMI_HDCP_KSV_LIST(n) HDMI_CORE_BASE(0x7050 + 4 * (n))