]>
Commit | Line | Data |
---|---|---|
4efb77d4 PW |
1 | /* |
2 | * arch/arm/mach-kirkwood/mpp.c | |
3 | * | |
4 | * MPP functions for Marvell Kirkwood SoCs | |
5 | * Referenced from Linux kernel source | |
6 | * | |
7 | * This file is licensed under the terms of the GNU General Public | |
8 | * License version 2. This program is licensed "as is" without any | |
9 | * warranty of any kind, whether express or implied. | |
10 | */ | |
11 | ||
12 | #include <common.h> | |
a7efd719 LW |
13 | #include <asm/io.h> |
14 | #include <asm/arch/cpu.h> | |
3dc23f78 | 15 | #include <asm/arch/soc.h> |
4efb77d4 PW |
16 | #include <asm/arch/mpp.h> |
17 | ||
18 | static u32 kirkwood_variant(void) | |
19 | { | |
20 | switch (readl(KW_REG_DEVICE_ID) & 0x03) { | |
21 | case 1: | |
22 | return MPP_F6192_MASK; | |
23 | case 2: | |
24 | return MPP_F6281_MASK; | |
25 | default: | |
26 | debug("MPP setup: unknown kirkwood variant\n"); | |
27 | return 0; | |
28 | } | |
29 | } | |
30 | ||
31 | #define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) | |
32 | #define MPP_NR_REGS (1 + MPP_MAX/8) | |
33 | ||
9d86f0c3 | 34 | void kirkwood_mpp_conf(const u32 *mpp_list, u32 *mpp_save) |
4efb77d4 PW |
35 | { |
36 | u32 mpp_ctrl[MPP_NR_REGS]; | |
37 | unsigned int variant_mask; | |
38 | int i; | |
39 | ||
40 | variant_mask = kirkwood_variant(); | |
41 | if (!variant_mask) | |
42 | return; | |
43 | ||
44 | debug( "initial MPP regs:"); | |
45 | for (i = 0; i < MPP_NR_REGS; i++) { | |
46 | mpp_ctrl[i] = readl(MPP_CTRL(i)); | |
47 | debug(" %08x", mpp_ctrl[i]); | |
48 | } | |
49 | debug("\n"); | |
50 | ||
51 | ||
52 | while (*mpp_list) { | |
53 | unsigned int num = MPP_NUM(*mpp_list); | |
54 | unsigned int sel = MPP_SEL(*mpp_list); | |
8f5d7a03 | 55 | unsigned int sel_save; |
4efb77d4 PW |
56 | int shift; |
57 | ||
58 | if (num > MPP_MAX) { | |
59 | debug("kirkwood_mpp_conf: invalid MPP " | |
60 | "number (%u)\n", num); | |
61 | continue; | |
62 | } | |
63 | if (!(*mpp_list & variant_mask)) { | |
64 | debug("kirkwood_mpp_conf: requested MPP%u config " | |
65 | "unavailable on this hardware\n", num); | |
66 | continue; | |
67 | } | |
68 | ||
69 | shift = (num & 7) << 2; | |
8f5d7a03 VL |
70 | |
71 | if (mpp_save) { | |
72 | sel_save = (mpp_ctrl[num / 8] >> shift) & 0xf; | |
73 | *mpp_save = num | (sel_save << 8) | variant_mask; | |
74 | mpp_save++; | |
75 | } | |
76 | ||
4efb77d4 PW |
77 | mpp_ctrl[num / 8] &= ~(0xf << shift); |
78 | mpp_ctrl[num / 8] |= sel << shift; | |
79 | ||
80 | mpp_list++; | |
81 | } | |
82 | ||
83 | debug(" final MPP regs:"); | |
84 | for (i = 0; i < MPP_NR_REGS; i++) { | |
85 | writel(mpp_ctrl[i], MPP_CTRL(i)); | |
86 | debug(" %08x", mpp_ctrl[i]); | |
87 | } | |
88 | debug("\n"); | |
89 | ||
90 | } |