Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * arch/arm/mach-dove/mpp.c
0004  *
0005  * MPP functions for Marvell Dove SoCs
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/gpio.h>
0010 #include <linux/io.h>
0011 #include <plat/mpp.h>
0012 #include <plat/orion-gpio.h>
0013 #include "dove.h"
0014 #include "mpp.h"
0015 
0016 struct dove_mpp_grp {
0017     int start;
0018     int end;
0019 };
0020 
0021 /* Map a group to a range of GPIO pins in that group */
0022 static const struct dove_mpp_grp dove_mpp_grp[] = {
0023     [MPP_24_39] = {
0024         .start  = 24,
0025         .end    = 39,
0026     },
0027     [MPP_40_45] = {
0028         .start  = 40,
0029         .end    = 45,
0030     },
0031     [MPP_46_51] = {
0032         .start  = 46,
0033         .end    = 51,
0034     },
0035     [MPP_58_61] = {
0036         .start  = 58,
0037         .end    = 61,
0038     },
0039     [MPP_62_63] = {
0040         .start  = 62,
0041         .end    = 63,
0042     },
0043 };
0044 
0045 /* Enable gpio for a range of pins. mode should be a combination of
0046    GPIO_OUTPUT_OK | GPIO_INPUT_OK */
0047 static void __init dove_mpp_gpio_mode(int start, int end, int gpio_mode)
0048 {
0049     int i;
0050 
0051     for (i = start; i <= end; i++)
0052         orion_gpio_set_valid(i, gpio_mode);
0053 }
0054 
0055 /* Dump all the extra MPP registers. The platform code will dump the
0056    registers for pins 0-23. */
0057 static void __init dove_mpp_dump_regs(void)
0058 {
0059     pr_debug("PMU_CTRL4_CTRL: %08x\n",
0060          readl(DOVE_MPP_CTRL4_VIRT_BASE));
0061 
0062     pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
0063          readl(DOVE_PMU_MPP_GENERAL_CTRL));
0064 
0065     pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
0066 }
0067 
0068 static void __init dove_mpp_cfg_nfc(int sel)
0069 {
0070     u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);
0071 
0072     mpp_gen_cfg &= ~0x1;
0073     mpp_gen_cfg |= sel;
0074     writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);
0075 
0076     dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
0077 }
0078 
0079 static void __init dove_mpp_cfg_au1(int sel)
0080 {
0081     u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
0082     u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
0083     u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
0084     u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
0085 
0086     mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
0087     ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
0088     mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
0089     global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);
0090 
0091     if (!sel || sel == 0x2)
0092         dove_mpp_gpio_mode(52, 57, 0);
0093     else
0094         dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
0095 
0096     if (sel & 0x1) {
0097         global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
0098         dove_mpp_gpio_mode(56, 57, 0);
0099     }
0100     if (sel & 0x2) {
0101         mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
0102         dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
0103     }
0104     if (sel & 0x4) {
0105         ssp_ctrl1 |= DOVE_SSP_ON_AU1;
0106         dove_mpp_gpio_mode(52, 55, 0);
0107     }
0108     if (sel & 0x8)
0109         mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;
0110 
0111     writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
0112     writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
0113     writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
0114     writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
0115 }
0116 
0117 /* Configure the group registers, enabling GPIO if sel indicates the
0118    pin is to be used for GPIO */
0119 static void __init dove_mpp_conf_grp(unsigned int *mpp_grp_list)
0120 {
0121     u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
0122     int gpio_mode;
0123 
0124     for ( ; *mpp_grp_list; mpp_grp_list++) {
0125         unsigned int num = MPP_NUM(*mpp_grp_list);
0126         unsigned int sel = MPP_SEL(*mpp_grp_list);
0127 
0128         if (num > MPP_GRP_MAX) {
0129             pr_err("dove: invalid MPP GRP number (%u)\n", num);
0130             continue;
0131         }
0132 
0133         mpp_ctrl4 &= ~(0x1 << num);
0134         mpp_ctrl4 |= sel << num;
0135 
0136         gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
0137         dove_mpp_gpio_mode(dove_mpp_grp[num].start,
0138                    dove_mpp_grp[num].end, gpio_mode);
0139     }
0140     writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
0141 }
0142 
0143 /* Configure the various MPP pins on Dove */
0144 void __init dove_mpp_conf(unsigned int *mpp_list,
0145               unsigned int *mpp_grp_list,
0146               unsigned int grp_au1_52_57,
0147               unsigned int grp_nfc_64_71)
0148 {
0149     dove_mpp_dump_regs();
0150 
0151     /* Use platform code for pins 0-23 */
0152     orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);
0153 
0154     dove_mpp_conf_grp(mpp_grp_list);
0155     dove_mpp_cfg_au1(grp_au1_52_57);
0156     dove_mpp_cfg_nfc(grp_nfc_64_71);
0157 
0158     dove_mpp_dump_regs();
0159 }