drm/radeon/kms: i2c reorg
[safe/jmp/linux-2.6] / drivers / gpu / drm / radeon / atombios_dp.c
1 /*
2  * Copyright 2007-8 Advanced Micro Devices, Inc.
3  * Copyright 2008 Red Hat Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Authors: Dave Airlie
24  *          Alex Deucher
25  */
26 #include "drmP.h"
27 #include "radeon_drm.h"
28 #include "radeon.h"
29
30 #include "atom.h"
31 #include "atom-bits.h"
32 #include "drm_dp_helper.h"
33
34 #define DP_LINK_STATUS_SIZE     6
35
36 bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
37                            int num_bytes, u8 *read_byte,
38                            u8 read_buf_len, u8 delay)
39 {
40         struct drm_device *dev = chan->dev;
41         struct radeon_device *rdev = dev->dev_private;
42         PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args;
43         int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
44         unsigned char *base;
45
46         memset(&args, 0, sizeof(args));
47
48         base = (unsigned char *)rdev->mode_info.atom_context->scratch;
49
50         memcpy(base, req_bytes, num_bytes);
51
52         args.lpAuxRequest = 0;
53         args.lpDataOut = 16;
54         args.ucDataOutLen = 0;
55         args.ucChannelID = chan->rec.i2c_id;
56         args.ucDelay = delay / 10;
57
58         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
59
60         if (args.ucReplyStatus) {
61                 DRM_ERROR("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n",
62                           req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
63                           chan->rec.i2c_id, args.ucReplyStatus);
64                 return false;
65         }
66
67         if (args.ucDataOutLen && read_byte && read_buf_len) {
68                 if (read_buf_len < args.ucDataOutLen) {
69                         DRM_ERROR("Buffer to small for return answer %d %d\n",
70                                   read_buf_len, args.ucDataOutLen);
71                         return false;
72                 }
73                 {
74                         int len = min(read_buf_len, args.ucDataOutLen);
75                         memcpy(read_byte, base + 16, len);
76                 }
77         }
78         return true;
79 }
80
81 int radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock,
82                               uint8_t ucconfig, uint8_t lane_num)
83 {
84         DP_ENCODER_SERVICE_PARAMETERS args;
85         int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
86
87         memset(&args, 0, sizeof(args));
88         args.ucLinkClock = dp_clock / 10;
89         args.ucConfig = ucconfig;
90         args.ucAction = action;
91         args.ucLaneNum = lane_num;
92         args.ucStatus = 0;
93
94         atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
95         return args.ucStatus;
96 }
97
98 int radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
99 {
100         struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
101         struct drm_device *dev = radeon_connector->base.dev;
102         struct radeon_device *rdev = dev->dev_private;
103
104         return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
105                                          radeon_dig_connector->dp_i2c_bus->rec.i2c_id, 0);
106 }
107
108 union dig_transmitter_control {
109         DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
110         DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
111 };
112
113 bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address,
114                                 uint8_t send_bytes, uint8_t *send)
115 {
116         struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
117         struct drm_device *dev = radeon_connector->base.dev;
118         struct radeon_device *rdev = dev->dev_private;
119         u8 msg[20];
120         u8 msg_len, dp_msg_len;
121         bool ret;
122
123         dp_msg_len = 4;
124         msg[0] = address;
125         msg[1] = address >> 8;
126         msg[2] = AUX_NATIVE_WRITE << 4;
127         dp_msg_len += send_bytes;
128         msg[3] = (dp_msg_len << 4) | (send_bytes - 1);
129
130         if (send_bytes > 16)
131                 return false;
132
133         memcpy(&msg[4], send, send_bytes);
134         msg_len = 4 + send_bytes;
135         ret = radeon_process_aux_ch(radeon_dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0);
136         return ret;
137 }
138
139 bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address,
140                                uint8_t delay, uint8_t expected_bytes,
141                                uint8_t *read_p)
142 {
143         struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
144         struct drm_device *dev = radeon_connector->base.dev;
145         struct radeon_device *rdev = dev->dev_private;
146         u8 msg[20];
147         u8 msg_len, dp_msg_len;
148         bool ret = false;
149         msg_len = 4;
150         dp_msg_len = 4;
151         msg[0] = address;
152         msg[1] = address >> 8;
153         msg[2] = AUX_NATIVE_READ << 4;
154         msg[3] = (dp_msg_len) << 4;
155         msg[3] |= expected_bytes - 1;
156
157         ret = radeon_process_aux_ch(radeon_dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay);
158         return ret;
159 }
160
161 void radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
162 {
163         struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
164         u8 msg[25];
165         int ret;
166
167         ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg);
168         if (ret) {
169                 memcpy(radeon_dig_connector->dpcd, msg, 8);
170                 {
171                         int i;
172                         printk("DPCD: ");
173                         for (i = 0; i < 8; i++)
174                                 printk("%02x ", msg[i]);
175                         printk("\n");
176                 }
177         }
178         radeon_dig_connector->dpcd[0] = 0;
179         return;
180 }
181
182 static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
183                                     u8 link_status[DP_LINK_STATUS_SIZE])
184 {
185         int ret;
186         ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100,
187                                         DP_LINK_STATUS_SIZE, link_status);
188         if (!ret) {
189                 DRM_ERROR("displayport link status failed\n");
190                 return false;
191         }
192
193         DRM_INFO("link status %02x %02x %02x %02x %02x %02x\n",
194                  link_status[0], link_status[1], link_status[2],
195                  link_status[3], link_status[4], link_status[5]);
196         return true;
197 }
198
199 static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
200 {
201         struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
202         if (radeon_dig_connector->dpcd[0] >= 0x11) {
203                 radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1,
204                                            &power_state);
205         }
206 }
207
208 static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector,
209                                 u8 train_set[4])
210 {
211         struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
212
213 //      radeon_dp_digtransmitter_setup_vsemph();
214         radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET,
215                                    0/* lc */, train_set);
216 }
217
218 static void dp_set_training(struct radeon_connector *radeon_connector,
219                             u8 training)
220 {
221         radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET,
222                                    1, &training);
223 }
224
225 int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
226                          uint8_t write_byte, uint8_t *read_byte)
227 {
228         struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
229         struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter;
230         int ret = 0;
231         uint16_t address = algo_data->address;
232         uint8_t msg[5];
233         uint8_t reply[2];
234         int msg_len, dp_msg_len;
235         int reply_bytes;
236
237         /* Set up the command byte */
238         if (mode & MODE_I2C_READ)
239                 msg[2] = AUX_I2C_READ << 4;
240         else
241                 msg[2] = AUX_I2C_WRITE << 4;
242
243         if (!(mode & MODE_I2C_STOP))
244                 msg[2] |= AUX_I2C_MOT << 4;
245
246         msg[0] = address;
247         msg[1] = address >> 8;
248
249         reply_bytes = 1;
250
251         msg_len = 4;
252         dp_msg_len = 3;
253         switch (mode) {
254         case MODE_I2C_WRITE:
255                 msg[4] = write_byte;
256                 msg_len++;
257                 dp_msg_len += 2;
258                 break;
259         case MODE_I2C_READ:
260                 dp_msg_len += 1;
261                 break;
262         default:
263                 break;
264         }
265
266         msg[3] = (dp_msg_len) << 4;
267         ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0);
268
269         if (ret) {
270                 if (read_byte)
271                         *read_byte = reply[0];
272                 return reply_bytes;
273         }
274         return -EREMOTEIO;
275 }