Linux Audio

Check our new training course

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