"Das U-Boot" Source Tree
at master 162 lines 4.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2018 Synopsys, Inc. All rights reserved. 4 */ 5 6#include <cpu_func.h> 7#include <init.h> 8#include <malloc.h> 9#include <dwmmc.h> 10#include <asm/global_data.h> 11#include <linux/bitops.h> 12#include <linux/libfdt.h> 13#include <fdtdec.h> 14 15#include <asm/arcregs.h> 16 17DECLARE_GLOBAL_DATA_PTR; 18 19#define SYSCON_BASE 0xf000a000 20#define AHBCKDIV (void *)(SYSCON_BASE + 0x04) 21#define APBCKDIV (void *)(SYSCON_BASE + 0x08) 22#define APBCKEN (void *)(SYSCON_BASE + 0x0C) 23#define RESET_REG (void *)(SYSCON_BASE + 0x18) 24#define CLKSEL (void *)(SYSCON_BASE + 0x24) 25#define CLKSTAT (void *)(SYSCON_BASE + 0x28) 26#define PLLCON (void *)(SYSCON_BASE + 0x2C) 27#define APBCKSEL (void *)(SYSCON_BASE + 0x30) 28#define AHBCKEN (void *)(SYSCON_BASE + 0x34) 29#define USBPHY_PLL (void *)(SYSCON_BASE + 0x78) 30#define USBCFG (void *)(SYSCON_BASE + 0x7c) 31 32#define PLL_MASK_0 0xffcfffff 33#define PLL_MASK_1 0xffcfff00 34#define PLL_MASK_2 0xfbcfff00 35 36#define CLKSEL_DEFAULT 0x5a690000 37 38static int set_cpu_freq(unsigned int clk) 39{ 40 clk /= 1000000; 41 42 /* Set clk to ext Xtal (LSN value 0) */ 43 writel(CLKSEL_DEFAULT, CLKSEL); 44 45 switch (clk) { 46 case 16: 47 /* Bypass mode */ 48 return 0; 49 50 case 50: 51 writel(readl(PLLCON) & PLL_MASK_0, PLLCON); 52 /* pll_off=1, M=25, N=1, OD=3, PLL_OUT_CLK=50M */ 53 writel((readl(PLLCON) & PLL_MASK_1) | 0x300191, PLLCON); 54 /* pll_off=0, M=25, N=1, OD=3, PLL_OUT_CLK=50M */ 55 writel((readl(PLLCON) & PLL_MASK_2) | 0x300191, PLLCON); 56 break; 57 58 case 72: 59 writel(readl(PLLCON) & PLL_MASK_0, PLLCON); 60 /* pll_off=1, M=18, N=1, OD=2, PLL_OUT_CLK=72M */ 61 writel((readl(PLLCON) & PLL_MASK_1) | 0x200121, PLLCON); 62 /* pll_off=0, M=18, N=1, OD=2, PLL_OUT_CLK=72M */ 63 writel((readl(PLLCON) & PLL_MASK_2) | 0x200121, PLLCON); 64 break; 65 66 case 100: 67 writel(readl(PLLCON) & PLL_MASK_0, PLLCON); 68 /* pll_off=1,M=25, N=1, OD=2, PLL_OUT_CLK=100M */ 69 writel((readl(PLLCON) & PLL_MASK_1) | 0x200191, PLLCON); 70 /* pll_off=0,M=25, N=1, OD=2, PLL_OUT_CLK=100M */ 71 writel((readl(PLLCON) & PLL_MASK_2) | 0x200191, PLLCON); 72 break; 73 74 case 136: 75 writel(readl(PLLCON) & PLL_MASK_0, PLLCON); 76 /* pll_off=1, M=17, N=1, OD=1, PLL_OUT_CLK=136M */ 77 writel((readl(PLLCON) & PLL_MASK_1) | 0x100111, PLLCON); 78 /* pll_off=0, M=17, N=1, OD=1, PLL_OUT_CLK=136M */ 79 writel((readl(PLLCON) & PLL_MASK_2) | 0x100111, PLLCON); 80 break; 81 82 case 144: 83 writel(readl(PLLCON) & PLL_MASK_0, PLLCON); 84 /* pll_off=1, M=18, N=1, OD=1, PLL_OUT_CLK=144M */ 85 writel((readl(PLLCON) & PLL_MASK_1) | 0x100121, PLLCON); 86 /* pll_off=0, M=18, N=1, OD=1, PLL_OUT_CLK=144M */ 87 writel((readl(PLLCON) & PLL_MASK_2) | 0x100121, PLLCON); 88 break; 89 90 default: 91 return -EINVAL; 92 } 93 94 while (!(readl(CLKSTAT) & 0x4)) 95 ; 96 97 /* Set clk from PLL on bus (LSN = 1) */ 98 writel(CLKSEL_DEFAULT | BIT(0), CLKSEL); 99 100 return 0; 101} 102 103extern u8 __rom_end[]; 104extern u8 __ram_start[]; 105extern u8 __ram_end[]; 106 107/* 108 * Use mach_cpu_init() for .data section copy as board_early_init_f() will be 109 * too late: initf_dm() will use a value of "av_" variable from not yet 110 * initialized (by copy) area. 111 */ 112int mach_cpu_init(void) 113{ 114 int offset; 115 116 /* Don't relocate U-Boot */ 117 gd->flags |= GD_FLG_SKIP_RELOC; 118 119 /* Copy data from ROM to RAM */ 120 u8 *src = __rom_end; 121 u8 *dst = __ram_start; 122 123 while (dst < __ram_end) 124 *dst++ = *src++; 125 126 /* Enable debug uart */ 127#define DEBUG_UART_BASE 0x80014000 128#define DEBUG_UART_DLF_OFFSET 0xc0 129 write_aux_reg(DEBUG_UART_BASE + DEBUG_UART_DLF_OFFSET, 1); 130 131 offset = fdt_path_offset(gd->fdt_blob, "/cpu_card/core_clk"); 132 if (offset < 0) 133 return offset; 134 135 gd->cpu_clk = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0); 136 if (!gd->cpu_clk) 137 return -EINVAL; 138 139 /* If CPU freq > 100 MHz, divide eFLASH clock by 2 */ 140 if (gd->cpu_clk > 100000000) { 141 u32 reg = readl(AHBCKDIV); 142 143 reg &= ~(0xF << 8); 144 reg |= 2 << 8; 145 writel(reg, AHBCKDIV); 146 } 147 148 return set_cpu_freq(gd->cpu_clk); 149} 150 151#define IOTDK_RESET_SEQ 0x55AA6699 152 153void reset_cpu(void) 154{ 155 writel(IOTDK_RESET_SEQ, RESET_REG); 156} 157 158int checkboard(void) 159{ 160 puts("Board: Synopsys IoT Development Kit\n"); 161 return 0; 162};