// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * SoundWire AMD Manager Initialize routines
 *
 * Initializes and creates SDW devices based on ACPI and Hardware values
 *
 * Copyright 2024 Advanced Micro Devices, Inc.
 */

#include <linux/acpi.h>
#include <linux/cleanup.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include "amd_init.h"

#define ACP_PAD_PULLDOWN_CTRL				0x0001448
#define ACP_SW_PAD_KEEPER_EN				0x0001454
#define AMD_SDW0_PAD_CTRL_MASK				0x60
#define AMD_SDW1_PAD_CTRL_MASK				5
#define AMD_SDW_PAD_CTRL_MASK		(AMD_SDW0_PAD_CTRL_MASK | AMD_SDW1_PAD_CTRL_MASK)
#define AMD_SDW0_PAD_EN					1
#define AMD_SDW1_PAD_EN					0x10
#define AMD_SDW_PAD_EN			(AMD_SDW0_PAD_EN | AMD_SDW1_PAD_EN)

static int amd_enable_sdw_pads(void __iomem *mmio, u32 link_mask, struct device *dev)
{
	u32 pad_keeper_en, pad_pulldown_ctrl_mask;

	switch (link_mask) {
	case 1:
		pad_keeper_en = AMD_SDW0_PAD_EN;
		pad_pulldown_ctrl_mask = AMD_SDW0_PAD_CTRL_MASK;
		break;
	case 2:
		pad_keeper_en = AMD_SDW1_PAD_EN;
		pad_pulldown_ctrl_mask = AMD_SDW1_PAD_CTRL_MASK;
		break;
	case 3:
		pad_keeper_en = AMD_SDW_PAD_EN;
		pad_pulldown_ctrl_mask = AMD_SDW_PAD_CTRL_MASK;
		break;
	default:
		dev_err(dev, "No SDW Links are enabled\n");
		return -ENODEV;
	}

	amd_updatel(mmio, ACP_SW_PAD_KEEPER_EN, pad_keeper_en, pad_keeper_en);
	amd_updatel(mmio, ACP_PAD_PULLDOWN_CTRL, pad_pulldown_ctrl_mask, 0);

	return 0;
}

static int sdw_amd_cleanup(struct sdw_amd_ctx *ctx)
{
	int i;

	for (i = 0; i < ctx->count; i++) {
		if (!(ctx->link_mask & BIT(i)))
			continue;
		platform_device_unregister(ctx->pdev[i]);
	}

	return 0;
}

static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res)
{
	struct sdw_amd_ctx *ctx;
	struct acpi_device *adev;
	struct acp_sdw_pdata sdw_pdata[2];
	struct platform_device_info pdevinfo[2];
	u32 link_mask;
	int count, index;
	int ret;

	if (!res)
		return NULL;

	adev = acpi_fetch_acpi_dev(res->handle);
	if (!adev)
		return NULL;

	if (!res->count)
		return NULL;

	count = res->count;
	dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);
	ret = amd_enable_sdw_pads(res->mmio_base, res->link_mask, res->parent);
	if (ret)
		return NULL;

	/*
	 * we need to alloc/free memory manually and can't use devm:
	 * this routine may be called from a workqueue, and not from
	 * the parent .probe.
	 * If devm_ was used, the memory might never be freed on errors.
	 */
	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return NULL;

	ctx->count = count;
	ctx->link_mask = res->link_mask;
	struct resource *sdw_res __free(kfree) = kzalloc(sizeof(*sdw_res),
							 GFP_KERNEL);
	if (!sdw_res) {
		kfree(ctx);
		return NULL;
	}
	sdw_res->flags = IORESOURCE_MEM;
	sdw_res->start = res->addr;
	sdw_res->end = res->addr + res->reg_range;
	memset(&pdevinfo, 0, sizeof(pdevinfo));
	link_mask = ctx->link_mask;
	for (index = 0; index < count; index++) {
		if (!(link_mask & BIT(index)))
			continue;

		sdw_pdata[index].instance = index;
		sdw_pdata[index].acp_sdw_lock = res->acp_lock;
		pdevinfo[index].name = "amd_sdw_manager";
		pdevinfo[index].id = index;
		pdevinfo[index].parent = res->parent;
		pdevinfo[index].num_res = 1;
		pdevinfo[index].res = sdw_res;
		pdevinfo[index].data = &sdw_pdata[index];
		pdevinfo[index].size_data = sizeof(struct acp_sdw_pdata);
		pdevinfo[index].fwnode = acpi_fwnode_handle(adev);
		ctx->pdev[index] = platform_device_register_full(&pdevinfo[index]);
		if (IS_ERR(ctx->pdev[index]))
			goto err;
	}
	return ctx;
