sc7280: Add CPUCP firmware support

CPUCP is CPUSS Control Processor. It refers to the firmware for control
CPUSS active power management.

BUG=b:182963902
TEST=Validated on qualcomm sc7280 development board

Change-Id: Idac22c8cb231658616999bc577bdf49f9aa7ae74
Signed-off-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/49768
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Ravi Kumar Bokka 2021-01-21 02:54:48 +05:30 committed by Shelley Chen
parent b8b833fc6a
commit b0d48ed88b
7 changed files with 101 additions and 3 deletions

View File

@ -24,5 +24,6 @@ DECLARE_REGION(dram_modem_extra)
DECLARE_REGION(dram_wlan)
DECLARE_REGION(dram_wpss)
DECLARE_REGION(shrm)
DECLARE_REGION(dram_cpucp)
#endif // _SOC_QUALCOMM_SYMBOLS_COMMON_H_

View File

@ -37,6 +37,7 @@ ramstage-y += soc.c
ramstage-y += cbmem.c
ramstage-$(CONFIG_DRIVERS_UART) += ../common/qupv3_uart.c
ramstage-y += ../common/aop_load_reset.c
ramstage-y += cpucp_load_reset.c
################################################################################
@ -111,6 +112,14 @@ $(AOP_CBFS)-type := payload
$(AOP_CBFS)-compression := $(CBFS_COMPRESS_FLAG)
cbfs-files-y += $(AOP_CBFS)
################################################################################
CPUCP_FILE := $(SC7280_BLOB)/cpucp/cpucp.elf
CPUCP_CBFS := $(CONFIG_CBFS_PREFIX)/cpucp
$(CPUCP_CBFS)-file := $(CPUCP_FILE)
$(CPUCP_CBFS)-type := payload
$(CPUCP_CBFS)-compression := $(CBFS_COMPRESS_FLAG)
cbfs-files-y += $(CPUCP_CBFS)
################################################################################
SHRM_FILE := $(SC7280_BLOB)/shrm/shrm.elf
SHRM_CBFS := $(CONFIG_CBFS_PREFIX)/shrm

View File

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <assert.h>
#include <delay.h>
#include <cbfs.h>
#include <console/console.h>
#include <soc/mmu.h>
#include <soc/cpucp.h>
#include <soc/clock.h>
#include <device/mmio.h>
#include <timer.h>
void cpucp_prepare(void)
{
/* allow NS access to EPSS memory*/
setbits32(&epss_top->access_override, 0x1);
/* Enable subsystem clock. Required for CPUCP PDMEM access*/
setbits32(&epss_fast->epss_muc_clk_ctrl, 0x1);
if (!wait_ms(300, ((read32(&epss_fast->epss_muc_clk_ctrl) & 0x1) != 0x1)))
printk(BIOS_ERR, "%s: cannot get CPUCP PDMEM access.\n", __func__);
}
void cpucp_fw_load_reset(void)
{
struct prog cpucp_fw_prog =
PROG_INIT(PROG_PAYLOAD, CONFIG_CBFS_PREFIX "/cpucp");
cpucp_prepare();
if (!selfload(&cpucp_fw_prog))
die("SOC image: CPUCP load failed");
printk(BIOS_DEBUG, "SOC:CPUCP image loaded successfully.\n");
}

View File

@ -55,4 +55,7 @@
#define QUP_WRAP1_BASE 0x00AC0000
#define QUP_1_GSI_BASE 0x00A04000
#define EPSSTOP_EPSS_TOP 0x18598000
#define EPSSFAST_BASE_ADDR 0x18580000
#endif /* __SOC_QUALCOMM_SC7280_ADDRESS_MAP_H__ */

View File

@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_QUALCOMM_SC7280_CPUCP_H__
#define _SOC_QUALCOMM_SC7280_CPUCP_H__
#include <soc/addressmap.h>
struct epsstop_epss_top {
uint32_t access_override;
uint32_t global_enable;
uint32_t trace_bus_ctrl;
uint32_t debug_bus_ctrl;
uint32_t muc_hang_det_ctrl;
uint32_t muc_hang_irq_sts;
uint32_t muc_hang_count_threshold;
uint32_t muc_hang_count_sts;
uint32_t muc_hang_det_sts;
uint32_t l3_voting_en;
};
struct epssfast_epss_fast {
uint32_t epss_muc_clk_ctrl;
uint32_t muc_rvbar;
uint32_t muc_rvbar_ctrl;
uint32_t muc_non_secure_dmem_start_addr;
uint32_t muc_non_secure_dmem_end_addr;
uint32_t reserved_1[2];
uint32_t cpr_data_fifo[4];
uint32_t reserved_2[4];
uint32_t pll_data_fifo[4];
uint32_t reserved_3[4];
uint32_t gfmux_data_fifo_1[4];
uint32_t cpu_pcu_spare_irq_status;
uint32_t cpu_pcu_spare_irq_clr;
uint32_t cpu_pcu_spare_wait_event;
uint32_t seq_mem[256];
};
static struct epsstop_epss_top *const epss_top = (void *)EPSSTOP_EPSS_TOP;
static struct epssfast_epss_fast *const epss_fast = (void *)EPSSFAST_BASE_ADDR;
void cpucp_fw_load_reset(void);
void cpucp_prepare(void);
#endif // _SOC_QUALCOMM_SC7280_CPUCP_H__

View File

@ -54,9 +54,10 @@ SECTIONS
/* Various hardware/software subsystems make use of this area */
REGION(dram_aop, 0x80800000, 0x080000, 0x1000)
REGION(dram_soc, 0x80900000, 0x200000, 0x1000)
BL31(0x80B00000, 1M)
REGION(dram_cpucp,0x80B00000, 0x100000, 0x1000)
REGION(dram_wlan, 0x80C00000, 0xC00000, 0x1000)
REGION(dram_wpss, 0x9AE00000, 0x1900000, 0x1000)
POSTRAM_CBFS_CACHE(0x9F800000, 16M)
RAMSTAGE(0xA0800000, 16M)
BL31(0xC0000000, 1M)
}

View File

@ -5,6 +5,7 @@
#include <soc/mmu_common.h>
#include <soc/symbols_common.h>
#include <soc/aop_common.h>
#include <soc/cpucp.h>
static void soc_read_resources(struct device *dev)
{
@ -13,16 +14,19 @@ static void soc_read_resources(struct device *dev)
reserved_ram_resource(dev, 1, (uintptr_t)_dram_soc / KiB,
REGION_SIZE(dram_soc) / KiB);
reserved_ram_resource(dev, 2, (uintptr_t)_dram_wlan / KiB,
REGION_SIZE(dram_wlan) / KiB);
REGION_SIZE(dram_wlan) / KiB);
reserved_ram_resource(dev, 3, (uintptr_t)_dram_wpss / KiB,
REGION_SIZE(dram_wpss) / KiB);
REGION_SIZE(dram_wpss) / KiB);
reserved_ram_resource(dev, 4, (uintptr_t)_dram_aop / KiB,
REGION_SIZE(dram_aop) / KiB);
reserved_ram_resource(dev, 5, (uintptr_t)_dram_cpucp / KiB,
REGION_SIZE(dram_cpucp) / KiB);
}
static void soc_init(struct device *dev)
{
aop_fw_load_reset();
cpucp_fw_load_reset();
}
static struct device_operations soc_ops = {