// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
 */

#define pr_fmt(fmt) "tegra-xusb-padctl: " fmt

#include <common.h>
#include <errno.h>
#include <log.h>
#include <linux/printk.h>

#include "xusb-padctl-common.h"

#include <asm/arch/clock.h>

int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy)
{
	if (phy && phy->ops && phy->ops->prepare)
		return phy->ops->prepare(phy);

	return phy ? -ENOSYS : -EINVAL;
}

int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy)
{
	if (phy && phy->ops && phy->ops->enable)
		return phy->ops->enable(phy);

	return phy ? -ENOSYS : -EINVAL;
}

int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy)
{
	if (phy && phy->ops && phy->ops->disable)
		return phy->ops->disable(phy);

	return phy ? -ENOSYS : -EINVAL;
}

int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy)
{
	if (phy && phy->ops && phy->ops->unprepare)
		return phy->ops->unprepare(phy);

	return phy ? -ENOSYS : -EINVAL;
}

struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type)
{
	struct tegra_xusb_phy *phy;
	int i;

	for (i = 0; i < padctl.socdata->num_phys; i++) {
		phy = &padctl.socdata->phys[i];
		if (phy->type != type)
			continue;
		return phy;
	}

	return NULL;
}

static const struct tegra_xusb_padctl_lane *
tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name)
{
	unsigned int i;

	for (i = 0; i < padctl->socdata->num_lanes; i++)
		if (strcmp(name, padctl->socdata->lanes[i].name) == 0)
			return &padctl->socdata->lanes[i];

	return NULL;
}

static int
tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl,
				 struct tegra_xusb_padctl_group *group,
				 ofnode node)
{
	unsigned int i;
	int len, ret;

	group->name = ofnode_get_name(node);

	len = ofnode_read_string_count(node, "nvidia,lanes");
	if (len < 0) {
		pr_err("failed to parse \"nvidia,lanes\" property\n");
		return -EINVAL;
	}

	group->num_pins = len;

	for (i = 0; i < group->num_pins; i++) {
		ret = ofnode_read_string_index(node, "nvidia,lanes", i,
					       &group->pins[i]);
		if (ret) {
			pr_err("failed to read string from \"nvidia,lanes\" property\n");
			return -EINVAL;
		}
	}

	group->num_pins = len;

	ret = ofnode_read_string_index(node, "nvidia,function", 0,
				       &group->func);
	if (ret) {
		pr_err("failed to parse \"nvidia,func\" property\n");
		return -EINVAL;
	}

	group->iddq = ofnode_read_u32_default(node, "nvidia,iddq", -1);

	return 0;
}

static int tegra_xusb_padctl_find_function(struct tegra_xusb_padctl *padctl,
					   const char *name)
{
	unsigned int i;

	for (i = 0; i < padctl->socdata->num_functions; i++)
		if (strcmp(name, padctl->socdata->functions[i]) == 0)
			return i;

	return -ENOENT;
}

static int
tegra_xusb_padctl_lane_find_function(struct tegra_xusb_padctl *padctl,
				     const struct tegra_xusb_padctl_lane *lane,
				     const char *name)
{
	unsigned int i;
	int func;

	func = tegra_xusb_padctl_find_function(padctl, name);
	if (func < 0)
		return func;

	for (i = 0; i < lane->num_funcs; i++)
		if (lane->funcs[i] == func)
			return i;

	return -ENOENT;
}

static int
tegra_xusb_padctl_group_apply(struct tegra_xusb_padctl *padctl,
			      const struct tegra_xusb_padctl_group *group)
{
	unsigned int i;

	for (i = 0; i < group->num_pins; i++) {
		const struct tegra_xusb_padctl_lane *lane;
		unsigned int func;
		u32 value;

		lane = tegra_xusb_padctl_find_lane(padctl, group->pins[i]);
		if (!lane) {
			pr_err("no lane for pin %s", group->pins[i]);
			continue;
		}

		func = tegra_xusb_padctl_lane_find_function(padctl, lane,
							    group->func);
		if (func < 0) {
			pr_err("function %s invalid for lane %s: %d",
			      group->func, lane->name, func);
			continue;
		}

		value = padctl_readl(padctl, lane->offset);

		/* set pin function */
		value &= ~(lane->mask << lane->shift);
		value |= func << lane->shift;

		/*
		 * Set IDDQ if supported on the lane and specified in the
		 * configuration.
		 */
		if (lane->iddq > 0 && group->iddq >= 0) {
			if (group->iddq != 0)
				value &= ~(1 << lane->iddq);
			else
				value |= 1 << lane->iddq;
		}

		padctl_writel(padctl, value, lane->offset);
	}

	return 0;
}

static int
tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl,
			       struct tegra_xusb_padctl_config *config)
{
	unsigned int i;

	for (i = 0; i < config->num_groups; i++) {
		const struct tegra_xusb_padctl_group *group;
		int err;

		group = &config->groups[i];

		err = tegra_xusb_padctl_group_apply(padctl, group);
		if (err < 0) {
			pr_err("failed to apply group %s: %d",
			      group->name, err);
			continue;
		}
	}

	return 0;
}

static int
tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl,
				  struct tegra_xusb_padctl_config *config,
				  ofnode node)
{
	ofnode subnode;

	config->name = ofnode_get_name(node);

	ofnode_for_each_subnode(subnode, node) {
		struct tegra_xusb_padctl_group *group;
		int err;

		group = &config->groups[config->num_groups];

		err = tegra_xusb_padctl_group_parse_dt(padctl, group, subnode);
		if (err < 0) {
			pr_err("failed to parse group %s\n", group->name);
			return err;
		}

		config->num_groups++;
	}

	return 0;
}

static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl,
				      ofnode node)
{
	ofnode subnode;
	int err;

	err = ofnode_read_resource(node, 0, &padctl->regs);
	if (err < 0) {
		pr_err("registers not found");
		return err;
	}

	ofnode_for_each_subnode(subnode, node) {
		struct tegra_xusb_padctl_config *config = &padctl->config;

		debug("%s: subnode=%s\n", __func__, ofnode_get_name(subnode));
		err = tegra_xusb_padctl_config_parse_dt(padctl, config,
							subnode);
		if (err < 0) {
			pr_err("failed to parse entry %s: %d\n",
			      config->name, err);
			continue;
		}
	}
	debug("%s: done\n", __func__);

	return 0;
}

struct tegra_xusb_padctl padctl;

int tegra_xusb_process_nodes(ofnode nodes[], unsigned int count,
			     const struct tegra_xusb_padctl_soc *socdata)
{
	unsigned int i;
	int err;

	debug("%s: count=%d\n", __func__, count);
	for (i = 0; i < count; i++) {
		debug("%s: i=%d, node=%p\n", __func__, i, nodes[i].np);
		if (!ofnode_is_enabled(nodes[i]))
			continue;

		padctl.socdata = socdata;

		err = tegra_xusb_padctl_parse_dt(&padctl, nodes[i]);
		if (err < 0) {
			pr_err("failed to parse DT: %d\n", err);
			continue;
		}

		/* deassert XUSB padctl reset */
		reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0);

		err = tegra_xusb_padctl_config_apply(&padctl, &padctl.config);
		if (err < 0) {
			pr_err("failed to apply pinmux: %d", err);
			continue;
		}

		/* only a single instance is supported */
		break;
	}
	debug("%s: done\n", __func__);

	return 0;
}
