Commit 2e8c54e8 authored by Russell King's avatar Russell King

[ARM PATCH] 1091/3: support for trizeps board (SA1110-based)

Patch from Guennadi Liakhovetski

The enclosed patch includes support for the trizeps board, based on the
StrongARM-1110 CPU, machine number 74. The patch is built against
2.5.44-rmk1. Only the core files - from arch/arm and
include/asm-arm directories.
parent 0f19a614
This diff is collapsed.
......@@ -314,6 +314,18 @@ config SA1100_STORK
Say Y here if you intend to run this kernel on the Stork
handheld computer.
#config SA1100_TRIZEPS
# bool "Trizeps"
# depends on ARCH_SA1100
# help
# :: write me ::
#config TRIZEPS_MFTB2
# bool "MFTB2"
# depends on SA1100_TRIZEPS
# help
# :: write me ::
config SA1100_USB
tristate "SA1100 USB function support"
depends on ARCH_SA1100
......
......@@ -98,6 +98,9 @@ led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
obj-$(CONFIG_SA1100_STORK) += stork.o
export-objs += stork.o
obj-$(CONFIG_SA1100_TRIZEPS) += trizeps.o
export-objs += trizeps.o
obj-$(CONFIG_SA1100_XP860) += xp860.o
obj-$(CONFIG_SA1100_YOPY) += yopy.o
......
/*
* linux/arch/arm/mach-sa1100/trizeps.c
*
* Authors:
* Andreas Hofer <ho@dsa-ac.de>,
* Peter Lueg <pl@dsa-ac.de>,
* Guennadi Liakhovetski <gl@dsa-ac.de>
*
* This file contains all Trizeps-specific tweaks.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/arch/trizeps.h>
#include <asm/setup.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/serial_sa1100.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <asm/arch/serial.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/irqs.h>
#include "generic.h"
#undef DEBUG_TRIZEPS
#ifdef DEBUG_TRIZEPS
#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
#else
#define DPRINTK( x... )
#endif
static struct tri_uart_cts_data_t tri_uart_cts_data[] = {
{ TRIZEPS_GPIO_UART1_CTS, 0, NULL, NULL,"int. UART1 cts" },
{ TRIZEPS_GPIO_UART2_CTS, 0, NULL, NULL,"int. UART2 cts" },
{ TRIZEPS_GPIO_UART3_CTS, 0, NULL, NULL,"int. UART3 cts" }
};
static void trizeps_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct tri_uart_cts_data_t * uart_data = (struct tri_uart_cts_data_t *)dev_id;
int cts = (!(GPLR & uart_data->cts_gpio));
/* NOTE: I suppose that we will not get any interrupts
if the GPIO is not changed, so maybe
the cts_prev_state can be removed ... */
if (cts != uart_data->cts_prev_state) {
uart_data->cts_prev_state = cts;
uart_handle_cts_change(uart_data->port, cts);
DPRINTK("(IRQ %d) changed (cts=%d) stop=%d\n",
irq, cts, uart_data->info->tty->hw_stopped);
}
}
static int
trizeps_register_cts_intr(int gpio,
int irq,
struct tri_uart_cts_data_t *uart_data)
{
int ret = 0;
if(irq != NO_IRQ)
{
set_irq_type(irq, IRQT_BOTHEDGE);
ret = request_irq(irq, trizeps_cts_intr,
SA_INTERRUPT, uart_data->name, uart_data);
if (ret)
printk(KERN_ERR "uart_open: failed to register CTS irq (%d)\n", ret);
}
return ret;
}
static void trizeps_set_mctrl(struct uart_port *port, u_int mctrl)
{
if (port->mapbase == _Ser1UTCR0)
{
/**** ttySA1 ****/
if (mctrl & TIOCM_RTS)
GPCR |= TRIZEPS_GPIO_UART1_RTS;
else
GPSR |= TRIZEPS_GPIO_UART1_RTS;
DPRINTK("2 ttySA%d Set RTS %s\n",port->line,
mctrl & TIOCM_RTS ? "low" : "high");
}
else if (port->mapbase == _Ser3UTCR0)
{
/**** ttySA0 ****/
}
else
{
/**** ttySA2 ****/
}
}
static u_int trizeps_get_mctrl(struct uart_port *port)
{
int result = TIOCM_CD | TIOCM_DSR;
if (port->mapbase == _Ser1UTCR0)
{
if (!(GPLR & TRIZEPS_GPIO_UART1_CTS))
result |= TIOCM_CTS;
}
else if (port->mapbase == _Ser2UTCR0)
{
result |= TIOCM_CTS;
}
else if (port->mapbase == _Ser3UTCR0)
{
result |= TIOCM_CTS;
}
else
{
result = TIOCM_CTS;
}
DPRINTK(" ttySA%d %s%s%s\n",port->line,
result & TIOCM_CD ? "CD " : "",
result & TIOCM_CTS ? "CTS " : "",
result & TIOCM_DSR ? "DSR " : "");
return result;
}
static struct sa1100_port_fns trizeps_port_fns __initdata = {
.set_mctrl = trizeps_set_mctrl,
.get_mctrl = trizeps_get_mctrl,
};
static void trizeps_power_off(void)
{
printk("trizeps power off\n");
mdelay(100);
cli();
/* disable internal oscillator, float CS lines */
PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
/* enable wake-up on GPIO0 (Assabet...) */
PWER = GFER = GRER = 1;
/*
* set scratchpad to zero, just in case it is used as a
* restart address by the bootloader.
*/
PSPR = 0;
/*
* Power off
* -> disconnect AKku
*/
TRIZEPS_BCR_set(TRIZEPS_BCR0, TRIZEPS_MFT_OFF);
/*
* if power supply no Akku
* -> enter sleep mode
*/
PMCR = PMCR_SF;
}
static int __init trizeps_init(void)
{
if (!machine_is_trizeps())
return -EINVAL;
DPRINTK(" \n");
pm_power_off = trizeps_power_off;
// Init UART2 for IrDA
// PPDR |= PPC_TXD2; // Set TXD2 as output
Ser2UTCR4 = UTCR4_HSE; // enable HSE
Ser2HSCR0 = 0;
Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR | HSSR0_RAB | HSSR0_FRE;
/* Init MECR */
MECR = 0x00060006;
/* Set up external serial IRQs */
GAFR &= ~(GPIO_GPIO16 | GPIO_GPIO17); // no alternate function
GPDR &= ~(GPIO_GPIO16 | GPIO_GPIO17); // Set to Input
set_irq_type(IRQ_GPIO16, IRQT_RISING);
set_irq_type(IRQ_GPIO17, IRQT_RISING);
return 0;
}
__initcall(trizeps_init);
static struct map_desc trizeps_io_desc[] __initdata = {
/* virtual physical length type */
{ 0xF0000000l, 0x30000000l, 0x00800000l, MT_DEVICE },
{ 0xF2000000l, 0x38000000l, 0x00800000l, MT_DEVICE },
};
void __init trizeps_map_io(void)
{
sa1100_map_io();
iotable_init(trizeps_io_desc, ARRAY_SIZE(trizeps_io_desc));
sa1100_register_uart_fns(&trizeps_port_fns);
sa1100_register_uart(0, 3);
sa1100_register_uart(1, 1);
sa1100_register_uart(2, 2);
}
MACHINE_START(TRIZEPS, "TRIZEPS")
MAINTAINER("DSA")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(trizeps_map_io)
INITIRQ(sa1100_init_irq)
MACHINE_END
#ifndef _ARCH_ARM_MFTB2_h_
#define _ARCH_ARM_MFTB2_h_
// Defines for arch/arm/mm/mm-sa1100.h
#define TRIZEPS_PHYS_VIRT_MAP_SIZE 0x00800000l
// physical address (only for mm-sa1100.h)
#define TRIZEPS_PHYS_IO_BASE 0x30000000l
#define TRIZEPS_PHYS_MEM_BASE 0x38000000l
// virtual
#define TRIZEPS_IO_BASE 0xF0000000l
#define TRIZEPS_MEM_BASE 0xF2000000l
// Offsets for phys and virtual
#define TRIZEPS_OFFSET_REG0 0x00300000l
#define TRIZEPS_OFFSET_REG1 0x00380000l
#define TRIZEPS_OFFSET_IDE_CS0 0x00000000l
#define TRIZEPS_OFFSET_IDE_CS1 0x00080000l
#define TRIZEPS_OFFSET_UART5 0x00100000l
#define TRIZEPS_OFFSET_UART6 0x00180000l
#define TRIZEPS_PHYS_REG0 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_REG0)
#define TRIZEPS_PHYS_REG1 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_REG1)
#define TRIZEPS_PHYS_IDE_CS0 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_IDE_CS0)
#define TRIZEPS_PHYS_IDE_CS1 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_IDE_CS1)
#define TRIZEPS_PHYS_UART5 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_UART5)
#define TRIZEPS_PHYS_UART6 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_UART6)
// Use follow defines in devices
// virtual address
#define TRIZEPS_REG0 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_REG0)
#define TRIZEPS_REG1 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_REG1)
#define TRIZEPS_IDE_CS0 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_IDE_CS0)
#define TRIZEPS_IDE_CS1 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_IDE_CS1)
#define TRIZEPS_UART5 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_UART5)
#define TRIZEPS_UART6 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_UART6)
#define TRIZEPS_BAUD_BASE 1500000
//#if 0 //temporarily disabled
#ifndef __ASSEMBLY__
struct tri_uart_cts_data_t {
int cts_gpio;
int cts_prev_state;
struct uart_info *info;
struct uart_port *port;
const char *name;
};
#endif /* __ASSEMBLY__ */
/* Defines for MFTB2 serial_sa1100.c hardware handshaking lines */
#define SERIAL_FULL
#define NOT_CONNECTED 0
#ifdef SERIAL_FULL
#define TRIZEPS_GPIO_UART1_RTS GPIO_GPIO14
#define TRIZEPS_GPIO_UART1_DTR NOT_CONNECTED //GPIO_GPIO9
#define TRIZEPS_GPIO_UART1_CTS GPIO_GPIO15
#define TRIZEPS_GPIO_UART1_DCD NOT_CONNECTED //GPIO_GPIO2
#define TRIZEPS_GPIO_UART1_DSR NOT_CONNECTED //GPIO_GPIO3
#define TRIZEPS_GPIO_UART3_RTS NOT_CONNECTED //GPIO_GPIO7
#define TRIZEPS_GPIO_UART3_DTR NOT_CONNECTED //GPIO_GPIO8
#define TRIZEPS_GPIO_UART3_CTS NOT_CONNECTED //GPIO_GPIO4
#define TRIZEPS_GPIO_UART3_DCD NOT_CONNECTED //GPIO_GPIO5
#define TRIZEPS_GPIO_UART3_DSR NOT_CONNECTED //GPIO_GPIO6
#define TRIZEPS_GPIO_UART2_RTS NOT_CONNECTED //GPIO_GPIO7
#define TRIZEPS_GPIO_UART2_DTR NOT_CONNECTED //GPIO_GPIO8
#define TRIZEPS_GPIO_UART2_CTS NOT_CONNECTED //GPIO_GPIO4
#define TRIZEPS_GPIO_UART2_DCD NOT_CONNECTED //GPIO_GPIO5
#define TRIZEPS_GPIO_UART2_DSR NOT_CONNECTED //GPIO_GPIO6
#define TRIZEPS_IRQ_UART1_CTS IRQ_GPIO15
#define TRIZEPS_IRQ_UART1_DCD NO_IRQ //IRQ_GPIO2
#define TRIZEPS_IRQ_UART1_DSR NO_IRQ //IRQ_GPIO3
#define TRIZEPS_IRQ_UART3_CTS NO_IRQ //IRQ_GPIO4
#define TRIZEPS_IRQ_UART3_DCD NO_IRQ //IRQ_GPIO5
#define TRIZEPS_IRQ_UART3_DSR NO_IRQ //IRQ_GPIO6
#define TRIZEPS_IRQ_UART2_CTS NO_IRQ //IRQ_GPIO4
#define TRIZEPS_IRQ_UART2_DCD NO_IRQ //IRQ_GPIO5
#define TRIZEPS_IRQ_UART2_DSR NO_IRQ //IRQ_GPIO6
#endif /* SERIAL_FULL */
//#endif //0
/*
* This section contains the defines for the MFTB2 implementation
* of drivers/ide/hd.c. HD_IOBASE_0 and HD_IOBASE_1 have to be
* adjusted if hardware changes.
*/
#define TRIZEPS_IRQ_IDE 10 /* MFTB2 specific */
/*--- ROOT ---*/
#define TRIZEPS_GPIO_ROOT_NFS 0
#define TRIZEPS_GPIO_ROOT_HD 21
/*--- PCMCIA ---*/
#define TRIZEPS_GPIO_PCMCIA_IRQ0 1
#define TRIZEPS_GPIO_PCMCIA_CD0 24
#define TRIZEPS_IRQ_PCMCIA_IRQ0 TRIZEPS_GPIO_PCMCIA_IRQ0
#define TRIZEPS_IRQ_PCMCIA_CD0 TRIZEPS_GPIO_PCMCIA_CD0 + 32 - 11
// REGISTER 0 -> 0x0XXXX (16bit access)
// read only
#define TRIZEPS_A_STAT 0x8000l
#define TRIZEPS_F_STAT 0x4000l
#define TRIZEPS_BATT_FAULT_EN 0x2000l
#define TRIZEPS_nDQ 0x1000l
#define TRIZEPS_MFT_OFF 0x0800l
#define TRIZEPS_D_APWOFF 0x0400l
#define TRIZEPS_F_CTRL 0x0200l
#define TRIZEPS_F_STOP 0x0100l
// read / write
#define TRIZEPS_KP_IR_EN 0x0080l
#define TRIZEPS_FIR 0x0040l
#define TRIZEPS_BAR_ON 0x0020l
#define TRIZEPS_VCI_ON 0x0010l
#define TRIZEPS_LED4 0x0008l
#define TRIZEPS_LED3 0x0004l
#define TRIZEPS_LED2 0x0002l
#define TRIZEPS_LED1 0x0001l
// REGISTER 1 -> 0x1XXXX (16bit access)
// read only
#define TRIZEPS_nVCI2 0x8000l
#define TRIZEPS_nAB_LOW 0x4000l
#define TRIZEPS_nMB_DEAD 0x2000l
#define TRIZEPS_nMB_LOW 0x1000l
#define TRIZEPS_nPCM_VS2 0x0800l
#define TRIZEPS_nPCM_VS1 0x0400l
#define TRIZEPS_PCM_BVD2 0x0200l
#define TRIZEPS_PCM_BVD1 0x0100l
// read / write
#define TRIZEPS_nROOT_NFS 0x0080l
#define TRIZEPS_nROOT_HD 0x0040l
#define TRIZEPS_nPCM_ENA_REG 0x0020l
#define TRIZEPS_nPCM_RESET_DISABLE 0x0010l
#define TRIZEPS_PCM_EN0_REG 0x0008l
#define TRIZEPS_PCM_EN1_REG 0x0004l
#define TRIZEPS_PCM_V3_EN_REG 0x0002l
#define TRIZEPS_PCM_V5_EN_REG 0x0001l
/* Access to Board Control Register */
#define TRIZEPS_BCR0 (*(volatile unsigned short *)(TRIZEPS_REG0))
#define TRIZEPS_BCR1 (*(volatile unsigned short *)(TRIZEPS_REG1))
#define TRIZEPS_BCR_set( reg, x ) do { \
unsigned long flags; \
local_irq_save(flags); \
(reg) |= (x); \
local_irq_restore(flags); \
} while (0)
#define TRIZEPS_BCR_clear( reg, x ) do { \
unsigned long flags; \
local_irq_save(flags); \
(reg) &= ~(x); \
local_irq_restore(flags); \
} while (0)
#define TRIZEPS_OFFSET_KP_REG 0x00200000l
#define TRIZEPS_OFFSET_VCI2 0x00280000l
#define TRIZEPS_OFFSET_VCI4 0x00400000l
#define TRIZEPS_OFFSET_VCI2_1_DPR (TRIZEPS_OFFSET_VCI2 + 0x00010000l)
#define TRIZEPS_OFFSET_VCI2_2_DPR (TRIZEPS_OFFSET_VCI2 + 0x00018000l)
#define TRIZEPS_OFFSET_VCI2_1_SEMA (TRIZEPS_OFFSET_VCI2 + 0x00020000l)
#define TRIZEPS_OFFSET_VCI2_2_SEMA (TRIZEPS_OFFSET_VCI2 + 0x00028000l)
#define TRIZEPS_OFFSET_VCI4_1_DPR (TRIZEPS_OFFSET_VCI4 + 0x00000000l)
#define TRIZEPS_OFFSET_VCI4_2_DPR (TRIZEPS_OFFSET_VCI4 + 0x00008000l)
#define TRIZEPS_OFFSET_VCI4_1_SEMA (TRIZEPS_OFFSET_VCI4 + 0x00000380l)
#define TRIZEPS_OFFSET_VCI4_2_SEMA (TRIZEPS_OFFSET_VCI4 + 0x00000388l)
#define TRIZEPS_OFFSET_VCI4_1_CNTR (TRIZEPS_OFFSET_VCI4 + 0x00000390l)
#define TRIZEPS_OFFSET_VCI4_2_CNTR (TRIZEPS_OFFSET_VCI4 + 0x00000392l)
#define TRIZEPS_PHYS_KP_REG (PHYS_TRIZEPS_IO_BASE + TRIZEPS_OFFSET_KP_REG)
// VCI address
#define TRIZEPS_PHYS_VCI2_1_DPR (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_DPR)
#define TRIZEPS_PHYS_VCI2_2_DPR (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_DPR)
#define TRIZEPS_PHYS_VCI2_1_SEMA (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_SEMA)
#define TRIZEPS_PHYS_VCI2_2_SEMA (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_SEMA)
// VCI4 address
#define TRIZEPS_PHYS_VCI4_1_DPR (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI4_1_DPR)
#define TRIZEPS_PHYS_VCI4_2_DPR (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI4_2_DPR)
#define TRIZEPS_PHYS_VCI4_1_SEMA (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_VCI4_1_SEMA)
#define TRIZEPS_PHYS_VCI4_2_SEMA (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_VCI4_2_SEMA)
#define TRIZEPS_PHYS_VCI4_1_CNTR (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_VCI4_1_CNTR)
#define TRIZEPS_PHYS_VCI4_2_CNTR (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_VCI4_2_CNTR)
#define TRIZEPS_KP_REG (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_KP_REG)
// VCI address
#define TRIZEPS_VCI2_1_DPR (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_DPR)
#define TRIZEPS_VCI2_2_DPR (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_DPR)
#define TRIZEPS_VCI2_1_SEMA (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_SEMA)
#define TRIZEPS_VCI2_2_SEMA (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_SEMA)
// VCI4 address
#define TRIZEPS_VCI4_1_DPR (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI4_1_DPR)
#define TRIZEPS_VCI4_2_DPR (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI4_2_DPR)
#define TRIZEPS_VCI4_1_SEMA (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_VCI4_1_SEMA)
#define TRIZEPS_VCI4_2_SEMA (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_VCI4_2_SEMA)
#define TRIZEPS_VCI4_1_CNTR (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_VCI4_1_CNTR)
#define TRIZEPS_VCI4_2_CNTR (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_VCI4_2_CNTR)
#endif
/*
* linux/include/asm-arm/arch-sa1100/trizeps.h
*
* This file contains the hardware specific definitions for Trizeps
*
* Authors:
* Andreas Hofer <ho@dsa-ac.de>,
* Peter Lueg <pl@dsa-ac.de>,
* Guennadi Liakhovetski <gl@dsa-ac.de>
*
*/
#ifndef _ASM_ARCH_TRIZEPS_H_
#define _ASM_ARCH_TRIZEPS_H_
#ifdef CONFIG_TRIZEPS_MFTB2
#include "mftb2.h"
#endif
#endif // _INCLUDE_TRIZEPS_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment