Commit b77d643c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus

* 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus: (46 commits)
  ftrace/MIPS: Enable C Version of recordmcount
  ftrace/MIPS: Add module support for C version of recordmcount
  ftrace/MIPS: Add MIPS64 support for C version of recordmcount
  MIPS: Make TASK_SIZE reflect proper size for both 32 and 64 bit processes.
  MIPS: Allow UserLocal on MIPS_R1 processors
  MIPS: Honor L2 bypass bit
  MIPS: Add BMIPS CP0 register definitions
  MIPS: Add BMIPS processor types to Kconfig
  MIPS: Decouple BMIPS CPU support from bcm47xx/bcm63xx SoC code
  MIPS: Add support for hardware performance events (mipsxx)
  MIPS: Perf-events: Add callchain support
  MIPS: add support for hardware performance events (skeleton)
  MIPS: add support for software performance events
  MIPS: define local_xchg from xchg_local to atomic_long_xchg
  MIPS: AR7: Add support for Titan (TNETV10xx) SoC variant
  MIPS: AR7: Initialize GPIO earlier
  MIPS: Add platform device and Kconfig for Octeon USB EHCI / OHCI
  USB: Add EHCI and OHCH glue for OCTEON II SOCs.
  MIPS: Octeon: Add register definitions for EHCI / OHCI USB glue logic.
  MIPS: Octeon: Apply CN63XXP1 errata workarounds.
  ...
