// 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_obj(*ctx);
	if (!ctx)
		return NULL;

	ctx->count = count;
	ctx->link_mask = res->link_mask;
	struct resource *sdw_res __free(kfree) = kzalloc_obj(*sdw_res);
	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;
		sdw_pdata[index].acp_rev = res->acp_rev;
		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->peripherals);
	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->peripherals = kmalloc_flex(*ctx->peripherals, array, num_slaves);
	if (!ctx->peripherals)
		return -ENOMEM;
	ctx->peripherals->num_peripherals = 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->peripherals->array[i] = slave;
				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");
