Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
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
d4dcadb0
Unverified
Commit
d4dcadb0
authored
6 years ago
by
Antonio Niño Díaz
Committed by
GitHub
6 years ago
Browse files
Options
Download
Plain Diff
Merge pull request #1773 from grandpaul/rpi3-gpio-driver
Rpi3 gpio driver
parents
83a2285e
2be86dd3
master
v2.5
v2.5-rc1
v2.5-rc0
v2.4
v2.4-rc2
v2.4-rc1
v2.4-rc0
v2.3
v2.3-rc2
v2.3-rc1
v2.3-rc0
v2.2
v2.2-rc2
v2.2-rc1
v2.2-rc0
v2.1
v2.1-rc1
v2.1-rc0
arm_cca_v0.2
arm_cca_v0.1
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
drivers/rpi3/gpio/rpi3_gpio.c
+169
-0
drivers/rpi3/gpio/rpi3_gpio.c
include/drivers/rpi3/gpio/rpi3_gpio.h
+38
-0
include/drivers/rpi3/gpio/rpi3_gpio.h
plat/rpi3/platform.mk
+4
-0
plat/rpi3/platform.mk
plat/rpi3/rpi3_bl2_setup.c
+19
-0
plat/rpi3/rpi3_bl2_setup.c
plat/rpi3/rpi3_hw.h
+6
-0
plat/rpi3/rpi3_hw.h
with
236 additions
and
0 deletions
+236
-0
drivers/rpi3/gpio/rpi3_gpio.c
0 → 100644
View file @
d4dcadb0
/*
* Copyright (c) 2019, Linaro Limited
* Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <string.h>
#include <assert.h>
#include <lib/mmio.h>
#include <drivers/delay_timer.h>
#include <drivers/rpi3/gpio/rpi3_gpio.h>
static
struct
rpi3_gpio_params
rpi3_gpio_params
;
static
int
rpi3_gpio_get_direction
(
int
gpio
);
static
void
rpi3_gpio_set_direction
(
int
gpio
,
int
direction
);
static
int
rpi3_gpio_get_value
(
int
gpio
);
static
void
rpi3_gpio_set_value
(
int
gpio
,
int
value
);
static
void
rpi3_gpio_set_pull
(
int
gpio
,
int
pull
);
static
const
gpio_ops_t
rpi3_gpio_ops
=
{
.
get_direction
=
rpi3_gpio_get_direction
,
.
set_direction
=
rpi3_gpio_set_direction
,
.
get_value
=
rpi3_gpio_get_value
,
.
set_value
=
rpi3_gpio_set_value
,
.
set_pull
=
rpi3_gpio_set_pull
,
};
/**
* Get selection of GPIO pinmux settings.
*
* @param gpio The pin number of GPIO. From 0 to 53.
* @return The selection of pinmux. RPI3_GPIO_FUNC_INPUT: input,
* RPI3_GPIO_FUNC_OUTPUT: output,
* RPI3_GPIO_FUNC_ALT0: alt-0,
* RPI3_GPIO_FUNC_ALT1: alt-1,
* RPI3_GPIO_FUNC_ALT2: alt-2,
* RPI3_GPIO_FUNC_ALT3: alt-3,
* RPI3_GPIO_FUNC_ALT4: alt-4,
* RPI3_GPIO_FUNC_ALT5: alt-5
*/
int
rpi3_gpio_get_select
(
int
gpio
)
{
int
ret
;
uintptr_t
reg_base
=
rpi3_gpio_params
.
reg_base
;
int
regN
=
gpio
/
10
;
int
shift
=
3
*
(
gpio
%
10
);
uintptr_t
reg_sel
=
reg_base
+
RPI3_GPIO_GPFSEL
(
regN
);
uint32_t
sel
=
mmio_read_32
(
reg_sel
);
ret
=
(
sel
>>
shift
)
&
0x07
;
return
ret
;
}
/**
* Set selection of GPIO pinmux settings.
*
* @param gpio The pin number of GPIO. From 0 to 53.
* @param fsel The selection of pinmux. RPI3_GPIO_FUNC_INPUT: input,
* RPI3_GPIO_FUNC_OUTPUT: output,
* RPI3_GPIO_FUNC_ALT0: alt-0,
* RPI3_GPIO_FUNC_ALT1: alt-1,
* RPI3_GPIO_FUNC_ALT2: alt-2,
* RPI3_GPIO_FUNC_ALT3: alt-3,
* RPI3_GPIO_FUNC_ALT4: alt-4,
* RPI3_GPIO_FUNC_ALT5: alt-5
*/
void
rpi3_gpio_set_select
(
int
gpio
,
int
fsel
)
{
uintptr_t
reg_base
=
rpi3_gpio_params
.
reg_base
;
int
regN
=
gpio
/
10
;
int
shift
=
3
*
(
gpio
%
10
);
uintptr_t
reg_sel
=
reg_base
+
RPI3_GPIO_GPFSEL
(
regN
);
uint32_t
sel
=
mmio_read_32
(
reg_sel
);
uint32_t
mask
=
U
(
0x07
)
<<
shift
;
sel
=
(
sel
&
(
~
mask
))
|
((
fsel
<<
shift
)
&
mask
);
mmio_write_32
(
reg_sel
,
sel
);
}
static
int
rpi3_gpio_get_direction
(
int
gpio
)
{
int
result
=
rpi3_gpio_get_select
(
gpio
);
if
(
result
==
RPI3_GPIO_FUNC_INPUT
)
return
GPIO_DIR_IN
;
else
if
(
result
==
RPI3_GPIO_FUNC_OUTPUT
)
return
GPIO_DIR_OUT
;
return
GPIO_DIR_IN
;
}
static
void
rpi3_gpio_set_direction
(
int
gpio
,
int
direction
)
{
switch
(
direction
)
{
case
GPIO_DIR_IN
:
rpi3_gpio_set_select
(
gpio
,
RPI3_GPIO_FUNC_INPUT
);
break
;
case
GPIO_DIR_OUT
:
rpi3_gpio_set_select
(
gpio
,
RPI3_GPIO_FUNC_OUTPUT
);
break
;
}
}
static
int
rpi3_gpio_get_value
(
int
gpio
)
{
uintptr_t
reg_base
=
rpi3_gpio_params
.
reg_base
;
int
regN
=
gpio
/
32
;
int
shift
=
gpio
%
32
;
uintptr_t
reg_lev
=
reg_base
+
RPI3_GPIO_GPLEV
(
regN
);
uint32_t
value
=
mmio_read_32
(
reg_lev
);
if
((
value
>>
shift
)
&
0x01
)
return
GPIO_LEVEL_HIGH
;
return
GPIO_LEVEL_LOW
;
}
static
void
rpi3_gpio_set_value
(
int
gpio
,
int
value
)
{
uintptr_t
reg_base
=
rpi3_gpio_params
.
reg_base
;
int
regN
=
gpio
/
32
;
int
shift
=
gpio
%
32
;
uintptr_t
reg_set
=
reg_base
+
RPI3_GPIO_GPSET
(
regN
);
uintptr_t
reg_clr
=
reg_base
+
RPI3_GPIO_GPSET
(
regN
);
switch
(
value
)
{
case
GPIO_LEVEL_LOW
:
mmio_write_32
(
reg_clr
,
U
(
1
)
<<
shift
);
break
;
case
GPIO_LEVEL_HIGH
:
mmio_write_32
(
reg_set
,
U
(
1
)
<<
shift
);
break
;
}
}
static
void
rpi3_gpio_set_pull
(
int
gpio
,
int
pull
)
{
uintptr_t
reg_base
=
rpi3_gpio_params
.
reg_base
;
int
regN
=
gpio
/
32
;
int
shift
=
gpio
%
32
;
uintptr_t
reg_pud
=
reg_base
+
RPI3_GPIO_GPPUD
;
uintptr_t
reg_clk
=
reg_base
+
RPI3_GPIO_GPPUDCLK
(
regN
);
switch
(
pull
)
{
case
GPIO_PULL_NONE
:
mmio_write_32
(
reg_pud
,
0x0
);
break
;
case
GPIO_PULL_UP
:
mmio_write_32
(
reg_pud
,
0x2
);
break
;
case
GPIO_PULL_DOWN
:
mmio_write_32
(
reg_pud
,
0x1
);
break
;
}
mdelay
(
150
);
mmio_write_32
(
reg_clk
,
U
(
1
)
<<
shift
);
mdelay
(
150
);
mmio_write_32
(
reg_clk
,
0x0
);
mmio_write_32
(
reg_pud
,
0x0
);
}
void
rpi3_gpio_init
(
struct
rpi3_gpio_params
*
params
)
{
assert
(
params
!=
0
);
memcpy
(
&
rpi3_gpio_params
,
params
,
sizeof
(
struct
rpi3_gpio_params
));
gpio_init
(
&
rpi3_gpio_ops
);
}
This diff is collapsed.
Click to expand it.
include/drivers/rpi3/gpio/rpi3_gpio.h
0 → 100644
View file @
d4dcadb0
/*
* Copyright (c) 2019, Linaro Limited
* Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RPI3_GPIO_H
#define RPI3_GPIO_H
#include <stdint.h>
#include <drivers/gpio.h>
struct
rpi3_gpio_params
{
uintptr_t
reg_base
;
};
void
rpi3_gpio_init
(
struct
rpi3_gpio_params
*
params
);
int
rpi3_gpio_get_select
(
int
gpio
);
void
rpi3_gpio_set_select
(
int
gpio
,
int
fsel
);
#define RPI3_GPIO_GPFSEL(n) ((n) * U(0x04))
#define RPI3_GPIO_GPSET(n) (((n) * U(0x04)) + U(0x1C))
#define RPI3_GPIO_GPCLR(n) (((n) * U(0x04)) + U(0x28))
#define RPI3_GPIO_GPLEV(n) (((n) * U(0x04)) + U(0x34))
#define RPI3_GPIO_GPPUD U(0x94)
#define RPI3_GPIO_GPPUDCLK(n) (((n) * U(0x04)) + U(0x98))
#define RPI3_GPIO_FUNC_INPUT U(0)
#define RPI3_GPIO_FUNC_OUTPUT U(1)
#define RPI3_GPIO_FUNC_ALT0 U(4)
#define RPI3_GPIO_FUNC_ALT1 U(5)
#define RPI3_GPIO_FUNC_ALT2 U(6)
#define RPI3_GPIO_FUNC_ALT3 U(7)
#define RPI3_GPIO_FUNC_ALT4 U(3)
#define RPI3_GPIO_FUNC_ALT5 U(2)
#endif
/* RPI3_GPIO_H */
This diff is collapsed.
Click to expand it.
plat/rpi3/platform.mk
View file @
d4dcadb0
...
...
@@ -27,6 +27,10 @@ BL2_SOURCES += common/desc_image_load.c \
drivers/io/io_fip.c
\
drivers/io/io_memmap.c
\
drivers/io/io_storage.c
\
drivers/gpio/gpio.c
\
drivers/delay_timer/delay_timer.c
\
drivers/delay_timer/generic_delay_timer.c
\
drivers/rpi3/gpio/rpi3_gpio.c
\
plat/common/aarch64/platform_mp_stack.S
\
plat/rpi3/aarch64/plat_helpers.S
\
plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c
\
...
...
This diff is collapsed.
Click to expand it.
plat/rpi3/rpi3_bl2_setup.c
View file @
d4dcadb0
...
...
@@ -15,12 +15,25 @@
#include <lib/optee_utils.h>
#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
#include <drivers/generic_delay_timer.h>
#include <drivers/rpi3/gpio/rpi3_gpio.h>
#include "rpi3_private.h"
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static
meminfo_t
bl2_tzram_layout
__aligned
(
CACHE_WRITEBACK_GRANULE
);
/* rpi3 GPIO setup function. */
static
void
rpi3_gpio_setup
(
void
)
{
struct
rpi3_gpio_params
params
;
memset
(
&
params
,
0
,
sizeof
(
struct
rpi3_gpio_params
));
params
.
reg_base
=
RPI3_GPIO_BASE
;
rpi3_gpio_init
(
&
params
);
}
/*******************************************************************************
* BL1 has passed the extents of the trusted SRAM that should be visible to BL2
* in x0. This memory layout is sitting at the base of the free trusted SRAM.
...
...
@@ -35,6 +48,12 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
/* Initialize the console to provide early debug support */
rpi3_console_init
();
/* Enable arch timer */
generic_delay_timer_init
();
/* Setup GPIO driver */
rpi3_gpio_setup
();
/* Setup the BL2 memory layout */
bl2_tzram_layout
=
*
mem_layout
;
...
...
This diff is collapsed.
Click to expand it.
plat/rpi3/rpi3_hw.h
View file @
d4dcadb0
...
...
@@ -83,6 +83,12 @@
#define RPI3_MINI_UART_BASE (RPI3_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
#define RPI3_MINI_UART_CLK_IN_HZ ULL(500000000)
/*
* GPIO controller
*/
#define RPI3_IO_GPIO_OFFSET ULL(0x00200000)
#define RPI3_GPIO_BASE (RPI3_IO_BASE + RPI3_IO_GPIO_OFFSET)
/*
* Local interrupt controller
*/
...
...
This diff is collapsed.
Click to expand it.
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
Menu
Projects
Groups
Snippets
Help