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
4531d3c9
Commit
4531d3c9
authored
Sep 12, 2016
by
davidcunado-arm
Committed by
GitHub
Sep 12, 2016
Browse files
Merge pull request #698 from rockchip-linux/set-APIO-for-rk3399
Set apio for rk3399
parents
048d802a
2bff35bb
Changes
6
Hide whitespace changes
Inline
Side-by-side
plat/rockchip/common/include/plat_params.h
View file @
4531d3c9
...
@@ -63,11 +63,31 @@
...
@@ -63,11 +63,31 @@
* alignment fault will occur during accessing its data member.
* alignment fault will occur during accessing its data member.
*/
*/
#define BL31_GPIO_DIR_OUT 0
#define BL31_GPIO_DIR_IN 1
#define BL31_GPIO_LEVEL_LOW 0
#define BL31_GPIO_LEVEL_HIGH 1
#define BL31_GPIO_PULL_NONE 0
#define BL31_GPIO_PULL_UP 1
#define BL31_GPIO_PULL_DOWN 2
/* param type */
/* param type */
enum
{
enum
{
PARAM_NONE
=
0
,
PARAM_NONE
=
0
,
PARAM_RESET
,
PARAM_RESET
,
PARAM_POWEROFF
,
PARAM_POWEROFF
,
PARAM_SUSPEND_GPIO
,
PARAM_SUSPEND_APIO
,
};
struct
apio_info
{
uint8_t
apio1
:
1
;
uint8_t
apio2
:
1
;
uint8_t
apio3
:
1
;
uint8_t
apio4
:
1
;
uint8_t
apio5
:
1
;
};
};
struct
gpio_info
{
struct
gpio_info
{
...
@@ -88,4 +108,9 @@ struct bl31_gpio_param {
...
@@ -88,4 +108,9 @@ struct bl31_gpio_param {
struct
gpio_info
gpio
;
struct
gpio_info
gpio
;
};
};
struct
bl31_apio_param
{
struct
bl31_plat_param
h
;
struct
apio_info
apio
;
};
#endif
/* __PLAT_PARAMS_H__ */
#endif
/* __PLAT_PARAMS_H__ */
plat/rockchip/common/include/plat_private.h
View file @
4531d3c9
...
@@ -121,8 +121,10 @@ uintptr_t plat_get_sec_entrypoint(void);
...
@@ -121,8 +121,10 @@ uintptr_t plat_get_sec_entrypoint(void);
void
platform_cpu_warmboot
(
void
);
void
platform_cpu_warmboot
(
void
);
void
*
plat_get_rockchip_gpio_reset
(
void
);
struct
gpio_info
*
plat_get_rockchip_gpio_reset
(
void
);
void
*
plat_get_rockchip_gpio_poweroff
(
void
);
struct
gpio_info
*
plat_get_rockchip_gpio_poweroff
(
void
);
struct
gpio_info
*
plat_get_rockchip_suspend_gpio
(
uint32_t
*
count
);
struct
apio_info
*
plat_get_rockchip_suspend_apio
(
void
);
void
plat_rockchip_gpio_init
(
void
);
void
plat_rockchip_gpio_init
(
void
);
extern
const
unsigned
char
rockchip_power_domain_tree_desc
[];
extern
const
unsigned
char
rockchip_power_domain_tree_desc
[];
...
...
plat/rockchip/common/params_setup.c
View file @
4531d3c9
...
@@ -40,25 +40,39 @@
...
@@ -40,25 +40,39 @@
#include <plat_private.h>
#include <plat_private.h>
#include <string.h>
#include <string.h>
static
struct
bl31_plat_param
*
bl31_params_head
;
static
struct
gpio_info
param_reset
;
static
struct
bl31_gpio_param
param_reset
;
static
struct
gpio_info
param_poweroff
;
static
struct
bl31_
g
pio_param
param_
poweroff
;
static
struct
bl31_
a
pio_param
param_
apio
;
static
struct
gpio_info
*
rst_gpio
;
static
struct
gpio_info
*
rst_gpio
;
static
struct
gpio_info
*
poweroff_gpio
;
static
struct
gpio_info
*
poweroff_gpio
;
static
struct
gpio_info
suspend_gpio
[
10
];
uint32_t
suspend_gpio_cnt
;
static
struct
apio_info
*
suspend_apio
;
void
*
plat_get_rockchip_gpio_reset
(
void
)
struct
gpio_info
*
plat_get_rockchip_gpio_reset
(
void
)
{
{
return
rst_gpio
;
return
rst_gpio
;
}
}
void
*
plat_get_rockchip_gpio_poweroff
(
void
)
struct
gpio_info
*
plat_get_rockchip_gpio_poweroff
(
void
)
{
{
return
poweroff_gpio
;
return
poweroff_gpio
;
}
}
struct
gpio_info
*
plat_get_rockchip_suspend_gpio
(
uint32_t
*
count
)
{
*
count
=
suspend_gpio_cnt
;
return
&
suspend_gpio
[
0
];
}
struct
apio_info
*
plat_get_rockchip_suspend_apio
(
void
)
{
return
suspend_apio
;
}
void
params_early_setup
(
void
*
plat_param_from_bl2
)
void
params_early_setup
(
void
*
plat_param_from_bl2
)
{
{
struct
bl31_plat_param
*
param
;
struct
bl31_plat_param
*
bl2_param
;
struct
bl31_plat_param
*
bl2_param
;
struct
bl31_gpio_param
*
gpio_param
;
struct
bl31_gpio_param
*
gpio_param
;
...
@@ -67,25 +81,38 @@ void params_early_setup(void *plat_param_from_bl2)
...
@@ -67,25 +81,38 @@ void params_early_setup(void *plat_param_from_bl2)
while
(
bl2_param
)
{
while
(
bl2_param
)
{
switch
(
bl2_param
->
type
)
{
switch
(
bl2_param
->
type
)
{
case
PARAM_RESET
:
case
PARAM_RESET
:
param
=
(
struct
bl31_plat_param
*
)
&
param_reset
;
gpio_param
=
(
struct
bl31_gpio_param
*
)
bl2_param
;
memcpy
((
void
*
)
param
,
(
void
*
)
bl2_param
,
memcpy
(
&
param_reset
,
&
gpio_param
->
gpio
,
sizeof
(
struct
bl31_gpio_param
));
sizeof
(
struct
gpio_info
));
gpio_param
=
(
struct
bl31_gpio_param
*
)
param
;
rst_gpio
=
&
param_reset
;
rst_gpio
=
&
gpio_param
->
gpio
;
break
;
break
;
case
PARAM_POWEROFF
:
case
PARAM_POWEROFF
:
param
=
(
struct
bl31_plat_param
*
)
&
param_poweroff
;
gpio_param
=
(
struct
bl31_gpio_param
*
)
bl2_param
;
memcpy
((
void
*
)
param
,
(
void
*
)
bl2_param
,
memcpy
(
&
param_poweroff
,
&
gpio_param
->
gpio
,
sizeof
(
struct
bl31_gpio_param
));
sizeof
(
struct
gpio_info
));
gpio_param
=
(
struct
bl31_gpio_param
*
)
param
;
poweroff_gpio
=
&
param_poweroff
;
poweroff_gpio
=
&
gpio_param
->
gpio
;
break
;
case
PARAM_SUSPEND_GPIO
:
if
(
suspend_gpio_cnt
>=
ARRAY_SIZE
(
suspend_gpio
))
{
ERROR
(
"exceed support suspend gpio number
\n
"
);
break
;
}
gpio_param
=
(
struct
bl31_gpio_param
*
)
bl2_param
;
memcpy
(
&
suspend_gpio
[
suspend_gpio_cnt
],
&
gpio_param
->
gpio
,
sizeof
(
struct
gpio_info
));
suspend_gpio_cnt
++
;
break
;
case
PARAM_SUSPEND_APIO
:
memcpy
(
&
param_apio
,
bl2_param
,
sizeof
(
struct
bl31_apio_param
));
suspend_apio
=
&
param_apio
.
apio
;
break
;
break
;
default:
default:
NOTICE
(
"not expected type found
\n
"
);
ERROR
(
"not expected type found %ld
\n
"
,
return
;
/* don't continue if unexpected type found */
bl2_param
->
type
);
break
;
}
}
param
->
next
=
bl31_params_head
;
bl31_params_head
=
param
;
bl2_param
=
bl2_param
->
next
;
bl2_param
=
bl2_param
->
next
;
}
}
}
}
plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c
View file @
4531d3c9
...
@@ -52,48 +52,105 @@ uint32_t gpio_port[] = {
...
@@ -52,48 +52,105 @@ uint32_t gpio_port[] = {
#define PMU_GPIO_PORT0 0
#define PMU_GPIO_PORT0 0
#define PMU_GPIO_PORT1 1
#define PMU_GPIO_PORT1 1
#define GPIO_PORT2 2
#define GPIO_PORT3 3
#define GPIO_PORT4 4
#define PMU_GRF_GPIO0A_P 0x40
#define PMU_GRF_GPIO0A_P 0x40
#define GRF_GPIO2A_P 0xe040
#define GRF_GPIO2A_P 0xe040
#define GPIO_P_MASK 0x03
#define GPIO_P_MASK 0x03
/*
#define GET_GPIO_PORT(pin) (pin / 32)
* gpio clock disabled when not operate
#define GET_GPIO_NUM(pin) (pin % 32)
* so need to enable gpio clock before operate gpio
#define GET_GPIO_BANK(pin) ((pin % 32) / 8)
* after setting, need to disable gpio clock
#define GET_GPIO_ID(pin) ((pin % 32) % 8)
* gate 1: disable clock; 0: enable clock
*/
/* returns old clock state, enables clock, in order to do GPIO access
*/
static
void
gpio_
clk
(
int
gpio
,
uint32_t
gate
)
static
int
gpio_
get_clock
(
uint32_t
gpio_number
)
{
{
uint32_t
port
=
gpio
/
32
;
uint32_t
port
=
GET_GPIO_PORT
(
gpio_number
);
uint32_t
clock_state
=
0
;
assert
(
port
<
5
);
assert
(
port
<
5
);
switch
(
port
)
{
switch
(
port
)
{
case
0
:
case
PMU_GPIO_PORT0
:
clock_state
=
(
mmio_read_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATE_CON
(
1
))
>>
PCLK_GPIO0_GATE_SHIFT
)
&
0x01
;
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATE_CON
(
1
),
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATE_CON
(
1
),
BITS_WITH_WMASK
(
gate
,
CLK_GATE_MASK
,
BITS_WITH_WMASK
(
0
,
CLK_GATE_MASK
,
PCLK_GPIO0_GATE_SHIFT
));
PCLK_GPIO0_GATE_SHIFT
));
break
;
break
;
case
1
:
case
PMU_GPIO_PORT1
:
clock_state
=
(
mmio_read_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATE_CON
(
1
))
>>
PCLK_GPIO1_GATE_SHIFT
)
&
0x01
;
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATE_CON
(
1
),
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATE_CON
(
1
),
BITS_WITH_WMASK
(
gate
,
CLK_GATE_MASK
,
BITS_WITH_WMASK
(
0
,
CLK_GATE_MASK
,
PCLK_GPIO1_GATE_SHIFT
));
PCLK_GPIO1_GATE_SHIFT
));
break
;
break
;
case
2
:
case
GPIO_PORT2
:
clock_state
=
(
mmio_read_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
))
>>
PCLK_GPIO2_GATE_SHIFT
)
&
0x01
;
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
BITS_WITH_WMASK
(
gate
,
CLK_GATE_MASK
,
BITS_WITH_WMASK
(
0
,
CLK_GATE_MASK
,
PCLK_GPIO2_GATE_SHIFT
));
PCLK_GPIO2_GATE_SHIFT
));
break
;
break
;
case
3
:
case
GPIO_PORT3
:
clock_state
=
(
mmio_read_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
))
>>
PCLK_GPIO3_GATE_SHIFT
)
&
0x01
;
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
BITS_WITH_WMASK
(
gate
,
CLK_GATE_MASK
,
BITS_WITH_WMASK
(
0
,
CLK_GATE_MASK
,
PCLK_GPIO3_GATE_SHIFT
));
PCLK_GPIO3_GATE_SHIFT
));
break
;
case
GPIO_PORT4
:
clock_state
=
(
mmio_read_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
))
>>
PCLK_GPIO4_GATE_SHIFT
)
&
0x01
;
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
BITS_WITH_WMASK
(
0
,
CLK_GATE_MASK
,
PCLK_GPIO4_GATE_SHIFT
));
break
;
default:
break
;
}
return
clock_state
;
}
/* restores old state of gpio clock */
void
gpio_put_clock
(
uint32_t
gpio_number
,
uint32_t
clock_state
)
{
uint32_t
port
=
GET_GPIO_PORT
(
gpio_number
);
switch
(
port
)
{
case
PMU_GPIO_PORT0
:
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATE_CON
(
1
),
BITS_WITH_WMASK
(
clock_state
,
CLK_GATE_MASK
,
PCLK_GPIO0_GATE_SHIFT
));
break
;
case
PMU_GPIO_PORT1
:
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATE_CON
(
1
),
BITS_WITH_WMASK
(
clock_state
,
CLK_GATE_MASK
,
PCLK_GPIO1_GATE_SHIFT
));
break
;
case
GPIO_PORT2
:
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
BITS_WITH_WMASK
(
clock_state
,
CLK_GATE_MASK
,
PCLK_GPIO2_GATE_SHIFT
));
break
;
break
;
case
4
:
case
GPIO_PORT3
:
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
BITS_WITH_WMASK
(
gate
,
CLK_GATE_MASK
,
BITS_WITH_WMASK
(
clock_state
,
CLK_GATE_MASK
,
PCLK_GPIO3_GATE_SHIFT
));
break
;
case
GPIO_PORT4
:
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
BITS_WITH_WMASK
(
clock_state
,
CLK_GATE_MASK
,
PCLK_GPIO4_GATE_SHIFT
));
PCLK_GPIO4_GATE_SHIFT
));
break
;
break
;
default:
default:
...
@@ -101,16 +158,58 @@ static void gpio_clk(int gpio, uint32_t gate)
...
@@ -101,16 +158,58 @@ static void gpio_clk(int gpio, uint32_t gate)
}
}
}
}
static
int
get_pull
(
int
gpio
)
{
uint32_t
port
=
GET_GPIO_PORT
(
gpio
);
uint32_t
bank
=
GET_GPIO_BANK
(
gpio
);
uint32_t
id
=
GET_GPIO_ID
(
gpio
);
uint32_t
val
,
clock_state
;
assert
((
port
<
5
)
&&
(
bank
<
4
));
clock_state
=
gpio_get_clock
(
gpio
);
if
(
port
==
PMU_GPIO_PORT0
||
port
==
PMU_GPIO_PORT1
)
{
val
=
mmio_read_32
(
PMUGRF_BASE
+
PMU_GRF_GPIO0A_P
+
port
*
16
+
bank
*
4
);
val
=
(
val
>>
(
id
*
2
))
&
GPIO_P_MASK
;
}
else
{
val
=
mmio_read_32
(
GRF_BASE
+
GRF_GPIO2A_P
+
(
port
-
2
)
*
16
+
bank
*
4
);
val
=
(
val
>>
(
id
*
2
))
&
GPIO_P_MASK
;
}
gpio_put_clock
(
gpio
,
clock_state
);
/*
* in gpio0a, gpio0b, gpio2c, gpio2d,
* 00: Z
* 01: pull down
* 10: Z
* 11: pull up
* different with other gpio, so need to correct it
*/
if
(((
port
==
0
)
&&
(
bank
<
2
))
||
((
port
==
2
)
&&
(
bank
>
1
)))
{
if
(
val
==
3
)
val
=
GPIO_PULL_UP
;
else
if
(
val
==
1
)
val
=
GPIO_PULL_DOWN
;
else
val
=
0
;
}
return
val
;
}
static
void
set_pull
(
int
gpio
,
int
pull
)
static
void
set_pull
(
int
gpio
,
int
pull
)
{
{
uint32_t
port
=
gpio
/
32
;
uint32_t
port
=
GET_GPIO_PORT
(
gpio
)
;
uint32_t
num
=
gpio
%
32
;
uint32_t
bank
=
GET_GPIO_BANK
(
gpio
)
;
uint32_t
bank
=
num
/
8
;
uint32_t
id
=
GET_GPIO_ID
(
gpio
)
;
uint32_t
id
=
num
%
8
;
uint32_t
clock_state
;
assert
((
port
<
5
)
&&
(
num
<
32
));
assert
((
port
<
5
)
&&
(
bank
<
4
));
gpio
_clk
(
gpio
,
0
);
clock_state
=
gpio_get
_cl
oc
k
(
gpio
);
/*
/*
* in gpio0a, gpio0b, gpio2c, gpio2d,
* in gpio0a, gpio0b, gpio2c, gpio2d,
...
@@ -120,7 +219,7 @@ static void set_pull(int gpio, int pull)
...
@@ -120,7 +219,7 @@ static void set_pull(int gpio, int pull)
* 11: pull up
* 11: pull up
* different with other gpio, so need to correct it
* different with other gpio, so need to correct it
*/
*/
if
(((
port
==
0
)
&&
(
bank
<
2
))
||
((
port
==
2
)
&&
(
bank
>
2
)))
{
if
(((
port
==
0
)
&&
(
bank
<
2
))
||
((
port
==
2
)
&&
(
bank
>
1
)))
{
if
(
pull
==
GPIO_PULL_UP
)
if
(
pull
==
GPIO_PULL_UP
)
pull
=
3
;
pull
=
3
;
else
if
(
pull
==
GPIO_PULL_DOWN
)
else
if
(
pull
==
GPIO_PULL_DOWN
)
...
@@ -138,17 +237,18 @@ static void set_pull(int gpio, int pull)
...
@@ -138,17 +237,18 @@ static void set_pull(int gpio, int pull)
(
port
-
2
)
*
16
+
bank
*
4
,
(
port
-
2
)
*
16
+
bank
*
4
,
BITS_WITH_WMASK
(
pull
,
GPIO_P_MASK
,
id
*
2
));
BITS_WITH_WMASK
(
pull
,
GPIO_P_MASK
,
id
*
2
));
}
}
gpio_
clk
(
gpio
,
1
);
gpio_
put_clock
(
gpio
,
clock_state
);
}
}
static
void
set_direction
(
int
gpio
,
int
direction
)
static
void
set_direction
(
int
gpio
,
int
direction
)
{
{
uint32_t
port
=
gpio
/
32
;
uint32_t
port
=
GET_GPIO_PORT
(
gpio
);
uint32_t
num
=
gpio
%
32
;
uint32_t
num
=
GET_GPIO_NUM
(
gpio
);
uint32_t
clock_state
;
assert
((
port
<
5
)
&&
(
num
<
32
));
assert
((
port
<
5
)
&&
(
num
<
32
));
gpio
_clk
(
gpio
,
0
);
clock_state
=
gpio_get
_cl
oc
k
(
gpio
);
/*
/*
* in gpio.h
* in gpio.h
...
@@ -158,18 +258,18 @@ static void set_direction(int gpio, int direction)
...
@@ -158,18 +258,18 @@ static void set_direction(int gpio, int direction)
* so need to revert direction value
* so need to revert direction value
*/
*/
mmio_setbits_32
(
gpio_port
[
port
]
+
SWPORTA_DDR
,
!
direction
<<
num
);
mmio_setbits_32
(
gpio_port
[
port
]
+
SWPORTA_DDR
,
!
direction
<<
num
);
gpio_
clk
(
gpio
,
1
);
gpio_
put_clock
(
gpio
,
clock_state
);
}
}
static
int
get_direction
(
int
gpio
)
static
int
get_direction
(
int
gpio
)
{
{
uint32_t
port
=
gpio
/
32
;
uint32_t
port
=
GET_GPIO_PORT
(
gpio
)
;
uint32_t
num
=
gpio
%
32
;
uint32_t
num
=
GET_GPIO_NUM
(
gpio
)
;
int
direction
;
int
direction
,
clock_state
;
assert
((
port
<
5
)
&&
(
num
<
32
));
assert
((
port
<
5
)
&&
(
num
<
32
));
gpio
_clk
(
gpio
,
0
);
clock_state
=
gpio_get
_cl
oc
k
(
gpio
);
/*
/*
* in gpio.h
* in gpio.h
...
@@ -180,37 +280,38 @@ static int get_direction(int gpio)
...
@@ -180,37 +280,38 @@ static int get_direction(int gpio)
*/
*/
direction
=
!
((
mmio_read_32
(
gpio_port
[
port
]
+
direction
=
!
((
mmio_read_32
(
gpio_port
[
port
]
+
SWPORTA_DDR
)
>>
num
)
&
0x1
);
SWPORTA_DDR
)
>>
num
)
&
0x1
);
gpio_
clk
(
gpio
,
1
);
gpio_
put_clock
(
gpio
,
clock_state
);
return
direction
;
return
direction
;
}
}
static
int
get_value
(
int
gpio
)
static
int
get_value
(
int
gpio
)
{
{
uint32_t
port
=
gpio
/
32
;
uint32_t
port
=
GET_GPIO_PORT
(
gpio
)
;
uint32_t
num
=
gpio
%
32
;
uint32_t
num
=
GET_GPIO_NUM
(
gpio
)
;
int
value
;
int
value
,
clock_state
;
assert
((
port
<
5
)
&&
(
num
<
32
));
assert
((
port
<
5
)
&&
(
num
<
32
));
gpio
_clk
(
gpio
,
0
);
clock_state
=
gpio_get
_cl
oc
k
(
gpio
);
value
=
(
mmio_read_32
(
gpio_port
[
port
]
+
EXT_PORTA
)
>>
num
)
&
0x1
;
value
=
(
mmio_read_32
(
gpio_port
[
port
]
+
EXT_PORTA
)
>>
num
)
&
0x1
;
gpio_
clk
(
gpio
,
1
);
gpio_
put_clock
(
gpio
,
clock_state
);
return
value
;
return
value
;
}
}
static
void
set_value
(
int
gpio
,
int
value
)
static
void
set_value
(
int
gpio
,
int
value
)
{
{
uint32_t
port
=
gpio
/
32
;
uint32_t
port
=
GET_GPIO_PORT
(
gpio
);
uint32_t
num
=
gpio
%
32
;
uint32_t
num
=
GET_GPIO_NUM
(
gpio
);
uint32_t
clock_state
;
assert
((
port
<
5
)
&&
(
num
<
32
));
assert
((
port
<
5
)
&&
(
num
<
32
));
gpio
_clk
(
gpio
,
0
);
clock_state
=
gpio_get
_cl
oc
k
(
gpio
);
mmio_clrsetbits_32
(
gpio_port
[
port
]
+
SWPORTA_DR
,
1
<<
num
,
mmio_clrsetbits_32
(
gpio_port
[
port
]
+
SWPORTA_DR
,
1
<<
num
,
!!
value
<<
num
);
!!
value
<<
num
);
gpio_
clk
(
gpio
,
0
);
gpio_
put_clock
(
gpio
,
clock_state
);
}
}
const
gpio_ops_t
rk3399_gpio_ops
=
{
const
gpio_ops_t
rk3399_gpio_ops
=
{
...
@@ -219,6 +320,7 @@ const gpio_ops_t rk3399_gpio_ops = {
...
@@ -219,6 +320,7 @@ const gpio_ops_t rk3399_gpio_ops = {
.
get_value
=
get_value
,
.
get_value
=
get_value
,
.
set_value
=
set_value
,
.
set_value
=
set_value
,
.
set_pull
=
set_pull
,
.
set_pull
=
set_pull
,
.
get_pull
=
get_pull
,
};
};
void
plat_rockchip_gpio_init
(
void
)
void
plat_rockchip_gpio_init
(
void
)
...
...
plat/rockchip/rk3399/drivers/pmu/pmu.c
View file @
4531d3c9
...
@@ -874,6 +874,190 @@ static void clr_hw_idle(uint32_t hw_idle)
...
@@ -874,6 +874,190 @@ static void clr_hw_idle(uint32_t hw_idle)
mmio_clrbits_32
(
PMU_BASE
+
PMU_BUS_CLR
,
hw_idle
);
mmio_clrbits_32
(
PMU_BASE
+
PMU_BUS_CLR
,
hw_idle
);
}
}
static
uint32_t
iomux_status
[
12
];
static
uint32_t
pull_mode_status
[
12
];
static
uint32_t
gpio_direction
[
3
];
static
uint32_t
gpio_2_4_clk_gate
;
static
void
suspend_apio
(
void
)
{
struct
apio_info
*
suspend_apio
;
int
i
;
suspend_apio
=
plat_get_rockchip_suspend_apio
();
if
(
!
suspend_apio
)
return
;
/* save gpio2 ~ gpio4 iomux and pull mode */
for
(
i
=
0
;
i
<
12
;
i
++
)
{
iomux_status
[
i
]
=
mmio_read_32
(
GRF_BASE
+
GRF_GPIO2A_IOMUX
+
i
*
4
);
pull_mode_status
[
i
]
=
mmio_read_32
(
GRF_BASE
+
GRF_GPIO2A_P
+
i
*
4
);
}
/* store gpio2 ~ gpio4 clock gate state */
gpio_2_4_clk_gate
=
(
mmio_read_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
))
>>
PCLK_GPIO2_GATE_SHIFT
)
&
0x07
;
/* enable gpio2 ~ gpio4 clock gate */
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
BITS_WITH_WMASK
(
0
,
0x07
,
PCLK_GPIO2_GATE_SHIFT
));
/* save gpio2 ~ gpio4 direction */
gpio_direction
[
0
]
=
mmio_read_32
(
GPIO2_BASE
+
0x04
);
gpio_direction
[
1
]
=
mmio_read_32
(
GPIO3_BASE
+
0x04
);
gpio_direction
[
2
]
=
mmio_read_32
(
GPIO4_BASE
+
0x04
);
/* apio1 charge gpio3a0 ~ gpio3c7 */
if
(
suspend_apio
->
apio1
)
{
/* set gpio3a0 ~ gpio3c7 iomux to gpio */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO3A_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO3B_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO3C_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
/* set gpio3a0 ~ gpio3c7 pull mode to pull none */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO3A_P
,
REG_SOC_WMSK
|
0
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO3B_P
,
REG_SOC_WMSK
|
0
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO3C_P
,
REG_SOC_WMSK
|
0
);
/* set gpio3a0 ~ gpio3c7 to input */
mmio_clrbits_32
(
GPIO3_BASE
+
0x04
,
0x00ffffff
);
}
/* apio2 charge gpio2a0 ~ gpio2b4 */
if
(
suspend_apio
->
apio2
)
{
/* set gpio2a0 ~ gpio2b4 iomux to gpio */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2A_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2B_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
/* set gpio2a0 ~ gpio2b4 pull mode to pull none */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2A_P
,
REG_SOC_WMSK
|
0
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2B_P
,
REG_SOC_WMSK
|
0
);
/* set gpio2a0 ~ gpio2b4 to input */
mmio_clrbits_32
(
GPIO2_BASE
+
0x04
,
0x00001fff
);
}
/* apio3 charge gpio2c0 ~ gpio2d4*/
if
(
suspend_apio
->
apio3
)
{
/* set gpio2a0 ~ gpio2b4 iomux to gpio */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2C_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2D_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
/* set gpio2c0 ~ gpio2d4 pull mode to pull none */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2C_P
,
REG_SOC_WMSK
|
0
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2D_P
,
REG_SOC_WMSK
|
0
);
/* set gpio2c0 ~ gpio2d4 to input */
mmio_clrbits_32
(
GPIO2_BASE
+
0x04
,
0x1fff0000
);
}
/* apio4 charge gpio4c0 ~ gpio4c7, gpio4d0 ~ gpio4d6 */
if
(
suspend_apio
->
apio4
)
{
/* set gpio4c0 ~ gpio4d6 iomux to gpio */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO4C_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO4D_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
/* set gpio4c0 ~ gpio4d6 pull mode to pull none */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO4C_P
,
REG_SOC_WMSK
|
0
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO4D_P
,
REG_SOC_WMSK
|
0
);
/* set gpio4c0 ~ gpio4d6 to input */
mmio_clrbits_32
(
GPIO4_BASE
+
0x04
,
0x7fff0000
);
}
/* apio5 charge gpio3d0 ~ gpio3d7, gpio4a0 ~ gpio4a7*/
if
(
suspend_apio
->
apio5
)
{
/* set gpio3d0 ~ gpio4a7 iomux to gpio */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO3D_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO4A_IOMUX
,
REG_SOC_WMSK
|
GRF_IOMUX_GPIO
);
/* set gpio3d0 ~ gpio4a7 pull mode to pull none */
mmio_write_32
(
GRF_BASE
+
GRF_GPIO3D_P
,
REG_SOC_WMSK
|
0
);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO4A_P
,
REG_SOC_WMSK
|
0
);
/* set gpio4c0 ~ gpio4d6 to input */
mmio_clrbits_32
(
GPIO3_BASE
+
0x04
,
0xff000000
);
mmio_clrbits_32
(
GPIO4_BASE
+
0x04
,
0x000000ff
);
}
}
static
void
resume_apio
(
void
)
{
struct
apio_info
*
suspend_apio
;
int
i
;
suspend_apio
=
plat_get_rockchip_suspend_apio
();
if
(
!
suspend_apio
)
return
;
for
(
i
=
0
;
i
<
12
;
i
++
)
{
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2A_P
+
i
*
4
,
REG_SOC_WMSK
|
pull_mode_status
[
i
]);
mmio_write_32
(
GRF_BASE
+
GRF_GPIO2A_IOMUX
+
i
*
4
,
REG_SOC_WMSK
|
iomux_status
[
i
]);
}
/* set gpio2 ~ gpio4 direction back to store value */
mmio_write_32
(
GPIO2_BASE
+
0x04
,
gpio_direction
[
0
]);
mmio_write_32
(
GPIO3_BASE
+
0x04
,
gpio_direction
[
1
]);
mmio_write_32
(
GPIO4_BASE
+
0x04
,
gpio_direction
[
2
]);
/* set gpio2 ~ gpio4 clock gate back to store value */
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
31
),
BITS_WITH_WMASK
(
gpio_2_4_clk_gate
,
0x07
,
PCLK_GPIO2_GATE_SHIFT
));
}
static
void
suspend_gpio
(
void
)
{
struct
gpio_info
*
suspend_gpio
;
uint32_t
count
;
int
i
;
suspend_gpio
=
plat_get_rockchip_suspend_gpio
(
&
count
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
gpio_set_value
(
suspend_gpio
[
i
].
index
,
suspend_gpio
[
i
].
polarity
);
gpio_set_direction
(
suspend_gpio
[
i
].
index
,
GPIO_DIR_OUT
);
udelay
(
1
);
}
}
static
void
resume_gpio
(
void
)
{
struct
gpio_info
*
suspend_gpio
;
uint32_t
count
;
int
i
;
suspend_gpio
=
plat_get_rockchip_suspend_gpio
(
&
count
);
for
(
i
=
count
-
1
;
i
>=
0
;
i
--
)
{
gpio_set_value
(
suspend_gpio
[
i
].
index
,
!
suspend_gpio
[
i
].
polarity
);
gpio_set_direction
(
suspend_gpio
[
i
].
index
,
GPIO_DIR_OUT
);
udelay
(
1
);
}
}
static
int
sys_pwr_domain_suspend
(
void
)
static
int
sys_pwr_domain_suspend
(
void
)
{
{
uint32_t
wait_cnt
=
0
;
uint32_t
wait_cnt
=
0
;
...
@@ -919,7 +1103,6 @@ static int sys_pwr_domain_suspend(void)
...
@@ -919,7 +1103,6 @@ static int sys_pwr_domain_suspend(void)
}
}
}
}
mmio_setbits_32
(
PMU_BASE
+
PMU_PWRDN_CON
,
BIT
(
PMU_SCU_B_PWRDWN_EN
));
mmio_setbits_32
(
PMU_BASE
+
PMU_PWRDN_CON
,
BIT
(
PMU_SCU_B_PWRDWN_EN
));
/*
/*
* Disabling PLLs/PWM/DVFS is approaching WFI which is
* Disabling PLLs/PWM/DVFS is approaching WFI which is
* the last steps in suspend.
* the last steps in suspend.
...
@@ -928,6 +1111,8 @@ static int sys_pwr_domain_suspend(void)
...
@@ -928,6 +1111,8 @@ static int sys_pwr_domain_suspend(void)
disable_dvfs_plls
();
disable_dvfs_plls
();
disable_pwms
();
disable_pwms
();
disable_nodvfs_plls
();
disable_nodvfs_plls
();
suspend_apio
();
suspend_gpio
();
return
0
;
return
0
;
}
}
...
@@ -937,6 +1122,8 @@ static int sys_pwr_domain_resume(void)
...
@@ -937,6 +1122,8 @@ static int sys_pwr_domain_resume(void)
uint32_t
wait_cnt
=
0
;
uint32_t
wait_cnt
=
0
;
uint32_t
status
=
0
;
uint32_t
status
=
0
;
resume_apio
();
resume_gpio
();
enable_nodvfs_plls
();
enable_nodvfs_plls
();
enable_pwms
();
enable_pwms
();
/* PWM regulators take time to come up; give 300us to be safe. */
/* PWM regulators take time to come up; give 300us to be safe. */
...
@@ -952,7 +1139,6 @@ static int sys_pwr_domain_resume(void)
...
@@ -952,7 +1139,6 @@ static int sys_pwr_domain_resume(void)
* somewhere.
* somewhere.
*/
*/
mmio_write_32
(
PMU_BASE
+
PMU_WAKEUP_STATUS
,
0xffffffff
);
mmio_write_32
(
PMU_BASE
+
PMU_WAKEUP_STATUS
,
0xffffffff
);
mmio_write_32
(
PMU_BASE
+
PMU_WKUP_CFG4
,
0x00
);
mmio_write_32
(
PMU_BASE
+
PMU_WKUP_CFG4
,
0x00
);
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON0_1
(
1
),
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON0_1
(
1
),
...
@@ -1010,7 +1196,7 @@ void __dead2 soc_soft_reset(void)
...
@@ -1010,7 +1196,7 @@ void __dead2 soc_soft_reset(void)
{
{
struct
gpio_info
*
rst_gpio
;
struct
gpio_info
*
rst_gpio
;
rst_gpio
=
(
struct
gpio_info
*
)
plat_get_rockchip_gpio_reset
();
rst_gpio
=
plat_get_rockchip_gpio_reset
();
if
(
rst_gpio
)
{
if
(
rst_gpio
)
{
gpio_set_direction
(
rst_gpio
->
index
,
GPIO_DIR_OUT
);
gpio_set_direction
(
rst_gpio
->
index
,
GPIO_DIR_OUT
);
...
@@ -1027,7 +1213,7 @@ void __dead2 soc_system_off(void)
...
@@ -1027,7 +1213,7 @@ void __dead2 soc_system_off(void)
{
{
struct
gpio_info
*
poweroff_gpio
;
struct
gpio_info
*
poweroff_gpio
;
poweroff_gpio
=
(
struct
gpio_info
*
)
plat_get_rockchip_gpio_poweroff
();
poweroff_gpio
=
plat_get_rockchip_gpio_poweroff
();
if
(
poweroff_gpio
)
{
if
(
poweroff_gpio
)
{
/*
/*
...
...
plat/rockchip/rk3399/drivers/pmu/pmu.h
View file @
4531d3c9
...
@@ -875,7 +875,32 @@ enum pmu_core_pwr_st {
...
@@ -875,7 +875,32 @@ enum pmu_core_pwr_st {
#define MAX_WAIT_COUNT 1000
#define MAX_WAIT_COUNT 1000
#define GRF_SOC_CON4 0x0e210
#define GRF_SOC_CON4 0x0e210
#define GRF_GPIO4C_IOMUX 0x0e028
#define GRF_GPIO2A_IOMUX 0xe000
#define GRF_GPIO2B_IOMUX 0xe004
#define GRF_GPIO2C_IOMUX 0xe008
#define GRF_GPIO2D_IOMUX 0xe00c
#define GRF_GPIO3A_IOMUX 0xe010
#define GRF_GPIO3B_IOMUX 0xe014
#define GRF_GPIO3C_IOMUX 0xe018
#define GRF_GPIO3D_IOMUX 0xe01c
#define GRF_GPIO4A_IOMUX 0xe020
#define GRF_GPIO4B_IOMUX 0xe024
#define GRF_GPIO4C_IOMUX 0xe028
#define GRF_GPIO4D_IOMUX 0xe02c
#define GRF_GPIO2A_P 0xe040
#define GRF_GPIO2B_P 0xe044
#define GRF_GPIO2C_P 0xe048
#define GRF_GPIO2D_P 0xe04C
#define GRF_GPIO3A_P 0xe050
#define GRF_GPIO3B_P 0xe054
#define GRF_GPIO3C_P 0xe058
#define GRF_GPIO3D_P 0xe05C
#define GRF_GPIO4A_P 0xe060
#define GRF_GPIO4B_P 0xe064
#define GRF_GPIO4C_P 0xe068
#define GRF_GPIO4D_P 0xe06C
#define PMUGRF_GPIO0A_SMT 0x0120
#define PMUGRF_GPIO0A_SMT 0x0120
#define PMUGRF_SOC_CON0 0x0180
#define PMUGRF_SOC_CON0 0x0180
...
...
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