cregit-Linux how code gets into the kernel

Release 4.7 drivers/pinctrl/tegra/pinctrl-tegra-xusb.c

/*
 * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/slab.h>

#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>

#include "../core.h"
#include "../pinctrl-utils.h"


#define XUSB_PADCTL_ELPG_PROGRAM 0x01c

#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26)

#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25)

#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24)


#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040

#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19)

#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12)

#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1)


#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044

#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6)

#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5)

#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4)


#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138

#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27)

#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24)

#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3)

#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1)

#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0)


#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148

#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1)

#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0)


struct tegra_xusb_padctl_function {
	
const char *name;
	
const char * const *groups;
	
unsigned int num_groups;
};


struct tegra_xusb_padctl_soc {
	
const struct pinctrl_pin_desc *pins;
	
unsigned int num_pins;

	
const struct tegra_xusb_padctl_function *functions;
	
unsigned int num_functions;

	
const struct tegra_xusb_padctl_lane *lanes;
	
unsigned int num_lanes;
};


struct tegra_xusb_padctl_lane {
	
const char *name;

	
unsigned int offset;
	
unsigned int shift;
	
unsigned int mask;
	
unsigned int iddq;

	
const unsigned int *funcs;
	
unsigned int num_funcs;
};


struct tegra_xusb_padctl {
	
struct device *dev;
	
void __iomem *regs;
	
struct mutex lock;
	
struct reset_control *rst;

	
const struct tegra_xusb_padctl_soc *soc;
	
struct pinctrl_dev *pinctrl;
	
struct pinctrl_desc desc;

	
struct phy_provider *provider;
	
struct phy *phys[2];

	
unsigned int enable;
};


static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value, unsigned long offset) { writel(value, padctl->regs + offset); }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding30100.00%1100.00%
Total30100.00%1100.00%


static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl, unsigned long offset) { return readl(padctl->regs + offset); }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding26100.00%1100.00%
Total26100.00%1100.00%


static int tegra_xusb_padctl_get_groups_count(struct pinctrl_dev *pinctrl) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); return padctl->soc->num_pins; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding28100.00%1100.00%
Total28100.00%1100.00%


static const char *tegra_xusb_padctl_get_group_name(struct pinctrl_dev *pinctrl, unsigned int group) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); return padctl->soc->pins[group].name; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding39100.00%1100.00%
Total39100.00%1100.00%


static int tegra_xusb_padctl_get_group_pins(struct pinctrl_dev *pinctrl, unsigned group, const unsigned **pins, unsigned *num_pins) { /* * For the tegra-xusb pad controller groups are synonomous * with lanes/pins and there is always one lane/pin per group. */ *pins = &pinctrl->desc->pins[group].number; *num_pins = 1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jon hunterjon hunter48100.00%1100.00%
Total48100.00%1100.00%

enum tegra_xusb_padctl_param { TEGRA_XUSB_PADCTL_IDDQ, }; static const struct tegra_xusb_padctl_property { const char *name; enum tegra_xusb_padctl_param param; } properties[] = { { "nvidia,iddq", TEGRA_XUSB_PADCTL_IDDQ }, }; #define TEGRA_XUSB_PADCTL_PACK(param, value) ((param) << 16 | (value)) #define TEGRA_XUSB_PADCTL_UNPACK_PARAM(config) ((config) >> 16) #define TEGRA_XUSB_PADCTL_UNPACK_VALUE(config) ((config) & 0xffff)
static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, struct device_node *np, struct pinctrl_map **maps, unsigned int *reserved_maps, unsigned int *num_maps) { unsigned int i, reserve = 0, num_configs = 0; unsigned long config, *configs = NULL; const char *function, *group; struct property *prop; int err = 0; u32 value; err = of_property_read_string(np, "nvidia,function", &function); if (err < 0) { if (err != -EINVAL) return err; function = NULL; } for (i = 0; i < ARRAY_SIZE(properties); i++) { err = of_property_read_u32(np, properties[i].name, &value); if (err < 0) { if (err == -EINVAL) continue; goto out; } config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value); err = pinctrl_utils_add_config(padctl->pinctrl, &configs, &num_configs, config); if (err < 0) goto out; } if (function) reserve++; if (num_configs) reserve++; err = of_property_count_strings(np, "nvidia,lanes"); if (err < 0) goto out; reserve *= err; err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps, num_maps, reserve); if (err < 0) goto out; of_property_for_each_string(np, "nvidia,lanes", prop, group) { if (function) { err = pinctrl_utils_add_map_mux(padctl->pinctrl, maps, reserved_maps, num_maps, group, function); if (err < 0) goto out; } if (num_configs) { err = pinctrl_utils_add_map_configs(padctl->pinctrl, maps, reserved_maps, num_maps, group, configs, num_configs, PIN_MAP_TYPE_CONFIGS_GROUP); if (err < 0) goto out; } } err = 0; out: kfree(configs); return err; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding362100.00%2100.00%
Total362100.00%2100.00%


