diff options
author | Heiko Schocher | 2020-02-03 10:23:53 +0100 |
---|---|---|
committer | Heiko Schocher | 2020-09-17 06:09:53 +0200 |
commit | 5990b059516c233bf845ad510decd6a44ba9864b (patch) | |
tree | a417046f565a3523dde0244a4f9d540ba284d0f2 /arch/powerpc | |
parent | 9bd6444826acc476110b81a16d9d16bfa57d9fbd (diff) |
powerpc, qe: add DTS support for parallel I/O ports
add DM support for parallel I/O ports on QUICC Engine Block
Signed-off-by: Heiko Schocher <hs@denx.de>
Patch-cc: Mario Six <mario.six@gdsys.cc>
Patch-cc: Qiang Zhao <qiang.zhao@nxp.com>
Patch-cc: Holger Brunck <holger.brunck@hitachi-powergrids.com>
Series-changes: 2
- remove RFC
- fixed Codingstyle errors, therefore new patch
powerpc, mpc83xx: fix codingstyle issues for qe_io.c
- moved DM part to drivers/pinctrl
Commit-notes:
Open questions / discussion:
- I let the old none DM based implementation in code
so boards should work with old implementation.
This should be removed if all boards are converted to
DM/DTS.
- Unfortunately linux DTS does not use "pinctrl-"
properties, instead "pio-handle" properties.
Even worser old U-Boot code initializes all pins
defined in "const qe_iop_conf_t qe_iop_conf_tab[]"
table in board code. As linux does the same I decided
to also scan through all subnodes containing "pio-map"
property and initialize them too.
The proper solution would be to check for "pio-handle"
when a device is probed.
END
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/cpu/mpc83xx/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc83xx/cpu_init.c | 8 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc83xx/qe_io.c | 83 |
3 files changed, 68 insertions, 25 deletions
diff --git a/arch/powerpc/cpu/mpc83xx/Makefile b/arch/powerpc/cpu/mpc83xx/Makefile index 304029977e5..aeb42b109d0 100644 --- a/arch/powerpc/cpu/mpc83xx/Makefile +++ b/arch/powerpc/cpu/mpc83xx/Makefile @@ -27,7 +27,9 @@ obj-y += cpu_init.o obj-y += speed.o obj-y += interrupts.o obj-y += ecc.o +ifndef CONFIG_PINCTRL obj-$(CONFIG_QE) += qe_io.o +endif obj-$(CONFIG_FSL_SERDES) += serdes.o ifndef CONFIG_ARCH_MPC8308 obj-$(CONFIG_PCI) += pci.o diff --git a/arch/powerpc/cpu/mpc83xx/cpu_init.c b/arch/powerpc/cpu/mpc83xx/cpu_init.c index b21b0b03249..840f907acb8 100644 --- a/arch/powerpc/cpu/mpc83xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc83xx/cpu_init.c @@ -14,6 +14,9 @@ #include <usb/ehci-ci.h> #endif #include <linux/delay.h> +#ifdef CONFIG_QE +#include <fsl_qe.h> +#endif #include "lblaw/lblaw.h" #include "elbc/elbc.h" @@ -28,6 +31,7 @@ extern qe_iop_conf_t qe_iop_conf_tab[]; extern void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign); +#if !defined(CONFIG_PINCTRL) static void config_qe_ioports(void) { u8 port, pin; @@ -44,6 +48,7 @@ static void config_qe_ioports(void) } } #endif +#endif /* * Breathe some life into the CPU... @@ -190,10 +195,13 @@ void cpu_init_f (volatile immap_t * im) __raw_writel(CONFIG_SYS_OBIR, &im->sysconf.obir); #endif +#if !defined(CONFIG_PINCTRL) #ifdef CONFIG_QE /* Config QE ioports */ config_qe_ioports(); #endif +#endif + /* Set up preliminary BR/OR regs */ init_early_memctl_regs(); diff --git a/arch/powerpc/cpu/mpc83xx/qe_io.c b/arch/powerpc/cpu/mpc83xx/qe_io.c index 1079ae128ae..52360703a7d 100644 --- a/arch/powerpc/cpu/mpc83xx/qe_io.c +++ b/arch/powerpc/cpu/mpc83xx/qe_io.c @@ -12,24 +12,35 @@ #include <asm/immap_83xx.h> #define NUM_OF_PINS 32 -void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) + +/** qe_cfg_iopin configure one io pin setting + * + * @par_io: pointer to parallel I/O base + * @port: io pin port + * @pin: io pin number which get configured + * @dir: direction of io pin 2 bits valid + * 00 = pin disabled + * 01 = output + * 10 = input + * 11 = pin is I/O + * @open_drain: is pin open drain + * @assign: pin assignment registers select the function of the pin + */ +static void qe_cfg_iopin(qepio83xx_t *par_io, u8 port, u8 pin, int dir, + int open_drain, int assign) { - u32 2bit_mask; - u32 2bit_dir; - u32 2bit_assign; - u32 1bit_mask; - u32 tmp_val; - immap_t *im; - qepio83xx_t *par_io; - int offset; + u32 dbit_mask; + u32 dbit_dir; + u32 dbit_asgn; + u32 bit_mask; + u32 tmp_val; + int offset; - im = (immap_t *)CONFIG_SYS_IMMR; - par_io = (qepio83xx_t *)&im->qepio; offset = (NUM_OF_PINS - (pin % (NUM_OF_PINS / 2) + 1) * 2); /* Calculate pin location and 2bit mask and dir */ - 2bit_mask = (u32)(0x3 << offset); - 2bit_dir = (u32)(dir << offset); + dbit_mask = (u32)(0x3 << offset); + dbit_dir = (u32)(dir << offset); /* Setup the direction */ tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? @@ -37,35 +48,57 @@ void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) in_be32(&par_io->ioport[port].dir1); if (pin > (NUM_OF_PINS / 2) - 1) { - out_be32(&par_io->ioport[port].dir2, ~2bit_mask & tmp_val); - out_be32(&par_io->ioport[port].dir2, 2bit_dir | tmp_val); + out_be32(&par_io->ioport[port].dir2, ~dbit_mask & tmp_val); + out_be32(&par_io->ioport[port].dir2, dbit_dir | tmp_val); } else { - out_be32(&par_io->ioport[port].dir1, ~2bit_mask & tmp_val); - out_be32(&par_io->ioport[port].dir1, 2bit_dir | tmp_val); + out_be32(&par_io->ioport[port].dir1, ~dbit_mask & tmp_val); + out_be32(&par_io->ioport[port].dir1, dbit_dir | tmp_val); } /* Calculate pin location for 1bit mask */ - 1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin + 1))); + bit_mask = (u32)(1 << (NUM_OF_PINS - (pin + 1))); /* Setup the open drain */ tmp_val = in_be32(&par_io->ioport[port].podr); if (open_drain) - out_be32(&par_io->ioport[port].podr, 1bit_mask | tmp_val); + out_be32(&par_io->ioport[port].podr, bit_mask | tmp_val); else - out_be32(&par_io->ioport[port].podr, ~1bit_mask & tmp_val); + out_be32(&par_io->ioport[port].podr, ~bit_mask & tmp_val); /* Setup the assignment */ tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? in_be32(&par_io->ioport[port].ppar2) : in_be32(&par_io->ioport[port].ppar1); - 2bit_assign = (u32)(assign << offset); + dbit_asgn = (u32)(assign << offset); /* Clear and set 2 bits mask */ if (pin > (NUM_OF_PINS / 2) - 1) { - out_be32(&par_io->ioport[port].ppar2, ~2bit_mask & tmp_val); - out_be32(&par_io->ioport[port].ppar2, 2bit_assign | tmp_val); + out_be32(&par_io->ioport[port].ppar2, ~dbit_mask & tmp_val); + out_be32(&par_io->ioport[port].ppar2, dbit_asgn | tmp_val); } else { - out_be32(&par_io->ioport[port].ppar1, ~2bit_mask & tmp_val); - out_be32(&par_io->ioport[port].ppar1, 2bit_assign | tmp_val); + out_be32(&par_io->ioport[port].ppar1, ~dbit_mask & tmp_val); + out_be32(&par_io->ioport[port].ppar1, dbit_asgn | tmp_val); } } + +#if !defined(CONFIG_PINCTRL) +/** qe_config_iopin configure one io pin setting + * + * @port: io pin port + * @pin: io pin number which get configured + * @dir: direction of io pin 2 bits valid + * 00 = pin disabled + * 01 = output + * 10 = input + * 11 = pin is I/O + * @open_drain: is pin open drain + * @assign: pin assignment registers select the function of the pin + */ +void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) +{ + immap_t *im = (immap_t *)CONFIG_SYS_IMMR; + qepio83xx_t *par_io = (qepio83xx_t *)&im->qepio; + + qe_cfg_iopin(par_io, port, pin, dir, open_drain, assign); +} +#endif |