Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
11c79740
Commit
11c79740
authored
May 23, 2009
by
Krzysztof Hałasa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IXP4xx: support for Goramo MultiLink router platform.
Signed-off-by:
Krzysztof Hałasa
<
khc@pm.waw.pl
>
parent
0771c693
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
514 additions
and
0 deletions
+514
-0
arch/arm/mach-ixp4xx/Kconfig
arch/arm/mach-ixp4xx/Kconfig
+6
-0
arch/arm/mach-ixp4xx/Makefile
arch/arm/mach-ixp4xx/Makefile
+1
-0
arch/arm/mach-ixp4xx/goramo_mlr.c
arch/arm/mach-ixp4xx/goramo_mlr.c
+507
-0
No files found.
arch/arm/mach-ixp4xx/Kconfig
View file @
11c79740
...
...
@@ -78,6 +78,12 @@ config MACH_IXDP465
IXDP465 Development Platform (Also known as BMP).
For more information on this platform, see <file:Documentation/arm/IXP4xx>.
config MACH_GORAMO_MLR
bool "GORAMO Multi Link Router"
help
Say 'Y' here if you want your kernel to support GORAMO
MultiLink router.
config MACH_KIXRP435
bool "KIXRP435"
help
...
...
arch/arm/mach-ixp4xx/Makefile
View file @
11c79740
...
...
@@ -30,6 +30,7 @@ obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o
obj-$(CONFIG_MACH_GATEWAY7001)
+=
gateway7001-setup.o
obj-$(CONFIG_MACH_WG302V2)
+=
wg302v2-setup.o
obj-$(CONFIG_MACH_FSG)
+=
fsg-setup.o
obj-$(CONFIG_MACH_GORAMO_MLR)
+=
goramo_mlr.o
obj-$(CONFIG_PCI)
+=
$
(
obj-pci-
$(CONFIG_PCI)
)
common-pci.o
obj-$(CONFIG_IXP4XX_QMGR)
+=
ixp4xx_qmgr.o
...
...
arch/arm/mach-ixp4xx/goramo_mlr.c
0 → 100644
View file @
11c79740
/*
* Goramo MultiLink router platform code
* Copyright (C) 2006-2009 Krzysztof Halasa <khc@pm.waw.pl>
*/
#include <linux/delay.h>
#include <linux/hdlc.h>
#include <linux/i2c-gpio.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/serial_8250.h>
#include <asm/mach-types.h>
#include <asm/system.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/pci.h>
#define xgpio_irq(n) (IRQ_IXP4XX_GPIO ## n)
#define gpio_irq(n) xgpio_irq(n)
#define SLOT_ETHA 0x0B
/* IDSEL = AD21 */
#define SLOT_ETHB 0x0C
/* IDSEL = AD20 */
#define SLOT_MPCI 0x0D
/* IDSEL = AD19 */
#define SLOT_NEC 0x0E
/* IDSEL = AD18 */
#define IRQ_ETHA IRQ_IXP4XX_GPIO4
#define IRQ_ETHB IRQ_IXP4XX_GPIO5
#define IRQ_NEC IRQ_IXP4XX_GPIO3
#define IRQ_MPCI IRQ_IXP4XX_GPIO12
/* GPIO lines */
#define GPIO_SCL 0
#define GPIO_SDA 1
#define GPIO_STR 2
#define GPIO_HSS0_DCD_N 6
#define GPIO_HSS1_DCD_N 7
#define GPIO_HSS0_CTS_N 10
#define GPIO_HSS1_CTS_N 11
#define GPIO_HSS1_RTS_N 13
#define GPIO_HSS0_RTS_N 14
/* Control outputs from 74HC4094 */
#define CONTROL_HSS0_CLK_INT 0
#define CONTROL_HSS1_CLK_INT 1
#define CONTROL_HSS0_DTR_N 2
#define CONTROL_HSS1_DTR_N 3
#define CONTROL_EXT 4
#define CONTROL_AUTO_RESET 5
#define CONTROL_PCI_RESET_N 6
#define CONTROL_EEPROM_WC_N 7
/* offsets from start of flash ROM = 0x50000000 */
#define CFG_ETH0_ADDRESS 0x40
/* 6 bytes */
#define CFG_ETH1_ADDRESS 0x46
/* 6 bytes */
#define CFG_REV 0x4C
/* u32 */
#define CFG_SDRAM_SIZE 0x50
/* u32 */
#define CFG_SDRAM_CONF 0x54
/* u32 */
#define CFG_SDRAM_MODE 0x58
/* u32 */
#define CFG_SDRAM_REFRESH 0x5C
/* u32 */
#define CFG_HW_BITS 0x60
/* u32 */
#define CFG_HW_USB_PORTS 0x00000007
/* 0 = no NEC chip, 1-5 = ports # */
#define CFG_HW_HAS_PCI_SLOT 0x00000008
#define CFG_HW_HAS_ETH0 0x00000010
#define CFG_HW_HAS_ETH1 0x00000020
#define CFG_HW_HAS_HSS0 0x00000040
#define CFG_HW_HAS_HSS1 0x00000080
#define CFG_HW_HAS_UART0 0x00000100
#define CFG_HW_HAS_UART1 0x00000200
#define CFG_HW_HAS_EEPROM 0x00000400
#define FLASH_CMD_READ_ARRAY 0xFF
#define FLASH_CMD_READ_ID 0x90
#define FLASH_SER_OFF 0x102
/* 0x81 in 16-bit mode */
static
u32
hw_bits
=
0xFFFFFFFD
;
/* assume all hardware present */
;
static
u8
control_value
;
static
void
set_scl
(
u8
value
)
{
gpio_line_set
(
GPIO_SCL
,
!!
value
);
udelay
(
3
);
}
static
void
set_sda
(
u8
value
)
{
gpio_line_set
(
GPIO_SDA
,
!!
value
);
udelay
(
3
);
}
static
void
set_str
(
u8
value
)
{
gpio_line_set
(
GPIO_STR
,
!!
value
);
udelay
(
3
);
}
static
inline
void
set_control
(
int
line
,
int
value
)
{
if
(
value
)
control_value
|=
(
1
<<
line
);
else
control_value
&=
~
(
1
<<
line
);
}
static
void
output_control
(
void
)
{
int
i
;
gpio_line_config
(
GPIO_SCL
,
IXP4XX_GPIO_OUT
);
gpio_line_config
(
GPIO_SDA
,
IXP4XX_GPIO_OUT
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
set_scl
(
0
);
set_sda
(
control_value
&
(
0x80
>>
i
));
/* MSB first */
set_scl
(
1
);
/* active edge */
}
set_str
(
1
);
set_str
(
0
);
set_scl
(
0
);
set_sda
(
1
);
/* Be ready for START */
set_scl
(
1
);
}
static
void
(
*
set_carrier_cb_tab
[
2
])(
void
*
pdev
,
int
carrier
);
static
int
hss_set_clock
(
int
port
,
unsigned
int
clock_type
)
{
int
ctrl_int
=
port
?
CONTROL_HSS1_CLK_INT
:
CONTROL_HSS0_CLK_INT
;
switch
(
clock_type
)
{
case
CLOCK_DEFAULT
:
case
CLOCK_EXT
:
set_control
(
ctrl_int
,
0
);
output_control
();
return
CLOCK_EXT
;
case
CLOCK_INT
:
set_control
(
ctrl_int
,
1
);
output_control
();
return
CLOCK_INT
;
default:
return
-
EINVAL
;
}
}
static
irqreturn_t
hss_dcd_irq
(
int
irq
,
void
*
pdev
)
{
int
i
,
port
=
(
irq
==
gpio_irq
(
GPIO_HSS1_DCD_N
));
gpio_line_get
(
port
?
GPIO_HSS1_DCD_N
:
GPIO_HSS0_DCD_N
,
&
i
);
set_carrier_cb_tab
[
port
](
pdev
,
!
i
);
return
IRQ_HANDLED
;
}
static
int
hss_open
(
int
port
,
void
*
pdev
,
void
(
*
set_carrier_cb
)(
void
*
pdev
,
int
carrier
))
{
int
i
,
irq
;
if
(
!
port
)
irq
=
gpio_irq
(
GPIO_HSS0_DCD_N
);
else
irq
=
gpio_irq
(
GPIO_HSS1_DCD_N
);
gpio_line_get
(
port
?
GPIO_HSS1_DCD_N
:
GPIO_HSS0_DCD_N
,
&
i
);
set_carrier_cb
(
pdev
,
!
i
);
set_carrier_cb_tab
[
!!
port
]
=
set_carrier_cb
;
if
((
i
=
request_irq
(
irq
,
hss_dcd_irq
,
0
,
"IXP4xx HSS"
,
pdev
))
!=
0
)
{
printk
(
KERN_ERR
"ixp4xx_hss: failed to request IRQ%i (%i)
\n
"
,
irq
,
i
);
return
i
;
}
set_control
(
port
?
CONTROL_HSS1_DTR_N
:
CONTROL_HSS0_DTR_N
,
0
);
output_control
();
gpio_line_set
(
port
?
GPIO_HSS1_RTS_N
:
GPIO_HSS0_RTS_N
,
0
);
return
0
;
}
static
void
hss_close
(
int
port
,
void
*
pdev
)
{
free_irq
(
port
?
gpio_irq
(
GPIO_HSS1_DCD_N
)
:
gpio_irq
(
GPIO_HSS0_DCD_N
),
pdev
);
set_carrier_cb_tab
[
!!
port
]
=
NULL
;
/* catch bugs */
set_control
(
port
?
CONTROL_HSS1_DTR_N
:
CONTROL_HSS0_DTR_N
,
1
);
output_control
();
gpio_line_set
(
port
?
GPIO_HSS1_RTS_N
:
GPIO_HSS0_RTS_N
,
1
);
}
/* Flash memory */
static
struct
flash_platform_data
flash_data
=
{
.
map_name
=
"cfi_probe"
,
.
width
=
2
,
};
static
struct
resource
flash_resource
=
{
.
flags
=
IORESOURCE_MEM
,
};
static
struct
platform_device
device_flash
=
{
.
name
=
"IXP4XX-Flash"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
flash_data
},
.
num_resources
=
1
,
.
resource
=
&
flash_resource
,
};
/* I^2C interface */
static
struct
i2c_gpio_platform_data
i2c_data
=
{
.
sda_pin
=
GPIO_SDA
,
.
scl_pin
=
GPIO_SCL
,
};
static
struct
platform_device
device_i2c
=
{
.
name
=
"i2c-gpio"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
i2c_data
},
};
/* IXP425 2 UART ports */
static
struct
resource
uart_resources
[]
=
{
{
.
start
=
IXP4XX_UART1_BASE_PHYS
,
.
end
=
IXP4XX_UART1_BASE_PHYS
+
0x0fff
,
.
flags
=
IORESOURCE_MEM
,
},
{
.
start
=
IXP4XX_UART2_BASE_PHYS
,
.
end
=
IXP4XX_UART2_BASE_PHYS
+
0x0fff
,
.
flags
=
IORESOURCE_MEM
,
}
};
static
struct
plat_serial8250_port
uart_data
[]
=
{
{
.
mapbase
=
IXP4XX_UART1_BASE_PHYS
,
.
membase
=
(
char
__iomem
*
)
IXP4XX_UART1_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART1
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
},
{
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
membase
=
(
char
__iomem
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART2
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
},
{
},
};
static
struct
platform_device
device_uarts
=
{
.
name
=
"serial8250"
,
.
id
=
PLAT8250_DEV_PLATFORM
,
.
dev
.
platform_data
=
uart_data
,
.
num_resources
=
2
,
.
resource
=
uart_resources
,
};
/* Built-in 10/100 Ethernet MAC interfaces */
static
struct
eth_plat_info
eth_plat
[]
=
{
{
.
phy
=
0
,
.
rxq
=
3
,
.
txreadyq
=
32
,
},
{
.
phy
=
1
,
.
rxq
=
4
,
.
txreadyq
=
33
,
}
};
static
struct
platform_device
device_eth_tab
[]
=
{
{
.
name
=
"ixp4xx_eth"
,
.
id
=
IXP4XX_ETH_NPEB
,
.
dev
.
platform_data
=
eth_plat
,
},
{
.
name
=
"ixp4xx_eth"
,
.
id
=
IXP4XX_ETH_NPEC
,
.
dev
.
platform_data
=
eth_plat
+
1
,
}
};
/* IXP425 2 synchronous serial ports */
static
struct
hss_plat_info
hss_plat
[]
=
{
{
.
set_clock
=
hss_set_clock
,
.
open
=
hss_open
,
.
close
=
hss_close
,
.
txreadyq
=
34
,
},
{
.
set_clock
=
hss_set_clock
,
.
open
=
hss_open
,
.
close
=
hss_close
,
.
txreadyq
=
35
,
}
};
static
struct
platform_device
device_hss_tab
[]
=
{
{
.
name
=
"ixp4xx_hss"
,
.
id
=
0
,
.
dev
.
platform_data
=
hss_plat
,
},
{
.
name
=
"ixp4xx_hss"
,
.
id
=
1
,
.
dev
.
platform_data
=
hss_plat
+
1
,
}
};
static
struct
platform_device
*
device_tab
[
6
]
__initdata
=
{
&
device_flash
,
/* index 0 */
};
static
inline
u8
__init
flash_readb
(
u8
__iomem
*
flash
,
u32
addr
)
{
#ifdef __ARMEB__
return
__raw_readb
(
flash
+
addr
);
#else
return
__raw_readb
(
flash
+
(
addr
^
3
));
#endif
}
static
inline
u16
__init
flash_readw
(
u8
__iomem
*
flash
,
u32
addr
)
{
#ifdef __ARMEB__
return
__raw_readw
(
flash
+
addr
);
#else
return
__raw_readw
(
flash
+
(
addr
^
2
));
#endif
}
static
void
__init
gmlr_init
(
void
)
{
u8
__iomem
*
flash
;
int
i
,
devices
=
1
;
/* flash */
ixp4xx_sys_init
();
if
((
flash
=
ioremap
(
IXP4XX_EXP_BUS_BASE_PHYS
,
0x80
))
==
NULL
)
printk
(
KERN_ERR
"goramo-mlr: unable to access system"
" configuration data
\n
"
);
else
{
system_rev
=
__raw_readl
(
flash
+
CFG_REV
);
hw_bits
=
__raw_readl
(
flash
+
CFG_HW_BITS
);
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
{
eth_plat
[
0
].
hwaddr
[
i
]
=
flash_readb
(
flash
,
CFG_ETH0_ADDRESS
+
i
);
eth_plat
[
1
].
hwaddr
[
i
]
=
flash_readb
(
flash
,
CFG_ETH1_ADDRESS
+
i
);
}
__raw_writew
(
FLASH_CMD_READ_ID
,
flash
);
system_serial_high
=
flash_readw
(
flash
,
FLASH_SER_OFF
);
system_serial_high
<<=
16
;
system_serial_high
|=
flash_readw
(
flash
,
FLASH_SER_OFF
+
2
);
system_serial_low
=
flash_readw
(
flash
,
FLASH_SER_OFF
+
4
);
system_serial_low
<<=
16
;
system_serial_low
|=
flash_readw
(
flash
,
FLASH_SER_OFF
+
6
);
__raw_writew
(
FLASH_CMD_READ_ARRAY
,
flash
);
iounmap
(
flash
);
}
switch
(
hw_bits
&
(
CFG_HW_HAS_UART0
|
CFG_HW_HAS_UART1
))
{
case
CFG_HW_HAS_UART0
:
memset
(
&
uart_data
[
1
],
0
,
sizeof
(
uart_data
[
1
]));
device_uarts
.
num_resources
=
1
;
break
;
case
CFG_HW_HAS_UART1
:
device_uarts
.
dev
.
platform_data
=
&
uart_data
[
1
];
device_uarts
.
resource
=
&
uart_resources
[
1
];
device_uarts
.
num_resources
=
1
;
break
;
}
if
(
hw_bits
&
(
CFG_HW_HAS_UART0
|
CFG_HW_HAS_UART1
))
device_tab
[
devices
++
]
=
&
device_uarts
;
/* max index 1 */
if
(
hw_bits
&
CFG_HW_HAS_ETH0
)
device_tab
[
devices
++
]
=
&
device_eth_tab
[
0
];
/* max index 2 */
if
(
hw_bits
&
CFG_HW_HAS_ETH1
)
device_tab
[
devices
++
]
=
&
device_eth_tab
[
1
];
/* max index 3 */
if
(
hw_bits
&
CFG_HW_HAS_HSS0
)
device_tab
[
devices
++
]
=
&
device_hss_tab
[
0
];
/* max index 4 */
if
(
hw_bits
&
CFG_HW_HAS_HSS1
)
device_tab
[
devices
++
]
=
&
device_hss_tab
[
1
];
/* max index 5 */
if
(
hw_bits
&
CFG_HW_HAS_EEPROM
)
device_tab
[
devices
++
]
=
&
device_i2c
;
/* max index 6 */
gpio_line_config
(
GPIO_SCL
,
IXP4XX_GPIO_OUT
);
gpio_line_config
(
GPIO_SDA
,
IXP4XX_GPIO_OUT
);
gpio_line_config
(
GPIO_STR
,
IXP4XX_GPIO_OUT
);
gpio_line_config
(
GPIO_HSS0_RTS_N
,
IXP4XX_GPIO_OUT
);
gpio_line_config
(
GPIO_HSS1_RTS_N
,
IXP4XX_GPIO_OUT
);
gpio_line_config
(
GPIO_HSS0_DCD_N
,
IXP4XX_GPIO_IN
);
gpio_line_config
(
GPIO_HSS1_DCD_N
,
IXP4XX_GPIO_IN
);
set_irq_type
(
gpio_irq
(
GPIO_HSS0_DCD_N
),
IRQ_TYPE_EDGE_BOTH
);
set_irq_type
(
gpio_irq
(
GPIO_HSS1_DCD_N
),
IRQ_TYPE_EDGE_BOTH
);
set_control
(
CONTROL_HSS0_DTR_N
,
1
);
set_control
(
CONTROL_HSS1_DTR_N
,
1
);
set_control
(
CONTROL_EEPROM_WC_N
,
1
);
set_control
(
CONTROL_PCI_RESET_N
,
1
);
output_control
();
msleep
(
1
);
/* Wait for PCI devices to initialize */
flash_resource
.
start
=
IXP4XX_EXP_BUS_BASE
(
0
);
flash_resource
.
end
=
IXP4XX_EXP_BUS_BASE
(
0
)
+
ixp4xx_exp_bus_size
-
1
;
platform_add_devices
(
device_tab
,
devices
);
}
#ifdef CONFIG_PCI
static
void
__init
gmlr_pci_preinit
(
void
)
{
set_irq_type
(
IRQ_ETHA
,
IRQ_TYPE_LEVEL_LOW
);
set_irq_type
(
IRQ_ETHB
,
IRQ_TYPE_LEVEL_LOW
);
set_irq_type
(
IRQ_NEC
,
IRQ_TYPE_LEVEL_LOW
);
set_irq_type
(
IRQ_MPCI
,
IRQ_TYPE_LEVEL_LOW
);
ixp4xx_pci_preinit
();
}
static
void
__init
gmlr_pci_postinit
(
void
)
{
if
((
hw_bits
&
CFG_HW_USB_PORTS
)
>=
2
&&
(
hw_bits
&
CFG_HW_USB_PORTS
)
<
5
)
{
/* need to adjust number of USB ports on NEC chip */
u32
value
,
addr
=
BIT
(
32
-
SLOT_NEC
)
|
0xE0
;
if
(
!
ixp4xx_pci_read
(
addr
,
NP_CMD_CONFIGREAD
,
&
value
))
{
value
&=
~
7
;
value
|=
(
hw_bits
&
CFG_HW_USB_PORTS
);
ixp4xx_pci_write
(
addr
,
NP_CMD_CONFIGWRITE
,
value
);
}
}
}
static
int
__init
gmlr_map_irq
(
struct
pci_dev
*
dev
,
u8
slot
,
u8
pin
)
{
switch
(
slot
)
{
case
SLOT_ETHA
:
return
IRQ_ETHA
;
case
SLOT_ETHB
:
return
IRQ_ETHB
;
case
SLOT_NEC
:
return
IRQ_NEC
;
default:
return
IRQ_MPCI
;
}
}
static
struct
hw_pci
gmlr_hw_pci
__initdata
=
{
.
nr_controllers
=
1
,
.
preinit
=
gmlr_pci_preinit
,
.
postinit
=
gmlr_pci_postinit
,
.
swizzle
=
pci_std_swizzle
,
.
setup
=
ixp4xx_setup
,
.
scan
=
ixp4xx_scan_bus
,
.
map_irq
=
gmlr_map_irq
,
};
static
int
__init
gmlr_pci_init
(
void
)
{
if
(
machine_is_goramo_mlr
()
&&
(
hw_bits
&
(
CFG_HW_USB_PORTS
|
CFG_HW_HAS_PCI_SLOT
)))
pci_common_init
(
&
gmlr_hw_pci
);
return
0
;
}
subsys_initcall
(
gmlr_pci_init
);
#endif
/* CONFIG_PCI */
MACHINE_START
(
GORAMO_MLR
,
"MultiLink"
)
/* Maintainer: Krzysztof Halasa */
.
phys_io
=
IXP4XX_PERIPHERAL_BASE_PHYS
,
.
io_pg_offst
=
((
IXP4XX_PERIPHERAL_BASE_VIRT
)
>>
18
)
&
0xFFFC
,
.
map_io
=
ixp4xx_map_io
,
.
init_irq
=
ixp4xx_init_irq
,
.
timer
=
&
ixp4xx_timer
,
.
boot_params
=
0x0100
,
.
init_machine
=
gmlr_init
,
MACHINE_END
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment