aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-02-06 17:06:42 -0500
committerDave Airlie <airlied@redhat.com>2010-02-08 18:32:32 -0500
commit57fcab620d05c3eb32b4787ce7501565c4c3162d (patch)
treecaa3b6f9ce5b5f4ccaf059423d29c91b9bd9b6e4 /drivers/gpu/drm
parent6d7f2d8da106ecf794a5a3e98c4239f348119e3c (diff)
drm/radeon/kms: take the pm mutex when using hw i2c
we need a constant sclk for i2c prescale. Also, get the current sclk when calculating prescale rather than using the default sclk. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index b47a5615fe6a..272c45db5cec 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -192,12 +192,16 @@ static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
192 struct radeon_i2c_bus_rec *rec = &i2c->rec; 192 struct radeon_i2c_bus_rec *rec = &i2c->rec;
193 struct i2c_msg *p; 193 struct i2c_msg *p;
194 int i, j, k, ret = num; 194 int i, j, k, ret = num;
195 /* XXX: use get_engine_clock() to get the current sclk */ 195 u32 sclk, prescale;
196 u32 prescale = (((rdev->clock.default_sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
197 u32 i2c_cntl_0, i2c_cntl_1, i2c_data; 196 u32 i2c_cntl_0, i2c_cntl_1, i2c_data;
198 u32 tmp, reg; 197 u32 tmp, reg;
199 198
200 mutex_lock(&rdev->dc_hw_i2c_mutex); 199 mutex_lock(&rdev->dc_hw_i2c_mutex);
200 /* take the pm lock since we need a constant sclk */
201 mutex_lock(&rdev->pm.mutex);
202
203 sclk = radeon_get_engine_clock(rdev);
204 prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
201 205
202 reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) | 206 reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) |
203 RADEON_I2C_START | 207 RADEON_I2C_START |
@@ -424,6 +428,7 @@ done:
424 WREG32(RADEON_BIOS_6_SCRATCH, tmp); 428 WREG32(RADEON_BIOS_6_SCRATCH, tmp);
425 } 429 }
426 430
431 mutex_unlock(&rdev->pm.mutex);
427 mutex_unlock(&rdev->dc_hw_i2c_mutex); 432 mutex_unlock(&rdev->dc_hw_i2c_mutex);
428 433
429 return ret; 434 return ret;
@@ -441,12 +446,19 @@ static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
441 struct i2c_msg *p; 446 struct i2c_msg *p;
442 int i2c_clock = 50; 447 int i2c_clock = 50;
443 int i, j, remaining, current_count, buffer_offset, ret = num; 448 int i, j, remaining, current_count, buffer_offset, ret = num;
444 /* XXX: use get_engine_clock() to get the current sclk */ 449 u32 sclk, prescale;
445 u32 prescale;
446 u32 tmp, reg; 450 u32 tmp, reg;
447 u32 saved1, saved2; 451 u32 saved1, saved2;
448 452
449 mutex_lock(&rdev->dc_hw_i2c_mutex); 453 mutex_lock(&rdev->dc_hw_i2c_mutex);
454 /* take the pm lock since we need a constant sclk */
455 mutex_lock(&rdev->pm.mutex);
456
457 sclk = radeon_get_engine_clock(rdev);
458 if (rdev->family == CHIP_R520)
459 prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock));
460 else
461 prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
450 462
451 /* clear gpio mask bits */ 463 /* clear gpio mask bits */
452 tmp = RREG32(rec->mask_clk_reg); 464 tmp = RREG32(rec->mask_clk_reg);
@@ -500,11 +512,6 @@ static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
500 goto done; 512 goto done;
501 } 513 }
502 514
503 if (rdev->family == CHIP_R520)
504 prescale = (127 << 8) + ((rdev->clock.default_sclk * 10) / (4 * 127 * i2c_clock));
505 else
506 prescale = (((rdev->clock.default_sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
507
508 reg = AVIVO_DC_I2C_START | AVIVO_DC_I2C_STOP | AVIVO_DC_I2C_EN; 515 reg = AVIVO_DC_I2C_START | AVIVO_DC_I2C_STOP | AVIVO_DC_I2C_EN;
509 switch (rec->mask_clk_reg) { 516 switch (rec->mask_clk_reg) {
510 case AVIVO_DC_GPIO_DDC1_MASK: 517 case AVIVO_DC_GPIO_DDC1_MASK:
@@ -662,6 +669,7 @@ done:
662 tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; 669 tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE;
663 WREG32(RADEON_BIOS_6_SCRATCH, tmp); 670 WREG32(RADEON_BIOS_6_SCRATCH, tmp);
664 671
672 mutex_unlock(&rdev->pm.mutex);
665 mutex_unlock(&rdev->dc_hw_i2c_mutex); 673 mutex_unlock(&rdev->dc_hw_i2c_mutex);
666 674
667 return ret; 675 return ret;