aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-12-22 15:04:48 -0500
committerDave Airlie <airlied@redhat.com>2010-02-05 00:10:19 -0500
commit5a6f98f5bff7f975c61d56b5c756b5a96c4db167 (patch)
treefc02a4d8e8440279a51c32792fcf90e9046f6dc6 /drivers
parent5ff55717674470b96562f931f778c878080755b7 (diff)
drm/radeon/kms: add radeon i2c algo
Currently just a wrapper around bit algo Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c40
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c91
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h25
5 files changed, 102 insertions, 72 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index e7b19440102e..318afe83e6b0 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -2289,23 +2289,21 @@ void radeon_external_tmds_setup(struct drm_encoder *encoder)
2289 switch (tmds->dvo_chip) { 2289 switch (tmds->dvo_chip) {
2290 case DVO_SIL164: 2290 case DVO_SIL164:
2291 /* sil 164 */ 2291 /* sil 164 */
2292 radeon_i2c_do_lock(tmds->i2c_bus, 1); 2292 radeon_i2c_put_byte(tmds->i2c_bus,
2293 radeon_i2c_sw_put_byte(tmds->i2c_bus, 2293 tmds->slave_addr,
2294 tmds->slave_addr, 2294 0x08, 0x30);
2295 0x08, 0x30); 2295 radeon_i2c_put_byte(tmds->i2c_bus,
2296 radeon_i2c_sw_put_byte(tmds->i2c_bus,
2297 tmds->slave_addr, 2296 tmds->slave_addr,
2298 0x09, 0x00); 2297 0x09, 0x00);
2299 radeon_i2c_sw_put_byte(tmds->i2c_bus, 2298 radeon_i2c_put_byte(tmds->i2c_bus,
2300 tmds->slave_addr, 2299 tmds->slave_addr,
2301 0x0a, 0x90); 2300 0x0a, 0x90);
2302 radeon_i2c_sw_put_byte(tmds->i2c_bus, 2301 radeon_i2c_put_byte(tmds->i2c_bus,
2303 tmds->slave_addr, 2302 tmds->slave_addr,
2304 0x0c, 0x89); 2303 0x0c, 0x89);
2305 radeon_i2c_sw_put_byte(tmds->i2c_bus, 2304 radeon_i2c_put_byte(tmds->i2c_bus,
2306 tmds->slave_addr, 2305 tmds->slave_addr,
2307 0x08, 0x3b); 2306 0x08, 0x3b);
2308 radeon_i2c_do_lock(tmds->i2c_bus, 0);
2309 break; 2307 break;
2310 case DVO_SIL1178: 2308 case DVO_SIL1178:
2311 /* sil 1178 - untested */ 2309 /* sil 1178 - untested */
@@ -2390,11 +2388,9 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
2390 index++; 2388 index++;
2391 val = RBIOS8(index); 2389 val = RBIOS8(index);
2392 index++; 2390 index++;
2393 radeon_i2c_do_lock(tmds->i2c_bus, 1); 2391 radeon_i2c_put_byte(tmds->i2c_bus,
2394 radeon_i2c_sw_put_byte(tmds->i2c_bus, 2392 slave_addr,
2395 slave_addr, 2393 reg, val);
2396 reg, val);
2397 radeon_i2c_do_lock(tmds->i2c_bus, 0);
2398 break; 2394 break;
2399 default: 2395 default:
2400 DRM_ERROR("Unknown id %d\n", id >> 13); 2396 DRM_ERROR("Unknown id %d\n", id >> 13);
@@ -2447,11 +2443,9 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
2447 reg = id & 0x1fff; 2443 reg = id & 0x1fff;
2448 val = RBIOS8(index); 2444 val = RBIOS8(index);
2449 index += 1; 2445 index += 1;
2450 radeon_i2c_do_lock(tmds->i2c_bus, 1); 2446 radeon_i2c_put_byte(tmds->i2c_bus,
2451 radeon_i2c_sw_put_byte(tmds->i2c_bus, 2447 tmds->slave_addr,
2452 tmds->slave_addr, 2448 reg, val);
2453 reg, val);
2454 radeon_i2c_do_lock(tmds->i2c_bus, 0);
2455 break; 2449 break;
2456 default: 2450 default:
2457 DRM_ERROR("Unknown id %d\n", id >> 13); 2451 DRM_ERROR("Unknown id %d\n", id >> 13);
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 2d8e5a70f284..6e9e7b59d67e 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -479,10 +479,8 @@ static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connec
479 ret = connector_status_connected; 479 ret = connector_status_connected;
480 else { 480 else {
481 if (radeon_connector->ddc_bus) { 481 if (radeon_connector->ddc_bus) {
482 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
483 radeon_connector->edid = drm_get_edid(&radeon_connector->base, 482 radeon_connector->edid = drm_get_edid(&radeon_connector->base,
484 &radeon_connector->ddc_bus->adapter); 483 &radeon_connector->ddc_bus->adapter);
485 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
486 if (radeon_connector->edid) 484 if (radeon_connector->edid)
487 ret = connector_status_connected; 485 ret = connector_status_connected;
488 } 486 }
@@ -587,17 +585,13 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
587 if (!encoder) 585 if (!encoder)
588 ret = connector_status_disconnected; 586 ret = connector_status_disconnected;
589 587
590 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
591 dret = radeon_ddc_probe(radeon_connector); 588 dret = radeon_ddc_probe(radeon_connector);
592 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
593 if (dret) { 589 if (dret) {
594 if (radeon_connector->edid) { 590 if (radeon_connector->edid) {
595 kfree(radeon_connector->edid); 591 kfree(radeon_connector->edid);
596 radeon_connector->edid = NULL; 592 radeon_connector->edid = NULL;
597 } 593 }
598 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
599 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); 594 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
600 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
601 595
602 if (!radeon_connector->edid) { 596 if (!radeon_connector->edid) {
603 DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", 597 DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
@@ -742,17 +736,13 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
742 enum drm_connector_status ret = connector_status_disconnected; 736 enum drm_connector_status ret = connector_status_disconnected;
743 bool dret; 737 bool dret;
744 738
745 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
746 dret = radeon_ddc_probe(radeon_connector); 739 dret = radeon_ddc_probe(radeon_connector);
747 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
748 if (dret) { 740 if (dret) {
749 if (radeon_connector->edid) { 741 if (radeon_connector->edid) {
750 kfree(radeon_connector->edid); 742 kfree(radeon_connector->edid);
751 radeon_connector->edid = NULL; 743 radeon_connector->edid = NULL;
752 } 744 }
753 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
754 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); 745 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
755 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
756 746
757 if (!radeon_connector->edid) { 747 if (!radeon_connector->edid) {
758 DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", 748 DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
@@ -948,7 +938,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)
948 if (radeon_connector->edid) 938 if (radeon_connector->edid)
949 kfree(radeon_connector->edid); 939 kfree(radeon_connector->edid);
950 if (radeon_dig_connector->dp_i2c_bus) 940 if (radeon_dig_connector->dp_i2c_bus)
951 radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); 941 radeon_i2c_destroy_dp(radeon_dig_connector->dp_i2c_bus);
952 kfree(radeon_connector->con_priv); 942 kfree(radeon_connector->con_priv);
953 drm_sysfs_connector_remove(connector); 943 drm_sysfs_connector_remove(connector);
954 drm_connector_cleanup(connector); 944 drm_connector_cleanup(connector);
@@ -984,12 +974,10 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto
984 ret = connector_status_connected; 974 ret = connector_status_connected;
985 } 975 }
986 } else { 976 } else {
987 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
988 if (radeon_ddc_probe(radeon_connector)) { 977 if (radeon_ddc_probe(radeon_connector)) {
989 radeon_dig_connector->dp_sink_type = sink_type; 978 radeon_dig_connector->dp_sink_type = sink_type;
990 ret = connector_status_connected; 979 ret = connector_status_connected;
991 } 980 }
992 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
993 } 981 }
994 982
995 return ret; 983 return ret;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 6a92f994cc26..ec3166bfaa49 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -364,9 +364,7 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
364 if (!radeon_connector->ddc_bus) 364 if (!radeon_connector->ddc_bus)
365 return -1; 365 return -1;
366 if (!radeon_connector->edid) { 366 if (!radeon_connector->edid) {
367 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
368 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); 367 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
369 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
370 } 368 }
371 369
372 if (radeon_connector->edid) { 370 if (radeon_connector->edid) {
@@ -386,9 +384,7 @@ static int radeon_ddc_dump(struct drm_connector *connector)
386 384
387 if (!radeon_connector->ddc_bus) 385 if (!radeon_connector->ddc_bus)
388 return -1; 386 return -1;
389 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
390 edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); 387 edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
391 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
392 if (edid) { 388 if (edid) {
393 kfree(edid); 389 kfree(edid);
394 } 390 }
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index da3da1e89d00..75b090f60208 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -59,7 +59,7 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
59} 59}
60 60
61 61
62void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) 62static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
63{ 63{
64 struct radeon_device *rdev = i2c->dev->dev_private; 64 struct radeon_device *rdev = i2c->dev->dev_private;
65 struct radeon_i2c_bus_rec *rec = &i2c->rec; 65 struct radeon_i2c_bus_rec *rec = &i2c->rec;
@@ -168,6 +168,32 @@ static void set_data(void *i2c_priv, int data)
168 WREG32(rec->en_data_reg, val); 168 WREG32(rec->en_data_reg, val);
169} 169}
170 170
171static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
172 struct i2c_msg *msgs, int num)
173{
174 struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
175 int ret;
176
177 radeon_i2c_do_lock(i2c, 1);
178 if (i2c_transfer(&i2c->algo.radeon.bit_adapter, msgs, num) == num)
179 ret = num;
180 else
181 ret = -1;
182 radeon_i2c_do_lock(i2c, 0);
183
184 return ret;
185}
186
187static u32 radeon_i2c_func(struct i2c_adapter *adap)
188{
189 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
190}
191
192static const struct i2c_algorithm radeon_i2c_algo = {
193 .master_xfer = radeon_i2c_xfer,
194 .functionality = radeon_i2c_func,
195};
196
171struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, 197struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
172 struct radeon_i2c_bus_rec *rec, 198 struct radeon_i2c_bus_rec *rec,
173 const char *name) 199 const char *name)
@@ -179,21 +205,34 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
179 if (i2c == NULL) 205 if (i2c == NULL)
180 return NULL; 206 return NULL;
181 207
182 i2c->adapter.owner = THIS_MODULE;
183 i2c->dev = dev; 208 i2c->dev = dev;
184 i2c_set_adapdata(&i2c->adapter, i2c); 209 i2c->rec = *rec;
185 i2c->adapter.algo_data = &i2c->algo.bit; 210 /* set the internal bit adapter */
186 i2c->algo.bit.setsda = set_data; 211 i2c->algo.radeon.bit_adapter.owner = THIS_MODULE;
187 i2c->algo.bit.setscl = set_clock; 212 i2c_set_adapdata(&i2c->algo.radeon.bit_adapter, i2c);
188 i2c->algo.bit.getsda = get_data; 213 sprintf(i2c->algo.radeon.bit_adapter.name, "Radeon internal i2c bit bus %s", name);
189 i2c->algo.bit.getscl = get_clock; 214 i2c->algo.radeon.bit_adapter.algo_data = &i2c->algo.radeon.bit_data;
190 i2c->algo.bit.udelay = 20; 215 i2c->algo.radeon.bit_data.setsda = set_data;
216 i2c->algo.radeon.bit_data.setscl = set_clock;
217 i2c->algo.radeon.bit_data.getsda = get_data;
218 i2c->algo.radeon.bit_data.getscl = get_clock;
219 i2c->algo.radeon.bit_data.udelay = 20;
191 /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always 220 /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
192 * make this, 2 jiffies is a lot more reliable */ 221 * make this, 2 jiffies is a lot more reliable */
193 i2c->algo.bit.timeout = 2; 222 i2c->algo.radeon.bit_data.timeout = 2;
194 i2c->algo.bit.data = i2c; 223 i2c->algo.radeon.bit_data.data = i2c;
195 i2c->rec = *rec; 224 ret = i2c_bit_add_bus(&i2c->algo.radeon.bit_adapter);
196 ret = i2c_bit_add_bus(&i2c->adapter); 225 if (ret) {
226 DRM_INFO("Failed to register internal bit i2c %s\n", name);
227 goto out_free;
228 }
229 /* set the radeon i2c adapter */
230 i2c->adapter.owner = THIS_MODULE;
231 i2c_set_adapdata(&i2c->adapter, i2c);
232 sprintf(i2c->adapter.name, "Radeon i2c %s", name);
233 i2c->adapter.algo_data = &i2c->algo.radeon;
234 i2c->adapter.algo = &radeon_i2c_algo;
235 ret = i2c_add_adapter(&i2c->adapter);
197 if (ret) { 236 if (ret) {
198 DRM_INFO("Failed to register i2c %s\n", name); 237 DRM_INFO("Failed to register i2c %s\n", name);
199 goto out_free; 238 goto out_free;
@@ -237,11 +276,19 @@ out_free:
237 276
238} 277}
239 278
240
241void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) 279void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
242{ 280{
243 if (!i2c) 281 if (!i2c)
244 return; 282 return;
283 i2c_del_adapter(&i2c->algo.radeon.bit_adapter);
284 i2c_del_adapter(&i2c->adapter);
285 kfree(i2c);
286}
287
288void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c)
289{
290 if (!i2c)
291 return;
245 292
246 i2c_del_adapter(&i2c->adapter); 293 i2c_del_adapter(&i2c->adapter);
247 kfree(i2c); 294 kfree(i2c);
@@ -252,10 +299,10 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector)
252 return NULL; 299 return NULL;
253} 300}
254 301
255void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus, 302void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
256 u8 slave_addr, 303 u8 slave_addr,
257 u8 addr, 304 u8 addr,
258 u8 *val) 305 u8 *val)
259{ 306{
260 u8 out_buf[2]; 307 u8 out_buf[2];
261 u8 in_buf[2]; 308 u8 in_buf[2];
@@ -286,10 +333,10 @@ void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus,
286 } 333 }
287} 334}
288 335
289void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus, 336void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus,
290 u8 slave_addr, 337 u8 slave_addr,
291 u8 addr, 338 u8 addr,
292 u8 val) 339 u8 val)
293{ 340{
294 uint8_t out_buf[2]; 341 uint8_t out_buf[2];
295 struct i2c_msg msg = { 342 struct i2c_msg msg = {
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index e81b2aeb6a8f..b884bacf09ff 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -159,12 +159,17 @@ struct radeon_pll {
159 uint32_t id; 159 uint32_t id;
160}; 160};
161 161
162struct i2c_algo_radeon_data {
163 struct i2c_adapter bit_adapter;
164 struct i2c_algo_bit_data bit_data;
165};
166
162struct radeon_i2c_chan { 167struct radeon_i2c_chan {
163 struct i2c_adapter adapter; 168 struct i2c_adapter adapter;
164 struct drm_device *dev; 169 struct drm_device *dev;
165 union { 170 union {
166 struct i2c_algo_dp_aux_data dp; 171 struct i2c_algo_dp_aux_data dp;
167 struct i2c_algo_bit_data bit; 172 struct i2c_algo_radeon_data radeon;
168 } algo; 173 } algo;
169 struct radeon_i2c_bus_rec rec; 174 struct radeon_i2c_bus_rec rec;
170}; 175};
@@ -411,14 +416,15 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
411 struct radeon_i2c_bus_rec *rec, 416 struct radeon_i2c_bus_rec *rec,
412 const char *name); 417 const char *name);
413extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); 418extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
414extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus, 419extern void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c);
415 u8 slave_addr, 420extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
416 u8 addr, 421 u8 slave_addr,
417 u8 *val); 422 u8 addr,
418extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c, 423 u8 *val);
419 u8 slave_addr, 424extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
420 u8 addr, 425 u8 slave_addr,
421 u8 val); 426 u8 addr,
427 u8 val);
422extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); 428extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
423extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); 429extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
424 430
@@ -531,7 +537,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
531 struct radeon_crtc *radeon_crtc); 537 struct radeon_crtc *radeon_crtc);
532void radeon_legacy_init_crtc(struct drm_device *dev, 538void radeon_legacy_init_crtc(struct drm_device *dev,
533 struct radeon_crtc *radeon_crtc); 539 struct radeon_crtc *radeon_crtc);
534extern void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state);
535 540
536void radeon_get_clock_info(struct drm_device *dev); 541void radeon_get_clock_info(struct drm_device *dev);
537 542