i2c-mv64xxx.c 27.4 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
/*
2 3
 * Driver for the i2c controller on the Marvell line of host bridges
 * (e.g, gt642[46]0, mv643[46]0, mv644[46]0, and Orion SoC family).
Linus Torvalds's avatar
Linus Torvalds committed
4 5 6 7 8 9 10 11 12
 *
 * Author: Mark A. Greer <mgreer@mvista.com>
 *
 * 2005 (c) MontaVista, Software, Inc.  This file is licensed under
 * the terms of the GNU General Public License version 2.  This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */
#include <linux/kernel.h>
13
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
14 15 16 17
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
18
#include <linux/mv643xx_i2c.h>
19
#include <linux/platform_device.h>
20
#include <linux/reset.h>
21
#include <linux/io.h>
22
#include <linux/of.h>
23
#include <linux/of_device.h>
24 25 26
#include <linux/of_irq.h>
#include <linux/clk.h>
#include <linux/err.h>
27
#include <linux/delay.h>
Linus Torvalds's avatar
Linus Torvalds committed
28

29 30 31 32
#define MV64XXX_I2C_ADDR_ADDR(val)			((val & 0x7f) << 1)
#define MV64XXX_I2C_BAUD_DIV_N(val)			(val & 0x7)
#define MV64XXX_I2C_BAUD_DIV_M(val)			((val & 0xf) << 3)

33 34 35 36 37 38
#define	MV64XXX_I2C_REG_CONTROL_ACK			BIT(2)
#define	MV64XXX_I2C_REG_CONTROL_IFLG			BIT(3)
#define	MV64XXX_I2C_REG_CONTROL_STOP			BIT(4)
#define	MV64XXX_I2C_REG_CONTROL_START			BIT(5)
#define	MV64XXX_I2C_REG_CONTROL_TWSIEN			BIT(6)
#define	MV64XXX_I2C_REG_CONTROL_INTEN			BIT(7)
Linus Torvalds's avatar
Linus Torvalds committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

/* Ctlr status values */
#define	MV64XXX_I2C_STATUS_BUS_ERR			0x00
#define	MV64XXX_I2C_STATUS_MAST_START			0x08
#define	MV64XXX_I2C_STATUS_MAST_REPEAT_START		0x10
#define	MV64XXX_I2C_STATUS_MAST_WR_ADDR_ACK		0x18
#define	MV64XXX_I2C_STATUS_MAST_WR_ADDR_NO_ACK		0x20
#define	MV64XXX_I2C_STATUS_MAST_WR_ACK			0x28
#define	MV64XXX_I2C_STATUS_MAST_WR_NO_ACK		0x30
#define	MV64XXX_I2C_STATUS_MAST_LOST_ARB		0x38
#define	MV64XXX_I2C_STATUS_MAST_RD_ADDR_ACK		0x40
#define	MV64XXX_I2C_STATUS_MAST_RD_ADDR_NO_ACK		0x48
#define	MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK		0x50
#define	MV64XXX_I2C_STATUS_MAST_RD_DATA_NO_ACK		0x58
#define	MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK		0xd0
#define	MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK	0xd8
#define	MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK		0xe0
#define	MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK	0xe8
#define	MV64XXX_I2C_STATUS_NO_STATUS			0xf8

59 60 61 62 63 64 65 66 67 68 69 70
/* Register defines (I2C bridge) */
#define	MV64XXX_I2C_REG_TX_DATA_LO			0xc0
#define	MV64XXX_I2C_REG_TX_DATA_HI			0xc4
#define	MV64XXX_I2C_REG_RX_DATA_LO			0xc8
#define	MV64XXX_I2C_REG_RX_DATA_HI			0xcc
#define	MV64XXX_I2C_REG_BRIDGE_CONTROL			0xd0
#define	MV64XXX_I2C_REG_BRIDGE_STATUS			0xd4
#define	MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE		0xd8
#define	MV64XXX_I2C_REG_BRIDGE_INTR_MASK		0xdC
#define	MV64XXX_I2C_REG_BRIDGE_TIMING			0xe0

/* Bridge Control values */
71 72
#define	MV64XXX_I2C_BRIDGE_CONTROL_WR			BIT(0)
#define	MV64XXX_I2C_BRIDGE_CONTROL_RD			BIT(1)
73
#define	MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT		2
74
#define	MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT		BIT(12)
75 76
#define	MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT	13
#define	MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT	16
77
#define	MV64XXX_I2C_BRIDGE_CONTROL_ENABLE		BIT(19)
78
#define	MV64XXX_I2C_BRIDGE_CONTROL_REPEATED_START	BIT(20)
79 80

/* Bridge Status values */
81
#define	MV64XXX_I2C_BRIDGE_STATUS_ERROR			BIT(0)
82

Linus Torvalds's avatar
Linus Torvalds committed
83 84 85 86 87
/* Driver states */
enum {
	MV64XXX_I2C_STATE_INVALID,
	MV64XXX_I2C_STATE_IDLE,
	MV64XXX_I2C_STATE_WAITING_FOR_START_COND,
88
	MV64XXX_I2C_STATE_WAITING_FOR_RESTART,
Linus Torvalds's avatar
Linus Torvalds committed
89 90 91 92 93 94 95 96 97 98
	MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK,
	MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
	MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
	MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA,
};

