Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 282574
b: refs/heads/master
c: b2337f2
h: refs/heads/master
v: v3
  • Loading branch information
Ben Skeggs committed Dec 21, 2011
1 parent cedb076 commit 1531f3d
Show file tree
Hide file tree
Showing 2 changed files with 104 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: 52c7bcdb6749a3920739640ca791e1f741f139d0
refs/heads/master: b2337f2333c0bdefc9b230da17ed7188e4eb7f6c
103 changes: 103 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,107 @@ nouveau_audio_mode_set(struct drm_encoder *encoder,
}
}

static void
nouveau_hdmi_infoframe(struct drm_encoder *encoder, u32 ctrl, u8 *frame)
{
/* calculate checksum for the infoframe */
u8 sum = 0, i;
for (i = 0; i < frame[2]; i++)
sum += frame[i];
frame[3] = 256 - sum;

/* disable infoframe, and write header */
hdmi_mask(encoder, ctrl + 0x00, 0x00000001, 0x00000000);
hdmi_wr32(encoder, ctrl + 0x08, *(u32 *)frame & 0xffffff);

/* register scans tell me the audio infoframe has only one set of
* subpack regs, according to tegra (gee nvidia, it'd be nice if we
* could get those docs too!), the hdmi block pads out the rest of
* the packet on its own.
*/
if (ctrl == 0x020)
frame[2] = 6;

/* write out checksum and data, weird weird 7 byte register pairs */
for (i = 0; i < frame[2] + 1; i += 7) {
u32 rsubpack = ctrl + 0x0c + ((i / 7) * 8);
u32 *subpack = (u32 *)&frame[3 + i];
hdmi_wr32(encoder, rsubpack + 0, subpack[0]);
hdmi_wr32(encoder, rsubpack + 4, subpack[1] & 0xffffff);
}

/* enable the infoframe */
hdmi_mask(encoder, ctrl, 0x00000001, 0x00000001);
}

static void
nouveau_hdmi_video_infoframe(struct drm_encoder *encoder,
struct drm_display_mode *mode)
{
const u8 Y = 0, A = 0, B = 0, S = 0, C = 0, M = 0, R = 0;
const u8 ITC = 0, EC = 0, Q = 0, SC = 0, VIC = 0, PR = 0;
const u8 bar_top = 0, bar_bottom = 0, bar_left = 0, bar_right = 0;
u8 frame[20];

frame[0x00] = 0x82; /* AVI infoframe */
frame[0x01] = 0x02; /* version */
frame[0x02] = 0x0d; /* length */
frame[0x03] = 0x00;
frame[0x04] = (Y << 5) | (A << 4) | (B << 2) | S;
frame[0x05] = (C << 6) | (M << 4) | R;
frame[0x06] = (ITC << 7) | (EC << 4) | (Q << 2) | SC;
frame[0x07] = VIC;
frame[0x08] = PR;
frame[0x09] = bar_top & 0xff;
frame[0x0a] = bar_top >> 8;
frame[0x0b] = bar_bottom & 0xff;
frame[0x0c] = bar_bottom >> 8;
frame[0x0d] = bar_left & 0xff;
frame[0x0e] = bar_left >> 8;
frame[0x0f] = bar_right & 0xff;
frame[0x10] = bar_right >> 8;
frame[0x11] = 0x00;
frame[0x12] = 0x00;
frame[0x13] = 0x00;

nouveau_hdmi_infoframe(encoder, 0x020, frame);
}

static void
nouveau_hdmi_audio_infoframe(struct drm_encoder *encoder,
struct drm_display_mode *mode)
{
const u8 CT = 0x00, CC = 0x01, ceaSS = 0x00, SF = 0x00, FMT = 0x00;
const u8 CA = 0x00, DM_INH = 0, LSV = 0x00;
u8 frame[12];

frame[0x00] = 0x84; /* Audio infoframe */
frame[0x01] = 0x01; /* version */
frame[0x02] = 0x0a; /* length */
frame[0x03] = 0x00;
frame[0x04] = (CT << 4) | CC;
frame[0x05] = (SF << 2) | ceaSS;
frame[0x06] = FMT;
frame[0x07] = CA;
frame[0x08] = (DM_INH << 7) | (LSV << 3);
frame[0x09] = 0x00;
frame[0x0a] = 0x00;
frame[0x0b] = 0x00;

nouveau_hdmi_infoframe(encoder, 0x000, frame);
}

static void
nouveau_hdmi_disconnect(struct drm_encoder *encoder)
{
nouveau_audio_disconnect(encoder);

/* disable audio and avi infoframes */
hdmi_mask(encoder, 0x000, 0x00000001, 0x00000000);
hdmi_mask(encoder, 0x020, 0x00000001, 0x00000000);

/* disable hdmi */
hdmi_mask(encoder, 0x0a4, 0x40000000, 0x00000000);
}

void
Expand All @@ -130,5 +227,11 @@ nouveau_hdmi_mode_set(struct drm_encoder *encoder,
return;
}

/* enable hdmi */
hdmi_mask(encoder, 0x0a4, 0x40000000, 0x40000000);

nouveau_hdmi_video_infoframe(encoder, mode);
nouveau_hdmi_audio_infoframe(encoder, mode);

nouveau_audio_mode_set(encoder, mode);
}

0 comments on commit 1531f3d

Please sign in to comment.