xref: /openbmc/u-boot/arch/arm/mach-snapdragon/dram.c (revision b71d9e8b)
1*36adb7c9SRamon Fried // SPDX-License-Identifier: GPL-2.0+
2*36adb7c9SRamon Fried /*
3*36adb7c9SRamon Fried  * Onboard memory detection for Snapdragon boards
4*36adb7c9SRamon Fried  *
5*36adb7c9SRamon Fried  * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
6*36adb7c9SRamon Fried  *
7*36adb7c9SRamon Fried  */
8*36adb7c9SRamon Fried 
9*36adb7c9SRamon Fried #include <common.h>
10*36adb7c9SRamon Fried #include <dm.h>
11*36adb7c9SRamon Fried #include <smem.h>
12*36adb7c9SRamon Fried #include <fdt_support.h>
13*36adb7c9SRamon Fried #include <asm/arch/dram.h>
14*36adb7c9SRamon Fried 
15*36adb7c9SRamon Fried #define SMEM_USABLE_RAM_PARTITION_TABLE 402
16*36adb7c9SRamon Fried #define RAM_PART_NAME_LENGTH            16
17*36adb7c9SRamon Fried #define RAM_NUM_PART_ENTRIES            32
18*36adb7c9SRamon Fried #define CATEGORY_SDRAM 0x0E
19*36adb7c9SRamon Fried #define TYPE_SYSMEM 0x01
20*36adb7c9SRamon Fried 
21*36adb7c9SRamon Fried struct smem_ram_ptable_hdr {
22*36adb7c9SRamon Fried 	u32 magic[2];
23*36adb7c9SRamon Fried 	u32 version;
24*36adb7c9SRamon Fried 	u32 reserved;
25*36adb7c9SRamon Fried 	u32 len;
26*36adb7c9SRamon Fried } __attribute__ ((__packed__));
27*36adb7c9SRamon Fried 
28*36adb7c9SRamon Fried struct smem_ram_ptn {
29*36adb7c9SRamon Fried 	char name[RAM_PART_NAME_LENGTH];
30*36adb7c9SRamon Fried 	u64 start;
31*36adb7c9SRamon Fried 	u64 size;
32*36adb7c9SRamon Fried 	u32 attr;
33*36adb7c9SRamon Fried 	u32 category;
34*36adb7c9SRamon Fried 	u32 domain;
35*36adb7c9SRamon Fried 	u32 type;
36*36adb7c9SRamon Fried 	u32 num_partitions;
37*36adb7c9SRamon Fried 	u32 reserved[3];
38*36adb7c9SRamon Fried } __attribute__ ((__packed__));
39*36adb7c9SRamon Fried 
40*36adb7c9SRamon Fried struct smem_ram_ptable {
41*36adb7c9SRamon Fried 	struct smem_ram_ptable_hdr hdr;
42*36adb7c9SRamon Fried 	u32 reserved;     /* Added for 8 bytes alignment of header */
43*36adb7c9SRamon Fried 	struct smem_ram_ptn parts[RAM_NUM_PART_ENTRIES];
44*36adb7c9SRamon Fried } __attribute__ ((__packed__));
45*36adb7c9SRamon Fried 
46*36adb7c9SRamon Fried #ifndef MEMORY_BANKS_MAX
47*36adb7c9SRamon Fried #define MEMORY_BANKS_MAX 4
48*36adb7c9SRamon Fried #endif
49*36adb7c9SRamon Fried 
msm_fixup_memory(void * blob)50*36adb7c9SRamon Fried int msm_fixup_memory(void *blob)
51*36adb7c9SRamon Fried {
52*36adb7c9SRamon Fried 	u64 bank_start[MEMORY_BANKS_MAX];
53*36adb7c9SRamon Fried 	u64 bank_size[MEMORY_BANKS_MAX];
54*36adb7c9SRamon Fried 	size_t size;
55*36adb7c9SRamon Fried 	int i;
56*36adb7c9SRamon Fried 	int count = 0;
57*36adb7c9SRamon Fried 	struct udevice *smem;
58*36adb7c9SRamon Fried 	int ret;
59*36adb7c9SRamon Fried 	struct smem_ram_ptable *ram_ptable;
60*36adb7c9SRamon Fried 	struct smem_ram_ptn *p;
61*36adb7c9SRamon Fried 
62*36adb7c9SRamon Fried 	ret = uclass_get_device_by_name(UCLASS_SMEM, "smem", &smem);
63*36adb7c9SRamon Fried 	if (ret < 0) {
64*36adb7c9SRamon Fried 		printf("Failed to find SMEM node. Check device tree\n");
65*36adb7c9SRamon Fried 		return 0;
66*36adb7c9SRamon Fried 	}
67*36adb7c9SRamon Fried 
68*36adb7c9SRamon Fried 	ram_ptable = smem_get(smem, -1, SMEM_USABLE_RAM_PARTITION_TABLE, &size);
69*36adb7c9SRamon Fried 
70*36adb7c9SRamon Fried 	if (!ram_ptable) {
71*36adb7c9SRamon Fried 		printf("Failed to find SMEM partition.\n");
72*36adb7c9SRamon Fried 		return -ENODEV;
73*36adb7c9SRamon Fried 	}
74*36adb7c9SRamon Fried 
75*36adb7c9SRamon Fried 	/* Check validy of RAM */
76*36adb7c9SRamon Fried 	for (i = 0; i < RAM_NUM_PART_ENTRIES; i++) {
77*36adb7c9SRamon Fried 		p = &ram_ptable->parts[i];
78*36adb7c9SRamon Fried 		if (p->category == CATEGORY_SDRAM && p->type == TYPE_SYSMEM) {
79*36adb7c9SRamon Fried 			bank_start[count] = p->start;
80*36adb7c9SRamon Fried 			bank_size[count] = p->size;
81*36adb7c9SRamon Fried 			debug("Detected memory bank %u: start: 0x%llx size: 0x%llx\n",
82*36adb7c9SRamon Fried 					count, p->start, p->size);
83*36adb7c9SRamon Fried 			count++;
84*36adb7c9SRamon Fried 		}
85*36adb7c9SRamon Fried 	}
86*36adb7c9SRamon Fried 
87*36adb7c9SRamon Fried 	if (!count) {
88*36adb7c9SRamon Fried 		printf("Failed to detect any memory bank\n");
89*36adb7c9SRamon Fried 		return -ENODEV;
90*36adb7c9SRamon Fried 	}
91*36adb7c9SRamon Fried 
92*36adb7c9SRamon Fried 	ret = fdt_fixup_memory_banks(blob, bank_start, bank_size, count);
93*36adb7c9SRamon Fried 	if (ret)
94*36adb7c9SRamon Fried 		return ret;
95*36adb7c9SRamon Fried 
96*36adb7c9SRamon Fried 	return 0;
97*36adb7c9SRamon Fried }
98*36adb7c9SRamon Fried 
99