Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
aaa0567c
Commit
aaa0567c
authored
Aug 11, 2015
by
danh-arm
Browse files
Merge pull request #356 from mtk09422/mt8173-support-v3
Mt8173 support v3
parents
c905376f
7d116dcc
Changes
45
Show whitespace changes
Inline
Side-by-side
docs/cpu-specific-build-macros.md
View file @
aaa0567c
...
...
@@ -43,6 +43,15 @@ for it to specify which errata workarounds should be enabled or not.
The value of the build flags are 0 by default, that is, disabled. Any other
value will enable it.
For Cortex-A53, following errata build flags are defined :
*
`ERRATA_A53_826319`
: This applies errata 826319 workaround to Cortex-A53
CPU. This needs to be enabled only for revision <= r0p2 of the CPU.
*
`ERRATA_A53_836870`
: This applies errata 836870 workaround to Cortex-A53
CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From
r0p4 and onwards, this errata is enabled by default.
For Cortex-A57, following errata build flags are defined :
*
`ERRATA_A57_806969`
: This applies errata 806969 workaround to Cortex-A57
...
...
include/lib/cpus/aarch64/cortex_a53.h
View file @
aaa0567c
...
...
@@ -41,4 +41,19 @@
#define CPUECTLR_SMP_BIT (1 << 6)
/*******************************************************************************
* CPU Auxiliary Control register specific definitions.
******************************************************************************/
#define CPUACTLR_EL1 S3_1_C15_C2_0
/* Instruction def. */
#define CPUACTLR_DTAH (1 << 24)
/*******************************************************************************
* L2 Auxiliary Control register specific definitions.
******************************************************************************/
#define L2ACTLR_EL1 S3_1_C15_C0_0
/* Instruction def. */
#define L2ACTLR_ENABLE_UNIQUECLEAN (1 << 14)
#define L2ACTLR_DISABLE_CLEAN_PUSH (1 << 3)
#endif
/* __CORTEX_A53_H__ */
include/lib/mmio.h
View file @
aaa0567c
...
...
@@ -43,6 +43,16 @@ static inline uint8_t mmio_read_8(uintptr_t addr)
return
*
(
volatile
uint8_t
*
)
addr
;
}
static
inline
void
mmio_write_16
(
uintptr_t
addr
,
uint16_t
value
)
{
*
(
volatile
uint16_t
*
)
addr
=
value
;
}
static
inline
uint16_t
mmio_read_16
(
uintptr_t
addr
)
{
return
*
(
volatile
uint16_t
*
)
addr
;
}
static
inline
void
mmio_write_32
(
uintptr_t
addr
,
uint32_t
value
)
{
*
(
volatile
uint32_t
*
)
addr
=
value
;
...
...
@@ -63,4 +73,21 @@ static inline uint64_t mmio_read_64(uintptr_t addr)
return
*
(
volatile
uint64_t
*
)
addr
;
}
static
inline
void
mmio_clrbits_32
(
uintptr_t
addr
,
uint32_t
clear
)
{
mmio_write_32
(
addr
,
mmio_read_32
(
addr
)
&
~
clear
);
}
static
inline
void
mmio_setbits_32
(
uintptr_t
addr
,
uint32_t
set
)
{
mmio_write_32
(
addr
,
mmio_read_32
(
addr
)
|
set
);
}
static
inline
void
mmio_clrsetbits_32
(
uintptr_t
addr
,
uint32_t
clear
,
uint32_t
set
)
{
mmio_write_32
(
addr
,
(
mmio_read_32
(
addr
)
&
~
clear
)
|
set
);
}
#endif
/* __MMIO_H__ */
lib/cpus/aarch64/cortex_a53.S
View file @
aaa0567c
...
...
@@ -59,11 +59,93 @@ func cortex_a53_disable_smp
ret
endfunc
cortex_a53_disable_smp
/
*
--------------------------------------------------
*
Errata
Workaround
for
Cortex
A53
Errata
#
826319
.
*
This
applies
only
to
revision
<=
r0p2
of
Cortex
A53
.
*
Inputs
:
*
x0
:
variant
[
4
:
7
]
and
revision
[
0
:
3
]
of
current
cpu
.
*
Clobbers
:
x0
-
x5
*
--------------------------------------------------
*/
func
errata_a53_826319_wa
/
*
*
Compare
x0
against
revision
r0p2
*/
cmp
x0
,
#
2
b.ls
apply_826319
#if DEBUG
b
print_revision_warning
#else
ret
#endif
apply_826319
:
mrs
x1
,
L2ACTLR_EL1
bic
x1
,
x1
,
#
L2ACTLR_ENABLE_UNIQUECLEAN
orr
x1
,
x1
,
#
L2ACTLR_DISABLE_CLEAN_PUSH
msr
L2ACTLR_EL1
,
x1
ret
endfunc
errata_a53_826319_wa
/
*
--------------------------------------------------
*
Errata
Workaround
for
Cortex
A53
Errata
#
836870
.
*
This
applies
only
to
revision
<=
r0p3
of
Cortex
A53
.
*
From
r0p4
and
onwards
,
this
errata
is
enabled
by
*
default
.
*
Inputs
:
*
x0
:
variant
[
4
:
7
]
and
revision
[
0
:
3
]
of
current
cpu
.
*
Clobbers
:
x0
-
x5
*
--------------------------------------------------
*/
func
errata_a53_836870_wa
/
*
*
Compare
x0
against
revision
r0p3
*/
cmp
x0
,
#
3
b.ls
apply_836870
#if DEBUG
b
print_revision_warning
#else
ret
#endif
apply_836870
:
mrs
x1
,
CPUACTLR_EL1
orr
x1
,
x1
,
#
CPUACTLR_DTAH
msr
CPUACTLR_EL1
,
x1
ret
endfunc
errata_a53_836870_wa
/
*
-------------------------------------------------
*
The
CPU
Ops
reset
function
for
Cortex
-
A53
.
*
Clobbers
:
x0
-
x5
,
x15
,
x19
,
x30
*
-------------------------------------------------
*/
func
cortex_a53_reset_func
mov
x19
,
x30
mrs
x0
,
midr_el1
/
*
*
Extract
the
variant
[
20
:
23
]
and
revision
[
0
:
3
]
from
x0
*
and
pack
it
in
x15
[
0
:
7
]
as
variant
[
4
:
7
]
and
revision
[
0
:
3
]
.
*
First
extract
x0
[
16
:
23
]
to
x15
[
0
:
7
]
and
zero
fill
the
rest
.
*
Then
extract
x0
[
0
:
3
]
into
x15
[
0
:
3
]
retaining
other
bits
.
*/
ubfx
x15
,
x0
,
#(
MIDR_VAR_SHIFT
-
MIDR_REV_BITS
),
\
#(
MIDR_REV_BITS
+
MIDR_VAR_BITS
)
bfxil
x15
,
x0
,
#
MIDR_REV_SHIFT
,
#
MIDR_REV_BITS
#if ERRATA_A53_826319
mov
x0
,
x15
bl
errata_a53_826319_wa
#endif
#if ERRATA_A53_836870
mov
x0
,
x15
bl
errata_a53_836870_wa
#endif
/
*
---------------------------------------------
*
As
a
bare
minimum
enable
the
SMP
bit
if
it
is
*
not
already
set
.
*
Clobbers
:
x0
*
---------------------------------------------
*/
mrs
x0
,
CPUECTLR_EL1
...
...
@@ -71,9 +153,9 @@ func cortex_a53_reset_func
b.ne
skip_smp_setup
orr
x0
,
x0
,
#
CPUECTLR_SMP_BIT
msr
CPUECTLR_EL1
,
x0
isb
skip_smp_setup
:
ret
isb
ret
x19
endfunc
cortex_a53_reset_func
func
cortex_a53_core_pwr_dwn
...
...
lib/cpus/cpu-ops.mk
View file @
aaa0567c
...
...
@@ -40,6 +40,15 @@ $(eval $(call add_define,SKIP_A57_L1_FLUSH_PWR_DWN))
# CPU Errata Build flags. These should be enabled by the
# platform if the errata needs to be applied.
# Flag to apply errata 826319 during reset. This errata applies only to
# revision <= r0p2 of the Cortex A53 cpu.
ERRATA_A53_826319
?=
0
# Flag to apply errata 836870 during reset. This errata applies only to
# revision <= r0p3 of the Cortex A53 cpu. From r0p4 and onwards, this
# errata is enabled by default.
ERRATA_A53_836870
?=
0
# Flag to apply errata 806969 during reset. This errata applies only to
# revision r0p0 of the Cortex A57 cpu.
ERRATA_A57_806969
?=
0
...
...
@@ -48,6 +57,14 @@ ERRATA_A57_806969 ?=0
# revision r0p0 of the Cortex A57 cpu.
ERRATA_A57_813420
?=
0
# Process ERRATA_A53_826319 flag
$(eval
$(call
assert_boolean,ERRATA_A53_826319))
$(eval
$(call
add_define,ERRATA_A53_826319))
# Process ERRATA_A53_836870 flag
$(eval
$(call
assert_boolean,ERRATA_A53_836870))
$(eval
$(call
add_define,ERRATA_A53_836870))
# Process ERRATA_A57_806969 flag
$(eval
$(call
assert_boolean,ERRATA_A57_806969))
$(eval
$(call
add_define,ERRATA_A57_806969))
...
...
plat/mediatek/common/mtk_sip_svc.c
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <debug.h>
#include <mtk_sip_svc.h>
#include <runtime_svc.h>
#include <uuid.h>
/* Mediatek SiP Service UUID */
DEFINE_SVC_UUID
(
mtk_sip_svc_uid
,
0xf7582ba4
,
0x4262
,
0x4d7d
,
0x80
,
0xe5
,
0x8f
,
0x95
,
0x05
,
0x00
,
0x0f
,
0x3d
);
/*
* This function handles Mediatek defined SiP Calls */
static
uint64_t
mediatek_sip_handler
(
uint32_t
smc_fid
,
uint64_t
x1
,
uint64_t
x2
,
uint64_t
x3
,
uint64_t
x4
,
void
*
cookie
,
void
*
handle
)
{
uint64_t
ret
;
switch
(
smc_fid
)
{
case
MTK_SIP_SET_AUTHORIZED_SECURE_REG
:
ret
=
mt_sip_set_authorized_sreg
((
uint32_t
)
x1
,
(
uint32_t
)
x2
);
SMC_RET1
(
handle
,
ret
);
default:
ERROR
(
"%s: unhandled SMC (0x%x)
\n
"
,
__func__
,
smc_fid
);
break
;
}
SMC_RET1
(
handle
,
SMC_UNK
);
}
/*
* This function is responsible for handling all SiP calls from the NS world
*/
uint64_t
sip_smc_handler
(
uint32_t
smc_fid
,
uint64_t
x1
,
uint64_t
x2
,
uint64_t
x3
,
uint64_t
x4
,
void
*
cookie
,
void
*
handle
,
uint64_t
flags
)
{
uint32_t
ns
;
/* Determine which security state this SMC originated from */
ns
=
is_caller_non_secure
(
flags
);
if
(
!
ns
)
SMC_RET1
(
handle
,
SMC_UNK
);
switch
(
smc_fid
)
{
case
SIP_SVC_CALL_COUNT
:
/* Return the number of Mediatek SiP Service Calls. */
SMC_RET1
(
handle
,
MTK_SIP_NUM_CALLS
);
case
SIP_SVC_UID
:
/* Return UID to the caller */
SMC_UUID_RET
(
handle
,
mtk_sip_svc_uid
);
case
SIP_SVC_VERSION
:
/* Return the version of current implementation */
SMC_RET2
(
handle
,
MTK_SIP_SVC_VERSION_MAJOR
,
MTK_SIP_SVC_VERSION_MINOR
);
default:
return
mediatek_sip_handler
(
smc_fid
,
x1
,
x2
,
x3
,
x4
,
cookie
,
handle
);
}
}
/* Define a runtime service descriptor for fast SMC calls */
DECLARE_RT_SVC
(
mediatek_sip_svc
,
OEN_SIP_START
,
OEN_SIP_END
,
SMC_TYPE_FAST
,
NULL
,
sip_smc_handler
);
plat/mediatek/common/mtk_sip_svc.h
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __PLAT_SIP_SVC_H__
#define __PLAT_SIP_SVC_H__
#include <stdint.h>
/* SMC function IDs for SiP Service queries */
#define SIP_SVC_CALL_COUNT 0x8200ff00
#define SIP_SVC_UID 0x8200ff01
/* 0x8200ff02 is reserved */
#define SIP_SVC_VERSION 0x8200ff03
/* Mediatek SiP Service Calls version numbers */
#define MTK_SIP_SVC_VERSION_MAJOR 0x0
#define MTK_SIP_SVC_VERSION_MINOR 0x1
/* Number of Mediatek SiP Calls implemented */
#define MTK_SIP_NUM_CALLS 1
/* Mediatek SiP Service Calls function IDs */
#define MTK_SIP_SET_AUTHORIZED_SECURE_REG 0x82000001
/* Mediatek SiP Calls error code */
enum
{
MTK_SIP_E_SUCCESS
=
0
,
MTK_SIP_E_INVALID_PARAM
=
-
1
};
/*
* This function should be implemented in Mediatek SOC directory. It fullfills
* MTK_SIP_SET_AUTHORIZED_SECURE_REG SiP call by checking the sreg with the
* predefined secure register list, if a match was found, set val to sreg.
*
* Return MTK_SIP_E_SUCCESS on success, and MTK_SIP_E_INVALID_PARAM on failure.
*/
uint64_t
mt_sip_set_authorized_sreg
(
uint32_t
sreg
,
uint32_t
val
);
#endif
/* __PLAT_SIP_SVC_H__ */
plat/mediatek/mt8173/aarch64/plat_helpers.S
0 → 100644
View file @
aaa0567c
/*
*
Copyright
(
c
)
2013
-
2015
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
Redistribution
and
use
in
source
and
binary
forms
,
with
or
without
*
modification
,
are
permitted
provided
that
the
following
conditions
are
met
:
*
*
Redistributions
of
source
code
must
retain
the
above
copyright
notice
,
this
*
list
of
conditions
and
the
following
disclaimer
.
*
*
Redistributions
in
binary
form
must
reproduce
the
above
copyright
notice
,
*
this
list
of
conditions
and
the
following
disclaimer
in
the
documentation
*
and
/
or
other
materials
provided
with
the
distribution
.
*
*
Neither
the
name
of
ARM
nor
the
names
of
its
contributors
may
be
used
*
to
endorse
or
promote
products
derived
from
this
software
without
specific
*
prior
written
permission
.
*
*
THIS
SOFTWARE
IS
PROVIDED
BY
THE
COPYRIGHT
HOLDERS
AND
CONTRIBUTORS
"AS IS"
*
AND
ANY
EXPRESS
OR
IMPLIED
WARRANTIES
,
INCLUDING
,
BUT
NOT
LIMITED
TO
,
THE
*
IMPLIED
WARRANTIES
OF
MERCHANTABILITY
AND
FITNESS
FOR
A
PARTICULAR
PURPOSE
*
ARE
DISCLAIMED
.
IN
NO
EVENT
SHALL
THE
COPYRIGHT
HOLDER
OR
CONTRIBUTORS
BE
*
LIABLE
FOR
ANY
DIRECT
,
INDIRECT
,
INCIDENTAL
,
SPECIAL
,
EXEMPLARY
,
OR
*
CONSEQUENTIAL
DAMAGES
(
INCLUDING
,
BUT
NOT
LIMITED
TO
,
PROCUREMENT
OF
*
SUBSTITUTE
GOODS
OR
SERVICES
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
*
INTERRUPTION
)
HOWEVER
CAUSED
AND
ON
ANY
THEORY
OF
LIABILITY
,
WHETHER
IN
*
CONTRACT
,
STRICT
LIABILITY
,
OR
TORT
(
INCLUDING
NEGLIGENCE
OR
OTHERWISE
)
*
ARISING
IN
ANY
WAY
OUT
OF
THE
USE
OF
THIS
SOFTWARE
,
EVEN
IF
ADVISED
OF
THE
*
POSSIBILITY
OF
SUCH
DAMAGE
.
*/
#include <arch.h>
#include <asm_macros.S>
#include <mt8173_def.h>
.
globl
plat_secondary_cold_boot_setup
.
globl
plat_report_exception
.
globl
platform_is_primary_cpu
.
globl
plat_crash_console_init
.
globl
plat_crash_console_putc
/
*
-----------------------------------------------------
*
void
plat_secondary_cold_boot_setup
(
void
)
;
*
*
This
function
performs
any
platform
specific
actions
*
needed
for
a
secondary
cpu
after
a
cold
reset
e
.
g
*
mark
the
cpu
's presence, mechanism to place it in a
*
holding
pen
etc
.
*
-----------------------------------------------------
*/
func
plat_secondary_cold_boot_setup
/
*
MT8173
Oak
does
not
do
cold
boot
for
secondary
CPU
*/
cb_panic
:
b
cb_panic
endfunc
plat_secondary_cold_boot_setup
func
platform_is_primary_cpu
and
x0
,
x0
,
#(
MPIDR_CLUSTER_MASK
|
MPIDR_CPU_MASK
)
cmp
x0
,
#
MT8173_PRIMARY_CPU
cset
x0
,
eq
ret
endfunc
platform_is_primary_cpu
/
*
---------------------------------------------
*
int
plat_crash_console_init
(
void
)
*
Function
to
initialize
the
crash
console
*
without
a
C
Runtime
to
print
crash
report
.
*
Clobber
list
:
x0
,
x1
,
x2
*
---------------------------------------------
*/
func
plat_crash_console_init
mov_imm
x0
,
MT8173_UART0_BASE
mov_imm
x1
,
MT8173_UART_CLOCK
mov_imm
x2
,
MT8173_BAUDRATE
b
console_core_init
endfunc
plat_crash_console_init
/
*
---------------------------------------------
*
int
plat_crash_console_putc
(
void
)
*
Function
to
print
a
character
on
the
crash
*
console
without
a
C
Runtime
.
*
Clobber
list
:
x1
,
x2
*
---------------------------------------------
*/
func
plat_crash_console_putc
mov_imm
x1
,
MT8173_UART0_BASE
b
console_core_putc
endfunc
plat_crash_console_putc
plat/mediatek/mt8173/aarch64/platform_common.c
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <arch_helpers.h>
#include <arm_gic.h>
#include <bl_common.h>
#include <cci.h>
#include <debug.h>
#include <mt8173_def.h>
#include <platform_def.h>
#include <xlat_tables.h>
static
const
int
cci_map
[]
=
{
PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX
,
PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX
};
/* Table of regions to map using the MMU. */
const
mmap_region_t
plat_mmap
[]
=
{
/* for TF text, RO, RW */
MAP_REGION_FLAT
(
TZRAM_BASE
,
TZRAM_SIZE
+
TZRAM2_SIZE
,
MT_MEMORY
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
MTK_DEV_RNG0_BASE
,
MTK_DEV_RNG0_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
MTK_DEV_RNG1_BASE
,
MTK_DEV_RNG1_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
{
0
}
};
/*******************************************************************************
* Macro generating the code for the function setting up the pagetables as per
* the platform memory map & initialize the mmu, for the given exception level
******************************************************************************/
#define DEFINE_CONFIGURE_MMU_EL(_el) \
void plat_configure_mmu_el ## _el(unsigned long total_base, \
unsigned long total_size, \
unsigned long ro_start, \
unsigned long ro_limit, \
unsigned long coh_start, \
unsigned long coh_limit) \
{ \
mmap_add_region(total_base, total_base, \
total_size, \
MT_MEMORY | MT_RW | MT_SECURE); \
mmap_add_region(ro_start, ro_start, \
ro_limit - ro_start, \
MT_MEMORY | MT_RO | MT_SECURE); \
mmap_add_region(coh_start, coh_start, \
coh_limit - coh_start, \
MT_DEVICE | MT_RW | MT_SECURE); \
mmap_add(plat_mmap); \
init_xlat_tables(); \
\
enable_mmu_el ## _el(0); \
}
/* Define EL3 variants of the function initialising the MMU */
DEFINE_CONFIGURE_MMU_EL
(
3
)
uint64_t
plat_get_syscnt_freq
(
void
)
{
return
SYS_COUNTER_FREQ_IN_TICKS
;
}
void
plat_cci_init
(
void
)
{
/* Initialize CCI driver */
cci_init
(
PLAT_MT_CCI_BASE
,
cci_map
,
ARRAY_SIZE
(
cci_map
));
}
void
plat_cci_enable
(
void
)
{
/*
* Enable CCI coherency for this cluster.
* No need for locks as no other cpu is active at the moment.
*/
cci_enable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
read_mpidr
()));
}
void
plat_cci_disable
(
void
)
{
cci_disable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
read_mpidr
()));
}
plat/mediatek/mt8173/bl31_plat_setup.c
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <arm_gic.h>
#include <assert.h>
#include <bl_common.h>
#include <console.h>
#include <debug.h>
#include <mcucfg.h>
#include <mmio.h>
#include <mtcmos.h>
#include <plat_private.h>
#include <platform.h>
#include <spm.h>
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM
******************************************************************************/
unsigned
long
__RO_START__
;
unsigned
long
__RO_END__
;
unsigned
long
__COHERENT_RAM_START__
;
unsigned
long
__COHERENT_RAM_END__
;
/*
* The next 2 constants identify the extents of the code & RO data region.
* These addresses are used by the MMU setup code and therefore they must be
* page-aligned. It is the responsibility of the linker script to ensure that
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
*/
#define BL31_RO_BASE (unsigned long)(&__RO_START__)
#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
/*
* The next 2 constants identify the extents of the coherent memory region.
* These addresses are used by the MMU setup code and therefore they must be
* page-aligned. It is the responsibility of the linker script to ensure that
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
* refer to page-aligned addresses.
*/
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
static
entry_point_info_t
bl32_ep_info
;
static
entry_point_info_t
bl33_ep_info
;
static
void
platform_setup_cpu
(
void
)
{
/* turn off all the little core's power except cpu 0 */
mtcmos_little_cpu_off
();
/* setup big cores */
mmio_write_32
((
uintptr_t
)
&
mt8173_mcucfg
->
mp1_config_res
,
MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK
|
MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK
|
MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK
|
MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK
|
MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK
);
mmio_setbits_32
((
uintptr_t
)
&
mt8173_mcucfg
->
mp1_miscdbg
,
MP1_AINACTS
);
mmio_setbits_32
((
uintptr_t
)
&
mt8173_mcucfg
->
mp1_clkenm_div
,
MP1_SW_CG_GEN
);
mmio_clrbits_32
((
uintptr_t
)
&
mt8173_mcucfg
->
mp1_rst_ctl
,
MP1_L2RSTDISABLE
);
/* set big cores arm64 boot mode */
mmio_setbits_32
((
uintptr_t
)
&
mt8173_mcucfg
->
mp1_cpucfg
,
MP1_CPUCFG_64BIT
);
/* set LITTLE cores arm64 boot mode */
mmio_setbits_32
((
uintptr_t
)
&
mt8173_mcucfg
->
mp0_rv_addr
[
0
].
rv_addr_hw
,
MP0_CPUCFG_64BIT
);
}
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
* the security state specified. BL33 corresponds to the non-secure image type
* while BL32 corresponds to the secure image type. A NULL pointer is returned
* if the image does not exist.
******************************************************************************/
entry_point_info_t
*
bl31_plat_get_next_image_ep_info
(
uint32_t
type
)
{
entry_point_info_t
*
next_image_info
;
next_image_info
=
(
type
==
NON_SECURE
)
?
&
bl33_ep_info
:
&
bl32_ep_info
;
/* None of the images on this platform can have 0x0 as the entrypoint */
if
(
next_image_info
->
pc
)
return
next_image_info
;
else
return
NULL
;
}
/*******************************************************************************
* Perform any BL3-1 early platform setup. Here is an opportunity to copy
* parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
* are lost (potentially). This needs to be done before the MMU is initialized
* so that the memory layout can be used while creating page tables.
* BL2 has flushed this information to memory, so we are guaranteed to pick up
* good data.
******************************************************************************/
void
bl31_early_platform_setup
(
bl31_params_t
*
from_bl2
,
void
*
plat_params_from_bl2
)
{
console_init
(
MT8173_UART0_BASE
,
MT8173_UART_CLOCK
,
MT8173_BAUDRATE
);
VERBOSE
(
"bl31_setup
\n
"
);
assert
(
from_bl2
!=
NULL
);
assert
(
from_bl2
->
h
.
type
==
PARAM_BL31
);
assert
(
from_bl2
->
h
.
version
>=
VERSION_1
);
assert
(((
unsigned
long
)
plat_params_from_bl2
)
==
MT_BL31_PLAT_PARAM_VAL
);
bl32_ep_info
=
*
from_bl2
->
bl32_ep_info
;
bl33_ep_info
=
*
from_bl2
->
bl33_ep_info
;
}
/*******************************************************************************
* Perform any BL3-1 platform setup code
******************************************************************************/
void
bl31_platform_setup
(
void
)
{
platform_setup_cpu
();
plat_delay_timer_init
();
/* Initialize the gic cpu and distributor interfaces */
plat_mt_gic_init
();
arm_gic_setup
();
/* Topologies are best known to the platform. */
mt_setup_topology
();
/* Initialize spm at boot time */
spm_boot_init
();
}
/*******************************************************************************
* Perform the very early platform specific architectural setup here. At the
* moment this is only intializes the mmu in a quick and dirty way.
******************************************************************************/
void
bl31_plat_arch_setup
(
void
)
{
plat_cci_init
();
plat_cci_enable
();
plat_configure_mmu_el3
(
BL31_RO_BASE
,
(
BL31_COHERENT_RAM_LIMIT
-
BL31_RO_BASE
),
BL31_RO_BASE
,
BL31_RO_LIMIT
,
BL31_COHERENT_RAM_BASE
,
BL31_COHERENT_RAM_LIMIT
);
}
plat/mediatek/mt8173/drivers/gpio/gpio.c
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <debug.h>
#include <gpio.h>
#include <mmio.h>
#include <mt8173_def.h>
#include <pmic_wrap_init.h>
enum
{
MAX_GPIO_REG_BITS
=
16
,
};
struct
mt_gpio_obj
{
struct
gpio_regs
*
reg
;
};
static
struct
mt_gpio_obj
gpio_dat
=
{
.
reg
=
(
struct
gpio_regs
*
)(
GPIO_BASE
),
};
static
struct
mt_gpio_obj
*
gpio_obj
=
&
gpio_dat
;
struct
mt_gpioext_obj
{
struct
gpioext_regs
*
reg
;
};
static
struct
mt_gpioext_obj
gpioext_dat
=
{
.
reg
=
(
struct
gpioext_regs
*
)(
GPIOEXT_BASE
),
};
static
struct
mt_gpioext_obj
*
gpioext_obj
=
&
gpioext_dat
;
static
inline
struct
mt_gpio_obj
*
mt_get_gpio_obj
(
void
)
{
return
gpio_obj
;
}
static
inline
struct
mt_gpioext_obj
*
mt_get_gpioext_obj
(
void
)
{
return
gpioext_obj
;
}
enum
{
GPIO_PRO_DIR
=
0
,
GPIO_PRO_DOUT
,
GPIO_PRO_DIN
,
GPIO_PRO_PULLEN
,
GPIO_PRO_PULLSEL
,
GPIO_PRO_MODE
,
GPIO_PRO_MAX
,
};
static
inline
int32_t
gpioext_write
(
uint16_t
*
addr
,
int64_t
data
)
{
return
pwrap_write
((
uint32_t
)(
uintptr_t
)
addr
,
data
);
}
static
inline
int32_t
gpioext_set_bits
(
uint32_t
bit
,
uint16_t
*
reg
)
{
return
gpioext_write
(
reg
,
bit
);
}
static
int32_t
mt_set_gpio_chip
(
uint32_t
pin
,
uint32_t
property
,
uint32_t
val
)
{
uint32_t
pos
=
0
;
uint32_t
bit
=
0
;
struct
mt_gpio_obj
*
obj
=
mt_get_gpio_obj
();
uint16_t
*
reg
;
uint32_t
data
=
0
;
if
(
!
obj
)
return
-
ERACCESS
;
if
(
pin
>=
GPIO_EXTEND_START
)
return
-
ERINVAL
;
if
(
property
>=
GPIO_PRO_MAX
)
return
-
ERINVAL
;
pos
=
pin
/
MAX_GPIO_REG_BITS
;
bit
=
pin
%
MAX_GPIO_REG_BITS
;
data
=
1L
<<
bit
;
switch
(
property
)
{
case
GPIO_PRO_DIR
:
if
(
val
==
GPIO_DIR_IN
)
reg
=
&
obj
->
reg
->
dir
[
pos
].
rst
;
else
reg
=
&
obj
->
reg
->
dir
[
pos
].
set
;
break
;
case
GPIO_PRO_DOUT
:
if
(
val
==
GPIO_OUT_ZERO
)
reg
=
&
obj
->
reg
->
dout
[
pos
].
rst
;
else
reg
=
&
obj
->
reg
->
dout
[
pos
].
set
;
break
;
default:
return
-
ERINVAL
;
}
mmio_write_16
((
uintptr_t
)
reg
,
data
);
return
RSUCCESS
;
}
static
int32_t
mt_set_gpio_ext
(
uint32_t
pin
,
uint32_t
property
,
uint32_t
val
)
{
uint32_t
pos
=
0
;
uint32_t
bit
=
0
;
struct
mt_gpioext_obj
*
obj
=
mt_get_gpioext_obj
();
uint16_t
*
reg
;
uint32_t
data
=
0
;
int
ret
=
0
;
if
(
!
obj
)
return
-
ERACCESS
;
if
(
pin
>=
MAX_GPIO_PIN
)
return
-
ERINVAL
;
if
(
property
>=
GPIO_PRO_MAX
)
return
-
ERINVAL
;
pin
-=
GPIO_EXTEND_START
;
pos
=
pin
/
MAX_GPIO_REG_BITS
;
bit
=
pin
%
MAX_GPIO_REG_BITS
;
switch
(
property
)
{
case
GPIO_PRO_DIR
:
if
(
val
==
GPIO_DIR_IN
)
reg
=
&
obj
->
reg
->
dir
[
pos
].
rst
;
else
reg
=
&
obj
->
reg
->
dir
[
pos
].
set
;
break
;
case
GPIO_PRO_DOUT
:
if
(
val
==
GPIO_OUT_ZERO
)
reg
=
&
obj
->
reg
->
dout
[
pos
].
rst
;
else
reg
=
&
obj
->
reg
->
dout
[
pos
].
set
;
break
;
default:
return
-
ERINVAL
;
}
data
=
(
1L
<<
bit
);
ret
=
gpioext_set_bits
(
data
,
reg
);
return
ret
?
-
ERWRAPPER
:
RSUCCESS
;
}
static
void
mt_gpio_pin_decrypt
(
uint32_t
*
cipher
)
{
if
((
*
cipher
&
(
0x80000000
))
==
0
)
INFO
(
"Pin %u decrypt warning!
\n
"
,
*
cipher
);
*
cipher
&=
~
(
0x80000000
);
}
int32_t
mt_set_gpio_out
(
uint32_t
pin
,
uint32_t
output
)
{
uint32_t
gp
=
GPIO_PRO_DOUT
;
mt_gpio_pin_decrypt
(
&
pin
);
return
(
pin
>=
GPIO_EXTEND_START
)
?
mt_set_gpio_ext
(
pin
,
gp
,
output
)
:
mt_set_gpio_chip
(
pin
,
gp
,
output
);
}
void
gpio_set
(
uint32_t
gpio
,
int32_t
value
)
{
mt_set_gpio_out
(
gpio
,
value
);
}
plat/mediatek/mt8173/drivers/gpio/gpio.h
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __PLAT_DRIVER_GPIO_H__
#define __PLAT_DRIVER_GPIO_H__
#include <stdint.h>
enum
{
GPIOEXT_BASE
=
0xC000
,
};
/* Error Code No. */
enum
{
RSUCCESS
=
0
,
ERACCESS
,
ERINVAL
,
ERWRAPPER
,
};
enum
{
GPIO_UNSUPPORTED
=
-
1
,
GPIO0
,
GPIO1
,
GPIO2
,
GPIO3
,
GPIO4
,
GPIO5
,
GPIO6
,
GPIO7
,
GPIO8
,
GPIO9
,
GPIO10
,
GPIO11
,
GPIO12
,
GPIO13
,
GPIO14
,
GPIO15
,
GPIO16
,
GPIO17
,
GPIO18
,
GPIO19
,
GPIO20
,
GPIO21
,
GPIO22
,
GPIO23
,
GPIO24
,
GPIO25
,
GPIO26
,
GPIO27
,
GPIO28
,
GPIO29
,
GPIO30
,
GPIO31
,
GPIO32
,
GPIO33
,
GPIO34
,
GPIO35
,
GPIO36
,
GPIO37
,
GPIO38
,
GPIO39
,
GPIO40
,
GPIO41
,
GPIO42
,
GPIO43
,
GPIO44
,
GPIO45
,
GPIO46
,
GPIO47
,
GPIO48
,
GPIO49
,
GPIO50
,
GPIO51
,
GPIO52
,
GPIO53
,
GPIO54
,
GPIO55
,
GPIO56
,
GPIO57
,
GPIO58
,
GPIO59
,
GPIO60
,
GPIO61
,
GPIO62
,
GPIO63
,
GPIO64
,
GPIO65
,
GPIO66
,
GPIO67
,
GPIO68
,
GPIO69
,
GPIO70
,
GPIO71
,
GPIO72
,
GPIO73
,
GPIO74
,
GPIO75
,
GPIO76
,
GPIO77
,
GPIO78
,
GPIO79
,
GPIO80
,
GPIO81
,
GPIO82
,
GPIO83
,
GPIO84
,
GPIO85
,
GPIO86
,
GPIO87
,
GPIO88
,
GPIO89
,
GPIO90
,
GPIO91
,
GPIO92
,
GPIO93
,
GPIO94
,
GPIO95
,
GPIO96
,
GPIO97
,
GPIO98
,
GPIO99
,
GPIO100
,
GPIO101
,
GPIO102
,
GPIO103
,
GPIO104
,
GPIO105
,
GPIO106
,
GPIO107
,
GPIO108
,
GPIO109
,
GPIO110
,
GPIO111
,
GPIO112
,
GPIO113
,
GPIO114
,
GPIO115
,
GPIO116
,
GPIO117
,
GPIO118
,
GPIO119
,
GPIO120
,
GPIO121
,
GPIO122
,
GPIO123
,
GPIO124
,
GPIO125
,
GPIO126
,
GPIO127
,
GPIO128
,
GPIO129
,
GPIO130
,
GPIO131
,
GPIO132
,
GPIO133
,
GPIO134
,
GPIOEXT0
,
GPIOEXT1
,
GPIOEXT2
,
GPIOEXT3
,
GPIOEXT4
,
GPIOEXT5
,
GPIOEXT6
,
GPIOEXT7
,
GPIOEXT8
,
GPIOEXT9
,
GPIOEXT10
,
GPIOEXT11
,
GPIOEXT12
,
GPIOEXT13
,
GPIOEXT14
,
GPIOEXT15
,
GPIOEXT16
,
GPIOEXT17
,
GPIOEXT18
,
GPIOEXT19
,
GPIOEXT20
,
GPIOEXT21
,
GPIOEXT22
,
GPIOEXT23
,
GPIOEXT24
,
GPIOEXT25
,
GPIOEXT26
,
GPIOEXT27
,
GPIOEXT28
,
GPIOEXT29
,
GPIOEXT30
,
GPIOEXT31
,
GPIOEXT32
,
GPIOEXT33
,
GPIOEXT34
,
GPIOEXT35
,
GPIOEXT36
,
GPIOEXT37
,
GPIOEXT38
,
GPIOEXT39
,
GPIOEXT40
,
GPIO_MAX
};
#define MAX_GPIO_PIN GPIO_MAX
#define GPIO_EXTEND_START GPIOEXT0
/* GPIO DIRECTION */
enum
{
GPIO_DIR_UNSUPPORTED
=
-
1
,
GPIO_DIR_IN
=
0
,
GPIO_DIR_OUT
=
1
,
GPIO_DIR_MAX
,
GPIO_DIR_DEFAULT
=
GPIO_DIR_IN
,
};
/* GPIO OUTPUT */
enum
{
GPIO_OUT_UNSUPPORTED
=
-
1
,
GPIO_OUT_ZERO
=
0
,
GPIO_OUT_ONE
=
1
,
GPIO_OUT_MAX
,
GPIO_OUT_DEFAULT
=
GPIO_OUT_ZERO
,
GPIO_DATA_OUT_DEFAULT
=
GPIO_OUT_ZERO
,
/* compatible with DCT */
};
struct
val_regs
{
uint16_t
val
;
uint16_t
_align1
;
uint16_t
set
;
uint16_t
_align2
;
uint16_t
rst
;
uint16_t
_align3
[
3
];
};
struct
gpio_regs
{
struct
val_regs
dir
[
9
];
/* 0x0000 ~ 0x008F: 144 bytes */
uint8_t
rsv00
[
112
];
/* 0x0090 ~ 0x00FF: 112 bytes */
struct
val_regs
pullen
[
9
];
/* 0x0100 ~ 0x018F: 144 bytes */
uint8_t
rsv01
[
112
];
/* 0x0190 ~ 0x01FF: 112 bytes */
struct
val_regs
pullsel
[
9
];
/* 0x0200 ~ 0x028F: 144 bytes */
uint8_t
rsv02
[
112
];
/* 0x0290 ~ 0x02FF: 112 bytes */
uint8_t
rsv03
[
256
];
/* 0x0300 ~ 0x03FF: 256 bytes */
struct
val_regs
dout
[
9
];
/* 0x0400 ~ 0x048F: 144 bytes */
uint8_t
rsv04
[
112
];
/* 0x0490 ~ 0x04FF: 112 bytes */
struct
val_regs
din
[
9
];
/* 0x0500 ~ 0x058F: 114 bytes */
uint8_t
rsv05
[
112
];
/* 0x0590 ~ 0x05FF: 112 bytes */
struct
val_regs
mode
[
27
];
/* 0x0600 ~ 0x07AF: 432 bytes */
uint8_t
rsv06
[
336
];
/* 0x07B0 ~ 0x08FF: 336 bytes */
struct
val_regs
ies
[
3
];
/* 0x0900 ~ 0x092F: 48 bytes */
struct
val_regs
smt
[
3
];
/* 0x0930 ~ 0x095F: 48 bytes */
uint8_t
rsv07
[
160
];
/* 0x0960 ~ 0x09FF: 160 bytes */
struct
val_regs
tdsel
[
8
];
/* 0x0A00 ~ 0x0A7F: 128 bytes */
struct
val_regs
rdsel
[
6
];
/* 0x0A80 ~ 0x0ADF: 96 bytes */
uint8_t
rsv08
[
32
];
/* 0x0AE0 ~ 0x0AFF: 32 bytes */
struct
val_regs
drv_mode
[
10
];
/* 0x0B00 ~ 0x0B9F: 160 bytes */
uint8_t
rsv09
[
96
];
/* 0x0BA0 ~ 0x0BFF: 96 bytes */
struct
val_regs
msdc0_ctrl0
;
/* 0x0C00 ~ 0x0C0F: 16 bytes */
struct
val_regs
msdc0_ctrl1
;
/* 0x0C10 ~ 0x0C1F: 16 bytes */
struct
val_regs
msdc0_ctrl2
;
/* 0x0C20 ~ 0x0C2F: 16 bytes */
struct
val_regs
msdc0_ctrl5
;
/* 0x0C30 ~ 0x0C3F: 16 bytes */
struct
val_regs
msdc1_ctrl0
;
/* 0x0C40 ~ 0x0C4F: 16 bytes */
struct
val_regs
msdc1_ctrl1
;
/* 0x0C50 ~ 0x0C5F: 16 bytes */
struct
val_regs
msdc1_ctrl2
;
/* 0x0C60 ~ 0x0C6F: 16 bytes */
struct
val_regs
msdc1_ctrl5
;
/* 0x0C70 ~ 0x0C7F: 16 bytes */
struct
val_regs
msdc2_ctrl0
;
/* 0x0C80 ~ 0x0C8F: 16 bytes */
struct
val_regs
msdc2_ctrl1
;
/* 0x0C90 ~ 0x0C9F: 16 bytes */
struct
val_regs
msdc2_ctrl2
;
/* 0x0CA0 ~ 0x0CAF: 16 bytes */
struct
val_regs
msdc2_ctrl5
;
/* 0x0CB0 ~ 0x0CBF: 16 bytes */
struct
val_regs
msdc3_ctrl0
;
/* 0x0CC0 ~ 0x0CCF: 16 bytes */
struct
val_regs
msdc3_ctrl1
;
/* 0x0CD0 ~ 0x0CDF: 16 bytes */
struct
val_regs
msdc3_ctrl2
;
/* 0x0CE0 ~ 0x0CEF: 16 bytes */
struct
val_regs
msdc3_ctrl5
;
/* 0x0CF0 ~ 0x0CFF: 16 bytes */
struct
val_regs
msdc0_ctrl3
;
/* 0x0D00 ~ 0x0D0F: 16 bytes */
struct
val_regs
msdc0_ctrl4
;
/* 0x0D10 ~ 0x0D1F: 16 bytes */
struct
val_regs
msdc1_ctrl3
;
/* 0x0D20 ~ 0x0D2F: 16 bytes */
struct
val_regs
msdc1_ctrl4
;
/* 0x0D30 ~ 0x0D3F: 16 bytes */
struct
val_regs
msdc2_ctrl3
;
/* 0x0D40 ~ 0x0D4F: 16 bytes */
struct
val_regs
msdc2_ctrl4
;
/* 0x0D50 ~ 0x0D5F: 16 bytes */
struct
val_regs
msdc3_ctrl3
;
/* 0x0D60 ~ 0x0D6F: 16 bytes */
struct
val_regs
msdc3_ctrl4
;
/* 0x0D70 ~ 0x0D7F: 16 bytes */
uint8_t
rsv10
[
64
];
/* 0x0D80 ~ 0x0DBF: 64 bytes */
struct
val_regs
exmd_ctrl
[
1
];
/* 0x0DC0 ~ 0x0DCF: 16 bytes */
uint8_t
rsv11
[
48
];
/* 0x0DD0 ~ 0x0DFF: 48 bytes */
struct
val_regs
kpad_ctrl
[
2
];
/* 0x0E00 ~ 0x0E1F: 32 bytes */
struct
val_regs
hsic_ctrl
[
4
];
/* 0x0E20 ~ 0x0E5F: 64 bytes */
};
struct
ext_val_regs
{
uint16_t
val
;
uint16_t
set
;
uint16_t
rst
;
uint16_t
_align
;
};
struct
gpioext_regs
{
struct
ext_val_regs
dir
[
4
];
/* 0x0000 ~ 0x001F: 32 bytes */
struct
ext_val_regs
pullen
[
4
];
/* 0x0020 ~ 0x003F: 32 bytes */
struct
ext_val_regs
pullsel
[
4
];
/* 0x0040 ~ 0x005F: 32 bytes */
struct
ext_val_regs
dinv
[
4
];
/* 0x0060 ~ 0x007F: 32 bytes */
struct
ext_val_regs
dout
[
4
];
/* 0x0080 ~ 0x009F: 32 bytes */
struct
ext_val_regs
din
[
4
];
/* 0x00A0 ~ 0x00BF: 32 bytes */
struct
ext_val_regs
mode
[
10
];
/* 0x00C0 ~ 0x010F: 80 bytes */
};
/* GPIO Driver interface */
void
gpio_set
(
uint32_t
gpio
,
int32_t
value
);
#endif
/* __PLAT_DRIVER_GPIO_H__ */
plat/mediatek/mt8173/drivers/mtcmos/mtcmos.c
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <mmio.h>
#include <mt8173_def.h>
#include <mtcmos.h>
#include <spm.h>
enum
{
SRAM_ISOINT_B
=
1U
<<
6
,
SRAM_CKISO
=
1U
<<
5
,
PWR_CLK_DIS
=
1U
<<
4
,
PWR_ON_2ND
=
1U
<<
3
,
PWR_ON
=
1U
<<
2
,
PWR_ISO
=
1U
<<
1
,
PWR_RST_B
=
1U
<<
0
};
enum
{
L1_PDN_ACK
=
1U
<<
8
,
L1_PDN
=
1U
<<
0
};
enum
{
LITTLE_CPU3
=
1U
<<
12
,
LITTLE_CPU2
=
1U
<<
11
,
LITTLE_CPU1
=
1U
<<
10
,
};
enum
{
SRAM_PDN
=
0xf
<<
8
,
DIS_SRAM_ACK
=
0x1
<<
12
,
AUD_SRAM_ACK
=
0xf
<<
12
,
};
enum
{
DIS_PWR_STA_MASK
=
0x1
<<
3
,
AUD_PWR_STA_MASK
=
0x1
<<
24
,
};
static
void
mtcmos_ctrl_little_off
(
unsigned
int
linear_id
)
{
uint32_t
reg_pwr_con
;
uint32_t
reg_l1_pdn
;
uint32_t
bit_cpu
;
switch
(
linear_id
)
{
case
1
:
reg_pwr_con
=
SPM_CA7_CPU1_PWR_CON
;
reg_l1_pdn
=
SPM_CA7_CPU1_L1_PDN
;
bit_cpu
=
LITTLE_CPU1
;
break
;
case
2
:
reg_pwr_con
=
SPM_CA7_CPU2_PWR_CON
;
reg_l1_pdn
=
SPM_CA7_CPU2_L1_PDN
;
bit_cpu
=
LITTLE_CPU2
;
break
;
case
3
:
reg_pwr_con
=
SPM_CA7_CPU3_PWR_CON
;
reg_l1_pdn
=
SPM_CA7_CPU3_L1_PDN
;
bit_cpu
=
LITTLE_CPU3
;
break
;
default:
/* should never come to here */
return
;
}
/* enable register control */
mmio_write_32
(
SPM_POWERON_CONFIG_SET
,
(
SPM_PROJECT_CODE
<<
16
)
|
(
1U
<<
0
));
mmio_setbits_32
(
reg_pwr_con
,
PWR_ISO
);
mmio_setbits_32
(
reg_pwr_con
,
SRAM_CKISO
);
mmio_clrbits_32
(
reg_pwr_con
,
SRAM_ISOINT_B
);
mmio_setbits_32
(
reg_l1_pdn
,
L1_PDN
);
while
(
!
(
mmio_read_32
(
reg_l1_pdn
)
&
L1_PDN_ACK
))
continue
;
mmio_clrbits_32
(
reg_pwr_con
,
PWR_RST_B
);
mmio_setbits_32
(
reg_pwr_con
,
PWR_CLK_DIS
);
mmio_clrbits_32
(
reg_pwr_con
,
PWR_ON
);
mmio_clrbits_32
(
reg_pwr_con
,
PWR_ON_2ND
);
while
((
mmio_read_32
(
SPM_PWR_STATUS
)
&
bit_cpu
)
||
(
mmio_read_32
(
SPM_PWR_STATUS_2ND
)
&
bit_cpu
))
continue
;
}
void
mtcmos_little_cpu_off
(
void
)
{
/* turn off little cpu 1 - 3 */
mtcmos_ctrl_little_off
(
1
);
mtcmos_ctrl_little_off
(
2
);
mtcmos_ctrl_little_off
(
3
);
}
plat/mediatek/mt8173/drivers/mtcmos/mtcmos.h
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MTCMOS_H__
#define __MTCMOS_H__
/*
* This function will turn off all the little core's power except cpu 0. The
* cores in cluster 0 are all powered when the system power on. The System
* Power Manager (SPM) will do nothing if it found the core's power was on
* during CPU_ON psci call.
*/
void
mtcmos_little_cpu_off
(
void
);
#endif
/* __MTCMOS_H__ */
plat/mediatek/mt8173/drivers/pmic/pmic_wrap_init.c
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <debug.h>
#include <delay_timer.h>
#include <mmio.h>
#include <mt8173_def.h>
#include <pmic_wrap_init.h>
/* pmic wrap module wait_idle and read polling interval (in microseconds) */
enum
{
WAIT_IDLE_POLLING_DELAY_US
=
1
,
READ_POLLING_DELAY_US
=
2
};
static
inline
uint32_t
wait_for_state_idle
(
uint32_t
timeout_us
,
void
*
wacs_register
,
void
*
wacs_vldclr_register
,
uint32_t
*
read_reg
)
{
uint32_t
reg_rdata
;
uint32_t
retry
;
retry
=
(
timeout_us
+
WAIT_IDLE_POLLING_DELAY_US
)
/
WAIT_IDLE_POLLING_DELAY_US
;
do
{
udelay
(
WAIT_IDLE_POLLING_DELAY_US
);
reg_rdata
=
mmio_read_32
((
uintptr_t
)
wacs_register
);
/* if last read command timeout,clear vldclr bit
read command state machine:FSM_REQ-->wfdle-->WFVLDCLR;
write:FSM_REQ-->idle */
switch
(((
reg_rdata
>>
RDATA_WACS_FSM_SHIFT
)
&
RDATA_WACS_FSM_MASK
))
{
case
WACS_FSM_WFVLDCLR
:
mmio_write_32
((
uintptr_t
)
wacs_vldclr_register
,
1
);
ERROR
(
"WACS_FSM = PMIC_WRAP_WACS_VLDCLR
\n
"
);
break
;
case
WACS_FSM_WFDLE
:
ERROR
(
"WACS_FSM = WACS_FSM_WFDLE
\n
"
);
break
;
case
WACS_FSM_REQ
:
ERROR
(
"WACS_FSM = WACS_FSM_REQ
\n
"
);
break
;
case
WACS_FSM_IDLE
:
goto
done
;
default:
break
;
}
retry
--
;
}
while
(
retry
);
done:
if
(
!
retry
)
/* timeout */
return
E_PWR_WAIT_IDLE_TIMEOUT
;
if
(
read_reg
)
*
read_reg
=
reg_rdata
;
return
0
;
}
static
inline
uint32_t
wait_for_state_ready
(
uint32_t
timeout_us
,
void
*
wacs_register
,
uint32_t
*
read_reg
)
{
uint32_t
reg_rdata
;
uint32_t
retry
;
retry
=
(
timeout_us
+
READ_POLLING_DELAY_US
)
/
READ_POLLING_DELAY_US
;
do
{
udelay
(
READ_POLLING_DELAY_US
);
reg_rdata
=
mmio_read_32
((
uintptr_t
)
wacs_register
);
if
(((
reg_rdata
>>
RDATA_WACS_FSM_SHIFT
)
&
RDATA_WACS_FSM_MASK
)
==
WACS_FSM_WFVLDCLR
)
break
;
retry
--
;
}
while
(
retry
);
if
(
!
retry
)
{
/* timeout */
ERROR
(
"timeout when waiting for idle
\n
"
);
return
E_PWR_WAIT_IDLE_TIMEOUT_READ
;
}
if
(
read_reg
)
*
read_reg
=
reg_rdata
;
return
0
;
}
static
int32_t
pwrap_wacs2
(
uint32_t
write
,
uint32_t
adr
,
uint32_t
wdata
,
uint32_t
*
rdata
,
uint32_t
init_check
)
{
uint32_t
reg_rdata
=
0
;
uint32_t
wacs_write
=
0
;
uint32_t
wacs_adr
=
0
;
uint32_t
wacs_cmd
=
0
;
uint32_t
return_value
=
0
;
if
(
init_check
)
{
reg_rdata
=
mmio_read_32
((
uintptr_t
)
&
mt8173_pwrap
->
wacs2_rdata
);
/* Prevent someone to used pwrap before pwrap init */
if
(((
reg_rdata
>>
RDATA_INIT_DONE_SHIFT
)
&
RDATA_INIT_DONE_MASK
)
!=
WACS_INIT_DONE
)
{
ERROR
(
"initialization isn't finished
\n
"
);
return
E_PWR_NOT_INIT_DONE
;
}
}
reg_rdata
=
0
;
/* Check IDLE in advance */
return_value
=
wait_for_state_idle
(
TIMEOUT_WAIT_IDLE
,
&
mt8173_pwrap
->
wacs2_rdata
,
&
mt8173_pwrap
->
wacs2_vldclr
,
0
);
if
(
return_value
!=
0
)
{
ERROR
(
"wait_for_fsm_idle fail,return_value=%d
\n
"
,
return_value
);
goto
FAIL
;
}
wacs_write
=
write
<<
31
;
wacs_adr
=
(
adr
>>
1
)
<<
16
;
wacs_cmd
=
wacs_write
|
wacs_adr
|
wdata
;
mmio_write_32
((
uintptr_t
)
&
mt8173_pwrap
->
wacs2_cmd
,
wacs_cmd
);
if
(
write
==
0
)
{
if
(
NULL
==
rdata
)
{
ERROR
(
"rdata is a NULL pointer
\n
"
);
return_value
=
E_PWR_INVALID_ARG
;
goto
FAIL
;
}
return_value
=
wait_for_state_ready
(
TIMEOUT_READ
,
&
mt8173_pwrap
->
wacs2_rdata
,
&
reg_rdata
);
if
(
return_value
!=
0
)
{
ERROR
(
"wait_for_fsm_vldclr fail,return_value=%d
\n
"
,
return_value
);
goto
FAIL
;
}
*
rdata
=
((
reg_rdata
>>
RDATA_WACS_RDATA_SHIFT
)
&
RDATA_WACS_RDATA_MASK
);
mmio_write_32
((
uintptr_t
)
&
mt8173_pwrap
->
wacs2_vldclr
,
1
);
}
FAIL:
return
return_value
;
}
/* external API for pmic_wrap user */
int32_t
pwrap_read
(
uint32_t
adr
,
uint32_t
*
rdata
)
{
return
pwrap_wacs2
(
0
,
adr
,
0
,
rdata
,
1
);
}
int32_t
pwrap_write
(
uint32_t
adr
,
uint32_t
wdata
)
{
return
pwrap_wacs2
(
1
,
adr
,
wdata
,
0
,
1
);
}
plat/mediatek/mt8173/drivers/pmic/pmic_wrap_init.h
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __PMIC_WRAP_INIT_H__
#define __PMIC_WRAP_INIT_H__
/* external API */
int32_t
pwrap_read
(
uint32_t
adr
,
uint32_t
*
rdata
);
int32_t
pwrap_write
(
uint32_t
adr
,
uint32_t
wdata
);
static
struct
mt8173_pmic_wrap_regs
*
const
mt8173_pwrap
=
(
void
*
)
PMIC_WRAP_BASE
;
/* timeout setting */
enum
{
TIMEOUT_RESET
=
50
,
/* us */
TIMEOUT_READ
=
50
,
/* us */
TIMEOUT_WAIT_IDLE
=
50
/* us */
};
/* PMIC_WRAP registers */
struct
mt8173_pmic_wrap_regs
{
uint32_t
mux_sel
;
uint32_t
wrap_en
;
uint32_t
dio_en
;
uint32_t
sidly
;
uint32_t
rddmy
;
uint32_t
si_ck_con
;
uint32_t
cshext_write
;
uint32_t
cshext_read
;
uint32_t
cslext_start
;
uint32_t
cslext_end
;
uint32_t
staupd_prd
;
uint32_t
staupd_grpen
;
uint32_t
reserved
[
4
];
uint32_t
staupd_man_trig
;
uint32_t
staupd_sta
;
uint32_t
wrap_sta
;
uint32_t
harb_init
;
uint32_t
harb_hprio
;
uint32_t
hiprio_arb_en
;
uint32_t
harb_sta0
;
uint32_t
harb_sta1
;
uint32_t
man_en
;
uint32_t
man_cmd
;
uint32_t
man_rdata
;
uint32_t
man_vldclr
;
uint32_t
wacs0_en
;
uint32_t
init_done0
;
uint32_t
wacs0_cmd
;
uint32_t
wacs0_rdata
;
uint32_t
wacs0_vldclr
;
uint32_t
wacs1_en
;
uint32_t
init_done1
;
uint32_t
wacs1_cmd
;
uint32_t
wacs1_rdata
;
uint32_t
wacs1_vldclr
;
uint32_t
wacs2_en
;
uint32_t
init_done2
;
uint32_t
wacs2_cmd
;
uint32_t
wacs2_rdata
;
uint32_t
wacs2_vldclr
;
uint32_t
int_en
;
uint32_t
int_flg_raw
;
uint32_t
int_flg
;
uint32_t
int_clr
;
uint32_t
sig_adr
;
uint32_t
sig_mode
;
uint32_t
sig_value
;
uint32_t
sig_errval
;
uint32_t
crc_en
;
uint32_t
timer_en
;
uint32_t
timer_sta
;
uint32_t
wdt_unit
;
uint32_t
wdt_src_en
;
uint32_t
wdt_flg
;
uint32_t
debug_int_sel
;
uint32_t
dvfs_adr0
;
uint32_t
dvfs_wdata0
;
uint32_t
dvfs_adr1
;
uint32_t
dvfs_wdata1
;
uint32_t
dvfs_adr2
;
uint32_t
dvfs_wdata2
;
uint32_t
dvfs_adr3
;
uint32_t
dvfs_wdata3
;
uint32_t
dvfs_adr4
;
uint32_t
dvfs_wdata4
;
uint32_t
dvfs_adr5
;
uint32_t
dvfs_wdata5
;
uint32_t
dvfs_adr6
;
uint32_t
dvfs_wdata6
;
uint32_t
dvfs_adr7
;
uint32_t
dvfs_wdata7
;
uint32_t
spminf_sta
;
uint32_t
cipher_key_sel
;
uint32_t
cipher_iv_sel
;
uint32_t
cipher_en
;
uint32_t
cipher_rdy
;
uint32_t
cipher_mode
;
uint32_t
cipher_swrst
;
uint32_t
dcm_en
;
uint32_t
dcm_dbc_prd
;
};
enum
{
RDATA_WACS_RDATA_SHIFT
=
0
,
RDATA_WACS_FSM_SHIFT
=
16
,
RDATA_WACS_REQ_SHIFT
=
19
,
RDATA_SYNC_IDLE_SHIFT
,
RDATA_INIT_DONE_SHIFT
,
RDATA_SYS_IDLE_SHIFT
,
};
enum
{
RDATA_WACS_RDATA_MASK
=
0xffff
,
RDATA_WACS_FSM_MASK
=
0x7
,
RDATA_WACS_REQ_MASK
=
0x1
,
RDATA_SYNC_IDLE_MASK
=
0x1
,
RDATA_INIT_DONE_MASK
=
0x1
,
RDATA_SYS_IDLE_MASK
=
0x1
,
};
/* WACS_FSM */
enum
{
WACS_FSM_IDLE
=
0x00
,
WACS_FSM_REQ
=
0x02
,
WACS_FSM_WFDLE
=
0x04
,
WACS_FSM_WFVLDCLR
=
0x06
,
WACS_INIT_DONE
=
0x01
,
WACS_SYNC_IDLE
=
0x01
,
WACS_SYNC_BUSY
=
0x00
};
/* error information flag */
enum
{
E_PWR_INVALID_ARG
=
1
,
E_PWR_INVALID_RW
=
2
,
E_PWR_INVALID_ADDR
=
3
,
E_PWR_INVALID_WDAT
=
4
,
E_PWR_INVALID_OP_MANUAL
=
5
,
E_PWR_NOT_IDLE_STATE
=
6
,
E_PWR_NOT_INIT_DONE
=
7
,
E_PWR_NOT_INIT_DONE_READ
=
8
,
E_PWR_WAIT_IDLE_TIMEOUT
=
9
,
E_PWR_WAIT_IDLE_TIMEOUT_READ
=
10
,
E_PWR_INIT_SIDLY_FAIL
=
11
,
E_PWR_RESET_TIMEOUT
=
12
,
E_PWR_TIMEOUT
=
13
,
E_PWR_INIT_RESET_SPI
=
20
,
E_PWR_INIT_SIDLY
=
21
,
E_PWR_INIT_REG_CLOCK
=
22
,
E_PWR_INIT_ENABLE_PMIC
=
23
,
E_PWR_INIT_DIO
=
24
,
E_PWR_INIT_CIPHER
=
25
,
E_PWR_INIT_WRITE_TEST
=
26
,
E_PWR_INIT_ENABLE_CRC
=
27
,
E_PWR_INIT_ENABLE_DEWRAP
=
28
,
E_PWR_INIT_ENABLE_EVENT
=
29
,
E_PWR_READ_TEST_FAIL
=
30
,
E_PWR_WRITE_TEST_FAIL
=
31
,
E_PWR_SWITCH_DIO
=
32
};
#endif
/* __PMIC_WRAP_INIT_H__ */
plat/mediatek/mt8173/drivers/rtc/rtc.c
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <debug.h>
#include <delay_timer.h>
#include <mt8173_def.h>
#include <pmic_wrap_init.h>
#include <rtc.h>
/* RTC busy status polling interval and retry count */
enum
{
RTC_WRTGR_POLLING_DELAY_MS
=
10
,
RTC_WRTGR_POLLING_CNT
=
100
};
static
uint16_t
RTC_Read
(
uint32_t
addr
)
{
uint32_t
rdata
=
0
;
pwrap_read
((
uint32_t
)
addr
,
&
rdata
);
return
(
uint16_t
)
rdata
;
}
static
void
RTC_Write
(
uint32_t
addr
,
uint16_t
data
)
{
pwrap_write
((
uint32_t
)
addr
,
(
uint32_t
)
data
);
}
static
inline
int32_t
rtc_busy_wait
(
void
)
{
uint64_t
retry
=
RTC_WRTGR_POLLING_CNT
;
do
{
mdelay
(
RTC_WRTGR_POLLING_DELAY_MS
);
if
(
!
(
RTC_Read
(
RTC_BBPU
)
&
RTC_BBPU_CBUSY
))
return
1
;
retry
--
;
}
while
(
retry
);
ERROR
(
"[RTC] rtc cbusy time out!
\n
"
);
return
0
;
}
static
int32_t
Write_trigger
(
void
)
{
RTC_Write
(
RTC_WRTGR
,
1
);
return
rtc_busy_wait
();
}
static
int32_t
Writeif_unlock
(
void
)
{
RTC_Write
(
RTC_PROT
,
RTC_PROT_UNLOCK1
);
if
(
!
Write_trigger
())
return
0
;
RTC_Write
(
RTC_PROT
,
RTC_PROT_UNLOCK2
);
if
(
!
Write_trigger
())
return
0
;
return
1
;
}
void
rtc_bbpu_power_down
(
void
)
{
uint16_t
bbpu
;
/* pull PWRBB low */
bbpu
=
RTC_BBPU_KEY
|
RTC_BBPU_AUTO
|
RTC_BBPU_PWREN
;
if
(
Writeif_unlock
())
{
RTC_Write
(
RTC_BBPU
,
bbpu
);
if
(
!
Write_trigger
())
assert
(
1
);
}
else
{
assert
(
1
);
}
}
plat/mediatek/mt8173/drivers/rtc/rtc.h
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __PLAT_DRIVER_RTC_H__
#define __PLAT_DRIVER_RTC_H__
/* RTC registers */
enum
{
RTC_BBPU
=
0xE000
,
RTC_IRQ_STA
=
0xE002
,
RTC_IRQ_EN
=
0xE004
,
RTC_CII_EN
=
0xE006
};
enum
{
RTC_OSC32CON
=
0xE026
,
RTC_CON
=
0xE03E
,
RTC_WRTGR
=
0xE03C
};
enum
{
RTC_PDN1
=
0xE02C
,
RTC_PDN2
=
0xE02E
,
RTC_SPAR0
=
0xE030
,
RTC_SPAR1
=
0xE032
,
RTC_PROT
=
0xE036
,
RTC_DIFF
=
0xE038
,
RTC_CALI
=
0xE03A
};
enum
{
RTC_PROT_UNLOCK1
=
0x586A
,
RTC_PROT_UNLOCK2
=
0x9136
};
enum
{
RTC_BBPU_PWREN
=
1U
<<
0
,
RTC_BBPU_BBPU
=
1U
<<
2
,
RTC_BBPU_AUTO
=
1U
<<
3
,
RTC_BBPU_CLRPKY
=
1U
<<
4
,
RTC_BBPU_RELOAD
=
1U
<<
5
,
RTC_BBPU_CBUSY
=
1U
<<
6
};
enum
{
RTC_BBPU_KEY
=
0x43
<<
8
};
void
rtc_bbpu_power_down
(
void
);
#endif
/* __PLAT_DRIVER_RTC_H__ */
plat/mediatek/mt8173/drivers/spm/spm.c
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bakery_lock.h>
#include <debug.h>
#include <mmio.h>
#include <mt8173_def.h>
#include <spm.h>
#include <spm_suspend.h>
/*
* System Power Manager (SPM) is a hardware module, which controls cpu or
* system power for different power scenarios using different firmware, i.e.,
* - spm_hotplug.c for cpu power control in cpu hotplug flow.
* - spm_mcdi.c for cpu power control in cpu idle power saving state.
* - spm_suspend.c for system power control in system suspend scenario.
*
* This file provide utility functions common to hotplug, mcdi(idle), suspend
* power scenarios. A bakery lock (software lock) is incoporated to protect
* certain critical sections to avoid kicking different SPM firmware
* concurrently.
*/
#define SPM_SYSCLK_SETTLE 128
/* 3.9ms */
#if DEBUG
static
int
spm_dormant_sta
=
CPU_DORMANT_RESET
;
#endif
static
bakery_lock_t
spm_lock
__attribute__
((
section
(
"tzfw_coherent_mem"
)));
static
int
spm_hotplug_ready
__attribute__
((
section
(
"tzfw_coherent_mem"
)));
static
int
spm_mcdi_ready
__attribute__
((
section
(
"tzfw_coherent_mem"
)));
static
int
spm_suspend_ready
__attribute__
((
section
(
"tzfw_coherent_mem"
)));
void
spm_lock_init
(
void
)
{
bakery_lock_init
(
&
spm_lock
);
}
void
spm_lock_get
(
void
)
{
bakery_lock_get
(
&
spm_lock
);
}
void
spm_lock_release
(
void
)
{
bakery_lock_release
(
&
spm_lock
);
}
int
is_mcdi_ready
(
void
)
{
return
spm_mcdi_ready
;
}
int
is_hotplug_ready
(
void
)
{
return
spm_hotplug_ready
;
}
int
is_suspend_ready
(
void
)
{
return
spm_suspend_ready
;
}
void
set_mcdi_ready
(
void
)
{
spm_mcdi_ready
=
1
;
spm_hotplug_ready
=
0
;
spm_suspend_ready
=
0
;
}
void
set_hotplug_ready
(
void
)
{
spm_mcdi_ready
=
0
;
spm_hotplug_ready
=
1
;
spm_suspend_ready
=
0
;
}
void
set_suspend_ready
(
void
)
{
spm_mcdi_ready
=
0
;
spm_hotplug_ready
=
0
;
spm_suspend_ready
=
1
;
}
void
clear_all_ready
(
void
)
{
spm_mcdi_ready
=
0
;
spm_hotplug_ready
=
0
;
spm_suspend_ready
=
0
;
}
void
spm_register_init
(
void
)
{
mmio_write_32
(
SPM_POWERON_CONFIG_SET
,
SPM_REGWR_CFG_KEY
|
SPM_REGWR_EN
);
mmio_write_32
(
SPM_POWER_ON_VAL0
,
0
);
mmio_write_32
(
SPM_POWER_ON_VAL1
,
POWER_ON_VAL1_DEF
);
mmio_write_32
(
SPM_PCM_PWR_IO_EN
,
0
);
mmio_write_32
(
SPM_PCM_CON0
,
CON0_CFG_KEY
|
CON0_PCM_SW_RESET
);
mmio_write_32
(
SPM_PCM_CON0
,
CON0_CFG_KEY
);
if
(
mmio_read_32
(
SPM_PCM_FSM_STA
)
!=
PCM_FSM_STA_DEF
)
WARN
(
"PCM reset failed
\n
"
);
mmio_write_32
(
SPM_PCM_CON0
,
CON0_CFG_KEY
|
CON0_IM_SLEEP_DVS
);
mmio_write_32
(
SPM_PCM_CON1
,
CON1_CFG_KEY
|
CON1_EVENT_LOCK_EN
|
CON1_SPM_SRAM_ISO_B
|
CON1_SPM_SRAM_SLP_B
|
CON1_MIF_APBEN
);
mmio_write_32
(
SPM_PCM_IM_PTR
,
0
);
mmio_write_32
(
SPM_PCM_IM_LEN
,
0
);
mmio_write_32
(
SPM_CLK_CON
,
CC_SYSCLK0_EN_1
|
CC_SYSCLK0_EN_0
|
CC_SYSCLK1_EN_0
|
CC_SRCLKENA_MASK_0
|
CC_CLKSQ1_SEL
|
CC_CXO32K_RM_EN_MD2
|
CC_CXO32K_RM_EN_MD1
|
CC_MD32_DCM_EN
);
mmio_write_32
(
SPM_SLEEP_ISR_MASK
,
0xff0c
);
mmio_write_32
(
SPM_SLEEP_ISR_STATUS
,
0xc
);
mmio_write_32
(
SPM_PCM_SW_INT_CLEAR
,
0xff
);
mmio_write_32
(
SPM_MD32_SRAM_CON
,
0xff0
);
}
void
spm_reset_and_init_pcm
(
void
)
{
unsigned
int
con1
;
int
i
=
0
;
mmio_write_32
(
SPM_PCM_CON0
,
CON0_CFG_KEY
|
CON0_PCM_SW_RESET
);
mmio_write_32
(
SPM_PCM_CON0
,
CON0_CFG_KEY
);
while
(
mmio_read_32
(
SPM_PCM_FSM_STA
)
!=
PCM_FSM_STA_DEF
)
{
i
++
;
if
(
i
>
1000
)
{
i
=
0
;
WARN
(
"PCM reset failed
\n
"
);
break
;
}
}
mmio_write_32
(
SPM_PCM_CON0
,
CON0_CFG_KEY
|
CON0_IM_SLEEP_DVS
);
con1
=
mmio_read_32
(
SPM_PCM_CON1
)
&
(
CON1_PCM_WDT_WAKE_MODE
|
CON1_PCM_WDT_EN
);
mmio_write_32
(
SPM_PCM_CON1
,
con1
|
CON1_CFG_KEY
|
CON1_EVENT_LOCK_EN
|
CON1_SPM_SRAM_ISO_B
|
CON1_SPM_SRAM_SLP_B
|
CON1_IM_NONRP_EN
|
CON1_MIF_APBEN
);
}
void
spm_init_pcm_register
(
void
)
{
mmio_write_32
(
SPM_PCM_REG_DATA_INI
,
mmio_read_32
(
SPM_POWER_ON_VAL0
));
mmio_write_32
(
SPM_PCM_PWR_IO_EN
,
PCM_RF_SYNC_R0
);
mmio_write_32
(
SPM_PCM_PWR_IO_EN
,
0
);
mmio_write_32
(
SPM_PCM_REG_DATA_INI
,
mmio_read_32
(
SPM_POWER_ON_VAL1
));
mmio_write_32
(
SPM_PCM_PWR_IO_EN
,
PCM_RF_SYNC_R7
);
mmio_write_32
(
SPM_PCM_PWR_IO_EN
,
0
);
}
void
spm_set_power_control
(
const
struct
pwr_ctrl
*
pwrctrl
)
{
mmio_write_32
(
SPM_AP_STANBY_CON
,
(
!
pwrctrl
->
md32_req_mask
<<
21
)
|
(
!
pwrctrl
->
mfg_req_mask
<<
17
)
|
(
!
pwrctrl
->
disp_req_mask
<<
16
)
|
(
!!
pwrctrl
->
mcusys_idle_mask
<<
7
)
|
(
!!
pwrctrl
->
ca15top_idle_mask
<<
6
)
|
(
!!
pwrctrl
->
ca7top_idle_mask
<<
5
)
|
(
!!
pwrctrl
->
wfi_op
<<
4
));
mmio_write_32
(
SPM_PCM_SRC_REQ
,
(
!!
pwrctrl
->
pcm_apsrc_req
<<
0
));
mmio_write_32
(
SPM_PCM_PASR_DPD_2
,
0
);
mmio_clrsetbits_32
(
SPM_CLK_CON
,
CC_SRCLKENA_MASK_0
,
(
pwrctrl
->
srclkenai_mask
?
CC_SRCLKENA_MASK_0
:
0
));
mmio_write_32
(
SPM_SLEEP_CA15_WFI0_EN
,
!!
pwrctrl
->
ca15_wfi0_en
);
mmio_write_32
(
SPM_SLEEP_CA15_WFI1_EN
,
!!
pwrctrl
->
ca15_wfi1_en
);
mmio_write_32
(
SPM_SLEEP_CA15_WFI2_EN
,
!!
pwrctrl
->
ca15_wfi2_en
);
mmio_write_32
(
SPM_SLEEP_CA15_WFI3_EN
,
!!
pwrctrl
->
ca15_wfi3_en
);
mmio_write_32
(
SPM_SLEEP_CA7_WFI0_EN
,
!!
pwrctrl
->
ca7_wfi0_en
);
mmio_write_32
(
SPM_SLEEP_CA7_WFI1_EN
,
!!
pwrctrl
->
ca7_wfi1_en
);
mmio_write_32
(
SPM_SLEEP_CA7_WFI2_EN
,
!!
pwrctrl
->
ca7_wfi2_en
);
mmio_write_32
(
SPM_SLEEP_CA7_WFI3_EN
,
!!
pwrctrl
->
ca7_wfi3_en
);
}
void
spm_set_wakeup_event
(
const
struct
pwr_ctrl
*
pwrctrl
)
{
unsigned
int
val
,
mask
;
if
(
pwrctrl
->
timer_val_cust
==
0
)
val
=
pwrctrl
->
timer_val
?
pwrctrl
->
timer_val
:
PCM_TIMER_MAX
;
else
val
=
pwrctrl
->
timer_val_cust
;
mmio_write_32
(
SPM_PCM_TIMER_VAL
,
val
);
mmio_setbits_32
(
SPM_PCM_CON1
,
CON1_CFG_KEY
);
if
(
pwrctrl
->
wake_src_cust
==
0
)
mask
=
pwrctrl
->
wake_src
;
else
mask
=
pwrctrl
->
wake_src_cust
;
if
(
pwrctrl
->
syspwreq_mask
)
mask
&=
~
WAKE_SRC_SYSPWREQ
;
mmio_write_32
(
SPM_SLEEP_WAKEUP_EVENT_MASK
,
~
mask
);
mmio_write_32
(
SPM_SLEEP_ISR_MASK
,
0xfe04
);
}
void
spm_get_wakeup_status
(
struct
wake_status
*
wakesta
)
{
wakesta
->
assert_pc
=
mmio_read_32
(
SPM_PCM_REG_DATA_INI
);
wakesta
->
r12
=
mmio_read_32
(
SPM_PCM_REG12_DATA
);
wakesta
->
raw_sta
=
mmio_read_32
(
SPM_SLEEP_ISR_RAW_STA
);
wakesta
->
wake_misc
=
mmio_read_32
(
SPM_SLEEP_WAKEUP_MISC
);
wakesta
->
timer_out
=
mmio_read_32
(
SPM_PCM_TIMER_OUT
);
wakesta
->
r13
=
mmio_read_32
(
SPM_PCM_REG13_DATA
);
wakesta
->
idle_sta
=
mmio_read_32
(
SPM_SLEEP_SUBSYS_IDLE_STA
);
wakesta
->
debug_flag
=
mmio_read_32
(
SPM_PCM_PASR_DPD_3
);
wakesta
->
event_reg
=
mmio_read_32
(
SPM_PCM_EVENT_REG_STA
);
wakesta
->
isr
=
mmio_read_32
(
SPM_SLEEP_ISR_STATUS
);
}
void
spm_init_event_vector
(
const
struct
pcm_desc
*
pcmdesc
)
{
/* init event vector register */
mmio_write_32
(
SPM_PCM_EVENT_VECTOR0
,
pcmdesc
->
vec0
);
mmio_write_32
(
SPM_PCM_EVENT_VECTOR1
,
pcmdesc
->
vec1
);
mmio_write_32
(
SPM_PCM_EVENT_VECTOR2
,
pcmdesc
->
vec2
);
mmio_write_32
(
SPM_PCM_EVENT_VECTOR3
,
pcmdesc
->
vec3
);
mmio_write_32
(
SPM_PCM_EVENT_VECTOR4
,
pcmdesc
->
vec4
);
mmio_write_32
(
SPM_PCM_EVENT_VECTOR5
,
pcmdesc
->
vec5
);
mmio_write_32
(
SPM_PCM_EVENT_VECTOR6
,
pcmdesc
->
vec6
);
mmio_write_32
(
SPM_PCM_EVENT_VECTOR7
,
pcmdesc
->
vec7
);
/* event vector will be enabled by PCM itself */
}
void
spm_kick_im_to_fetch
(
const
struct
pcm_desc
*
pcmdesc
)
{
unsigned
int
ptr
=
0
,
len
,
con0
;
ptr
=
(
unsigned
int
)(
unsigned
long
)(
pcmdesc
->
base
);
len
=
pcmdesc
->
size
-
1
;
if
(
mmio_read_32
(
SPM_PCM_IM_PTR
)
!=
ptr
||
mmio_read_32
(
SPM_PCM_IM_LEN
)
!=
len
||
pcmdesc
->
sess
>
2
)
{
mmio_write_32
(
SPM_PCM_IM_PTR
,
ptr
);
mmio_write_32
(
SPM_PCM_IM_LEN
,
len
);
}
else
{
mmio_setbits_32
(
SPM_PCM_CON1
,
CON1_CFG_KEY
|
CON1_IM_SLAVE
);
}
/* kick IM to fetch (only toggle IM_KICK) */
con0
=
mmio_read_32
(
SPM_PCM_CON0
)
&
~
(
CON0_IM_KICK
|
CON0_PCM_KICK
);
mmio_write_32
(
SPM_PCM_CON0
,
con0
|
CON0_CFG_KEY
|
CON0_IM_KICK
);
mmio_write_32
(
SPM_PCM_CON0
,
con0
|
CON0_CFG_KEY
);
/* kick IM to fetch (only toggle PCM_KICK) */
con0
=
mmio_read_32
(
SPM_PCM_CON0
)
&
~
(
CON0_IM_KICK
|
CON0_PCM_KICK
);
mmio_write_32
(
SPM_PCM_CON0
,
con0
|
CON0_CFG_KEY
|
CON0_PCM_KICK
);
mmio_write_32
(
SPM_PCM_CON0
,
con0
|
CON0_CFG_KEY
);
}
void
spm_set_sysclk_settle
(
void
)
{
mmio_write_32
(
SPM_CLK_SETTLE
,
SPM_SYSCLK_SETTLE
);
INFO
(
"settle = %u
\n
"
,
mmio_read_32
(
SPM_CLK_SETTLE
));
}
void
spm_kick_pcm_to_run
(
struct
pwr_ctrl
*
pwrctrl
)
{
unsigned
int
con1
;
con1
=
mmio_read_32
(
SPM_PCM_CON1
)
&
~
(
CON1_PCM_WDT_WAKE_MODE
|
CON1_PCM_WDT_EN
);
mmio_write_32
(
SPM_PCM_CON1
,
CON1_CFG_KEY
|
con1
);
if
(
mmio_read_32
(
SPM_PCM_TIMER_VAL
)
>
PCM_TIMER_MAX
)
mmio_write_32
(
SPM_PCM_TIMER_VAL
,
PCM_TIMER_MAX
);
mmio_write_32
(
SPM_PCM_WDT_TIMER_VAL
,
mmio_read_32
(
SPM_PCM_TIMER_VAL
)
+
PCM_WDT_TIMEOUT
);
mmio_write_32
(
SPM_PCM_CON1
,
con1
|
CON1_CFG_KEY
|
CON1_PCM_WDT_EN
);
mmio_write_32
(
SPM_PCM_PASR_DPD_0
,
0
);
mmio_write_32
(
SPM_PCM_MAS_PAUSE_MASK
,
0xffffffff
);
mmio_write_32
(
SPM_PCM_REG_DATA_INI
,
0
);
mmio_clrbits_32
(
SPM_CLK_CON
,
CC_DISABLE_DORM_PWR
);
mmio_write_32
(
SPM_PCM_FLAGS
,
pwrctrl
->
pcm_flags
);
mmio_clrsetbits_32
(
SPM_CLK_CON
,
CC_LOCK_INFRA_DCM
,
(
pwrctrl
->
infra_dcm_lock
?
CC_LOCK_INFRA_DCM
:
0
));
mmio_write_32
(
SPM_PCM_PWR_IO_EN
,
(
pwrctrl
->
r0_ctrl_en
?
PCM_PWRIO_EN_R0
:
0
)
|
(
pwrctrl
->
r7_ctrl_en
?
PCM_PWRIO_EN_R7
:
0
));
}
void
spm_clean_after_wakeup
(
void
)
{
mmio_clrsetbits_32
(
SPM_PCM_CON1
,
CON1_PCM_WDT_EN
,
CON1_CFG_KEY
);
mmio_write_32
(
SPM_PCM_PWR_IO_EN
,
0
);
mmio_write_32
(
SPM_SLEEP_CPU_WAKEUP_EVENT
,
0
);
mmio_clrsetbits_32
(
SPM_PCM_CON1
,
CON1_PCM_TIMER_EN
,
CON1_CFG_KEY
);
mmio_write_32
(
SPM_SLEEP_WAKEUP_EVENT_MASK
,
~
0
);
mmio_write_32
(
SPM_SLEEP_ISR_MASK
,
0xFF0C
);
mmio_write_32
(
SPM_SLEEP_ISR_STATUS
,
0xC
);
mmio_write_32
(
SPM_PCM_SW_INT_CLEAR
,
0xFF
);
}
enum
wake_reason_t
spm_output_wake_reason
(
struct
wake_status
*
wakesta
)
{
enum
wake_reason_t
wr
;
int
i
;
wr
=
WR_UNKNOWN
;
if
(
wakesta
->
assert_pc
!=
0
)
{
ERROR
(
"PCM ASSERT AT %u, r12=0x%x, r13=0x%x, debug_flag=0x%x
\n
"
,
wakesta
->
assert_pc
,
wakesta
->
r12
,
wakesta
->
r13
,
wakesta
->
debug_flag
);
return
WR_PCM_ASSERT
;
}
if
(
wakesta
->
r12
&
WAKE_SRC_SPM_MERGE
)
{
if
(
wakesta
->
wake_misc
&
WAKE_MISC_PCM_TIMER
)
wr
=
WR_PCM_TIMER
;
if
(
wakesta
->
wake_misc
&
WAKE_MISC_CPU_WAKE
)
wr
=
WR_WAKE_SRC
;
}
for
(
i
=
1
;
i
<
32
;
i
++
)
{
if
(
wakesta
->
r12
&
(
1U
<<
i
))
wr
=
WR_WAKE_SRC
;
}
if
((
wakesta
->
event_reg
&
0x100000
)
==
0
)
{
INFO
(
"pcm sleep abort!
\n
"
);
wr
=
WR_PCM_ABORT
;
}
INFO
(
"timer_out = %u, r12 = 0x%x, r13 = 0x%x, debug_flag = 0x%x
\n
"
,
wakesta
->
timer_out
,
wakesta
->
r12
,
wakesta
->
r13
,
wakesta
->
debug_flag
);
INFO
(
"raw_sta = 0x%x, idle_sta = 0x%x, event_reg = 0x%x, isr = 0x%x
\n
"
,
wakesta
->
raw_sta
,
wakesta
->
idle_sta
,
wakesta
->
event_reg
,
wakesta
->
isr
);
INFO
(
"dormant state = %d
\n
"
,
spm_dormant_sta
);
return
wr
;
}
void
spm_boot_init
(
void
)
{
/* Only CPU0 is online during boot, initialize cpu online reserve bit */
mmio_write_32
(
SPM_PCM_RESERVE
,
0xFE
);
spm_lock_init
();
spm_register_init
();
}
plat/mediatek/mt8173/drivers/spm/spm.h
0 → 100644
View file @
aaa0567c
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SPM_H__
#define __SPM_H__
#define SPM_POWERON_CONFIG_SET (SPM_BASE + 0x000)
#define SPM_POWER_ON_VAL0 (SPM_BASE + 0x010)
#define SPM_POWER_ON_VAL1 (SPM_BASE + 0x014)
#define SPM_CLK_SETTLE (SPM_BASE + 0x100)
#define SPM_CA7_CPU1_PWR_CON (SPM_BASE + 0x218)
#define SPM_CA7_CPU2_PWR_CON (SPM_BASE + 0x21c)
#define SPM_CA7_CPU3_PWR_CON (SPM_BASE + 0x220)
#define SPM_CA7_CPU1_L1_PDN (SPM_BASE + 0x264)
#define SPM_CA7_CPU2_L1_PDN (SPM_BASE + 0x26c)
#define SPM_CA7_CPU3_L1_PDN (SPM_BASE + 0x274)
#define SPM_MD32_SRAM_CON (SPM_BASE + 0x2c8)
#define SPM_PCM_CON0 (SPM_BASE + 0x310)
#define SPM_PCM_CON1 (SPM_BASE + 0x314)
#define SPM_PCM_IM_PTR (SPM_BASE + 0x318)
#define SPM_PCM_IM_LEN (SPM_BASE + 0x31c)
#define SPM_PCM_REG_DATA_INI (SPM_BASE + 0x320)
#define SPM_PCM_EVENT_VECTOR0 (SPM_BASE + 0x340)
#define SPM_PCM_EVENT_VECTOR1 (SPM_BASE + 0x344)
#define SPM_PCM_EVENT_VECTOR2 (SPM_BASE + 0x348)
#define SPM_PCM_EVENT_VECTOR3 (SPM_BASE + 0x34c)
#define SPM_PCM_MAS_PAUSE_MASK (SPM_BASE + 0x354)
#define SPM_PCM_PWR_IO_EN (SPM_BASE + 0x358)
#define SPM_PCM_TIMER_VAL (SPM_BASE + 0x35c)
#define SPM_PCM_TIMER_OUT (SPM_BASE + 0x360)
#define SPM_PCM_REG0_DATA (SPM_BASE + 0x380)
#define SPM_PCM_REG1_DATA (SPM_BASE + 0x384)
#define SPM_PCM_REG2_DATA (SPM_BASE + 0x388)
#define SPM_PCM_REG3_DATA (SPM_BASE + 0x38c)
#define SPM_PCM_REG4_DATA (SPM_BASE + 0x390)
#define SPM_PCM_REG5_DATA (SPM_BASE + 0x394)
#define SPM_PCM_REG6_DATA (SPM_BASE + 0x398)
#define SPM_PCM_REG7_DATA (SPM_BASE + 0x39c)
#define SPM_PCM_REG8_DATA (SPM_BASE + 0x3a0)
#define SPM_PCM_REG9_DATA (SPM_BASE + 0x3a4)
#define SPM_PCM_REG10_DATA (SPM_BASE + 0x3a8)
#define SPM_PCM_REG11_DATA (SPM_BASE + 0x3ac)
#define SPM_PCM_REG12_DATA (SPM_BASE + 0x3b0)
#define SPM_PCM_REG13_DATA (SPM_BASE + 0x3b4)
#define SPM_PCM_REG14_DATA (SPM_BASE + 0x3b8)
#define SPM_PCM_REG15_DATA (SPM_BASE + 0x3bc)
#define SPM_PCM_EVENT_REG_STA (SPM_BASE + 0x3c0)
#define SPM_PCM_FSM_STA (SPM_BASE + 0x3c4)
#define SPM_PCM_IM_HOST_RW_PTR (SPM_BASE + 0x3c8)
#define SPM_PCM_IM_HOST_RW_DAT (SPM_BASE + 0x3cc)
#define SPM_PCM_EVENT_VECTOR4 (SPM_BASE + 0x3d0)
#define SPM_PCM_EVENT_VECTOR5 (SPM_BASE + 0x3d4)
#define SPM_PCM_EVENT_VECTOR6 (SPM_BASE + 0x3d8)
#define SPM_PCM_EVENT_VECTOR7 (SPM_BASE + 0x3dc)
#define SPM_PCM_SW_INT_SET (SPM_BASE + 0x3e0)
#define SPM_PCM_SW_INT_CLEAR (SPM_BASE + 0x3e4)
#define SPM_CLK_CON (SPM_BASE + 0x400)
#define SPM_SLEEP_PTPOD2_CON (SPM_BASE + 0x408)
#define SPM_APMCU_PWRCTL (SPM_BASE + 0x600)
#define SPM_AP_DVFS_CON_SET (SPM_BASE + 0x604)
#define SPM_AP_STANBY_CON (SPM_BASE + 0x608)
#define SPM_PWR_STATUS (SPM_BASE + 0x60c)
#define SPM_PWR_STATUS_2ND (SPM_BASE + 0x610)
#define SPM_AP_BSI_REQ (SPM_BASE + 0x614)
#define SPM_SLEEP_TIMER_STA (SPM_BASE + 0x720)
#define SPM_SLEEP_WAKEUP_EVENT_MASK (SPM_BASE + 0x810)
#define SPM_SLEEP_CPU_WAKEUP_EVENT (SPM_BASE + 0x814)
#define SPM_SLEEP_MD32_WAKEUP_EVENT_MASK (SPM_BASE + 0x818)
#define SPM_PCM_WDT_TIMER_VAL (SPM_BASE + 0x824)
#define SPM_PCM_WDT_TIMER_OUT (SPM_BASE + 0x828)
#define SPM_PCM_MD32_MAILBOX (SPM_BASE + 0x830)
#define SPM_PCM_MD32_IRQ (SPM_BASE + 0x834)
#define SPM_SLEEP_ISR_MASK (SPM_BASE + 0x900)
#define SPM_SLEEP_ISR_STATUS (SPM_BASE + 0x904)
#define SPM_SLEEP_ISR_RAW_STA (SPM_BASE + 0x910)
#define SPM_SLEEP_MD32_ISR_RAW_STA (SPM_BASE + 0x914)
#define SPM_SLEEP_WAKEUP_MISC (SPM_BASE + 0x918)
#define SPM_SLEEP_BUS_PROTECT_RDY (SPM_BASE + 0x91c)
#define SPM_SLEEP_SUBSYS_IDLE_STA (SPM_BASE + 0x920)
#define SPM_PCM_RESERVE (SPM_BASE + 0xb00)
#define SPM_PCM_RESERVE2 (SPM_BASE + 0xb04)
#define SPM_PCM_FLAGS (SPM_BASE + 0xb08)
#define SPM_PCM_SRC_REQ (SPM_BASE + 0xb0c)
#define SPM_PCM_DEBUG_CON (SPM_BASE + 0xb20)
#define SPM_CA7_CPU0_IRQ_MASK (SPM_BASE + 0xb30)
#define SPM_CA7_CPU1_IRQ_MASK (SPM_BASE + 0xb34)
#define SPM_CA7_CPU2_IRQ_MASK (SPM_BASE + 0xb38)
#define SPM_CA7_CPU3_IRQ_MASK (SPM_BASE + 0xb3c)
#define SPM_CA15_CPU0_IRQ_MASK (SPM_BASE + 0xb40)
#define SPM_CA15_CPU1_IRQ_MASK (SPM_BASE + 0xb44)
#define SPM_CA15_CPU2_IRQ_MASK (SPM_BASE + 0xb48)
#define SPM_CA15_CPU3_IRQ_MASK (SPM_BASE + 0xb4c)
#define SPM_PCM_PASR_DPD_0 (SPM_BASE + 0xb60)
#define SPM_PCM_PASR_DPD_1 (SPM_BASE + 0xb64)
#define SPM_PCM_PASR_DPD_2 (SPM_BASE + 0xb68)
#define SPM_PCM_PASR_DPD_3 (SPM_BASE + 0xb6c)
#define SPM_SLEEP_CA7_WFI0_EN (SPM_BASE + 0xf00)
#define SPM_SLEEP_CA7_WFI1_EN (SPM_BASE + 0xf04)
#define SPM_SLEEP_CA7_WFI2_EN (SPM_BASE + 0xf08)
#define SPM_SLEEP_CA7_WFI3_EN (SPM_BASE + 0xf0c)
#define SPM_SLEEP_CA15_WFI0_EN (SPM_BASE + 0xf10)
#define SPM_SLEEP_CA15_WFI1_EN (SPM_BASE + 0xf14)
#define SPM_SLEEP_CA15_WFI2_EN (SPM_BASE + 0xf18)
#define SPM_SLEEP_CA15_WFI3_EN (SPM_BASE + 0xf1c)
#define SPM_PROJECT_CODE 0xb16
#define SPM_REGWR_EN (1U << 0)
#define SPM_REGWR_CFG_KEY (SPM_PROJECT_CODE << 16)
#define SPM_CPU_PDN_DIS (1U << 0)
#define SPM_INFRA_PDN_DIS (1U << 1)
#define SPM_DDRPHY_PDN_DIS (1U << 2)
#define SPM_DUALVCORE_PDN_DIS (1U << 3)
#define SPM_PASR_DIS (1U << 4)
#define SPM_DPD_DIS (1U << 5)
#define SPM_SODI_DIS (1U << 6)
#define SPM_MEMPLL_RESET (1U << 7)
#define SPM_MAINPLL_PDN_DIS (1U << 8)
#define SPM_CPU_DVS_DIS (1U << 9)
#define SPM_CPU_DORMANT (1U << 10)
#define SPM_EXT_VSEL_GPIO103 (1U << 11)
#define SPM_DDR_HIGH_SPEED (1U << 12)
#define SPM_OPT (1U << 13)
#define POWER_ON_VAL1_DEF 0x01011820
#define PCM_FSM_STA_DEF 0x48490
#define PCM_END_FSM_STA_DEF 0x08490
#define PCM_END_FSM_STA_MASK 0x3fff0
#define PCM_HANDSHAKE_SEND1 0xbeefbeef
#define PCM_WDT_TIMEOUT (30 * 32768)
#define PCM_TIMER_MAX (0xffffffff - PCM_WDT_TIMEOUT)
#define CON0_PCM_KICK (1U << 0)
#define CON0_IM_KICK (1U << 1)
#define CON0_IM_SLEEP_DVS (1U << 3)
#define CON0_PCM_SW_RESET (1U << 15)
#define CON0_CFG_KEY (SPM_PROJECT_CODE << 16)
#define CON1_IM_SLAVE (1U << 0)
#define CON1_MIF_APBEN (1U << 3)
#define CON1_PCM_TIMER_EN (1U << 5)
#define CON1_IM_NONRP_EN (1U << 6)
#define CON1_PCM_WDT_EN (1U << 8)
#define CON1_PCM_WDT_WAKE_MODE (1U << 9)
#define CON1_SPM_SRAM_SLP_B (1U << 10)
#define CON1_SPM_SRAM_ISO_B (1U << 11)
#define CON1_EVENT_LOCK_EN (1U << 12)
#define CON1_CFG_KEY (SPM_PROJECT_CODE << 16)
#define PCM_PWRIO_EN_R0 (1U << 0)
#define PCM_PWRIO_EN_R7 (1U << 7)
#define PCM_RF_SYNC_R0 (1U << 16)
#define PCM_RF_SYNC_R2 (1U << 18)
#define PCM_RF_SYNC_R6 (1U << 22)
#define PCM_RF_SYNC_R7 (1U << 23)
#define CC_SYSCLK0_EN_0 (1U << 0)
#define CC_SYSCLK0_EN_1 (1U << 1)
#define CC_SYSCLK1_EN_0 (1U << 2)
#define CC_SYSCLK1_EN_1 (1U << 3)
#define CC_SYSSETTLE_SEL (1U << 4)
#define CC_LOCK_INFRA_DCM (1U << 5)
#define CC_SRCLKENA_MASK_0 (1U << 6)
#define CC_CXO32K_RM_EN_MD1 (1U << 9)
#define CC_CXO32K_RM_EN_MD2 (1U << 10)
#define CC_CLKSQ1_SEL (1U << 12)
#define CC_DISABLE_DORM_PWR (1U << 14)
#define CC_MD32_DCM_EN (1U << 18)
#define WFI_OP_AND 1
#define WFI_OP_OR 0
#define WAKE_MISC_PCM_TIMER (1U << 19)
#define WAKE_MISC_CPU_WAKE (1U << 20)
/* define WAKE_SRC_XXX */
#define WAKE_SRC_SPM_MERGE (1 << 0)
#define WAKE_SRC_KP (1 << 2)
#define WAKE_SRC_WDT (1 << 3)
#define WAKE_SRC_GPT (1 << 4)
#define WAKE_SRC_EINT (1 << 6)
#define WAKE_SRC_LOW_BAT (1 << 9)
#define WAKE_SRC_MD32 (1 << 10)
#define WAKE_SRC_USB_CD (1 << 14)
#define WAKE_SRC_USB_PDN (1 << 15)
#define WAKE_SRC_AFE (1 << 20)
#define WAKE_SRC_THERM (1 << 21)
#define WAKE_SRC_SYSPWREQ (1 << 24)
#define WAKE_SRC_SEJ (1 << 27)
#define WAKE_SRC_ALL_MD32 (1 << 28)
#define WAKE_SRC_CPU_IRQ (1 << 29)
enum
wake_reason_t
{
WR_NONE
=
0
,
WR_UART_BUSY
=
1
,
WR_PCM_ASSERT
=
2
,
WR_PCM_TIMER
=
3
,
WR_PCM_ABORT
=
4
,
WR_WAKE_SRC
=
5
,
WR_UNKNOWN
=
6
,
};
struct
pwr_ctrl
{
unsigned
int
pcm_flags
;
unsigned
int
pcm_flags_cust
;
unsigned
int
pcm_reserve
;
unsigned
int
timer_val
;
unsigned
int
timer_val_cust
;
unsigned
int
wake_src
;
unsigned
int
wake_src_cust
;
unsigned
int
wake_src_md32
;
unsigned
short
r0_ctrl_en
;
unsigned
short
r7_ctrl_en
;
unsigned
short
infra_dcm_lock
;
unsigned
short
pcm_apsrc_req
;
unsigned
short
mcusys_idle_mask
;
unsigned
short
ca15top_idle_mask
;
unsigned
short
ca7top_idle_mask
;
unsigned
short
wfi_op
;
unsigned
short
ca15_wfi0_en
;
unsigned
short
ca15_wfi1_en
;
unsigned
short
ca15_wfi2_en
;
unsigned
short
ca15_wfi3_en
;
unsigned
short
ca7_wfi0_en
;
unsigned
short
ca7_wfi1_en
;
unsigned
short
ca7_wfi2_en
;
unsigned
short
ca7_wfi3_en
;
unsigned
short
disp_req_mask
;
unsigned
short
mfg_req_mask
;
unsigned
short
md32_req_mask
;
unsigned
short
syspwreq_mask
;
unsigned
short
srclkenai_mask
;
};
struct
wake_status
{
unsigned
int
assert_pc
;
unsigned
int
r12
;
unsigned
int
raw_sta
;
unsigned
int
wake_misc
;
unsigned
int
timer_out
;
unsigned
int
r13
;
unsigned
int
idle_sta
;
unsigned
int
debug_flag
;
unsigned
int
event_reg
;
unsigned
int
isr
;
};
struct
pcm_desc
{
const
char
*
version
;
/* PCM code version */
const
unsigned
int
*
base
;
/* binary array base */
const
unsigned
int
size
;
/* binary array size */
const
unsigned
char
sess
;
/* session number */
const
unsigned
char
replace
;
/* replace mode */
unsigned
int
vec0
;
/* event vector 0 config */
unsigned
int
vec1
;
/* event vector 1 config */
unsigned
int
vec2
;
/* event vector 2 config */
unsigned
int
vec3
;
/* event vector 3 config */
unsigned
int
vec4
;
/* event vector 4 config */
unsigned
int
vec5
;
/* event vector 5 config */
unsigned
int
vec6
;
/* event vector 6 config */
unsigned
int
vec7
;
/* event vector 7 config */
};
struct
spm_lp_scen
{
const
struct
pcm_desc
*
pcmdesc
;
struct
pwr_ctrl
*
pwrctrl
;
};
#define EVENT_VEC(event, resume, imme, pc) \
(((pc) << 16) | \
(!!(imme) << 6) | \
(!!(resume) << 5) | \
((event) & 0x1f))
#define spm_read(addr) mmio_read_32(addr)
#define spm_write(addr, val) mmio_write_32(addr, val)
#define is_cpu_pdn(flags) (!((flags) & SPM_CPU_PDN_DIS))
#define is_infra_pdn(flags) (!((flags) & SPM_INFRA_PDN_DIS))
#define is_ddrphy_pdn(flags) (!((flags) & SPM_DDRPHY_PDN_DIS))
static
inline
void
set_pwrctrl_pcm_flags
(
struct
pwr_ctrl
*
pwrctrl
,
unsigned
int
flags
)
{
flags
&=
~
SPM_EXT_VSEL_GPIO103
;
if
(
pwrctrl
->
pcm_flags_cust
==
0
)
pwrctrl
->
pcm_flags
=
flags
;
else
pwrctrl
->
pcm_flags
=
pwrctrl
->
pcm_flags_cust
;
}
static
inline
void
set_pwrctrl_pcm_data
(
struct
pwr_ctrl
*
pwrctrl
,
unsigned
int
data
)
{
pwrctrl
->
pcm_reserve
=
data
;
}
void
spm_reset_and_init_pcm
(
void
);
void
spm_init_pcm_register
(
void
);
/* init r0 and r7 */
void
spm_set_power_control
(
const
struct
pwr_ctrl
*
pwrctrl
);
void
spm_set_wakeup_event
(
const
struct
pwr_ctrl
*
pwrctrl
);
void
spm_get_wakeup_status
(
struct
wake_status
*
wakesta
);
void
spm_set_sysclk_settle
(
void
);
void
spm_kick_pcm_to_run
(
struct
pwr_ctrl
*
pwrctrl
);
void
spm_clean_after_wakeup
(
void
);
enum
wake_reason_t
spm_output_wake_reason
(
struct
wake_status
*
wakesta
);
void
spm_register_init
(
void
);
void
spm_go_to_hotplug
(
void
);
void
spm_init_event_vector
(
const
struct
pcm_desc
*
pcmdesc
);
void
spm_kick_im_to_fetch
(
const
struct
pcm_desc
*
pcmdesc
);
void
spm_set_sysclk_settle
(
void
);
int
is_mcdi_ready
(
void
);
int
is_hotplug_ready
(
void
);
int
is_suspend_ready
(
void
);
void
set_mcdi_ready
(
void
);
void
set_hotplug_ready
(
void
);
void
set_suspend_ready
(
void
);
void
clear_all_ready
(
void
);
void
spm_lock_init
(
void
);
void
spm_lock_get
(
void
);
void
spm_lock_release
(
void
);
void
spm_boot_init
(
void
);
#endif
/* __SPM_H__ */
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment