160812Sps/* 260786Sps * arch/arm/mach-kirkwood/mpp.c 360786Sps * 460786Sps * MPP functions for Marvell Kirkwood SoCs 560786Sps * Referenced from Linux kernel source 660786Sps * 760786Sps * This file is licensed under the terms of the GNU General Public 860786Sps * License version 2. This program is licensed "as is" without any 960786Sps * warranty of any kind, whether express or implied. 1060786Sps */ 1160786Sps 1260786Sps#include <common.h> 1360786Sps#include <log.h> 1460786Sps#include <asm/io.h> 1560786Sps#include <asm/arch/cpu.h> 1660786Sps#include <asm/arch/soc.h> 1760786Sps#include <asm/arch/mpp.h> 1889022Sps 1989022Spsstatic u32 kirkwood_variant(void) 2089022Sps{ 2160786Sps switch (readl(KW_REG_DEVICE_ID) & 0x03) { 2260786Sps case 1: 2360786Sps return MPP_F6192_MASK; 2460786Sps case 2: 2560786Sps return MPP_F6281_MASK; 2660786Sps default: 2760786Sps debug("MPP setup: unknown kirkwood variant\n"); 2860786Sps return 0; 2960786Sps } 3060786Sps} 3160786Sps 3260786Sps#define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) 3360786Sps#define MPP_NR_REGS (1 + MPP_MAX/8) 3460786Sps 3560786Spsvoid kirkwood_mpp_conf(const u32 *mpp_list, u32 *mpp_save) 3660786Sps{ 3760786Sps u32 mpp_ctrl[MPP_NR_REGS]; 3860786Sps unsigned int variant_mask; 3960786Sps int i; 4060786Sps 4160786Sps variant_mask = kirkwood_variant(); 4260812Sps if (!variant_mask) 4360786Sps return; 4460786Sps 4560786Sps debug( "initial MPP regs:"); 4660786Sps for (i = 0; i < MPP_NR_REGS; i++) { 4760786Sps mpp_ctrl[i] = readl(MPP_CTRL(i)); 4860786Sps debug(" %08x", mpp_ctrl[i]); 4960786Sps } 5060786Sps debug("\n"); 5160786Sps 5260786Sps 5360786Sps while (*mpp_list) { 5460786Sps unsigned int num = MPP_NUM(*mpp_list); 5560786Sps unsigned int sel = MPP_SEL(*mpp_list); 5660786Sps unsigned int sel_save; 5760786Sps int shift; 5863131Sps 5960786Sps if (num > MPP_MAX) { 6060786Sps debug("kirkwood_mpp_conf: invalid MPP " 6160786Sps "number (%u)\n", num); 6260786Sps continue; 6360786Sps } 6460786Sps if (!(*mpp_list & variant_mask)) { 6560786Sps debug("kirkwood_mpp_conf: requested MPP%u config " 6660786Sps "unavailable on this hardware\n", num); 6760786Sps continue; 6860786Sps } 6960786Sps 7060786Sps shift = (num & 7) << 2; 7160786Sps 7260786Sps if (mpp_save) { 7360786Sps sel_save = (mpp_ctrl[num / 8] >> shift) & 0xf; 7460786Sps *mpp_save = num | (sel_save << 8) | variant_mask; 7560786Sps mpp_save++; 7660786Sps } 7760786Sps 7860786Sps mpp_ctrl[num / 8] &= ~(0xf << shift); 7960786Sps mpp_ctrl[num / 8] |= sel << shift; 8060786Sps 8160786Sps mpp_list++; 8260786Sps } 8360786Sps 8460786Sps debug(" final MPP regs:"); 8560786Sps for (i = 0; i < MPP_NR_REGS; i++) { 8660786Sps writel(mpp_ctrl[i], MPP_CTRL(i)); 8760786Sps debug(" %08x", mpp_ctrl[i]); 8860786Sps } 8960786Sps debug("\n"); 9060786Sps 9160786Sps} 9260786Sps