/* Driver actions */
enum {
	MV64XXX_I2C_ACTION_INVALID,
	MV64XXX_I2C_ACTION_CONTINUE,
99
	MV64XXX_I2C_ACTION_SEND_RESTART,
Linus Torvalds's avatar
Linus Torvalds committed
100 101 102 103 104 105 106 107
	MV64XXX_I2C_ACTION_SEND_ADDR_1,
	MV64XXX_I2C_ACTION_SEND_ADDR_2,
	MV64XXX_I2C_ACTION_SEND_DATA,
	MV64XXX_I2C_ACTION_RCV_DATA,
	MV64XXX_I2C_ACTION_RCV_DATA_STOP,
	MV64XXX_I2C_ACTION_SEND_STOP,
};

108 109 110 111 112 113 114 115 116 117
struct mv64xxx_i2c_regs {
	u8	addr;
	u8	ext_addr;
	u8	data;
	u8	control;
	u8	status;
	u8	clock;
	u8	soft_reset;
};

Linus Torvalds's avatar
Linus Torvalds committed
118
struct mv64xxx_i2c_data {
119 120
	struct i2c_msg		*msgs;
	int			num_msgs;
Linus Torvalds's avatar
Linus Torvalds committed
121 122 123
	int			irq;
	u32			state;
	u32			action;
124
	u32			aborting;
Linus Torvalds's avatar
Linus Torvalds committed
125 126
	u32			cntl_bits;
	void __iomem		*reg_base;
127
	struct mv64xxx_i2c_regs	reg_offsets;
Linus Torvalds's avatar
Linus Torvalds committed
128 129 130 131
	u32			addr1;
	u32			addr2;
	u32			bytes_left;
	u32			byte_posn;
132
	u32			send_stop;
Linus Torvalds's avatar
Linus Torvalds committed
133 134 135 136
	u32			block;
	int			rc;
	u32			freq_m;
	u32			freq_n;
137 138 139
#if defined(CONFIG_HAVE_CLK)
	struct clk              *clk;
#endif
Linus Torvalds's avatar
Linus Torvalds committed
140 141 142 143
	wait_queue_head_t	waitq;
	spinlock_t		lock;
	struct i2c_msg		*msg;
	struct i2c_adapter	adapter;
144
	bool			offload_enabled;
145 146
/* 5us delay in order to avoid repeated start timing violation */
	bool			errata_delay;
147
	struct reset_control	*rstc;
148
	bool			irq_clear_inverted;
149 150
	/* Clk div is 2 to the power n, not 2 to the power n + 1 */
	bool			clk_n_base_0;
Linus Torvalds's avatar
Linus Torvalds committed
151 152
};

153 154 155 156 157 158 159 160 161 162
static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
	.addr		= 0x00,
	.ext_addr	= 0x10,
	.data		= 0x04,
	.control	= 0x08,
	.status		= 0x0c,
	.clock		= 0x0c,
	.soft_reset	= 0x1c,
};

163 164 165 166 167 168 169 170 171 172
static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_sun4i = {
	.addr		= 0x00,
	.ext_addr	= 0x04,
	.data		= 0x08,
	.control	= 0x0c,
	.status		= 0x10,
	.clock		= 0x14,
	.soft_reset	= 0x18,
};

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
static void
mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
	struct i2c_msg *msg)
{
	u32	dir = 0;

	drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
		MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;

	if (msg->flags & I2C_M_RD)
		dir = 1;

	if (msg->flags & I2C_M_TEN) {
		drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
		drv_data->addr2 = (u32)msg->addr & 0xff;
	} else {
189
		drv_data->addr1 = MV64XXX_I2C_ADDR_ADDR((u32)msg->addr) | dir;
190 191 192 193
		drv_data->addr2 = 0;
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
194 195 196 197 198 199 200
/*
 *****************************************************************************
 *
 *	Finite State Machine & Interrupt Routines
 *
 *****************************************************************************
 */
201 202 203 204 205

/* Reset hardware and initialize FSM */
static void
mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
{
206 207 208 209 210 211 212 213 214
	if (drv_data->offload_enabled) {
		writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL);
		writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_TIMING);
		writel(0, drv_data->reg_base +
			MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE);
		writel(0, drv_data->reg_base +
			MV64XXX_I2C_REG_BRIDGE_INTR_MASK);
	}

215
	writel(0, drv_data->reg_base + drv_data->reg_offsets.soft_reset);
216
	writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n),
217 218 219
		drv_data->reg_base + drv_data->reg_offsets.clock);
	writel(0, drv_data->reg_base + drv_data->reg_offsets.addr);
	writel(0, drv_data->reg_base + drv_data->reg_offsets.ext_addr);
220
	writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP,
221
		drv_data->reg_base + drv_data->reg_offsets.control);
222 223 224
	drv_data->state = MV64XXX_I2C_STATE_IDLE;
}

