Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 205096
b: refs/heads/master
c: 6d416d8
h: refs/heads/master
v: v3
  • Loading branch information
Francisco Jerez authored and Ben Skeggs committed Jul 26, 2010
1 parent 1c346c9 commit 9d0f8ad
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 100 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d6a413aa23c8bc7a5787596e06f3d6d8d4f11c7
refs/heads/master: 6d416d80f720f71e2dfe903d672bcca071822538
22 changes: 3 additions & 19 deletions trunk/drivers/gpu/drm/nouveau/nouveau_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,26 +139,10 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
struct nouveau_encoder **pnv_encoder)
{
struct drm_device *dev = connector->dev;
uint8_t out_buf[] = { 0x0, 0x0}, buf[2];
int ret, flags, i;

struct i2c_msg msgs[] = {
{
.addr = 0x50,
.flags = 0,
.len = 1,
.buf = out_buf,
},
{
.addr = 0x50,
.flags = I2C_M_RD,
.len = 1,
.buf = buf,
}
};

for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
struct nouveau_i2c_chan *i2c = NULL;
struct nouveau_i2c_chan *i2c;
struct nouveau_encoder *nv_encoder;
struct drm_mode_object *obj;
int id;
Expand All @@ -178,10 +162,10 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
continue;

nouveau_connector_ddc_prepare(connector, &flags);
ret = i2c_transfer(&i2c->adapter, msgs, 2);
ret = nouveau_probe_i2c_addr(i2c, 0x50);
nouveau_connector_ddc_finish(connector, flags);

if (ret == 2) {
if (ret) {
*pnv_encoder = nv_encoder;
return i2c;
}
Expand Down
34 changes: 34 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,37 @@ nouveau_i2c_find(struct drm_device *dev, int index)
return i2c->chan;
}

bool
nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
{
struct i2c_msg msg = {
.addr = addr,
.len = 0,
};

return i2c_transfer(&i2c->adapter, &msg, 1) == 1;
}

int
nouveau_i2c_identify(struct drm_device *dev, const char *what,
struct i2c_board_info *info, int index)
{
struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
int was_locked, i;

was_locked = NVLockVgaCrtcs(dev, false);
NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);

for (i = 0; info[i].addr; i++) {
if (nouveau_probe_i2c_addr(i2c, info[i].addr)) {
NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
goto out;
}
}

NV_DEBUG(dev, "No devices found.\n");
out:
NVLockVgaCrtcs(dev, was_locked);

return info[i].addr ? i : -ENODEV;
}
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ struct nouveau_i2c_chan {
int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index);
void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *);
struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index);
bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr);
int nouveau_i2c_identify(struct drm_device *dev, const char *what,
struct i2c_board_info *info, int index);

int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte,
uint8_t *read_byte);
Expand Down
115 changes: 35 additions & 80 deletions trunk/drivers/gpu/drm/nouveau/nv04_tv.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,69 +34,26 @@

#include "i2c/ch7006.h"

static struct {
struct i2c_board_info board_info;
struct drm_encoder_funcs funcs;
struct drm_encoder_helper_funcs hfuncs;
void *params;

} nv04_tv_encoder_info[] = {
static struct i2c_board_info nv04_tv_encoder_info[] = {
{
.board_info = { I2C_BOARD_INFO("ch7006", 0x75) },
.params = &(struct ch7006_encoder_params) {
I2C_BOARD_INFO("ch7006", 0x75),
.platform_data = &(struct ch7006_encoder_params) {
CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER,
0, 0, 0,
CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED,
CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC
},
}
},
{ }
};

static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr)
{
struct i2c_msg msg = {
.addr = addr,
.len = 0,
};

return i2c_transfer(adapter, &msg, 1) == 1;
}

int nv04_tv_identify(struct drm_device *dev, int i2c_index)
{
struct nouveau_i2c_chan *i2c;
bool was_locked;
int i, ret;

NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index);

i2c = nouveau_i2c_find(dev, i2c_index);
if (!i2c)
return -ENODEV;

was_locked = NVLockVgaCrtcs(dev, false);

