Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1962 → Rev 1963

/drivers/video/drm/radeon/radeon_i2c.c
52,6 → 52,10
}
};
 
/* on hw with routers, select right port */
if (radeon_connector->router.ddc_valid)
radeon_router_select_ddc_port(radeon_connector);
 
ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
if (ret == 2)
return true;
59,6 → 63,7
return false;
}
 
/* bit banging i2c */
 
static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
{
94,6 → 99,13
}
}
 
/* switch the pads to ddc mode */
if (ASIC_IS_DCE3(rdev) && rec->hw_capable) {
temp = RREG32(rec->mask_clk_reg);
temp &= ~(1 << 16);
WREG32(rec->mask_clk_reg, temp);
}
 
/* clear the output pin values */
temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask;
WREG32(rec->a_clk_reg, temp);
181,13 → 193,30
WREG32(rec->en_data_reg, val);
}
 
static int pre_xfer(struct i2c_adapter *i2c_adap)
{
struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
 
radeon_i2c_do_lock(i2c, 1);
 
return 0;
}
 
static void post_xfer(struct i2c_adapter *i2c_adap)
{
struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
 
radeon_i2c_do_lock(i2c, 0);
}
 
/* hw i2c */
 
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 sclk = rdev->pm.current_sclk;
u32 prescale = 0;
u32 n, m;
u8 loop;
u32 nm;
u8 n, m, loop;
int i2c_clock;
 
switch (rdev->family) {
203,13 → 232,15
case CHIP_R300:
case CHIP_R350:
case CHIP_RV350:
n = (spll->reference_freq) / (4 * 6);
i2c_clock = 60;
nm = (sclk * 10) / (i2c_clock * 4);
for (loop = 1; loop < 255; loop++) {
if ((loop * (loop - 1)) > n)
if ((nm / loop) < loop)
break;
}
m = loop - 1;
prescale = m | (loop << 8);
n = loop - 1;
m = loop - 2;
prescale = m | (n << 8);
break;
case CHIP_RV380:
case CHIP_RS400:
217,7 → 248,6
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:
232,7 → 262,6
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
291,6 → 320,7
prescale = radeon_get_i2c_prescale(rdev);
 
reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) |
RADEON_I2C_DRIVE_EN |
RADEON_I2C_START |
RADEON_I2C_STOP |
RADEON_I2C_GO);
757,27 → 787,16
return ret;
}
 
static int radeon_sw_i2c_xfer(struct i2c_adapter *i2c_adap,
static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num)
{
struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
int ret;
 
radeon_i2c_do_lock(i2c, 1);
ret = i2c_transfer(&i2c->algo.radeon.bit_adapter, msgs, num);
radeon_i2c_do_lock(i2c, 0);
 
return ret;
}
 
static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num)
{
struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
struct radeon_device *rdev = i2c->dev->dev_private;
struct radeon_i2c_bus_rec *rec = &i2c->rec;
int ret;
int ret = 0;
 
ENTER();
 
switch (rdev->family) {
case CHIP_R100:
case CHIP_RV100:
797,16 → 816,12
case CHIP_RV410:
case CHIP_RS400:
case CHIP_RS480:
if (rec->hw_capable)
ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
else
ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_RS600:
case CHIP_RS690:
case CHIP_RS740:
/* XXX fill in hw i2c implementation */
ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_RV515:
case CHIP_R520:
814,13 → 829,10
case CHIP_RV560:
case CHIP_RV570:
case CHIP_R580:
if (rec->hw_capable) {
if (rec->mm_i2c)
ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
else
ret = r500_hw_i2c_xfer(i2c_adap, msgs, num);
} else
ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_R600:
case CHIP_RV610:
827,7 → 839,6
case CHIP_RV630:
case CHIP_RV670:
/* XXX fill in hw i2c implementation */
ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_RV620:
case CHIP_RV635:
838,7 → 849,6
case CHIP_RV710:
case CHIP_RV740:
/* XXX fill in hw i2c implementation */
ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_CEDAR:
case CHIP_REDWOOD:
846,7 → 856,6
case CHIP_CYPRESS:
case CHIP_HEMLOCK:
/* XXX fill in hw i2c implementation */
ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
default:
DRM_ERROR("i2c: unhandled radeon chip\n");
853,18 → 862,19
ret = -EIO;
break;
}
LEAVE();
 
return ret;
}
 
