Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 218339
b: refs/heads/master
c: 3c17fe4
h: refs/heads/master
i:
  218337: 226a705
  218335: b9eb63c
v: v3
  • Loading branch information
David Härdeman authored and Chris Wilson committed Oct 22, 2010
1 parent a6c5886 commit 8e41a79
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 106 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dc3f82c2e5c3f06e43855f417e4fcfc244383916
refs/heads/master: 3c17fe4b8f40a112a85758a9ab2aebf772bdd647
16 changes: 16 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,22 @@
#define LVDS_B0B3_POWER_DOWN (0 << 2)
#define LVDS_B0B3_POWER_UP (3 << 2)

/* Video Data Island Packet control */
#define VIDEO_DIP_DATA 0x61178
#define VIDEO_DIP_CTL 0x61170
#define VIDEO_DIP_ENABLE (1 << 31)
#define VIDEO_DIP_PORT_B (1 << 29)
#define VIDEO_DIP_PORT_C (2 << 29)
#define VIDEO_DIP_ENABLE_AVI (1 << 21)
#define VIDEO_DIP_ENABLE_VENDOR (2 << 21)
#define VIDEO_DIP_ENABLE_SPD (8 << 21)
#define VIDEO_DIP_SELECT_AVI (0 << 19)
#define VIDEO_DIP_SELECT_VENDOR (1 << 19)
#define VIDEO_DIP_SELECT_SPD (3 << 19)
#define VIDEO_DIP_FREQ_ONCE (0 << 16)
#define VIDEO_DIP_FREQ_VSYNC (1 << 16)
#define VIDEO_DIP_FREQ_2VSYNC (2 << 16)

/* Panel power sequencing */
#define PP_STATUS 0x61200
#define PP_ON (1 << 31)
Expand Down
33 changes: 33 additions & 0 deletions trunk/drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,38 @@ struct intel_crtc {
#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)

#define DIP_TYPE_AVI 0x82
#define DIP_VERSION_AVI 0x2
#define DIP_LEN_AVI 13

struct dip_infoframe {
uint8_t type; /* HB0 */
uint8_t ver; /* HB1 */
uint8_t len; /* HB2 - body len, not including checksum */
uint8_t ecc; /* Header ECC */
uint8_t checksum; /* PB0 */
union {
struct {
/* PB1 - Y 6:5, A 4:4, B 3:2, S 1:0 */
uint8_t Y_A_B_S;
/* PB2 - C 7:6, M 5:4, R 3:0 */
uint8_t C_M_R;
/* PB3 - ITC 7:7, EC 6:4, Q 3:2, SC 1:0 */
uint8_t ITC_EC_Q_SC;
/* PB4 - VIC 6:0 */
uint8_t VIC;
/* PB5 - PR 3:0 */
uint8_t PR;
/* PB6 to PB13 */
uint16_t top_bar_end;
uint16_t bottom_bar_start;
uint16_t left_bar_end;
uint16_t right_bar_start;
} avi;
uint8_t payload[27];
} __attribute__ ((packed)) body;
} __attribute__((packed));

static inline struct drm_crtc *
intel_get_crtc_for_pipe(struct drm_device *dev, int pipe)
{
Expand All @@ -200,6 +232,7 @@ extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus);

extern void intel_crt_init(struct drm_device *dev);
extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
extern void intel_dvo_init(struct drm_device *dev);
extern void intel_tv_init(struct drm_device *dev);
Expand Down
60 changes: 59 additions & 1 deletion trunk/drivers/gpu/drm/i915/intel_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,60 @@ static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector)
struct intel_hdmi, base);
}

void intel_dip_infoframe_csum(struct dip_infoframe *avi_if)
{
uint8_t *data = (uint8_t *)avi_if;
uint8_t sum = 0;
unsigned i;

avi_if->checksum = 0;
avi_if->ecc = 0;

for (i = 0; i < sizeof(*avi_if); i++)
sum += data[i];

avi_if->checksum = 0x100 - sum;
}

static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
{
struct dip_infoframe avi_if = {
.type = DIP_TYPE_AVI,
.ver = DIP_VERSION_AVI,
.len = DIP_LEN_AVI,
};
uint32_t *data = (uint32_t *)&avi_if;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
u32 port;
unsigned i;

if (!intel_hdmi->has_hdmi_sink)
return;

/* XXX first guess at handling video port, is this corrent? */
if (intel_hdmi->sdvox_reg == SDVOB)
port = VIDEO_DIP_PORT_B;
else if (intel_hdmi->sdvox_reg == SDVOC)
port = VIDEO_DIP_PORT_C;
else
return;

I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | port |
VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC);

