soc/qc/x1p42100: Dynamically configure DRAM resources in ramstage

This commit updates the x1p42100 platform to support a dynamic memory
layout for DRAM. This is a crucial step toward supporting different
board variants with varying memory capacities.

The changes involve:

- ramstage build: The mmu.c source file is now included in the ramstage
build, providing the necessary functions to configure the Memory
Management Unit (MMU) for fragmented memory regions.

- Linker Script (memlayout.ld): The dram_space_1 and dram_space_2
regions are statically defined with their maximum possible sizes.

- SoC Initialization (soc.c): The soc_read_resources function is
refactored to use a new helper function, qc_get_soc_dram_space_config,
to retrieve a list of available DRAM regions. It then iterates through
this list to dynamically register each memory region with ram_range.
This replaces the previous static ram_range call with a more flexible
approach that can handle fragmented memory maps. Reserved regions are
also updated to use a dynamic index.

This refactoring allows the system to correctly handle memory maps for
devices with more than 2GB of DRAM, which was a limitation of the
previous static configuration.

TEST=Able to build and boot google/quenbi w/ 16GB of DRAM (using
DDR_SPACE and DDR_SPACE_1 regions).

Change-Id: If94644110272713f77db5a0dd6d23ec0798a15f0
Signed-off-by: Subrata Banik <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/88753
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Subrata Banik 2025-08-15 00:51:57 +05:30
commit 1b760645b9
3 changed files with 34 additions and 6 deletions

View file

@ -40,6 +40,7 @@ romstage-$(CONFIG_DRIVERS_UART) += ../common/qupv3_uart.c
################################################################################
ramstage-y += soc.c
ramstage-y += cbmem.c
ramstage-y += ../common/mmu.c
ramstage-$(CONFIG_DRIVERS_UART) += ../common/qupv3_uart.c
ramstage-$(CONFIG_PCI) += ../common/pcie_common.c
ramstage-$(CONFIG_PCI) += pcie.c

View file

@ -65,4 +65,23 @@ SECTIONS
REGION(dram_tz, 0xD8000000, 0xD6000, 0x1000)
BL31(0xD80D6000, 1M)
REGION(dram_tz_rem, 0xD81D6000, 0x72EA000, 0x1000)
DRAM_END(0x100000000)
/*
* Define the address range limits for fragmented DRAM regions.
*
* These regions, `dram_space_1` and `dram_space_2`, are used to map physical
* memory beyond the initial `_dram` region. The MMU configuration logic in
* `mmu.c` uses `REGION_SIZE()` to dynamically size these ranges based on the
* total system DRAM capacity, which is determined by the QCLib.
*
* Example for a 16GB DRAM system:
* - `_dram` (2GB): 0x80000000 - 0x100000000
* - `_dram_space_1` (14GB): 0x880000000 - 0x440000000 (0x880000000 + 14GB)
*
* Note: The example memory addresses are for illustration and depend on the
* platform's specific memory map.
*/
REGION(dram_space_1, 0x880000000, 0x780000000, 4K)
REGION(dram_space_2, 0x8800000000, 0x7800000000, 4K)
}

View file

@ -12,16 +12,24 @@ static struct device_operations pci_domain_ops = {
.scan_bus = &pci_host_bridge_scan_bus,
.enable = &qcom_setup_pcie_host,
};
static void soc_read_resources(struct device *dev)
{
ram_range(dev, 0, (uintptr_t)region_offset(ddr_region), region_sz(ddr_region));
reserved_ram_range(dev, 1, (uintptr_t)_dram_cpucp_dtbs, REGION_SIZE(dram_cpucp_dtbs));
reserved_ram_range(dev, 2, (uintptr_t)_dram_cpucp, REGION_SIZE(dram_cpucp));
int index = 0;
int count;
struct region *config = qc_get_soc_dram_space_config(region_sz(ddr_region),
&count);
reserved_ram_range(dev, 3, (uintptr_t)_dram_tz, REGION_SIZE(dram_tz));
reserved_ram_range(dev, 4, (uintptr_t)_dram_tz_rem, REGION_SIZE(dram_tz_rem));
for (int i = 0; i < count; i++)
ram_range(dev, index++, (uintptr_t)config[i].offset, config[i].size);
reserved_ram_range(dev, 5, (uintptr_t)_dram_aop, REGION_SIZE(dram_aop));
reserved_ram_range(dev, index++, (uintptr_t)_dram_cpucp_dtbs, REGION_SIZE(dram_cpucp_dtbs));
reserved_ram_range(dev, index++, (uintptr_t)_dram_cpucp, REGION_SIZE(dram_cpucp));
reserved_ram_range(dev, index++, (uintptr_t)_dram_tz, REGION_SIZE(dram_tz));
reserved_ram_range(dev, index++, (uintptr_t)_dram_tz_rem, REGION_SIZE(dram_tz_rem));
reserved_ram_range(dev, index++, (uintptr_t)_dram_aop, REGION_SIZE(dram_aop));
}
static void soc_init(struct device *dev)