1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. 4 * 5 * Author: Weijie Gao <weijie.gao@mediatek.com> 6 */ 7 8#include <asm/addrspace.h> 9#include <linux/bitops.h> 10#include <linux/delay.h> 11#include <linux/sizes.h> 12#include <linux/io.h> 13#include <mach/ddr.h> 14#include <mach/mc.h> 15#include "mt7620.h" 16 17/* SDR parameters */ 18#define SDR_CFG0_VAL 0x51B283B3 19#define SDR_CFG1_VAL 0xC00003A9 20 21/* DDR2 DQ_DLY */ 22#define DDR2_DQ_DLY 0x88888888 23 24/* DDR2 DQS_DLY */ 25#define DDR2_DQS_DLY 0x88888888 26 27static const struct mc_ddr_cfg ddr1_cfgs_200mhz[] = { 28 [DRAM_8MB] = { 0x34A1EB94, 0x20262324, 0x28000033, 0x00000002, 0x00000000 }, 29 [DRAM_16MB] = { 0x34A1EB94, 0x202A2324, 0x28000033, 0x00000002, 0x00000000 }, 30 [DRAM_32MB] = { 0x34A1E5CA, 0x202E2324, 0x28000033, 0x00000002, 0x00000000 }, 31 [DRAM_64MB] = { 0x3421E5CA, 0x20322324, 0x28000033, 0x00000002, 0x00000000 }, 32 [DRAM_128MB] = { 0x241B05CA, 0x20362334, 0x28000033, 0x00000002, 0x00000000 }, 33}; 34 35static const struct mc_ddr_cfg ddr1_cfgs_160mhz[] = { 36 [DRAM_8MB] = { 0x239964A1, 0x20262323, 0x00000033, 0x00000002, 0x00000000 }, 37 [DRAM_16MB] = { 0x239964A1, 0x202A2323, 0x00000033, 0x00000002, 0x00000000 }, 38 [DRAM_32MB] = { 0x239964A1, 0x202E2323, 0x00000033, 0x00000002, 0x00000000 }, 39 [DRAM_64MB] = { 0x239984A1, 0x20322323, 0x00000033, 0x00000002, 0x00000000 }, 40 [DRAM_128MB] = { 0x239AB4A1, 0x20362333, 0x00000033, 0x00000002, 0x00000000 }, 41}; 42 43static const struct mc_ddr_cfg ddr2_cfgs_200mhz[] = { 44 [DRAM_32MB] = { 0x2519E2E5, 0x222E2323, 0x68000C43, 0x00000416, 0x0000000A }, 45 [DRAM_64MB] = { 0x249AA2E5, 0x22322323, 0x68000C43, 0x00000416, 0x0000000A }, 46 [DRAM_128MB] = { 0x249B42E5, 0x22362323, 0x68000C43, 0x00000416, 0x0000000A }, 47 [DRAM_256MB] = { 0x249CE2E5, 0x223A2323, 0x68000C43, 0x00000416, 0x0000000A }, 48}; 49 50static const struct mc_ddr_cfg ddr2_cfgs_160mhz[] = { 51 [DRAM_32MB] = { 0x23918250, 0x222E2322, 0x40000A43, 0x00000416, 0x00000006 }, 52 [DRAM_64MB] = { 0x239A2250, 0x22322322, 0x40000A43, 0x00000416, 0x00000008 }, 53 [DRAM_128MB] = { 0x2392A250, 0x22362322, 0x40000A43, 0x00000416, 0x00000008 }, 54 [DRAM_256MB] = { 0x24140250, 0x223A2322, 0x40000A43, 0x00000416, 0x00000008 }, 55}; 56 57static void mt7620_memc_reset(int assert) 58{ 59 void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); 60 61 if (assert) 62 setbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST); 63 else 64 clrbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST); 65} 66 67void mt7620_dram_init(void) 68{ 69 void __iomem *sysc; 70 bool lspd = false; 71 int ddr_type, aux; 72 struct mc_ddr_init_param param; 73 74 sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); 75 ddr_type = (readl(sysc + SYSCTL_SYSCFG0_REG) & DRAM_TYPE_M) 76 >> DRAM_TYPE_S; 77 aux = readl(sysc + SYSCTL_CPLL_CFG1_REG) & 78 (CPU_CLK_AUX1 | CPU_CLK_AUX0); 79 80 if (aux == CPU_CLK_AUX1 || aux == CPU_CLK_AUX0) 81 lspd = true; 82 83 mt7620_memc_reset(1); 84 __udelay(200); 85 86 param.memc = ioremap_nocache(MEMCTL_BASE, MEMCTL_SIZE); 87 param.dq_dly = DDR2_DQ_DLY; 88 param.dqs_dly = DDR2_DQS_DLY; 89 param.mc_reset = mt7620_memc_reset; 90 param.memsize = 0; 91 param.bus_width = 0; 92 93 if (ddr_type == DRAM_DDR1) { 94 if (lspd) 95 param.cfgs = ddr1_cfgs_160mhz; 96 else 97 param.cfgs = ddr1_cfgs_200mhz; 98 99 ddr1_init(¶m); 100 } else if (ddr_type == DRAM_DDR2) { 101 if (lspd) 102 param.cfgs = ddr2_cfgs_160mhz; 103 else 104 param.cfgs = ddr2_cfgs_200mhz; 105 106 ddr2_init(¶m); 107 } else { 108 param.sdr_cfg0 = SDR_CFG0_VAL; 109 param.sdr_cfg1 = SDR_CFG1_VAL; 110 111 sdr_init(¶m); 112 } 113} 114