8250_dw.c 15.3 KB
Newer Older
J
Jamie Iles 已提交
1 2 3 4
/*
 * Synopsys DesignWare 8250 driver.
 *
 * Copyright 2011 Picochip, Jamie Iles.
5
 * Copyright 2013 Intel Corporation
J
Jamie Iles 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
 * LCR is written whilst busy.  If it is, then a busy detect interrupt is
 * raised, the LCR needs to be rewritten and the uart status register read.
 */
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
26
#include <linux/acpi.h>
27
#include <linux/clk.h>
28
#include <linux/reset.h>
29
#include <linux/pm_runtime.h>
J
Jamie Iles 已提交
30

31 32
#include <asm/byteorder.h>

33 34
#include "8250.h"

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
/* Offsets for the DesignWare specific registers */
#define DW_UART_USR	0x1f /* UART Status Register */
#define DW_UART_CPR	0xf4 /* Component Parameter Register */
#define DW_UART_UCV	0xf8 /* UART Component Version */

/* Component Parameter Register bits */
#define DW_UART_CPR_ABP_DATA_WIDTH	(3 << 0)
#define DW_UART_CPR_AFCE_MODE		(1 << 4)
#define DW_UART_CPR_THRE_MODE		(1 << 5)
#define DW_UART_CPR_SIR_MODE		(1 << 6)
#define DW_UART_CPR_SIR_LP_MODE		(1 << 7)
#define DW_UART_CPR_ADDITIONAL_FEATURES	(1 << 8)
#define DW_UART_CPR_FIFO_ACCESS		(1 << 9)
#define DW_UART_CPR_FIFO_STAT		(1 << 10)
#define DW_UART_CPR_SHADOW		(1 << 11)
#define DW_UART_CPR_ENCODED_PARMS	(1 << 12)
#define DW_UART_CPR_DMA_EXTRA		(1 << 13)
#define DW_UART_CPR_FIFO_MODE		(0xff << 16)
/* Helper for fifo size calculation */
#define DW_UART_CPR_FIFO_SIZE(a)	(((a >> 16) & 0xff) * 16)


J
Jamie Iles 已提交
57
struct dw8250_data {
58 59
	u8			usr_reg;
	int			line;
60 61
	int			msr_mask_on;
	int			msr_mask_off;
62
	struct clk		*clk;
63
	struct clk		*pclk;
64
	struct reset_control	*rst;
65
	struct uart_8250_dma	dma;
J
Jamie Iles 已提交
66 67
};

68 69 70 71 72 73
#define BYT_PRV_CLK			0x800
#define BYT_PRV_CLK_EN			(1 << 0)
#define BYT_PRV_CLK_M_VAL_SHIFT		1
#define BYT_PRV_CLK_N_VAL_SHIFT		16
#define BYT_PRV_CLK_UPDATE		(1 << 31)

74 75 76 77
static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
{
	struct dw8250_data *d = p->private_data;

78 79 80 81 82 83
	/* Override any modem control signals if needed */
	if (offset == UART_MSR) {
		value |= d->msr_mask_on;
		value &= ~d->msr_mask_off;
	}

84 85 86
	return value;
}

87 88
static void dw8250_force_idle(struct uart_port *p)
{
89 90 91
	struct uart_8250_port *up = up_to_u8250p(p);

	serial8250_clear_and_reinit_fifos(up);
92 93 94
	(void)p->serial_in(p, UART_RX);
}

J
Jamie Iles 已提交
95 96
static void dw8250_serial_out(struct uart_port *p, int offset, int value)
{
97
	writeb(value, p->membase + (offset << p->regshift));
98 99 100 101 102

	/* Make sure LCR write wasn't ignored */
	if (offset == UART_LCR) {
		int tries = 1000;
		while (tries--) {
103 104
			unsigned int lcr = p->serial_in(p, UART_LCR);
			if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
105 106 107 108
				return;
			dw8250_force_idle(p);
			writeb(value, p->membase + (UART_LCR << p->regshift));
		}
109 110 111 112
		/*
		 * FIXME: this deadlocks if port->lock is already held
		 * dev_err(p->dev, "Couldn't set LCR to %d\n", value);
		 */
113
	}
J
Jamie Iles 已提交
114 115 116 117
}

static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
{
118
	unsigned int value = readb(p->membase + (offset << p->regshift));
J
Jamie Iles 已提交
119

120
	return dw8250_modify_msr(p, offset, value);
J
Jamie Iles 已提交
121 122
}

