]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.6.7/drm-i915-clear-the-entire-sdvo-infoframe-buffer.patch
Linux 3.6.7
[thirdparty/kernel/stable-queue.git] / releases / 3.6.7 / drm-i915-clear-the-entire-sdvo-infoframe-buffer.patch
CommitLineData
6e442dd5
GKH
1From b6e0e543f75729f207b9c72b0162ae61170635b2 Mon Sep 17 00:00:00 2001
2From: Daniel Vetter <daniel.vetter@ffwll.ch>
3Date: Sun, 21 Oct 2012 12:52:39 +0200
4Subject: drm/i915: clear the entire sdvo infoframe buffer
5
6From: Daniel Vetter <daniel.vetter@ffwll.ch>
7
8commit b6e0e543f75729f207b9c72b0162ae61170635b2 upstream.
9
10Like in the case of native hdmi, which is fixed already in
11
12commit adf00b26d18e1b3570451296e03bcb20e4798cdd
13Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
14Date: Tue Sep 25 13:23:34 2012 -0300
15
16 drm/i915: make sure we write all the DIP data bytes
17
18we need to clear the entire sdvo buffer to avoid upsetting the
19display.
20
21Since infoframe buffer writing is now a bit more elaborate, extract it
22into it's own function. This will be useful if we ever get around to
23properly update the ELD for sdvo. Also #define proper names for the
24two buffer indexes with fixed usage.
25
26v2: Cite the right commit above, spotted by Paulo Zanoni.
27
28v3: I'm too stupid to paste the right commit.
29
30v4: Ben Hutchings noticed that I've failed to handle an underflow in
31my loop logic, breaking it for i >= length + 8. Since I've just lost C
32programmer license, use his solution. Also, make the frustrated 0-base
33buffer size a notch more clear.
34
35Reported-and-tested-by: Jürg Billeter <j@bitron.ch>
36Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25732
37Cc: Paulo Zanoni <przanoni@gmail.com>
38Cc: Ben Hutchings <ben@decadent.org.uk>
39Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com>
40Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
41Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
42
43---
44 drivers/gpu/drm/i915/intel_sdvo.c | 62 ++++++++++++++++++++++-----------
45 drivers/gpu/drm/i915/intel_sdvo_regs.h | 2 +
46 2 files changed, 44 insertions(+), 20 deletions(-)
47
48--- a/drivers/gpu/drm/i915/intel_sdvo.c
49+++ b/drivers/gpu/drm/i915/intel_sdvo.c
50@@ -882,6 +882,45 @@ static void intel_sdvo_dump_hdmi_buf(str
51 }
52 #endif
53
54+static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
55+ unsigned if_index, uint8_t tx_rate,
56+ uint8_t *data, unsigned length)
57+{
58+ uint8_t set_buf_index[2] = { if_index, 0 };
59+ uint8_t hbuf_size, tmp[8];
60+ int i;
61+
62+ if (!intel_sdvo_set_value(intel_sdvo,
63+ SDVO_CMD_SET_HBUF_INDEX,
64+ set_buf_index, 2))
65+ return false;
66+
67+ if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO,
68+ &hbuf_size, 1))
69+ return false;
70+
71+ /* Buffer size is 0 based, hooray! */
72+ hbuf_size++;
73+
74+ DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n",
75+ if_index, length, hbuf_size);
76+
77+ for (i = 0; i < hbuf_size; i += 8) {
78+ memset(tmp, 0, 8);
79+ if (i < length)
80+ memcpy(tmp, data + i, min_t(unsigned, 8, length - i));
81+
82+ if (!intel_sdvo_set_value(intel_sdvo,
83+ SDVO_CMD_SET_HBUF_DATA,
84+ tmp, 8))
85+ return false;
86+ }
87+
88+ return intel_sdvo_set_value(intel_sdvo,
89+ SDVO_CMD_SET_HBUF_TXRATE,
90+ &tx_rate, 1);
91+}
92+
93 static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
94 {
95 struct dip_infoframe avi_if = {
96@@ -889,11 +928,7 @@ static bool intel_sdvo_set_avi_infoframe
97 .ver = DIP_VERSION_AVI,
98 .len = DIP_LEN_AVI,
99 };
100- uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
101- uint8_t set_buf_index[2] = { 1, 0 };
102 uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
103- uint64_t *data = (uint64_t *)sdvo_data;
104- unsigned i;
105
106 intel_dip_infoframe_csum(&avi_if);
107
108@@ -903,22 +938,9 @@ static bool intel_sdvo_set_avi_infoframe
109 sdvo_data[3] = avi_if.checksum;
110 memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
111
112- if (!intel_sdvo_set_value(intel_sdvo,
113- SDVO_CMD_SET_HBUF_INDEX,
114- set_buf_index, 2))
115- return false;
116-
117- for (i = 0; i < sizeof(sdvo_data); i += 8) {
118- if (!intel_sdvo_set_value(intel_sdvo,
119- SDVO_CMD_SET_HBUF_DATA,
120- data, 8))
121- return false;
122- data++;
123- }
124-
125- return intel_sdvo_set_value(intel_sdvo,
126- SDVO_CMD_SET_HBUF_TXRATE,
127- &tx_rate, 1);
128+ return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
129+ SDVO_HBUF_TX_VSYNC,
130+ sdvo_data, sizeof(sdvo_data));
131 }
132
133 static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
134--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h
135+++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
136@@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg {
137 #define SDVO_CMD_SET_AUDIO_STAT 0x91
138 #define SDVO_CMD_GET_AUDIO_STAT 0x92
139 #define SDVO_CMD_SET_HBUF_INDEX 0x93
140+ #define SDVO_HBUF_INDEX_ELD 0
141+ #define SDVO_HBUF_INDEX_AVI_IF 1
142 #define SDVO_CMD_GET_HBUF_INDEX 0x94
143 #define SDVO_CMD_GET_HBUF_INFO 0x95
144 #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96