libs:xilpm_v1_0: Adding Power Management Library for ZynqMP
swbeta2 commit 8e824dfe3b169461916c0190194a3eb5a7810b1a xilpm provides a set of APIs which can be used by standalone applications to call in PMUFW power management APIs via IPI. Self-suspend example is provided to demonstrate the usage of this library. Signed-off-by: Jyotheeswar Reddy <jyothee@xilinx.com>
This commit is contained in:
parent
91f8d3bf88
commit
ef6ec50aa5
20 changed files with 7586 additions and 0 deletions
42
lib/sw_services/xilpm/data/xilpm.mld
Normal file
42
lib/sw_services/xilpm/data/xilpm.mld
Normal file
|
@ -0,0 +1,42 @@
|
|||
#/******************************************************************************
|
||||
#*
|
||||
#* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
#*
|
||||
#* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
#* of this software and associated documentation files (the "Software"), to deal
|
||||
#* in the Software without restriction, including without limitation the rights
|
||||
#* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
#* copies of the Software, and to permit persons to whom the Software is
|
||||
#* furnished to do so, subject to the following conditions:
|
||||
#*
|
||||
#* The above copyright notice and this permission notice shall be included in
|
||||
#* all copies or substantial portions of the Software.
|
||||
#*
|
||||
#* Use of the Software is limited solely to applications:
|
||||
#* (a) running on a Xilinx device, or
|
||||
#* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
#*
|
||||
#* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
#* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
#* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
#* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
#* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
#* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
#* SOFTWARE.
|
||||
#*
|
||||
#* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
#* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
#* this Software without prior written authorization from Xilinx.
|
||||
#*
|
||||
#******************************************************************************/
|
||||
|
||||
OPTION psf_version = 2.1;
|
||||
|
||||
BEGIN LIBRARY xilpm
|
||||
OPTION copyfiles = all;
|
||||
OPTION REQUIRES_OS = (standalone);
|
||||
OPTION APP_LINKER_FLAGS = "-Wl,--start-group,-lxilpm,-lxil,-lgcc,-lc,--end-group";
|
||||
OPTION desc = "Power Management API Library for ZynqMP";
|
||||
OPTION VERSION = 1.0;
|
||||
OPTION NAME = xilpm;
|
||||
END LIBRARY
|
105
lib/sw_services/xilpm/data/xilpm.tcl
Normal file
105
lib/sw_services/xilpm/data/xilpm.tcl
Normal file
|
@ -0,0 +1,105 @@
|
|||
#/******************************************************************************
|
||||
#*
|
||||
#* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
#*
|
||||
#* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
#* of this software and associated documentation files (the "Software"), to deal
|
||||
#* in the Software without restriction, including without limitation the rights
|
||||
#* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
#* copies of the Software, and to permit persons to whom the Software is
|
||||
#* furnished to do so, subject to the following conditions:
|
||||
#*
|
||||
#* The above copyright notice and this permission notice shall be included in
|
||||
#* all copies or substantial portions of the Software.
|
||||
#*
|
||||
#* Use of the Software is limited solely to applications:
|
||||
#* (a) running on a Xilinx device, or
|
||||
#* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
#*
|
||||
#* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
#* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
#* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
#* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
#* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
#* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
#* SOFTWARE.
|
||||
#*
|
||||
#* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
#* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
#* this Software without prior written authorization from Xilinx.
|
||||
#*
|
||||
#******************************************************************************/
|
||||
|
||||
proc generate {libhandle} {
|
||||
# Copy over the right set of files as src based on processor type
|
||||
set sw_proc_handle [hsi::get_sw_processor]
|
||||
set hw_proc_handle [hsi::get_cells [common::get_property HW_INSTANCE $sw_proc_handle] ]
|
||||
set proctype [common::get_property IP_NAME $hw_proc_handle]
|
||||
set procname [common::get_property NAME $hw_proc_handle]
|
||||
|
||||
set cortexa53srcdir "./src/apu"
|
||||
set cortexr5srcdir "./src/rpu"
|
||||
|
||||
set commonsrcdir "./src/common"
|
||||
|
||||
foreach entry [glob -nocomplain [file join $commonsrcdir *]] {
|
||||
file copy -force $entry "./src"
|
||||
}
|
||||
|
||||
switch $proctype {
|
||||
"psu_cortexa53" {
|
||||
foreach entry [glob -nocomplain [file join $cortexa53srcdir *]] {
|
||||
file copy -force $entry "./src/"
|
||||
}
|
||||
}
|
||||
|
||||
"psu_cortexr5" {
|
||||
foreach entry [glob -nocomplain [file join $cortexr5srcdir *]] {
|
||||
file copy -force $entry "./src/"
|
||||
}
|
||||
}
|
||||
|
||||
"default" {error "Error: Processor type $proctype is not supported\n"}
|
||||
|
||||
}
|
||||
|
||||
file delete -force $cortexr5srcdir
|
||||
file delete -force $cortexa53srcdir
|
||||
file delete -force $commonsrcdir
|
||||
|
||||
}
|
||||
|
||||
|
||||
#-------
|
||||
# post_generate: called after generate called on all libraries
|
||||
#-------
|
||||
proc post_generate {libhandle} {
|
||||
xgen_opts_file $libhandle
|
||||
}
|
||||
|
||||
#-------
|
||||
# execs_generate: called after BSP's, libraries and drivers have been compiled
|
||||
#-------
|
||||
proc execs_generate {libhandle} {
|
||||
|
||||
}
|
||||
|
||||
proc xgen_opts_file {libhandle} {
|
||||
|
||||
# Copy the include files to the include directory
|
||||
set srcdir src
|
||||
set dstdir [file join .. .. include]
|
||||
|
||||
# Create dstdir if it does not exist
|
||||
if { ! [file exists $dstdir] } {
|
||||
file mkdir $dstdir
|
||||
}
|
||||
|
||||
# Get list of files in the srcdir
|
||||
set sources [glob -join $srcdir *.h]
|
||||
|
||||
# Copy each of the files in the list to dstdir
|
||||
foreach source $sources {
|
||||
file copy -force $source $dstdir
|
||||
}
|
||||
}
|
128
lib/sw_services/xilpm/examples/gic_setup.c
Normal file
128
lib/sw_services/xilpm/examples/gic_setup.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* CONTENT
|
||||
* Generic functions for gic initialization and interrupt enabling
|
||||
*********************************************************************/
|
||||
|
||||
#include "gic_setup.h"
|
||||
|
||||
XScuGic GicInst;
|
||||
/**
|
||||
* GicSetupHandler() - Connect interrupt Handler to the specified interrupt number
|
||||
* @IntId Interrupt id
|
||||
* @PeriphInstPtr Pointer to the peripheral driver
|
||||
* @Handler Interrupt Handler that for the specified peripheral
|
||||
*
|
||||
* @return Status of operation success (XST_* from xstatus.h)
|
||||
*/
|
||||
int32_t GicSetupHandler(uint32_t IntId, void *PeriphInstPtr, Xil_ExceptionHandler Handler)
|
||||
{
|
||||
int32_t status;
|
||||
/*
|
||||
* Connect a device driver Handler that will be called when an
|
||||
* interrupt for the device occurs, the device driver Handler
|
||||
* performs the specific interrupt processing for the device
|
||||
*/
|
||||
status = XScuGic_Connect(&GicInst, IntId,
|
||||
Handler,
|
||||
PeriphInstPtr);
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* GicEnableInterrupt() - Enable interrupt in gic
|
||||
*/
|
||||
void GicEnableInterrupt(uint32_t IntId)
|
||||
{
|
||||
XScuGic_Enable(&GicInst, IntId);
|
||||
}
|
||||
|
||||
/**
|
||||
* GicInit() - Initialize gic
|
||||
*
|
||||
* @return Status of operation success (XST_* from xstatus.h)
|
||||
*/
|
||||
int32_t GicInit()
|
||||
{
|
||||
int32_t Status;
|
||||
XScuGic_Config *GicCfgPtr;
|
||||
/* Initialize the interrupt controller driver */
|
||||
GicCfgPtr = XScuGic_LookupConfig(INTC_DEVICE_ID);
|
||||
if (NULL == GicCfgPtr)
|
||||
return XST_FAILURE;
|
||||
|
||||
Status = XScuGic_CfgInitialize(&GicInst, GicCfgPtr, GicCfgPtr->CpuBaseAddress);
|
||||
if (XST_SUCCESS != Status)
|
||||
return Status;
|
||||
|
||||
/*
|
||||
* Connect the interrupt controller interrupt Handler to the
|
||||
* hardware interrupt handling logic in the processor.
|
||||
*/
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
&GicInst);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* GicSetupInterruptSystem() - configure the system to receive peripheral interrupt
|
||||
* @IntId interrupt id of the timer
|
||||
* @PeriphInstPtr peripheral
|
||||
* @Handler interrupt Handler
|
||||
*
|
||||
* Does everything that is needed for enabling interrupts (gic setup, Handler connecting,
|
||||
* interrupt enabling on processor and gic level)
|
||||
*
|
||||
* @return: status of operation success (XST_* from xstatus.h)
|
||||
*/
|
||||
int32_t GicSetupInterruptSystem(uint32_t IntId,
|
||||
void *PeriphInstPtr, Xil_ExceptionHandler Handler)
|
||||
{
|
||||
int32_t Status;
|
||||
|
||||
Status = GicInit();
|
||||
if(XST_SUCCESS != Status)
|
||||
return Status;
|
||||
|
||||
Status = GicSetupHandler(IntId, PeriphInstPtr, Handler);
|
||||
if(XST_SUCCESS != Status)
|
||||
return Status;
|
||||
|
||||
GicEnableInterrupt(IntId);
|
||||
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
50
lib/sw_services/xilpm/examples/gic_setup.h
Normal file
50
lib/sw_services/xilpm/examples/gic_setup.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _GIC_SETUP_H_
|
||||
#define _GIC_SETUP_H_
|
||||
|
||||
#include <xscugic.h>
|
||||
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
|
||||
extern XScuGic GicInst;
|
||||
|
||||
int32_t GicSetupHandler(uint32_t IntId, void *PeriphInstPtr, Xil_ExceptionHandler Handler);
|
||||
|
||||
void GicEnableInterrupt(uint32_t IntId);
|
||||
|
||||
int32_t GicSetupInterruptSystem(uint32_t IntId,
|
||||
void *PeriphInstPtr, Xil_ExceptionHandler Handler);
|
||||
|
||||
int32_t GicInit();
|
||||
#endif
|
133
lib/sw_services/xilpm/examples/timer.c
Normal file
133
lib/sw_services/xilpm/examples/timer.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* CONTENT
|
||||
* Timer peripheral driver. Code is mostly reused from
|
||||
* hello_ttc0_interrupt application.
|
||||
*********************************************************************/
|
||||
|
||||
#include <xil_exception.h>
|
||||
#include <xil_printf.h>
|
||||
|
||||
#include <xttcps.h>
|
||||
#include "timer.h"
|
||||
#include "gic_setup.h"
|
||||
#include "pm_client.h"
|
||||
|
||||
volatile uint32_t TickCount = 0;
|
||||
static XTtcPs timer0_inst;
|
||||
|
||||
/**
|
||||
* TickHandler() - interrupt handler for timer 0
|
||||
* @timer_inst: pointer to the timer instance
|
||||
*/
|
||||
static void TickHandler(XTtcPs *timer_inst)
|
||||
{
|
||||
uint32_t int_status = XTtcPs_GetInterruptStatus(timer_inst);
|
||||
int_status &= XTtcPs_ReadReg(timer_inst->Config.BaseAddress, XTTCPS_IER_OFFSET);
|
||||
XTtcPs_ClearInterruptStatus(timer_inst, int_status);
|
||||
TickCount++;
|
||||
pm_dbg("Timer0 interrupt handler, tick_count = %d\n", TickCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* TimerSetIntervalMode() - This fuction sets TTC into interval mode
|
||||
* @timer_inst pointer to the timer instance
|
||||
* @sec interval timeout in seconds
|
||||
*/
|
||||
static void TimerSetIntervalMode(XTtcPs *TimerInstPtr, uint32_t PeriodInSec)
|
||||
{
|
||||
/* Stop the timer */
|
||||
XTtcPs_Stop(TimerInstPtr);
|
||||
/* Set Interval mode */
|
||||
XTtcPs_SetOptions(TimerInstPtr, XTTCPS_OPTION_INTERVAL_MODE);
|
||||
XTtcPs_SetInterval(TimerInstPtr, (PeriodInSec * COUNT_PER_SEC));
|
||||
XTtcPs_ResetCounterValue(TimerInstPtr);
|
||||
XTtcPs_SetPrescaler(TimerInstPtr, 15);
|
||||
/* Enable interrupt */
|
||||
XTtcPs_EnableInterrupts(TimerInstPtr, XTTCPS_IXR_INTERVAL_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* TimerInit() - initializes timer0 device
|
||||
* @timeout period for the interval timer interrupt generation
|
||||
*/
|
||||
int32_t TimerInit(uint32_t PeriodInSec)
|
||||
{
|
||||
int32_t status;
|
||||
XTtcPs_Config *timer_config;
|
||||
/* Look up the configuration based on the device identifier */
|
||||
timer_config = XTtcPs_LookupConfig(TTC0_0_DEVICE_ID);
|
||||
if (NULL == timer_config) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/* Initialize the device */
|
||||
status = XTtcPs_CfgInitialize(&timer0_inst, timer_config, timer_config->BaseAddress);
|
||||
if (XST_SUCCESS != status) {
|
||||
return status;
|
||||
}
|
||||
/* Setup interrupts */
|
||||
status = GicSetupInterruptSystem(TTC_INT_ID0,
|
||||
&timer0_inst, (Xil_ExceptionHandler) TickHandler);
|
||||
if (XST_SUCCESS == status) {
|
||||
TimerSetIntervalMode(&timer0_inst, PeriodInSec);
|
||||
XTtcPs_Start(&timer0_inst);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* TimerConfigure() - configure timer to generate periodic interrupts
|
||||
* timer_period Time between two timer ticks
|
||||
*
|
||||
* @return Status of configuration success
|
||||
*/
|
||||
int32_t TimerConfigure(uint32_t Period)
|
||||
{
|
||||
int32_t ret_status = TimerInit(Period);
|
||||
switch (ret_status) {
|
||||
case XST_SUCCESS:
|
||||
pm_dbg("OK, configured timer\n");
|
||||
break;
|
||||
case XST_DEVICE_IS_STARTED:
|
||||
pm_dbg("WARNING, timer is already counting\n");
|
||||
break;
|
||||
case XST_FAILURE:
|
||||
pm_dbg("ERROR, failed to configure timer\n");
|
||||
break;
|
||||
default:
|
||||
pm_dbg("??? unhandled status %d\n", ret_status);
|
||||
break;
|
||||
}
|
||||
return ret_status;
|
||||
}
|
55
lib/sw_services/xilpm/examples/timer.h
Normal file
55
lib/sw_services/xilpm/examples/timer.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* CONTENT
|
||||
* Timer interface, contains function to initialize timer and
|
||||
* global variable tick_count which stores total number of interrupts
|
||||
* generated by the timer.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#define TTC0_0_DEVICE_ID XPAR_XTTCPS_0_DEVICE_ID
|
||||
#define COUNT_PER_SEC (XPAR_XTTCPS_0_CLOCK_HZ / 65535)
|
||||
#define TTC_INT_ID0 XPAR_XTTCPS_0_INTR
|
||||
|
||||
#define TIMER_PERIOD 3
|
||||
|
||||
int32_t TimerInit(uint32_t timeout);
|
||||
|
||||
int32_t TimerConfigure(uint32_t timer_period);
|
||||
|
||||
extern volatile uint32_t TickCount;
|
||||
|
||||
#endif /* _TIMER_H_ */
|
193
lib/sw_services/xilpm/examples/xilpm_selfsuspend_example.c
Normal file
193
lib/sw_services/xilpm/examples/xilpm_selfsuspend_example.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* CONTENT
|
||||
* Assumptions: only PROCESSOR core is executing this code,
|
||||
* other cores in PROCESSOR subsystem are already powered down.
|
||||
* 1) PROCESSOR configures timer0 peripheral to generate interrupts.
|
||||
* 2) PROCESSOR waits for few interrupts to be generated by the timer and
|
||||
* then initiates self suspend. Before calling pm_self_suspend APU
|
||||
* has saved its context (which is in this case only tick_count
|
||||
* variable value) in CONTEXT memory. Suspending of the PROCESSOR is followed
|
||||
* by CONTEXT retention.
|
||||
* 3) Timer is still counting while PROCESSOR is suspended and the next timer
|
||||
* interrupt causes CONTEXT to be woken up by PMU.
|
||||
* 4) Processor resumes its execution, meaning that it restores value of
|
||||
* tick_count from CONTEXT MEM and does not configure timer again because it
|
||||
* is already configured. PROCESSOR enables interrupts at the processor
|
||||
* level (CPSR) and handle timer interrupt that caused wake-up.
|
||||
* 5) PROCESSOR waits for few more timer interrupts and repeats the suspend
|
||||
* procedure.
|
||||
*********************************************************************/
|
||||
|
||||
#include <xil_exception.h>
|
||||
#include <xil_printf.h>
|
||||
#include <xil_io.h>
|
||||
#include <xil_cache.h>
|
||||
#include <xstatus.h>
|
||||
#include <sleep.h>
|
||||
#include "pm_api_sys.h"
|
||||
#include "timer.h"
|
||||
#include "pm_client.h"
|
||||
|
||||
#ifdef __aarch64__
|
||||
/* Use OCM for saving context */
|
||||
#define CONTEXT_MEM_BASE 0xFFFC0000U
|
||||
#else
|
||||
/* Use TCM for saving context */
|
||||
#define CONTEXT_MEM_BASE 0x20000U
|
||||
#endif
|
||||
|
||||
/* The below sections will be saved during suspend */
|
||||
extern uint8_t __data_start;
|
||||
extern uint8_t __bss_start__;
|
||||
extern uint8_t __data_end;
|
||||
extern uint8_t __bss_end__;
|
||||
|
||||
/**
|
||||
* SaveContext() - called to save context of bss and data sections in OCM
|
||||
*/
|
||||
static void SaveContext(void)
|
||||
{
|
||||
uint8_t *MemPtr;
|
||||
uint8_t *ContextMemPtr = (uint8_t *)CONTEXT_MEM_BASE;
|
||||
for (MemPtr = &__data_start; MemPtr < &__data_end; MemPtr++, ContextMemPtr++) {
|
||||
*ContextMemPtr = *MemPtr;
|
||||
}
|
||||
for (MemPtr = &__bss_start__; MemPtr < &__bss_end__; MemPtr++, ContextMemPtr++) {
|
||||
*ContextMemPtr = *MemPtr;
|
||||
}
|
||||
pm_dbg("Saved context (tick_count = %d)\n", TickCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* RestoreContext() - called to restore context of bss and data sections from OCM
|
||||
*/
|
||||
static void RestoreContext(void)
|
||||
{
|
||||
uint8_t *MemPtr;
|
||||
uint8_t *ContextMemPtr = (uint8_t *)CONTEXT_MEM_BASE;
|
||||
for (MemPtr = &__data_start; MemPtr < &__data_end; MemPtr++, ContextMemPtr++) {
|
||||
*MemPtr = *ContextMemPtr;
|
||||
}
|
||||
for (MemPtr = &__bss_start__; MemPtr < &__bss_end__; MemPtr++, ContextMemPtr++) {
|
||||
*MemPtr = *ContextMemPtr;
|
||||
}
|
||||
pm_dbg("Restored context (tick_count = %d)\n", TickCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* PrepareSuspend() - save context and request suspend
|
||||
*/
|
||||
static void PrepareSuspend(void)
|
||||
{
|
||||
SaveContext();
|
||||
/* usleep is used to prevents UART prints from overlapping */
|
||||
#ifdef __aarch64__
|
||||
/* APU */
|
||||
XPm_SelfSuspend(NODE_APU_0, MAX_LATENCY, 0);
|
||||
usleep(100000);
|
||||
XPm_SetRequirement(NODE_OCM_BANK_0, PM_CAP_CONTEXT, 0, REQ_ACK_NO);
|
||||
usleep(100000);
|
||||
XPm_SetRequirement(NODE_OCM_BANK_1, PM_CAP_CONTEXT, 0, REQ_ACK_NO);
|
||||
usleep(100000);
|
||||
XPm_SetRequirement(NODE_OCM_BANK_2, PM_CAP_CONTEXT, 0, REQ_ACK_NO);
|
||||
usleep(100000);
|
||||
XPm_SetRequirement(NODE_OCM_BANK_3, PM_CAP_CONTEXT, 0, REQ_ACK_NO);
|
||||
usleep(100000);
|
||||
#else
|
||||
/* RPU */
|
||||
XPm_SelfSuspend(NODE_RPU_0, MAX_LATENCY, 0);
|
||||
usleep(100000);
|
||||
XPm_SetRequirement(NODE_TCM_0_A, PM_CAP_CONTEXT, 0, REQ_ACK_NO);
|
||||
usleep(100000);
|
||||
XPm_SetRequirement(NODE_TCM_0_B, PM_CAP_CONTEXT, 0, REQ_ACK_NO);
|
||||
usleep(100000);
|
||||
XPm_SetRequirement(NODE_TCM_1_A, PM_CAP_CONTEXT, 0, REQ_ACK_NO);
|
||||
usleep(100000);
|
||||
XPm_SetRequirement(NODE_TCM_1_B, PM_CAP_CONTEXT, 0, REQ_ACK_NO);
|
||||
usleep(100000);
|
||||
#endif /* __aarch64__ */
|
||||
}
|
||||
|
||||
/**
|
||||
* InitApp() - initialize interrupts and context
|
||||
*/
|
||||
static uint32_t InitApp(void)
|
||||
{
|
||||
enum XPmBootStatus status;
|
||||
pm_dbg("Main\n");
|
||||
/* Get boot status for APU core #0 */
|
||||
status = XPm_GetBootStatus();
|
||||
if (PM_INITIAL_BOOT == status) {
|
||||
pm_dbg("INITIAL BOOT\n");
|
||||
/* Configure timer, if configuration fails return from main */
|
||||
if (XST_FAILURE == TimerConfigure(TIMER_PERIOD)) {
|
||||
pm_dbg("Exiting main...\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
} else if (PM_RESUME == status) {
|
||||
pm_dbg("RESUMED\n");
|
||||
RestoreContext();
|
||||
/* Timer is already counting, just enable interrupts */
|
||||
Xil_ExceptionEnable();
|
||||
} else {
|
||||
pm_dbg("ERROR cannot identify boot reason\n");
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Xil_DCacheDisable();
|
||||
uint32_t Status = InitApp();
|
||||
if (XST_SUCCESS != Status) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
pm_dbg("Waiting for ticks...\n");
|
||||
/* Wait for 3 timer ticks */
|
||||
while ((TickCount + 1) % 4);
|
||||
|
||||
PrepareSuspend();
|
||||
pm_dbg("Going to WFI...\n");
|
||||
__asm__("wfi");
|
||||
/*
|
||||
* Can execute code below only if interrupt is generated between calling
|
||||
* the PrepareSuspend and executing wfi. Shouldn't happen.
|
||||
*/
|
||||
pm_dbg("Error! WFI exit...\n");
|
||||
return XST_FAILURE;
|
||||
}
|
614
lib/sw_services/xilpm/src/apu/pm_apu.h
Normal file
614
lib/sw_services/xilpm/src/apu/pm_apu.h
Normal file
|
@ -0,0 +1,614 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _PM_APU_H_
|
||||
#define _PM_APU_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* APU Base Address
|
||||
*/
|
||||
#define APU_BASEADDR 0XFD5C0000
|
||||
|
||||
/**
|
||||
* Register: APU_ERR_CTRL
|
||||
*/
|
||||
#define APU_ERR_CTRL ( ( APU_BASEADDR ) + 0X00000000 )
|
||||
|
||||
#define APU_ERR_CTRL_PSLVERR_SHIFT 0
|
||||
#define APU_ERR_CTRL_PSLVERR_WIDTH 1
|
||||
#define APU_ERR_CTRL_PSLVERR_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_ISR
|
||||
*/
|
||||
#define APU_ISR ( ( APU_BASEADDR ) + 0X00000010 )
|
||||
|
||||
#define APU_ISR_INV_APB_SHIFT 0
|
||||
#define APU_ISR_INV_APB_WIDTH 1
|
||||
#define APU_ISR_INV_APB_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_IMR
|
||||
*/
|
||||
#define APU_IMR ( ( APU_BASEADDR ) + 0X00000014 )
|
||||
|
||||
#define APU_IMR_INV_APB_SHIFT 0
|
||||
#define APU_IMR_INV_APB_WIDTH 1
|
||||
#define APU_IMR_INV_APB_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_IEN
|
||||
*/
|
||||
#define APU_IEN ( ( APU_BASEADDR ) + 0X00000018 )
|
||||
|
||||
#define APU_IEN_INV_APB_SHIFT 0
|
||||
#define APU_IEN_INV_APB_WIDTH 1
|
||||
#define APU_IEN_INV_APB_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_IDS
|
||||
*/
|
||||
#define APU_IDS ( ( APU_BASEADDR ) + 0X0000001C )
|
||||
|
||||
#define APU_IDS_INV_APB_SHIFT 0
|
||||
#define APU_IDS_INV_APB_WIDTH 1
|
||||
#define APU_IDS_INV_APB_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_CONFIG_0
|
||||
*/
|
||||
#define APU_CONFIG_0 ( ( APU_BASEADDR ) + 0X00000020 )
|
||||
|
||||
#define APU_CONFIG_0_CFGTE_SHIFT 24
|
||||
#define APU_CONFIG_0_CFGTE_WIDTH 4
|
||||
#define APU_CONFIG_0_CFGTE_MASK 0X0F000000
|
||||
|
||||
#define APU_CONFIG_0_CFGEND_SHIFT 16
|
||||
#define APU_CONFIG_0_CFGEND_WIDTH 4
|
||||
#define APU_CONFIG_0_CFGEND_MASK 0X000F0000
|
||||
|
||||
#define APU_CONFIG_0_VINITHI_SHIFT 8
|
||||
#define APU_CONFIG_0_VINITHI_WIDTH 4
|
||||
#define APU_CONFIG_0_VINITHI_MASK 0X00000F00
|
||||
|
||||
#define APU_CONFIG_0_AA64NAA32_SHIFT 0
|
||||
#define APU_CONFIG_0_AA64NAA32_WIDTH 4
|
||||
#define APU_CONFIG_0_AA64NAA32_MASK 0X0000000F
|
||||
|
||||
/**
|
||||
* Register: APU_CONFIG_1
|
||||
*/
|
||||
#define APU_CONFIG_1 ( ( APU_BASEADDR ) + 0X00000024 )
|
||||
|
||||
#define APU_CONFIG_1_L2RSTDISABLE_SHIFT 29
|
||||
#define APU_CONFIG_1_L2RSTDISABLE_WIDTH 1
|
||||
#define APU_CONFIG_1_L2RSTDISABLE_MASK 0X20000000
|
||||
|
||||
#define APU_CONFIG_1_L1RSTDISABLE_SHIFT 28
|
||||
#define APU_CONFIG_1_L1RSTDISABLE_WIDTH 1
|
||||
#define APU_CONFIG_1_L1RSTDISABLE_MASK 0X10000000
|
||||
|
||||
#define APU_CONFIG_1_CP15DISABLE_SHIFT 0
|
||||
#define APU_CONFIG_1_CP15DISABLE_WIDTH 4
|
||||
#define APU_CONFIG_1_CP15DISABLE_MASK 0X0000000F
|
||||
|
||||
/**
|
||||
* Register: APU_RVBARADDR0L
|
||||
*/
|
||||
#define APU_RVBARADDR0L ( ( APU_BASEADDR ) + 0X00000040 )
|
||||
|
||||
#define APU_RVBARADDR0L_ADDR_SHIFT 2
|
||||
#define APU_RVBARADDR0L_ADDR_WIDTH 30
|
||||
#define APU_RVBARADDR0L_ADDR_MASK 0XFFFFFFFC
|
||||
|
||||
/**
|
||||
* Register: APU_RVBARADDR0H
|
||||
*/
|
||||
#define APU_RVBARADDR0H ( ( APU_BASEADDR ) + 0X00000044 )
|
||||
|
||||
#define APU_RVBARADDR0H_ADDR_SHIFT 0
|
||||
#define APU_RVBARADDR0H_ADDR_WIDTH 8
|
||||
#define APU_RVBARADDR0H_ADDR_MASK 0X000000FF
|
||||
|
||||
/**
|
||||
* Register: APU_RVBARADDR1L
|
||||
*/
|
||||
#define APU_RVBARADDR1L ( ( APU_BASEADDR ) + 0X00000048 )
|
||||
|
||||
#define APU_RVBARADDR1L_ADDR_SHIFT 2
|
||||
#define APU_RVBARADDR1L_ADDR_WIDTH 30
|
||||
#define APU_RVBARADDR1L_ADDR_MASK 0XFFFFFFFC
|
||||
|
||||
/**
|
||||
* Register: APU_RVBARADDR1H
|
||||
*/
|
||||
#define APU_RVBARADDR1H ( ( APU_BASEADDR ) + 0X0000004C )
|
||||
|
||||
#define APU_RVBARADDR1H_ADDR_SHIFT 0
|
||||
#define APU_RVBARADDR1H_ADDR_WIDTH 8
|
||||
#define APU_RVBARADDR1H_ADDR_MASK 0X000000FF
|
||||
|
||||
/**
|
||||
* Register: APU_RVBARADDR2L
|
||||
*/
|
||||
#define APU_RVBARADDR2L ( ( APU_BASEADDR ) + 0X00000050 )
|
||||
|
||||
#define APU_RVBARADDR2L_ADDR_SHIFT 2
|
||||
#define APU_RVBARADDR2L_ADDR_WIDTH 30
|
||||
#define APU_RVBARADDR2L_ADDR_MASK 0XFFFFFFFC
|
||||
|
||||
/**
|
||||
* Register: APU_RVBARADDR2H
|
||||
*/
|
||||
#define APU_RVBARADDR2H ( ( APU_BASEADDR ) + 0X00000054 )
|
||||
|
||||
#define APU_RVBARADDR2H_ADDR_SHIFT 0
|
||||
#define APU_RVBARADDR2H_ADDR_WIDTH 8
|
||||
#define APU_RVBARADDR2H_ADDR_MASK 0X000000FF
|
||||
|
||||
/**
|
||||
* Register: APU_RVBARADDR3L
|
||||
*/
|
||||
#define APU_RVBARADDR3L ( ( APU_BASEADDR ) + 0X00000058 )
|
||||
|
||||
#define APU_RVBARADDR3L_ADDR_SHIFT 2
|
||||
#define APU_RVBARADDR3L_ADDR_WIDTH 30
|
||||
#define APU_RVBARADDR3L_ADDR_MASK 0XFFFFFFFC
|
||||
|
||||
/**
|
||||
* Register: APU_RVBARADDR3H
|
||||
*/
|
||||
#define APU_RVBARADDR3H ( ( APU_BASEADDR ) + 0X0000005C )
|
||||
|
||||
#define APU_RVBARADDR3H_ADDR_SHIFT 0
|
||||
#define APU_RVBARADDR3H_ADDR_WIDTH 8
|
||||
#define APU_RVBARADDR3H_ADDR_MASK 0X000000FF
|
||||
|
||||
/**
|
||||
* Register: APU_ACE_CTRL
|
||||
*/
|
||||
#define APU_ACE_CTRL ( ( APU_BASEADDR ) + 0X00000060 )
|
||||
|
||||
#define APU_ACE_CTRL_AWQOS_SHIFT 16
|
||||
#define APU_ACE_CTRL_AWQOS_WIDTH 4
|
||||
#define APU_ACE_CTRL_AWQOS_MASK 0X000F0000
|
||||
|
||||
#define APU_ACE_CTRL_ARQOS_SHIFT 0
|
||||
#define APU_ACE_CTRL_ARQOS_WIDTH 4
|
||||
#define APU_ACE_CTRL_ARQOS_MASK 0X0000000F
|
||||
|
||||
/**
|
||||
* Register: APU_SNOOP_CTRL
|
||||
*/
|
||||
#define APU_SNOOP_CTRL ( ( APU_BASEADDR ) + 0X00000080 )
|
||||
|
||||
#define APU_SNOOP_CTRL_ACE_INACT_SHIFT 4
|
||||
#define APU_SNOOP_CTRL_ACE_INACT_WIDTH 1
|
||||
#define APU_SNOOP_CTRL_ACE_INACT_MASK 0X00000010
|
||||
|
||||
#define APU_SNOOP_CTRL_ACP_INACT_SHIFT 0
|
||||
#define APU_SNOOP_CTRL_ACP_INACT_WIDTH 1
|
||||
#define APU_SNOOP_CTRL_ACP_INACT_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_PWRCTL
|
||||
*/
|
||||
#define APU_PWRCTL ( ( APU_BASEADDR ) + 0X00000090 )
|
||||
|
||||
#define APU_PWRCTL_CLREXMONREQ_SHIFT 17
|
||||
#define APU_PWRCTL_CLREXMONREQ_WIDTH 1
|
||||
#define APU_PWRCTL_CLREXMONREQ_MASK 0X00020000
|
||||
|
||||
#define APU_PWRCTL_L2FLUSHREQ_SHIFT 16
|
||||
#define APU_PWRCTL_L2FLUSHREQ_WIDTH 1
|
||||
#define APU_PWRCTL_L2FLUSHREQ_MASK 0X00010000
|
||||
|
||||
#define APU_PWRCTL_CPUPWRDWNREQ_SHIFT 0
|
||||
#define APU_PWRCTL_CPUPWRDWNREQ_WIDTH 4
|
||||
#define APU_PWRCTL_CPUPWRDWNREQ_MASK 0X0000000F
|
||||
|
||||
/**
|
||||
* Register: APU_PWRSTAT
|
||||
*/
|
||||
#define APU_PWRSTAT ( ( APU_BASEADDR ) + 0X00000094 )
|
||||
|
||||
#define APU_PWRSTAT_CLREXMONACK_SHIFT 17
|
||||
#define APU_PWRSTAT_CLREXMONACK_WIDTH 1
|
||||
#define APU_PWRSTAT_CLREXMONACK_MASK 0X00020000
|
||||
|
||||
#define APU_PWRSTAT_L2FLUSHDONE_SHIFT 16
|
||||
#define APU_PWRSTAT_L2FLUSHDONE_WIDTH 1
|
||||
#define APU_PWRSTAT_L2FLUSHDONE_MASK 0X00010000
|
||||
|
||||
#define APU_PWRSTAT_DBGNOPWRDWN_SHIFT 0
|
||||
#define APU_PWRSTAT_DBGNOPWRDWN_WIDTH 4
|
||||
#define APU_PWRSTAT_DBGNOPWRDWN_MASK 0X0000000F
|
||||
|
||||
/**
|
||||
* Register: APU_ECO
|
||||
*/
|
||||
#define APU_ECO ( ( APU_BASEADDR ) + 0X000000EC )
|
||||
|
||||
#define APU_ECO_SPARE_SHIFT 0
|
||||
#define APU_ECO_SPARE_WIDTH 32
|
||||
#define APU_ECO_SPARE_MASK 0XFFFFFFFF
|
||||
|
||||
/**
|
||||
* Register: APU_RAM_ADJ_0
|
||||
*/
|
||||
#define APU_RAM_ADJ_0 ( ( APU_BASEADDR ) + 0X000000F0 )
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMAS_SHIFT 29
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMAS_MASK 0X20000000
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMAW_SHIFT 27
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMAW_MASK 0X18000000
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMA_SHIFT 24
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_0_L1_ITAG_EMA_MASK 0X07000000
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMAS_SHIFT 21
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMAS_MASK 0X00200000
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMAW_SHIFT 19
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMAW_MASK 0X00180000
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMA_SHIFT 16
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_0_L1_IDATA_EMA_MASK 0X00070000
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMAS_SHIFT 13
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMAS_MASK 0X00002000
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMAW_SHIFT 11
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMAW_MASK 0X00001800
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMA_SHIFT 8
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_0_L1_DTAG_EMA_MASK 0X00000700
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMAS_SHIFT 5
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMAS_MASK 0X00000020
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMAW_SHIFT 3
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMAW_MASK 0X00000018
|
||||
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMA_SHIFT 0
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_0_L1_DDATA_EMA_MASK 0X00000007
|
||||
|
||||
/**
|
||||
* Register: APU_RAM_ADJ_1
|
||||
*/
|
||||
#define APU_RAM_ADJ_1 ( ( APU_BASEADDR ) + 0X000000F4 )
|
||||
|
||||
#define APU_RAM_ADJ_1_TLB_EMAS_SHIFT 29
|
||||
#define APU_RAM_ADJ_1_TLB_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_1_TLB_EMAS_MASK 0X20000000
|
||||
|
||||
#define APU_RAM_ADJ_1_TLB_EMAW_SHIFT 27
|
||||
#define APU_RAM_ADJ_1_TLB_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_1_TLB_EMAW_MASK 0X18000000
|
||||
|
||||
#define APU_RAM_ADJ_1_TLB_EMA_SHIFT 24
|
||||
#define APU_RAM_ADJ_1_TLB_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_1_TLB_EMA_MASK 0X07000000
|
||||
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMAS_SHIFT 21
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMAS_MASK 0X00200000
|
||||
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMAW_SHIFT 19
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMAW_MASK 0X00180000
|
||||
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMA_SHIFT 16
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_1_DIRTY_EMA_MASK 0X00070000
|
||||
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMAS_SHIFT 13
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMAS_MASK 0X00002000
|
||||
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMAW_SHIFT 11
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMAW_MASK 0X00001800
|
||||
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMA_SHIFT 8
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_1_BTAC1_EMA_MASK 0X00000700
|
||||
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMAS_SHIFT 5
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMAS_MASK 0X00000020
|
||||
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMAW_SHIFT 3
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMAW_MASK 0X00000018
|
||||
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMA_SHIFT 0
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_1_BTAC0_EMA_MASK 0X00000007
|
||||
|
||||
/**
|
||||
* Register: APU_RAM_ADJ_2
|
||||
*/
|
||||
#define APU_RAM_ADJ_2 ( ( APU_BASEADDR ) + 0X000000F8 )
|
||||
|
||||
#define APU_RAM_ADJ_2_ETF_EMAS_SHIFT 29
|
||||
#define APU_RAM_ADJ_2_ETF_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_2_ETF_EMAS_MASK 0X20000000
|
||||
|
||||
#define APU_RAM_ADJ_2_ETF_EMAW_SHIFT 27
|
||||
#define APU_RAM_ADJ_2_ETF_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_2_ETF_EMAW_MASK 0X18000000
|
||||
|
||||
#define APU_RAM_ADJ_2_ETF_EMA_SHIFT 24
|
||||
#define APU_RAM_ADJ_2_ETF_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_2_ETF_EMA_MASK 0X07000000
|
||||
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMAS_SHIFT 13
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMAS_MASK 0X00002000
|
||||
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMAW_SHIFT 11
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMAW_MASK 0X00001800
|
||||
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMA_SHIFT 8
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_2_SCU_TAG_EMA_MASK 0X00000700
|
||||
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMAS_SHIFT 5
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMAS_MASK 0X00000020
|
||||
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMAW_SHIFT 3
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMAW_MASK 0X00000018
|
||||
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMA_SHIFT 0
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_2_L2_VICTIM_EMA_MASK 0X00000007
|
||||
|
||||
/**
|
||||
* Register: APU_RAM_ADJ_3
|
||||
*/
|
||||
#define APU_RAM_ADJ_3 ( ( APU_BASEADDR ) + 0X000000FC )
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMAS_SHIFT 29
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMAS_MASK 0X20000000
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMAW_SHIFT 27
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMAW_MASK 0X18000000
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMA_SHIFT 24
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_3_L2_TAGECC_EMA_MASK 0X07000000
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMAS_SHIFT 21
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMAS_MASK 0X00200000
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMAW_SHIFT 19
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMAW_MASK 0X00180000
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMA_SHIFT 16
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_3_L2_TAG_EMA_MASK 0X00070000
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMAS_SHIFT 13
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMAS_MASK 0X00002000
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMAW_SHIFT 11
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMAW_MASK 0X00001800
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMA_SHIFT 8
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_3_L2_DATAECC_EMA_MASK 0X00000700
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMAS_SHIFT 5
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMAS_WIDTH 1
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMAS_MASK 0X00000020
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMAW_SHIFT 3
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMAW_WIDTH 2
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMAW_MASK 0X00000018
|
||||
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMA_SHIFT 0
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMA_WIDTH 3
|
||||
#define APU_RAM_ADJ_3_L2_DATA_EMA_MASK 0X00000007
|
||||
|
||||
/**
|
||||
* Register: APU_XPD_REG0
|
||||
*/
|
||||
#define APU_XPD_REG0 ( ( APU_BASEADDR ) + 0X00000600 )
|
||||
|
||||
#define APU_XPD_REG0_PRE_LOAD_SHIFT 0
|
||||
#define APU_XPD_REG0_PRE_LOAD_WIDTH 32
|
||||
#define APU_XPD_REG0_PRE_LOAD_MASK 0XFFFFFFFF
|
||||
|
||||
/**
|
||||
* Register: APU_XPD_REG1
|
||||
*/
|
||||
#define APU_XPD_REG1 ( ( APU_BASEADDR ) + 0X00000604 )
|
||||
|
||||
#define APU_XPD_REG1_EXPECTED_SHIFT 0
|
||||
#define APU_XPD_REG1_EXPECTED_WIDTH 32
|
||||
#define APU_XPD_REG1_EXPECTED_MASK 0XFFFFFFFF
|
||||
|
||||
/**
|
||||
* Register: APU_XPD_CTRL0
|
||||
*/
|
||||
#define APU_XPD_CTRL0 ( ( APU_BASEADDR ) + 0X00000608 )
|
||||
|
||||
#define APU_XPD_CTRL0_DELAY_SPARE_SHIFT 25
|
||||
#define APU_XPD_CTRL0_DELAY_SPARE_WIDTH 5
|
||||
#define APU_XPD_CTRL0_DELAY_SPARE_MASK 0X3E000000
|
||||
|
||||
#define APU_XPD_CTRL0_CMP_SEL_SHIFT 24
|
||||
#define APU_XPD_CTRL0_CMP_SEL_WIDTH 1
|
||||
#define APU_XPD_CTRL0_CMP_SEL_MASK 0X01000000
|
||||
|
||||
#define APU_XPD_CTRL0_DELAY_CELL_TYPE_SHIFT 19
|
||||
#define APU_XPD_CTRL0_DELAY_CELL_TYPE_WIDTH 5
|
||||
#define APU_XPD_CTRL0_DELAY_CELL_TYPE_MASK 0X00F80000
|
||||
|
||||
#define APU_XPD_CTRL0_DELAY_VT_TYPE_SHIFT 17
|
||||
#define APU_XPD_CTRL0_DELAY_VT_TYPE_WIDTH 2
|
||||
#define APU_XPD_CTRL0_DELAY_VT_TYPE_MASK 0X00060000
|
||||
|
||||
#define APU_XPD_CTRL0_DELAY_VALUE_SHIFT 6
|
||||
#define APU_XPD_CTRL0_DELAY_VALUE_WIDTH 11
|
||||
#define APU_XPD_CTRL0_DELAY_VALUE_MASK 0X0001FFC0
|
||||
|
||||
#define APU_XPD_CTRL0_PATH_SEL_SHIFT 0
|
||||
#define APU_XPD_CTRL0_PATH_SEL_WIDTH 6
|
||||
#define APU_XPD_CTRL0_PATH_SEL_MASK 0X0000003F
|
||||
|
||||
/**
|
||||
* Register: APU_XPD_CTRL1
|
||||
*/
|
||||
#define APU_XPD_CTRL1 ( ( APU_BASEADDR ) + 0X0000060C )
|
||||
|
||||
#define APU_XPD_CTRL1_CLK_SPARE_SHIFT 12
|
||||
#define APU_XPD_CTRL1_CLK_SPARE_WIDTH 4
|
||||
#define APU_XPD_CTRL1_CLK_SPARE_MASK 0X0000F000
|
||||
|
||||
#define APU_XPD_CTRL1_CLK_PHASE_SEL_SHIFT 10
|
||||
#define APU_XPD_CTRL1_CLK_PHASE_SEL_WIDTH 2
|
||||
#define APU_XPD_CTRL1_CLK_PHASE_SEL_MASK 0X00000C00
|
||||
|
||||
#define APU_XPD_CTRL1_CLK_VT_TYPE_SHIFT 8
|
||||
#define APU_XPD_CTRL1_CLK_VT_TYPE_WIDTH 2
|
||||
#define APU_XPD_CTRL1_CLK_VT_TYPE_MASK 0X00000300
|
||||
|
||||
#define APU_XPD_CTRL1_CLK_CELL_TYPE_SHIFT 6
|
||||
#define APU_XPD_CTRL1_CLK_CELL_TYPE_WIDTH 2
|
||||
#define APU_XPD_CTRL1_CLK_CELL_TYPE_MASK 0X000000C0
|
||||
|
||||
#define APU_XPD_CTRL1_CLK_INSERT_DLY_SHIFT 2
|
||||
#define APU_XPD_CTRL1_CLK_INSERT_DLY_WIDTH 4
|
||||
#define APU_XPD_CTRL1_CLK_INSERT_DLY_MASK 0X0000003C
|
||||
|
||||
#define APU_XPD_CTRL1_CLK_SEL_SHIFT 0
|
||||
#define APU_XPD_CTRL1_CLK_SEL_WIDTH 2
|
||||
#define APU_XPD_CTRL1_CLK_SEL_MASK 0X00000003
|
||||
|
||||
/**
|
||||
* Register: APU_XPD_CTRL2
|
||||
*/
|
||||
#define APU_XPD_CTRL2 ( ( APU_BASEADDR ) + 0X00000614 )
|
||||
|
||||
#define APU_XPD_CTRL2_CTRL_SPARE_SHIFT 1
|
||||
#define APU_XPD_CTRL2_CTRL_SPARE_WIDTH 2
|
||||
#define APU_XPD_CTRL2_CTRL_SPARE_MASK 0X00000006
|
||||
|
||||
#define APU_XPD_CTRL2_ENABLE_SHIFT 0
|
||||
#define APU_XPD_CTRL2_ENABLE_WIDTH 1
|
||||
#define APU_XPD_CTRL2_ENABLE_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_XPD_CTRL3
|
||||
*/
|
||||
#define APU_XPD_CTRL3 ( ( APU_BASEADDR ) + 0X00000618 )
|
||||
|
||||
#define APU_XPD_CTRL3_DCYCLE_CNT_VALUE_SHIFT 3
|
||||
#define APU_XPD_CTRL3_DCYCLE_CNT_VALUE_WIDTH 12
|
||||
#define APU_XPD_CTRL3_DCYCLE_CNT_VALUE_MASK 0X00007FF8
|
||||
|
||||
#define APU_XPD_CTRL3_DCYCLE_HIGH_LOW_SHIFT 2
|
||||
#define APU_XPD_CTRL3_DCYCLE_HIGH_LOW_WIDTH 1
|
||||
#define APU_XPD_CTRL3_DCYCLE_HIGH_LOW_MASK 0X00000004
|
||||
|
||||
#define APU_XPD_CTRL3_DCYCLE_CNT_CLR_SHIFT 1
|
||||
#define APU_XPD_CTRL3_DCYCLE_CNT_CLR_WIDTH 1
|
||||
#define APU_XPD_CTRL3_DCYCLE_CNT_CLR_MASK 0X00000002
|
||||
|
||||
#define APU_XPD_CTRL3_DCYCLE_START_SHIFT 0
|
||||
#define APU_XPD_CTRL3_DCYCLE_START_WIDTH 1
|
||||
#define APU_XPD_CTRL3_DCYCLE_START_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_XPD_SOFT_RST
|
||||
*/
|
||||
#define APU_XPD_SOFT_RST ( ( APU_BASEADDR ) + 0X0000061C )
|
||||
|
||||
#define APU_XPD_SOFT_RST_CLK2_SHIFT 2
|
||||
#define APU_XPD_SOFT_RST_CLK2_WIDTH 1
|
||||
#define APU_XPD_SOFT_RST_CLK2_MASK 0X00000004
|
||||
|
||||
#define APU_XPD_SOFT_RST_CLK1_SHIFT 1
|
||||
#define APU_XPD_SOFT_RST_CLK1_WIDTH 1
|
||||
#define APU_XPD_SOFT_RST_CLK1_MASK 0X00000002
|
||||
|
||||
#define APU_XPD_SOFT_RST_CLK0_SHIFT 0
|
||||
#define APU_XPD_SOFT_RST_CLK0_WIDTH 1
|
||||
#define APU_XPD_SOFT_RST_CLK0_MASK 0X00000001
|
||||
|
||||
/**
|
||||
* Register: APU_XPD_STAT
|
||||
*/
|
||||
#define APU_XPD_STAT ( ( APU_BASEADDR ) + 0X00000620 )
|
||||
|
||||
#define APU_XPD_STAT_CMP_RESULT_SHIFT 1
|
||||
#define APU_XPD_STAT_CMP_RESULT_WIDTH 1
|
||||
#define APU_XPD_STAT_CMP_RESULT_MASK 0X00000002
|
||||
|
||||
#define APU_XPD_STAT_CMP_DONE_SHIFT 0
|
||||
#define APU_XPD_STAT_CMP_DONE_WIDTH 1
|
||||
#define APU_XPD_STAT_CMP_DONE_MASK 0X00000001
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _PM_APU_H_ */
|
152
lib/sw_services/xilpm/src/apu/pm_client.c
Normal file
152
lib/sw_services/xilpm/src/apu/pm_client.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* CONTENT
|
||||
* Each PU client in the system have such file with definitions of
|
||||
* masters in the subsystem and functions for getting informations
|
||||
* about the master.
|
||||
*********************************************************************/
|
||||
|
||||
#include "pm_client.h"
|
||||
|
||||
static const struct XPm_Ipi apu_ipi = {
|
||||
.mask = IPI_APU_MASK,
|
||||
.base = IPI_BASEADDR,
|
||||
.buffer_base = IPI_BUFFER_APU_BASE,
|
||||
};
|
||||
|
||||
static const struct XPm_Master pm_apu_0_master = {
|
||||
.node_id = NODE_APU_0,
|
||||
.pwrdn_mask = APU_0_PWRCTL_CPUPWRDWNREQ_MASK,
|
||||
.ipi = &apu_ipi,
|
||||
};
|
||||
|
||||
static const struct XPm_Master pm_apu_1_master = {
|
||||
.node_id = NODE_APU_1,
|
||||
.pwrdn_mask = APU_1_PWRCTL_CPUPWRDWNREQ_MASK,
|
||||
.ipi = &apu_ipi,
|
||||
};
|
||||
|
||||
static const struct XPm_Master pm_apu_2_master = {
|
||||
.node_id = NODE_APU_2,
|
||||
.pwrdn_mask = APU_2_PWRCTL_CPUPWRDWNREQ_MASK,
|
||||
.ipi = &apu_ipi,
|
||||
};
|
||||
|
||||
static const struct XPm_Master pm_apu_3_master = {
|
||||
.node_id = NODE_APU_3,
|
||||
.pwrdn_mask = APU_3_PWRCTL_CPUPWRDWNREQ_MASK,
|
||||
.ipi = &apu_ipi,
|
||||
};
|
||||
|
||||
/*
|
||||
* Order in pm_master_all array must match cpu ids
|
||||
*/
|
||||
static const struct XPm_Master *const pm_masters_all[] = {
|
||||
&pm_apu_0_master,
|
||||
&pm_apu_1_master,
|
||||
&pm_apu_2_master,
|
||||
&pm_apu_3_master,
|
||||
};
|
||||
|
||||
/**
|
||||
* pm_get_master() - returns pointer to the master structure
|
||||
* @cpuid: id of the cpu whose master struct pointer should be returned
|
||||
*
|
||||
* Return: pointer to a master structure if master is found, otherwise NULL
|
||||
*/
|
||||
const struct XPm_Master *pm_get_master(const uint32_t cpuid)
|
||||
{
|
||||
if (cpuid >=0 && PM_ARRAY_SIZE(pm_masters_all)) {
|
||||
return pm_masters_all[cpuid];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_get_master_by_node() - returns pointer to the master structure
|
||||
* @nid: ndoe id of the cpu master
|
||||
*
|
||||
* Return: pointer to a master structure if master is found, otherwise NULL
|
||||
*/
|
||||
const struct XPm_Master *pm_get_master_by_node(const enum XPmNodeId nid)
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < PM_ARRAY_SIZE(pm_masters_all); i++) {
|
||||
if (nid == pm_masters_all[i]->node_id) {
|
||||
return pm_masters_all[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint32_t pm_get_cpuid(const enum XPmNodeId node)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < PM_ARRAY_SIZE(pm_masters_all); i++) {
|
||||
if (pm_masters_all[i]->node_id == node) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return UNDEFINED_CPUID;
|
||||
}
|
||||
|
||||
const enum XPmNodeId subsystem_node = NODE_APU;
|
||||
const struct XPm_Master *primary_master = &pm_apu_0_master;
|
||||
|
||||
void XPm_ClientSuspend(const struct XPm_Master *const master)
|
||||
{
|
||||
/* Disable interrupts at processor level */
|
||||
pm_disable_int();
|
||||
/* Set powerdown request */
|
||||
pm_write(MASTER_PWRCTL, pm_read(MASTER_PWRCTL) | master->pwrdn_mask);
|
||||
}
|
||||
|
||||
void XPm_ClientAbortSuspend()
|
||||
{
|
||||
/* Enable interrupts at processor level */
|
||||
pm_enable_int();
|
||||
/* Clear powerdown request */
|
||||
pm_write(MASTER_PWRCTL, pm_read(MASTER_PWRCTL) & ~primary_master->pwrdn_mask);
|
||||
}
|
||||
|
||||
void XPm_ClientWakeup(const struct XPm_Master *const master)
|
||||
{
|
||||
uint32_t cpuid = pm_get_cpuid(master->node_id);
|
||||
|
||||
if (UNDEFINED_CPUID != cpuid) {
|
||||
uint32_t val = pm_read(MASTER_PWRCTL);
|
||||
val &= ~(master->pwrdn_mask);
|
||||
pm_write(MASTER_PWRCTL, val);
|
||||
}
|
||||
}
|
95
lib/sw_services/xilpm/src/apu/pm_client.h
Normal file
95
lib/sw_services/xilpm/src/apu/pm_client.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* CONTENT
|
||||
* File is specific for each PU instance and must exist in order to
|
||||
* port Power Management code for some new PU.
|
||||
* Contains PU specific macros and macros to be defined depending on
|
||||
* the execution environment.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef _PM_CLIENT_H_
|
||||
#define _PM_CLIENT_H_
|
||||
|
||||
#include <xil_exception.h>
|
||||
#include <xil_io.h>
|
||||
#include "pm_apu.h"
|
||||
#include "pm_defs.h"
|
||||
#include "pm_common.h"
|
||||
|
||||
#define MASTER_PWRCTL APU_PWRCTL
|
||||
|
||||
#define APU_0_PWRCTL_CPUPWRDWNREQ_MASK 0x00000001U
|
||||
#define APU_1_PWRCTL_CPUPWRDWNREQ_MASK 0x00000002U
|
||||
#define APU_2_PWRCTL_CPUPWRDWNREQ_MASK 0x00000004U
|
||||
#define APU_3_PWRCTL_CPUPWRDWNREQ_MASK 0x00000008U
|
||||
|
||||
#define IPI_APU_MASK 0x00000001U
|
||||
|
||||
#define IPI_TRIG_OFFSET 0x00000000
|
||||
#define IPI_OBS_OFFSET 0x00000004
|
||||
|
||||
#define UNDEFINED_CPUID (~0)
|
||||
|
||||
#define pm_read(addr) Xil_In32(addr)
|
||||
#define pm_write(addr, value) Xil_Out32(addr, value)
|
||||
#define pm_enable_int() Xil_ExceptionEnable()
|
||||
#define pm_disable_int() Xil_ExceptionDisable()
|
||||
#define pm_print(MSG, ...) xil_printf("APU: "MSG,##__VA_ARGS__)
|
||||
#define pm_this_cpuid() 0U
|
||||
|
||||
/* Conditional debugging prints */
|
||||
#ifdef DEBUG_MODE
|
||||
#define pm_dbg(MSG, ...) \
|
||||
do { \
|
||||
pm_print(MSG,##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define pm_dbg(MSG, ...) {}
|
||||
#endif
|
||||
|
||||
#ifndef bool
|
||||
#define bool uint8_t
|
||||
#define true 1U
|
||||
#define false 0U
|
||||
#endif
|
||||
|
||||
void XPm_ClientSuspend(const struct XPm_Master *const master);
|
||||
void XPm_ClientAbortSuspend();
|
||||
void XPm_ClientWakeup(const struct XPm_Master *const master);
|
||||
|
||||
/* Do not modify below this line */
|
||||
extern const enum XPmNodeId subsystem_node;
|
||||
extern const struct XPm_Master *primary_master;
|
||||
|
||||
#endif /* _PM_CLIENT_H_ */
|
35
lib/sw_services/xilpm/src/common/Makefile
Normal file
35
lib/sw_services/xilpm/src/common/Makefile
Normal file
|
@ -0,0 +1,35 @@
|
|||
COMPILER=
|
||||
ARCHIVER=
|
||||
CP=cp
|
||||
COMPILER_FLAGS=
|
||||
EXTRA_COMPILER_FLAGS=
|
||||
LIB=libxilpm.a
|
||||
|
||||
CC_FLAGS = $(COMPILER_FLAGS)
|
||||
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
|
||||
|
||||
RELEASEDIR=../../../lib
|
||||
INCLUDEDIR=../../../include
|
||||
INCLUDES=-I./. -I${INCLUDEDIR}
|
||||
|
||||
OUTS = *.o
|
||||
|
||||
LIBSOURCES:=*.c
|
||||
INCLUDEFILES:=*.h
|
||||
|
||||
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
|
||||
|
||||
libs: banner xilpm_libs clean
|
||||
|
||||
%.o: %.c
|
||||
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
|
||||
|
||||
banner:
|
||||
echo "Compiling xilpm library"
|
||||
|
||||
xilpm_libs: ${OBJECTS}
|
||||
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
|
||||
include:
|
||||
echo "Include files for this library have already been copied."
|
||||
clean:
|
||||
rm -rf ${OBJECTS}
|
455
lib/sw_services/xilpm/src/common/pm_api_sys.c
Normal file
455
lib/sw_services/xilpm/src/common/pm_api_sys.c
Normal file
|
@ -0,0 +1,455 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "pm_client.h"
|
||||
#include "pm_common.h"
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_ipi_buffer.h"
|
||||
|
||||
/**
|
||||
* Assigning of argument values into array elements.
|
||||
* pause and pm_dbg are used for debugging and should be removed in
|
||||
* final version.
|
||||
*/
|
||||
#define PACK_PAYLOAD(pl, arg0, arg1, arg2, arg3, arg4) \
|
||||
pl[0] = (uint32_t)arg0; \
|
||||
pl[1] = (uint32_t)arg1; \
|
||||
pl[2] = (uint32_t)arg2; \
|
||||
pl[3] = (uint32_t)arg3; \
|
||||
pl[4] = (uint32_t)arg4; \
|
||||
pm_dbg("%s(%d, %d, %d, %d)\n", __func__, arg1, arg2, arg3, arg4);
|
||||
|
||||
/**
|
||||
* pm_get_boot_status() - checks for reason of boot
|
||||
*
|
||||
* Function returns information about the boot reason.
|
||||
* If the boot is not a system startup but a resume,
|
||||
* power down request bitfield for this processor will be cleared.
|
||||
*
|
||||
* @return Returns processor boot status
|
||||
*/
|
||||
enum XPmBootStatus XPm_GetBootStatus()
|
||||
{
|
||||
uint32_t pwrdn_req = pm_read(MASTER_PWRCTL);
|
||||
if (0 != (pwrdn_req & primary_master->pwrdn_mask)) {
|
||||
pm_write(MASTER_PWRCTL, pwrdn_req & (~primary_master->pwrdn_mask));
|
||||
return PM_RESUME;
|
||||
} else {
|
||||
return PM_INITIAL_BOOT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ipi_wait() - wait for pmu to handle request
|
||||
* @master master which is waiting for PMU to handle request
|
||||
*/
|
||||
static enum XPmStatus pm_ipi_wait(const struct XPm_Master *const master)
|
||||
{
|
||||
volatile uint32_t status = 1;
|
||||
|
||||
/* Wait until previous interrupt is handled by PMU */
|
||||
while (status) {
|
||||
status = pm_read(master->ipi->base + IPI_OBS_OFFSET)
|
||||
& IPI_PMU_PM_INT_MASK;
|
||||
/* TODO: 1) Use timer to add delay between read attempts */
|
||||
/* TODO: 2) Return PM_RET_ERR_TIMEOUT if this times out */
|
||||
}
|
||||
return PM_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ipi_send() - Sends IPI request to the PMU
|
||||
* @master Pointer to the master who is initiating request
|
||||
* @payload API id and call arguments to be written in IPI buffer
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum XPmStatus pm_ipi_send(const struct XPm_Master *const master,
|
||||
uint32_t payload[PAYLOAD_ARG_CNT])
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t offset = 0;
|
||||
uint32_t buffer_base = master->ipi->buffer_base
|
||||
+ IPI_BUFFER_TARGET_PMU_OFFSET
|
||||
+ IPI_BUFFER_REQ_OFFSET;
|
||||
|
||||
/* Wait until previous interrupt is handled by PMU */
|
||||
pm_ipi_wait(master);
|
||||
/* Write payload into IPI buffer */
|
||||
for (i = 0; i < PAYLOAD_ARG_CNT; i++) {
|
||||
pm_write(buffer_base + offset, payload[i]);
|
||||
offset += PAYLOAD_ARG_SIZE;
|
||||
}
|
||||
/* Generate IPI to PMU */
|
||||
pm_write(master->ipi->base + IPI_TRIG_OFFSET, IPI_PMU_PM_INT_MASK);
|
||||
return PM_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ipi_buff_read32() - Reads IPI response after PMU has handled interrupt
|
||||
* @master Pointer to the master who is waiting and reading response
|
||||
* @value Used to return value from 2nd IPI buffer element (optional)
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum XPmStatus pm_ipi_buff_read32(const struct XPm_Master *const master,
|
||||
uint32_t *value)
|
||||
{
|
||||
uint32_t buffer_base = master->ipi->buffer_base
|
||||
+ IPI_BUFFER_TARGET_PMU_OFFSET
|
||||
+ IPI_BUFFER_RESP_OFFSET;
|
||||
volatile uint32_t status = 1;
|
||||
|
||||
/* Wait until current IPI interrupt is handled by PMU */
|
||||
while (status) {
|
||||
status = pm_read(master->ipi->base + IPI_OBS_OFFSET) & IPI_PMU_PM_INT_MASK;
|
||||
/* TODO: 1) Use timer to add delay between read attempts */
|
||||
/* TODO: 2) Return PM_RET_ERR_TIMEOUT if this times out */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read response from IPI buffer
|
||||
* buf-0: success or error+reason
|
||||
* buf-1: value
|
||||
* buf-2: unused
|
||||
* buf-3: unused
|
||||
*/
|
||||
if (NULL != value)
|
||||
*value = pm_read(buffer_base + PAYLOAD_ARG_SIZE);
|
||||
|
||||
return pm_read(buffer_base);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_self_suspend() - PM call for master to suspend itself
|
||||
* @node Node id of the master or subsystem
|
||||
* @latency Requested maximum wakeup latency (not supported)
|
||||
* @state Requested state (not supported)
|
||||
*
|
||||
* This is a blocking call, it will return only once PMU has responded
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_SelfSuspend(const enum XPmNodeId nid,
|
||||
const uint32_t latency,
|
||||
const uint8_t state)
|
||||
{
|
||||
enum XPmStatus ret;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
const struct XPm_Master *master = pm_get_master_by_node(nid);
|
||||
if (NULL == master) {
|
||||
/*
|
||||
* If a subsystem node ID (APU or RPU) was passed then
|
||||
* the master to be used is the primary master.
|
||||
* E.g. for the APU the primary master is APU0
|
||||
*/
|
||||
if (subsystem_node == nid) {
|
||||
master = primary_master;
|
||||
} else {
|
||||
return PM_RET_ERROR_ARGS;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Do client specific suspend operations
|
||||
* (e.g. disable interrupts and set powerdown request bit)
|
||||
*/
|
||||
XPm_ClientSuspend(master);
|
||||
/* Send request to the PMU */
|
||||
PACK_PAYLOAD(payload, PM_SELF_SUSPEND, nid, latency, state, 0);
|
||||
ret = pm_ipi_send(master, payload);
|
||||
if (PM_RET_SUCCESS != ret)
|
||||
return ret;
|
||||
/* Wait for PMU to finish handling request */
|
||||
return pm_ipi_wait(master);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_req_suspend() - PM call to request for another PU or subsystem to
|
||||
* be suspended gracefully.
|
||||
* @target Node id of the targeted PU or subsystem
|
||||
* @ack Flag to specify whether acknowledge is requested
|
||||
* @latency Requested wakeup latency (not supported)
|
||||
* @state Requested state (not supported)
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_ReqSuspend(const enum XPmNodeId target,
|
||||
const enum XPmRequestAck ack,
|
||||
const uint32_t latency, const uint8_t state)
|
||||
{
|
||||
enum XPmStatus ret;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMU */
|
||||
PACK_PAYLOAD(payload, PM_REQ_SUSPEND, target, ack, latency, state);
|
||||
ret = pm_ipi_send(primary_master, payload);
|
||||
|
||||
if ((PM_RET_SUCCESS == ret) && (REQ_ACK_BLOCKING == ack))
|
||||
return pm_ipi_buff_read32(primary_master, NULL);
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_req_wakeup() - PM call for master to wake up selected master or subsystem
|
||||
* @node Node id of the master or subsystem
|
||||
* @ack Flag to specify whether acknowledge requested
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_ReqWakeUp(const enum XPmNodeId target,
|
||||
const enum XPmRequestAck ack)
|
||||
{
|
||||
enum XPmStatus ret;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
const struct XPm_Master *master = pm_get_master_by_node(target);
|
||||
|
||||
XPm_ClientWakeup(master);
|
||||
/* Send request to the PMU */
|
||||
PACK_PAYLOAD(payload, PM_REQ_WAKEUP, target, ack, 0, 0);
|
||||
ret = pm_ipi_send(primary_master, payload);
|
||||
|
||||
if ((PM_RET_SUCCESS == ret) && (REQ_ACK_BLOCKING == ack))
|
||||
return pm_ipi_buff_read32(primary_master, NULL);
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_force_powerdown() - PM call to request for another PU or subsystem to
|
||||
* be powered down forcefully
|
||||
* @target Node id of the targeted PU or subsystem
|
||||
* @ack Flag to specify whether acknowledge is requested
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_ForcePowerDown(const enum XPmNodeId target,
|
||||
const enum XPmRequestAck ack)
|
||||
{
|
||||
enum XPmStatus ret;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMU */
|
||||
PACK_PAYLOAD(payload, PM_FORCE_POWERDOWN, target, ack, 0, 0);
|
||||
ret = pm_ipi_send(primary_master, payload);
|
||||
|
||||
if ((PM_RET_SUCCESS == ret) && (REQ_ACK_BLOCKING == ack))
|
||||
return pm_ipi_buff_read32(primary_master, NULL);
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_abort_suspend() - PM call to announce that a prior suspend request
|
||||
* is to be aborted.
|
||||
* @reason Reason for the abort
|
||||
*
|
||||
* Calling PU expects the PMU to abort the initiated suspend procedure.
|
||||
* This is a non-blocking call without any acknowledge.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_AbortSuspend(const enum XPmAbortReason reason)
|
||||
{
|
||||
enum XPmStatus status;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/*
|
||||
* Do client specific abort suspend operations
|
||||
* (e.g. enable interrupts and clear powerdown request bit)
|
||||
*/
|
||||
XPm_ClientAbortSuspend();
|
||||
/* Send request to the PMU */
|
||||
PACK_PAYLOAD(payload, PM_ABORT_SUSPEND, reason, primary_master->node_id, 0, 0);
|
||||
status = pm_ipi_send(primary_master, payload);
|
||||
if (PM_RET_SUCCESS == status)
|
||||
/* Wait for PMU to finish handling request */
|
||||
status = pm_ipi_wait(primary_master);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
|
||||
* @target Node id of the targeted PU or subsystem
|
||||
* @wkup_node Node id of the wakeup peripheral
|
||||
* @enable Enable or disable the specified peripheral as wake source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_SetWakeUpSource(const enum XPmNodeId target,
|
||||
const enum XPmNodeId wkup_node,
|
||||
const uint8_t enable)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
PACK_PAYLOAD(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node, enable, 0);
|
||||
return pm_ipi_send(primary_master, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_system_shutdown() - PM call to request a system shutdown or restart
|
||||
* @restart Shutdown or restart? 0 for shutdown, 1 for restart
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_SystemShutdown(const uint8_t restart)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
PACK_PAYLOAD(payload, PM_SYSTEM_SHUTDOWN, restart, 0, 0, 0);
|
||||
return pm_ipi_send(primary_master, payload);
|
||||
}
|
||||
|
||||
/* APIs for managing PM slaves: */
|
||||
|
||||
/**
|
||||
* pm_req_node() - PM call to request a node with specifc capabilities
|
||||
* @node Node id of the slave
|
||||
* @capabilities Requested capabilities of the slave
|
||||
* @qos Quality of service (not supported)
|
||||
* @ack Flag to specify whether acknowledge is requested
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_ReqNode(const enum XPmNodeId node,
|
||||
const uint32_t capabilities,
|
||||
const uint32_t qos,
|
||||
const enum XPmRequestAck ack)
|
||||
{
|
||||
enum XPmStatus ret;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
PACK_PAYLOAD(payload, PM_REQ_NODE, node, capabilities, qos, ack);
|
||||
ret = pm_ipi_send(primary_master, payload);
|
||||
|
||||
if ((PM_RET_SUCCESS == ret) && (REQ_ACK_BLOCKING == ack))
|
||||
return pm_ipi_buff_read32(primary_master, NULL);
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_set_requirement() - PM call to set requirement for PM slaves
|
||||
* @node Node id of the slave
|
||||
* @capabilities Requested capabilities of the slave
|
||||
* @qos Quality of service (not supported)
|
||||
* @ack Flag to specify whether acknowledge is requested
|
||||
*
|
||||
* This API function is to be used for slaves a PU already has requested
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_SetRequirement(const enum XPmNodeId nid,
|
||||
const uint32_t capabilities,
|
||||
const uint32_t qos,
|
||||
const enum XPmRequestAck ack)
|
||||
{
|
||||
enum XPmStatus ret;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
PACK_PAYLOAD(payload, PM_SET_REQUIREMENT, nid, capabilities, qos, ack);
|
||||
ret = pm_ipi_send(primary_master, payload);
|
||||
|
||||
if ((PM_RET_SUCCESS == ret) && (REQ_ACK_BLOCKING == ack))
|
||||
return pm_ipi_buff_read32(primary_master, NULL);
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_release_node() - PM call to release a node
|
||||
* @node Node id of the slave
|
||||
* @latency Requested maximum wakeup latency
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_ReleaseNode(const enum XPmNodeId node,
|
||||
const uint32_t latency)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
PACK_PAYLOAD(payload, PM_RELEASE_NODE, node, latency, 0, 0);
|
||||
return pm_ipi_send(primary_master, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_set_max_latency() - PM call to set wakeup latency requirements
|
||||
* @node Node id of the slave
|
||||
* @latency Requested maximum wakeup latency
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_SetMaxLatency(const enum XPmNodeId node,
|
||||
const uint32_t latency)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMU */
|
||||
PACK_PAYLOAD(payload, PM_SET_MAX_LATENCY, node, latency, 0, 0);
|
||||
return pm_ipi_send(primary_master, payload);
|
||||
}
|
||||
|
||||
/* Miscellaneous API functions */
|
||||
|
||||
/**
|
||||
* pm_get_api_version() - Get version number of PMU PM firmware
|
||||
* @version Returns 32-bit version number of PMU Power Management Firmware
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_GetApiVersion(uint32_t *version)
|
||||
{
|
||||
enum XPmStatus ret;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMU */
|
||||
PACK_PAYLOAD(payload, PM_GET_API_VERSION, 0, 0, 0, 0);
|
||||
ret = pm_ipi_send(primary_master, payload);
|
||||
|
||||
if (PM_RET_SUCCESS != ret)
|
||||
return ret;
|
||||
|
||||
/* Return result from IPI return buffer */
|
||||
return pm_ipi_buff_read32(primary_master, version);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pm_get_node_status() - PM call to request a node's current power state
|
||||
* @node Node id of the slave
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum XPmStatus XPm_GetNodeStatus(const enum XPmNodeId node)
|
||||
{
|
||||
/* TODO: Add power state argument!! */
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
PACK_PAYLOAD(payload, PM_GET_NODE_STATUS, node, 0, 0, 0);
|
||||
return pm_ipi_send(primary_master, payload);
|
||||
}
|
91
lib/sw_services/xilpm/src/common/pm_api_sys.h
Normal file
91
lib/sw_services/xilpm/src/common/pm_api_sys.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _PM_API_SYS_H_
|
||||
#define _PM_API_SYS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "pm_defs.h"
|
||||
|
||||
enum XPmBootStatus XPm_GetBootStatus();
|
||||
|
||||
/**********************************************************
|
||||
* System-level API function declarations
|
||||
**********************************************************/
|
||||
enum XPmStatus XPm_ReqSuspend(const enum XPmNodeId node,
|
||||
const enum XPmRequestAck ack,
|
||||
const uint32_t latency,
|
||||
const uint8_t state);
|
||||
|
||||
enum XPmStatus XPm_SelfSuspend(const enum XPmNodeId node,
|
||||
const uint32_t latency,
|
||||
const uint8_t state);
|
||||
|
||||
enum XPmStatus XPm_ForcePowerDown(const enum XPmNodeId node,
|
||||
const enum XPmRequestAck ack);
|
||||
|
||||
enum XPmStatus XPm_AbortSuspend(const enum XPmAbortReason reason);
|
||||
|
||||
enum XPmStatus XPm_ReqWakeUp(const enum XPmNodeId node,
|
||||
const enum XPmRequestAck ack);
|
||||
|
||||
enum XPmStatus XPm_SetWakeUpSource(const enum XPmNodeId target,
|
||||
const enum XPmNodeId wkup_node,
|
||||
const uint8_t enable);
|
||||
|
||||
enum XPmStatus XPm_SystemShutdown(const uint8_t restart);
|
||||
|
||||
|
||||
|
||||
/* API functions for managing PM Slaves */
|
||||
enum XPmStatus XPm_ReqNode(const enum XPmNodeId node,
|
||||
const uint32_t capabilities,
|
||||
const uint32_t qos,
|
||||
const enum XPmRequestAck ack);
|
||||
enum XPmStatus XPm_ReleaseNode(const enum XPmNodeId node,
|
||||
const uint32_t latency);
|
||||
enum XPmStatus XPm_SetRequirement(const enum XPmNodeId node,
|
||||
const uint32_t capabilities,
|
||||
const uint32_t qos,
|
||||
const enum XPmRequestAck ack);
|
||||
enum XPmStatus XPm_SetMaxLatency(const enum XPmNodeId node,
|
||||
const uint32_t latency);
|
||||
|
||||
/* Miscellaneous API functions */
|
||||
enum XPmStatus XPm_GetApiVersion(uint32_t *version);
|
||||
|
||||
enum XPmStatus XPm_GetNodeStatus(const enum XPmNodeId node);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* _PM_API_SYS_H_ */
|
78
lib/sw_services/xilpm/src/common/pm_common.h
Normal file
78
lib/sw_services/xilpm/src/common/pm_common.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**********************************************************************
|
||||
* CONTENT
|
||||
* Definitions of commonly used macros and data types needed for
|
||||
* PU Power Management. This file should be common for all PU's.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef _PM_COMMON_H_
|
||||
#define _PM_COMMON_H_
|
||||
|
||||
#include "pm_ipi.h"
|
||||
#include "pm_ipi_buffer.h"
|
||||
#include "pm_defs.h"
|
||||
|
||||
#define DEBUG_MODE
|
||||
|
||||
#define PM_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
#define PAYLOAD_ARG_CNT 5U
|
||||
#define PAYLOAD_ARG_SIZE 4U /* size in bytes */
|
||||
|
||||
/* Power Management IPI interrupt number */
|
||||
#define PM_INT_NUM 0
|
||||
#define IPI_PMU_PM_INT_BASE (IPI_PMU_0_TRIG + (PM_INT_NUM * 0x1000))
|
||||
#define IPI_PMU_PM_INT_MASK (IPI_APU_ISR_PMU_0_MASK << PM_INT_NUM)
|
||||
#if (PM_INT_NUM < 0 || PM_INT_NUM > 3)
|
||||
#error PM_INT_NUM value out of range
|
||||
#endif
|
||||
|
||||
struct XPm_Ipi {
|
||||
const uint32_t mask;
|
||||
const uint32_t base;
|
||||
const uint32_t buffer_base;
|
||||
};
|
||||
|
||||
struct XPm_Master {
|
||||
const enum XPmNodeId node_id;
|
||||
const uint32_t pwrdn_mask;
|
||||
const struct XPm_Ipi *const ipi;
|
||||
};
|
||||
|
||||
const enum XPmNodeId pm_get_subsystem_node(void);
|
||||
const struct XPm_Master *pm_get_master(const uint32_t cpuid);
|
||||
const struct XPm_Master *pm_get_master_by_node(const enum XPmNodeId nid);
|
||||
|
||||
|
||||
#endif /* _PM_COMMON_H_ */
|
196
lib/sw_services/xilpm/src/common/pm_defs.h
Normal file
196
lib/sw_services/xilpm/src/common/pm_defs.h
Normal file
|
@ -0,0 +1,196 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef PM_DEFS_H_
|
||||
#define PM_DEFS_H_
|
||||
|
||||
/*********************************************************************
|
||||
* Macro definitions
|
||||
********************************************************************/
|
||||
|
||||
/*
|
||||
* Version number is a 32bit value, like:
|
||||
* (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
|
||||
*/
|
||||
#define PM_VERSION_MAJOR 0
|
||||
#define PM_VERSION_MINOR 1
|
||||
|
||||
#define PM_VERSION ((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR)
|
||||
|
||||
/* Capabilities for RAM */
|
||||
#define PM_CAP_ACCESS 0x1U
|
||||
#define PM_CAP_CONTEXT 0x2U
|
||||
|
||||
#define MAX_LATENCY (~0U)
|
||||
#define MAX_QOS 100U
|
||||
|
||||
/*********************************************************************
|
||||
* Enum definitions
|
||||
********************************************************************/
|
||||
|
||||
enum XPmApiId {
|
||||
/* Miscellaneous API functions: */
|
||||
PM_GET_API_VERSION = 1, /* Do not change or move */
|
||||
PM_SET_CONFIGURATION = 2,
|
||||
PM_GET_NODE_STATUS = 3,
|
||||
PM_GET_OP_CHARACTERISTIC = 4,
|
||||
PM_REGISTER_NOTIFIER = 5,
|
||||
/* API for suspending of PUs: */
|
||||
PM_REQ_SUSPEND = 6,
|
||||
PM_SELF_SUSPEND = 7,
|
||||
PM_FORCE_POWERDOWN = 8,
|
||||
PM_ABORT_SUSPEND = 9,
|
||||
PM_REQ_WAKEUP = 10,
|
||||
PM_SET_WAKEUP_SOURCE = 11,
|
||||
PM_SYSTEM_SHUTDOWN = 12,
|
||||
/* API for managing PM slaves: */
|
||||
PM_REQ_NODE = 13,
|
||||
PM_RELEASE_NODE = 14,
|
||||
PM_SET_REQUIREMENT = 15,
|
||||
PM_SET_MAX_LATENCY = 16,
|
||||
/* Direct control API functions: */
|
||||
PM_CLOCK_REQUEST = 17,
|
||||
PM_CLOCK_RELEASE = 18,
|
||||
PM_CLOCK_SET_RATE = 19,
|
||||
PM_CLOCK_GET_RATE = 20,
|
||||
PM_CLOCK_GET_RATE_INFO = 21,
|
||||
PM_RESET_ASSERT = 22,
|
||||
PM_RESET_GET_STATUS = 23,
|
||||
PM_MMIO_WRITE = 24,
|
||||
PM_MMIO_READ = 25,
|
||||
};
|
||||
|
||||
#define PM_API_MIN 1
|
||||
#define PM_API_MAX 25
|
||||
|
||||
enum XPmApiCbId {
|
||||
PM_INIT_SUSPEND_CB = 30,
|
||||
PM_ACKNOWLEDGE_CB,
|
||||
PM_NOTIFY_CB,
|
||||
};
|
||||
|
||||
enum XPmNodeId {
|
||||
NODE_UNKNOWN = 0,
|
||||
NODE_APU,
|
||||
NODE_APU_0,
|
||||
NODE_APU_1,
|
||||
NODE_APU_2,
|
||||
NODE_APU_3,
|
||||
NODE_RPU,
|
||||
NODE_RPU_0,
|
||||
NODE_RPU_1,
|
||||
NODE_PL,
|
||||
NODE_FPD,
|
||||
NODE_OCM_BANK_0,
|
||||
NODE_OCM_BANK_1,
|
||||
NODE_OCM_BANK_2,
|
||||
NODE_OCM_BANK_3,
|
||||
NODE_TCM_0_A,
|
||||
NODE_TCM_0_B,
|
||||
NODE_TCM_1_A,
|
||||
NODE_TCM_1_B,
|
||||
NODE_L2,
|
||||
NODE_GPU_PP_0,
|
||||
NODE_GPU_PP_1,
|
||||
NODE_USB_0,
|
||||
NODE_USB_1,
|
||||
NODE_TTC_0,
|
||||
};
|
||||
|
||||
enum XPmRequestAck {
|
||||
REQ_ACK_NO = 1,
|
||||
REQ_ACK_BLOCKING = 2,
|
||||
REQ_ACK_CB_STANDARD = 3,
|
||||
REQ_ACK_CB_ERROR = 4,
|
||||
};
|
||||
|
||||
enum XPmAbortReason {
|
||||
ABORT_REASON_WKUP_EVENT = 100,
|
||||
ABORT_REASON_PU_BUSY,
|
||||
ABORT_REASON_NO_PWRDN,
|
||||
ABORT_REASON_UNKNOWN,
|
||||
};
|
||||
|
||||
enum XPmSuspendReason {
|
||||
SUSPEND_REASON_PU_REQ = 201,
|
||||
SUSPEND_REASON_ALERT,
|
||||
SUSPEND_REASON_SYS_SHUTDOWN,
|
||||
};
|
||||
|
||||
enum XPmRamState {
|
||||
PM_RAM_STATE_OFF = 1,
|
||||
PM_RAM_STATE_RETENTION,
|
||||
PM_RAM_STATE_ON,
|
||||
};
|
||||
|
||||
enum XPmOpCharType {
|
||||
PM_OPCHAR_TYPE_POWER = 1,
|
||||
PM_OPCHAR_TYPE_ENERGY = 2,
|
||||
PM_OPCHAR_TYPE_TEMP = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* @PM_RET_SUCCESS: success
|
||||
* @PM_RET_ERROR_ARGS: illegal arguments provided
|
||||
* @PM_RET_ERROR_ACCESS: access rights violation
|
||||
* @PM_RET_ERROR_TIMEOUT: timeout in communication with PMU
|
||||
* @PM_RET_ERROR_NOTSUPPORTED: feature not supported
|
||||
* @PM_RET_ERROR_PROC: node is not a processor node
|
||||
* @PM_RET_ERROR_API_ID: illegal API ID
|
||||
* @PM_RET_ERROR_OTHER: other error
|
||||
*/
|
||||
enum XPmStatus {
|
||||
PM_RET_SUCCESS = 0,
|
||||
PM_RET_ERROR_ARGS = 1,
|
||||
PM_RET_ERROR_ACCESS = 2,
|
||||
PM_RET_ERROR_TIMEOUT = 3,
|
||||
PM_RET_ERROR_NOTSUPPORTED = 4,
|
||||
PM_RET_ERROR_PROC = 5,
|
||||
PM_RET_ERROR_API_ID = 6,
|
||||
PM_RET_ERROR_FAILURE = 7,
|
||||
PM_RET_ERROR_COMMUNIC = 8,
|
||||
PM_RET_ERROR_DOUBLEREQ = 9,
|
||||
PM_RET_ERROR_OTHER = 25,
|
||||
};
|
||||
|
||||
/**
|
||||
* @PM_INITIAL_BOOT: boot is a fresh system startup
|
||||
* @PM_RESUME: boot is a resume
|
||||
* @PM_BOOT_ERROR: error, boot cause cannot be identified
|
||||
*/
|
||||
enum XPmBootStatus {
|
||||
PM_INITIAL_BOOT,
|
||||
PM_RESUME,
|
||||
PM_BOOT_ERROR,
|
||||
};
|
||||
|
||||
#endif /* PM_DEFS_H_ */
|
3347
lib/sw_services/xilpm/src/common/pm_ipi.h
Normal file
3347
lib/sw_services/xilpm/src/common/pm_ipi.h
Normal file
File diff suppressed because it is too large
Load diff
58
lib/sw_services/xilpm/src/common/pm_ipi_buffer.h
Normal file
58
lib/sw_services/xilpm/src/common/pm_ipi_buffer.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef PM_IPI_BUFFER_H_
|
||||
#define PM_IPI_BUFFER_H_
|
||||
|
||||
#define IPI_BUFFER_BASEADDR 0xFF990000U
|
||||
|
||||
#define IPI_BUFFER_RPU_0_BASE (IPI_BUFFER_BASEADDR + 0x0U)
|
||||
#define IPI_BUFFER_RPU_1_BASE (IPI_BUFFER_BASEADDR + 0x200U)
|
||||
#define IPI_BUFFER_APU_BASE (IPI_BUFFER_BASEADDR + 0x400U)
|
||||
#define IPI_BUFFER_PL_0_BASE (IPI_BUFFER_BASEADDR + 0x600U)
|
||||
#define IPI_BUFFER_PL_1_BASE (IPI_BUFFER_BASEADDR + 0x800U)
|
||||
#define IPI_BUFFER_PL_2_BASE (IPI_BUFFER_BASEADDR + 0xA00U)
|
||||
#define IPI_BUFFER_PL_3_BASE (IPI_BUFFER_BASEADDR + 0xC00U)
|
||||
#define IPI_BUFFER_PMU_BASE (IPI_BUFFER_BASEADDR + 0xE00U)
|
||||
|
||||
#define IPI_BUFFER_TARGET_RPU_0_OFFSET 0x0U
|
||||
#define IPI_BUFFER_TARGET_RPU_1_OFFSET 0x40U
|
||||
#define IPI_BUFFER_TARGET_APU_OFFSET 0x80U
|
||||
#define IPI_BUFFER_TARGET_PL_0_OFFSET 0xC0U
|
||||
#define IPI_BUFFER_TARGET_PL_1_OFFSET 0x100U
|
||||
#define IPI_BUFFER_TARGET_PL_2_OFFSET 0x140U
|
||||
#define IPI_BUFFER_TARGET_PL_3_OFFSET 0x180U
|
||||
#define IPI_BUFFER_TARGET_PMU_OFFSET 0x1C0U
|
||||
|
||||
#define IPI_BUFFER_REQ_OFFSET 0x0U
|
||||
#define IPI_BUFFER_RESP_OFFSET 0x20U
|
||||
|
||||
#endif
|
142
lib/sw_services/xilpm/src/rpu/pm_client.c
Normal file
142
lib/sw_services/xilpm/src/rpu/pm_client.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* CONTENT
|
||||
* Each PU client in the system have such file with definitions of
|
||||
* masters in the subsystem and functions for getting informations
|
||||
* about the master.
|
||||
*********************************************************************/
|
||||
|
||||
#include "pm_client.h"
|
||||
|
||||
static const struct XPm_Ipi rpu_0_ipi = {
|
||||
.mask = IPI_RPU_MASK,
|
||||
.base = IPI_BASEADDR,
|
||||
.buffer_base = IPI_BUFFER_RPU_0_BASE,
|
||||
};
|
||||
|
||||
static const struct XPm_Master pm_rpu_0_master = {
|
||||
.node_id = NODE_RPU_0,
|
||||
.pwrdn_mask = RPU_RPU_0_PWRDWN_EN_MASK,
|
||||
.ipi = &rpu_0_ipi,
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const struct XPm_Master pm_rpu_1_master = {
|
||||
.node_id = NODE_APU_1,
|
||||
.pwrdn_mask = RPU_RPU_0_PWRDWN_EN_MASK,
|
||||
.ipi = &rpu_0_ipi,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Order in pm_master_all array must match cpu ids
|
||||
*/
|
||||
static const struct XPm_Master *const pm_masters_all[] = {
|
||||
&pm_rpu_0_master,
|
||||
#if 0
|
||||
&pm_rpu_1_master,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* pm_get_master() - returns pointer to the master structure
|
||||
* @cpuid: id of the cpu whose master struct pointer should be returned
|
||||
*
|
||||
* Return: pointer to a master structure if master is found, otherwise NULL
|
||||
*/
|
||||
const struct XPm_Master *pm_get_master(const uint32_t cpuid)
|
||||
{
|
||||
if (cpuid >=0 && PM_ARRAY_SIZE(pm_masters_all)) {
|
||||
return pm_masters_all[cpuid];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_get_master_by_node() - returns pointer to the master structure
|
||||
* @nid: ndoe id of the cpu master
|
||||
*
|
||||
* Return: pointer to a master structure if master is found, otherwise NULL
|
||||
*/
|
||||
const struct XPm_Master *pm_get_master_by_node(const enum XPmNodeId nid)
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < PM_ARRAY_SIZE(pm_masters_all); i++) {
|
||||
if (nid == pm_masters_all[i]->node_id) {
|
||||
return pm_masters_all[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint32_t pm_get_cpuid(const enum XPmNodeId node)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < PM_ARRAY_SIZE(pm_masters_all); i++) {
|
||||
if (pm_masters_all[i]->node_id == node) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return UNDEFINED_CPUID;
|
||||
}
|
||||
|
||||
const enum XPmNodeId subsystem_node = NODE_RPU;
|
||||
const struct XPm_Master *primary_master = &pm_rpu_0_master;
|
||||
|
||||
void XPm_ClientSuspend(const struct XPm_Master *const master)
|
||||
{
|
||||
/* Disable interrupts at processor level */
|
||||
pm_disable_int();
|
||||
/* Set powerdown request */
|
||||
pm_write(MASTER_PWRCTL, pm_read(MASTER_PWRCTL) | master->pwrdn_mask);
|
||||
}
|
||||
|
||||
void XPm_ClientAbortSuspend()
|
||||
{
|
||||
/* Enable interrupts at processor level */
|
||||
pm_enable_int();
|
||||
/* Clear powerdown request */
|
||||
pm_write(MASTER_PWRCTL, pm_read(MASTER_PWRCTL) & ~primary_master->pwrdn_mask);
|
||||
}
|
||||
|
||||
void XPm_ClientWakeup(const struct XPm_Master *const master)
|
||||
{
|
||||
uint32_t cpuid = pm_get_cpuid(master->node_id);
|
||||
|
||||
if (UNDEFINED_CPUID != cpuid) {
|
||||
uint32_t val = pm_read(MASTER_PWRCTL);
|
||||
val &= ~(master->pwrdn_mask);
|
||||
pm_write(MASTER_PWRCTL, val);
|
||||
}
|
||||
}
|
90
lib/sw_services/xilpm/src/rpu/pm_client.h
Normal file
90
lib/sw_services/xilpm/src/rpu/pm_client.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* CONTENT
|
||||
* File is specific for each PU instance and must exist in order to
|
||||
* port Power Management code for some new PU.
|
||||
* Contains PU specific macros and macros to be defined depending on
|
||||
* the execution environment.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef _PM_CLIENT_H_
|
||||
#define _PM_CLIENT_H_
|
||||
|
||||
#include <xil_exception.h>
|
||||
#include <xil_io.h>
|
||||
#include "pm_rpu.h"
|
||||
#include "pm_defs.h"
|
||||
#include "pm_common.h"
|
||||
|
||||
#define MASTER_PWRCTL RPU_RPU_0_PWRDWN
|
||||
|
||||
#define IPI_RPU_MASK 0x00000100U
|
||||
|
||||
#define IPI_TRIG_OFFSET 0x00010000
|
||||
#define IPI_OBS_OFFSET 0x00010004
|
||||
|
||||
#define UNDEFINED_CPUID (~0)
|
||||
|
||||
#define pm_read(addr) Xil_In32(addr)
|
||||
#define pm_write(addr, value) Xil_Out32(addr, value)
|
||||
#define pm_enable_int() Xil_ExceptionEnable()
|
||||
#define pm_disable_int() Xil_ExceptionDisable()
|
||||
#define pm_print(MSG, ...) xil_printf("RPU: "MSG,##__VA_ARGS__)
|
||||
#define pm_this_cpuid() 0U
|
||||
|
||||
/* Conditional debugging prints */
|
||||
#ifdef DEBUG_MODE
|
||||
#define pm_dbg(MSG, ...) \
|
||||
do { \
|
||||
pm_print(MSG,##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define pm_dbg(MSG, ...) {}
|
||||
#endif
|
||||
|
||||
#ifndef bool
|
||||
#define bool uint8_t
|
||||
#define true 1U
|
||||
#define false 0U
|
||||
#endif
|
||||
|
||||
void XPm_ClientSuspend(const struct XPm_Master *const master);
|
||||
void XPm_ClientAbortSuspend();
|
||||
void XPm_ClientWakeup(const struct XPm_Master *const master);
|
||||
|
||||
/* Do not modify below this line */
|
||||
extern const enum XPmNodeId subsystem_node;
|
||||
extern const struct XPm_Master *primary_master;
|
||||
|
||||
#endif /* _PM_CLIENT_H_ */
|
1527
lib/sw_services/xilpm/src/rpu/pm_rpu.h
Normal file
1527
lib/sw_services/xilpm/src/rpu/pm_rpu.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue