14c835a60SStefan Roese/* SPDX-License-Identifier: GPL-2.0+ */ 24c835a60SStefan Roese/* 34c835a60SStefan Roese * (c) 2018 Stefan Roese <sr@denx.de> 44c835a60SStefan Roese * 54c835a60SStefan Roese * This code is mostly based on the code extracted from this MediaTek 64c835a60SStefan Roese * github repository: 74c835a60SStefan Roese * 84c835a60SStefan Roese * https://github.com/MediaTek-Labs/linkit-smart-uboot.git 94c835a60SStefan Roese * 104c835a60SStefan Roese * I was not able to find a specific license or other developers 114c835a60SStefan Roese * copyrights here, so I can't add them here. 124c835a60SStefan Roese */ 134c835a60SStefan Roese 144c835a60SStefan Roese#include <config.h> 154c835a60SStefan Roese#include <asm/regdef.h> 164c835a60SStefan Roese#include <asm/mipsregs.h> 174c835a60SStefan Roese#include <asm/addrspace.h> 184c835a60SStefan Roese#include <asm/asm.h> 194c835a60SStefan Roese#include "mt76xx.h" 204c835a60SStefan Roese 214c835a60SStefan Roese#ifndef BIT 224c835a60SStefan Roese#define BIT(nr) (1 << (nr)) 234c835a60SStefan Roese#endif 244c835a60SStefan Roese 254c835a60SStefan Roese#define DELAY_USEC(us) ((us) / 100) 264c835a60SStefan Roese 274c835a60SStefan Roese#define DDR_CFG1_CHIP_WIDTH_MASK (0x3 << 16) 284c835a60SStefan Roese#define DDR_CFG1_BUS_WIDTH_MASK (0x3 << 12) 294c835a60SStefan Roese 304c835a60SStefan Roese#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT) 314c835a60SStefan Roese#define DDR_CFG1_SIZE_VAL 0x222e2323 324c835a60SStefan Roese#define DDR_CFG4_SIZE_VAL 7 334c835a60SStefan Roese#endif 344c835a60SStefan Roese#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT) 354c835a60SStefan Roese#define DDR_CFG1_SIZE_VAL 0x22322323 364c835a60SStefan Roese#define DDR_CFG4_SIZE_VAL 9 374c835a60SStefan Roese#endif 384c835a60SStefan Roese#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT) 394c835a60SStefan Roese#define DDR_CFG1_SIZE_VAL 0x22362323 404c835a60SStefan Roese#define DDR_CFG4_SIZE_VAL 9 414c835a60SStefan Roese#endif 424c835a60SStefan Roese#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT) 434c835a60SStefan Roese#define DDR_CFG1_SIZE_VAL 0x223a2323 444c835a60SStefan Roese#define DDR_CFG4_SIZE_VAL 9 454c835a60SStefan Roese#endif 464c835a60SStefan Roese 474c835a60SStefan Roese#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_8BIT) 484c835a60SStefan Roese#define DDR_CFG1_CHIP_WIDTH_VAL (0x1 << 16) 494c835a60SStefan Roese#endif 504c835a60SStefan Roese#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT) 514c835a60SStefan Roese#define DDR_CFG1_CHIP_WIDTH_VAL (0x2 << 16) 524c835a60SStefan Roese#endif 534c835a60SStefan Roese 544c835a60SStefan Roese#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_16BIT) 554c835a60SStefan Roese#define DDR_CFG1_BUS_WIDTH_VAL (0x2 << 12) 564c835a60SStefan Roese#endif 574c835a60SStefan Roese#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_32BIT) 584c835a60SStefan Roese#define DDR_CFG1_BUS_WIDTH_VAL (0x3 << 12) 594c835a60SStefan Roese#endif 604c835a60SStefan Roese 614c835a60SStefan Roese .set noreorder 624c835a60SStefan Roese 634c835a60SStefan RoeseLEAF(lowlevel_init) 644c835a60SStefan Roese 654c835a60SStefan Roese /* Load base addresses as physical addresses for later usage */ 664c835a60SStefan Roese li s0, CKSEG1ADDR(MT76XX_SYSCTL_BASE) 674c835a60SStefan Roese li s1, CKSEG1ADDR(MT76XX_MEMCTRL_BASE) 684c835a60SStefan Roese li s2, CKSEG1ADDR(MT76XX_RGCTRL_BASE) 694c835a60SStefan Roese 704c835a60SStefan Roese /* polling CPLL is ready */ 714c835a60SStefan Roese li t1, DELAY_USEC(1000000) 724c835a60SStefan Roese la t5, MT76XX_ROM_STATUS_REG 734c835a60SStefan Roese1: 744c835a60SStefan Roese lw t2, 0(t5) 754c835a60SStefan Roese andi t2, t2, 0x1 764c835a60SStefan Roese bnez t2, CPLL_READY 774c835a60SStefan Roese subu t1, t1, 1 784c835a60SStefan Roese bgtz t1, 1b 794c835a60SStefan Roese nop 804c835a60SStefan Roese la t0, MT76XX_CLKCFG0_REG 814c835a60SStefan Roese lw t3, 0(t0) 824c835a60SStefan Roese ori t3, t3, 0x1 834c835a60SStefan Roese sw t3, 0(t0) 844c835a60SStefan Roese b CPLL_DONE 854c835a60SStefan Roese nop 864c835a60SStefan RoeseCPLL_READY: 874c835a60SStefan Roese la t0, MT76XX_CLKCFG0_REG 884c835a60SStefan Roese lw t1, 0(t0) 894c835a60SStefan Roese li t2, ~0x0c 904c835a60SStefan Roese and t1, t1, t2 914c835a60SStefan Roese ori t1, t1, 0xc 924c835a60SStefan Roese sw t1, 0(t0) 934c835a60SStefan Roese la t0, MT76XX_DYN_CFG0_REG 944c835a60SStefan Roese lw t3, 0(t0) 954c835a60SStefan Roese li t5, ~((0x0f << 8) | (0x0f << 0)) 964c835a60SStefan Roese and t3, t3, t5 974c835a60SStefan Roese li t5, (10 << 8) | (1 << 0) 984c835a60SStefan Roese or t3, t3, t5 994c835a60SStefan Roese sw t3, 0(t0) 1004c835a60SStefan Roese la t0, MT76XX_CLKCFG0_REG 1014c835a60SStefan Roese lw t3, 0(t0) 1024c835a60SStefan Roese li t4, ~0x0F 1034c835a60SStefan Roese and t3, t3, t4 1044c835a60SStefan Roese ori t3, t3, 0xc 1054c835a60SStefan Roese sw t3, 0(t0) 1064c835a60SStefan Roese lw t3, 0(t0) 1074c835a60SStefan Roese ori t3, t3, 0x08 1084c835a60SStefan Roese sw t3, 0(t0) 1094c835a60SStefan Roese 1104c835a60SStefan RoeseCPLL_DONE: 111*a8b0bf63SStefan Roese /* Reset MC */ 112*a8b0bf63SStefan Roese lw t2, 0x34(s0) 113*a8b0bf63SStefan Roese ori t2, BIT(10) 114*a8b0bf63SStefan Roese sw t2, 0x34(s0) 115*a8b0bf63SStefan Roese nop 116*a8b0bf63SStefan Roese 1174c835a60SStefan Roese /* 1184c835a60SStefan Roese * SDR and DDR initialization: delay 200us 1194c835a60SStefan Roese */ 1204c835a60SStefan Roese li t0, DELAY_USEC(200 + 40) 1214c835a60SStefan Roese li t1, 0x1 1224c835a60SStefan Roese1: 1234c835a60SStefan Roese sub t0, t0, t1 1244c835a60SStefan Roese bnez t0, 1b 1254c835a60SStefan Roese nop 1264c835a60SStefan Roese 1274c835a60SStefan Roese /* set DRAM IO PAD for MT7628IC */ 1284c835a60SStefan Roese /* DDR LDO Enable */ 1294c835a60SStefan Roese lw t4, 0x100(s2) 1304c835a60SStefan Roese li t2, BIT(31) 1314c835a60SStefan Roese or t4, t4, t2 1324c835a60SStefan Roese sw t4, 0x100(s2) 1334c835a60SStefan Roese lw t4, 0x10c(s2) 1344c835a60SStefan Roese j LDO_1P8V 1354c835a60SStefan Roese nop 1364c835a60SStefan RoeseLDO_1P8V: 1374c835a60SStefan Roese li t2, ~BIT(6) 1384c835a60SStefan Roese and t4, t4, t2 1394c835a60SStefan Roese sw t4, 0x10c(s2) 1404c835a60SStefan Roese j DDRLDO_SOFT_START 1414c835a60SStefan RoeseLDO_2P5V: 1424c835a60SStefan Roese /* suppose external DDR1 LDO 2.5V */ 1434c835a60SStefan Roese li t2, BIT(6) 1444c835a60SStefan Roese or t4, t4, t2 1454c835a60SStefan Roese sw t4, 0x10c(s2) 1464c835a60SStefan Roese 1474c835a60SStefan RoeseDDRLDO_SOFT_START: 1484c835a60SStefan Roese lw t2, 0x10c(s2) 1494c835a60SStefan Roese li t3, BIT(16) 1504c835a60SStefan Roese or t2, t2, t3 1514c835a60SStefan Roese sw t2, 0x10c(s2) 1524c835a60SStefan Roese li t3, DELAY_USEC(250*50) 1534c835a60SStefan RoeseLDO_DELAY: 1544c835a60SStefan Roese subu t3, t3, 1 1554c835a60SStefan Roese bnez t3, LDO_DELAY 1564c835a60SStefan Roese nop 1574c835a60SStefan Roese 1584c835a60SStefan Roese lw t2, 0x10c(s2) 1594c835a60SStefan Roese li t3, BIT(18) 1604c835a60SStefan Roese or t2, t2, t3 1614c835a60SStefan Roese sw t2, 0x10c(s2) 1624c835a60SStefan Roese 1634c835a60SStefan RoeseSET_RG_BUCK_FPWM: 1644c835a60SStefan Roese lw t2, 0x104(s2) 1654c835a60SStefan Roese ori t2, t2, BIT(10) 1664c835a60SStefan Roese sw t2, 0x104(s2) 1674c835a60SStefan Roese 1684c835a60SStefan RoeseDDR_PAD_CFG: 1694c835a60SStefan Roese /* clean CLK PAD */ 1704c835a60SStefan Roese lw t2, 0x704(s2) 1714c835a60SStefan Roese li t8, 0xfffff0f0 1724c835a60SStefan Roese and t2, t2, t8 1734c835a60SStefan Roese /* clean CMD PAD */ 1744c835a60SStefan Roese lw t3, 0x70c(s2) 1754c835a60SStefan Roese li t8, 0xfffff0f0 1764c835a60SStefan Roese and t3, t3, t8 1774c835a60SStefan Roese /* clean DQ IPAD */ 1784c835a60SStefan Roese lw t4, 0x710(s2) 1794c835a60SStefan Roese li t8, 0xfffff8ff 1804c835a60SStefan Roese and t4, t4, t8 1814c835a60SStefan Roese /* clean DQ OPAD */ 1824c835a60SStefan Roese lw t5, 0x714(s2) 1834c835a60SStefan Roese li t8, 0xfffff0f0 1844c835a60SStefan Roese and t5, t5, t8 1854c835a60SStefan Roese /* clean DQS IPAD */ 1864c835a60SStefan Roese lw t6, 0x718(s2) 1874c835a60SStefan Roese li t8, 0xfffff8ff 1884c835a60SStefan Roese and t6, t6, t8 1894c835a60SStefan Roese /* clean DQS OPAD */ 1904c835a60SStefan Roese lw t7, 0x71c(s2) 1914c835a60SStefan Roese li t8, 0xfffff0f0 1924c835a60SStefan Roese and t7, t7, t8 1934c835a60SStefan Roese 1944c835a60SStefan Roese lw t9, 0xc(s0) 1954c835a60SStefan Roese srl t9, t9, 16 1964c835a60SStefan Roese andi t9, t9, 0x1 1974c835a60SStefan Roese bnez t9, MT7628_AN_DDR1_PAD 1984c835a60SStefan RoeseMT7628_KN_PAD: 1994c835a60SStefan Roese li t8, 0x00000303 2004c835a60SStefan Roese or t2, t2, t8 2014c835a60SStefan Roese or t3, t3, t8 2024c835a60SStefan Roese or t5, t5, t8 2034c835a60SStefan Roese or t7, t7, t8 2044c835a60SStefan Roese li t8, 0x00000000 2054c835a60SStefan Roese or t4, t4, t8 2064c835a60SStefan Roese or t6, t6, t8 2074c835a60SStefan Roese j SET_PAD_CFG 2084c835a60SStefan RoeseMT7628_AN_DDR1_PAD: 2094c835a60SStefan Roese lw t1, 0x10(s0) 2104c835a60SStefan Roese andi t1, t1, 0x1 2114c835a60SStefan Roese beqz t1, MT7628_AN_DDR2_PAD 2124c835a60SStefan Roese li t8, 0x00000c0c 2134c835a60SStefan Roese or t2, t2, t8 2144c835a60SStefan Roese li t8, 0x00000202 2154c835a60SStefan Roese or t3, t3, t8 2164c835a60SStefan Roese li t8, 0x00000707 2174c835a60SStefan Roese or t5, t5, t8 2184c835a60SStefan Roese li t8, 0x00000c0c 2194c835a60SStefan Roese or t7, t7, t8 2204c835a60SStefan Roese li t8, 0x00000000 2214c835a60SStefan Roese or t4, t4, t8 2224c835a60SStefan Roese or t6, t6, t8 2234c835a60SStefan Roese j SET_PAD_CFG 2244c835a60SStefan RoeseMT7628_AN_DDR2_PAD: 2254c835a60SStefan Roese li t8, 0x00000c0c 2264c835a60SStefan Roese or t2, t2, t8 2274c835a60SStefan Roese li t8, 0x00000202 2284c835a60SStefan Roese or t3, t3, t8 2294c835a60SStefan Roese li t8, 0x00000404 2304c835a60SStefan Roese or t5, t5, t8 2314c835a60SStefan Roese li t8, 0x00000c0c 2324c835a60SStefan Roese or t7, t7, t8 2334c835a60SStefan Roese li t8, 0x00000000 /* ODT off */ 2344c835a60SStefan Roese or t4, t4, t8 2354c835a60SStefan Roese or t6, t6, t8 2364c835a60SStefan Roese 2374c835a60SStefan RoeseSET_PAD_CFG: 2384c835a60SStefan Roese sw t2, 0x704(s2) 2394c835a60SStefan Roese sw t3, 0x70c(s2) 2404c835a60SStefan Roese sw t4, 0x710(s2) 2414c835a60SStefan Roese sw t5, 0x714(s2) 2424c835a60SStefan Roese sw t6, 0x718(s2) 2434c835a60SStefan Roese sw t7, 0x71c(s2) 2444c835a60SStefan Roese 2454c835a60SStefan Roese /* 2464c835a60SStefan Roese * DDR initialization: reset pin to 0 2474c835a60SStefan Roese */ 2484c835a60SStefan Roese lw t2, 0x34(s0) 2494c835a60SStefan Roese and t2, ~BIT(10) 2504c835a60SStefan Roese sw t2, 0x34(s0) 2514c835a60SStefan Roese nop 2524c835a60SStefan Roese 2534c835a60SStefan Roese /* 2544c835a60SStefan Roese * DDR initialization: wait til reg DDR_CFG1 bit 21 equal to 1 (ready) 2554c835a60SStefan Roese */ 2564c835a60SStefan RoeseDDR_READY: 2574c835a60SStefan Roese li t1, DDR_CFG1_REG 2584c835a60SStefan Roese lw t0, 0(t1) 2594c835a60SStefan Roese nop 2604c835a60SStefan Roese and t2, t0, BIT(21) 2614c835a60SStefan Roese beqz t2, DDR_READY 2624c835a60SStefan Roese nop 2634c835a60SStefan Roese 2644c835a60SStefan Roese /* 2654c835a60SStefan Roese * DDR initialization 2664c835a60SStefan Roese * 2674c835a60SStefan Roese * Only DDR2 supported right now. DDR2 support can be added, once 2684c835a60SStefan Roese * boards using it will get added to mainline U-Boot. 2694c835a60SStefan Roese */ 2704c835a60SStefan Roese li t1, DDR_CFG2_REG 2714c835a60SStefan Roese lw t0, 0(t1) 2724c835a60SStefan Roese nop 2734c835a60SStefan Roese and t0, ~BIT(30) 2744c835a60SStefan Roese and t0, ~(7 << 4) 2754c835a60SStefan Roese or t0, (4 << 4) 2764c835a60SStefan Roese or t0, BIT(30) 2774c835a60SStefan Roese or t0, BIT(11) 2784c835a60SStefan Roese sw t0, 0(t1) 2794c835a60SStefan Roese nop 2804c835a60SStefan Roese 2814c835a60SStefan Roese li t1, DDR_CFG3_REG 2824c835a60SStefan Roese lw t2, 0(t1) 2834c835a60SStefan Roese /* Disable ODT; reference board ok, ev board fail */ 2844c835a60SStefan Roese and t2, ~BIT(6) 2854c835a60SStefan Roese or t2, BIT(2) 2864c835a60SStefan Roese li t0, DDR_CFG4_REG 2874c835a60SStefan Roese lw t1, 0(t0) 2884c835a60SStefan Roese li t2, ~(0x01f | 0x0f0) 2894c835a60SStefan Roese and t1, t1, t2 2904c835a60SStefan Roese ori t1, t1, DDR_CFG4_SIZE_VAL 2914c835a60SStefan Roese sw t1, 0(t0) 2924c835a60SStefan Roese nop 2934c835a60SStefan Roese 2944c835a60SStefan Roese /* 2954c835a60SStefan Roese * DDR initialization: config size and width on reg DDR_CFG1 2964c835a60SStefan Roese */ 2974c835a60SStefan Roese li t6, DDR_CFG1_SIZE_VAL 2984c835a60SStefan Roese 2994c835a60SStefan Roese and t6, ~DDR_CFG1_CHIP_WIDTH_MASK 3004c835a60SStefan Roese or t6, DDR_CFG1_CHIP_WIDTH_VAL 3014c835a60SStefan Roese 3024c835a60SStefan Roese /* CONFIG DDR_CFG1[13:12] about TOTAL WIDTH */ 3034c835a60SStefan Roese and t6, ~DDR_CFG1_BUS_WIDTH_MASK 3044c835a60SStefan Roese or t6, DDR_CFG1_BUS_WIDTH_VAL 3054c835a60SStefan Roese 3064c835a60SStefan Roese li t5, DDR_CFG1_REG 3074c835a60SStefan Roese sw t6, 0(t5) 3084c835a60SStefan Roese nop 3094c835a60SStefan Roese 3104c835a60SStefan Roese /* 3114c835a60SStefan Roese * DDR: enable self auto refresh for power saving 3124c835a60SStefan Roese * enable it by default for both RAM and ROM version (for CoC) 3134c835a60SStefan Roese */ 3144c835a60SStefan Roese lw t1, 0x14(s1) 3154c835a60SStefan Roese nop 3164c835a60SStefan Roese and t1, 0xff000000 3174c835a60SStefan Roese or t1, 0x01 3184c835a60SStefan Roese sw t1, 0x14(s1) 3194c835a60SStefan Roese nop 3204c835a60SStefan Roese lw t1, 0x10(s1) 3214c835a60SStefan Roese nop 3224c835a60SStefan Roese or t1, 0x10 3234c835a60SStefan Roese sw t1, 0x10(s1) 3244c835a60SStefan Roese nop 3254c835a60SStefan Roese 3264c835a60SStefan Roese jr ra 3274c835a60SStefan Roese nop 3284c835a60SStefan Roese END(lowlevel_init) 329