Merge changes I6bf1db15,I8631c34a,Id76ada14 into integration

* changes:
  qti/sc7180: Do shutdown handling outside qtiseclib
  qti: Add SPMI PMIC arbitrator driver
  qti/sc7180: Fix GIC-600 support setting
This commit is contained in:
Madhukar Pappireddy 2020-08-26 14:59:05 +00:00 committed by TrustedFirmware Code Review
commit a4c979ade4
9 changed files with 206 additions and 19 deletions

View File

@ -50,4 +50,7 @@ unsigned int plat_qti_my_cluster_pos(void);
void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr);
void qti_pmic_prepare_reset(void);
void qti_pmic_prepare_shutdown(void);
#endif /* QTI_PLAT_H */

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2020, Google LLC. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SPMI_ARB_H
#define SPMI_ARB_H
#include <stdint.h>
/*******************************************************************************
* WARNING: This driver does not arbitrate access with the kernel. These APIs
* must only be called when the kernel is known to be quiesced (such as before
* boot or while the system is shutting down).
******************************************************************************/
/* 32-bit addresses combine (U)SID, PID and register address. */
int spmi_arb_read8(uint32_t addr);
int spmi_arb_write8(uint32_t addr, uint8_t data);
#endif /* SPMI_ARB_H */

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2020, Google LLC. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <drivers/delay_timer.h>
#include <qti_plat.h>
#include <spmi_arb.h>
/*
* This driver implements PON support for PM8998-compatible PMICs. This can
* include other part numbers like PM6150.
*/
#define PON_PS_HOLD_RESET_CTL 0x85a
#define RESET_TYPE_WARM_RESET 1
#define RESET_TYPE_SHUTDOWN 4
#define PON_PS_HOLD_RESET_CTL2 0x85b
#define S2_RESET_EN BIT(7)
static void configure_ps_hold(uint32_t reset_type)
{
/* QTI recommends disabling reset for 10 cycles before reconfiguring. */
spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, 0);
mdelay(1);
spmi_arb_write8(PON_PS_HOLD_RESET_CTL, reset_type);
spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, S2_RESET_EN);
mdelay(1);
}
void qti_pmic_prepare_reset(void)
{
configure_ps_hold(RESET_TYPE_WARM_RESET);
}
void qti_pmic_prepare_shutdown(void)
{
configure_ps_hold(RESET_TYPE_SHUTDOWN);
}

View File

