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
6f7dba4b
Commit
6f7dba4b
authored
Nov 15, 2018
by
Pankaj Gupta
Browse files
ccn: Introduce API to set and read value of node register
Signed-off-by:
Pankaj Gupta
<
pankaj.gupta@nxp.com
>
parent
91ece4e2
Changes
2
Hide whitespace changes
Inline
Side-by-side
drivers/arm/ccn/ccn.c
View file @
6f7dba4b
...
...
@@ -11,6 +11,7 @@
#include <debug.h>
#include <errno.h>
#include <mmio.h>
#include <stdbool.h>
#include "ccn_private.h"
static
const
ccn_desc_t
*
ccn_plat_desc
;
...
...
@@ -490,3 +491,123 @@ int ccn_get_part0_id(uintptr_t periphbase)
return
(
int
)(
mmio_read_64
(
periphbase
+
MN_PERIPH_ID_0_1_OFFSET
)
&
0xFF
);
}
/*******************************************************************************
* This function returns the region id corresponding to a node_id of node_type.
******************************************************************************/
static
unsigned
int
get_region_id_for_node
(
node_types_t
node_type
,
unsigned
int
node_id
)
{
unsigned
int
mn_reg_off
,
region_id
;
unsigned
long
long
node_bitmap
;
unsigned
int
loc_node_id
,
node_pos_in_map
=
0
;
assert
(
node_type
<
NUM_NODE_TYPES
);
assert
(
node_id
<
MAX_RN_NODES
);
switch
(
node_type
)
{
case
NODE_TYPE_RNI
:
region_id
=
RNI_REGION_ID_START
;
break
;
case
NODE_TYPE_HNF
:
region_id
=
HNF_REGION_ID_START
;
break
;
case
NODE_TYPE_HNI
:
region_id
=
HNI_REGION_ID_START
;
break
;
case
NODE_TYPE_SN
:
region_id
=
SBSX_REGION_ID_START
;
break
;
default:
ERROR
(
"Un-supported Node Type = %d.
\n
"
,
node_type
);
assert
(
false
);
return
REGION_ID_LIMIT
;
}
/*
* RN-I, HN-F, HN-I, SN node registers in the MN region
* occupy contiguous 16 byte apart offsets.
*
* RN-F and RN-D node are not supported as
* none of them exposes any memory map to
* configure any of their offset registers.
*/
mn_reg_off
=
MN_RNF_NODEID_OFFSET
+
(
node_type
<<
4
);
node_bitmap
=
ccn_reg_read
(
ccn_plat_desc
->
periphbase
,
MN_REGION_ID
,
mn_reg_off
);
assert
((
node_bitmap
&
(
1ULL
<<
(
node_id
)))
!=
0U
);
FOR_EACH_PRESENT_NODE_ID
(
loc_node_id
,
node_bitmap
)
{
INFO
(
"Index = %u with loc_nod=%u and input nod=%u
\n
"
,
node_pos_in_map
,
loc_node_id
,
node_id
);
if
(
loc_node_id
==
node_id
)
break
;
node_pos_in_map
++
;
}
if
(
node_pos_in_map
==
CCN_MAX_RN_MASTERS
)
{
ERROR
(
"Node Id = %d, is not found.
\n
"
,
node_id
);
assert
(
false
);
return
REGION_ID_LIMIT
;
}
region_id
+=
node_pos_in_map
;
return
region_id
;
}
/*******************************************************************************
* This function sets the value 'val' to the register at register_offset from
* the base address pointed to by the region_id.
* where, region id is mapped to a node_id of node_type.
******************************************************************************/
void
ccn_write_node_reg
(
node_types_t
node_type
,
unsigned
int
node_id
,
unsigned
int
reg_offset
,
unsigned
long
long
val
)
{
unsigned
int
region_id
=
get_region_id_for_node
(
node_type
,
node_id
);
if
(
reg_offset
>
REGION_ID_OFFSET
)
{
ERROR
(
"Invalid Register offset 0x%x is provided.
\n
"
,
reg_offset
);
assert
(
false
);
return
;
}
/* Setting the value of Auxilary Control Register of the Node */
ccn_reg_write
(
ccn_plat_desc
->
periphbase
,
region_id
,
reg_offset
,
val
);
VERBOSE
(
"Value is successfully written at address 0x%lx.
\n
"
,
(
ccn_plat_desc
->
periphbase
+
region_id_to_base
(
region_id
))
+
reg_offset
);
}
/*******************************************************************************
* This function read the value 'val' stored in the register at register_offset
* from the base address pointed to by the region_id.
* where, region id is mapped to a node_id of node_type.
******************************************************************************/
unsigned
long
long
ccn_read_node_reg
(
node_types_t
node_type
,
unsigned
int
node_id
,
unsigned
int
reg_offset
)
{
unsigned
long
long
val
;
unsigned
int
region_id
=
get_region_id_for_node
(
node_type
,
node_id
);
if
(
reg_offset
>
REGION_ID_OFFSET
)
{
ERROR
(
"Invalid Register offset 0x%x is provided.
\n
"
,
reg_offset
);
assert
(
false
);
return
ULL
(
0
);
}
/* Setting the value of Auxilary Control Register of the Node */
val
=
ccn_reg_read
(
ccn_plat_desc
->
periphbase
,
region_id
,
reg_offset
);
VERBOSE
(
"Value is successfully read from address 0x%lx.
\n
"
,
(
ccn_plat_desc
->
periphbase
+
region_id_to_base
(
region_id
))
+
reg_offset
);
return
val
;
}
include/drivers/arm/ccn.h
View file @
6f7dba4b
...
...
@@ -76,6 +76,16 @@ typedef struct ccn_desc {
uintptr_t
periphbase
;
}
ccn_desc_t
;
/* Enum used to loop through all types of nodes in CCN*/
typedef
enum
node_types
{
NODE_TYPE_RNF
=
0
,
NODE_TYPE_RNI
,
NODE_TYPE_RND
,
NODE_TYPE_HNF
,
NODE_TYPE_HNI
,
NODE_TYPE_SN
,
NUM_NODE_TYPES
}
node_types_t
;
void
ccn_init
(
const
ccn_desc_t
*
plat_ccn_desc
);
void
ccn_enter_snoop_dvm_domain
(
unsigned
long
long
master_iface_map
);
...
...
@@ -92,5 +102,12 @@ void ccn_program_sys_addrmap(unsigned int sn0_id,
unsigned
int
ccn_get_l3_run_mode
(
void
);
int
ccn_get_part0_id
(
uintptr_t
periphbase
);
void
ccn_write_node_reg
(
node_types_t
node_type
,
unsigned
int
node_id
,
unsigned
int
reg_offset
,
unsigned
long
long
val
);
unsigned
long
long
ccn_read_node_reg
(
node_types_t
node_type
,
unsigned
int
node_id
,
unsigned
int
reg_offset
);
#endif
/* __ASSEMBLY__ */
#endif
/* CCN_H */
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