1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2006 Freescale Semiconductor, Inc. 4 * 5 * Dave Liu <daveliu@freescale.com> 6 * based on source code of Shlomi Gridish 7 */ 8 9#include <common.h> 10#include <linux/errno.h> 11#include <asm/io.h> 12#include <asm/immap_83xx.h> 13 14#if defined(CONFIG_PINCTRL) 15#include <dm.h> 16#include <dm/device_compat.h> 17#include <dm/pinctrl.h> 18#include <linux/ioport.h> 19 20/** 21 * struct qe_io_plat 22 * 23 * @base: Base register address 24 * @num_par_io_ports number of io ports 25 */ 26struct qe_io_plat { 27 qepio83xx_t *base; 28 u32 num_io_ports; 29}; 30#endif 31 32#define NUM_OF_PINS 32 33 34/** qe_cfg_iopin configure one io pin setting 35 * 36 * @par_io: pointer to parallel I/O base 37 * @port: io pin port 38 * @pin: io pin number which get configured 39 * @dir: direction of io pin 2 bits valid 40 * 00 = pin disabled 41 * 01 = output 42 * 10 = input 43 * 11 = pin is I/O 44 * @open_drain: is pin open drain 45 * @assign: pin assignment registers select the function of the pin 46 */ 47static void qe_cfg_iopin(qepio83xx_t *par_io, u8 port, u8 pin, int dir, 48 int open_drain, int assign) 49{ 50 u32 dbit_mask; 51 u32 dbit_dir; 52 u32 dbit_asgn; 53 u32 bit_mask; 54 u32 tmp_val; 55 int offset; 56 57 offset = (NUM_OF_PINS - (pin % (NUM_OF_PINS / 2) + 1) * 2); 58 59 /* Calculate pin location and 2bit mask and dir */ 60 dbit_mask = (u32)(0x3 << offset); 61 dbit_dir = (u32)(dir << offset); 62 63 /* Setup the direction */ 64 tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? 65 in_be32(&par_io->ioport[port].dir2) : 66 in_be32(&par_io->ioport[port].dir1); 67 68 if (pin > (NUM_OF_PINS / 2) - 1) { 69 out_be32(&par_io->ioport[port].dir2, ~dbit_mask & tmp_val); 70 out_be32(&par_io->ioport[port].dir2, dbit_dir | tmp_val); 71 } else { 72 out_be32(&par_io->ioport[port].dir1, ~dbit_mask & tmp_val); 73 out_be32(&par_io->ioport[port].dir1, dbit_dir | tmp_val); 74 } 75 76 /* Calculate pin location for 1bit mask */ 77 bit_mask = (u32)(1 << (NUM_OF_PINS - (pin + 1))); 78 79 /* Setup the open drain */ 80 tmp_val = in_be32(&par_io->ioport[port].podr); 81 if (open_drain) 82 out_be32(&par_io->ioport[port].podr, bit_mask | tmp_val); 83 else 84 out_be32(&par_io->ioport[port].podr, ~bit_mask & tmp_val); 85 86 /* Setup the assignment */ 87 tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? 88 in_be32(&par_io->ioport[port].ppar2) : 89 in_be32(&par_io->ioport[port].ppar1); 90 dbit_asgn = (u32)(assign << offset); 91 92 /* Clear and set 2 bits mask */ 93 if (pin > (NUM_OF_PINS / 2) - 1) { 94 out_be32(&par_io->ioport[port].ppar2, ~dbit_mask & tmp_val); 95 out_be32(&par_io->ioport[port].ppar2, dbit_asgn | tmp_val); 96 } else { 97 out_be32(&par_io->ioport[port].ppar1, ~dbit_mask & tmp_val); 98 out_be32(&par_io->ioport[port].ppar1, dbit_asgn | tmp_val); 99 } 100} 101 102#if !defined(CONFIG_PINCTRL) 103/** qe_config_iopin configure one io pin setting 104 * 105 * @port: io pin port 106 * @pin: io pin number which get configured 107 * @dir: direction of io pin 2 bits valid 108 * 00 = pin disabled 109 * 01 = output 110 * 10 = input 111 * 11 = pin is I/O 112 * @open_drain: is pin open drain 113 * @assign: pin assignment registers select the function of the pin 114 */ 115void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) 116{ 117 immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 118 qepio83xx_t *par_io = (qepio83xx_t *)&im->qepio; 119 120 qe_cfg_iopin(par_io, port, pin, dir, open_drain, assign); 121} 122#else 123static int qe_io_of_to_plat(struct udevice *dev) 124{ 125 struct qe_io_plat *plat = dev_get_plat(dev); 126 fdt_addr_t addr; 127 128 addr = dev_read_addr(dev); 129 if (addr == FDT_ADDR_T_NONE) 130 return -EINVAL; 131 132 plat->base = (qepio83xx_t *)addr; 133 if (dev_read_u32(dev, "num-ports", &plat->num_io_ports)) 134 return -EINVAL; 135 136 return 0; 137} 138 139/** 140 * par_io_of_config_node config 141 * @dev: pointer to pinctrl device 142 * @pio: ofnode of pinconfig property 143 */ 144static int par_io_of_config_node(struct udevice *dev, ofnode pio) 145{ 146 struct qe_io_plat *plat = dev_get_plat(dev); 147 qepio83xx_t *par_io = plat->base; 148 const unsigned int *pio_map; 149 int pio_map_len; 150 151 pio_map = ofnode_get_property(pio, "pio-map", &pio_map_len); 152 if (!pio_map) 153 return -ENOENT; 154 155 pio_map_len /= sizeof(unsigned int); 156 if ((pio_map_len % 6) != 0) { 157 dev_err(dev, "%s: pio-map format wrong!\n", __func__); 158 return -EINVAL; 159 } 160 161 while (pio_map_len > 0) { 162 /* 163 * column pio_map[5] from linux (has_irq) not 164 * supported in u-boot yet. 165 */ 166 qe_cfg_iopin(par_io, (u8)pio_map[0], (u8)pio_map[1], 167 (int)pio_map[2], (int)pio_map[3], 168 (int)pio_map[4]); 169 pio_map += 6; 170 pio_map_len -= 6; 171 } 172 return 0; 173} 174 175int par_io_of_config(struct udevice *dev) 176{ 177 u32 phandle; 178 ofnode pio; 179 int err; 180 181 err = ofnode_read_u32(dev_ofnode(dev), "pio-handle", &phandle); 182 if (err) { 183 dev_err(dev, "%s: pio-handle not available\n", __func__); 184 return err; 185 } 186 187 pio = ofnode_get_by_phandle(phandle); 188 if (!ofnode_valid(pio)) { 189 dev_err(dev, "%s: unable to find node\n", __func__); 190 return -EINVAL; 191 } 192 193 /* To Do: find pinctrl device and pass it */ 194 return par_io_of_config_node(NULL, pio); 195} 196 197/* 198 * This is not nice! 199 * pinsettings should work with "pinctrl-" properties. 200 * Unfortunately on mpc83xx powerpc linux device trees 201 * devices handle this with "pio-handle" properties ... 202 * 203 * Even worser, old board code inits all par_io 204 * pins in one step, if U-Boot uses the device 205 * or not. So init all par_io definitions here too 206 * as linux does this also. 207 */ 208static void config_qe_ioports(struct udevice *dev) 209{ 210 ofnode ofn; 211 212 for (ofn = dev_read_first_subnode(dev); ofnode_valid(ofn); 213 ofn = dev_read_next_subnode(ofn)) { 214 /* 215 * ignore errors here, as may the subnode 216 * has no pio-handle 217 */ 218 par_io_of_config_node(dev, ofn); 219 } 220} 221 222static int par_io_pinctrl_probe(struct udevice *dev) 223{ 224 config_qe_ioports(dev); 225 226 return 0; 227} 228 229static int par_io_pinctrl_set_state(struct udevice *dev, struct udevice *config) 230{ 231 return 0; 232} 233 234const struct pinctrl_ops par_io_pinctrl_ops = { 235 .set_state = par_io_pinctrl_set_state, 236}; 237 238static const struct udevice_id par_io_pinctrl_match[] = { 239 { .compatible = "fsl,mpc8360-par_io"}, 240 { /* sentinel */ } 241}; 242 243U_BOOT_DRIVER(par_io_pinctrl) = { 244 .name = "par-io-pinctrl", 245 .id = UCLASS_PINCTRL, 246 .of_match = of_match_ptr(par_io_pinctrl_match), 247 .probe = par_io_pinctrl_probe, 248 .of_to_plat = qe_io_of_to_plat, 249 .plat_auto = sizeof(struct qe_io_plat), 250 .ops = &par_io_pinctrl_ops, 251#if CONFIG_IS_ENABLED(OF_REAL) 252 .flags = DM_FLAG_PRE_RELOC, 253#endif 254}; 255#endif 256