WREG32(rec->en_data_reg, val);
}
+static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
+{
+ struct radeon_pll *spll = &rdev->clock.spll;
+ u32 sclk = radeon_get_engine_clock(rdev);
+ u32 prescale = 0;
+ u32 n, m;
+ u8 loop;
+ int i2c_clock;
+
+ switch (rdev->family) {
+ case CHIP_R100:
+ case CHIP_RV100:
+ case CHIP_RS100:
+ case CHIP_RV200:
+ case CHIP_RS200:
+ case CHIP_R200:
+ case CHIP_RV250:
+ case CHIP_RS300:
+ case CHIP_RV280:
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_RV350:
+ n = (spll->reference_freq) / (4 * 6);
+ for (loop = 1; loop < 255; loop++) {
+ if ((loop * (loop - 1)) > n)
+ break;
+ }
+ m = loop - 1;
+ prescale = m | (loop << 8);
+ break;
+ case CHIP_RV380:
+ case CHIP_RS400:
+ case CHIP_RS480:
+ case CHIP_R420:
+ case CHIP_R423:
+ case CHIP_RV410:
+ sclk = radeon_get_engine_clock(rdev);
+ prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
+ break;
+ case CHIP_RS600:
+ case CHIP_RS690:
+ case CHIP_RS740:
+ /* todo */
+ break;
+ case CHIP_RV515:
+ case CHIP_R520:
+ case CHIP_RV530:
+ case CHIP_RV560:
+ case CHIP_RV570:
+ case CHIP_R580:
+ i2c_clock = 50;
+ sclk = radeon_get_engine_clock(rdev);
+ if (rdev->family == CHIP_R520)
+ prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock));
+ else
+ prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
+ break;
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ /* todo */
+ break;
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ /* todo */
+ break;
+ default:
+ DRM_ERROR("i2c: unhandled radeon chip\n");
+ break;
+ }
+ return prescale;
+}
+
+
/* hw i2c engine for r1xx-4xx hardware
* hw can buffer up to 15 bytes
*/
struct radeon_i2c_bus_rec *rec = &i2c->rec;
struct i2c_msg *p;
int i, j, k, ret = num;
- u32 sclk, prescale;
+ u32 prescale;
u32 i2c_cntl_0, i2c_cntl_1, i2c_data;
u32 tmp, reg;
/* take the pm lock since we need a constant sclk */
mutex_lock(&rdev->pm.mutex);
- sclk = radeon_get_engine_clock(rdev);
- prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
+ prescale = radeon_get_i2c_prescale(rdev);
reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) |
RADEON_I2C_START |
struct radeon_device *rdev = i2c->dev->dev_private;
struct radeon_i2c_bus_rec *rec = &i2c->rec;
struct i2c_msg *p;
- int i2c_clock = 50;
int i, j, remaining, current_count, buffer_offset, ret = num;
- u32 sclk, prescale;
+ u32 prescale;
u32 tmp, reg;
u32 saved1, saved2;
/* take the pm lock since we need a constant sclk */
mutex_lock(&rdev->pm.mutex);
- sclk = radeon_get_engine_clock(rdev);
- if (rdev->family == CHIP_R520)
- prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock));
- else
- prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
+ prescale = radeon_get_i2c_prescale(rdev);
/* clear gpio mask bits */
tmp = RREG32(rec->mask_clk_reg);