123 124
#ifdef CONFIG_64BIT
static unsigned int dw8250_serial_inq(struct uart_port *p, int offset)
125
{
126 127 128 129 130
	unsigned int value;

	value = (u8)__raw_readq(p->membase + (offset << p->regshift));

	return dw8250_modify_msr(p, offset, value);
131 132
}

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
static void dw8250_serial_outq(struct uart_port *p, int offset, int value)
{
	value &= 0xff;
	__raw_writeq(value, p->membase + (offset << p->regshift));
	/* Read back to ensure register write ordering. */
	__raw_readq(p->membase + (UART_LCR << p->regshift));

	/* Make sure LCR write wasn't ignored */
	if (offset == UART_LCR) {
		int tries = 1000;
		while (tries--) {
			unsigned int lcr = p->serial_in(p, UART_LCR);
			if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
				return;
			dw8250_force_idle(p);
			__raw_writeq(value & 0xff,
				     p->membase + (UART_LCR << p->regshift));
		}
151 152 153 154
		/*
		 * FIXME: this deadlocks if port->lock is already held
		 * dev_err(p->dev, "Couldn't set LCR to %d\n", value);
		 */
155 156 157 158
	}
}
#endif /* CONFIG_64BIT */

J
Jamie Iles 已提交
159 160
static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
{
161
	writel(value, p->membase + (offset << p->regshift));
162 163 164 165 166

	/* Make sure LCR write wasn't ignored */
	if (offset == UART_LCR) {
		int tries = 1000;
		while (tries--) {
167 168
			unsigned int lcr = p->serial_in(p, UART_LCR);
			if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
169 170 171 172
				return;
			dw8250_force_idle(p);
			writel(value, p->membase + (UART_LCR << p->regshift));
		}
173 174 175 176
		/*
		 * FIXME: this deadlocks if port->lock is already held
		 * dev_err(p->dev, "Couldn't set LCR to %d\n", value);
		 */
177
	}
J
Jamie Iles 已提交
178 179 180 181
}

static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
{
182
	unsigned int value = readl(p->membase + (offset << p->regshift));
J
Jamie Iles 已提交
183

184
	return dw8250_modify_msr(p, offset, value);
J
Jamie Iles 已提交
185 186 187 188 189 190 191 192 193 194
}

static int dw8250_handle_irq(struct uart_port *p)
{
	struct dw8250_data *d = p->private_data;
	unsigned int iir = p->serial_in(p, UART_IIR);

	if (serial8250_handle_irq(p, iir)) {
		return 1;
	} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
195
		/* Clear the USR */
196
		(void)p->serial_in(p, d->usr_reg);
J
Jamie Iles 已提交
197 198 199 200 201 202 203

		return 1;
	}

	return 0;
}

204 205 206 207 208 209 210 211 212 213 214 215
static void
dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
{
	if (!state)
		pm_runtime_get_sync(port->dev);

	serial8250_do_pm(port, state, old);

	if (state)
		pm_runtime_put_sync_suspend(port->dev);
}

216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
			       struct ktermios *old)
{
	unsigned int baud = tty_termios_baud_rate(termios);
	struct dw8250_data *d = p->private_data;
	unsigned int rate;
	int ret;

	if (IS_ERR(d->clk) || !old)
		goto out;

	/* Not requesting clock rates below 1.8432Mhz */
	if (baud < 115200)
		baud = 115200;

	clk_disable_unprepare(d->clk);
	rate = clk_round_rate(d->clk, baud * 16);
	ret = clk_set_rate(d->clk, rate);
	clk_prepare_enable(d->clk);

	if (!ret)
		p->uartclk = rate;
238 239 240 241 242

	p->status &= ~UPSTAT_AUTOCTS;
	if (termios->c_cflag & CRTSCTS)
		p->status |= UPSTAT_AUTOCTS;

243 244 245 246
out:
	serial8250_do_set_termios(p, termios, old);
}

