Skip to content

Commit

Permalink
MIPS: Lantiq: Add initial support for Lantiq SoCs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
John Crispin authored and ralfbaechle committed May 19, 2011
1 parent c0a5afb commit 171bb2f
Show file tree
Hide file tree
Showing 13 changed files with 774 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/mips/Kbuild.platforms
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ platforms += dec
platforms += emma
platforms += jazz
platforms += jz4740
platforms += lantiq
platforms += lasat
platforms += loongson
platforms += mipssim
Expand Down
17 changes: 17 additions & 0 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,23 @@ config MACH_JZ4740
select HAVE_PWM
select HAVE_CLK

config LANTIQ
bool "Lantiq based platforms"
select DMA_NONCOHERENT
select IRQ_CPU
select CEVT_R4K
select CSRC_R4K
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_MULTITHREADING
select SYS_HAS_EARLY_PRINTK
select ARCH_REQUIRE_GPIOLIB
select SWAP_IO_SPACE
select BOOT_RAW
select HAVE_CLK

config LASAT
bool "LASAT Networks platforms"
select CEVT_R4K
Expand Down
63 changes: 63 additions & 0 deletions arch/mips/include/asm/mach-lantiq/lantiq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LANTIQ_H__
#define _LANTIQ_H__

#include <linux/irq.h>

/* generic reg access functions */
#define ltq_r32(reg) __raw_readl(reg)
#define ltq_w32(val, reg) __raw_writel(val, reg)
#define ltq_w32_mask(clear, set, reg) \
ltq_w32((ltq_r32(reg) & ~(clear)) | (set), reg)
#define ltq_r8(reg) __raw_readb(reg)
#define ltq_w8(val, reg) __raw_writeb(val, reg)

/* register access macros for EBU and CGU */
#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))

extern __iomem void *ltq_ebu_membase;
extern __iomem void *ltq_cgu_membase;

extern unsigned int ltq_get_cpu_ver(void);
extern unsigned int ltq_get_soc_type(void);

/* clock speeds */
#define CLOCK_60M 60000000
#define CLOCK_83M 83333333
#define CLOCK_111M 111111111
#define CLOCK_133M 133333333
#define CLOCK_167M 166666667
#define CLOCK_200M 200000000
#define CLOCK_266M 266666666
#define CLOCK_333M 333333333
#define CLOCK_400M 400000000

/* spinlock all ebu i/o */
extern spinlock_t ebu_lock;

/* some irq helpers */
extern void ltq_disable_irq(struct irq_data *data);
extern void ltq_mask_and_ack_irq(struct irq_data *data);
extern void ltq_enable_irq(struct irq_data *data);

/* find out what caused the last cpu reset */
extern int ltq_reset_cause(void);
#define LTQ_RST_CAUSE_WDTRST 0x20

#define IOPORT_RESOURCE_START 0x10000000
#define IOPORT_RESOURCE_END 0xffffffff
#define IOMEM_RESOURCE_START 0x10000000
#define IOMEM_RESOURCE_END 0xffffffff
#define LTQ_FLASH_START 0x10000000
#define LTQ_FLASH_MAX 0x04000000

#endif
24 changes: 24 additions & 0 deletions arch/mips/include/asm/mach-lantiq/war.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
*/
#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H
#define __ASM_MIPS_MACH_LANTIQ_WAR_H

#define R4600_V1_INDEX_ICACHEOP_WAR 0
#define R4600_V1_HIT_CACHEOP_WAR 0
#define R4600_V2_HIT_CACHEOP_WAR 0
#define R5432_CP0_INTERRUPT_WAR 0
#define BCM1250_M3_WAR 0
#define SIBYTE_1956_WAR 0
#define MIPS4K_ICACHE_REFILL_WAR 0
#define MIPS_CACHE_SYNC_WAR 0
#define TX49XX_ICACHE_INDEX_INV_WAR 0
#define RM9000_CDEX_SMP_WAR 0
#define ICACHE_REFILLS_WORKAROUND_WAR 0
#define R10000_LLSC_WAR 0
#define MIPS34K_MISSED_ITLB_WAR 0

#endif
9 changes: 9 additions & 0 deletions arch/mips/lantiq/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (C) 2010 John Crispin <blogic@openwrt.org>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.