Linus Torvalds's avatar
Linus Torvalds committed
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
static void
mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
{
	/*
	 * If state is idle, then this is likely the remnants of an old
	 * operation that driver has given up on or the user has killed.
	 * If so, issue the stop condition and go to idle.
	 */
	if (drv_data->state == MV64XXX_I2C_STATE_IDLE) {
		drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
		return;
	}

	/* The status from the ctlr [mostly] tells us what to do next */
	switch (status) {
	/* Start condition interrupt */
	case MV64XXX_I2C_STATUS_MAST_START: /* 0x08 */
	case MV64XXX_I2C_STATUS_MAST_REPEAT_START: /* 0x10 */
		drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_1;
		drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
		break;

	/* Performing a write */
	case MV64XXX_I2C_STATUS_MAST_WR_ADDR_ACK: /* 0x18 */
		if (drv_data->msg->flags & I2C_M_TEN) {
			drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_2;
			drv_data->state =
				MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
			break;
		}
		/* FALLTHRU */
	case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
	case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
258 259 260
		if ((drv_data->bytes_left == 0)
				|| (drv_data->aborting
					&& (drv_data->byte_posn != 0))) {
261
			if (drv_data->send_stop || drv_data->aborting) {
262 263 264 265 266 267 268 269
				drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
				drv_data->state = MV64XXX_I2C_STATE_IDLE;
			} else {
				drv_data->action =
					MV64XXX_I2C_ACTION_SEND_RESTART;
				drv_data->state =
					MV64XXX_I2C_STATE_WAITING_FOR_RESTART;
			}
270
		} else {
Linus Torvalds's avatar
Linus Torvalds committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
			drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
			drv_data->state =
				MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
			drv_data->bytes_left--;
		}
		break;

	/* Performing a read */
	case MV64XXX_I2C_STATUS_MAST_RD_ADDR_ACK: /* 40 */
		if (drv_data->msg->flags & I2C_M_TEN) {
			drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_2;
			drv_data->state =
				MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
			break;
		}
		/* FALLTHRU */
	case MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK: /* 0xe0 */
		if (drv_data->bytes_left == 0) {
			drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
			drv_data->state = MV64XXX_I2C_STATE_IDLE;
			break;
		}
		/* FALLTHRU */
	case MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK: /* 0x50 */
		if (status != MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK)
			drv_data->action = MV64XXX_I2C_ACTION_CONTINUE;
		else {
			drv_data->action = MV64XXX_I2C_ACTION_RCV_DATA;
			drv_data->bytes_left--;
		}
		drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;

303
		if ((drv_data->bytes_left == 1) || drv_data->aborting)
Linus Torvalds's avatar
Linus Torvalds committed
304 305 306 307 308 309 310 311 312 313 314 315 316 317
			drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK;
		break;

	case MV64XXX_I2C_STATUS_MAST_RD_DATA_NO_ACK: /* 0x58 */
		drv_data->action = MV64XXX_I2C_ACTION_RCV_DATA_STOP;
		drv_data->state = MV64XXX_I2C_STATE_IDLE;
		break;

	case MV64XXX_I2C_STATUS_MAST_WR_ADDR_NO_ACK: /* 0x20 */
	case MV64XXX_I2C_STATUS_MAST_WR_NO_ACK: /* 30 */
	case MV64XXX_I2C_STATUS_MAST_RD_ADDR_NO_ACK: /* 48 */
		/* Doesn't seem to be a device at other end */
		drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
		drv_data->state = MV64XXX_I2C_STATE_IDLE;
318
		drv_data->rc = -ENXIO;
Linus Torvalds's avatar
Linus Torvalds committed
319 320 321 322 323 324 325 326 327
		break;

	default:
		dev_err(&drv_data->adapter.dev,
			"mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, "
			"status: 0x%x, addr: 0x%x, flags: 0x%x\n",
			 drv_data->state, status, drv_data->msg->addr,
			 drv_data->msg->flags);
		drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
328
		mv64xxx_i2c_hw_init(drv_data);
Linus Torvalds's avatar
Linus Torvalds committed
329 330 331 332
		drv_data->rc = -EIO;
	}
}

333 334
static void mv64xxx_i2c_send_start(struct mv64xxx_i2c_data *drv_data)
{
335 336 337 338 339 340
	drv_data->msg = drv_data->msgs;
	drv_data->byte_posn = 0;
	drv_data->bytes_left = drv_data->msg->len;
	drv_data->aborting = 0;
	drv_data->rc = 0;

341 342 343
	mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
	writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
	       drv_data->reg_base + drv_data->reg_offsets.control);
344 345
}