247 248
static bool dw8250_dma_filter(struct dma_chan *chan, void *param)
{
249
	return false;
250 251
}

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
static void dw8250_setup_port(struct uart_8250_port *up)
{
	struct uart_port	*p = &up->port;
	u32			reg = readl(p->membase + DW_UART_UCV);

	/*
	 * If the Component Version Register returns zero, we know that
	 * ADDITIONAL_FEATURES are not enabled. No need to go any further.
	 */
	if (!reg)
		return;

	dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n",
		(reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);

	reg = readl(p->membase + DW_UART_CPR);
	if (!reg)
		return;

	/* Select the type based on fifo */
	if (reg & DW_UART_CPR_FIFO_MODE) {
		p->type = PORT_16550A;
		p->flags |= UPF_FIXED_TYPE;
		p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
		up->tx_loadsz = p->fifosize;
		up->capabilities = UART_CAP_FIFO;
	}

	if (reg & DW_UART_CPR_AFCE_MODE)
		up->capabilities |= UART_CAP_AFE;
}

static int dw8250_probe_of(struct uart_port *p,
			   struct dw8250_data *data)
286 287
{
	struct device_node	*np = p->dev->of_node;
288
	struct uart_8250_port *up = up_to_u8250p(p);
289
	bool has_ucv = true;
290
	int id;
291

292
#ifdef CONFIG_64BIT
293
	if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) {
294 295
		p->serial_in = dw8250_serial_inq;
		p->serial_out = dw8250_serial_outq;
296
		p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
297 298 299
		p->type = PORT_OCTEON;
		data->usr_reg = 0x27;
		has_ucv = false;
300
	}
301
#endif
302
	if (has_ucv)
303
		dw8250_setup_port(up);
304

305 306 307 308 309
	/* get index of serial line, if found in DT aliases */
	id = of_alias_get_id(np, "serial");
	if (id >= 0)
		p->line = id;

310 311 312
	return 0;
}

313 314 315 316 317 318 319 320 321 322
static bool dw8250_idma_filter(struct dma_chan *chan, void *param)
{
	struct device *dev = param;

	if (dev != chan->device->dev->parent)
		return false;

	return true;
}

323 324
static int dw8250_probe_acpi(struct uart_8250_port *up,
			     struct dw8250_data *data)
325
{
326
	struct uart_port *p = &up->port;
327

328 329
	dw8250_setup_port(up);

330 331 332 333
	p->iotype = UPIO_MEM32;
	p->serial_in = dw8250_serial_in32;
	p->serial_out = dw8250_serial_out32;
	p->regshift = 2;
334

335 336 337 338 339 340 341
	/* Platforms with iDMA */
	if (platform_get_resource_byname(to_platform_device(up->port.dev),
					 IORESOURCE_MEM, "lpss_priv")) {
		data->dma.rx_param = up->port.dev->parent;
		data->dma.tx_param = up->port.dev->parent;
		data->dma.fn = dw8250_idma_filter;
	}
342

343
	up->port.set_termios = dw8250_set_termios;
344

345 346 347
	return 0;
}

B
Bill Pemberton 已提交
348
static int dw8250_probe(struct platform_device *pdev)
J
Jamie Iles 已提交
349
{
350
	struct uart_8250_port uart = {};
J
Jamie Iles 已提交
351
	struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
352
	int irq = platform_get_irq(pdev, 0);
353
	struct uart_port *p = &uart.port;
J
Jamie Iles 已提交
354
	struct dw8250_data *data;
355
	int err;
356
	u32 val;
J
Jamie Iles 已提交
357

358 359
	if (!regs) {
		dev_err(&pdev->dev, "no registers defined\n");
J
Jamie Iles 已提交
360 361 362
		return -EINVAL;
	}

363 364 365 366 367 368
	if (irq < 0) {
		if (irq != -EPROBE_DEFER)
			dev_err(&pdev->dev, "cannot get irq\n");
		return irq;
	}

369 370 371 372 373 374 375 376 377 378 379 380 381 382
	spin_lock_init(&p->lock);
	p->mapbase	= regs->start;
	p->irq		= irq;
	p->handle_irq	= dw8250_handle_irq;
	p->pm		= dw8250_do_pm;
	p->type		= PORT_8250;
	p->flags	= UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
	p->dev		= &pdev->dev;
	p->iotype	= UPIO_MEM;
	p->serial_in	= dw8250_serial_in;
	p->serial_out	= dw8250_serial_out;

	p->membase = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
	if (!p->membase)
H
Heikki Krogerus 已提交
383 384
		return -ENOMEM;

385 386 387 388
	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

389
	data->usr_reg = DW_UART_USR;
390
	p->private_data = data;
391

392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
	err = device_property_read_u32(p->dev, "reg-shift", &val);
	if (!err)
		p->regshift = val;

	err = device_property_read_u32(p->dev, "reg-io-width", &val);
	if (!err && val == 4) {
		p->iotype = UPIO_MEM32;
		p->serial_in = dw8250_serial_in32;
		p->serial_out = dw8250_serial_out32;
	}

	if (device_property_read_bool(p->dev, "dcd-override")) {
		/* Always report DCD as active */
		data->msr_mask_on |= UART_MSR_DCD;
		data->msr_mask_off |= UART_MSR_DDCD;
	}

	if (device_property_read_bool(p->dev, "dsr-override")) {
		/* Always report DSR as active */
		data->msr_mask_on |= UART_MSR_DSR;
		data->msr_mask_off |= UART_MSR_DDSR;
	}

	if (device_property_read_bool(p->dev, "cts-override")) {
		/* Always report CTS as active */
		data->msr_mask_on |= UART_MSR_CTS;
		data->msr_mask_off |= UART_MSR_DCTS;
	}

	if (device_property_read_bool(p->dev, "ri-override")) {
		/* Always report Ring indicator as inactive */
		data->msr_mask_off |= UART_MSR_RI;
		data->msr_mask_off |= UART_MSR_TERI;
	}

427
	/* Always ask for fixed clock rate from a property. */
428
	device_property_read_u32(p->dev, "clock-frequency", &p->uartclk);
429 430

	/* If there is separate baudclk, get the rate from it. */
431
	data->clk = devm_clk_get(&pdev->dev, "baudclk");
432
	if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER)