parents b4020c1b 64575f91
......@@ -4,16 +4,21 @@ config MIPS
select HAVE_GENERIC_DMA_COHERENT
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select HAVE_ARCH_KGDB
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_C_RECORDMCOUNT
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_KPROBES
select HAVE_KRETPROBES
select RTC_LIB if !MACH_LOONGSON
select GENERIC_ATOMIC64 if !64BIT
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
menu "Machine selection"
......@@ -691,6 +696,9 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
select SWAP_IO_SPACE
select HW_HAS_PCI
select ARCH_SUPPORTS_MSI
select ZONE_DMA32
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
help
This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon
......@@ -1334,6 +1342,57 @@ config CPU_CAVIUM_OCTEON
can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
Full details can be found at http://www.caviumnetworks.com.
config CPU_BMIPS3300
bool "BMIPS3300"
depends on SYS_HAS_CPU_BMIPS3300
select DMA_NONCOHERENT
select IRQ_CPU
select SWAP_IO_SPACE
select SYS_SUPPORTS_32BIT_KERNEL
select WEAK_ORDERING
help
Broadcom BMIPS3300 processors.
config CPU_BMIPS4350
bool "BMIPS4350"
depends on SYS_HAS_CPU_BMIPS4350
select CPU_SUPPORTS_32BIT_KERNEL
select DMA_NONCOHERENT
select IRQ_CPU
select SWAP_IO_SPACE
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
select WEAK_ORDERING
help
Broadcom BMIPS4350 ("VIPER") processors.
config CPU_BMIPS4380
bool "BMIPS4380"
depends on SYS_HAS_CPU_BMIPS4380
select CPU_SUPPORTS_32BIT_KERNEL
select DMA_NONCOHERENT
select IRQ_CPU
select SWAP_IO_SPACE
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
select WEAK_ORDERING
help
Broadcom BMIPS4380 processors.
config CPU_BMIPS5000
bool "BMIPS5000"
depends on SYS_HAS_CPU_BMIPS5000
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select DMA_NONCOHERENT
select IRQ_CPU
select SWAP_IO_SPACE
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
select WEAK_ORDERING
help
Broadcom BMIPS5000 processors.
endchoice
if CPU_LOONGSON2F
......@@ -1452,6 +1511,18 @@ config SYS_HAS_CPU_SB1
config SYS_HAS_CPU_CAVIUM_OCTEON
bool
config SYS_HAS_CPU_BMIPS3300
bool
config SYS_HAS_CPU_BMIPS4350
bool
config SYS_HAS_CPU_BMIPS4380
bool
config SYS_HAS_CPU_BMIPS5000
bool
#
# CPU may reorder R->R, R->W, W->R, W->W
# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
......@@ -1928,6 +1999,14 @@ config NODES_SHIFT
default "6"
depends on NEED_MULTIPLE_NODES
config HW_PERF_EVENTS
bool "Enable hardware performance counter support for perf events"
depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32
default y
help
Enable hardware performance counter support for perf events. If
disabled, perf events will use software events only.
source "mm/Kconfig"
config SMP
......
......@@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE
Normally, you will choose 'N' here.
config DEBUG_STACKOVERFLOW
bool "Check for stack overflows"
depends on DEBUG_KERNEL
help
This option will cause messages to be printed if free stack space
drops below a certain limit(2GB on MIPS). The debugging option
provides another way to check stack overflow happened on kernel mode
stack usually caused by nested interruption.
config DEBUG_STACK_USAGE
bool "Enable stack utilization instrumentation"
depends on DEBUG_KERNEL
......
......@@ -48,9 +48,6 @@ ifneq ($(SUBARCH),$(ARCH))
endif
endif
ifndef CONFIG_FUNCTION_TRACER
cflags-y := -ffunction-sections
endif
ifdef CONFIG_FUNCTION_GRAPH_TRACER
ifndef KBUILD_MCOUNT_RA_ADDRESS
ifeq ($(call cc-option-yn,-mmcount-ra-address), y)
......@@ -159,6 +156,7 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
endif
cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
......
/*
* Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
* Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
* Copyright (C) 2009-2010 Florian Fainelli <florian@openwrt.org>
*
* 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
......@@ -37,6 +37,16 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
return readl(gpio_in) & (1 << gpio);
}
static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
struct ar7_gpio_chip *gpch =
container_of(chip, struct ar7_gpio_chip, chip);
void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
return readl(gpio >> 5 ? gpio_in1 : gpio_in0) & (1 << (gpio & 0x1f));
}
static void ar7_gpio_set_value(struct gpio_chip *chip,
unsigned gpio, int value)
{
......@@ -51,6 +61,21 @@ static void ar7_gpio_set_value(struct gpio_chip *chip,
writel(tmp, gpio_out);
}
static void titan_gpio_set_value(struct gpio_chip *chip,
unsigned gpio, int value)
{
struct ar7_gpio_chip *gpch =
container_of(chip, struct ar7_gpio_chip, chip);
void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
unsigned tmp;
tmp = readl(gpio >> 5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio & 0x1f));
if (value)
tmp |= 1 << (gpio & 0x1f);
writel(tmp, gpio >> 5 ? gpio_out1 : gpio_out0);
}
static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
struct ar7_gpio_chip *gpch =
......@@ -62,6 +87,21 @@ static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
return 0;
}
static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
struct ar7_gpio_chip *gpch =
container_of(chip, struct ar7_gpio_chip, chip);
void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
if (gpio >= TITAN_GPIO_MAX)
return -EINVAL;
writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio & 0x1f)),
gpio >> 5 ? gpio_dir1 : gpio_dir0);
return 0;
}
static int ar7_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value)
{
......@@ -75,6 +115,24 @@ static int ar7_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
static int titan_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value)
{
struct ar7_gpio_chip *gpch =
container_of(chip, struct ar7_gpio_chip, chip);
void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
if (gpio >= TITAN_GPIO_MAX)
return -EINVAL;
titan_gpio_set_value(chip, gpio, value);
writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) & ~(1 <<
(gpio & 0x1f)), gpio >> 5 ? gpio_dir1 : gpio_dir0);
return 0;
}
static struct ar7_gpio_chip ar7_gpio_chip = {
.chip = {
.label = "ar7-gpio",
......@@ -87,7 +145,19 @@ static struct ar7_gpio_chip ar7_gpio_chip = {
}
};
int ar7_gpio_enable(unsigned gpio)
static struct ar7_gpio_chip titan_gpio_chip = {
.chip = {
.label = "titan-gpio",
.direction_input = titan_gpio_direction_input,
.direction_output = titan_gpio_direction_output,
.set = titan_gpio_set_value,
.get = titan_gpio_get_value,
.base = 0,
.ngpio = TITAN_GPIO_MAX,
}
};
static inline int ar7_gpio_enable_ar7(unsigned gpio)
{
void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
......@@ -95,9 +165,26 @@ int ar7_gpio_enable(unsigned gpio)
return 0;
}
static inline int ar7_gpio_enable_titan(unsigned gpio)
{
void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) | (1 << (gpio & 0x1f)),
gpio >> 5 ? gpio_en1 : gpio_en0);
return 0;
}
int ar7_gpio_enable(unsigned gpio)
{
return ar7_is_titan() ? ar7_gpio_enable_titan(gpio) :
ar7_gpio_enable_ar7(gpio);
}
EXPORT_SYMBOL(ar7_gpio_enable);
int ar7_gpio_disable(unsigned gpio)
static inline int ar7_gpio_disable_ar7(unsigned gpio)
{
void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
......@@ -105,27 +192,159 @@ int ar7_gpio_disable(unsigned gpio)
return 0;
}
static inline int ar7_gpio_disable_titan(unsigned gpio)
{
void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio & 0x1f)),
gpio >> 5 ? gpio_en1 : gpio_en0);
return 0;
}
int ar7_gpio_disable(unsigned gpio)
{
return ar7_is_titan() ? ar7_gpio_disable_titan(gpio) :
ar7_gpio_disable_ar7(gpio);
}
EXPORT_SYMBOL(ar7_gpio_disable);
static int __init ar7_gpio_init(void)
struct titan_gpio_cfg {
u32 reg;
u32 shift;
u32 func;
};
static struct titan_gpio_cfg titan_gpio_table[] = {
/* reg, start bit, mux value */
{4, 24, 1},
{4, 26, 1},
{4, 28, 1},
{4, 30, 1},
{5, 6, 1},
{5, 8, 1},
{5, 10, 1},
{5, 12, 1},
{7, 14, 3},
{7, 16, 3},
{7, 18, 3},
{7, 20, 3},
{7, 22, 3},
{7, 26, 3},
{7, 28, 3},
{7, 30, 3},
{8, 0, 3},
{8, 2, 3},
{8, 4, 3},
{8, 10, 3},
{8, 14, 3},
{8, 16, 3},
{8, 18, 3},
{8, 20, 3},
{9, 8, 3},
{9, 10, 3},
{9, 12, 3},
{9, 14, 3},
{9, 18, 3},
{9, 20, 3},
{9, 24, 3},
{9, 26, 3},
{9, 28, 3},
{9, 30, 3},
{10, 0, 3},
{10, 2, 3},
{10, 8, 3},
{10, 10, 3},
{10, 12, 3},
{10, 14, 3},
{13, 12, 3},
{13, 14, 3},
{13, 16, 3},
{13, 18, 3},
{13, 24, 3},
{13, 26, 3},
{13, 28, 3},
{13, 30, 3},
{14, 2, 3},
{14, 6, 3},
{14, 8, 3},
{14, 12, 3}
};
static int titan_gpio_pinsel(unsigned gpio)
{
struct titan_gpio_cfg gpio_cfg;
u32 mux_status, pin_sel_reg, tmp;
void __iomem *pin_sel = (void __iomem *)KSEG1ADDR(AR7_REGS_PINSEL);
if (gpio >= ARRAY_SIZE(titan_gpio_table))
return -EINVAL;
gpio_cfg = titan_gpio_table[gpio];
pin_sel_reg = gpio_cfg.reg - 1;
mux_status = (readl(pin_sel + pin_sel_reg) >> gpio_cfg.shift) & 0x3;
/* Check the mux status */
if (!((mux_status == 0) || (mux_status == gpio_cfg.func)))
return 0;
/* Set the pin sel value */
tmp = readl(pin_sel + pin_sel_reg);
tmp |= ((gpio_cfg.func & 0x3) << gpio_cfg.shift);
writel(tmp, pin_sel + pin_sel_reg);
return 0;
}
/* Perform minimal Titan GPIO configuration */
static void titan_gpio_init(void)
{
unsigned i;
for (i = 44; i < 48; i++) {
titan_gpio_pinsel(i);
ar7_gpio_enable_titan(i);
titan_gpio_direction_input(&titan_gpio_chip.chip, i);
}
}
int __init ar7_gpio_init(void)
{
int ret;
struct ar7_gpio_chip *gpch;
unsigned size;
if (!ar7_is_titan()) {
gpch = &ar7_gpio_chip;
size = 0x10;
} else {
gpch = &titan_gpio_chip;
size = 0x1f;
}
ar7_gpio_chip.regs = ioremap_nocache(AR7_REGS_GPIO,
gpch->regs = ioremap_nocache(AR7_REGS_GPIO,
AR7_REGS_GPIO + 0x10);
if (!ar7_gpio_chip.regs) {
printk(KERN_ERR "ar7-gpio: failed to ioremap regs\n");
if (!gpch->regs) {
printk(KERN_ERR "%s: failed to ioremap regs\n",
gpch->chip.label);
return -ENOMEM;
}
ret = gpiochip_add(&ar7_gpio_chip.chip);
ret = gpiochip_add(&gpch->chip);
if (ret) {
printk(KERN_ERR "ar7-gpio: failed to add gpiochip\n");
printk(KERN_ERR "%s: failed to add gpiochip\n",
gpch->chip.label);
return ret;
}
printk(KERN_INFO "ar7-gpio: registered %d GPIOs\n",
ar7_gpio_chip.chip.ngpio);
printk(KERN_INFO "%s: registered %d GPIOs\n",
gpch->chip.label, gpch->chip.ngpio);
if (ar7_is_titan())
titan_gpio_init();
return ret;
}
arch_initcall(ar7_gpio_init);
......@@ -357,6 +357,11 @@ static struct gpio_led default_leds[] = {
},
};
static struct gpio_led titan_leds[] = {
{ .name = "status", .gpio = 8, .active_low = 1, },
{ .name = "wifi", .gpio = 13, .active_low = 1, },
};
static struct gpio_led dsl502t_leds[] = {
{
.name = "status",
......@@ -495,6 +500,9 @@ static void __init detect_leds(void)
} else if (strstr(prid, "DG834")) {
ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
ar7_led_data.leds = dg834g_leds;
} else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
ar7_led_data.leds = titan_leds;
}
}
......@@ -560,6 +568,51 @@ static int __init ar7_register_uarts(void)
return 0;
}
static void __init titan_fixup_devices(void)
{
/* Set vlynq0 data */
vlynq_low_data.reset_bit = 15;
vlynq_low_data.gpio_bit = 14;
/* Set vlynq1 data */
vlynq_high_data.reset_bit = 16;
vlynq_high_data.gpio_bit = 7;
/* Set vlynq0 resources */
vlynq_low_res[0].start = TITAN_REGS_VLYNQ0;
vlynq_low_res[0].end = TITAN_REGS_VLYNQ0 + 0xff;
vlynq_low_res[1].start = 33;
vlynq_low_res[1].end = 33;
vlynq_low_res[2].start = 0x0c000000;
vlynq_low_res[2].end = 0x0fffffff;
vlynq_low_res[3].start = 80;
vlynq_low_res[3].end = 111;
/* Set vlynq1 resources */
vlynq_high_res[0].start = TITAN_REGS_VLYNQ1;
vlynq_high_res[0].end = TITAN_REGS_VLYNQ1 + 0xff;
vlynq_high_res[1].start = 34;
vlynq_high_res[1].end = 34;
vlynq_high_res[2].start = 0x40000000;
vlynq_high_res[2].end = 0x43ffffff;
vlynq_high_res[3].start = 112;
vlynq_high_res[3].end = 143;
/* Set cpmac0 data */
cpmac_low_data.phy_mask = 0x40000000;
/* Set cpmac1 data */
cpmac_high_data.phy_mask = 0x80000000;
/* Set cpmac0 resources */
cpmac_low_res[0].start = TITAN_REGS_MAC0;
cpmac_low_res[0].end = TITAN_REGS_MAC0 + 0x7ff;
/* Set cpmac1 resources */
cpmac_high_res[0].start = TITAN_REGS_MAC1;
cpmac_high_res[0].end = TITAN_REGS_MAC1 + 0x7ff;
}
static int __init ar7_register_devices(void)
{
void __iomem *bootcr;
......@@ -574,6 +627,9 @@ static int __init ar7_register_devices(void)
if (res)
pr_warning("unable to register physmap-flash: %d\n", res);
if (ar7_is_titan())
titan_fixup_devices();
ar7_device_disable(vlynq_low_data.reset_bit);
res = platform_device_register(&vlynq_low);
if (res)
......
......@@ -246,6 +246,8 @@ void __init prom_init(void)
ar7_init_cmdline(fw_arg0, (char **)fw_arg1);
ar7_init_env((struct env_var *)fw_arg2);
console_config();
ar7_gpio_init();
}
#define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4)))
......
......@@ -23,6 +23,7 @@
#include <asm/reboot.h>
#include <asm/mach-ar7/ar7.h>
#include <asm/mach-ar7/prom.h>
#include <asm/mach-ar7/gpio.h>
static void ar7_machine_restart(char *command)
{
......@@ -49,6 +50,8 @@ static void ar7_machine_power_off(void)
const char *get_system_type(void)
{
u16 chip_id = ar7_chip_id();
u16 titan_variant_id = titan_chip_id();
switch (chip_id) {
case AR7_CHIP_7100:
return "TI AR7 (TNETD7100)";
......@@ -56,6 +59,17 @@ const char *get_system_type(void)
return "TI AR7 (TNETD7200)";
case AR7_CHIP_7300:
return "TI AR7 (TNETD7300)";
case AR7_CHIP_TITAN:
switch (titan_variant_id) {
case TITAN_CHIP_1050:
return "TI AR7 (TNETV1050)";
case TITAN_CHIP_1055:
return "TI AR7 (TNETV1055)";
case TITAN_CHIP_1056:
return "TI AR7 (TNETV1056)";
case TITAN_CHIP_1060:
return "TI AR7 (TNETV1060)";
}
default:
return "TI AR7 (unknown)";
}
......
......@@ -10,7 +10,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpu.h>
#include <asm/cpu.h>
#include <asm/cpu-info.h>
#include <asm/mipsregs.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_io.h>
......@@ -296,26 +298,24 @@ void __init bcm63xx_cpu_init(void)
expected_cpu_id = 0;
switch (c->cputype) {
/*
* BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
*/
case CPU_BCM3302:
__cpu_name[cpu] = "Broadcom BCM6338";
expected_cpu_id = BCM6338_CPU_ID;
bcm63xx_regs_base = bcm96338_regs_base;
bcm63xx_irqs = bcm96338_irqs;
case CPU_BMIPS3300:
if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) {
expected_cpu_id = BCM6348_CPU_ID;
bcm63xx_regs_base = bcm96348_regs_base;
bcm63xx_irqs = bcm96348_irqs;
} else {
__cpu_name[cpu] = "Broadcom BCM6338";
expected_cpu_id = BCM6338_CPU_ID;
bcm63xx_regs_base = bcm96338_regs_base;
bcm63xx_irqs = bcm96338_irqs;
}
break;
case CPU_BCM6345:
case CPU_BMIPS32:
expected_cpu_id = BCM6345_CPU_ID;
bcm63xx_regs_base = bcm96345_regs_base;
bcm63xx_irqs = bcm96345_irqs;
break;
case CPU_BCM6348:
expected_cpu_id = BCM6348_CPU_ID;
bcm63xx_regs_base = bcm96348_regs_base;
bcm63xx_irqs = bcm96348_irqs;
break;
case CPU_BCM6358:
case CPU_BMIPS4350:
expected_cpu_id = BCM6358_CPU_ID;
bcm63xx_regs_base = bcm96358_regs_base;
bcm63xx_irqs = bcm96358_irqs;
......
......@@ -3,6 +3,17 @@ config CAVIUM_OCTEON_SPECIFIC_OPTIONS
depends on CPU_CAVIUM_OCTEON
default "y"
config CAVIUM_CN63XXP1
bool "Enable CN63XXP1 errata worarounds"
depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
default "n"
help
The CN63XXP1 chip requires build time workarounds to
function reliably, select this option to enable them. These
workarounds will cause a slight decrease in performance on
non-CN63XXP1 hardware, so it is recommended to select "n"
unless it is known the workarounds are needed.
config CAVIUM_OCTEON_2ND_KERNEL
bool "Build the kernel to be used as a 2nd kernel on the same chip"
depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
......@@ -87,3 +98,15 @@ config ARCH_SPARSEMEM_ENABLE
config CAVIUM_OCTEON_HELPER
def_bool y
depends on OCTEON_ETHERNET || PCI
config IOMMU_HELPER
bool
config NEED_SG_DMA_LENGTH
bool
config SWIOTLB
def_bool y
depends on CPU_CAVIUM_OCTEON
select IOMMU_HELPER
select NEED_SG_DMA_LENGTH
......@@ -4,14 +4,18 @@
* for more details.
*
* Copyright (C) 2007 by Ralf Baechle
* Copyright (C) 2009, 2010 Cavium Networks, Inc.
*/
#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <asm/cpu-info.h>
#include <asm/time.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-ipd-defs.h>
#include <asm/octeon/cvmx-mio-defs.h>
/*
* Set the current core's cvmcount counter to the value of the
......@@ -19,11 +23,23 @@
* on-line. This allows for a read from a local cpu register to
* access a synchronized counter.
*
* On CPU_CAVIUM_OCTEON2 the IPD_CLK_COUNT is scaled by rdiv/sdiv.
*/
void octeon_init_cvmcount(void)
{
unsigned long flags;
unsigned loops = 2;
u64 f = 0;
u64 rdiv = 0;
u64 sdiv = 0;
if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
union cvmx_mio_rst_boot rst_boot;
rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
rdiv = rst_boot.s.c_mul; /* CPU clock */
sdiv = rst_boot.s.pnr_mul; /* I/O clock */
f = (0x8000000000000000ull / sdiv) * 2;
}
/* Clobber loops so GCC will not unroll the following while loop. */
asm("" : "+r" (loops));
......@@ -33,8 +49,20 @@ void octeon_init_cvmcount(void)
* Loop several times so we are executing from the cache,
* which should give more deterministic timing.
*/
while (loops--)
write_c0_cvmcount(cvmx_read_csr(CVMX_IPD_CLK_COUNT));
while (loops--) {
u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT);
if (rdiv != 0) {
ipd_clk_count *= rdiv;
if (f != 0) {
asm("dmultu\t%[cnt],%[f]\n\t"
"mfhi\t%[cnt]"
: [cnt] "+r" (ipd_clk_count),
[f] "=r" (f)
: : "hi", "lo");
}
}
write_c0_cvmcount(ipd_clk_count);
}
local_irq_restore(flags);
}
......@@ -77,7 +105,7 @@ unsigned long long notrace sched_clock(void)
void __init plat_time_init(void)
{
clocksource_mips.rating = 300;
clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
clocksource_set_clock(&clocksource_mips, octeon_get_clock_rate());
clocksource_register(&clocksource_mips);
}
......
This diff is collapsed.
......@@ -3,13 +3,15 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004-2009 Cavium Networks
* Copyright (C) 2004-2010 Cavium Networks
* Copyright (C) 2008 Wind River Systems
*/
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/i2c.h>
#include <linux/usb.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/platform_device.h>
......@@ -198,7 +200,7 @@ static int __init octeon_i2c_device_init(void)
num_ports = 1;
for (port = 0; port < num_ports; port++) {
octeon_i2c_data[port].sys_freq = octeon_get_clock_rate();
octeon_i2c_data[port].sys_freq = octeon_get_io_clock_rate();
/*FIXME: should be examined. At the moment is set for 100Khz */
octeon_i2c_data[port].i2c_freq = 100000;
......@@ -301,6 +303,10 @@ static int __init octeon_mgmt_device_init(void)
ret = -ENOMEM;
goto out;
}
/* No DMA restrictions */
pd->dev.coherent_dma_mask = DMA_BIT_MASK(64);
pd->dev.dma_mask = &pd->dev.coherent_dma_mask;
switch (port) {
case 0:
mgmt_port_resource.start = OCTEON_IRQ_MII0;
......@@ -332,6 +338,108 @@ static int __init octeon_mgmt_device_init(void)
}
device_initcall(octeon_mgmt_device_init);
#ifdef CONFIG_USB
static int __init octeon_ehci_device_init(void)
{
struct platform_device *pd;
int ret = 0;
struct resource usb_resources[] = {
{
.flags = IORESOURCE_MEM,
}, {
.flags = IORESOURCE_IRQ,
}
};
/* Only Octeon2 has ehci/ohci */
if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
return 0;
if (octeon_is_simulation() || usb_disabled())
return 0; /* No USB in the simulator. */
pd = platform_device_alloc("octeon-ehci", 0);
if (!pd) {
ret = -ENOMEM;
goto out;
}
usb_resources[0].start = 0x00016F0000000000ULL;
usb_resources[0].end = usb_resources[0].start + 0x100;
usb_resources[1].start = OCTEON_IRQ_USB0;
usb_resources[1].end = OCTEON_IRQ_USB0;
ret = platform_device_add_resources(pd, usb_resources,
ARRAY_SIZE(usb_resources));
if (ret)
goto fail;
ret = platform_device_add(pd);
if (ret)
goto fail;
return ret;
fail:
platform_device_put(pd);
out:
return ret;
}
device_initcall(octeon_ehci_device_init);
static int __init octeon_ohci_device_init(void)
{
struct platform_device *pd;
int ret = 0;
struct resource usb_resources[] = {
{
.flags = IORESOURCE_MEM,
}, {
.flags = IORESOURCE_IRQ,
}
};
/* Only Octeon2 has ehci/ohci */
if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
return 0;
if (octeon_is_simulation() || usb_disabled())
return 0; /* No USB in the simulator. */
pd = platform_device_alloc("octeon-ohci", 0);
if (!pd) {
ret = -ENOMEM;
goto out;
}
usb_resources[0].start = 0x00016F0000000400ULL;
usb_resources[0].end = usb_resources[0].start + 0x100;
usb_resources[1].start = OCTEON_IRQ_USB0;
usb_resources[1].end = OCTEON_IRQ_USB0;
ret = platform_device_add_resources(pd, usb_resources,
ARRAY_SIZE(usb_resources));
if (ret)
goto fail;
ret = platform_device_add(pd);
if (ret)
goto fail;
return ret;
fail:
platform_device_put(pd);
out:
return ret;
}
device_initcall(octeon_ohci_device_init);
#endif /* CONFIG_USB */
MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Platform driver for Octeon SOC");
......@@ -66,7 +66,7 @@ static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
/* Make simulator output fast*/
p->uartclk = 115200 * 16;
else
p->uartclk = mips_hpt_frequency;
p->uartclk = octeon_get_io_clock_rate();
p->serial_in = octeon_serial_in;
p->serial_out = octeon_serial_out;
}
......
......@@ -33,6 +33,7 @@
#include <asm/octeon/octeon.h>
#include <asm/octeon/pci-octeon.h>
#include <asm/octeon/cvmx-mio-defs.h>
#ifdef CONFIG_CAVIUM_DECODE_RSL
extern void cvmx_interrupt_rsl_decode(void);
......@@ -96,12 +97,21 @@ int octeon_is_pci_host(void)
*/
uint64_t octeon_get_clock_rate(void)
{
if (octeon_is_simulation())
octeon_bootinfo->eclock_hz = 6000000;
return octeon_bootinfo->eclock_hz;
struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();
return sysinfo->cpu_clock_hz;
}
EXPORT_SYMBOL(octeon_get_clock_rate);
static u64 octeon_io_clock_rate;
u64 octeon_get_io_clock_rate(void)
{
return octeon_io_clock_rate;
}
EXPORT_SYMBOL(octeon_get_io_clock_rate);
/**
* Write to the LCD display connected to the bootbus. This display
* exists on most Cavium evaluation boards. If it doesn't exist, then
......@@ -346,8 +356,18 @@ void octeon_user_io_init(void)
cvmmemctl.s.wbfltime = 0;
/* R/W If set, do not put Istream in the L2 cache. */
cvmmemctl.s.istrnol2 = 0;
/* R/W The write buffer threshold. */
cvmmemctl.s.wbthresh = 10;
/*
* R/W The write buffer threshold. As per erratum Core-14752
* for CN63XX, a sc/scd might fail if the write buffer is
* full. Lowering WBTHRESH greatly lowers the chances of the
* write buffer ever being full and triggering the erratum.
*/
if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
cvmmemctl.s.wbthresh = 4;
else
cvmmemctl.s.wbthresh = 10;
/* R/W If set, CVMSEG is available for loads/stores in
* kernel/debug mode. */
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
......@@ -365,14 +385,13 @@ void octeon_user_io_init(void)
* is max legal value. */
cvmmemctl.s.lmemsz = CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE;
write_c0_cvmmemctl(cvmmemctl.u64);
if (smp_processor_id() == 0)
pr_notice("CVMSEG size: %d cache lines (%d bytes)\n",
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
write_c0_cvmmemctl(cvmmemctl.u64);
/* Move the performance counter interrupts to IRQ 6 */
cvmctl = read_c0_cvmctl();
cvmctl &= ~(7 << 7);
......@@ -416,6 +435,41 @@ void __init prom_init(void)
cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
cvmx_bootmem_init(cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr));
sysinfo = cvmx_sysinfo_get();
memset(sysinfo, 0, sizeof(*sysinfo));
sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
sysinfo->phy_mem_desc_ptr =
cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
sysinfo->core_mask = octeon_bootinfo->core_mask;
sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
sysinfo->board_type = octeon_bootinfo->board_type;
sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
sizeof(sysinfo->mac_addr_base));
sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
memcpy(sysinfo->board_serial_number,
octeon_bootinfo->board_serial_number,
sizeof(sysinfo->board_serial_number));
sysinfo->compact_flash_common_base_addr =
octeon_bootinfo->compact_flash_common_base_addr;
sysinfo->compact_flash_attribute_base_addr =
octeon_bootinfo->compact_flash_attribute_base_addr;
sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
/* I/O clock runs at a different rate than the CPU. */
union cvmx_mio_rst_boot rst_boot;
rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
octeon_io_clock_rate = 50000000 * rst_boot.s.pnr_mul;
} else {
octeon_io_clock_rate = sysinfo->cpu_clock_hz;
}
/*
* Only enable the LED controller if we're running on a CN38XX, CN58XX,
* or CN56XX. The CN30XX and CN31XX don't have an LED controller.
......@@ -479,33 +533,6 @@ void __init prom_init(void)
}
#endif
sysinfo = cvmx_sysinfo_get();
memset(sysinfo, 0, sizeof(*sysinfo));
sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
sysinfo->phy_mem_desc_ptr =
cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
sysinfo->core_mask = octeon_bootinfo->core_mask;
sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
sysinfo->board_type = octeon_bootinfo->board_type;
sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
sizeof(sysinfo->mac_addr_base));
sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
memcpy(sysinfo->board_serial_number,
octeon_bootinfo->board_serial_number,
sizeof(sysinfo->board_serial_number));
sysinfo->compact_flash_common_base_addr =
octeon_bootinfo->compact_flash_common_base_addr;
sysinfo->compact_flash_attribute_base_addr =
octeon_bootinfo->compact_flash_attribute_base_addr;
sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
octeon_check_cpu_bist();
octeon_uart = octeon_get_boot_uart();
......@@ -740,6 +767,31 @@ EXPORT_SYMBOL(prom_putchar);
void prom_free_prom_memory(void)
{
if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) {
/* Check for presence of Core-14449 fix. */
u32 insn;
u32 *foo;
foo = &insn;
asm volatile("# before" : : : "memory");
prefetch(foo);
asm volatile(
".set push\n\t"
".set noreorder\n\t"
"bal 1f\n\t"
"nop\n"
"1:\tlw %0,-12($31)\n\t"
".set pop\n\t"
: "=r" (insn) : : "$31", "memory");
if ((insn >> 26) != 0x33)
panic("No PREF instruction at Core-14449 probe point.\n");
if (((insn >> 16) & 0x1f) != 28)
panic("Core-14449 WAR not in place (%04x).\n"
"Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).\n", insn);
}
#ifdef CONFIG_CAVIUM_DECODE_RSL
cvmx_interrupt_rsl_enable();
......
......@@ -64,18 +64,16 @@ static __inline__ void atomic_add(int i, atomic_t * v)
} else if (kernel_uses_llsc) {
int temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
do {
__asm__ __volatile__(
" .set mips3 \n"
" ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} while (unlikely(!temp));
} else {
unsigned long flags;
......@@ -109,18 +107,16 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
} else if (kernel_uses_llsc) {
int temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: ll %0, %1 # atomic_sub \n"
" subu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
do {
__asm__ __volatile__(
" .set mips3 \n"
" ll %0, %1 # atomic_sub \n"
" subu %0, %2 \n"
" sc %0, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} while (unlikely(!temp));
} else {
unsigned long flags;
......@@ -156,20 +152,19 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
} else if (kernel_uses_llsc) {
int temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: ll %1, %2 # atomic_add_return \n"
" addu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqz %0, 2f \n"
" addu %0, %1, %3 \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
do {
__asm__ __volatile__(
" .set mips3 \n"
" ll %1, %2 # atomic_add_return \n"
" addu %0, %1, %3 \n"
" sc %0, %2 \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
} while (unlikely(!result));
result = temp + i;
} else {
unsigned long flags;
......@@ -205,23 +200,24 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
result = temp - i;
} else if (kernel_uses_llsc) {
int temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: ll %1, %2 # atomic_sub_return \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" beqz %0, 2f \n"
" subu %0, %1, %3 \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
do {
__asm__ __volatile__(
" .set mips3 \n"
" ll %1, %2 # atomic_sub_return \n"
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
} while (unlikely(!result));
result = temp - i;
} else {
unsigned long flags;
......@@ -279,12 +275,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" bltz %0, 1f \n"
" sc %0, %2 \n"
" .set noreorder \n"
" beqz %0, 2f \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
" .set reorder \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
"1: \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
......@@ -443,18 +436,16 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
} else if (kernel_uses_llsc) {
long temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: lld %0, %1 # atomic64_add \n"
" daddu %0, %2 \n"
" scd %0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
do {
__asm__ __volatile__(
" .set mips3 \n"
" lld %0, %1 # atomic64_add \n"
" daddu %0, %2 \n"
" scd %0, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} while (unlikely(!temp));
} else {
unsigned long flags;
......@@ -488,18 +479,16 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
} else if (kernel_uses_llsc) {
long temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: lld %0, %1 # atomic64_sub \n"
" dsubu %0, %2 \n"
" scd %0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
do {
__asm__ __volatile__(
" .set mips3 \n"
" lld %0, %1 # atomic64_sub \n"
" dsubu %0, %2 \n"
" scd %0, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
} while (unlikely(!temp));
} else {
unsigned long flags;
......@@ -535,20 +524,19 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
} else if (kernel_uses_llsc) {
long temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: lld %1, %2 # atomic64_add_return \n"
" daddu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqz %0, 2f \n"
" daddu %0, %1, %3 \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
do {
__asm__ __volatile__(
" .set mips3 \n"
" lld %1, %2 # atomic64_add_return \n"
" daddu %0, %1, %3 \n"
" scd %0, %2 \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
} while (unlikely(!result));
result = temp + i;
} else {
unsigned long flags;
......@@ -587,20 +575,19 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
} else if (kernel_uses_llsc) {
long temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: lld %1, %2 # atomic64_sub_return \n"
" dsubu %0, %1, %3 \n"
" scd %0, %2 \n"
" beqz %0, 2f \n"
" dsubu %0, %1, %3 \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
do {
__asm__ __volatile__(
" .set mips3 \n"
" lld %1, %2 # atomic64_sub_return \n"
" dsubu %0, %1, %3 \n"
" scd %0, %2 \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
} while (unlikely(!result));
result = temp - i;
} else {
unsigned long flags;
......@@ -658,12 +645,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" bltz %0, 1f \n"
" scd %0, %2 \n"
" .set noreorder \n"
" beqz %0, 2f \n"
" beqz %0, 1b \n"
" dsubu %0, %1, %3 \n"
" .set reorder \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
"1: \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
......
......@@ -73,30 +73,26 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
: "ir" (1UL << bit), "m" (*m));
#ifdef CONFIG_CPU_MIPSR2
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
__asm__ __volatile__(
"1: " __LL "%0, %1 # set_bit \n"
" " __INS "%0, %4, %2, 1 \n"
" " __SC "%0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
: "=&r" (temp), "=m" (*m)
: "ir" (bit), "m" (*m), "r" (~0));
do {
__asm__ __volatile__(
" " __LL "%0, %1 # set_bit \n"
" " __INS "%0, %3, %2, 1 \n"
" " __SC "%0, %1 \n"
: "=&r" (temp), "+m" (*m)
: "ir" (bit), "r" (~0));
} while (unlikely(!temp));
#endif /* CONFIG_CPU_MIPSR2 */
} else if (kernel_uses_llsc) {
__asm__ __volatile__(
" .set mips3 \n"
"1: " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
" " __SC "%0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << bit), "m" (*m));
do {
__asm__ __volatile__(
" .set mips3 \n"
" " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
" " __SC "%0, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "+m" (*m)
: "ir" (1UL << bit));
} while (unlikely(!temp));
} else {
volatile unsigned long *a = addr;
unsigned long mask;
......@@ -134,34 +130,30 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (~(1UL << bit)), "m" (*m));
: "=&r" (temp), "+m" (*m)
: "ir" (~(1UL << bit)));
#ifdef CONFIG_CPU_MIPSR2
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
__asm__ __volatile__(
"1: " __LL "%0, %1 # clear_bit \n"
" " __INS "%0, $0, %2, 1 \n"
" " __SC "%0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
: "=&r" (temp), "=m" (*m)
: "ir" (bit), "m" (*m));
do {
__asm__ __volatile__(
" " __LL "%0, %1 # clear_bit \n"
" " __INS "%0, $0, %2, 1 \n"
" " __SC "%0, %1 \n"
: "=&r" (temp), "+m" (*m)
: "ir" (bit));
} while (unlikely(!temp));
#endif /* CONFIG_CPU_MIPSR2 */
} else if (kernel_uses_llsc) {
__asm__ __volatile__(
" .set mips3 \n"
"1: " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (~(1UL << bit)), "m" (*m));
do {
__asm__ __volatile__(
" .set mips3 \n"
" " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "+m" (*m)
: "ir" (~(1UL << bit)));
} while (unlikely(!temp));
} else {
volatile unsigned long *a = addr;
unsigned long mask;
......@@ -213,24 +205,22 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
" " __SC "%0, %1 \n"
" beqzl %0, 1b \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << bit), "m" (*m));
: "=&r" (temp), "+m" (*m)
: "ir" (1UL << bit));
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set mips3 \n"
"1: " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
" " __SC "%0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m)
: "ir" (1UL << bit), "m" (*m));
do {
__asm__ __volatile__(
" .set mips3 \n"
" " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
" " __SC "%0, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "+m" (*m)
: "ir" (1UL << bit));
} while (unlikely(!temp));
} else {
volatile unsigned long *a = addr;
unsigned long mask;
......@@ -272,30 +262,26 @@ static inline int test_and_set_bit(unsigned long nr,
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << bit), "m" (*m)
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: "memory");
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set noreorder \n"
" .set mips3 \n"
"1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqz %2, 2f \n"
" and %2, %0, %3 \n"
" .subsection 2 \n"
"2: b 1b \n"
" nop \n"
" .previous \n"
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << bit), "m" (*m)
: "memory");
do {
__asm__ __volatile__(
" .set mips3 \n"
" " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: "memory");
} while (unlikely(!res));
res = temp & (1UL << bit);
} else {
volatile unsigned long *a = addr;
unsigned long mask;
......@@ -340,30 +326,26 @@ static inline int test_and_set_bit_lock(unsigned long nr,
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << bit), "m" (*m)
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: "memory");
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set noreorder \n"
" .set mips3 \n"
"1: " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" beqz %2, 2f \n"
" and %2, %0, %3 \n"
" .subsection 2 \n"
"2: b 1b \n"
" nop \n"
" .previous \n"
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << bit), "m" (*m)
: "memory");
do {
__asm__ __volatile__(
" .set mips3 \n"
" " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: "memory");
} while (unlikely(!res));
res = temp & (1UL << bit);
} else {
volatile unsigned long *a = addr;
unsigned long mask;
......@@ -410,49 +392,43 @@ static inline int test_and_clear_bit(unsigned long nr,
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << bit), "m" (*m)
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: "memory");
#ifdef CONFIG_CPU_MIPSR2
} else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
"1: " __LL "%0, %1 # test_and_clear_bit \n"
" " __EXT "%2, %0, %3, 1 \n"
" " __INS "%0, $0, %3, 1 \n"
" " __SC "%0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "ir" (bit), "m" (*m)
: "memory");
do {
__asm__ __volatile__(
" " __LL "%0, %1 # test_and_clear_bit \n"
" " __EXT "%2, %0, %3, 1 \n"
" " __INS "%0, $0, %3, 1 \n"
" " __SC "%0, %1 \n"
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "ir" (bit)
: "memory");
} while (unlikely(!temp));
#endif
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set noreorder \n"
" .set mips3 \n"
"1: " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
" " __SC "%2, %1 \n"
" beqz %2, 2f \n"
" and %2, %0, %3 \n"
" .subsection 2 \n"
"2: b 1b \n"
" nop \n"
" .previous \n"
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << bit), "m" (*m)
: "memory");
do {
__asm__ __volatile__(
" .set mips3 \n"
" " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
" " __SC "%2, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: "memory");
} while (unlikely(!res));
res = temp & (1UL << bit);
} else {
volatile unsigned long *a = addr;
unsigned long mask;
......@@ -499,30 +475,26 @@ static inline int test_and_change_bit(unsigned long nr,
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << bit), "m" (*m)
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: "memory");
} else if (kernel_uses_llsc) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
__asm__ __volatile__(
" .set push \n"
" .set noreorder \n"
" .set mips3 \n"
"1: " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
" " __SC "\t%2, %1 \n"
" beqz %2, 2f \n"
" and %2, %0, %3 \n"
" .subsection 2 \n"
"2: b 1b \n"
" nop \n"
" .previous \n"
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << bit), "m" (*m)
: "memory");
do {
__asm__ __volatile__(
" .set mips3 \n"
" " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
" " __SC "\t%2, %1 \n"
" .set mips0 \n"
: "=&r" (temp), "+m" (*m), "=&r" (res)
: "r" (1UL << bit)
: "memory");
} while (unlikely(!res));
res = temp & (1UL << bit);
} else {
volatile unsigned long *a = addr;
unsigned long mask;
......
......@@ -125,4 +125,16 @@ extern unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
*/
extern void plat_mem_setup(void);
#ifdef CONFIG_SWIOTLB
/*
* Optional platform hook to call swiotlb_setup().
*/
extern void plat_swiotlb_setup(void);
#else
static inline void plat_swiotlb_setup(void) {}
#endif /* CONFIG_SWIOTLB */
#endif /* _ASM_BOOTINFO_H */
......@@ -44,12 +44,9 @@
" move $1, %z4 \n" \
" .set mips3 \n" \
" " st " $1, %1 \n" \
" beqz $1, 3f \n" \
"2: \n" \
" .subsection 2 \n" \
"3: b 1b \n" \
" .previous \n" \
" beqz $1, 1b \n" \
" .set pop \n" \
"2: \n" \
: "=&r" (__ret), "=R" (*m) \
: "R" (*m), "Jr" (old), "Jr" (new) \
: "memory"); \
......
......@@ -111,14 +111,16 @@
* These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
*/
#define PRID_IMP_BCM4710 0x4000
#define PRID_IMP_BCM3302 0x9000
#define PRID_IMP_BCM6338 0x9000
#define PRID_IMP_BCM6345 0x8000
#define PRID_IMP_BCM6348 0x9100
#define PRID_IMP_BCM4350 0xA000
#define PRID_REV_BCM6358 0x0010
#define PRID_REV_BCM6368 0x0030
#define PRID_IMP_BMIPS4KC 0x4000
#define PRID_IMP_BMIPS32 0x8000
#define PRID_IMP_BMIPS3300 0x9000
#define PRID_IMP_BMIPS3300_ALT 0x9100
#define PRID_IMP_BMIPS3300_BUG 0x0000
#define PRID_IMP_BMIPS43XX 0xa000
#define PRID_IMP_BMIPS5000 0x5a00
#define PRID_REV_BMIPS4380_LO 0x0040
#define PRID_REV_BMIPS4380_HI 0x006f
/*
* These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
......@@ -131,6 +133,7 @@
#define PRID_IMP_CAVIUM_CN56XX 0x0400
#define PRID_IMP_CAVIUM_CN50XX 0x0600
#define PRID_IMP_CAVIUM_CN52XX 0x0700
#define PRID_IMP_CAVIUM_CN63XX 0x9000
/*
* These are the PRID's for when 23:16 == PRID_COMP_INGENIC
......@@ -223,15 +226,14 @@ enum cpu_type_enum {
* MIPS32 class processors
*/
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358,
CPU_JZRISC,
CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC,
/*
* MIPS64 class processors
*/
CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
CPU_LAST
};
......
......@@ -3,4 +3,17 @@
*
* This file is released under the GPLv2
*/
#include <asm-generic/device.h>
#ifndef _ASM_MIPS_DEVICE_H
#define _ASM_MIPS_DEVICE_H
struct dma_map_ops;
struct dev_archdata {
/* DMA operations on that device */
struct dma_map_ops *dma_ops;
};
struct pdev_archdata {
};
#endif /* _ASM_MIPS_DEVICE_H*/
......@@ -5,51 +5,41 @@
#include <asm/cache.h>
#include <asm-generic/dma-coherent.h>
void *dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
#include <dma-coherence.h>
void dma_free_noncoherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
extern struct dma_map_ops *mips_dma_map_ops;
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
if (dev && dev->archdata.dma_ops)
return dev->archdata.dma_ops;
else
return mips_dma_map_ops;
}
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
return 0;
extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction);
extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction);
extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction);
extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction direction);
static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
size_t size, enum dma_data_direction direction)
return addr + size <= *dev->dma_mask;
}
static inline void dma_mark_clean(void *addr, size_t size) {}
#include <asm-generic/dma-mapping-common.h>
static inline int dma_supported(struct device *dev, u64 mask)
{
dma_unmap_single(dev, dma_address, size, direction);
struct dma_map_ops *ops = get_dma_ops(dev);
return ops->dma_supported(dev, mask);
}
extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction direction);
extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction direction);
extern void dma_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size, enum dma_data_direction direction);
extern void dma_sync_single_range_for_cpu(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction);
extern void dma_sync_single_range_for_device(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction);
extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
int nelems, enum dma_data_direction direction);
extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
int nelems, enum dma_data_direction direction);
extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
extern int dma_supported(struct device *dev, u64 mask);
static inline int dma_mapping_error(struct device *dev, u64 mask)
{
struct dma_map_ops *ops = get_dma_ops(dev);
return ops->mapping_error(dev, mask);
}
static inline int
dma_set_mask(struct device *dev, u64 mask)
......@@ -65,4 +55,34 @@ dma_set_mask(struct device *dev, u64 mask)
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
struct dma_map_ops *ops = get_dma_ops(dev);
ret = ops->alloc_coherent(dev, size, dma_handle, gfp);
debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
return ret;
}
static inline void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
struct dma_map_ops *ops = get_dma_ops(dev);
ops->free_coherent(dev, size, vaddr, dma_handle);
debug_dma_free_coherent(dev, size, vaddr, dma_handle);
}
void *dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
void dma_free_noncoherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
#endif /* _ASM_DMA_MAPPING_H */
......@@ -91,7 +91,10 @@
#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000)
#endif
#define MAX_DMA_PFN PFN_DOWN(virt_to_phys((void *)MAX_DMA_ADDRESS))
#ifndef MAX_DMA32_PFN
#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT))
#endif
/* 8237 DMA controllers */
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
......
......@@ -117,7 +117,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
#define local_cmpxchg(l, o, n) \
((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
/**
* local_add_unless - add unless the number is a given value
......
......@@ -39,6 +39,7 @@
#define AR7_REGS_UART0 (AR7_REGS_BASE + 0x0e00)
#define AR7_REGS_USB (AR7_REGS_BASE + 0x1200)
#define AR7_REGS_RESET (AR7_REGS_BASE + 0x1600)
#define AR7_REGS_PINSEL (AR7_REGS_BASE + 0x160C)
#define AR7_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1800)
#define AR7_REGS_DCL (AR7_REGS_BASE + 0x1a00)
#define AR7_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1c00)
......@@ -50,6 +51,14 @@
#define UR8_REGS_WDT (AR7_REGS_BASE + 0x0b00)
#define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00)
/* Titan registers */
#define TITAN_REGS_ESWITCH_BASE (0x08640000)
#define TITAN_REGS_MAC0 (TITAN_REGS_ESWITCH_BASE)
#define TITAN_REGS_MAC1 (TITAN_REGS_ESWITCH_BASE + 0x0800)
#define TITAN_REGS_MDIO (TITAN_REGS_ESWITCH_BASE + 0x02000)
#define TITAN_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1c00)
#define TITAN_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1300)
#define AR7_RESET_PERIPHERAL 0x0
#define AR7_RESET_SOFTWARE 0x4
#define AR7_RESET_STATUS 0x8
......@@ -59,15 +68,30 @@
#define AR7_RESET_BIT_MDIO 22
#define AR7_RESET_BIT_EPHY 26
#define TITAN_RESET_BIT_EPHY1 28
/* GPIO control registers */
#define AR7_GPIO_INPUT 0x0
#define AR7_GPIO_OUTPUT 0x4
#define AR7_GPIO_DIR 0x8
#define AR7_GPIO_ENABLE 0xc
#define TITAN_GPIO_INPUT_0 0x0
#define TITAN_GPIO_INPUT_1 0x4
#define TITAN_GPIO_OUTPUT_0 0x8
#define TITAN_GPIO_OUTPUT_1 0xc
#define TITAN_GPIO_DIR_0 0x10
#define TITAN_GPIO_DIR_1 0x14
#define TITAN_GPIO_ENBL_0 0x18
#define TITAN_GPIO_ENBL_1 0x1c
#define AR7_CHIP_7100 0x18
#define AR7_CHIP_7200 0x2b
#define AR7_CHIP_7300 0x05
#define AR7_CHIP_TITAN 0x07
#define TITAN_CHIP_1050 0x0f
#define TITAN_CHIP_1055 0x0e
#define TITAN_CHIP_1056 0x0d
#define TITAN_CHIP_1060 0x07
/* Interrupts */
#define AR7_IRQ_UART0 15
......@@ -95,14 +119,29 @@ struct plat_dsl_data {
extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock;
static inline int ar7_is_titan(void)
{
return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x24)) & 0xffff) ==
AR7_CHIP_TITAN;
}
static inline u16 ar7_chip_id(void)
{
return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff;
return ar7_is_titan() ? AR7_CHIP_TITAN : (readl((void *)
KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff);
}
static inline u16 titan_chip_id(void)
{
unsigned int val = readl((void *)KSEG1ADDR(AR7_REGS_GPIO +
TITAN_GPIO_INPUT_1));
return ((val >> 12) & 0x0f);
}
static inline u8 ar7_chip_rev(void)
{
return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff;
return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + (ar7_is_titan() ? 0x24 :
0x14))) >> 16) & 0xff;
}
struct clk {
......@@ -161,4 +200,8 @@ static inline void ar7_device_off(u32 bit)
msleep(20);
}
int __init ar7_gpio_init(void);
int __init ar7_gpio_init(void);
#endif /* __AR7_H__ */
......@@ -22,7 +22,8 @@
#include <asm/mach-ar7/ar7.h>
#define AR7_GPIO_MAX 32
#define NR_BUILTIN_GPIO AR7_GPIO_MAX
#define TITAN_GPIO_MAX 51
#define NR_BUILTIN_GPIO TITAN_GPIO_MAX
#define gpio_to_irq(gpio) -1
......
......@@ -59,7 +59,7 @@
#define cpu_has_veic 0
#define cpu_hwrena_impl_bits 0xc0000000
#define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS)
#define kernel_uses_smartmips_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
#define ARCH_HAS_IRQ_PER_CPU 1
#define ARCH_HAS_SPINLOCK_PREFETCH 1
......@@ -81,4 +81,10 @@ static inline int octeon_has_saa(void)
return id >= 0x000d0300;
}
/*
* The last 256MB are reserved for device to device mappings and the
* BAR1 hole.
*/
#define MAX_DMA32_PFN (((1ULL << 32) - (1ULL << 28)) >> PAGE_SHIFT)
#endif
......@@ -15,41 +15,40 @@
struct device;
dma_addr_t octeon_map_dma_mem(struct device *, void *, size_t);
void octeon_unmap_dma_mem(struct device *, dma_addr_t);
extern void octeon_pci_dma_init(void);
static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
size_t size)
{
return octeon_map_dma_mem(dev, addr, size);
BUG();
}
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
struct page *page)
{
return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
BUG();
}
static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
return dma_addr;
BUG();
}
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction)
{
octeon_unmap_dma_mem(dev, dma_addr);
BUG();
}
static inline int plat_dma_supported(struct device *dev, u64 mask)
{
return 1;
BUG();
}
static inline void plat_extra_sync_for_device(struct device *dev)
{
mb();
BUG();
}
static inline int plat_device_is_coherent(struct device *dev)
......@@ -60,7 +59,14 @@ static inline int plat_device_is_coherent(struct device *dev)
static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr)
{
return dma_addr == -1;
BUG();
}
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
struct dma_map_ops;
extern struct dma_map_ops *octeon_pci_dma_map_ops;
extern char *octeon_swiotlb;
#endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
......@@ -26,14 +26,15 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
return pa;
}
static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
struct page *page)
{
dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));
return pa;
}
static unsigned long plat_dma_addr_to_phys(struct device *dev,
static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
return dma_addr & ~(0xffUL << 56);
......
......@@ -37,7 +37,8 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
return pa;
}
static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
struct page *page)
{
dma_addr_t pa;
......@@ -50,7 +51,7 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
}
/* This is almost certainly wrong but it's what dma-ip32.c used to use */
static unsigned long plat_dma_addr_to_phys(struct device *dev,
static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
unsigned long addr = dma_addr & RAM_OFFSET_MASK;
......
......@@ -12,23 +12,24 @@
struct device;
static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
{
return vdma_alloc(virt_to_phys(addr), size);
}
static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
struct page *page)
{
return vdma_alloc(page_to_phys(page), PAGE_SIZE);
}
static unsigned long plat_dma_addr_to_phys(struct device *dev,
static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
return vdma_log2phys(dma_addr);
}
static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction)
{
vdma_free(dma_addr);
......
......@@ -1040,6 +1040,12 @@ do { \
#define read_c0_dtaglo() __read_32bit_c0_register($28, 2)
#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val)
#define read_c0_ddatalo() __read_32bit_c0_register($28, 3)
#define write_c0_ddatalo(val) __write_32bit_c0_register($28, 3, val)
#define read_c0_staglo() __read_32bit_c0_register($28, 4)
#define write_c0_staglo(val) __write_32bit_c0_register($28, 4, val)
#define read_c0_taghi() __read_32bit_c0_register($29, 0)
#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val)
......@@ -1082,6 +1088,51 @@ do { \
#define read_octeon_c0_dcacheerr() __read_64bit_c0_register($27, 1)
#define write_octeon_c0_dcacheerr(val) __write_64bit_c0_register($27, 1, val)
/* BMIPS3300 */
#define read_c0_brcm_config_0() __read_32bit_c0_register($22, 0)
#define write_c0_brcm_config_0(val) __write_32bit_c0_register($22, 0, val)
#define read_c0_brcm_bus_pll() __read_32bit_c0_register($22, 4)
#define write_c0_brcm_bus_pll(val) __write_32bit_c0_register($22, 4, val)
#define read_c0_brcm_reset() __read_32bit_c0_register($22, 5)
#define write_c0_brcm_reset(val) __write_32bit_c0_register($22, 5, val)
/* BMIPS4380 */
#define read_c0_brcm_cmt_intr() __read_32bit_c0_register($22, 1)
#define write_c0_brcm_cmt_intr(val) __write_32bit_c0_register($22, 1, val)
#define read_c0_brcm_cmt_ctrl() __read_32bit_c0_register($22, 2)
#define write_c0_brcm_cmt_ctrl(val) __write_32bit_c0_register($22, 2, val)
#define read_c0_brcm_cmt_local() __read_32bit_c0_register($22, 3)
#define write_c0_brcm_cmt_local(val) __write_32bit_c0_register($22, 3, val)
#define read_c0_brcm_config_1() __read_32bit_c0_register($22, 5)
#define write_c0_brcm_config_1(val) __write_32bit_c0_register($22, 5, val)
#define read_c0_brcm_cbr() __read_32bit_c0_register($22, 6)
#define write_c0_brcm_cbr(val) __write_32bit_c0_register($22, 6, val)
/* BMIPS5000 */
#define read_c0_brcm_config() __read_32bit_c0_register($22, 0)
#define write_c0_brcm_config(val) __write_32bit_c0_register($22, 0, val)
#define read_c0_brcm_mode() __read_32bit_c0_register($22, 1)
#define write_c0_brcm_mode(val) __write_32bit_c0_register($22, 1, val)
#define read_c0_brcm_action() __read_32bit_c0_register($22, 2)
#define write_c0_brcm_action(val) __write_32bit_c0_register($22, 2, val)
#define read_c0_brcm_edsp() __read_32bit_c0_register($22, 3)
#define write_c0_brcm_edsp(val) __write_32bit_c0_register($22, 3, val)
#define read_c0_brcm_bootvec() __read_32bit_c0_register($22, 4)
#define write_c0_brcm_bootvec(val) __write_32bit_c0_register($22, 4, val)
#define read_c0_brcm_sleepcount() __read_32bit_c0_register($22, 7)
#define write_c0_brcm_sleepcount(val) __write_32bit_c0_register($22, 7, val)
/*
* Macros to access the floating point coprocessor control registers
*/
......
......@@ -114,6 +114,17 @@
#define CVMX_DCACHE_INVALIDATE \
{ CVMX_SYNC; asm volatile ("cache 9, 0($0)" : : ); }
#define CVMX_CACHE(op, address, offset) \
asm volatile ("cache " CVMX_TMP_STR(op) ", " CVMX_TMP_STR(offset) "(%[rbase])" \
: : [rbase] "d" (address) )
/* fetch and lock the state. */
#define CVMX_CACHE_LCKL2(address, offset) CVMX_CACHE(31, address, offset)
/* unlock the state. */
#define CVMX_CACHE_WBIL2(address, offset) CVMX_CACHE(23, address, offset)
/* invalidate the cache block and clear the USED bits for the block */
#define CVMX_CACHE_WBIL2I(address, offset) CVMX_CACHE(3, address, offset)
/* load virtual tag and data for the L2 cache block into L2C_TAD0_TAG register */
#define CVMX_CACHE_LTGL2I(address, offset) CVMX_CACHE(7, address, offset)
#define CVMX_POP(result, input) \
asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
......
......@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
* Copyright (c) 2003-2010 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
......@@ -28,29 +28,22 @@
#ifndef __CVMX_GPIO_DEFS_H__
#define __CVMX_GPIO_DEFS_H__
#define CVMX_GPIO_BIT_CFGX(offset) \
CVMX_ADD_IO_SEG(0x0001070000000800ull + (((offset) & 15) * 8))
#define CVMX_GPIO_BOOT_ENA \
CVMX_ADD_IO_SEG(0x00010700000008A8ull)
#define CVMX_GPIO_CLK_GENX(offset) \
CVMX_ADD_IO_SEG(0x00010700000008C0ull + (((offset) & 3) * 8))
#define CVMX_GPIO_DBG_ENA \
CVMX_ADD_IO_SEG(0x00010700000008A0ull)
#define CVMX_GPIO_INT_CLR \
CVMX_ADD_IO_SEG(0x0001070000000898ull)
#define CVMX_GPIO_RX_DAT \
CVMX_ADD_IO_SEG(0x0001070000000880ull)
#define CVMX_GPIO_TX_CLR \
CVMX_ADD_IO_SEG(0x0001070000000890ull)
#define CVMX_GPIO_TX_SET \
CVMX_ADD_IO_SEG(0x0001070000000888ull)
#define CVMX_GPIO_XBIT_CFGX(offset) \
CVMX_ADD_IO_SEG(0x0001070000000900ull + (((offset) & 31) * 8) - 8 * 16)
#define CVMX_GPIO_BIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000800ull) + ((offset) & 15) * 8)
#define CVMX_GPIO_BOOT_ENA (CVMX_ADD_IO_SEG(0x00010700000008A8ull))
#define CVMX_GPIO_CLK_GENX(offset) (CVMX_ADD_IO_SEG(0x00010700000008C0ull) + ((offset) & 3) * 8)
#define CVMX_GPIO_CLK_QLMX(offset) (CVMX_ADD_IO_SEG(0x00010700000008E0ull) + ((offset) & 1) * 8)
#define CVMX_GPIO_DBG_ENA (CVMX_ADD_IO_SEG(0x00010700000008A0ull))
#define CVMX_GPIO_INT_CLR (CVMX_ADD_IO_SEG(0x0001070000000898ull))
#define CVMX_GPIO_RX_DAT (CVMX_ADD_IO_SEG(0x0001070000000880ull))
#define CVMX_GPIO_TX_CLR (CVMX_ADD_IO_SEG(0x0001070000000890ull))
#define CVMX_GPIO_TX_SET (CVMX_ADD_IO_SEG(0x0001070000000888ull))
#define CVMX_GPIO_XBIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000900ull) + ((offset) & 31) * 8 - 8*16)
union cvmx_gpio_bit_cfgx {
uint64_t u64;
struct cvmx_gpio_bit_cfgx_s {
uint64_t reserved_15_63:49;
uint64_t reserved_17_63:47;
uint64_t synce_sel:2;
uint64_t clk_gen:1;
uint64_t clk_sel:2;
uint64_t fil_sel:4;
......@@ -73,12 +66,24 @@ union cvmx_gpio_bit_cfgx {
struct cvmx_gpio_bit_cfgx_cn30xx cn38xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2;
struct cvmx_gpio_bit_cfgx_cn30xx cn50xx;
struct cvmx_gpio_bit_cfgx_s cn52xx;
struct cvmx_gpio_bit_cfgx_s cn52xxp1;
struct cvmx_gpio_bit_cfgx_s cn56xx;
struct cvmx_gpio_bit_cfgx_s cn56xxp1;
struct cvmx_gpio_bit_cfgx_cn52xx {
uint64_t reserved_15_63:49;
uint64_t clk_gen:1;
uint64_t clk_sel:2;
uint64_t fil_sel:4;
uint64_t fil_cnt:4;
uint64_t int_type:1;
uint64_t int_en:1;
uint64_t rx_xor:1;
uint64_t tx_oe:1;
} cn52xx;
struct cvmx_gpio_bit_cfgx_cn52xx cn52xxp1;
struct cvmx_gpio_bit_cfgx_cn52xx cn56xx;
struct cvmx_gpio_bit_cfgx_cn52xx cn56xxp1;
struct cvmx_gpio_bit_cfgx_cn30xx cn58xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1;
struct cvmx_gpio_bit_cfgx_s cn63xx;
struct cvmx_gpio_bit_cfgx_s cn63xxp1;
};
union cvmx_gpio_boot_ena {
......@@ -103,6 +108,19 @@ union cvmx_gpio_clk_genx {
struct cvmx_gpio_clk_genx_s cn52xxp1;
struct cvmx_gpio_clk_genx_s cn56xx;
struct cvmx_gpio_clk_genx_s cn56xxp1;
struct cvmx_gpio_clk_genx_s cn63xx;
struct cvmx_gpio_clk_genx_s cn63xxp1;
};
union cvmx_gpio_clk_qlmx {
uint64_t u64;
struct cvmx_gpio_clk_qlmx_s {
uint64_t reserved_3_63:61;
uint64_t div:1;
uint64_t lane_sel:2;
} s;
struct cvmx_gpio_clk_qlmx_s cn63xx;
struct cvmx_gpio_clk_qlmx_s cn63xxp1;
};
union cvmx_gpio_dbg_ena {
......@@ -133,6 +151,8 @@ union cvmx_gpio_int_clr {
struct cvmx_gpio_int_clr_s cn56xxp1;
struct cvmx_gpio_int_clr_s cn58xx;
struct cvmx_gpio_int_clr_s cn58xxp1;
struct cvmx_gpio_int_clr_s cn63xx;
struct cvmx_gpio_int_clr_s cn63xxp1;
};
union cvmx_gpio_rx_dat {
......@@ -155,6 +175,8 @@ union cvmx_gpio_rx_dat {
struct cvmx_gpio_rx_dat_cn38xx cn56xxp1;
struct cvmx_gpio_rx_dat_cn38xx cn58xx;
struct cvmx_gpio_rx_dat_cn38xx cn58xxp1;
struct cvmx_gpio_rx_dat_cn38xx cn63xx;
struct cvmx_gpio_rx_dat_cn38xx cn63xxp1;
};
union cvmx_gpio_tx_clr {
......@@ -177,6 +199,8 @@ union cvmx_gpio_tx_clr {
struct cvmx_gpio_tx_clr_cn38xx cn56xxp1;
struct cvmx_gpio_tx_clr_cn38xx cn58xx;
struct cvmx_gpio_tx_clr_cn38xx cn58xxp1;
struct cvmx_gpio_tx_clr_cn38xx cn63xx;
struct cvmx_gpio_tx_clr_cn38xx cn63xxp1;
};
union cvmx_gpio_tx_set {
......@@ -199,6 +223,8 @@ union cvmx_gpio_tx_set {
struct cvmx_gpio_tx_set_cn38xx cn56xxp1;
struct cvmx_gpio_tx_set_cn38xx cn58xx;
struct cvmx_gpio_tx_set_cn38xx cn58xxp1;
struct cvmx_gpio_tx_set_cn38xx cn63xx;
struct cvmx_gpio_tx_set_cn38xx cn63xxp1;
};
union cvmx_gpio_xbit_cfgx {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -35,6 +35,7 @@ extern int octeon_is_simulation(void);
extern int octeon_is_pci_host(void);
extern int octeon_usb_is_ref_clk(void);
extern uint64_t octeon_get_clock_rate(void);
extern u64 octeon_get_io_clock_rate(void);
extern const char *octeon_board_type_string(void);
extern const char *octeon_get_pci_interrupts(void);
extern int octeon_get_southbridge_interrupt(void);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -34,3 +34,4 @@ obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment