xref: /openbmc/u-boot/arch/arm/cpu/arm926ejs/mxs/iomux.c (revision e8f80a5a)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
23a0398d7SOtavio Salvador /*
33a0398d7SOtavio Salvador  * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
43a0398d7SOtavio Salvador  * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
53a0398d7SOtavio Salvador  * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
63a0398d7SOtavio Salvador  *                       <armlinux@phytec.de>
73a0398d7SOtavio Salvador  */
83a0398d7SOtavio Salvador 
93a0398d7SOtavio Salvador #include <common.h>
101221ce45SMasahiro Yamada #include <linux/errno.h>
113a0398d7SOtavio Salvador #include <asm/io.h>
123a0398d7SOtavio Salvador #include <asm/arch/clock.h>
133a0398d7SOtavio Salvador #include <asm/arch/iomux.h>
143a0398d7SOtavio Salvador #include <asm/arch/imx-regs.h>
153a0398d7SOtavio Salvador 
163a0398d7SOtavio Salvador #if	defined(CONFIG_MX23)
173a0398d7SOtavio Salvador #define	DRIVE_OFFSET	0x200
183a0398d7SOtavio Salvador #define	PULL_OFFSET	0x400
193a0398d7SOtavio Salvador #elif	defined(CONFIG_MX28)
203a0398d7SOtavio Salvador #define	DRIVE_OFFSET	0x300
213a0398d7SOtavio Salvador #define	PULL_OFFSET	0x600
223a0398d7SOtavio Salvador #else
233a0398d7SOtavio Salvador #error "Please select CONFIG_MX23 or CONFIG_MX28"
243a0398d7SOtavio Salvador #endif
253a0398d7SOtavio Salvador 
263a0398d7SOtavio Salvador /*
273a0398d7SOtavio Salvador  * configures a single pad in the iomuxer
283a0398d7SOtavio Salvador  */
mxs_iomux_setup_pad(iomux_cfg_t pad)293a0398d7SOtavio Salvador int mxs_iomux_setup_pad(iomux_cfg_t pad)
303a0398d7SOtavio Salvador {
313a0398d7SOtavio Salvador 	u32 reg, ofs, bp, bm;
323a0398d7SOtavio Salvador 	void *iomux_base = (void *)MXS_PINCTRL_BASE;
33ddcf13b1SOtavio Salvador 	struct mxs_register_32 *mxs_reg;
343a0398d7SOtavio Salvador 
353a0398d7SOtavio Salvador 	/* muxsel */
363a0398d7SOtavio Salvador 	ofs = 0x100;
373a0398d7SOtavio Salvador 	ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
383a0398d7SOtavio Salvador 	bp = PAD_PIN(pad) % 16 * 2;
393a0398d7SOtavio Salvador 	bm = 0x3 << bp;
403a0398d7SOtavio Salvador 	reg = readl(iomux_base + ofs);
413a0398d7SOtavio Salvador 	reg &= ~bm;
423a0398d7SOtavio Salvador 	reg |= PAD_MUXSEL(pad) << bp;
433a0398d7SOtavio Salvador 	writel(reg, iomux_base + ofs);
443a0398d7SOtavio Salvador 
453a0398d7SOtavio Salvador 	/* drive */
463a0398d7SOtavio Salvador 	ofs = DRIVE_OFFSET;
473a0398d7SOtavio Salvador 	ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
483a0398d7SOtavio Salvador 	/* mA */
493a0398d7SOtavio Salvador 	if (PAD_MA_VALID(pad)) {
503a0398d7SOtavio Salvador 		bp = PAD_PIN(pad) % 8 * 4;
513a0398d7SOtavio Salvador 		bm = 0x3 << bp;
523a0398d7SOtavio Salvador 		reg = readl(iomux_base + ofs);
533a0398d7SOtavio Salvador 		reg &= ~bm;
543a0398d7SOtavio Salvador 		reg |= PAD_MA(pad) << bp;
553a0398d7SOtavio Salvador 		writel(reg, iomux_base + ofs);
563a0398d7SOtavio Salvador 	}
573a0398d7SOtavio Salvador 	/* vol */
583a0398d7SOtavio Salvador 	if (PAD_VOL_VALID(pad)) {
593a0398d7SOtavio Salvador 		bp = PAD_PIN(pad) % 8 * 4 + 2;
60ddcf13b1SOtavio Salvador 		mxs_reg = (struct mxs_register_32 *)(iomux_base + ofs);
613a0398d7SOtavio Salvador 		if (PAD_VOL(pad))
623a0398d7SOtavio Salvador 			writel(1 << bp, &mxs_reg->reg_set);
633a0398d7SOtavio Salvador 		else
643a0398d7SOtavio Salvador 			writel(1 << bp, &mxs_reg->reg_clr);
653a0398d7SOtavio Salvador 	}
663a0398d7SOtavio Salvador 
673a0398d7SOtavio Salvador 	/* pull */
683a0398d7SOtavio Salvador 	if (PAD_PULL_VALID(pad)) {
693a0398d7SOtavio Salvador 		ofs = PULL_OFFSET;
703a0398d7SOtavio Salvador 		ofs += PAD_BANK(pad) * 0x10;
713a0398d7SOtavio Salvador 		bp = PAD_PIN(pad);
72ddcf13b1SOtavio Salvador 		mxs_reg = (struct mxs_register_32 *)(iomux_base + ofs);
733a0398d7SOtavio Salvador 		if (PAD_PULL(pad))
743a0398d7SOtavio Salvador 			writel(1 << bp, &mxs_reg->reg_set);
753a0398d7SOtavio Salvador 		else
763a0398d7SOtavio Salvador 			writel(1 << bp, &mxs_reg->reg_clr);
773a0398d7SOtavio Salvador 	}
783a0398d7SOtavio Salvador 
793a0398d7SOtavio Salvador 	return 0;
803a0398d7SOtavio Salvador }
813a0398d7SOtavio Salvador 
mxs_iomux_setup_multiple_pads(const iomux_cfg_t * pad_list,unsigned count)823a0398d7SOtavio Salvador int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
833a0398d7SOtavio Salvador {
843a0398d7SOtavio Salvador 	const iomux_cfg_t *p = pad_list;
853a0398d7SOtavio Salvador 	int i;
863a0398d7SOtavio Salvador 	int ret;
873a0398d7SOtavio Salvador 
883a0398d7SOtavio Salvador 	for (i = 0; i < count; i++) {
893a0398d7SOtavio Salvador 		ret = mxs_iomux_setup_pad(*p);
903a0398d7SOtavio Salvador 		if (ret)
913a0398d7SOtavio Salvador 			return ret;
923a0398d7SOtavio Salvador 		p++;
933a0398d7SOtavio Salvador 	}
943a0398d7SOtavio Salvador 
953a0398d7SOtavio Salvador 	return 0;
963a0398d7SOtavio Salvador }
97