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
47e9cffd
Commit
47e9cffd
authored
Apr 26, 2008
by
Sylver Bruneau
Committed by
Lennert Buytenhek
Jun 22, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ARM] Orion: add QNAP TS-409 support
Signed-off-by:
Lennert Buytenhek
<
buytenh@marvell.com
>
parent
a0087f2f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
392 additions
and
0 deletions
+392
-0
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/Kconfig
+6
-0
arch/arm/mach-orion5x/Makefile
arch/arm/mach-orion5x/Makefile
+1
-0
arch/arm/mach-orion5x/ts409-setup.c
arch/arm/mach-orion5x/ts409-setup.c
+385
-0
No files found.
arch/arm/mach-orion5x/Kconfig
View file @
47e9cffd
...
...
@@ -44,6 +44,12 @@ config MACH_LINKSTATION_PRO
Buffalo Linkstation Pro/Live platform. Both v1 and
v2 devices are supported.
config MACH_TS409
bool "QNAP TS-409"
help
Say 'Y' here if you want your kernel to support the
QNAP TS-409 platform.
endmenu
endif
arch/arm/mach-orion5x/Makefile
View file @
47e9cffd
...
...
@@ -5,3 +5,4 @@ obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
obj-$(CONFIG_MACH_LINKSTATION_PRO)
+=
kurobox_pro-setup.o
obj-$(CONFIG_MACH_DNS323)
+=
dns323-setup.o
obj-$(CONFIG_MACH_TS209)
+=
ts209-setup.o
obj-$(CONFIG_MACH_TS409)
+=
ts409-setup.o
arch/arm/mach-orion5x/ts409-setup.c
0 → 100644
View file @
47e9cffd
/*
* QNAP TS-409 Board Setup
*
* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.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; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/irq.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/serial_reg.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <asm/arch/orion5x.h>
#include "common.h"
#include "mpp.h"
/*****************************************************************************
* QNAP TS-409 Info
****************************************************************************/
/*
* QNAP TS-409 hardware :
* - Marvell 88F5281-D0
* - Marvell 88SX7042 SATA controller (PCIe)
* - Marvell 88E1118 Gigabit Ethernet PHY
* - RTC S35390A (@0x30) on I2C bus
* - 8MB NOR flash
* - 256MB of DDR-2 RAM
*/
/*
* 8MB NOR flash Device bus boot chip select
*/
#define QNAP_TS409_NOR_BOOT_BASE 0xff800000
#define QNAP_TS409_NOR_BOOT_SIZE SZ_8M
/****************************************************************************
* 8MiB NOR flash. The struct mtd_partition is not in the same order as the
* partitions on the device because we want to keep compatability with
* existing QNAP firmware.
*
* Layout as used by QNAP:
* [2] 0x00000000-0x00200000 : "Kernel"
* [3] 0x00200000-0x00600000 : "RootFS1"
* [4] 0x00600000-0x00700000 : "RootFS2"
* [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
* [5] 0x00760000-0x00780000 : "U-Boot Config"
* [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
***************************************************************************/
static
struct
mtd_partition
qnap_ts409_partitions
[]
=
{
{
.
name
=
"U-Boot"
,
.
size
=
0x00080000
,
.
offset
=
0x00780000
,
.
mask_flags
=
MTD_WRITEABLE
,
},
{
.
name
=
"Kernel"
,
.
size
=
0x00200000
,
.
offset
=
0
,
},
{
.
name
=
"RootFS1"
,
.
size
=
0x00400000
,
.
offset
=
0x00200000
,
},
{
.
name
=
"RootFS2"
,
.
size
=
0x00100000
,
.
offset
=
0x00600000
,
},
{
.
name
=
"U-Boot Config"
,
.
size
=
0x00020000
,
.
offset
=
0x00760000
,
},
{
.
name
=
"NAS Config"
,
.
size
=
0x00060000
,
.
offset
=
0x00700000
,
.
mask_flags
=
MTD_WRITEABLE
,
},
};
static
struct
physmap_flash_data
qnap_ts409_nor_flash_data
=
{
.
width
=
1
,
.
parts
=
qnap_ts409_partitions
,
.
nr_parts
=
ARRAY_SIZE
(
qnap_ts409_partitions
)
};
static
struct
resource
qnap_ts409_nor_flash_resource
=
{
.
flags
=
IORESOURCE_MEM
,
.
start
=
QNAP_TS409_NOR_BOOT_BASE
,
.
end
=
QNAP_TS409_NOR_BOOT_BASE
+
QNAP_TS409_NOR_BOOT_SIZE
-
1
,
};
static
struct
platform_device
qnap_ts409_nor_flash
=
{
.
name
=
"physmap-flash"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
qnap_ts409_nor_flash_data
,
},
.
num_resources
=
1
,
.
resource
=
&
qnap_ts409_nor_flash_resource
,
};
/*****************************************************************************
* PCI
****************************************************************************/
static
int
__init
qnap_ts409_pci_map_irq
(
struct
pci_dev
*
dev
,
u8
slot
,
u8
pin
)
{
int
irq
;
/*
* Check for devices with hard-wired IRQs.
*/
irq
=
orion5x_pci_map_irq
(
dev
,
slot
,
pin
);
if
(
irq
!=
-
1
)
return
irq
;
/*
* PCI isn't used on the TS-409
*/
return
-
1
;
}
static
struct
hw_pci
qnap_ts409_pci
__initdata
=
{
.
nr_controllers
=
2
,
.
swizzle
=
pci_std_swizzle
,
.
setup
=
orion5x_pci_sys_setup
,
.
scan
=
orion5x_pci_sys_scan_bus
,
.
map_irq
=
qnap_ts409_pci_map_irq
,
};
static
int
__init
qnap_ts409_pci_init
(
void
)
{
if
(
machine_is_ts409
())
pci_common_init
(
&
qnap_ts409_pci
);
return
0
;
}
subsys_initcall
(
qnap_ts409_pci_init
);
/*****************************************************************************
* Ethernet
****************************************************************************/
static
struct
mv643xx_eth_platform_data
qnap_ts409_eth_data
=
{
.
phy_addr
=
8
,
};
static
int
__init
parse_hex_nibble
(
char
n
)
{
if
(
n
>=
'0'
&&
n
<=
'9'
)
return
n
-
'0'
;
if
(
n
>=
'A'
&&
n
<=
'F'
)
return
n
-
'A'
+
10
;
if
(
n
>=
'a'
&&
n
<=
'f'
)
return
n
-
'a'
+
10
;
return
-
1
;
}
static
int
__init
parse_hex_byte
(
const
char
*
b
)
{
int
hi
;
int
lo
;
hi
=
parse_hex_nibble
(
b
[
0
]);
lo
=
parse_hex_nibble
(
b
[
1
]);
if
(
hi
<
0
||
lo
<
0
)
return
-
1
;
return
(
hi
<<
4
)
|
lo
;
}
static
int
__init
check_mac_addr
(
const
char
*
addr_str
)
{
u_int8_t
addr
[
6
];
int
i
;
for
(
i
=
0
;
i
<
6
;
i
++
)
{
int
byte
;
/*
* Enforce "xx:xx:xx:xx:xx:xx\n" format.
*/
if
(
addr_str
[(
i
*
3
)
+
2
]
!=
((
i
<
5
)
?
':'
:
'\n'
))
return
-
1
;
byte
=
parse_hex_byte
(
addr_str
+
(
i
*
3
));
if
(
byte
<
0
)
return
-
1
;
addr
[
i
]
=
byte
;
}
printk
(
KERN_INFO
"ts409: found ethernet mac address "
);
for
(
i
=
0
;
i
<
6
;
i
++
)
printk
(
"%.2x%s"
,
addr
[
i
],
(
i
<
5
)
?
":"
:
".
\n
"
);
memcpy
(
qnap_ts409_eth_data
.
mac_addr
,
addr
,
6
);
return
0
;
}
/*
* The 'NAS Config' flash partition has an ext2 filesystem which
* contains a file that has the ethernet MAC address in plain text
* (format "xx:xx:xx:xx:xx:xx\n").
*/
static
void
__init
ts409_find_mac_addr
(
void
)
{
unsigned
long
addr
;
for
(
addr
=
0x00700000
;
addr
<
0x00760000
;
addr
+=
1024
)
{
char
*
nor_page
;
int
ret
=
0
;
nor_page
=
ioremap
(
QNAP_TS409_NOR_BOOT_BASE
+
addr
,
1024
);
if
(
nor_page
!=
NULL
)
{
ret
=
check_mac_addr
(
nor_page
);
iounmap
(
nor_page
);
}
if
(
ret
==
0
)
break
;
}
}
/*****************************************************************************
* RTC S35390A on I2C bus
****************************************************************************/
#define TS409_RTC_GPIO 10
static
struct
i2c_board_info
__initdata
qnap_ts409_i2c_rtc
=
{
I2C_BOARD_INFO
(
"s35390a"
,
0x30
),
};
/****************************************************************************
* GPIO Attached Keys
* Power button is attached to the PIC microcontroller
****************************************************************************/
#define QNAP_TS409_GPIO_KEY_MEDIA 15
static
struct
gpio_keys_button
qnap_ts409_buttons
[]
=
{
{
.
code
=
KEY_RESTART
,
.
gpio
=
QNAP_TS409_GPIO_KEY_MEDIA
,
.
desc
=
"USB Copy Button"
,
.
active_low
=
1
,
},
};
static
struct
gpio_keys_platform_data
qnap_ts409_button_data
=
{
.
buttons
=
qnap_ts409_buttons
,
.
nbuttons
=
ARRAY_SIZE
(
qnap_ts409_buttons
),
};
static
struct
platform_device
qnap_ts409_button_device
=
{
.
name
=
"gpio-keys"
,
.
id
=
-
1
,
.
num_resources
=
0
,
.
dev
=
{
.
platform_data
=
&
qnap_ts409_button_data
,
},
};
/*****************************************************************************
* General Setup
****************************************************************************/
static
struct
orion5x_mpp_mode
ts409_mpp_modes
[]
__initdata
=
{
{
0
,
MPP_UNUSED
},
{
1
,
MPP_UNUSED
},
{
2
,
MPP_UNUSED
},
{
3
,
MPP_UNUSED
},
{
4
,
MPP_GPIO
},
/* HDD 1 status */
{
5
,
MPP_GPIO
},
/* HDD 2 status */
{
6
,
MPP_GPIO
},
/* HDD 3 status */
{
7
,
MPP_GPIO
},
/* HDD 4 status */
{
8
,
MPP_UNUSED
},
{
9
,
MPP_UNUSED
},
{
10
,
MPP_GPIO
},
/* RTC int */
{
11
,
MPP_UNUSED
},
{
12
,
MPP_UNUSED
},
{
13
,
MPP_UNUSED
},
{
14
,
MPP_GPIO
},
/* SW_RST */
{
15
,
MPP_GPIO
},
/* USB copy button */
{
16
,
MPP_UART
},
/* UART1 RXD */
{
17
,
MPP_UART
},
/* UART1 TXD */
{
18
,
MPP_UNUSED
},
{
19
,
MPP_UNUSED
},
{
-
1
},
};
/*
* QNAP TS-409 specific power off method via UART1-attached PIC
*/
#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
static
void
qnap_ts409_power_off
(
void
)
{
/* 19200 baud divisor */
const
unsigned
divisor
=
((
ORION5X_TCLK
+
(
8
*
19200
))
/
(
16
*
19200
));
pr_info
(
"%s: triggering power-off...
\n
"
,
__func__
);
/* hijack uart1 and reset into sane state (19200,8n1) */
writel
(
0x83
,
UART1_REG
(
LCR
));
writel
(
divisor
&
0xff
,
UART1_REG
(
DLL
));
writel
((
divisor
>>
8
)
&
0xff
,
UART1_REG
(
DLM
));
writel
(
0x03
,
UART1_REG
(
LCR
));
writel
(
0x00
,
UART1_REG
(
IER
));
writel
(
0x00
,
UART1_REG
(
FCR
));
writel
(
0x00
,
UART1_REG
(
MCR
));
/* send the power-off command 'A' to PIC */
writel
(
'A'
,
UART1_REG
(
TX
));
}
static
void
__init
qnap_ts409_init
(
void
)
{
/*
* Setup basic Orion functions. Need to be called early.
*/
orion5x_init
();
orion5x_mpp_conf
(
ts409_mpp_modes
);
/*
* Configure peripherals.
*/
orion5x_ehci0_init
();
ts409_find_mac_addr
();
orion5x_eth_init
(
&
qnap_ts409_eth_data
);
orion5x_i2c_init
();
orion5x_uart0_init
();
orion5x_setup_dev_boot_win
(
QNAP_TS409_NOR_BOOT_BASE
,
QNAP_TS409_NOR_BOOT_SIZE
);
platform_device_register
(
&
qnap_ts409_nor_flash
);
platform_device_register
(
&
qnap_ts409_button_device
);
/* Get RTC IRQ and register the chip */
if
(
gpio_request
(
TS409_RTC_GPIO
,
"rtc"
)
==
0
)
{
if
(
gpio_direction_input
(
TS409_RTC_GPIO
)
==
0
)
qnap_ts409_i2c_rtc
.
irq
=
gpio_to_irq
(
TS409_RTC_GPIO
);
else
gpio_free
(
TS409_RTC_GPIO
);
}
if
(
qnap_ts409_i2c_rtc
.
irq
==
0
)
pr_warning
(
"qnap_ts409_init: failed to get RTC IRQ
\n
"
);
i2c_register_board_info
(
0
,
&
qnap_ts409_i2c_rtc
,
1
);
/* register ts409 specific power-off method */
pm_power_off
=
qnap_ts409_power_off
;
}
MACHINE_START
(
TS409
,
"QNAP TS-409"
)
/* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */
.
phys_io
=
ORION5X_REGS_PHYS_BASE
,
.
io_pg_offst
=
((
ORION5X_REGS_VIRT_BASE
)
>>
18
)
&
0xFFFC
,
.
boot_params
=
0x00000100
,
.
init_machine
=
qnap_ts409_init
,
.
map_io
=
orion5x_map_io
,
.
init_irq
=
orion5x_init_irq
,
.
timer
=
&
orion5x_timer
,
.
fixup
=
tag_fixup_mem32
,
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