Linus Torvalds's avatar
Linus Torvalds committed
346 347 348 349
static void
mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
{
	switch(drv_data->action) {
350
	case MV64XXX_I2C_ACTION_SEND_RESTART:
351 352 353 354 355
		/* We should only get here if we have further messages */
		BUG_ON(drv_data->num_msgs == 0);

		drv_data->msgs++;
		drv_data->num_msgs--;
356
		mv64xxx_i2c_send_start(drv_data);
357

358 359 360
		if (drv_data->errata_delay)
			udelay(5);

361 362 363 364 365 366
		/*
		 * We're never at the start of the message here, and by this
		 * time it's already too late to do any protocol mangling.
		 * Thankfully, do not advertise support for that feature.
		 */
		drv_data->send_stop = drv_data->num_msgs == 1;
367 368
		break;

Linus Torvalds's avatar
Linus Torvalds committed
369 370
	case MV64XXX_I2C_ACTION_CONTINUE:
		writel(drv_data->cntl_bits,
371
			drv_data->reg_base + drv_data->reg_offsets.control);
Linus Torvalds's avatar
Linus Torvalds committed
372 373 374 375
		break;

	case MV64XXX_I2C_ACTION_SEND_ADDR_1:
		writel(drv_data->addr1,
376
			drv_data->reg_base + drv_data->reg_offsets.data);
Linus Torvalds's avatar
Linus Torvalds committed
377
		writel(drv_data->cntl_bits,
378
			drv_data->reg_base + drv_data->reg_offsets.control);
Linus Torvalds's avatar
Linus Torvalds committed
379 380 381 382
		break;

	case MV64XXX_I2C_ACTION_SEND_ADDR_2:
		writel(drv_data->addr2,
383
			drv_data->reg_base + drv_data->reg_offsets.data);
Linus Torvalds's avatar
Linus Torvalds committed
384
		writel(drv_data->cntl_bits,
385
			drv_data->reg_base + drv_data->reg_offsets.control);
Linus Torvalds's avatar
Linus Torvalds committed
386 387 388 389
		break;

	case MV64XXX_I2C_ACTION_SEND_DATA:
		writel(drv_data->msg->buf[drv_data->byte_posn++],
390
			drv_data->reg_base + drv_data->reg_offsets.data);
Linus Torvalds's avatar
Linus Torvalds committed
391
		writel(drv_data->cntl_bits,
392
			drv_data->reg_base + drv_data->reg_offsets.control);
Linus Torvalds's avatar
Linus Torvalds committed
393 394 395 396
		break;

	case MV64XXX_I2C_ACTION_RCV_DATA:
		drv_data->msg->buf[drv_data->byte_posn++] =
397
			readl(drv_data->reg_base + drv_data->reg_offsets.data);
Linus Torvalds's avatar
Linus Torvalds committed
398
		writel(drv_data->cntl_bits,
399
			drv_data->reg_base + drv_data->reg_offsets.control);
Linus Torvalds's avatar
Linus Torvalds committed
400 401 402 403
		break;

	case MV64XXX_I2C_ACTION_RCV_DATA_STOP:
		drv_data->msg->buf[drv_data->byte_posn++] =
404
			readl(drv_data->reg_base + drv_data->reg_offsets.data);
Linus Torvalds's avatar
Linus Torvalds committed
405 406
		drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
407
			drv_data->reg_base + drv_data->reg_offsets.control);
Linus Torvalds's avatar
Linus Torvalds committed
408
		drv_data->block = 0;
409 410 411
		if (drv_data->errata_delay)
			udelay(5);

412
		wake_up(&drv_data->waitq);
Linus Torvalds's avatar
Linus Torvalds committed
413 414 415 416 417 418 419 420
		break;

	case MV64XXX_I2C_ACTION_INVALID:
	default:
		dev_err(&drv_data->adapter.dev,
			"mv64xxx_i2c_do_action: Invalid action: %d\n",
			drv_data->action);
		drv_data->rc = -EIO;
421

Linus Torvalds's avatar
Linus Torvalds committed
422 423 424 425
		/* FALLTHRU */
	case MV64XXX_I2C_ACTION_SEND_STOP:
		drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
426
			drv_data->reg_base + drv_data->reg_offsets.control);
Linus Torvalds's avatar
Linus Torvalds committed
427
		drv_data->block = 0;
428
		wake_up(&drv_data->waitq);
Linus Torvalds's avatar
Linus Torvalds committed
429
		break;
430 431
	}
}
432

433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
static void
mv64xxx_i2c_read_offload_rx_data(struct mv64xxx_i2c_data *drv_data,
				 struct i2c_msg *msg)
{
	u32 buf[2];

	buf[0] = readl(drv_data->reg_base + MV64XXX_I2C_REG_RX_DATA_LO);
	buf[1] = readl(drv_data->reg_base + MV64XXX_I2C_REG_RX_DATA_HI);

	memcpy(msg->buf, buf, msg->len);
}

