aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-07-02 06:43:42 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:05:24 -0400
commiteeb3ca12b4658c569bd60fe60c4c45c627e842a6 (patch)
treef4e4340e8ec379cf8b8e90fb1df7b4135b1ffefa /drivers/gpu
parentd9f61c2d2847fb2889ed01d2240db38927ab7e18 (diff)
drm/nvd0/i2c: initial implementation
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
index cb389d014326..739c0ac3a9b7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -107,6 +107,13 @@ nv4e_i2c_getsda(void *data)
107 return !!((nv_rd32(dev, i2c->rd) >> 16) & 8); 107 return !!((nv_rd32(dev, i2c->rd) >> 16) & 8);
108} 108}
109 109
110static const uint32_t nv50_i2c_port[] = {
111 0x00e138, 0x00e150, 0x00e168, 0x00e180,
112 0x00e254, 0x00e274, 0x00e764, 0x00e780,
113 0x00e79c, 0x00e7b8
114};
115#define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port)
116
110static int 117static int
111nv50_i2c_getscl(void *data) 118nv50_i2c_getscl(void *data)
112{ 119{
@@ -130,28 +137,32 @@ static void
130nv50_i2c_setscl(void *data, int state) 137nv50_i2c_setscl(void *data, int state)
131{ 138{
132 struct nouveau_i2c_chan *i2c = data; 139 struct nouveau_i2c_chan *i2c = data;
133 struct drm_device *dev = i2c->dev;
134 140
135 nv_wr32(dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0)); 141 nv_wr32(i2c->dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0));
136} 142}
137 143
138static void 144static void
139nv50_i2c_setsda(void *data, int state) 145nv50_i2c_setsda(void *data, int state)
140{ 146{
141 struct nouveau_i2c_chan *i2c = data; 147 struct nouveau_i2c_chan *i2c = data;
142 struct drm_device *dev = i2c->dev;
143 148
144 nv_wr32(dev, i2c->wr, 149 nv_mask(i2c->dev, i2c->wr, 0x00000006, 4 | (state ? 2 : 0));
145 (nv_rd32(dev, i2c->rd) & 1) | 4 | (state ? 2 : 0));
146 i2c->data = state; 150 i2c->data = state;
147} 151}
148 152
149static const uint32_t nv50_i2c_port[] = { 153static int
150 0x00e138, 0x00e150, 0x00e168, 0x00e180, 154nvd0_i2c_getscl(void *data)
151 0x00e254, 0x00e274, 0x00e764, 0x00e780, 155{
152 0x00e79c, 0x00e7b8 156 struct nouveau_i2c_chan *i2c = data;
153}; 157 return !!(nv_rd32(i2c->dev, i2c->rd) & 0x10);
154#define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port) 158}
159
160static int
161nvd0_i2c_getsda(void *data)
162{
163 struct nouveau_i2c_chan *i2c = data;
164 return !!(nv_rd32(i2c->dev, i2c->rd) & 0x20);
165}
155 166
156int 167int
157nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) 168nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
@@ -163,7 +174,8 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
163 if (entry->chan) 174 if (entry->chan)
164 return -EEXIST; 175 return -EEXIST;
165 176
166 if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) { 177 if (dev_priv->card_type >= NV_50 &&
178 dev_priv->card_type <= NV_C0 && entry->read >= NV50_I2C_PORTS) {
167 NV_ERROR(dev, "unknown i2c port %d\n", entry->read); 179 NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
168 return -EINVAL; 180 return -EINVAL;
169 } 181 }
@@ -192,10 +204,17 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
192 case 5: 204 case 5:
193 i2c->bit.setsda = nv50_i2c_setsda; 205 i2c->bit.setsda = nv50_i2c_setsda;
194 i2c->bit.setscl = nv50_i2c_setscl; 206 i2c->bit.setscl = nv50_i2c_setscl;
195 i2c->bit.getsda = nv50_i2c_getsda; 207 if (dev_priv->card_type < NV_D0) {
196 i2c->bit.getscl = nv50_i2c_getscl; 208 i2c->bit.getsda = nv50_i2c_getsda;
197 i2c->rd = nv50_i2c_port[entry->read]; 209 i2c->bit.getscl = nv50_i2c_getscl;
198 i2c->wr = i2c->rd; 210 i2c->rd = nv50_i2c_port[entry->read];
211 i2c->wr = i2c->rd;
212 } else {
213 i2c->bit.getsda = nvd0_i2c_getsda;
214 i2c->bit.getscl = nvd0_i2c_getscl;
215 i2c->rd = 0x00d014 + (entry->read * 0x20);
216 i2c->wr = i2c->rd;
217 }
199 break; 218 break;
200 case 6: 219 case 6:
201 i2c->rd = entry->read; 220 i2c->rd = entry->read;