static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl, struct device_node *parent, struct pinctrl_map **maps, unsigned int *num_maps) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); unsigned int reserved_maps = 0; struct device_node *np; int err; *num_maps = 0; *maps = NULL; for_each_child_of_node(parent, np) { err = tegra_xusb_padctl_parse_subnode(padctl, np, maps, &reserved_maps, num_maps); if (err < 0) { of_node_put(np); return err; } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding9793.27%150.00%
julia lawalljulia lawall76.73%150.00%
Total104100.00%2100.00%

static const struct pinctrl_ops tegra_xusb_padctl_pinctrl_ops = { .get_groups_count = tegra_xusb_padctl_get_groups_count, .get_group_name = tegra_xusb_padctl_get_group_name, .get_group_pins = tegra_xusb_padctl_get_group_pins, .dt_node_to_map = tegra_xusb_padctl_dt_node_to_map, .dt_free_map = pinctrl_utils_free_map, };
static int tegra_xusb_padctl_get_functions_count(struct pinctrl_dev *pinctrl) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); return padctl->soc->num_functions; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding28100.00%1100.00%
Total28100.00%1100.00%


static const char * tegra_xusb_padctl_get_function_name(struct pinctrl_dev *pinctrl, unsigned int function) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); return padctl->soc->functions[function].name; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding39100.00%1100.00%
Total39100.00%1100.00%


static int tegra_xusb_padctl_get_function_groups(struct pinctrl_dev *pinctrl, unsigned int function, const char * const **groups, unsigned * const num_groups) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); *num_groups = padctl->soc->functions[function].num_groups; *groups = padctl->soc->functions[function].groups; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding69100.00%1100.00%
Total69100.00%1100.00%


static int tegra_xusb_padctl_pinmux_set(struct pinctrl_dev *pinctrl, unsigned int function, unsigned int group) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); const struct tegra_xusb_padctl_lane *lane; unsigned int i; u32 value; lane = &padctl->soc->lanes[group]; for (i = 0; i < lane->num_funcs; i++) if (lane->funcs[i] == function) break; if (i >= lane->num_funcs) return -EINVAL; value = padctl_readl(padctl, lane->offset); value &= ~(lane->mask << lane->shift); value |= i << lane->shift; padctl_writel(padctl, value, lane->offset); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding13899.28%150.00%
linus walleijlinus walleij10.72%150.00%
Total139100.00%2100.00%

static const struct pinmux_ops tegra_xusb_padctl_pinmux_ops = { .get_functions_count = tegra_xusb_padctl_get_functions_count, .get_function_name = tegra_xusb_padctl_get_function_name, .get_function_groups = tegra_xusb_padctl_get_function_groups, .set_mux = tegra_xusb_padctl_pinmux_set, };
static int tegra_xusb_padctl_pinconf_group_get(struct pinctrl_dev *pinctrl, unsigned int group, unsigned long *config) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); const struct tegra_xusb_padctl_lane *lane; enum tegra_xusb_padctl_param param; u32 value; param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(*config); lane = &padctl->soc->lanes[group]; switch (param) { case TEGRA_XUSB_PADCTL_IDDQ: /* lanes with iddq == 0 don't support this parameter */ if (lane->iddq == 0) return -EINVAL; value = padctl_readl(padctl, lane->offset); if (value & BIT(lane->iddq)) value = 0; else value = 1; *config = TEGRA_XUSB_PADCTL_PACK(param, value); break; default: dev_err(padctl->dev, "invalid configuration parameter: %04x\n", param); return -ENOTSUPP; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding146100.00%1100.00%
Total146100.00%1100.00%


static int tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev *pinctrl, unsigned int group, unsigned long *configs, unsigned int num_configs) { struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl); const struct tegra_xusb_padctl_lane *lane; enum tegra_xusb_padctl_param param; unsigned long value; unsigned int i; u32 regval; lane = &padctl->soc->lanes[group]; for (i = 0; i < num_configs; i++) { param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(configs[i]); value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(configs[i]); switch (param) { case TEGRA_XUSB_PADCTL_IDDQ: /* lanes with iddq == 0 don't support this parameter */ if (lane->iddq == 0) return -EINVAL; regval = padctl_readl(padctl, lane->offset); if (value) regval &= ~BIT(lane->iddq); else regval |= BIT(lane->iddq); padctl_writel(padctl, regval, lane->offset); break; default: dev_err(padctl->dev, "invalid configuration parameter: %04x\n", param); return -ENOTSUPP; } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding190100.00%1100.00%
Total190100.00%1100.00%

#ifdef CONFIG_DEBUG_FS
static const char *strip_prefix(const char *s) { const char *comma = strchr(s, ','); if (!comma) return s; return comma + 1; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding38100.00%1100.00%
Total38100.00%1100.00%


static void tegra_xusb_padctl_pinconf_group_dbg_show(struct pinctrl_dev *pinctrl, struct seq_file *s, unsigned int group) { unsigned int i; for (i = 0; i < ARRAY_SIZE(properties); i++) { unsigned long config, value; int err; config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, 0); err = tegra_xusb_padctl_pinconf_group_get(pinctrl, group, &config); if (err < 0) continue; value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config); seq_printf(s, "\n\t%s=%lu\n", strip_prefix(properties[i].name), value); } }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding110100.00%1100.00%
Total110100.00%1100.00%