static int
mv64xxx_i2c_intr_offload(struct mv64xxx_i2c_data *drv_data)
{
	u32 cause, status;

	cause = readl(drv_data->reg_base +
		      MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE);
	if (!cause)
		return IRQ_NONE;

	status = readl(drv_data->reg_base +
		       MV64XXX_I2C_REG_BRIDGE_STATUS);

	if (status & MV64XXX_I2C_BRIDGE_STATUS_ERROR) {
		drv_data->rc = -EIO;
		goto out;
	}

	drv_data->rc = 0;

	/*
	 * Transaction is a one message read transaction, read data
	 * for this message.
	 */
	if (drv_data->num_msgs == 1 && drv_data->msgs[0].flags & I2C_M_RD) {
		mv64xxx_i2c_read_offload_rx_data(drv_data, drv_data->msgs);
		drv_data->msgs++;
		drv_data->num_msgs--;
Linus Torvalds's avatar
Linus Torvalds committed
473
	}
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
	/*
	 * Transaction is a two messages write/read transaction, read
	 * data for the second (read) message.
	 */
	else if (drv_data->num_msgs == 2 &&
		 !(drv_data->msgs[0].flags & I2C_M_RD) &&
		 drv_data->msgs[1].flags & I2C_M_RD) {
		mv64xxx_i2c_read_offload_rx_data(drv_data, drv_data->msgs + 1);
		drv_data->msgs += 2;
		drv_data->num_msgs -= 2;
	}

out:
	writel(0, drv_data->reg_base +	MV64XXX_I2C_REG_BRIDGE_CONTROL);
	writel(0, drv_data->reg_base +
	       MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE);
	drv_data->block = 0;

	wake_up(&drv_data->waitq);

	return IRQ_HANDLED;
Linus Torvalds's avatar
Linus Torvalds committed
495 496
}

497
static irqreturn_t
498
mv64xxx_i2c_intr(int irq, void *dev_id)
Linus Torvalds's avatar
Linus Torvalds committed
499 500 501 502
{
	struct mv64xxx_i2c_data	*drv_data = dev_id;
	unsigned long	flags;
	u32		status;
503
	irqreturn_t	rc = IRQ_NONE;
Linus Torvalds's avatar
Linus Torvalds committed
504 505

	spin_lock_irqsave(&drv_data->lock, flags);
506

507 508 509
	if (drv_data->offload_enabled)
		rc = mv64xxx_i2c_intr_offload(drv_data);

510
	while (readl(drv_data->reg_base + drv_data->reg_offsets.control) &
Linus Torvalds's avatar
Linus Torvalds committed
511
						MV64XXX_I2C_REG_CONTROL_IFLG) {
512
		status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
Linus Torvalds's avatar
Linus Torvalds committed
513 514
		mv64xxx_i2c_fsm(drv_data, status);
		mv64xxx_i2c_do_action(drv_data);
515 516 517 518 519

		if (drv_data->irq_clear_inverted)
			writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_IFLG,
			       drv_data->reg_base + drv_data->reg_offsets.control);

Linus Torvalds's avatar
Linus Torvalds committed
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
		rc = IRQ_HANDLED;
	}
	spin_unlock_irqrestore(&drv_data->lock, flags);

	return rc;
}

/*
 *****************************************************************************
 *
 *	I2C Msg Execution Routines
 *
 *****************************************************************************
 */
static void
mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
{
	long		time_left;
	unsigned long	flags;
	char		abort = 0;

541
	time_left = wait_event_timeout(drv_data->waitq,
542
		!drv_data->block, drv_data->adapter.timeout);
Linus Torvalds's avatar
Linus Torvalds committed
543 544 545 546 547 548 549 550 551 552 553

	spin_lock_irqsave(&drv_data->lock, flags);
	if (!time_left) { /* Timed out */
		drv_data->rc = -ETIMEDOUT;
		abort = 1;
	} else if (time_left < 0) { /* Interrupted/Error */
		drv_data->rc = time_left; /* errno value */
		abort = 1;
	}

	if (abort && drv_data->block) {
554
		drv_data->aborting = 1;
Linus Torvalds's avatar
Linus Torvalds committed
555 556 557
		spin_unlock_irqrestore(&drv_data->lock, flags);

		time_left = wait_event_timeout(drv_data->waitq,
558
			!drv_data->block, drv_data->adapter.timeout);
Linus Torvalds's avatar
Linus Torvalds committed
559

560
		if ((time_left <= 0) && drv_data->block) {
Linus Torvalds's avatar
Linus Torvalds committed
561 562
			drv_data->state = MV64XXX_I2C_STATE_IDLE;
			dev_err(&drv_data->adapter.dev,
563 564 565
				"mv64xxx: I2C bus locked, block: %d, "
				"time_left: %d\n", drv_data->block,
				(int)time_left);
566
			mv64xxx_i2c_hw_init(drv_data);
Linus Torvalds's avatar
Linus Torvalds committed
567 568 569 570 571 572
		}
	} else
		spin_unlock_irqrestore(&drv_data->lock, flags);
}

static int
573
mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
574
				int is_last)
Linus Torvalds's avatar
Linus Torvalds committed
575 576 577 578 579
{
	unsigned long	flags;

	spin_lock_irqsave(&drv_data->lock, flags);

580 581
	drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;

582
	drv_data->send_stop = is_last;
Linus Torvalds's avatar
Linus Torvalds committed
583
	drv_data->block = 1;
584
	mv64xxx_i2c_send_start(drv_data);
Linus Torvalds's avatar
Linus Torvalds committed
585 586 587 588 589 590
	spin_unlock_irqrestore(&drv_data->lock, flags);

	mv64xxx_i2c_wait_for_completion(drv_data);
	return drv_data->rc;
}

591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
static void
mv64xxx_i2c_prepare_tx(struct mv64xxx_i2c_data *drv_data)
{
	struct i2c_msg *msg = drv_data->msgs;
	u32 buf[2];

	memcpy(buf, msg->buf, msg->len);

	writel(buf[0], drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO);
	writel(buf[1], drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI);
}