intel_dip_infoframe_csum(&avi_if);
for (i = 0; i < sizeof(avi_if); i += 4) {
I915_WRITE(VIDEO_DIP_DATA, *data);
data++;
}

I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | port |
VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC |
VIDEO_DIP_ENABLE_AVI);
}

static void intel_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
Expand All @@ -79,8 +133,10 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
if (intel_hdmi->has_hdmi_sink && HAS_PCH_CPT(dev))
sdvox |= HDMI_MODE_SELECT;

if (intel_hdmi->has_audio)
if (intel_hdmi->has_audio) {
sdvox |= SDVO_AUDIO_ENABLE;
sdvox |= SDVO_NULL_PACKETS_DURING_VSYNC;
}

if (intel_crtc->pipe == 1) {
if (HAS_PCH_CPT(dev))
Expand All @@ -91,6 +147,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,

I915_WRITE(intel_hdmi->sdvox_reg, sdvox);
POSTING_READ(intel_hdmi->sdvox_reg);

intel_hdmi_set_avi_infoframe(encoder);
}

static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
Expand Down
126 changes: 22 additions & 104 deletions trunk/drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,115 +854,33 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
}
#endif

static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo,
int index,
uint8_t *data, int8_t size, uint8_t tx_rate)
{
uint8_t set_buf_index[2];

set_buf_index[0] = index;
set_buf_index[1] = 0;

if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX,
set_buf_index, 2))
return false;

for (; size > 0; size -= 8) {
if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8))
return false;

data += 8;
}

return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
}

static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
{
uint8_t csum = 0;
int i;

for (i = 0; i < size; i++)
csum += data[i];

return 0x100 - csum;
}

#define DIP_TYPE_AVI 0x82
#define DIP_VERSION_AVI 0x2
#define DIP_LEN_AVI 13

struct dip_infoframe {
uint8_t type;
uint8_t version;
uint8_t len;
uint8_t checksum;
union {
struct {
/* Packet Byte #1 */
uint8_t S:2;
uint8_t B:2;
uint8_t A:1;
uint8_t Y:2;
uint8_t rsvd1:1;
/* Packet Byte #2 */
uint8_t R:4;
uint8_t M:2;
uint8_t C:2;
/* Packet Byte #3 */
uint8_t SC:2;
uint8_t Q:2;
uint8_t EC:3;
uint8_t ITC:1;
/* Packet Byte #4 */
uint8_t VIC:7;
uint8_t rsvd2:1;
/* Packet Byte #5 */
uint8_t PR:4;
uint8_t rsvd3:4;
/* Packet Byte #6~13 */
uint16_t top_bar_end;
uint16_t bottom_bar_start;
uint16_t left_bar_end;
uint16_t right_bar_start;
} avi;
struct {
/* Packet Byte #1 */
uint8_t channel_count:3;
uint8_t rsvd1:1;
uint8_t coding_type:4;
/* Packet Byte #2 */
uint8_t sample_size:2; /* SS0, SS1 */
uint8_t sample_frequency:3;
uint8_t rsvd2:3;
/* Packet Byte #3 */
uint8_t coding_type_private:5;
uint8_t rsvd3:3;
/* Packet Byte #4 */
uint8_t channel_allocation;
/* Packet Byte #5 */
uint8_t rsvd4:3;
uint8_t level_shift:4;
uint8_t downmix_inhibit:1;
} audio;
uint8_t payload[28];
} __attribute__ ((packed)) u;
} __attribute__((packed));

static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
struct drm_display_mode * mode)
static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
{
struct dip_infoframe avi_if = {
.type = DIP_TYPE_AVI,
.version = DIP_VERSION_AVI,
.ver = DIP_VERSION_AVI,
.len = DIP_LEN_AVI,
};
uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
uint8_t set_buf_index[2] = { 1, 0 };
uint64_t *data = (uint64_t *)&avi_if;
unsigned i;

intel_dip_infoframe_csum(&avi_if);

if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX,
set_buf_index, 2))
return false;

for (i = 0; i < sizeof(avi_if); i += 8) {
if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA,
data, 8))
return false;
data++;
}

avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
4 + avi_if.len);
return intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if,
4 + avi_if.len,
SDVO_HBUF_TX_VSYNC);
return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE,
&tx_rate, 1);
}

static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
Expand Down Expand Up @@ -1116,7 +1034,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
return;

if (intel_sdvo->is_hdmi &&
!intel_sdvo_set_avi_infoframe(intel_sdvo, mode))
!intel_sdvo_set_avi_infoframe(intel_sdvo))
return;

if (intel_sdvo->is_tv &&
Expand Down

0 comments on commit 8e41a79

Please sign in to comment.