err:
	while (index--) {
		if (!(link_mask & BIT(index)))
			continue;

		platform_device_unregister(ctx->pdev[index]);
	}

	kfree(ctx);
	return NULL;
}

static int sdw_amd_startup(struct sdw_amd_ctx *ctx)
{
	struct amd_sdw_manager *amd_manager;
	int i, ret;

	/* Startup SDW Manager devices */
	for (i = 0; i < ctx->count; i++) {
		if (!(ctx->link_mask & BIT(i)))
			continue;
		amd_manager = dev_get_drvdata(&ctx->pdev[i]->dev);
		ret = amd_sdw_manager_start(amd_manager);
		if (ret)
			return ret;
	}

	return 0;
}

int sdw_amd_probe(struct sdw_amd_res *res, struct sdw_amd_ctx **sdw_ctx)
{
	*sdw_ctx = sdw_amd_probe_controller(res);
	if (!*sdw_ctx)
		return -ENODEV;

	return sdw_amd_startup(*sdw_ctx);
}
EXPORT_SYMBOL_NS(sdw_amd_probe, SOUNDWIRE_AMD_INIT);

void sdw_amd_exit(struct sdw_amd_ctx *ctx)
{
	sdw_amd_cleanup(ctx);
	kfree(ctx->ids);
	kfree(ctx);
}
EXPORT_SYMBOL_NS(sdw_amd_exit, SOUNDWIRE_AMD_INIT);

int sdw_amd_get_slave_info(struct sdw_amd_ctx *ctx)
{
	struct amd_sdw_manager *amd_manager;
	struct sdw_bus *bus;
	struct sdw_slave *slave;
	struct list_head *node;
	int index;
	int i = 0;
	int num_slaves = 0;

	for (index = 0; index < ctx->count; index++) {
		if (!(ctx->link_mask & BIT(index)))
			continue;
		amd_manager = dev_get_drvdata(&ctx->pdev[index]->dev);
		if (!amd_manager)
			return -ENODEV;
		bus = &amd_manager->bus;
		/* Calculate number of slaves */
		list_for_each(node, &bus->slaves)
			num_slaves++;
	}

	ctx->ids = kcalloc(num_slaves, sizeof(*ctx->ids), GFP_KERNEL);
	if (!ctx->ids)
		return -ENOMEM;
	ctx->num_slaves = num_slaves;
	for (index = 0; index < ctx->count; index++) {
		if (!(ctx->link_mask & BIT(index)))
			continue;
		amd_manager = dev_get_drvdata(&ctx->pdev[index]->dev);
		if (amd_manager) {
			bus = &amd_manager->bus;
			list_for_each_entry(slave, &bus->slaves, node) {
				ctx->ids[i].id = slave->id;
				ctx->ids[i].link_id = bus->link_id;
				i++;
			}
		}
	}
	return 0;
}
EXPORT_SYMBOL_NS(sdw_amd_get_slave_info, SOUNDWIRE_AMD_INIT);

MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
MODULE_DESCRIPTION("AMD SoundWire Init Library");
MODULE_LICENSE("Dual BSD/GPL");