static int
mv64xxx_i2c_offload_xfer(struct mv64xxx_i2c_data *drv_data)
{
	struct i2c_msg *msgs = drv_data->msgs;
	int num = drv_data->num_msgs;
	unsigned long ctrl_reg;
	unsigned long flags;

	spin_lock_irqsave(&drv_data->lock, flags);

	/* Build transaction */
	ctrl_reg = MV64XXX_I2C_BRIDGE_CONTROL_ENABLE |
		(msgs[0].addr << MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT);

	if (msgs[0].flags & I2C_M_TEN)
		ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT;

	/* Single write message transaction */
	if (num == 1 && !(msgs[0].flags & I2C_M_RD)) {
		size_t len = msgs[0].len - 1;

		ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR |
			(len << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT);
		mv64xxx_i2c_prepare_tx(drv_data);
	}
	/* Single read message transaction */
	else if (num == 1 && msgs[0].flags & I2C_M_RD) {
		size_t len = msgs[0].len - 1;

		ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_RD |
			(len << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT);
	}
	/*
	 * Transaction with one write and one read message. This is
	 * guaranteed by the mv64xx_i2c_can_offload() checks.
	 */
	else if (num == 2) {
		size_t lentx = msgs[0].len - 1;
		size_t lenrx = msgs[1].len - 1;

		ctrl_reg |=
			MV64XXX_I2C_BRIDGE_CONTROL_RD |
			MV64XXX_I2C_BRIDGE_CONTROL_WR |
			(lentx << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT) |
			(lenrx << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT) |
			MV64XXX_I2C_BRIDGE_CONTROL_REPEATED_START;
		mv64xxx_i2c_prepare_tx(drv_data);
	}

	/* Execute transaction */
	drv_data->block = 1;
	writel(ctrl_reg, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL);
	spin_unlock_irqrestore(&drv_data->lock, flags);

	mv64xxx_i2c_wait_for_completion(drv_data);

	return drv_data->rc;
}

static bool
mv64xxx_i2c_valid_offload_sz(struct i2c_msg *msg)
{
	return msg->len <= 8 && msg->len >= 1;
}

static bool
mv64xxx_i2c_can_offload(struct mv64xxx_i2c_data *drv_data)
{
	struct i2c_msg *msgs = drv_data->msgs;
	int num = drv_data->num_msgs;

	if (!drv_data->offload_enabled)
		return false;

	/*
	 * We can offload a transaction consisting of a single
	 * message, as long as the message has a length between 1 and
	 * 8 bytes.
	 */
	if (num == 1 && mv64xxx_i2c_valid_offload_sz(msgs))
		return true;

	/*
	 * We can offload a transaction consisting of two messages, if
	 * the first is a write and a second is a read, and both have
	 * a length between 1 and 8 bytes.
	 */
	if (num == 2 &&
	    mv64xxx_i2c_valid_offload_sz(msgs) &&
	    mv64xxx_i2c_valid_offload_sz(msgs + 1) &&
	    !(msgs[0].flags & I2C_M_RD) &&
	    msgs[1].flags & I2C_M_RD)
		return true;

	return false;
}

Linus Torvalds's avatar
Linus Torvalds committed
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
/*
 *****************************************************************************
 *
 *	I2C Core Support Routines (Interface to higher level I2C code)
 *
 *****************************************************************************
 */
static u32
mv64xxx_i2c_functionality(struct i2c_adapter *adap)
{
	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
}

static int
mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
	struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
717
	int rc, ret = num;
Linus Torvalds's avatar
Linus Torvalds committed
718

719 720 721 722
	BUG_ON(drv_data->msgs != NULL);
	drv_data->msgs = msgs;
	drv_data->num_msgs = num;

723 724 725 726 727
	if (mv64xxx_i2c_can_offload(drv_data))
		rc = mv64xxx_i2c_offload_xfer(drv_data);
	else
		rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1);

728 729 730 731 732
	if (rc < 0)
		ret = rc;

	drv_data->num_msgs = 0;
	drv_data->msgs = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
733

734
	return ret;
Linus Torvalds's avatar
Linus Torvalds committed
735 736
}

737
static const struct i2c_algorithm mv64xxx_i2c_algo = {
Linus Torvalds's avatar
Linus Torvalds committed
738 739 740 741 742 743 744 745 746 747 748
	.master_xfer = mv64xxx_i2c_xfer,
	.functionality = mv64xxx_i2c_functionality,
};

/*
 *****************************************************************************
 *
 *	Driver Interface & Early Init Routines
 *
 *****************************************************************************
 */
749
static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
750
	{ .compatible = "allwinner,sun4i-a10-i2c", .data = &mv64xxx_i2c_regs_sun4i},
751
	{ .compatible = "allwinner,sun6i-a31-i2c", .data = &mv64xxx_i2c_regs_sun4i},
