1/*
2 * arch/arm/mach-dove/mpp.c
3 *
4 * MPP functions for Marvell Dove SoCs
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2.  This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/gpio.h>
13#include <linux/io.h>
14#include <plat/mpp.h>
15#include <mach/dove.h>
16#include <plat/orion-gpio.h>
17#include "mpp.h"
18
19struct dove_mpp_grp {
20	int start;
21	int end;
22};
23
24/* Map a group to a range of GPIO pins in that group */
25static const struct dove_mpp_grp dove_mpp_grp[] = {
26	[MPP_24_39] = {
27		.start	= 24,
28		.end	= 39,
29	},
30	[MPP_40_45] = {
31		.start	= 40,
32		.end	= 45,
33	},
34	[MPP_46_51] = {
35		.start	= 46,
36		.end	= 51,
37	},
38	[MPP_58_61] = {
39		.start	= 58,
40		.end	= 61,
41	},
42	[MPP_62_63] = {
43		.start	= 62,
44		.end	= 63,
45	},
46};
47
48/* Enable gpio for a range of pins. mode should be a combination of
49   GPIO_OUTPUT_OK | GPIO_INPUT_OK */
50static void __init dove_mpp_gpio_mode(int start, int end, int gpio_mode)
51{
52	int i;
53
54	for (i = start; i <= end; i++)
55		orion_gpio_set_valid(i, gpio_mode);
56}
57
58/* Dump all the extra MPP registers. The platform code will dump the
59   registers for pins 0-23. */
60static void __init dove_mpp_dump_regs(void)
61{
62	pr_debug("PMU_CTRL4_CTRL: %08x\n",
63		 readl(DOVE_MPP_CTRL4_VIRT_BASE));
64
65	pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
66		 readl(DOVE_PMU_MPP_GENERAL_CTRL));
67
68	pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
69}
70
71static void __init dove_mpp_cfg_nfc(int sel)
72{
73	u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);
74
75	mpp_gen_cfg &= ~0x1;
76	mpp_gen_cfg |= sel;
77	writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);
78
79	dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
80}
81
82static void __init dove_mpp_cfg_au1(int sel)
83{
84	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
85	u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
86	u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
87	u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
88
89	mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
90	ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
91	mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
92	global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);
93
94	if (!sel || sel == 0x2)
95		dove_mpp_gpio_mode(52, 57, 0);
96	else
97		dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
98
99	if (sel & 0x1) {
100		global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
101		dove_mpp_gpio_mode(56, 57, 0);
102	}
103	if (sel & 0x2) {
104		mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
105		dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
106	}
107	if (sel & 0x4) {
108		ssp_ctrl1 |= DOVE_SSP_ON_AU1;
109		dove_mpp_gpio_mode(52, 55, 0);
110	}
111	if (sel & 0x8)
112		mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;
113
114	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
115	writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
116	writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
117	writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
118}
119
120/* Configure the group registers, enabling GPIO if sel indicates the
121   pin is to be used for GPIO */
122static void __init dove_mpp_conf_grp(unsigned int *mpp_grp_list)
123{
124	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
125	int gpio_mode;
126
127	for ( ; *mpp_grp_list; mpp_grp_list++) {
128		unsigned int num = MPP_NUM(*mpp_grp_list);
129		unsigned int sel = MPP_SEL(*mpp_grp_list);
130
131		if (num > MPP_GRP_MAX) {
132			pr_err("dove: invalid MPP GRP number (%u)\n", num);
133			continue;
134		}
135
136		mpp_ctrl4 &= ~(0x1 << num);
137		mpp_ctrl4 |= sel << num;
138
139		gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
140		dove_mpp_gpio_mode(dove_mpp_grp[num].start,
141				   dove_mpp_grp[num].end, gpio_mode);
142	}
143	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
144}
145
146/* Configure the various MPP pins on Dove */
147void __init dove_mpp_conf(unsigned int *mpp_list,
148			  unsigned int *mpp_grp_list,
149			  unsigned int grp_au1_52_57,
150			  unsigned int grp_nfc_64_71)
151{
152	dove_mpp_dump_regs();
153
154	/* Use platform code for pins 0-23 */
155	orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);
156
157	dove_mpp_conf_grp(mpp_grp_list);
158	dove_mpp_cfg_au1(grp_au1_52_57);
159	dove_mpp_cfg_nfc(grp_nfc_64_71);
160
161	dove_mpp_dump_regs();
162}
163