for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) {
if (probe_i2c_addr(&i2c->adapter,
nv04_tv_encoder_info[i].board_info.addr)) {
ret = i;
break;
}
}

if (i < ARRAY_SIZE(nv04_tv_encoder_info)) {
NV_TRACE(dev, "Detected TV encoder: %s\n",
nv04_tv_encoder_info[i].board_info.type);

} else {
NV_TRACE(dev, "No TV encoders found.\n");
i = -ENODEV;
}

NVLockVgaCrtcs(dev, was_locked);
return i;
return nouveau_i2c_identify(dev, "TV encoder",
nv04_tv_encoder_info, i2c_index);
}


#define PLLSEL_TV_CRTC1_MASK \
(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \
| NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1)
Expand Down Expand Up @@ -214,32 +171,33 @@ static void nv04_tv_commit(struct drm_encoder *encoder)

static void nv04_tv_destroy(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);

to_encoder_slave(encoder)->slave_funcs->destroy(encoder);

drm_encoder_cleanup(encoder);

kfree(nv_encoder);
kfree(encoder->helper_private);
kfree(nouveau_encoder(encoder));
}

static const struct drm_encoder_funcs nv04_tv_funcs = {
.destroy = nv04_tv_destroy,
};

int
nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
{
struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
struct drm_device *dev = connector->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct i2c_adapter *adap;
struct drm_encoder_funcs *funcs = NULL;
struct drm_encoder_helper_funcs *hfuncs = NULL;
struct drm_encoder_slave_funcs *sfuncs = NULL;
int i2c_index = entry->i2c_index;
struct drm_encoder_helper_funcs *hfuncs;
struct drm_encoder_slave_funcs *sfuncs;
struct nouveau_i2c_chan *i2c =
nouveau_i2c_find(dev, entry->i2c_index);
int type, ret;
bool was_locked;

/* Ensure that we can talk to this encoder */
type = nv04_tv_identify(dev, i2c_index);
type = nv04_tv_identify(dev, entry->i2c_index);
if (type < 0)
return type;

Expand All @@ -248,41 +206,37 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
if (!nv_encoder)
return -ENOMEM;

hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL);
if (!hfuncs) {
ret = -ENOMEM;
goto fail_free;
}

/* Initialize the common members */
encoder = to_drm_encoder(nv_encoder);

funcs = &nv04_tv_encoder_info[type].funcs;
hfuncs = &nv04_tv_encoder_info[type].hfuncs;

drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC);
drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC);
drm_encoder_helper_add(encoder, hfuncs);

encoder->possible_crtcs = entry->heads;
encoder->possible_clones = 0;

nv_encoder->dcb = entry;
nv_encoder->or = ffs(entry->or) - 1;

/* Run the slave-specific initialization */
adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter;

was_locked = NVLockVgaCrtcs(dev, false);

ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), adap,
&nv04_tv_encoder_info[type].board_info);
ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
&i2c->adapter, &nv04_tv_encoder_info[type]);

NVLockVgaCrtcs(dev, was_locked);

if (ret < 0)
goto fail;
goto fail_cleanup;

/* Fill the function pointers */
sfuncs = to_encoder_slave(encoder)->slave_funcs;

*funcs = (struct drm_encoder_funcs) {
.destroy = nv04_tv_destroy,
};

*hfuncs = (struct drm_encoder_helper_funcs) {
.dpms = nv04_tv_dpms,
.save = sfuncs->save,
Expand All @@ -294,16 +248,17 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
.detect = sfuncs->detect,
};

/* Set the slave encoder configuration */
sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params);
/* Attach it to the specified connector. */
sfuncs->set_config(encoder, nv04_tv_encoder_info[type].platform_data);
sfuncs->create_resources(encoder, connector);

drm_mode_connector_attach_encoder(connector, encoder);

return 0;

fail:
fail_cleanup:
drm_encoder_cleanup(encoder);

kfree(hfuncs);
fail_free:
kfree(nv_encoder);
return ret;
}

0 comments on commit 9d0f8ad

Please sign in to comment.