@ -9,6 +9,8 @@
#include <arch_helpers.h>
#include <bl31/bl31.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <platform.h>
@ -204,14 +206,25 @@ __dead2 void qti_domain_power_down_wfi(const psci_power_state_t *target_state)
/* We should never reach here */
}
static __dead2 void assert_ps_hold(void)
{
mmio_write_32(QTI_PS_HOLD_REG, 0);
mdelay(1000);
/* Should be dead before reaching this. */
panic();
}
__dead2 void qti_system_off(void)
{
qtiseclib_psci_system_off();
qti_pmic_prepare_shutdown();
assert_ps_hold();
}
__dead2 void qti_system_reset(void)
{
qtiseclib_psci_system_reset();
qti_pmic_prepare_reset();
assert_ps_hold();
}
void qti_get_sys_suspend_power_state(psci_power_state_t *req_state)

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2020, Google LLC. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <spmi_arb.h>
#define REG_APID_MAP(apid) (0x0C440900 + 4 * i)
#define NUM_APID 0x80
#define PPID_MASK (0xfff << 8)
#define REG_ARB_CMD(apid) (0x0C600000 + 0x10000 * apid)
/* These are opcodes specific to this SPMI arbitrator, *not* SPMI commands. */
#define OPC_EXT_WRITEL 0
#define OPC_EXT_READL 1
#define REG_ARB_STATUS(apid) (0x0C600008 + 0x10000 * apid)
#define ARB_STATUS_DONE BIT(0)
#define ARB_STATUS_FAILURE BIT(1)
#define ARB_STATUS_DENIED BIT(2)
#define ARB_STATUS_DROPPED BIT(3)
/* Fake status to report driver errors. */
#define ARB_FAKE_STATUS_TIMEOUT BIT(8)
#define REG_ARB_RDATA0(apid) (0x0C600018 + 0x10000 * apid)
#define REG_ARB_WDATA0(apid) (0x0C600010 + 0x10000 * apid)
static int addr_to_apid(uint32_t addr)
{
unsigned int i;
for (i = 0U; i < NUM_APID; i++) {
uint32_t reg = mmio_read_32(REG_APID_MAP(i));
if ((reg != 0U) && ((addr & PPID_MASK) == (reg & PPID_MASK))) {
return i;
}
}
return -1;
}
static int wait_for_done(uint16_t apid)
{
unsigned int timeout = 100;
while (timeout-- != 0U) {
uint32_t status = mmio_read_32(REG_ARB_STATUS(apid));
if ((status & ARB_STATUS_DONE) != 0U) {
if ((status & ARB_STATUS_FAILURE) != 0U ||
(status & ARB_STATUS_DENIED) != 0U ||
(status & ARB_STATUS_DROPPED) != 0U) {
return status & 0xff;
}
return 0;
}
mdelay(1);
}
ERROR("SPMI_ARB timeout!\n");
return ARB_FAKE_STATUS_TIMEOUT;
}
static void arb_command(uint16_t apid, uint8_t opcode, uint32_t addr,
uint8_t bytes)
{
mmio_write_32(REG_ARB_CMD(apid), (uint32_t)opcode << 27 |
(addr & 0xff) << 4 | (bytes - 1));
}
int spmi_arb_read8(uint32_t addr)
{
int apid = addr_to_apid(addr);
if (apid < 0) {
return apid;
}
arb_command(apid, OPC_EXT_READL, addr, 1);
int ret = wait_for_done(apid);
if (ret != 0) {
ERROR("SPMI_ARB read error [0x%x]: 0x%x\n", addr, ret);
return ret;
}
return mmio_read_32(REG_ARB_RDATA0(apid)) & 0xff;
}
int spmi_arb_write8(uint32_t addr, uint8_t data)
{
int apid = addr_to_apid(addr);
if (apid < 0) {
return apid;
}
mmio_write_32(REG_ARB_WDATA0(apid), data);
arb_command(apid, OPC_EXT_WRITEL, addr, 1);
int ret = wait_for_done(apid);
if (ret != 0) {
ERROR("SPMI_ARB write error [0x%x] = 0x%x: 0x%x\n",
addr, data, ret);
}
return ret;
}

View File

@ -78,10 +78,6 @@ void qtiseclib_psci_cpu_standby(uint8_t pwr_state);
void qtiseclib_psci_node_power_off(const uint8_t *states);
void qtiseclib_psci_node_suspend(const uint8_t *states);
void qtiseclib_psci_node_suspend_finish(const uint8_t *states);
__attribute__ ((noreturn))
void qtiseclib_psci_system_off(void);
__attribute__ ((noreturn))
void qtiseclib_psci_system_reset(void);
void qtiseclib_disable_cluster_coherency(uint8_t state);
#endif /* QTISECLIB_INTERFACE_H */

View File

@ -108,18 +108,6 @@ void qtiseclib_psci_node_suspend_finish(const uint8_t *states)
{
}
void qtiseclib_psci_system_off(void)
{
while (1) {
};
}
void qtiseclib_psci_system_reset(void)
{
while (1) {
};
}
void qtiseclib_disable_cluster_coherency(uint8_t state)
{
}

View File

@ -173,4 +173,10 @@
*/
#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
/*----------------------------------------------------------------------------*/
/* AOSS registers */
/*----------------------------------------------------------------------------*/
#define QTI_PS_HOLD_REG 0x0C264000
/*----------------------------------------------------------------------------*/
#endif /* PLATFORM_DEF_H */

View File

@ -51,6 +51,7 @@ QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \
$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S \
$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S \
$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \
$(QTI_PLAT_PATH)/common/src/pm8998.c \
$(QTI_PLAT_PATH)/common/src/qti_stack_protector.c \
$(QTI_PLAT_PATH)/common/src/qti_common.c \
$(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \
@ -60,6 +61,7 @@ QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \
$(QTI_PLAT_PATH)/common/src/qti_topology.c \
$(QTI_PLAT_PATH)/common/src/qti_pm.c \
$(QTI_PLAT_PATH)/common/src/qti_rng.c \
$(QTI_PLAT_PATH)/common/src/spmi_arb.c \
$(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c \
@ -79,7 +81,7 @@ include lib/coreboot/coreboot.mk
PSCI_SOURCES := plat/common/plat_psci_common.c \
# GIC-600 configuration
GICV3_IMPL := GIC600
GICV3_SUPPORT_GIC600 := 1
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk