You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver patches from Greg KH: "Here's the big tty/serial driver update for 3.20-rc1. Nothing huge here, just lots of driver updates and some core tty layer fixes as well. All have been in linux-next with no reported issues" * tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (119 commits) serial: 8250: Fix UART_BUG_TXEN workaround serial: driver for ETRAX FS UART tty: remove unused variable sprop serial: of-serial: fetch line number from DT serial: samsung: earlycon support depends on CONFIG_SERIAL_SAMSUNG_CONSOLE tty/serial: serial8250_set_divisor() can be static tty/serial: Add Spreadtrum sc9836-uart driver support Documentation: DT: Add bindings for Spreadtrum SoC Platform serial: samsung: remove redundant interrupt enabling tty: Remove external interface for tty_set_termios() serial: omap: Fix RTS handling serial: 8250_omap: Use UPSTAT_AUTORTS for RTS handling serial: core: Rework hw-assisted flow control support tty/serial: 8250_early: Add support for PXA UARTs tty/serial: of_serial: add support for PXA/MMP uarts tty/serial: of_serial: add DT alias ID handling serial: 8250: Prevent concurrent updates to shadow registers serial: 8250: Use canary to restart console after suspend serial: 8250: Refactor XR17V35X divisor calculation serial: 8250: Refactor divisor programming ...
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
Spreadtrum SoC Platforms Device Tree Bindings
|
||||
----------------------------------------------------
|
||||
|
||||
Sharkl64 is a Spreadtrum's SoC Platform which is based
|
||||
on ARM 64-bit processor.
|
||||
|
||||
SC9836 openphone board with SC9836 SoC based on the
|
||||
Sharkl64 Platform shall have the following properties.
|
||||
|
||||
Required root node properties:
|
||||
- compatible = "sprd,sc9836-openphone", "sprd,sc9836";
|
||||
@@ -0,0 +1,27 @@
|
||||
Binding for Conexant Digicolor USART
|
||||
|
||||
Note: this binding is only applicable for using the USART peripheral as
|
||||
UART. USART also support synchronous serial protocols like SPI and I2S. Use
|
||||
the binding that matches the wiring of your system.
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "cnxt,cx92755-usart".
|
||||
- reg: Should contain USART controller registers location and length.
|
||||
- interrupts: Should contain a single USART controller interrupt.
|
||||
- clocks: Must contain phandles to the USART clock
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
|
||||
Note: Each UART port should have an alias correctly numbered
|
||||
in "aliases" node.
|
||||
|
||||
Example:
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
uart0: uart@f0000740 {
|
||||
compatible = "cnxt,cx92755-usart";
|
||||
reg = <0xf0000740 0x20>;
|
||||
clocks = <&main_clk>;
|
||||
interrupts = <44>;
|
||||
};
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "sirf,prima2-uart", "sirf, prima2-usp-uart",
|
||||
"sirf,marco-uart" or "sirf,marco-bt-uart" which means
|
||||
"sirf,atlas7-uart" or "sirf,atlas7-bt-uart" which means
|
||||
uart located in BT module and used for BT.
|
||||
- reg : Offset and length of the register set for the device
|
||||
- interrupts : Should contain uart interrupt
|
||||
@@ -37,7 +37,7 @@ usp@b0090000 {
|
||||
for uart use in BT module,
|
||||
uart6: uart@11000000 {
|
||||
cell-index = <6>;
|
||||
compatible = "sirf,marco-bt-uart", "sirf,marco-uart";
|
||||
compatible = "sirf,atlas7-bt-uart", "sirf,atlas7-uart";
|
||||
reg = <0x11000000 0x1000>;
|
||||
interrupts = <0 100 0>;
|
||||
clocks = <&clks 138>, <&clks 140>, <&clks 141>;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
* Spreadtrum serial UART
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "sprd,sc9836-uart"
|
||||
- reg: offset and length of the register set for the device
|
||||
- interrupts: exactly one interrupt specifier
|
||||
- clocks: phandles to input clocks.
|
||||
@@ -37,6 +37,7 @@ chrp Common Hardware Reference Platform
|
||||
chunghwa Chunghwa Picture Tubes Ltd.
|
||||
cirrus Cirrus Logic, Inc.
|
||||
cnm Chips&Media, Inc.
|
||||
cnxt Conexant Systems, Inc.
|
||||
cortina Cortina Systems, Inc.
|
||||
cosmic Cosmic Circuits
|
||||
crystalfontz Crystalfontz America, Inc.
|
||||
@@ -162,6 +163,7 @@ snps Synopsys, Inc.
|
||||
solidrun SolidRun
|
||||
sony Sony Corporation
|
||||
spansion Spansion Inc.
|
||||
sprd Spreadtrum Communications Inc.
|
||||
st STMicroelectronics
|
||||
ste ST-Ericsson
|
||||
stericsson ST-Ericsson
|
||||
|
||||
@@ -970,6 +970,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
|
||||
smh Use ARM semihosting calls for early console.
|
||||
|
||||
s3c2410,<addr>
|
||||
s3c2412,<addr>
|
||||
s3c2440,<addr>
|
||||
s3c6400,<addr>
|
||||
s5pv210,<addr>
|
||||
exynos4210,<addr>
|
||||
Use early console provided by serial driver available
|
||||
on Samsung SoCs, requires selecting proper type and
|
||||
a correct base address of the selected UART port. The
|
||||
serial port must already be setup and configured.
|
||||
Options are not yet supported.
|
||||
|
||||
earlyprintk= [X86,SH,BLACKFIN,ARM,M68k]
|
||||
earlyprintk=vga
|
||||
earlyprintk=efi
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
chosen {
|
||||
bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
|
||||
stdout-path = &serial_2;
|
||||
};
|
||||
|
||||
regulators {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
chosen {
|
||||
bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
|
||||
stdout-path = &serial_1;
|
||||
};
|
||||
|
||||
sdhci@12530000 {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
|
||||
stdout-path = &serial_2;
|
||||
};
|
||||
|
||||
regulators {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rw rootwait earlyprintk panic=5 maxcpus=1";
|
||||
stdout-path = &serial_2;
|
||||
};
|
||||
|
||||
sysram@02020000 {
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include "exynos4412.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = &serial_1;
|
||||
};
|
||||
|
||||
firmware@0204F000 {
|
||||
compatible = "samsung,secure-firmware";
|
||||
reg = <0x0204F000 0x1000>;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
chosen {
|
||||
bootargs ="console=ttySAC2,115200";
|
||||
stdout-path = &serial_2;
|
||||
};
|
||||
|
||||
firmware@0203F000 {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
chosen {
|
||||
bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
|
||||
stdout-path = &serial_1;
|
||||
};
|
||||
|
||||
g2d@10800000 {
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
model = "FriendlyARM TINY4412 board based on Exynos4412";
|
||||
compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
|
||||
|
||||
chosen {
|
||||
stdout-path = &serial_0;
|
||||
};
|
||||
|
||||
memory {
|
||||
reg = <0x40000000 0x40000000>;
|
||||
};
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
|
||||
stdout-path = &serial_2;
|
||||
};
|
||||
|
||||
firmware@0204F000 {
|
||||
|
||||
@@ -136,9 +136,6 @@ extern enum intel_mid_timer_options intel_mid_timer_options;
|
||||
#define SFI_MTMR_MAX_NUM 8
|
||||
#define SFI_MRTC_MAX 8
|
||||
|
||||
extern struct console early_mrst_console;
|
||||
extern void mrst_early_console_init(void);
|
||||
|
||||
extern struct console early_hsu_console;
|
||||
extern void hsu_early_console_init(const char *);
|
||||
|
||||
|
||||
+167
-22
@@ -19,6 +19,7 @@
|
||||
#include <linux/usb/ehci_def.h>
|
||||
#include <linux/efi.h>
|
||||
#include <asm/efi.h>
|
||||
#include <asm/pci_x86.h>
|
||||
|
||||
/* Simple VGA output */
|
||||
#define VGABASE (__ISA_IO_base + 0xb8000)
|
||||
@@ -76,7 +77,7 @@ static struct console early_vga_console = {
|
||||
|
||||
/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */
|
||||
|
||||
static int early_serial_base = 0x3f8; /* ttyS0 */
|
||||
static unsigned long early_serial_base = 0x3f8; /* ttyS0 */
|
||||
|
||||
#define XMTRDY 0x20
|
||||
|
||||
@@ -94,13 +95,40 @@ static int early_serial_base = 0x3f8; /* ttyS0 */
|
||||
#define DLL 0 /* Divisor Latch Low */
|
||||
#define DLH 1 /* Divisor latch High */
|
||||
|
||||
static void mem32_serial_out(unsigned long addr, int offset, int value)
|
||||
{
|
||||
uint32_t *vaddr = (uint32_t *)addr;
|
||||
/* shift implied by pointer type */
|
||||
writel(value, vaddr + offset);
|
||||
}
|
||||
|
||||
static unsigned int mem32_serial_in(unsigned long addr, int offset)
|
||||
{
|
||||
uint32_t *vaddr = (uint32_t *)addr;
|
||||
/* shift implied by pointer type */
|
||||
return readl(vaddr + offset);
|
||||
}
|
||||
|
||||
static unsigned int io_serial_in(unsigned long addr, int offset)
|
||||
{
|
||||
return inb(addr + offset);
|
||||
}
|
||||
|
||||
static void io_serial_out(unsigned long addr, int offset, int value)
|
||||
{
|
||||
outb(value, addr + offset);
|
||||
}
|
||||
|
||||
static unsigned int (*serial_in)(unsigned long addr, int offset) = io_serial_in;
|
||||
static void (*serial_out)(unsigned long addr, int offset, int value) = io_serial_out;
|
||||
|
||||
static int early_serial_putc(unsigned char ch)
|
||||
{
|
||||
unsigned timeout = 0xffff;
|
||||
|
||||
while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
|
||||
while ((serial_in(early_serial_base, LSR) & XMTRDY) == 0 && --timeout)
|
||||
cpu_relax();
|
||||
outb(ch, early_serial_base + TXR);
|
||||
serial_out(early_serial_base, TXR, ch);
|
||||
return timeout ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -114,13 +142,28 @@ static void early_serial_write(struct console *con, const char *s, unsigned n)
|
||||
}
|
||||
}
|
||||
|
||||
static __init void early_serial_hw_init(unsigned divisor)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
serial_out(early_serial_base, LCR, 0x3); /* 8n1 */
|
||||
serial_out(early_serial_base, IER, 0); /* no interrupt */
|
||||
serial_out(early_serial_base, FCR, 0); /* no fifo */
|
||||
serial_out(early_serial_base, MCR, 0x3); /* DTR + RTS */
|
||||
|
||||
c = serial_in(early_serial_base, LCR);
|
||||
serial_out(early_serial_base, LCR, c | DLAB);
|
||||
serial_out(early_serial_base, DLL, divisor & 0xff);
|
||||
serial_out(early_serial_base, DLH, (divisor >> 8) & 0xff);
|
||||
serial_out(early_serial_base, LCR, c & ~DLAB);
|
||||
}
|
||||
|
||||
#define DEFAULT_BAUD 9600
|
||||
|
||||
static __init void early_serial_init(char *s)
|
||||
{
|
||||
unsigned char c;
|
||||
unsigned divisor;
|
||||
unsigned baud = DEFAULT_BAUD;
|
||||
unsigned long baud = DEFAULT_BAUD;
|
||||
char *e;
|
||||
|
||||
if (*s == ',')
|
||||
@@ -145,25 +188,125 @@ static __init void early_serial_init(char *s)
|
||||
s++;
|
||||
}
|
||||
|
||||
outb(0x3, early_serial_base + LCR); /* 8n1 */
|
||||
outb(0, early_serial_base + IER); /* no interrupt */
|
||||
outb(0, early_serial_base + FCR); /* no fifo */
|
||||
outb(0x3, early_serial_base + MCR); /* DTR + RTS */
|
||||
|
||||
if (*s) {
|
||||
baud = simple_strtoul(s, &e, 0);
|
||||
if (baud == 0 || s == e)
|
||||
if (kstrtoul(s, 0, &baud) < 0 || baud == 0)
|
||||
baud = DEFAULT_BAUD;
|
||||
}
|
||||
|
||||
/* Convert from baud to divisor value */
|
||||
divisor = 115200 / baud;
|
||||
c = inb(early_serial_base + LCR);
|
||||
outb(c | DLAB, early_serial_base + LCR);
|
||||
outb(divisor & 0xff, early_serial_base + DLL);
|
||||
outb((divisor >> 8) & 0xff, early_serial_base + DLH);
|
||||
outb(c & ~DLAB, early_serial_base + LCR);
|
||||
|
||||
/* These will always be IO based ports */
|
||||
serial_in = io_serial_in;
|
||||
serial_out = io_serial_out;
|
||||
|
||||
/* Set up the HW */
|
||||
early_serial_hw_init(divisor);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/*
|
||||
* early_pci_serial_init()
|
||||
*
|
||||
* This function is invoked when the early_printk param starts with "pciserial"
|
||||
* The rest of the param should be ",B:D.F,baud" where B, D & F describe the
|
||||
* location of a PCI device that must be a UART device.
|
||||
*/
|
||||
static __init void early_pci_serial_init(char *s)
|
||||
{
|
||||
unsigned divisor;
|
||||
unsigned long baud = DEFAULT_BAUD;
|
||||
u8 bus, slot, func;
|
||||
uint32_t classcode, bar0;
|
||||
uint16_t cmdreg;
|
||||
char *e;
|
||||
|
||||
|
||||
/*
|
||||
* First, part the param to get the BDF values
|
||||
*/
|
||||
if (*s == ',')
|
||||
++s;
|
||||
|
||||
if (*s == 0)
|
||||
return;
|
||||
|
||||
bus = (u8)simple_strtoul(s, &e, 16);
|
||||
s = e;
|
||||
if (*s != ':')
|
||||
return;
|
||||
++s;
|
||||
slot = (u8)simple_strtoul(s, &e, 16);
|
||||
s = e;
|
||||
if (*s != '.')
|
||||
return;
|
||||
++s;
|
||||
func = (u8)simple_strtoul(s, &e, 16);
|
||||
s = e;
|
||||
|
||||
/* A baud might be following */
|
||||
if (*s == ',')
|
||||
s++;
|
||||
|
||||
/*
|
||||
* Second, find the device from the BDF
|
||||
*/
|
||||
cmdreg = read_pci_config(bus, slot, func, PCI_COMMAND);
|
||||
classcode = read_pci_config(bus, slot, func, PCI_CLASS_REVISION);
|
||||
bar0 = read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
|
||||
|
||||
/*
|
||||
* Verify it is a UART type device
|
||||
*/
|
||||
if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) &&
|
||||
(classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) ||
|
||||
(((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */
|
||||
return;
|
||||
|
||||
/*
|
||||
* Determine if it is IO or memory mapped
|
||||
*/
|
||||
if (bar0 & 0x01) {
|
||||
/* it is IO mapped */
|
||||
serial_in = io_serial_in;
|
||||
serial_out = io_serial_out;
|
||||
early_serial_base = bar0&0xfffffffc;
|
||||
write_pci_config(bus, slot, func, PCI_COMMAND,
|
||||
cmdreg|PCI_COMMAND_IO);
|
||||
} else {
|
||||
/* It is memory mapped - assume 32-bit alignment */
|
||||
serial_in = mem32_serial_in;
|
||||
serial_out = mem32_serial_out;
|
||||
/* WARNING! assuming the address is always in the first 4G */
|
||||
early_serial_base =
|
||||
(unsigned long)early_ioremap(bar0 & 0xfffffff0, 0x10);
|
||||
write_pci_config(bus, slot, func, PCI_COMMAND,
|
||||
cmdreg|PCI_COMMAND_MEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lastly, initalize the hardware
|
||||
*/
|
||||
if (*s) {
|
||||
if (strcmp(s, "nocfg") == 0)
|
||||
/* Sometimes, we want to leave the UART alone
|
||||
* and assume the BIOS has set it up correctly.
|
||||
* "nocfg" tells us this is the case, and we
|
||||
* should do no more setup.
|
||||
*/
|
||||
return;
|
||||
if (kstrtoul(s, 0, &baud) < 0 || baud == 0)
|
||||
baud = DEFAULT_BAUD;
|
||||
}
|
||||
|
||||
/* Convert from baud to divisor value */
|
||||
divisor = 115200 / baud;
|
||||
|
||||
/* Set up the HW */
|
||||
early_serial_hw_init(divisor);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct console early_serial_console = {
|
||||
.name = "earlyser",
|
||||
.write = early_serial_write,
|
||||
@@ -210,6 +353,13 @@ static int __init setup_early_printk(char *buf)
|
||||
early_serial_init(buf + 4);
|
||||
early_console_register(&early_serial_console, keep);
|
||||
}
|
||||
#ifdef CONFIG_PCI
|
||||
if (!strncmp(buf, "pciserial", 9)) {
|
||||
early_pci_serial_init(buf + 9);
|
||||
early_console_register(&early_serial_console, keep);
|
||||
buf += 9; /* Keep from match the above "serial" */
|
||||
}
|
||||
#endif
|
||||
if (!strncmp(buf, "vga", 3) &&
|
||||
boot_params.screen_info.orig_video_isVGA == 1) {
|
||||
max_xpos = boot_params.screen_info.orig_video_cols;
|
||||
@@ -226,11 +376,6 @@ static int __init setup_early_printk(char *buf)
|
||||
early_console_register(&xenboot_console, keep);
|
||||
#endif
|
||||
#ifdef CONFIG_EARLY_PRINTK_INTEL_MID
|
||||
if (!strncmp(buf, "mrst", 4)) {
|
||||
mrst_early_console_init();
|
||||
early_console_register(&early_mrst_console, keep);
|
||||
}
|
||||
|
||||
if (!strncmp(buf, "hsu", 3)) {
|
||||
hsu_early_console_init(buf + 3);
|
||||
early_console_register(&early_hsu_console, keep);
|
||||
|
||||
@@ -16,8 +16,6 @@ obj-$(subst m,y,$(CONFIG_INPUT_MPU3050)) += platform_mpu3050.o
|
||||
obj-$(subst m,y,$(CONFIG_INPUT_BMA150)) += platform_bma023.o
|
||||
obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o
|
||||
obj-$(subst m,y,$(CONFIG_DRM_MEDFIELD)) += platform_tc35876x.o
|
||||
# SPI Devices
|
||||
obj-$(subst m,y,$(CONFIG_SERIAL_MRST_MAX3110)) += platform_max3111.o
|
||||
# MISC Devices
|
||||
obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o
|
||||
obj-$(subst m,y,$(CONFIG_INTEL_MID_WATCHDOG)) += platform_wdt.o
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* platform_max3111.c: max3111 platform data initilization file
|
||||
*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
|
||||
*
|
||||
* 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; version 2
|
||||
* of the License.
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
static void __init *max3111_platform_data(void *info)
|
||||
{
|
||||
struct spi_board_info *spi_info = info;
|
||||
int intr = get_gpio_by_name("max3111_int");
|
||||
|
||||
spi_info->mode = SPI_MODE_0;
|
||||
if (intr == -1)
|
||||
return NULL;
|
||||
spi_info->irq = intr + INTEL_MID_IRQ_OFFSET;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct devs_id max3111_dev_id __initconst = {
|
||||
.name = "spi_max3111",
|
||||
.type = SFI_DEV_TYPE_SPI,
|
||||
.get_platform_data = &max3111_platform_data,
|
||||
};
|
||||
|
||||
sfi_device(max3111_dev_id);
|
||||
@@ -10,15 +10,13 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file implements two early consoles named mrst and hsu.
|
||||
* mrst is based on Maxim3110 spi-uart device, it exists in both
|
||||
* Moorestown and Medfield platforms, while hsu is based on a High
|
||||
* Speed UART device which only exists in the Medfield platform
|
||||
* This file implements early console named hsu.
|
||||
* hsu is based on a High Speed UART device which only exists in the Medfield
|
||||
* platform
|
||||
*/
|
||||
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/serial_mfd.h>
|
||||
#include <linux/kmsg_dump.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -28,216 +26,6 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/intel-mid.h>
|
||||
|
||||
#define MRST_SPI_TIMEOUT 0x200000
|
||||
#define MRST_REGBASE_SPI0 0xff128000
|
||||
#define MRST_REGBASE_SPI1 0xff128400
|
||||
#define MRST_CLK_SPI0_REG 0xff11d86c
|
||||
|
||||
/* Bit fields in CTRLR0 */
|
||||
#define SPI_DFS_OFFSET 0
|
||||
|
||||
#define SPI_FRF_OFFSET 4
|
||||
#define SPI_FRF_SPI 0x0
|
||||
#define SPI_FRF_SSP 0x1
|
||||
#define SPI_FRF_MICROWIRE 0x2
|
||||
#define SPI_FRF_RESV 0x3
|
||||
|
||||
#define SPI_MODE_OFFSET 6
|
||||
#define SPI_SCPH_OFFSET 6
|
||||
#define SPI_SCOL_OFFSET 7
|
||||
#define SPI_TMOD_OFFSET 8
|
||||
#define SPI_TMOD_TR 0x0 /* xmit & recv */
|
||||
#define SPI_TMOD_TO 0x1 /* xmit only */
|
||||
#define SPI_TMOD_RO 0x2 /* recv only */
|
||||
#define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */
|
||||
|
||||
#define SPI_SLVOE_OFFSET 10
|
||||
#define SPI_SRL_OFFSET 11
|
||||
#define SPI_CFS_OFFSET 12
|
||||
|
||||
/* Bit fields in SR, 7 bits */
|
||||
#define SR_MASK 0x7f /* cover 7 bits */
|
||||
#define SR_BUSY (1 << 0)
|
||||
#define SR_TF_NOT_FULL (1 << 1)
|
||||
#define SR_TF_EMPT (1 << 2)
|
||||
#define SR_RF_NOT_EMPT (1 << 3)
|
||||
#define SR_RF_FULL (1 << 4)
|
||||
#define SR_TX_ERR (1 << 5)
|
||||
#define SR_DCOL (1 << 6)
|
||||
|
||||
struct dw_spi_reg {
|
||||
u32 ctrl0;
|
||||
u32 ctrl1;
|
||||
u32 ssienr;
|
||||
u32 mwcr;
|
||||
u32 ser;
|
||||
u32 baudr;
|
||||
u32 txfltr;
|
||||
u32 rxfltr;
|
||||
u32 txflr;
|
||||
u32 rxflr;
|
||||
u32 sr;
|
||||
u32 imr;
|
||||
u32 isr;
|
||||
u32 risr;
|
||||
u32 txoicr;
|
||||
u32 rxoicr;
|
||||
u32 rxuicr;
|
||||
u32 msticr;
|
||||
u32 icr;
|
||||
u32 dmacr;
|
||||
u32 dmatdlr;
|
||||
u32 dmardlr;
|
||||
u32 idr;
|
||||
u32 version;
|
||||
|
||||
/* Currently operates as 32 bits, though only the low 16 bits matter */
|
||||
u32 dr;
|
||||
} __packed;
|
||||
|
||||
#define dw_readl(dw, name) __raw_readl(&(dw)->name)
|
||||
#define dw_writel(dw, name, val) __raw_writel((val), &(dw)->name)
|
||||
|
||||
/* Default use SPI0 register for mrst, we will detect Penwell and use SPI1 */
|
||||
static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0;
|
||||
|
||||
static u32 *pclk_spi0;
|
||||
/* Always contains an accessible address, start with 0 */
|
||||
static struct dw_spi_reg *pspi;
|
||||
|
||||
static struct kmsg_dumper dw_dumper;
|
||||
static int dumper_registered;
|
||||
|
||||
static void dw_kmsg_dump(struct kmsg_dumper *dumper,
|
||||
enum kmsg_dump_reason reason)
|
||||
{
|
||||
static char line[1024];
|
||||
size_t len;
|
||||
|
||||
/* When run to this, we'd better re-init the HW */
|
||||
mrst_early_console_init();
|
||||
|
||||
while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len))
|
||||
early_mrst_console.write(&early_mrst_console, line, len);
|
||||
}
|
||||
|
||||
/* Set the ratio rate to 115200, 8n1, IRQ disabled */
|
||||
static void max3110_write_config(void)
|
||||
{
|
||||
u16 config;
|
||||
|
||||
config = 0xc001;
|
||||
dw_writel(pspi, dr, config);
|
||||
}
|
||||
|
||||
/* Translate char to a eligible word and send to max3110 */
|
||||
static void max3110_write_data(char c)
|
||||
{
|
||||
u16 data;
|
||||
|
||||
data = 0x8000 | c;
|
||||
dw_writel(pspi, dr, data);
|
||||
}
|
||||
|
||||
void mrst_early_console_init(void)
|
||||
{
|
||||
u32 ctrlr0 = 0;
|
||||
u32 spi0_cdiv;
|
||||
u32 freq; /* Freqency info only need be searched once */
|
||||
|
||||
/* Base clk is 100 MHz, the actual clk = 100M / (clk_divider + 1) */
|
||||
pclk_spi0 = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
|
||||
MRST_CLK_SPI0_REG);
|
||||
spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9;
|
||||
freq = 100000000 / (spi0_cdiv + 1);
|
||||
|
||||
if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL)
|
||||
mrst_spi_paddr = MRST_REGBASE_SPI1;
|
||||
|
||||
pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
|
||||
mrst_spi_paddr);
|
||||
|
||||
/* Disable SPI controller */
|
||||
dw_writel(pspi, ssienr, 0);
|
||||
|
||||
/* Set control param, 8 bits, transmit only mode */
|
||||
ctrlr0 = dw_readl(pspi, ctrl0);
|
||||
|
||||
ctrlr0 &= 0xfcc0;
|
||||
ctrlr0 |= 0xf | (SPI_FRF_SPI << SPI_FRF_OFFSET)
|
||||
| (SPI_TMOD_TO << SPI_TMOD_OFFSET);
|
||||
dw_writel(pspi, ctrl0, ctrlr0);
|
||||
|
||||
/*
|
||||
* Change the spi0 clk to comply with 115200 bps, use 100000 to
|
||||
* calculate the clk dividor to make the clock a little slower
|
||||
* than real baud rate.
|
||||
*/
|
||||
dw_writel(pspi, baudr, freq/100000);
|
||||
|
||||
/* Disable all INT for early phase */
|
||||
dw_writel(pspi, imr, 0x0);
|
||||
|
||||
/* Set the cs to spi-uart */
|
||||
dw_writel(pspi, ser, 0x2);
|
||||
|
||||
/* Enable the HW, the last step for HW init */
|
||||
dw_writel(pspi, ssienr, 0x1);
|
||||
|
||||
/* Set the default configuration */
|
||||
max3110_write_config();
|
||||
|
||||
/* Register the kmsg dumper */
|
||||
if (!dumper_registered) {
|
||||
dw_dumper.dump = dw_kmsg_dump;
|
||||
kmsg_dump_register(&dw_dumper);
|
||||
dumper_registered = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Slave select should be called in the read/write function */
|
||||
static void early_mrst_spi_putc(char c)
|
||||
{
|
||||
unsigned int timeout;
|
||||
u32 sr;
|
||||
|
||||
timeout = MRST_SPI_TIMEOUT;
|
||||
/* Early putc needs to make sure the TX FIFO is not full */
|
||||
while (--timeout) {
|
||||
sr = dw_readl(pspi, sr);
|
||||
if (!(sr & SR_TF_NOT_FULL))
|
||||
cpu_relax();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!timeout)
|
||||
pr_warn("MRST earlycon: timed out\n");
|
||||
else
|
||||
max3110_write_data(c);
|
||||
}
|
||||
|
||||
/* Early SPI only uses polling mode */
|
||||
static void early_mrst_spi_write(struct console *con, const char *str,
|
||||
unsigned n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n && *str; i++) {
|
||||
if (*str == '\n')
|
||||
early_mrst_spi_putc('\r');
|
||||
early_mrst_spi_putc(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
struct console early_mrst_console = {
|
||||
.name = "earlymrst",
|
||||
.write = early_mrst_spi_write,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.index = -1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Following is the early console based on Medfield HSU (High
|
||||
* Speed UART) device.
|
||||
@@ -259,7 +47,7 @@ void hsu_early_console_init(const char *s)
|
||||
port = clamp_val(port, 0, 2);
|
||||
|
||||
paddr = HSU_PORT_BASE + port * 0x80;
|
||||
phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr);
|
||||
phsu = (void __iomem *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr);
|
||||
|
||||
/* Disable FIFO */
|
||||
writeb(0x0, phsu + UART_FCR);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user