1190207Srpaulo// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 298524Sfenner// Copyright(c) 2015-2021 Intel Corporation. 398524Sfenner 498524Sfenner/* 598524Sfenner * SDW Intel ACPI scan helpers 698524Sfenner */ 798524Sfenner 898524Sfenner#include <linux/acpi.h> 998524Sfenner#include <linux/bits.h> 1098524Sfenner#include <linux/bitfield.h> 1198524Sfenner#include <linux/device.h> 1298524Sfenner#include <linux/errno.h> 1398524Sfenner#include <linux/export.h> 1498524Sfenner#include <linux/fwnode.h> 1598524Sfenner#include <linux/module.h> 1698524Sfenner#include <linux/soundwire/sdw_intel.h> 1798524Sfenner#include <linux/string.h> 1898524Sfenner 1998524Sfenner#define SDW_LINK_TYPE 4 /* from Intel ACPI documentation */ 2098524Sfenner#define SDW_MAX_LINKS 4 2198524Sfenner 2298524Sfennerstatic int ctrl_link_mask; 2398524Sfennermodule_param_named(sdw_link_mask, ctrl_link_mask, int, 0444); 2498524SfennerMODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)"); 2598524Sfenner 2698524Sfennerstatic ulong ctrl_addr = 0x40000000; 2798524Sfennermodule_param_named(sdw_ctrl_addr, ctrl_addr, ulong, 0444); 2898524SfennerMODULE_PARM_DESC(sdw_ctrl_addr, "Intel SoundWire Controller _ADR"); 2998524Sfenner 3098524Sfennerstatic bool is_link_enabled(struct fwnode_handle *fw_node, u8 idx) 3198524Sfenner{ 3298524Sfenner struct fwnode_handle *link; 3398524Sfenner char name[32]; 34127668Sbms u32 quirk_mask = 0; 3598524Sfenner 3698524Sfenner /* Find master handle */ 37127668Sbms snprintf(name, sizeof(name), 3898524Sfenner "mipi-sdw-link-%hhu-subproperties", idx); 3998524Sfenner 4098524Sfenner link = fwnode_get_named_child_node(fw_node, name); 41127668Sbms if (!link) 4298524Sfenner return false; 4398524Sfenner 4498524Sfenner fwnode_property_read_u32(link, 4598524Sfenner "intel-quirk-mask", 4698524Sfenner &quirk_mask); 4798524Sfenner 4898524Sfenner fwnode_handle_put(link); 4998524Sfenner 5098524Sfenner if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE) 5198524Sfenner return false; 5298524Sfenner 5398524Sfenner return true; 5498524Sfenner} 5598524Sfenner 5698524Sfennerstatic int 5798524Sfennersdw_intel_scan_controller(struct sdw_intel_acpi_info *info) 5898524Sfenner{ 5998524Sfenner struct acpi_device *adev = acpi_fetch_acpi_dev(info->handle); 6098524Sfenner u8 count, i; 61127668Sbms int ret; 6298524Sfenner 6398524Sfenner if (!adev) 6498524Sfenner return -EINVAL; 6598524Sfenner 6698524Sfenner /* Found controller, find links supported */ 6798524Sfenner count = 0; 6898524Sfenner ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev), 6998524Sfenner "mipi-sdw-master-count", &count, 1); 7098524Sfenner 7198524Sfenner /* 7298524Sfenner * In theory we could check the number of links supported in 7398524Sfenner * hardware, but in that step we cannot assume SoundWire IP is 7498524Sfenner * powered. 7598524Sfenner * 7698524Sfenner * In addition, if the BIOS doesn't even provide this 7798524Sfenner * 'master-count' property then all the inits based on link 7898524Sfenner * masks will fail as well. 7998524Sfenner * 8098524Sfenner * We will check the hardware capabilities in the startup() step 8198524Sfenner */ 8298524Sfenner 8398524Sfenner if (ret) { 8498524Sfenner dev_err(&adev->dev, 85127668Sbms "Failed to read mipi-sdw-master-count: %d\n", ret); 8698524Sfenner return -EINVAL; 8798524Sfenner } 8898524Sfenner 8998524Sfenner /* Check count is within bounds */ 9098524Sfenner if (count > SDW_MAX_LINKS) { 9198524Sfenner dev_err(&adev->dev, "Link count %d exceeds max %d\n", 9298524Sfenner count, SDW_MAX_LINKS); 9398524Sfenner return -EINVAL; 9498524Sfenner } 9598524Sfenner 9698524Sfenner if (!count) { 9798524Sfenner dev_warn(&adev->dev, "No SoundWire links detected\n"); 9898524Sfenner return -EINVAL; 9998524Sfenner } 10098524Sfenner dev_dbg(&adev->dev, "ACPI reports %d SDW Link devices\n", count); 10198524Sfenner 10298524Sfenner info->count = count; 10398524Sfenner info->link_mask = 0; 10498524Sfenner 10598524Sfenner for (i = 0; i < count; i++) { 10698524Sfenner if (ctrl_link_mask && !(ctrl_link_mask & BIT(i))) { 10798524Sfenner dev_dbg(&adev->dev, 10898524Sfenner "Link %d masked, will not be enabled\n", i); 109127668Sbms continue; 110127668Sbms } 11198524Sfenner 11298524Sfenner if (!is_link_enabled(acpi_fwnode_handle(adev), i)) { 11398524Sfenner dev_dbg(&adev->dev, 11498524Sfenner "Link %d not selected in firmware\n", i); 11598524Sfenner continue; 11698524Sfenner } 11798524Sfenner 11898524Sfenner info->link_mask |= BIT(i); 11998524Sfenner } 12098524Sfenner 12198524Sfenner return 0; 12298524Sfenner} 12398524Sfenner 12498524Sfennerstatic acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level, 12598524Sfenner void *cdata, void **return_value) 12698524Sfenner{ 12798524Sfenner struct sdw_intel_acpi_info *info = cdata; 12898524Sfenner acpi_status status; 12998524Sfenner u64 adr; 13098524Sfenner 13198524Sfenner status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr); 13298524Sfenner if (ACPI_FAILURE(status)) 13398524Sfenner return AE_OK; /* keep going */ 13498524Sfenner 13598524Sfenner if (!acpi_fetch_acpi_dev(handle)) { 13698524Sfenner pr_err("%s: Couldn't find ACPI handle\n", __func__); 13798524Sfenner return AE_NOT_FOUND; 13898524Sfenner } 13998524Sfenner 14098524Sfenner /* 14198524Sfenner * On some Intel platforms, multiple children of the HDAS 14298524Sfenner * device can be found, but only one of them is the SoundWire 14398524Sfenner * controller. The SNDW device is always exposed with 14498524Sfenner * Name(_ADR, 0x40000000), with bits 31..28 representing the 14598524Sfenner * SoundWire link so filter accordingly 14698524Sfenner */ 14798524Sfenner if (FIELD_GET(GENMASK(31, 28), adr) != SDW_LINK_TYPE) 14898524Sfenner return AE_OK; /* keep going */ 14998524Sfenner 15098524Sfenner if (adr != ctrl_addr) 15198524Sfenner return AE_OK; /* keep going */ 15298524Sfenner 15398524Sfenner /* found the correct SoundWire controller */ 15498524Sfenner info->handle = handle; 15598524Sfenner 15698524Sfenner /* device found, stop namespace walk */ 15798524Sfenner return AE_CTRL_TERMINATE; 15898524Sfenner} 15998524Sfenner 16098524Sfenner/** 16198524Sfenner * sdw_intel_acpi_scan() - SoundWire Intel init routine 16298524Sfenner * @parent_handle: ACPI parent handle 16398524Sfenner * @info: description of what firmware/DSDT tables expose 16498524Sfenner * 16598524Sfenner * This scans the namespace and queries firmware to figure out which 16698524Sfenner * links to enable. A follow-up use of sdw_intel_probe() and 16798524Sfenner * sdw_intel_startup() is required for creation of devices and bus 16898524Sfenner * startup 16998524Sfenner */ 17098524Sfennerint sdw_intel_acpi_scan(acpi_handle *parent_handle, 17198524Sfenner struct sdw_intel_acpi_info *info) 17298524Sfenner{ 17398524Sfenner acpi_status status; 17498524Sfenner 17598524Sfenner info->handle = NULL; 17698524Sfenner /* 17798524Sfenner * In the HDAS ACPI scope, 'SNDW' may be either the child of 17898524Sfenner * 'HDAS' or the grandchild of 'HDAS'. So let's go through 17998524Sfenner * the ACPI from 'HDAS' at max depth of 2 to find the 'SNDW' 18098524Sfenner * device. 18198524Sfenner */ 18298524Sfenner status = acpi_walk_namespace(ACPI_TYPE_DEVICE, 18398524Sfenner parent_handle, 2, 18498524Sfenner sdw_intel_acpi_cb, 18598524Sfenner NULL, info, NULL); 18698524Sfenner if (ACPI_FAILURE(status) || info->handle == NULL) 18798524Sfenner return -ENODEV; 18898524Sfenner 18998524Sfenner return sdw_intel_scan_controller(info); 19098524Sfenner} 19198524SfennerEXPORT_SYMBOL_NS(sdw_intel_acpi_scan, SND_INTEL_SOUNDWIRE_ACPI); 19298524Sfenner 19398524SfennerMODULE_LICENSE("Dual BSD/GPL"); 19498524SfennerMODULE_DESCRIPTION("Intel Soundwire ACPI helpers"); 19598524Sfenner