752
	{ .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
753
	{ .compatible = "marvell,mv78230-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
754
	{ .compatible = "marvell,mv78230-a0-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
755 756 757 758
	{}
};
MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);

759
#ifdef CONFIG_OF
760
#ifdef CONFIG_HAVE_CLK
761
static int
762 763
mv64xxx_calc_freq(struct mv64xxx_i2c_data *drv_data,
		  const int tclk, const int n, const int m)
764
{
765 766 767 768
	if (drv_data->clk_n_base_0)
		return tclk / (10 * (m + 1) * (1 << n));
	else
		return tclk / (10 * (m + 1) * (2 << n));
769 770
}

771
static bool
772 773
mv64xxx_find_baud_factors(struct mv64xxx_i2c_data *drv_data,
			  const u32 req_freq, const u32 tclk)
774 775 776 777 778 779
{
	int freq, delta, best_delta = INT_MAX;
	int m, n;

	for (n = 0; n <= 7; n++)
		for (m = 0; m <= 15; m++) {
780
			freq = mv64xxx_calc_freq(drv_data, tclk, n, m);
781 782
			delta = req_freq - freq;
			if (delta >= 0 && delta < best_delta) {
783 784
				drv_data->freq_m = m;
				drv_data->freq_n = n;
785 786 787 788 789 790 791 792 793
				best_delta = delta;
			}
			if (best_delta == 0)
				return true;
		}
	if (best_delta == INT_MAX)
		return false;
	return true;
}
794
#endif /* CONFIG_HAVE_CLK */
795

796
static int
797
mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
798
		  struct device *dev)
799 800 801 802 803 804 805 806 807
{
	/* CLK is mandatory when using DT to describe the i2c bus. We
	 * need to know tclk in order to calculate bus clock
	 * factors.
	 */
#if !defined(CONFIG_HAVE_CLK)
	/* Have OF but no CLK */
	return -ENODEV;
#else
808 809 810 811 812
	const struct of_device_id *device;
	struct device_node *np = dev->of_node;
	u32 bus_freq, tclk;
	int rc = 0;

813 814 815 816 817
	if (IS_ERR(drv_data->clk)) {
		rc = -ENODEV;
		goto out;
	}
	tclk = clk_get_rate(drv_data->clk);
818

819
	if (of_property_read_u32(np, "clock-frequency", &bus_freq))
820 821
		bus_freq = 100000; /* 100kHz by default */

822 823 824 825 826
	if (of_device_is_compatible(np, "allwinner,sun4i-a10-i2c") ||
	    of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
		drv_data->clk_n_base_0 = true;

	if (!mv64xxx_find_baud_factors(drv_data, bus_freq, tclk)) {
827 828 829 830 831
		rc = -EINVAL;
		goto out;
	}
	drv_data->irq = irq_of_parse_and_map(np, 0);

832
	drv_data->rstc = devm_reset_control_get_optional(dev, NULL);
833 834 835 836 837 838 839 840 841
	if (IS_ERR(drv_data->rstc)) {
		if (PTR_ERR(drv_data->rstc) == -EPROBE_DEFER) {
			rc = -EPROBE_DEFER;
			goto out;
		}
	} else {
		reset_control_deassert(drv_data->rstc);
	}

842 843 844 845
	/* Its not yet defined how timeouts will be specified in device tree.
	 * So hard code the value to 1 second.
	 */
	drv_data->adapter.timeout = HZ;
846 847 848 849 850 851 852

	device = of_match_device(mv64xxx_i2c_of_match_table, dev);
	if (!device)
		return -ENODEV;

	memcpy(&drv_data->reg_offsets, device->data, sizeof(drv_data->reg_offsets));

853 854
	/*
	 * For controllers embedded in new SoCs activate the
855
	 * Transaction Generator support and the errata fix.
856
	 */
857
	if (of_device_is_compatible(np, "marvell,mv78230-i2c")) {
858
		drv_data->offload_enabled = true;
859 860
		drv_data->errata_delay = true;
	}
861

862 863 864 865
	if (of_device_is_compatible(np, "marvell,mv78230-a0-i2c")) {
		drv_data->offload_enabled = false;
		drv_data->errata_delay = true;
	}
866 867 868 869

	if (of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
		drv_data->irq_clear_inverted = true;

870 871 872 873 874
out:
	return rc;
#endif
}
#else /* CONFIG_OF */
875
static int
876
mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
877
		  struct device *dev)
878 879 880 881 882
{
	return -ENODEV;
}
#endif /* CONFIG_OF */

883
static int
884
mv64xxx_i2c_probe(struct platform_device *pd)
Linus Torvalds's avatar
Linus Torvalds committed
885 886
{
	struct mv64xxx_i2c_data		*drv_data;
Jingoo Han's avatar
Jingoo Han committed
887
	struct mv64xxx_i2c_pdata	*pdata = dev_get_platdata(&pd->dev);
888
	struct resource	*r;
Linus Torvalds's avatar
Linus Torvalds committed
889 890
	int	rc;

891
	if ((!pdata && !pd->dev.of_node))
Linus Torvalds's avatar
Linus Torvalds committed
892 893
		return -ENODEV;

894 895
	drv_data = devm_kzalloc(&pd->dev, sizeof(struct mv64xxx_i2c_data),
				GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
896 897 898
	if (!drv_data)
		return -ENOMEM;

899 900
	r = platform_get_resource(pd, IORESOURCE_MEM, 0);
	drv_data->reg_base = devm_ioremap_resource(&pd->dev, r);
901 902
	if (IS_ERR(drv_data->reg_base))
		return PTR_ERR(drv_data->reg_base);
Linus Torvalds's avatar
Linus Torvalds committed
903

904
	strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
905
		sizeof(drv_data->adapter.name));
Linus Torvalds's avatar
Linus Torvalds committed
906 907 908 909

	init_waitqueue_head(&drv_data->waitq);
	spin_lock_init(&drv_data->lock);

910 911
#if defined(CONFIG_HAVE_CLK)
	/* Not all platforms have a clk */
912
	drv_data->clk = devm_clk_get(&pd->dev, NULL);
913 914 915 916 917 918 919 920 921 922
	if (!IS_ERR(drv_data->clk)) {
		clk_prepare(drv_data->clk);
		clk_enable(drv_data->clk);
	}
#endif
	if (pdata) {
		drv_data->freq_m = pdata->freq_m;
		drv_data->freq_n = pdata->freq_n;
		drv_data->irq = platform_get_irq(pd, 0);
		drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
923
		drv_data->offload_enabled = false;
924
		memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets));
925
	} else if (pd->dev.of_node) {
926
		rc = mv64xxx_of_config(drv_data, &pd->dev);
927
		if (rc)
928
			goto exit_clk;
929
	}
