source: trunk/target/linux/lantiq/patches-2.6.39/0001-MIPS-Lantiq-Add-initial-support-for-Lantiq-SoCs.patch @ 27104

Last change on this file since 27104 was 27104, checked in by florian, 5 years ago

[kernel] update to 2.6.39.1

patch from Peter Wagner

File size: 23.3 KB
  • arch/mips/Kconfig

    From 9e0235e97ea2617beaacaa16ab5f0b9e75f4680e Mon Sep 17 00:00:00 2001
    From: John Crispin <blogic@openwrt.org>
    Date: Wed, 30 Mar 2011 09:27:47 +0200
    Subject: [PATCH 01/13] MIPS: Lantiq: Add initial support for Lantiq SoCs
    
    Add initial support for Mips based SoCs made by Lantiq. This series will add
    support for the XWAY family.
    
    The series allows booting a minimal system using a initramfs or NOR. Missing
    drivers and support for Amazon and GPON family will be provided in a later
    series.
    
    [Ralf: Remove some cargo cult programming and fixed formatting.]
    
    Signed-off-by: John Crispin <blogic@openwrt.org>
    Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
    Signed-off-by: David Daney <ddaney@caviumnetworks.com>
    Cc: linux-mips@linux-mips.org
    Patchwork: https://patchwork.linux-mips.org/patch/2252/
    Patchwork: https://patchwork.linux-mips.org/patch/2371/
    Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
    ---
     arch/mips/Kbuild.platforms                 |    1 +
     arch/mips/Kconfig                          |   17 ++
     arch/mips/include/asm/mach-lantiq/lantiq.h |   63 ++++++
     arch/mips/include/asm/mach-lantiq/war.h    |   24 ++
     arch/mips/lantiq/Makefile                  |    9 +
     arch/mips/lantiq/Platform                  |    7 +
     arch/mips/lantiq/clk.c                     |  140 ++++++++++++
     arch/mips/lantiq/clk.h                     |   18 ++
     arch/mips/lantiq/early_printk.c            |   33 +++
     arch/mips/lantiq/irq.c                     |  326 ++++++++++++++++++++++++++++
     arch/mips/lantiq/prom.c                    |   71 ++++++
     arch/mips/lantiq/prom.h                    |   24 ++
     arch/mips/lantiq/setup.c                   |   41 ++++
     13 files changed, 774 insertions(+), 0 deletions(-)
     create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq.h
     create mode 100644 arch/mips/include/asm/mach-lantiq/war.h
     create mode 100644 arch/mips/lantiq/Makefile
     create mode 100644 arch/mips/lantiq/Platform
     create mode 100644 arch/mips/lantiq/clk.c
     create mode 100644 arch/mips/lantiq/clk.h
     create mode 100644 arch/mips/lantiq/early_printk.c
     create mode 100644 arch/mips/lantiq/irq.c
     create mode 100644 arch/mips/lantiq/prom.c
     create mode 100644 arch/mips/lantiq/prom.h
     create mode 100644 arch/mips/lantiq/setup.c
    
    a b config MACH_JZ4740 
    212212        select HAVE_PWM 
    213213        select HAVE_CLK 
    214214 
     215config LANTIQ 
     216        bool "Lantiq based platforms" 
     217        select DMA_NONCOHERENT 
     218        select IRQ_CPU 
     219        select CEVT_R4K 
     220        select CSRC_R4K 
     221        select SYS_HAS_CPU_MIPS32_R1 
     222        select SYS_HAS_CPU_MIPS32_R2 
     223        select SYS_SUPPORTS_BIG_ENDIAN 
     224        select SYS_SUPPORTS_32BIT_KERNEL 
     225        select SYS_SUPPORTS_MULTITHREADING 
     226        select SYS_HAS_EARLY_PRINTK 
     227        select ARCH_REQUIRE_GPIOLIB 
     228        select SWAP_IO_SPACE 
     229        select BOOT_RAW 
     230        select HAVE_CLK 
     231 
    215232config LASAT 
    216233        bool "LASAT Networks platforms" 
    217234        select CEVT_R4K 
  • new file arch/mips/include/asm/mach-lantiq/lantiq.h

    - +  
     1/* 
     2 *  This program is free software; you can redistribute it and/or modify it 
     3 *  under the terms of the GNU General Public License version 2 as published 
     4 *  by the Free Software Foundation. 
     5 * 
     6 *  Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     7 */ 
     8#ifndef _LANTIQ_H__ 
     9#define _LANTIQ_H__ 
     10 
     11#include <linux/irq.h> 
     12 
     13/* generic reg access functions */ 
     14#define ltq_r32(reg)            __raw_readl(reg) 
     15#define ltq_w32(val, reg)       __raw_writel(val, reg) 
     16#define ltq_w32_mask(clear, set, reg)   \ 
     17        ltq_w32((ltq_r32(reg) & ~(clear)) | (set), reg) 
     18#define ltq_r8(reg)             __raw_readb(reg) 
     19#define ltq_w8(val, reg)        __raw_writeb(val, reg) 
     20 
     21/* register access macros for EBU and CGU */ 
     22#define ltq_ebu_w32(x, y)       ltq_w32((x), ltq_ebu_membase + (y)) 
     23#define ltq_ebu_r32(x)          ltq_r32(ltq_ebu_membase + (x)) 
     24#define ltq_cgu_w32(x, y)       ltq_w32((x), ltq_cgu_membase + (y)) 
     25#define ltq_cgu_r32(x)          ltq_r32(ltq_cgu_membase + (x)) 
     26 
     27extern __iomem void *ltq_ebu_membase; 
     28extern __iomem void *ltq_cgu_membase; 
     29 
     30extern unsigned int ltq_get_cpu_ver(void); 
     31extern unsigned int ltq_get_soc_type(void); 
     32 
     33/* clock speeds */ 
     34#define CLOCK_60M       60000000 
     35#define CLOCK_83M       83333333 
     36#define CLOCK_111M      111111111 
     37#define CLOCK_133M      133333333 
     38#define CLOCK_167M      166666667 
     39#define CLOCK_200M      200000000 
     40#define CLOCK_266M      266666666 
     41#define CLOCK_333M      333333333 
     42#define CLOCK_400M      400000000 
     43 
     44/* spinlock all ebu i/o */ 
     45extern spinlock_t ebu_lock; 
     46 
     47/* some irq helpers */ 
     48extern void ltq_disable_irq(struct irq_data *d); 
     49extern void ltq_mask_and_ack_irq(struct irq_data *d); 
     50extern void ltq_enable_irq(struct irq_data *d); 
     51 
     52/* find out what caused the last cpu reset */ 
     53extern int ltq_reset_cause(void); 
     54#define LTQ_RST_CAUSE_WDTRST    0x20 
     55 
     56#define IOPORT_RESOURCE_START   0x10000000 
     57#define IOPORT_RESOURCE_END     0xffffffff 
     58#define IOMEM_RESOURCE_START    0x10000000 
     59#define IOMEM_RESOURCE_END      0xffffffff 
     60#define LTQ_FLASH_START         0x10000000 
     61#define LTQ_FLASH_MAX           0x04000000 
     62 
     63#endif 
  • new file arch/mips/include/asm/mach-lantiq/war.h

    - +  
     1/* 
     2 * This file is subject to the terms and conditions of the GNU General Public 
     3 * License.  See the file "COPYING" in the main directory of this archive 
     4 * for more details. 
     5 * 
     6 */ 
     7#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H 
     8#define __ASM_MIPS_MACH_LANTIQ_WAR_H 
     9 
     10#define R4600_V1_INDEX_ICACHEOP_WAR     0 
     11#define R4600_V1_HIT_CACHEOP_WAR        0 
     12#define R4600_V2_HIT_CACHEOP_WAR        0 
     13#define R5432_CP0_INTERRUPT_WAR         0 
     14#define BCM1250_M3_WAR                  0 
     15#define SIBYTE_1956_WAR                 0 
     16#define MIPS4K_ICACHE_REFILL_WAR        0 
     17#define MIPS_CACHE_SYNC_WAR             0 
     18#define TX49XX_ICACHE_INDEX_INV_WAR     0 
     19#define RM9000_CDEX_SMP_WAR             0 
     20#define ICACHE_REFILLS_WORKAROUND_WAR   0 
     21#define R10000_LLSC_WAR                 0 
     22#define MIPS34K_MISSED_ITLB_WAR         0 
     23 
     24#endif 
  • new file arch/mips/lantiq/Makefile

    - +  
     1# Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     2# 
     3# This program is free software; you can redistribute it and/or modify it 
     4# under the terms of the GNU General Public License version 2 as published 
     5# by the Free Software Foundation. 
     6 
     7obj-y := irq.o setup.o clk.o prom.o 
     8 
     9obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 
  • new file arch/mips/lantiq/Platform

    - +  
     1# 
     2# Lantiq 
     3# 
     4 
     5platform-$(CONFIG_LANTIQ)       += lantiq/ 
     6cflags-$(CONFIG_LANTIQ)         += -I$(srctree)/arch/mips/include/asm/mach-lantiq 
     7load-$(CONFIG_LANTIQ)           = 0xffffffff80002000 
  • new file arch/mips/lantiq/clk.c

    - +  
     1/* 
     2 *  This program is free software; you can redistribute it and/or modify it 
     3 *  under the terms of the GNU General Public License version 2 as published 
     4 *  by the Free Software Foundation. 
     5 * 
     6 * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> 
     7 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     8 */ 
     9#include <linux/io.h> 
     10#include <linux/module.h> 
     11#include <linux/init.h> 
     12#include <linux/kernel.h> 
     13#include <linux/types.h> 
     14#include <linux/clk.h> 
     15#include <linux/err.h> 
     16#include <linux/list.h> 
     17 
     18#include <asm/time.h> 
     19#include <asm/irq.h> 
     20#include <asm/div64.h> 
     21 
     22#include <lantiq_soc.h> 
     23 
     24#include "clk.h" 
     25 
     26struct clk { 
     27        const char *name; 
     28        unsigned long rate; 
     29        unsigned long (*get_rate) (void); 
     30}; 
     31 
     32static struct clk *cpu_clk; 
     33static int cpu_clk_cnt; 
     34 
     35/* lantiq socs have 3 static clocks */ 
     36static struct clk cpu_clk_generic[] = { 
     37        { 
     38                .name = "cpu", 
     39                .get_rate = ltq_get_cpu_hz, 
     40        }, { 
     41                .name = "fpi", 
     42                .get_rate = ltq_get_fpi_hz, 
     43        }, { 
     44                .name = "io", 
     45                .get_rate = ltq_get_io_region_clock, 
     46        }, 
     47}; 
     48 
     49#ifdef CONFIG_SOC_TYPE_XWAY 
     50static struct resource ltq_cgu_resource = { 
     51        .name   = "cgu", 
     52        .start  = LTQ_CGU_BASE_ADDR, 
     53        .end    = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1, 
     54        .flags  = IORESOURCE_MEM, 
     55}; 
     56 
     57/* remapped clock register range */ 
     58void __iomem *ltq_cgu_membase; 
     59#endif 
     60 
     61void clk_init(void) 
     62{ 
     63        cpu_clk = cpu_clk_generic; 
     64        cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic); 
     65} 
     66 
     67static inline int clk_good(struct clk *clk) 
     68{ 
     69        return clk && !IS_ERR(clk); 
     70} 
     71 
     72unsigned long clk_get_rate(struct clk *clk) 
     73{ 
     74        if (unlikely(!clk_good(clk))) 
     75                return 0; 
     76 
     77        if (clk->rate != 0) 
     78                return clk->rate; 
     79 
     80        if (clk->get_rate != NULL) 
     81                return clk->get_rate(); 
     82 
     83        return 0; 
     84} 
     85EXPORT_SYMBOL(clk_get_rate); 
     86 
     87struct clk *clk_get(struct device *dev, const char *id) 
     88{ 
     89        int i; 
     90 
     91        for (i = 0; i < cpu_clk_cnt; i++) 
     92                if (!strcmp(id, cpu_clk[i].name)) 
     93                        return &cpu_clk[i]; 
     94        BUG(); 
     95        return ERR_PTR(-ENOENT); 
     96} 
     97EXPORT_SYMBOL(clk_get); 
     98 
     99void clk_put(struct clk *clk) 
     100{ 
     101        /* not used */ 
     102} 
     103EXPORT_SYMBOL(clk_put); 
     104 
     105static inline u32 ltq_get_counter_resolution(void) 
     106{ 
     107        u32 res; 
     108 
     109        __asm__ __volatile__( 
     110                ".set   push\n" 
     111                ".set   mips32r2\n" 
     112                "rdhwr  %0, $3\n" 
     113                ".set pop\n" 
     114                : "=&r" (res) 
     115                : /* no input */ 
     116                : "memory"); 
     117 
     118        return res; 
     119} 
     120 
     121void __init plat_time_init(void) 
     122{ 
     123        struct clk *clk; 
     124 
     125#ifdef CONFIG_SOC_TYPE_XWAY 
     126        if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0) 
     127                panic("Failed to insert cgu memory\n"); 
     128 
     129        if (request_mem_region(ltq_cgu_resource.start, 
     130                        resource_size(&ltq_cgu_resource), "cgu") < 0) 
     131                panic("Failed to request cgu memory\n"); 
     132 
     133        ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start, 
     134                                resource_size(&ltq_cgu_resource)); 
     135        if (!ltq_cgu_membase) { 
     136                pr_err("Failed to remap cgu memory\n"); 
     137                unreachable(); 
     138        } 
     139#endif 
     140        clk = clk_get(0, "cpu"); 
     141        mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution(); 
     142        write_c0_compare(read_c0_count()); 
     143        clk_put(clk); 
     144} 
  • new file arch/mips/lantiq/clk.h

    - +  
     1/* 
     2 *  This program is free software; you can redistribute it and/or modify it 
     3 *  under the terms of the GNU General Public License version 2 as published 
     4 *  by the Free Software Foundation. 
     5 * 
     6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     7 */ 
     8 
     9#ifndef _LTQ_CLK_H__ 
     10#define _LTQ_CLK_H__ 
     11 
     12extern void clk_init(void); 
     13 
     14extern unsigned long ltq_get_cpu_hz(void); 
     15extern unsigned long ltq_get_fpi_hz(void); 
     16extern unsigned long ltq_get_io_region_clock(void); 
     17 
     18#endif 
  • new file arch/mips/lantiq/early_printk.c

    - +  
     1/* 
     2 *  This program is free software; you can redistribute it and/or modify it 
     3 *  under the terms of the GNU General Public License version 2 as published 
     4 *  by the Free Software Foundation. 
     5 * 
     6 *  Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     7 */ 
     8 
     9#include <linux/init.h> 
     10#include <linux/cpu.h> 
     11 
     12#include <lantiq.h> 
     13#include <lantiq_soc.h> 
     14 
     15/* no ioremap possible at this early stage, lets use KSEG1 instead  */ 
     16#ifdef CONFIG_SOC_FALCON 
     17#define LTQ_ASC_BASE    KSEG1ADDR(LTQ_ASC0_BASE_ADDR) 
     18#else 
     19#define LTQ_ASC_BASE    KSEG1ADDR(LTQ_ASC1_BASE_ADDR) 
     20#endif 
     21#define ASC_BUF         1024 
     22#define LTQ_ASC_FSTAT   ((u32 *)(LTQ_ASC_BASE + 0x0048)) 
     23#define LTQ_ASC_TBUF    ((u32 *)(LTQ_ASC_BASE + 0x0020)) 
     24#define TXMASK          0x3F00 
     25#define TXOFFSET        8 
     26 
     27void prom_putchar(char c) 
     28{ 
     29        unsigned long flags; 
     30 
     31        local_irq_save(flags); 
     32        do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET); 
     33        if (c == '\n') 
     34                ltq_w32('\r', LTQ_ASC_TBUF); 
     35        ltq_w32(c, LTQ_ASC_TBUF); 
     36        local_irq_restore(flags); 
     37} 
  • new file arch/mips/lantiq/irq.c

    - +  
     1/* 
     2 *  This program is free software; you can redistribute it and/or modify it 
     3 *  under the terms of the GNU General Public License version 2 as published 
     4 *  by the Free Software Foundation. 
     5 * 
     6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     7 * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> 
     8 */ 
     9 
     10#include <linux/interrupt.h> 
     11#include <linux/ioport.h> 
     12#include <linux/module.h> 
     13 
     14#include <asm/bootinfo.h> 
     15#include <asm/irq_cpu.h> 
     16 
     17#include <lantiq_soc.h> 
     18#include <irq.h> 
     19 
     20/* register definitions */ 
     21#define LTQ_ICU_IM0_ISR         0x0000 
     22#define LTQ_ICU_IM0_IER         0x0008 
     23#define LTQ_ICU_IM0_IOSR        0x0010 
     24#define LTQ_ICU_IM0_IRSR        0x0018 
     25#define LTQ_ICU_IM0_IMR         0x0020 
     26#define LTQ_ICU_IM1_ISR         0x0028 
     27#define LTQ_ICU_OFFSET          (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR) 
     28 
     29#ifdef CONFIG_SOC_TYPE_XWAY 
     30 
     31#define LTQ_EIU_EXIN_C          0x0000 
     32#define LTQ_EIU_EXIN_INIC       0x0004 
     33#define LTQ_EIU_EXIN_INEN       0x000C 
     34 
     35/* irq numbers used by the external interrupt unit (EIU) */ 
     36#define LTQ_EIU_IR0             (INT_NUM_IM4_IRL0 + 30) 
     37#define LTQ_EIU_IR1             (INT_NUM_IM3_IRL0 + 31) 
     38#define LTQ_EIU_IR2             (INT_NUM_IM1_IRL0 + 26) 
     39#define LTQ_EIU_IR3             INT_NUM_IM1_IRL0 
     40#define LTQ_EIU_IR4             (INT_NUM_IM1_IRL0 + 1) 
     41#define LTQ_EIU_IR5             (INT_NUM_IM1_IRL0 + 2) 
     42#define LTQ_EIU_IR6             (INT_NUM_IM2_IRL0 + 30) 
     43 
     44#define MAX_EIU                 6 
     45 
     46/* irqs generated by device attached to the EBU need to be acked in 
     47 * a special manner 
     48 */ 
     49#define LTQ_ICU_EBU_IRQ         22 
     50 
     51#define ltq_eiu_w32(x, y)       ltq_w32((x), ltq_eiu_membase + (y)) 
     52#define ltq_eiu_r32(x)          ltq_r32(ltq_eiu_membase + (x)) 
     53 
     54static unsigned short ltq_eiu_irq[MAX_EIU] = { 
     55        LTQ_EIU_IR0, 
     56        LTQ_EIU_IR1, 
     57        LTQ_EIU_IR2, 
     58        LTQ_EIU_IR3, 
     59        LTQ_EIU_IR4, 
     60        LTQ_EIU_IR5, 
     61}; 
     62 
     63static void __iomem *ltq_eiu_membase; 
     64 
     65static struct resource ltq_eiu_resource = { 
     66        .name   = "eiu", 
     67        .start  = LTQ_EIU_BASE_ADDR, 
     68        .end    = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1, 
     69        .flags  = IORESOURCE_MEM, 
     70}; 
     71 
     72#endif 
     73 
     74static struct resource ltq_icu_resource = { 
     75        .name   = "icu", 
     76        .start  = LTQ_ICU_BASE_ADDR, 
     77        .end    = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1, 
     78        .flags  = IORESOURCE_MEM, 
     79}; 
     80 
     81#define ltq_icu_w32(x, y)       ltq_w32((x), ltq_icu_membase + (y)) 
     82#define ltq_icu_r32(x)          ltq_r32(ltq_icu_membase + (x)) 
     83 
     84static void __iomem *ltq_icu_membase; 
     85 
     86 
     87void ltq_disable_irq(struct irq_data *d) 
     88{ 
     89        u32 ier = LTQ_ICU_IM0_IER; 
     90        int irq_nr = d->irq - INT_NUM_IRQ0; 
     91 
     92        ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 
     93        irq_nr %= INT_NUM_IM_OFFSET; 
     94        ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); 
     95} 
     96 
     97void ltq_mask_and_ack_irq(struct irq_data *d) 
     98{ 
     99        u32 ier = LTQ_ICU_IM0_IER; 
     100        u32 isr = LTQ_ICU_IM0_ISR; 
     101        int irq_nr = d->irq - INT_NUM_IRQ0; 
     102 
     103        ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 
     104        isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 
     105        irq_nr %= INT_NUM_IM_OFFSET; 
     106        ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); 
     107        ltq_icu_w32((1 << irq_nr), isr); 
     108} 
     109EXPORT_SYMBOL(ltq_mask_and_ack_irq); 
     110 
     111static void ltq_ack_irq(struct irq_data *d) 
     112{ 
     113        u32 isr = LTQ_ICU_IM0_ISR; 
     114        int irq_nr = d->irq - INT_NUM_IRQ0; 
     115 
     116        isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 
     117        irq_nr %= INT_NUM_IM_OFFSET; 
     118        ltq_icu_w32((1 << irq_nr), isr); 
     119} 
     120 
     121void ltq_enable_irq(struct irq_data *d) 
     122{ 
     123        u32 ier = LTQ_ICU_IM0_IER; 
     124        int irq_nr = d->irq - INT_NUM_IRQ0; 
     125 
     126        ier += LTQ_ICU_OFFSET  * (irq_nr / INT_NUM_IM_OFFSET); 
     127        irq_nr %= INT_NUM_IM_OFFSET; 
     128        ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier); 
     129} 
     130 
     131#ifdef CONFIG_SOC_TYPE_XWAY 
     132static unsigned int ltq_startup_eiu_irq(struct irq_data *d) 
     133{ 
     134        int i; 
     135        int irq_nr = d->irq - INT_NUM_IRQ0; 
     136 
     137        ltq_enable_irq(d); 
     138        for (i = 0; i < MAX_EIU; i++) { 
     139                if (irq_nr == ltq_eiu_irq[i]) { 
     140                        /* low level - we should really handle set_type */ 
     141                        ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | 
     142                                (0x6 << (i * 4)), LTQ_EIU_EXIN_C); 
     143                        /* clear all pending */ 
     144                        ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i), 
     145                                LTQ_EIU_EXIN_INIC); 
     146                        /* enable */ 
     147                        ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i), 
     148                                LTQ_EIU_EXIN_INEN); 
     149                        break; 
     150                } 
     151        } 
     152 
     153        return 0; 
     154} 
     155 
     156static void ltq_shutdown_eiu_irq(struct irq_data *d) 
     157{ 
     158        int i; 
     159        int irq_nr = d->irq - INT_NUM_IRQ0; 
     160 
     161        ltq_disable_irq(d); 
     162        for (i = 0; i < MAX_EIU; i++) { 
     163                if (irq_nr == ltq_eiu_irq[i]) { 
     164                        /* disable */ 
     165                        ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i), 
     166                                LTQ_EIU_EXIN_INEN); 
     167                        break; 
     168                } 
     169        } 
     170} 
     171#endif 
     172 
     173static struct irq_chip ltq_irq_type = { 
     174        "icu", 
     175        .irq_enable = ltq_enable_irq, 
     176        .irq_disable = ltq_disable_irq, 
     177        .irq_unmask = ltq_enable_irq, 
     178        .irq_ack = ltq_ack_irq, 
     179        .irq_mask = ltq_disable_irq, 
     180        .irq_mask_ack = ltq_mask_and_ack_irq, 
     181}; 
     182 
     183#ifdef CONFIG_SOC_TYPE_XWAY 
     184static struct irq_chip ltq_eiu_type = { 
     185        "eiu", 
     186        .irq_startup = ltq_startup_eiu_irq, 
     187        .irq_shutdown = ltq_shutdown_eiu_irq, 
     188        .irq_enable = ltq_enable_irq, 
     189        .irq_disable = ltq_disable_irq, 
     190        .irq_unmask = ltq_enable_irq, 
     191        .irq_ack = ltq_ack_irq, 
     192        .irq_mask = ltq_disable_irq, 
     193        .irq_mask_ack = ltq_mask_and_ack_irq, 
     194}; 
     195#endif 
     196 
     197static void ltq_hw_irqdispatch(int module) 
     198{ 
     199        u32 irq; 
     200 
     201        irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET)); 
     202        if (irq == 0) 
     203                return; 
     204 
     205        /* silicon bug causes only the msb set to 1 to be valid. all 
     206         * other bits might be bogus 
     207         */ 
     208        irq = __fls(irq); 
     209        do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module)); 
     210 
     211#ifdef CONFIG_SOC_TYPE_XWAY 
     212        /* if this is a EBU irq, we need to ack it or get a deadlock */ 
     213        if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0)) 
     214                ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10, 
     215                        LTQ_EBU_PCC_ISTAT); 
     216#endif 
     217} 
     218 
     219#define DEFINE_HWx_IRQDISPATCH(x)                                       \ 
     220        static void ltq_hw ## x ## _irqdispatch(void)                   \ 
     221        {                                                               \ 
     222                ltq_hw_irqdispatch(x);                                  \ 
     223        } 
     224DEFINE_HWx_IRQDISPATCH(0) 
     225DEFINE_HWx_IRQDISPATCH(1) 
     226DEFINE_HWx_IRQDISPATCH(2) 
     227DEFINE_HWx_IRQDISPATCH(3) 
     228DEFINE_HWx_IRQDISPATCH(4) 
     229 
     230static void ltq_hw5_irqdispatch(void) 
     231{ 
     232        do_IRQ(MIPS_CPU_TIMER_IRQ); 
     233} 
     234 
     235asmlinkage void plat_irq_dispatch(void) 
     236{ 
     237        unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; 
     238        unsigned int i; 
     239 
     240        if (pending & CAUSEF_IP7) { 
     241                do_IRQ(MIPS_CPU_TIMER_IRQ); 
     242                goto out; 
     243        } else { 
     244                for (i = 0; i < 5; i++) { 
     245                        if (pending & (CAUSEF_IP2 << i)) { 
     246                                ltq_hw_irqdispatch(i); 
     247                                goto out; 
     248                        } 
     249                } 
     250        } 
     251        pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status()); 
     252 
     253out: 
     254        return; 
     255} 
     256 
     257static struct irqaction cascade = { 
     258        .handler = no_action, 
     259        .flags = IRQF_DISABLED, 
     260        .name = "cascade", 
     261}; 
     262 
     263void __init arch_init_irq(void) 
     264{ 
     265        int i; 
     266 
     267        if (insert_resource(&iomem_resource, &ltq_icu_resource) < 0) 
     268                panic("Failed to insert icu memory\n"); 
     269 
     270        if (request_mem_region(ltq_icu_resource.start, 
     271                        resource_size(&ltq_icu_resource), "icu") < 0) 
     272                panic("Failed to request icu memory\n"); 
     273 
     274        ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start, 
     275                                resource_size(&ltq_icu_resource)); 
     276        if (!ltq_icu_membase) 
     277                panic("Failed to remap icu memory\n"); 
     278 
     279#ifdef CONFIG_SOC_TYPE_XWAY 
     280        if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0) 
     281                panic("Failed to insert eiu memory\n"); 
     282 
     283        if (request_mem_region(ltq_eiu_resource.start, 
     284                        resource_size(&ltq_eiu_resource), "eiu") < 0) 
     285                panic("Failed to request eiu memory\n"); 
     286 
     287        ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start, 
     288                                resource_size(&ltq_eiu_resource)); 
     289        if (!ltq_eiu_membase) 
     290                panic("Failed to remap eiu memory\n"); 
     291#endif 
     292        /* make sure all irqs are turned off by default */ 
     293        for (i = 0; i < 5; i++) 
     294                ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET)); 
     295 
     296        /* clear all possibly pending interrupts */ 
     297        ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET)); 
     298 
     299        mips_cpu_irq_init(); 
     300 
     301        for (i = 2; i <= 6; i++) 
     302                setup_irq(i, &cascade); 
     303 
     304        if (cpu_has_vint) { 
     305                pr_info("Setting up vectored interrupts\n"); 
     306                set_vi_handler(2, ltq_hw0_irqdispatch); 
     307                set_vi_handler(3, ltq_hw1_irqdispatch); 
     308                set_vi_handler(4, ltq_hw2_irqdispatch); 
     309                set_vi_handler(5, ltq_hw3_irqdispatch); 
     310                set_vi_handler(6, ltq_hw4_irqdispatch); 
     311                set_vi_handler(7, ltq_hw5_irqdispatch); 
     312        } 
     313 
     314        for (i = INT_NUM_IRQ0; 
     315                i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++) 
     316#ifdef CONFIG_SOC_TYPE_XWAY 
     317                        if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) || (i == LTQ_EIU_IR2)) 
     318                                irq_set_chip_and_handler(i, &ltq_eiu_type, handle_level_irq); 
     319                        /* EIU3-5 only exist on ar9 and vr9 */ 
     320                        else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) || 
     321                                (i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9())) 
     322                                irq_set_chip_and_handler(i, &ltq_eiu_type, handle_level_irq); 
     323                        else 
     324#endif 
     325                                irq_set_chip_and_handler(i, &ltq_irq_type, handle_level_irq); 
     326 
     327#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) 
     328        set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | 
     329                IE_IRQ3 | IE_IRQ4 | IE_IRQ5); 
     330#else 
     331        set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 | 
     332                IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); 
     333#endif 
     334} 
     335 
     336unsigned int __cpuinit get_c0_compare_int(void) 
     337{ 
     338        return CP0_LEGACY_COMPARE_IRQ; 
     339} 
  • new file arch/mips/lantiq/prom.c

    - +  
     1/* 
     2 *  This program is free software; you can redistribute it and/or modify it 
     3 *  under the terms of the GNU General Public License version 2 as published 
     4 *  by the Free Software Foundation. 
     5 * 
     6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     7 */ 
     8 
     9#include <linux/module.h> 
     10#include <linux/clk.h> 
     11#include <asm/bootinfo.h> 
     12#include <asm/time.h> 
     13 
     14#include <lantiq.h> 
     15 
     16#include "prom.h" 
     17#include "clk.h" 
     18 
     19static struct ltq_soc_info soc_info; 
     20 
     21unsigned int ltq_get_cpu_ver(void) 
     22{ 
     23        return soc_info.rev; 
     24} 
     25EXPORT_SYMBOL(ltq_get_cpu_ver); 
     26 
     27unsigned int ltq_get_soc_type(void) 
     28{ 
     29        return soc_info.type; 
     30} 
     31EXPORT_SYMBOL(ltq_get_soc_type); 
     32 
     33const char *get_system_type(void) 
     34{ 
     35        return soc_info.sys_type; 
     36} 
     37 
     38void prom_free_prom_memory(void) 
     39{ 
     40} 
     41 
     42static void __init prom_init_cmdline(void) 
     43{ 
     44        int argc = fw_arg0; 
     45        char **argv = (char **) KSEG1ADDR(fw_arg1); 
     46        int i; 
     47 
     48        for (i = 0; i < argc; i++) { 
     49                char *p = (char *)  KSEG1ADDR(argv[i]); 
     50 
     51                if (p && *p) { 
     52                        strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); 
     53                        strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); 
     54                } 
     55        } 
     56} 
     57 
     58void __init prom_init(void) 
     59{ 
     60        struct clk *clk; 
     61 
     62        ltq_soc_detect(&soc_info); 
     63        clk_init(); 
     64        clk = clk_get(0, "cpu"); 
     65        snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d", 
     66                soc_info.name, soc_info.rev); 
     67        clk_put(clk); 
     68        soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; 
     69        pr_info("SoC: %s\n", soc_info.sys_type); 
     70        prom_init_cmdline(); 
     71} 
  • new file arch/mips/lantiq/prom.h

    - +  
     1/* 
     2 *  This program is free software; you can redistribute it and/or modify it 
     3 *  under the terms of the GNU General Public License version 2 as published 
     4 *  by the Free Software Foundation. 
     5 * 
     6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     7 */ 
     8 
     9#ifndef _LTQ_PROM_H__ 
     10#define _LTQ_PROM_H__ 
     11 
     12#define LTQ_SYS_TYPE_LEN        0x100 
     13 
     14struct ltq_soc_info { 
     15        unsigned char *name; 
     16        unsigned int rev; 
     17        unsigned int partnum; 
     18        unsigned int type; 
     19        unsigned char sys_type[LTQ_SYS_TYPE_LEN]; 
     20}; 
     21 
     22extern void ltq_soc_detect(struct ltq_soc_info *i); 
     23 
     24#endif 
  • new file arch/mips/lantiq/setup.c

    - +  
     1/* 
     2 *  This program is free software; you can redistribute it and/or modify it 
     3 *  under the terms of the GNU General Public License version 2 as published 
     4 *  by the Free Software Foundation. 
     5 * 
     6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     7 */ 
     8 
     9#include <linux/kernel.h> 
     10#include <linux/module.h> 
     11#include <linux/io.h> 
     12#include <linux/ioport.h> 
     13#include <asm/bootinfo.h> 
     14 
     15#include <lantiq_soc.h> 
     16 
     17void __init plat_mem_setup(void) 
     18{ 
     19        /* assume 16M as default incase uboot fails to pass proper ramsize */ 
     20        unsigned long memsize = 16; 
     21        char **envp = (char **) KSEG1ADDR(fw_arg2); 
     22 
     23        ioport_resource.start = IOPORT_RESOURCE_START; 
     24        ioport_resource.end = IOPORT_RESOURCE_END; 
     25        iomem_resource.start = IOMEM_RESOURCE_START; 
     26        iomem_resource.end = IOMEM_RESOURCE_END; 
     27 
     28        set_io_port_base((unsigned long) KSEG1); 
     29 
     30        while (*envp) { 
     31                char *e = (char *)KSEG1ADDR(*envp); 
     32                if (!strncmp(e, "memsize=", 8)) { 
     33                        e += 8; 
     34                        if (strict_strtoul(e, 0, &memsize)) 
     35                                pr_warn("bad memsize specified\n"); 
     36                } 
     37                envp++; 
     38        } 
     39        memsize *= 1024 * 1024; 
     40        add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); 
     41} 
  • arch/mips/Kbuild.platforms

    a b platforms += dec 
    1111platforms += emma 
    1212platforms += jazz 
    1313platforms += jz4740 
     14platforms += lantiq 
    1415platforms += lasat 
    1516platforms += loongson 
    1617platforms += mipssim 
Note: See TracBrowser for help on using the repository browser.