-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Mike Rapoport
authored and
Nicolas Pitre
committed
Dec 15, 2010
1 parent
7a1fd7e
commit 9fe2bfd
Showing
5 changed files
with
441 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 8d4ce4cd7480ccd8412d4391d063733d6fc52f5c | ||
refs/heads/master: 5af244fdf2a2405b2181da2a32636f3ca5ef162e |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
obj-y += common.o addr-map.o irq.o pcie.o | ||
obj-y += common.o addr-map.o irq.o pcie.o mpp.o | ||
|
||
obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o | ||
obj-$(CONFIG_MACH_CM_A510) += cm-a510.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
/* | ||
* arch/arm/mach-dove/mpp.c | ||
* | ||
* MPP functions for Marvell Dove SoCs | ||
* | ||
* 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 <linux/kernel.h> | ||
#include <linux/gpio.h> | ||
#include <linux/io.h> | ||
|
||
#include <mach/dove.h> | ||
|
||
#include "mpp.h" | ||
|
||
#define MPP_NR_REGS 4 | ||
#define MPP_CTRL(i) ((i) == 3 ? \ | ||
DOVE_MPP_CTRL4_VIRT_BASE : \ | ||
DOVE_MPP_VIRT_BASE + (i) * 4) | ||
#define PMU_SIG_REGS 2 | ||
#define PMU_SIG_CTRL(i) (DOVE_PMU_SIG_CTRL + (i) * 4) | ||
|
||
struct dove_mpp_grp { | ||
int start; | ||
int end; | ||
}; | ||
|
||
static struct dove_mpp_grp dove_mpp_grp[] = { | ||
[MPP_24_39] = { | ||
.start = 24, | ||
.end = 39, | ||
}, | ||
[MPP_40_45] = { | ||
.start = 40, | ||
.end = 45, | ||
}, | ||
[MPP_46_51] = { | ||
.start = 40, | ||
.end = 45, | ||
}, | ||
[MPP_58_61] = { | ||
.start = 58, | ||
.end = 61, | ||
}, | ||
[MPP_62_63] = { | ||
.start = 62, | ||
.end = 63, | ||
}, | ||
}; | ||
|
||
static void dove_mpp_gpio_mode(int start, int end, int gpio_mode) | ||
{ | ||
int i; | ||
|
||
for (i = start; i <= end; i++) | ||
orion_gpio_set_valid(i, gpio_mode); | ||
} | ||
|
||
static void dove_mpp_dump_regs(void) | ||
{ | ||
#ifdef DEBUG | ||
int i; | ||
|
||
pr_debug("MPP_CTRL regs:"); | ||
for (i = 0; i < MPP_NR_REGS; i++) | ||
printk(" %08x", readl(MPP_CTRL(i))); | ||
printk("\n"); | ||
|
||
pr_debug("PMU_SIG_CTRL regs:"); | ||
for (i = 0; i < PMU_SIG_REGS; i++) | ||
printk(" %08x", readl(PMU_SIG_CTRL(i))); | ||
printk("\n"); | ||
|
||
pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n", readl(DOVE_PMU_MPP_GENERAL_CTRL)); | ||
pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE)); | ||
#endif | ||
} | ||
|
||
static void dove_mpp_cfg_nfc(int sel) | ||
{ | ||
u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
|
||
mpp_gen_cfg &= ~0x1; | ||
mpp_gen_cfg |= sel; | ||
writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE); | ||
|
||
dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK); | ||
} | ||
|
||
static void dove_mpp_cfg_au1(int sel) | ||
{ | ||
u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | ||
u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1); | ||
u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2); | ||
|
||
mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL); | ||
ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1); | ||
mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN); | ||
global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO); | ||
|
||
if (!sel || sel == 0x2) | ||
dove_mpp_gpio_mode(52, 57, 0); | ||
else | ||
dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK); | ||
|
||
if (sel & 0x1) { | ||
global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO; | ||
dove_mpp_gpio_mode(56, 57, 0); | ||
} | ||
if (sel & 0x2) { | ||
mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN; | ||
dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK); | ||
} | ||
if (sel & 0x4) { | ||
ssp_ctrl1 |= DOVE_SSP_ON_AU1; | ||
dove_mpp_gpio_mode(52, 55, 0); | ||
} | ||
if (sel & 0x8) | ||
mpp_ctrl4 |= DOVE_AU1_GPIO_SEL; | ||
|
||
writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE); | ||
writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1); | ||
writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE); | ||
writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2); | ||
} | ||
|
||
static void dove_mpp_conf_grp(int num, int sel, u32 *mpp_ctrl) | ||
{ | ||
int start = dove_mpp_grp[num].start; | ||
int end = dove_mpp_grp[num].end; | ||
int gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0; | ||
|
||
*mpp_ctrl &= ~(0x1 << num); | ||
*mpp_ctrl |= sel << num; | ||
|
||
dove_mpp_gpio_mode(start, end, gpio_mode); | ||
} | ||
|
||
void __init dove_mpp_conf(unsigned int *mpp_list) | ||
{ | ||
u32 mpp_ctrl[MPP_NR_REGS]; | ||
u32 pmu_mpp_ctrl = 0; | ||
u32 pmu_sig_ctrl[PMU_SIG_REGS]; | ||
int i; | ||
|
||
/* Initialize gpiolib. */ | ||
orion_gpio_init(); | ||
|
||
for (i = 0; i < MPP_NR_REGS; i++) | ||
mpp_ctrl[i] = readl(MPP_CTRL(i)); | ||
|
||
for (i = 0; i < PMU_SIG_REGS; i++) | ||
pmu_sig_ctrl[i] = readl(PMU_SIG_CTRL(i)); | ||
|
||
pmu_mpp_ctrl = readl(DOVE_PMU_MPP_GENERAL_CTRL); | ||
|
||
dove_mpp_dump_regs(); | ||
|
||
for ( ; *mpp_list != MPP_END; mpp_list++) { | ||
unsigned int num = MPP_NUM(*mpp_list); | ||
unsigned int sel = MPP_SEL(*mpp_list); | ||
int shift, gpio_mode; | ||
|
||
if (num > MPP_MAX) { | ||
pr_err("dove: invalid MPP number (%u)\n", num); | ||
continue; | ||
} | ||
|
||
if (*mpp_list & MPP_NFC_MASK) { | ||
dove_mpp_cfg_nfc(sel); | ||
continue; | ||
} | ||
|
||
if (*mpp_list & MPP_AU1_MASK) { | ||
dove_mpp_cfg_au1(sel); | ||
continue; | ||
} | ||
|
||
if (*mpp_list & MPP_GRP_MASK) { | ||
dove_mpp_conf_grp(num, sel, &mpp_ctrl[3]); | ||
continue; | ||
} | ||
|
||
shift = (num & 7) << 2; | ||
if (*mpp_list & MPP_PMU_MASK) { | ||
pmu_mpp_ctrl |= (0x1 << num); | ||
pmu_sig_ctrl[num / 8] &= ~(0xf << shift); | ||
pmu_sig_ctrl[num / 8] |= 0xf << shift; | ||
gpio_mode = 0; | ||
} else { | ||
mpp_ctrl[num / 8] &= ~(0xf << shift); | ||
mpp_ctrl[num / 8] |= sel << shift; | ||
gpio_mode = GPIO_OUTPUT_OK | GPIO_INPUT_OK; | ||
} | ||
|
||
orion_gpio_set_valid(num, gpio_mode); | ||
} | ||
|
||
for (i = 0; i < MPP_NR_REGS; i++) | ||
writel(mpp_ctrl[i], MPP_CTRL(i)); | ||
|
||
for (i = 0; i < PMU_SIG_REGS; i++) | ||
writel(pmu_sig_ctrl[i], PMU_SIG_CTRL(i)); | ||
|
||
writel(pmu_mpp_ctrl, DOVE_PMU_MPP_GENERAL_CTRL); | ||
|
||
dove_mpp_dump_regs(); | ||
} |
Oops, something went wrong.