| /* | |
| * arch/arm/mach-kirkwood/mpp.c | |
| * | |
| * MPP functions for Marvell Kirkwood SoCs | |
| * Referenced from Linux kernel source | |
| * | |
| * This file is licensed under the terms of the GNU General Public | |
| * License version 2. This program is licensed "as is" without any | |
| * warranty of any kind, whether express or implied. | |
| */ | |
| #include <common.h> | |
| #include <asm/io.h> | |
| #include <asm/arch/cpu.h> | |
| #include <asm/arch/soc.h> | |
| #include <asm/arch/mpp.h> | |
| static u32 kirkwood_variant(void) | |
| { | |
| switch (readl(KW_REG_DEVICE_ID) & 0x03) { | |
| case 1: | |
| return MPP_F6192_MASK; | |
| case 2: | |
| return MPP_F6281_MASK; | |
| default: | |
| debug("MPP setup: unknown kirkwood variant\n"); | |
| return 0; | |
| } | |
| } | |
| #define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) | |
| #define MPP_NR_REGS (1 + MPP_MAX/8) | |
| void kirkwood_mpp_conf(const u32 *mpp_list, u32 *mpp_save) | |
| { | |
| u32 mpp_ctrl[MPP_NR_REGS]; | |
| unsigned int variant_mask; | |
| int i; | |
| variant_mask = kirkwood_variant(); | |
| if (!variant_mask) | |
| return; | |
| debug( "initial MPP regs:"); | |
| for (i = 0; i < MPP_NR_REGS; i++) { | |
| mpp_ctrl[i] = readl(MPP_CTRL(i)); | |
| debug(" %08x", mpp_ctrl[i]); | |
| } | |
| debug("\n"); | |
| while (*mpp_list) { | |
| unsigned int num = MPP_NUM(*mpp_list); | |
| unsigned int sel = MPP_SEL(*mpp_list); | |
| unsigned int sel_save; | |
| int shift; | |
| if (num > MPP_MAX) { | |
| debug("kirkwood_mpp_conf: invalid MPP " | |
| "number (%u)\n", num); | |
| continue; | |
| } | |
| if (!(*mpp_list & variant_mask)) { | |
| debug("kirkwood_mpp_conf: requested MPP%u config " | |
| "unavailable on this hardware\n", num); | |
| continue; | |
| } | |
| shift = (num & 7) << 2; | |
| if (mpp_save) { | |
| sel_save = (mpp_ctrl[num / 8] >> shift) & 0xf; | |
| *mpp_save = num | (sel_save << 8) | variant_mask; | |
| mpp_save++; | |
| } | |
| mpp_ctrl[num / 8] &= ~(0xf << shift); | |
| mpp_ctrl[num / 8] |= sel << shift; | |
| mpp_list++; | |
| } | |
| debug(" final MPP regs:"); | |
| for (i = 0; i < MPP_NR_REGS; i++) { | |
| writel(mpp_ctrl[i], MPP_CTRL(i)); | |
| debug(" %08x", mpp_ctrl[i]); | |
| } | |
| debug("\n"); | |
| } |