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
094a935d
Commit
094a935d
authored
Feb 22, 2016
by
danh-arm
Browse files
Merge pull request #518 from hzhuang1/pl061_gpio_v5
Pl061 gpio v5
parents
6f8016b8
7dc4b227
Changes
5
Hide whitespace changes
Inline
Side-by-side
docs/porting-guide.md
View file @
094a935d
...
...
@@ -476,6 +476,18 @@ memory layout implies some image overlaying like in ARM standard platforms.
Defines the maximum address that the TSP's progbits sections can occupy.
If the platform port uses the PL061 GPIO driver, the following constant may
optionally be defined:
*
**PLAT_PL061_MAX_GPIOS**
Maximum number of GPIOs required by the platform. This allows control how
much memory is allocated for PL061 GPIO controllers. The default value is
32.
[
For example, define the build flag in platform.mk
]:
PLAT_PL061_MAX_GPIOS
:= 160
$(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
### File : plat_macros.S [mandatory]
Each platform must ensure a file of this name is in the system include path with
...
...
drivers/arm/pl061/pl061_gpio.c
0 → 100644
View file @
094a935d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* ARM PL061 GPIO Driver.
* Reference to ARM DDI 0190B document.
*
*/
#include <assert.h>
#include <cassert.h>
#include <debug.h>
#include <errno.h>
#include <gpio.h>
#include <mmio.h>
#include <pl061_gpio.h>
#if !PLAT_PL061_MAX_GPIOS
# define PLAT_PL061_MAX_GPIOS 32
#endif
/* PLAT_PL061_MAX_GPIOS */
CASSERT
(
PLAT_PL061_MAX_GPIOS
>
0
,
assert_plat_pl061_max_gpios
);
#define MAX_GPIO_DEVICES ((PLAT_PL061_MAX_GPIOS + \
(GPIOS_PER_PL061 - 1)) / GPIOS_PER_PL061)
#define PL061_GPIO_DIR 0x400
#define GPIOS_PER_PL061 8
#define BIT(nr) (1UL << (nr))
static
int
pl061_get_direction
(
int
gpio
);
static
void
pl061_set_direction
(
int
gpio
,
int
direction
);
static
int
pl061_get_value
(
int
gpio
);
static
void
pl061_set_value
(
int
gpio
,
int
value
);
static
uintptr_t
pl061_reg_base
[
MAX_GPIO_DEVICES
];
static
const
gpio_ops_t
pl061_gpio_ops
=
{
.
get_direction
=
pl061_get_direction
,
.
set_direction
=
pl061_set_direction
,
.
get_value
=
pl061_get_value
,
.
set_value
=
pl061_set_value
,
};
static
int
pl061_get_direction
(
int
gpio
)
{
uintptr_t
base_addr
;
unsigned
int
data
,
offset
;
assert
((
gpio
>=
0
)
&&
(
gpio
<
PLAT_PL061_MAX_GPIOS
));
base_addr
=
pl061_reg_base
[
gpio
/
GPIOS_PER_PL061
];
offset
=
gpio
%
GPIOS_PER_PL061
;
data
=
mmio_read_8
(
base_addr
+
PL061_GPIO_DIR
);
if
(
data
&
BIT
(
offset
))
return
GPIO_DIR_OUT
;
return
GPIO_DIR_IN
;
}
static
void
pl061_set_direction
(
int
gpio
,
int
direction
)
{
uintptr_t
base_addr
;
unsigned
int
data
,
offset
;
assert
((
gpio
>=
0
)
&&
(
gpio
<
PLAT_PL061_MAX_GPIOS
));
base_addr
=
pl061_reg_base
[
gpio
/
GPIOS_PER_PL061
];
offset
=
gpio
%
GPIOS_PER_PL061
;
if
(
direction
==
GPIO_DIR_OUT
)
{
data
=
mmio_read_8
(
base_addr
+
PL061_GPIO_DIR
)
|
BIT
(
offset
);
mmio_write_8
(
base_addr
+
PL061_GPIO_DIR
,
data
);
}
else
{
data
=
mmio_read_8
(
base_addr
+
PL061_GPIO_DIR
)
&
~
BIT
(
offset
);
mmio_write_8
(
base_addr
+
PL061_GPIO_DIR
,
data
);
}
}
/*
* The offset of GPIODATA register is 0.
* The values read from GPIODATA are determined for each bit, by the mask bit
* derived from the address used to access the data register, PADDR[9:2].
* Bits that are 1 in the address mask cause the corresponding bits in GPIODATA
* to be read, and bits that are 0 in the address mask cause the corresponding
* bits in GPIODATA to be read as 0, regardless of their value.
*/
static
int
pl061_get_value
(
int
gpio
)
{
uintptr_t
base_addr
;
unsigned
int
offset
;
assert
((
gpio
>=
0
)
&&
(
gpio
<
PLAT_PL061_MAX_GPIOS
));
base_addr
=
pl061_reg_base
[
gpio
/
GPIOS_PER_PL061
];
offset
=
gpio
%
GPIOS_PER_PL061
;
if
(
mmio_read_8
(
base_addr
+
BIT
(
offset
+
2
)))
return
GPIO_LEVEL_HIGH
;
return
GPIO_LEVEL_LOW
;
}
/*
* In order to write GPIODATA, the corresponding bits in the mask, resulting
* from the address bus, PADDR[9:2], must be HIGH. Otherwise the bit values
* remain unchanged by the write.
*/
static
void
pl061_set_value
(
int
gpio
,
int
value
)
{
uintptr_t
base_addr
;
int
offset
;
assert
((
gpio
>=
0
)
&&
(
gpio
<
PLAT_PL061_MAX_GPIOS
));
base_addr
=
pl061_reg_base
[
gpio
/
GPIOS_PER_PL061
];
offset
=
gpio
%
GPIOS_PER_PL061
;
if
(
value
==
GPIO_LEVEL_HIGH
)
mmio_write_8
(
base_addr
+
BIT
(
offset
+
2
),
BIT
(
offset
));
else
mmio_write_8
(
base_addr
+
BIT
(
offset
+
2
),
0
);
}
/*
* Register the PL061 GPIO controller with a base address and the offset
* of start pin in this GPIO controller.
* This function is called after pl061_gpio_ops_init().
*/
void
pl061_gpio_register
(
uintptr_t
base_addr
,
int
gpio_dev
)
{
assert
((
gpio_dev
>=
0
)
&&
(
gpio_dev
<
MAX_GPIO_DEVICES
));
pl061_reg_base
[
gpio_dev
]
=
base_addr
;
}
/*
* Initialize PL061 GPIO controller with the total GPIO numbers in SoC.
*/
void
pl061_gpio_init
(
void
)
{
gpio_init
(
&
pl061_gpio_ops
);
}
drivers/gpio/gpio.c
0 → 100644
View file @
094a935d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* GPIO -- General Purpose Input/Output
*
* Defines a simple and generic interface to access GPIO device.
*
*/
#include <assert.h>
#include <errno.h>
#include <gpio.h>
/*
* The gpio implementation
*/
static
const
gpio_ops_t
*
ops
;
int
gpio_get_direction
(
int
gpio
)
{
assert
(
ops
);
assert
(
ops
->
get_direction
!=
0
);
assert
(
gpio
>=
0
);
return
ops
->
get_direction
(
gpio
);
}
void
gpio_set_direction
(
int
gpio
,
int
direction
)
{
assert
(
ops
);
assert
(
ops
->
set_direction
!=
0
);
assert
((
direction
==
GPIO_DIR_OUT
)
||
(
direction
==
GPIO_DIR_IN
));
assert
(
gpio
>=
0
);
ops
->
set_direction
(
gpio
,
direction
);
}
int
gpio_get_value
(
int
gpio
)
{
assert
(
ops
);
assert
(
ops
->
get_value
!=
0
);
assert
(
gpio
>=
0
);
return
ops
->
get_value
(
gpio
);
}
void
gpio_set_value
(
int
gpio
,
int
value
)
{
assert
(
ops
);
assert
(
ops
->
set_value
!=
0
);
assert
((
value
==
GPIO_LEVEL_LOW
)
||
(
value
==
GPIO_LEVEL_HIGH
));
assert
(
gpio
>=
0
);
ops
->
set_value
(
gpio
,
value
);
}
/*
* Initialize the gpio. The fields in the provided gpio
* ops pointer must be valid.
*/
void
gpio_init
(
const
gpio_ops_t
*
ops_ptr
)
{
assert
(
ops_ptr
!=
0
&&
(
ops_ptr
->
get_direction
!=
0
)
&&
(
ops_ptr
->
set_direction
!=
0
)
&&
(
ops_ptr
->
get_value
!=
0
)
&&
(
ops_ptr
->
set_value
!=
0
));
ops
=
ops_ptr
;
}
include/drivers/arm/pl061_gpio.h
0 → 100644
View file @
094a935d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __PL061_GPIO_H__
#define __PL061_GPIO_H__
#include <gpio.h>
void
pl061_gpio_register
(
uintptr_t
base_addr
,
int
gpio_dev
);
void
pl061_gpio_init
(
void
);
#endif
/* __PL061_GPIO_H__ */
include/drivers/gpio.h
0 → 100644
View file @
094a935d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GPIO_H__
#define __GPIO_H__
#define GPIO_DIR_OUT 0
#define GPIO_DIR_IN 1
#define GPIO_LEVEL_LOW 0
#define GPIO_LEVEL_HIGH 1
typedef
struct
gpio_ops
{
int
(
*
get_direction
)(
int
gpio
);
void
(
*
set_direction
)(
int
gpio
,
int
direction
);
int
(
*
get_value
)(
int
gpio
);
void
(
*
set_value
)(
int
gpio
,
int
value
);
}
gpio_ops_t
;
int
gpio_get_direction
(
int
gpio
);
void
gpio_set_direction
(
int
gpio
,
int
direction
);
int
gpio_get_value
(
int
gpio
);
void
gpio_set_value
(
int
gpio
,
int
value
);
void
gpio_init
(
const
gpio_ops_t
*
ops
);
#endif
/* __GPIO_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