2 * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
4 * Derived from linux/arch/mips/bcm63xx/cpu.c:
5 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
6 * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
8 * SPDX-License-Identifier: GPL-2.0+
17 #define SDRAM_CFG_REG 0x0
18 #define SDRAM_CFG_COL_SHIFT 4
19 #define SDRAM_CFG_COL_MASK (0x3 << SDRAM_CFG_COL_SHIFT)
20 #define SDRAM_CFG_ROW_SHIFT 6
21 #define SDRAM_CFG_ROW_MASK (0x3 << SDRAM_CFG_ROW_SHIFT)
22 #define SDRAM_CFG_32B_SHIFT 10
23 #define SDRAM_CFG_32B_MASK (1 << SDRAM_CFG_32B_SHIFT)
24 #define SDRAM_CFG_BANK_SHIFT 13
25 #define SDRAM_CFG_BANK_MASK (1 << SDRAM_CFG_BANK_SHIFT)
27 #define MEMC_CFG_REG 0x4
28 #define MEMC_CFG_32B_SHIFT 1
29 #define MEMC_CFG_32B_MASK (1 << MEMC_CFG_32B_SHIFT)
30 #define MEMC_CFG_COL_SHIFT 3
31 #define MEMC_CFG_COL_MASK (0x3 << MEMC_CFG_COL_SHIFT)
32 #define MEMC_CFG_ROW_SHIFT 6
33 #define MEMC_CFG_ROW_MASK (0x3 << MEMC_CFG_ROW_SHIFT)
35 #define DDR_CSEND_REG 0x8
37 struct bmips_ram_priv
;
40 ulong (*get_ram_size
)(struct bmips_ram_priv
*);
43 struct bmips_ram_priv
{
45 const struct bmips_ram_hw
*hw
;
48 static ulong
bcm6328_get_ram_size(struct bmips_ram_priv
*priv
)
50 return readl_be(priv
->regs
+ DDR_CSEND_REG
) << 24;
53 static ulong
bmips_dram_size(unsigned int cols
, unsigned int rows
,
54 unsigned int is_32b
, unsigned int banks
)
56 rows
+= 11; /* 0 => 11 address bits ... 2 => 13 address bits */
57 cols
+= 8; /* 0 => 8 address bits ... 2 => 10 address bits */
60 return 1 << (cols
+ rows
+ is_32b
+ banks
);
63 static ulong
bcm6338_get_ram_size(struct bmips_ram_priv
*priv
)
65 unsigned int cols
= 0, rows
= 0, is_32b
= 0, banks
= 0;
68 val
= readl_be(priv
->regs
+ SDRAM_CFG_REG
);
69 rows
= (val
& SDRAM_CFG_ROW_MASK
) >> SDRAM_CFG_ROW_SHIFT
;
70 cols
= (val
& SDRAM_CFG_COL_MASK
) >> SDRAM_CFG_COL_SHIFT
;
71 is_32b
= (val
& SDRAM_CFG_32B_MASK
) ? 1 : 0;
72 banks
= (val
& SDRAM_CFG_BANK_MASK
) ? 2 : 1;
74 return bmips_dram_size(cols
, rows
, is_32b
, banks
);
77 static ulong
bcm6358_get_ram_size(struct bmips_ram_priv
*priv
)
79 unsigned int cols
= 0, rows
= 0, is_32b
= 0;
82 val
= readl_be(priv
->regs
+ MEMC_CFG_REG
);
83 rows
= (val
& MEMC_CFG_ROW_MASK
) >> MEMC_CFG_ROW_SHIFT
;
84 cols
= (val
& MEMC_CFG_COL_MASK
) >> MEMC_CFG_COL_SHIFT
;
85 is_32b
= (val
& MEMC_CFG_32B_MASK
) ? 0 : 1;
87 return bmips_dram_size(cols
, rows
, is_32b
, 2);
90 static int bmips_ram_get_info(struct udevice
*dev
, struct ram_info
*info
)
92 struct bmips_ram_priv
*priv
= dev_get_priv(dev
);
93 const struct bmips_ram_hw
*hw
= priv
->hw
;
95 info
->base
= 0x80000000;
96 info
->size
= hw
->get_ram_size(priv
);
101 static const struct ram_ops bmips_ram_ops
= {
102 .get_info
= bmips_ram_get_info
,
105 static const struct bmips_ram_hw bmips_ram_bcm6328
= {
106 .get_ram_size
= bcm6328_get_ram_size
,
109 static const struct bmips_ram_hw bmips_ram_bcm6338
= {
110 .get_ram_size
= bcm6338_get_ram_size
,
113 static const struct bmips_ram_hw bmips_ram_bcm6358
= {
114 .get_ram_size
= bcm6358_get_ram_size
,
117 static const struct udevice_id bmips_ram_ids
[] = {
119 .compatible
= "brcm,bcm6328-mc",
120 .data
= (ulong
)&bmips_ram_bcm6328
,
122 .compatible
= "brcm,bcm6338-mc",
123 .data
= (ulong
)&bmips_ram_bcm6338
,
125 .compatible
= "brcm,bcm6358-mc",
126 .data
= (ulong
)&bmips_ram_bcm6358
,
127 }, { /* sentinel */ }
130 static int bmips_ram_probe(struct udevice
*dev
)
132 struct bmips_ram_priv
*priv
= dev_get_priv(dev
);
133 const struct bmips_ram_hw
*hw
=
134 (const struct bmips_ram_hw
*)dev_get_driver_data(dev
);
138 addr
= devfdt_get_addr_size_index(dev
, 0, &size
);
139 if (addr
== FDT_ADDR_T_NONE
)
142 priv
->regs
= ioremap(addr
, size
);
148 U_BOOT_DRIVER(bmips_ram
) = {
151 .of_match
= bmips_ram_ids
,
152 .probe
= bmips_ram_probe
,
153 .priv_auto_alloc_size
= sizeof(struct bmips_ram_priv
),
154 .ops
= &bmips_ram_ops
,
155 .flags
= DM_FLAG_PRE_RELOC
,