Merge branch '2020-10-08-misc-board-improvements'
- Move ASPEED ram driver, update. - Exhance pinctrl/gpio support, update Kendryte K210 support - Enhance qemu_arm64 support for a single binary to work with and without TF-A
This commit is contained in:
commit
0570938e3c
37 changed files with 2170 additions and 302 deletions
8
Kconfig
8
Kconfig
|
@ -422,6 +422,14 @@ config SYS_SRAM_SIZE
|
|||
default 0x10000 if TARGET_TRICORDER
|
||||
default 0x0
|
||||
|
||||
config EXAMPLES
|
||||
bool "Compile API examples"
|
||||
depends on !SANDBOX
|
||||
default y if ARCH_QEMU
|
||||
help
|
||||
U-Boot provides an API for standalone applications. Examples are
|
||||
provided in directory examples/.
|
||||
|
||||
endmenu # General setup
|
||||
|
||||
menu "Boot images"
|
||||
|
|
|
@ -935,7 +935,9 @@ RISC-V KENDRYTE
|
|||
M: Sean Anderson <seanga2@gmail.com>
|
||||
S: Maintained
|
||||
F: doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt
|
||||
F: doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
|
||||
F: drivers/clk/kendryte/
|
||||
F: drivers/pinctrl/kendryte/
|
||||
F: include/kendryte/
|
||||
|
||||
RNG
|
||||
|
@ -960,6 +962,7 @@ M: Simon Glass <sjg@chromium.org>
|
|||
S: Maintained
|
||||
F: arch/sandbox/
|
||||
F: doc/arch/sandbox.rst
|
||||
F: include/dt-bindings/*/sandbox*.h
|
||||
|
||||
SH
|
||||
M: Marek Vasut <marek.vasut+renesas@gmail.com>
|
||||
|
|
|
@ -12,7 +12,6 @@ config ARM64
|
|||
if ARM64
|
||||
config POSITION_INDEPENDENT
|
||||
bool "Generate position-independent pre-relocation code"
|
||||
select INIT_SP_RELATIVE
|
||||
help
|
||||
U-Boot expects to be linked to a specific hard-coded address, and to
|
||||
be loaded to and run from that address. This option lifts that
|
||||
|
@ -23,6 +22,8 @@ config POSITION_INDEPENDENT
|
|||
|
||||
config INIT_SP_RELATIVE
|
||||
bool "Specify the early stack pointer relative to the .bss section"
|
||||
default n if ARCH_QEMU
|
||||
default y if POSITION_INDEPENDENT
|
||||
help
|
||||
U-Boot typically uses a hard-coded value for the stack pointer
|
||||
before relocation. Enable this option to instead calculate the
|
||||
|
@ -76,7 +77,7 @@ config GIC_V3_ITS
|
|||
|
||||
config STATIC_RELA
|
||||
bool
|
||||
default y if ARM64 && !POSITION_INDEPENDENT
|
||||
default y if ARM64
|
||||
|
||||
config DMA_ADDR_T_64BIT
|
||||
bool
|
||||
|
@ -932,7 +933,6 @@ config ARCH_OWL
|
|||
|
||||
config ARCH_QEMU
|
||||
bool "QEMU Virtual Platform"
|
||||
select ARCH_SUPPORT_TFABOOT
|
||||
select DM
|
||||
select DM_SERIAL
|
||||
select OF_CONTROL
|
||||
|
@ -1801,8 +1801,13 @@ config TFABOOT
|
|||
depends on ARCH_SUPPORT_TFABOOT
|
||||
default n
|
||||
help
|
||||
Enabling this will make a U-Boot binary that is capable of being
|
||||
booted via TF-A (Trusted Firmware for Cortex-A).
|
||||
Some platforms support the setup of secure registers (for instance
|
||||
for CPU errata handling) or provide secure services like PSCI.
|
||||
Those services could also be provided by other firmware parts
|
||||
like TF-A (Trusted Firmware for Cortex-A), in which case U-Boot
|
||||
does not need to (and cannot) execute this code.
|
||||
Enabling this option will make a U-Boot binary that is relying
|
||||
on other firmware layers to provide secure functionality.
|
||||
|
||||
config TI_SECURE_DEVICE
|
||||
bool "HS Device Type Support"
|
||||
|
|
|
@ -83,7 +83,8 @@ save_boot_params_ret:
|
|||
pie_fixup:
|
||||
adr x0, _start /* x0 <- Runtime value of _start */
|
||||
ldr x1, _TEXT_BASE /* x1 <- Linked value of _start */
|
||||
sub x9, x0, x1 /* x9 <- Run-vs-link offset */
|
||||
subs x9, x0, x1 /* x9 <- Run-vs-link offset */
|
||||
beq pie_fixup_done
|
||||
adrp x2, __rel_dyn_start /* x2 <- Runtime &__rel_dyn_start */
|
||||
add x2, x2, #:lo12:__rel_dyn_start
|
||||
adrp x3, __rel_dyn_end /* x3 <- Runtime &__rel_dyn_end */
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
obj-y += lowlevel_init.o
|
||||
obj-y += board_common.o
|
||||
obj-y += clk_ast2500.o sdram_ast2500.o
|
||||
obj-y += clk_ast2500.o
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "k210.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
model = "Sipeed Maix Bit 2.0";
|
||||
|
@ -17,6 +18,32 @@
|
|||
stdout-path = "serial0:115200";
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
green {
|
||||
gpios = <&gpio1_0 4 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
red {
|
||||
gpios = <&gpio1_0 5 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
blue {
|
||||
gpios = <&gpio1_0 6 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
boot {
|
||||
label = "BOOT";
|
||||
linux,code = <BTN_0>;
|
||||
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,format = "i2s";
|
||||
|
@ -39,9 +66,97 @@
|
|||
};
|
||||
|
||||
&uarths0 {
|
||||
pinctrl-0 = <&fpioa_uarths>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
pinctrl-0 = <&fpioa_gpiohs>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
pinctrl-0 = <&fpioa_gpio>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
#sound-dai-cells = <1>;
|
||||
pinctrl-0 = <&fpioa_i2s0>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&fpioa {
|
||||
status = "okay";
|
||||
|
||||
fpioa_uarths: uarths {
|
||||
pinmux = <K210_FPIOA(4, K210_PCF_UARTHS_RX)>,
|
||||
<K210_FPIOA(5, K210_PCF_UARTHS_TX)>;
|
||||
};
|
||||
|
||||
fpioa_gpio: gpio {
|
||||
pinmux = <K210_FPIOA(8, K210_PCF_GPIO0)>,
|
||||
<K210_FPIOA(9, K210_PCF_GPIO1)>,
|
||||
<K210_FPIOA(10, K210_PCF_GPIO2)>,
|
||||
<K210_FPIOA(11, K210_PCF_GPIO3)>,
|
||||
<K210_FPIOA(12, K210_PCF_GPIO4)>,
|
||||
<K210_FPIOA(13, K210_PCF_GPIO5)>,
|
||||
<K210_FPIOA(14, K210_PCF_GPIO6)>,
|
||||
<K210_FPIOA(15, K210_PCF_GPIO7)>;
|
||||
};
|
||||
|
||||
fpioa_gpiohs: gpiohs {
|
||||
pinmux = <K210_FPIOA(16, K210_PCF_GPIOHS0)>,
|
||||
<K210_FPIOA(17, K210_PCF_GPIOHS1)>,
|
||||
<K210_FPIOA(21, K210_PCF_GPIOHS5)>,
|
||||
<K210_FPIOA(22, K210_PCF_GPIOHS6)>,
|
||||
<K210_FPIOA(23, K210_PCF_GPIOHS7)>,
|
||||
<K210_FPIOA(24, K210_PCF_GPIOHS8)>,
|
||||
<K210_FPIOA(25, K210_PCF_GPIOHS9)>,
|
||||
<K210_FPIOA(30, K210_PCF_GPIOHS14)>,
|
||||
<K210_FPIOA(31, K210_PCF_GPIOHS15)>,
|
||||
<K210_FPIOA(32, K210_PCF_GPIOHS16)>,
|
||||
<K210_FPIOA(33, K210_PCF_GPIOHS17)>,
|
||||
<K210_FPIOA(34, K210_PCF_GPIOHS18)>,
|
||||
<K210_FPIOA(35, K210_PCF_GPIOHS19)>;
|
||||
};
|
||||
|
||||
fpioa_i2s0: i2s0 {
|
||||
pinmux = <K210_FPIOA(18, K210_PCF_I2S0_SCLK)>,
|
||||
<K210_FPIOA(19, K210_PCF_I2S0_WS)>,
|
||||
<K210_FPIOA(20, K210_PCF_I2S0_IN_D0)>;
|
||||
};
|
||||
|
||||
fpioa_dvp: dvp {
|
||||
pinmux = <K210_FPIOA(40, K210_PCF_SCCB_SDA)>,
|
||||
<K210_FPIOA(41, K210_PCF_SCCB_SCLK)>,
|
||||
<K210_FPIOA(42, K210_PCF_DVP_RST)>,
|
||||
<K210_FPIOA(43, K210_PCF_DVP_VSYNC)>,
|
||||
<K210_FPIOA(44, K210_PCF_DVP_PWDN)>,
|
||||
<K210_FPIOA(45, K210_PCF_DVP_HSYNC)>,
|
||||
<K210_FPIOA(46, K210_PCF_DVP_XCLK)>,
|
||||
<K210_FPIOA(47, K210_PCF_DVP_PCLK)>;
|
||||
};
|
||||
|
||||
fpioa_spi0: spi0 {
|
||||
pinmux = <K210_FPIOA(36, K210_PCF_GPIOHS20)>, /* cs */
|
||||
<K210_FPIOA(37, K210_PCF_GPIOHS21)>, /* rst */
|
||||
<K210_FPIOA(38, K210_PCF_GPIOHS22)>, /* dc */
|
||||
<K210_FPIOA(39, K210_PCF_SPI0_SCLK)>; /* wr */
|
||||
};
|
||||
|
||||
fpioa_spi1: spi1 {
|
||||
pinmux = <K210_FPIOA(26, K210_PCF_SPI1_D1)>,
|
||||
<K210_FPIOA(27, K210_PCF_SPI1_SCLK)>,
|
||||
<K210_FPIOA(28, K210_PCF_SPI1_D0)>,
|
||||
<K210_FPIOA(29, K210_PCF_GPIOHS13)>;
|
||||
};
|
||||
};
|
||||
|
||||
&dvp0 {
|
||||
pinctrl-0 = <&fpioa_dvp>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <dt-bindings/clock/k210-sysctl.h>
|
||||
#include <dt-bindings/mfd/k210-sysctl.h>
|
||||
#include <dt-bindings/pinctrl/k210-pinctrl.h>
|
||||
#include <dt-bindings/reset/k210-sysctl.h>
|
||||
|
||||
/ {
|
||||
|
@ -368,7 +369,18 @@
|
|||
reg = <0x502B0000 0x100>;
|
||||
clocks = <&sysclk K210_CLK_FPIOA>;
|
||||
resets = <&sysrst K210_RST_FPIOA>;
|
||||
kendryte,sysctl = <&sysctl>;
|
||||
kendryte,power-offset = <K210_SYSCTL_POWER_SEL>;
|
||||
pinctrl-0 = <&fpioa_jtag>;
|
||||
pinctrl-names = "default";
|
||||
status = "disabled";
|
||||
|
||||
fpioa_jtag: jtag {
|
||||
pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCLK)>,
|
||||
<K210_FPIOA(1, K210_PCF_JTAG_TDI)>,
|
||||
<K210_FPIOA(2, K210_PCF_JTAG_TMS)>,
|
||||
<K210_FPIOA(3, K210_PCF_JTAG_TDO)>;
|
||||
};
|
||||
};
|
||||
|
||||
sha256: sha256@502C0000 {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/gpio/sandbox-gpio.h>
|
||||
#include <dt-bindings/pinctrl/sandbox-pinmux.h>
|
||||
|
||||
/ {
|
||||
model = "sandbox";
|
||||
|
@ -558,7 +559,7 @@
|
|||
|
||||
default_off {
|
||||
gpios = <&gpio_a 6 0>;
|
||||
label = "sandbox:default_off";
|
||||
/* label intentionally omitted */
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
@ -1094,30 +1095,60 @@
|
|||
pinctrl {
|
||||
compatible = "sandbox,pinctrl";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&gpios>;
|
||||
pinctrl-names = "default", "alternate";
|
||||
pinctrl-0 = <&pinctrl_gpios>, <&pinctrl_i2s>;
|
||||
pinctrl-1 = <&pinctrl_spi>, <&pinctrl_i2c>;
|
||||
|
||||
gpios: gpios {
|
||||
pinctrl_gpios: gpios {
|
||||
gpio0 {
|
||||
pins = "GPIO0";
|
||||
pins = "P5";
|
||||
function = "GPIO";
|
||||
bias-pull-up;
|
||||
input-disable;
|
||||
};
|
||||
gpio1 {
|
||||
pins = "GPIO1";
|
||||
pins = "P6";
|
||||
function = "GPIO";
|
||||
output-high;
|
||||
drive-open-drain;
|
||||
};
|
||||
gpio2 {
|
||||
pins = "GPIO2";
|
||||
pinmux = <SANDBOX_PINMUX(7, SANDBOX_PINMUX_GPIO)>;
|
||||
bias-pull-down;
|
||||
input-enable;
|
||||
};
|
||||
gpio3 {
|
||||
pins = "GPIO3";
|
||||
pinmux = <SANDBOX_PINMUX(8, SANDBOX_PINMUX_GPIO)>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
pinctrl_i2c: i2c {
|
||||
groups {
|
||||
groups = "I2C_UART";
|
||||
function = "I2C";
|
||||
};
|
||||
|
||||
pins {
|
||||
pins = "P0", "P1";
|
||||
drive-open-drain;
|
||||
};
|
||||
};
|
||||
|
||||
pinctrl_i2s: i2s {
|
||||
groups = "SPI_I2S";
|
||||
function = "I2S";
|
||||
};
|
||||
|
||||
pinctrl_spi: spi {
|
||||
groups = "SPI_I2S";
|
||||
function = "SPI";
|
||||
|
||||
cs {
|
||||
pinmux = <SANDBOX_PINMUX(5, SANDBOX_PINMUX_CS)>,
|
||||
<SANDBOX_PINMUX(6, SANDBOX_PINMUX_CS)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hwspinlock@0 {
|
||||
|
|
|
@ -44,4 +44,13 @@ config BOARD_SPECIFIC_OPTIONS
|
|||
imply RESET_SYSCON
|
||||
imply SYSRESET
|
||||
imply SYSRESET_SYSCON
|
||||
imply PINCTRL
|
||||
imply PINCONF
|
||||
imply PINCTRL_K210
|
||||
imply DM_GPIO
|
||||
imply DWAPB_GPIO
|
||||
imply SIFIVE_GPIO
|
||||
imply CMD_GPIO
|
||||
imply LED
|
||||
imply LED_GPIO
|
||||
endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_QEMU=y
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_POSITION_INDEPENDENT=y
|
||||
CONFIG_ENV_SIZE=0x40000
|
||||
CONFIG_ENV_SECT_SIZE=0x40000
|
||||
CONFIG_AHCI=y
|
||||
|
|
|
@ -9,6 +9,7 @@ U-Boot API documentation
|
|||
dfu
|
||||
efi
|
||||
linker_lists
|
||||
pinctrl
|
||||
rng
|
||||
serial
|
||||
unicode
|
||||
|
|
7
doc/api/pinctrl.rst
Normal file
7
doc/api/pinctrl.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Pinctrl and Pinmux
|
||||
==================
|
||||
|
||||
.. kernel-doc:: include/dm/pinctrl.h
|
||||
:internal:
|
|
@ -199,7 +199,7 @@ To run legacy images, use the ``bootm`` command:
|
|||
Load Address: 80000000
|
||||
Entry Point: 80000000
|
||||
|
||||
$ picocom -b 115200 /dev/ttyUSB0i
|
||||
$ picocom -b 115200 /dev/ttyUSB0
|
||||
=> loady
|
||||
## Ready for binary (ymodem) download to 0x80000000 at 115200 bps...
|
||||
C
|
||||
|
@ -230,6 +230,66 @@ To run legacy images, use the ``bootm`` command:
|
|||
argv[0] = "<NULL>"
|
||||
Hit any key to exit ...
|
||||
|
||||
Pin Assignment
|
||||
--------------
|
||||
|
||||
The K210 contains a Fully Programmable I/O Array (FPIOA), which can remap any of
|
||||
its 256 input functions to any any of 48 output pins. The following table has
|
||||
the default pin assignments for the BitM.
|
||||
|
||||
===== ========== =======
|
||||
Pin Function Comment
|
||||
===== ========== =======
|
||||
IO_0 JTAG_TCLK
|
||||
IO_1 JTAG_TDI
|
||||
IO_2 JTAG_TMS
|
||||
IO_3 JTAG_TDO
|
||||
IO_4 UARTHS_RX
|
||||
IO_5 UARTHS_TX
|
||||
IO_6 Not set
|
||||
IO_7 Not set
|
||||
IO_8 GPIO_0
|
||||
IO_9 GPIO_1
|
||||
IO_10 GPIO_2
|
||||
IO_11 GPIO_3
|
||||
IO_12 GPIO_4 Green LED
|
||||
IO_13 GPIO_5 Red LED
|
||||
IO_14 GPIO_6 Blue LED
|
||||
IO_15 GPIO_7
|
||||
IO_16 GPIOHS_0 ISP
|
||||
IO_17 GPIOHS_1
|
||||
IO_18 I2S0_SCLK MIC CLK
|
||||
IO_19 I2S0_WS MIC WS
|
||||
IO_20 I2S0_IN_D0 MIC SD
|
||||
IO_21 GPIOHS_5
|
||||
IO_22 GPIOHS_6
|
||||
IO_23 GPIOHS_7
|
||||
IO_24 GPIOHS_8
|
||||
IO_25 GPIOHS_9
|
||||
IO_26 SPI1_D1 MMC MISO
|
||||
IO_27 SPI1_SCLK MMC CLK
|
||||
IO_28 SPI1_D0 MMC MOSI
|
||||
IO_29 GPIOHS_13 MMC CS
|
||||
IO_30 GPIOHS_14
|
||||
IO_31 GPIOHS_15
|
||||
IO_32 GPIOHS_16
|
||||
IO_33 GPIOHS_17
|
||||
IO_34 GPIOHS_18
|
||||
IO_35 GPIOHS_19
|
||||
IO_36 GPIOHS_20 Panel CS
|
||||
IO_37 GPIOHS_21 Panel RST
|
||||
IO_38 GPIOHS_22 Panel DC
|
||||
IO_39 SPI0_SCK Panel WR
|
||||
IO_40 SCCP_SDA
|
||||
IO_41 SCCP_SCLK
|
||||
IO_42 DVP_RST
|
||||
IO_43 DVP_VSYNC
|
||||
IO_44 DVP_PWDN
|
||||
IO_45 DVP_HSYNC
|
||||
IO_46 DVP_XCLK
|
||||
IO_47 DVP_PCLK
|
||||
===== ========== =======
|
||||
|
||||
Over- and Under-clocking
|
||||
------------------------
|
||||
|
||||
|
@ -408,7 +468,7 @@ Address Size Description
|
|||
0x8801C000 0x1000 riscv priv spec 1.9 config
|
||||
0x8801D000 0x2000 flattened device tree (contains only addresses and
|
||||
interrupts)
|
||||
0x8801f000 0x1000 credits
|
||||
0x8801F000 0x1000 credits
|
||||
========== ========= ===========
|
||||
|
||||
Links
|
||||
|
|
102
doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
Normal file
102
doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
Normal file
|
@ -0,0 +1,102 @@
|
|||
Kendryte K210 FPIOA
|
||||
|
||||
This binding describes the Fully-Programmable Input/Output Array (FPIOA) found
|
||||
in Kendryte K210 SoCs. Any of the 256 functions can be mapped to any of the 48
|
||||
pins.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "kendryte,k210-fpioa"
|
||||
- reg: address and length of the FPIOA registers
|
||||
- kendryte,sysctl: phandle to the "sysctl" register map node
|
||||
- kendryte,power-offset: offset in the register map of the power bank control
|
||||
register (in bytes)
|
||||
|
||||
Configuration nodes
|
||||
|
||||
Pin configuration nodes are documented in pinctrl-bindings.txt
|
||||
|
||||
Required properties for pin-configuration nodes or sub-nodes are:
|
||||
- groups: list of power groups to which the configuration applies. Valid groups
|
||||
are:
|
||||
A0, A1, A2, B0, B1, B2, C0, C1
|
||||
(either this or "pinmux" must be specified)
|
||||
- pinmux: integer array representing pin multiplexing configuration. In addition
|
||||
to the 256 standard functions, each pin can also output the direction
|
||||
indicator (DO) of any function. This signal is high whenever the function
|
||||
would normally drive the output. Helper macros to ease assembling the "pinmux"
|
||||
arguments from the pin and function are provided by the FPIOA header file at:
|
||||
<dt-bindings/pinctrl/k210-pinctrl.h>
|
||||
Integer values in the "pinmux" argument list are assembled as:
|
||||
((PIN << 16) | (DO << 8) | (FUNC))
|
||||
Valid values for PIN are numbers 0 through 47.
|
||||
Valid values for DO are 0 or 1.
|
||||
Valid values for FUNC are numbers 0 through 255. For a complete list of
|
||||
acceptable functions, consult the FPIOA header file.
|
||||
(either this or "groups" must be specified)
|
||||
|
||||
Optional properties for "pinmux" nodes are:
|
||||
bias-disable, bias-pull-down, bias-pull-up, drive-strength,
|
||||
drive-strength-ua, input-enable, input-disable, input-schmitt-enable,
|
||||
input-schmitt-disable, output-low, output-high, output-enable,
|
||||
output-disable, slew-rate, output-polarity-invert, input-polarity-invert
|
||||
|
||||
Optional properties for "groups" nodes are:
|
||||
power-source
|
||||
|
||||
Notes on specific properties include:
|
||||
- bias-pull-up, -down, and -pin-default: The pull strength cannot be configured.
|
||||
- drive-strength: There are 8 drive strength settings between 11 and 50 mA.
|
||||
- input- and output-polarity-invert: Invert the polarity of either the input or
|
||||
the output, respectively.
|
||||
- power-source: Controls the output voltage of a bank of pins. Either
|
||||
K210_PC_POWER_1V8 or K210_PC_POWER_3V3 may be specified.
|
||||
- slew-rate: Specifying this property reduces the slew rate.
|
||||
|
||||
Example:
|
||||
fpioa: pinmux@502B0000 {
|
||||
compatible = "kendryte,k210-fpioa";
|
||||
reg = <0x502B0000 0x100>;
|
||||
kendryte,sysctl = <&sysctl>;
|
||||
kendryte,power-offset = <K210_SYSCTL_POWER_SEL>;
|
||||
|
||||
/* JTAG running at 3.3V and driven at 11 mA */
|
||||
fpioa_jtag: jtag {
|
||||
voltage {
|
||||
group = "A0";
|
||||
power-source = <K210_PC_POWER_3V3>;
|
||||
};
|
||||
|
||||
jtag {
|
||||
pinmux = <K210_FPIOA(0, K210_PCF_JTAG_TCK)>,
|
||||
<K210_FPIOA(1, K210_PCF_JTAG_TDI)>,
|
||||
<K210_FPIOA(2, K210_PCF_JTAG_TMS)>,
|
||||
<K210_FPIOA(3, K210_PCF_JTAG_TDO)>;
|
||||
drive-strength = <11>;
|
||||
}
|
||||
};
|
||||
|
||||
/* I2C configured for use with a TCA9800 level shifter */
|
||||
fpioa_i2c: i2c {
|
||||
i2c {
|
||||
pinmux = <K210_FPIOA(6, K210_PCF_I2C0_SCLK)>,
|
||||
<K210_FPIOA(7, K210_PCF_I2C0_SDA)>;
|
||||
};
|
||||
|
||||
direction {
|
||||
pinmux = <K210_FPIOA_DO(8, K210_PCF_I2C0_SDA)>;
|
||||
output-polarity-invert;
|
||||
};
|
||||
};
|
||||
|
||||
/* UART with an active-high TX status LED */
|
||||
fpioa_uart1: uart1 {
|
||||
uart {
|
||||
pinmux = <K210_FPIOA(9, K210_PCF_UART1_TX)>,
|
||||
<K210_FPIOA(10, K210_PCF_UART1_RX)>;
|
||||
};
|
||||
|
||||
status {
|
||||
pinmux = <K210_FPIOA_DO(11, K210_PCF_UART1_TX)>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -119,7 +119,8 @@ For example:
|
|||
|
||||
The contents of each of those pin configuration child nodes is defined
|
||||
entirely by the binding for the individual pin controller device. There
|
||||
exists no common standard for this content.
|
||||
exists no common standard for this content. The pinctrl framework only
|
||||
provides generic helper bindings that the pin controller driver can use.
|
||||
|
||||
The pin configuration nodes need not be direct children of the pin controller
|
||||
device; they may be grandchildren, for example. Whether this is legal, and
|
||||
|
@ -156,6 +157,29 @@ state_2_node_a {
|
|||
pins = "mfio29", "mfio30";
|
||||
};
|
||||
|
||||
For hardware where pin multiplexing configurations have to be specified for
|
||||
each single pin the number of required sub-nodes containing "pin" and
|
||||
"function" properties can quickly escalate and become hard to write and
|
||||
maintain.
|
||||
|
||||
For cases like this, the pin controller driver may use the pinmux helper
|
||||
property, where the pin identifier is provided with mux configuration settings
|
||||
in a pinmux group. A pinmux group consists of the pin identifier and mux
|
||||
settings represented as a single integer or an array of integers.
|
||||
|
||||
The pinmux property accepts an array of pinmux groups, each of them describing
|
||||
a single pin multiplexing configuration.
|
||||
|
||||
pincontroller {
|
||||
state_0_node_a {
|
||||
pinmux = <PINMUX_GROUP>, <PINMUX_GROUP>, ...;
|
||||
};
|
||||
};
|
||||
|
||||
Each individual pin controller driver bindings documentation shall specify
|
||||
how pin IDs and pin multiplexing configuration are defined and assembled
|
||||
together in a pinmux group.
|
||||
|
||||
== Generic pin configuration node content ==
|
||||
|
||||
Many data items that are represented in a pin configuration node are common
|
||||
|
@ -168,12 +192,15 @@ structure of the DT nodes that contain these properties.
|
|||
Supported generic properties are:
|
||||
|
||||
pins - the list of pins that properties in the node
|
||||
apply to (either this or "group" has to be
|
||||
apply to (either this, "group" or "pinmux" has to be
|
||||
specified)
|
||||
group - the group to apply the properties to, if the driver
|
||||
supports configuration of whole groups rather than
|
||||
individual pins (either this or "pins" has to be
|
||||
specified)
|
||||
individual pins (either this, "pins" or "pinmux" has
|
||||
to be specified)
|
||||
pinmux - the list of numeric pin ids and their mux settings
|
||||
that properties in the node apply to (either this,
|
||||
"pins" or "groups" have to be specified)
|
||||
bias-disable - disable any pin bias
|
||||
bias-high-impedance - high impedance mode ("third-state", "floating")
|
||||
bias-bus-hold - latch weakly
|
||||
|
@ -184,17 +211,30 @@ drive-push-pull - drive actively high and low
|
|||
drive-open-drain - drive with open drain
|
||||
drive-open-source - drive with open source
|
||||
drive-strength - sink or source at most X mA
|
||||
input-enable - enable input on pin (no effect on output)
|
||||
input-disable - disable input on pin (no effect on output)
|
||||
drive-strength-microamp - sink or source at most X uA
|
||||
input-enable - enable input on pin (no effect on output, such as
|
||||
enabling an input buffer)
|
||||
input-disable - disable input on pin (no effect on output, such as
|
||||
disabling an input buffer)
|
||||
input-schmitt-enable - enable schmitt-trigger mode
|
||||
input-schmitt-disable - disable schmitt-trigger mode
|
||||
input-debounce - debounce mode with debound time X
|
||||
power-source - select between different power supplies
|
||||
low-power-enable - enable low power mode
|
||||
low-power-disable - disable low power mode
|
||||
output-disable - disable output on a pin (such as disable an output
|
||||
buffer)
|
||||
output-enable - enable output on a pin without actively driving it
|
||||
(such as enabling an output buffer)
|
||||
output-low - set the pin to output mode with low level
|
||||
output-high - set the pin to output mode with high level
|
||||
sleep-hardware-state - indicate this is sleep related state which will be programmed
|
||||
into the registers for the sleep state.
|
||||
slew-rate - set the slew rate
|
||||
skew-delay - this affects the expected clock skew on input pins
|
||||
and the delay before latching a value to an output
|
||||
pin. Typically indicates how many double-inverters are
|
||||
used to delay the signal.
|
||||
|
||||
For example:
|
||||
|
||||
|
@ -216,6 +256,12 @@ state_2_node_a {
|
|||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
state_3_node_a {
|
||||
mux {
|
||||
pinmux = <GPIOx_PINm_MUXn>, <GPIOx_PINj_MUXk)>;
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
|
||||
Some of the generic properties take arguments. For those that do, the
|
||||
arguments are described below.
|
||||
|
@ -224,11 +270,18 @@ arguments are described below.
|
|||
binding for the hardware defines:
|
||||
- Whether the entries are integers or strings, and their meaning.
|
||||
|
||||
- pinmux takes a list of pin IDs and mux settings as required argument. The
|
||||
specific bindings for the hardware defines:
|
||||
- How pin IDs and mux settings are defined and assembled together in a single
|
||||
integer or an array of integers.
|
||||
|
||||
- bias-pull-up, -down and -pin-default take as optional argument on hardware
|
||||
supporting it the pull strength in Ohm. bias-disable will disable the pull.
|
||||
|
||||
- drive-strength takes as argument the target strength in mA.
|
||||
|
||||
- drive-strength-microamp takes as argument the target strength in uA.
|
||||
|
||||
- input-debounce takes the debounce time in usec as argument
|
||||
or 0 to disable debouncing
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ struct gpio_dwapb_platdata {
|
|||
const char *name;
|
||||
int bank;
|
||||
int pins;
|
||||
fdt_addr_t base;
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static int dwapb_gpio_direction_input(struct udevice *dev, unsigned pin)
|
||||
|
@ -66,13 +66,6 @@ static int dwapb_gpio_direction_output(struct udevice *dev, unsigned pin,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dwapb_gpio_get_value(struct udevice *dev, unsigned pin)
|
||||
{
|
||||
struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
|
||||
return !!(readl(plat->base + GPIO_EXT_PORT(plat->bank)) & (1 << pin));
|
||||
}
|
||||
|
||||
|
||||
static int dwapb_gpio_set_value(struct udevice *dev, unsigned pin, int val)
|
||||
{
|
||||
struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
|
||||
|
@ -98,6 +91,18 @@ static int dwapb_gpio_get_function(struct udevice *dev, unsigned offset)
|
|||
return GPIOF_INPUT;
|
||||
}
|
||||
|
||||
static int dwapb_gpio_get_value(struct udevice *dev, unsigned pin)
|
||||
{
|
||||
struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
|
||||
u32 value;
|
||||
|
||||
if (dwapb_gpio_get_function(dev, pin) == GPIOF_OUTPUT)
|
||||
value = readl(plat->base + GPIO_SWPORT_DR(plat->bank));
|
||||
else
|
||||
value = readl(plat->base + GPIO_EXT_PORT(plat->bank));
|
||||
return !!(value & BIT(pin));
|
||||
}
|
||||
|
||||
static const struct dm_gpio_ops gpio_dwapb_ops = {
|
||||
.direction_input = dwapb_gpio_direction_input,
|
||||
.direction_output = dwapb_gpio_direction_output,
|
||||
|
@ -176,7 +181,7 @@ static int gpio_dwapb_bind(struct udevice *dev)
|
|||
if (!plat)
|
||||
return -ENOMEM;
|
||||
|
||||
plat->base = base;
|
||||
plat->base = (void *)base;
|
||||
plat->bank = bank;
|
||||
plat->pins = ofnode_read_u32_default(node, "snps,nr-gpios", 0);
|
||||
|
||||
|
@ -186,7 +191,15 @@ static int gpio_dwapb_bind(struct udevice *dev)
|
|||
* Fall back to node name. This means accessing pins
|
||||
* via bank name won't work.
|
||||
*/
|
||||
plat->name = ofnode_get_name(node);
|
||||
char name[32];
|
||||
|
||||
snprintf(name, sizeof(name), "%s_",
|
||||
ofnode_get_name(node));
|
||||
plat->name = strdup(name);
|
||||
if (!plat->name) {
|
||||
kfree(plat);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
ret = device_bind_ofnode(dev, dev->driver, plat->name,
|
||||
|
|
|
@ -99,11 +99,8 @@ static int led_gpio_bind(struct udevice *parent)
|
|||
const char *label;
|
||||
|
||||
label = ofnode_read_string(node, "label");
|
||||
if (!label) {
|
||||
debug("%s: node %s has no label\n", __func__,
|
||||
ofnode_get_name(node));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!label)
|
||||
label = ofnode_get_name(node);
|
||||
ret = device_bind_driver_to_node(parent, "gpio_led",
|
||||
ofnode_get_name(node),
|
||||
node, &dev);
|
||||
|
|
|
@ -291,6 +291,13 @@ config ASPEED_AST2500_PINCTRL
|
|||
uses Generic Pinctrl framework and is compatible with the Linux
|
||||
driver, i.e. it uses the same device tree configuration.
|
||||
|
||||
config PINCTRL_K210
|
||||
bool "Kendryte K210 Fully-Programmable Input/Output Array driver"
|
||||
depends on DM && PINCTRL_GENERIC
|
||||
help
|
||||
Support pin multiplexing on the K210. The "FPIOA" can remap any
|
||||
supported function to any multifunctional IO pin. It can also perform
|
||||
basic GPIO functions, such as reading the current value of a pin.
|
||||
endif
|
||||
|
||||
source "drivers/pinctrl/broadcom/Kconfig"
|
||||
|
|
|
@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
|
|||
obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
|
||||
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o
|
||||
obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/
|
||||
obj-$(CONFIG_PINCTRL_K210) += pinctrl-kendryte.o
|
||||
obj-$(CONFIG_PINCTRL_MESON) += meson/
|
||||
obj-$(CONFIG_PINCTRL_MTK) += mediatek/
|
||||
obj-$(CONFIG_PINCTRL_MSCC) += mscc/
|
||||
|
|
|
@ -227,6 +227,13 @@ static int pinconf_enable_setting(struct udevice *dev, bool is_group,
|
|||
}
|
||||
#endif
|
||||
|
||||
enum pinmux_subnode_type {
|
||||
PST_NONE = 0,
|
||||
PST_PIN,
|
||||
PST_GROUP,
|
||||
PST_PINMUX,
|
||||
};
|
||||
|
||||
/**
|
||||
* pinctrl_generic_set_state_one() - set state for a certain pin/group
|
||||
* Apply all pin multiplexing and pin configurations specified by @config
|
||||
|
@ -234,13 +241,15 @@ static int pinconf_enable_setting(struct udevice *dev, bool is_group,
|
|||
*
|
||||
* @dev: pin controller device
|
||||
* @config: pseudo device pointing to config node
|
||||
* @is_group: target of operation (true: pin group, false: pin)
|
||||
* @selector: pin selector or group selector, depending on @is_group
|
||||
* @subnode_type: target of operation (pin, group, or pin specified by a pinmux
|
||||
* group)
|
||||
* @selector: pin selector or group selector, depending on @subnode_type
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
static int pinctrl_generic_set_state_one(struct udevice *dev,
|
||||
struct udevice *config,
|
||||
bool is_group, unsigned selector)
|
||||
enum pinmux_subnode_type subnode_type,
|
||||
unsigned selector)
|
||||
{
|
||||
const char *propname;
|
||||
const void *value;
|
||||
|
@ -248,17 +257,22 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
|
|||
int len, func_selector, param, ret;
|
||||
u32 arg, default_val;
|
||||
|
||||
assert(subnode_type != PST_NONE);
|
||||
|
||||
dev_for_each_property(property, config) {
|
||||
value = dev_read_prop_by_prop(&property, &propname, &len);
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
if (!strcmp(propname, "function")) {
|
||||
/* pinmux subnodes already have their muxing set */
|
||||
if (subnode_type != PST_PINMUX &&
|
||||
!strcmp(propname, "function")) {
|
||||
func_selector = pinmux_func_name_to_selector(dev,
|
||||
value);
|
||||
if (func_selector < 0)
|
||||
return func_selector;
|
||||
ret = pinmux_enable_setting(dev, is_group,
|
||||
ret = pinmux_enable_setting(dev,
|
||||
subnode_type == PST_GROUP,
|
||||
selector,
|
||||
func_selector);
|
||||
} else {
|
||||
|
@ -272,7 +286,8 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
|
|||
else
|
||||
arg = default_val;
|
||||
|
||||
ret = pinconf_enable_setting(dev, is_group,
|
||||
ret = pinconf_enable_setting(dev,
|
||||
subnode_type == PST_GROUP,
|
||||
selector, param, arg);
|
||||
}
|
||||
|
||||
|
@ -283,6 +298,41 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinctrl_generic_get_subnode_type() - determine whether there is a valid
|
||||
* pins, groups, or pinmux property in the config node
|
||||
*
|
||||
* @dev: pin controller device
|
||||
* @config: pseudo device pointing to config node
|
||||
* @count: number of specifiers contained within the property
|
||||
* @return: the type of the subnode, or PST_NONE
|
||||
*/
|
||||
static enum pinmux_subnode_type pinctrl_generic_get_subnode_type(struct udevice *dev,
|
||||
struct udevice *config,
|
||||
int *count)
|
||||
{
|
||||
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
|
||||
|
||||
*count = dev_read_string_count(config, "pins");
|
||||
if (*count >= 0)
|
||||
return PST_PIN;
|
||||
|
||||
*count = dev_read_string_count(config, "groups");
|
||||
if (*count >= 0)
|
||||
return PST_GROUP;
|
||||
|
||||
if (ops->pinmux_property_set) {
|
||||
*count = dev_read_size(config, "pinmux");
|
||||
if (*count >= 0 && !(*count % sizeof(u32))) {
|
||||
*count /= sizeof(u32);
|
||||
return PST_PINMUX;
|
||||
}
|
||||
}
|
||||
|
||||
*count = 0;
|
||||
return PST_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinctrl_generic_set_state_subnode() - apply all settings in config node
|
||||
*
|
||||
|
@ -293,38 +343,55 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
|
|||
static int pinctrl_generic_set_state_subnode(struct udevice *dev,
|
||||
struct udevice *config)
|
||||
{
|
||||
const char *subnode_target_type = "pins";
|
||||
bool is_group = false;
|
||||
enum pinmux_subnode_type subnode_type;
|
||||
const char *name;
|
||||
int strings_count, selector, i, ret;
|
||||
int count, selector, i, ret, scratch;
|
||||
const u32 *pinmux_groups = NULL; /* prevent use-uninitialized warning */
|
||||
|
||||
strings_count = dev_read_string_count(config, subnode_target_type);
|
||||
if (strings_count < 0) {
|
||||
subnode_target_type = "groups";
|
||||
is_group = true;
|
||||
strings_count = dev_read_string_count(config,
|
||||
subnode_target_type);
|
||||
if (strings_count < 0) {
|
||||
subnode_type = pinctrl_generic_get_subnode_type(dev, config, &count);
|
||||
|
||||
debug("%s(%s, %s): count=%d\n", __func__, dev->name, config->name,
|
||||
count);
|
||||
|
||||
if (subnode_type == PST_PINMUX) {
|
||||
pinmux_groups = dev_read_prop(config, "pinmux", &scratch);
|
||||
if (!pinmux_groups)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
switch (subnode_type) {
|
||||
case PST_PIN:
|
||||
ret = dev_read_string_index(config, "pins", i, &name);
|
||||
if (ret)
|
||||
return ret;
|
||||
selector = pinctrl_pin_name_to_selector(dev, name);
|
||||
break;
|
||||
case PST_GROUP:
|
||||
ret = dev_read_string_index(config, "groups", i, &name);
|
||||
if (ret)
|
||||
return ret;
|
||||
selector = pinctrl_group_name_to_selector(dev, name);
|
||||
break;
|
||||
case PST_PINMUX: {
|
||||
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
|
||||
u32 pinmux_group = fdt32_to_cpu(pinmux_groups[i]);
|
||||
|
||||
/* Checked for in pinctrl_generic_get_subnode_type */
|
||||
selector = ops->pinmux_property_set(dev, pinmux_group);
|
||||
break;
|
||||
}
|
||||
case PST_NONE:
|
||||
default:
|
||||
/* skip this node; may contain config child nodes */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < strings_count; i++) {
|
||||
ret = dev_read_string_index(config, subnode_target_type, i,
|
||||
&name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (is_group)
|
||||
selector = pinctrl_group_name_to_selector(dev, name);
|
||||
else
|
||||
selector = pinctrl_pin_name_to_selector(dev, name);
|
||||
if (selector < 0)
|
||||
return selector;
|
||||
|
||||
ret = pinctrl_generic_set_state_one(dev, config,
|
||||
is_group, selector);
|
||||
ret = pinctrl_generic_set_state_one(dev, config, subnode_type,
|
||||
selector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
737
drivers/pinctrl/pinctrl-kendryte.c
Normal file
737
drivers/pinctrl/pinctrl-kendryte.c
Normal file
|
@ -0,0 +1,737 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/k210-pinctrl.h>
|
||||
#include <mapmem.h>
|
||||
#include <regmap.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
/*
|
||||
* The K210 only implements 8 drive levels, even though there is register space
|
||||
* for 16
|
||||
*/
|
||||
#define K210_PC_DRIVE_MASK GENMASK(11, 8)
|
||||
#define K210_PC_DRIVE_SHIFT 8
|
||||
#define K210_PC_DRIVE_0 (0 << K210_PC_DRIVE_SHIFT)
|
||||
#define K210_PC_DRIVE_1 (1 << K210_PC_DRIVE_SHIFT)
|
||||
#define K210_PC_DRIVE_2 (2 << K210_PC_DRIVE_SHIFT)
|
||||
#define K210_PC_DRIVE_3 (3 << K210_PC_DRIVE_SHIFT)
|
||||
#define K210_PC_DRIVE_4 (4 << K210_PC_DRIVE_SHIFT)
|
||||
#define K210_PC_DRIVE_5 (5 << K210_PC_DRIVE_SHIFT)
|
||||
#define K210_PC_DRIVE_6 (6 << K210_PC_DRIVE_SHIFT)
|
||||
#define K210_PC_DRIVE_7 (7 << K210_PC_DRIVE_SHIFT)
|
||||
#define K210_PC_DRIVE_MAX 7
|
||||
|
||||
#define K210_PC_MODE_MASK GENMASK(23, 12)
|
||||
/*
|
||||
* output enabled == PC_OE & (PC_OE_INV ^ FUNCTION_OE) where FUNCTION_OE is a
|
||||
* physical signal from the function
|
||||
*/
|
||||
#define K210_PC_OE BIT(12) /* Output Enable */
|
||||
#define K210_PC_OE_INV BIT(13) /* INVert function-controlled Output Enable */
|
||||
#define K210_PC_DO_OE BIT(14) /* set Data Out to the Output Enable signal */
|
||||
#define K210_PC_DO_INV BIT(15) /* INVert final Data Output */
|
||||
#define K210_PC_PU BIT(16) /* Pull Up */
|
||||
#define K210_PC_PD BIT(17) /* Pull Down */
|
||||
/* Strong pull up not implemented on K210 */
|
||||
#define K210_PC_SL BIT(19) /* reduce SLew rate to prevent overshoot */
|
||||
/* Same semantics as OE above */
|
||||
#define K210_PC_IE BIT(20) /* Input Enable */
|
||||
#define K210_PC_IE_INV BIT(21) /* INVert function-controlled Input Enable */
|
||||
#define K210_PC_DI_INV BIT(22) /* INVert Data Input */
|
||||
#define K210_PC_ST BIT(23) /* Schmitt Trigger */
|
||||
#define K210_PC_DI BIT(31) /* raw Data Input */
|
||||
#define K210_PC_BIAS_MASK (K210_PC_PU & K210_PC_PD)
|
||||
|
||||
#define K210_PC_MODE_IN (K210_PC_IE | K210_PC_ST)
|
||||
#define K210_PC_MODE_OUT (K210_PC_DRIVE_7 | K210_PC_OE)
|
||||
#define K210_PC_MODE_I2C (K210_PC_MODE_IN | K210_PC_IE_INV | K210_PC_SL | \
|
||||
K210_PC_OE | K210_PC_OE_INV | K210_PC_PU)
|
||||
#define K210_PC_MODE_SPI (K210_PC_MODE_IN | K210_PC_IE_INV | \
|
||||
K210_PC_MODE_OUT | K210_PC_OE_INV)
|
||||
#define K210_PC_MODE_GPIO (K210_PC_MODE_IN | K210_PC_MODE_OUT)
|
||||
|
||||
#define K210_PG_FUNC GENMASK(7, 0)
|
||||
#define K210_PG_DO BIT(8)
|
||||
#define K210_PG_PIN GENMASK(22, 16)
|
||||
|
||||
#define PIN_CONFIG_OUTPUT_INVERT (PIN_CONFIG_END + 1)
|
||||
#define PIN_CONFIG_INPUT_INVERT (PIN_CONFIG_END + 2)
|
||||
|
||||
struct k210_fpioa {
|
||||
u32 pins[48];
|
||||
u32 tie_en[8];
|
||||
u32 tie_val[8];
|
||||
};
|
||||
|
||||
struct k210_pc_priv {
|
||||
struct clk clk;
|
||||
struct k210_fpioa __iomem *fpioa; /* FPIOA register */
|
||||
struct regmap *sysctl; /* Sysctl regmap */
|
||||
u32 power_offset; /* Power bank register offset */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CMD_PINMUX
|
||||
static const char k210_pc_pin_names[][6] = {
|
||||
#define PIN(i) \
|
||||
[i] = "IO_" #i
|
||||
PIN(0),
|
||||
PIN(1),
|
||||
PIN(2),
|
||||
PIN(3),
|
||||
PIN(4),
|
||||
PIN(5),
|
||||
PIN(6),
|
||||
PIN(7),
|
||||
PIN(8),
|
||||
PIN(9),
|
||||
PIN(10),
|
||||
PIN(11),
|
||||
PIN(12),
|
||||
PIN(13),
|
||||
PIN(14),
|
||||
PIN(15),
|
||||
PIN(16),
|
||||
PIN(17),
|
||||
PIN(18),
|
||||
PIN(19),
|
||||
PIN(20),
|
||||
PIN(21),
|
||||
PIN(22),
|
||||
PIN(23),
|
||||
PIN(24),
|
||||
PIN(25),
|
||||
PIN(26),
|
||||
PIN(27),
|
||||
PIN(28),
|
||||
PIN(29),
|
||||
PIN(30),
|
||||
PIN(31),
|
||||
PIN(32),
|
||||
PIN(33),
|
||||
PIN(34),
|
||||
PIN(35),
|
||||
PIN(36),
|
||||
PIN(37),
|
||||
PIN(38),
|
||||
PIN(39),
|
||||
PIN(40),
|
||||
PIN(41),
|
||||
PIN(42),
|
||||
PIN(43),
|
||||
PIN(44),
|
||||
PIN(45),
|
||||
PIN(46),
|
||||
PIN(47),
|
||||
#undef PIN
|
||||
};
|
||||
|
||||
static int k210_pc_get_pins_count(struct udevice *dev)
|
||||
{
|
||||
return ARRAY_SIZE(k210_pc_pin_names);
|
||||
};
|
||||
|
||||
static const char *k210_pc_get_pin_name(struct udevice *dev, unsigned selector)
|
||||
{
|
||||
return k210_pc_pin_names[selector];
|
||||
}
|
||||
#endif /* CONFIG_CMD_PINMUX */
|
||||
|
||||
/* These are just power domains */
|
||||
static const char k210_pc_group_names[][3] = {
|
||||
[0] = "A0",
|
||||
[1] = "A1",
|
||||
[2] = "A2",
|
||||
[3] = "B0",
|
||||
[4] = "B1",
|
||||
[5] = "B2",
|
||||
[6] = "C0",
|
||||
[7] = "C1",
|
||||
};
|
||||
|
||||
static int k210_pc_get_groups_count(struct udevice *dev)
|
||||
{
|
||||
return ARRAY_SIZE(k210_pc_group_names);
|
||||
}
|
||||
|
||||
static const char *k210_pc_get_group_name(struct udevice *dev,
|
||||
unsigned selector)
|
||||
{
|
||||
return k210_pc_group_names[selector];
|
||||
}
|
||||
|
||||
enum k210_pc_mode_id {
|
||||
K210_PC_DEFAULT_DISABLED,
|
||||
K210_PC_DEFAULT_IN,
|
||||
K210_PC_DEFAULT_IN_TIE,
|
||||
K210_PC_DEFAULT_OUT,
|
||||
K210_PC_DEFAULT_I2C,
|
||||
K210_PC_DEFAULT_SPI,
|
||||
K210_PC_DEFAULT_GPIO,
|
||||
K210_PC_DEFAULT_INT13,
|
||||
};
|
||||
|
||||
static const u32 k210_pc_mode_id_to_mode[] = {
|
||||
#define DEFAULT(mode) \
|
||||
[K210_PC_DEFAULT_##mode] = K210_PC_MODE_##mode
|
||||
[K210_PC_DEFAULT_DISABLED] = 0,
|
||||
DEFAULT(IN),
|
||||
[K210_PC_DEFAULT_IN_TIE] = K210_PC_MODE_IN,
|
||||
DEFAULT(OUT),
|
||||
DEFAULT(I2C),
|
||||
DEFAULT(SPI),
|
||||
DEFAULT(GPIO),
|
||||
[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
|
||||
#undef DEFAULT
|
||||
};
|
||||
|
||||
/* This saves around 2K vs having a pointer+mode */
|
||||
struct k210_pcf_info {
|
||||
#ifdef CONFIG_CMD_PINMUX
|
||||
char name[15];
|
||||
#endif
|
||||
u8 mode_id;
|
||||
};
|
||||
|
||||
static const struct k210_pcf_info k210_pcf_infos[] = {
|
||||
#ifdef CONFIG_CMD_PINMUX
|
||||
#define FUNC(id, mode) \
|
||||
[K210_PCF_##id] = { \
|
||||
.name = #id, \
|
||||
.mode_id = K210_PC_DEFAULT_##mode \
|
||||
}
|
||||
#else
|
||||
#define FUNC(id, mode) \
|
||||
[K210_PCF_##id] = { \
|
||||
.mode_id = K210_PC_DEFAULT_##mode \
|
||||
}
|
||||
#endif
|
||||
FUNC(JTAG_TCLK, IN),
|
||||
FUNC(JTAG_TDI, IN),
|
||||
FUNC(JTAG_TMS, IN),
|
||||
FUNC(JTAG_TDO, OUT),
|
||||
FUNC(SPI0_D0, SPI),
|
||||
FUNC(SPI0_D1, SPI),
|
||||
FUNC(SPI0_D2, SPI),
|
||||
FUNC(SPI0_D3, SPI),
|
||||
FUNC(SPI0_D4, SPI),
|
||||
FUNC(SPI0_D5, SPI),
|
||||
FUNC(SPI0_D6, SPI),
|
||||
FUNC(SPI0_D7, SPI),
|
||||
FUNC(SPI0_SS0, OUT),
|
||||
FUNC(SPI0_SS1, OUT),
|
||||
FUNC(SPI0_SS2, OUT),
|
||||
FUNC(SPI0_SS3, OUT),
|
||||
FUNC(SPI0_ARB, IN_TIE),
|
||||
FUNC(SPI0_SCLK, OUT),
|
||||
FUNC(UARTHS_RX, IN),
|
||||
FUNC(UARTHS_TX, OUT),
|
||||
FUNC(RESV6, IN),
|
||||
FUNC(RESV7, IN),
|
||||
FUNC(CLK_SPI1, OUT),
|
||||
FUNC(CLK_I2C1, OUT),
|
||||
FUNC(GPIOHS0, GPIO),
|
||||
FUNC(GPIOHS1, GPIO),
|
||||
FUNC(GPIOHS2, GPIO),
|
||||
FUNC(GPIOHS3, GPIO),
|
||||
FUNC(GPIOHS4, GPIO),
|
||||
FUNC(GPIOHS5, GPIO),
|
||||
FUNC(GPIOHS6, GPIO),
|
||||
FUNC(GPIOHS7, GPIO),
|
||||
FUNC(GPIOHS8, GPIO),
|
||||
FUNC(GPIOHS9, GPIO),
|
||||
FUNC(GPIOHS10, GPIO),
|
||||
FUNC(GPIOHS11, GPIO),
|
||||
FUNC(GPIOHS12, GPIO),
|
||||
FUNC(GPIOHS13, GPIO),
|
||||
FUNC(GPIOHS14, GPIO),
|
||||
FUNC(GPIOHS15, GPIO),
|
||||
FUNC(GPIOHS16, GPIO),
|
||||
FUNC(GPIOHS17, GPIO),
|
||||
FUNC(GPIOHS18, GPIO),
|
||||
FUNC(GPIOHS19, GPIO),
|
||||
FUNC(GPIOHS20, GPIO),
|
||||
FUNC(GPIOHS21, GPIO),
|
||||
FUNC(GPIOHS22, GPIO),
|
||||
FUNC(GPIOHS23, GPIO),
|
||||
FUNC(GPIOHS24, GPIO),
|
||||
FUNC(GPIOHS25, GPIO),
|
||||
FUNC(GPIOHS26, GPIO),
|
||||
FUNC(GPIOHS27, GPIO),
|
||||
FUNC(GPIOHS28, GPIO),
|
||||
FUNC(GPIOHS29, GPIO),
|
||||
FUNC(GPIOHS30, GPIO),
|
||||
FUNC(GPIOHS31, GPIO),
|
||||
FUNC(GPIO0, GPIO),
|
||||
FUNC(GPIO1, GPIO),
|
||||
FUNC(GPIO2, GPIO),
|
||||
FUNC(GPIO3, GPIO),
|
||||
FUNC(GPIO4, GPIO),
|
||||
FUNC(GPIO5, GPIO),
|
||||
FUNC(GPIO6, GPIO),
|
||||
FUNC(GPIO7, GPIO),
|
||||
FUNC(UART1_RX, IN),
|
||||
FUNC(UART1_TX, OUT),
|
||||
FUNC(UART2_RX, IN),
|
||||
FUNC(UART2_TX, OUT),
|
||||
FUNC(UART3_RX, IN),
|
||||
FUNC(UART3_TX, OUT),
|
||||
FUNC(SPI1_D0, SPI),
|
||||
FUNC(SPI1_D1, SPI),
|
||||
FUNC(SPI1_D2, SPI),
|
||||
FUNC(SPI1_D3, SPI),
|
||||
FUNC(SPI1_D4, SPI),
|
||||
FUNC(SPI1_D5, SPI),
|
||||
FUNC(SPI1_D6, SPI),
|
||||
FUNC(SPI1_D7, SPI),
|
||||
FUNC(SPI1_SS0, OUT),
|
||||
FUNC(SPI1_SS1, OUT),
|
||||
FUNC(SPI1_SS2, OUT),
|
||||
FUNC(SPI1_SS3, OUT),
|
||||
FUNC(SPI1_ARB, IN_TIE),
|
||||
FUNC(SPI1_SCLK, OUT),
|
||||
FUNC(SPI2_D0, SPI),
|
||||
FUNC(SPI2_SS, IN),
|
||||
FUNC(SPI2_SCLK, IN),
|
||||
FUNC(I2S0_MCLK, OUT),
|
||||
FUNC(I2S0_SCLK, OUT),
|
||||
FUNC(I2S0_WS, OUT),
|
||||
FUNC(I2S0_IN_D0, IN),
|
||||
FUNC(I2S0_IN_D1, IN),
|
||||
FUNC(I2S0_IN_D2, IN),
|
||||
FUNC(I2S0_IN_D3, IN),
|
||||
FUNC(I2S0_OUT_D0, OUT),
|
||||
FUNC(I2S0_OUT_D1, OUT),
|
||||
FUNC(I2S0_OUT_D2, OUT),
|
||||
FUNC(I2S0_OUT_D3, OUT),
|
||||
FUNC(I2S1_MCLK, OUT),
|
||||
FUNC(I2S1_SCLK, OUT),
|
||||
FUNC(I2S1_WS, OUT),
|
||||
FUNC(I2S1_IN_D0, IN),
|
||||
FUNC(I2S1_IN_D1, IN),
|
||||
FUNC(I2S1_IN_D2, IN),
|
||||
FUNC(I2S1_IN_D3, IN),
|
||||
FUNC(I2S1_OUT_D0, OUT),
|
||||
FUNC(I2S1_OUT_D1, OUT),
|
||||
FUNC(I2S1_OUT_D2, OUT),
|
||||
FUNC(I2S1_OUT_D3, OUT),
|
||||
FUNC(I2S2_MCLK, OUT),
|
||||
FUNC(I2S2_SCLK, OUT),
|
||||
FUNC(I2S2_WS, OUT),
|
||||
FUNC(I2S2_IN_D0, IN),
|
||||
FUNC(I2S2_IN_D1, IN),
|
||||
FUNC(I2S2_IN_D2, IN),
|
||||
FUNC(I2S2_IN_D3, IN),
|
||||
FUNC(I2S2_OUT_D0, OUT),
|
||||
FUNC(I2S2_OUT_D1, OUT),
|
||||
FUNC(I2S2_OUT_D2, OUT),
|
||||
FUNC(I2S2_OUT_D3, OUT),
|
||||
FUNC(RESV0, DISABLED),
|
||||
FUNC(RESV1, DISABLED),
|
||||
FUNC(RESV2, DISABLED),
|
||||
FUNC(RESV3, DISABLED),
|
||||
FUNC(RESV4, DISABLED),
|
||||
FUNC(RESV5, DISABLED),
|
||||
FUNC(I2C0_SCLK, I2C),
|
||||
FUNC(I2C0_SDA, I2C),
|
||||
FUNC(I2C1_SCLK, I2C),
|
||||
FUNC(I2C1_SDA, I2C),
|
||||
FUNC(I2C2_SCLK, I2C),
|
||||
FUNC(I2C2_SDA, I2C),
|
||||
FUNC(DVP_XCLK, OUT),
|
||||
FUNC(DVP_RST, OUT),
|
||||
FUNC(DVP_PWDN, OUT),
|
||||
FUNC(DVP_VSYNC, IN),
|
||||
FUNC(DVP_HSYNC, IN),
|
||||
FUNC(DVP_PCLK, IN),
|
||||
FUNC(DVP_D0, IN),
|
||||
FUNC(DVP_D1, IN),
|
||||
FUNC(DVP_D2, IN),
|
||||
FUNC(DVP_D3, IN),
|
||||
FUNC(DVP_D4, IN),
|
||||
FUNC(DVP_D5, IN),
|
||||
FUNC(DVP_D6, IN),
|
||||
FUNC(DVP_D7, IN),
|
||||
FUNC(SCCB_SCLK, I2C),
|
||||
FUNC(SCCB_SDA, I2C),
|
||||
FUNC(UART1_CTS, IN),
|
||||
FUNC(UART1_DSR, IN),
|
||||
FUNC(UART1_DCD, IN),
|
||||
FUNC(UART1_RI, IN),
|
||||
FUNC(UART1_SIR_IN, IN),
|
||||
FUNC(UART1_DTR, OUT),
|
||||
FUNC(UART1_RTS, OUT),
|
||||
FUNC(UART1_OUT2, OUT),
|
||||
FUNC(UART1_OUT1, OUT),
|
||||
FUNC(UART1_SIR_OUT, OUT),
|
||||
FUNC(UART1_BAUD, OUT),
|
||||
FUNC(UART1_RE, OUT),
|
||||
FUNC(UART1_DE, OUT),
|
||||
FUNC(UART1_RS485_EN, OUT),
|
||||
FUNC(UART2_CTS, IN),
|
||||
FUNC(UART2_DSR, IN),
|
||||
FUNC(UART2_DCD, IN),
|
||||
FUNC(UART2_RI, IN),
|
||||
FUNC(UART2_SIR_IN, IN),
|
||||
FUNC(UART2_DTR, OUT),
|
||||
FUNC(UART2_RTS, OUT),
|
||||
FUNC(UART2_OUT2, OUT),
|
||||
FUNC(UART2_OUT1, OUT),
|
||||
FUNC(UART2_SIR_OUT, OUT),
|
||||
FUNC(UART2_BAUD, OUT),
|
||||
FUNC(UART2_RE, OUT),
|
||||
FUNC(UART2_DE, OUT),
|
||||
FUNC(UART2_RS485_EN, OUT),
|
||||
FUNC(UART3_CTS, IN),
|
||||
FUNC(UART3_DSR, IN),
|
||||
FUNC(UART3_DCD, IN),
|
||||
FUNC(UART3_RI, IN),
|
||||
FUNC(UART3_SIR_IN, IN),
|
||||
FUNC(UART3_DTR, OUT),
|
||||
FUNC(UART3_RTS, OUT),
|
||||
FUNC(UART3_OUT2, OUT),
|
||||
FUNC(UART3_OUT1, OUT),
|
||||
FUNC(UART3_SIR_OUT, OUT),
|
||||
FUNC(UART3_BAUD, OUT),
|
||||
FUNC(UART3_RE, OUT),
|
||||
FUNC(UART3_DE, OUT),
|
||||
FUNC(UART3_RS485_EN, OUT),
|
||||
FUNC(TIMER0_TOGGLE1, OUT),
|
||||
FUNC(TIMER0_TOGGLE2, OUT),
|
||||
FUNC(TIMER0_TOGGLE3, OUT),
|
||||
FUNC(TIMER0_TOGGLE4, OUT),
|
||||
FUNC(TIMER1_TOGGLE1, OUT),
|
||||
FUNC(TIMER1_TOGGLE2, OUT),
|
||||
FUNC(TIMER1_TOGGLE3, OUT),
|
||||
FUNC(TIMER1_TOGGLE4, OUT),
|
||||
FUNC(TIMER2_TOGGLE1, OUT),
|
||||
FUNC(TIMER2_TOGGLE2, OUT),
|
||||
FUNC(TIMER2_TOGGLE3, OUT),
|
||||
FUNC(TIMER2_TOGGLE4, OUT),
|
||||
FUNC(CLK_SPI2, OUT),
|
||||
FUNC(CLK_I2C2, OUT),
|
||||
FUNC(INTERNAL0, OUT),
|
||||
FUNC(INTERNAL1, OUT),
|
||||
FUNC(INTERNAL2, OUT),
|
||||
FUNC(INTERNAL3, OUT),
|
||||
FUNC(INTERNAL4, OUT),
|
||||
FUNC(INTERNAL5, OUT),
|
||||
FUNC(INTERNAL6, OUT),
|
||||
FUNC(INTERNAL7, OUT),
|
||||
FUNC(INTERNAL8, OUT),
|
||||
FUNC(INTERNAL9, IN),
|
||||
FUNC(INTERNAL10, IN),
|
||||
FUNC(INTERNAL11, IN),
|
||||
FUNC(INTERNAL12, IN),
|
||||
FUNC(INTERNAL13, INT13),
|
||||
FUNC(INTERNAL14, I2C),
|
||||
FUNC(INTERNAL15, IN),
|
||||
FUNC(INTERNAL16, IN),
|
||||
FUNC(INTERNAL17, IN),
|
||||
FUNC(CONSTANT, DISABLED),
|
||||
FUNC(INTERNAL18, IN),
|
||||
FUNC(DEBUG0, OUT),
|
||||
FUNC(DEBUG1, OUT),
|
||||
FUNC(DEBUG2, OUT),
|
||||
FUNC(DEBUG3, OUT),
|
||||
FUNC(DEBUG4, OUT),
|
||||
FUNC(DEBUG5, OUT),
|
||||
FUNC(DEBUG6, OUT),
|
||||
FUNC(DEBUG7, OUT),
|
||||
FUNC(DEBUG8, OUT),
|
||||
FUNC(DEBUG9, OUT),
|
||||
FUNC(DEBUG10, OUT),
|
||||
FUNC(DEBUG11, OUT),
|
||||
FUNC(DEBUG12, OUT),
|
||||
FUNC(DEBUG13, OUT),
|
||||
FUNC(DEBUG14, OUT),
|
||||
FUNC(DEBUG15, OUT),
|
||||
FUNC(DEBUG16, OUT),
|
||||
FUNC(DEBUG17, OUT),
|
||||
FUNC(DEBUG18, OUT),
|
||||
FUNC(DEBUG19, OUT),
|
||||
FUNC(DEBUG20, OUT),
|
||||
FUNC(DEBUG21, OUT),
|
||||
FUNC(DEBUG22, OUT),
|
||||
FUNC(DEBUG23, OUT),
|
||||
FUNC(DEBUG24, OUT),
|
||||
FUNC(DEBUG25, OUT),
|
||||
FUNC(DEBUG26, OUT),
|
||||
FUNC(DEBUG27, OUT),
|
||||
FUNC(DEBUG28, OUT),
|
||||
FUNC(DEBUG29, OUT),
|
||||
FUNC(DEBUG30, OUT),
|
||||
FUNC(DEBUG31, OUT),
|
||||
#undef FUNC
|
||||
};
|
||||
|
||||
static int k210_pc_pinmux_set(struct udevice *dev, u32 pinmux_group)
|
||||
{
|
||||
unsigned pin = FIELD_GET(K210_PG_PIN, pinmux_group);
|
||||
bool do_oe = FIELD_GET(K210_PG_DO, pinmux_group);
|
||||
unsigned func = FIELD_GET(K210_PG_FUNC, pinmux_group);
|
||||
struct k210_pc_priv *priv = dev_get_priv(dev);
|
||||
const struct k210_pcf_info *info = &k210_pcf_infos[func];
|
||||
u32 mode = k210_pc_mode_id_to_mode[info->mode_id];
|
||||
u32 val = func | mode | (do_oe ? K210_PC_DO_OE : 0);
|
||||
|
||||
debug("%s(%.8x): IO_%.2u = %3u | %.8x\n", __func__, pinmux_group, pin,
|
||||
func, mode);
|
||||
|
||||
writel(val, &priv->fpioa->pins[pin]);
|
||||
return pin;
|
||||
}
|
||||
|
||||
/* Max drive strength in uA */
|
||||
static const int k210_pc_drive_strength[] = {
|
||||
[0] = 11200,
|
||||
[1] = 16800,
|
||||
[2] = 22300,
|
||||
[3] = 27800,
|
||||
[4] = 33300,
|
||||
[5] = 38700,
|
||||
[6] = 44100,
|
||||
[7] = 49500,
|
||||
};
|
||||
|
||||
static int k210_pc_get_drive(unsigned max_strength_ua)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = K210_PC_DRIVE_MAX; i; i--)
|
||||
if (k210_pc_drive_strength[i] < max_strength_ua)
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int k210_pc_pinconf_set(struct udevice *dev, unsigned pin_selector,
|
||||
unsigned param, unsigned argument)
|
||||
{
|
||||
struct k210_pc_priv *priv = dev_get_priv(dev);
|
||||
u32 val = readl(&priv->fpioa->pins[pin_selector]);
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
val &= ~K210_PC_BIAS_MASK;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
if (argument)
|
||||
val |= K210_PC_PD;
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
if (argument)
|
||||
val |= K210_PC_PD;
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
argument *= 1000;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH_UA: {
|
||||
int drive = k210_pc_get_drive(argument);
|
||||
|
||||
if (IS_ERR_VALUE(drive))
|
||||
return drive;
|
||||
val &= ~K210_PC_DRIVE_MASK;
|
||||
val |= FIELD_PREP(K210_PC_DRIVE_MASK, drive);
|
||||
break;
|
||||
}
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
if (argument)
|
||||
val |= K210_PC_IE;
|
||||
else
|
||||
val &= ~K210_PC_IE;
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT:
|
||||
argument = 1;
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
if (argument)
|
||||
val |= K210_PC_ST;
|
||||
else
|
||||
val &= ~K210_PC_ST;
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
k210_pc_pinmux_set(dev,
|
||||
K210_FPIOA(pin_selector, K210_PCF_CONSTANT));
|
||||
val = readl(&priv->fpioa->pins[pin_selector]);
|
||||
val |= K210_PC_MODE_OUT;
|
||||
|
||||
if (!argument)
|
||||
val |= K210_PC_DO_INV;
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT_ENABLE:
|
||||
if (argument)
|
||||
val |= K210_PC_OE;
|
||||
else
|
||||
val &= ~K210_PC_OE;
|
||||
break;
|
||||
case PIN_CONFIG_SLEW_RATE:
|
||||
if (argument)
|
||||
val |= K210_PC_SL;
|
||||
else
|
||||
val &= ~K210_PC_SL;
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT_INVERT:
|
||||
if (argument)
|
||||
val |= K210_PC_DO_INV;
|
||||
else
|
||||
val &= ~K210_PC_DO_INV;
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_INVERT:
|
||||
if (argument)
|
||||
val |= K210_PC_DI_INV;
|
||||
else
|
||||
val &= ~K210_PC_DI_INV;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(val, &priv->fpioa->pins[pin_selector]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int k210_pc_pinconf_group_set(struct udevice *dev,
|
||||
unsigned group_selector, unsigned param,
|
||||
unsigned argument)
|
||||
{
|
||||
struct k210_pc_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (param == PIN_CONFIG_POWER_SOURCE) {
|
||||
u32 bit = BIT(group_selector);
|
||||
|
||||
regmap_update_bits(priv->sysctl, priv->power_offset, bit,
|
||||
argument ? bit : 0);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CMD_PINMUX
|
||||
static int k210_pc_get_pin_muxing(struct udevice *dev, unsigned int selector,
|
||||
char *buf, int size)
|
||||
{
|
||||
struct k210_pc_priv *priv = dev_get_priv(dev);
|
||||
u32 val = readl(&priv->fpioa->pins[selector]);
|
||||
const struct k210_pcf_info *info = &k210_pcf_infos[val & K210_PCF_MASK];
|
||||
|
||||
strncpy(buf, info->name, min((size_t)size, sizeof(info->name)));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct pinconf_param k210_pc_pinconf_params[] = {
|
||||
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
|
||||
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
|
||||
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
|
||||
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, U32_MAX },
|
||||
{ "drive-strength-ua", PIN_CONFIG_DRIVE_STRENGTH_UA, U32_MAX },
|
||||
{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
|
||||
{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
|
||||
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
|
||||
{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
|
||||
{ "power-source", PIN_CONFIG_POWER_SOURCE, K210_PC_POWER_1V8 },
|
||||
{ "output-low", PIN_CONFIG_OUTPUT, 0 },
|
||||
{ "output-high", PIN_CONFIG_OUTPUT, 1 },
|
||||
{ "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
|
||||
{ "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 },
|
||||
{ "slew-rate", PIN_CONFIG_SLEW_RATE, 1 },
|
||||
{ "output-polarity-invert", PIN_CONFIG_OUTPUT_INVERT, 1},
|
||||
{ "input-polarity-invert", PIN_CONFIG_INPUT_INVERT, 1},
|
||||
};
|
||||
|
||||
static const struct pinctrl_ops k210_pc_pinctrl_ops = {
|
||||
#ifdef CONFIG_CMD_PINMUX
|
||||
.get_pins_count = k210_pc_get_pins_count,
|
||||
.get_pin_name = k210_pc_get_pin_name,
|
||||
#endif
|
||||
.get_groups_count = k210_pc_get_groups_count,
|
||||
.get_group_name = k210_pc_get_group_name,
|
||||
.pinmux_property_set = k210_pc_pinmux_set,
|
||||
.pinconf_num_params = ARRAY_SIZE(k210_pc_pinconf_params),
|
||||
.pinconf_params = k210_pc_pinconf_params,
|
||||
.pinconf_set = k210_pc_pinconf_set,
|
||||
.pinconf_group_set = k210_pc_pinconf_group_set,
|
||||
.set_state = pinctrl_generic_set_state,
|
||||
#ifdef CONFIG_CMD_PINMUX
|
||||
.get_pin_muxing = k210_pc_get_pin_muxing,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int k210_pc_probe(struct udevice *dev)
|
||||
{
|
||||
int ret, i, j;
|
||||
struct k210_pc_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->fpioa = dev_read_addr_ptr(dev);
|
||||
if (!priv->fpioa)
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &priv->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_enable(&priv->clk);
|
||||
if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
|
||||
goto err;
|
||||
|
||||
priv->sysctl = syscon_regmap_lookup_by_phandle(dev, "kendryte,sysctl");
|
||||
if (IS_ERR(priv->sysctl)) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = dev_read_u32(dev, "kendryte,power-offset", &priv->power_offset);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
debug("%s: fpioa = %p sysctl = %p power offset = %x\n", __func__,
|
||||
priv->fpioa, (void *)priv->sysctl->ranges[0].start,
|
||||
priv->power_offset);
|
||||
|
||||
/* Init input ties */
|
||||
for (i = 0; i < ARRAY_SIZE(priv->fpioa->tie_en); i++) {
|
||||
u32 val = 0;
|
||||
|
||||
for (j = 0; j < 32; j++)
|
||||
if (k210_pcf_infos[i * 32 + j].mode_id ==
|
||||
K210_PC_DEFAULT_IN_TIE)
|
||||
val |= BIT(j);
|
||||
writel(val, &priv->fpioa->tie_en[i]);
|
||||
writel(val, &priv->fpioa->tie_val[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
clk_free(&priv->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct udevice_id k210_pc_ids[] = {
|
||||
{ .compatible = "kendryte,k210-fpioa" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pinctrl_k210) = {
|
||||
.name = "pinctrl_k210",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = k210_pc_ids,
|
||||
.probe = k210_pc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct k210_pc_priv),
|
||||
.ops = &k210_pc_pinctrl_ops,
|
||||
};
|
|
@ -1,57 +1,70 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
|
||||
* Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
|
||||
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <log.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/sandbox-pinmux.h>
|
||||
#include <log.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
/*
|
||||
* This driver emulates a pin controller with the following rules:
|
||||
* - The pinctrl config for each pin must be set individually
|
||||
* - The first three pins (P0-P2) must be muxed as a group
|
||||
* - The next two pins (P3-P4) must be muxed as a group
|
||||
* - The last four pins (P5-P8) must be muxed individually
|
||||
*/
|
||||
|
||||
static const char * const sandbox_pins[] = {
|
||||
"SCL",
|
||||
"SDA",
|
||||
"TX",
|
||||
"RX",
|
||||
"W1",
|
||||
"GPIO0",
|
||||
"GPIO1",
|
||||
"GPIO2",
|
||||
"GPIO3",
|
||||
#define PIN(x) \
|
||||
[x] = "P" #x
|
||||
PIN(0),
|
||||
PIN(1),
|
||||
PIN(2),
|
||||
PIN(3),
|
||||
PIN(4),
|
||||
PIN(5),
|
||||
PIN(6),
|
||||
PIN(7),
|
||||
PIN(8),
|
||||
#undef PIN
|
||||
};
|
||||
|
||||
static const char * const sandbox_pins_muxing[] = {
|
||||
"I2C SCL",
|
||||
"I2C SDA",
|
||||
"Uart TX",
|
||||
"Uart RX",
|
||||
"1-wire gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
static const char * const sandbox_pins_muxing[][2] = {
|
||||
{ "UART TX", "I2C SCL" },
|
||||
{ "UART RX", "I2C SDA" },
|
||||
{ "SPI SCLK", "I2S SCK" },
|
||||
{ "SPI MOSI", "I2S SD" },
|
||||
{ "SPI MISO", "I2S WS" },
|
||||
{ "GPIO0", "SPI CS0" },
|
||||
{ "GPIO1", "SPI CS1" },
|
||||
{ "GPIO2", "PWM0" },
|
||||
{ "GPIO3", "PWM1" },
|
||||
};
|
||||
|
||||
#define SANDBOX_GROUP_I2C_UART 0
|
||||
#define SANDBOX_GROUP_SPI_I2S 1
|
||||
|
||||
static const char * const sandbox_groups[] = {
|
||||
"i2c",
|
||||
"serial_a",
|
||||
"serial_b",
|
||||
"spi",
|
||||
"w1",
|
||||
[SANDBOX_GROUP_I2C_UART] = "I2C_UART",
|
||||
[SANDBOX_GROUP_SPI_I2S] = "SPI_I2S",
|
||||
};
|
||||
|
||||
static const char * const sandbox_functions[] = {
|
||||
"i2c",
|
||||
"serial",
|
||||
"spi",
|
||||
"w1",
|
||||
"gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
#define FUNC(id) \
|
||||
[SANDBOX_PINMUX_##id] = #id
|
||||
FUNC(UART),
|
||||
FUNC(I2C),
|
||||
FUNC(SPI),
|
||||
FUNC(I2S),
|
||||
FUNC(GPIO),
|
||||
FUNC(CS),
|
||||
FUNC(PWM),
|
||||
#undef FUNC
|
||||
};
|
||||
|
||||
static const struct pinconf_param sandbox_conf_params[] = {
|
||||
|
@ -68,9 +81,12 @@ static const struct pinconf_param sandbox_conf_params[] = {
|
|||
{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
|
||||
};
|
||||
|
||||
/* bitfield used to save param and value of each pin/selector */
|
||||
static unsigned int sandbox_pins_param[ARRAY_SIZE(sandbox_pins)];
|
||||
static unsigned int sandbox_pins_value[ARRAY_SIZE(sandbox_pins)];
|
||||
/* Bitfield used to save param and value of each pin/selector */
|
||||
struct sandbox_pinctrl_priv {
|
||||
unsigned int mux;
|
||||
unsigned int pins_param[ARRAY_SIZE(sandbox_pins)];
|
||||
unsigned int pins_value[ARRAY_SIZE(sandbox_pins)];
|
||||
};
|
||||
|
||||
static int sandbox_get_pins_count(struct udevice *dev)
|
||||
{
|
||||
|
@ -87,16 +103,18 @@ static int sandbox_get_pin_muxing(struct udevice *dev,
|
|||
char *buf, int size)
|
||||
{
|
||||
const struct pinconf_param *p;
|
||||
struct sandbox_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
int i;
|
||||
|
||||
snprintf(buf, size, "%s", sandbox_pins_muxing[selector]);
|
||||
snprintf(buf, size, "%s",
|
||||
sandbox_pins_muxing[selector][!!(priv->mux & BIT(selector))]);
|
||||
|
||||
if (sandbox_pins_param[selector]) {
|
||||
if (priv->pins_param[selector]) {
|
||||
for (i = 0, p = sandbox_conf_params;
|
||||
i < ARRAY_SIZE(sandbox_conf_params);
|
||||
i++, p++) {
|
||||
if ((sandbox_pins_param[selector] & BIT(p->param)) &&
|
||||
(!!(sandbox_pins_value[selector] & BIT(p->param)) ==
|
||||
if ((priv->pins_param[selector] & BIT(p->param)) &&
|
||||
(!!(priv->pins_value[selector] & BIT(p->param)) ==
|
||||
p->default_value)) {
|
||||
strncat(buf, " ", size);
|
||||
strncat(buf, p->property, size);
|
||||
|
@ -133,12 +151,32 @@ static const char *sandbox_get_function_name(struct udevice *dev,
|
|||
static int sandbox_pinmux_set(struct udevice *dev, unsigned pin_selector,
|
||||
unsigned func_selector)
|
||||
{
|
||||
int mux;
|
||||
struct sandbox_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
debug("sandbox pinmux: pin = %d (%s), function = %d (%s)\n",
|
||||
pin_selector, sandbox_get_pin_name(dev, pin_selector),
|
||||
func_selector, sandbox_get_function_name(dev, func_selector));
|
||||
|
||||
sandbox_pins_param[pin_selector] = 0;
|
||||
sandbox_pins_value[pin_selector] = 0;
|
||||
if (pin_selector < 5)
|
||||
return -EINVAL;
|
||||
|
||||
switch (func_selector) {
|
||||
case SANDBOX_PINMUX_GPIO:
|
||||
mux = 0;
|
||||
break;
|
||||
case SANDBOX_PINMUX_CS:
|
||||
case SANDBOX_PINMUX_PWM:
|
||||
mux = BIT(pin_selector);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->mux &= ~BIT(pin_selector);
|
||||
priv->mux |= mux;
|
||||
priv->pins_param[pin_selector] = 0;
|
||||
priv->pins_value[pin_selector] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -147,25 +185,75 @@ static int sandbox_pinmux_group_set(struct udevice *dev,
|
|||
unsigned group_selector,
|
||||
unsigned func_selector)
|
||||
{
|
||||
bool mux;
|
||||
int i, group_start, group_end;
|
||||
struct sandbox_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
unsigned int mask;
|
||||
|
||||
debug("sandbox pinmux: group = %d (%s), function = %d (%s)\n",
|
||||
group_selector, sandbox_get_group_name(dev, group_selector),
|
||||
func_selector, sandbox_get_function_name(dev, func_selector));
|
||||
|
||||
if (group_selector == SANDBOX_GROUP_I2C_UART) {
|
||||
group_start = 0;
|
||||
group_end = 1;
|
||||
|
||||
if (func_selector == SANDBOX_PINMUX_UART)
|
||||
mux = false;
|
||||
else if (func_selector == SANDBOX_PINMUX_I2C)
|
||||
mux = true;
|
||||
else
|
||||
return -EINVAL;
|
||||
} else if (group_selector == SANDBOX_GROUP_SPI_I2S) {
|
||||
group_start = 2;
|
||||
group_end = 4;
|
||||
|
||||
if (func_selector == SANDBOX_PINMUX_SPI)
|
||||
mux = false;
|
||||
else if (func_selector == SANDBOX_PINMUX_I2S)
|
||||
mux = true;
|
||||
else
|
||||
return -EINVAL;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mask = GENMASK(group_end, group_start);
|
||||
priv->mux &= ~mask;
|
||||
priv->mux |= mux ? mask : 0;
|
||||
|
||||
for (i = group_start; i < group_end; i++) {
|
||||
priv->pins_param[i] = 0;
|
||||
priv->pins_value[i] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_pinmux_property_set(struct udevice *dev, u32 pinmux_group)
|
||||
{
|
||||
int ret;
|
||||
unsigned pin_selector = pinmux_group & 0xFFFF;
|
||||
unsigned func_selector = pinmux_group >> 16;
|
||||
|
||||
ret = sandbox_pinmux_set(dev, pin_selector, func_selector);
|
||||
return ret ? ret : pin_selector;
|
||||
}
|
||||
|
||||
static int sandbox_pinconf_set(struct udevice *dev, unsigned pin_selector,
|
||||
unsigned param, unsigned argument)
|
||||
{
|
||||
struct sandbox_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
debug("sandbox pinconf: pin = %d (%s), param = %d, arg = %d\n",
|
||||
pin_selector, sandbox_get_pin_name(dev, pin_selector),
|
||||
param, argument);
|
||||
|
||||
sandbox_pins_param[pin_selector] |= BIT(param);
|
||||
priv->pins_param[pin_selector] |= BIT(param);
|
||||
if (argument)
|
||||
sandbox_pins_value[pin_selector] |= BIT(param);
|
||||
priv->pins_value[pin_selector] |= BIT(param);
|
||||
else
|
||||
sandbox_pins_value[pin_selector] &= ~BIT(param);
|
||||
priv->pins_value[pin_selector] &= ~BIT(param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -191,6 +279,7 @@ const struct pinctrl_ops sandbox_pinctrl_ops = {
|
|||
.get_function_name = sandbox_get_function_name,
|
||||
.pinmux_set = sandbox_pinmux_set,
|
||||
.pinmux_group_set = sandbox_pinmux_group_set,
|
||||
.pinmux_property_set = sandbox_pinmux_property_set,
|
||||
.pinconf_num_params = ARRAY_SIZE(sandbox_conf_params),
|
||||
.pinconf_params = sandbox_conf_params,
|
||||
.pinconf_set = sandbox_pinconf_set,
|
||||
|
@ -207,5 +296,6 @@ U_BOOT_DRIVER(sandbox_pinctrl) = {
|
|||
.name = "sandbox_pinctrl",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = sandbox_pinctrl_match,
|
||||
.priv_auto_alloc_size = sizeof(struct sandbox_pinctrl_priv),
|
||||
.ops = &sandbox_pinctrl_ops,
|
||||
};
|
||||
|
|
|
@ -73,6 +73,7 @@ config IMXRT_SDRAM
|
|||
to support external memories like sdram, psram & nand.
|
||||
This driver is for the sdram memory interface with the SEMC.
|
||||
|
||||
source "drivers/ram/aspeed/Kconfig"
|
||||
source "drivers/ram/rockchip/Kconfig"
|
||||
source "drivers/ram/sifive/Kconfig"
|
||||
source "drivers/ram/stm32mp1/Kconfig"
|
||||
|
|
|
@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
|||
|
||||
obj-$(CONFIG_K3_AM654_DDRSS) += k3-am654-ddrss.o
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
|
||||
obj-$(CONFIG_K3_J721E_DDRSS) += k3-j721e/
|
||||
|
||||
obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o
|
||||
|
|
10
drivers/ram/aspeed/Kconfig
Normal file
10
drivers/ram/aspeed/Kconfig
Normal file
|
@ -0,0 +1,10 @@
|
|||
if RAM || SPL_RAM
|
||||
config ASPEED_DDR4_DUALX8
|
||||
bool "Enable Dual X8 DDR4 die"
|
||||
depends on DM && OF_CONTROL && ARCH_ASPEED
|
||||
default n
|
||||
help
|
||||
Say Y if dual X8 DDR4 die is used on the board. The aspeed ddr sdram
|
||||
controller needs to know if the memory chip mounted on the board is dual
|
||||
x8 die or not. Or it may get the wrong size of the memory space.
|
||||
endif
|
3
drivers/ram/aspeed/Makefile
Normal file
3
drivers/ram/aspeed/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
obj-$(CONFIG_ASPEED_AST2500) += sdram_ast2500.o
|
|
@ -247,7 +247,7 @@ static int ast2500_sdrammc_init_ddr4(struct dram_info *info)
|
|||
| SDRAM_PCR_RESETN_DIS
|
||||
| SDRAM_PCR_RGAP_CTRL_EN | SDRAM_PCR_ODT_EN | SDRAM_PCR_ODT_EXT_EN;
|
||||
const u32 conf = (SDRAM_CONF_CAP_1024M << SDRAM_CONF_CAP_SHIFT)
|
||||
#ifdef CONFIG_DUALX8_RAM
|
||||
#ifdef CONFIG_ASPEED_DDR4_DUALX8
|
||||
| SDRAM_CONF_DUALX8
|
||||
#endif
|
||||
| SDRAM_CONF_SCRAMBLE | SDRAM_CONF_SCRAMBLE_PAT2 | SDRAM_CONF_DDR4;
|
|
@ -130,7 +130,7 @@ static int designware_wdt_probe(struct udevice *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->clk_khz = clk_get_rate(&clk);
|
||||
priv->clk_khz = clk_get_rate(&clk) / 1000;
|
||||
if (!priv->clk_khz)
|
||||
return -EINVAL;
|
||||
#else
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
ifndef CONFIG_SANDBOX
|
||||
ifdef CONFIG_EXAMPLES
|
||||
|
||||
ifdef FTRACE
|
||||
subdir-ccflags-y += -finstrument-functions -DFTRACE
|
||||
|
|
|
@ -45,13 +45,7 @@
|
|||
#define CONFIG_SYS_CBSIZE 512
|
||||
|
||||
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
|
||||
#ifdef CONFIG_TFABOOT
|
||||
#define CONFIG_SYS_FLASH_BASE 0x4000000
|
||||
#define CONFIG_SYS_MAX_FLASH_BANKS 1
|
||||
#else
|
||||
#define CONFIG_SYS_FLASH_BASE 0x0
|
||||
#define CONFIG_SYS_MAX_FLASH_BANKS 2
|
||||
#endif
|
||||
#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 2
|
||||
#define CONFIG_SYS_MAX_FLASH_SECT 256 /* Sector: 256K, Bank: 64M */
|
||||
#define CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
|
||||
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@com>
|
||||
*/
|
||||
|
||||
#ifndef __PINCTRL_H
|
||||
|
@ -11,11 +11,10 @@
|
|||
|
||||
/**
|
||||
* struct pinconf_param - pin config parameters
|
||||
*
|
||||
* @property: property name in DT nodes
|
||||
* @param: ID for this config parameter
|
||||
* @default_value: default value for this config parameter used in case
|
||||
* no value is specified in DT nodes
|
||||
* @property: Property name in DT nodes
|
||||
* @param: ID for this config parameter
|
||||
* @default_value: default value for this config parameter used in case
|
||||
* no value is specified in DT nodes
|
||||
*/
|
||||
struct pinconf_param {
|
||||
const char * const property;
|
||||
|
@ -27,106 +26,274 @@ struct pinconf_param {
|
|||
* struct pinctrl_ops - pin control operations, to be implemented by
|
||||
* pin controller drivers.
|
||||
*
|
||||
* The @set_state is the only mandatory operation. You can implement your
|
||||
* pinctrl driver with its own @set_state. In this case, the other callbacks
|
||||
* are not required. Otherwise, generic pinctrl framework is also available;
|
||||
* use pinctrl_generic_set_state for @set_state, and implement other operations
|
||||
* set_state() is the only mandatory operation. You can implement your pinctrl
|
||||
* driver with its own @set_state. In this case, the other callbacks are not
|
||||
* required. Otherwise, generic pinctrl framework is also available; use
|
||||
* pinctrl_generic_set_state for @set_state, and implement other operations
|
||||
* depending on your necessity.
|
||||
*
|
||||
* @get_pins_count: return number of selectable named pins available
|
||||
* in this driver. (necessary to parse "pins" property in DTS)
|
||||
* @get_pin_name: return the pin name of the pin selector,
|
||||
* called by the core to figure out which pin it shall do
|
||||
* operations to. (necessary to parse "pins" property in DTS)
|
||||
* @get_groups_count: return number of selectable named groups available
|
||||
* in this driver. (necessary to parse "groups" property in DTS)
|
||||
* @get_group_name: return the group name of the group selector,
|
||||
* called by the core to figure out which pin group it shall do
|
||||
* operations to. (necessary to parse "groups" property in DTS)
|
||||
* @get_functions_count: return number of selectable named functions available
|
||||
* in this driver. (necessary for pin-muxing)
|
||||
* @get_function_name: return the function name of the muxing selector,
|
||||
* called by the core to figure out which mux setting it shall map a
|
||||
* certain device to. (necessary for pin-muxing)
|
||||
* @pinmux_set: enable a certain muxing function with a certain pin.
|
||||
* The @func_selector selects a certain function whereas @pin_selector
|
||||
* selects a certain pin to be used. On simple controllers one of them
|
||||
* may be ignored. (necessary for pin-muxing against a single pin)
|
||||
* @pinmux_group_set: enable a certain muxing function with a certain pin
|
||||
* group. The @func_selector selects a certain function whereas
|
||||
* @group_selector selects a certain set of pins to be used. On simple
|
||||
* controllers one of them may be ignored.
|
||||
* (necessary for pin-muxing against a pin group)
|
||||
* @pinconf_num_params: number of driver-specific parameters to be parsed
|
||||
* from device trees (necessary for pin-configuration)
|
||||
* @pinconf_params: list of driver_specific parameters to be parsed from
|
||||
* device trees (necessary for pin-configuration)
|
||||
* @pinconf_set: configure an individual pin with a given parameter.
|
||||
* (necessary for pin-configuration against a single pin)
|
||||
* @pinconf_group_set: configure all pins in a group with a given parameter.
|
||||
* (necessary for pin-configuration against a pin group)
|
||||
* @set_state: do pinctrl operations specified by @config, a pseudo device
|
||||
* pointing a config node. (necessary for pinctrl_full)
|
||||
* @set_state_simple: do needed pinctrl operations for a peripherl @periph.
|
||||
* (necessary for pinctrl_simple)
|
||||
* @get_pin_muxing: display the muxing of a given pin.
|
||||
* @gpio_request_enable: requests and enables GPIO on a certain pin.
|
||||
* Implement this only if you can mux every pin individually as GPIO. The
|
||||
* affected GPIO range is passed along with an offset(pin number) into that
|
||||
* specific GPIO range - function selectors and pin groups are orthogonal
|
||||
* to this, the core will however make sure the pins do not collide.
|
||||
* @gpio_disable_free: free up GPIO muxing on a certain pin, the reverse of
|
||||
* @gpio_request_enable
|
||||
*/
|
||||
struct pinctrl_ops {
|
||||
/**
|
||||
* @get_pins_count: Get the number of selectable pins
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* This function is necessary to parse the "pins" property in DTS.
|
||||
*
|
||||
* @Return:
|
||||
* number of selectable named pins available in this driver
|
||||
*/
|
||||
int (*get_pins_count)(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* @get_pin_name: Get the name of a pin
|
||||
*
|
||||
* @dev: Pinctrl device of the pin
|
||||
*
|
||||
* @selector: The pin selector
|
||||
*
|
||||
* This function is called by the core to figure out which pin it will
|
||||
* do operations to. This function is necessary to parse the "pins"
|
||||
* property in DTS.
|
||||
*
|
||||
* @Return: const pointer to the name of the pin
|
||||
*/
|
||||
const char *(*get_pin_name)(struct udevice *dev, unsigned selector);
|
||||
|
||||
/**
|
||||
* @get_groups_count: Get the number of selectable groups
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* This function is necessary to parse the "groups" property in DTS.
|
||||
*
|
||||
* @Return:
|
||||
* number of selectable named groups available in the driver
|
||||
*/
|
||||
int (*get_groups_count)(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* @get_group_name: Get the name of a group
|
||||
*
|
||||
* @dev: Pinctrl device of the group
|
||||
*
|
||||
* @selector: The group selector
|
||||
*
|
||||
* This function is called by the core to figure out which group it
|
||||
* will do operations to. This function is necessary to parse the
|
||||
* "groups" property in DTS.
|
||||
*
|
||||
* @Return: Pointer to the name of the group
|
||||
*/
|
||||
const char *(*get_group_name)(struct udevice *dev, unsigned selector);
|
||||
|
||||
/**
|
||||
* @get_functions_count: Get the number of selectable functions
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* This function is necessary for pin-muxing.
|
||||
*
|
||||
* @Return:
|
||||
* number of selectable named functions available in this driver
|
||||
*/
|
||||
int (*get_functions_count)(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* @get_function_name: Get the name of a function
|
||||
*
|
||||
* @dev: Pinmux device of the function
|
||||
*
|
||||
* @selector: The function selector
|
||||
*
|
||||
* This function is called by the core to figure out which mux setting
|
||||
* it will map a certain device to. This function is necessary for
|
||||
* pin-muxing.
|
||||
*
|
||||
* @Return:
|
||||
* Pointer to the function name of the muxing selector
|
||||
*/
|
||||
const char *(*get_function_name)(struct udevice *dev,
|
||||
unsigned selector);
|
||||
|
||||
/**
|
||||
* @pinmux_set: Mux a pin to a function
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @pin_selector: The pin selector
|
||||
*
|
||||
* @func_selector: The func selector
|
||||
*
|
||||
* On simple controllers one of @pin_selector or @func_selector may be
|
||||
* ignored. This function is necessary for pin-muxing against a single
|
||||
* pin.
|
||||
*
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*pinmux_set)(struct udevice *dev, unsigned pin_selector,
|
||||
unsigned func_selector);
|
||||
|
||||
/**
|
||||
* @pinmux_group_set: Mux a group of pins to a function
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @group_selector: The group selector
|
||||
*
|
||||
* @func_selector: The func selector
|
||||
*
|
||||
* On simple controllers one of @group_selector or @func_selector may be
|
||||
* ignored. This function is necessary for pin-muxing against a group of
|
||||
* pins.
|
||||
*
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*pinmux_group_set)(struct udevice *dev, unsigned group_selector,
|
||||
unsigned func_selector);
|
||||
|
||||
/**
|
||||
* @pinmux_property_set: Enable a pinmux group
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @pinmux_group: A u32 representing the pin identifier and mux
|
||||
* settings. The exact format of a pinmux group is left
|
||||
* up to the driver.
|
||||
*
|
||||
* Mux a single pin to a single function based on a driver-specific
|
||||
* pinmux group. This function is necessary for parsing the "pinmux"
|
||||
* property in DTS, and for pin-muxing against a pinmux group.
|
||||
*
|
||||
* @Return:
|
||||
* Pin selector for the muxed pin if OK, or negative error code on
|
||||
* failure
|
||||
*/
|
||||
int (*pinmux_property_set)(struct udevice *dev, u32 pinmux_group);
|
||||
|
||||
/**
|
||||
* @pinconf_num_params:
|
||||
* Number of driver-specific parameters to be parsed from device
|
||||
* trees. This member is necessary for pin configuration.
|
||||
*/
|
||||
unsigned int pinconf_num_params;
|
||||
|
||||
/**
|
||||
* @pinconf_params:
|
||||
* List of driver-specific parameters to be parsed from the device
|
||||
* tree. This member is necessary for pin configuration.
|
||||
*/
|
||||
const struct pinconf_param *pinconf_params;
|
||||
|
||||
/**
|
||||
* @pinconf_set: Configure an individual pin with a parameter
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @pin_selector: The pin selector
|
||||
*
|
||||
* @param: An &enum pin_config_param from @pinconf_params
|
||||
*
|
||||
* @argument: The argument to this param from the device tree, or
|
||||
* @pinconf_params.default_value
|
||||
*
|
||||
* This function is necessary for pin configuration against a single
|
||||
* pin.
|
||||
*
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*pinconf_set)(struct udevice *dev, unsigned pin_selector,
|
||||
unsigned param, unsigned argument);
|
||||
|
||||
/**
|
||||
* @pinconf_group_set: Configure all pins in a group with a parameter
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @pin_selector: The group selector
|
||||
*
|
||||
* @param: A &enum pin_config_param from
|
||||
* @pinconf_params
|
||||
*
|
||||
* @argument: The argument to this param from the device tree, or
|
||||
* @pinconf_params.default_value
|
||||
*
|
||||
* This function is necessary for pin configuration against a group of
|
||||
* pins.
|
||||
*
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*pinconf_group_set)(struct udevice *dev, unsigned group_selector,
|
||||
unsigned param, unsigned argument);
|
||||
|
||||
/**
|
||||
* @set_state: Configure a pinctrl device
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @config: Pseudo device pointing a config node
|
||||
*
|
||||
* This function is required to be implemented by all pinctrl drivers.
|
||||
* Drivers may set this member to pinctrl_generic_set_state(), which
|
||||
* will call other functions in &struct pinctrl_ops to parse
|
||||
* @config.
|
||||
*
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*set_state)(struct udevice *dev, struct udevice *config);
|
||||
|
||||
/* for pinctrl-simple */
|
||||
int (*set_state_simple)(struct udevice *dev, struct udevice *periph);
|
||||
/**
|
||||
* request() - Request a particular pinctrl function
|
||||
* @set_state_simple: Configure a pinctrl device
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @config: Pseudo-device pointing a config node
|
||||
*
|
||||
* This function is usually a simpler version of set_state(). Only the
|
||||
* first pinctrl device on the system is supported by this function.
|
||||
*
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*set_state_simple)(struct udevice *dev, struct udevice *periph);
|
||||
|
||||
/**
|
||||
* @request: Request a particular pinctrl function
|
||||
*
|
||||
* @dev: Device to adjust (%UCLASS_PINCTRL)
|
||||
*
|
||||
* @func: Function number (driver-specific)
|
||||
*
|
||||
* This activates the selected function.
|
||||
*
|
||||
* @dev: Device to adjust (UCLASS_PINCTRL)
|
||||
* @func: Function number (driver-specific)
|
||||
* @return 0 if OK, -ve on error
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*request)(struct udevice *dev, int func, int flags);
|
||||
|
||||
/**
|
||||
* get_periph_id() - get the peripheral ID for a device
|
||||
* @get_periph_id: Get the peripheral ID for a device
|
||||
*
|
||||
* @dev: Pinctrl device to use for decoding
|
||||
*
|
||||
* @periph: Device to check
|
||||
*
|
||||
* This generally looks at the peripheral's device tree node to work
|
||||
* out the peripheral ID. The return value is normally interpreted as
|
||||
* enum periph_id. so long as this is defined by the platform (which it
|
||||
* &enum periph_id. so long as this is defined by the platform (which it
|
||||
* should be).
|
||||
*
|
||||
* @dev: Pinctrl device to use for decoding
|
||||
* @periph: Device to check
|
||||
* @return peripheral ID of @periph, or -ENOENT on error
|
||||
* @Return:
|
||||
* Peripheral ID of @periph, or %-ENOENT on error
|
||||
*/
|
||||
int (*get_periph_id)(struct udevice *dev, struct udevice *periph);
|
||||
|
||||
/**
|
||||
* get_gpio_mux() - get the mux value for a particular GPIO
|
||||
* @get_gpio_mux: Get the mux value for a particular GPIO
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @banknum: GPIO bank number
|
||||
*
|
||||
* @index: GPIO index within the bank
|
||||
*
|
||||
* This allows the raw mux value for a GPIO to be obtained. It is
|
||||
* useful for displaying the function being used by that GPIO, such
|
||||
|
@ -134,46 +301,60 @@ struct pinctrl_ops {
|
|||
* subsystem and should not be used by generic code. Typically it is
|
||||
* used by a GPIO driver with knowledge of the SoC pinctrl setup.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @banknum: GPIO bank number
|
||||
* @index: GPIO index within the bank
|
||||
* @return mux value (SoC-specific, e.g. 0 for input, 1 for output)
|
||||
* @Return:
|
||||
* Mux value (SoC-specific, e.g. 0 for input, 1 for output)
|
||||
*/
|
||||
int (*get_gpio_mux)(struct udevice *dev, int banknum, int index);
|
||||
|
||||
/**
|
||||
* get_pin_muxing() - show pin muxing
|
||||
* @get_pin_muxing: Show pin muxing
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @selector: Pin selector
|
||||
*
|
||||
* @buf: Buffer to fill with pin muxing description
|
||||
*
|
||||
* @size: Size of @buf
|
||||
*
|
||||
* This allows to display the muxing of a given pin. It's useful for
|
||||
* debug purpose to know if a pin is configured as GPIO or as an
|
||||
* alternate function and which one.
|
||||
* Typically it is used by a PINCTRL driver with knowledge of the SoC
|
||||
* pinctrl setup.
|
||||
* debug purposes to know if a pin is configured as GPIO or as an
|
||||
* alternate function and which one. Typically it is used by a PINCTRL
|
||||
* driver with knowledge of the SoC pinctrl setup.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin selector
|
||||
* @buf Pin's muxing description
|
||||
* @size Pin's muxing description length
|
||||
* return 0 if OK, -ve on error
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*get_pin_muxing)(struct udevice *dev, unsigned int selector,
|
||||
char *buf, int size);
|
||||
|
||||
/**
|
||||
* gpio_request_enable: requests and enables GPIO on a certain pin.
|
||||
* @gpio_request_enable: Request and enable GPIO on a certain pin.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin selector
|
||||
* return 0 if OK, -ve on error
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @selector: Pin selector
|
||||
*
|
||||
* Implement this only if you can mux every pin individually as GPIO.
|
||||
* The affected GPIO range is passed along with an offset(pin number)
|
||||
* into that specific GPIO range - function selectors and pin groups are
|
||||
* orthogonal to this, the core will however make sure the pins do not
|
||||
* collide.
|
||||
*
|
||||
* @Return:
|
||||
* 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*gpio_request_enable)(struct udevice *dev, unsigned int selector);
|
||||
|
||||
/**
|
||||
* gpio_disable_free: free up GPIO muxing on a certain pin.
|
||||
* @gpio_disable_free: Free up GPIO muxing on a certain pin.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin selector
|
||||
* return 0 if OK, -ve on error
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* @selector: Pin selector
|
||||
*
|
||||
* This function is the reverse of @gpio_request_enable.
|
||||
*
|
||||
* @Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int (*gpio_disable_free)(struct udevice *dev, unsigned int selector);
|
||||
};
|
||||
|
@ -181,27 +362,26 @@ struct pinctrl_ops {
|
|||
#define pinctrl_get_ops(dev) ((struct pinctrl_ops *)(dev)->driver->ops)
|
||||
|
||||
/**
|
||||
* Generic pin configuration paramters
|
||||
* enum pin_config_param - Generic pin configuration parameters
|
||||
*
|
||||
* enum pin_config_param - possible pin configuration parameters
|
||||
* @PIN_CONFIG_BIAS_BUS_HOLD: the pin will be set to weakly latch so that it
|
||||
* @PIN_CONFIG_BIAS_BUS_HOLD: The pin will be set to weakly latch so that it
|
||||
* weakly drives the last value on a tristate bus, also known as a "bus
|
||||
* holder", "bus keeper" or "repeater". This allows another device on the
|
||||
* bus to change the value by driving the bus high or low and switching to
|
||||
* tristate. The argument is ignored.
|
||||
* @PIN_CONFIG_BIAS_DISABLE: disable any pin bias on the pin, a
|
||||
* @PIN_CONFIG_BIAS_DISABLE: Disable any pin bias on the pin, a
|
||||
* transition from say pull-up to pull-down implies that you disable
|
||||
* pull-up in the process, this setting disables all biasing.
|
||||
* @PIN_CONFIG_BIAS_HIGH_IMPEDANCE: the pin will be set to a high impedance
|
||||
* @PIN_CONFIG_BIAS_HIGH_IMPEDANCE: The pin will be set to a high impedance
|
||||
* mode, also know as "third-state" (tristate) or "high-Z" or "floating".
|
||||
* On output pins this effectively disconnects the pin, which is useful
|
||||
* if for example some other pin is going to drive the signal connected
|
||||
* to it for a while. Pins used for input are usually always high
|
||||
* impedance.
|
||||
* @PIN_CONFIG_BIAS_PULL_DOWN: the pin will be pulled down (usually with high
|
||||
* @PIN_CONFIG_BIAS_PULL_DOWN: The pin will be pulled down (usually with high
|
||||
* impedance to GROUND). If the argument is != 0 pull-down is enabled,
|
||||
* if it is 0, pull-down is total, i.e. the pin is connected to GROUND.
|
||||
* @PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: the pin will be pulled up or down based
|
||||
* @PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: The pin will be pulled up or down based
|
||||
* on embedded knowledge of the controller hardware, like current mux
|
||||
* function. The pull direction and possibly strength too will normally
|
||||
* be decided completely inside the hardware block and not be readable
|
||||
|
@ -209,67 +389,67 @@ struct pinctrl_ops {
|
|||
* If the argument is != 0 pull up/down is enabled, if it is 0, the
|
||||
* configuration is ignored. The proper way to disable it is to use
|
||||
* @PIN_CONFIG_BIAS_DISABLE.
|
||||
* @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
|
||||
* @PIN_CONFIG_BIAS_PULL_UP: The pin will be pulled up (usually with high
|
||||
* impedance to VDD). If the argument is != 0 pull-up is enabled,
|
||||
* if it is 0, pull-up is total, i.e. the pin is connected to VDD.
|
||||
* @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open
|
||||
* @PIN_CONFIG_DRIVE_OPEN_DRAIN: The pin will be driven with open drain (open
|
||||
* collector) which means it is usually wired with other output ports
|
||||
* which are then pulled up with an external resistor. Setting this
|
||||
* config will enable open drain mode, the argument is ignored.
|
||||
* @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
|
||||
* @PIN_CONFIG_DRIVE_OPEN_SOURCE: The pin will be driven with open source
|
||||
* (open emitter). Setting this config will enable open source mode, the
|
||||
* argument is ignored.
|
||||
* @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and
|
||||
* @PIN_CONFIG_DRIVE_PUSH_PULL: The pin will be driven actively high and
|
||||
* low, this is the most typical case and is typically achieved with two
|
||||
* active transistors on the output. Setting this config will enable
|
||||
* push-pull mode, the argument is ignored.
|
||||
* @PIN_CONFIG_DRIVE_STRENGTH: the pin will sink or source at most the current
|
||||
* @PIN_CONFIG_DRIVE_STRENGTH: The pin will sink or source at most the current
|
||||
* passed as argument. The argument is in mA.
|
||||
* @PIN_CONFIG_DRIVE_STRENGTH_UA: the pin will sink or source at most the current
|
||||
* passed as argument. The argument is in uA.
|
||||
* @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode,
|
||||
* @PIN_CONFIG_DRIVE_STRENGTH_UA: The pin will sink or source at most the
|
||||
* current passed as argument. The argument is in uA.
|
||||
* @PIN_CONFIG_INPUT_DEBOUNCE: This will configure the pin to debounce mode,
|
||||
* which means it will wait for signals to settle when reading inputs. The
|
||||
* argument gives the debounce time in usecs. Setting the
|
||||
* argument to zero turns debouncing off.
|
||||
* @PIN_CONFIG_INPUT_ENABLE: enable the pin's input. Note that this does not
|
||||
* @PIN_CONFIG_INPUT_ENABLE: Enable the pin's input. Note that this does not
|
||||
* affect the pin's ability to drive output. 1 enables input, 0 disables
|
||||
* input.
|
||||
* @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in
|
||||
* @PIN_CONFIG_INPUT_SCHMITT: This will configure an input pin to run in
|
||||
* schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis,
|
||||
* the threshold value is given on a custom format as argument when
|
||||
* setting pins to this mode.
|
||||
* @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin.
|
||||
* @PIN_CONFIG_INPUT_SCHMITT_ENABLE: Control schmitt-trigger mode on the pin.
|
||||
* If the argument != 0, schmitt-trigger mode is enabled. If it's 0,
|
||||
* schmitt-trigger mode is disabled.
|
||||
* @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power
|
||||
* @PIN_CONFIG_LOW_POWER_MODE: This will configure the pin for low power
|
||||
* operation, if several modes of operation are supported these can be
|
||||
* passed in the argument on a custom form, else just use argument 1
|
||||
* to indicate low power mode, argument 0 turns low power mode off.
|
||||
* @PIN_CONFIG_OUTPUT_ENABLE: this will enable the pin's output mode
|
||||
* @PIN_CONFIG_OUTPUT_ENABLE: This will enable the pin's output mode
|
||||
* without driving a value there. For most platforms this reduces to
|
||||
* enable the output buffers and then let the pin controller current
|
||||
* configuration (eg. the currently selected mux function) drive values on
|
||||
* the line. Use argument 1 to enable output mode, argument 0 to disable
|
||||
* it.
|
||||
* @PIN_CONFIG_OUTPUT: this will configure the pin as an output and drive a
|
||||
* @PIN_CONFIG_OUTPUT: This will configure the pin as an output and drive a
|
||||
* value on the line. Use argument 1 to indicate high level, argument 0 to
|
||||
* indicate low level. (Please see Documentation/driver-api/pinctl.rst,
|
||||
* section "GPIO mode pitfalls" for a discussion around this parameter.)
|
||||
* @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power
|
||||
* @PIN_CONFIG_POWER_SOURCE: If the pin can select between different power
|
||||
* supplies, the argument to this parameter (on a custom format) tells
|
||||
* the driver which alternative power source to use.
|
||||
* @PIN_CONFIG_SLEEP_HARDWARE_STATE: indicate this is sleep related state.
|
||||
* @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to
|
||||
* @PIN_CONFIG_SLEEP_HARDWARE_STATE: Indicate this is sleep related state.
|
||||
* @PIN_CONFIG_SLEW_RATE: If the pin can select slew rate, the argument to
|
||||
* this parameter (on a custom format) tells the driver which alternative
|
||||
* slew rate to use.
|
||||
* @PIN_CONFIG_SKEW_DELAY: if the pin has programmable skew rate (on inputs)
|
||||
* @PIN_CONFIG_SKEW_DELAY: If the pin has programmable skew rate (on inputs)
|
||||
* or latch delay (on outputs) this parameter (in a custom format)
|
||||
* specifies the clock skew or latch delay. It typically controls how
|
||||
* many double inverters are put in front of the line.
|
||||
* @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
|
||||
* @PIN_CONFIG_END: This is the last enumerator for pin configurations, if
|
||||
* you need to pass in custom configurations to the pin controller, use
|
||||
* PIN_CONFIG_END+1 as the base offset.
|
||||
* @PIN_CONFIG_MAX: this is the maximum configuration value that can be
|
||||
* @PIN_CONFIG_MAX: This is the maximum configuration value that can be
|
||||
* presented using the packed format.
|
||||
*/
|
||||
enum pin_config_param {
|
||||
|
@ -301,13 +481,14 @@ enum pin_config_param {
|
|||
|
||||
#if CONFIG_IS_ENABLED(PINCTRL_GENERIC)
|
||||
/**
|
||||
* pinctrl_generic_set_state() - generic set_state operation
|
||||
* pinctrl_generic_set_state() - Generic set_state operation
|
||||
* @pctldev: Pinctrl device to use
|
||||
* @config: Config device (pseudo device), pointing a config node in DTS
|
||||
*
|
||||
* Parse the DT node of @config and its children and handle generic properties
|
||||
* such as "pins", "groups", "functions", and pin configuration parameters.
|
||||
*
|
||||
* @pctldev: pinctrl device
|
||||
* @config: config device (pseudo device), pointing a config node in DTS
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
* Return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_generic_set_state(struct udevice *pctldev, struct udevice *config);
|
||||
#else
|
||||
|
@ -320,11 +501,11 @@ static inline int pinctrl_generic_set_state(struct udevice *pctldev,
|
|||
|
||||
#if CONFIG_IS_ENABLED(PINCTRL)
|
||||
/**
|
||||
* pinctrl_select_state() - set a device to a given state
|
||||
* pinctrl_select_state() - Set a device to a given state
|
||||
* @dev: Peripheral device
|
||||
* @statename: State name, like "default"
|
||||
*
|
||||
* @dev: peripheral device
|
||||
* @statename: state name, like "default"
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
* Return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_select_state(struct udevice *dev, const char *statename);
|
||||
#else
|
||||
|
@ -337,40 +518,43 @@ static inline int pinctrl_select_state(struct udevice *dev,
|
|||
|
||||
/**
|
||||
* pinctrl_request() - Request a particular pinctrl function
|
||||
*
|
||||
* @dev: Device to check (UCLASS_PINCTRL)
|
||||
* @dev: Pinctrl device to use
|
||||
* @func: Function number (driver-specific)
|
||||
* @flags: Flags (driver-specific)
|
||||
* @return 0 if OK, -ve on error
|
||||
*
|
||||
* Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_request(struct udevice *dev, int func, int flags);
|
||||
|
||||
/**
|
||||
* pinctrl_request_noflags() - Request a particular pinctrl function
|
||||
* @dev: Pinctrl device to use
|
||||
* @func: Function number (driver-specific)
|
||||
*
|
||||
* This is similar to pinctrl_request() but uses 0 for @flags.
|
||||
*
|
||||
* @dev: Device to check (UCLASS_PINCTRL)
|
||||
* @func: Function number (driver-specific)
|
||||
* @return 0 if OK, -ve on error
|
||||
* Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_request_noflags(struct udevice *dev, int func);
|
||||
|
||||
/**
|
||||
* pinctrl_get_periph_id() - get the peripheral ID for a device
|
||||
* pinctrl_get_periph_id() - Get the peripheral ID for a device
|
||||
* @dev: Pinctrl device to use for decoding
|
||||
* @periph: Device to check
|
||||
*
|
||||
* This generally looks at the peripheral's device tree node to work out the
|
||||
* peripheral ID. The return value is normally interpreted as enum periph_id.
|
||||
* so long as this is defined by the platform (which it should be).
|
||||
*
|
||||
* @dev: Pinctrl device to use for decoding
|
||||
* @periph: Device to check
|
||||
* @return peripheral ID of @periph, or -ENOENT on error
|
||||
* Return: Peripheral ID of @periph, or -ENOENT on error
|
||||
*/
|
||||
int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
|
||||
|
||||
/**
|
||||
* pinctrl_get_gpio_mux() - get the mux value for a particular GPIO
|
||||
* @dev: Pinctrl device to use
|
||||
* @banknum: GPIO bank number
|
||||
* @index: GPIO index within the bank
|
||||
*
|
||||
* This allows the raw mux value for a GPIO to be obtained. It is
|
||||
* useful for displaying the function being used by that GPIO, such
|
||||
|
@ -378,66 +562,64 @@ int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
|
|||
* subsystem and should not be used by generic code. Typically it is
|
||||
* used by a GPIO driver with knowledge of the SoC pinctrl setup.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @banknum: GPIO bank number
|
||||
* @index: GPIO index within the bank
|
||||
* @return mux value (SoC-specific, e.g. 0 for input, 1 for output)
|
||||
* Return: Mux value (SoC-specific, e.g. 0 for input, 1 for output)
|
||||
*/
|
||||
int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index);
|
||||
|
||||
/**
|
||||
* pinctrl_get_pin_muxing() - Returns the muxing description
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin index within pin-controller
|
||||
* @buf: Pin's muxing description
|
||||
* @size: Pin's muxing description length
|
||||
*
|
||||
* This allows to display the muxing description of the given pin for
|
||||
* debug purpose
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector Pin index within pin-controller
|
||||
* @buf Pin's muxing description
|
||||
* @size Pin's muxing description length
|
||||
* @return 0 if OK, -ve on error
|
||||
* Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf,
|
||||
int size);
|
||||
|
||||
/**
|
||||
* pinctrl_get_pins_count() - display pin-controller pins number
|
||||
* pinctrl_get_pins_count() - Display pin-controller pins number
|
||||
* @dev: Pinctrl device to use
|
||||
*
|
||||
* This allows to know the number of pins owned by a given pin-controller
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @return pins number if OK, -ve on error
|
||||
* Return: Number of pins if OK, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_get_pins_count(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* pinctrl_get_pin_name() - Returns the pin's name
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin index within pin-controller
|
||||
* @buf: Buffer to fill with the name of the pin
|
||||
* @size: Size of @buf
|
||||
*
|
||||
* This allows to display the pin's name for debug purpose
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector Pin index within pin-controller
|
||||
* @buf Pin's name
|
||||
* @return 0 if OK, -ve on error
|
||||
* Return: 0 if OK, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_get_pin_name(struct udevice *dev, int selector, char *buf,
|
||||
int size);
|
||||
|
||||
/**
|
||||
* pinctrl_gpio_request() - request a single pin to be used as GPIO
|
||||
* pinctrl_gpio_request() - Request a single pin to be used as GPIO
|
||||
* @dev: GPIO peripheral device
|
||||
* @offset: GPIO pin offset from the GPIO controller
|
||||
*
|
||||
* @dev: GPIO peripheral device
|
||||
* @offset: the GPIO pin offset from the GPIO controller
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
* Return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_gpio_request(struct udevice *dev, unsigned offset);
|
||||
|
||||
/**
|
||||
* pinctrl_gpio_free() - free a single pin used as GPIO
|
||||
* pinctrl_gpio_free() - Free a single pin used as GPIO
|
||||
* @dev: GPIO peripheral device
|
||||
* @offset: GPIO pin offset from the GPIO controller
|
||||
*
|
||||
* @dev: GPIO peripheral device
|
||||
* @offset: the GPIO pin offset from the GPIO controller
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
* Return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
int pinctrl_gpio_free(struct udevice *dev, unsigned offset);
|
||||
|
||||
|
|
277
include/dt-bindings/pinctrl/k210-pinctrl.h
Normal file
277
include/dt-bindings/pinctrl/k210-pinctrl.h
Normal file
|
@ -0,0 +1,277 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef DT_K210_PINCTRL_H
|
||||
#define DT_K210_PINCTRL_H
|
||||
|
||||
/*
|
||||
* Full list of FPIOA functions from
|
||||
* kendryte-standalone-sdk/lib/drivers/include/fpioa.h
|
||||
*/
|
||||
#define K210_PCF_MASK GENMASK(7, 0)
|
||||
#define K210_PCF_JTAG_TCLK 0 /* JTAG Test Clock */
|
||||
#define K210_PCF_JTAG_TDI 1 /* JTAG Test Data In */
|
||||
#define K210_PCF_JTAG_TMS 2 /* JTAG Test Mode Select */
|
||||
#define K210_PCF_JTAG_TDO 3 /* JTAG Test Data Out */
|
||||
#define K210_PCF_SPI0_D0 4 /* SPI0 Data 0 */
|
||||
#define K210_PCF_SPI0_D1 5 /* SPI0 Data 1 */
|
||||
#define K210_PCF_SPI0_D2 6 /* SPI0 Data 2 */
|
||||
#define K210_PCF_SPI0_D3 7 /* SPI0 Data 3 */
|
||||
#define K210_PCF_SPI0_D4 8 /* SPI0 Data 4 */
|
||||
#define K210_PCF_SPI0_D5 9 /* SPI0 Data 5 */
|
||||
#define K210_PCF_SPI0_D6 10 /* SPI0 Data 6 */
|
||||
#define K210_PCF_SPI0_D7 11 /* SPI0 Data 7 */
|
||||
#define K210_PCF_SPI0_SS0 12 /* SPI0 Chip Select 0 */
|
||||
#define K210_PCF_SPI0_SS1 13 /* SPI0 Chip Select 1 */
|
||||
#define K210_PCF_SPI0_SS2 14 /* SPI0 Chip Select 2 */
|
||||
#define K210_PCF_SPI0_SS3 15 /* SPI0 Chip Select 3 */
|
||||
#define K210_PCF_SPI0_ARB 16 /* SPI0 Arbitration */
|
||||
#define K210_PCF_SPI0_SCLK 17 /* SPI0 Serial Clock */
|
||||
#define K210_PCF_UARTHS_RX 18 /* UART High speed Receiver */
|
||||
#define K210_PCF_UARTHS_TX 19 /* UART High speed Transmitter */
|
||||
#define K210_PCF_RESV6 20 /* Reserved function */
|
||||
#define K210_PCF_RESV7 21 /* Reserved function */
|
||||
#define K210_PCF_CLK_SPI1 22 /* Clock SPI1 */
|
||||
#define K210_PCF_CLK_I2C1 23 /* Clock I2C1 */
|
||||
#define K210_PCF_GPIOHS0 24 /* GPIO High speed 0 */
|
||||
#define K210_PCF_GPIOHS1 25 /* GPIO High speed 1 */
|
||||
#define K210_PCF_GPIOHS2 26 /* GPIO High speed 2 */
|
||||
#define K210_PCF_GPIOHS3 27 /* GPIO High speed 3 */
|
||||
#define K210_PCF_GPIOHS4 28 /* GPIO High speed 4 */
|
||||
#define K210_PCF_GPIOHS5 29 /* GPIO High speed 5 */
|
||||
#define K210_PCF_GPIOHS6 30 /* GPIO High speed 6 */
|
||||
#define K210_PCF_GPIOHS7 31 /* GPIO High speed 7 */
|
||||
#define K210_PCF_GPIOHS8 32 /* GPIO High speed 8 */
|
||||
#define K210_PCF_GPIOHS9 33 /* GPIO High speed 9 */
|
||||
#define K210_PCF_GPIOHS10 34 /* GPIO High speed 10 */
|
||||
#define K210_PCF_GPIOHS11 35 /* GPIO High speed 11 */
|
||||
#define K210_PCF_GPIOHS12 36 /* GPIO High speed 12 */
|
||||
#define K210_PCF_GPIOHS13 37 /* GPIO High speed 13 */
|
||||
#define K210_PCF_GPIOHS14 38 /* GPIO High speed 14 */
|
||||
#define K210_PCF_GPIOHS15 39 /* GPIO High speed 15 */
|
||||
#define K210_PCF_GPIOHS16 40 /* GPIO High speed 16 */
|
||||
#define K210_PCF_GPIOHS17 41 /* GPIO High speed 17 */
|
||||
#define K210_PCF_GPIOHS18 42 /* GPIO High speed 18 */
|
||||
#define K210_PCF_GPIOHS19 43 /* GPIO High speed 19 */
|
||||
#define K210_PCF_GPIOHS20 44 /* GPIO High speed 20 */
|
||||
#define K210_PCF_GPIOHS21 45 /* GPIO High speed 21 */
|
||||
#define K210_PCF_GPIOHS22 46 /* GPIO High speed 22 */
|
||||
#define K210_PCF_GPIOHS23 47 /* GPIO High speed 23 */
|
||||
#define K210_PCF_GPIOHS24 48 /* GPIO High speed 24 */
|
||||
#define K210_PCF_GPIOHS25 49 /* GPIO High speed 25 */
|
||||
#define K210_PCF_GPIOHS26 50 /* GPIO High speed 26 */
|
||||
#define K210_PCF_GPIOHS27 51 /* GPIO High speed 27 */
|
||||
#define K210_PCF_GPIOHS28 52 /* GPIO High speed 28 */
|
||||
#define K210_PCF_GPIOHS29 53 /* GPIO High speed 29 */
|
||||
#define K210_PCF_GPIOHS30 54 /* GPIO High speed 30 */
|
||||
#define K210_PCF_GPIOHS31 55 /* GPIO High speed 31 */
|
||||
#define K210_PCF_GPIO0 56 /* GPIO pin 0 */
|
||||
#define K210_PCF_GPIO1 57 /* GPIO pin 1 */
|
||||
#define K210_PCF_GPIO2 58 /* GPIO pin 2 */
|
||||
#define K210_PCF_GPIO3 59 /* GPIO pin 3 */
|
||||
#define K210_PCF_GPIO4 60 /* GPIO pin 4 */
|
||||
#define K210_PCF_GPIO5 61 /* GPIO pin 5 */
|
||||
#define K210_PCF_GPIO6 62 /* GPIO pin 6 */
|
||||
#define K210_PCF_GPIO7 63 /* GPIO pin 7 */
|
||||
#define K210_PCF_UART1_RX 64 /* UART1 Receiver */
|
||||
#define K210_PCF_UART1_TX 65 /* UART1 Transmitter */
|
||||
#define K210_PCF_UART2_RX 66 /* UART2 Receiver */
|
||||
#define K210_PCF_UART2_TX 67 /* UART2 Transmitter */
|
||||
#define K210_PCF_UART3_RX 68 /* UART3 Receiver */
|
||||
#define K210_PCF_UART3_TX 69 /* UART3 Transmitter */
|
||||
#define K210_PCF_SPI1_D0 70 /* SPI1 Data 0 */
|
||||
#define K210_PCF_SPI1_D1 71 /* SPI1 Data 1 */
|
||||
#define K210_PCF_SPI1_D2 72 /* SPI1 Data 2 */
|
||||
#define K210_PCF_SPI1_D3 73 /* SPI1 Data 3 */
|
||||
#define K210_PCF_SPI1_D4 74 /* SPI1 Data 4 */
|
||||
#define K210_PCF_SPI1_D5 75 /* SPI1 Data 5 */
|
||||
#define K210_PCF_SPI1_D6 76 /* SPI1 Data 6 */
|
||||
#define K210_PCF_SPI1_D7 77 /* SPI1 Data 7 */
|
||||
#define K210_PCF_SPI1_SS0 78 /* SPI1 Chip Select 0 */
|
||||
#define K210_PCF_SPI1_SS1 79 /* SPI1 Chip Select 1 */
|
||||
#define K210_PCF_SPI1_SS2 80 /* SPI1 Chip Select 2 */
|
||||
#define K210_PCF_SPI1_SS3 81 /* SPI1 Chip Select 3 */
|
||||
#define K210_PCF_SPI1_ARB 82 /* SPI1 Arbitration */
|
||||
#define K210_PCF_SPI1_SCLK 83 /* SPI1 Serial Clock */
|
||||
#define K210_PCF_SPI2_D0 84 /* SPI2 Data 0 */
|
||||
#define K210_PCF_SPI2_SS 85 /* SPI2 Select */
|
||||
#define K210_PCF_SPI2_SCLK 86 /* SPI2 Serial Clock */
|
||||
#define K210_PCF_I2S0_MCLK 87 /* I2S0 Master Clock */
|
||||
#define K210_PCF_I2S0_SCLK 88 /* I2S0 Serial Clock(BCLK) */
|
||||
#define K210_PCF_I2S0_WS 89 /* I2S0 Word Select(LRCLK) */
|
||||
#define K210_PCF_I2S0_IN_D0 90 /* I2S0 Serial Data Input 0 */
|
||||
#define K210_PCF_I2S0_IN_D1 91 /* I2S0 Serial Data Input 1 */
|
||||
#define K210_PCF_I2S0_IN_D2 92 /* I2S0 Serial Data Input 2 */
|
||||
#define K210_PCF_I2S0_IN_D3 93 /* I2S0 Serial Data Input 3 */
|
||||
#define K210_PCF_I2S0_OUT_D0 94 /* I2S0 Serial Data Output 0 */
|
||||
#define K210_PCF_I2S0_OUT_D1 95 /* I2S0 Serial Data Output 1 */
|
||||
#define K210_PCF_I2S0_OUT_D2 96 /* I2S0 Serial Data Output 2 */
|
||||
#define K210_PCF_I2S0_OUT_D3 97 /* I2S0 Serial Data Output 3 */
|
||||
#define K210_PCF_I2S1_MCLK 98 /* I2S1 Master Clock */
|
||||
#define K210_PCF_I2S1_SCLK 99 /* I2S1 Serial Clock(BCLK) */
|
||||
#define K210_PCF_I2S1_WS 100 /* I2S1 Word Select(LRCLK) */
|
||||
#define K210_PCF_I2S1_IN_D0 101 /* I2S1 Serial Data Input 0 */
|
||||
#define K210_PCF_I2S1_IN_D1 102 /* I2S1 Serial Data Input 1 */
|
||||
#define K210_PCF_I2S1_IN_D2 103 /* I2S1 Serial Data Input 2 */
|
||||
#define K210_PCF_I2S1_IN_D3 104 /* I2S1 Serial Data Input 3 */
|
||||
#define K210_PCF_I2S1_OUT_D0 105 /* I2S1 Serial Data Output 0 */
|
||||
#define K210_PCF_I2S1_OUT_D1 106 /* I2S1 Serial Data Output 1 */
|
||||
#define K210_PCF_I2S1_OUT_D2 107 /* I2S1 Serial Data Output 2 */
|
||||
#define K210_PCF_I2S1_OUT_D3 108 /* I2S1 Serial Data Output 3 */
|
||||
#define K210_PCF_I2S2_MCLK 109 /* I2S2 Master Clock */
|
||||
#define K210_PCF_I2S2_SCLK 110 /* I2S2 Serial Clock(BCLK) */
|
||||
#define K210_PCF_I2S2_WS 111 /* I2S2 Word Select(LRCLK) */
|
||||
#define K210_PCF_I2S2_IN_D0 112 /* I2S2 Serial Data Input 0 */
|
||||
#define K210_PCF_I2S2_IN_D1 113 /* I2S2 Serial Data Input 1 */
|
||||
#define K210_PCF_I2S2_IN_D2 114 /* I2S2 Serial Data Input 2 */
|
||||
#define K210_PCF_I2S2_IN_D3 115 /* I2S2 Serial Data Input 3 */
|
||||
#define K210_PCF_I2S2_OUT_D0 116 /* I2S2 Serial Data Output 0 */
|
||||
#define K210_PCF_I2S2_OUT_D1 117 /* I2S2 Serial Data Output 1 */
|
||||
#define K210_PCF_I2S2_OUT_D2 118 /* I2S2 Serial Data Output 2 */
|
||||
#define K210_PCF_I2S2_OUT_D3 119 /* I2S2 Serial Data Output 3 */
|
||||
#define K210_PCF_RESV0 120 /* Reserved function */
|
||||
#define K210_PCF_RESV1 121 /* Reserved function */
|
||||
#define K210_PCF_RESV2 122 /* Reserved function */
|
||||
#define K210_PCF_RESV3 123 /* Reserved function */
|
||||
#define K210_PCF_RESV4 124 /* Reserved function */
|
||||
#define K210_PCF_RESV5 125 /* Reserved function */
|
||||
#define K210_PCF_I2C0_SCLK 126 /* I2C0 Serial Clock */
|
||||
#define K210_PCF_I2C0_SDA 127 /* I2C0 Serial Data */
|
||||
#define K210_PCF_I2C1_SCLK 128 /* I2C1 Serial Clock */
|
||||
#define K210_PCF_I2C1_SDA 129 /* I2C1 Serial Data */
|
||||
#define K210_PCF_I2C2_SCLK 130 /* I2C2 Serial Clock */
|
||||
#define K210_PCF_I2C2_SDA 131 /* I2C2 Serial Data */
|
||||
#define K210_PCF_DVP_XCLK 132 /* DVP System Clock */
|
||||
#define K210_PCF_DVP_RST 133 /* DVP System Reset */
|
||||
#define K210_PCF_DVP_PWDN 134 /* DVP Power Down Mode */
|
||||
#define K210_PCF_DVP_VSYNC 135 /* DVP Vertical Sync */
|
||||
#define K210_PCF_DVP_HSYNC 136 /* DVP Horizontal Sync */
|
||||
#define K210_PCF_DVP_PCLK 137 /* Pixel Clock */
|
||||
#define K210_PCF_DVP_D0 138 /* Data Bit 0 */
|
||||
#define K210_PCF_DVP_D1 139 /* Data Bit 1 */
|
||||
#define K210_PCF_DVP_D2 140 /* Data Bit 2 */
|
||||
#define K210_PCF_DVP_D3 141 /* Data Bit 3 */
|
||||
#define K210_PCF_DVP_D4 142 /* Data Bit 4 */
|
||||
#define K210_PCF_DVP_D5 143 /* Data Bit 5 */
|
||||
#define K210_PCF_DVP_D6 144 /* Data Bit 6 */
|
||||
#define K210_PCF_DVP_D7 145 /* Data Bit 7 */
|
||||
#define K210_PCF_SCCB_SCLK 146 /* Serial Camera Control Bus Clock */
|
||||
#define K210_PCF_SCCB_SDA 147 /* Serial Camera Control Bus Data */
|
||||
#define K210_PCF_UART1_CTS 148 /* UART1 Clear To Send */
|
||||
#define K210_PCF_UART1_DSR 149 /* UART1 Data Set Ready */
|
||||
#define K210_PCF_UART1_DCD 150 /* UART1 Data Carrier Detect */
|
||||
#define K210_PCF_UART1_RI 151 /* UART1 Ring Indicator */
|
||||
#define K210_PCF_UART1_SIR_IN 152 /* UART1 Serial Infrared Input */
|
||||
#define K210_PCF_UART1_DTR 153 /* UART1 Data Terminal Ready */
|
||||
#define K210_PCF_UART1_RTS 154 /* UART1 Request To Send */
|
||||
#define K210_PCF_UART1_OUT2 155 /* UART1 User-designated Output 2 */
|
||||
#define K210_PCF_UART1_OUT1 156 /* UART1 User-designated Output 1 */
|
||||
#define K210_PCF_UART1_SIR_OUT 157 /* UART1 Serial Infrared Output */
|
||||
#define K210_PCF_UART1_BAUD 158 /* UART1 Transmit Clock Output */
|
||||
#define K210_PCF_UART1_RE 159 /* UART1 Receiver Output Enable */
|
||||
#define K210_PCF_UART1_DE 160 /* UART1 Driver Output Enable */
|
||||
#define K210_PCF_UART1_RS485_EN 161 /* UART1 RS485 Enable */
|
||||
#define K210_PCF_UART2_CTS 162 /* UART2 Clear To Send */
|
||||
#define K210_PCF_UART2_DSR 163 /* UART2 Data Set Ready */
|
||||
#define K210_PCF_UART2_DCD 164 /* UART2 Data Carrier Detect */
|
||||
#define K210_PCF_UART2_RI 165 /* UART2 Ring Indicator */
|
||||
#define K210_PCF_UART2_SIR_IN 166 /* UART2 Serial Infrared Input */
|
||||
#define K210_PCF_UART2_DTR 167 /* UART2 Data Terminal Ready */
|
||||
#define K210_PCF_UART2_RTS 168 /* UART2 Request To Send */
|
||||
#define K210_PCF_UART2_OUT2 169 /* UART2 User-designated Output 2 */
|
||||
#define K210_PCF_UART2_OUT1 170 /* UART2 User-designated Output 1 */
|
||||
#define K210_PCF_UART2_SIR_OUT 171 /* UART2 Serial Infrared Output */
|
||||
#define K210_PCF_UART2_BAUD 172 /* UART2 Transmit Clock Output */
|
||||
#define K210_PCF_UART2_RE 173 /* UART2 Receiver Output Enable */
|
||||
#define K210_PCF_UART2_DE 174 /* UART2 Driver Output Enable */
|
||||
#define K210_PCF_UART2_RS485_EN 175 /* UART2 RS485 Enable */
|
||||
#define K210_PCF_UART3_CTS 176 /* UART3 Clear To Send */
|
||||
#define K210_PCF_UART3_DSR 177 /* UART3 Data Set Ready */
|
||||
#define K210_PCF_UART3_DCD 178 /* UART3 Data Carrier Detect */
|
||||
#define K210_PCF_UART3_RI 179 /* UART3 Ring Indicator */
|
||||
#define K210_PCF_UART3_SIR_IN 180 /* UART3 Serial Infrared Input */
|
||||
#define K210_PCF_UART3_DTR 181 /* UART3 Data Terminal Ready */
|
||||
#define K210_PCF_UART3_RTS 182 /* UART3 Request To Send */
|
||||
#define K210_PCF_UART3_OUT2 183 /* UART3 User-designated Output 2 */
|
||||
#define K210_PCF_UART3_OUT1 184 /* UART3 User-designated Output 1 */
|
||||
#define K210_PCF_UART3_SIR_OUT 185 /* UART3 Serial Infrared Output */
|
||||
#define K210_PCF_UART3_BAUD 186 /* UART3 Transmit Clock Output */
|
||||
#define K210_PCF_UART3_RE 187 /* UART3 Receiver Output Enable */
|
||||
#define K210_PCF_UART3_DE 188 /* UART3 Driver Output Enable */
|
||||
#define K210_PCF_UART3_RS485_EN 189 /* UART3 RS485 Enable */
|
||||
#define K210_PCF_TIMER0_TOGGLE1 190 /* TIMER0 Toggle Output 1 */
|
||||
#define K210_PCF_TIMER0_TOGGLE2 191 /* TIMER0 Toggle Output 2 */
|
||||
#define K210_PCF_TIMER0_TOGGLE3 192 /* TIMER0 Toggle Output 3 */
|
||||
#define K210_PCF_TIMER0_TOGGLE4 193 /* TIMER0 Toggle Output 4 */
|
||||
#define K210_PCF_TIMER1_TOGGLE1 194 /* TIMER1 Toggle Output 1 */
|
||||
#define K210_PCF_TIMER1_TOGGLE2 195 /* TIMER1 Toggle Output 2 */
|
||||
#define K210_PCF_TIMER1_TOGGLE3 196 /* TIMER1 Toggle Output 3 */
|
||||
#define K210_PCF_TIMER1_TOGGLE4 197 /* TIMER1 Toggle Output 4 */
|
||||
#define K210_PCF_TIMER2_TOGGLE1 198 /* TIMER2 Toggle Output 1 */
|
||||
#define K210_PCF_TIMER2_TOGGLE2 199 /* TIMER2 Toggle Output 2 */
|
||||
#define K210_PCF_TIMER2_TOGGLE3 200 /* TIMER2 Toggle Output 3 */
|
||||
#define K210_PCF_TIMER2_TOGGLE4 201 /* TIMER2 Toggle Output 4 */
|
||||
#define K210_PCF_CLK_SPI2 202 /* Clock SPI2 */
|
||||
#define K210_PCF_CLK_I2C2 203 /* Clock I2C2 */
|
||||
#define K210_PCF_INTERNAL0 204 /* Internal function signal 0 */
|
||||
#define K210_PCF_INTERNAL1 205 /* Internal function signal 1 */
|
||||
#define K210_PCF_INTERNAL2 206 /* Internal function signal 2 */
|
||||
#define K210_PCF_INTERNAL3 207 /* Internal function signal 3 */
|
||||
#define K210_PCF_INTERNAL4 208 /* Internal function signal 4 */
|
||||
#define K210_PCF_INTERNAL5 209 /* Internal function signal 5 */
|
||||
#define K210_PCF_INTERNAL6 210 /* Internal function signal 6 */
|
||||
#define K210_PCF_INTERNAL7 211 /* Internal function signal 7 */
|
||||
#define K210_PCF_INTERNAL8 212 /* Internal function signal 8 */
|
||||
#define K210_PCF_INTERNAL9 213 /* Internal function signal 9 */
|
||||
#define K210_PCF_INTERNAL10 214 /* Internal function signal 10 */
|
||||
#define K210_PCF_INTERNAL11 215 /* Internal function signal 11 */
|
||||
#define K210_PCF_INTERNAL12 216 /* Internal function signal 12 */
|
||||
#define K210_PCF_INTERNAL13 217 /* Internal function signal 13 */
|
||||
#define K210_PCF_INTERNAL14 218 /* Internal function signal 14 */
|
||||
#define K210_PCF_INTERNAL15 219 /* Internal function signal 15 */
|
||||
#define K210_PCF_INTERNAL16 220 /* Internal function signal 16 */
|
||||
#define K210_PCF_INTERNAL17 221 /* Internal function signal 17 */
|
||||
#define K210_PCF_CONSTANT 222 /* Constant function */
|
||||
#define K210_PCF_INTERNAL18 223 /* Internal function signal 18 */
|
||||
#define K210_PCF_DEBUG0 224 /* Debug function 0 */
|
||||
#define K210_PCF_DEBUG1 225 /* Debug function 1 */
|
||||
#define K210_PCF_DEBUG2 226 /* Debug function 2 */
|
||||
#define K210_PCF_DEBUG3 227 /* Debug function 3 */
|
||||
#define K210_PCF_DEBUG4 228 /* Debug function 4 */
|
||||
#define K210_PCF_DEBUG5 229 /* Debug function 5 */
|
||||
#define K210_PCF_DEBUG6 230 /* Debug function 6 */
|
||||
#define K210_PCF_DEBUG7 231 /* Debug function 7 */
|
||||
#define K210_PCF_DEBUG8 232 /* Debug function 8 */
|
||||
#define K210_PCF_DEBUG9 233 /* Debug function 9 */
|
||||
#define K210_PCF_DEBUG10 234 /* Debug function 10 */
|
||||
#define K210_PCF_DEBUG11 235 /* Debug function 11 */
|
||||
#define K210_PCF_DEBUG12 236 /* Debug function 12 */
|
||||
#define K210_PCF_DEBUG13 237 /* Debug function 13 */
|
||||
#define K210_PCF_DEBUG14 238 /* Debug function 14 */
|
||||
#define K210_PCF_DEBUG15 239 /* Debug function 15 */
|
||||
#define K210_PCF_DEBUG16 240 /* Debug function 16 */
|
||||
#define K210_PCF_DEBUG17 241 /* Debug function 17 */
|
||||
#define K210_PCF_DEBUG18 242 /* Debug function 18 */
|
||||
#define K210_PCF_DEBUG19 243 /* Debug function 19 */
|
||||
#define K210_PCF_DEBUG20 244 /* Debug function 20 */
|
||||
#define K210_PCF_DEBUG21 245 /* Debug function 21 */
|
||||
#define K210_PCF_DEBUG22 246 /* Debug function 22 */
|
||||
#define K210_PCF_DEBUG23 247 /* Debug function 23 */
|
||||
#define K210_PCF_DEBUG24 248 /* Debug function 24 */
|
||||
#define K210_PCF_DEBUG25 249 /* Debug function 25 */
|
||||
#define K210_PCF_DEBUG26 250 /* Debug function 26 */
|
||||
#define K210_PCF_DEBUG27 251 /* Debug function 27 */
|
||||
#define K210_PCF_DEBUG28 252 /* Debug function 28 */
|
||||
#define K210_PCF_DEBUG29 253 /* Debug function 29 */
|
||||
#define K210_PCF_DEBUG30 254 /* Debug function 30 */
|
||||
#define K210_PCF_DEBUG31 255 /* Debug function 31 */
|
||||
|
||||
#define K210_FPIOA(pin, func) (((pin) << 16) | (func))
|
||||
#define K210_FPIOA_DO(pin, func) (((pin) << 16) | (1 << 8) | (func))
|
||||
|
||||
#define K210_PC_POWER_3V3 0
|
||||
#define K210_PC_POWER_1V8 1
|
||||
|
||||
#endif /* DT_K210_PINCTRL_H */
|
19
include/dt-bindings/pinctrl/sandbox-pinmux.h
Normal file
19
include/dt-bindings/pinctrl/sandbox-pinmux.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef SANDBOX_PINMUX_H
|
||||
#define SANDBOX_PINMUX_H
|
||||
|
||||
#define SANDBOX_PINMUX_UART 0
|
||||
#define SANDBOX_PINMUX_I2C 1
|
||||
#define SANDBOX_PINMUX_SPI 2
|
||||
#define SANDBOX_PINMUX_I2S 3
|
||||
#define SANDBOX_PINMUX_GPIO 4
|
||||
#define SANDBOX_PINMUX_CS 5
|
||||
#define SANDBOX_PINMUX_PWM 6
|
||||
|
||||
#define SANDBOX_PINMUX(pin, func) ((func) << 16 | (pin))
|
||||
|
||||
#endif /* SANDBOX_PINMUX_H */
|
|
@ -81,4 +81,7 @@ obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o
|
|||
obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
|
||||
obj-$(CONFIG_RESET_SYSCON) += syscon-reset.o
|
||||
obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o
|
||||
ifneq ($(CONFIG_PINMUX),)
|
||||
obj-$(CONFIG_PINCONF) += pinmux.o
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -40,7 +40,8 @@ static int dm_test_led_default_state(struct unit_test_state *uts)
|
|||
ut_assertok(led_get_by_label("sandbox:default_on", &dev));
|
||||
ut_asserteq(LEDST_ON, led_get_state(dev));
|
||||
|
||||
ut_assertok(led_get_by_label("sandbox:default_off", &dev));
|
||||
/* Also tests default label behaviour */
|
||||
ut_assertok(led_get_by_label("default_off", &dev));
|
||||
ut_asserteq(LEDST_OFF, led_get_state(dev));
|
||||
|
||||
return 0;
|
||||
|
|
57
test/dm/pinmux.c
Normal file
57
test/dm/pinmux.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <dm/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
static int dm_test_pinmux(struct unit_test_state *uts)
|
||||
{
|
||||
char buf[64];
|
||||
struct udevice *dev;
|
||||
|
||||
#define test_muxing(selector, expected) do { \
|
||||
ut_assertok(pinctrl_get_pin_muxing(dev, selector, buf, sizeof(buf))); \
|
||||
ut_asserteq_str(expected, (char *)&buf); \
|
||||
} while (0)
|
||||
|
||||
ut_assertok(uclass_get_device_by_name(UCLASS_PINCTRL, "pinctrl", &dev));
|
||||
test_muxing(0, "UART TX.");
|
||||
test_muxing(1, "UART RX.");
|
||||
test_muxing(2, "I2S SCK.");
|
||||
test_muxing(3, "I2S SD.");
|
||||
test_muxing(4, "I2S WS.");
|
||||
test_muxing(5, "GPIO0 bias-pull-up input-disable.");
|
||||
test_muxing(6, "GPIO1 drive-open-drain.");
|
||||
test_muxing(7, "GPIO2 bias-pull-down input-enable.");
|
||||
test_muxing(8, "GPIO3 bias-disable.");
|
||||
|
||||
ut_assertok(pinctrl_select_state(dev, "alternate"));
|
||||
test_muxing(0, "I2C SCL drive-open-drain.");
|
||||
test_muxing(1, "I2C SDA drive-open-drain.");
|
||||
test_muxing(2, "SPI SCLK.");
|
||||
test_muxing(3, "SPI MOSI.");
|
||||
test_muxing(4, "SPI MISO.");
|
||||
test_muxing(5, "SPI CS0.");
|
||||
test_muxing(6, "SPI CS1.");
|
||||
test_muxing(7, "GPIO2 bias-pull-down input-enable.");
|
||||
test_muxing(8, "GPIO3 bias-disable.");
|
||||
|
||||
ut_assertok(pinctrl_select_state(dev, "0"));
|
||||
test_muxing(0, "I2C SCL drive-open-drain.");
|
||||
test_muxing(1, "I2C SDA drive-open-drain.");
|
||||
test_muxing(2, "I2S SCK.");
|
||||
test_muxing(3, "I2S SD.");
|
||||
test_muxing(4, "I2S WS.");
|
||||
test_muxing(5, "GPIO0 bias-pull-up input-disable.");
|
||||
test_muxing(6, "GPIO1 drive-open-drain.");
|
||||
test_muxing(7, "GPIO2 bias-pull-down input-enable.");
|
||||
test_muxing(8, "GPIO3 bias-disable.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_pinmux, UT_TESTF_SCAN_FDT);
|
|
@ -28,15 +28,15 @@ def test_pinmux_status_all(u_boot_console):
|
|||
assert ('a6 : gpio output .' in output)
|
||||
|
||||
assert ('pinctrl:' in output)
|
||||
assert ('SCL : I2C SCL.' in output)
|
||||
assert ('SDA : I2C SDA.' in output)
|
||||
assert ('TX : Uart TX.' in output)
|
||||
assert ('RX : Uart RX.' in output)
|
||||
assert ('W1 : 1-wire gpio.' in output)
|
||||
assert ('GPIO0 : gpio bias-pull-up input-disable.' in output)
|
||||
assert ('GPIO1 : gpio drive-open-drain.' in output)
|
||||
assert ('GPIO2 : gpio bias-pull-down input-enable.' in output)
|
||||
assert ('GPIO3 : gpio bias-disable.' in output)
|
||||
assert ('P0 : UART TX.' in output)
|
||||
assert ('P1 : UART RX.' in output)
|
||||
assert ('P2 : I2S SCK.' in output)
|
||||
assert ('P3 : I2S SD.' in output)
|
||||
assert ('P4 : I2S WS.' in output)
|
||||
assert ('P5 : GPIO0 bias-pull-up input-disable.' in output)
|
||||
assert ('P6 : GPIO1 drive-open-drain.' in output)
|
||||
assert ('P7 : GPIO2 bias-pull-down input-enable.' in output)
|
||||
assert ('P8 : GPIO3 bias-disable.' in output)
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_pinmux')
|
||||
@pytest.mark.boardspec('sandbox')
|
||||
|
@ -73,12 +73,12 @@ def test_pinmux_status(u_boot_console):
|
|||
assert (not 'pinctrl-gpio:' in output)
|
||||
assert (not 'pinctrl:' in output)
|
||||
|
||||
assert ('SCL : I2C SCL.' in output)
|
||||
assert ('SDA : I2C SDA.' in output)
|
||||
assert ('TX : Uart TX.' in output)
|
||||
assert ('RX : Uart RX.' in output)
|
||||
assert ('W1 : 1-wire gpio.' in output)
|
||||
assert ('GPIO0 : gpio bias-pull-up input-disable.' in output)
|
||||
assert ('GPIO1 : gpio drive-open-drain.' in output)
|
||||
assert ('GPIO2 : gpio bias-pull-down input-enable.' in output)
|
||||
assert ('GPIO3 : gpio bias-disable.' in output)
|
||||
assert ('P0 : UART TX.' in output)
|
||||
assert ('P1 : UART RX.' in output)
|
||||
assert ('P2 : I2S SCK.' in output)
|
||||
assert ('P3 : I2S SD.' in output)
|
||||
assert ('P4 : I2S WS.' in output)
|
||||
assert ('P5 : GPIO0 bias-pull-up input-disable.' in output)
|
||||
assert ('P6 : GPIO1 drive-open-drain.' in output)
|
||||
assert ('P7 : GPIO2 bias-pull-down input-enable.' in output)
|
||||
assert ('P8 : GPIO3 bias-disable.' in output)
|
||||
|
|
Loading…
Reference in a new issue