^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * arch/arm/mach-spear13xx/spear13xx.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * SPEAr13XX machines common source file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2012 ST Microelectronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Viresh Kumar <vireshk@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This file is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * License version 2. This program is licensed "as is" without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * warranty of any kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define pr_fmt(fmt) "SPEAr13xx: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/amba/pl022.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/clocksource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/hardware/cache-l2x0.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/mach/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <mach/spear.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "generic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) void __init spear13xx_l2x0_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * 512KB (64KB/way), 8-way associativity, parity supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * FIXME: 9th bit, of Auxillary Controller register must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * for some spear13xx devices for stable L2 operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Enable Early BRESP, L2 prefetch for Instruction and Data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * write alloc and 'Full line of zero' options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (!IS_ENABLED(CONFIG_CACHE_L2X0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) writel_relaxed(0x06, VA_L2CC_BASE + L310_PREFETCH_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Program following latencies in order to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * SPEAr1340 work at 600 MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) writel_relaxed(0x221, VA_L2CC_BASE + L310_TAG_LATENCY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) writel_relaxed(0x441, VA_L2CC_BASE + L310_DATA_LATENCY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) l2x0_init(VA_L2CC_BASE, 0x30a00001, 0xfe0fffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Following will create 16MB static virtual/physical mappings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * PHYSICAL VIRTUAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * 0xB3000000 0xF9000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * 0xE0000000 0xFD000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * 0xEC000000 0xFC000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * 0xED000000 0xFB000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static struct map_desc spear13xx_io_desc[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .virtual = (unsigned long)VA_PERIP_GRP2_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .pfn = __phys_to_pfn(PERIP_GRP2_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .length = SZ_16M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .type = MT_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .virtual = (unsigned long)VA_PERIP_GRP1_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .pfn = __phys_to_pfn(PERIP_GRP1_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .length = SZ_16M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .type = MT_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .virtual = (unsigned long)VA_A9SM_AND_MPMC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .pfn = __phys_to_pfn(A9SM_AND_MPMC_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .length = SZ_16M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .type = MT_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .virtual = (unsigned long)VA_L2CC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .pfn = __phys_to_pfn(L2CC_BASE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .length = SZ_4K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .type = MT_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* This will create static memory mapping for selected devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) void __init spear13xx_map_io(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static void __init spear13xx_clk_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (of_machine_is_compatible("st,spear1310"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) spear1310_clk_init(VA_MISC_BASE, VA_SPEAR1310_RAS_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) else if (of_machine_is_compatible("st,spear1340"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) spear1340_clk_init(VA_MISC_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) pr_err("%s: Unknown machine\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void __init spear13xx_timer_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) char pclk_name[] = "osc_24m_clk";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct clk *gpt_clk, *pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) spear13xx_clk_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* get the system timer clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) gpt_clk = clk_get_sys("gpt0", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (IS_ERR(gpt_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) pr_err("%s:couldn't get clk for gpt\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* get the suitable parent clock for timer*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) pclk = clk_get(NULL, pclk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (IS_ERR(pclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) pr_err("%s:couldn't get %s as parent for gpt\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) pclk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) clk_set_parent(gpt_clk, pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) clk_put(gpt_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) clk_put(pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) spear_setup_of_timer();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) timer_probe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }