Path: blob/master/arch/powerpc/platforms/embedded6xx/c2k.c
10818 views
/*1* Board setup routines for the GEFanuc C2K board2*3* Author: Remi Machet <[email protected]>4*5* Originated from prpmc2800.c6*7* 2008 (c) Stanford University8* 2007 (c) MontaVista, Software, Inc.9*10* This program is free software; you can redistribute it and/or modify it11* under the terms of the GNU General Public License version 2 as published12* by the Free Software Foundation.13*/1415#include <linux/stddef.h>16#include <linux/kernel.h>17#include <linux/delay.h>18#include <linux/interrupt.h>19#include <linux/seq_file.h>20#include <linux/time.h>21#include <linux/of.h>2223#include <asm/machdep.h>24#include <asm/prom.h>25#include <asm/system.h>26#include <asm/time.h>2728#include <mm/mmu_decl.h>2930#include <sysdev/mv64x60.h>3132#define MV64x60_MPP_CNTL_0 0x000033#define MV64x60_MPP_CNTL_2 0x00083435#define MV64x60_GPP_IO_CNTL 0x000036#define MV64x60_GPP_LEVEL_CNTL 0x001037#define MV64x60_GPP_VALUE_SET 0x00183839static void __iomem *mv64x60_mpp_reg_base;40static void __iomem *mv64x60_gpp_reg_base;4142static void __init c2k_setup_arch(void)43{44struct device_node *np;45phys_addr_t paddr;46const unsigned int *reg;4748/*49* ioremap mpp and gpp registers in case they are later50* needed by c2k_reset_board().51*/52np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-mpp");53reg = of_get_property(np, "reg", NULL);54paddr = of_translate_address(np, reg);55of_node_put(np);56mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);5758np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");59reg = of_get_property(np, "reg", NULL);60paddr = of_translate_address(np, reg);61of_node_put(np);62mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);6364#ifdef CONFIG_PCI65mv64x60_pci_init();66#endif67}6869static void c2k_reset_board(void)70{71u32 temp;7273local_irq_disable();7475temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);76temp &= 0xFFFF0FFF;77out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);7879temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);80temp |= 0x00000004;81out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);8283temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);84temp |= 0x00000004;85out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);8687temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);88temp &= 0xFFFF0FFF;89out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);9091temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);92temp |= 0x00080000;93out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);9495temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);96temp |= 0x00080000;97out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);9899out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);100}101102static void c2k_restart(char *cmd)103{104c2k_reset_board();105msleep(100);106panic("restart failed\n");107}108109#ifdef CONFIG_NOT_COHERENT_CACHE110#define COHERENCY_SETTING "off"111#else112#define COHERENCY_SETTING "on"113#endif114115void c2k_show_cpuinfo(struct seq_file *m)116{117seq_printf(m, "Vendor\t\t: GEFanuc\n");118seq_printf(m, "coherency\t: %s\n", COHERENCY_SETTING);119}120121/*122* Called very early, device-tree isn't unflattened123*/124static int __init c2k_probe(void)125{126unsigned long root = of_get_flat_dt_root();127128if (!of_flat_dt_is_compatible(root, "GEFanuc,C2K"))129return 0;130131printk(KERN_INFO "Detected a GEFanuc C2K board\n");132133_set_L2CR(0);134_set_L2CR(L2CR_L2E | L2CR_L2PE | L2CR_L2I);135return 1;136}137138define_machine(c2k) {139.name = "C2K",140.probe = c2k_probe,141.setup_arch = c2k_setup_arch,142.init_early = mv64x60_init_early,143.show_cpuinfo = c2k_show_cpuinfo,144.init_IRQ = mv64x60_init_irq,145.get_irq = mv64x60_get_irq,146.restart = c2k_restart,147.calibrate_decr = generic_calibrate_decr,148};149150151