mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'soc-drivers-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull SoC driver updates from Arnd Bergmann:
"The highlights for the driver support this time are
- Qualcomm platforms gain support for the Qualcomm Secure Execution
Environment firmware interface to access EFI variables on certain
devices, and new features for multiple platform and firmware
drivers.
- Arm FF-A firmware support gains support for v1.1 specification
features, in particular notification and memory transaction
descriptor changes.
- SCMI firmware support now support v3.2 features for clock and DVFS
configuration and a new transport for Qualcomm platforms.
- Minor cleanups and bugfixes are added to pretty much all the active
platforms: qualcomm, broadcom, dove, ti-k3, rockchip, sifive,
amlogic, atmel, tegra, aspeed, vexpress, mediatek, samsung and
more.
In particular, this contains portions of the treewide conversion to
use __counted_by annotations and the device_get_match_data helper"
* tag 'soc-drivers-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (156 commits)
soc: qcom: pmic_glink_altmode: Print return value on error
firmware: qcom: scm: remove unneeded 'extern' specifiers
firmware: qcom: scm: add a missing forward declaration for struct device
firmware: qcom: move Qualcomm code into its own directory
soc: samsung: exynos-chipid: Convert to platform remove callback returning void
soc: qcom: apr: Add __counted_by for struct apr_rx_buf and use struct_size()
soc: qcom: pmic_glink: fix connector type to be DisplayPort
soc: ti: k3-socinfo: Avoid overriding return value
soc: ti: k3-socinfo: Fix typo in bitfield documentation
soc: ti: knav_qmss_queue: Use device_get_match_data()
firmware: ti_sci: Use device_get_match_data()
firmware: qcom: qseecom: add missing include guards
soc/pxa: ssp: Convert to platform remove callback returning void
soc/mediatek: mtk-mmsys: Convert to platform remove callback returning void
soc/mediatek: mtk-devapc: Convert to platform remove callback returning void
soc/loongson: loongson2_guts: Convert to platform remove callback returning void
soc/litex: litex_soc_ctrl: Convert to platform remove callback returning void
soc/ixp4xx: ixp4xx-qmgr: Convert to platform remove callback returning void
soc/ixp4xx: ixp4xx-npe: Convert to platform remove callback returning void
soc/hisilicon: kunpeng_hccs: Convert to platform remove callback returning void
...
This commit is contained in:
@@ -309,7 +309,9 @@ properties:
|
||||
power-domains property.
|
||||
|
||||
For PSCI based platforms, the name corresponding to the index of the PSCI
|
||||
PM domain provider, must be "psci".
|
||||
PM domain provider, must be "psci". For SCMI based platforms, the name
|
||||
corresponding to the index of an SCMI performance domain provider, must be
|
||||
"perf".
|
||||
|
||||
qcom,saw:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
@@ -20,6 +20,7 @@ description: |
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qdu1000-llcc
|
||||
- qcom,sc7180-llcc
|
||||
- qcom,sc7280-llcc
|
||||
- qcom,sc8180x-llcc
|
||||
@@ -44,6 +45,14 @@ properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
nvmem-cells:
|
||||
items:
|
||||
- description: Reference to an nvmem node for multi channel DDR
|
||||
|
||||
nvmem-cell-names:
|
||||
items:
|
||||
- const: multi-chan-ddr
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@@ -92,6 +101,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qdu1000-llcc
|
||||
- qcom,sc8180x-llcc
|
||||
- qcom,sc8280xp-llcc
|
||||
then:
|
||||
|
||||
@@ -38,6 +38,9 @@ properties:
|
||||
with shmem address(4KB-page, offset) as parameters
|
||||
items:
|
||||
- const: arm,scmi-smc-param
|
||||
- description: SCMI compliant firmware with Qualcomm SMC/HVC transport
|
||||
items:
|
||||
- const: qcom,scmi-smc
|
||||
- description: SCMI compliant firmware with SCMI Virtio transport.
|
||||
The virtio transport only supports a single device.
|
||||
items:
|
||||
@@ -149,8 +152,15 @@ properties:
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- '#clock-cells'
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- '#clock-cells'
|
||||
|
||||
- required:
|
||||
- '#power-domain-cells'
|
||||
|
||||
protocol@14:
|
||||
$ref: '#/$defs/protocol-node'
|
||||
@@ -306,6 +316,7 @@ else:
|
||||
enum:
|
||||
- arm,scmi-smc
|
||||
- arm,scmi-smc-param
|
||||
- qcom,scmi-smc
|
||||
then:
|
||||
required:
|
||||
- arm,smc-id
|
||||
|
||||
@@ -24,6 +24,7 @@ properties:
|
||||
- qcom,scm-apq8064
|
||||
- qcom,scm-apq8084
|
||||
- qcom,scm-ipq4019
|
||||
- qcom,scm-ipq5018
|
||||
- qcom,scm-ipq5332
|
||||
- qcom,scm-ipq6018
|
||||
- qcom,scm-ipq806x
|
||||
@@ -56,6 +57,7 @@ properties:
|
||||
- qcom,scm-sm6125
|
||||
- qcom,scm-sm6350
|
||||
- qcom,scm-sm6375
|
||||
- qcom,scm-sm7150
|
||||
- qcom,scm-sm8150
|
||||
- qcom,scm-sm8250
|
||||
- qcom,scm-sm8350
|
||||
@@ -89,6 +91,14 @@ properties:
|
||||
protocol to handle sleeping SCM calls.
|
||||
maxItems: 1
|
||||
|
||||
qcom,sdi-enabled:
|
||||
description:
|
||||
Indicates that the SDI (Secure Debug Image) has been enabled by TZ
|
||||
by default and it needs to be disabled.
|
||||
If not disabled WDT assertion or reboot will cause the board to hang
|
||||
in the debug mode.
|
||||
type: boolean
|
||||
|
||||
qcom,dload-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
|
||||
@@ -40,6 +40,7 @@ patternProperties:
|
||||
".*@[0-9]+$":
|
||||
type: object
|
||||
$ref: mc-peripheral-props.yaml#
|
||||
additionalProperties: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
@@ -80,6 +80,8 @@ properties:
|
||||
patternProperties:
|
||||
"flash@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
|
||||
@@ -130,7 +130,7 @@ patternProperties:
|
||||
bus. The device can be a NAND chip, SRAM device, NOR device
|
||||
or an ASIC.
|
||||
$ref: ti,gpmc-child.yaml
|
||||
|
||||
additionalProperties: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
@@ -13,8 +13,9 @@ maintainers:
|
||||
|
||||
description: |+
|
||||
System on chip designs are often divided into multiple PM domains that can be
|
||||
used for power gating of selected IP blocks for power saving by reduced leakage
|
||||
current.
|
||||
used for power gating of selected IP blocks for power saving by reduced
|
||||
leakage current. Moreover, in some cases the similar PM domains may also be
|
||||
capable of scaling performance for a group of IP blocks.
|
||||
|
||||
This device tree binding can be used to bind PM domain consumer devices with
|
||||
their PM domains provided by PM domain providers. A PM domain provider can be
|
||||
@@ -25,7 +26,7 @@ description: |+
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^(power-controller|power-domain)([@-].*)?$"
|
||||
pattern: "^(power-controller|power-domain|performance-domain)([@-].*)?$"
|
||||
|
||||
domain-idle-states:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
@@ -44,11 +45,11 @@ properties:
|
||||
|
||||
operating-points-v2:
|
||||
description:
|
||||
Phandles to the OPP tables of power domains provided by a power domain
|
||||
provider. If the provider provides a single power domain only or all
|
||||
the power domains provided by the provider have identical OPP tables,
|
||||
then this shall contain a single phandle. Refer to ../opp/opp-v2-base.yaml
|
||||
for more information.
|
||||
Phandles to the OPP tables of power domains that are capable of scaling
|
||||
performance, provided by a power domain provider. If the provider provides
|
||||
a single power domain only or all the power domains provided by the
|
||||
provider have identical OPP tables, then this shall contain a single
|
||||
phandle. Refer to ../opp/opp-v2-base.yaml for more information.
|
||||
|
||||
"#power-domain-cells":
|
||||
description:
|
||||
|
||||
@@ -26,6 +26,17 @@ properties:
|
||||
description: >
|
||||
identifier of the client to use this region for buffers
|
||||
|
||||
qcom,use-guard-pages:
|
||||
type: boolean
|
||||
description: >
|
||||
Indicates that the firmware, or hardware, does not gracefully handle
|
||||
memory protection of this region when placed adjacent to other protected
|
||||
memory regions, and that padding around the used portion of the memory
|
||||
region is necessary.
|
||||
|
||||
When this is set, the first and last page should be left unused, and the
|
||||
effective size of the region will thereby shrink with two pages.
|
||||
|
||||
qcom,vmid:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description: >
|
||||
|
||||
@@ -22,6 +22,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt8183-svs
|
||||
- mediatek,mt8188-svs
|
||||
- mediatek,mt8192-svs
|
||||
|
||||
reg:
|
||||
|
||||
@@ -52,6 +52,8 @@ properties:
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
dma-coherent: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
+13
@@ -17894,6 +17894,18 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
|
||||
F: drivers/mtd/nand/raw/qcom_nandc.c
|
||||
|
||||
QUALCOMM QSEECOM DRIVER
|
||||
M: Maximilian Luz <luzmaximilian@gmail.com>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/firmware/qcom/qcom_qseecom.c
|
||||
|
||||
QUALCOMM QSEECOM UEFISECAPP DRIVER
|
||||
M: Maximilian Luz <luzmaximilian@gmail.com>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
|
||||
|
||||
QUALCOMM RMNET DRIVER
|
||||
M: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
|
||||
M: Sean Tranchetti <quic_stranche@quicinc.com>
|
||||
@@ -21003,6 +21015,7 @@ F: drivers/clk/clk-sc[mp]i.c
|
||||
F: drivers/cpufreq/sc[mp]i-cpufreq.c
|
||||
F: drivers/firmware/arm_scmi/
|
||||
F: drivers/firmware/arm_scpi.c
|
||||
F: drivers/pmdomain/arm/
|
||||
F: drivers/powercap/arm_scmi_powercap.c
|
||||
F: drivers/regulator/scmi-regulator.c
|
||||
F: drivers/reset/reset-scmi.c
|
||||
|
||||
@@ -423,6 +423,7 @@ static __always_inline void do_ffa_mem_xfer(const u64 func_id,
|
||||
DECLARE_REG(u32, fraglen, ctxt, 2);
|
||||
DECLARE_REG(u64, addr_mbz, ctxt, 3);
|
||||
DECLARE_REG(u32, npages_mbz, ctxt, 4);
|
||||
struct ffa_mem_region_attributes *ep_mem_access;
|
||||
struct ffa_composite_mem_region *reg;
|
||||
struct ffa_mem_region *buf;
|
||||
u32 offset, nr_ranges;
|
||||
@@ -452,7 +453,9 @@ static __always_inline void do_ffa_mem_xfer(const u64 func_id,
|
||||
buf = hyp_buffers.tx;
|
||||
memcpy(buf, host_buffers.tx, fraglen);
|
||||
|
||||
offset = buf->ep_mem_access[0].composite_off;
|
||||
ep_mem_access = (void *)buf +
|
||||
ffa_mem_desc_offset(buf, 0, FFA_VERSION_1_0);
|
||||
offset = ep_mem_access->composite_off;
|
||||
if (!offset || buf->ep_count != 1 || buf->sender_id != HOST_FFA_ID) {
|
||||
ret = FFA_RET_INVALID_PARAMETERS;
|
||||
goto out_unlock;
|
||||
@@ -504,6 +507,7 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
|
||||
DECLARE_REG(u32, handle_lo, ctxt, 1);
|
||||
DECLARE_REG(u32, handle_hi, ctxt, 2);
|
||||
DECLARE_REG(u32, flags, ctxt, 3);
|
||||
struct ffa_mem_region_attributes *ep_mem_access;
|
||||
struct ffa_composite_mem_region *reg;
|
||||
u32 offset, len, fraglen, fragoff;
|
||||
struct ffa_mem_region *buf;
|
||||
@@ -528,7 +532,9 @@ static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
|
||||
len = res->a1;
|
||||
fraglen = res->a2;
|
||||
|
||||
offset = buf->ep_mem_access[0].composite_off;
|
||||
ep_mem_access = (void *)buf +
|
||||
ffa_mem_desc_offset(buf, 0, FFA_VERSION_1_0);
|
||||
offset = ep_mem_access->composite_off;
|
||||
/*
|
||||
* We can trust the SPMD to get this right, but let's at least
|
||||
* check that we end up with something that doesn't look _completely_
|
||||
|
||||
@@ -34,6 +34,7 @@ config SOC_STARFIVE
|
||||
bool "StarFive SoCs"
|
||||
select PINCTRL
|
||||
select RESET_CONTROLLER
|
||||
select ARM_AMBA
|
||||
help
|
||||
This enables support for StarFive SoC platform hardware.
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
|
||||
#define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
|
||||
#define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
|
||||
#define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
|
||||
#define genpd_is_opp_table_fw(genpd) (genpd->flags & GENPD_FLAG_OPP_TABLE_FW)
|
||||
|
||||
static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
|
||||
const struct generic_pm_domain *genpd)
|
||||
@@ -2337,7 +2338,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
|
||||
genpd->dev.of_node = np;
|
||||
|
||||
/* Parse genpd OPP table */
|
||||
if (genpd->set_performance_state) {
|
||||
if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
|
||||
ret = dev_pm_opp_of_add_table(&genpd->dev);
|
||||
if (ret)
|
||||
return dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n");
|
||||
@@ -2352,7 +2353,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
|
||||
|
||||
ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
|
||||
if (ret) {
|
||||
if (genpd->set_performance_state) {
|
||||
if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
|
||||
dev_pm_opp_put_opp_table(genpd->opp_table);
|
||||
dev_pm_opp_of_remove_table(&genpd->dev);
|
||||
}
|
||||
@@ -2396,7 +2397,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
|
||||
genpd->dev.of_node = np;
|
||||
|
||||
/* Parse genpd OPP table */
|
||||
if (genpd->set_performance_state) {
|
||||
if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
|
||||
ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i);
|
||||
if (ret) {
|
||||
dev_err_probe(&genpd->dev, ret,
|
||||
@@ -2432,7 +2433,7 @@ error:
|
||||
genpd->provider = NULL;
|
||||
genpd->has_provider = false;
|
||||
|
||||
if (genpd->set_performance_state) {
|
||||
if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
|
||||
dev_pm_opp_put_opp_table(genpd->opp_table);
|
||||
dev_pm_opp_of_remove_table(&genpd->dev);
|
||||
}
|
||||
@@ -2464,7 +2465,7 @@ void of_genpd_del_provider(struct device_node *np)
|
||||
if (gpd->provider == &np->fwnode) {
|
||||
gpd->has_provider = false;
|
||||
|
||||
if (!gpd->set_performance_state)
|
||||
if (genpd_is_opp_table_fw(gpd) || !gpd->set_performance_state)
|
||||
continue;
|
||||
|
||||
dev_pm_opp_put_opp_table(gpd->opp_table);
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ config ARM_INTEGRATOR_LM
|
||||
|
||||
config BRCMSTB_GISB_ARB
|
||||
tristate "Broadcom STB GISB bus arbiter"
|
||||
depends on ARM || ARM64 || MIPS
|
||||
depends on ARCH_BRCMSTB || BMIPS_GENERIC
|
||||
default ARCH_BRCMSTB || BMIPS_GENERIC
|
||||
help
|
||||
Driver for the Broadcom Set Top Box System-on-a-chip internal bus
|
||||
|
||||
@@ -54,7 +54,7 @@ struct vexpress_syscfg_func {
|
||||
struct vexpress_syscfg *syscfg;
|
||||
struct regmap *regmap;
|
||||
int num_templates;
|
||||
u32 template[]; /* Keep it last! */
|
||||
u32 template[] __counted_by(num_templates); /* Keep it last! */
|
||||
};
|
||||
|
||||
struct vexpress_config_bridge_ops {
|
||||
|
||||
+88
-8
@@ -13,13 +13,18 @@
|
||||
#include <linux/scmi_protocol.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#define NOT_ATOMIC false
|
||||
#define ATOMIC true
|
||||
|
||||
static const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
|
||||
|
||||
struct scmi_clk {
|
||||
u32 id;
|
||||
struct device *dev;
|
||||
struct clk_hw hw;
|
||||
const struct scmi_clock_info *info;
|
||||
const struct scmi_protocol_handle *ph;
|
||||
struct clk_parent_data *parent_data;
|
||||
};
|
||||
|
||||
#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
|
||||
@@ -74,38 +79,89 @@ static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return scmi_proto_clk_ops->rate_set(clk->ph, clk->id, rate);
|
||||
}
|
||||
|
||||
static int scmi_clk_set_parent(struct clk_hw *hw, u8 parent_index)
|
||||
{
|
||||
struct scmi_clk *clk = to_scmi_clk(hw);
|
||||
|
||||
return scmi_proto_clk_ops->parent_set(clk->ph, clk->id, parent_index);
|
||||
}
|
||||
|
||||
static u8 scmi_clk_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct scmi_clk *clk = to_scmi_clk(hw);
|
||||
u32 parent_id, p_idx;
|
||||
int ret;
|
||||
|
||||
ret = scmi_proto_clk_ops->parent_get(clk->ph, clk->id, &parent_id);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
for (p_idx = 0; p_idx < clk->info->num_parents; p_idx++) {
|
||||
if (clk->parent_data[p_idx].index == parent_id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_idx == clk->info->num_parents)
|
||||
return 0;
|
||||
|
||||
return p_idx;
|
||||
}
|
||||
|
||||
static int scmi_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
|
||||
{
|
||||
/*
|
||||
* Suppose all the requested rates are supported, and let firmware
|
||||
* to handle the left work.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scmi_clk_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct scmi_clk *clk = to_scmi_clk(hw);
|
||||
|
||||
return scmi_proto_clk_ops->enable(clk->ph, clk->id);
|
||||
return scmi_proto_clk_ops->enable(clk->ph, clk->id, NOT_ATOMIC);
|
||||
}
|
||||
|
||||
static void scmi_clk_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct scmi_clk *clk = to_scmi_clk(hw);
|
||||
|
||||
scmi_proto_clk_ops->disable(clk->ph, clk->id);
|
||||
scmi_proto_clk_ops->disable(clk->ph, clk->id, NOT_ATOMIC);
|
||||
}
|
||||
|
||||
static int scmi_clk_atomic_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct scmi_clk *clk = to_scmi_clk(hw);
|
||||
|
||||
return scmi_proto_clk_ops->enable_atomic(clk->ph, clk->id);
|
||||
return scmi_proto_clk_ops->enable(clk->ph, clk->id, ATOMIC);
|
||||
}
|
||||
|
||||
static void scmi_clk_atomic_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct scmi_clk *clk = to_scmi_clk(hw);
|
||||
|
||||
scmi_proto_clk_ops->disable_atomic(clk->ph, clk->id);
|
||||
scmi_proto_clk_ops->disable(clk->ph, clk->id, ATOMIC);
|
||||
}
|
||||
|
||||
static int scmi_clk_atomic_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
int ret;
|
||||
bool enabled = false;
|
||||
struct scmi_clk *clk = to_scmi_clk(hw);
|
||||
|
||||
ret = scmi_proto_clk_ops->state_get(clk->ph, clk->id, &enabled, ATOMIC);
|
||||
if (ret)
|
||||
dev_warn(clk->dev,
|
||||
"Failed to get state for clock ID %d\n", clk->id);
|
||||
|
||||
return !!enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can provide enable/disable atomic callbacks only if the underlying SCMI
|
||||
* transport for an SCMI instance is configured to handle SCMI commands in an
|
||||
* atomic manner.
|
||||
* We can provide enable/disable/is_enabled atomic callbacks only if the
|
||||
* underlying SCMI transport for an SCMI instance is configured to handle
|
||||
* SCMI commands in an atomic manner.
|
||||
*
|
||||
* When no SCMI atomic transport support is available we instead provide only
|
||||
* the prepare/unprepare API, as allowed by the clock framework when atomic
|
||||
@@ -121,6 +177,9 @@ static const struct clk_ops scmi_clk_ops = {
|
||||
.set_rate = scmi_clk_set_rate,
|
||||
.prepare = scmi_clk_enable,
|
||||
.unprepare = scmi_clk_disable,
|
||||
.set_parent = scmi_clk_set_parent,
|
||||
.get_parent = scmi_clk_get_parent,
|
||||
.determine_rate = scmi_clk_determine_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops scmi_atomic_clk_ops = {
|
||||
@@ -129,6 +188,10 @@ static const struct clk_ops scmi_atomic_clk_ops = {
|
||||
.set_rate = scmi_clk_set_rate,
|
||||
.enable = scmi_clk_atomic_enable,
|
||||
.disable = scmi_clk_atomic_disable,
|
||||
.is_enabled = scmi_clk_atomic_is_enabled,
|
||||
.set_parent = scmi_clk_set_parent,
|
||||
.get_parent = scmi_clk_get_parent,
|
||||
.determine_rate = scmi_clk_determine_rate,
|
||||
};
|
||||
|
||||
static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
|
||||
@@ -139,9 +202,10 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
|
||||
|
||||
struct clk_init_data init = {
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.num_parents = 0,
|
||||
.num_parents = sclk->info->num_parents,
|
||||
.ops = scmi_ops,
|
||||
.name = sclk->info->name,
|
||||
.parent_data = sclk->parent_data,
|
||||
};
|
||||
|
||||
sclk->hw.init = &init;
|
||||
@@ -213,11 +277,13 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
|
||||
sclk->info = scmi_proto_clk_ops->info_get(ph, idx);
|
||||
if (!sclk->info) {
|
||||
dev_dbg(dev, "invalid clock info for idx %d\n", idx);
|
||||
devm_kfree(dev, sclk);
|
||||
continue;
|
||||
}
|
||||
|
||||
sclk->id = idx;
|
||||
sclk->ph = ph;
|
||||
sclk->dev = dev;
|
||||
|
||||
/*
|
||||
* Note that when transport is atomic but SCMI protocol did not
|
||||
@@ -230,9 +296,23 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
|
||||
else
|
||||
scmi_ops = &scmi_clk_ops;
|
||||
|
||||
/* Initialize clock parent data. */
|
||||
if (sclk->info->num_parents > 0) {
|
||||
sclk->parent_data = devm_kcalloc(dev, sclk->info->num_parents,
|
||||
sizeof(*sclk->parent_data), GFP_KERNEL);
|
||||
if (!sclk->parent_data)
|
||||
return -ENOMEM;
|
||||
|
||||
for (int i = 0; i < sclk->info->num_parents; i++) {
|
||||
sclk->parent_data[i].index = sclk->info->parents[i];
|
||||
sclk->parent_data[i].hw = hws[sclk->info->parents[i]];
|
||||
}
|
||||
}
|
||||
|
||||
err = scmi_clk_ops_init(dev, sclk, scmi_ops);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to register clock %d\n", idx);
|
||||
devm_kfree(dev, sclk->parent_data);
|
||||
devm_kfree(dev, sclk);
|
||||
hws[idx] = NULL;
|
||||
} else {
|
||||
|
||||
@@ -70,15 +70,35 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
|
||||
static int scmi_cpu_domain_id(struct device *cpu_dev)
|
||||
{
|
||||
int cpu, domain, tdomain;
|
||||
struct device *tcpu_dev;
|
||||
struct device_node *np = cpu_dev->of_node;
|
||||
struct of_phandle_args domain_id;
|
||||
int index;
|
||||
|
||||
domain = perf_ops->device_domain_id(cpu_dev);
|
||||
if (domain < 0)
|
||||
return domain;
|
||||
if (of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
|
||||
&domain_id)) {
|
||||
/* Find the corresponding index for power-domain "perf". */
|
||||
index = of_property_match_string(np, "power-domain-names",
|
||||
"perf");
|
||||
if (index < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (of_parse_phandle_with_args(np, "power-domains",
|
||||
"#power-domain-cells", index,
|
||||
&domain_id))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return domain_id.args[0];
|
||||
}
|
||||
|
||||
static int
|
||||
scmi_get_sharing_cpus(struct device *cpu_dev, int domain,
|
||||
struct cpumask *cpumask)
|
||||
{
|
||||
int cpu, tdomain;
|
||||
struct device *tcpu_dev;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (cpu == cpu_dev->id)
|
||||
@@ -88,7 +108,7 @@ scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
|
||||
if (!tcpu_dev)
|
||||
continue;
|
||||
|
||||
tdomain = perf_ops->device_domain_id(tcpu_dev);
|
||||
tdomain = scmi_cpu_domain_id(tcpu_dev);
|
||||
if (tdomain == domain)
|
||||
cpumask_set_cpu(cpu, cpumask);
|
||||
}
|
||||
@@ -104,7 +124,7 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
|
||||
unsigned long Hz;
|
||||
int ret, domain;
|
||||
|
||||
domain = perf_ops->device_domain_id(cpu_dev);
|
||||
domain = scmi_cpu_domain_id(cpu_dev);
|
||||
if (domain < 0)
|
||||
return domain;
|
||||
|
||||
@@ -126,7 +146,7 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
|
||||
|
||||
static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int ret, nr_opp;
|
||||
int ret, nr_opp, domain;
|
||||
unsigned int latency;
|
||||
struct device *cpu_dev;
|
||||
struct scmi_data *priv;
|
||||
@@ -138,6 +158,10 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
domain = scmi_cpu_domain_id(cpu_dev);
|
||||
if (domain < 0)
|
||||
return domain;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
@@ -148,7 +172,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
}
|
||||
|
||||
/* Obtain CPUs that share SCMI performance controls */
|
||||
ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
|
||||
ret = scmi_get_sharing_cpus(cpu_dev, domain, policy->cpus);
|
||||
if (ret) {
|
||||
dev_warn(cpu_dev, "failed to get sharing cpumask\n");
|
||||
goto out_free_cpumask;
|
||||
@@ -176,7 +200,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
*/
|
||||
nr_opp = dev_pm_opp_get_opp_count(cpu_dev);
|
||||
if (nr_opp <= 0) {
|
||||
ret = perf_ops->device_opps_add(ph, cpu_dev);
|
||||
ret = perf_ops->device_opps_add(ph, cpu_dev, domain);
|
||||
if (ret) {
|
||||
dev_warn(cpu_dev, "failed to add opps to the device\n");
|
||||
goto out_free_cpumask;
|
||||
@@ -209,7 +233,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
}
|
||||
|
||||
priv->cpu_dev = cpu_dev;
|
||||
priv->domain_id = perf_ops->device_domain_id(cpu_dev);
|
||||
priv->domain_id = domain;
|
||||
|
||||
policy->driver_data = priv;
|
||||
policy->freq_table = freq_table;
|
||||
@@ -217,14 +241,14 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
|
||||
/* SCMI allows DVFS request for any domain from any CPU */
|
||||
policy->dvfs_possible_from_any_cpu = true;
|
||||
|
||||
latency = perf_ops->transition_latency_get(ph, cpu_dev);
|
||||
latency = perf_ops->transition_latency_get(ph, domain);
|
||||
if (!latency)
|
||||
latency = CPUFREQ_ETERNAL;
|
||||
|
||||
policy->cpuinfo.transition_latency = latency;
|
||||
|
||||
policy->fast_switch_possible =
|
||||
perf_ops->fast_switch_possible(ph, cpu_dev);
|
||||
perf_ops->fast_switch_possible(ph, domain);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -212,20 +212,6 @@ config MTK_ADSP_IPC
|
||||
ADSP exists on some mtk processors.
|
||||
Client might use shared memory to exchange information with ADSP.
|
||||
|
||||
config QCOM_SCM
|
||||
tristate
|
||||
|
||||
config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
|
||||
bool "Qualcomm download mode enabled by default"
|
||||
depends on QCOM_SCM
|
||||
help
|
||||
A device with "download mode" enabled will upon an unexpected
|
||||
warm-restart enter a special debug mode that allows the user to
|
||||
"download" memory content over USB for offline postmortem analysis.
|
||||
The feature can be enabled/disabled on the kernel command line.
|
||||
|
||||
Say Y here to enable "download mode" by default.
|
||||
|
||||
config SYSFB
|
||||
bool
|
||||
select BOOT_VESA_SUPPORT
|
||||
@@ -311,6 +297,7 @@ source "drivers/firmware/efi/Kconfig"
|
||||
source "drivers/firmware/imx/Kconfig"
|
||||
source "drivers/firmware/meson/Kconfig"
|
||||
source "drivers/firmware/psci/Kconfig"
|
||||
source "drivers/firmware/qcom/Kconfig"
|
||||
source "drivers/firmware/smccc/Kconfig"
|
||||
source "drivers/firmware/tegra/Kconfig"
|
||||
source "drivers/firmware/xilinx/Kconfig"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user