12025cf9eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
225cbac77SMasahiro Yamada /*
325cbac77SMasahiro Yamada * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
425cbac77SMasahiro Yamada */
525cbac77SMasahiro Yamada
625cbac77SMasahiro Yamada #include <linux/delay.h>
725cbac77SMasahiro Yamada #include <linux/io.h>
825cbac77SMasahiro Yamada #include <linux/module.h>
925cbac77SMasahiro Yamada #include <linux/of.h>
1025cbac77SMasahiro Yamada #include <linux/phy/phy.h>
1125cbac77SMasahiro Yamada #include <linux/platform_device.h>
1225cbac77SMasahiro Yamada #include <linux/reset.h>
13*eebeeb53SAndy Shevchenko #include <linux/seq_file.h>
1425cbac77SMasahiro Yamada #include <linux/slab.h>
1525cbac77SMasahiro Yamada
16*eebeeb53SAndy Shevchenko #include <linux/pinctrl/pinconf.h>
17*eebeeb53SAndy Shevchenko #include <linux/pinctrl/pinctrl.h>
18*eebeeb53SAndy Shevchenko #include <linux/pinctrl/pinmux.h>
19*eebeeb53SAndy Shevchenko
2025cbac77SMasahiro Yamada #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
2125cbac77SMasahiro Yamada
2225cbac77SMasahiro Yamada #include "../core.h"
2325cbac77SMasahiro Yamada #include "../pinctrl-utils.h"
2425cbac77SMasahiro Yamada
2525cbac77SMasahiro Yamada #define XUSB_PADCTL_ELPG_PROGRAM 0x01c
2625cbac77SMasahiro Yamada #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26)
2725cbac77SMasahiro Yamada #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25)
2825cbac77SMasahiro Yamada #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24)
2925cbac77SMasahiro Yamada
3025cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040
3125cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19)
3225cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12)
3325cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1)
3425cbac77SMasahiro Yamada
3525cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044
3625cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6)
3725cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5)
3825cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4)
3925cbac77SMasahiro Yamada
4025cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138
4125cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27)
4225cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24)
4325cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3)
4425cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1)
4525cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0)
4625cbac77SMasahiro Yamada
4725cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148
4825cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1)
4925cbac77SMasahiro Yamada #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0)
5025cbac77SMasahiro Yamada
5125cbac77SMasahiro Yamada struct tegra_xusb_padctl_function {
5225cbac77SMasahiro Yamada const char *name;
5325cbac77SMasahiro Yamada const char * const *groups;
5425cbac77SMasahiro Yamada unsigned int num_groups;
5525cbac77SMasahiro Yamada };
5625cbac77SMasahiro Yamada
5725cbac77SMasahiro Yamada struct tegra_xusb_padctl_soc {
5825cbac77SMasahiro Yamada const struct pinctrl_pin_desc *pins;
5925cbac77SMasahiro Yamada unsigned int num_pins;
6025cbac77SMasahiro Yamada
6125cbac77SMasahiro Yamada const struct tegra_xusb_padctl_function *functions;
6225cbac77SMasahiro Yamada unsigned int num_functions;
6325cbac77SMasahiro Yamada
6425cbac77SMasahiro Yamada const struct tegra_xusb_padctl_lane *lanes;
6525cbac77SMasahiro Yamada unsigned int num_lanes;
6625cbac77SMasahiro Yamada };
6725cbac77SMasahiro Yamada
6825cbac77SMasahiro Yamada struct tegra_xusb_padctl_lane {
6925cbac77SMasahiro Yamada const char *name;
7025cbac77SMasahiro Yamada
7125cbac77SMasahiro Yamada unsigned int offset;
7225cbac77SMasahiro Yamada unsigned int shift;
7325cbac77SMasahiro Yamada unsigned int mask;
7425cbac77SMasahiro Yamada unsigned int iddq;
7525cbac77SMasahiro Yamada
7625cbac77SMasahiro Yamada const unsigned int *funcs;
7725cbac77SMasahiro Yamada unsigned int num_funcs;
7825cbac77SMasahiro Yamada };
7925cbac77SMasahiro Yamada
8025cbac77SMasahiro Yamada struct tegra_xusb_padctl {
8125cbac77SMasahiro Yamada struct device *dev;
8225cbac77SMasahiro Yamada void __iomem *regs;
8325cbac77SMasahiro Yamada struct mutex lock;
8425cbac77SMasahiro Yamada struct reset_control *rst;
8525cbac77SMasahiro Yamada
8625cbac77SMasahiro Yamada const struct tegra_xusb_padctl_soc *soc;
8725cbac77SMasahiro Yamada struct pinctrl_dev *pinctrl;
8825cbac77SMasahiro Yamada struct pinctrl_desc desc;
8925cbac77SMasahiro Yamada
9025cbac77SMasahiro Yamada struct phy_provider *provider;
9125cbac77SMasahiro Yamada struct phy *phys[2];
9225cbac77SMasahiro Yamada
9325cbac77SMasahiro Yamada unsigned int enable;
9425cbac77SMasahiro Yamada };
9525cbac77SMasahiro Yamada
padctl_writel(struct tegra_xusb_padctl * padctl,u32 value,unsigned long offset)9625cbac77SMasahiro Yamada static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value,
9725cbac77SMasahiro Yamada unsigned long offset)
9825cbac77SMasahiro Yamada {
9925cbac77SMasahiro Yamada writel(value, padctl->regs + offset);
10025cbac77SMasahiro Yamada }
10125cbac77SMasahiro Yamada
padctl_readl(struct tegra_xusb_padctl * padctl,unsigned long offset)10225cbac77SMasahiro Yamada static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
10325cbac77SMasahiro Yamada unsigned long offset)
10425cbac77SMasahiro Yamada {
10525cbac77SMasahiro Yamada return readl(padctl->regs + offset);
10625cbac77SMasahiro Yamada }
10725cbac77SMasahiro Yamada
tegra_xusb_padctl_get_groups_count(struct pinctrl_dev * pinctrl)10825cbac77SMasahiro Yamada static int tegra_xusb_padctl_get_groups_count(struct pinctrl_dev *pinctrl)
10925cbac77SMasahiro Yamada {
11025cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
11125cbac77SMasahiro Yamada
11225cbac77SMasahiro Yamada return padctl->soc->num_pins;
11325cbac77SMasahiro Yamada }
11425cbac77SMasahiro Yamada
tegra_xusb_padctl_get_group_name(struct pinctrl_dev * pinctrl,unsigned int group)11525cbac77SMasahiro Yamada static const char *tegra_xusb_padctl_get_group_name(struct pinctrl_dev *pinctrl,
11625cbac77SMasahiro Yamada unsigned int group)
11725cbac77SMasahiro Yamada {
11825cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
11925cbac77SMasahiro Yamada
12025cbac77SMasahiro Yamada return padctl->soc->pins[group].name;
12125cbac77SMasahiro Yamada }
12225cbac77SMasahiro Yamada
tegra_xusb_padctl_get_group_pins(struct pinctrl_dev * pinctrl,unsigned group,const unsigned ** pins,unsigned * num_pins)12325cbac77SMasahiro Yamada static int tegra_xusb_padctl_get_group_pins(struct pinctrl_dev *pinctrl,
12425cbac77SMasahiro Yamada unsigned group,
12525cbac77SMasahiro Yamada const unsigned **pins,
12625cbac77SMasahiro Yamada unsigned *num_pins)
12725cbac77SMasahiro Yamada {
12825cbac77SMasahiro Yamada /*
129d71ffeb9SDejin Zheng * For the tegra-xusb pad controller groups are synonymous
13025cbac77SMasahiro Yamada * with lanes/pins and there is always one lane/pin per group.
13125cbac77SMasahiro Yamada */
13225cbac77SMasahiro Yamada *pins = &pinctrl->desc->pins[group].number;
13325cbac77SMasahiro Yamada *num_pins = 1;
13425cbac77SMasahiro Yamada
13525cbac77SMasahiro Yamada return 0;
13625cbac77SMasahiro Yamada }
13725cbac77SMasahiro Yamada
13825cbac77SMasahiro Yamada enum tegra_xusb_padctl_param {
13925cbac77SMasahiro Yamada TEGRA_XUSB_PADCTL_IDDQ,
14025cbac77SMasahiro Yamada };
14125cbac77SMasahiro Yamada
14225cbac77SMasahiro Yamada static const struct tegra_xusb_padctl_property {
14325cbac77SMasahiro Yamada const char *name;
14425cbac77SMasahiro Yamada enum tegra_xusb_padctl_param param;
14525cbac77SMasahiro Yamada } properties[] = {
14625cbac77SMasahiro Yamada { "nvidia,iddq", TEGRA_XUSB_PADCTL_IDDQ },
14725cbac77SMasahiro Yamada };
14825cbac77SMasahiro Yamada
14925cbac77SMasahiro Yamada #define TEGRA_XUSB_PADCTL_PACK(param, value) ((param) << 16 | (value))
15025cbac77SMasahiro Yamada #define TEGRA_XUSB_PADCTL_UNPACK_PARAM(config) ((config) >> 16)
15125cbac77SMasahiro Yamada #define TEGRA_XUSB_PADCTL_UNPACK_VALUE(config) ((config) & 0xffff)
15225cbac77SMasahiro Yamada
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)15325cbac77SMasahiro Yamada static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl,
15425cbac77SMasahiro Yamada struct device_node *np,
15525cbac77SMasahiro Yamada struct pinctrl_map **maps,
15625cbac77SMasahiro Yamada unsigned int *reserved_maps,
15725cbac77SMasahiro Yamada unsigned int *num_maps)
15825cbac77SMasahiro Yamada {
15925cbac77SMasahiro Yamada unsigned int i, reserve = 0, num_configs = 0;
16025cbac77SMasahiro Yamada unsigned long config, *configs = NULL;
16125cbac77SMasahiro Yamada const char *function, *group;
16225cbac77SMasahiro Yamada struct property *prop;
16325cbac77SMasahiro Yamada int err = 0;
16425cbac77SMasahiro Yamada u32 value;
16525cbac77SMasahiro Yamada
16625cbac77SMasahiro Yamada err = of_property_read_string(np, "nvidia,function", &function);
16725cbac77SMasahiro Yamada if (err < 0) {
16825cbac77SMasahiro Yamada if (err != -EINVAL)
16925cbac77SMasahiro Yamada return err;
17025cbac77SMasahiro Yamada
17125cbac77SMasahiro Yamada function = NULL;
17225cbac77SMasahiro Yamada }
17325cbac77SMasahiro Yamada
17425cbac77SMasahiro Yamada for (i = 0; i < ARRAY_SIZE(properties); i++) {
17525cbac77SMasahiro Yamada err = of_property_read_u32(np, properties[i].name, &value);
17625cbac77SMasahiro Yamada if (err < 0) {
17725cbac77SMasahiro Yamada if (err == -EINVAL)
17825cbac77SMasahiro Yamada continue;
17925cbac77SMasahiro Yamada
18025cbac77SMasahiro Yamada goto out;
18125cbac77SMasahiro Yamada }
18225cbac77SMasahiro Yamada
18325cbac77SMasahiro Yamada config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value);
18425cbac77SMasahiro Yamada
18525cbac77SMasahiro Yamada err = pinctrl_utils_add_config(padctl->pinctrl, &configs,
18625cbac77SMasahiro Yamada &num_configs, config);
18725cbac77SMasahiro Yamada if (err < 0)
18825cbac77SMasahiro Yamada goto out;
18925cbac77SMasahiro Yamada }
19025cbac77SMasahiro Yamada
19125cbac77SMasahiro Yamada if (function)
19225cbac77SMasahiro Yamada reserve++;
19325cbac77SMasahiro Yamada
19425cbac77SMasahiro Yamada if (num_configs)
19525cbac77SMasahiro Yamada reserve++;
19625cbac77SMasahiro Yamada
19725cbac77SMasahiro Yamada err = of_property_count_strings(np, "nvidia,lanes");
19825cbac77SMasahiro Yamada if (err < 0)
19925cbac77SMasahiro Yamada goto out;
20025cbac77SMasahiro Yamada
20125cbac77SMasahiro Yamada reserve *= err;
20225cbac77SMasahiro Yamada
20325cbac77SMasahiro Yamada err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps,
20425cbac77SMasahiro Yamada num_maps, reserve);
20525cbac77SMasahiro Yamada if (err < 0)
20625cbac77SMasahiro Yamada goto out;
20725cbac77SMasahiro Yamada
20825cbac77SMasahiro Yamada of_property_for_each_string(np, "nvidia,lanes", prop, group) {
20925cbac77SMasahiro Yamada if (function) {
21025cbac77SMasahiro Yamada err = pinctrl_utils_add_map_mux(padctl->pinctrl, maps,
21125cbac77SMasahiro Yamada reserved_maps, num_maps, group,
21225cbac77SMasahiro Yamada function);
21325cbac77SMasahiro Yamada if (err < 0)
21425cbac77SMasahiro Yamada goto out;
21525cbac77SMasahiro Yamada }
21625cbac77SMasahiro Yamada
21725cbac77SMasahiro Yamada if (num_configs) {
21825cbac77SMasahiro Yamada err = pinctrl_utils_add_map_configs(padctl->pinctrl,
21925cbac77SMasahiro Yamada maps, reserved_maps, num_maps, group,
22025cbac77SMasahiro Yamada configs, num_configs,
22125cbac77SMasahiro Yamada PIN_MAP_TYPE_CONFIGS_GROUP);
22225cbac77SMasahiro Yamada if (err < 0)
22325cbac77SMasahiro Yamada goto out;
22425cbac77SMasahiro Yamada }
22525cbac77SMasahiro Yamada }
22625cbac77SMasahiro Yamada
22725cbac77SMasahiro Yamada err = 0;
22825cbac77SMasahiro Yamada
22925cbac77SMasahiro Yamada out:
23025cbac77SMasahiro Yamada kfree(configs);
23125cbac77SMasahiro Yamada return err;
23225cbac77SMasahiro Yamada }
23325cbac77SMasahiro Yamada
tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev * pinctrl,struct device_node * parent,struct pinctrl_map ** maps,unsigned int * num_maps)23425cbac77SMasahiro Yamada static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl,
23525cbac77SMasahiro Yamada struct device_node *parent,
23625cbac77SMasahiro Yamada struct pinctrl_map **maps,
23725cbac77SMasahiro Yamada unsigned int *num_maps)
23825cbac77SMasahiro Yamada {
23925cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
24025cbac77SMasahiro Yamada unsigned int reserved_maps = 0;
24125cbac77SMasahiro Yamada struct device_node *np;
24225cbac77SMasahiro Yamada int err;
24325cbac77SMasahiro Yamada
24425cbac77SMasahiro Yamada *num_maps = 0;
24525cbac77SMasahiro Yamada *maps = NULL;
24625cbac77SMasahiro Yamada
24725cbac77SMasahiro Yamada for_each_child_of_node(parent, np) {
24825cbac77SMasahiro Yamada err = tegra_xusb_padctl_parse_subnode(padctl, np, maps,
24925cbac77SMasahiro Yamada &reserved_maps,
25025cbac77SMasahiro Yamada num_maps);
25125cbac77SMasahiro Yamada if (err < 0) {
25225cbac77SMasahiro Yamada of_node_put(np);
25325cbac77SMasahiro Yamada return err;
25425cbac77SMasahiro Yamada }
25525cbac77SMasahiro Yamada }
25625cbac77SMasahiro Yamada
25725cbac77SMasahiro Yamada return 0;
25825cbac77SMasahiro Yamada }
25925cbac77SMasahiro Yamada
26025cbac77SMasahiro Yamada static const struct pinctrl_ops tegra_xusb_padctl_pinctrl_ops = {
26125cbac77SMasahiro Yamada .get_groups_count = tegra_xusb_padctl_get_groups_count,
26225cbac77SMasahiro Yamada .get_group_name = tegra_xusb_padctl_get_group_name,
26325cbac77SMasahiro Yamada .get_group_pins = tegra_xusb_padctl_get_group_pins,
26425cbac77SMasahiro Yamada .dt_node_to_map = tegra_xusb_padctl_dt_node_to_map,
265d32f7fd3SIrina Tirdea .dt_free_map = pinctrl_utils_free_map,
26625cbac77SMasahiro Yamada };
26725cbac77SMasahiro Yamada
tegra_xusb_padctl_get_functions_count(struct pinctrl_dev * pinctrl)26825cbac77SMasahiro Yamada static int tegra_xusb_padctl_get_functions_count(struct pinctrl_dev *pinctrl)
26925cbac77SMasahiro Yamada {
27025cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
27125cbac77SMasahiro Yamada
27225cbac77SMasahiro Yamada return padctl->soc->num_functions;
27325cbac77SMasahiro Yamada }
27425cbac77SMasahiro Yamada
27525cbac77SMasahiro Yamada static const char *
tegra_xusb_padctl_get_function_name(struct pinctrl_dev * pinctrl,unsigned int function)27625cbac77SMasahiro Yamada tegra_xusb_padctl_get_function_name(struct pinctrl_dev *pinctrl,
27725cbac77SMasahiro Yamada unsigned int function)
27825cbac77SMasahiro Yamada {
27925cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
28025cbac77SMasahiro Yamada
28125cbac77SMasahiro Yamada return padctl->soc->functions[function].name;
28225cbac77SMasahiro Yamada }
28325cbac77SMasahiro Yamada
tegra_xusb_padctl_get_function_groups(struct pinctrl_dev * pinctrl,unsigned int function,const char * const ** groups,unsigned * const num_groups)28425cbac77SMasahiro Yamada static int tegra_xusb_padctl_get_function_groups(struct pinctrl_dev *pinctrl,
28525cbac77SMasahiro Yamada unsigned int function,
28625cbac77SMasahiro Yamada const char * const **groups,
28725cbac77SMasahiro Yamada unsigned * const num_groups)
28825cbac77SMasahiro Yamada {
28925cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
29025cbac77SMasahiro Yamada
29125cbac77SMasahiro Yamada *num_groups = padctl->soc->functions[function].num_groups;
29225cbac77SMasahiro Yamada *groups = padctl->soc->functions[function].groups;
29325cbac77SMasahiro Yamada
29425cbac77SMasahiro Yamada return 0;
29525cbac77SMasahiro Yamada }
29625cbac77SMasahiro Yamada
tegra_xusb_padctl_pinmux_set(struct pinctrl_dev * pinctrl,unsigned int function,unsigned int group)29725cbac77SMasahiro Yamada static int tegra_xusb_padctl_pinmux_set(struct pinctrl_dev *pinctrl,
29825cbac77SMasahiro Yamada unsigned int function,
29925cbac77SMasahiro Yamada unsigned int group)
30025cbac77SMasahiro Yamada {
30125cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
30225cbac77SMasahiro Yamada const struct tegra_xusb_padctl_lane *lane;
30325cbac77SMasahiro Yamada unsigned int i;
30425cbac77SMasahiro Yamada u32 value;
30525cbac77SMasahiro Yamada
30625cbac77SMasahiro Yamada lane = &padctl->soc->lanes[group];
30725cbac77SMasahiro Yamada
30825cbac77SMasahiro Yamada for (i = 0; i < lane->num_funcs; i++)
30925cbac77SMasahiro Yamada if (lane->funcs[i] == function)
31025cbac77SMasahiro Yamada break;
31125cbac77SMasahiro Yamada
31225cbac77SMasahiro Yamada if (i >= lane->num_funcs)
31325cbac77SMasahiro Yamada return -EINVAL;
31425cbac77SMasahiro Yamada
31525cbac77SMasahiro Yamada value = padctl_readl(padctl, lane->offset);
31625cbac77SMasahiro Yamada value &= ~(lane->mask << lane->shift);
31725cbac77SMasahiro Yamada value |= i << lane->shift;
31825cbac77SMasahiro Yamada padctl_writel(padctl, value, lane->offset);
31925cbac77SMasahiro Yamada
32025cbac77SMasahiro Yamada return 0;
32125cbac77SMasahiro Yamada }
32225cbac77SMasahiro Yamada
32325cbac77SMasahiro Yamada static const struct pinmux_ops tegra_xusb_padctl_pinmux_ops = {
32425cbac77SMasahiro Yamada .get_functions_count = tegra_xusb_padctl_get_functions_count,
32525cbac77SMasahiro Yamada .get_function_name = tegra_xusb_padctl_get_function_name,
32625cbac77SMasahiro Yamada .get_function_groups = tegra_xusb_padctl_get_function_groups,
32725cbac77SMasahiro Yamada .set_mux = tegra_xusb_padctl_pinmux_set,
32825cbac77SMasahiro Yamada };
32925cbac77SMasahiro Yamada
tegra_xusb_padctl_pinconf_group_get(struct pinctrl_dev * pinctrl,unsigned int group,unsigned long * config)33025cbac77SMasahiro Yamada static int tegra_xusb_padctl_pinconf_group_get(struct pinctrl_dev *pinctrl,
33125cbac77SMasahiro Yamada unsigned int group,
33225cbac77SMasahiro Yamada unsigned long *config)
33325cbac77SMasahiro Yamada {
33425cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
33525cbac77SMasahiro Yamada const struct tegra_xusb_padctl_lane *lane;
33625cbac77SMasahiro Yamada enum tegra_xusb_padctl_param param;
33725cbac77SMasahiro Yamada u32 value;
33825cbac77SMasahiro Yamada
33925cbac77SMasahiro Yamada param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(*config);
34025cbac77SMasahiro Yamada lane = &padctl->soc->lanes[group];
34125cbac77SMasahiro Yamada
34225cbac77SMasahiro Yamada switch (param) {
34325cbac77SMasahiro Yamada case TEGRA_XUSB_PADCTL_IDDQ:
34425cbac77SMasahiro Yamada /* lanes with iddq == 0 don't support this parameter */
34525cbac77SMasahiro Yamada if (lane->iddq == 0)
34625cbac77SMasahiro Yamada return -EINVAL;
34725cbac77SMasahiro Yamada
34825cbac77SMasahiro Yamada value = padctl_readl(padctl, lane->offset);
34925cbac77SMasahiro Yamada
35025cbac77SMasahiro Yamada if (value & BIT(lane->iddq))
35125cbac77SMasahiro Yamada value = 0;
35225cbac77SMasahiro Yamada else
35325cbac77SMasahiro Yamada value = 1;
35425cbac77SMasahiro Yamada
35525cbac77SMasahiro Yamada *config = TEGRA_XUSB_PADCTL_PACK(param, value);
35625cbac77SMasahiro Yamada break;
35725cbac77SMasahiro Yamada
35825cbac77SMasahiro Yamada default:
35925cbac77SMasahiro Yamada dev_err(padctl->dev, "invalid configuration parameter: %04x\n",
36025cbac77SMasahiro Yamada param);
36125cbac77SMasahiro Yamada return -ENOTSUPP;
36225cbac77SMasahiro Yamada }
36325cbac77SMasahiro Yamada
36425cbac77SMasahiro Yamada return 0;
36525cbac77SMasahiro Yamada }
36625cbac77SMasahiro Yamada
tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev * pinctrl,unsigned int group,unsigned long * configs,unsigned int num_configs)36725cbac77SMasahiro Yamada static int tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev *pinctrl,
36825cbac77SMasahiro Yamada unsigned int group,
36925cbac77SMasahiro Yamada unsigned long *configs,
37025cbac77SMasahiro Yamada unsigned int num_configs)
37125cbac77SMasahiro Yamada {
37225cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
37325cbac77SMasahiro Yamada const struct tegra_xusb_padctl_lane *lane;
37425cbac77SMasahiro Yamada enum tegra_xusb_padctl_param param;
37525cbac77SMasahiro Yamada unsigned long value;
37625cbac77SMasahiro Yamada unsigned int i;
37725cbac77SMasahiro Yamada u32 regval;
37825cbac77SMasahiro Yamada
37925cbac77SMasahiro Yamada lane = &padctl->soc->lanes[group];
38025cbac77SMasahiro Yamada
38125cbac77SMasahiro Yamada for (i = 0; i < num_configs; i++) {
38225cbac77SMasahiro Yamada param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(configs[i]);
38325cbac77SMasahiro Yamada value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(configs[i]);
38425cbac77SMasahiro Yamada
38525cbac77SMasahiro Yamada switch (param) {
38625cbac77SMasahiro Yamada case TEGRA_XUSB_PADCTL_IDDQ:
38725cbac77SMasahiro Yamada /* lanes with iddq == 0 don't support this parameter */
38825cbac77SMasahiro Yamada if (lane->iddq == 0)
38925cbac77SMasahiro Yamada return -EINVAL;
39025cbac77SMasahiro Yamada
39125cbac77SMasahiro Yamada regval = padctl_readl(padctl, lane->offset);
39225cbac77SMasahiro Yamada
39325cbac77SMasahiro Yamada if (value)
39425cbac77SMasahiro Yamada regval &= ~BIT(lane->iddq);
39525cbac77SMasahiro Yamada else
39625cbac77SMasahiro Yamada regval |= BIT(lane->iddq);
39725cbac77SMasahiro Yamada
39825cbac77SMasahiro Yamada padctl_writel(padctl, regval, lane->offset);
39925cbac77SMasahiro Yamada break;
40025cbac77SMasahiro Yamada
40125cbac77SMasahiro Yamada default:
40225cbac77SMasahiro Yamada dev_err(padctl->dev,
40325cbac77SMasahiro Yamada "invalid configuration parameter: %04x\n",
40425cbac77SMasahiro Yamada param);
40525cbac77SMasahiro Yamada return -ENOTSUPP;
40625cbac77SMasahiro Yamada }
40725cbac77SMasahiro Yamada }
40825cbac77SMasahiro Yamada
40925cbac77SMasahiro Yamada return 0;
41025cbac77SMasahiro Yamada }
41125cbac77SMasahiro Yamada
41225cbac77SMasahiro Yamada #ifdef CONFIG_DEBUG_FS
strip_prefix(const char * s)41325cbac77SMasahiro Yamada static const char *strip_prefix(const char *s)
41425cbac77SMasahiro Yamada {
41525cbac77SMasahiro Yamada const char *comma = strchr(s, ',');
41625cbac77SMasahiro Yamada if (!comma)
41725cbac77SMasahiro Yamada return s;
41825cbac77SMasahiro Yamada
41925cbac77SMasahiro Yamada return comma + 1;
42025cbac77SMasahiro Yamada }
42125cbac77SMasahiro Yamada
42225cbac77SMasahiro Yamada static void
tegra_xusb_padctl_pinconf_group_dbg_show(struct pinctrl_dev * pinctrl,struct seq_file * s,unsigned int group)42325cbac77SMasahiro Yamada tegra_xusb_padctl_pinconf_group_dbg_show(struct pinctrl_dev *pinctrl,
42425cbac77SMasahiro Yamada struct seq_file *s,
42525cbac77SMasahiro Yamada unsigned int group)
42625cbac77SMasahiro Yamada {
42725cbac77SMasahiro Yamada unsigned int i;
42825cbac77SMasahiro Yamada
42925cbac77SMasahiro Yamada for (i = 0; i < ARRAY_SIZE(properties); i++) {
43025cbac77SMasahiro Yamada unsigned long config, value;
43125cbac77SMasahiro Yamada int err;
43225cbac77SMasahiro Yamada
43325cbac77SMasahiro Yamada config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, 0);
43425cbac77SMasahiro Yamada
43525cbac77SMasahiro Yamada err = tegra_xusb_padctl_pinconf_group_get(pinctrl, group,
43625cbac77SMasahiro Yamada &config);
43725cbac77SMasahiro Yamada if (err < 0)
43825cbac77SMasahiro Yamada continue;
43925cbac77SMasahiro Yamada
44025cbac77SMasahiro Yamada value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config);
44125cbac77SMasahiro Yamada
44225cbac77SMasahiro Yamada seq_printf(s, "\n\t%s=%lu\n", strip_prefix(properties[i].name),
44325cbac77SMasahiro Yamada value);
44425cbac77SMasahiro Yamada }
44525cbac77SMasahiro Yamada }
44625cbac77SMasahiro Yamada
44725cbac77SMasahiro Yamada static void
tegra_xusb_padctl_pinconf_config_dbg_show(struct pinctrl_dev * pinctrl,struct seq_file * s,unsigned long config)44825cbac77SMasahiro Yamada tegra_xusb_padctl_pinconf_config_dbg_show(struct pinctrl_dev *pinctrl,
44925cbac77SMasahiro Yamada struct seq_file *s,
45025cbac77SMasahiro Yamada unsigned long config)
45125cbac77SMasahiro Yamada {
45225cbac77SMasahiro Yamada enum tegra_xusb_padctl_param param;
45325cbac77SMasahiro Yamada const char *name = "unknown";
45425cbac77SMasahiro Yamada unsigned long value;
45525cbac77SMasahiro Yamada unsigned int i;
45625cbac77SMasahiro Yamada
45725cbac77SMasahiro Yamada param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(config);
45825cbac77SMasahiro Yamada value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config);
45925cbac77SMasahiro Yamada
46025cbac77SMasahiro Yamada for (i = 0; i < ARRAY_SIZE(properties); i++) {
46125cbac77SMasahiro Yamada if (properties[i].param == param) {
46225cbac77SMasahiro Yamada name = properties[i].name;
46325cbac77SMasahiro Yamada break;
46425cbac77SMasahiro Yamada }
46525cbac77SMasahiro Yamada }
46625cbac77SMasahiro Yamada
46725cbac77SMasahiro Yamada seq_printf(s, "%s=%lu", strip_prefix(name), value);
46825cbac77SMasahiro Yamada }
46925cbac77SMasahiro Yamada #endif
47025cbac77SMasahiro Yamada
47125cbac77SMasahiro Yamada static const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = {
47225cbac77SMasahiro Yamada .pin_config_group_get = tegra_xusb_padctl_pinconf_group_get,
47325cbac77SMasahiro Yamada .pin_config_group_set = tegra_xusb_padctl_pinconf_group_set,
47425cbac77SMasahiro Yamada #ifdef CONFIG_DEBUG_FS
47525cbac77SMasahiro Yamada .pin_config_group_dbg_show = tegra_xusb_padctl_pinconf_group_dbg_show,
47625cbac77SMasahiro Yamada .pin_config_config_dbg_show = tegra_xusb_padctl_pinconf_config_dbg_show,
47725cbac77SMasahiro Yamada #endif
47825cbac77SMasahiro Yamada };
47925cbac77SMasahiro Yamada
tegra_xusb_padctl_enable(struct tegra_xusb_padctl * padctl)48025cbac77SMasahiro Yamada static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
48125cbac77SMasahiro Yamada {
48225cbac77SMasahiro Yamada u32 value;
48325cbac77SMasahiro Yamada
48425cbac77SMasahiro Yamada mutex_lock(&padctl->lock);
48525cbac77SMasahiro Yamada
48625cbac77SMasahiro Yamada if (padctl->enable++ > 0)
48725cbac77SMasahiro Yamada goto out;
48825cbac77SMasahiro Yamada
48925cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
49025cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
49125cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
49225cbac77SMasahiro Yamada
49325cbac77SMasahiro Yamada usleep_range(100, 200);
49425cbac77SMasahiro Yamada
49525cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
49625cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
49725cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
49825cbac77SMasahiro Yamada
49925cbac77SMasahiro Yamada usleep_range(100, 200);
50025cbac77SMasahiro Yamada
50125cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
50225cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
50325cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
50425cbac77SMasahiro Yamada
50525cbac77SMasahiro Yamada out:
50625cbac77SMasahiro Yamada mutex_unlock(&padctl->lock);
50725cbac77SMasahiro Yamada return 0;
50825cbac77SMasahiro Yamada }
50925cbac77SMasahiro Yamada
tegra_xusb_padctl_disable(struct tegra_xusb_padctl * padctl)51025cbac77SMasahiro Yamada static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
51125cbac77SMasahiro Yamada {
51225cbac77SMasahiro Yamada u32 value;
51325cbac77SMasahiro Yamada
51425cbac77SMasahiro Yamada mutex_lock(&padctl->lock);
51525cbac77SMasahiro Yamada
51625cbac77SMasahiro Yamada if (WARN_ON(padctl->enable == 0))
51725cbac77SMasahiro Yamada goto out;
51825cbac77SMasahiro Yamada
51925cbac77SMasahiro Yamada if (--padctl->enable > 0)
52025cbac77SMasahiro Yamada goto out;
52125cbac77SMasahiro Yamada
52225cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
52325cbac77SMasahiro Yamada value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
52425cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
52525cbac77SMasahiro Yamada
52625cbac77SMasahiro Yamada usleep_range(100, 200);
52725cbac77SMasahiro Yamada
52825cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
52925cbac77SMasahiro Yamada value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
53025cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
53125cbac77SMasahiro Yamada
53225cbac77SMasahiro Yamada usleep_range(100, 200);
53325cbac77SMasahiro Yamada
53425cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
53525cbac77SMasahiro Yamada value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
53625cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
53725cbac77SMasahiro Yamada
53825cbac77SMasahiro Yamada out:
53925cbac77SMasahiro Yamada mutex_unlock(&padctl->lock);
54025cbac77SMasahiro Yamada return 0;
54125cbac77SMasahiro Yamada }
54225cbac77SMasahiro Yamada
tegra_xusb_phy_init(struct phy * phy)54325cbac77SMasahiro Yamada static int tegra_xusb_phy_init(struct phy *phy)
54425cbac77SMasahiro Yamada {
54525cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
54625cbac77SMasahiro Yamada
54725cbac77SMasahiro Yamada return tegra_xusb_padctl_enable(padctl);
54825cbac77SMasahiro Yamada }
54925cbac77SMasahiro Yamada
tegra_xusb_phy_exit(struct phy * phy)55025cbac77SMasahiro Yamada static int tegra_xusb_phy_exit(struct phy *phy)
55125cbac77SMasahiro Yamada {
55225cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
55325cbac77SMasahiro Yamada
55425cbac77SMasahiro Yamada return tegra_xusb_padctl_disable(padctl);
55525cbac77SMasahiro Yamada }
55625cbac77SMasahiro Yamada
pcie_phy_power_on(struct phy * phy)55725cbac77SMasahiro Yamada static int pcie_phy_power_on(struct phy *phy)
55825cbac77SMasahiro Yamada {
55925cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
56025cbac77SMasahiro Yamada unsigned long timeout;
56125cbac77SMasahiro Yamada int err = -ETIMEDOUT;
56225cbac77SMasahiro Yamada u32 value;
56325cbac77SMasahiro Yamada
56425cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
56525cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK;
56625cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
56725cbac77SMasahiro Yamada
56825cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
56925cbac77SMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN |
57025cbac77SMasahiro Yamada XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN |
57125cbac77SMasahiro Yamada XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL;
57225cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
57325cbac77SMasahiro Yamada
57425cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
57525cbac77SMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
57625cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
57725cbac77SMasahiro Yamada
57825cbac77SMasahiro Yamada timeout = jiffies + msecs_to_jiffies(50);
57925cbac77SMasahiro Yamada
58025cbac77SMasahiro Yamada while (time_before(jiffies, timeout)) {
58125cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
58225cbac77SMasahiro Yamada if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) {
58325cbac77SMasahiro Yamada err = 0;
58425cbac77SMasahiro Yamada break;
58525cbac77SMasahiro Yamada }
58625cbac77SMasahiro Yamada
58725cbac77SMasahiro Yamada usleep_range(100, 200);
58825cbac77SMasahiro Yamada }
58925cbac77SMasahiro Yamada
59025cbac77SMasahiro Yamada return err;
59125cbac77SMasahiro Yamada }
59225cbac77SMasahiro Yamada
pcie_phy_power_off(struct phy * phy)59325cbac77SMasahiro Yamada static int pcie_phy_power_off(struct phy *phy)
59425cbac77SMasahiro Yamada {
59525cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
59625cbac77SMasahiro Yamada u32 value;
59725cbac77SMasahiro Yamada
59825cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
59925cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
60025cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
60125cbac77SMasahiro Yamada
60225cbac77SMasahiro Yamada return 0;
60325cbac77SMasahiro Yamada }
60425cbac77SMasahiro Yamada
60525cbac77SMasahiro Yamada static const struct phy_ops pcie_phy_ops = {
60625cbac77SMasahiro Yamada .init = tegra_xusb_phy_init,
60725cbac77SMasahiro Yamada .exit = tegra_xusb_phy_exit,
60825cbac77SMasahiro Yamada .power_on = pcie_phy_power_on,
60925cbac77SMasahiro Yamada .power_off = pcie_phy_power_off,
61025cbac77SMasahiro Yamada .owner = THIS_MODULE,
61125cbac77SMasahiro Yamada };
61225cbac77SMasahiro Yamada
sata_phy_power_on(struct phy * phy)61325cbac77SMasahiro Yamada static int sata_phy_power_on(struct phy *phy)
61425cbac77SMasahiro Yamada {
61525cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
61625cbac77SMasahiro Yamada unsigned long timeout;
61725cbac77SMasahiro Yamada int err = -ETIMEDOUT;
61825cbac77SMasahiro Yamada u32 value;
61925cbac77SMasahiro Yamada
62025cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
62125cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
62225cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
62325cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
62425cbac77SMasahiro Yamada
62525cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
62625cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
62725cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
62825cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
62925cbac77SMasahiro Yamada
63025cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
63125cbac77SMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
63225cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
63325cbac77SMasahiro Yamada
63425cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
63525cbac77SMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
63625cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
63725cbac77SMasahiro Yamada
63825cbac77SMasahiro Yamada timeout = jiffies + msecs_to_jiffies(50);
63925cbac77SMasahiro Yamada
64025cbac77SMasahiro Yamada while (time_before(jiffies, timeout)) {
64125cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
64225cbac77SMasahiro Yamada if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) {
64325cbac77SMasahiro Yamada err = 0;
64425cbac77SMasahiro Yamada break;
64525cbac77SMasahiro Yamada }
64625cbac77SMasahiro Yamada
64725cbac77SMasahiro Yamada usleep_range(100, 200);
64825cbac77SMasahiro Yamada }
64925cbac77SMasahiro Yamada
65025cbac77SMasahiro Yamada return err;
65125cbac77SMasahiro Yamada }
65225cbac77SMasahiro Yamada
sata_phy_power_off(struct phy * phy)65325cbac77SMasahiro Yamada static int sata_phy_power_off(struct phy *phy)
65425cbac77SMasahiro Yamada {
65525cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
65625cbac77SMasahiro Yamada u32 value;
65725cbac77SMasahiro Yamada
65825cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
65925cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
66025cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
66125cbac77SMasahiro Yamada
66225cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
66325cbac77SMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
66425cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
66525cbac77SMasahiro Yamada
66625cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
66725cbac77SMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
66825cbac77SMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
66925cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
67025cbac77SMasahiro Yamada
67125cbac77SMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
67225cbac77SMasahiro Yamada value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
67325cbac77SMasahiro Yamada value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
67425cbac77SMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
67525cbac77SMasahiro Yamada
67625cbac77SMasahiro Yamada return 0;
67725cbac77SMasahiro Yamada }
67825cbac77SMasahiro Yamada
67925cbac77SMasahiro Yamada static const struct phy_ops sata_phy_ops = {
68025cbac77SMasahiro Yamada .init = tegra_xusb_phy_init,
68125cbac77SMasahiro Yamada .exit = tegra_xusb_phy_exit,
68225cbac77SMasahiro Yamada .power_on = sata_phy_power_on,
68325cbac77SMasahiro Yamada .power_off = sata_phy_power_off,
68425cbac77SMasahiro Yamada .owner = THIS_MODULE,
68525cbac77SMasahiro Yamada };
68625cbac77SMasahiro Yamada
tegra_xusb_padctl_xlate(struct device * dev,struct of_phandle_args * args)68725cbac77SMasahiro Yamada static struct phy *tegra_xusb_padctl_xlate(struct device *dev,
68825cbac77SMasahiro Yamada struct of_phandle_args *args)
68925cbac77SMasahiro Yamada {
69025cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev);
69125cbac77SMasahiro Yamada unsigned int index = args->args[0];
69225cbac77SMasahiro Yamada
69325cbac77SMasahiro Yamada if (args->args_count <= 0)
69425cbac77SMasahiro Yamada return ERR_PTR(-EINVAL);
69525cbac77SMasahiro Yamada
69625cbac77SMasahiro Yamada if (index >= ARRAY_SIZE(padctl->phys))
69725cbac77SMasahiro Yamada return ERR_PTR(-EINVAL);
69825cbac77SMasahiro Yamada
69925cbac77SMasahiro Yamada return padctl->phys[index];
70025cbac77SMasahiro Yamada }
70125cbac77SMasahiro Yamada
70225cbac77SMasahiro Yamada #define PIN_OTG_0 0
70325cbac77SMasahiro Yamada #define PIN_OTG_1 1
70425cbac77SMasahiro Yamada #define PIN_OTG_2 2
70525cbac77SMasahiro Yamada #define PIN_ULPI_0 3
70625cbac77SMasahiro Yamada #define PIN_HSIC_0 4
70725cbac77SMasahiro Yamada #define PIN_HSIC_1 5
70825cbac77SMasahiro Yamada #define PIN_PCIE_0 6
70925cbac77SMasahiro Yamada #define PIN_PCIE_1 7
71025cbac77SMasahiro Yamada #define PIN_PCIE_2 8
71125cbac77SMasahiro Yamada #define PIN_PCIE_3 9
71225cbac77SMasahiro Yamada #define PIN_PCIE_4 10
71325cbac77SMasahiro Yamada #define PIN_SATA_0 11
71425cbac77SMasahiro Yamada
71525cbac77SMasahiro Yamada static const struct pinctrl_pin_desc tegra124_pins[] = {
71625cbac77SMasahiro Yamada PINCTRL_PIN(PIN_OTG_0, "otg-0"),
71725cbac77SMasahiro Yamada PINCTRL_PIN(PIN_OTG_1, "otg-1"),
71825cbac77SMasahiro Yamada PINCTRL_PIN(PIN_OTG_2, "otg-2"),
71925cbac77SMasahiro Yamada PINCTRL_PIN(PIN_ULPI_0, "ulpi-0"),
72025cbac77SMasahiro Yamada PINCTRL_PIN(PIN_HSIC_0, "hsic-0"),
72125cbac77SMasahiro Yamada PINCTRL_PIN(PIN_HSIC_1, "hsic-1"),
72225cbac77SMasahiro Yamada PINCTRL_PIN(PIN_PCIE_0, "pcie-0"),
72325cbac77SMasahiro Yamada PINCTRL_PIN(PIN_PCIE_1, "pcie-1"),
72425cbac77SMasahiro Yamada PINCTRL_PIN(PIN_PCIE_2, "pcie-2"),
72525cbac77SMasahiro Yamada PINCTRL_PIN(PIN_PCIE_3, "pcie-3"),
72625cbac77SMasahiro Yamada PINCTRL_PIN(PIN_PCIE_4, "pcie-4"),
72725cbac77SMasahiro Yamada PINCTRL_PIN(PIN_SATA_0, "sata-0"),
72825cbac77SMasahiro Yamada };
72925cbac77SMasahiro Yamada
73025cbac77SMasahiro Yamada static const char * const tegra124_snps_groups[] = {
73125cbac77SMasahiro Yamada "otg-0",
73225cbac77SMasahiro Yamada "otg-1",
73325cbac77SMasahiro Yamada "otg-2",
73425cbac77SMasahiro Yamada "ulpi-0",
73525cbac77SMasahiro Yamada "hsic-0",
73625cbac77SMasahiro Yamada "hsic-1",
73725cbac77SMasahiro Yamada };
73825cbac77SMasahiro Yamada
73925cbac77SMasahiro Yamada static const char * const tegra124_xusb_groups[] = {
74025cbac77SMasahiro Yamada "otg-0",
74125cbac77SMasahiro Yamada "otg-1",
74225cbac77SMasahiro Yamada "otg-2",
74325cbac77SMasahiro Yamada "ulpi-0",
74425cbac77SMasahiro Yamada "hsic-0",
74525cbac77SMasahiro Yamada "hsic-1",
74625cbac77SMasahiro Yamada };
74725cbac77SMasahiro Yamada
74825cbac77SMasahiro Yamada static const char * const tegra124_uart_groups[] = {
74925cbac77SMasahiro Yamada "otg-0",
75025cbac77SMasahiro Yamada "otg-1",
75125cbac77SMasahiro Yamada "otg-2",
75225cbac77SMasahiro Yamada };
75325cbac77SMasahiro Yamada
75425cbac77SMasahiro Yamada static const char * const tegra124_pcie_groups[] = {
75525cbac77SMasahiro Yamada "pcie-0",
75625cbac77SMasahiro Yamada "pcie-1",
75725cbac77SMasahiro Yamada "pcie-2",
75825cbac77SMasahiro Yamada "pcie-3",
75925cbac77SMasahiro Yamada "pcie-4",
76025cbac77SMasahiro Yamada };
76125cbac77SMasahiro Yamada
76225cbac77SMasahiro Yamada static const char * const tegra124_usb3_groups[] = {
76325cbac77SMasahiro Yamada "pcie-0",
76425cbac77SMasahiro Yamada "pcie-1",
76525cbac77SMasahiro Yamada "sata-0",
76625cbac77SMasahiro Yamada };
76725cbac77SMasahiro Yamada
76825cbac77SMasahiro Yamada static const char * const tegra124_sata_groups[] = {
76925cbac77SMasahiro Yamada "sata-0",
77025cbac77SMasahiro Yamada };
77125cbac77SMasahiro Yamada
77225cbac77SMasahiro Yamada static const char * const tegra124_rsvd_groups[] = {
77325cbac77SMasahiro Yamada "otg-0",
77425cbac77SMasahiro Yamada "otg-1",
77525cbac77SMasahiro Yamada "otg-2",
77625cbac77SMasahiro Yamada "pcie-0",
77725cbac77SMasahiro Yamada "pcie-1",
77825cbac77SMasahiro Yamada "pcie-2",
77925cbac77SMasahiro Yamada "pcie-3",
78025cbac77SMasahiro Yamada "pcie-4",
78125cbac77SMasahiro Yamada "sata-0",
78225cbac77SMasahiro Yamada };
78325cbac77SMasahiro Yamada
78425cbac77SMasahiro Yamada #define TEGRA124_FUNCTION(_name) \
78525cbac77SMasahiro Yamada { \
78625cbac77SMasahiro Yamada .name = #_name, \
78725cbac77SMasahiro Yamada .num_groups = ARRAY_SIZE(tegra124_##_name##_groups), \
78825cbac77SMasahiro Yamada .groups = tegra124_##_name##_groups, \
78925cbac77SMasahiro Yamada }
79025cbac77SMasahiro Yamada
79125cbac77SMasahiro Yamada static struct tegra_xusb_padctl_function tegra124_functions[] = {
79225cbac77SMasahiro Yamada TEGRA124_FUNCTION(snps),
79325cbac77SMasahiro Yamada TEGRA124_FUNCTION(xusb),
79425cbac77SMasahiro Yamada TEGRA124_FUNCTION(uart),
79525cbac77SMasahiro Yamada TEGRA124_FUNCTION(pcie),
79625cbac77SMasahiro Yamada TEGRA124_FUNCTION(usb3),
79725cbac77SMasahiro Yamada TEGRA124_FUNCTION(sata),
79825cbac77SMasahiro Yamada TEGRA124_FUNCTION(rsvd),
79925cbac77SMasahiro Yamada };
80025cbac77SMasahiro Yamada
80125cbac77SMasahiro Yamada enum tegra124_function {
80225cbac77SMasahiro Yamada TEGRA124_FUNC_SNPS,
80325cbac77SMasahiro Yamada TEGRA124_FUNC_XUSB,
80425cbac77SMasahiro Yamada TEGRA124_FUNC_UART,
80525cbac77SMasahiro Yamada TEGRA124_FUNC_PCIE,
80625cbac77SMasahiro Yamada TEGRA124_FUNC_USB3,
80725cbac77SMasahiro Yamada TEGRA124_FUNC_SATA,
80825cbac77SMasahiro Yamada TEGRA124_FUNC_RSVD,
80925cbac77SMasahiro Yamada };
81025cbac77SMasahiro Yamada
81125cbac77SMasahiro Yamada static const unsigned int tegra124_otg_functions[] = {
81225cbac77SMasahiro Yamada TEGRA124_FUNC_SNPS,
81325cbac77SMasahiro Yamada TEGRA124_FUNC_XUSB,
81425cbac77SMasahiro Yamada TEGRA124_FUNC_UART,
81525cbac77SMasahiro Yamada TEGRA124_FUNC_RSVD,
81625cbac77SMasahiro Yamada };
81725cbac77SMasahiro Yamada
81825cbac77SMasahiro Yamada static const unsigned int tegra124_usb_functions[] = {
81925cbac77SMasahiro Yamada TEGRA124_FUNC_SNPS,
82025cbac77SMasahiro Yamada TEGRA124_FUNC_XUSB,
82125cbac77SMasahiro Yamada };
82225cbac77SMasahiro Yamada
82325cbac77SMasahiro Yamada static const unsigned int tegra124_pci_functions[] = {
82425cbac77SMasahiro Yamada TEGRA124_FUNC_PCIE,
82525cbac77SMasahiro Yamada TEGRA124_FUNC_USB3,
82625cbac77SMasahiro Yamada TEGRA124_FUNC_SATA,
82725cbac77SMasahiro Yamada TEGRA124_FUNC_RSVD,
82825cbac77SMasahiro Yamada };
82925cbac77SMasahiro Yamada
83025cbac77SMasahiro Yamada #define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \
83125cbac77SMasahiro Yamada { \
83225cbac77SMasahiro Yamada .name = _name, \
83325cbac77SMasahiro Yamada .offset = _offset, \
83425cbac77SMasahiro Yamada .shift = _shift, \
83525cbac77SMasahiro Yamada .mask = _mask, \
83625cbac77SMasahiro Yamada .iddq = _iddq, \
83725cbac77SMasahiro Yamada .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \
83825cbac77SMasahiro Yamada .funcs = tegra124_##_funcs##_functions, \
83925cbac77SMasahiro Yamada }
84025cbac77SMasahiro Yamada
84125cbac77SMasahiro Yamada static const struct tegra_xusb_padctl_lane tegra124_lanes[] = {
84225cbac77SMasahiro Yamada TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg),
84325cbac77SMasahiro Yamada TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg),
84425cbac77SMasahiro Yamada TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg),
84525cbac77SMasahiro Yamada TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb),
84625cbac77SMasahiro Yamada TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb),
84725cbac77SMasahiro Yamada TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb),
84825cbac77SMasahiro Yamada TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci),
84925cbac77SMasahiro Yamada TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci),
85025cbac77SMasahiro Yamada TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci),
85125cbac77SMasahiro Yamada TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci),
85225cbac77SMasahiro Yamada TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci),
85325cbac77SMasahiro Yamada TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci),
85425cbac77SMasahiro Yamada };
85525cbac77SMasahiro Yamada
85625cbac77SMasahiro Yamada static const struct tegra_xusb_padctl_soc tegra124_soc = {
85725cbac77SMasahiro Yamada .num_pins = ARRAY_SIZE(tegra124_pins),
85825cbac77SMasahiro Yamada .pins = tegra124_pins,
85925cbac77SMasahiro Yamada .num_functions = ARRAY_SIZE(tegra124_functions),
86025cbac77SMasahiro Yamada .functions = tegra124_functions,
86125cbac77SMasahiro Yamada .num_lanes = ARRAY_SIZE(tegra124_lanes),
86225cbac77SMasahiro Yamada .lanes = tegra124_lanes,
86325cbac77SMasahiro Yamada };
86425cbac77SMasahiro Yamada
86525cbac77SMasahiro Yamada static const struct of_device_id tegra_xusb_padctl_of_match[] = {
86625cbac77SMasahiro Yamada { .compatible = "nvidia,tegra124-xusb-padctl", .data = &tegra124_soc },
86725cbac77SMasahiro Yamada { }
86825cbac77SMasahiro Yamada };
86925cbac77SMasahiro Yamada MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match);
87025cbac77SMasahiro Yamada
87102101cb3SThierry Reding /* predeclare these in order to silence sparse */
87202101cb3SThierry Reding int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
87302101cb3SThierry Reding int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev);
87402101cb3SThierry Reding
tegra_xusb_padctl_legacy_probe(struct platform_device * pdev)87553d2a715SThierry Reding int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev)
87625cbac77SMasahiro Yamada {
87725cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl;
87825cbac77SMasahiro Yamada const struct of_device_id *match;
87925cbac77SMasahiro Yamada struct phy *phy;
88025cbac77SMasahiro Yamada int err;
88125cbac77SMasahiro Yamada
88225cbac77SMasahiro Yamada padctl = devm_kzalloc(&pdev->dev, sizeof(*padctl), GFP_KERNEL);
88325cbac77SMasahiro Yamada if (!padctl)
88425cbac77SMasahiro Yamada return -ENOMEM;
88525cbac77SMasahiro Yamada
88625cbac77SMasahiro Yamada platform_set_drvdata(pdev, padctl);
88725cbac77SMasahiro Yamada mutex_init(&padctl->lock);
88825cbac77SMasahiro Yamada padctl->dev = &pdev->dev;
88925cbac77SMasahiro Yamada
8909978339aSThierry Reding /*
8919978339aSThierry Reding * Note that we can't replace this by of_device_get_match_data()
8929978339aSThierry Reding * because we need the separate matching table for this legacy code on
8939978339aSThierry Reding * Tegra124. of_device_get_match_data() would attempt to use the table
8949978339aSThierry Reding * from the updated driver and fail.
8959978339aSThierry Reding */
89625cbac77SMasahiro Yamada match = of_match_node(tegra_xusb_padctl_of_match, pdev->dev.of_node);
89725cbac77SMasahiro Yamada padctl->soc = match->data;
89825cbac77SMasahiro Yamada
8994b024225SYueHaibing padctl->regs = devm_platform_ioremap_resource(pdev, 0);
90025cbac77SMasahiro Yamada if (IS_ERR(padctl->regs))
90125cbac77SMasahiro Yamada return PTR_ERR(padctl->regs);
90225cbac77SMasahiro Yamada
903725e2221SPhilipp Zabel padctl->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
90425cbac77SMasahiro Yamada if (IS_ERR(padctl->rst))
90525cbac77SMasahiro Yamada return PTR_ERR(padctl->rst);
90625cbac77SMasahiro Yamada
90725cbac77SMasahiro Yamada err = reset_control_deassert(padctl->rst);
90825cbac77SMasahiro Yamada if (err < 0)
90925cbac77SMasahiro Yamada return err;
91025cbac77SMasahiro Yamada
91125cbac77SMasahiro Yamada memset(&padctl->desc, 0, sizeof(padctl->desc));
91225cbac77SMasahiro Yamada padctl->desc.name = dev_name(padctl->dev);
91325cbac77SMasahiro Yamada padctl->desc.pins = tegra124_pins;
91425cbac77SMasahiro Yamada padctl->desc.npins = ARRAY_SIZE(tegra124_pins);
91525cbac77SMasahiro Yamada padctl->desc.pctlops = &tegra_xusb_padctl_pinctrl_ops;
91625cbac77SMasahiro Yamada padctl->desc.pmxops = &tegra_xusb_padctl_pinmux_ops;
91725cbac77SMasahiro Yamada padctl->desc.confops = &tegra_xusb_padctl_pinconf_ops;
91825cbac77SMasahiro Yamada padctl->desc.owner = THIS_MODULE;
91925cbac77SMasahiro Yamada
920e46e3ef3SLaxman Dewangan padctl->pinctrl = devm_pinctrl_register(&pdev->dev, &padctl->desc,
921e46e3ef3SLaxman Dewangan padctl);
92225cbac77SMasahiro Yamada if (IS_ERR(padctl->pinctrl)) {
92325cbac77SMasahiro Yamada dev_err(&pdev->dev, "failed to register pincontrol\n");
92425cbac77SMasahiro Yamada err = PTR_ERR(padctl->pinctrl);
92525cbac77SMasahiro Yamada goto reset;
92625cbac77SMasahiro Yamada }
92725cbac77SMasahiro Yamada
92825cbac77SMasahiro Yamada phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops);
92925cbac77SMasahiro Yamada if (IS_ERR(phy)) {
93025cbac77SMasahiro Yamada err = PTR_ERR(phy);
931e46e3ef3SLaxman Dewangan goto reset;
93225cbac77SMasahiro Yamada }
93325cbac77SMasahiro Yamada
93425cbac77SMasahiro Yamada padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy;
93525cbac77SMasahiro Yamada phy_set_drvdata(phy, padctl);
93625cbac77SMasahiro Yamada
93725cbac77SMasahiro Yamada phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops);
93825cbac77SMasahiro Yamada if (IS_ERR(phy)) {
93925cbac77SMasahiro Yamada err = PTR_ERR(phy);
940e46e3ef3SLaxman Dewangan goto reset;
94125cbac77SMasahiro Yamada }
94225cbac77SMasahiro Yamada
94325cbac77SMasahiro Yamada padctl->phys[TEGRA_XUSB_PADCTL_SATA] = phy;
94425cbac77SMasahiro Yamada phy_set_drvdata(phy, padctl);
94525cbac77SMasahiro Yamada
94625cbac77SMasahiro Yamada padctl->provider = devm_of_phy_provider_register(&pdev->dev,
94725cbac77SMasahiro Yamada tegra_xusb_padctl_xlate);
94825cbac77SMasahiro Yamada if (IS_ERR(padctl->provider)) {
94925cbac77SMasahiro Yamada err = PTR_ERR(padctl->provider);
95025cbac77SMasahiro Yamada dev_err(&pdev->dev, "failed to register PHYs: %d\n", err);
951e46e3ef3SLaxman Dewangan goto reset;
95225cbac77SMasahiro Yamada }
95325cbac77SMasahiro Yamada
95425cbac77SMasahiro Yamada return 0;
95525cbac77SMasahiro Yamada
95625cbac77SMasahiro Yamada reset:
95725cbac77SMasahiro Yamada reset_control_assert(padctl->rst);
95825cbac77SMasahiro Yamada return err;
95925cbac77SMasahiro Yamada }
96053d2a715SThierry Reding EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_probe);
96125cbac77SMasahiro Yamada
tegra_xusb_padctl_legacy_remove(struct platform_device * pdev)96253d2a715SThierry Reding int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev)
96325cbac77SMasahiro Yamada {
96425cbac77SMasahiro Yamada struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev);
96525cbac77SMasahiro Yamada int err;
96625cbac77SMasahiro Yamada
96725cbac77SMasahiro Yamada err = reset_control_assert(padctl->rst);
96825cbac77SMasahiro Yamada if (err < 0)
96925cbac77SMasahiro Yamada dev_err(&pdev->dev, "failed to assert reset: %d\n", err);
97025cbac77SMasahiro Yamada
97125cbac77SMasahiro Yamada return err;
97225cbac77SMasahiro Yamada }
97353d2a715SThierry Reding EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_remove);
974