]>
Commit | Line | Data |
---|---|---|
6e442dd5 GKH |
1 | From b6e0e543f75729f207b9c72b0162ae61170635b2 Mon Sep 17 00:00:00 2001 |
2 | From: Daniel Vetter <daniel.vetter@ffwll.ch> | |
3 | Date: Sun, 21 Oct 2012 12:52:39 +0200 | |
4 | Subject: drm/i915: clear the entire sdvo infoframe buffer | |
5 | ||
6 | From: Daniel Vetter <daniel.vetter@ffwll.ch> | |
7 | ||
8 | commit b6e0e543f75729f207b9c72b0162ae61170635b2 upstream. | |
9 | ||
10 | Like in the case of native hdmi, which is fixed already in | |
11 | ||
12 | commit adf00b26d18e1b3570451296e03bcb20e4798cdd | |
13 | Author: Paulo Zanoni <paulo.r.zanoni@intel.com> | |
14 | Date: Tue Sep 25 13:23:34 2012 -0300 | |
15 | ||
16 | drm/i915: make sure we write all the DIP data bytes | |
17 | ||
18 | we need to clear the entire sdvo buffer to avoid upsetting the | |
19 | display. | |
20 | ||
21 | Since infoframe buffer writing is now a bit more elaborate, extract it | |
22 | into it's own function. This will be useful if we ever get around to | |
23 | properly update the ELD for sdvo. Also #define proper names for the | |
24 | two buffer indexes with fixed usage. | |
25 | ||
26 | v2: Cite the right commit above, spotted by Paulo Zanoni. | |
27 | ||
28 | v3: I'm too stupid to paste the right commit. | |
29 | ||
30 | v4: Ben Hutchings noticed that I've failed to handle an underflow in | |
31 | my loop logic, breaking it for i >= length + 8. Since I've just lost C | |
32 | programmer license, use his solution. Also, make the frustrated 0-base | |
33 | buffer size a notch more clear. | |
34 | ||
35 | Reported-and-tested-by: Jürg Billeter <j@bitron.ch> | |
36 | Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=25732 | |
37 | Cc: Paulo Zanoni <przanoni@gmail.com> | |
38 | Cc: Ben Hutchings <ben@decadent.org.uk> | |
39 | Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com> | |
40 | Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> | |
41 | Signed-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 |