static void tegra_xusb_padctl_pinconf_config_dbg_show(struct pinctrl_dev *pinctrl, struct seq_file *s, unsigned long config) { enum tegra_xusb_padctl_param param; const char *name = "unknown"; unsigned long value; unsigned int i; param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(config); value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config); for (i = 0; i < ARRAY_SIZE(properties); i++) { if (properties[i].param == param) { name = properties[i].name; break; } } seq_printf(s, "%s=%lu", strip_prefix(name), value); }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding108100.00%1100.00%
Total108100.00%1100.00%

#endif static const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = { .pin_config_group_get = tegra_xusb_padctl_pinconf_group_get, .pin_config_group_set = tegra_xusb_padctl_pinconf_group_set, #ifdef CONFIG_DEBUG_FS .pin_config_group_dbg_show = tegra_xusb_padctl_pinconf_group_dbg_show, .pin_config_config_dbg_show = tegra_xusb_padctl_pinconf_config_dbg_show, #endif };
static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) { u32 value; mutex_lock(&padctl->lock); if (padctl->enable++ > 0) goto out; value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); usleep_range(100, 200); value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); usleep_range(100, 200); value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); out: mutex_unlock(&padctl->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding130100.00%1100.00%
Total130100.00%1100.00%


static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) { u32 value; mutex_lock(&padctl->lock); if (WARN_ON(padctl->enable == 0)) goto out; if (--padctl->enable > 0) goto out; value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); usleep_range(100, 200); value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); usleep_range(100, 200); value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); out: mutex_unlock(&padctl->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding141100.00%1100.00%
Total141100.00%1100.00%


static int tegra_xusb_phy_init(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); return tegra_xusb_padctl_enable(padctl); }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding27100.00%1100.00%
Total27100.00%1100.00%


static int tegra_xusb_phy_exit(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); return tegra_xusb_padctl_disable(padctl); }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding27100.00%1100.00%
Total27100.00%1100.00%


static int pcie_phy_power_on(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); unsigned long timeout; int err = -ETIMEDOUT; u32 value; value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN | XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN | XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); timeout = jiffies + msecs_to_jiffies(50); while (time_before(jiffies, timeout)) { value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) { err = 0; break; } usleep_range(100, 200); } return err; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding157100.00%1100.00%
Total157100.00%1100.00%


static int pcie_phy_power_off(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); u32 value; value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding50100.00%1100.00%
Total50100.00%1100.00%

static const struct phy_ops pcie_phy_ops = { .init = tegra_xusb_phy_init, .exit = tegra_xusb_phy_exit, .power_on = pcie_phy_power_on, .power_off = pcie_phy_power_off, .owner = THIS_MODULE, };
static int sata_phy_power_on(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); unsigned long timeout; int err = -ETIMEDOUT; u32 value; value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); timeout = jiffies + msecs_to_jiffies(50); while (time_before(jiffies, timeout)) { value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) { err = 0; break; } usleep_range(100, 200); } return err; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding186100.00%1100.00%
Total186100.00%1100.00%


static int sata_phy_power_off(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); u32 value; value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding127100.00%1100.00%
Total127100.00%1100.00%