433
		data->clk = devm_clk_get(&pdev->dev, NULL);
434 435
	if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER)
		return -EPROBE_DEFER;
436
	if (!IS_ERR_OR_NULL(data->clk)) {
437 438 439 440 441
		err = clk_prepare_enable(data->clk);
		if (err)
			dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n",
				 err);
		else
442
			p->uartclk = clk_get_rate(data->clk);
443 444
	}

445
	/* If no clock rate is defined, fail. */
446
	if (!p->uartclk) {
447 448 449 450
		dev_err(&pdev->dev, "clock rate not defined\n");
		return -EINVAL;
	}

451
	data->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
452 453 454 455
	if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) {
		err = -EPROBE_DEFER;
		goto err_clk;
	}
456 457 458 459
	if (!IS_ERR(data->pclk)) {
		err = clk_prepare_enable(data->pclk);
		if (err) {
			dev_err(&pdev->dev, "could not enable apb_pclk\n");
460
			goto err_clk;
461
		}
462 463
	}

464
	data->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
465 466 467 468
	if (IS_ERR(data->rst) && PTR_ERR(data->rst) == -EPROBE_DEFER) {
		err = -EPROBE_DEFER;
		goto err_pclk;
	}
469 470 471
	if (!IS_ERR(data->rst))
		reset_control_deassert(data->rst);

472 473 474 475
	data->dma.rx_param = data;
	data->dma.tx_param = data;
	data->dma.fn = dw8250_dma_filter;

476
	if (pdev->dev.of_node) {
477
		err = dw8250_probe_of(p, data);
478
		if (err)
479
			goto err_reset;
480
	} else if (ACPI_HANDLE(&pdev->dev)) {
481
		err = dw8250_probe_acpi(&uart, data);
482
		if (err)
483
			goto err_reset;
484
	} else {
485 486
		err = -ENODEV;
		goto err_reset;
J
Jamie Iles 已提交
487 488
	}

489 490 491 492 493 494 495
	/* If we have a valid fifosize, try hooking up DMA */
	if (p->fifosize) {
		data->dma.rxconf.src_maxburst = p->fifosize / 4;
		data->dma.txconf.dst_maxburst = p->fifosize / 4;
		uart.dma = &data->dma;
	}

496
	data->line = serial8250_register_8250_port(&uart);
497 498 499 500
	if (data->line < 0) {
		err = data->line;
		goto err_reset;
	}
J
Jamie Iles 已提交
501 502 503

	platform_set_drvdata(pdev, data);

504 505 506
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

J
Jamie Iles 已提交
507
	return 0;
508 509 510 511 512 513 514 515 516 517 518 519 520 521

err_reset:
	if (!IS_ERR(data->rst))
		reset_control_assert(data->rst);

err_pclk:
	if (!IS_ERR(data->pclk))
		clk_disable_unprepare(data->pclk);