static u32 radeon_i2c_func(struct i2c_adapter *adap)
static u32 radeon_hw_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
 
static const struct i2c_algorithm radeon_i2c_algo = {
.master_xfer = radeon_i2c_xfer,
.functionality = radeon_i2c_func,
.master_xfer = radeon_hw_i2c_xfer,
.functionality = radeon_hw_i2c_func,
};
 
struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
871,6 → 881,7
struct radeon_i2c_bus_rec *rec,
const char *name)
{
struct radeon_device *rdev = dev->dev_private;
struct radeon_i2c_chan *i2c;
int ret;
 
878,33 → 889,46
if (i2c == NULL)
return NULL;
 
/* set the internal bit adapter */
// i2c->algo.radeon.bit_adapter.owner = THIS_MODULE;
i2c_set_adapdata(&i2c->algo.radeon.bit_adapter, i2c);
// sprintf(i2c->algo.radeon.bit_adapter.name, "Radeon internal i2c bit bus %s", name);
i2c->algo.radeon.bit_adapter.algo_data = &i2c->algo.radeon.bit_data;
i2c->algo.radeon.bit_data.setsda = set_data;
i2c->algo.radeon.bit_data.setscl = set_clock;
i2c->algo.radeon.bit_data.getsda = get_data;
i2c->algo.radeon.bit_data.getscl = get_clock;
i2c->algo.radeon.bit_data.udelay = 20;
i2c->rec = *rec;
// i2c->adapter.owner = THIS_MODULE;
i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);
if (rec->mm_i2c ||
(rec->hw_capable &&
radeon_hw_i2c &&
((rdev->family <= CHIP_RS480) ||
((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) {
/* set the radeon hw i2c adapter */
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"Radeon i2c hw bus %s", name);
i2c->adapter.algo = &radeon_i2c_algo;
// ret = i2c_add_adapter(&i2c->adapter);
// if (ret) {
// DRM_ERROR("Failed to register hw i2c %s\n", name);
// goto out_free;
// }
} else {
/* set the radeon bit adapter */
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"Radeon i2c bit bus %s", name);
i2c->adapter.algo_data = &i2c->algo.bit;
i2c->algo.bit.pre_xfer = pre_xfer;
i2c->algo.bit.post_xfer = post_xfer;
i2c->algo.bit.setsda = set_data;
i2c->algo.bit.setscl = set_clock;
i2c->algo.bit.getsda = get_data;
i2c->algo.bit.getscl = get_clock;
i2c->algo.bit.udelay = 20;
/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
* make this, 2 jiffies is a lot more reliable */
i2c->algo.radeon.bit_data.timeout = 2;
i2c->algo.radeon.bit_data.data = i2c;
ret = i2c_bit_add_bus(&i2c->algo.radeon.bit_adapter);
i2c->algo.bit.timeout = 2;
i2c->algo.bit.data = i2c;
ret = i2c_bit_add_bus(&i2c->adapter);
if (ret) {
DRM_ERROR("Failed to register internal bit i2c %s\n", name);
DRM_ERROR("Failed to register bit i2c %s\n", name);
goto out_free;
}
/* set the radeon i2c adapter */
i2c->dev = dev;
i2c->rec = *rec;
// i2c->adapter.owner = THIS_MODULE;
i2c_set_adapdata(&i2c->adapter, i2c);
// sprintf(i2c->adapter.name, "Radeon i2c %s", name);
i2c->adapter.algo_data = &i2c->algo.radeon;
i2c->adapter.algo = &radeon_i2c_algo;
}
 
return i2c;
out_free:
926,7 → 950,10
 
i2c->rec = *rec;
// i2c->adapter.owner = THIS_MODULE;
i2c->adapter.class = I2C_CLASS_DDC;
i2c->dev = dev;
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"Radeon aux bus %s", name);
i2c_set_adapdata(&i2c->adapter, i2c);
i2c->adapter.algo_data = &i2c->algo.dp;
i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
948,16 → 975,62
{
if (!i2c)
return;
// i2c_del_adapter(&i2c->adapter);
kfree(i2c);
}
 
void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c)
/* Add the default buses */
void radeon_i2c_init(struct radeon_device *rdev)
{
if (!i2c)
if (rdev->is_atom_bios)
radeon_atombios_i2c_init(rdev);
else
radeon_combios_i2c_init(rdev);
}
 
