1dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding/* 2dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 3dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * 4dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * This program is free software; you can redistribute it and/or modify it 5dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * under the terms and conditions of the GNU General Public License, 6dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * version 2, as published by the Free Software Foundation. 7dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * 8dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * This program is distributed in the hope it will be useful, but WITHOUT 9dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding * more details. 12dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding */ 13dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 14dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/delay.h> 15dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/io.h> 16dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/module.h> 17dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/of.h> 18dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/phy/phy.h> 19dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/pinctrl/pinctrl.h> 20dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/pinctrl/pinmux.h> 21dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/platform_device.h> 22dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <linux/reset.h> 23dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 24dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> 25dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 26dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include "core.h" 27dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#include "pinctrl-utils.h" 28dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 29dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_ELPG_PROGRAM 0x01c 30dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26) 31dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25) 32dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24) 33dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 34dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040 35dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19) 36dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12) 37dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1) 38dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 39dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044 40dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6) 41dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5) 42dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4) 43dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 44dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138 45dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27) 46dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24) 47dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3) 48dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1) 49dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0) 50dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 51dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148 52dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1) 53dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0) 54dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 55dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstruct tegra_xusb_padctl_function { 56dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const char *name; 57dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const char * const *groups; 58dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int num_groups; 59dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 60dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 61dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstruct tegra_xusb_padctl_group { 62dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const unsigned int *funcs; 63dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int num_funcs; 64dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 65dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 66dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstruct tegra_xusb_padctl_soc { 67dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const struct pinctrl_pin_desc *pins; 68dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int num_pins; 69dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 70dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const struct tegra_xusb_padctl_function *functions; 71dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int num_functions; 72dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 73dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const struct tegra_xusb_padctl_lane *lanes; 74dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int num_lanes; 75dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 76dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 77dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstruct tegra_xusb_padctl_lane { 78dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const char *name; 79dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 80dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int offset; 81dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int shift; 82dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int mask; 83dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int iddq; 84dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 85dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const unsigned int *funcs; 86dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int num_funcs; 87dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 88dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 89dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstruct tegra_xusb_padctl { 90dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct device *dev; 91dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding void __iomem *regs; 92dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct mutex lock; 93dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct reset_control *rst; 94dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 95dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const struct tegra_xusb_padctl_soc *soc; 96dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct pinctrl_dev *pinctrl; 97dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct pinctrl_desc desc; 98dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 99dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct phy_provider *provider; 100dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct phy *phys[2]; 101dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 102dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int enable; 103dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 104dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 105dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value, 106dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long offset) 107dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 108dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding writel(value, padctl->regs + offset); 109dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 110dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 111dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic inline u32 padctl_readl(struct tegra_xusb_padctl *padctl, 112dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long offset) 113dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 114dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return readl(padctl->regs + offset); 115dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 116dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 117dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_get_groups_count(struct pinctrl_dev *pinctrl) 118dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 119dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 120dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 121dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return padctl->soc->num_pins; 122dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 123dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 124dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char *tegra_xusb_padctl_get_group_name(struct pinctrl_dev *pinctrl, 125dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int group) 126dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 127dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 128dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 129dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return padctl->soc->pins[group].name; 130dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 131dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 132dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingenum tegra_xusb_padctl_param { 133dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA_XUSB_PADCTL_IDDQ, 134dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 135dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 136dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct tegra_xusb_padctl_property { 137dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const char *name; 138dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding enum tegra_xusb_padctl_param param; 139dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} properties[] = { 140dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding { "nvidia,iddq", TEGRA_XUSB_PADCTL_IDDQ }, 141dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 142dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 143dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define TEGRA_XUSB_PADCTL_PACK(param, value) ((param) << 16 | (value)) 144dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define TEGRA_XUSB_PADCTL_UNPACK_PARAM(config) ((config) >> 16) 145dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define TEGRA_XUSB_PADCTL_UNPACK_VALUE(config) ((config) & 0xffff) 146dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 147dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, 148dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct device_node *np, 149dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct pinctrl_map **maps, 150dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int *reserved_maps, 151dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int *num_maps) 152dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 153dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int i, reserve = 0, num_configs = 0; 154dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long config, *configs = NULL; 155dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const char *function, *group; 156dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct property *prop; 157dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding int err = 0; 158dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 159dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 160dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = of_property_read_string(np, "nvidia,function", &function); 161dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) { 162dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err != -EINVAL) 163dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 164dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 165dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding function = NULL; 166dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 167dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 168dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding for (i = 0; i < ARRAY_SIZE(properties); i++) { 169dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = of_property_read_u32(np, properties[i].name, &value); 170dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) { 171dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err == -EINVAL) 172dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding continue; 173dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 174dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 175dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 176dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 177dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value); 178dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 179dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = pinctrl_utils_add_config(padctl->pinctrl, &configs, 180dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding &num_configs, config); 181dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 182dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 183dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 184dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 185dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (function) 186dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding reserve++; 187dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 188dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (num_configs) 189dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding reserve++; 190dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 191dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = of_property_count_strings(np, "nvidia,lanes"); 192dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 193dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 194dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 195dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding reserve *= err; 196dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 197dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps, 198dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding num_maps, reserve); 199dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 200dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 201dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 202dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding of_property_for_each_string(np, "nvidia,lanes", prop, group) { 203dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (function) { 204dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = pinctrl_utils_add_map_mux(padctl->pinctrl, maps, 205dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding reserved_maps, num_maps, group, 206dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding function); 207dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 208dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 209dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 210dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 211dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (num_configs) { 212dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = pinctrl_utils_add_map_configs(padctl->pinctrl, 213dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding maps, reserved_maps, num_maps, group, 214dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding configs, num_configs, 215dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PIN_MAP_TYPE_CONFIGS_GROUP); 216dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 217dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 218dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 219dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 220dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 221dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 222dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 223dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 224dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl, 225dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct device_node *parent, 226dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct pinctrl_map **maps, 227dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int *num_maps) 228dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 229dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 230dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int reserved_maps = 0; 231dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct device_node *np; 232dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding int err; 233dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 234dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding *num_maps = 0; 235dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding *maps = NULL; 236dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 237dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding for_each_child_of_node(parent, np) { 238dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = tegra_xusb_padctl_parse_subnode(padctl, np, maps, 239dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding &reserved_maps, 240dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding num_maps); 241dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 242dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 243dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 244dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 245dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 246dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 247dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 248dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct pinctrl_ops tegra_xusb_padctl_pinctrl_ops = { 249dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .get_groups_count = tegra_xusb_padctl_get_groups_count, 250dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .get_group_name = tegra_xusb_padctl_get_group_name, 251dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .dt_node_to_map = tegra_xusb_padctl_dt_node_to_map, 252dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .dt_free_map = pinctrl_utils_dt_free_map, 253dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 254dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 255dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_get_functions_count(struct pinctrl_dev *pinctrl) 256dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 257dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 258dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 259dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return padctl->soc->num_functions; 260dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 261dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 262dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char * 263dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingtegra_xusb_padctl_get_function_name(struct pinctrl_dev *pinctrl, 264dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int function) 265dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 266dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 267dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 268dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return padctl->soc->functions[function].name; 269dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 270dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 271dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_get_function_groups(struct pinctrl_dev *pinctrl, 272dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int function, 273dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const char * const **groups, 274dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned * const num_groups) 275dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 276dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 277dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 278dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding *num_groups = padctl->soc->functions[function].num_groups; 279dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding *groups = padctl->soc->functions[function].groups; 280dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 281dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 282dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 283dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 28403e9f0cac5da6af85758276cb4624caf5911f2b9Linus Walleijstatic int tegra_xusb_padctl_pinmux_set(struct pinctrl_dev *pinctrl, 28503e9f0cac5da6af85758276cb4624caf5911f2b9Linus Walleij unsigned int function, 28603e9f0cac5da6af85758276cb4624caf5911f2b9Linus Walleij unsigned int group) 287dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 288dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 289dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const struct tegra_xusb_padctl_lane *lane; 290dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int i; 291dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 292dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 293dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding lane = &padctl->soc->lanes[group]; 294dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 295dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding for (i = 0; i < lane->num_funcs; i++) 296dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (lane->funcs[i] == function) 297dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding break; 298dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 299dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (i >= lane->num_funcs) 300dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return -EINVAL; 301dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 302dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, lane->offset); 303dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~(lane->mask << lane->shift); 304dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= i << lane->shift; 305dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, lane->offset); 306dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 307dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 308dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 309dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 310dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct pinmux_ops tegra_xusb_padctl_pinmux_ops = { 311dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .get_functions_count = tegra_xusb_padctl_get_functions_count, 312dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .get_function_name = tegra_xusb_padctl_get_function_name, 313dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .get_function_groups = tegra_xusb_padctl_get_function_groups, 31403e9f0cac5da6af85758276cb4624caf5911f2b9Linus Walleij .set_mux = tegra_xusb_padctl_pinmux_set, 315dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 316dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 317dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_pinconf_group_get(struct pinctrl_dev *pinctrl, 318dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int group, 319dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long *config) 320dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 321dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 322dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const struct tegra_xusb_padctl_lane *lane; 323dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding enum tegra_xusb_padctl_param param; 324dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 325dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 326dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(*config); 327dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding lane = &padctl->soc->lanes[group]; 328dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 329dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding switch (param) { 330dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding case TEGRA_XUSB_PADCTL_IDDQ: 331dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding /* lanes with iddq == 0 don't support this parameter */ 332dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (lane->iddq == 0) 333dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return -EINVAL; 334dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 335dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, lane->offset); 336dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 337dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (value & BIT(lane->iddq)) 338dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = 0; 339dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding else 340dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = 1; 341dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 342dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding *config = TEGRA_XUSB_PADCTL_PACK(param, value); 343dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding break; 344dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 345dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding default: 346dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding dev_err(padctl->dev, "invalid configuration parameter: %04x\n", 347dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding param); 348dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return -ENOTSUPP; 349dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 350dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 351dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 352dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 353dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 354dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev *pinctrl, 355dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int group, 356dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long *configs, 357dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int num_configs) 358dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 359dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); 360dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const struct tegra_xusb_padctl_lane *lane; 361dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding enum tegra_xusb_padctl_param param; 362dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long value; 363dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int i; 364dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 regval; 365dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 366dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding lane = &padctl->soc->lanes[group]; 367dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 368dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding for (i = 0; i < num_configs; i++) { 369dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(configs[i]); 370dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(configs[i]); 371dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 372dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding switch (param) { 373dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding case TEGRA_XUSB_PADCTL_IDDQ: 374dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding /* lanes with iddq == 0 don't support this parameter */ 375dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (lane->iddq == 0) 376dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return -EINVAL; 377dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 378dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding regval = padctl_readl(padctl, lane->offset); 379dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 380dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (value) 381dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding regval &= ~BIT(lane->iddq); 382dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding else 383dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding regval |= BIT(lane->iddq); 384dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 385dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, regval, lane->offset); 386dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding break; 387dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 388dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding default: 389dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding dev_err(padctl->dev, 390dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "invalid configuration parameter: %04x\n", 391dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding param); 392dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return -ENOTSUPP; 393dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 394dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 395dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 396dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 397dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 398dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 399dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#ifdef CONFIG_DEBUG_FS 400dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char *strip_prefix(const char *s) 401dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 402dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const char *comma = strchr(s, ','); 403dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (!comma) 404dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return s; 405dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 406dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return comma + 1; 407dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 408dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 409dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic void 410dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingtegra_xusb_padctl_pinconf_group_dbg_show(struct pinctrl_dev *pinctrl, 411dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct seq_file *s, 412dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int group) 413dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 414dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int i; 415dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 416dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding for (i = 0; i < ARRAY_SIZE(properties); i++) { 417dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long config, value; 418dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding int err; 419dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 420dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, 0); 421dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 422dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = tegra_xusb_padctl_pinconf_group_get(pinctrl, group, 423dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding &config); 424dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 425dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding continue; 426dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 427dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config); 428dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 429dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding seq_printf(s, "\n\t%s=%lu\n", strip_prefix(properties[i].name), 430dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value); 431dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 432dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 433dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 434dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic void 435dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingtegra_xusb_padctl_pinconf_config_dbg_show(struct pinctrl_dev *pinctrl, 436dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct seq_file *s, 437dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long config) 438dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 439dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding enum tegra_xusb_padctl_param param; 440dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const char *name = "unknown"; 441dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long value; 442dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int i; 443dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 444dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(config); 445dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config); 446dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 447dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding for (i = 0; i < ARRAY_SIZE(properties); i++) { 448dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (properties[i].param == param) { 449dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding name = properties[i].name; 450dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding break; 451dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 452dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 453dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 454dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding seq_printf(s, "%s=%lu", strip_prefix(name), value); 455dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 456dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#endif 457dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 458dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = { 459dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .pin_config_group_get = tegra_xusb_padctl_pinconf_group_get, 460dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .pin_config_group_set = tegra_xusb_padctl_pinconf_group_set, 461dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#ifdef CONFIG_DEBUG_FS 462dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .pin_config_group_dbg_show = tegra_xusb_padctl_pinconf_group_dbg_show, 463dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .pin_config_config_dbg_show = tegra_xusb_padctl_pinconf_config_dbg_show, 464dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#endif 465dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 466dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 467dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) 468dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 469dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 470dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 471dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding mutex_lock(&padctl->lock); 472dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 473dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (padctl->enable++ > 0) 474dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding goto out; 475dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 476dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 477dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; 478dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 479dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 480dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding usleep_range(100, 200); 481dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 482dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 483dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; 484dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 485dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 486dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding usleep_range(100, 200); 487dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 488dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 489dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; 490dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 491dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 492dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingout: 493dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding mutex_unlock(&padctl->lock); 494dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 495dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 496dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 497dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) 498dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 499dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 500dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 501dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding mutex_lock(&padctl->lock); 502dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 503dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (WARN_ON(padctl->enable == 0)) 504dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding goto out; 505dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 506dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (--padctl->enable > 0) 507dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding goto out; 508dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 509dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 510dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; 511dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 512dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 513dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding usleep_range(100, 200); 514dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 515dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 516dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; 517dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 518dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 519dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding usleep_range(100, 200); 520dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 521dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 522dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; 523dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 524dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 525dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingout: 526dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding mutex_unlock(&padctl->lock); 527dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 528dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 529dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 530dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_phy_init(struct phy *phy) 531dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 532dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); 533dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 534dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return tegra_xusb_padctl_enable(padctl); 535dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 536dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 537dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_phy_exit(struct phy *phy) 538dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 539dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); 540dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 541dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return tegra_xusb_padctl_disable(padctl); 542dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 543dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 544dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int pcie_phy_power_on(struct phy *phy) 545dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 546dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); 547dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long timeout; 548dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding int err = -ETIMEDOUT; 549dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 550dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 551dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 552dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK; 553dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 554dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 555dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); 556dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN | 557dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN | 558dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL; 559dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); 560dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 561dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 562dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; 563dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 564dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 565dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding timeout = jiffies + msecs_to_jiffies(50); 566dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 567dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding while (time_before(jiffies, timeout)) { 568dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 569dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) { 570dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = 0; 571dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding break; 572dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 573dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 574dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding usleep_range(100, 200); 575dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 576dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 577dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 578dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 579dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 580dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int pcie_phy_power_off(struct phy *phy) 581dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 582dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); 583dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 584dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 585dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 586dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; 587dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 588dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 589dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 590dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 591dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 592dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct phy_ops pcie_phy_ops = { 593dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .init = tegra_xusb_phy_init, 594dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .exit = tegra_xusb_phy_exit, 595dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .power_on = pcie_phy_power_on, 596dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .power_off = pcie_phy_power_off, 597dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .owner = THIS_MODULE, 598dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 599dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 600dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int sata_phy_power_on(struct phy *phy) 601dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 602dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); 603dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned long timeout; 604dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding int err = -ETIMEDOUT; 605dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 606dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 607dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 608dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; 609dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; 610dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 611dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 612dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 613dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; 614dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; 615dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 616dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 617dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 618dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; 619dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 620dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 621dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 622dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; 623dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 624dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 625dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding timeout = jiffies + msecs_to_jiffies(50); 626dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 627dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding while (time_before(jiffies, timeout)) { 628dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 629dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) { 630dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = 0; 631dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding break; 632dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 633dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 634dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding usleep_range(100, 200); 635dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 636dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 637dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 638dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 639dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 640dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int sata_phy_power_off(struct phy *phy) 641dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 642dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); 643dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding u32 value; 644dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 645dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 646dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; 647dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 648dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 649dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 650dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; 651dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 652dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 653dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 654dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; 655dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; 656dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 657dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 658dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 659dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; 660dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; 661dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 662dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 663dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 664dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 665dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 666dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct phy_ops sata_phy_ops = { 667dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .init = tegra_xusb_phy_init, 668dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .exit = tegra_xusb_phy_exit, 669dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .power_on = sata_phy_power_on, 670dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .power_off = sata_phy_power_off, 671dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .owner = THIS_MODULE, 672dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 673dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 674dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic struct phy *tegra_xusb_padctl_xlate(struct device *dev, 675dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct of_phandle_args *args) 676dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 677dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev); 678dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding unsigned int index = args->args[0]; 679dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 680dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (args->args_count <= 0) 681dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return ERR_PTR(-EINVAL); 682dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 6838e1594db7e43eaf4ea88b870e97fa3ab9f8f98e0Dan Carpenter if (index >= ARRAY_SIZE(padctl->phys)) 684dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return ERR_PTR(-EINVAL); 685dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 686dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return padctl->phys[index]; 687dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 688dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 689dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_OTG_0 0 690dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_OTG_1 1 691dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_OTG_2 2 692dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_ULPI_0 3 693dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_HSIC_0 4 694dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_HSIC_1 5 695dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_PCIE_0 6 696dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_PCIE_1 7 697dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_PCIE_2 8 698dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_PCIE_3 9 699dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_PCIE_4 10 700dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define PIN_SATA_0 11 701dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 702dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct pinctrl_pin_desc tegra124_pins[] = { 703dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_OTG_0, "otg-0"), 704dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_OTG_1, "otg-1"), 705dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_OTG_2, "otg-2"), 706dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_ULPI_0, "ulpi-0"), 707dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_HSIC_0, "hsic-0"), 708dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_HSIC_1, "hsic-1"), 709dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_PCIE_0, "pcie-0"), 710dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_PCIE_1, "pcie-1"), 711dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_PCIE_2, "pcie-2"), 712dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_PCIE_3, "pcie-3"), 713dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_PCIE_4, "pcie-4"), 714dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding PINCTRL_PIN(PIN_SATA_0, "sata-0"), 715dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 716dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 717dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char * const tegra124_snps_groups[] = { 718dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-0", 719dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-1", 720dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-2", 721dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "ulpi-0", 722dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "hsic-0", 723dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "hsic-1", 724dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 725dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 726dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char * const tegra124_xusb_groups[] = { 727dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-0", 728dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-1", 729dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-2", 730dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "ulpi-0", 731dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "hsic-0", 732dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "hsic-1", 733dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 734dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 735dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char * const tegra124_uart_groups[] = { 736dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-0", 737dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-1", 738dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-2", 739dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 740dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 741dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char * const tegra124_pcie_groups[] = { 742dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-0", 743dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-1", 744dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-2", 745dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-3", 746dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-4", 747dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "sata-0", 748dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 749dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 750dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char * const tegra124_usb3_groups[] = { 751dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-0", 752dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-1", 753dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-2", 754dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-3", 755dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-4", 756dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "sata-0", 757dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 758dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 759dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char * const tegra124_sata_groups[] = { 760dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-0", 761dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-1", 762dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-2", 763dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-3", 764dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-4", 765dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "sata-0", 766dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 767dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 768dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const char * const tegra124_rsvd_groups[] = { 769dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-0", 770dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-1", 771dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "otg-2", 772dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-0", 773dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-1", 774dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-2", 775dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-3", 776dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "pcie-4", 777dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding "sata-0", 778dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 779dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 780dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define TEGRA124_FUNCTION(_name) \ 781dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding { \ 782dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .name = #_name, \ 783dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .num_groups = ARRAY_SIZE(tegra124_##_name##_groups), \ 784dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .groups = tegra124_##_name##_groups, \ 785dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 786dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 787dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic struct tegra_xusb_padctl_function tegra124_functions[] = { 788dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNCTION(snps), 789dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNCTION(xusb), 790dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNCTION(uart), 791dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNCTION(pcie), 792dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNCTION(usb3), 793dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNCTION(sata), 794dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNCTION(rsvd), 795dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 796dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 797dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingenum tegra124_function { 798dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_SNPS, 799dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_XUSB, 800dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_UART, 801dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_PCIE, 802dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_USB3, 803dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_SATA, 804dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_RSVD, 805dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 806dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 807dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const unsigned int tegra124_otg_functions[] = { 808dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_SNPS, 809dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_XUSB, 810dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_UART, 811dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_RSVD, 812dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 813dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 814dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const unsigned int tegra124_usb_functions[] = { 815dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_SNPS, 816dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_XUSB, 817dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 818dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 819dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const unsigned int tegra124_pci_functions[] = { 820dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_PCIE, 821dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_USB3, 822dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_SATA, 823dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_FUNC_RSVD, 824dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 825dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 826dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding#define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ 827dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding { \ 828dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .name = _name, \ 829dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .offset = _offset, \ 830dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .shift = _shift, \ 831dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .mask = _mask, \ 832dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .iddq = _iddq, \ 833dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \ 834dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .funcs = tegra124_##_funcs##_functions, \ 835dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 836dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 837dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct tegra_xusb_padctl_lane tegra124_lanes[] = { 838dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg), 839dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg), 840dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg), 841dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb), 842dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb), 843dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb), 844dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci), 845dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci), 846dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci), 847dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci), 848dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci), 849dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci), 850dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 851dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 852dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct tegra_xusb_padctl_soc tegra124_soc = { 853dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .num_pins = ARRAY_SIZE(tegra124_pins), 854dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .pins = tegra124_pins, 855dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .num_functions = ARRAY_SIZE(tegra124_functions), 856dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .functions = tegra124_functions, 857dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .num_lanes = ARRAY_SIZE(tegra124_lanes), 858dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .lanes = tegra124_lanes, 859dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 860dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 861dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic const struct of_device_id tegra_xusb_padctl_of_match[] = { 862dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding { .compatible = "nvidia,tegra124-xusb-padctl", .data = &tegra124_soc }, 863dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding { } 864dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 865dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry RedingMODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match); 866dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 867dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_probe(struct platform_device *pdev) 868dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 869dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl; 870dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding const struct of_device_id *match; 871dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct resource *res; 872dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct phy *phy; 873dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding int err; 874dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 875dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl = devm_kzalloc(&pdev->dev, sizeof(*padctl), GFP_KERNEL); 876dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (!padctl) 877dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return -ENOMEM; 878dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 879dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding platform_set_drvdata(pdev, padctl); 880dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding mutex_init(&padctl->lock); 881dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->dev = &pdev->dev; 882dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 883dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding match = of_match_node(tegra_xusb_padctl_of_match, pdev->dev.of_node); 884dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->soc = match->data; 885dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 886dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 887dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->regs = devm_ioremap_resource(&pdev->dev, res); 888dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (IS_ERR(padctl->regs)) 889dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return PTR_ERR(padctl->regs); 890dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 891dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->rst = devm_reset_control_get(&pdev->dev, NULL); 892dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (IS_ERR(padctl->rst)) 893dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return PTR_ERR(padctl->rst); 894dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 895dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = reset_control_deassert(padctl->rst); 896dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 897dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 898dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 899dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding memset(&padctl->desc, 0, sizeof(padctl->desc)); 900dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->desc.name = dev_name(padctl->dev); 901dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->desc.pctlops = &tegra_xusb_padctl_pinctrl_ops; 902dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->desc.pmxops = &tegra_xusb_padctl_pinmux_ops; 903dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->desc.confops = &tegra_xusb_padctl_pinconf_ops; 904dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->desc.owner = THIS_MODULE; 905dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 906dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->pinctrl = pinctrl_register(&padctl->desc, &pdev->dev, padctl); 907dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (!padctl->pinctrl) { 908dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding dev_err(&pdev->dev, "failed to register pincontrol\n"); 909dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = -ENODEV; 910dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding goto reset; 911dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 912dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 91310c8e0562057b5d64ea170feab148e1550420030Linus Torvalds phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops, NULL); 914dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (IS_ERR(phy)) { 915dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = PTR_ERR(phy); 916dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding goto unregister; 917dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 918dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 919dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy; 920dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding phy_set_drvdata(phy, padctl); 921dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 92210c8e0562057b5d64ea170feab148e1550420030Linus Torvalds phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops, NULL); 923dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (IS_ERR(phy)) { 924dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = PTR_ERR(phy); 925dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding goto unregister; 926dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 927dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 928dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->phys[TEGRA_XUSB_PADCTL_SATA] = phy; 929dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding phy_set_drvdata(phy, padctl); 930dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 931dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding padctl->provider = devm_of_phy_provider_register(&pdev->dev, 932dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding tegra_xusb_padctl_xlate); 9338a3cfb7c1700732df9fc13439b313bf8db39fefdDan Carpenter if (IS_ERR(padctl->provider)) { 9348a3cfb7c1700732df9fc13439b313bf8db39fefdDan Carpenter err = PTR_ERR(padctl->provider); 935dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding dev_err(&pdev->dev, "failed to register PHYs: %d\n", err); 936dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding goto unregister; 937dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding } 938dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 939dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return 0; 940dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 941dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingunregister: 942dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding pinctrl_unregister(padctl->pinctrl); 943dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingreset: 944dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding reset_control_assert(padctl->rst); 945dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 946dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 947dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 948dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic int tegra_xusb_padctl_remove(struct platform_device *pdev) 949dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding{ 950dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev); 951dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding int err; 952dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 953dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding pinctrl_unregister(padctl->pinctrl); 954dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 955dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding err = reset_control_assert(padctl->rst); 956dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding if (err < 0) 957dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding dev_err(&pdev->dev, "failed to assert reset: %d\n", err); 958dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 959dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding return err; 960dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding} 961dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 962dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingstatic struct platform_driver tegra_xusb_padctl_driver = { 963dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .driver = { 964dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .name = "tegra-xusb-padctl", 965dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .of_match_table = tegra_xusb_padctl_of_match, 966dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding }, 967dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .probe = tegra_xusb_padctl_probe, 968dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding .remove = tegra_xusb_padctl_remove, 969dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding}; 970dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Redingmodule_platform_driver(tegra_xusb_padctl_driver); 971dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry Reding 972dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry RedingMODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 973dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry RedingMODULE_DESCRIPTION("Tegra 124 XUSB Pad Control driver"); 974dc0a3938668706f3a63cde4ceb431e9189fb2a0aThierry RedingMODULE_LICENSE("GPL v2"); 975