err_clk:
	if (!IS_ERR(data->clk))
		clk_disable_unprepare(data->clk);

	return err;
J
Jamie Iles 已提交
522 523
}

B
Bill Pemberton 已提交
524
static int dw8250_remove(struct platform_device *pdev)
J
Jamie Iles 已提交
525 526 527
{
	struct dw8250_data *data = platform_get_drvdata(pdev);

528 529
	pm_runtime_get_sync(&pdev->dev);

J
Jamie Iles 已提交
530 531
	serial8250_unregister_port(data->line);

532 533 534
	if (!IS_ERR(data->rst))
		reset_control_assert(data->rst);

535 536 537
	if (!IS_ERR(data->pclk))
		clk_disable_unprepare(data->pclk);

538 539 540
	if (!IS_ERR(data->clk))
		clk_disable_unprepare(data->clk);

541 542 543
	pm_runtime_disable(&pdev->dev);
	pm_runtime_put_noidle(&pdev->dev);

J
Jamie Iles 已提交
544 545 546
	return 0;
}

547
#ifdef CONFIG_PM_SLEEP
548
static int dw8250_suspend(struct device *dev)
549
{
550
	struct dw8250_data *data = dev_get_drvdata(dev);
551 552 553 554 555 556

	serial8250_suspend_port(data->line);

	return 0;
}

557
static int dw8250_resume(struct device *dev)
558
{
559
	struct dw8250_data *data = dev_get_drvdata(dev);
560 561 562 563 564

	serial8250_resume_port(data->line);

	return 0;
}
565
#endif /* CONFIG_PM_SLEEP */
566

567
#ifdef CONFIG_PM
568 569 570 571
static int dw8250_runtime_suspend(struct device *dev)
{
	struct dw8250_data *data = dev_get_drvdata(dev);

572 573
	if (!IS_ERR(data->clk))
		clk_disable_unprepare(data->clk);
574

575 576 577
	if (!IS_ERR(data->pclk))
		clk_disable_unprepare(data->pclk);

578 579 580 581 582 583 584
	return 0;
}

static int dw8250_runtime_resume(struct device *dev)
{
	struct dw8250_data *data = dev_get_drvdata(dev);

585 586 587
	if (!IS_ERR(data->pclk))
		clk_prepare_enable(data->pclk);

588 589
	if (!IS_ERR(data->clk))
		clk_prepare_enable(data->clk);
590 591 592 593 594 595 596 597 598 599

	return 0;
}
#endif

static const struct dev_pm_ops dw8250_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(dw8250_suspend, dw8250_resume)
	SET_RUNTIME_PM_OPS(dw8250_runtime_suspend, dw8250_runtime_resume, NULL)
};

600
static const struct of_device_id dw8250_of_match[] = {
J
Jamie Iles 已提交
601
	{ .compatible = "snps,dw-apb-uart" },
602
	{ .compatible = "cavium,octeon-3860-uart" },
J
Jamie Iles 已提交
603 604
	{ /* Sentinel */ }
};
605
MODULE_DEVICE_TABLE(of, dw8250_of_match);
J
Jamie Iles 已提交
606

607
static const struct acpi_device_id dw8250_acpi_match[] = {
608 609
	{ "INT33C4", 0 },
	{ "INT33C5", 0 },
610 611
	{ "INT3434", 0 },
	{ "INT3435", 0 },
612
	{ "80860F0A", 0 },
613
	{ "8086228A", 0 },
614
	{ "APMC0D08", 0},
615
	{ "AMD0020", 0 },
616 617 618 619
	{ },
};
MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);

J
Jamie Iles 已提交
620 621 622
static struct platform_driver dw8250_platform_driver = {
	.driver = {
		.name		= "dw-apb-uart",
623
		.pm		= &dw8250_pm_ops,
624
		.of_match_table	= dw8250_of_match,
625
		.acpi_match_table = ACPI_PTR(dw8250_acpi_match),
J
Jamie Iles 已提交
626 627
	},
	.probe			= dw8250_probe,
628
	.remove			= dw8250_remove,
J
Jamie Iles 已提交
629 630
};

631
module_platform_driver(dw8250_platform_driver);
J
Jamie Iles 已提交
632 633 634 635

MODULE_AUTHOR("Jamie Iles");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver");
636
MODULE_ALIAS("platform:dw-apb-uart");