~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/gpu/drm/nouveau/nouveau_i2c.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 * Authors: Ben Skeggs
23
23
 */
24
24
 
 
25
#include <linux/module.h>
 
26
 
25
27
#include "drmP.h"
26
28
#include "nouveau_drv.h"
27
29
#include "nouveau_i2c.h"
107
109
        return !!((nv_rd32(dev, i2c->rd) >> 16) & 8);
108
110
}
109
111
 
 
112
static const uint32_t nv50_i2c_port[] = {
 
113
        0x00e138, 0x00e150, 0x00e168, 0x00e180,
 
114
        0x00e254, 0x00e274, 0x00e764, 0x00e780,
 
115
        0x00e79c, 0x00e7b8
 
116
};
 
117
#define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port)
 
118
 
110
119
static int
111
120
nv50_i2c_getscl(void *data)
112
121
{
130
139
nv50_i2c_setscl(void *data, int state)
131
140
{
132
141
        struct nouveau_i2c_chan *i2c = data;
133
 
        struct drm_device *dev = i2c->dev;
134
142
 
135
 
        nv_wr32(dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0));
 
143
        nv_wr32(i2c->dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0));
136
144
}
137
145
 
138
146
static void
139
147
nv50_i2c_setsda(void *data, int state)
140
148
{
141
149
        struct nouveau_i2c_chan *i2c = data;
142
 
        struct drm_device *dev = i2c->dev;
143
150
 
144
 
        nv_wr32(dev, i2c->wr,
145
 
                        (nv_rd32(dev, i2c->rd) & 1) | 4 | (state ? 2 : 0));
 
151
        nv_mask(i2c->dev, i2c->wr, 0x00000006, 4 | (state ? 2 : 0));
146
152
        i2c->data = state;
147
153
}
148
154
 
149
 
static const uint32_t nv50_i2c_port[] = {
150
 
        0x00e138, 0x00e150, 0x00e168, 0x00e180,
151
 
        0x00e254, 0x00e274, 0x00e764, 0x00e780,
152
 
        0x00e79c, 0x00e7b8
153
 
};
154
 
#define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port)
 
155
static int
 
156
nvd0_i2c_getscl(void *data)
 
157
{
 
158
        struct nouveau_i2c_chan *i2c = data;
 
159
        return !!(nv_rd32(i2c->dev, i2c->rd) & 0x10);
 
160
}
 
161
 
 
162
static int
 
163
nvd0_i2c_getsda(void *data)
 
164
{
 
165
        struct nouveau_i2c_chan *i2c = data;
 
166
        return !!(nv_rd32(i2c->dev, i2c->rd) & 0x20);
 
167
}
155
168
 
156
169
int
157
170
nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
163
176
        if (entry->chan)
164
177
                return -EEXIST;
165
178
 
166
 
        if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) {
 
179
        if (dev_priv->card_type >= NV_50 &&
 
180
            dev_priv->card_type <= NV_C0 && entry->read >= NV50_I2C_PORTS) {
167
181
                NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
168
182
                return -EINVAL;
169
183
        }
192
206
        case 5:
193
207
                i2c->bit.setsda = nv50_i2c_setsda;
194
208
                i2c->bit.setscl = nv50_i2c_setscl;
195
 
                i2c->bit.getsda = nv50_i2c_getsda;
196
 
                i2c->bit.getscl = nv50_i2c_getscl;
197
 
                i2c->rd = nv50_i2c_port[entry->read];
198
 
                i2c->wr = i2c->rd;
 
209
                if (dev_priv->card_type < NV_D0) {
 
210
                        i2c->bit.getsda = nv50_i2c_getsda;
 
211
                        i2c->bit.getscl = nv50_i2c_getscl;
 
212
                        i2c->rd = nv50_i2c_port[entry->read];
 
213
                        i2c->wr = i2c->rd;
 
214
                } else {
 
215
                        i2c->bit.getsda = nvd0_i2c_getsda;
 
216
                        i2c->bit.getscl = nvd0_i2c_getscl;
 
217
                        i2c->rd = 0x00d014 + (entry->read * 0x20);
 
218
                        i2c->wr = i2c->rd;
 
219
                }
199
220
                break;
200
221
        case 6:
201
222
                i2c->rd = entry->read;
267
288
                        val  = 0xe001;
268
289
                }
269
290
 
270
 
                nv_wr32(dev, reg, (nv_rd32(dev, reg) & ~0xf003) | val);
 
291
                /* nfi, but neither auxch or i2c work if it's 1 */
 
292
                nv_mask(dev, reg + 0x0c, 0x00000001, 0x00000000);
 
293
                /* nfi, but switches auxch vs normal i2c */
 
294
                nv_mask(dev, reg + 0x00, 0x0000f003, val);
271
295
        }
272
296
 
273
297
        if (!i2c->chan && nouveau_i2c_init(dev, i2c, index))
309
333
 
310
334
        NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
311
335
 
312
 
        for (i = 0; info[i].addr; i++) {
 
336
        for (i = 0; i2c && info[i].addr; i++) {
313
337
                if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
314
338
                    (!match || match(i2c, &info[i]))) {
315
339
                        NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);