obj-y := irq.o setup.o clk.o prom.o

obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
7 changes: 7 additions & 0 deletions arch/mips/lantiq/Platform
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#
# Lantiq
#

platform-$(CONFIG_LANTIQ) += lantiq/
cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
load-$(CONFIG_LANTIQ) = 0xffffffff80002000
140 changes: 140 additions & 0 deletions arch/mips/lantiq/clk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/list.h>

#include <asm/time.h>
#include <asm/irq.h>
#include <asm/div64.h>

#include <lantiq_soc.h>

#include "clk.h"

struct clk {
const char *name;
unsigned long rate;
unsigned long (*get_rate) (void);
};

static struct clk *cpu_clk;
static int cpu_clk_cnt;

/* lantiq socs have 3 static clocks */
static struct clk cpu_clk_generic[] = {
{
.name = "cpu",
.get_rate = ltq_get_cpu_hz,
}, {
.name = "fpi",
.get_rate = ltq_get_fpi_hz,
}, {
.name = "io",
.get_rate = ltq_get_io_region_clock,
},
};

static struct resource ltq_cgu_resource = {
.name = "cgu",
.start = LTQ_CGU_BASE_ADDR,
.end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
.flags = IORESOURCE_MEM,
};

/* remapped clock register range */
void __iomem *ltq_cgu_membase;

void clk_init(void)
{
cpu_clk = cpu_clk_generic;
cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
}

static inline int clk_good(struct clk *clk)
{
return clk && !IS_ERR(clk);
}

unsigned long clk_get_rate(struct clk *clk)
{
if (unlikely(!clk_good(clk)))
return 0;

if (clk->rate != 0)
return clk->rate;

if (clk->get_rate != NULL)
return clk->get_rate();

return 0;
}
EXPORT_SYMBOL(clk_get_rate);

struct clk *clk_get(struct device *dev, const char *id)
{
int i;

for (i = 0; i < cpu_clk_cnt; i++)
if (!strcmp(id, cpu_clk[i].name))
return &cpu_clk[i];
BUG();
return ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL(clk_get);

void clk_put(struct clk *clk)
{
/* not used */
}
EXPORT_SYMBOL(clk_put);

static inline u32 ltq_get_counter_resolution(void)
{
u32 res;

__asm__ __volatile__(
".set push\n"
".set mips32r2\n"
"rdhwr %0, $3\n"
".set pop\n"
: "=&r" (res)
: /* no input */
: "memory");

return res;
}

void __init plat_time_init(void)
{
struct clk *clk;

if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
panic("Failed to insert cgu memory\n");

if (request_mem_region(ltq_cgu_resource.start,
resource_size(&ltq_cgu_resource), "cgu") < 0)
panic("Failed to request cgu memory\n");

ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
resource_size(&ltq_cgu_resource));
if (!ltq_cgu_membase) {
pr_err("Failed to remap cgu memory\n");
unreachable();
}
clk = clk_get(0, "cpu");
mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
write_c0_compare(read_c0_count());
clk_put(clk);
}
18 changes: 18 additions & 0 deletions arch/mips/lantiq/clk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/

#ifndef _LTQ_CLK_H__
#define _LTQ_CLK_H__

extern void clk_init(void);

extern unsigned long ltq_get_cpu_hz(void);
extern unsigned long ltq_get_fpi_hz(void);
extern unsigned long ltq_get_io_region_clock(void);

#endif
33 changes: 33 additions & 0 deletions arch/mips/lantiq/early_printk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/

#include <linux/init.h>
#include <linux/cpu.h>

#include <lantiq.h>
#include <lantiq_soc.h>

/* no ioremap possible at this early stage, lets use KSEG1 instead */
#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
#define ASC_BUF 1024
#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020))
#define TXMASK 0x3F00
#define TXOFFSET 8

void prom_putchar(char c)
{
unsigned long flags;

local_irq_save(flags);
do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
if (c == '\n')
ltq_w32('\r', LTQ_ASC_TBUF);
ltq_w32(c, LTQ_ASC_TBUF);
local_irq_restore(flags);
}
Loading

0 comments on commit 171bb2f

Please sign in to comment.