Home | History | Annotate | Download | only in mach-tegra
      1 // SPDX-License-Identifier: GPL-2.0
      2 /*
      3  * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
      4  */
      5 
      6 #define pr_fmt(fmt) "tegra-xusb-padctl: " fmt
      7 
      8 #include <common.h>
      9 #include <errno.h>
     10 
     11 #include "xusb-padctl-common.h"
     12 
     13 #include <asm/arch/clock.h>
     14 
     15 int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy)
     16 {
     17 	if (phy && phy->ops && phy->ops->prepare)
     18 		return phy->ops->prepare(phy);
     19 
     20 	return phy ? -ENOSYS : -EINVAL;
     21 }
     22 
     23 int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy)
     24 {
     25 	if (phy && phy->ops && phy->ops->enable)
     26 		return phy->ops->enable(phy);
     27 
     28 	return phy ? -ENOSYS : -EINVAL;
     29 }
     30 
     31 int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy)
     32 {
     33 	if (phy && phy->ops && phy->ops->disable)
     34 		return phy->ops->disable(phy);
     35 
     36 	return phy ? -ENOSYS : -EINVAL;
     37 }
     38 
     39 int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy)
     40 {
     41 	if (phy && phy->ops && phy->ops->unprepare)
     42 		return phy->ops->unprepare(phy);
     43 
     44 	return phy ? -ENOSYS : -EINVAL;
     45 }
     46 
     47 struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type)
     48 {
     49 	struct tegra_xusb_phy *phy;
     50 	int i;
     51 
     52 	for (i = 0; i < padctl.socdata->num_phys; i++) {
     53 		phy = &padctl.socdata->phys[i];
     54 		if (phy->type != type)
     55 			continue;
     56 		return phy;
     57 	}
     58 
     59 	return NULL;
     60 }
     61 
     62 static const struct tegra_xusb_padctl_lane *
     63 tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name)
     64 {
     65 	unsigned int i;
     66 
     67 	for (i = 0; i < padctl->socdata->num_lanes; i++)
     68 		if (strcmp(name, padctl->socdata->lanes[i].name) == 0)
     69 			return &padctl->socdata->lanes[i];
     70 
     71 	return NULL;
     72 }
     73 
     74 static int
     75 tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl,
     76 				 struct tegra_xusb_padctl_group *group,
     77 				 ofnode node)
     78 {
     79 	unsigned int i;
     80 	int len, ret;
     81 
     82 	group->name = ofnode_get_name(node);
     83 
     84 	len = ofnode_read_string_count(node, "nvidia,lanes");
     85 	if (len < 0) {
     86 		pr_err("failed to parse \"nvidia,lanes\" property");
     87 		return -EINVAL;
     88 	}
     89 
     90 	group->num_pins = len;
     91 
     92 	for (i = 0; i < group->num_pins; i++) {
     93 		ret = ofnode_read_string_index(node, "nvidia,lanes", i,
     94 					       &group->pins[i]);
     95 		if (ret) {
     96 			pr_err("failed to read string from \"nvidia,lanes\" property");
     97 			return -EINVAL;
     98 		}
     99 	}
    100 
    101 	group->num_pins = len;
    102 
    103 	ret = ofnode_read_string_index(node, "nvidia,function", 0,
    104 				       &group->func);
    105 	if (ret) {
    106 		pr_err("failed to parse \"nvidia,func\" property");
    107 		return -EINVAL;
    108 	}
    109 
    110 	group->iddq = ofnode_read_u32_default(node, "nvidia,iddq", -1);
    111 
    112 	return 0;
    113 }
    114 
    115 static int tegra_xusb_padctl_find_function(struct tegra_xusb_padctl *padctl,
    116 					   const char *name)
    117 {
    118 	unsigned int i;
    119 
    120 	for (i = 0; i < padctl->socdata->num_functions; i++)
    121 		if (strcmp(name, padctl->socdata->functions[i]) == 0)
    122 			return i;
    123 
    124 	return -ENOENT;
    125 }
    126 
    127 static int
    128 tegra_xusb_padctl_lane_find_function(struct tegra_xusb_padctl *padctl,
    129 				     const struct tegra_xusb_padctl_lane *lane,
    130 				     const char *name)
    131 {
    132 	unsigned int i;
    133 	int func;
    134 
    135 	func = tegra_xusb_padctl_find_function(padctl, name);
    136 	if (func < 0)
    137 		return func;
    138 
    139 	for (i = 0; i < lane->num_funcs; i++)
    140 		if (lane->funcs[i] == func)
    141 			return i;
    142 
    143 	return -ENOENT;
    144 }
    145 
    146 static int
    147 tegra_xusb_padctl_group_apply(struct tegra_xusb_padctl *padctl,
    148 			      const struct tegra_xusb_padctl_group *group)
    149 {
    150 	unsigned int i;
    151 
    152 	for (i = 0; i < group->num_pins; i++) {
    153 		const struct tegra_xusb_padctl_lane *lane;
    154 		unsigned int func;
    155 		u32 value;
    156 
    157 		lane = tegra_xusb_padctl_find_lane(padctl, group->pins[i]);
    158 		if (!lane) {
    159 			pr_err("no lane for pin %s", group->pins[i]);
    160 			continue;
    161 		}
    162 
    163 		func = tegra_xusb_padctl_lane_find_function(padctl, lane,
    164 							    group->func);
    165 		if (func < 0) {
    166 			pr_err("function %s invalid for lane %s: %d",
    167 			      group->func, lane->name, func);
    168 			continue;
    169 		}
    170 
    171 		value = padctl_readl(padctl, lane->offset);
    172 
    173 		/* set pin function */
    174 		value &= ~(lane->mask << lane->shift);
    175 		value |= func << lane->shift;
    176 
    177 		/*
    178 		 * Set IDDQ if supported on the lane and specified in the
    179 		 * configuration.
    180 		 */
    181 		if (lane->iddq > 0 && group->iddq >= 0) {
    182 			if (group->iddq != 0)
    183 				value &= ~(1 << lane->iddq);
    184 			else
    185 				value |= 1 << lane->iddq;
    186 		}
    187 
    188 		padctl_writel(padctl, value, lane->offset);
    189 	}
    190 
    191 	return 0;
    192 }
    193 
    194 static int
    195 tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl,
    196 			       struct tegra_xusb_padctl_config *config)
    197 {
    198 	unsigned int i;
    199 
    200 	for (i = 0; i < config->num_groups; i++) {
    201 		const struct tegra_xusb_padctl_group *group;
    202 		int err;
    203 
    204 		group = &config->groups[i];
    205 
    206 		err = tegra_xusb_padctl_group_apply(padctl, group);
    207 		if (err < 0) {
    208 			pr_err("failed to apply group %s: %d",
    209 			      group->name, err);
    210 			continue;
    211 		}
    212 	}
    213 
    214 	return 0;
    215 }
    216 
    217 static int
    218 tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl,
    219 				  struct tegra_xusb_padctl_config *config,
    220 				  ofnode node)
    221 {
    222 	ofnode subnode;
    223 
    224 	config->name = ofnode_get_name(node);
    225 
    226 	ofnode_for_each_subnode(subnode, node) {
    227 		struct tegra_xusb_padctl_group *group;
    228 		int err;
    229 
    230 		group = &config->groups[config->num_groups];
    231 
    232 		err = tegra_xusb_padctl_group_parse_dt(padctl, group, subnode);
    233 		if (err < 0) {
    234 			pr_err("failed to parse group %s", group->name);
    235 			return err;
    236 		}
    237 
    238 		config->num_groups++;
    239 	}
    240 
    241 	return 0;
    242 }
    243 
    244 static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl,
    245 				      ofnode node)
    246 {
    247 	ofnode subnode;
    248 	int err;
    249 
    250 	err = ofnode_read_resource(node, 0, &padctl->regs);
    251 	if (err < 0) {
    252 		pr_err("registers not found");
    253 		return err;
    254 	}
    255 
    256 	ofnode_for_each_subnode(subnode, node) {
    257 		struct tegra_xusb_padctl_config *config = &padctl->config;
    258 
    259 		debug("%s: subnode=%s\n", __func__, ofnode_get_name(subnode));
    260 		err = tegra_xusb_padctl_config_parse_dt(padctl, config,
    261 							subnode);
    262 		if (err < 0) {
    263 			pr_err("failed to parse entry %s: %d",
    264 			      config->name, err);
    265 			continue;
    266 		}
    267 	}
    268 	debug("%s: done\n", __func__);
    269 
    270 	return 0;
    271 }
    272 
    273 struct tegra_xusb_padctl padctl;
    274 
    275 int tegra_xusb_process_nodes(ofnode nodes[], unsigned int count,
    276 			     const struct tegra_xusb_padctl_soc *socdata)
    277 {
    278 	unsigned int i;
    279 	int err;
    280 
    281 	debug("%s: count=%d\n", __func__, count);
    282 	for (i = 0; i < count; i++) {
    283 		debug("%s: i=%d, node=%p\n", __func__, i, nodes[i].np);
    284 		if (!ofnode_is_available(nodes[i]))
    285 			continue;
    286 
    287 		padctl.socdata = socdata;
    288 
    289 		err = tegra_xusb_padctl_parse_dt(&padctl, nodes[i]);
    290 		if (err < 0) {
    291 			pr_err("failed to parse DT: %d", err);
    292 			continue;
    293 		}
    294 
    295 		/* deassert XUSB padctl reset */
    296 		reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0);
    297 
    298 		err = tegra_xusb_padctl_config_apply(&padctl, &padctl.config);
    299 		if (err < 0) {
    300 			pr_err("failed to apply pinmux: %d", err);
    301 			continue;
    302 		}
    303 
    304 		/* only a single instance is supported */
    305 		break;
    306 	}
    307 	debug("%s: done\n", __func__);
    308 
    309 	return 0;
    310 }
    311