930 931
	if (drv_data->irq < 0) {
		rc = -ENXIO;
932
		goto exit_reset;
933
	}
934

935
	drv_data->adapter.dev.parent = &pd->dev;
Linus Torvalds's avatar
Linus Torvalds committed
936 937
	drv_data->adapter.algo = &mv64xxx_i2c_algo;
	drv_data->adapter.owner = THIS_MODULE;
938
	drv_data->adapter.class = I2C_CLASS_DEPRECATED;
939
	drv_data->adapter.nr = pd->id;
940
	drv_data->adapter.dev.of_node = pd->dev.of_node;
941
	platform_set_drvdata(pd, drv_data);
Linus Torvalds's avatar
Linus Torvalds committed
942 943
	i2c_set_adapdata(&drv_data->adapter, drv_data);

944 945
	mv64xxx_i2c_hw_init(drv_data);

946 947 948
	rc = request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
			 MV64XXX_I2C_CTLR_NAME, drv_data);
	if (rc) {
949
		dev_err(&drv_data->adapter.dev,
950 951
			"mv64xxx: Can't register intr handler irq%d: %d\n",
			drv_data->irq, rc);
952
		goto exit_reset;
953
	} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
954 955
		dev_err(&drv_data->adapter.dev,
			"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
Linus Torvalds's avatar
Linus Torvalds committed
956 957 958 959 960
		goto exit_free_irq;
	}

	return 0;

961 962
exit_free_irq:
	free_irq(drv_data->irq, drv_data);
963
exit_reset:
964
	if (!IS_ERR_OR_NULL(drv_data->rstc))
965
		reset_control_assert(drv_data->rstc);
966
exit_clk:
967 968 969 970 971 972 973
#if defined(CONFIG_HAVE_CLK)
	/* Not all platforms have a clk */
	if (!IS_ERR(drv_data->clk)) {
		clk_disable(drv_data->clk);
		clk_unprepare(drv_data->clk);
	}
#endif
Linus Torvalds's avatar
Linus Torvalds committed
974 975 976
	return rc;
}

977
static int
978
mv64xxx_i2c_remove(struct platform_device *dev)
Linus Torvalds's avatar
Linus Torvalds committed
979
{
980
	struct mv64xxx_i2c_data		*drv_data = platform_get_drvdata(dev);
Linus Torvalds's avatar
Linus Torvalds committed
981

982
	i2c_del_adapter(&drv_data->adapter);
Linus Torvalds's avatar
Linus Torvalds committed
983
	free_irq(drv_data->irq, drv_data);
984
	if (!IS_ERR_OR_NULL(drv_data->rstc))
985
		reset_control_assert(drv_data->rstc);
986 987 988 989 990 991 992
#if defined(CONFIG_HAVE_CLK)
	/* Not all platforms have a clk */
	if (!IS_ERR(drv_data->clk)) {
		clk_disable(drv_data->clk);
		clk_unprepare(drv_data->clk);
	}
#endif
Linus Torvalds's avatar
Linus Torvalds committed
993

994
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
995 996
}

997
static struct platform_driver mv64xxx_i2c_driver = {
Linus Torvalds's avatar
Linus Torvalds committed
998
	.probe	= mv64xxx_i2c_probe,
999
	.remove	= mv64xxx_i2c_remove,
1000 1001
	.driver	= {
		.name	= MV64XXX_I2C_CTLR_NAME,
1002
		.of_match_table = mv64xxx_i2c_of_match_table,
1003
	},
Linus Torvalds's avatar
Linus Torvalds committed
1004 1005
};

1006
module_platform_driver(mv64xxx_i2c_driver);
Linus Torvalds's avatar
Linus Torvalds committed
1007 1008 1009 1010

MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
MODULE_DESCRIPTION("Marvell mv64xxx host bridge i2c ctlr driver");
MODULE_LICENSE("GPL");