Set memory attributes on page
[pscnv.git] / pscnv / nouveau_iic.c
blobf82b9fab340e61f3e1df816d02c517fcb33d5433
1 /*
2 * Copyright 2009 Red Hat Inc.
3 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
4 * Copyright © 2006-2008,2010 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 * Authors:
27 * Eric Anholt <eric@anholt.net>
28 * Chris Wilson <chris@chris-wilson.co.uk>
30 * Copyright (c) 2011 The FreeBSD Foundation
31 * All rights reserved.
33 * This software was developed by Konstantin Belousov under sponsorship from
34 * the FreeBSD Foundation.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
58 #include "nouveau_drv.h"
59 #include "nouveau_reg.h"
60 #include "nouveau_i2c.h"
61 #include "nouveau_hw.h"
63 static void
64 nv04_i2c_setscl(void *data, int state)
66 struct nouveau_i2c_chan *i2c = data;
67 struct drm_device *dev = i2c->dev;
68 uint8_t val;
70 val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
71 NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
74 static void
75 nv04_i2c_setsda(void *data, int state)
77 struct nouveau_i2c_chan *i2c = data;
78 struct drm_device *dev = i2c->dev;
79 uint8_t val;
81 val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
82 NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
85 static int
86 nv04_i2c_getscl(void *data)
88 struct nouveau_i2c_chan *i2c = data;
89 struct drm_device *dev = i2c->dev;
91 return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 4);
94 static int
95 nv04_i2c_getsda(void *data)
97 struct nouveau_i2c_chan *i2c = data;
98 struct drm_device *dev = i2c->dev;
100 return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 8);
103 static void
104 nv4e_i2c_setscl(void *data, int state)
106 struct nouveau_i2c_chan *i2c = data;
107 struct drm_device *dev = i2c->dev;
108 uint8_t val;
110 val = (nv_rd32(dev, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
111 nv_wr32(dev, i2c->wr, val | 0x01);
114 static void
115 nv4e_i2c_setsda(void *data, int state)
117 struct nouveau_i2c_chan *i2c = data;
118 struct drm_device *dev = i2c->dev;
119 uint8_t val;
121 val = (nv_rd32(dev, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
122 nv_wr32(dev, i2c->wr, val | 0x01);
125 static int
126 nv4e_i2c_getscl(void *data)
128 struct nouveau_i2c_chan *i2c = data;
129 struct drm_device *dev = i2c->dev;
131 return !!((nv_rd32(dev, i2c->rd) >> 16) & 4);
134 static int
135 nv4e_i2c_getsda(void *data)
137 struct nouveau_i2c_chan *i2c = data;
138 struct drm_device *dev = i2c->dev;
140 return !!((nv_rd32(dev, i2c->rd) >> 16) & 8);
143 static int
144 nv50_i2c_getscl(void *data)
146 struct nouveau_i2c_chan *i2c = data;
147 struct drm_device *dev = i2c->dev;
149 return !!(nv_rd32(dev, i2c->rd) & 1);
153 static int
154 nv50_i2c_getsda(void *data)
156 struct nouveau_i2c_chan *i2c = data;
157 struct drm_device *dev = i2c->dev;
159 return !!(nv_rd32(dev, i2c->rd) & 2);
162 static void
163 nv50_i2c_setscl(void *data, int state)
165 struct nouveau_i2c_chan *i2c = data;
166 struct drm_device *dev = i2c->dev;
168 nv_wr32(dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0));
171 static void
172 nv50_i2c_setsda(void *data, int state)
174 struct nouveau_i2c_chan *i2c = data;
175 struct drm_device *dev = i2c->dev;
177 nv_wr32(dev, i2c->wr,
178 (nv_rd32(dev, i2c->rd) & 1) | 4 | (state ? 2 : 0));
179 i2c->data = state;
182 static int
183 nvd0_i2c_getscl(void *data)
185 struct nouveau_i2c_chan *i2c = data;
186 return !!(nv_rd32(i2c->dev, i2c->rd) & 0x10);
189 static int
190 nvd0_i2c_getsda(void *data)
192 struct nouveau_i2c_chan *i2c = data;
193 return !!(nv_rd32(i2c->dev, i2c->rd) & 0x20);
196 static void
197 pscnv_iicbb_setsda(device_t idev, int val)
199 struct nouveau_i2c_chan *i2c = device_get_softc(idev);
200 i2c->bit.setsda(i2c, val);
203 static void
204 pscnv_iicbb_setscl(device_t idev, int val)
206 struct nouveau_i2c_chan *i2c = device_get_softc(idev);
207 i2c->bit.setscl(i2c, val);
210 static int
211 pscnv_iicbb_getsda(device_t idev)
213 struct nouveau_i2c_chan *i2c = device_get_softc(idev);
214 return i2c->bit.getsda(i2c);
217 static int
218 pscnv_iicbb_getscl(device_t idev)
220 struct nouveau_i2c_chan *i2c = device_get_softc(idev);
221 return i2c->bit.getscl(i2c);
225 static const uint32_t nv50_i2c_port[] = {
226 0x00e138, 0x00e150, 0x00e168, 0x00e180,
227 0x00e254, 0x00e274, 0x00e764, 0x00e780,
228 0x00e79c, 0x00e7b8
230 #define NV50_I2C_PORTS DRM_ARRAY_SIZE(nv50_i2c_port)
233 nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
235 struct drm_nouveau_private *dev_priv = dev->dev_private;
236 struct nouveau_i2c_chan *i2c;
237 int ret;
238 device_t idev;
240 if (entry->chan)
241 return -EEXIST;
243 if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) {
244 NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
245 return -EINVAL;
248 if (entry->port_type < 6) {
249 idev = device_add_child(dev->device, "pscnv_iicbb", index);
250 } else {
251 idev = device_add_child(dev->device, "pscnv_gmbus", index);
253 if (!idev) {
254 return -ENODEV;
256 ret = device_probe_and_attach(idev);
257 if (ret) {
258 NV_ERROR(dev, "Couldn't attach device: %d\n", ret);
259 device_delete_child(dev->device, idev);
260 return -ret;
262 device_quiet(idev);
263 i2c = device_get_softc(idev);
264 if (!i2c) {
265 NV_ERROR(dev, "Erp?!\n");
266 return -ENODEV;
269 switch (entry->port_type) {
270 case 0:
271 i2c->bit.setsda = nv04_i2c_setsda;
272 i2c->bit.setscl = nv04_i2c_setscl;
273 i2c->bit.getsda = nv04_i2c_getsda;
274 i2c->bit.getscl = nv04_i2c_getscl;
275 i2c->rd = entry->read;
276 i2c->wr = entry->write;
277 break;
278 case 4:
279 i2c->bit.setsda = nv4e_i2c_setsda;
280 i2c->bit.setscl = nv4e_i2c_setscl;
281 i2c->bit.getsda = nv4e_i2c_getsda;
282 i2c->bit.getscl = nv4e_i2c_getscl;
283 i2c->rd = 0x600800 + entry->read;
284 i2c->wr = 0x600800 + entry->write;
285 break;
286 case 5:
287 i2c->bit.setsda = nv50_i2c_setsda;
288 i2c->bit.setscl = nv50_i2c_setscl;
289 if (dev_priv->card_type < NV_D0) {
290 i2c->bit.getsda = nv50_i2c_getsda;
291 i2c->bit.getscl = nv50_i2c_getscl;
292 i2c->rd = nv50_i2c_port[entry->read];
293 } else {
294 i2c->bit.getsda = nvd0_i2c_getsda;
295 i2c->bit.getscl = nvd0_i2c_getscl;
296 i2c->rd = 0x00d014 + (entry->read * 0x20);
298 i2c->wr = i2c->rd;
299 break;
300 case 6:
301 i2c->rd = entry->read;
302 i2c->wr = entry->write;
303 break;
304 default:
305 NV_ERROR(dev, "DCB I2C port type %d unknown\n",
306 entry->port_type);
307 return -EINVAL;
310 entry->chan = i2c;
311 return 0;
314 void
315 nouveau_i2c_fini(struct drm_device *dev, struct dcb_i2c_entry *entry)
317 if (!entry->chan)
318 return;
320 device_delete_child(dev->device, entry->chan->adapter);
323 struct nouveau_i2c_chan *
324 nouveau_i2c_find(struct drm_device *dev, int index)
326 struct drm_nouveau_private *dev_priv = dev->dev_private;
327 struct dcb_i2c_entry *i2c = &dev_priv->vbios.dcb.i2c[index];
329 if (index >= DCB_MAX_NUM_I2C_ENTRIES)
330 return NULL;
332 if (dev_priv->chipset >= NV_50 && (i2c->entry & 0x00000100)) {
333 uint32_t reg = 0xe500, val;
335 if (i2c->port_type == 6) {
336 reg += i2c->read * 0x50;
337 val = 0x2002;
338 } else {
339 reg += ((i2c->entry & 0x1e00) >> 9) * 0x50;
340 val = 0xe001;
343 nv_wr32(dev, reg, (nv_rd32(dev, reg) & ~0xf003) | val);
346 if (!i2c->chan && nouveau_i2c_init(dev, i2c, index))
347 return NULL;
348 return i2c->chan;
351 bool
352 nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
354 uint8_t buf[] = { 0 };
355 struct i2c_msg msgs[] = {
357 .slave = addr,
358 .flags = 0,
359 .len = 1,
360 .buf = buf,
363 .slave = addr,
364 .flags = IIC_M_RD,
365 .len = 1,
366 .buf = buf,
370 return !iicbus_transfer(i2c->bus, msgs, 2);
374 nouveau_i2c_identify(struct drm_device *dev, const char *what,
375 struct i2c_board_info *info,
376 bool (*match)(struct nouveau_i2c_chan *,
377 struct i2c_board_info *),
378 int index)
380 struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
381 int i;
383 NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
385 for (i = 0; info[i].addr; i++) {
386 if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
387 (!match || match(i2c, &info[i]))) {
388 NV_INFO(dev, "Detected %s on %i\n", what, index);
389 return i;
393 NV_DEBUG(dev, "No devices found.\n");
394 return -ENODEV;
397 static int
398 pscnv_gmbus_attach(device_t idev)
400 struct drm_nouveau_private *dev_priv;
401 struct nouveau_i2c_chan *sc;
402 int pin;
404 sc = device_get_softc(idev);
405 sc->dev = device_get_softc(device_get_parent(idev));
406 dev_priv = sc->dev->dev_private;
407 pin = device_get_unit(idev);
409 snprintf(sc->name, sizeof(sc->name), "pscnv_iicbb %u", pin);
410 device_set_desc(idev, sc->name);
412 /* add bus interface device */
413 sc->bus = sc->iic_dev = device_add_child(idev, "iicbus", -1);
414 if (sc->iic_dev == NULL) {
415 NV_ERROR(sc->dev, "Could not add iicbus to gmbus!\n");
416 return (ENXIO);
418 device_quiet(sc->iic_dev);
419 bus_generic_attach(idev);
421 return (0);
424 static int
425 pscnv_iicbb_attach(device_t idev)
427 struct drm_nouveau_private *dev_priv;
428 struct nouveau_i2c_chan *sc;
429 int pin;
431 sc = device_get_softc(idev);
432 sc->dev = device_get_softc(device_get_parent(idev));
433 dev_priv = sc->dev->dev_private;
434 pin = device_get_unit(idev);
436 snprintf(sc->name, sizeof(sc->name), "pscnv_iicbb %u", pin);
437 device_set_desc(idev, sc->name);
439 /* add bus interface device */
440 sc->iic_dev = device_add_child(idev, "iicbb", -1);
441 if (sc->iic_dev == NULL) {
442 NV_ERROR(sc->dev, "Could not add iicbb to our bitbanger!\n");
443 return (ENXIO);
445 device_quiet(sc->iic_dev);
446 bus_generic_attach(idev);
447 sc->bus = device_find_child(sc->iic_dev, "iicbus", -1);
449 return (0);
452 static int
453 pscnv_gmbus_transfer(device_t idev, struct iic_msg *msgs, uint32_t nmsgs)
455 struct drm_nouveau_private *dev_priv;
456 struct nouveau_i2c_chan *auxch;
457 struct i2c_msg *msg = msgs;
458 int ret, mcnt = nmsgs;
460 auxch = device_get_softc(idev);
461 dev_priv = auxch->dev->dev_private;
463 while (mcnt--) {
464 u8 remaining = msg->len;
465 u8 *ptr = msg->buf;
467 while (remaining) {
468 u8 cnt = (remaining > 16) ? 16 : remaining;
469 u8 cmd;
471 if (msg->flags & I2C_M_RD)
472 cmd = AUX_I2C_READ;
473 else
474 cmd = AUX_I2C_WRITE;
476 if (mcnt || remaining > 16)
477 cmd |= AUX_I2C_MOT;
479 ret = nouveau_dp_auxch(auxch, cmd, msg->slave, ptr, cnt);
480 if (ret < 0)
481 return (-ret);
483 switch (ret & NV50_AUXCH_STAT_REPLY_I2C) {
484 case NV50_AUXCH_STAT_REPLY_I2C_ACK:
485 break;
486 case NV50_AUXCH_STAT_REPLY_I2C_NACK:
487 return (EREMOTEIO);
488 case NV50_AUXCH_STAT_REPLY_I2C_DEFER:
489 udelay(100);
490 continue;
491 default:
492 NV_ERROR(auxch->dev, "bad auxch reply: 0x%08x\n", ret);
493 return (EREMOTEIO);
496 ptr += cnt;
497 remaining -= cnt;
500 msg++;
503 return (0);
506 static int
507 pscnv_iic_probe(device_t dev)
509 return (BUS_PROBE_SPECIFIC);
512 static int
513 pscnv_iic_detach(device_t idev)
515 struct nouveau_i2c_chan *sc;
516 device_t child;
518 sc = device_get_softc(idev);
519 child = sc->iic_dev;
520 bus_generic_detach(idev);
521 if (child)
522 device_delete_child(idev, child);
523 return (0);
526 static int
527 pscnv_iicbus_reset(device_t idev, u_char speed, u_char addr, u_char *oldaddr)
529 return (0);
532 /* DP transfer with auxch */
533 static device_method_t pscnv_gmbus_methods[] = {
534 DEVMETHOD(device_probe, pscnv_iic_probe),
535 DEVMETHOD(device_attach, pscnv_gmbus_attach),
536 DEVMETHOD(device_detach, pscnv_iic_detach),
537 DEVMETHOD(iicbus_reset, pscnv_iicbus_reset),
538 DEVMETHOD(iicbus_transfer, pscnv_gmbus_transfer),
539 DEVMETHOD_END
541 static driver_t pscnv_gmbus_driver = {
542 "pscnv_gmbus",
543 pscnv_gmbus_methods,
544 sizeof(struct nouveau_i2c_chan)
546 static devclass_t pscnv_gmbus_devclass;
547 DRIVER_MODULE_ORDERED(pscnv_gmbus, drm, pscnv_gmbus_driver,
548 pscnv_gmbus_devclass, 0, 0, SI_ORDER_FIRST);
549 DRIVER_MODULE(iicbus, pscnv_gmbus, iicbus_driver, iicbus_devclass, 0, 0);
551 /* Bit banging */
552 static device_method_t pscnv_iicbb_methods[] = {
553 DEVMETHOD(device_probe, pscnv_iic_probe),
554 DEVMETHOD(device_attach, pscnv_iicbb_attach),
555 DEVMETHOD(device_detach, pscnv_iic_detach),
557 DEVMETHOD(bus_add_child, bus_generic_add_child),
558 DEVMETHOD(bus_print_child, bus_generic_print_child),
560 DEVMETHOD(iicbb_callback, iicbus_null_callback),
561 DEVMETHOD(iicbus_reset, pscnv_iicbus_reset),
562 DEVMETHOD(iicbb_setsda, pscnv_iicbb_setsda),
563 DEVMETHOD(iicbb_setscl, pscnv_iicbb_setscl),
564 DEVMETHOD(iicbb_getsda, pscnv_iicbb_getsda),
565 DEVMETHOD(iicbb_getscl, pscnv_iicbb_getscl),
566 DEVMETHOD_END
568 static driver_t pscnv_iicbb_driver = {
569 "pscnv_iicbb",
570 pscnv_iicbb_methods,
571 sizeof(struct nouveau_i2c_chan)
573 static devclass_t pscnv_iicbb_devclass;
574 DRIVER_MODULE_ORDERED(pscnv_iicbb, drm, pscnv_iicbb_driver,
575 pscnv_iicbb_devclass, 0, 0, SI_ORDER_FIRST);
576 DRIVER_MODULE(iicbb, pscnv_iicbb, iicbb_driver, iicbb_devclass, 0, 0);