diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_i2c.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_i2c.c | 182 |
1 files changed, 141 insertions, 41 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index dd438d32e5c0..da3da1e89d00 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -59,35 +59,43 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) | |||
59 | } | 59 | } |
60 | 60 | ||
61 | 61 | ||
62 | void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state) | 62 | void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) |
63 | { | 63 | { |
64 | struct radeon_device *rdev = radeon_connector->base.dev->dev_private; | 64 | struct radeon_device *rdev = i2c->dev->dev_private; |
65 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | ||
65 | uint32_t temp; | 66 | uint32_t temp; |
66 | struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec; | ||
67 | 67 | ||
68 | /* RV410 appears to have a bug where the hw i2c in reset | 68 | /* RV410 appears to have a bug where the hw i2c in reset |
69 | * holds the i2c port in a bad state - switch hw i2c away before | 69 | * holds the i2c port in a bad state - switch hw i2c away before |
70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake | 70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake |
71 | */ | 71 | */ |
72 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { | 72 | if (rec->hw_capable) { |
73 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { | 73 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { |
74 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 74 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { |
75 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); | 75 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | |
76 | } else { | 76 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); |
77 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 77 | } else { |
78 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | 78 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | |
79 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | ||
80 | } | ||
79 | } | 81 | } |
80 | } | 82 | } |
81 | if (lock_state) { | ||
82 | temp = RREG32(rec->a_clk_reg); | ||
83 | temp &= ~(rec->a_clk_mask); | ||
84 | WREG32(rec->a_clk_reg, temp); | ||
85 | |||
86 | temp = RREG32(rec->a_data_reg); | ||
87 | temp &= ~(rec->a_data_mask); | ||
88 | WREG32(rec->a_data_reg, temp); | ||
89 | } | ||
90 | 83 | ||
84 | /* clear the output pin values */ | ||
85 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; | ||
86 | WREG32(rec->a_clk_reg, temp); | ||
87 | |||
88 | temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; | ||
89 | WREG32(rec->a_data_reg, temp); | ||
90 | |||
91 | /* set the pins to input */ | ||
92 | temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; | ||
93 | WREG32(rec->en_clk_reg, temp); | ||
94 | |||
95 | temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; | ||
96 | WREG32(rec->en_data_reg, temp); | ||
97 | |||
98 | /* mask the gpio pins for software use */ | ||
91 | temp = RREG32(rec->mask_clk_reg); | 99 | temp = RREG32(rec->mask_clk_reg); |
92 | if (lock_state) | 100 | if (lock_state) |
93 | temp |= rec->mask_clk_mask; | 101 | temp |= rec->mask_clk_mask; |
@@ -112,8 +120,9 @@ static int get_clock(void *i2c_priv) | |||
112 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 120 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
113 | uint32_t val; | 121 | uint32_t val; |
114 | 122 | ||
115 | val = RREG32(rec->get_clk_reg); | 123 | /* read the value off the pin */ |
116 | val &= rec->get_clk_mask; | 124 | val = RREG32(rec->y_clk_reg); |
125 | val &= rec->y_clk_mask; | ||
117 | 126 | ||
118 | return (val != 0); | 127 | return (val != 0); |
119 | } | 128 | } |
@@ -126,8 +135,10 @@ static int get_data(void *i2c_priv) | |||
126 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 135 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
127 | uint32_t val; | 136 | uint32_t val; |
128 | 137 | ||
129 | val = RREG32(rec->get_data_reg); | 138 | /* read the value off the pin */ |
130 | val &= rec->get_data_mask; | 139 | val = RREG32(rec->y_data_reg); |
140 | val &= rec->y_data_mask; | ||
141 | |||
131 | return (val != 0); | 142 | return (val != 0); |
132 | } | 143 | } |
133 | 144 | ||
@@ -138,9 +149,10 @@ static void set_clock(void *i2c_priv, int clock) | |||
138 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 149 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
139 | uint32_t val; | 150 | uint32_t val; |
140 | 151 | ||
141 | val = RREG32(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask); | 152 | /* set pin direction */ |
142 | val |= clock ? 0 : rec->put_clk_mask; | 153 | val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; |
143 | WREG32(rec->put_clk_reg, val); | 154 | val |= clock ? 0 : rec->en_clk_mask; |
155 | WREG32(rec->en_clk_reg, val); | ||
144 | } | 156 | } |
145 | 157 | ||
146 | static void set_data(void *i2c_priv, int data) | 158 | static void set_data(void *i2c_priv, int data) |
@@ -150,14 +162,15 @@ static void set_data(void *i2c_priv, int data) | |||
150 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 162 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
151 | uint32_t val; | 163 | uint32_t val; |
152 | 164 | ||
153 | val = RREG32(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask); | 165 | /* set pin direction */ |
154 | val |= data ? 0 : rec->put_data_mask; | 166 | val = RREG32(rec->en_data_reg) & ~rec->en_data_mask; |
155 | WREG32(rec->put_data_reg, val); | 167 | val |= data ? 0 : rec->en_data_mask; |
168 | WREG32(rec->en_data_reg, val); | ||
156 | } | 169 | } |
157 | 170 | ||
158 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | 171 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
159 | struct radeon_i2c_bus_rec *rec, | 172 | struct radeon_i2c_bus_rec *rec, |
160 | const char *name) | 173 | const char *name) |
161 | { | 174 | { |
162 | struct radeon_i2c_chan *i2c; | 175 | struct radeon_i2c_chan *i2c; |
163 | int ret; | 176 | int ret; |
@@ -167,20 +180,19 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
167 | return NULL; | 180 | return NULL; |
168 | 181 | ||
169 | i2c->adapter.owner = THIS_MODULE; | 182 | i2c->adapter.owner = THIS_MODULE; |
170 | i2c->adapter.algo_data = &i2c->algo; | ||
171 | i2c->dev = dev; | 183 | i2c->dev = dev; |
172 | i2c->algo.setsda = set_data; | 184 | i2c_set_adapdata(&i2c->adapter, i2c); |
173 | i2c->algo.setscl = set_clock; | 185 | i2c->adapter.algo_data = &i2c->algo.bit; |
174 | i2c->algo.getsda = get_data; | 186 | i2c->algo.bit.setsda = set_data; |
175 | i2c->algo.getscl = get_clock; | 187 | i2c->algo.bit.setscl = set_clock; |
176 | i2c->algo.udelay = 20; | 188 | i2c->algo.bit.getsda = get_data; |
189 | i2c->algo.bit.getscl = get_clock; | ||
190 | i2c->algo.bit.udelay = 20; | ||
177 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | 191 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always |
178 | * make this, 2 jiffies is a lot more reliable */ | 192 | * make this, 2 jiffies is a lot more reliable */ |
179 | i2c->algo.timeout = 2; | 193 | i2c->algo.bit.timeout = 2; |
180 | i2c->algo.data = i2c; | 194 | i2c->algo.bit.data = i2c; |
181 | i2c->rec = *rec; | 195 | i2c->rec = *rec; |
182 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
183 | |||
184 | ret = i2c_bit_add_bus(&i2c->adapter); | 196 | ret = i2c_bit_add_bus(&i2c->adapter); |
185 | if (ret) { | 197 | if (ret) { |
186 | DRM_INFO("Failed to register i2c %s\n", name); | 198 | DRM_INFO("Failed to register i2c %s\n", name); |
@@ -194,6 +206,38 @@ out_free: | |||
194 | 206 | ||
195 | } | 207 | } |
196 | 208 | ||
209 | struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | ||
210 | struct radeon_i2c_bus_rec *rec, | ||
211 | const char *name) | ||
212 | { | ||
213 | struct radeon_i2c_chan *i2c; | ||
214 | int ret; | ||
215 | |||
216 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); | ||
217 | if (i2c == NULL) | ||
218 | return NULL; | ||
219 | |||
220 | i2c->rec = *rec; | ||
221 | i2c->adapter.owner = THIS_MODULE; | ||
222 | i2c->dev = dev; | ||
223 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
224 | i2c->adapter.algo_data = &i2c->algo.dp; | ||
225 | i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; | ||
226 | i2c->algo.dp.address = 0; | ||
227 | ret = i2c_dp_aux_add_bus(&i2c->adapter); | ||
228 | if (ret) { | ||
229 | DRM_INFO("Failed to register i2c %s\n", name); | ||
230 | goto out_free; | ||
231 | } | ||
232 | |||
233 | return i2c; | ||
234 | out_free: | ||
235 | kfree(i2c); | ||
236 | return NULL; | ||
237 | |||
238 | } | ||
239 | |||
240 | |||
197 | void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) | 241 | void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) |
198 | { | 242 | { |
199 | if (!i2c) | 243 | if (!i2c) |
@@ -207,3 +251,59 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) | |||
207 | { | 251 | { |
208 | return NULL; | 252 | return NULL; |
209 | } | 253 | } |
254 | |||
255 | void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus, | ||
256 | u8 slave_addr, | ||
257 | u8 addr, | ||
258 | u8 *val) | ||
259 | { | ||
260 | u8 out_buf[2]; | ||
261 | u8 in_buf[2]; | ||
262 | struct i2c_msg msgs[] = { | ||
263 | { | ||
264 | .addr = slave_addr, | ||
265 | .flags = 0, | ||
266 | .len = 1, | ||
267 | .buf = out_buf, | ||
268 | }, | ||
269 | { | ||
270 | .addr = slave_addr, | ||
271 | .flags = I2C_M_RD, | ||
272 | .len = 1, | ||
273 | .buf = in_buf, | ||
274 | } | ||
275 | }; | ||
276 | |||
277 | out_buf[0] = addr; | ||
278 | out_buf[1] = 0; | ||
279 | |||
280 | if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) { | ||
281 | *val = in_buf[0]; | ||
282 | DRM_DEBUG("val = 0x%02x\n", *val); | ||
283 | } else { | ||
284 | DRM_ERROR("i2c 0x%02x 0x%02x read failed\n", | ||
285 | addr, *val); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus, | ||
290 | u8 slave_addr, | ||
291 | u8 addr, | ||
292 | u8 val) | ||
293 | { | ||
294 | uint8_t out_buf[2]; | ||
295 | struct i2c_msg msg = { | ||
296 | .addr = slave_addr, | ||
297 | .flags = 0, | ||
298 | .len = 2, | ||
299 | .buf = out_buf, | ||
300 | }; | ||
301 | |||
302 | out_buf[0] = addr; | ||
303 | out_buf[1] = val; | ||
304 | |||
305 | if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) | ||
306 | DRM_ERROR("i2c 0x%02x 0x%02x write failed\n", | ||
307 | addr, val); | ||
308 | } | ||
309 | |||