mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 16:29:05 +00:00
i.MX drivers change for 5.9:
- Update SCU irq code to call pm_system_wakeup() in general MU IRQ handler, so that system can be waked up when MU IRQ arrives. - Move i.MX SCU soc driver into imx firmware folder to get it initialized from i.MX SCU firmware driver. - Clean up soc-imx-scu driver a bit by using devm_kasprintf(). - Correct postfix setting for cm40 power domain in scu-pd driver. - Add resource management support for IMX_SCU firmware driver. - Add more cm4 resources to i.MX SCU power domain driver. - Select ARM_GIC_V3 from SOC_IMX8M for being able to use GICv3 driver in AARCH32 mode Linux on AARCH64 hardware. -----BEGIN PGP SIGNATURE----- iQFIBAABCgAyFiEEFmJXigPl4LoGSz08UFdYWoewfM4FAl8VPiUUHHNoYXduZ3Vv QGtlcm5lbC5vcmcACgkQUFdYWoewfM5L9wf/VY0Q2oZ+gaJRNhSfVSf7O7QpscHV mtQZPHg81jv3D2NkOpycJ1vaJEo118Ho6vb5IfeheChyZ2eWEJKkaPpVuhyKjPhK B+nUmFnsTm8MTL+GKA1W7g6Gg+lJN3wT/mOITNmGMW0NID4/rse/XeM18+28nNb/ 2svVyc1+4uTM5m+4i+scBCdnxgBK2H71/DQYLfDvNtZesWzas1PNN1nJh10D/PMM X6d7AZ92c//pf5eR3wpm/JKZ+hubefBNWkrpw50pNlAASbgOogXWL1GU9q3r/VAV 9dS0dW9mIlpqlONEO+2zv9v1/RnoUypkCe/FFTUsA1bJ7ZGqhxWmrYwyfg== =7Pd6 -----END PGP SIGNATURE----- Merge tag 'imx-drivers-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers i.MX drivers change for 5.9: - Update SCU irq code to call pm_system_wakeup() in general MU IRQ handler, so that system can be waked up when MU IRQ arrives. - Move i.MX SCU soc driver into imx firmware folder to get it initialized from i.MX SCU firmware driver. - Clean up soc-imx-scu driver a bit by using devm_kasprintf(). - Correct postfix setting for cm40 power domain in scu-pd driver. - Add resource management support for IMX_SCU firmware driver. - Add more cm4 resources to i.MX SCU power domain driver. - Select ARM_GIC_V3 from SOC_IMX8M for being able to use GICv3 driver in AARCH32 mode Linux on AARCH64 hardware. * tag 'imx-drivers-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux: soc: imx: select ARM_GIC_V3 for i.MX8M firmware: imx: Move i.MX SCU soc driver into imx firmware folder firmware: imx: scu-pd: add more cm4 resources firmware: imx: add resource management api firmware: imx: scu-pd: fix cm40 power domain soc: imx: scu: use devm_kasprintf firmware: imx: make sure MU irq can wake up system from suspend mode Link: https://lore.kernel.org/r/20200720085536.24138-1-shawnguo@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
e2837df668
@ -850,7 +850,6 @@ CONFIG_OWL_PM_DOMAINS=y
|
||||
CONFIG_RASPBERRYPI_POWER=y
|
||||
CONFIG_FSL_DPAA=y
|
||||
CONFIG_FSL_MC_DPIO=y
|
||||
CONFIG_IMX_SCU_SOC=y
|
||||
CONFIG_QCOM_AOSS_QMP=y
|
||||
CONFIG_QCOM_GENI_SE=y
|
||||
CONFIG_QCOM_RMTFS_MEM=m
|
||||
|
@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_IMX_DSP) += imx-dsp.o
|
||||
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o
|
||||
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
|
||||
obj-$(CONFIG_IMX_SCU_PD) += scu-pd.o
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/firmware/imx/ipc.h>
|
||||
#include <linux/firmware/imx/sci.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#define IMX_SC_IRQ_FUNC_ENABLE 1
|
||||
#define IMX_SC_IRQ_FUNC_STATUS 2
|
||||
@ -91,6 +92,7 @@ static void imx_scu_irq_work_handler(struct work_struct *work)
|
||||
if (!irq_status)
|
||||
continue;
|
||||
|
||||
pm_system_wakeup();
|
||||
imx_scu_irq_notifier_call_chain(irq_status, &i);
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#define IMX_SCU_SOC_DRIVER_NAME "imx-scu-soc"
|
||||
|
||||
static struct imx_sc_ipc *soc_ipc_handle;
|
||||
static struct imx_sc_ipc *imx_sc_soc_ipc_handle;
|
||||
|
||||
struct imx_sc_msg_misc_get_soc_id {
|
||||
struct imx_sc_rpc_msg hdr;
|
||||
@ -44,7 +42,7 @@ static int imx_scu_soc_uid(u64 *soc_uid)
|
||||
hdr->func = IMX_SC_MISC_FUNC_UNIQUE_ID;
|
||||
hdr->size = 1;
|
||||
|
||||
ret = imx_scu_call_rpc(soc_ipc_handle, &msg, true);
|
||||
ret = imx_scu_call_rpc(imx_sc_soc_ipc_handle, &msg, true);
|
||||
if (ret) {
|
||||
pr_err("%s: get soc uid failed, ret %d\n", __func__, ret);
|
||||
return ret;
|
||||
@ -71,7 +69,7 @@ static int imx_scu_soc_id(void)
|
||||
msg.data.req.control = IMX_SC_C_ID;
|
||||
msg.data.req.resource = IMX_SC_R_SYSTEM;
|
||||
|
||||
ret = imx_scu_call_rpc(soc_ipc_handle, &msg, true);
|
||||
ret = imx_scu_call_rpc(imx_sc_soc_ipc_handle, &msg, true);
|
||||
if (ret) {
|
||||
pr_err("%s: get soc info failed, ret %d\n", __func__, ret);
|
||||
return ret;
|
||||
@ -80,7 +78,7 @@ static int imx_scu_soc_id(void)
|
||||
return msg.data.resp.id;
|
||||
}
|
||||
|
||||
static int imx_scu_soc_probe(struct platform_device *pdev)
|
||||
int imx_scu_soc_init(struct device *dev)
|
||||
{
|
||||
struct soc_device_attribute *soc_dev_attr;
|
||||
struct soc_device *soc_dev;
|
||||
@ -88,11 +86,11 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
|
||||
u64 uid = 0;
|
||||
u32 val;
|
||||
|
||||
ret = imx_scu_get_handle(&soc_ipc_handle);
|
||||
ret = imx_scu_get_handle(&imx_sc_soc_ipc_handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr),
|
||||
soc_dev_attr = devm_kzalloc(dev, sizeof(*soc_dev_attr),
|
||||
GFP_KERNEL);
|
||||
if (!soc_dev_attr)
|
||||
return -ENOMEM;
|
||||
@ -115,73 +113,26 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
|
||||
|
||||
/* format soc_id value passed from SCU firmware */
|
||||
val = id & 0x1f;
|
||||
soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x", val);
|
||||
soc_dev_attr->soc_id = devm_kasprintf(dev, GFP_KERNEL, "0x%x", val);
|
||||
if (!soc_dev_attr->soc_id)
|
||||
return -ENOMEM;
|
||||
|
||||
/* format revision value passed from SCU firmware */
|
||||
val = (id >> 5) & 0xf;
|
||||
val = (((val >> 2) + 1) << 4) | (val & 0x3);
|
||||
soc_dev_attr->revision = kasprintf(GFP_KERNEL,
|
||||
"%d.%d",
|
||||
(val >> 4) & 0xf,
|
||||
val & 0xf);
|
||||
if (!soc_dev_attr->revision) {
|
||||
ret = -ENOMEM;
|
||||
goto free_soc_id;
|
||||
}
|
||||
soc_dev_attr->revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
|
||||
(val >> 4) & 0xf, val & 0xf);
|
||||
if (!soc_dev_attr->revision)
|
||||
return -ENOMEM;
|
||||
|
||||
soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", uid);
|
||||
if (!soc_dev_attr->serial_number) {
|
||||
ret = -ENOMEM;
|
||||
goto free_revision;
|
||||
}
|
||||
soc_dev_attr->serial_number = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%016llX", uid);
|
||||
if (!soc_dev_attr->serial_number)
|
||||
return -ENOMEM;
|
||||
|
||||
soc_dev = soc_device_register(soc_dev_attr);
|
||||
if (IS_ERR(soc_dev)) {
|
||||
ret = PTR_ERR(soc_dev);
|
||||
goto free_serial_number;
|
||||
}
|
||||
if (IS_ERR(soc_dev))
|
||||
return PTR_ERR(soc_dev);
|
||||
|
||||
return 0;
|
||||
|
||||
free_serial_number:
|
||||
kfree(soc_dev_attr->serial_number);
|
||||
free_revision:
|
||||
kfree(soc_dev_attr->revision);
|
||||
free_soc_id:
|
||||
kfree(soc_dev_attr->soc_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver imx_scu_soc_driver = {
|
||||
.driver = {
|
||||
.name = IMX_SCU_SOC_DRIVER_NAME,
|
||||
},
|
||||
.probe = imx_scu_soc_probe,
|
||||
};
|
||||
|
||||
static int __init imx_scu_soc_init(void)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct device_node *np;
|
||||
int ret;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx-scu");
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
ret = platform_driver_register(&imx_scu_soc_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pdev = platform_device_register_simple(IMX_SCU_SOC_DRIVER_NAME,
|
||||
-1, NULL, 0);
|
||||
if (IS_ERR(pdev))
|
||||
platform_driver_unregister(&imx_scu_soc_driver);
|
||||
|
||||
return PTR_ERR_OR_ZERO(pdev);
|
||||
}
|
||||
device_initcall(imx_scu_soc_init);
|
@ -328,6 +328,10 @@ static int imx_scu_probe(struct platform_device *pdev)
|
||||
|
||||
imx_sc_ipc_handle = sc_ipc;
|
||||
|
||||
ret = imx_scu_soc_init(dev);
|
||||
if (ret)
|
||||
dev_warn(dev, "failed to initialize SoC info: %d\n", ret);
|
||||
|
||||
ret = imx_scu_enable_general_irq_channel(dev);
|
||||
if (ret)
|
||||
dev_warn(dev,
|
||||
|
45
drivers/firmware/imx/rm.c
Normal file
45
drivers/firmware/imx/rm.c
Normal file
@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 NXP
|
||||
*
|
||||
* File containing client-side RPC functions for the RM service. These
|
||||
* function are ported to clients that communicate to the SC.
|
||||
*/
|
||||
|
||||
#include <linux/firmware/imx/svc/rm.h>
|
||||
|
||||
struct imx_sc_msg_rm_rsrc_owned {
|
||||
struct imx_sc_rpc_msg hdr;
|
||||
u16 resource;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/*
|
||||
* This function check @resource is owned by current partition or not
|
||||
*
|
||||
* @param[in] ipc IPC handle
|
||||
* @param[in] resource resource the control is associated with
|
||||
*
|
||||
* @return Returns 0 for not owned and 1 for owned.
|
||||
*/
|
||||
bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
|
||||
{
|
||||
struct imx_sc_msg_rm_rsrc_owned msg;
|
||||
struct imx_sc_rpc_msg *hdr = &msg.hdr;
|
||||
|
||||
hdr->ver = IMX_SC_RPC_VERSION;
|
||||
hdr->svc = IMX_SC_RPC_SVC_RM;
|
||||
hdr->func = IMX_SC_RM_FUNC_IS_RESOURCE_OWNED;
|
||||
hdr->size = 2;
|
||||
|
||||
msg.resource = resource;
|
||||
|
||||
/*
|
||||
* SCU firmware only returns value 0 or 1
|
||||
* for resource owned check which means not owned or owned.
|
||||
* So it is always successful.
|
||||
*/
|
||||
imx_scu_call_rpc(ipc, &msg, true);
|
||||
|
||||
return hdr->func;
|
||||
}
|
||||
EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);
|
@ -167,8 +167,18 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
|
||||
{ "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, true, 0 },
|
||||
|
||||
/* CM40 SS */
|
||||
{ "cm40_i2c", IMX_SC_R_M4_0_I2C, 1, 0 },
|
||||
{ "cm40_intmux", IMX_SC_R_M4_0_INTMUX, 1, 0 },
|
||||
{ "cm40-i2c", IMX_SC_R_M4_0_I2C, 1, false, 0 },
|
||||
{ "cm40-intmux", IMX_SC_R_M4_0_INTMUX, 1, false, 0 },
|
||||
{ "cm40-pid", IMX_SC_R_M4_0_PID0, 5, true, 0},
|
||||
{ "cm40-mu-a1", IMX_SC_R_M4_0_MU_1A, 1, false, 0},
|
||||
{ "cm40-lpuart", IMX_SC_R_M4_0_UART, 1, false, 0},
|
||||
|
||||
/* CM41 SS */
|
||||
{ "cm41-i2c", IMX_SC_R_M4_1_I2C, 1, false, 0 },
|
||||
{ "cm41-intmux", IMX_SC_R_M4_1_INTMUX, 1, false, 0 },
|
||||
{ "cm41-pid", IMX_SC_R_M4_1_PID0, 5, true, 0},
|
||||
{ "cm41-mu-a1", IMX_SC_R_M4_1_MU_1A, 1, false, 0},
|
||||
{ "cm41-lpuart", IMX_SC_R_M4_1_UART, 1, false, 0},
|
||||
};
|
||||
|
||||
static const struct imx_sc_pd_soc imx8qxp_scu_pd = {
|
||||
|
@ -8,20 +8,12 @@ config IMX_GPCV2_PM_DOMAINS
|
||||
select PM_GENERIC_DOMAINS
|
||||
default y if SOC_IMX7D
|
||||
|
||||
config IMX_SCU_SOC
|
||||
bool "i.MX System Controller Unit SoC info support"
|
||||
depends on IMX_SCU
|
||||
select SOC_BUS
|
||||
help
|
||||
If you say yes here you get support for the NXP i.MX System
|
||||
Controller Unit SoC info module, it will provide the SoC info
|
||||
like SoC family, ID and revision etc.
|
||||
|
||||
config SOC_IMX8M
|
||||
bool "i.MX8M SoC family support"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
default ARCH_MXC && ARM64
|
||||
select SOC_BUS
|
||||
select ARM_GIC_V3 if ARCH_MXC
|
||||
help
|
||||
If you say yes here you get support for the NXP i.MX8M family
|
||||
support, it will provide the SoC info like SoC family,
|
||||
|
@ -5,4 +5,3 @@ endif
|
||||
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
|
||||
obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
|
||||
obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
|
||||
obj-$(CONFIG_IMX_SCU_SOC) += soc-imx-scu.o
|
||||
|
@ -14,9 +14,11 @@
|
||||
|
||||
#include <linux/firmware/imx/svc/misc.h>
|
||||
#include <linux/firmware/imx/svc/pm.h>
|
||||
#include <linux/firmware/imx/svc/rm.h>
|
||||
|
||||
int imx_scu_enable_general_irq_channel(struct device *dev);
|
||||
int imx_scu_irq_register_notifier(struct notifier_block *nb);
|
||||
int imx_scu_irq_unregister_notifier(struct notifier_block *nb);
|
||||
int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable);
|
||||
int imx_scu_soc_init(struct device *dev);
|
||||
#endif /* _SC_SCI_H */
|
||||
|
69
include/linux/firmware/imx/svc/rm.h
Normal file
69
include/linux/firmware/imx/svc/rm.h
Normal file
@ -0,0 +1,69 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017-2020 NXP
|
||||
*
|
||||
* Header file containing the public API for the System Controller (SC)
|
||||
* Resource Management (RM) function. This includes functions for
|
||||
* partitioning resources, pads, and memory regions.
|
||||
*
|
||||
* RM_SVC (SVC) Resource Management Service
|
||||
*
|
||||
* Module for the Resource Management (RM) service.
|
||||
*/
|
||||
|
||||
#ifndef _SC_RM_API_H
|
||||
#define _SC_RM_API_H
|
||||
|
||||
#include <linux/firmware/imx/sci.h>
|
||||
|
||||
/*
|
||||
* This type is used to indicate RPC RM function calls.
|
||||
*/
|
||||
enum imx_sc_rm_func {
|
||||
IMX_SC_RM_FUNC_UNKNOWN = 0,
|
||||
IMX_SC_RM_FUNC_PARTITION_ALLOC = 1,
|
||||
IMX_SC_RM_FUNC_SET_CONFIDENTIAL = 31,
|
||||
IMX_SC_RM_FUNC_PARTITION_FREE = 2,
|
||||
IMX_SC_RM_FUNC_GET_DID = 26,
|
||||
IMX_SC_RM_FUNC_PARTITION_STATIC = 3,
|
||||
IMX_SC_RM_FUNC_PARTITION_LOCK = 4,
|
||||
IMX_SC_RM_FUNC_GET_PARTITION = 5,
|
||||
IMX_SC_RM_FUNC_SET_PARENT = 6,
|
||||
IMX_SC_RM_FUNC_MOVE_ALL = 7,
|
||||
IMX_SC_RM_FUNC_ASSIGN_RESOURCE = 8,
|
||||
IMX_SC_RM_FUNC_SET_RESOURCE_MOVABLE = 9,
|
||||
IMX_SC_RM_FUNC_SET_SUBSYS_RSRC_MOVABLE = 28,
|
||||
IMX_SC_RM_FUNC_SET_MASTER_ATTRIBUTES = 10,
|
||||
IMX_SC_RM_FUNC_SET_MASTER_SID = 11,
|
||||
IMX_SC_RM_FUNC_SET_PERIPHERAL_PERMISSIONS = 12,
|
||||
IMX_SC_RM_FUNC_IS_RESOURCE_OWNED = 13,
|
||||
IMX_SC_RM_FUNC_GET_RESOURCE_OWNER = 33,
|
||||
IMX_SC_RM_FUNC_IS_RESOURCE_MASTER = 14,
|
||||
IMX_SC_RM_FUNC_IS_RESOURCE_PERIPHERAL = 15,
|
||||
IMX_SC_RM_FUNC_GET_RESOURCE_INFO = 16,
|
||||
IMX_SC_RM_FUNC_MEMREG_ALLOC = 17,
|
||||
IMX_SC_RM_FUNC_MEMREG_SPLIT = 29,
|
||||
IMX_SC_RM_FUNC_MEMREG_FRAG = 32,
|
||||
IMX_SC_RM_FUNC_MEMREG_FREE = 18,
|
||||
IMX_SC_RM_FUNC_FIND_MEMREG = 30,
|
||||
IMX_SC_RM_FUNC_ASSIGN_MEMREG = 19,
|
||||
IMX_SC_RM_FUNC_SET_MEMREG_PERMISSIONS = 20,
|
||||
IMX_SC_RM_FUNC_IS_MEMREG_OWNED = 21,
|
||||
IMX_SC_RM_FUNC_GET_MEMREG_INFO = 22,
|
||||
IMX_SC_RM_FUNC_ASSIGN_PAD = 23,
|
||||
IMX_SC_RM_FUNC_SET_PAD_MOVABLE = 24,
|
||||
IMX_SC_RM_FUNC_IS_PAD_OWNED = 25,
|
||||
IMX_SC_RM_FUNC_DUMP = 27,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_IMX_SCU)
|
||||
bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource);
|
||||
#else
|
||||
static inline bool
|
||||
imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user