blob: 0b53c7b98e93b1f34e6700d9b0bd33866957fdc8 [file] [log] [blame]
Kenneth Johansson66894842008-07-15 12:13:38 +02001/*
2 * (C) Copyright 2008
3 * Martha J Marx, Silicon Turnkey Express, mmarx@silicontkx.com
4 * mpc512x I/O pin/pad initialization for the ADS5121 board
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Kenneth Johansson66894842008-07-15 12:13:38 +02006 */
7
8#include <common.h>
9#include <linux/types.h>
Wolfgang Denk843efb12009-05-16 10:47:43 +020010#include <asm/io.h>
Kenneth Johansson66894842008-07-15 12:13:38 +020011
12void iopin_initialize(iopin_t *ioregs_init, int len)
13{
Wolfgang Denkc9c101c2008-08-12 00:36:53 +020014 short i, j, p;
Wolfgang Denk19dc7e12009-05-16 10:47:42 +020015 u32 *reg;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020016 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
Kenneth Johansson66894842008-07-15 12:13:38 +020017
Wolfgang Denk19dc7e12009-05-16 10:47:42 +020018 reg = (u32 *)&(im->io_ctrl);
Kenneth Johansson66894842008-07-15 12:13:38 +020019
20 if (sizeof(ioregs_init) == 0)
21 return;
22
23 for (i = 0; i < len; i++) {
24 for (p = 0, j = ioregs_init[i].p_offset / sizeof(u_long);
25 p < ioregs_init[i].nr_pins; p++, j++) {
26 if (ioregs_init[i].bit_or)
Wolfgang Denk843efb12009-05-16 10:47:43 +020027 setbits_be32(reg + j, ioregs_init[i].val);
Kenneth Johansson66894842008-07-15 12:13:38 +020028 else
Wolfgang Denk843efb12009-05-16 10:47:43 +020029 out_be32 (reg + j, ioregs_init[i].val);
Kenneth Johansson66894842008-07-15 12:13:38 +020030 }
31 }
32 return;
33}
Anatolij Gustschinfcc7fe42013-02-08 00:03:48 +000034
35void iopin_initialize_bits(iopin_t *ioregs_init, int len)
36{
37 short i, j, p;
38 u32 *reg, mask;
39 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
40
41 reg = (u32 *)&(im->io_ctrl);
42
43 /* iterate over table entries */
44 for (i = 0; i < len; i++) {
45 /* iterate over pins within a table entry */
46 for (p = 0, j = ioregs_init[i].p_offset / sizeof(u_long);
47 p < ioregs_init[i].nr_pins; p++, j++) {
48 if (ioregs_init[i].bit_or & IO_PIN_OVER_EACH) {
49 /* replace all settings at once */
50 out_be32(reg + j, ioregs_init[i].val);
51 } else {
52 /*
53 * only replace individual parts, but
54 * REPLACE them instead of just ORing
55 * them in and "inheriting" previously
56 * set bits which we don't want
57 */
58 mask = 0;
59 if (ioregs_init[i].bit_or & IO_PIN_OVER_FMUX)
60 mask |= IO_PIN_FMUX(3);
61
62 if (ioregs_init[i].bit_or & IO_PIN_OVER_HOLD)
63 mask |= IO_PIN_HOLD(3);
64
65 if (ioregs_init[i].bit_or & IO_PIN_OVER_PULL)
66 mask |= IO_PIN_PUD(1) | IO_PIN_PUE(1);
67
68 if (ioregs_init[i].bit_or & IO_PIN_OVER_STRIG)
69 mask |= IO_PIN_ST(1);
70
71 if (ioregs_init[i].bit_or & IO_PIN_OVER_DRVSTR)
72 mask |= IO_PIN_DS(3);
73 /*
74 * DON'T do the "mask, then insert"
75 * in place on the register, it may
76 * break access to external hardware
77 * (like boot ROMs) when configuring
78 * LPB related pins, while the code to
79 * configure the pin is read from this
80 * very address region
81 */
82 clrsetbits_be32(reg + j, mask,
83 ioregs_init[i].val & mask);
84 }
85 }
86 }
87}