static const struct phy_ops sata_phy_ops = { .init = tegra_xusb_phy_init, .exit = tegra_xusb_phy_exit, .power_on = sata_phy_power_on, .power_off = sata_phy_power_off, .owner = THIS_MODULE, };
static struct phy *tegra_xusb_padctl_xlate(struct device *dev, struct of_phandle_args *args) { struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev); unsigned int index = args->args[0]; if (args->args_count <= 0) return ERR_PTR(-EINVAL); if (index >= ARRAY_SIZE(padctl->phys)) return ERR_PTR(-EINVAL); return padctl->phys[index]; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding7998.75%150.00%
dan carpenterdan carpenter11.25%150.00%
Total80100.00%2100.00%

#define PIN_OTG_0 0 #define PIN_OTG_1 1 #define PIN_OTG_2 2 #define PIN_ULPI_0 3 #define PIN_HSIC_0 4 #define PIN_HSIC_1 5 #define PIN_PCIE_0 6 #define PIN_PCIE_1 7 #define PIN_PCIE_2 8 #define PIN_PCIE_3 9 #define PIN_PCIE_4 10 #define PIN_SATA_0 11 static const struct pinctrl_pin_desc tegra124_pins[] = { PINCTRL_PIN(PIN_OTG_0, "otg-0"), PINCTRL_PIN(PIN_OTG_1, "otg-1"), PINCTRL_PIN(PIN_OTG_2, "otg-2"), PINCTRL_PIN(PIN_ULPI_0, "ulpi-0"), PINCTRL_PIN(PIN_HSIC_0, "hsic-0"), PINCTRL_PIN(PIN_HSIC_1, "hsic-1"), PINCTRL_PIN(PIN_PCIE_0, "pcie-0"), PINCTRL_PIN(PIN_PCIE_1, "pcie-1"), PINCTRL_PIN(PIN_PCIE_2, "pcie-2"), PINCTRL_PIN(PIN_PCIE_3, "pcie-3"), PINCTRL_PIN(PIN_PCIE_4, "pcie-4"), PINCTRL_PIN(PIN_SATA_0, "sata-0"), }; static const char * const tegra124_snps_groups[] = { "otg-0", "otg-1", "otg-2", "ulpi-0", "hsic-0", "hsic-1", }; static const char * const tegra124_xusb_groups[] = { "otg-0", "otg-1", "otg-2", "ulpi-0", "hsic-0", "hsic-1", }; static const char * const tegra124_uart_groups[] = { "otg-0", "otg-1", "otg-2", }; static const char * const tegra124_pcie_groups[] = { "pcie-0", "pcie-1", "pcie-2", "pcie-3", "pcie-4", }; static const char * const tegra124_usb3_groups[] = { "pcie-0", "pcie-1", "sata-0", }; static const char * const tegra124_sata_groups[] = { "sata-0", }; static const char * const tegra124_rsvd_groups[] = { "otg-0", "otg-1", "otg-2", "pcie-0", "pcie-1", "pcie-2", "pcie-3", "pcie-4", "sata-0", }; #define TEGRA124_FUNCTION(_name) \ { \ .name = #_name, \ .num_groups = ARRAY_SIZE(tegra124_##_name##_groups), \ .groups = tegra124_##_name##_groups, \ } static struct tegra_xusb_padctl_function tegra124_functions[] = { TEGRA124_FUNCTION(snps), TEGRA124_FUNCTION(xusb), TEGRA124_FUNCTION(uart), TEGRA124_FUNCTION(pcie), TEGRA124_FUNCTION(usb3), TEGRA124_FUNCTION(sata), TEGRA124_FUNCTION(rsvd), }; enum tegra124_function { TEGRA124_FUNC_SNPS, TEGRA124_FUNC_XUSB, TEGRA124_FUNC_UART, TEGRA124_FUNC_PCIE, TEGRA124_FUNC_USB3, TEGRA124_FUNC_SATA, TEGRA124_FUNC_RSVD, }; static const unsigned int tegra124_otg_functions[] = { TEGRA124_FUNC_SNPS, TEGRA124_FUNC_XUSB, TEGRA124_FUNC_UART, TEGRA124_FUNC_RSVD, }; static const unsigned int tegra124_usb_functions[] = { TEGRA124_FUNC_SNPS, TEGRA124_FUNC_XUSB, }; static const unsigned int tegra124_pci_functions[] = { TEGRA124_FUNC_PCIE, TEGRA124_FUNC_USB3, TEGRA124_FUNC_SATA, TEGRA124_FUNC_RSVD, }; #define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ { \ .name = _name, \ .offset = _offset, \ .shift = _shift, \ .mask = _mask, \ .iddq = _iddq, \ .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \ .funcs = tegra124_##_funcs##_functions, \ } static const struct tegra_xusb_padctl_lane tegra124_lanes[] = { TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg), TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg), TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg), TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb), TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb), TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb), TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci), TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci), TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci), TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci), TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci), TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci), }; static const struct tegra_xusb_padctl_soc tegra124_soc = { .num_pins = ARRAY_SIZE(tegra124_pins), .pins = tegra124_pins, .num_functions = ARRAY_SIZE(tegra124_functions), .functions = tegra124_functions, .num_lanes = ARRAY_SIZE(tegra124_lanes), .lanes = tegra124_lanes, }; static const struct of_device_id tegra_xusb_padctl_of_match[] = { { .compatible = "nvidia,tegra124-xusb-padctl", .data = &tegra124_soc }, { } }; MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match);
int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev) { struct tegra_xusb_padctl *padctl; const struct of_device_id *match; struct resource *res; struct phy *phy; int err; padctl = devm_kzalloc(&pdev->dev, sizeof(*padctl), GFP_KERNEL); if (!padctl) return -ENOMEM; platform_set_drvdata(pdev, padctl); mutex_init(&padctl->lock); padctl->dev = &pdev->dev; match = of_match_node(tegra_xusb_padctl_of_match, pdev->dev.of_node); padctl->soc = match->data; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); padctl->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(padctl->regs)) return PTR_ERR(padctl->regs); padctl->rst = devm_reset_control_get(&pdev->dev, NULL); if (IS_ERR(padctl->rst)) return PTR_ERR(padctl->rst); err = reset_control_deassert(padctl->rst); if (err < 0) return err; memset(&padctl->desc, 0, sizeof(padctl->desc)); padctl->desc.name = dev_name(padctl->dev); padctl->desc.pins = tegra124_pins; padctl->desc.npins = ARRAY_SIZE(tegra124_pins); padctl->desc.pctlops = &tegra_xusb_padctl_pinctrl_ops; padctl->desc.pmxops = &tegra_xusb_padctl_pinmux_ops; padctl->desc.confops = &tegra_xusb_padctl_pinconf_ops; padctl->desc.owner = THIS_MODULE; padctl->pinctrl = devm_pinctrl_register(&pdev->dev, &padctl->desc, padctl); if (IS_ERR(padctl->pinctrl)) { dev_err(&pdev->dev, "failed to register pincontrol\n"); err = PTR_ERR(padctl->pinctrl); goto reset; } phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops); if (IS_ERR(phy)) { err = PTR_ERR(phy); goto reset; } padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy; phy_set_drvdata(phy, padctl); phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops); if (IS_ERR(phy)) { err = PTR_ERR(phy); goto reset; } padctl->phys[TEGRA_XUSB_PADCTL_SATA] = phy; phy_set_drvdata(phy, padctl); padctl->provider = devm_of_phy_provider_register(&pdev->dev, tegra_xusb_padctl_xlate); if (IS_ERR(padctl->provider)) { err = PTR_ERR(padctl->provider); dev_err(&pdev->dev, "failed to register PHYs: %d\n", err); goto reset; } return 0; reset: reset_control_assert(padctl->rst); return err; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding44288.93%228.57%
jon hunterjon hunter193.82%114.29%
dan carpenterdan carpenter153.02%114.29%
masahiro yamadamasahiro yamada91.81%114.29%
laxman dewanganlaxman dewangan81.61%114.29%
linus torvaldslinus torvalds40.80%114.29%
Total497100.00%7100.00%

EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_probe);
int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev) { struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev); int err; err = reset_control_assert(padctl->rst); if (err < 0) dev_err(&pdev->dev, "failed to assert reset: %d\n", err); return err; }

Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding53100.00%2100.00%
Total53100.00%2100.00%

EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_remove);

Overall Contributors

PersonTokensPropCommitsCommitProp
thierry redingthierry reding403897.07%323.08%
jon hunterjon hunter721.73%17.69%
dan carpenterdan carpenter160.38%215.38%
masahiro yamadamasahiro yamada110.26%215.38%
laxman dewanganlaxman dewangan80.19%17.69%
julia lawalljulia lawall70.17%17.69%
linus torvaldslinus torvalds40.10%17.69%
linus walleijlinus walleij30.07%17.69%
irina tirdeairina tirdea10.02%17.69%
Total4160100.00%13100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}