summaryrefslogtreecommitdiffstats
path: root/drivers/soundwire/amd_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soundwire/amd_manager.c')
-rw-r--r--drivers/soundwire/amd_manager.c59
1 files changed, 17 insertions, 42 deletions
diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c
index 42028ace06..795e223f7e 100644
--- a/drivers/soundwire/amd_manager.c
+++ b/drivers/soundwire/amd_manager.c
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
* SoundWire AMD Manager driver
*
- * Copyright 2023 Advanced Micro Devices, Inc.
+ * Copyright 2023-24 Advanced Micro Devices, Inc.
*/
#include <linux/completion.h>
@@ -19,29 +19,13 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "bus.h"
+#include "amd_init.h"
#include "amd_manager.h"
#define DRV_NAME "amd_sdw_manager"
#define to_amd_sdw(b) container_of(b, struct amd_sdw_manager, bus)
-static void amd_enable_sdw_pads(struct amd_sdw_manager *amd_manager)
-{
- u32 sw_pad_pulldown_val;
- u32 val;
-
- mutex_lock(amd_manager->acp_sdw_lock);
- val = readl(amd_manager->acp_mmio + ACP_SW_PAD_KEEPER_EN);
- val |= amd_manager->reg_mask->sw_pad_enable_mask;
- writel(val, amd_manager->acp_mmio + ACP_SW_PAD_KEEPER_EN);
- usleep_range(1000, 1500);
-
- sw_pad_pulldown_val = readl(amd_manager->acp_mmio + ACP_PAD_PULLDOWN_CTRL);
- sw_pad_pulldown_val &= amd_manager->reg_mask->sw_pad_pulldown_mask;
- writel(sw_pad_pulldown_val, amd_manager->acp_mmio + ACP_PAD_PULLDOWN_CTRL);
- mutex_unlock(amd_manager->acp_sdw_lock);
-}
-
static int amd_init_sdw_manager(struct amd_sdw_manager *amd_manager)
{
u32 val;
@@ -102,13 +86,11 @@ static int amd_disable_sdw_manager(struct amd_sdw_manager *amd_manager)
static void amd_enable_sdw_interrupts(struct amd_sdw_manager *amd_manager)
{
- struct sdw_manager_reg_mask *reg_mask = amd_manager->reg_mask;
u32 val;
mutex_lock(amd_manager->acp_sdw_lock);
- val = readl(amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(amd_manager->instance));
- val |= reg_mask->acp_sdw_intr_mask;
- writel(val, amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(amd_manager->instance));
+ val = sdw_manager_reg_mask_array[amd_manager->instance];
+ amd_updatel(amd_manager->acp_mmio, ACP_EXTERNAL_INTR_CNTL(amd_manager->instance), val, val);
mutex_unlock(amd_manager->acp_sdw_lock);
writel(AMD_SDW_IRQ_MASK_0TO7, amd_manager->mmio +
@@ -120,13 +102,12 @@ static void amd_enable_sdw_interrupts(struct amd_sdw_manager *amd_manager)
static void amd_disable_sdw_interrupts(struct amd_sdw_manager *amd_manager)
{
- struct sdw_manager_reg_mask *reg_mask = amd_manager->reg_mask;
- u32 val;
+ u32 irq_mask;
mutex_lock(amd_manager->acp_sdw_lock);
- val = readl(amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(amd_manager->instance));
- val &= ~reg_mask->acp_sdw_intr_mask;
- writel(val, amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(amd_manager->instance));
+ irq_mask = sdw_manager_reg_mask_array[amd_manager->instance];
+ amd_updatel(amd_manager->acp_mmio, ACP_EXTERNAL_INTR_CNTL(amd_manager->instance),
+ irq_mask, 0);
mutex_unlock(amd_manager->acp_sdw_lock);
writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_0TO7);
@@ -590,6 +571,9 @@ static int sdw_master_read_amd_prop(struct sdw_bus *bus)
amd_manager->wake_en_mask = wake_en_mask;
fwnode_property_read_u32(link, "amd-sdw-power-mode", &power_mode_mask);
amd_manager->power_mode_mask = power_mode_mask;
+
+ fwnode_handle_put(link);
+
return 0;
}
@@ -877,23 +861,20 @@ static void amd_sdw_irq_thread(struct work_struct *work)
writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_0TO7);
}
-static void amd_sdw_probe_work(struct work_struct *work)
+int amd_sdw_manager_start(struct amd_sdw_manager *amd_manager)
{
- struct amd_sdw_manager *amd_manager = container_of(work, struct amd_sdw_manager,
- probe_work);
struct sdw_master_prop *prop;
int ret;
prop = &amd_manager->bus.prop;
if (!prop->hw_disabled) {
- amd_enable_sdw_pads(amd_manager);
ret = amd_init_sdw_manager(amd_manager);
if (ret)
- return;
+ return ret;
amd_enable_sdw_interrupts(amd_manager);
ret = amd_enable_sdw_manager(amd_manager);
if (ret)
- return;
+ return ret;
amd_sdw_set_frameshape(amd_manager);
}
/* Enable runtime PM */
@@ -902,6 +883,7 @@ static void amd_sdw_probe_work(struct work_struct *work)
pm_runtime_mark_last_busy(amd_manager->dev);
pm_runtime_set_active(amd_manager->dev);
pm_runtime_enable(amd_manager->dev);
+ return 0;
}
static int amd_sdw_manager_probe(struct platform_device *pdev)
@@ -961,7 +943,6 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
return -EINVAL;
}
- amd_manager->reg_mask = &sdw_manager_reg_mask_array[amd_manager->instance];
params = &amd_manager->bus.params;
params->col = AMD_SDW_DEFAULT_COLUMNS;
@@ -985,11 +966,6 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
dev_set_drvdata(dev, amd_manager);
INIT_WORK(&amd_manager->amd_sdw_irq_thread, amd_sdw_irq_thread);
INIT_WORK(&amd_manager->amd_sdw_work, amd_sdw_update_slave_status_work);
- INIT_WORK(&amd_manager->probe_work, amd_sdw_probe_work);
- /*
- * Instead of having lengthy probe sequence, use deferred probe.
- */
- schedule_work(&amd_manager->probe_work);
return 0;
}
@@ -999,7 +975,6 @@ static void amd_sdw_manager_remove(struct platform_device *pdev)
int ret;
pm_runtime_disable(&pdev->dev);
- cancel_work_sync(&amd_manager->probe_work);
amd_disable_sdw_interrupts(amd_manager);
sdw_bus_master_delete(&amd_manager->bus);
ret = amd_disable_sdw_manager(amd_manager);
@@ -1230,5 +1205,5 @@ module_platform_driver(amd_sdw_driver);
MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
MODULE_DESCRIPTION("AMD SoundWire driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("platform:" DRV_NAME);