1 /* 2 * R-Car Generation 2 support 3 * 4 * Copyright (C) 2013 Renesas Solutions Corp. 5 * Copyright (C) 2013 Magnus Damm 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; version 2 of the License. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <linux/clk/shmobile.h> 22 #include <linux/clocksource.h> 23 #include <linux/io.h> 24 #include <linux/kernel.h> 25 #include <mach/common.h> 26 #include <mach/rcar-gen2.h> 27 #include <asm/mach/arch.h> 28 29 #define MODEMR 0xe6160060 30 31 u32 rcar_gen2_read_mode_pins(void) 32 { 33 void __iomem *modemr = ioremap_nocache(MODEMR, 4); 34 u32 mode; 35 36 BUG_ON(!modemr); 37 mode = ioread32(modemr); 38 iounmap(modemr); 39 40 return mode; 41 } 42 43 #define CNTCR 0 44 #define CNTFID0 0x20 45 46 void __init rcar_gen2_timer_init(void) 47 { 48 #if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK) 49 u32 mode = rcar_gen2_read_mode_pins(); 50 #endif 51 #ifdef CONFIG_ARM_ARCH_TIMER 52 void __iomem *base; 53 int extal_mhz = 0; 54 u32 freq; 55 56 /* At Linux boot time the r8a7790 arch timer comes up 57 * with the counter disabled. Moreover, it may also report 58 * a potentially incorrect fixed 13 MHz frequency. To be 59 * correct these registers need to be updated to use the 60 * frequency EXTAL / 2 which can be determined by the MD pins. 61 */ 62 63 switch (mode & (MD(14) | MD(13))) { 64 case 0: 65 extal_mhz = 15; 66 break; 67 case MD(13): 68 extal_mhz = 20; 69 break; 70 case MD(14): 71 extal_mhz = 26; 72 break; 73 case MD(13) | MD(14): 74 extal_mhz = 30; 75 break; 76 } 77 78 /* The arch timer frequency equals EXTAL / 2 */ 79 freq = extal_mhz * (1000000 / 2); 80 81 /* Remap "armgcnt address map" space */ 82 base = ioremap(0xe6080000, PAGE_SIZE); 83 84 /* 85 * Update the timer if it is either not running, or is not at the 86 * right frequency. The timer is only configurable in secure mode 87 * so this avoids an abort if the loader started the timer and 88 * entered the kernel in non-secure mode. 89 */ 90 91 if ((ioread32(base + CNTCR) & 1) == 0 || 92 ioread32(base + CNTFID0) != freq) { 93 /* Update registers with correct frequency */ 94 iowrite32(freq, base + CNTFID0); 95 asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); 96 97 /* make sure arch timer is started by setting bit 0 of CNTCR */ 98 iowrite32(1, base + CNTCR); 99 } 100 101 iounmap(base); 102 #endif /* CONFIG_ARM_ARCH_TIMER */ 103 104 #ifdef CONFIG_COMMON_CLK 105 rcar_gen2_clocks_init(mode); 106 #endif 107 clocksource_of_init(); 108 } 109