32fd6901a6
Implement reset / poweroff in the board code instead. The peripheral reset code is gone too since YAMON which all in-tree boards use does the same work when it boots. Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com> Signed-off-by: Yoichi Yuasa <yuasa@linux-mips.org> Cc: Linux-MIPS <linux-mips@linux-mips.org> Patchwork: http://patchwork.linux-mips.org/patch/783/ Patchwork: http://patchwork.linux-mips.org/patch/882/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
119 lines
3.1 KiB
C
119 lines
3.1 KiB
C
/*
|
|
* Alchemy/AMD/RMI DB1200 board setup.
|
|
*
|
|
* Licensed under the terms outlined in the file COPYING in the root of
|
|
* this source archive.
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/io.h>
|
|
#include <linux/kernel.h>
|
|
#include <asm/mach-au1x00/au1000.h>
|
|
#include <asm/mach-db1x00/bcsr.h>
|
|
#include <asm/mach-db1x00/db1200.h>
|
|
|
|
const char *get_system_type(void)
|
|
{
|
|
return "Alchemy Db1200";
|
|
}
|
|
|
|
void __init board_setup(void)
|
|
{
|
|
unsigned long freq0, clksrc, div, pfc;
|
|
unsigned short whoami;
|
|
|
|
bcsr_init(DB1200_BCSR_PHYS_ADDR,
|
|
DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
|
|
|
|
whoami = bcsr_read(BCSR_WHOAMI);
|
|
printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d"
|
|
" Board-ID %d Daughtercard ID %d\n",
|
|
(whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
|
|
|
|
/* SMBus/SPI on PSC0, Audio on PSC1 */
|
|
pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
|
|
pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
|
|
pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
|
|
pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
|
|
__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
|
|
wmb();
|
|
|
|
/* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
|
|
* CPU clock; all other clock generators off/unused.
|
|
*/
|
|
div = (get_au1x00_speed() + 25000000) / 50000000;
|
|
if (div & 1)
|
|
div++;
|
|
div = ((div >> 1) - 1) & 0xff;
|
|
|
|
freq0 = div << SYS_FC_FRDIV0_BIT;
|
|
__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
|
|
wmb();
|
|
freq0 |= SYS_FC_FE0; /* enable F0 */
|
|
__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
|
|
wmb();
|
|
|
|
/* psc0_intclk comes 1:1 from F0 */
|
|
clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
|
|
__raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
|
|
wmb();
|
|
}
|
|
|
|
/* use the hexleds to count the number of times the cpu has entered
|
|
* wait, the dots to indicate whether the CPU is currently idle or
|
|
* active (dots off = sleeping, dots on = working) for cases where
|
|
* the number doesn't change for a long(er) period of time.
|
|
*/
|
|
static void db1200_wait(void)
|
|
{
|
|
__asm__(" .set push \n"
|
|
" .set mips3 \n"
|
|
" .set noreorder \n"
|
|
" cache 0x14, 0(%0) \n"
|
|
" cache 0x14, 32(%0) \n"
|
|
" cache 0x14, 64(%0) \n"
|
|
/* dots off: we're about to call wait */
|
|
" lui $26, 0xb980 \n"
|
|
" ori $27, $0, 3 \n"
|
|
" sb $27, 0x18($26) \n"
|
|
" sync \n"
|
|
" nop \n"
|
|
" wait \n"
|
|
" nop \n"
|
|
" nop \n"
|
|
" nop \n"
|
|
" nop \n"
|
|
" nop \n"
|
|
/* dots on: there's work to do, increment cntr */
|
|
" lui $26, 0xb980 \n"
|
|
" sb $0, 0x18($26) \n"
|
|
" lui $26, 0xb9c0 \n"
|
|
" lb $27, 0($26) \n"
|
|
" addiu $27, $27, 1 \n"
|
|
" sb $27, 0($26) \n"
|
|
" sync \n"
|
|
" .set pop \n"
|
|
: : "r" (db1200_wait));
|
|
}
|
|
|
|
static int __init db1200_arch_init(void)
|
|
{
|
|
/* GPIO7 is low-level triggered CPLD cascade */
|
|
set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
|
|
bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
|
|
|
|
/* do not autoenable these: CPLD has broken edge int handling,
|
|
* and the CD handler setup requires manual enabling to work
|
|
* around that.
|
|
*/
|
|
irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
|
|
irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
|
|
|
|
if (cpu_wait)
|
|
cpu_wait = db1200_wait;
|
|
|
|
return 0;
|
|
}
|
|
arch_initcall(db1200_arch_init);
|