From 4eaa276df12bdec097fcf782cb242afacf51705a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Mon, 2 Dec 2013 21:12:58 +0800 Subject: [PATCH] ARM: rockchip: add rk3188.c, common.c, remove rockchip.c --- arch/arm/boot/dts/rk3188.dtsi | 65 ++++++++++ arch/arm/mach-rockchip/Makefile | 3 +- arch/arm/mach-rockchip/common.c | 111 ++++++++++++++++++ arch/arm/mach-rockchip/cpu_axi.h | 41 +++++++ .../mach-rockchip/{rockchip.c => rk3188.c} | 37 +++--- 5 files changed, 235 insertions(+), 22 deletions(-) create mode 100644 arch/arm/mach-rockchip/common.c create mode 100644 arch/arm/mach-rockchip/cpu_axi.h rename arch/arm/mach-rockchip/{rockchip.c => rk3188.c} (60%) diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index b6a1a740ef75..26b05e08aa82 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -53,6 +53,71 @@ cache-level = <2>; arm,tag-latency = <1 1 1>; arm,data-latency = <2 3 1>; + prefetch-ctrl = <0x70000003>; + /* L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN */ + power-ctrl = <0x3>; +/* + (0x1 << 0) | // Full line of write zero behavior Enabled + (0x1 << 25) | // Round-robin replacement + (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) | + (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) | + (0x1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT) +*/ + aux-ctrl = <0x72000001 (~0x72000001)>; + }; + + cpu_axi_bus: cpu_axi_bus@10128000 { + compatible = "rockchip,cpu_axi_bus"; + reg = <0x10128000 0x8000>; + qos { + dmac { + offset = <0x1000>; + priority = <0 0>; + }; + cpu0 { + offset = <0x2000>; + priority = <0 0>; + }; + cpu1r { + offset = <0x2080>; + priority = <0 0>; + }; + cpu1w { + offset = <0x2100>; + priority = <0 0>; + }; + peri { + offset = <0x4000>; + priority = <2 2>; + }; + gpu { + offset = <0x5000>; + priority = <2 1>; + }; + vpu { + offset = <0x6000>; + }; + vop0 { + offset = <0x7000>; + priority = <3 3>; + }; + cif0 { + offset = <0x7080>; + }; + ipp { + offset = <0x7100>; + }; + vop1 { + offset = <0x7180>; + priority = <3 3>; + }; + cif1 { + offset = <0x7200>; + }; + rga { + offset = <0x7280>; + }; + }; }; bootrom@10120000 { diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 3bd6ba0ec95e..7cb3156ff216 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -1,2 +1,3 @@ -obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o +obj-y += common.o +obj-y += rk3188.o obj-$(CONFIG_SMP) += platsmp.o diff --git a/arch/arm/mach-rockchip/common.c b/arch/arm/mach-rockchip/common.c new file mode 100644 index 000000000000..83ab47f9808b --- /dev/null +++ b/arch/arm/mach-rockchip/common.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2013 ROCKCHIP, Inc. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "cpu_axi.h" + +static int __init rockchip_cpu_axi_init(void) +{ + struct device_node *np, *cp; + void __iomem *base, *cbase; + + np = of_find_compatible_node(NULL, NULL, "rockchip,cpu_axi_bus"); + if (!np) + return -ENODEV; + + base = of_iomap(np, 0); + + np = of_get_child_by_name(np, "qos"); + if (np) { + for_each_child_of_node(np, cp) { + u32 offset, priority[2], mode, bandwidth, saturation; + if (of_property_read_u32(cp, "offset", &offset)) + continue; + pr_debug("qos: %s offset %x\n", cp->name, offset); + cbase = base + offset; + if (!of_property_read_u32_array(cp, "priority", priority, ARRAY_SIZE(priority))) { + CPU_AXI_SET_QOS_PRIORITY(priority[0], priority[1], cbase); + pr_debug("qos: %s priority %x %x\n", cp->name, priority[0], priority[1]); + } + if (!of_property_read_u32(cp, "mode", &mode)) { + CPU_AXI_SET_QOS_MODE(mode, cbase); + pr_debug("qos: %s mode %x\n", cp->name, mode); + } + if (!of_property_read_u32(cp, "bandwidth", &bandwidth)) { + CPU_AXI_SET_QOS_BANDWIDTH(bandwidth, cbase); + pr_debug("qos: %s bandwidth %x\n", cp->name, bandwidth); + } + if (!of_property_read_u32(cp, "saturation", &saturation)) { + CPU_AXI_SET_QOS_SATURATION(saturation, cbase); + pr_debug("qos: %s saturation %x\n", cp->name, saturation); + } + } + }; + + writel_relaxed(0x3f, base + 0x0014); // memory scheduler read latency + dsb(); + + iounmap(base); + + return 0; +} +early_initcall(rockchip_cpu_axi_init); + +static const struct of_device_id pl330_ids[] __initconst = { + { .compatible = "arm,pl310-cache" }, + {} +}; + +static int __init rockchip_pl330_l2_cache_init(void) +{ + struct device_node *np; + void __iomem *base; + u32 aux[2] = { 0, ~0 }, prefetch, power; + + np = of_find_matching_node(NULL, pl330_ids); + if (!np) + return -ENODEV; + + base = of_iomap(np, 0); + if (!base) + return -EINVAL; + + if (!of_property_read_u32(np, "prefetch-ctrl", &prefetch)) { + /* L2X0 Prefetch Control */ + writel_relaxed(prefetch, base + L2X0_PREFETCH_CTRL); + pr_debug("l2c: prefetch %x\n", prefetch); + } + + if (!of_property_read_u32(np, "power-ctrl", &power)) { + /* L2X0 Power Control */ + writel_relaxed(power, base + L2X0_POWER_CTRL); + pr_debug("l2c: power %x\n", power); + } + + iounmap(base); + + of_property_read_u32_array(np, "aux-ctrl", aux, ARRAY_SIZE(aux)); + pr_debug("l2c: aux %08x mask %08x\n", aux[0], aux[1]); + + l2x0_of_init(aux[0], aux[1]); + + return 0; +} +early_initcall(rockchip_pl330_l2_cache_init); diff --git a/arch/arm/mach-rockchip/cpu_axi.h b/arch/arm/mach-rockchip/cpu_axi.h new file mode 100644 index 000000000000..0523be5a4557 --- /dev/null +++ b/arch/arm/mach-rockchip/cpu_axi.h @@ -0,0 +1,41 @@ +#ifndef __CPU_AXI_H +#define __CPU_AXI_H + +#define CPU_AXI_QOS_PRIORITY 0x08 +#define CPU_AXI_QOS_MODE 0x0c +#define CPU_AXI_QOS_BANDWIDTH 0x10 +#define CPU_AXI_QOS_SATURATION 0x14 + +#define CPU_AXI_QOS_MODE_NONE 0 +#define CPU_AXI_QOS_MODE_FIXED 1 +#define CPU_AXI_QOS_MODE_LIMITER 2 +#define CPU_AXI_QOS_MODE_REGULATOR 3 + +#define CPU_AXI_QOS_PRIORITY_LEVEL(h, l) ((((h) & 3) << 2) | ((l) & 3)) +#define CPU_AXI_SET_QOS_PRIORITY(h, l, base) \ + writel_relaxed(CPU_AXI_QOS_PRIORITY_LEVEL(h, l), base + CPU_AXI_QOS_PRIORITY) + +#define CPU_AXI_SET_QOS_MODE(mode, base) \ + writel_relaxed((mode) & 3, base + CPU_AXI_QOS_MODE) + +#define CPU_AXI_SET_QOS_BANDWIDTH(bandwidth, base) \ + writel_relaxed((bandwidth) & 0x7ff, base + CPU_AXI_QOS_BANDWIDTH) + +#define CPU_AXI_SET_QOS_SATURATION(saturation, base) \ + writel_relaxed((saturation) & 0x3ff, base + CPU_AXI_QOS_SATURATION) + +#define CPU_AXI_QOS_NUM_REGS 4 +#define CPU_AXI_SAVE_QOS(array, base) do { \ + array[0] = readl_relaxed(base + CPU_AXI_QOS_PRIORITY); \ + array[1] = readl_relaxed(base + CPU_AXI_QOS_MODE); \ + array[2] = readl_relaxed(base + CPU_AXI_QOS_BANDWIDTH); \ + array[3] = readl_relaxed(base + CPU_AXI_QOS_SATURATION); \ +} while (0) +#define CPU_AXI_RESTORE_QOS(array, base) do { \ + writel_relaxed(array[0], base + CPU_AXI_QOS_PRIORITY); \ + writel_relaxed(array[1], base + CPU_AXI_QOS_MODE); \ + writel_relaxed(array[2], base + CPU_AXI_QOS_BANDWIDTH); \ + writel_relaxed(array[3], base + CPU_AXI_QOS_SATURATION); \ +} while (0) + +#endif diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rk3188.c similarity index 60% rename from arch/arm/mach-rockchip/rockchip.c rename to arch/arm/mach-rockchip/rk3188.c index d96ee44b3b98..16ebe854d349 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rk3188.c @@ -1,9 +1,7 @@ /* - * Device Tree support for Rockchip SoCs + * Device Tree support for Rockchip RK3188 * * Copyright (C) 2013 ROCKCHIP, Inc. - * Copyright (c) 2013 MundoReader S.L. - * Author: Heiko Stuebner * * 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 @@ -16,47 +14,44 @@ * GNU General Public License for more details. */ -#include +#include +#include #include -#include #include -#include -#include +#include +#include +#include #include #include -#include #include "core.h" +#include "cpu_axi.h" -static void __init rockchip_dt_map_io(void) +static void __init rk3188_dt_map_io(void) { preset_lpj = 11996091ULL / 2; debug_ll_io_init(); } -static void __init rockchip_timer_init(void) +static void __init rk3188_dt_timer_init(void) { of_clk_init(NULL); clocksource_of_init(); } -static void __init rockchip_dt_init(void) +static void __init rk3188_dt_init(void) { - l2x0_of_init(0, ~0UL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static const char * const rockchip_board_dt_compat[] = { - "rockchip,rk2928", - "rockchip,rk3066a", - "rockchip,rk3066b", +static const char * const rk3188_dt_compat[] = { "rockchip,rk3188", NULL, }; -DT_MACHINE_START(ROCKCHIP_DT, "Rockchip SoC (Flattened Device Tree)") +DT_MACHINE_START(RK3188_DT, "Rockchip RK3188 (Flattened Device Tree)") .smp = smp_ops(rockchip_smp_ops), - .map_io = rockchip_dt_map_io, - .init_machine = rockchip_dt_init, - .init_time = rockchip_timer_init, - .dt_compat = rockchip_board_dt_compat, + .map_io = rk3188_dt_map_io, + .init_machine = rk3188_dt_init, + .init_time = rk3188_dt_timer_init, + .dt_compat = rk3188_dt_compat, MACHINE_END -- 2.34.1