/*
 * Actions Semi Owl Smart Power System (SPS)
 *
 * Copyright 2012 Actions Semi Inc.
 * Author: Actions Semi, Inc.
 *
 * Copyright (c) 2017 Andreas Färber
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pm_domain.h>
#include <linux/soc/actions/owl-sps.h>
#include <dt-bindings/power/owl-s500-powergate.h>
#include <dt-bindings/power/owl-s700-powergate.h>

struct owl_sps_domain_info {
	const char *name;
	int pwr_bit;
	int ack_bit;
	unsigned int genpd_flags;
};

struct owl_sps_info {
	unsigned num_domains;
	const struct owl_sps_domain_info *domains;
};

struct owl_sps {
	struct device *dev;
	const struct owl_sps_info *info;
	void __iomem *base;
	struct genpd_onecell_data genpd_data;
	struct generic_pm_domain *domains[];
};

#define to_owl_pd(gpd) container_of(gpd, struct owl_sps_domain, genpd)

struct owl_sps_domain {
	struct generic_pm_domain genpd;
	const struct owl_sps_domain_info *info;
	struct owl_sps *sps;
};

static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable)
{
	u32 pwr_mask, ack_mask;

	ack_mask = BIT(pd->info->ack_bit);
	pwr_mask = BIT(pd->info->pwr_bit);

	return owl_sps_set_pg(pd->sps->base, pwr_mask, ack_mask, enable);
}

static int owl_sps_power_on(struct generic_pm_domain *domain)
{
	struct owl_sps_domain *pd = to_owl_pd(domain);

	dev_dbg(pd->sps->dev, "%s power on", pd->info->name);

	return owl_sps_set_power(pd, true);
}

static int owl_sps_power_off(struct generic_pm_domain *domain)
{
	struct owl_sps_domain *pd = to_owl_pd(domain);

	dev_dbg(pd->sps->dev, "%s power off", pd->info->name);

	return owl_sps_set_power(pd, false);
}

static int owl_sps_init_domain(struct owl_sps *sps, int index)
{
	struct owl_sps_domain *pd;

	pd = devm_kzalloc(sps->dev, sizeof(*pd), GFP_KERNEL);
	if (!pd)
		return -ENOMEM;

	pd->info = &sps->info->domains[index];
	pd->sps = sps;

	pd->genpd.name = pd->info->name;
	pd->genpd.power_on = owl_sps_power_on;
	pd->genpd.power_off = owl_sps_power_off;
	pd->genpd.flags = pd->info->genpd_flags;
	pm_genpd_init(&pd->genpd, NULL, false);

	sps->genpd_data.domains[index] = &pd->genpd;

	return 0;
}

static int owl_sps_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	const struct owl_sps_info *sps_info;
	struct owl_sps *sps;
	int i, ret;

	if (!pdev->dev.of_node) {
		dev_err(&pdev->dev, "no device node\n");
		return -ENODEV;
	}

	match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
	if (!match || !match->data) {
		dev_err(&pdev->dev, "unknown compatible or missing data\n");
		return -EINVAL;
	}

	sps_info = match->data;

	sps = devm_kzalloc(&pdev->dev,
			   struct_size(sps, domains, sps_info->num_domains),
			   GFP_KERNEL);
	if (!sps)
		return -ENOMEM;

	sps->base = of_io_request_and_map(pdev->dev.of_node, 0, "owl-sps");
	if (IS_ERR(sps->base)) {
		dev_err(&pdev->dev, "failed to map sps registers\n");
		return PTR_ERR(sps->base);
	}

	sps->dev = &pdev->dev;
	sps->info = sps_info;
	sps->genpd_data.domains = sps->domains;
	sps->genpd_data.num_domains = sps_info->num_domains;

	for (i = 0; i < sps_info->num_domains; i++) {
		ret = owl_sps_init_domain(sps, i);
		if (ret)
			return ret;
	}

	ret = of_genpd_add_provider_onecell(pdev->dev.of_node, &sps->genpd_data);
	if (ret) {
		dev_err(&pdev->dev, "failed to add provider (%d)", ret);
		return ret;
	}

	return 0;
}

static const struct owl_sps_domain_info s500_sps_domains[] = {
	[S500_PD_VDE] = {
		.name = "VDE",
		.pwr_bit = 0,
		.ack_bit = 16,
	},
	[S500_PD_VCE_SI] = {
		.name = "VCE_SI",
		.pwr_bit = 1,
		.ack_bit = 17,
	},
	[S500_PD_USB2_1] = {
		.name = "USB2_1",
		.pwr_bit = 2,
		.ack_bit = 18,
	},
	[S500_PD_CPU2] = {
		.name = "CPU2",
		.pwr_bit = 5,
		.ack_bit = 21,
		.genpd_flags = GENPD_FLAG_ALWAYS_ON,
	},
	[S500_PD_CPU3] = {
		.name = "CPU3",
		.pwr_bit = 6,
		.ack_bit = 22,
		.genpd_flags = GENPD_FLAG_ALWAYS_ON,
	},
	[S500_PD_DMA] = {
		.name = "DMA",
		.pwr_bit = 8,
		.ack_bit = 12,
	},
	[S500_PD_DS] = {
		.name = "DS",
		.pwr_bit = 9,
		.ack_bit = 13,
	},
	[S500_PD_USB3] = {
		.name = "USB3",
		.pwr_bit = 10,
		.ack_bit = 14,
	},
	[S500_PD_USB2_0] = {
		.name = "USB2_0",
		.pwr_bit = 11,
		.ack_bit = 15,
	},
};

static const struct owl_sps_info s500_sps_info = {
	.num_domains = ARRAY_SIZE(s500_sps_domains),
	.domains = s500_sps_domains,
};

static const struct owl_sps_domain_info s700_sps_domains[] = {
	[S700_PD_VDE] = {
		.name = "VDE",
		.pwr_bit = 0,
	},
	[S700_PD_VCE_SI] = {
		.name = "VCE_SI",
		.pwr_bit = 1,
	},
	[S700_PD_USB2_1] = {
		.name = "USB2_1",
		.pwr_bit = 2,
	},
	[S700_PD_HDE] = {
		.name = "HDE",
		.pwr_bit = 7,
	},
	[S700_PD_DMA] = {
		.name = "DMA",
		.pwr_bit = 8,
	},
	[S700_PD_DS] = {
		.name = "DS",
		.pwr_bit = 9,
	},
	[S700_PD_USB3] = {
		.name = "USB3",
		.pwr_bit = 10,
	},
	[S700_PD_USB2_0] = {
		.name = "USB2_0",
		.pwr_bit = 11,
	},
};

static const struct owl_sps_info s700_sps_info = {
	.num_domains = ARRAY_SIZE(s700_sps_domains),
	.domains = s700_sps_domains,
};

static const struct of_device_id owl_sps_of_matches[] = {
	{ .compatible = "actions,s500-sps", .data = &s500_sps_info },
	{ .compatible = "actions,s700-sps", .data = &s700_sps_info },
	{ }
};

static struct platform_driver owl_sps_platform_driver = {
	.probe = owl_sps_probe,
	.driver = {
		.name = "owl-sps",
		.of_match_table = owl_sps_of_matches,
		.suppress_bind_attrs = true,
	},
};

static int __init owl_sps_init(void)
{
	return platform_driver_register(&owl_sps_platform_driver);
}
postcore_initcall(owl_sps_init);
