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
fbf35335
Unverified
Commit
fbf35335
authored
Jan 21, 2019
by
Antonio Niño Díaz
Committed by
GitHub
Jan 21, 2019
Browse files
Merge pull request #1767 from Yann-lms/updates_stm32mp1
Updates for STM32MP1
parents
f0bfe15b
7747356d
Changes
45
Show whitespace changes
Inline
Side-by-side
drivers/st/bsec/bsec.c
0 → 100644
View file @
fbf35335
/*
* Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <limits.h>
#include <libfdt.h>
#include <platform_def.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/st/bsec.h>
#include <lib/mmio.h>
#include <lib/spinlock.h>
#define BSEC_IP_VERSION_1_0 0x10
#define BSEC_COMPAT "st,stm32mp15-bsec"
#define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
static
uint32_t
otp_nsec_access
[
OTP_ACCESS_SIZE
]
__unused
;
static
uint32_t
bsec_power_safmem
(
bool
power
);
/* BSEC access protection */
static
spinlock_t
bsec_spinlock
;
static
uintptr_t
bsec_base
;
static
void
bsec_lock
(
void
)
{
const
uint32_t
mask
=
SCTLR_M_BIT
|
SCTLR_C_BIT
;
/* Lock is currently required only when MMU and cache are enabled */
if
((
read_sctlr
()
&
mask
)
==
mask
)
{
spin_lock
(
&
bsec_spinlock
);
}
}
static
void
bsec_unlock
(
void
)
{
const
uint32_t
mask
=
SCTLR_M_BIT
|
SCTLR_C_BIT
;
/* Unlock is required only when MMU and cache are enabled */
if
((
read_sctlr
()
&
mask
)
==
mask
)
{
spin_unlock
(
&
bsec_spinlock
);
}
}
static
int
bsec_get_dt_node
(
struct
dt_node_info
*
info
)
{
int
node
;
node
=
dt_get_node
(
info
,
-
1
,
BSEC_COMPAT
);
if
(
node
<
0
)
{
return
-
FDT_ERR_NOTFOUND
;
}
return
node
;
}
#if defined(IMAGE_BL32)
static
void
enable_non_secure_access
(
uint32_t
otp
)
{
otp_nsec_access
[
otp
/
__WORD_BIT
]
|=
BIT
(
otp
%
__WORD_BIT
);
if
(
bsec_shadow_register
(
otp
)
!=
BSEC_OK
)
{
panic
();
}
}
static
bool
non_secure_can_access
(
uint32_t
otp
)
{
return
(
otp_nsec_access
[
otp
/
__WORD_BIT
]
&
BIT
(
otp
%
__WORD_BIT
))
!=
0
;
}
static
int
bsec_dt_otp_nsec_access
(
void
*
fdt
,
int
bsec_node
)
{
int
bsec_subnode
;
fdt_for_each_subnode
(
bsec_subnode
,
fdt
,
bsec_node
)
{
const
fdt32_t
*
cuint
;
uint32_t
reg
;
uint32_t
i
;
uint32_t
size
;
uint8_t
status
;
cuint
=
fdt_getprop
(
fdt
,
bsec_subnode
,
"reg"
,
NULL
);
if
(
cuint
==
NULL
)
{
panic
();
}
reg
=
fdt32_to_cpu
(
*
cuint
)
/
sizeof
(
uint32_t
);
if
(
reg
<
STM32MP1_UPPER_OTP_START
)
{
continue
;
}
status
=
fdt_get_status
(
bsec_subnode
);
if
((
status
&
DT_NON_SECURE
)
==
0U
)
{
continue
;
}
size
=
fdt32_to_cpu
(
*
(
cuint
+
1
))
/
sizeof
(
uint32_t
);
if
((
fdt32_to_cpu
(
*
(
cuint
+
1
))
%
sizeof
(
uint32_t
))
!=
0
)
{
size
++
;
}
for
(
i
=
reg
;
i
<
(
reg
+
size
);
i
++
)
{
enable_non_secure_access
(
i
);
}
}
return
0
;
}
#endif
static
uint32_t
otp_bank_offset
(
uint32_t
otp
)
{
assert
(
otp
<=
STM32MP1_OTP_MAX_ID
);
return
((
otp
&
~
BSEC_OTP_MASK
)
>>
BSEC_OTP_BANK_SHIFT
)
*
sizeof
(
uint32_t
);
}
static
uint32_t
bsec_check_error
(
uint32_t
otp
)
{
uint32_t
bit
=
BIT
(
otp
&
BSEC_OTP_MASK
);
uint32_t
bank
=
otp_bank_offset
(
otp
);
if
((
mmio_read_32
(
bsec_base
+
BSEC_DISTURBED_OFF
+
bank
)
&
bit
)
!=
0U
)
{
return
BSEC_DISTURBED
;
}
if
((
mmio_read_32
(
bsec_base
+
BSEC_ERROR_OFF
+
bank
)
&
bit
)
!=
0U
)
{
return
BSEC_ERROR
;
}
return
BSEC_OK
;
}
/*
* bsec_probe: initialize BSEC driver.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_probe
(
void
)
{
void
*
fdt
;
int
node
;
struct
dt_node_info
bsec_info
;
if
(
fdt_get_address
(
&
fdt
)
==
0
)
{
panic
();
}
node
=
bsec_get_dt_node
(
&
bsec_info
);
if
(
node
<
0
)
{
panic
();
}
bsec_base
=
bsec_info
.
base
;
#if defined(IMAGE_BL32)
bsec_dt_otp_nsec_access
(
fdt
,
node
);
#endif
return
BSEC_OK
;
}
/*
* bsec_get_base: return BSEC base address.
*/
uint32_t
bsec_get_base
(
void
)
{
return
bsec_base
;
}
/*
* bsec_set_config: enable and configure BSEC.
* cfg: pointer to param structure used to set register.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_set_config
(
struct
bsec_config
*
cfg
)
{
uint32_t
value
;
int32_t
result
;
value
=
((((
uint32_t
)
cfg
->
freq
<<
BSEC_CONF_FRQ_SHIFT
)
&
BSEC_CONF_FRQ_MASK
)
|
(((
uint32_t
)
cfg
->
pulse_width
<<
BSEC_CONF_PRG_WIDTH_SHIFT
)
&
BSEC_CONF_PRG_WIDTH_MASK
)
|
(((
uint32_t
)
cfg
->
tread
<<
BSEC_CONF_TREAD_SHIFT
)
&
BSEC_CONF_TREAD_MASK
));
bsec_lock
();
mmio_write_32
(
bsec_base
+
BSEC_OTP_CONF_OFF
,
value
);
bsec_unlock
();
result
=
bsec_power_safmem
((
bool
)
cfg
->
power
&
BSEC_CONF_POWER_UP_MASK
);
if
(
result
!=
BSEC_OK
)
{
return
result
;
}
value
=
((((
uint32_t
)
cfg
->
upper_otp_lock
<<
UPPER_OTP_LOCK_SHIFT
)
&
UPPER_OTP_LOCK_MASK
)
|
(((
uint32_t
)
cfg
->
den_lock
<<
DENREG_LOCK_SHIFT
)
&
DENREG_LOCK_MASK
)
|
(((
uint32_t
)
cfg
->
prog_lock
<<
GPLOCK_LOCK_SHIFT
)
&
GPLOCK_LOCK_MASK
));
bsec_lock
();
mmio_write_32
(
bsec_base
+
BSEC_OTP_LOCK_OFF
,
value
);
bsec_unlock
();
return
BSEC_OK
;
}
/*
* bsec_get_config: return config parameters set in BSEC registers.
* cfg: config param return.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_get_config
(
struct
bsec_config
*
cfg
)
{
uint32_t
value
;
if
(
cfg
==
NULL
)
{
return
BSEC_INVALID_PARAM
;
}
value
=
mmio_read_32
(
bsec_base
+
BSEC_OTP_CONF_OFF
);
cfg
->
power
=
(
uint8_t
)((
value
&
BSEC_CONF_POWER_UP_MASK
)
>>
BSEC_CONF_POWER_UP_SHIFT
);
cfg
->
freq
=
(
uint8_t
)((
value
&
BSEC_CONF_FRQ_MASK
)
>>
BSEC_CONF_FRQ_SHIFT
);
cfg
->
pulse_width
=
(
uint8_t
)((
value
&
BSEC_CONF_PRG_WIDTH_MASK
)
>>
BSEC_CONF_PRG_WIDTH_SHIFT
);
cfg
->
tread
=
(
uint8_t
)((
value
&
BSEC_CONF_TREAD_MASK
)
>>
BSEC_CONF_TREAD_SHIFT
);
value
=
mmio_read_32
(
bsec_base
+
BSEC_OTP_LOCK_OFF
);
cfg
->
upper_otp_lock
=
(
uint8_t
)((
value
&
UPPER_OTP_LOCK_MASK
)
>>
UPPER_OTP_LOCK_SHIFT
);
cfg
->
den_lock
=
(
uint8_t
)((
value
&
DENREG_LOCK_MASK
)
>>
DENREG_LOCK_SHIFT
);
cfg
->
prog_lock
=
(
uint8_t
)((
value
&
GPLOCK_LOCK_MASK
)
>>
GPLOCK_LOCK_SHIFT
);
return
BSEC_OK
;
}
/*
* bsec_shadow_register: copy SAFMEM OTP to BSEC data.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_shadow_register
(
uint32_t
otp
)
{
uint32_t
result
;
bool
power_up
=
false
;
if
(
otp
>
STM32MP1_OTP_MAX_ID
)
{
return
BSEC_INVALID_PARAM
;
}
/* Check if shadowing of OTP is locked */
if
(
bsec_read_sr_lock
(
otp
))
{
VERBOSE
(
"BSEC: OTP %i is locked and will not be refreshed
\n
"
,
otp
);
}
if
((
bsec_get_status
()
&
BSEC_MODE_PWR_MASK
)
==
0U
)
{
result
=
bsec_power_safmem
(
true
);
if
(
result
!=
BSEC_OK
)
{
return
result
;
}
power_up
=
true
;
}
bsec_lock
();
/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
mmio_write_32
(
bsec_base
+
BSEC_OTP_CTRL_OFF
,
otp
|
BSEC_READ
);
while
((
bsec_get_status
()
&
BSEC_MODE_BUSY_MASK
)
!=
0U
)
{
;
}
result
=
bsec_check_error
(
otp
);
bsec_unlock
();
if
(
power_up
)
{
if
(
bsec_power_safmem
(
false
)
!=
BSEC_OK
)
{
panic
();
}
}
return
result
;
}
/*
* bsec_read_otp: read an OTP data value.
* val: read value.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_read_otp
(
uint32_t
*
val
,
uint32_t
otp
)
{
uint32_t
result
;
if
(
otp
>
STM32MP1_OTP_MAX_ID
)
{
return
BSEC_INVALID_PARAM
;
}
bsec_lock
();
*
val
=
mmio_read_32
(
bsec_base
+
BSEC_OTP_DATA_OFF
+
(
otp
*
sizeof
(
uint32_t
)));
result
=
bsec_check_error
(
otp
);
bsec_unlock
();
return
result
;
}
/*
* bsec_write_otp: write value in BSEC data register.
* val: value to write.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_write_otp
(
uint32_t
val
,
uint32_t
otp
)
{
uint32_t
result
;
if
(
otp
>
STM32MP1_OTP_MAX_ID
)
{
return
BSEC_INVALID_PARAM
;
}
/* Check if programming of OTP is locked */
if
(
bsec_read_sw_lock
(
otp
))
{
VERBOSE
(
"BSEC: OTP %i is locked and write will be ignored
\n
"
,
otp
);
}
bsec_lock
();
mmio_write_32
(
bsec_base
+
BSEC_OTP_DATA_OFF
+
(
otp
*
sizeof
(
uint32_t
)),
val
);
result
=
bsec_check_error
(
otp
);
bsec_unlock
();
return
result
;
}
/*
* bsec_program_otp: program a bit in SAFMEM after the prog.
* The OTP data is not refreshed.
* val: value to program.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_program_otp
(
uint32_t
val
,
uint32_t
otp
)
{
uint32_t
result
;
bool
power_up
=
false
;
if
(
otp
>
STM32MP1_OTP_MAX_ID
)
{
return
BSEC_INVALID_PARAM
;
}
/* Check if programming of OTP is locked */
if
(
bsec_read_sp_lock
(
otp
))
{
WARN
(
"BSEC: OTP locked, prog will be ignored
\n
"
);
}
if
((
mmio_read_32
(
bsec_base
+
BSEC_OTP_LOCK_OFF
)
&
BIT
(
BSEC_LOCK_PROGRAM
))
!=
0U
)
{
WARN
(
"BSEC: GPLOCK activated, prog will be ignored
\n
"
);
}
if
((
bsec_get_status
()
&
BSEC_MODE_PWR_MASK
)
==
0U
)
{
result
=
bsec_power_safmem
(
true
);
if
(
result
!=
BSEC_OK
)
{
return
result
;
}
power_up
=
true
;
}
bsec_lock
();
/* Set value in write register */
mmio_write_32
(
bsec_base
+
BSEC_OTP_WRDATA_OFF
,
val
);
/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
mmio_write_32
(
bsec_base
+
BSEC_OTP_CTRL_OFF
,
otp
|
BSEC_WRITE
);
while
((
bsec_get_status
()
&
BSEC_MODE_BUSY_MASK
)
!=
0U
)
{
;
}
if
((
bsec_get_status
()
&
BSEC_MODE_PROGFAIL_MASK
)
!=
0U
)
{
result
=
BSEC_PROG_FAIL
;
}
else
{
result
=
bsec_check_error
(
otp
);
}
bsec_unlock
();
if
(
power_up
)
{
if
(
bsec_power_safmem
(
false
)
!=
BSEC_OK
)
{
panic
();
}
}
return
result
;
}
/*
* bsec_permanent_lock_otp: permanent lock of OTP in SAFMEM.
* otp: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_permanent_lock_otp
(
uint32_t
otp
)
{
uint32_t
result
;
bool
power_up
=
false
;
uint32_t
data
;
uint32_t
addr
;
if
(
otp
>
STM32MP1_OTP_MAX_ID
)
{
return
BSEC_INVALID_PARAM
;
}
if
((
bsec_get_status
()
&
BSEC_MODE_PWR_MASK
)
==
0U
)
{
result
=
bsec_power_safmem
(
true
);
if
(
result
!=
BSEC_OK
)
{
return
result
;
}
power_up
=
true
;
}
if
(
otp
<
STM32MP1_UPPER_OTP_START
)
{
addr
=
otp
>>
ADDR_LOWER_OTP_PERLOCK_SHIFT
;
data
=
DATA_LOWER_OTP_PERLOCK_BIT
<<
((
otp
&
DATA_LOWER_OTP_PERLOCK_MASK
)
<<
1U
);
}
else
{
addr
=
(
otp
>>
ADDR_UPPER_OTP_PERLOCK_SHIFT
)
+
2U
;
data
=
DATA_UPPER_OTP_PERLOCK_BIT
<<
(
otp
&
DATA_UPPER_OTP_PERLOCK_MASK
);
}
bsec_lock
();
/* Set value in write register */
mmio_write_32
(
bsec_base
+
BSEC_OTP_WRDATA_OFF
,
data
);
/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
mmio_write_32
(
bsec_base
+
BSEC_OTP_CTRL_OFF
,
addr
|
BSEC_WRITE
|
BSEC_LOCK
);
while
((
bsec_get_status
()
&
BSEC_MODE_BUSY_MASK
)
!=
0U
)
{
;
}
if
((
bsec_get_status
()
&
BSEC_MODE_PROGFAIL_MASK
)
!=
0U
)
{
result
=
BSEC_PROG_FAIL
;
}
else
{
result
=
bsec_check_error
(
otp
);
}
bsec_unlock
();
if
(
power_up
)
{
if
(
bsec_power_safmem
(
false
)
!=
BSEC_OK
)
{
panic
();
}
}
return
result
;
}
/*
* bsec_write_debug_conf: write value in debug feature
* to enable/disable debug service.
* val: value to write.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_write_debug_conf
(
uint32_t
val
)
{
uint32_t
result
=
BSEC_ERROR
;
uint32_t
masked_val
=
val
&
BSEC_DEN_ALL_MSK
;
bsec_lock
();
mmio_write_32
(
bsec_base
+
BSEC_DEN_OFF
,
masked_val
);
if
((
mmio_read_32
(
bsec_base
+
BSEC_DEN_OFF
)
^
masked_val
)
==
0U
)
{
result
=
BSEC_OK
;
}
bsec_unlock
();
return
result
;
}
/*
* bsec_read_debug_conf: read debug configuration.
*/
uint32_t
bsec_read_debug_conf
(
void
)
{
return
mmio_read_32
(
bsec_base
+
BSEC_DEN_OFF
);
}
/*
* bsec_get_status: return status register value.
*/
uint32_t
bsec_get_status
(
void
)
{
return
mmio_read_32
(
bsec_base
+
BSEC_OTP_STATUS_OFF
);
}
/*
* bsec_get_hw_conf: return hardware configuration.
*/
uint32_t
bsec_get_hw_conf
(
void
)
{
return
mmio_read_32
(
bsec_base
+
BSEC_IPHW_CFG_OFF
);
}
/*
* bsec_get_version: return BSEC version.
*/
uint32_t
bsec_get_version
(
void
)
{
return
mmio_read_32
(
bsec_base
+
BSEC_IPVR_OFF
);
}
/*
* bsec_get_id: return BSEC ID.
*/
uint32_t
bsec_get_id
(
void
)
{
return
mmio_read_32
(
bsec_base
+
BSEC_IP_ID_OFF
);
}
/*
* bsec_get_magic_id: return BSEC magic number.
*/
uint32_t
bsec_get_magic_id
(
void
)
{
return
mmio_read_32
(
bsec_base
+
BSEC_IP_MAGIC_ID_OFF
);
}
/*
* bsec_write_sr_lock: write shadow-read lock.
* otp: OTP number.
* value: value to write in the register.
* Must be always 1.
* return: true if OTP is locked, else false.
*/
bool
bsec_write_sr_lock
(
uint32_t
otp
,
uint32_t
value
)
{
bool
result
=
false
;
uint32_t
bank
=
otp_bank_offset
(
otp
);
uint32_t
bank_value
;
uint32_t
otp_mask
=
BIT
(
otp
&
BSEC_OTP_MASK
);
bsec_lock
();
bank_value
=
mmio_read_32
(
bsec_base
+
BSEC_SRLOCK_OFF
+
bank
);
if
((
bank_value
&
otp_mask
)
==
value
)
{
/*
* In case of write don't need to write,
* the lock is already set.
*/
if
(
value
!=
0U
)
{
result
=
true
;
}
}
else
{
if
(
value
!=
0U
)
{
bank_value
=
bank_value
|
otp_mask
;
}
else
{
bank_value
=
bank_value
&
~
otp_mask
;
}
/*
* We can write 0 in all other OTP
* if the lock is activated in one of other OTP.
* Write 0 has no effect.
*/
mmio_write_32
(
bsec_base
+
BSEC_SRLOCK_OFF
+
bank
,
bank_value
);
result
=
true
;
}
bsec_unlock
();
return
result
;
}
/*
* bsec_read_sr_lock: read shadow-read lock.
* otp: OTP number.
* return: true if otp is locked, else false.
*/
bool
bsec_read_sr_lock
(
uint32_t
otp
)
{
uint32_t
bank
=
otp_bank_offset
(
otp
);
uint32_t
otp_mask
=
BIT
(
otp
&
BSEC_OTP_MASK
);
uint32_t
bank_value
=
mmio_read_32
(
bsec_base
+
BSEC_SRLOCK_OFF
+
bank
);
return
(
bank_value
&
otp_mask
)
!=
0U
;
}
/*
* bsec_write_sw_lock: write shadow-write lock.
* otp: OTP number.
* value: Value to write in the register.
* Must be always 1.
* return: true if OTP is locked, else false.
*/
bool
bsec_write_sw_lock
(
uint32_t
otp
,
uint32_t
value
)
{
bool
result
=
false
;
uint32_t
bank
=
otp_bank_offset
(
otp
);
uint32_t
otp_mask
=
BIT
(
otp
&
BSEC_OTP_MASK
);
uint32_t
bank_value
;
bsec_lock
();
bank_value
=
mmio_read_32
(
bsec_base
+
BSEC_SWLOCK_OFF
+
bank
);
if
((
bank_value
&
otp_mask
)
==
value
)
{
/*
* In case of write don't need to write,
* the lock is already set.
*/
if
(
value
!=
0U
)
{
result
=
true
;
}
}
else
{
if
(
value
!=
0U
)
{
bank_value
=
bank_value
|
otp_mask
;
}
else
{
bank_value
=
bank_value
&
~
otp_mask
;
}
/*
* We can write 0 in all other OTP
* if the lock is activated in one of other OTP.
* Write 0 has no effect.
*/
mmio_write_32
(
bsec_base
+
BSEC_SWLOCK_OFF
+
bank
,
bank_value
);
result
=
true
;
}
bsec_unlock
();
return
result
;
}
/*
* bsec_read_sw_lock: read shadow-write lock.
* otp: OTP number.
* return: true if OTP is locked, else false.
*/
bool
bsec_read_sw_lock
(
uint32_t
otp
)
{
uint32_t
bank
=
otp_bank_offset
(
otp
);
uint32_t
otp_mask
=
BIT
(
otp
&
BSEC_OTP_MASK
);
uint32_t
bank_value
=
mmio_read_32
(
bsec_base
+
BSEC_SWLOCK_OFF
+
bank
);
return
(
bank_value
&
otp_mask
)
!=
0U
;
}
/*
* bsec_write_sp_lock: write shadow-program lock.
* otp: OTP number.
* value: Value to write in the register.
* Must be always 1.
* return: true if OTP is locked, else false.
*/
bool
bsec_write_sp_lock
(
uint32_t
otp
,
uint32_t
value
)
{
bool
result
=
false
;
uint32_t
bank
=
otp_bank_offset
(
otp
);
uint32_t
bank_value
;
uint32_t
otp_mask
=
BIT
(
otp
&
BSEC_OTP_MASK
);
bsec_lock
();
bank_value
=
mmio_read_32
(
bsec_base
+
BSEC_SPLOCK_OFF
+
bank
);
if
((
bank_value
&
otp_mask
)
==
value
)
{
/*
* In case of write don't need to write,
* the lock is already set.
*/
if
(
value
!=
0U
)
{
result
=
true
;
}
}
else
{
if
(
value
!=
0U
)
{
bank_value
=
bank_value
|
otp_mask
;
}
else
{
bank_value
=
bank_value
&
~
otp_mask
;
}
/*
* We can write 0 in all other OTP
* if the lock is activated in one of other OTP.
* Write 0 has no effect.
*/
mmio_write_32
(
bsec_base
+
BSEC_SPLOCK_OFF
+
bank
,
bank_value
);
result
=
true
;
}
bsec_unlock
();
return
result
;
}
/*
* bsec_read_sp_lock: read shadow-program lock.
* otp: OTP number.
* return: true if OTP is locked, else false.
*/
bool
bsec_read_sp_lock
(
uint32_t
otp
)
{
uint32_t
bank
=
otp_bank_offset
(
otp
);
uint32_t
otp_mask
=
BIT
(
otp
&
BSEC_OTP_MASK
);
uint32_t
bank_value
=
mmio_read_32
(
bsec_base
+
BSEC_SPLOCK_OFF
+
bank
);
return
(
bank_value
&
otp_mask
)
!=
0U
;
}
/*
* bsec_wr_lock: Read permanent lock status.
* otp: OTP number.
* return: true if OTP is locked, else false.
*/
bool
bsec_wr_lock
(
uint32_t
otp
)
{
uint32_t
bank
=
otp_bank_offset
(
otp
);
uint32_t
lock_bit
=
BIT
(
otp
&
BSEC_OTP_MASK
);
if
((
mmio_read_32
(
bsec_base
+
BSEC_WRLOCK_OFF
+
bank
)
&
lock_bit
)
!=
0U
)
{
/*
* In case of write don't need to write,
* the lock is already set.
*/
return
true
;
}
return
false
;
}
/*
* bsec_otp_lock: Lock Upper OTP or Global programming or debug enable
* service: Service to lock see header file.
* value: Value to write must always set to 1 (only use for debug purpose).
* return: BSEC_OK if succeed.
*/
uint32_t
bsec_otp_lock
(
uint32_t
service
,
uint32_t
value
)
{
uintptr_t
reg
=
bsec_base
+
BSEC_OTP_LOCK_OFF
;
switch
(
service
)
{
case
BSEC_LOCK_UPPER_OTP
:
mmio_write_32
(
reg
,
value
<<
BSEC_LOCK_UPPER_OTP
);
break
;
case
BSEC_LOCK_DEBUG
:
mmio_write_32
(
reg
,
value
<<
BSEC_LOCK_DEBUG
);
break
;
case
BSEC_LOCK_PROGRAM
:
mmio_write_32
(
reg
,
value
<<
BSEC_LOCK_PROGRAM
);
break
;
default:
return
BSEC_INVALID_PARAM
;
}
return
BSEC_OK
;
}
/*
* bsec_power_safmem: Activate or deactivate SAFMEM power.
* power: true to power up, false to power down.
* return: BSEC_OK if succeed.
*/
static
uint32_t
bsec_power_safmem
(
bool
power
)
{
uint32_t
register_val
;
uint32_t
timeout
=
BSEC_TIMEOUT_VALUE
;
bsec_lock
();
register_val
=
mmio_read_32
(
bsec_base
+
BSEC_OTP_CONF_OFF
);
if
(
power
)
{
register_val
|=
BSEC_CONF_POWER_UP_MASK
;
}
else
{
register_val
&=
~
BSEC_CONF_POWER_UP_MASK
;
}
mmio_write_32
(
bsec_base
+
BSEC_OTP_CONF_OFF
,
register_val
);
/* Waiting loop */
if
(
power
)
{
while
(((
bsec_get_status
()
&
BSEC_MODE_PWR_MASK
)
==
0U
)
&&
(
timeout
!=
0U
))
{
timeout
--
;
}
}
else
{
while
(((
bsec_get_status
()
&
BSEC_MODE_PWR_MASK
)
!=
0U
)
&&
(
timeout
!=
0U
))
{
timeout
--
;
}
}
bsec_unlock
();
if
(
timeout
==
0U
)
{
return
BSEC_TIMEOUT
;
}
return
BSEC_OK
;
}
/*
* bsec_mode_is_closed_device: read OTP secure sub-mode.
* return: false if open_device and true of closed_device.
*/
bool
bsec_mode_is_closed_device
(
void
)
{
uint32_t
value
;
if
((
bsec_shadow_register
(
DATA0_OTP
)
!=
BSEC_OK
)
||
(
bsec_read_otp
(
&
value
,
DATA0_OTP
)
!=
BSEC_OK
))
{
return
true
;
}
return
(
value
&
DATA0_OTP_SECURED
)
==
DATA0_OTP_SECURED
;
}
/*
* bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
* otp_value: read value.
* word: OTP number.
* return value: BSEC_OK if no error.
*/
uint32_t
bsec_shadow_read_otp
(
uint32_t
*
otp_value
,
uint32_t
word
)
{
uint32_t
result
;
result
=
bsec_shadow_register
(
word
);
if
(
result
!=
BSEC_OK
)
{
ERROR
(
"BSEC: %u Shadowing Error %i
\n
"
,
word
,
result
);
return
result
;
}
result
=
bsec_read_otp
(
otp_value
,
word
);
if
(
result
!=
BSEC_OK
)
{
ERROR
(
"BSEC: %u Read Error %i
\n
"
,
word
,
result
);
}
return
result
;
}
/*
* bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
* otp: OTP number.
* return: BSEC_OK if authorized access.
*/
uint32_t
bsec_check_nsec_access_rights
(
uint32_t
otp
)
{
#if defined(IMAGE_BL32)
if
(
otp
>
STM32MP1_OTP_MAX_ID
)
{
return
BSEC_INVALID_PARAM
;
}
if
(
otp
>=
STM32MP1_UPPER_OTP_START
)
{
/* Check if BSEC is in OTP-SECURED closed_device state. */
if
(
bsec_mode_is_closed_device
())
{
if
(
!
non_secure_can_access
(
otp
))
{
return
BSEC_ERROR
;
}
}
}
#endif
return
BSEC_OK
;
}
drivers/st/clk/stm32mp1_clkfunc.c
View file @
fbf35335
/*
* Copyright (c) 2017-201
8
, STMicroelectronics - All Rights Reserved
* Copyright (c) 2017-201
9
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -31,11 +31,19 @@ const char *stm32mp_osc_node_label[NB_OSC] = {
[
_USB_PHY_48
]
=
"ck_usbo_48m"
};
/*******************************************************************************
* This function returns the RCC node in the device tree.
******************************************************************************/
static
int
fdt_get_rcc_node
(
void
*
fdt
)
{
return
fdt_node_offset_by_compatible
(
fdt
,
-
1
,
DT_RCC_CLK_COMPAT
);
}
/*******************************************************************************
* This function reads the frequency of an oscillator from its name.
* It reads the value indicated inside the device tree.
* Returns 0
if
success, and a negative
value els
e.
*
If
success, value is stored in the second parameter.
* Returns 0
on
success, and a negative
FDT/ERRNO error code on failur
e.
*
On
success, value is stored in the second parameter.
******************************************************************************/
int
fdt_osc_read_freq
(
const
char
*
name
,
uint32_t
*
freq
)
{
...
...
@@ -127,7 +135,7 @@ bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name)
/*******************************************************************************
* This function reads a value of a oscillator property from its id.
* Returns value
if
success, and a default value if property not found.
* Returns value
on
success, and a default value if property not found.
* Default value is passed as parameter.
******************************************************************************/
uint32_t
fdt_osc_read_uint32_default
(
enum
stm32mp_osc_id
osc_id
,
...
...
@@ -240,7 +248,7 @@ int fdt_rcc_read_uint32_array(const char *prop_name,
/*******************************************************************************
* This function gets the subnode offset in rcc-clk section from its name.
* It reads the values indicated inside the device tree.
* Returns offset
if
success, and a negative
value els
e.
* Returns offset
on
success, and a negative
FDT/ERRNO error code on failur
e.
******************************************************************************/
int
fdt_rcc_subnode_offset
(
const
char
*
name
)
{
...
...
@@ -251,7 +259,7 @@ int fdt_rcc_subnode_offset(const char *name)
return
-
ENOENT
;
}
node
=
fdt_
node_offset_by_compatible
(
fdt
,
-
1
,
DT_RCC_CLK_COMPAT
);
node
=
fdt_
get_rcc_node
(
fdt
);
if
(
node
<
0
)
{
return
-
FDT_ERR_NOTFOUND
;
}
...
...
@@ -280,7 +288,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
return
NULL
;
}
node
=
fdt_
node_offset_by_compatible
(
fdt
,
-
1
,
DT_RCC_CLK_COMPAT
);
node
=
fdt_
get_rcc_node
(
fdt
);
if
(
node
<
0
)
{
return
NULL
;
}
...
...
@@ -297,7 +305,7 @@ const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
/*******************************************************************************
* This function gets the secure status for rcc node.
* It reads secure-status in device tree.
* Returns
1
if rcc is available from secure world,
0 else
.
* Returns
true
if rcc is available from secure world,
false if not
.
******************************************************************************/
bool
fdt_get_rcc_secure_status
(
void
)
{
...
...
@@ -308,18 +316,18 @@ bool fdt_get_rcc_secure_status(void)
return
false
;
}
node
=
fdt_
node_offset_by_compatible
(
fdt
,
-
1
,
DT_RCC_COMPAT
);
node
=
fdt_
get_rcc_node
(
fdt
);
if
(
node
<
0
)
{
return
false
;
}
return
fdt_
check_secure
_status
(
node
);
return
(
fdt_
get
_status
(
node
)
&
DT_SECURE
)
!=
0U
;
}
/*******************************************************************************
* This function reads the stgen base address.
* It reads the value indicated inside the device tree.
* Returns address
if
success, and NULL value
els
e.
* Returns address
on
success, and NULL value
on failur
e.
******************************************************************************/
uintptr_t
fdt_get_stgen_base
(
void
)
{
...
...
@@ -347,7 +355,7 @@ uintptr_t fdt_get_stgen_base(void)
/*******************************************************************************
* This function gets the clock ID of the given node.
* It reads the value indicated inside the device tree.
* Returns ID
if
success, and a negative
value els
e.
* Returns ID
on
success, and a negative
FDT/ERRNO error code on failur
e.
******************************************************************************/
int
fdt_get_clock_id
(
int
node
)
{
...
...
drivers/st/ddr/stm32mp1_ddr.c
View file @
fbf35335
/*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
* Copyright (C) 2018
-2019
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
#include <errno.h>
#include <stddef.h>
#include <platform_def.h>
...
...
@@ -12,10 +13,10 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_ddr.h>
#include <drivers/st/stm32mp1_ddr_regs.h>
#include <drivers/st/stm32mp1_pmic.h>
#include <drivers/st/stm32mp1_pwr.h>
#include <drivers/st/stm32mp1_ram.h>
#include <drivers/st/stm32mp1_rcc.h>
...
...
@@ -233,40 +234,67 @@ struct ddr_reg_info {
static
const
struct
ddr_reg_info
ddr_registers
[
REG_TYPE_NB
]
=
{
[
REG_REG
]
=
{
"static"
,
ddr_reg
,
ARRAY_SIZE
(
ddr_reg
),
DDR_BASE
.
name
=
"static"
,
.
desc
=
ddr_reg
,
.
size
=
ARRAY_SIZE
(
ddr_reg
),
.
base
=
DDR_BASE
},
[
REG_TIMING
]
=
{
"timing"
,
ddr_timing
,
ARRAY_SIZE
(
ddr_timing
),
DDR_BASE
.
name
=
"timing"
,
.
desc
=
ddr_timing
,
.
size
=
ARRAY_SIZE
(
ddr_timing
),
.
base
=
DDR_BASE
},
[
REG_PERF
]
=
{
"perf"
,
ddr_perf
,
ARRAY_SIZE
(
ddr_perf
),
DDR_BASE
.
name
=
"perf"
,
.
desc
=
ddr_perf
,
.
size
=
ARRAY_SIZE
(
ddr_perf
),
.
base
=
DDR_BASE
},
[
REG_MAP
]
=
{
"map"
,
ddr_map
,
ARRAY_SIZE
(
ddr_map
),
DDR_BASE
.
name
=
"map"
,
.
desc
=
ddr_map
,
.
size
=
ARRAY_SIZE
(
ddr_map
),
.
base
=
DDR_BASE
},
[
REGPHY_REG
]
=
{
"static"
,
ddrphy_reg
,
ARRAY_SIZE
(
ddrphy_reg
),
DDRPHY_BASE
.
name
=
"static"
,
.
desc
=
ddrphy_reg
,
.
size
=
ARRAY_SIZE
(
ddrphy_reg
),
.
base
=
DDRPHY_BASE
},
[
REGPHY_TIMING
]
=
{
"timing"
,
ddrphy_timing
,
ARRAY_SIZE
(
ddrphy_timing
),
DDRPHY_BASE
.
name
=
"timing"
,
.
desc
=
ddrphy_timing
,
.
size
=
ARRAY_SIZE
(
ddrphy_timing
),
.
base
=
DDRPHY_BASE
},
[
REGPHY_CAL
]
=
{
"cal"
,
ddrphy_cal
,
ARRAY_SIZE
(
ddrphy_cal
),
DDRPHY_BASE
.
name
=
"cal"
,
.
desc
=
ddrphy_cal
,
.
size
=
ARRAY_SIZE
(
ddrphy_cal
),
.
base
=
DDRPHY_BASE
},
[
REG_DYN
]
=
{
"dyn"
,
ddr_dyn
,
ARRAY_SIZE
(
ddr_dyn
),
DDR_BASE
.
name
=
"dyn"
,
.
desc
=
ddr_dyn
,
.
size
=
ARRAY_SIZE
(
ddr_dyn
),
.
base
=
DDR_BASE
},
[
REGPHY_DYN
]
=
{
"dyn"
,
ddrphy_dyn
,
ARRAY_SIZE
(
ddrphy_dyn
),
DDRPHY_BASE
.
name
=
"dyn"
,
.
desc
=
ddrphy_dyn
,
.
size
=
ARRAY_SIZE
(
ddrphy_dyn
),
.
base
=
DDRPHY_BASE
},
};
static
uint
32
_t
get_base_addr
(
const
struct
ddr_info
*
priv
,
enum
base_type
base
)
static
uint
ptr
_t
get_base_addr
(
const
struct
ddr_info
*
priv
,
enum
base_type
base
)
{
if
(
base
==
DDRPHY_BASE
)
{
return
(
uint
32
_t
)
priv
->
phy
;
return
(
uint
ptr
_t
)
priv
->
phy
;
}
else
{
return
(
uint
32
_t
)
priv
->
ctl
;
return
(
uint
ptr
_t
)
priv
->
ctl
;
}
}
...
...
@@ -275,21 +303,22 @@ static void set_reg(const struct ddr_info *priv,
const
void
*
param
)
{
unsigned
int
i
;
unsigned
int
*
ptr
,
value
;
unsigned
int
value
;
enum
base_type
base
=
ddr_registers
[
type
].
base
;
uint
32
_t
base_addr
=
get_base_addr
(
priv
,
base
);
uint
ptr
_t
base_addr
=
get_base_addr
(
priv
,
base
);
const
struct
reg_desc
*
desc
=
ddr_registers
[
type
].
desc
;
VERBOSE
(
"init %s
\n
"
,
ddr_registers
[
type
].
name
);
for
(
i
=
0
;
i
<
ddr_registers
[
type
].
size
;
i
++
)
{
ptr
=
(
unsigned
int
*
)(
base_addr
+
desc
[
i
].
offset
);
uintptr_t
ptr
=
base_addr
+
desc
[
i
].
offset
;
if
(
desc
[
i
].
par_offset
==
INVALID_OFFSET
)
{
ERROR
(
"invalid parameter offset for %s"
,
desc
[
i
].
name
);
panic
();
}
else
{
value
=
*
((
uint32_t
*
)((
uint
32
_t
)
param
+
value
=
*
((
uint32_t
*
)((
uint
ptr
_t
)
param
+
desc
[
i
].
par_offset
));
mmio_write_32
(
(
uint32_t
)
ptr
,
value
);
mmio_write_32
(
ptr
,
value
);
}
}
}
...
...
@@ -305,15 +334,15 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
time0
=
start
;
do
{
pgsr
=
mmio_read_32
((
uint
32
_t
)
&
phy
->
pgsr
);
pgsr
=
mmio_read_32
((
uint
ptr
_t
)
&
phy
->
pgsr
);
time
=
get_timer
(
start
);
if
(
time
!=
time0
)
{
VERBOSE
(
" > [0x%x] pgsr = 0x%x &
\n
"
,
(
uint
32
_t
)
&
phy
->
pgsr
,
pgsr
);
VERBOSE
(
" [0x%x] pir = 0x%x (time=%x)
\n
"
,
(
uint
32
_t
)
&
phy
->
pir
,
mmio_read_32
((
uint
32
_t
)
&
phy
->
pir
),
(
uint32_t
)
time
);
VERBOSE
(
" > [0x%
l
x] pgsr = 0x%x &
\n
"
,
(
uint
ptr
_t
)
&
phy
->
pgsr
,
pgsr
);
VERBOSE
(
" [0x%
l
x] pir = 0x%x (time=%
l
x)
\n
"
,
(
uint
ptr
_t
)
&
phy
->
pir
,
mmio_read_32
((
uint
ptr
_t
)
&
phy
->
pir
),
time
);
}
time0
=
time
;
...
...
@@ -341,18 +370,18 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
error
++
;
}
}
while
((
pgsr
&
DDRPHYC_PGSR_IDONE
)
==
0U
&&
error
==
0
);
VERBOSE
(
"
\n
[0x%x] pgsr = 0x%x
\n
"
,
(
uint
32
_t
)
&
phy
->
pgsr
,
pgsr
);
VERBOSE
(
"
\n
[0x%
l
x] pgsr = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
phy
->
pgsr
,
pgsr
);
}
static
void
stm32mp1_ddrphy_init
(
struct
stm32mp1_ddrphy
*
phy
,
uint32_t
pir
)
{
uint32_t
pir_init
=
pir
|
DDRPHYC_PIR_INIT
;
mmio_write_32
((
uint
32
_t
)
&
phy
->
pir
,
pir_init
);
VERBOSE
(
"[0x%x] pir = 0x%x -> 0x%x
\n
"
,
(
uint
32
_t
)
&
phy
->
pir
,
pir_init
,
mmio_read_32
((
uint
32
_t
)
&
phy
->
pir
));
mmio_write_32
((
uint
ptr
_t
)
&
phy
->
pir
,
pir_init
);
VERBOSE
(
"[0x%
l
x] pir = 0x%x -> 0x%x
\n
"
,
(
uint
ptr
_t
)
&
phy
->
pir
,
pir_init
,
mmio_read_32
((
uint
ptr
_t
)
&
phy
->
pir
));
/* Need to wait 10 configuration clock before start polling */
udelay
(
10
);
...
...
@@ -364,9 +393,9 @@ static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
/* Start quasi dynamic register update */
static
void
stm32mp1_start_sw_done
(
struct
stm32mp1_ddrctl
*
ctl
)
{
mmio_clrbits_32
((
uint
32
_t
)
&
ctl
->
swctl
,
DDRCTRL_SWCTL_SW_DONE
);
VERBOSE
(
"[0x%x] swctl = 0x%x
\n
"
,
(
uint
32
_t
)
&
ctl
->
swctl
,
mmio_read_32
((
uint
32
_t
)
&
ctl
->
swctl
));
mmio_clrbits_32
((
uint
ptr
_t
)
&
ctl
->
swctl
,
DDRCTRL_SWCTL_SW_DONE
);
VERBOSE
(
"[0x%
l
x] swctl = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
ctl
->
swctl
,
mmio_read_32
((
uint
ptr
_t
)
&
ctl
->
swctl
));
}
/* Wait quasi dynamic register update */
...
...
@@ -375,15 +404,15 @@ static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
unsigned
long
start
;
uint32_t
swstat
;
mmio_setbits_32
((
uint
32
_t
)
&
ctl
->
swctl
,
DDRCTRL_SWCTL_SW_DONE
);
VERBOSE
(
"[0x%x] swctl = 0x%x
\n
"
,
(
uint
32
_t
)
&
ctl
->
swctl
,
mmio_read_32
((
uint
32
_t
)
&
ctl
->
swctl
));
mmio_setbits_32
((
uint
ptr
_t
)
&
ctl
->
swctl
,
DDRCTRL_SWCTL_SW_DONE
);
VERBOSE
(
"[0x%
l
x] swctl = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
ctl
->
swctl
,
mmio_read_32
((
uint
ptr
_t
)
&
ctl
->
swctl
));
start
=
get_timer
(
0
);
do
{
swstat
=
mmio_read_32
((
uint
32
_t
)
&
ctl
->
swstat
);
VERBOSE
(
"[0x%x] swstat = 0x%x "
,
(
uint
32
_t
)
&
ctl
->
swstat
,
swstat
);
swstat
=
mmio_read_32
((
uint
ptr
_t
)
&
ctl
->
swstat
);
VERBOSE
(
"[0x%
l
x] swstat = 0x%x "
,
(
uint
ptr
_t
)
&
ctl
->
swstat
,
swstat
);
VERBOSE
(
"timer in ms 0x%x = start 0x%lx
\r
"
,
get_timer
(
0
),
start
);
if
(
get_timer
(
start
)
>
plat_get_syscnt_freq2
())
{
...
...
@@ -391,8 +420,8 @@ static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
}
}
while
((
swstat
&
DDRCTRL_SWSTAT_SW_DONE_ACK
)
==
0U
);
VERBOSE
(
"[0x%x] swstat = 0x%x
\n
"
,
(
uint
32
_t
)
&
ctl
->
swstat
,
swstat
);
VERBOSE
(
"[0x%
l
x] swstat = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
ctl
->
swstat
,
swstat
);
}
/* Wait quasi dynamic register update */
...
...
@@ -406,11 +435,11 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode)
start
=
get_timer
(
0
);
for
(
;
;
)
{
stat
=
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
stat
);
stat
=
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
stat
);
operating_mode
=
stat
&
DDRCTRL_STAT_OPERATING_MODE_MASK
;
selref_type
=
stat
&
DDRCTRL_STAT_SELFREF_TYPE_MASK
;
VERBOSE
(
"[0x%x] stat = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
stat
,
stat
);
VERBOSE
(
"[0x%
l
x] stat = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
stat
,
stat
);
VERBOSE
(
"timer in ms 0x%x = start 0x%lx
\r
"
,
get_timer
(
0
),
start
);
if
(
get_timer
(
start
)
>
plat_get_syscnt_freq2
())
{
...
...
@@ -441,8 +470,8 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode)
}
}
VERBOSE
(
"[0x%x] stat = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
stat
,
stat
);
VERBOSE
(
"[0x%
l
x] stat = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
stat
,
stat
);
}
/* Mode Register Writes (MRW or MRS) */
...
...
@@ -459,7 +488,7 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
* No write should be performed to MRCTRL0 and MRCTRL1
* if MRSTAT.mr_wr_busy = 1.
*/
while
((
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
mrstat
)
&
while
((
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mrstat
)
&
DDRCTRL_MRSTAT_MR_WR_BUSY
)
!=
0U
)
{
;
}
...
...
@@ -472,14 +501,14 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
DDRCTRL_MRCTRL0_MR_RANK_ALL
|
(((
uint32_t
)
addr
<<
DDRCTRL_MRCTRL0_MR_ADDR_SHIFT
)
&
DDRCTRL_MRCTRL0_MR_ADDR_MASK
);
mmio_write_32
((
uint
32
_t
)
&
priv
->
ctl
->
mrctrl0
,
mrctrl0
);
VERBOSE
(
"[0x%x] mrctrl0 = 0x%x (0x%x)
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
mrctrl0
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
mrctrl0
),
mrctrl0
);
mmio_write_32
((
uint
32
_t
)
&
priv
->
ctl
->
mrctrl1
,
data
);
VERBOSE
(
"[0x%x] mrctrl1 = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
mrctrl1
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
mrctrl1
));
mmio_write_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mrctrl0
,
mrctrl0
);
VERBOSE
(
"[0x%
l
x] mrctrl0 = 0x%x (0x%x)
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
mrctrl0
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mrctrl0
),
mrctrl0
);
mmio_write_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mrctrl1
,
data
);
VERBOSE
(
"[0x%
l
x] mrctrl1 = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
mrctrl1
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mrctrl1
));
/*
* 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This
...
...
@@ -489,22 +518,22 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
* initiated until it is deasserted.
*/
mrctrl0
|=
DDRCTRL_MRCTRL0_MR_WR
;
mmio_write_32
((
uint
32
_t
)
&
priv
->
ctl
->
mrctrl0
,
mrctrl0
);
mmio_write_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mrctrl0
,
mrctrl0
);
while
((
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
mrstat
)
&
while
((
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mrstat
)
&
DDRCTRL_MRSTAT_MR_WR_BUSY
)
!=
0U
)
{
;
}
VERBOSE
(
"[0x%x] mrctrl0 = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
mrctrl0
,
mrctrl0
);
VERBOSE
(
"[0x%
l
x] mrctrl0 = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
mrctrl0
,
mrctrl0
);
}
/* Switch DDR3 from DLL-on to DLL-off */
static
void
stm32mp1_ddr3_dll_off
(
struct
ddr_info
*
priv
)
{
uint32_t
mr1
=
mmio_read_32
((
uint
32
_t
)
&
priv
->
phy
->
mr1
);
uint32_t
mr2
=
mmio_read_32
((
uint
32
_t
)
&
priv
->
phy
->
mr2
);
uint32_t
mr1
=
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
phy
->
mr1
);
uint32_t
mr2
=
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
phy
->
mr2
);
uint32_t
dbgcam
;
VERBOSE
(
"mr1: 0x%x
\n
"
,
mr1
);
...
...
@@ -514,10 +543,10 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
* 1. Set the DBG1.dis_hif = 1.
* This prevents further reads/writes being received on the HIF.
*/
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
dbg1
,
DDRCTRL_DBG1_DIS_HIF
);
VERBOSE
(
"[0x%x] dbg1 = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
dbg1
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
dbg1
));
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dbg1
,
DDRCTRL_DBG1_DIS_HIF
);
VERBOSE
(
"[0x%
l
x] dbg1 = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
dbg1
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dbg1
));
/*
* 2. Ensure all commands have been flushed from the uMCTL2 by polling
...
...
@@ -528,9 +557,9 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
* DBGCAM.dbg_hpr_q_depth = 0.
*/
do
{
dbgcam
=
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
dbgcam
);
VERBOSE
(
"[0x%x] dbgcam = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
dbgcam
,
dbgcam
);
dbgcam
=
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dbgcam
);
VERBOSE
(
"[0x%
l
x] dbgcam = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
dbgcam
,
dbgcam
);
}
while
((((
dbgcam
&
DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY
)
==
DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY
))
&&
((
dbgcam
&
DDRCTRL_DBGCAM_DBG_Q_DEPTH
)
==
0U
));
...
...
@@ -574,11 +603,11 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
* PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure
* the DDRC has entered self-refresh.
*/
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
pwrctl
,
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
pwrctl
,
DDRCTRL_PWRCTL_SELFREF_SW
);
VERBOSE
(
"[0x%x] pwrctl = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
pwrctl
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
pwrctl
));
VERBOSE
(
"[0x%
l
x] pwrctl = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
pwrctl
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
pwrctl
));
/*
* 8. Wait until STAT.operating_mode[1:0]==11 indicating that the
...
...
@@ -594,10 +623,10 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
*/
stm32mp1_start_sw_done
(
priv
->
ctl
);
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
mstr
,
DDRCTRL_MSTR_DLL_OFF_MODE
);
VERBOSE
(
"[0x%x] mstr = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
mstr
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
mstr
));
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mstr
,
DDRCTRL_MSTR_DLL_OFF_MODE
);
VERBOSE
(
"[0x%
l
x] mstr = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
mstr
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mstr
));
stm32mp1_wait_sw_done_ack
(
priv
->
ctl
);
...
...
@@ -611,26 +640,26 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
/* Change Bypass Mode Frequency Range */
if
(
stm32mp1_clk_get_rate
(
DDRPHYC
)
<
100000000U
)
{
mmio_clrbits_32
((
uint
32
_t
)
&
priv
->
phy
->
dllgcr
,
mmio_clrbits_32
((
uint
ptr
_t
)
&
priv
->
phy
->
dllgcr
,
DDRPHYC_DLLGCR_BPS200
);
}
else
{
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
phy
->
dllgcr
,
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
phy
->
dllgcr
,
DDRPHYC_DLLGCR_BPS200
);
}
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
phy
->
acdllcr
,
DDRPHYC_ACDLLCR_DLLDIS
);
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
phy
->
acdllcr
,
DDRPHYC_ACDLLCR_DLLDIS
);
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
phy
->
dx0dllcr
,
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
phy
->
dx0dllcr
,
DDRPHYC_DXNDLLCR_DLLDIS
);
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
phy
->
dx1dllcr
,
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
phy
->
dx1dllcr
,
DDRPHYC_DXNDLLCR_DLLDIS
);
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
phy
->
dx2dllcr
,
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
phy
->
dx2dllcr
,
DDRPHYC_DXNDLLCR_DLLDIS
);
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
phy
->
dx3dllcr
,
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
phy
->
dx3dllcr
,
DDRPHYC_DXNDLLCR_DLLDIS
);
/* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
mmio_clrbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
pwrctl
,
mmio_clrbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
pwrctl
,
DDRCTRL_PWRCTL_SELFREF_SW
);
stm32mp1_wait_operating_mode
(
priv
,
DDRCTRL_STAT_OPERATING_MODE_NORMAL
);
...
...
@@ -646,20 +675,20 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
*/
/* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
mmio_clrbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
dbg1
,
DDRCTRL_DBG1_DIS_HIF
);
VERBOSE
(
"[0x%x] dbg1 = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
dbg1
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
dbg1
));
mmio_clrbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dbg1
,
DDRCTRL_DBG1_DIS_HIF
);
VERBOSE
(
"[0x%
l
x] dbg1 = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
dbg1
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dbg1
));
}
static
void
stm32mp1_refresh_disable
(
struct
stm32mp1_ddrctl
*
ctl
)
{
stm32mp1_start_sw_done
(
ctl
);
/* Quasi-dynamic register update*/
mmio_setbits_32
((
uint
32
_t
)
&
ctl
->
rfshctl3
,
mmio_setbits_32
((
uint
ptr
_t
)
&
ctl
->
rfshctl3
,
DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH
);
mmio_clrbits_32
((
uint
32
_t
)
&
ctl
->
pwrctl
,
DDRCTRL_PWRCTL_POWERDOWN_EN
);
mmio_clrbits_32
((
uint
32
_t
)
&
ctl
->
dfimisc
,
mmio_clrbits_32
((
uint
ptr
_t
)
&
ctl
->
pwrctl
,
DDRCTRL_PWRCTL_POWERDOWN_EN
);
mmio_clrbits_32
((
uint
ptr
_t
)
&
ctl
->
dfimisc
,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN
);
stm32mp1_wait_sw_done_ack
(
ctl
);
}
...
...
@@ -669,14 +698,14 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
{
stm32mp1_start_sw_done
(
ctl
);
if
((
rfshctl3
&
DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH
)
==
0U
)
{
mmio_clrbits_32
((
uint
32
_t
)
&
ctl
->
rfshctl3
,
mmio_clrbits_32
((
uint
ptr
_t
)
&
ctl
->
rfshctl3
,
DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH
);
}
if
((
pwrctl
&
DDRCTRL_PWRCTL_POWERDOWN_EN
)
!=
0U
)
{
mmio_setbits_32
((
uint
32
_t
)
&
ctl
->
pwrctl
,
mmio_setbits_32
((
uint
ptr
_t
)
&
ctl
->
pwrctl
,
DDRCTRL_PWRCTL_POWERDOWN_EN
);
}
mmio_setbits_32
((
uint
32
_t
)
&
ctl
->
dfimisc
,
mmio_setbits_32
((
uint
ptr
_t
)
&
ctl
->
dfimisc
,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN
);
stm32mp1_wait_sw_done_ack
(
ctl
);
}
...
...
@@ -694,12 +723,14 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
struct
stm32mp1_ddr_config
*
config
)
{
uint32_t
pir
;
int
ret
;
int
ret
=
-
EINVAL
;
if
((
config
->
c_reg
.
mstr
&
DDRCTRL_MSTR_DDR3
)
!=
0U
)
{
ret
=
board_ddr_power_init
(
STM32MP_DDR3
);
}
else
{
}
else
if
((
config
->
c_reg
.
mstr
&
DDRCTRL_MSTR_LPDDR2
)
!=
0U
)
{
ret
=
board_ddr_power_init
(
STM32MP_LPDDR2
);
}
else
{
ERROR
(
"DDR type not supported
\n
"
);
}
if
(
ret
!=
0
)
{
...
...
@@ -707,7 +738,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
}
VERBOSE
(
"name = %s
\n
"
,
config
->
info
.
name
);
VERBOSE
(
"speed = %d
M
Hz
\n
"
,
config
->
info
.
speed
);
VERBOSE
(
"speed = %d
k
Hz
\n
"
,
config
->
info
.
speed
);
VERBOSE
(
"size = 0x%x
\n
"
,
config
->
info
.
size
);
/* DDR INIT SEQUENCE */
...
...
@@ -746,11 +777,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
/* 1.5. initialize registers ddr_umctl2 */
/* Stop uMCTL2 before PHY is ready */
mmio_clrbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
dfimisc
,
mmio_clrbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dfimisc
,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN
);
VERBOSE
(
"[0x%x] dfimisc = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
dfimisc
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
dfimisc
));
VERBOSE
(
"[0x%
l
x] dfimisc = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
dfimisc
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dfimisc
));
set_reg
(
priv
,
REG_REG
,
&
config
->
c_reg
);
...
...
@@ -759,23 +790,23 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
(
DDRCTRL_MSTR_DDR3
|
DDRCTRL_MSTR_DLL_OFF_MODE
))
==
(
DDRCTRL_MSTR_DDR3
|
DDRCTRL_MSTR_DLL_OFF_MODE
))
{
VERBOSE
(
"deactivate DLL OFF in mstr
\n
"
);
mmio_clrbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
mstr
,
mmio_clrbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mstr
,
DDRCTRL_MSTR_DLL_OFF_MODE
);
VERBOSE
(
"[0x%x] mstr = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
mstr
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
mstr
));
VERBOSE
(
"[0x%
l
x] mstr = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
mstr
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
mstr
));
}
set_reg
(
priv
,
REG_TIMING
,
&
config
->
c_timing
);
set_reg
(
priv
,
REG_MAP
,
&
config
->
c_map
);
/* Skip CTRL init, SDRAM init is done by PHY PUBL */
mmio_clrsetbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
init0
,
mmio_clrsetbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
init0
,
DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK
,
DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL
);
VERBOSE
(
"[0x%x] init0 = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
init0
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
init0
));
VERBOSE
(
"[0x%
l
x] init0 = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
init0
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
init0
));
set_reg
(
priv
,
REG_PERF
,
&
config
->
c_perf
);
...
...
@@ -797,10 +828,10 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
(
DDRCTRL_MSTR_DDR3
|
DDRCTRL_MSTR_DLL_OFF_MODE
))
==
(
DDRCTRL_MSTR_DDR3
|
DDRCTRL_MSTR_DLL_OFF_MODE
))
{
VERBOSE
(
"deactivate DLL OFF in mr1
\n
"
);
mmio_clrbits_32
((
uint
32
_t
)
&
priv
->
phy
->
mr1
,
BIT
(
0
));
VERBOSE
(
"[0x%x] mr1 = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
phy
->
mr1
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
phy
->
mr1
));
mmio_clrbits_32
((
uint
ptr
_t
)
&
priv
->
phy
->
mr1
,
BIT
(
0
));
VERBOSE
(
"[0x%
l
x] mr1 = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
phy
->
mr1
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
phy
->
mr1
));
}
/*
...
...
@@ -830,11 +861,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
*/
stm32mp1_start_sw_done
(
priv
->
ctl
);
mmio_setbits_32
((
uint
32
_t
)
&
priv
->
ctl
->
dfimisc
,
mmio_setbits_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dfimisc
,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN
);
VERBOSE
(
"[0x%x] dfimisc = 0x%x
\n
"
,
(
uint
32
_t
)
&
priv
->
ctl
->
dfimisc
,
mmio_read_32
((
uint
32
_t
)
&
priv
->
ctl
->
dfimisc
));
VERBOSE
(
"[0x%
l
x] dfimisc = 0x%x
\n
"
,
(
uint
ptr
_t
)
&
priv
->
ctl
->
dfimisc
,
mmio_read_32
((
uint
ptr
_t
)
&
priv
->
ctl
->
dfimisc
));
stm32mp1_wait_sw_done_ack
(
priv
->
ctl
);
...
...
@@ -884,14 +915,16 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
config
->
c_reg
.
pwrctl
);
/* Enable uMCTL2 AXI port 0 */
mmio_setbits_32
((
uint32_t
)
&
priv
->
ctl
->
pctrl_0
,
DDRCTRL_PCTRL_N_PORT_EN
);
VERBOSE
(
"[0x%x] pctrl_0 = 0x%x
\n
"
,
(
uint32_t
)
&
priv
->
ctl
->
pctrl_0
,
mmio_read_32
((
uint32_t
)
&
priv
->
ctl
->
pctrl_0
));
mmio_setbits_32
((
uintptr_t
)
&
priv
->
ctl
->
pctrl_0
,
DDRCTRL_PCTRL_N_PORT_EN
);
VERBOSE
(
"[0x%lx] pctrl_0 = 0x%x
\n
"
,
(
uintptr_t
)
&
priv
->
ctl
->
pctrl_0
,
mmio_read_32
((
uintptr_t
)
&
priv
->
ctl
->
pctrl_0
));
/* Enable uMCTL2 AXI port 1 */
mmio_setbits_32
((
uint32_t
)
&
priv
->
ctl
->
pctrl_1
,
DDRCTRL_PCTRL_N_PORT_EN
);
VERBOSE
(
"[0x%x] pctrl_1 = 0x%x
\n
"
,
(
uint32_t
)
&
priv
->
ctl
->
pctrl_1
,
mmio_read_32
((
uint32_t
)
&
priv
->
ctl
->
pctrl_1
));
mmio_setbits_32
((
uintptr_t
)
&
priv
->
ctl
->
pctrl_1
,
DDRCTRL_PCTRL_N_PORT_EN
);
VERBOSE
(
"[0x%lx] pctrl_1 = 0x%x
\n
"
,
(
uintptr_t
)
&
priv
->
ctl
->
pctrl_1
,
mmio_read_32
((
uintptr_t
)
&
priv
->
ctl
->
pctrl_1
));
}
drivers/st/ddr/stm32mp1_ram.c
View file @
fbf35335
/*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
* Copyright (C) 2018
-2019
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
...
...
@@ -25,7 +25,7 @@
static
struct
ddr_info
ddr_priv_data
;
int
stm32mp1_ddr_clk_enable
(
struct
ddr_info
*
priv
,
uint
16
_t
mem_speed
)
int
stm32mp1_ddr_clk_enable
(
struct
ddr_info
*
priv
,
uint
32
_t
mem_speed
)
{
unsigned
long
ddrphy_clk
,
ddr_clk
,
mem_speed_hz
;
...
...
@@ -33,10 +33,10 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
ddrphy_clk
=
stm32mp1_clk_get_rate
(
DDRPHYC
);
VERBOSE
(
"DDR: mem_speed (%d
M
Hz), RCC %ld
M
Hz
\n
"
,
mem_speed
,
ddrphy_clk
/
1000U
/
1000U
);
VERBOSE
(
"DDR: mem_speed (%d
k
Hz), RCC %ld
k
Hz
\n
"
,
mem_speed
,
ddrphy_clk
/
1000U
);
mem_speed_hz
=
(
uint32_t
)
mem_speed
*
1000U
*
1000U
;
mem_speed_hz
=
mem_speed
*
1000U
;
/* Max 10% frequency delta */
if
(
ddrphy_clk
>
mem_speed_hz
)
{
...
...
@@ -44,9 +44,9 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
}
else
{
ddr_clk
=
mem_speed_hz
-
ddrphy_clk
;
}
if
(
ddr_clk
>
mem_speed_hz
)
{
ERROR
(
"DDR expected freq %d
M
Hz, current is %ld
M
Hz
\n
"
,
mem_speed
,
ddrphy_clk
/
1000U
/
1000U
);
if
(
ddr_clk
>
(
mem_speed_hz
/
10
)
)
{
ERROR
(
"DDR expected freq %d
k
Hz, current is %ld
k
Hz
\n
"
,
mem_speed
,
ddrphy_clk
/
1000U
);
return
-
1
;
}
return
0
;
...
...
@@ -208,11 +208,16 @@ static int stm32mp1_ddr_setup(void)
return
-
EINVAL
;
}
config
.
info
.
speed
=
(
uint16_t
)
fdt_read_uint32_default
(
node
,
"st,mem-speed"
,
STM32MP1_DDR_SPEED_DFLT
);
config
.
info
.
size
=
fdt_read_uint32_default
(
node
,
"st,mem-size"
,
STM32MP1_DDR_SIZE_DFLT
);
config
.
info
.
speed
=
fdt_read_uint32_default
(
node
,
"st,mem-speed"
,
0
);
if
(
!
config
.
info
.
speed
)
{
VERBOSE
(
"%s: no st,mem-speed
\n
"
,
__func__
);
return
-
EINVAL
;
}
config
.
info
.
size
=
fdt_read_uint32_default
(
node
,
"st,mem-size"
,
0
);
if
(
!
config
.
info
.
size
)
{
VERBOSE
(
"%s: no st,mem-size
\n
"
,
__func__
);
return
-
EINVAL
;
}
config
.
info
.
name
=
fdt_getprop
(
fdt
,
node
,
"st,mem-name"
,
&
len
);
if
(
config
.
info
.
name
==
NULL
)
{
VERBOSE
(
"%s: no st,mem-name
\n
"
,
__func__
);
...
...
@@ -222,7 +227,7 @@ static int stm32mp1_ddr_setup(void)
for
(
idx
=
0
;
idx
<
ARRAY_SIZE
(
param
);
idx
++
)
{
ret
=
fdt_read_uint32_array
(
node
,
param
[
idx
].
name
,
(
void
*
)((
uint
32
_t
)
&
config
+
(
void
*
)((
uint
ptr
_t
)
&
config
+
param
[
idx
].
offset
),
param
[
idx
].
size
);
...
...
@@ -261,8 +266,8 @@ static int stm32mp1_ddr_setup(void)
VERBOSE
(
"%s : ram size(%x, %x)
\n
"
,
__func__
,
(
uint32_t
)
priv
->
info
.
base
,
(
uint32_t
)
priv
->
info
.
size
);
dcsw_op_all
(
DC_OP_CISW
);
write_sctlr
(
read_sctlr
()
&
~
SCTLR_C_BIT
);
dcsw_op_all
(
DC_OP_CISW
);
uret
=
ddr_test_data_bus
();
if
(
uret
!=
0U
)
{
...
...
drivers/st/gpio/stm32_gpio.c
View file @
fbf35335
/*
* Copyright (c) 2016-201
8
, STMicroelectronics - All Rights Reserved
* Copyright (c) 2016-201
9
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <libfdt.h>
#include <platform_def.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_clkfunc.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>
#define DT_GPIO_BANK_SHIFT 12
#define DT_GPIO_BANK_MASK GENMASK(16, 12)
#define DT_GPIO_PIN_SHIFT 8
#define DT_GPIO_PIN_MASK GENMASK(11, 8)
#define DT_GPIO_MODE_MASK GENMASK(7, 0)
static
bool
check_gpio
(
uint32_t
bank
,
uint32_t
pin
)
/*******************************************************************************
* This function gets GPIO bank node in DT.
* Returns node offset if status is okay in DT, else return 0
******************************************************************************/
static
int
ckeck_gpio_bank
(
void
*
fdt
,
uint32_t
bank
,
int
pinctrl_node
)
{
if
(
pin
>
GPIO_PIN_MAX
)
{
ERROR
(
"%s: wrong pin number (%d)
\n
"
,
__func__
,
pin
);
return
false
;
int
pinctrl_subnode
;
uint32_t
bank_offset
=
stm32_get_gpio_bank_offset
(
bank
);
fdt_for_each_subnode
(
pinctrl_subnode
,
fdt
,
pinctrl_node
)
{
const
fdt32_t
*
cuint
;
if
(
fdt_getprop
(
fdt
,
pinctrl_subnode
,
"gpio-controller"
,
NULL
)
==
NULL
)
{
continue
;
}
if
((
bank
>
GPIO_BANK_K
)
&&
(
bank
!=
GPIO_BANK_Z
))
{
ERROR
(
"%s: wrong GPIO bank number (%d)
\n
"
,
__func__
,
bank
);
return
fals
e
;
cuint
=
fdt_getprop
(
fdt
,
pinctrl_subnode
,
"reg"
,
NULL
);
if
(
cuint
==
NULL
)
{
continu
e
;
}
return
true
;
if
((
fdt32_to_cpu
(
*
cuint
)
==
bank_offset
)
&&
(
fdt_get_status
(
pinctrl_subnode
)
!=
DT_DISABLED
))
{
return
pinctrl_subnode
;
}
}
return
0
;
}
void
set_gpio
(
uint32_t
bank
,
uint32_t
pin
,
uint32_t
mode
,
uint32_t
speed
,
uint32_t
pull
,
uint32_t
alternate
)
/*******************************************************************************
* This function gets the pin settings from DT information.
* When analyze and parsing is done, set the GPIO registers.
* Returns 0 on success and a negative FDT error code on failure.
******************************************************************************/
static
int
dt_set_gpio_config
(
void
*
fdt
,
int
node
,
uint8_t
status
)
{
volatile
uint32_t
bank_address
;
const
fdt32_t
*
cuint
,
*
slewrate
;
int
len
;
int
pinctrl_node
;
uint32_t
i
;
uint32_t
speed
=
GPIO_SPEED_LOW
;
uint32_t
pull
=
GPIO_NO_PULL
;
if
(
!
check_gpio
(
bank
,
pin
))
{
return
;
cuint
=
fdt_getprop
(
fdt
,
node
,
"pinmux"
,
&
len
);
if
(
cuint
==
NULL
)
{
return
-
FDT_ERR_NOTFOUND
;
}
if
(
bank
==
GPIO_BANK_Z
)
{
bank_address
=
STM32_GPIOZ_BANK
;
pinctrl_node
=
fdt_parent_offset
(
fdt
,
fdt_parent_offset
(
fdt
,
node
));
if
(
pinctrl_node
<
0
)
{
return
-
FDT_ERR_NOTFOUND
;
}
slewrate
=
fdt_getprop
(
fdt
,
node
,
"slew-rate"
,
NULL
);
if
(
slewrate
!=
NULL
)
{
speed
=
fdt32_to_cpu
(
*
slewrate
);
}
if
(
fdt_getprop
(
fdt
,
node
,
"bias-pull-up"
,
NULL
)
!=
NULL
)
{
pull
=
GPIO_PULL_UP
;
}
else
if
(
fdt_getprop
(
fdt
,
node
,
"bias-pull-down"
,
NULL
)
!=
NULL
)
{
pull
=
GPIO_PULL_DOWN
;
}
else
{
bank_address
=
STM32_GPIOA_BANK
+
(
bank
*
STM32_GPIO_BANK_OFFSET
);
VERBOSE
(
"No bias configured in node %d
\n
"
,
node
);
}
for
(
i
=
0U
;
i
<
((
uint32_t
)
len
/
sizeof
(
uint32_t
));
i
++
)
{
uint32_t
pincfg
;
uint32_t
bank
;
uint32_t
pin
;
uint32_t
mode
;
uint32_t
alternate
=
GPIO_ALTERNATE_
(
0
);
int
bank_node
;
int
clk
;
pincfg
=
fdt32_to_cpu
(
*
cuint
);
cuint
++
;
bank
=
(
pincfg
&
DT_GPIO_BANK_MASK
)
>>
DT_GPIO_BANK_SHIFT
;
pin
=
(
pincfg
&
DT_GPIO_PIN_MASK
)
>>
DT_GPIO_PIN_SHIFT
;
mode
=
pincfg
&
DT_GPIO_MODE_MASK
;
switch
(
mode
)
{
case
0
:
mode
=
GPIO_MODE_INPUT
;
break
;
case
1
...
16
:
alternate
=
mode
-
1U
;
mode
=
GPIO_MODE_ALTERNATE
;
break
;
case
17
:
mode
=
GPIO_MODE_ANALOG
;
break
;
default:
mode
=
GPIO_MODE_OUTPUT
;
break
;
}
if
(
fdt_getprop
(
fdt
,
node
,
"drive-open-drain"
,
NULL
)
!=
NULL
)
{
mode
|=
GPIO_OPEN_DRAIN
;
}
bank_node
=
ckeck_gpio_bank
(
fdt
,
bank
,
pinctrl_node
);
if
(
bank_node
==
0
)
{
ERROR
(
"PINCTRL inconsistent in DT
\n
"
);
panic
();
}
clk
=
fdt_get_clock_id
(
bank_node
);
if
(
clk
<
0
)
{
return
-
FDT_ERR_NOTFOUND
;
}
/* Platform knows the clock: assert it is okay */
assert
((
unsigned
long
)
clk
==
stm32_get_gpio_bank_clock
(
bank
));
set_gpio
(
bank
,
pin
,
mode
,
speed
,
pull
,
alternate
,
status
);
}
return
0
;
}
/*******************************************************************************
* This function gets the pin settings from DT information.
* When analyze and parsing is done, set the GPIO registers.
* Returns 0 on success and a negative FDT/ERRNO error code on failure.
******************************************************************************/
int
dt_set_pinctrl_config
(
int
node
)
{
const
fdt32_t
*
cuint
;
int
lenp
=
0
;
uint32_t
i
;
uint8_t
status
=
fdt_get_status
(
node
);
void
*
fdt
;
if
(
fdt_get_address
(
&
fdt
)
==
0
)
{
return
-
ENOENT
;
}
if
(
status
==
DT_DISABLED
)
{
return
-
FDT_ERR_NOTFOUND
;
}
cuint
=
fdt_getprop
(
fdt
,
node
,
"pinctrl-0"
,
&
lenp
);
if
(
cuint
==
NULL
)
{
return
-
FDT_ERR_NOTFOUND
;
}
for
(
i
=
0
;
i
<
((
uint32_t
)
lenp
/
4U
);
i
++
)
{
int
p_node
,
p_subnode
;
p_node
=
fdt_node_offset_by_phandle
(
fdt
,
fdt32_to_cpu
(
*
cuint
));
if
(
p_node
<
0
)
{
return
-
FDT_ERR_NOTFOUND
;
}
mmio_clrbits_32
(
bank_address
+
GPIO_MODE_OFFSET
,
fdt_for_each_subnode
(
p_subnode
,
fdt
,
p_node
)
{
int
ret
=
dt_set_gpio_config
(
fdt
,
p_subnode
,
status
);
if
(
ret
<
0
)
{
return
ret
;
}
}
cuint
++
;
}
return
0
;
}
void
set_gpio
(
uint32_t
bank
,
uint32_t
pin
,
uint32_t
mode
,
uint32_t
speed
,
uint32_t
pull
,
uint32_t
alternate
,
uint8_t
status
)
{
uintptr_t
base
=
stm32_get_gpio_bank_base
(
bank
);
unsigned
long
clock
=
stm32_get_gpio_bank_clock
(
bank
);
assert
(
pin
<=
GPIO_PIN_MAX
);
stm32mp1_clk_enable
(
clock
);
mmio_clrbits_32
(
base
+
GPIO_MODE_OFFSET
,
((
uint32_t
)
GPIO_MODE_MASK
<<
(
pin
<<
1
)));
mmio_setbits_32
(
ba
nk_addres
s
+
GPIO_MODE_OFFSET
,
mmio_setbits_32
(
bas
e
+
GPIO_MODE_OFFSET
,
(
mode
&
~
GPIO_OPEN_DRAIN
)
<<
(
pin
<<
1
));
if
((
mode
&
GPIO_OPEN_DRAIN
)
!=
0U
)
{
mmio_setbits_32
(
bank_address
+
GPIO_TYPE_OFFSET
,
BIT
(
pin
));
mmio_setbits_32
(
base
+
GPIO_TYPE_OFFSET
,
BIT
(
pin
));
}
else
{
mmio_clrbits_32
(
base
+
GPIO_TYPE_OFFSET
,
BIT
(
pin
));
}
mmio_clrbits_32
(
ba
nk_addres
s
+
GPIO_SPEED_OFFSET
,
mmio_clrbits_32
(
bas
e
+
GPIO_SPEED_OFFSET
,
((
uint32_t
)
GPIO_SPEED_MASK
<<
(
pin
<<
1
)));
mmio_setbits_32
(
ba
nk_addres
s
+
GPIO_SPEED_OFFSET
,
speed
<<
(
pin
<<
1
));
mmio_setbits_32
(
bas
e
+
GPIO_SPEED_OFFSET
,
speed
<<
(
pin
<<
1
));
mmio_clrbits_32
(
ba
nk_addres
s
+
GPIO_PUPD_OFFSET
,
mmio_clrbits_32
(
bas
e
+
GPIO_PUPD_OFFSET
,
((
uint32_t
)
GPIO_PULL_MASK
<<
(
pin
<<
1
)));
mmio_setbits_32
(
ba
nk_addres
s
+
GPIO_PUPD_OFFSET
,
pull
<<
(
pin
<<
1
));
mmio_setbits_32
(
bas
e
+
GPIO_PUPD_OFFSET
,
pull
<<
(
pin
<<
1
));
if
(
pin
<
GPIO_ALT_LOWER_LIMIT
)
{
mmio_clrbits_32
(
ba
nk_addres
s
+
GPIO_AFRL_OFFSET
,
mmio_clrbits_32
(
bas
e
+
GPIO_AFRL_OFFSET
,
((
uint32_t
)
GPIO_ALTERNATE_MASK
<<
(
pin
<<
2
)));
mmio_setbits_32
(
ba
nk_addres
s
+
GPIO_AFRL_OFFSET
,
mmio_setbits_32
(
bas
e
+
GPIO_AFRL_OFFSET
,
alternate
<<
(
pin
<<
2
));
}
else
{
mmio_clrbits_32
(
ba
nk_addres
s
+
GPIO_AFRH_OFFSET
,
mmio_clrbits_32
(
bas
e
+
GPIO_AFRH_OFFSET
,
((
uint32_t
)
GPIO_ALTERNATE_MASK
<<
((
pin
-
GPIO_ALT_LOWER_LIMIT
)
<<
2
)));
mmio_setbits_32
(
ba
nk_addres
s
+
GPIO_AFRH_OFFSET
,
mmio_setbits_32
(
bas
e
+
GPIO_AFRH_OFFSET
,
alternate
<<
((
pin
-
GPIO_ALT_LOWER_LIMIT
)
<<
2
));
}
VERBOSE
(
"GPIO %u mode set to 0x%x
\n
"
,
bank
,
mmio_read_32
(
ba
nk_addres
s
+
GPIO_MODE_OFFSET
));
mmio_read_32
(
bas
e
+
GPIO_MODE_OFFSET
));
VERBOSE
(
"GPIO %u speed set to 0x%x
\n
"
,
bank
,
mmio_read_32
(
ba
nk_addres
s
+
GPIO_SPEED_OFFSET
));
mmio_read_32
(
bas
e
+
GPIO_SPEED_OFFSET
));
VERBOSE
(
"GPIO %u mode pull to 0x%x
\n
"
,
bank
,
mmio_read_32
(
ba
nk_addres
s
+
GPIO_PUPD_OFFSET
));
mmio_read_32
(
bas
e
+
GPIO_PUPD_OFFSET
));
VERBOSE
(
"GPIO %u mode alternate low to 0x%x
\n
"
,
bank
,
mmio_read_32
(
ba
nk_addres
s
+
GPIO_AFRL_OFFSET
));
mmio_read_32
(
bas
e
+
GPIO_AFRL_OFFSET
));
VERBOSE
(
"GPIO %u mode alternate high to 0x%x
\n
"
,
bank
,
mmio_read_32
(
bank_address
+
GPIO_AFRH_OFFSET
));
mmio_read_32
(
base
+
GPIO_AFRH_OFFSET
));
stm32mp1_clk_disable
((
unsigned
long
)
clock
);
}
void
set_gpio_secure_cfg
(
uint32_t
bank
,
uint32_t
pin
,
bool
secure
)
{
uintptr_t
base
=
stm32_get_gpio_bank_base
(
bank
);
int
clock
=
stm32_get_gpio_bank_clock
(
bank
);
assert
(
pin
<=
GPIO_PIN_MAX
);
stm32mp1_clk_enable
((
unsigned
long
)
clock
);
if
(
secure
)
{
mmio_setbits_32
(
base
+
GPIO_SECR_OFFSET
,
BIT
(
pin
));
}
else
{
mmio_clrbits_32
(
base
+
GPIO_SECR_OFFSET
,
BIT
(
pin
));
}
stm32mp1_clk_disable
((
unsigned
long
)
clock
);
}
drivers/st/
pm
ic/stm32_i2c.c
→
drivers/st/i
2
c/stm32_i2c.c
View file @
fbf35335
/*
* Copyright (c) 2016-201
8
, STMicroelectronics - All Rights Reserved
* Copyright (c) 2016-201
9
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
drivers/st/io/io_stm32image.c
View file @
fbf35335
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018
-2019
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -94,6 +94,8 @@ static int stm32image_dev_open(const uintptr_t init_params,
for
(
i
=
0
;
i
<
STM32_PART_NUM
;
i
++
)
{
memcpy
(
stm32image_dev
.
part_info
[
i
].
name
,
device_info
->
part_info
[
i
].
name
,
MAX_PART_NAME_SIZE
);
stm32image_dev
.
part_info
[
i
].
binary_type
=
device_info
->
part_info
[
i
].
binary_type
;
stm32image_dev
.
part_info
[
i
].
part_offset
=
device_info
->
part_info
[
i
].
part_offset
;
stm32image_dev
.
part_info
[
i
].
bkp_offset
=
...
...
@@ -193,21 +195,29 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length)
result
=
io_read
(
backend_handle
,
(
uintptr_t
)
header
,
MAX_LBA_SIZE
,
(
size_t
*
)
&
bytes_read
);
if
(
result
!=
0
)
{
if
(
current_part
->
bkp_offset
==
0U
)
{
ERROR
(
"%s: io_read (%i)
\n
"
,
__func__
,
result
);
break
;
}
header
->
magic
=
0
;
}
if
((
header
->
magic
!=
BOOT_API_IMAGE_HEADER_MAGIC_NB
)
||
(
header
->
binary_type
!=
current_part
->
binary_type
)
||
(
header
->
image_length
>=
stm32image_dev
.
device_size
))
{
WARN
(
"%s: partition %s wrong header
\n
"
,
__func__
,
current_part
->
name
);
VERBOSE
(
"%s: partition %s not found at %x
\n
"
,
__func__
,
current_part
->
name
,
*
stm32_img
);
if
(
current_part
->
bkp_offset
==
0U
)
{
result
=
-
ENOMEM
;
break
;
}
/* Header not correct, check next offset for backup */
*
stm32_img
+=
current_part
->
bkp_offset
;
if
(
*
stm32_img
>
stm32image_dev
.
device_size
)
{
/* No backup found, end of device reached */
WARN
(
"Out of memory
\n
"
);
WARN
(
"%s : partition %s not found
\n
"
,
__func__
,
current_part
->
name
);
result
=
-
ENOMEM
;
break
;
}
...
...
@@ -221,9 +231,13 @@ static int stm32image_partition_size(io_entity_t *entity, size_t *length)
return
result
;
}
if
(
header
->
image_length
<
stm32image_dev
.
lba_size
)
{
*
length
=
stm32image_dev
.
lba_size
;
}
else
{
*
length
=
header
->
image_length
;
}
INFO
(
"STM32 Image size : %
i
\n
"
,
*
length
);
INFO
(
"STM32 Image size : %
lu
\n
"
,
(
unsigned
long
)
*
length
);
return
0
;
}
...
...
@@ -266,11 +280,10 @@ static int check_header(boot_api_image_header_t *header, uintptr_t buffer)
static
int
stm32image_partition_read
(
io_entity_t
*
entity
,
uintptr_t
buffer
,
size_t
length
,
size_t
*
length_read
)
{
int
result
=
0
,
offset
,
local_length
=
0
;
int
result
=
0
;
uint8_t
*
local_buffer
=
(
uint8_t
*
)
buffer
;
boot_api_image_header_t
*
header
=
(
boot_api_image_header_t
*
)
first_lba_buffer
;
uintptr_t
backend_handle
;
assert
(
entity
!=
NULL
);
assert
(
buffer
!=
0U
);
...
...
@@ -279,8 +292,17 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
*
length_read
=
0U
;
while
(
*
length_read
==
0U
)
{
int
offset
;
int
local_length
;
uintptr_t
backend_handle
;
if
(
header
->
magic
!=
BOOT_API_IMAGE_HEADER_MAGIC_NB
)
{
/* Check for backup as image is corrupted */
if
(
current_part
->
bkp_offset
==
0U
)
{
result
=
-
ENOMEM
;
break
;
}
*
stm32_img
+=
current_part
->
bkp_offset
;
if
(
*
stm32_img
>=
stm32image_dev
.
device_size
)
{
/* End of device reached */
...
...
@@ -342,8 +364,8 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
if
(
result
!=
0
)
{
ERROR
(
"%s: io_read (%i)
\n
"
,
__func__
,
result
);
*
length_read
=
0
;
io_close
(
backend_handle
)
;
break
;
header
->
magic
=
0
;
continue
;
}
result
=
check_header
(
header
,
buffer
);
...
...
@@ -351,8 +373,6 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
ERROR
(
"Header check failed
\n
"
);
*
length_read
=
0
;
header
->
magic
=
0
;
io_close
(
backend_handle
);
break
;
}
io_close
(
backend_handle
);
...
...
drivers/st/mmc/stm32_sdmmc2.c
View file @
fbf35335
/*
* Copyright (c) 2018, STMicroelectronics - All Rights Reserved
* Copyright (c) 2018
-2019
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -17,6 +17,7 @@
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/mmc.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32_sdmmc2.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_rcc.h>
...
...
@@ -470,12 +471,11 @@ static int stm32_sdmmc2_prepare(int lba, uintptr_t buf, size_t size)
}
/* Prepare CMD 16*/
mmio_write_32
(
base
+
SDMMC_DTIMER
,
UINT32_MAX
);
mmio_write_32
(
base
+
SDMMC_DTIMER
,
0
);
mmio_write_32
(
base
+
SDMMC_DLENR
,
0
);
mmio_clrsetbits_32
(
base
+
SDMMC_DCTRLR
,
SDMMC_DCTRLR_CLEAR_MASK
,
SDMMC_DCTRLR_DTDIR
);
mmio_write_32
(
base
+
SDMMC_DCTRLR
,
0
);
zeromem
(
&
cmd
,
sizeof
(
struct
mmc_cmd
));
...
...
@@ -643,7 +643,7 @@ static int stm32_sdmmc2_dt_get_config(void)
return
-
FDT_ERR_NOTFOUND
;
}
if
(
fdt_
check
_status
(
sdmmc_node
)
==
0
)
{
if
(
fdt_
get
_status
(
sdmmc_node
)
==
DT_DISABLED
)
{
return
-
FDT_ERR_NOTFOUND
;
}
...
...
@@ -667,15 +667,15 @@ static int stm32_sdmmc2_dt_get_config(void)
cuint
++
;
sdmmc2_params
.
reset_id
=
fdt32_to_cpu
(
*
cuint
);
if
((
fdt_getprop
(
fdt
,
sdmmc_node
,
"st,
pin
-ckin"
,
NULL
))
!=
NULL
)
{
if
((
fdt_getprop
(
fdt
,
sdmmc_node
,
"st,
use
-ckin"
,
NULL
))
!=
NULL
)
{
sdmmc2_params
.
pin_ckin
=
SDMMC_CLKCR_SELCLKRX_0
;
}
if
((
fdt_getprop
(
fdt
,
sdmmc_node
,
"st,dir
pol
"
,
NULL
))
!=
NULL
)
{
if
((
fdt_getprop
(
fdt
,
sdmmc_node
,
"st,
sig-
dir"
,
NULL
))
!=
NULL
)
{
sdmmc2_params
.
dirpol
=
SDMMC_POWER_DIRPOL
;
}
if
((
fdt_getprop
(
fdt
,
sdmmc_node
,
"st,negedge"
,
NULL
))
!=
NULL
)
{
if
((
fdt_getprop
(
fdt
,
sdmmc_node
,
"st,neg
-
edge"
,
NULL
))
!=
NULL
)
{
sdmmc2_params
.
negedge
=
SDMMC_CLKCR_NEGEDGE
;
}
...
...
drivers/st/pmic/stm32mp
1
_pmic.c
→
drivers/st/pmic/stm32mp_pmic.c
View file @
fbf35335
/*
* Copyright (c) 2017-201
8
, STMicroelectronics - All Rights Reserved
* Copyright (c) 2017-201
9
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -13,10 +13,10 @@
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_pmic.h>
#include <drivers/st/stpmu1.h>
#include <drivers/st/stpmic1.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>
...
...
@@ -27,23 +27,23 @@
#define MASK_RESET_BUCK3 BIT(2)
#define STPM
U
1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2))
#define STPM
U
1_LDO12356_OUTPUT_SHIFT 2
#define STPM
U
1_LDO3_MODE (uint8_t)(BIT(7))
#define STPM
U
1_LDO3_DDR_SEL 31U
#define STPM
U
1_LDO3_1800000 (9U << STPM
U
1_LDO12356_OUTPUT_SHIFT)
#define STPM
IC
1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2))
#define STPM
IC
1_LDO12356_OUTPUT_SHIFT 2
#define STPM
IC
1_LDO3_MODE (uint8_t)(BIT(7))
#define STPM
IC
1_LDO3_DDR_SEL 31U
#define STPM
IC
1_LDO3_1800000 (9U << STPM
IC
1_LDO12356_OUTPUT_SHIFT)
#define STPM
U
1_BUCK_OUTPUT_SHIFT 2
#define STPM
U
1_BUCK3_1V8 (39U << STPM
U
1_BUCK_OUTPUT_SHIFT)
#define STPM
IC
1_BUCK_OUTPUT_SHIFT 2
#define STPM
IC
1_BUCK3_1V8 (39U << STPM
IC
1_BUCK_OUTPUT_SHIFT)
#define STPM
U
1_DEFAULT_START_UP_DELAY_MS 1
#define STPM
IC
1_DEFAULT_START_UP_DELAY_MS 1
static
struct
i2c_handle_s
i2c_handle
;
static
uint32_t
pmic_i2c_addr
;
static
int
dt_get_pmic_node
(
void
*
fdt
)
{
return
fdt_node_offset_by_compatible
(
fdt
,
-
1
,
"st,stpm
u
1"
);
return
fdt_node_offset_by_compatible
(
fdt
,
-
1
,
"st,stpm
ic
1"
);
}
bool
dt_check_pmic
(
void
)
...
...
@@ -61,7 +61,7 @@ bool dt_check_pmic(void)
return
false
;
}
return
fdt_
check
_status
(
node
);
return
fdt_
get
_status
(
node
);
}
static
int
dt_pmic_i2c_config
(
struct
dt_node_info
*
i2c_info
)
...
...
@@ -138,16 +138,16 @@ int dt_pmic_enable_boot_on_regulators(void)
voltage
=
(
uint16_t
)(
fdt32_to_cpu
(
*
cuint
)
/
1000U
);
node_name
=
fdt_get_name
(
fdt
,
regulator_node
,
NULL
);
if
(
stpm
u
1_is_regulator_enabled
(
node_name
)
==
0U
)
{
if
(
stpm
ic
1_is_regulator_enabled
(
node_name
)
==
0U
)
{
int
status
;
status
=
stpm
u
1_regulator_voltage_set
(
node_name
,
status
=
stpm
ic
1_regulator_voltage_set
(
node_name
,
voltage
);
if
(
status
!=
0
)
{
return
status
;
}
status
=
stpm
u
1_regulator_enable
(
node_name
);
status
=
stpm
ic
1_regulator_enable
(
node_name
);
if
(
status
!=
0
)
{
return
status
;
}
...
...
@@ -204,7 +204,7 @@ void initialize_pmic_i2c(void)
panic
();
}
stpm
u
1_bind_i2c
(
&
i2c_handle
,
(
uint16_t
)
pmic_i2c_addr
);
stpm
ic
1_bind_i2c
(
&
i2c_handle
,
(
uint16_t
)
pmic_i2c_addr
);
}
void
initialize_pmic
(
void
)
...
...
@@ -214,7 +214,7 @@ void initialize_pmic(void)
initialize_pmic_i2c
();
status
=
stpm
u
1_register_read
(
VERSION_STATUS_REG
,
&
read_val
);
status
=
stpm
ic
1_register_read
(
VERSION_STATUS_REG
,
&
read_val
);
if
(
status
!=
0
)
{
panic
();
}
...
...
@@ -222,7 +222,7 @@ void initialize_pmic(void)
INFO
(
"PMIC version = 0x%x
\n
"
,
read_val
);
/* Keep VDD on during the reset cycle */
status
=
stpm
u
1_register_update
(
MASK_RESET_BUCK_REG
,
status
=
stpm
ic
1_register_update
(
MASK_RESET_BUCK_REG
,
MASK_RESET_BUCK3
,
MASK_RESET_BUCK3
);
if
(
status
!=
0
)
{
...
...
@@ -239,45 +239,46 @@ int pmic_ddr_power_init(enum ddr_type ddr_type)
switch
(
ddr_type
)
{
case
STM32MP_DDR3
:
/* Set LDO3 to sync mode */
status
=
stpm
u
1_register_read
(
LDO3_CONTROL_REG
,
&
read_val
);
status
=
stpm
ic
1_register_read
(
LDO3_CONTROL_REG
,
&
read_val
);
if
(
status
!=
0
)
{
return
status
;
}
read_val
&=
~
STPMU1_LDO3_MODE
;
read_val
&=
~
STPMU1_LDO12356_OUTPUT_MASK
;
read_val
|=
STPMU1_LDO3_DDR_SEL
<<
STPMU1_LDO12356_OUTPUT_SHIFT
;
read_val
&=
~
STPMIC1_LDO3_MODE
;
read_val
&=
~
STPMIC1_LDO12356_OUTPUT_MASK
;
read_val
|=
STPMIC1_LDO3_DDR_SEL
<<
STPMIC1_LDO12356_OUTPUT_SHIFT
;
status
=
stpm
u
1_register_write
(
LDO3_CONTROL_REG
,
read_val
);
status
=
stpm
ic
1_register_write
(
LDO3_CONTROL_REG
,
read_val
);
if
(
status
!=
0
)
{
return
status
;
}
status
=
stpm
u
1_regulator_voltage_set
(
"buck2"
,
1350
);
status
=
stpm
ic
1_regulator_voltage_set
(
"buck2"
,
1350
);
if
(
status
!=
0
)
{
return
status
;
}
status
=
stpm
u
1_regulator_enable
(
"buck2"
);
status
=
stpm
ic
1_regulator_enable
(
"buck2"
);
if
(
status
!=
0
)
{
return
status
;
}
mdelay
(
STPM
U
1_DEFAULT_START_UP_DELAY_MS
);
mdelay
(
STPM
IC
1_DEFAULT_START_UP_DELAY_MS
);
status
=
stpm
u
1_regulator_enable
(
"vref_ddr"
);
status
=
stpm
ic
1_regulator_enable
(
"vref_ddr"
);
if
(
status
!=
0
)
{
return
status
;
}
mdelay
(
STPM
U
1_DEFAULT_START_UP_DELAY_MS
);
mdelay
(
STPM
IC
1_DEFAULT_START_UP_DELAY_MS
);
status
=
stpm
u
1_regulator_enable
(
"ldo3"
);
status
=
stpm
ic
1_regulator_enable
(
"ldo3"
);
if
(
status
!=
0
)
{
return
status
;
}
mdelay
(
STPM
U
1_DEFAULT_START_UP_DELAY_MS
);
mdelay
(
STPM
IC
1_DEFAULT_START_UP_DELAY_MS
);
break
;
case
STM32MP_LPDDR2
:
...
...
@@ -286,57 +287,57 @@ int pmic_ddr_power_init(enum ddr_type ddr_type)
* Set LDO3 to bypass mode if BUCK3 = 1.8V
* Set LDO3 to normal mode if BUCK3 != 1.8V
*/
status
=
stpm
u
1_register_read
(
BUCK3_CONTROL_REG
,
&
read_val
);
status
=
stpm
ic
1_register_read
(
BUCK3_CONTROL_REG
,
&
read_val
);
if
(
status
!=
0
)
{
return
status
;
}
if
((
read_val
&
STPM
U
1_BUCK3_1V8
)
==
STPM
U
1_BUCK3_1V8
)
{
if
((
read_val
&
STPM
IC
1_BUCK3_1V8
)
==
STPM
IC
1_BUCK3_1V8
)
{
buck3_at_1v8
=
true
;
}
status
=
stpm
u
1_register_read
(
LDO3_CONTROL_REG
,
&
read_val
);
status
=
stpm
ic
1_register_read
(
LDO3_CONTROL_REG
,
&
read_val
);
if
(
status
!=
0
)
{
return
status
;
}
read_val
&=
~
STPM
U
1_LDO3_MODE
;
read_val
&=
~
STPM
U
1_LDO12356_OUTPUT_MASK
;
read_val
|=
STPM
U
1_LDO3_1800000
;
read_val
&=
~
STPM
IC
1_LDO3_MODE
;
read_val
&=
~
STPM
IC
1_LDO12356_OUTPUT_MASK
;
read_val
|=
STPM
IC
1_LDO3_1800000
;
if
(
buck3_at_1v8
)
{
read_val
|=
STPM
U
1_LDO3_MODE
;
read_val
|=
STPM
IC
1_LDO3_MODE
;
}
status
=
stpm
u
1_register_write
(
LDO3_CONTROL_REG
,
read_val
);
status
=
stpm
ic
1_register_write
(
LDO3_CONTROL_REG
,
read_val
);
if
(
status
!=
0
)
{
return
status
;
}
status
=
stpm
u
1_regulator_voltage_set
(
"buck2"
,
1200
);
status
=
stpm
ic
1_regulator_voltage_set
(
"buck2"
,
1200
);
if
(
status
!=
0
)
{
return
status
;
}
status
=
stpm
u
1_regulator_enable
(
"ldo3"
);
status
=
stpm
ic
1_regulator_enable
(
"ldo3"
);
if
(
status
!=
0
)
{
return
status
;
}
mdelay
(
STPM
U
1_DEFAULT_START_UP_DELAY_MS
);
mdelay
(
STPM
IC
1_DEFAULT_START_UP_DELAY_MS
);
status
=
stpm
u
1_regulator_enable
(
"buck2"
);
status
=
stpm
ic
1_regulator_enable
(
"buck2"
);
if
(
status
!=
0
)
{
return
status
;
}
mdelay
(
STPM
U
1_DEFAULT_START_UP_DELAY_MS
);
mdelay
(
STPM
IC
1_DEFAULT_START_UP_DELAY_MS
);
status
=
stpm
u
1_regulator_enable
(
"vref_ddr"
);
status
=
stpm
ic
1_regulator_enable
(
"vref_ddr"
);
if
(
status
!=
0
)
{
return
status
;
}
mdelay
(
STPM
U
1_DEFAULT_START_UP_DELAY_MS
);
mdelay
(
STPM
IC
1_DEFAULT_START_UP_DELAY_MS
);
break
;
default:
...
...
drivers/st/pmic/stpm
u
1.c
→
drivers/st/pmic/stpm
ic
1.c
View file @
fbf35335
/*
* Copyright (c) 2016-201
8
, STMicroelectronics - All Rights Reserved
* Copyright (c) 2016-201
9
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -7,7 +7,7 @@
#include <string.h>
#include <common/debug.h>
#include <drivers/st/stpm
u
1.h>
#include <drivers/st/stpm
ic
1.h>
#include <plat/common/platform.h>
struct
regul_struct
{
...
...
@@ -16,18 +16,22 @@ struct regul_struct {
uint8_t
voltage_table_size
;
uint8_t
control_reg
;
uint8_t
low_power_reg
;
uint8_t
pull_down_reg
;
uint8_t
pull_down
;
uint8_t
mask_reset_reg
;
uint8_t
mask_reset
;
};
static
struct
i2c_handle_s
*
stpmu
_i2c_handle
;
static
uint16_t
stpmu
_i2c_addr
;
static
struct
i2c_handle_s
*
pmic
_i2c_handle
;
static
uint16_t
pmic
_i2c_addr
;
/* Voltage tables in mV */
static
const
uint16_t
buck1_voltage_table
[]
=
{
600
,
6
25
,
650
,
6
75
,
7
00
,
725
,
7
25
,
725
,
7
2
5
,
7
25
,
725
,
750
,
775
,
...
...
@@ -54,7 +58,39 @@ static const uint16_t buck1_voltage_table[] = {
1300
,
1325
,
1350
,
1350
,
1375
,
1400
,
1425
,
1450
,
1475
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
1500
,
};
static
const
uint16_t
buck2_voltage_table
[]
=
{
...
...
@@ -308,6 +344,7 @@ static const uint16_t ldo3_voltage_table[] = {
3300
,
3300
,
3300
,
500
,
0xFFFF
,
/* VREFDDR */
};
...
...
@@ -389,6 +426,10 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
buck1_voltage_table
),
.
control_reg
=
BUCK1_CONTROL_REG
,
.
low_power_reg
=
BUCK1_PWRCTRL_REG
,
.
pull_down_reg
=
BUCK_PULL_DOWN_REG
,
.
pull_down
=
BUCK1_PULL_DOWN_SHIFT
,
.
mask_reset_reg
=
MASK_RESET_BUCK_REG
,
.
mask_reset
=
BUCK1_MASK_RESET
,
},
{
.
dt_node_name
=
"buck2"
,
...
...
@@ -396,6 +437,10 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
buck2_voltage_table
),
.
control_reg
=
BUCK2_CONTROL_REG
,
.
low_power_reg
=
BUCK2_PWRCTRL_REG
,
.
pull_down_reg
=
BUCK_PULL_DOWN_REG
,
.
pull_down
=
BUCK2_PULL_DOWN_SHIFT
,
.
mask_reset_reg
=
MASK_RESET_BUCK_REG
,
.
mask_reset
=
BUCK2_MASK_RESET
,
},
{
.
dt_node_name
=
"buck3"
,
...
...
@@ -403,6 +448,10 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
buck3_voltage_table
),
.
control_reg
=
BUCK3_CONTROL_REG
,
.
low_power_reg
=
BUCK3_PWRCTRL_REG
,
.
pull_down_reg
=
BUCK_PULL_DOWN_REG
,
.
pull_down
=
BUCK3_PULL_DOWN_SHIFT
,
.
mask_reset_reg
=
MASK_RESET_BUCK_REG
,
.
mask_reset
=
BUCK3_MASK_RESET
,
},
{
.
dt_node_name
=
"buck4"
,
...
...
@@ -410,6 +459,10 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
buck4_voltage_table
),
.
control_reg
=
BUCK4_CONTROL_REG
,
.
low_power_reg
=
BUCK4_PWRCTRL_REG
,
.
pull_down_reg
=
BUCK_PULL_DOWN_REG
,
.
pull_down
=
BUCK4_PULL_DOWN_SHIFT
,
.
mask_reset_reg
=
MASK_RESET_BUCK_REG
,
.
mask_reset
=
BUCK4_MASK_RESET
,
},
{
.
dt_node_name
=
"ldo1"
,
...
...
@@ -417,6 +470,8 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
ldo1_voltage_table
),
.
control_reg
=
LDO1_CONTROL_REG
,
.
low_power_reg
=
LDO1_PWRCTRL_REG
,
.
mask_reset_reg
=
MASK_RESET_LDO_REG
,
.
mask_reset
=
LDO1_MASK_RESET
,
},
{
.
dt_node_name
=
"ldo2"
,
...
...
@@ -424,6 +479,8 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
ldo2_voltage_table
),
.
control_reg
=
LDO2_CONTROL_REG
,
.
low_power_reg
=
LDO2_PWRCTRL_REG
,
.
mask_reset_reg
=
MASK_RESET_LDO_REG
,
.
mask_reset
=
LDO2_MASK_RESET
,
},
{
.
dt_node_name
=
"ldo3"
,
...
...
@@ -431,6 +488,8 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
ldo3_voltage_table
),
.
control_reg
=
LDO3_CONTROL_REG
,
.
low_power_reg
=
LDO3_PWRCTRL_REG
,
.
mask_reset_reg
=
MASK_RESET_LDO_REG
,
.
mask_reset
=
LDO3_MASK_RESET
,
},
{
.
dt_node_name
=
"ldo4"
,
...
...
@@ -438,6 +497,8 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
ldo4_voltage_table
),
.
control_reg
=
LDO4_CONTROL_REG
,
.
low_power_reg
=
LDO4_PWRCTRL_REG
,
.
mask_reset_reg
=
MASK_RESET_LDO_REG
,
.
mask_reset
=
LDO4_MASK_RESET
,
},
{
.
dt_node_name
=
"ldo5"
,
...
...
@@ -445,6 +506,8 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
ldo5_voltage_table
),
.
control_reg
=
LDO5_CONTROL_REG
,
.
low_power_reg
=
LDO5_PWRCTRL_REG
,
.
mask_reset_reg
=
MASK_RESET_LDO_REG
,
.
mask_reset
=
LDO5_MASK_RESET
,
},
{
.
dt_node_name
=
"ldo6"
,
...
...
@@ -452,6 +515,8 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
ldo6_voltage_table
),
.
control_reg
=
LDO6_CONTROL_REG
,
.
low_power_reg
=
LDO6_PWRCTRL_REG
,
.
mask_reset_reg
=
MASK_RESET_LDO_REG
,
.
mask_reset
=
LDO6_MASK_RESET
,
},
{
.
dt_node_name
=
"vref_ddr"
,
...
...
@@ -459,12 +524,14 @@ static const struct regul_struct regulators_table[] = {
.
voltage_table_size
=
ARRAY_SIZE
(
vref_ddr_voltage_table
),
.
control_reg
=
VREF_DDR_CONTROL_REG
,
.
low_power_reg
=
VREF_DDR_PWRCTRL_REG
,
.
mask_reset_reg
=
MASK_RESET_LDO_REG
,
.
mask_reset
=
VREF_DDR_MASK_RESET
,
},
};
#define MAX_REGUL ARRAY_SIZE(regulators_table)
static
const
struct
regul_struct
*
stpmu1_
get_regulator_data
(
const
char
*
name
)
static
const
struct
regul_struct
*
get_regulator_data
(
const
char
*
name
)
{
uint8_t
i
;
...
...
@@ -480,10 +547,9 @@ static const struct regul_struct *stpmu1_get_regulator_data(const char *name)
return
NULL
;
}
static
uint8_t
stpmu1_voltage_find_index
(
const
char
*
name
,
uint16_t
millivolts
)
static
uint8_t
voltage_to_index
(
const
char
*
name
,
uint16_t
millivolts
)
{
const
struct
regul_struct
*
regul
=
stpmu1_
get_regulator_data
(
name
);
const
struct
regul_struct
*
regul
=
get_regulator_data
(
name
);
uint8_t
i
;
for
(
i
=
0
;
i
<
regul
->
voltage_table_size
;
i
++
)
{
...
...
@@ -498,62 +564,132 @@ static uint8_t stpmu1_voltage_find_index(const char *name,
return
0
;
}
int
stpmu1_switch_off
(
void
)
int
stpmic1_powerctrl_on
(
void
)
{
return
stpmic1_register_update
(
MAIN_CONTROL_REG
,
PWRCTRL_PIN_VALID
,
PWRCTRL_PIN_VALID
);
}
int
stpmic1_switch_off
(
void
)
{
return
stpm
u
1_register_update
(
MAIN_CONTROL_REG
,
1
,
return
stpm
ic
1_register_update
(
MAIN_CONTROL_REG
,
1
,
SOFTWARE_SWITCH_OFF_ENABLED
);
}
int
stpm
u
1_regulator_enable
(
const
char
*
name
)
int
stpm
ic
1_regulator_enable
(
const
char
*
name
)
{
const
struct
regul_struct
*
regul
=
stpmu1_
get_regulator_data
(
name
);
const
struct
regul_struct
*
regul
=
get_regulator_data
(
name
);
return
stpm
u
1_register_update
(
regul
->
control_reg
,
BIT
(
0
),
BIT
(
0
));
return
stpm
ic
1_register_update
(
regul
->
control_reg
,
BIT
(
0
),
BIT
(
0
));
}
int
stpm
u
1_regulator_disable
(
const
char
*
name
)
int
stpm
ic
1_regulator_disable
(
const
char
*
name
)
{
const
struct
regul_struct
*
regul
=
stpmu1_
get_regulator_data
(
name
);
const
struct
regul_struct
*
regul
=
get_regulator_data
(
name
);
return
stpm
u
1_register_update
(
regul
->
control_reg
,
0
,
BIT
(
0
));
return
stpm
ic
1_register_update
(
regul
->
control_reg
,
0
,
BIT
(
0
));
}
uint8_t
stpm
u
1_is_regulator_enabled
(
const
char
*
name
)
uint8_t
stpm
ic
1_is_regulator_enabled
(
const
char
*
name
)
{
uint8_t
val
;
const
struct
regul_struct
*
regul
=
stpmu1_
get_regulator_data
(
name
);
const
struct
regul_struct
*
regul
=
get_regulator_data
(
name
);
if
(
stpm
u
1_register_read
(
regul
->
control_reg
,
&
val
)
!=
0
)
{
if
(
stpm
ic
1_register_read
(
regul
->
control_reg
,
&
val
)
!=
0
)
{
panic
();
}
return
(
val
&
0x1U
);
}
int
stpm
u
1_regulator_voltage_set
(
const
char
*
name
,
uint16_t
millivolts
)
int
stpm
ic
1_regulator_voltage_set
(
const
char
*
name
,
uint16_t
millivolts
)
{
uint8_t
voltage_index
=
stpmu1_voltage_find_index
(
name
,
millivolts
);
const
struct
regul_struct
*
regul
=
stpmu1_get_regulator_data
(
name
);
uint8_t
voltage_index
=
voltage_to_index
(
name
,
millivolts
);
const
struct
regul_struct
*
regul
=
get_regulator_data
(
name
);
uint8_t
mask
;
/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
if
(
strncmp
(
name
,
"buck"
,
4
)
==
0
)
{
mask
=
BUCK_VOLTAGE_MASK
;
}
else
if
((
strncmp
(
name
,
"ldo"
,
3
)
==
0
)
&&
(
strncmp
(
name
,
"ldo4"
,
4
)
!=
0
))
{
mask
=
LDO_VOLTAGE_MASK
;
}
else
{
return
0
;
}
return
stpmic1_register_update
(
regul
->
control_reg
,
voltage_index
<<
LDO_BUCK_VOLTAGE_SHIFT
,
mask
);
}
int
stpmic1_regulator_pull_down_set
(
const
char
*
name
)
{
const
struct
regul_struct
*
regul
=
get_regulator_data
(
name
);
if
(
regul
->
pull_down_reg
!=
0
)
{
return
stpmic1_register_update
(
regul
->
pull_down_reg
,
BIT
(
regul
->
pull_down
),
LDO_BUCK_PULL_DOWN_MASK
<<
regul
->
pull_down
);
}
return
0
;
}
int
stpmic1_regulator_mask_reset_set
(
const
char
*
name
)
{
const
struct
regul_struct
*
regul
=
get_regulator_data
(
name
);
return
stpmic1_register_update
(
regul
->
mask_reset_reg
,
BIT
(
regul
->
mask_reset
),
LDO_BUCK_RESET_MASK
<<
regul
->
mask_reset
);
}
int
stpmic1_regulator_voltage_get
(
const
char
*
name
)
{
const
struct
regul_struct
*
regul
=
get_regulator_data
(
name
);
uint8_t
value
;
uint8_t
mask
;
/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
if
(
strncmp
(
name
,
"buck"
,
4
)
==
0
)
{
mask
=
BUCK_VOLTAGE_MASK
;
}
else
if
((
strncmp
(
name
,
"ldo"
,
3
)
==
0
)
&&
(
strncmp
(
name
,
"ldo4"
,
4
)
!=
0
))
{
mask
=
LDO_VOLTAGE_MASK
;
}
else
{
return
0
;
}
return
stpmu1_register_update
(
regul
->
control_reg
,
voltage_index
<<
2
,
0xFC
);
if
(
stpmic1_register_read
(
regul
->
control_reg
,
&
value
))
return
-
1
;
value
=
(
value
&
mask
)
>>
LDO_BUCK_VOLTAGE_SHIFT
;
if
(
value
>
regul
->
voltage_table_size
)
return
-
1
;
return
(
int
)
regul
->
voltage_table
[
value
];
}
int
stpm
u
1_register_read
(
uint8_t
register_id
,
uint8_t
*
value
)
int
stpm
ic
1_register_read
(
uint8_t
register_id
,
uint8_t
*
value
)
{
return
stm32_i2c_mem_read
(
stpmu
_i2c_handle
,
stpmu
_i2c_addr
,
return
stm32_i2c_mem_read
(
pmic
_i2c_handle
,
pmic
_i2c_addr
,
(
uint16_t
)
register_id
,
I2C_MEMADD_SIZE_8BIT
,
value
,
1
,
100000
);
}
int
stpm
u
1_register_write
(
uint8_t
register_id
,
uint8_t
value
)
int
stpm
ic
1_register_write
(
uint8_t
register_id
,
uint8_t
value
)
{
int
status
;
status
=
stm32_i2c_mem_write
(
stpmu
_i2c_handle
,
stpmu
_i2c_addr
,
status
=
stm32_i2c_mem_write
(
pmic
_i2c_handle
,
pmic
_i2c_addr
,
(
uint16_t
)
register_id
,
I2C_MEMADD_SIZE_8BIT
,
&
value
,
1
,
100000
);
#if ENABLE_ASSERTIONS
if
(
status
!=
0
)
{
return
status
;
}
...
...
@@ -561,7 +697,7 @@ int stpmu1_register_write(uint8_t register_id, uint8_t value)
if
((
register_id
!=
WATCHDOG_CONTROL_REG
)
&&
(
register_id
<=
0x40U
))
{
uint8_t
readval
;
status
=
stpm
u
1_register_read
(
register_id
,
&
readval
);
status
=
stpm
ic
1_register_read
(
register_id
,
&
readval
);
if
(
status
!=
0
)
{
return
status
;
}
...
...
@@ -570,32 +706,57 @@ int stpmu1_register_write(uint8_t register_id, uint8_t value)
return
-
1
;
}
}
#endif
return
0
;
return
status
;
}
int
stpm
u
1_register_update
(
uint8_t
register_id
,
uint8_t
value
,
uint8_t
mask
)
int
stpm
ic
1_register_update
(
uint8_t
register_id
,
uint8_t
value
,
uint8_t
mask
)
{
int
status
;
uint8_t
val
;
status
=
stpm
u
1_register_read
(
register_id
,
&
val
);
status
=
stpm
ic
1_register_read
(
register_id
,
&
val
);
if
(
status
!=
0
)
{
return
status
;
}
/* Clear bits to update */
val
&=
~
mask
;
val
=
(
val
&
~
mask
)
|
(
value
&
mask
);
/* Update approp
ri
a
te
bits*/
val
|=
(
value
&
mask
);
return
stpmic1_register_w
rite
(
register_id
,
val
);
}
/* Send new value on I2C Bus */
return
stpmu1_register_write
(
register_id
,
val
);
void
stpmic1_bind_i2c
(
struct
i2c_handle_s
*
i2c_handle
,
uint16_t
i2c_addr
)
{
pmic_i2c_handle
=
i2c_handle
;
pmic_i2c_addr
=
i2c_addr
;
}
void
stpm
u1_bind_i2c
(
struct
i2c_handle_s
*
i2c_handle
,
uint16_t
i2c_addr
)
void
stpm
ic1_dump_regulators
(
void
)
{
stpmu_i2c_handle
=
i2c_handle
;
stpmu_i2c_addr
=
i2c_addr
;
uint32_t
i
;
for
(
i
=
0U
;
i
<
MAX_REGUL
;
i
++
)
{
const
char
*
name
__unused
=
regulators_table
[
i
].
dt_node_name
;
VERBOSE
(
"PMIC regul %s: %sable, %dmV"
,
name
,
stpmic1_is_regulator_enabled
(
name
)
?
"en"
:
"dis"
,
stpmic1_regulator_voltage_get
(
name
));
}
}
int
stpmic1_get_version
(
unsigned
long
*
version
)
{
int
rc
;
uint8_t
read_val
;
rc
=
stpmic1_register_read
(
VERSION_STATUS_REG
,
&
read_val
);
if
(
rc
)
{
return
-
1
;
}
*
version
=
(
unsigned
long
)
read_val
;
return
0
;
}
fdts/stm32mp15-ddr.dtsi
View file @
fbf35335
...
...
@@ -5,7 +5,7 @@
/ {
soc {
ddr: ddr@
0x
5A003000{
ddr: ddr@5A003000{
compatible = "st,stm32mp1-ddr";
...
...
fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
View file @
fbf35335
...
...
@@ -3,7 +3,7 @@
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
*/
/* STM32MP157C ED1
and ED2
BOARD configuration
/* STM32MP157C ED1 BOARD configuration
* 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
* Reference used NT5CC256M16DP-DI from NANYA
*
...
...
@@ -15,10 +15,11 @@
* timing mode optimized
* Scheduling/QoS options : type = 2
* address mapping : RBC
* Tc > + 85C : N
*/
#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.
39
"
#define DDR_MEM_SPEED 533
#define DDR_MEM_NAME "DDR3-1066
/888
bin G 2x4Gb 533MHz v1.
41
"
#define DDR_MEM_SPEED 533
000
#define DDR_MEM_SIZE 0x40000000
#define DDR_MSTR 0x00040401
...
...
@@ -62,7 +63,7 @@
#define DDR_ADDRMAP11 0x00000000
#define DDR_ODTCFG 0x06000600
#define DDR_ODTMAP 0x00000001
#define DDR_SCHED 0x0000
12
01
#define DDR_SCHED 0x0000
0C
01
#define DDR_SCHED1 0x00000000
#define DDR_PERFHPR1 0x01000001
#define DDR_PERFLPR1 0x08000200
...
...
@@ -74,15 +75,15 @@
#define DDR_PCCFG 0x00000010
#define DDR_PCFGR_0 0x00010000
#define DDR_PCFGW_0 0x00000000
#define DDR_PCFGQOS0_0 0x02100
B
03
#define DDR_PCFGQOS0_0 0x02100
C
03
#define DDR_PCFGQOS1_0 0x00800100
#define DDR_PCFGWQOS0_0 0x01100
B
03
#define DDR_PCFGWQOS0_0 0x01100
C
03
#define DDR_PCFGWQOS1_0 0x01000200
#define DDR_PCFGR_1 0x00010000
#define DDR_PCFGW_1 0x00000000
#define DDR_PCFGQOS0_1 0x02100
B
03
#define DDR_PCFGQOS1_1 0x008000
0
0
#define DDR_PCFGWQOS0_1 0x01100
B
03
#define DDR_PCFGQOS0_1 0x02100
C
03
#define DDR_PCFGQOS1_1 0x008000
4
0
#define DDR_PCFGWQOS0_1 0x01100
C
03
#define DDR_PCFGWQOS1_1 0x01000200
#define DDR_PGCR 0x01442E02
#define DDR_PTR0 0x0022AA5B
...
...
fdts/stm32mp157-pinctrl.dtsi
View file @
fbf35335
...
...
@@ -3,13 +3,14 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
/ {
soc {
pinctrl: pin-controller {
pinctrl: pin-controller
@50002000
{
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32mp157-pinctrl";
ranges = <0 0x50002000 0xa400>;
pins-are-numbered;
...
...
@@ -134,54 +135,76 @@
status = "disabled";
};
uart4
_pins_a:
uart4@
0 {
qspi_bk1
_pins_a:
qspi-bk1-
0 {
pins1 {
pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
<STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
<STM32_PINMUX('F', 7, AF9)>, /* QSPI_BK1_IO2 */
<STM32_PINMUX('F', 6, AF9)>; /* QSPI_BK1_IO3 */
bias-disable;
drive-push-pull;
slew-rate = <
0
>;
slew-rate = <
1
>;
};
pins2 {
pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
bias-disable;
pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
bias-pull-up;
drive-push-pull;
slew-rate = <1>;
};
};
usart3
_pins_a:
usart3@
0 {
qspi_bk2
_pins_a:
qspi-bk2-
0 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
<STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
<STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
<STM32_PINMUX('G', 10, AF11)>, /* QSPI_BK2_IO2 */
<STM32_PINMUX('G', 7, AF11)>; /* QSPI_BK2_IO3 */
bias-disable;
drive-push-pull;
slew-rate = <
0
>;
slew-rate = <
1
>;
};
pins2 {
pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
<STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
bias-disable;
pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
bias-pull-up;
drive-push-pull;
slew-rate = <1>;
};
};
sdmmc1_b4_pins_a: sdmmc1-b4@
0 {
qspi_clk_pins_a: qspi-clk-
0 {
pins {
pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
bias-disable;
drive-push-pull;
slew-rate = <3>;
};
};
sdmmc1_b4_pins_a: sdmmc1-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
<STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
<STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
<STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
<STM32_PINMUX('C', 12, AF12)>, /* SDMMC1_CK */
<STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
slew-rate = <3>;
slew-rate = <1>;
drive-push-pull;
bias-disable;
};
pins2 {
pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
slew-rate = <2>;
drive-push-pull;
bias-disable;
};
};
sdmmc1_dir_pins_a: sdmmc1-dir
@
0 {
sdmmc1_dir_pins_a: sdmmc1-dir
-
0 {
pins1 {
pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
<STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
<STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
slew-rate = <
3
>;
slew-rate = <
1
>;
drive-push-pull;
bias-pull-up;
};
...
...
@@ -191,36 +214,85 @@
};
};
sdmmc2_b4_pins_a: sdmmc2-b4@0 {
pins {
sdmmc1_dir_pins_b: sdmmc1-dir-1 {
pins1 {
pinmux = <STM32_PINMUX('E', 12, AF8)>, /* SDMMC1_D0DIR */
<STM32_PINMUX('E', 14, AF11)>, /* SDMMC1_D123DIR */
<STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
slew-rate = <3>;
drive-push-pull;
bias-pull-up;
};
pins2 {
pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
bias-pull-up;
};
};
sdmmc2_b4_pins_a: sdmmc2-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
<STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
<STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
<STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
<STM32_PINMUX('E', 3, AF9)>, /* SDMMC2_CK */
<STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
slew-rate = <3>;
slew-rate = <1>;
drive-push-pull;
bias-pull-up;
};
pins2 {
pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
slew-rate = <2>;
drive-push-pull;
bias-pull-up;
};
};
sdmmc2_d47_pins_a: sdmmc2-d47
@
0 {
sdmmc2_d47_pins_a: sdmmc2-d47
-
0 {
pins {
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
<STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
<STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
<STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
slew-rate = <
3
>;
slew-rate = <
1
>;
drive-push-pull;
bias-pull-up;
};
};
uart4_pins_a: uart4-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
pins2 {
pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
bias-disable;
};
};
usart3_pins_a: usart3-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
<STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
pins2 {
pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
<STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
bias-disable;
};
};
};
pinctrl_z: pin-controller-z {
pinctrl_z: pin-controller-z
@54004000
{
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32mp157-z-pinctrl";
ranges = <0 0x54004000 0x400>;
pins-are-numbered;
...
...
@@ -236,7 +308,7 @@
status = "disabled";
};
i2c4_pins_a: i2c4
@
0 {
i2c4_pins_a: i2c4
-
0 {
pins {
pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
<STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
...
...
fdts/stm32mp157c-ed1.dts
View file @
fbf35335
...
...
@@ -3,22 +3,28 @@
*
Copyright
(
C
)
STMicroelectronics
2017
-
All
Rights
Reserved
*
Author
:
Ludovic
Barre
<
ludovic
.
barre
@
st
.
com
>
for
STMicroelectronics
.
*/
/
dts
-
v1
/;
#
include
"stm32mp157c.dtsi"
#
include
"stm32mp157caa-pinctrl.dtsi"
/
{
model
=
"STMicroelectronics STM32MP157C
-ED1 pmic
eval daughter"
;
model
=
"STMicroelectronics STM32MP157C eval daughter"
;
compatible
=
"st,stm32mp157c-ed1"
,
"st,stm32mp157"
;
chosen
{
bootargs
=
"earlyprintk console=ttyS3,115200 root=/dev/ram"
;
stdout
-
path
=
"serial3:115200n8"
;
stdout
-
path
=
"serial0:115200n8"
;
};
aliases
{
serial0
=
&
uart4
;
};
};
&
clk_hse
{
st
,
digbypass
;
};
&
i2c4
{
pinctrl
-
names
=
"default"
;
pinctrl
-
0
=
<&
i2c4_pins_a
>;
...
...
@@ -26,37 +32,88 @@
i2c
-
scl
-
falling
-
time
-
ns
=
<
20
>;
status
=
"okay"
;
pmic
:
stpm
u1
@
33
{
compatible
=
"st,stpm
u
1"
;
pmic
:
stpm
ic
@
33
{
compatible
=
"st,stpm
ic
1"
;
reg
=
<
0x33
>;
interrupts
-
extended
=
<&
exti_pwr
55
IRQ_TYPE_EDGE_FALLING
>;
interrupt
-
controller
;
#
interrupt
-
cells
=
<
2
>;
status
=
"okay"
;
st
,
main
_
control
_
register
=
<
0x04
>;
st
,
vin
_
control
_
register
=
<
0xc0
>;
st
,
usb
_
control
_
register
=
<
0x30
>;
st
,
main
-
control
-
register
=
<
0x04
>;
st
,
vin
-
control
-
register
=
<
0xc0
>;
st
,
usb
-
control
-
register
=
<
0x30
>;
regulators
{
compatible
=
"st,stpmu1-regulators"
;
compatible
=
"st,stpmic1-regulators"
;
ldo1
-
supply
=
<&
v3v3
>;
ldo2
-
supply
=
<&
v3v3
>;
ldo3
-
supply
=
<&
vdd_ddr
>;
ldo5
-
supply
=
<&
v3v3
>;
ldo6
-
supply
=
<&
v3v3
>;
vddcore
:
buck1
{
regulator
-
name
=
"vddcore"
;
regulator
-
min
-
microvolt
=
<
800000
>;
regulator
-
max
-
microvolt
=
<
1350000
>;
regulator
-
always
-
on
;
regulator
-
initial
-
mode
=
<
0
>;
regulator
-
over
-
current
-
protection
;
};
vdd_ddr
:
buck2
{
regulator
-
name
=
"vdd_ddr"
;
regulator
-
min
-
microvolt
=
<
1350000
>;
regulator
-
max
-
microvolt
=
<
1350000
>;
regulator
-
always
-
on
;
regulator
-
initial
-
mode
=
<
0
>;
regulator
-
over
-
current
-
protection
;
};
vdd
:
buck3
{
regulator
-
name
=
"vdd"
;
regulator
-
min
-
microvolt
=
<
3300000
>;
regulator
-
max
-
microvolt
=
<
3300000
>;
regulator
-
always
-
on
;
st
,
mask
-
reset
;
regulator
-
initial
-
mode
=
<
0
>;
regulator
-
over
-
current
-
protection
;
};
v3v3
:
buck4
{
regulator
-
name
=
"v3v3"
;
regulator
-
min
-
microvolt
=
<
3300000
>;
regulator
-
max
-
microvolt
=
<
3300000
>;
regulator
-
boot
-
on
;
regulator
-
always
-
on
;
regulator
-
over
-
current
-
protection
;
regulator
-
initial
-
mode
=
<
8
>;
regulator
-
initial
-
mode
=
<
0
>;
};
regulator
-
state
-
standby
{
regulator
-
suspend
-
microvolt
=
<
3300000
>
;
regulator
-
unchanged
-
in
-
suspend
;
regulator
-
m
ode
=
<
8
>;
vdda
:
ldo1
{
regulator
-
name
=
"vdda"
;
regulator
-
min
-
microvolt
=
<
2900000
>
;
regulator
-
m
ax
-
microvolt
=
<
2900000
>;
};
regulator
-
state
-
mem
{
regulator
-
off
-
in
-
suspend
;
v2v8
:
ldo2
{
regulator
-
name
=
"v2v8"
;
regulator
-
min
-
microvolt
=
<
2800000
>;
regulator
-
max
-
microvolt
=
<
2800000
>;
};
regulator
-
state
-
disk
{
regulator
-
off
-
in
-
suspend
;
vtt_ddr
:
ldo3
{
regulator
-
name
=
"vtt_ddr"
;
regulator
-
min
-
microvolt
=
<
500000
>;
regulator
-
max
-
microvolt
=
<
750000
>;
regulator
-
always
-
on
;
regulator
-
over
-
current
-
protection
;
};
vdd_usb
:
ldo4
{
regulator
-
name
=
"vdd_usb"
;
regulator
-
min
-
microvolt
=
<
3300000
>;
regulator
-
max
-
microvolt
=
<
3300000
>;
};
vdd_sd
:
ldo5
{
...
...
@@ -64,24 +121,24 @@
regulator
-
min
-
microvolt
=
<
2900000
>;
regulator
-
max
-
microvolt
=
<
2900000
>;
regulator
-
boot
-
on
;
regulator
-
state
-
standby
{
regulator
-
suspend
-
microvolt
=
<
2900000
>;
regulator
-
unchanged
-
in
-
suspend
;
};
regulator
-
state
-
mem
{
regulator
-
off
-
in
-
suspend
;
};
regulator
-
state
-
disk
{
regulator
-
off
-
in
-
suspend
;
v1v8
:
ldo6
{
regulator
-
name
=
"v1v8"
;
regulator
-
min
-
microvolt
=
<
1800000
>;
regulator
-
max
-
microvolt
=
<
1800000
>;
};
vref_ddr
:
vref_ddr
{
regulator
-
name
=
"vref_ddr"
;
regulator
-
always
-
on
;
regulator
-
over
-
current
-
protection
;
};
};
};
};
&
iwdg2
{
instance
=
<
2
>;
timeout
-
sec
=
<
32
>;
status
=
"okay"
;
};
...
...
@@ -90,14 +147,19 @@
status
=
"okay"
;
};
&
rtc
{
status
=
"okay"
;
};
&
sdmmc1
{
pinctrl
-
names
=
"default"
;
pinctrl
-
0
=
<&
sdmmc1_b4_pins_a
&
sdmmc1_dir_pins_a
>;
broken
-
cd
;
st
,
dir
pol
;
st
,
negedge
;
st
,
pin
-
ckin
;
st
,
sig
-
dir
;
st
,
neg
-
edge
;
st
,
use
-
ckin
;
bus
-
width
=
<
4
>;
vmmc
-
supply
=
<&
vdd_sd
>;
sd
-
uhs
-
sdr12
;
sd
-
uhs
-
sdr25
;
sd
-
uhs
-
sdr50
;
...
...
@@ -112,16 +174,17 @@
non
-
removable
;
no
-
sd
;
no
-
sdio
;
st
,
dirpol
;
st
,
negedge
;
st
,
neg
-
edge
;
bus
-
width
=
<
8
>;
vmmc
-
supply
=
<&
v3v3
>;
vqmmc
-
supply
=
<&
v3v3
>;
mmc
-
ddr
-
3
_3v
;
status
=
"okay"
;
};
&
uart4
{
pinctrl
-
names
=
"default"
;
pinctrl
-
0
=
<&
uart4_pins_a
>;
resets
=
<&
rcc
UART4_R
>;
status
=
"okay"
;
};
...
...
@@ -157,6 +220,7 @@
/*
CLOCK
init
*/
&
rcc
{
secure
-
status
=
"disabled"
;
st
,
clksrc
=
<
CLK_MPU_PLL1P
CLK_AXI_PLL2P
...
...
@@ -186,7 +250,7 @@
CLK_FMC_ACLK
CLK_QSPI_ACLK
CLK_ETH_DISABLED
CLK_SDMMC12_PLL
3R
CLK_SDMMC12_PLL
4P
CLK_DSI_DSIPLL
CLK_STGEN_HSE
CLK_USBPHY_HSE
...
...
@@ -195,7 +259,7 @@
CLK_SPI45_HSI
CLK_SPI6_HSI
CLK_I2C46_HSI
CLK_SDMMC3_PLL
3R
CLK_SDMMC3_PLL
4P
CLK_USBO_USBPHY
CLK_ADC_CKPER
CLK_CEC_LSE
...
...
@@ -206,17 +270,17 @@
CLK_UART35_HSI
CLK_UART6_HSI
CLK_UART78_HSI
CLK_SPDIF_PLL
3Q
CLK_SPDIF_PLL
4P
CLK_FDCAN_PLL4Q
CLK_SAI1_PLL3Q
CLK_SAI2_PLL3Q
CLK_SAI3_PLL3Q
CLK_SAI4_PLL3Q
CLK_RNG1_
C
SI
CLK_RNG2_
C
SI
CLK_RNG1_
L
SI
CLK_RNG2_
L
SI
CLK_LPTIM1_PCLK1
CLK_LPTIM23_PCLK3
CLK_LPTIM45_
PCLK3
CLK_LPTIM45_
LSE
>;
/*
VCO
=
1300.0
MHz
=>
P
=
650
(
CPU
)
*/
...
...
@@ -231,15 +295,15 @@
frac
=
<
0x1400
>;
};
/*
VCO
=
786.4
MHz
=>
P
=
197
,
Q
=
4
9
,
R
=
98
*/
/*
VCO
=
417.8
MHz
=>
P
=
209
,
Q
=
2
4
,
R
=
11
*/
pll3
:
st
,
pll
@
2
{
cfg
=
<
2
97
3
15
7
PQR
(
1
,
1
,
1
)
>;
frac
=
<
0x
9ba
>;
cfg
=
<
1
33
1
16
36
PQR
(
1
,
1
,
1
)
>;
frac
=
<
0x
1a04
>;
};
/*
VCO
=
5
08
.0
MHz
=>
P
=
56
,
Q
=
56
,
R
=
56
*/
/*
VCO
=
5
94
.0
MHz
=>
P
=
99
,
Q
=
74
,
R
=
74
*/
pll4
:
st
,
pll
@
3
{
cfg
=
<
5
126
8
8
8
PQR
(
1
,
1
,
1
)
>;
cfg
=
<
3
98
5
7
7
PQR
(
1
,
1
,
1
)
>;
};
};
...
...
fdts/stm32mp157c-ev1.dts
View file @
fbf35335
...
...
@@ -3,23 +3,65 @@
*
Copyright
(
C
)
STMicroelectronics
2017
-
All
Rights
Reserved
*
Author
:
Ludovic
Barre
<
ludovic
.
barre
@
st
.
com
>
for
STMicroelectronics
.
*/
/
dts
-
v1
/;
#
include
"stm32mp157c-ed1.dts"
/
{
model
=
"STMicroelectronics STM32MP157C
-EV1 pmic
eval daughter on eval mother"
;
model
=
"STMicroelectronics STM32MP157C eval daughter on eval mother"
;
compatible
=
"st,stm32mp157c-ev1"
,
"st,stm32mp157c-ed1"
,
"st,stm32mp157"
;
chosen
{
bootargs
=
"earlyprintk console=ttyS3,115200 root=/dev/ram"
;
stdout
-
path
=
"serial3:115200n8"
;
stdout
-
path
=
"serial0:115200n8"
;
};
aliases
{
serial1
=
&
usart3
;
};
};
&
fmc
{
status
=
"okay"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
nand
:
nand
@
0
{
reg
=
<
0
>;
nand
-
on
-
flash
-
bbt
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
1
>;
};
};
&
qspi
{
pinctrl
-
names
=
"default"
;
pinctrl
-
0
=
<&
qspi_clk_pins_a
&
qspi_bk1_pins_a
&
qspi_bk2_pins_a
>;
reg
=
<
0x58003000
0x1000
>,
<
0x70000000
0x4000000
>;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
status
=
"okay"
;
flash0
:
mx66l51235l
@
0
{
compatible
=
"jedec,spi-nor"
;
reg
=
<
0
>;
spi
-
rx
-
bus
-
width
=
<
4
>;
spi
-
max
-
frequency
=
<
108000000
>;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
1
>;
};
flash1
:
mx66l51235l
@
1
{
compatible
=
"jedec,spi-nor"
;
reg
=
<
1
>;
spi
-
rx
-
bus
-
width
=
<
4
>;
spi
-
max
-
frequency
=
<
108000000
>;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
1
>;
};
};
&
usart3
{
pinctrl
-
names
=
"default"
;
pinctrl
-
0
=
<&
usart3_pins_a
>;
resets
=
<&
rcc
USART3_R
>;
status
=
"disabled"
;
};
fdts/stm32mp157c.dtsi
View file @
fbf35335
...
...
@@ -3,7 +3,7 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <dt-bindings/reset/stm32mp1-resets.h>
...
...
@@ -11,15 +11,12 @@
#address-cells = <1>;
#size-cells = <1>;
aliases {
serial0 = &usart1;
serial1 = &usart2;
serial2 = &usart3;
serial3 = &uart4;
serial4 = &uart5;
serial5 = &usart6;
serial6 = &uart7;
serial7 = &uart8;
intc: interrupt-controller@a0021000 {
compatible = "arm,cortex-a7-gic";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0xa0021000 0x1000>,
<0xa0022000 0x2000>;
};
clocks {
...
...
@@ -56,7 +53,7 @@
clk_i2s_ckin: i2s_ckin {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <
6400000
0>;
clock-frequency = <0>;
};
clk_dsi_phy: ck_dsi_phy {
...
...
@@ -64,31 +61,28 @@
compatible = "fixed-clock";
clock-frequency = <0>;
};
clk_usbo_48m: ck_usbo_48m {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <48000000>;
};
};
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
ranges;
usart2: serial@4000e000 {
compatible = "st,stm32h7-u
s
art";
compatible = "st,stm32h7-uart";
reg = <0x4000e000 0x400>;
clocks = <&rcc USART2_K>;
resets = <&rcc USART2_R>;
status = "disabled";
};
usart3: serial@4000f000 {
compatible = "st,stm32h7-u
s
art";
compatible = "st,stm32h7-uart";
reg = <0x4000f000 0x400>;
clocks = <&rcc USART3_K>;
resets = <&rcc USART3_R>;
status = "disabled";
};
...
...
@@ -96,6 +90,7 @@
compatible = "st,stm32h7-uart";
reg = <0x40010000 0x400>;
clocks = <&rcc UART4_K>;
resets = <&rcc UART4_R>;
status = "disabled";
};
...
...
@@ -103,6 +98,7 @@
compatible = "st,stm32h7-uart";
reg = <0x40011000 0x400>;
clocks = <&rcc UART5_K>;
resets = <&rcc UART5_R>;
status = "disabled";
};
...
...
@@ -111,6 +107,7 @@
compatible = "st,stm32h7-uart";
reg = <0x40018000 0x400>;
clocks = <&rcc UART7_K>;
resets = <&rcc UART7_R>;
status = "disabled";
};
...
...
@@ -118,21 +115,23 @@
compatible = "st,stm32h7-uart";
reg = <0x40019000 0x400>;
clocks = <&rcc UART8_K>;
resets = <&rcc UART8_R>;
status = "disabled";
};
usart6: serial@44003000 {
compatible = "st,stm32h7-u
s
art";
compatible = "st,stm32h7-uart";
reg = <0x44003000 0x400>;
clocks = <&rcc USART6_K>;
resets = <&rcc USART6_R>;
status = "disabled";
};
sdmmc3: sdmmc@48004000 {
compatible = "st,stm32-sdmmc2";
reg = <0x48004000 0x400>, <0x48005000 0x400>;
reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC3_K>;
clock-names = "apb_pclk";
resets = <&rcc SDMMC3_R>;
cap-sd-highspeed;
cap-mmc-highspeed;
...
...
@@ -141,17 +140,34 @@
};
rcc: rcc@50000000 {
compatible = "syscon", "st,stm32mp1-rcc";
compatible = "st,stm32mp1-rcc", "syscon";
reg = <0x50000000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
reg = <0x50000000 0x1000
>;
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH
>;
};
rcc_reboot: rcc-reboot@50000000 {
compatible = "syscon-reboot";
regmap = <&rcc>;
offset = <0x404>;
mask = <0x1>;
pwr: pwr@50001000 {
compatible = "st,stm32mp1-pwr", "syscon", "simple-mfd";
reg = <0x50001000 0x400>;
};
exti: interrupt-controller@5000d000 {
compatible = "st,stm32mp1-exti", "syscon";
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x5000d000 0x400>;
/* exti_pwr is an extra interrupt controller used for
* EXTI 55 to 60. It's mapped on pwr interrupt
* controller.
*/
exti_pwr: exti-pwr {
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&pwr>;
st,irq-number = <6>;
};
};
rng1: rng@54003000 {
...
...
@@ -162,13 +178,15 @@
status = "disabled";
};
fmc
_nand: fmc_nand
@58002000 {
compatible = "st,stm32mp1-fmc";
fmc
: nand-controller
@58002000 {
compatible = "st,stm32mp1
5
-fmc
2
";
reg = <0x58002000 0x1000>,
<0x80000000 0x40000>,
<0x81000000 0x40000>,
<0x88000000 0x40000>,
<0x89000000 0x40000>;
<0x80000000 0x1000>,
<0x88010000 0x1000>,
<0x88020000 0x1000>,
<0x81000000 0x1000>,
<0x89010000 0x1000>,
<0x89020000 0x1000>;
clocks = <&rcc FMC_K>;
resets = <&rcc FMC_R>;
status = "disabled";
...
...
@@ -177,15 +195,17 @@
qspi: qspi@58003000 {
compatible = "st,stm32f469-qspi";
reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
reg-names = "qspi", "qspi_mm";
clocks = <&rcc QSPI_K>;
resets = <&rcc QSPI_R>;
status = "disabled";
};
sdmmc1: sdmmc@58005000 {
compatible = "st,stm32-sdmmc2";
reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC1_K>;
clock-names = "apb_pclk";
resets = <&rcc SDMMC1_R>;
cap-sd-highspeed;
cap-mmc-highspeed;
...
...
@@ -196,8 +216,8 @@
sdmmc2: sdmmc@58007000 {
compatible = "st,stm32-sdmmc2";
reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC2_K>;
clock-names = "apb_pclk";
resets = <&rcc SDMMC2_R>;
cap-sd-highspeed;
cap-mmc-highspeed;
...
...
@@ -205,7 +225,7 @@
status = "disabled";
};
iwdg2:
iwd
g@5a002000 {
iwdg2:
watchdo
g@5a002000 {
compatible = "st,stm32mp1-iwdg";
reg = <0x5a002000 0x400>;
clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
...
...
@@ -214,15 +234,34 @@
};
usart1: serial@5c000000 {
compatible = "st,stm32h7-u
s
art";
compatible = "st,stm32h7-uart";
reg = <0x5c000000 0x400>;
interrupt-names = "event", "wakeup";
interrupts-extended = <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
<&exti 26 1>;
clocks = <&rcc USART1_K>;
resets = <&rcc USART1_R>;
status = "disabled";
};
spi6: spi@5c001000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32h7-spi";
reg = <0x5c001000 0x400>;
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc SPI6_K>;
resets = <&rcc SPI6_R>;
status = "disabled";
};
i2c4: i2c@5c002000 {
compatible = "st,stm32f7-i2c";
reg = <0x5c002000 0x400>;
interrupt-names = "event", "error", "wakeup";
interrupts-extended = <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
<&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
<&exti 24 1>;
clocks = <&rcc I2C4_K>;
resets = <&rcc I2C4_R>;
#address-cells = <1>;
...
...
@@ -235,6 +274,36 @@
reg = <0x5c004000 0x400>;
clocks = <&rcc RTCAPB>, <&rcc RTC>;
clock-names = "pclk", "rtc_ck";
interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<&exti 19 1>;
status = "disabled";
};
bsec: nvmem@5c005000 {
compatible = "st,stm32mp15-bsec";
reg = <0x5c005000 0x400>;
#address-cells = <1>;
#size-cells = <1>;
ts_cal1: calib@5c {
reg = <0x5c 0x2>;
};
ts_cal2: calib@5e {
reg = <0x5e 0x2>;
};
};
i2c6: i2c@5c009000 {
compatible = "st,stm32f7-i2c";
reg = <0x5c009000 0x400>;
interrupt-names = "event", "error", "wakeup";
interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
<&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
<&exti 54 1>;
clocks = <&rcc I2C6_K>;
resets = <&rcc I2C6_R>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
};
};
fdts/stm32mp157caa-pinctrl.dtsi
View file @
fbf35335
...
...
@@ -7,8 +7,8 @@
#include "stm32mp157-pinctrl.dtsi"
/ {
soc {
pinctrl: pin-controller {
compatible = "st,stm32mp157caa-pinctrl"
;
pinctrl: pin-controller
@50002000
{
st,package = <STM32MP157CAA>
;
gpioa: gpio@50002000 {
status = "okay";
...
...
@@ -77,8 +77,8 @@
};
};
pinctrl_z: pin-controller-z {
compatible = "st,stm32mp157caa-z-pinctrl"
;
pinctrl_z: pin-controller-z
@54004000
{
st,package = <STM32MP157CAA>
;
gpioz: gpio@54004000 {
status = "okay";
...
...
include/drivers/st/bsec.h
0 → 100644
View file @
fbf35335
/*
* Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef BSEC_H
#define BSEC_H
#include <stdbool.h>
#include <stdint.h>
#include <lib/utils_def.h>
/*
* IP configuration
*/
#define BSEC_OTP_MASK GENMASK(4, 0)
#define BSEC_OTP_BANK_SHIFT 5
#define BSEC_TIMEOUT_VALUE 0xFFFF
#define ADDR_LOWER_OTP_PERLOCK_SHIFT 0x03
#define DATA_LOWER_OTP_PERLOCK_BIT 0x03U
/* 2 significants bits are used */
#define DATA_LOWER_OTP_PERLOCK_MASK GENMASK(2, 0)
#define ADDR_UPPER_OTP_PERLOCK_SHIFT 0x04
#define DATA_UPPER_OTP_PERLOCK_BIT 0x01U
/* 1 significants bits are used */
#define DATA_UPPER_OTP_PERLOCK_MASK GENMASK(3, 0)
/*
* Return status
*/
#define BSEC_OK 0U
#define BSEC_ERROR 0xFFFFFFFFU
#define BSEC_DISTURBED 0xFFFFFFFEU
#define BSEC_INVALID_PARAM 0xFFFFFFFCU
#define BSEC_PROG_FAIL 0xFFFFFFFBU
#define BSEC_LOCK_FAIL 0xFFFFFFFAU
#define BSEC_WRITE_FAIL 0xFFFFFFF9U
#define BSEC_SHADOW_FAIL 0xFFFFFFF8U
#define BSEC_TIMEOUT 0xFFFFFFF7U
/*
* BSEC REGISTER OFFSET (base relative)
*/
#define BSEC_OTP_CONF_OFF 0x000U
#define BSEC_OTP_CTRL_OFF 0x004U
#define BSEC_OTP_WRDATA_OFF 0x008U
#define BSEC_OTP_STATUS_OFF 0x00CU
#define BSEC_OTP_LOCK_OFF 0x010U
#define BSEC_DEN_OFF 0x014U
#define BSEC_DISTURBED_OFF 0x01CU
#define BSEC_DISTURBED1_OFF 0x020U
#define BSEC_DISTURBED2_OFF 0x024U
#define BSEC_ERROR_OFF 0x034U
#define BSEC_ERROR1_OFF 0x038U
#define BSEC_ERROR2_OFF 0x03CU
#define BSEC_WRLOCK_OFF 0x04CU
/* Safmem permanent lock */
#define BSEC_WRLOCK1_OFF 0x050U
#define BSEC_WRLOCK2_OFF 0x054U
#define BSEC_SPLOCK_OFF 0x064U
/* Program safmem sticky lock */
#define BSEC_SPLOCK1_OFF 0x068U
#define BSEC_SPLOCK2_OFF 0x06CU
#define BSEC_SWLOCK_OFF 0x07CU
/* Write in OTP sticky lock */
#define BSEC_SWLOCK1_OFF 0x080U
#define BSEC_SWLOCK2_OFF 0x084U
#define BSEC_SRLOCK_OFF 0x094U
/* Shadowing sticky lock */
#define BSEC_SRLOCK1_OFF 0x098U
#define BSEC_SRLOCK2_OFF 0x09CU
#define BSEC_JTAG_IN_OFF 0x0ACU
#define BSEC_JTAG_OUT_OFF 0x0B0U
#define BSEC_SCRATCH_OFF 0x0B4U
#define BSEC_OTP_DATA_OFF 0x200U
#define BSEC_IPHW_CFG_OFF 0xFF0U
#define BSEC_IPVR_OFF 0xFF4U
#define BSEC_IP_ID_OFF 0xFF8U
#define BSEC_IP_MAGIC_ID_OFF 0xFFCU
/*
* BSEC_CONFIGURATION Register
*/
#define BSEC_CONF_POWER_UP_MASK BIT(0)
#define BSEC_CONF_POWER_UP_SHIFT 0
#define BSEC_CONF_FRQ_MASK GENMASK(2, 1)
#define BSEC_CONF_FRQ_SHIFT 1
#define BSEC_CONF_PRG_WIDTH_MASK GENMASK(6, 3)
#define BSEC_CONF_PRG_WIDTH_SHIFT 3
#define BSEC_CONF_TREAD_MASK GENMASK(8, 7)
#define BSEC_CONF_TREAD_SHIFT 7
/*
* BSEC_CONTROL Register
*/
#define BSEC_READ 0x000U
#define BSEC_WRITE 0x100U
#define BSEC_LOCK 0x200U
/*
* BSEC_OTP_LOCK register
*/
#define UPPER_OTP_LOCK_MASK BIT(0)
#define UPPER_OTP_LOCK_SHIFT 0
#define DENREG_LOCK_MASK BIT(2)
#define DENREG_LOCK_SHIFT 2
#define GPLOCK_LOCK_MASK BIT(4)
#define GPLOCK_LOCK_SHIFT 4
/*
* BSEC_OTP_STATUS Register
*/
#define BSEC_MODE_STATUS_MASK GENMASK(2, 0)
#define BSEC_MODE_BUSY_MASK BIT(3)
#define BSEC_MODE_PROGFAIL_MASK BIT(4)
#define BSEC_MODE_PWR_MASK BIT(5)
#define BSEC_MODE_BIST1_LOCK_MASK BIT(6)
#define BSEC_MODE_BIST2_LOCK_MASK BIT(7)
/* OTP MODE*/
#define BSEC_MODE_OPEN1 0x00
#define BSEC_MODE_SECURED 0x01
#define BSEC_MODE_OPEN2 0x02
#define BSEC_MODE_INVALID 0x04
/* BSEC_DENABLE Register */
#define BSEC_HDPEN BIT(4)
#define BSEC_SPIDEN BIT(5)
#define BSEC_SPINDEN BIT(6)
#define BSEC_DBGSWGEN BIT(10)
#define BSEC_DEN_ALL_MSK GENMASK(10, 0)
/* BSEC_FENABLE Register */
#define BSEC_FEN_ALL_MSK GENMASK(14, 0)
/*
* OTP Lock services definition
* Value must corresponding to the bit number in the register
*/
#define BSEC_LOCK_UPPER_OTP 0x00
#define BSEC_LOCK_DEBUG 0x02
#define BSEC_LOCK_PROGRAM 0x03
/* Values for struct bsec_config::freq */
#define FREQ_10_20_MHZ 0x0
#define FREQ_20_30_MHZ 0x1
#define FREQ_30_45_MHZ 0x2
#define FREQ_45_67_MHZ 0x3
/*
* Device info structure, providing device-specific functions and a means of
* adding driver-specific state
*/
struct
bsec_config
{
uint8_t
tread
;
/* SAFMEM Reading current level default 0 */
uint8_t
pulse_width
;
/* SAFMEM Programming pulse width default 1 */
uint8_t
freq
;
/* SAFMEM CLOCK see freq value define
* default FREQ_45_67_MHZ
*/
uint8_t
power
;
/* Power up SAFMEM. 1 power up, 0 power off */
uint8_t
prog_lock
;
/* Programming Sticky lock
* 1 programming is locked until next reset
*/
uint8_t
den_lock
;
/* Debug enable sticky lock
* 1 debug enable is locked until next reset
*/
uint8_t
upper_otp_lock
;
/* Shadowing of upper OTP sticky lock
* 1 shadowing of upper OTP is locked
* until next reset
*/
};
uint32_t
bsec_probe
(
void
);
uint32_t
bsec_get_base
(
void
);
uint32_t
bsec_set_config
(
struct
bsec_config
*
cfg
);
uint32_t
bsec_get_config
(
struct
bsec_config
*
cfg
);
uint32_t
bsec_shadow_register
(
uint32_t
otp
);
uint32_t
bsec_read_otp
(
uint32_t
*
val
,
uint32_t
otp
);
uint32_t
bsec_write_otp
(
uint32_t
val
,
uint32_t
otp
);
uint32_t
bsec_program_otp
(
uint32_t
val
,
uint32_t
otp
);
uint32_t
bsec_permanent_lock_otp
(
uint32_t
otp
);
uint32_t
bsec_write_debug_conf
(
uint32_t
val
);
uint32_t
bsec_read_debug_conf
(
void
);
uint32_t
bsec_write_feature_conf
(
uint32_t
val
);
uint32_t
bsec_read_feature_conf
(
uint32_t
*
val
);
uint32_t
bsec_get_status
(
void
);
uint32_t
bsec_get_hw_conf
(
void
);
uint32_t
bsec_get_version
(
void
);
uint32_t
bsec_get_id
(
void
);
uint32_t
bsec_get_magic_id
(
void
);
bool
bsec_write_sr_lock
(
uint32_t
otp
,
uint32_t
value
);
bool
bsec_read_sr_lock
(
uint32_t
otp
);
bool
bsec_write_sw_lock
(
uint32_t
otp
,
uint32_t
value
);
bool
bsec_read_sw_lock
(
uint32_t
otp
);
bool
bsec_write_sp_lock
(
uint32_t
otp
,
uint32_t
value
);
bool
bsec_read_sp_lock
(
uint32_t
otp
);
bool
bsec_wr_lock
(
uint32_t
otp
);
uint32_t
bsec_otp_lock
(
uint32_t
service
,
uint32_t
value
);
bool
bsec_mode_is_closed_device
(
void
);
uint32_t
bsec_shadow_read_otp
(
uint32_t
*
otp_value
,
uint32_t
word
);
uint32_t
bsec_check_nsec_access_rights
(
uint32_t
otp
);
#endif
/* BSEC_H */
include/drivers/st/stm32_gpio.h
View file @
fbf35335
/*
* Copyright (c) 2015-201
8
, STMicroelectronics - All Rights Reserved
* Copyright (c) 2015-201
9
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -9,10 +9,6 @@
#include <lib/utils_def.h>
#define STM32_GPIOA_BANK U(0x50002000)
#define STM32_GPIOZ_BANK U(0x54004000)
#define STM32_GPIO_BANK_OFFSET U(0x1000)
#define GPIO_MODE_OFFSET U(0x00)
#define GPIO_TYPE_OFFSET U(0x04)
#define GPIO_SPEED_OFFSET U(0x08)
...
...
@@ -20,56 +16,14 @@
#define GPIO_BSRR_OFFSET U(0x18)
#define GPIO_AFRL_OFFSET U(0x20)
#define GPIO_AFRH_OFFSET U(0x24)
#define GPIO_SECR_OFFSET U(0x30)
#define GPIO_ALT_LOWER_LIMIT U(0x08)
#define GPIO_BANK_A U(0x00)
#define GPIO_BANK_B U(0x01)
#define GPIO_BANK_C U(0x02)
#define GPIO_BANK_D U(0x03)
#define GPIO_BANK_E U(0x04)
#define GPIO_BANK_F U(0x05)
#define GPIO_BANK_G U(0x06)
#define GPIO_BANK_H U(0x07)
#define GPIO_BANK_I U(0x08)
#define GPIO_BANK_J U(0x09)
#define GPIO_BANK_K U(0x0A)
#define GPIO_BANK_Z U(0x19)
#define GPIO_PIN_0 U(0x00)
#define GPIO_PIN_1 U(0x01)
#define GPIO_PIN_2 U(0x02)
#define GPIO_PIN_3 U(0x03)
#define GPIO_PIN_4 U(0x04)
#define GPIO_PIN_5 U(0x05)
#define GPIO_PIN_6 U(0x06)
#define GPIO_PIN_7 U(0x07)
#define GPIO_PIN_8 U(0x08)
#define GPIO_PIN_9 U(0x09)
#define GPIO_PIN_10 U(0x0A)
#define GPIO_PIN_11 U(0x0B)
#define GPIO_PIN_12 U(0x0C)
#define GPIO_PIN_13 U(0x0D)
#define GPIO_PIN_14 U(0x0E)
#define GPIO_PIN_15 U(0x0F)
#define GPIO_PIN_MAX GPIO_PIN_15
#define GPIO_PIN_(_x) U(_x)
#define GPIO_PIN_MAX GPIO_PIN_(15)
#define GPIO_ALTERNATE_0 0x00
#define GPIO_ALTERNATE_1 0x01
#define GPIO_ALTERNATE_2 0x02
#define GPIO_ALTERNATE_3 0x03
#define GPIO_ALTERNATE_4 0x04
#define GPIO_ALTERNATE_5 0x05
#define GPIO_ALTERNATE_6 0x06
#define GPIO_ALTERNATE_7 0x07
#define GPIO_ALTERNATE_8 0x08
#define GPIO_ALTERNATE_9 0x09
#define GPIO_ALTERNATE_10 0x0A
#define GPIO_ALTERNATE_11 0x0B
#define GPIO_ALTERNATE_12 0x0C
#define GPIO_ALTERNATE_13 0x0D
#define GPIO_ALTERNATE_14 0x0E
#define GPIO_ALTERNATE_15 0x0F
#define GPIO_ALTERNATE_(_x) U(_x)
#define GPIO_ALTERNATE_MASK U(0x0F)
#define GPIO_MODE_INPUT 0x00
...
...
@@ -82,8 +36,8 @@
#define GPIO_SPEED_LOW 0x00
#define GPIO_SPEED_MEDIUM 0x01
#define GPIO_SPEED_
FAST
0x02
#define GPIO_SPEED_HIGH
0x03
#define GPIO_SPEED_
HIGH
0x02
#define GPIO_SPEED_
VERY_
HIGH 0x03
#define GPIO_SPEED_MASK U(0x03)
#define GPIO_NO_PULL 0x00
...
...
@@ -94,8 +48,10 @@
#ifndef __ASSEMBLY__
#include <stdint.h>
int
dt_set_pinctrl_config
(
int
node
);
void
set_gpio
(
uint32_t
bank
,
uint32_t
pin
,
uint32_t
mode
,
uint32_t
speed
,
uint32_t
pull
,
uint32_t
alternate
);
uint32_t
pull
,
uint32_t
alternate
,
uint8_t
status
);
void
set_gpio_secure_cfg
(
uint32_t
bank
,
uint32_t
pin
,
bool
secure
);
#endif
/*__ASSEMBLY__*/
#endif
/* STM32_GPIO_H */
include/drivers/st/stm32mp1_ddr.h
View file @
fbf35335
/*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
* Copyright (C) 2018
-2019
, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
...
...
@@ -153,7 +153,7 @@ struct stm32mp1_ddrphy_cal {
struct
stm32mp1_ddr_info
{
const
char
*
name
;
uint
16
_t
speed
;
/* in
M
HZ */
uint
32
_t
speed
;
/* in
k
HZ */
uint32_t
size
;
/* Memory size in byte = col * row * width */
};
...
...
@@ -168,7 +168,7 @@ struct stm32mp1_ddr_config {
struct
stm32mp1_ddrphy_cal
p_cal
;
};
int
stm32mp1_ddr_clk_enable
(
struct
ddr_info
*
priv
,
uint
16
_t
mem_speed
);
int
stm32mp1_ddr_clk_enable
(
struct
ddr_info
*
priv
,
uint
32
_t
mem_speed
);
void
stm32mp1_ddr_init
(
struct
ddr_info
*
priv
,
struct
stm32mp1_ddr_config
*
config
);
#endif
/* STM32MP1_DDR_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