/* remove all the buses */
void radeon_i2c_fini(struct radeon_device *rdev)
{
int i;
 
for (i = 0; i < RADEON_MAX_I2C_BUS; i++) {
if (rdev->i2c_bus[i]) {
radeon_i2c_destroy(rdev->i2c_bus[i]);
rdev->i2c_bus[i] = NULL;
}
}
}
 
/* Add additional buses */
void radeon_i2c_add(struct radeon_device *rdev,
struct radeon_i2c_bus_rec *rec,
const char *name)
{
struct drm_device *dev = rdev->ddev;
int i;
 
for (i = 0; i < RADEON_MAX_I2C_BUS; i++) {
if (!rdev->i2c_bus[i]) {
rdev->i2c_bus[i] = radeon_i2c_create(dev, rec, name);
return;
}
}
}
 
kfree(i2c);
/* looks up bus based on id */
struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev,
struct radeon_i2c_bus_rec *i2c_bus)
{
int i;
 
for (i = 0; i < RADEON_MAX_I2C_BUS; i++) {
if (rdev->i2c_bus[i] &&
(rdev->i2c_bus[i]->rec.i2c_id == i2c_bus->i2c_id)) {
return rdev->i2c_bus[i];
}
}
return NULL;
}
 
struct drm_encoder *radeon_best_encoder(struct drm_connector *connector)
{
993,7 → 1066,7
*val = in_buf[0];
DRM_DEBUG("val = 0x%02x\n", *val);
} else {
DRM_ERROR("i2c 0x%02x 0x%02x read failed\n",
DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n",
addr, *val);
}
}
1015,7 → 1088,63
out_buf[1] = val;
 
if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
DRM_ERROR("i2c 0x%02x 0x%02x write failed\n",
DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n",
addr, val);
}
 
/* ddc router switching */
void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector)
{
u8 val;
 
if (!radeon_connector->router.ddc_valid)
return;
 
if (!radeon_connector->router_bus)
return;
 
radeon_i2c_get_byte(radeon_connector->router_bus,
radeon_connector->router.i2c_addr,
0x3, &val);
val &= ~radeon_connector->router.ddc_mux_control_pin;
radeon_i2c_put_byte(radeon_connector->router_bus,
radeon_connector->router.i2c_addr,
0x3, val);
radeon_i2c_get_byte(radeon_connector->router_bus,
radeon_connector->router.i2c_addr,
0x1, &val);
val &= ~radeon_connector->router.ddc_mux_control_pin;
val |= radeon_connector->router.ddc_mux_state;
radeon_i2c_put_byte(radeon_connector->router_bus,
radeon_connector->router.i2c_addr,
0x1, val);
}
 
/* clock/data router switching */
void radeon_router_select_cd_port(struct radeon_connector *radeon_connector)
{
u8 val;
 
if (!radeon_connector->router.cd_valid)
return;
 
if (!radeon_connector->router_bus)
return;
 
radeon_i2c_get_byte(radeon_connector->router_bus,
radeon_connector->router.i2c_addr,
0x3, &val);
val &= ~radeon_connector->router.cd_mux_control_pin;
radeon_i2c_put_byte(radeon_connector->router_bus,
radeon_connector->router.i2c_addr,
0x3, val);
radeon_i2c_get_byte(radeon_connector->router_bus,
radeon_connector->router.i2c_addr,
0x1, &val);
val &= ~radeon_connector->router.cd_mux_control_pin;
val |= radeon_connector->router.cd_mux_state;
radeon_i2c_put_byte(radeon_connector->router_bus,
radeon_connector->router.i2c_addr,
0x1, val);
}