mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
Merge branch 'next/drivers' into next/late
Merge in a few missing patches from the pull request (my copy of the branch was behind the staged version in linux-next). * next/drivers: memory: pl353: Add driver for arm pl353 static memory controller dt-bindings: memory: Add pl353 smc controller devicetree binding information firmware: qcom: scm: fix compilation error when disabled Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
00f8ccd0c9
@ -58,19 +58,11 @@ This binding for the SCU power domain providers uses the generic power
|
||||
domain binding[2].
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,scu-pd".
|
||||
- #address-cells: Should be 1.
|
||||
- #size-cells: Should be 0.
|
||||
|
||||
Required properties for power domain sub nodes:
|
||||
- #power-domain-cells: Must be 0.
|
||||
|
||||
Optional Properties:
|
||||
- reg: Resource ID of this power domain.
|
||||
No exist means uncontrollable by user.
|
||||
- compatible: Should be "fsl,imx8qxp-scu-pd".
|
||||
- #power-domain-cells: Must be 1. Contains the Resource ID used by
|
||||
SCU commands.
|
||||
See detailed Resource ID list from:
|
||||
include/dt-bindings/power/imx-rsrc.h
|
||||
- power-domains: phandle pointing to the parent power domain.
|
||||
include/dt-bindings/firmware/imx/rsrc.h
|
||||
|
||||
Clock bindings based on SCU Message Protocol
|
||||
------------------------------------------------------------
|
||||
@ -152,22 +144,9 @@ firmware {
|
||||
...
|
||||
};
|
||||
|
||||
imx8qx-pm {
|
||||
compatible = "fsl,scu-pd";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pd_dma: dma-power-domain {
|
||||
#power-domain-cells = <0>;
|
||||
|
||||
pd_dma_lpuart0: dma-lpuart0@57 {
|
||||
reg = <SC_R_UART_0>;
|
||||
#power-domain-cells = <0>;
|
||||
power-domains = <&pd_dma>;
|
||||
};
|
||||
...
|
||||
};
|
||||
...
|
||||
pd: imx8qx-pd {
|
||||
compatible = "fsl,imx8qxp-scu-pd";
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -179,5 +158,5 @@ serial@5a060000 {
|
||||
clocks = <&clk IMX8QXP_UART0_CLK>,
|
||||
<&clk IMX8QXP_UART0_IPG_CLK>;
|
||||
clock-names = "per", "ipg";
|
||||
power-domains = <&pd_dma_lpuart0>;
|
||||
power-domains = <&pd IMX_SC_R_UART_0>;
|
||||
};
|
||||
|
@ -35,6 +35,7 @@ Required standard properties:
|
||||
"ti,sysc-omap3-sham"
|
||||
"ti,sysc-omap-aes"
|
||||
"ti,sysc-mcasp"
|
||||
"ti,sysc-dra7-mcasp"
|
||||
"ti,sysc-usb-host-fs"
|
||||
"ti,sysc-dra7-mcan"
|
||||
|
||||
|
@ -0,0 +1,47 @@
|
||||
Device tree bindings for ARM PL353 static memory controller
|
||||
|
||||
PL353 static memory controller supports two kinds of memory
|
||||
interfaces.i.e NAND and SRAM/NOR interfaces.
|
||||
The actual devices are instantiated from the child nodes of pl353 smc node.
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "arm,pl353-smc-r2p1", "arm,primecell".
|
||||
- reg : Controller registers map and length.
|
||||
- clock-names : List of input clock names - "memclk", "apb_pclk"
|
||||
(See clock bindings for details).
|
||||
- clocks : Clock phandles (see clock bindings for details).
|
||||
- address-cells : Must be 2.
|
||||
- size-cells : Must be 1.
|
||||
|
||||
Child nodes:
|
||||
For NAND the "arm,pl353-nand-r2p1" and for NOR the "cfi-flash" drivers are
|
||||
supported as child nodes.
|
||||
|
||||
for NAND partition information please refer the below file
|
||||
Documentation/devicetree/bindings/mtd/partition.txt
|
||||
|
||||
Example:
|
||||
smcc: memory-controller@e000e000
|
||||
compatible = "arm,pl353-smc-r2p1", "arm,primecell";
|
||||
clock-names = "memclk", "apb_pclk";
|
||||
clocks = <&clkc 11>, <&clkc 44>;
|
||||
reg = <0xe000e000 0x1000>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x0 0xe1000000 0x1000000 //Nand CS Region
|
||||
0x1 0x0 0xe2000000 0x2000000 //SRAM/NOR CS Region
|
||||
0x2 0x0 0xe4000000 0x2000000>; //SRAM/NOR CS Region
|
||||
nand_0: flash@e1000000 {
|
||||
compatible = "arm,pl353-nand-r2p1"
|
||||
reg = <0 0 0x1000000>;
|
||||
(...)
|
||||
};
|
||||
nor0: flash@e2000000 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <1 0 0x2000000>;
|
||||
};
|
||||
nor1: flash@e4000000 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <2 0 0x2000000>;
|
||||
};
|
||||
};
|
@ -6,7 +6,9 @@ Control (PGC) for various power domains.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Should be "fsl,imx7d-gpc"
|
||||
- compatible: Should be one of:
|
||||
- "fsl,imx7d-gpc"
|
||||
- "fsl,imx8mq-gpc"
|
||||
|
||||
- reg: should be register base and length as documented in the
|
||||
datasheet
|
||||
@ -22,7 +24,8 @@ which, in turn, is expected to contain the following:
|
||||
Required properties:
|
||||
|
||||
- reg: Power domain index. Valid values are defined in
|
||||
include/dt-bindings/power/imx7-power.h
|
||||
include/dt-bindings/power/imx7-power.h for fsl,imx7d-gpc and
|
||||
include/dt-bindings/power/imx8m-power.h for fsl,imx8mq-gpc
|
||||
|
||||
- #power-domain-cells: Should be 0
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
Amlogic Internal Clock Measurer
|
||||
===============================
|
||||
|
||||
The Amlogic SoCs contains an IP to measure the internal clocks.
|
||||
The precision is multiple of MHz, useful to debug the clock states.
|
||||
|
||||
Required properties:
|
||||
- compatible: Shall contain one of the following :
|
||||
"amlogic,meson-gx-clk-measure" for GX SoCs
|
||||
"amlogic,meson8-clk-measure" for Meson8 SoCs
|
||||
"amlogic,meson8b-clk-measure" for Meson8b SoCs
|
||||
- reg: base address and size of the Clock Measurer register space.
|
||||
|
||||
Example:
|
||||
clock-measure@8758 {
|
||||
compatible = "amlogic,meson-gx-clk-measure";
|
||||
reg = <0x0 0x8758 0x0 0x10>;
|
||||
};
|
@ -23,6 +23,7 @@ resources.
|
||||
"qcom,rpm-msm8916"
|
||||
"qcom,rpm-msm8974"
|
||||
"qcom,rpm-msm8998"
|
||||
"qcom,rpm-qcs404"
|
||||
|
||||
- qcom,smd-channels:
|
||||
Usage: required
|
||||
|
@ -7,7 +7,9 @@ Required properties for power domain controller:
|
||||
- compatible: Should be one of the following.
|
||||
"rockchip,px30-power-controller" - for PX30 SoCs.
|
||||
"rockchip,rk3036-power-controller" - for RK3036 SoCs.
|
||||
"rockchip,rk3066-power-controller" - for RK3066 SoCs.
|
||||
"rockchip,rk3128-power-controller" - for RK3128 SoCs.
|
||||
"rockchip,rk3188-power-controller" - for RK3188 SoCs.
|
||||
"rockchip,rk3228-power-controller" - for RK3228 SoCs.
|
||||
"rockchip,rk3288-power-controller" - for RK3288 SoCs.
|
||||
"rockchip,rk3328-power-controller" - for RK3328 SoCs.
|
||||
@ -23,7 +25,9 @@ Required properties for power domain sub nodes:
|
||||
- reg: index of the power domain, should use macros in:
|
||||
"include/dt-bindings/power/px30-power.h" - for PX30 type power domain.
|
||||
"include/dt-bindings/power/rk3036-power.h" - for RK3036 type power domain.
|
||||
"include/dt-bindings/power/rk3066-power.h" - for RK3066 type power domain.
|
||||
"include/dt-bindings/power/rk3128-power.h" - for RK3128 type power domain.
|
||||
"include/dt-bindings/power/rk3188-power.h" - for RK3188 type power domain.
|
||||
"include/dt-bindings/power/rk3228-power.h" - for RK3228 type power domain.
|
||||
"include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
|
||||
"include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain.
|
||||
|
@ -18,7 +18,9 @@ Required properties:
|
||||
- "allwinner,sun8i-h3-system-control"
|
||||
- "allwinner,sun50i-a64-sram-controller" (deprecated)
|
||||
- "allwinner,sun50i-a64-system-control"
|
||||
- "allwinner,sun50i-h5-system-control"
|
||||
- "allwinner,sun50i-h6-system-control", "allwinner,sun50i-a64-system-control"
|
||||
- "allwinner,suniv-f1c100s-system-control", "allwinner,sun4i-a10-system-control"
|
||||
- reg : sram controller register offset + length
|
||||
|
||||
SRAM nodes
|
||||
@ -54,10 +56,17 @@ The valid sections compatible for H3 are:
|
||||
|
||||
The valid sections compatible for A64 are:
|
||||
- allwinner,sun50i-a64-sram-c
|
||||
- allwinner,sun50i-a64-sram-c1, allwinner,sun4i-a10-sram-c1
|
||||
|
||||
The valid sections compatible for H5 are:
|
||||
- allwinner,sun50i-h5-sram-c1, allwinner,sun4i-a10-sram-c1
|
||||
|
||||
The valid sections compatible for H6 are:
|
||||
- allwinner,sun50i-h6-sram-c, allwinner,sun50i-a64-sram-c
|
||||
|
||||
The valid sections compatible for F1C100s are:
|
||||
- allwinner,suniv-f1c100s-sram-d, allwinner,sun4i-a10-sram-d
|
||||
|
||||
Devices using SRAM sections
|
||||
---------------------------
|
||||
|
||||
|
@ -2345,6 +2345,17 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init parse_module_flags(struct omap_hwmod *oh,
|
||||
struct device_node *np)
|
||||
{
|
||||
if (of_find_property(np, "ti,no-reset-on-init", NULL))
|
||||
oh->flags |= HWMOD_INIT_NO_RESET;
|
||||
if (of_find_property(np, "ti,no-idle-on-init", NULL))
|
||||
oh->flags |= HWMOD_INIT_NO_IDLE;
|
||||
if (of_find_property(np, "ti,no-idle", NULL))
|
||||
oh->flags |= HWMOD_NO_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _init - initialize internal data for the hwmod @oh
|
||||
* @oh: struct omap_hwmod *
|
||||
@ -2392,12 +2403,12 @@ static int __init _init(struct omap_hwmod *oh, void *data)
|
||||
}
|
||||
|
||||
if (np) {
|
||||
if (of_find_property(np, "ti,no-reset-on-init", NULL))
|
||||
oh->flags |= HWMOD_INIT_NO_RESET;
|
||||
if (of_find_property(np, "ti,no-idle-on-init", NULL))
|
||||
oh->flags |= HWMOD_INIT_NO_IDLE;
|
||||
if (of_find_property(np, "ti,no-idle", NULL))
|
||||
oh->flags |= HWMOD_NO_IDLE;
|
||||
struct device_node *child;
|
||||
|
||||
parse_module_flags(oh, np);
|
||||
child = of_get_next_child(np, NULL);
|
||||
if (child)
|
||||
parse_module_flags(oh, child);
|
||||
}
|
||||
|
||||
oh->_state = _HWMOD_STATE_INITIALIZED;
|
||||
|
@ -150,8 +150,7 @@ static ssize_t gisb_arb_get_timeout(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
|
||||
struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
|
||||
u32 timeout;
|
||||
|
||||
mutex_lock(&gdev->lock);
|
||||
@ -165,8 +164,7 @@ static ssize_t gisb_arb_set_timeout(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
|
||||
struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
|
||||
int val, ret;
|
||||
|
||||
ret = kstrtoint(buf, 10, &val);
|
||||
@ -418,8 +416,7 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int brcmstb_gisb_arb_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
|
||||
struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
|
||||
|
||||
gdev->saved_timeout = gisb_read(gdev, ARB_TIMER);
|
||||
|
||||
@ -431,8 +428,7 @@ static int brcmstb_gisb_arb_suspend(struct device *dev)
|
||||
*/
|
||||
static int brcmstb_gisb_arb_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
|
||||
struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
|
||||
|
||||
gisb_write(gdev, gdev->saved_timeout, ARB_TIMER);
|
||||
|
||||
|
@ -91,6 +91,9 @@ struct sysc {
|
||||
struct delayed_work idle_work;
|
||||
};
|
||||
|
||||
static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
|
||||
bool is_child);
|
||||
|
||||
void sysc_write(struct sysc *ddata, int offset, u32 value)
|
||||
{
|
||||
writel_relaxed(value, ddata->module_va + offset);
|
||||
@ -214,8 +217,13 @@ static int sysc_get_clocks(struct sysc *ddata)
|
||||
if (!ddata->clocks)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ddata->nr_clocks; i++) {
|
||||
error = sysc_get_one_clock(ddata, ddata->clock_roles[i]);
|
||||
for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
|
||||
const char *name = ddata->clock_roles[i];
|
||||
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
error = sysc_get_one_clock(ddata, name);
|
||||
if (error && error != -ENOENT)
|
||||
return error;
|
||||
}
|
||||
@ -374,6 +382,7 @@ static int sysc_check_one_child(struct sysc *ddata,
|
||||
dev_warn(ddata->dev, "really a child ti,hwmods property?");
|
||||
|
||||
sysc_check_quirk_stdout(ddata, np);
|
||||
sysc_parse_dts_quirks(ddata, np, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -815,6 +824,7 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
|
||||
SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xfffffff0, 0),
|
||||
SYSC_QUIRK("ocp2scp", 0, 0, -1, -1, 0x50060007, 0xffffffff, 0),
|
||||
SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff, 0),
|
||||
SYSC_QUIRK("padconf", 0, 0, -1, -1, 0x40001100, 0xffffffff, 0),
|
||||
SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff, 0),
|
||||
SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x00004102, 0xffffffff, 0),
|
||||
SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000400, 0xffffffff, 0),
|
||||
@ -833,7 +843,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
|
||||
SYSC_QUIRK("rtc", 0, 0x74, 0x78, -1, 0x4eb01908, 0xffff00f0, 0),
|
||||
SYSC_QUIRK("timer32k", 0, 0, 0x4, -1, 0x00000060, 0xffffffff, 0),
|
||||
SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0),
|
||||
SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000008, 0xffffffff, 0),
|
||||
SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0),
|
||||
SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0),
|
||||
SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
|
||||
0xffffffff, 0),
|
||||
SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, 0),
|
||||
@ -1271,23 +1283,37 @@ static const struct sysc_dts_quirk sysc_dts_quirks[] = {
|
||||
.mask = SYSC_QUIRK_NO_RESET_ON_INIT, },
|
||||
};
|
||||
|
||||
static int sysc_init_dts_quirks(struct sysc *ddata)
|
||||
static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
|
||||
bool is_child)
|
||||
{
|
||||
struct device_node *np = ddata->dev->of_node;
|
||||
const struct property *prop;
|
||||
int i, len, error;
|
||||
u32 val;
|
||||
|
||||
ddata->legacy_mode = of_get_property(np, "ti,hwmods", NULL);
|
||||
int i, len;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sysc_dts_quirks); i++) {
|
||||
prop = of_get_property(np, sysc_dts_quirks[i].name, &len);
|
||||
const char *name = sysc_dts_quirks[i].name;
|
||||
|
||||
prop = of_get_property(np, name, &len);
|
||||
if (!prop)
|
||||
continue;
|
||||
|
||||
ddata->cfg.quirks |= sysc_dts_quirks[i].mask;
|
||||
if (is_child) {
|
||||
dev_warn(ddata->dev,
|
||||
"dts flag should be at module level for %s\n",
|
||||
name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int sysc_init_dts_quirks(struct sysc *ddata)
|
||||
{
|
||||
struct device_node *np = ddata->dev->of_node;
|
||||
int error;
|
||||
u32 val;
|
||||
|
||||
ddata->legacy_mode = of_get_property(np, "ti,hwmods", NULL);
|
||||
|
||||
sysc_parse_dts_quirks(ddata, np, false);
|
||||
error = of_property_read_u32(np, "ti,sysc-delay-us", &val);
|
||||
if (!error) {
|
||||
if (val > 255) {
|
||||
@ -1498,6 +1524,16 @@ static const struct sysc_regbits sysc_regbits_omap4_mcasp = {
|
||||
static const struct sysc_capabilities sysc_omap4_mcasp = {
|
||||
.type = TI_SYSC_OMAP4_MCASP,
|
||||
.regbits = &sysc_regbits_omap4_mcasp,
|
||||
.mod_quirks = SYSC_QUIRK_OPT_CLKS_NEEDED,
|
||||
};
|
||||
|
||||
/*
|
||||
* McASP found on dra7 and later
|
||||
*/
|
||||
static const struct sysc_capabilities sysc_dra7_mcasp = {
|
||||
.type = TI_SYSC_OMAP4_SIMPLE,
|
||||
.regbits = &sysc_regbits_omap4_simple,
|
||||
.mod_quirks = SYSC_QUIRK_OPT_CLKS_NEEDED,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1726,6 +1762,7 @@ static const struct of_device_id sysc_match[] = {
|
||||
{ .compatible = "ti,sysc-omap3-sham", .data = &sysc_omap3_sham, },
|
||||
{ .compatible = "ti,sysc-omap-aes", .data = &sysc_omap3_aes, },
|
||||
{ .compatible = "ti,sysc-mcasp", .data = &sysc_omap4_mcasp, },
|
||||
{ .compatible = "ti,sysc-dra7-mcasp", .data = &sysc_dra7_mcasp, },
|
||||
{ .compatible = "ti,sysc-usb-host-fs",
|
||||
.data = &sysc_omap4_usb_host_fs, },
|
||||
{ .compatible = "ti,sysc-dra7-mcan", .data = &sysc_dra7_mcan, },
|
||||
|
@ -179,7 +179,7 @@ static unsigned int pxad_drcmr(unsigned int line)
|
||||
return 0x1000 + line * 4;
|
||||
}
|
||||
|
||||
bool pxad_filter_fn(struct dma_chan *chan, void *param);
|
||||
static bool pxad_filter_fn(struct dma_chan *chan, void *param);
|
||||
|
||||
/*
|
||||
* Debug fs
|
||||
@ -1500,7 +1500,7 @@ static struct platform_driver pxad_driver = {
|
||||
.remove = pxad_remove,
|
||||
};
|
||||
|
||||
bool pxad_filter_fn(struct dma_chan *chan, void *param)
|
||||
static bool pxad_filter_fn(struct dma_chan *chan, void *param)
|
||||
{
|
||||
struct pxad_chan *c = to_pxad_chan(chan);
|
||||
struct pxad_param *p = param;
|
||||
@ -1513,7 +1513,6 @@ bool pxad_filter_fn(struct dma_chan *chan, void *param)
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxad_filter_fn);
|
||||
|
||||
module_platform_driver(pxad_driver);
|
||||
|
||||
|
@ -9,3 +9,9 @@ config IMX_SCU
|
||||
|
||||
This driver manages the IPC interface between host CPU and the
|
||||
SCU firmware running on M4.
|
||||
|
||||
config IMX_SCU_PD
|
||||
bool "IMX SCU Power Domain driver"
|
||||
depends on IMX_SCU
|
||||
help
|
||||
The System Controller Firmware (SCFW) based power domain driver.
|
||||
|
@ -1,2 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o
|
||||
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o
|
||||
obj-$(CONFIG_IMX_SCU_PD) += scu-pd.o
|
||||
|
339
drivers/firmware/imx/scu-pd.c
Normal file
339
drivers/firmware/imx/scu-pd.c
Normal file
@ -0,0 +1,339 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017-2018 NXP
|
||||
* Dong Aisheng <aisheng.dong@nxp.com>
|
||||
*
|
||||
* Implementation of the SCU based Power Domains
|
||||
*
|
||||
* NOTE: a better implementation suggested by Ulf Hansson is using a
|
||||
* single global power domain and implement the ->attach|detach_dev()
|
||||
* callback for the genpd and use the regular of_genpd_add_provider_simple().
|
||||
* From within the ->attach_dev(), we could get the OF node for
|
||||
* the device that is being attached and then parse the power-domain
|
||||
* cell containing the "resource id" and store that in the per device
|
||||
* struct generic_pm_domain_data (we have void pointer there for
|
||||
* storing these kind of things).
|
||||
*
|
||||
* Additionally, we need to implement the ->stop() and ->start()
|
||||
* callbacks of genpd, which is where you "power on/off" devices,
|
||||
* rather than using the above ->power_on|off() callbacks.
|
||||
*
|
||||
* However, there're two known issues:
|
||||
* 1. The ->attach_dev() of power domain infrastructure still does
|
||||
* not support multi domains case as the struct device *dev passed
|
||||
* in is a virtual PD device, it does not help for parsing the real
|
||||
* device resource id from device tree, so it's unware of which
|
||||
* real sub power domain of device should be attached.
|
||||
*
|
||||
* The framework needs some proper extension to support multi power
|
||||
* domain cases.
|
||||
*
|
||||
* 2. It also breaks most of current drivers as the driver probe sequence
|
||||
* behavior changed if removing ->power_on|off() callback and use
|
||||
* ->start() and ->stop() instead. genpd_dev_pm_attach will only power
|
||||
* up the domain and attach device, but will not call .start() which
|
||||
* relies on device runtime pm. That means the device power is still
|
||||
* not up before running driver probe function. For SCU enabled
|
||||
* platforms, all device drivers accessing registers/clock without power
|
||||
* domain enabled will trigger a HW access error. That means we need fix
|
||||
* most drivers probe sequence with proper runtime pm.
|
||||
*
|
||||
* In summary, we need fix above two issue before being able to switch to
|
||||
* the "single global power domain" way.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
#include <linux/firmware/imx/sci.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* SCU Power Mode Protocol definition */
|
||||
struct imx_sc_msg_req_set_resource_power_mode {
|
||||
struct imx_sc_rpc_msg hdr;
|
||||
u16 resource;
|
||||
u8 mode;
|
||||
} __packed;
|
||||
|
||||
#define IMX_SCU_PD_NAME_SIZE 20
|
||||
struct imx_sc_pm_domain {
|
||||
struct generic_pm_domain pd;
|
||||
char name[IMX_SCU_PD_NAME_SIZE];
|
||||
u32 rsrc;
|
||||
};
|
||||
|
||||
struct imx_sc_pd_range {
|
||||
char *name;
|
||||
u32 rsrc;
|
||||
u8 num;
|
||||
bool postfix;
|
||||
};
|
||||
|
||||
struct imx_sc_pd_soc {
|
||||
const struct imx_sc_pd_range *pd_ranges;
|
||||
u8 num_ranges;
|
||||
};
|
||||
|
||||
static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
|
||||
/* LSIO SS */
|
||||
{ "lsio-pwm", IMX_SC_R_PWM_0, 8, 1 },
|
||||
{ "lsio-gpio", IMX_SC_R_GPIO_0, 8, 1 },
|
||||
{ "lsio-gpt", IMX_SC_R_GPT_0, 5, 1 },
|
||||
{ "lsio-kpp", IMX_SC_R_KPP, 1, 0 },
|
||||
{ "lsio-fspi", IMX_SC_R_FSPI_0, 2, 1 },
|
||||
{ "lsio-mu", IMX_SC_R_MU_0A, 14, 1 },
|
||||
|
||||
/* CONN SS */
|
||||
{ "con-usb", IMX_SC_R_USB_0, 2, 1 },
|
||||
{ "con-usb0phy", IMX_SC_R_USB_0_PHY, 1, 0 },
|
||||
{ "con-usb2", IMX_SC_R_USB_2, 1, 0 },
|
||||
{ "con-usb2phy", IMX_SC_R_USB_2_PHY, 1, 0 },
|
||||
{ "con-sdhc", IMX_SC_R_SDHC_0, 3, 1 },
|
||||
{ "con-enet", IMX_SC_R_ENET_0, 2, 1 },
|
||||
{ "con-nand", IMX_SC_R_NAND, 1, 0 },
|
||||
{ "con-mlb", IMX_SC_R_MLB_0, 1, 1 },
|
||||
|
||||
/* Audio DMA SS */
|
||||
{ "adma-audio-pll0", IMX_SC_R_AUDIO_PLL_0, 1, 0 },
|
||||
{ "adma-audio-pll1", IMX_SC_R_AUDIO_PLL_1, 1, 0 },
|
||||
{ "adma-audio-clk-0", IMX_SC_R_AUDIO_CLK_0, 1, 0 },
|
||||
{ "adma-dma0-ch", IMX_SC_R_DMA_0_CH0, 16, 1 },
|
||||
{ "adma-dma1-ch", IMX_SC_R_DMA_1_CH0, 16, 1 },
|
||||
{ "adma-dma2-ch", IMX_SC_R_DMA_2_CH0, 5, 1 },
|
||||
{ "adma-asrc0", IMX_SC_R_ASRC_0, 1, 0 },
|
||||
{ "adma-asrc1", IMX_SC_R_ASRC_1, 1, 0 },
|
||||
{ "adma-esai0", IMX_SC_R_ESAI_0, 1, 0 },
|
||||
{ "adma-spdif0", IMX_SC_R_SPDIF_0, 1, 0 },
|
||||
{ "adma-sai", IMX_SC_R_SAI_0, 3, 1 },
|
||||
{ "adma-amix", IMX_SC_R_AMIX, 1, 0 },
|
||||
{ "adma-mqs0", IMX_SC_R_MQS_0, 1, 0 },
|
||||
{ "adma-dsp", IMX_SC_R_DSP, 1, 0 },
|
||||
{ "adma-dsp-ram", IMX_SC_R_DSP_RAM, 1, 0 },
|
||||
{ "adma-can", IMX_SC_R_CAN_0, 3, 1 },
|
||||
{ "adma-ftm", IMX_SC_R_FTM_0, 2, 1 },
|
||||
{ "adma-lpi2c", IMX_SC_R_I2C_0, 4, 1 },
|
||||
{ "adma-adc", IMX_SC_R_ADC_0, 1, 1 },
|
||||
{ "adma-lcd", IMX_SC_R_LCD_0, 1, 1 },
|
||||
{ "adma-lcd0-pwm", IMX_SC_R_LCD_0_PWM_0, 1, 1 },
|
||||
{ "adma-lpuart", IMX_SC_R_UART_0, 4, 1 },
|
||||
{ "adma-lpspi", IMX_SC_R_SPI_0, 4, 1 },
|
||||
|
||||
/* VPU SS */
|
||||
{ "vpu", IMX_SC_R_VPU, 1, 0 },
|
||||
{ "vpu-pid", IMX_SC_R_VPU_PID0, 8, 1 },
|
||||
{ "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, 0 },
|
||||
{ "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, 0 },
|
||||
|
||||
/* GPU SS */
|
||||
{ "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, 1 },
|
||||
|
||||
/* HSIO SS */
|
||||
{ "hsio-pcie-b", IMX_SC_R_PCIE_B, 1, 0 },
|
||||
{ "hsio-serdes-1", IMX_SC_R_SERDES_1, 1, 0 },
|
||||
{ "hsio-gpio", IMX_SC_R_HSIO_GPIO, 1, 0 },
|
||||
|
||||
/* MIPI/LVDS SS */
|
||||
{ "mipi0", IMX_SC_R_MIPI_0, 1, 0 },
|
||||
{ "mipi0-pwm0", IMX_SC_R_MIPI_0_PWM_0, 1, 0 },
|
||||
{ "mipi0-i2c", IMX_SC_R_MIPI_0_I2C_0, 2, 1 },
|
||||
{ "lvds0", IMX_SC_R_LVDS_0, 1, 0 },
|
||||
|
||||
/* DC SS */
|
||||
{ "dc0", IMX_SC_R_DC_0, 1, 0 },
|
||||
{ "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, 1 },
|
||||
};
|
||||
|
||||
static const struct imx_sc_pd_soc imx8qxp_scu_pd = {
|
||||
.pd_ranges = imx8qxp_scu_pd_ranges,
|
||||
.num_ranges = ARRAY_SIZE(imx8qxp_scu_pd_ranges),
|
||||
};
|
||||
|
||||
static struct imx_sc_ipc *pm_ipc_handle;
|
||||
|
||||
static inline struct imx_sc_pm_domain *
|
||||
to_imx_sc_pd(struct generic_pm_domain *genpd)
|
||||
{
|
||||
return container_of(genpd, struct imx_sc_pm_domain, pd);
|
||||
}
|
||||
|
||||
static int imx_sc_pd_power(struct generic_pm_domain *domain, bool power_on)
|
||||
{
|
||||
struct imx_sc_msg_req_set_resource_power_mode msg;
|
||||
struct imx_sc_rpc_msg *hdr = &msg.hdr;
|
||||
struct imx_sc_pm_domain *pd;
|
||||
int ret;
|
||||
|
||||
pd = to_imx_sc_pd(domain);
|
||||
|
||||
hdr->ver = IMX_SC_RPC_VERSION;
|
||||
hdr->svc = IMX_SC_RPC_SVC_PM;
|
||||
hdr->func = IMX_SC_PM_FUNC_SET_RESOURCE_POWER_MODE;
|
||||
hdr->size = 2;
|
||||
|
||||
msg.resource = pd->rsrc;
|
||||
msg.mode = power_on ? IMX_SC_PM_PW_MODE_ON : IMX_SC_PM_PW_MODE_LP;
|
||||
|
||||
ret = imx_scu_call_rpc(pm_ipc_handle, &msg, true);
|
||||
if (ret)
|
||||
dev_err(&domain->dev, "failed to power %s resource %d ret %d\n",
|
||||
power_on ? "up" : "off", pd->rsrc, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int imx_sc_pd_power_on(struct generic_pm_domain *domain)
|
||||
{
|
||||
return imx_sc_pd_power(domain, true);
|
||||
}
|
||||
|
||||
static int imx_sc_pd_power_off(struct generic_pm_domain *domain)
|
||||
{
|
||||
return imx_sc_pd_power(domain, false);
|
||||
}
|
||||
|
||||
static struct generic_pm_domain *imx_scu_pd_xlate(struct of_phandle_args *spec,
|
||||
void *data)
|
||||
{
|
||||
struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
|
||||
struct genpd_onecell_data *pd_data = data;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < pd_data->num_domains; i++) {
|
||||
struct imx_sc_pm_domain *sc_pd;
|
||||
|
||||
sc_pd = to_imx_sc_pd(pd_data->domains[i]);
|
||||
if (sc_pd->rsrc == spec->args[0]) {
|
||||
domain = &sc_pd->pd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
static struct imx_sc_pm_domain *
|
||||
imx_scu_add_pm_domain(struct device *dev, int idx,
|
||||
const struct imx_sc_pd_range *pd_ranges)
|
||||
{
|
||||
struct imx_sc_pm_domain *sc_pd;
|
||||
int ret;
|
||||
|
||||
sc_pd = devm_kzalloc(dev, sizeof(*sc_pd), GFP_KERNEL);
|
||||
if (!sc_pd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
sc_pd->rsrc = pd_ranges->rsrc + idx;
|
||||
sc_pd->pd.power_off = imx_sc_pd_power_off;
|
||||
sc_pd->pd.power_on = imx_sc_pd_power_on;
|
||||
|
||||
if (pd_ranges->postfix)
|
||||
snprintf(sc_pd->name, sizeof(sc_pd->name),
|
||||
"%s%i", pd_ranges->name, idx);
|
||||
else
|
||||
snprintf(sc_pd->name, sizeof(sc_pd->name),
|
||||
"%s", pd_ranges->name);
|
||||
|
||||
sc_pd->pd.name = sc_pd->name;
|
||||
|
||||
if (sc_pd->rsrc >= IMX_SC_R_LAST) {
|
||||
dev_warn(dev, "invalid pd %s rsrc id %d found",
|
||||
sc_pd->name, sc_pd->rsrc);
|
||||
|
||||
devm_kfree(dev, sc_pd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = pm_genpd_init(&sc_pd->pd, NULL, true);
|
||||
if (ret) {
|
||||
dev_warn(dev, "failed to init pd %s rsrc id %d",
|
||||
sc_pd->name, sc_pd->rsrc);
|
||||
devm_kfree(dev, sc_pd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sc_pd;
|
||||
}
|
||||
|
||||
static int imx_scu_init_pm_domains(struct device *dev,
|
||||
const struct imx_sc_pd_soc *pd_soc)
|
||||
{
|
||||
const struct imx_sc_pd_range *pd_ranges = pd_soc->pd_ranges;
|
||||
struct generic_pm_domain **domains;
|
||||
struct genpd_onecell_data *pd_data;
|
||||
struct imx_sc_pm_domain *sc_pd;
|
||||
u32 count = 0;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < pd_soc->num_ranges; i++)
|
||||
count += pd_ranges[i].num;
|
||||
|
||||
domains = devm_kcalloc(dev, count, sizeof(*domains), GFP_KERNEL);
|
||||
if (!domains)
|
||||
return -ENOMEM;
|
||||
|
||||
pd_data = devm_kzalloc(dev, sizeof(*pd_data), GFP_KERNEL);
|
||||
if (!pd_data)
|
||||
return -ENOMEM;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < pd_soc->num_ranges; i++) {
|
||||
for (j = 0; j < pd_ranges[i].num; j++) {
|
||||
sc_pd = imx_scu_add_pm_domain(dev, j, &pd_ranges[i]);
|
||||
if (IS_ERR_OR_NULL(sc_pd))
|
||||
continue;
|
||||
|
||||
domains[count++] = &sc_pd->pd;
|
||||
dev_dbg(dev, "added power domain %s\n", sc_pd->pd.name);
|
||||
}
|
||||
}
|
||||
|
||||
pd_data->domains = domains;
|
||||
pd_data->num_domains = count;
|
||||
pd_data->xlate = imx_scu_pd_xlate;
|
||||
|
||||
of_genpd_add_provider_onecell(dev->of_node, pd_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_sc_pd_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct imx_sc_pd_soc *pd_soc;
|
||||
int ret;
|
||||
|
||||
ret = imx_scu_get_handle(&pm_ipc_handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pd_soc = of_device_get_match_data(&pdev->dev);
|
||||
if (!pd_soc)
|
||||
return -ENODEV;
|
||||
|
||||
return imx_scu_init_pm_domains(&pdev->dev, pd_soc);
|
||||
}
|
||||
|
||||
static const struct of_device_id imx_sc_pd_match[] = {
|
||||
{ .compatible = "fsl,imx8qxp-scu-pd", &imx8qxp_scu_pd},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver imx_sc_pd_driver = {
|
||||
.driver = {
|
||||
.name = "imx-scu-pd",
|
||||
.of_match_table = imx_sc_pd_match,
|
||||
},
|
||||
.probe = imx_sc_pd_probe,
|
||||
};
|
||||
builtin_platform_driver(imx_sc_pd_driver);
|
||||
|
||||
MODULE_AUTHOR("Dong Aisheng <aisheng.dong@nxp.com>");
|
||||
MODULE_DESCRIPTION("IMX SCU Power Domain driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -1,12 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Defines interfaces for interacting wtih the Raspberry Pi firmware's
|
||||
* property channel.
|
||||
*
|
||||
* Copyright © 2015 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
@ -14,6 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <soc/bcm2835/raspberrypi-firmware.h>
|
||||
|
||||
#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf))
|
||||
@ -21,8 +19,6 @@
|
||||
#define MBOX_DATA28(msg) ((msg) & ~0xf)
|
||||
#define MBOX_CHAN_PROPERTY 8
|
||||
|
||||
#define MAX_RPI_FW_PROP_BUF_SIZE 32
|
||||
|
||||
static struct platform_device *rpi_hwmon;
|
||||
|
||||
struct rpi_firmware {
|
||||
@ -56,8 +52,12 @@ rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data)
|
||||
reinit_completion(&fw->c);
|
||||
ret = mbox_send_message(fw->chan, &message);
|
||||
if (ret >= 0) {
|
||||
wait_for_completion(&fw->c);
|
||||
ret = 0;
|
||||
if (wait_for_completion_timeout(&fw->c, HZ)) {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -ETIMEDOUT;
|
||||
WARN_ONCE(1, "Firmware transaction timeout");
|
||||
}
|
||||
} else {
|
||||
dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret);
|
||||
}
|
||||
@ -144,28 +144,30 @@ EXPORT_SYMBOL_GPL(rpi_firmware_property_list);
|
||||
int rpi_firmware_property(struct rpi_firmware *fw,
|
||||
u32 tag, void *tag_data, size_t buf_size)
|
||||
{
|
||||
/* Single tags are very small (generally 8 bytes), so the
|
||||
* stack should be safe.
|
||||
*/
|
||||
u8 data[sizeof(struct rpi_firmware_property_tag_header) +
|
||||
MAX_RPI_FW_PROP_BUF_SIZE];
|
||||
struct rpi_firmware_property_tag_header *header =
|
||||
(struct rpi_firmware_property_tag_header *)data;
|
||||
struct rpi_firmware_property_tag_header *header;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(buf_size > sizeof(data) - sizeof(*header)))
|
||||
return -EINVAL;
|
||||
/* Some mailboxes can use over 1k bytes. Rather than checking
|
||||
* size and using stack or kmalloc depending on requirements,
|
||||
* just use kmalloc. Mailboxes don't get called enough to worry
|
||||
* too much about the time taken in the allocation.
|
||||
*/
|
||||
void *data = kmalloc(sizeof(*header) + buf_size, GFP_KERNEL);
|
||||
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
header = data;
|
||||
header->tag = tag;
|
||||
header->buf_size = buf_size;
|
||||
header->req_resp_size = 0;
|
||||
memcpy(data + sizeof(struct rpi_firmware_property_tag_header),
|
||||
tag_data, buf_size);
|
||||
memcpy(data + sizeof(*header), tag_data, buf_size);
|
||||
|
||||
ret = rpi_firmware_property_list(fw, &data, buf_size + sizeof(*header));
|
||||
memcpy(tag_data,
|
||||
data + sizeof(struct rpi_firmware_property_tag_header),
|
||||
buf_size);
|
||||
ret = rpi_firmware_property_list(fw, data, buf_size + sizeof(*header));
|
||||
|
||||
memcpy(tag_data, data + sizeof(*header), buf_size);
|
||||
|
||||
kfree(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -379,33 +379,6 @@ static int create_debugfs_mirror(struct tegra_bpmp *bpmp, void *buf,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq)
|
||||
{
|
||||
struct mrq_query_abi_request req = { .mrq = cpu_to_le32(mrq) };
|
||||
struct mrq_query_abi_response resp;
|
||||
struct tegra_bpmp_message msg = {
|
||||
.mrq = MRQ_QUERY_ABI,
|
||||
.tx = {
|
||||
.data = &req,
|
||||
.size = sizeof(req),
|
||||
},
|
||||
.rx = {
|
||||
.data = &resp,
|
||||
.size = sizeof(resp),
|
||||
},
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = tegra_bpmp_transfer(bpmp, &msg);
|
||||
if (ret < 0) {
|
||||
/* something went wrong; assume not supported */
|
||||
dev_warn(bpmp->dev, "tegra_bpmp_transfer failed (%d)\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return resp.status ? 0 : 1;
|
||||
}
|
||||
|
||||
int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
|
||||
{
|
||||
dma_addr_t phys;
|
||||
@ -415,7 +388,7 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
|
||||
int ret;
|
||||
struct dentry *root;
|
||||
|
||||
if (!mrq_is_supported(bpmp, MRQ_DEBUGFS))
|
||||
if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS))
|
||||
return 0;
|
||||
|
||||
root = debugfs_create_dir("bpmp", NULL);
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#define MSG_ACK BIT(0)
|
||||
#define MSG_RING BIT(1)
|
||||
#define TAG_SZ 32
|
||||
|
||||
static inline struct tegra_bpmp *
|
||||
mbox_client_to_bpmp(struct mbox_client *client)
|
||||
@ -470,6 +471,31 @@ unlock:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra_bpmp_free_mrq);
|
||||
|
||||
bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq)
|
||||
{
|
||||
struct mrq_query_abi_request req = { .mrq = cpu_to_le32(mrq) };
|
||||
struct mrq_query_abi_response resp;
|
||||
struct tegra_bpmp_message msg = {
|
||||
.mrq = MRQ_QUERY_ABI,
|
||||
.tx = {
|
||||
.data = &req,
|
||||
.size = sizeof(req),
|
||||
},
|
||||
.rx = {
|
||||
.data = &resp,
|
||||
.size = sizeof(resp),
|
||||
},
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = tegra_bpmp_transfer(bpmp, &msg);
|
||||
if (ret || msg.rx.ret)
|
||||
return false;
|
||||
|
||||
return resp.status == 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra_bpmp_mrq_is_supported);
|
||||
|
||||
static void tegra_bpmp_mrq_handle_ping(unsigned int mrq,
|
||||
struct tegra_bpmp_channel *channel,
|
||||
void *data)
|
||||
@ -521,8 +547,9 @@ static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
|
||||
size_t size)
|
||||
/* deprecated version of tag query */
|
||||
static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag,
|
||||
size_t size)
|
||||
{
|
||||
struct mrq_query_tag_request request;
|
||||
struct tegra_bpmp_message msg;
|
||||
@ -531,7 +558,10 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
|
||||
void *virt;
|
||||
int err;
|
||||
|
||||
virt = dma_alloc_coherent(bpmp->dev, MSG_DATA_MIN_SZ, &phys,
|
||||
if (size != TAG_SZ)
|
||||
return -EINVAL;
|
||||
|
||||
virt = dma_alloc_coherent(bpmp->dev, TAG_SZ, &phys,
|
||||
GFP_KERNEL | GFP_DMA32);
|
||||
if (!virt)
|
||||
return -ENOMEM;
|
||||
@ -549,13 +579,44 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
|
||||
local_irq_restore(flags);
|
||||
|
||||
if (err == 0)
|
||||
strlcpy(tag, virt, size);
|
||||
memcpy(tag, virt, TAG_SZ);
|
||||
|
||||
dma_free_coherent(bpmp->dev, MSG_DATA_MIN_SZ, virt, phys);
|
||||
dma_free_coherent(bpmp->dev, TAG_SZ, virt, phys);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
|
||||
size_t size)
|
||||
{
|
||||
if (tegra_bpmp_mrq_is_supported(bpmp, MRQ_QUERY_FW_TAG)) {
|
||||
struct mrq_query_fw_tag_response resp;
|
||||
struct tegra_bpmp_message msg = {
|
||||
.mrq = MRQ_QUERY_FW_TAG,
|
||||
.rx = {
|
||||
.data = &resp,
|
||||
.size = sizeof(resp),
|
||||
},
|
||||
};
|
||||
int err;
|
||||
|
||||
if (size != sizeof(resp.tag))
|
||||
return -EINVAL;
|
||||
|
||||
err = tegra_bpmp_transfer(bpmp, &msg);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
if (msg.rx.ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(tag, resp.tag, sizeof(resp.tag));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tegra_bpmp_get_firmware_tag_old(bpmp, tag, size);
|
||||
}
|
||||
|
||||
static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
|
||||
{
|
||||
unsigned long flags = channel->ob->flags;
|
||||
@ -664,7 +725,7 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_bpmp *bpmp;
|
||||
unsigned int i;
|
||||
char tag[32];
|
||||
char tag[TAG_SZ];
|
||||
size_t size;
|
||||
int err;
|
||||
|
||||
@ -792,13 +853,13 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
|
||||
goto free_mrq;
|
||||
}
|
||||
|
||||
err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag) - 1);
|
||||
err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag));
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err);
|
||||
goto free_mrq;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "firmware: %s\n", tag);
|
||||
dev_info(&pdev->dev, "firmware: %.*s\n", (int)sizeof(tag), tag);
|
||||
|
||||
platform_set_drvdata(pdev, bpmp);
|
||||
|
||||
|
@ -902,26 +902,6 @@ static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the list of RPMh voltage levels from cmd-db */
|
||||
static int a6xx_gmu_rpmh_arc_cmds(const char *id, void *vals, int size)
|
||||
{
|
||||
u32 len = cmd_db_read_aux_data_len(id);
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (WARN_ON(len > size))
|
||||
return -EINVAL;
|
||||
|
||||
cmd_db_read_aux_data(id, vals, len);
|
||||
|
||||
/*
|
||||
* The data comes back as an array of unsigned shorts so adjust the
|
||||
* count accordingly
|
||||
*/
|
||||
return len >> 1;
|
||||
}
|
||||
|
||||
/* Return the 'arc-level' for the given frequency */
|
||||
static u32 a6xx_gmu_get_arc_level(struct device *dev, unsigned long freq)
|
||||
{
|
||||
@ -949,11 +929,30 @@ static u32 a6xx_gmu_get_arc_level(struct device *dev, unsigned long freq)
|
||||
}
|
||||
|
||||
static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes,
|
||||
unsigned long *freqs, int freqs_count,
|
||||
u16 *pri, int pri_count,
|
||||
u16 *sec, int sec_count)
|
||||
unsigned long *freqs, int freqs_count, const char *id)
|
||||
{
|
||||
int i, j;
|
||||
const u16 *pri, *sec;
|
||||
size_t pri_count, sec_count;
|
||||
|
||||
pri = cmd_db_read_aux_data(id, &pri_count);
|
||||
if (IS_ERR(pri))
|
||||
return PTR_ERR(pri);
|
||||
/*
|
||||
* The data comes back as an array of unsigned shorts so adjust the
|
||||
* count accordingly
|
||||
*/
|
||||
pri_count >>= 1;
|
||||
if (!pri_count)
|
||||
return -EINVAL;
|
||||
|
||||
sec = cmd_db_read_aux_data("mx.lvl", &sec_count);
|
||||
if (IS_ERR(sec))
|
||||
return PTR_ERR(sec);
|
||||
|
||||
sec_count >>= 1;
|
||||
if (!sec_count)
|
||||
return -EINVAL;
|
||||
|
||||
/* Construct a vote for each frequency */
|
||||
for (i = 0; i < freqs_count; i++) {
|
||||
@ -1012,25 +1011,15 @@ static int a6xx_gmu_rpmh_votes_init(struct a6xx_gmu *gmu)
|
||||
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
|
||||
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
|
||||
struct msm_gpu *gpu = &adreno_gpu->base;
|
||||
|
||||
u16 gx[16], cx[16], mx[16];
|
||||
u32 gxcount, cxcount, mxcount;
|
||||
int ret;
|
||||
|
||||
/* Get the list of available voltage levels for each component */
|
||||
gxcount = a6xx_gmu_rpmh_arc_cmds("gfx.lvl", gx, sizeof(gx));
|
||||
cxcount = a6xx_gmu_rpmh_arc_cmds("cx.lvl", cx, sizeof(cx));
|
||||
mxcount = a6xx_gmu_rpmh_arc_cmds("mx.lvl", mx, sizeof(mx));
|
||||
|
||||
/* Build the GX votes */
|
||||
ret = a6xx_gmu_rpmh_arc_votes_init(&gpu->pdev->dev, gmu->gx_arc_votes,
|
||||
gmu->gpu_freqs, gmu->nr_gpu_freqs,
|
||||
gx, gxcount, mx, mxcount);
|
||||
gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl");
|
||||
|
||||
/* Build the CX votes */
|
||||
ret |= a6xx_gmu_rpmh_arc_votes_init(gmu->dev, gmu->cx_arc_votes,
|
||||
gmu->gmu_freqs, gmu->nr_gmu_freqs,
|
||||
cx, cxcount, mx, mxcount);
|
||||
gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -145,6 +145,15 @@ config DA8XX_DDRCTL
|
||||
Texas Instruments da8xx SoCs. It's used to tweak various memory
|
||||
controller configuration options.
|
||||
|
||||
config PL353_SMC
|
||||
tristate "ARM PL35X Static Memory Controller(SMC) driver"
|
||||
default y
|
||||
depends on ARM
|
||||
depends on ARM_AMBA
|
||||
help
|
||||
This driver is for the ARM PL351/PL353 Static Memory
|
||||
Controller(SMC) module.
|
||||
|
||||
source "drivers/memory/samsung/Kconfig"
|
||||
source "drivers/memory/tegra/Kconfig"
|
||||
|
||||
|
@ -19,6 +19,7 @@ obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
|
||||
obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
|
||||
obj-$(CONFIG_MTK_SMI) += mtk-smi.o
|
||||
obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
|
||||
obj-$(CONFIG_PL353_SMC) += pl353-smc.o
|
||||
|
||||
obj-$(CONFIG_SAMSUNG_MC) += samsung/
|
||||
obj-$(CONFIG_TEGRA_MC) += tegra/
|
||||
|
@ -2060,7 +2060,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
|
||||
* timings.
|
||||
*/
|
||||
name = gpmc_cs_get_name(cs);
|
||||
if (name && of_node_cmp(child->name, name) == 0)
|
||||
if (name && of_node_name_eq(child, name))
|
||||
goto no_timings;
|
||||
|
||||
ret = gpmc_cs_request(cs, resource_size(&res), &base);
|
||||
@ -2068,7 +2068,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
|
||||
dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
|
||||
return ret;
|
||||
}
|
||||
gpmc_cs_set_name(cs, child->name);
|
||||
gpmc_cs_set_name(cs, child->full_name);
|
||||
|
||||
gpmc_read_settings_dt(child, &gpmc_s);
|
||||
gpmc_read_timings_dt(child, &gpmc_t);
|
||||
@ -2113,7 +2113,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (of_node_cmp(child->name, "nand") == 0) {
|
||||
if (of_node_name_eq(child, "nand")) {
|
||||
/* Warn about older DT blobs with no compatible property */
|
||||
if (!of_property_read_bool(child, "compatible")) {
|
||||
dev_warn(&pdev->dev,
|
||||
@ -2123,7 +2123,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
|
||||
}
|
||||
}
|
||||
|
||||
if (of_node_cmp(child->name, "onenand") == 0) {
|
||||
if (of_node_name_eq(child, "onenand")) {
|
||||
/* Warn about older DT blobs with no compatible property */
|
||||
if (!of_property_read_bool(child, "compatible")) {
|
||||
dev_warn(&pdev->dev,
|
||||
|
463
drivers/memory/pl353-smc.c
Normal file
463
drivers/memory/pl353-smc.c
Normal file
@ -0,0 +1,463 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* ARM PL353 SMC driver
|
||||
*
|
||||
* Copyright (C) 2012 - 2018 Xilinx, Inc
|
||||
* Author: Punnaiah Choudary Kalluri <punnaiah@xilinx.com>
|
||||
* Author: Naga Sureshkumar Relli <nagasure@xilinx.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pl353-smc.h>
|
||||
#include <linux/amba/bus.h>
|
||||
|
||||
/* Register definitions */
|
||||
#define PL353_SMC_MEMC_STATUS_OFFS 0 /* Controller status reg, RO */
|
||||
#define PL353_SMC_CFG_CLR_OFFS 0xC /* Clear config reg, WO */
|
||||
#define PL353_SMC_DIRECT_CMD_OFFS 0x10 /* Direct command reg, WO */
|
||||
#define PL353_SMC_SET_CYCLES_OFFS 0x14 /* Set cycles register, WO */
|
||||
#define PL353_SMC_SET_OPMODE_OFFS 0x18 /* Set opmode register, WO */
|
||||
#define PL353_SMC_ECC_STATUS_OFFS 0x400 /* ECC status register */
|
||||
#define PL353_SMC_ECC_MEMCFG_OFFS 0x404 /* ECC mem config reg */
|
||||
#define PL353_SMC_ECC_MEMCMD1_OFFS 0x408 /* ECC mem cmd1 reg */
|
||||
#define PL353_SMC_ECC_MEMCMD2_OFFS 0x40C /* ECC mem cmd2 reg */
|
||||
#define PL353_SMC_ECC_VALUE0_OFFS 0x418 /* ECC value 0 reg */
|
||||
|
||||
/* Controller status register specific constants */
|
||||
#define PL353_SMC_MEMC_STATUS_RAW_INT_1_SHIFT 6
|
||||
|
||||
/* Clear configuration register specific constants */
|
||||
#define PL353_SMC_CFG_CLR_INT_CLR_1 0x10
|
||||
#define PL353_SMC_CFG_CLR_ECC_INT_DIS_1 0x40
|
||||
#define PL353_SMC_CFG_CLR_INT_DIS_1 0x2
|
||||
#define PL353_SMC_CFG_CLR_DEFAULT_MASK (PL353_SMC_CFG_CLR_INT_CLR_1 | \
|
||||
PL353_SMC_CFG_CLR_ECC_INT_DIS_1 | \
|
||||
PL353_SMC_CFG_CLR_INT_DIS_1)
|
||||
|
||||
/* Set cycles register specific constants */
|
||||
#define PL353_SMC_SET_CYCLES_T0_MASK 0xF
|
||||
#define PL353_SMC_SET_CYCLES_T0_SHIFT 0
|
||||
#define PL353_SMC_SET_CYCLES_T1_MASK 0xF
|
||||
#define PL353_SMC_SET_CYCLES_T1_SHIFT 4
|
||||
#define PL353_SMC_SET_CYCLES_T2_MASK 0x7
|
||||
#define PL353_SMC_SET_CYCLES_T2_SHIFT 8
|
||||
#define PL353_SMC_SET_CYCLES_T3_MASK 0x7
|
||||
#define PL353_SMC_SET_CYCLES_T3_SHIFT 11
|
||||
#define PL353_SMC_SET_CYCLES_T4_MASK 0x7
|
||||
#define PL353_SMC_SET_CYCLES_T4_SHIFT 14
|
||||
#define PL353_SMC_SET_CYCLES_T5_MASK 0x7
|
||||
#define PL353_SMC_SET_CYCLES_T5_SHIFT 17
|
||||
#define PL353_SMC_SET_CYCLES_T6_MASK 0xF
|
||||
#define PL353_SMC_SET_CYCLES_T6_SHIFT 20
|
||||
|
||||
/* ECC status register specific constants */
|
||||
#define PL353_SMC_ECC_STATUS_BUSY BIT(6)
|
||||
#define PL353_SMC_ECC_REG_SIZE_OFFS 4
|
||||
|
||||
/* ECC memory config register specific constants */
|
||||
#define PL353_SMC_ECC_MEMCFG_MODE_MASK 0xC
|
||||
#define PL353_SMC_ECC_MEMCFG_MODE_SHIFT 2
|
||||
#define PL353_SMC_ECC_MEMCFG_PGSIZE_MASK 0xC
|
||||
|
||||
#define PL353_SMC_DC_UPT_NAND_REGS ((4 << 23) | /* CS: NAND chip */ \
|
||||
(2 << 21)) /* UpdateRegs operation */
|
||||
|
||||
#define PL353_NAND_ECC_CMD1 ((0x80) | /* Write command */ \
|
||||
(0 << 8) | /* Read command */ \
|
||||
(0x30 << 16) | /* Read End command */ \
|
||||
(1 << 24)) /* Read End command calid */
|
||||
|
||||
#define PL353_NAND_ECC_CMD2 ((0x85) | /* Write col change cmd */ \
|
||||
(5 << 8) | /* Read col change cmd */ \
|
||||
(0xE0 << 16) | /* Read col change end cmd */ \
|
||||
(1 << 24)) /* Read col change end cmd valid */
|
||||
#define PL353_NAND_ECC_BUSY_TIMEOUT (1 * HZ)
|
||||
/**
|
||||
* struct pl353_smc_data - Private smc driver structure
|
||||
* @memclk: Pointer to the peripheral clock
|
||||
* @aclk: Pointer to the APER clock
|
||||
*/
|
||||
struct pl353_smc_data {
|
||||
struct clk *memclk;
|
||||
struct clk *aclk;
|
||||
};
|
||||
|
||||
/* SMC virtual register base */
|
||||
static void __iomem *pl353_smc_base;
|
||||
|
||||
/**
|
||||
* pl353_smc_set_buswidth - Set memory buswidth
|
||||
* @bw: Memory buswidth (8 | 16)
|
||||
* Return: 0 on success or negative errno.
|
||||
*/
|
||||
int pl353_smc_set_buswidth(unsigned int bw)
|
||||
{
|
||||
if (bw != PL353_SMC_MEM_WIDTH_8 && bw != PL353_SMC_MEM_WIDTH_16)
|
||||
return -EINVAL;
|
||||
|
||||
writel(bw, pl353_smc_base + PL353_SMC_SET_OPMODE_OFFS);
|
||||
writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
|
||||
PL353_SMC_DIRECT_CMD_OFFS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pl353_smc_set_buswidth);
|
||||
|
||||
/**
|
||||
* pl353_smc_set_cycles - Set memory timing parameters
|
||||
* @timings: NAND controller timing parameters
|
||||
*
|
||||
* Sets NAND chip specific timing parameters.
|
||||
*/
|
||||
void pl353_smc_set_cycles(u32 timings[])
|
||||
{
|
||||
/*
|
||||
* Set write pulse timing. This one is easy to extract:
|
||||
*
|
||||
* NWE_PULSE = tWP
|
||||
*/
|
||||
timings[0] &= PL353_SMC_SET_CYCLES_T0_MASK;
|
||||
timings[1] = (timings[1] & PL353_SMC_SET_CYCLES_T1_MASK) <<
|
||||
PL353_SMC_SET_CYCLES_T1_SHIFT;
|
||||
timings[2] = (timings[2] & PL353_SMC_SET_CYCLES_T2_MASK) <<
|
||||
PL353_SMC_SET_CYCLES_T2_SHIFT;
|
||||
timings[3] = (timings[3] & PL353_SMC_SET_CYCLES_T3_MASK) <<
|
||||
PL353_SMC_SET_CYCLES_T3_SHIFT;
|
||||
timings[4] = (timings[4] & PL353_SMC_SET_CYCLES_T4_MASK) <<
|
||||
PL353_SMC_SET_CYCLES_T4_SHIFT;
|
||||
timings[5] = (timings[5] & PL353_SMC_SET_CYCLES_T5_MASK) <<
|
||||
PL353_SMC_SET_CYCLES_T5_SHIFT;
|
||||
timings[6] = (timings[6] & PL353_SMC_SET_CYCLES_T6_MASK) <<
|
||||
PL353_SMC_SET_CYCLES_T6_SHIFT;
|
||||
timings[0] |= timings[1] | timings[2] | timings[3] |
|
||||
timings[4] | timings[5] | timings[6];
|
||||
|
||||
writel(timings[0], pl353_smc_base + PL353_SMC_SET_CYCLES_OFFS);
|
||||
writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
|
||||
PL353_SMC_DIRECT_CMD_OFFS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pl353_smc_set_cycles);
|
||||
|
||||
/**
|
||||
* pl353_smc_ecc_is_busy - Read ecc busy flag
|
||||
* Return: the ecc_status bit from the ecc_status register. 1 = busy, 0 = idle
|
||||
*/
|
||||
bool pl353_smc_ecc_is_busy(void)
|
||||
{
|
||||
return ((readl(pl353_smc_base + PL353_SMC_ECC_STATUS_OFFS) &
|
||||
PL353_SMC_ECC_STATUS_BUSY) == PL353_SMC_ECC_STATUS_BUSY);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pl353_smc_ecc_is_busy);
|
||||
|
||||
/**
|
||||
* pl353_smc_get_ecc_val - Read ecc_valueN registers
|
||||
* @ecc_reg: Index of the ecc_value reg (0..3)
|
||||
* Return: the content of the requested ecc_value register.
|
||||
*
|
||||
* There are four valid ecc_value registers. The argument is truncated to stay
|
||||
* within this valid boundary.
|
||||
*/
|
||||
u32 pl353_smc_get_ecc_val(int ecc_reg)
|
||||
{
|
||||
u32 addr, reg;
|
||||
|
||||
addr = PL353_SMC_ECC_VALUE0_OFFS +
|
||||
(ecc_reg * PL353_SMC_ECC_REG_SIZE_OFFS);
|
||||
reg = readl(pl353_smc_base + addr);
|
||||
|
||||
return reg;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pl353_smc_get_ecc_val);
|
||||
|
||||
/**
|
||||
* pl353_smc_get_nand_int_status_raw - Get NAND interrupt status bit
|
||||
* Return: the raw_int_status1 bit from the memc_status register
|
||||
*/
|
||||
int pl353_smc_get_nand_int_status_raw(void)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = readl(pl353_smc_base + PL353_SMC_MEMC_STATUS_OFFS);
|
||||
reg >>= PL353_SMC_MEMC_STATUS_RAW_INT_1_SHIFT;
|
||||
reg &= 1;
|
||||
|
||||
return reg;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pl353_smc_get_nand_int_status_raw);
|
||||
|
||||
/**
|
||||
* pl353_smc_clr_nand_int - Clear NAND interrupt
|
||||
*/
|
||||
void pl353_smc_clr_nand_int(void)
|
||||
{
|
||||
writel(PL353_SMC_CFG_CLR_INT_CLR_1,
|
||||
pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pl353_smc_clr_nand_int);
|
||||
|
||||
/**
|
||||
* pl353_smc_set_ecc_mode - Set SMC ECC mode
|
||||
* @mode: ECC mode (BYPASS, APB, MEM)
|
||||
* Return: 0 on success or negative errno.
|
||||
*/
|
||||
int pl353_smc_set_ecc_mode(enum pl353_smc_ecc_mode mode)
|
||||
{
|
||||
u32 reg;
|
||||
int ret = 0;
|
||||
|
||||
switch (mode) {
|
||||
case PL353_SMC_ECCMODE_BYPASS:
|
||||
case PL353_SMC_ECCMODE_APB:
|
||||
case PL353_SMC_ECCMODE_MEM:
|
||||
|
||||
reg = readl(pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
|
||||
reg &= ~PL353_SMC_ECC_MEMCFG_MODE_MASK;
|
||||
reg |= mode << PL353_SMC_ECC_MEMCFG_MODE_SHIFT;
|
||||
writel(reg, pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
|
||||
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pl353_smc_set_ecc_mode);
|
||||
|
||||
/**
|
||||
* pl353_smc_set_ecc_pg_size - Set SMC ECC page size
|
||||
* @pg_sz: ECC page size
|
||||
* Return: 0 on success or negative errno.
|
||||
*/
|
||||
int pl353_smc_set_ecc_pg_size(unsigned int pg_sz)
|
||||
{
|
||||
u32 reg, sz;
|
||||
|
||||
switch (pg_sz) {
|
||||
case 0:
|
||||
sz = 0;
|
||||
break;
|
||||
case SZ_512:
|
||||
sz = 1;
|
||||
break;
|
||||
case SZ_1K:
|
||||
sz = 2;
|
||||
break;
|
||||
case SZ_2K:
|
||||
sz = 3;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reg = readl(pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
|
||||
reg &= ~PL353_SMC_ECC_MEMCFG_PGSIZE_MASK;
|
||||
reg |= sz;
|
||||
writel(reg, pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pl353_smc_set_ecc_pg_size);
|
||||
|
||||
static int __maybe_unused pl353_smc_suspend(struct device *dev)
|
||||
{
|
||||
struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable(pl353_smc->memclk);
|
||||
clk_disable(pl353_smc->aclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused pl353_smc_resume(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev);
|
||||
|
||||
ret = clk_enable(pl353_smc->aclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "Cannot enable axi domain clock.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(pl353_smc->memclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "Cannot enable memory clock.\n");
|
||||
clk_disable(pl353_smc->aclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct amba_driver pl353_smc_driver;
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(pl353_smc_dev_pm_ops, pl353_smc_suspend,
|
||||
pl353_smc_resume);
|
||||
|
||||
/**
|
||||
* pl353_smc_init_nand_interface - Initialize the NAND interface
|
||||
* @adev: Pointer to the amba_device struct
|
||||
* @nand_node: Pointer to the pl353_nand device_node struct
|
||||
*/
|
||||
static void pl353_smc_init_nand_interface(struct amba_device *adev,
|
||||
struct device_node *nand_node)
|
||||
{
|
||||
unsigned long timeout;
|
||||
|
||||
pl353_smc_set_buswidth(PL353_SMC_MEM_WIDTH_8);
|
||||
writel(PL353_SMC_CFG_CLR_INT_CLR_1,
|
||||
pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
|
||||
writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
|
||||
PL353_SMC_DIRECT_CMD_OFFS);
|
||||
|
||||
timeout = jiffies + PL353_NAND_ECC_BUSY_TIMEOUT;
|
||||
/* Wait till the ECC operation is complete */
|
||||
do {
|
||||
if (pl353_smc_ecc_is_busy())
|
||||
cpu_relax();
|
||||
else
|
||||
break;
|
||||
} while (!time_after_eq(jiffies, timeout));
|
||||
|
||||
if (time_after_eq(jiffies, timeout))
|
||||
return;
|
||||
|
||||
writel(PL353_NAND_ECC_CMD1,
|
||||
pl353_smc_base + PL353_SMC_ECC_MEMCMD1_OFFS);
|
||||
writel(PL353_NAND_ECC_CMD2,
|
||||
pl353_smc_base + PL353_SMC_ECC_MEMCMD2_OFFS);
|
||||
}
|
||||
|
||||
static const struct of_device_id pl353_smc_supported_children[] = {
|
||||
{
|
||||
.compatible = "cfi-flash"
|
||||
},
|
||||
{
|
||||
.compatible = "arm,pl353-nand-r2p1",
|
||||
.data = pl353_smc_init_nand_interface
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
{
|
||||
struct pl353_smc_data *pl353_smc;
|
||||
struct device_node *child;
|
||||
struct resource *res;
|
||||
int err;
|
||||
struct device_node *of_node = adev->dev.of_node;
|
||||
static void (*init)(struct amba_device *adev,
|
||||
struct device_node *nand_node);
|
||||
const struct of_device_id *match = NULL;
|
||||
|
||||
pl353_smc = devm_kzalloc(&adev->dev, sizeof(*pl353_smc), GFP_KERNEL);
|
||||
if (!pl353_smc)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Get the NAND controller virtual address */
|
||||
res = &adev->res;
|
||||
pl353_smc_base = devm_ioremap_resource(&adev->dev, res);
|
||||
if (IS_ERR(pl353_smc_base))
|
||||
return PTR_ERR(pl353_smc_base);
|
||||
|
||||
pl353_smc->aclk = devm_clk_get(&adev->dev, "apb_pclk");
|
||||
if (IS_ERR(pl353_smc->aclk)) {
|
||||
dev_err(&adev->dev, "aclk clock not found.\n");
|
||||
return PTR_ERR(pl353_smc->aclk);
|
||||
}
|
||||
|
||||
pl353_smc->memclk = devm_clk_get(&adev->dev, "memclk");
|
||||
if (IS_ERR(pl353_smc->memclk)) {
|
||||
dev_err(&adev->dev, "memclk clock not found.\n");
|
||||
return PTR_ERR(pl353_smc->memclk);
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(pl353_smc->aclk);
|
||||
if (err) {
|
||||
dev_err(&adev->dev, "Unable to enable AXI clock.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(pl353_smc->memclk);
|
||||
if (err) {
|
||||
dev_err(&adev->dev, "Unable to enable memory clock.\n");
|
||||
goto out_clk_dis_aper;
|
||||
}
|
||||
|
||||
amba_set_drvdata(adev, pl353_smc);
|
||||
|
||||
/* clear interrupts */
|
||||
writel(PL353_SMC_CFG_CLR_DEFAULT_MASK,
|
||||
pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
|
||||
|
||||
/* Find compatible children. Only a single child is supported */
|
||||
for_each_available_child_of_node(of_node, child) {
|
||||
match = of_match_node(pl353_smc_supported_children, child);
|
||||
if (!match) {
|
||||
dev_warn(&adev->dev, "unsupported child node\n");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!match) {
|
||||
dev_err(&adev->dev, "no matching children\n");
|
||||
goto out_clk_disable;
|
||||
}
|
||||
|
||||
init = match->data;
|
||||
if (init)
|
||||
init(adev, child);
|
||||
of_platform_device_create(child, NULL, &adev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
out_clk_disable:
|
||||
clk_disable_unprepare(pl353_smc->memclk);
|
||||
out_clk_dis_aper:
|
||||
clk_disable_unprepare(pl353_smc->aclk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int pl353_smc_remove(struct amba_device *adev)
|
||||
{
|
||||
struct pl353_smc_data *pl353_smc = amba_get_drvdata(adev);
|
||||
|
||||
clk_disable_unprepare(pl353_smc->memclk);
|
||||
clk_disable_unprepare(pl353_smc->aclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amba_id pl353_ids[] = {
|
||||
{
|
||||
.id = 0x00041353,
|
||||
.mask = 0x000fffff,
|
||||
},
|
||||
{ 0, 0 },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(amba, pl353_ids);
|
||||
|
||||
static struct amba_driver pl353_smc_driver = {
|
||||
.drv = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pl353-smc",
|
||||
.pm = &pl353_smc_dev_pm_ops,
|
||||
},
|
||||
.id_table = pl353_ids,
|
||||
.probe = pl353_smc_probe,
|
||||
.remove = pl353_smc_remove,
|
||||
};
|
||||
|
||||
module_amba_driver(pl353_smc_driver);
|
||||
|
||||
MODULE_AUTHOR("Xilinx, Inc.");
|
||||
MODULE_DESCRIPTION("ARM PL353 SMC Driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -6,6 +6,16 @@ config TEGRA_MC
|
||||
This driver supports the Memory Controller (MC) hardware found on
|
||||
NVIDIA Tegra SoCs.
|
||||
|
||||
config TEGRA20_EMC
|
||||
bool "NVIDIA Tegra20 External Memory Controller driver"
|
||||
default y
|
||||
depends on ARCH_TEGRA_2x_SOC
|
||||
help
|
||||
This driver is for the External Memory Controller (EMC) found on
|
||||
Tegra20 chips. The EMC controls the external DRAM on the board.
|
||||
This driver is required to change memory timings / clock rate for
|
||||
external memory.
|
||||
|
||||
config TEGRA124_EMC
|
||||
bool "NVIDIA Tegra124 External Memory Controller driver"
|
||||
default y
|
||||
|
@ -10,5 +10,6 @@ tegra-mc-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
|
||||
|
||||
obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
|
||||
|
||||
obj-$(CONFIG_TEGRA20_EMC) += tegra20-emc.o
|
||||
obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
|
||||
|
591
drivers/memory/tegra/tegra20-emc.c
Normal file
591
drivers/memory/tegra/tegra20-emc.c
Normal file
@ -0,0 +1,591 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Tegra20 External Memory Controller driver
|
||||
*
|
||||
* Author: Dmitry Osipenko <digetx@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
||||
#define EMC_INTSTATUS 0x000
|
||||
#define EMC_INTMASK 0x004
|
||||
#define EMC_TIMING_CONTROL 0x028
|
||||
#define EMC_RC 0x02c
|
||||
#define EMC_RFC 0x030
|
||||
#define EMC_RAS 0x034
|
||||
#define EMC_RP 0x038
|
||||
#define EMC_R2W 0x03c
|
||||
#define EMC_W2R 0x040
|
||||
#define EMC_R2P 0x044
|
||||
#define EMC_W2P 0x048
|
||||
#define EMC_RD_RCD 0x04c
|
||||
#define EMC_WR_RCD 0x050
|
||||
#define EMC_RRD 0x054
|
||||
#define EMC_REXT 0x058
|
||||
#define EMC_WDV 0x05c
|
||||
#define EMC_QUSE 0x060
|
||||
#define EMC_QRST 0x064
|
||||
#define EMC_QSAFE 0x068
|
||||
#define EMC_RDV 0x06c
|
||||
#define EMC_REFRESH 0x070
|
||||
#define EMC_BURST_REFRESH_NUM 0x074
|
||||
#define EMC_PDEX2WR 0x078
|
||||
#define EMC_PDEX2RD 0x07c
|
||||
#define EMC_PCHG2PDEN 0x080
|
||||
#define EMC_ACT2PDEN 0x084
|
||||
#define EMC_AR2PDEN 0x088
|
||||
#define EMC_RW2PDEN 0x08c
|
||||
#define EMC_TXSR 0x090
|
||||
#define EMC_TCKE 0x094
|
||||
#define EMC_TFAW 0x098
|
||||
#define EMC_TRPAB 0x09c
|
||||
#define EMC_TCLKSTABLE 0x0a0
|
||||
#define EMC_TCLKSTOP 0x0a4
|
||||
#define EMC_TREFBW 0x0a8
|
||||
#define EMC_QUSE_EXTRA 0x0ac
|
||||
#define EMC_ODT_WRITE 0x0b0
|
||||
#define EMC_ODT_READ 0x0b4
|
||||
#define EMC_FBIO_CFG5 0x104
|
||||
#define EMC_FBIO_CFG6 0x114
|
||||
#define EMC_AUTO_CAL_INTERVAL 0x2a8
|
||||
#define EMC_CFG_2 0x2b8
|
||||
#define EMC_CFG_DIG_DLL 0x2bc
|
||||
#define EMC_DLL_XFORM_DQS 0x2c0
|
||||
#define EMC_DLL_XFORM_QUSE 0x2c4
|
||||
#define EMC_ZCAL_REF_CNT 0x2e0
|
||||
#define EMC_ZCAL_WAIT_CNT 0x2e4
|
||||
#define EMC_CFG_CLKTRIM_0 0x2d0
|
||||
#define EMC_CFG_CLKTRIM_1 0x2d4
|
||||
#define EMC_CFG_CLKTRIM_2 0x2d8
|
||||
|
||||
#define EMC_CLKCHANGE_REQ_ENABLE BIT(0)
|
||||
#define EMC_CLKCHANGE_PD_ENABLE BIT(1)
|
||||
#define EMC_CLKCHANGE_SR_ENABLE BIT(2)
|
||||
|
||||
#define EMC_TIMING_UPDATE BIT(0)
|
||||
|
||||
#define EMC_REFRESH_OVERFLOW_INT BIT(3)
|
||||
#define EMC_CLKCHANGE_COMPLETE_INT BIT(4)
|
||||
|
||||
static const u16 emc_timing_registers[] = {
|
||||
EMC_RC,
|
||||
EMC_RFC,
|
||||
EMC_RAS,
|
||||
EMC_RP,
|
||||
EMC_R2W,
|
||||
EMC_W2R,
|
||||
EMC_R2P,
|
||||
EMC_W2P,
|
||||
EMC_RD_RCD,
|
||||
EMC_WR_RCD,
|
||||
EMC_RRD,
|
||||
EMC_REXT,
|
||||
EMC_WDV,
|
||||
EMC_QUSE,
|
||||
EMC_QRST,
|
||||
EMC_QSAFE,
|
||||
EMC_RDV,
|
||||
EMC_REFRESH,
|
||||
EMC_BURST_REFRESH_NUM,
|
||||
EMC_PDEX2WR,
|
||||
EMC_PDEX2RD,
|
||||
EMC_PCHG2PDEN,
|
||||
EMC_ACT2PDEN,
|
||||
EMC_AR2PDEN,
|
||||
EMC_RW2PDEN,
|
||||
EMC_TXSR,
|
||||
EMC_TCKE,
|
||||
EMC_TFAW,
|
||||
EMC_TRPAB,
|
||||
EMC_TCLKSTABLE,
|
||||
EMC_TCLKSTOP,
|
||||
EMC_TREFBW,
|
||||
EMC_QUSE_EXTRA,
|
||||
EMC_FBIO_CFG6,
|
||||
EMC_ODT_WRITE,
|
||||
EMC_ODT_READ,
|
||||
EMC_FBIO_CFG5,
|
||||
EMC_CFG_DIG_DLL,
|
||||
EMC_DLL_XFORM_DQS,
|
||||
EMC_DLL_XFORM_QUSE,
|
||||
EMC_ZCAL_REF_CNT,
|
||||
EMC_ZCAL_WAIT_CNT,
|
||||
EMC_AUTO_CAL_INTERVAL,
|
||||
EMC_CFG_CLKTRIM_0,
|
||||
EMC_CFG_CLKTRIM_1,
|
||||
EMC_CFG_CLKTRIM_2,
|
||||
};
|
||||
|
||||
struct emc_timing {
|
||||
unsigned long rate;
|
||||
u32 data[ARRAY_SIZE(emc_timing_registers)];
|
||||
};
|
||||
|
||||
struct tegra_emc {
|
||||
struct device *dev;
|
||||
struct completion clk_handshake_complete;
|
||||
struct notifier_block clk_nb;
|
||||
struct clk *backup_clk;
|
||||
struct clk *emc_mux;
|
||||
struct clk *pll_m;
|
||||
struct clk *clk;
|
||||
void __iomem *regs;
|
||||
|
||||
struct emc_timing *timings;
|
||||
unsigned int num_timings;
|
||||
};
|
||||
|
||||
static irqreturn_t tegra_emc_isr(int irq, void *data)
|
||||
{
|
||||
struct tegra_emc *emc = data;
|
||||
u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
|
||||
u32 status;
|
||||
|
||||
status = readl_relaxed(emc->regs + EMC_INTSTATUS) & intmask;
|
||||
if (!status)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* notify about EMC-CAR handshake completion */
|
||||
if (status & EMC_CLKCHANGE_COMPLETE_INT)
|
||||
complete(&emc->clk_handshake_complete);
|
||||
|
||||
/* notify about HW problem */
|
||||
if (status & EMC_REFRESH_OVERFLOW_INT)
|
||||
dev_err_ratelimited(emc->dev,
|
||||
"refresh request overflow timeout\n");
|
||||
|
||||
/* clear interrupts */
|
||||
writel_relaxed(status, emc->regs + EMC_INTSTATUS);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc,
|
||||
unsigned long rate)
|
||||
{
|
||||
struct emc_timing *timing = NULL;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < emc->num_timings; i++) {
|
||||
if (emc->timings[i].rate >= rate) {
|
||||
timing = &emc->timings[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!timing) {
|
||||
dev_err(emc->dev, "no timing for rate %lu\n", rate);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return timing;
|
||||
}
|
||||
|
||||
static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
|
||||
{
|
||||
struct emc_timing *timing = tegra_emc_find_timing(emc, rate);
|
||||
unsigned int i;
|
||||
|
||||
if (!timing)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(emc->dev, "%s: using timing rate %lu for requested rate %lu\n",
|
||||
__func__, timing->rate, rate);
|
||||
|
||||
/* program shadow registers */
|
||||
for (i = 0; i < ARRAY_SIZE(timing->data); i++)
|
||||
writel_relaxed(timing->data[i],
|
||||
emc->regs + emc_timing_registers[i]);
|
||||
|
||||
/* wait until programming has settled */
|
||||
readl_relaxed(emc->regs + emc_timing_registers[i - 1]);
|
||||
|
||||
reinit_completion(&emc->clk_handshake_complete);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int emc_complete_timing_change(struct tegra_emc *emc, bool flush)
|
||||
{
|
||||
long timeout;
|
||||
|
||||
dev_dbg(emc->dev, "%s: flush %d\n", __func__, flush);
|
||||
|
||||
if (flush) {
|
||||
/* manually initiate memory timing update */
|
||||
writel_relaxed(EMC_TIMING_UPDATE,
|
||||
emc->regs + EMC_TIMING_CONTROL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
timeout = wait_for_completion_timeout(&emc->clk_handshake_complete,
|
||||
usecs_to_jiffies(100));
|
||||
if (timeout == 0) {
|
||||
dev_err(emc->dev, "EMC-CAR handshake failed\n");
|
||||
return -EIO;
|
||||
} else if (timeout < 0) {
|
||||
dev_err(emc->dev, "failed to wait for EMC-CAR handshake: %ld\n",
|
||||
timeout);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_emc_clk_change_notify(struct notifier_block *nb,
|
||||
unsigned long msg, void *data)
|
||||
{
|
||||
struct tegra_emc *emc = container_of(nb, struct tegra_emc, clk_nb);
|
||||
struct clk_notifier_data *cnd = data;
|
||||
int err;
|
||||
|
||||
switch (msg) {
|
||||
case PRE_RATE_CHANGE:
|
||||
err = emc_prepare_timing_change(emc, cnd->new_rate);
|
||||
break;
|
||||
|
||||
case ABORT_RATE_CHANGE:
|
||||
err = emc_prepare_timing_change(emc, cnd->old_rate);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
err = emc_complete_timing_change(emc, true);
|
||||
break;
|
||||
|
||||
case POST_RATE_CHANGE:
|
||||
err = emc_complete_timing_change(emc, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
static int load_one_timing_from_dt(struct tegra_emc *emc,
|
||||
struct emc_timing *timing,
|
||||
struct device_node *node)
|
||||
{
|
||||
u32 rate;
|
||||
int err;
|
||||
|
||||
if (!of_device_is_compatible(node, "nvidia,tegra20-emc-table")) {
|
||||
dev_err(emc->dev, "incompatible DT node: %pOF\n", node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = of_property_read_u32(node, "clock-frequency", &rate);
|
||||
if (err) {
|
||||
dev_err(emc->dev, "timing %pOF: failed to read rate: %d\n",
|
||||
node, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = of_property_read_u32_array(node, "nvidia,emc-registers",
|
||||
timing->data,
|
||||
ARRAY_SIZE(emc_timing_registers));
|
||||
if (err) {
|
||||
dev_err(emc->dev,
|
||||
"timing %pOF: failed to read emc timing data: %d\n",
|
||||
node, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* The EMC clock rate is twice the bus rate, and the bus rate is
|
||||
* measured in kHz.
|
||||
*/
|
||||
timing->rate = rate * 2 * 1000;
|
||||
|
||||
dev_dbg(emc->dev, "%s: %pOF: EMC rate %lu\n",
|
||||
__func__, node, timing->rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmp_timings(const void *_a, const void *_b)
|
||||
{
|
||||
const struct emc_timing *a = _a;
|
||||
const struct emc_timing *b = _b;
|
||||
|
||||
if (a->rate < b->rate)
|
||||
return -1;
|
||||
|
||||
if (a->rate > b->rate)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
|
||||
struct device_node *node)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct emc_timing *timing;
|
||||
int child_count;
|
||||
int err;
|
||||
|
||||
child_count = of_get_child_count(node);
|
||||
if (!child_count) {
|
||||
dev_err(emc->dev, "no memory timings in DT node: %pOF\n", node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
emc->timings = devm_kcalloc(emc->dev, child_count, sizeof(*timing),
|
||||
GFP_KERNEL);
|
||||
if (!emc->timings)
|
||||
return -ENOMEM;
|
||||
|
||||
emc->num_timings = child_count;
|
||||
timing = emc->timings;
|
||||
|
||||
for_each_child_of_node(node, child) {
|
||||
err = load_one_timing_from_dt(emc, timing++, child);
|
||||
if (err) {
|
||||
of_node_put(child);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings,
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_node *
|
||||
tegra_emc_find_node_by_ram_code(struct device *dev)
|
||||
{
|
||||
struct device_node *np;
|
||||
u32 value, ram_code;
|
||||
int err;
|
||||
|
||||
if (!of_property_read_bool(dev->of_node, "nvidia,use-ram-code"))
|
||||
return of_node_get(dev->of_node);
|
||||
|
||||
ram_code = tegra_read_ram_code();
|
||||
|
||||
for (np = of_find_node_by_name(dev->of_node, "emc-tables"); np;
|
||||
np = of_find_node_by_name(np, "emc-tables")) {
|
||||
err = of_property_read_u32(np, "nvidia,ram-code", &value);
|
||||
if (err || value != ram_code) {
|
||||
of_node_put(np);
|
||||
continue;
|
||||
}
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
dev_err(dev, "no memory timings for RAM code %u found in device tree\n",
|
||||
ram_code);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int emc_setup_hw(struct tegra_emc *emc)
|
||||
{
|
||||
u32 intmask = EMC_REFRESH_OVERFLOW_INT | EMC_CLKCHANGE_COMPLETE_INT;
|
||||
u32 emc_cfg;
|
||||
|
||||
emc_cfg = readl_relaxed(emc->regs + EMC_CFG_2);
|
||||
|
||||
/*
|
||||
* Depending on a memory type, DRAM should enter either self-refresh
|
||||
* or power-down state on EMC clock change.
|
||||
*/
|
||||
if (!(emc_cfg & EMC_CLKCHANGE_PD_ENABLE) &&
|
||||
!(emc_cfg & EMC_CLKCHANGE_SR_ENABLE)) {
|
||||
dev_err(emc->dev,
|
||||
"bootloader didn't specify DRAM auto-suspend mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* enable EMC and CAR to handshake on PLL divider/source changes */
|
||||
emc_cfg |= EMC_CLKCHANGE_REQ_ENABLE;
|
||||
writel_relaxed(emc_cfg, emc->regs + EMC_CFG_2);
|
||||
|
||||
/* initialize interrupt */
|
||||
writel_relaxed(intmask, emc->regs + EMC_INTMASK);
|
||||
writel_relaxed(intmask, emc->regs + EMC_INTSTATUS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int emc_init(struct tegra_emc *emc, unsigned long rate)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = clk_set_parent(emc->emc_mux, emc->backup_clk);
|
||||
if (err) {
|
||||
dev_err(emc->dev,
|
||||
"failed to reparent to backup source: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = clk_set_rate(emc->pll_m, rate);
|
||||
if (err) {
|
||||
dev_err(emc->dev,
|
||||
"failed to change pll_m rate: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = clk_set_parent(emc->emc_mux, emc->pll_m);
|
||||
if (err) {
|
||||
dev_err(emc->dev,
|
||||
"failed to reparent to pll_m: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = clk_set_rate(emc->clk, rate);
|
||||
if (err) {
|
||||
dev_err(emc->dev,
|
||||
"failed to change emc rate: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_emc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct tegra_emc *emc;
|
||||
struct resource *res;
|
||||
int irq, err;
|
||||
|
||||
/* driver has nothing to do in a case of memory timing absence */
|
||||
if (of_get_child_count(pdev->dev.of_node) == 0) {
|
||||
dev_info(&pdev->dev,
|
||||
"EMC device tree node doesn't have memory timings\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "interrupt not specified\n");
|
||||
dev_err(&pdev->dev, "please update your device tree\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
np = tegra_emc_find_node_by_ram_code(&pdev->dev);
|
||||
if (!np)
|
||||
return -EINVAL;
|
||||
|
||||
emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
|
||||
if (!emc) {
|
||||
of_node_put(np);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
init_completion(&emc->clk_handshake_complete);
|
||||
emc->clk_nb.notifier_call = tegra_emc_clk_change_notify;
|
||||
emc->dev = &pdev->dev;
|
||||
|
||||
err = tegra_emc_load_timings_from_dt(emc, np);
|
||||
of_node_put(np);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
emc->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(emc->regs))
|
||||
return PTR_ERR(emc->regs);
|
||||
|
||||
err = emc_setup_hw(emc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devm_request_irq(&pdev->dev, irq, tegra_emc_isr, 0,
|
||||
dev_name(&pdev->dev), emc);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", irq, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
emc->clk = devm_clk_get(&pdev->dev, "emc");
|
||||
if (IS_ERR(emc->clk)) {
|
||||
err = PTR_ERR(emc->clk);
|
||||
dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
emc->pll_m = clk_get_sys(NULL, "pll_m");
|
||||
if (IS_ERR(emc->pll_m)) {
|
||||
err = PTR_ERR(emc->pll_m);
|
||||
dev_err(&pdev->dev, "failed to get pll_m clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
emc->backup_clk = clk_get_sys(NULL, "pll_p");
|
||||
if (IS_ERR(emc->backup_clk)) {
|
||||
err = PTR_ERR(emc->backup_clk);
|
||||
dev_err(&pdev->dev, "failed to get pll_p clock: %d\n", err);
|
||||
goto put_pll_m;
|
||||
}
|
||||
|
||||
emc->emc_mux = clk_get_parent(emc->clk);
|
||||
if (IS_ERR(emc->emc_mux)) {
|
||||
err = PTR_ERR(emc->emc_mux);
|
||||
dev_err(&pdev->dev, "failed to get emc_mux clock: %d\n", err);
|
||||
goto put_backup;
|
||||
}
|
||||
|
||||
err = clk_notifier_register(emc->clk, &emc->clk_nb);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to register clk notifier: %d\n",
|
||||
err);
|
||||
goto put_backup;
|
||||
}
|
||||
|
||||
/* set DRAM clock rate to maximum */
|
||||
err = emc_init(emc, emc->timings[emc->num_timings - 1].rate);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to initialize EMC clock rate: %d\n",
|
||||
err);
|
||||
goto unreg_notifier;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
unreg_notifier:
|
||||
clk_notifier_unregister(emc->clk, &emc->clk_nb);
|
||||
put_backup:
|
||||
clk_put(emc->backup_clk);
|
||||
put_pll_m:
|
||||
clk_put(emc->pll_m);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct of_device_id tegra_emc_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra20-emc", },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver tegra_emc_driver = {
|
||||
.probe = tegra_emc_probe,
|
||||
.driver = {
|
||||
.name = "tegra20-emc",
|
||||
.of_match_table = tegra_emc_of_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init tegra_emc_init(void)
|
||||
{
|
||||
return platform_driver_register(&tegra_emc_driver);
|
||||
}
|
||||
subsys_initcall(tegra_emc_init);
|
@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_GEMINI) += gemini/
|
||||
obj-$(CONFIG_ARCH_MXC) += imx/
|
||||
obj-$(CONFIG_SOC_XWAY) += lantiq/
|
||||
obj-y += mediatek/
|
||||
obj-$(CONFIG_ARCH_MESON) += amlogic/
|
||||
obj-y += amlogic/
|
||||
obj-y += qcom/
|
||||
obj-y += renesas/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
|
@ -7,6 +7,15 @@ config MESON_CANVAS
|
||||
help
|
||||
Say yes to support the canvas IP for Amlogic SoCs.
|
||||
|
||||
config MESON_CLK_MEASURE
|
||||
bool "Amlogic Meson SoC Clock Measure driver"
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
default ARCH_MESON
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Say yes to support of Measuring a set of internal SoC clocks
|
||||
from the debugfs interface.
|
||||
|
||||
config MESON_GX_SOCINFO
|
||||
bool "Amlogic Meson GX SoC Information driver"
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
|
@ -1,4 +1,5 @@
|
||||
obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o
|
||||
obj-$(CONFIG_MESON_CLK_MEASURE) += meson-clk-measure.o
|
||||
obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
|
||||
obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o
|
||||
obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
|
||||
|
350
drivers/soc/amlogic/meson-clk-measure.c
Normal file
350
drivers/soc/amlogic/meson-clk-measure.c
Normal file
@ -0,0 +1,350 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2018 BayLibre, SAS
|
||||
* Author: Neil Armstrong <narmstrong@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define MSR_CLK_DUTY 0x0
|
||||
#define MSR_CLK_REG0 0x4
|
||||
#define MSR_CLK_REG1 0x8
|
||||
#define MSR_CLK_REG2 0xc
|
||||
|
||||
#define MSR_DURATION GENMASK(15, 0)
|
||||
#define MSR_ENABLE BIT(16)
|
||||
#define MSR_CONT BIT(17) /* continuous measurement */
|
||||
#define MSR_INTR BIT(18) /* interrupts */
|
||||
#define MSR_RUN BIT(19)
|
||||
#define MSR_CLK_SRC GENMASK(26, 20)
|
||||
#define MSR_BUSY BIT(31)
|
||||
|
||||
#define MSR_VAL_MASK GENMASK(15, 0)
|
||||
|
||||
#define DIV_MIN 32
|
||||
#define DIV_STEP 32
|
||||
#define DIV_MAX 640
|
||||
|
||||
#define CLK_MSR_MAX 128
|
||||
|
||||
struct meson_msr_id {
|
||||
struct meson_msr *priv;
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct meson_msr {
|
||||
struct regmap *regmap;
|
||||
struct meson_msr_id msr_table[CLK_MSR_MAX];
|
||||
};
|
||||
|
||||
#define CLK_MSR_ID(__id, __name) \
|
||||
[__id] = {.id = __id, .name = __name,}
|
||||
|
||||
static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = {
|
||||
CLK_MSR_ID(0, "ring_osc_out_ee0"),
|
||||
CLK_MSR_ID(1, "ring_osc_out_ee1"),
|
||||
CLK_MSR_ID(2, "ring_osc_out_ee2"),
|
||||
CLK_MSR_ID(3, "a9_ring_osck"),
|
||||
CLK_MSR_ID(6, "vid_pll"),
|
||||
CLK_MSR_ID(7, "clk81"),
|
||||
CLK_MSR_ID(8, "encp"),
|
||||
CLK_MSR_ID(9, "encl"),
|
||||
CLK_MSR_ID(11, "eth_rmii"),
|
||||
CLK_MSR_ID(13, "amclk"),
|
||||
CLK_MSR_ID(14, "fec_clk_0"),
|
||||
CLK_MSR_ID(15, "fec_clk_1"),
|
||||
CLK_MSR_ID(16, "fec_clk_2"),
|
||||
CLK_MSR_ID(18, "a9_clk_div16"),
|
||||
CLK_MSR_ID(19, "hdmi_sys"),
|
||||
CLK_MSR_ID(20, "rtc_osc_clk_out"),
|
||||
CLK_MSR_ID(21, "i2s_clk_in_src0"),
|
||||
CLK_MSR_ID(22, "clk_rmii_from_pad"),
|
||||
CLK_MSR_ID(23, "hdmi_ch0_tmds"),
|
||||
CLK_MSR_ID(24, "lvds_fifo"),
|
||||
CLK_MSR_ID(26, "sc_clk_int"),
|
||||
CLK_MSR_ID(28, "sar_adc"),
|
||||
CLK_MSR_ID(30, "mpll_clk_test_out"),
|
||||
CLK_MSR_ID(31, "audac_clkpi"),
|
||||
CLK_MSR_ID(32, "vdac"),
|
||||
CLK_MSR_ID(33, "sdhc_rx"),
|
||||
CLK_MSR_ID(34, "sdhc_sd"),
|
||||
CLK_MSR_ID(35, "mali"),
|
||||
CLK_MSR_ID(36, "hdmi_tx_pixel"),
|
||||
CLK_MSR_ID(38, "vdin_meas"),
|
||||
CLK_MSR_ID(39, "pcm_sclk"),
|
||||
CLK_MSR_ID(40, "pcm_mclk"),
|
||||
CLK_MSR_ID(41, "eth_rx_tx"),
|
||||
CLK_MSR_ID(42, "pwm_d"),
|
||||
CLK_MSR_ID(43, "pwm_c"),
|
||||
CLK_MSR_ID(44, "pwm_b"),
|
||||
CLK_MSR_ID(45, "pwm_a"),
|
||||
CLK_MSR_ID(46, "pcm2_sclk"),
|
||||
CLK_MSR_ID(47, "ddr_dpll_pt"),
|
||||
CLK_MSR_ID(48, "pwm_f"),
|
||||
CLK_MSR_ID(49, "pwm_e"),
|
||||
CLK_MSR_ID(59, "hcodec"),
|
||||
CLK_MSR_ID(60, "usb_32k_alt"),
|
||||
CLK_MSR_ID(61, "gpio"),
|
||||
CLK_MSR_ID(62, "vid2_pll"),
|
||||
CLK_MSR_ID(63, "mipi_csi_cfg"),
|
||||
};
|
||||
|
||||
static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = {
|
||||
CLK_MSR_ID(0, "ring_osc_out_ee_0"),
|
||||
CLK_MSR_ID(1, "ring_osc_out_ee_1"),
|
||||
CLK_MSR_ID(2, "ring_osc_out_ee_2"),
|
||||
CLK_MSR_ID(3, "a53_ring_osc"),
|
||||
CLK_MSR_ID(4, "gp0_pll"),
|
||||
CLK_MSR_ID(6, "enci"),
|
||||
CLK_MSR_ID(7, "clk81"),
|
||||
CLK_MSR_ID(8, "encp"),
|
||||
CLK_MSR_ID(9, "encl"),
|
||||
CLK_MSR_ID(10, "vdac"),
|
||||
CLK_MSR_ID(11, "rgmii_tx"),
|
||||
CLK_MSR_ID(12, "pdm"),
|
||||
CLK_MSR_ID(13, "amclk"),
|
||||
CLK_MSR_ID(14, "fec_0"),
|
||||
CLK_MSR_ID(15, "fec_1"),
|
||||
CLK_MSR_ID(16, "fec_2"),
|
||||
CLK_MSR_ID(17, "sys_pll_div16"),
|
||||
CLK_MSR_ID(18, "sys_cpu_div16"),
|
||||
CLK_MSR_ID(19, "hdmitx_sys"),
|
||||
CLK_MSR_ID(20, "rtc_osc_out"),
|
||||
CLK_MSR_ID(21, "i2s_in_src0"),
|
||||
CLK_MSR_ID(22, "eth_phy_ref"),
|
||||
CLK_MSR_ID(23, "hdmi_todig"),
|
||||
CLK_MSR_ID(26, "sc_int"),
|
||||
CLK_MSR_ID(28, "sar_adc"),
|
||||
CLK_MSR_ID(31, "mpll_test_out"),
|
||||
CLK_MSR_ID(32, "vdec"),
|
||||
CLK_MSR_ID(35, "mali"),
|
||||
CLK_MSR_ID(36, "hdmi_tx_pixel"),
|
||||
CLK_MSR_ID(37, "i958"),
|
||||
CLK_MSR_ID(38, "vdin_meas"),
|
||||
CLK_MSR_ID(39, "pcm_sclk"),
|
||||
CLK_MSR_ID(40, "pcm_mclk"),
|
||||
CLK_MSR_ID(41, "eth_rx_or_rmii"),
|
||||
CLK_MSR_ID(42, "mp0_out"),
|
||||
CLK_MSR_ID(43, "fclk_div5"),
|
||||
CLK_MSR_ID(44, "pwm_b"),
|
||||
CLK_MSR_ID(45, "pwm_a"),
|
||||
CLK_MSR_ID(46, "vpu"),
|
||||
CLK_MSR_ID(47, "ddr_dpll_pt"),
|
||||
CLK_MSR_ID(48, "mp1_out"),
|
||||
CLK_MSR_ID(49, "mp2_out"),
|
||||
CLK_MSR_ID(50, "mp3_out"),
|
||||
CLK_MSR_ID(51, "nand_core"),
|
||||
CLK_MSR_ID(52, "sd_emmc_b"),
|
||||
CLK_MSR_ID(53, "sd_emmc_a"),
|
||||
CLK_MSR_ID(55, "vid_pll_div_out"),
|
||||
CLK_MSR_ID(56, "cci"),
|
||||
CLK_MSR_ID(57, "wave420l_c"),
|
||||
CLK_MSR_ID(58, "wave420l_b"),
|
||||
CLK_MSR_ID(59, "hcodec"),
|
||||
CLK_MSR_ID(60, "alt_32k"),
|
||||
CLK_MSR_ID(61, "gpio_msr"),
|
||||
CLK_MSR_ID(62, "hevc"),
|
||||
CLK_MSR_ID(66, "vid_lock"),
|
||||
CLK_MSR_ID(70, "pwm_f"),
|
||||
CLK_MSR_ID(71, "pwm_e"),
|
||||
CLK_MSR_ID(72, "pwm_d"),
|
||||
CLK_MSR_ID(73, "pwm_c"),
|
||||
CLK_MSR_ID(75, "aoclkx2_int"),
|
||||
CLK_MSR_ID(76, "aoclk_int"),
|
||||
CLK_MSR_ID(77, "rng_ring_osc_0"),
|
||||
CLK_MSR_ID(78, "rng_ring_osc_1"),
|
||||
CLK_MSR_ID(79, "rng_ring_osc_2"),
|
||||
CLK_MSR_ID(80, "rng_ring_osc_3"),
|
||||
CLK_MSR_ID(81, "vapb"),
|
||||
CLK_MSR_ID(82, "ge2d"),
|
||||
};
|
||||
|
||||
static int meson_measure_id(struct meson_msr_id *clk_msr_id,
|
||||
unsigned int duration)
|
||||
{
|
||||
struct meson_msr *priv = clk_msr_id->priv;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
regmap_write(priv->regmap, MSR_CLK_REG0, 0);
|
||||
|
||||
/* Set measurement duration */
|
||||
regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION,
|
||||
FIELD_PREP(MSR_DURATION, duration - 1));
|
||||
|
||||
/* Set ID */
|
||||
regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC,
|
||||
FIELD_PREP(MSR_CLK_SRC, clk_msr_id->id));
|
||||
|
||||
/* Enable & Start */
|
||||
regmap_update_bits(priv->regmap, MSR_CLK_REG0,
|
||||
MSR_RUN | MSR_ENABLE,
|
||||
MSR_RUN | MSR_ENABLE);
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
|
||||
val, !(val & MSR_BUSY), 10, 10000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Disable */
|
||||
regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
|
||||
|
||||
/* Get the value in multiple of gate time counts */
|
||||
regmap_read(priv->regmap, MSR_CLK_REG2, &val);
|
||||
|
||||
if (val >= MSR_VAL_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL,
|
||||
duration);
|
||||
}
|
||||
|
||||
static int meson_measure_best_id(struct meson_msr_id *clk_msr_id,
|
||||
unsigned int *precision)
|
||||
{
|
||||
unsigned int duration = DIV_MAX;
|
||||
int ret;
|
||||
|
||||
/* Start from max duration and down to min duration */
|
||||
do {
|
||||
ret = meson_measure_id(clk_msr_id, duration);
|
||||
if (ret >= 0)
|
||||
*precision = (2 * 1000000) / duration;
|
||||
else
|
||||
duration -= DIV_STEP;
|
||||
} while (duration >= DIV_MIN && ret == -EINVAL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_msr_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct meson_msr_id *clk_msr_id = s->private;
|
||||
unsigned int precision = 0;
|
||||
int val;
|
||||
|
||||
val = meson_measure_best_id(clk_msr_id, &precision);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
seq_printf(s, "%d\t+/-%dHz\n", val, precision);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(clk_msr);
|
||||
|
||||
static int clk_msr_summary_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct meson_msr_id *msr_table = s->private;
|
||||
unsigned int precision = 0;
|
||||
int val, i;
|
||||
|
||||
seq_puts(s, " clock rate precision\n");
|
||||
seq_puts(s, "---------------------------------------------\n");
|
||||
|
||||
for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
|
||||
if (!msr_table[i].name)
|
||||
continue;
|
||||
|
||||
val = meson_measure_best_id(&msr_table[i], &precision);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
seq_printf(s, " %-20s %10d +/-%dHz\n",
|
||||
msr_table[i].name, val, precision);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(clk_msr_summary);
|
||||
|
||||
static const struct regmap_config meson_clk_msr_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = MSR_CLK_REG2,
|
||||
};
|
||||
|
||||
static int meson_msr_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct meson_msr_id *match_data;
|
||||
struct meson_msr *priv;
|
||||
struct resource *res;
|
||||
struct dentry *root, *clks;
|
||||
void __iomem *base;
|
||||
int i;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct meson_msr),
|
||||
GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
match_data = device_get_match_data(&pdev->dev);
|
||||
if (!match_data) {
|
||||
dev_err(&pdev->dev, "failed to get match data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
memcpy(priv->msr_table, match_data, sizeof(priv->msr_table));
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(base)) {
|
||||
dev_err(&pdev->dev, "io resource mapping failed\n");
|
||||
return PTR_ERR(base);
|
||||
}
|
||||
|
||||
priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
|
||||
&meson_clk_msr_regmap_config);
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
root = debugfs_create_dir("meson-clk-msr", NULL);
|
||||
clks = debugfs_create_dir("clks", root);
|
||||
|
||||
debugfs_create_file("measure_summary", 0444, root,
|
||||
priv->msr_table, &clk_msr_summary_fops);
|
||||
|
||||
for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
|
||||
if (!priv->msr_table[i].name)
|
||||
continue;
|
||||
|
||||
priv->msr_table[i].priv = priv;
|
||||
|
||||
debugfs_create_file(priv->msr_table[i].name, 0444, clks,
|
||||
&priv->msr_table[i], &clk_msr_fops);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id meson_msr_match_table[] = {
|
||||
{
|
||||
.compatible = "amlogic,meson-gx-clk-measure",
|
||||
.data = (void *)clk_msr_gx,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic,meson8-clk-measure",
|
||||
.data = (void *)clk_msr_m8,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic,meson8b-clk-measure",
|
||||
.data = (void *)clk_msr_m8,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver meson_msr_driver = {
|
||||
.probe = meson_msr_probe,
|
||||
.driver = {
|
||||
.name = "meson_msr",
|
||||
.of_match_table = meson_msr_match_table,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(meson_msr_driver);
|
@ -66,6 +66,8 @@ static const struct at91_soc __initconst socs[] = {
|
||||
AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"),
|
||||
AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"),
|
||||
AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"),
|
||||
AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_EXID_MATCH,
|
||||
"sam9x60", "sam9x60"),
|
||||
#endif
|
||||
#ifdef CONFIG_SOC_SAMA5
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D21CU_EXID_MATCH,
|
||||
@ -90,12 +92,20 @@ static const struct at91_soc __initconst socs[] = {
|
||||
"sama5d27c 128MiB SiP", "sama5d2"),
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_D5M_EXID_MATCH,
|
||||
"sama5d27c 64MiB SiP", "sama5d2"),
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_LD1G_EXID_MATCH,
|
||||
"sama5d27c 128MiB LPDDR2 SiP", "sama5d2"),
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_LD2G_EXID_MATCH,
|
||||
"sama5d27c 256MiB LPDDR2 SiP", "sama5d2"),
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CU_EXID_MATCH,
|
||||
"sama5d28", "sama5d2"),
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CN_EXID_MATCH,
|
||||
"sama5d28", "sama5d2"),
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_D1G_EXID_MATCH,
|
||||
"sama5d28c 128MiB SiP", "sama5d2"),
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_LD1G_EXID_MATCH,
|
||||
"sama5d28c 128MiB LPDDR2 SiP", "sama5d2"),
|
||||
AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_LD2G_EXID_MATCH,
|
||||
"sama5d28c 256MiB LPDDR2 SiP", "sama5d2"),
|
||||
AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH,
|
||||
"sama5d31", "sama5d3"),
|
||||
AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH,
|
||||
|
@ -42,6 +42,7 @@ at91_soc_init(const struct at91_soc *socs);
|
||||
#define AT91SAM9G45_CIDR_MATCH 0x019b05a0
|
||||
#define AT91SAM9X5_CIDR_MATCH 0x019a05a0
|
||||
#define AT91SAM9N12_CIDR_MATCH 0x019a07a0
|
||||
#define SAM9X60_CIDR_MATCH 0x019b35a0
|
||||
|
||||
#define AT91SAM9M11_EXID_MATCH 0x00000001
|
||||
#define AT91SAM9M10_EXID_MATCH 0x00000002
|
||||
@ -58,6 +59,8 @@ at91_soc_init(const struct at91_soc *socs);
|
||||
#define AT91SAM9N12_EXID_MATCH 0x00000006
|
||||
#define AT91SAM9CN11_EXID_MATCH 0x00000009
|
||||
|
||||
#define SAM9X60_EXID_MATCH 0x00000000
|
||||
|
||||
#define AT91SAM9XE128_CIDR_MATCH 0x329973a0
|
||||
#define AT91SAM9XE256_CIDR_MATCH 0x329a93a0
|
||||
#define AT91SAM9XE512_CIDR_MATCH 0x329aa3a0
|
||||
@ -73,9 +76,13 @@ at91_soc_init(const struct at91_soc *socs);
|
||||
#define SAMA5D26CU_EXID_MATCH 0x00000012
|
||||
#define SAMA5D27C_D1G_EXID_MATCH 0x00000033
|
||||
#define SAMA5D27C_D5M_EXID_MATCH 0x00000032
|
||||
#define SAMA5D27C_LD1G_EXID_MATCH 0x00000061
|
||||
#define SAMA5D27C_LD2G_EXID_MATCH 0x00000062
|
||||
#define SAMA5D27CU_EXID_MATCH 0x00000011
|
||||
#define SAMA5D27CN_EXID_MATCH 0x00000021
|
||||
#define SAMA5D28C_D1G_EXID_MATCH 0x00000013
|
||||
#define SAMA5D28C_LD1G_EXID_MATCH 0x00000071
|
||||
#define SAMA5D28C_LD2G_EXID_MATCH 0x00000072
|
||||
#define SAMA5D28CU_EXID_MATCH 0x00000010
|
||||
#define SAMA5D28CN_EXID_MATCH 0x00000020
|
||||
|
||||
|
@ -31,13 +31,17 @@ static const struct of_device_id brcmstb_machine_match[] = {
|
||||
|
||||
bool soc_is_brcmstb(void)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct device_node *root;
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
if (!root)
|
||||
return false;
|
||||
|
||||
return of_match_node(brcmstb_machine_match, root) != NULL;
|
||||
match = of_match_node(brcmstb_machine_match, root);
|
||||
of_node_put(root);
|
||||
|
||||
return match != NULL;
|
||||
}
|
||||
|
||||
u32 brcmstb_get_family_id(void)
|
||||
|
@ -404,7 +404,7 @@ noinline int brcmstb_pm_s3_finish(void)
|
||||
{
|
||||
struct brcmstb_s3_params *params = ctrl.s3_params;
|
||||
dma_addr_t params_pa = ctrl.s3_params_pa;
|
||||
phys_addr_t reentry = virt_to_phys(&cpu_resume);
|
||||
phys_addr_t reentry = virt_to_phys(&cpu_resume_arm);
|
||||
enum bsp_initiate_command cmd;
|
||||
u32 flags;
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander Aring <aar@pengutronix.de>
|
||||
|
@ -1,8 +1,8 @@
|
||||
menu "i.MX SoC drivers"
|
||||
|
||||
config IMX7_PM_DOMAINS
|
||||
bool "i.MX7 PM domains"
|
||||
depends on SOC_IMX7D || (COMPILE_TEST && OF)
|
||||
config IMX_GPCV2_PM_DOMAINS
|
||||
bool "i.MX GPCv2 PM domains"
|
||||
depends on SOC_IMX7D || SOC_IMX8MQ || (COMPILE_TEST && OF)
|
||||
depends on PM
|
||||
select PM_GENERIC_DOMAINS
|
||||
default y if SOC_IMX7D
|
||||
|
@ -1,2 +1,2 @@
|
||||
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
|
||||
obj-$(CONFIG_IMX7_PM_DOMAINS) += gpcv2.o
|
||||
obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
|
||||
|
@ -35,7 +35,7 @@
|
||||
#define GPU_VPU_PUP_REQ BIT(1)
|
||||
#define GPU_VPU_PDN_REQ BIT(0)
|
||||
|
||||
#define GPC_CLK_MAX 6
|
||||
#define GPC_CLK_MAX 7
|
||||
|
||||
#define PGC_DOMAIN_FLAG_NO_PD BIT(0)
|
||||
|
||||
|
@ -14,23 +14,54 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <dt-bindings/power/imx7-power.h>
|
||||
#include <dt-bindings/power/imx8mq-power.h>
|
||||
|
||||
#define GPC_LPCR_A_CORE_BSC 0x000
|
||||
|
||||
#define GPC_PGC_CPU_MAPPING 0x0ec
|
||||
#define USB_HSIC_PHY_A_CORE_DOMAIN BIT(6)
|
||||
#define USB_OTG2_PHY_A_CORE_DOMAIN BIT(5)
|
||||
#define USB_OTG1_PHY_A_CORE_DOMAIN BIT(4)
|
||||
#define PCIE_PHY_A_CORE_DOMAIN BIT(3)
|
||||
#define MIPI_PHY_A_CORE_DOMAIN BIT(2)
|
||||
|
||||
#define IMX7_USB_HSIC_PHY_A_CORE_DOMAIN BIT(6)
|
||||
#define IMX7_USB_OTG2_PHY_A_CORE_DOMAIN BIT(5)
|
||||
#define IMX7_USB_OTG1_PHY_A_CORE_DOMAIN BIT(4)
|
||||
#define IMX7_PCIE_PHY_A_CORE_DOMAIN BIT(3)
|
||||
#define IMX7_MIPI_PHY_A_CORE_DOMAIN BIT(2)
|
||||
|
||||
#define IMX8M_PCIE2_A53_DOMAIN BIT(15)
|
||||
#define IMX8M_MIPI_CSI2_A53_DOMAIN BIT(14)
|
||||
#define IMX8M_MIPI_CSI1_A53_DOMAIN BIT(13)
|
||||
#define IMX8M_DISP_A53_DOMAIN BIT(12)
|
||||
#define IMX8M_HDMI_A53_DOMAIN BIT(11)
|
||||
#define IMX8M_VPU_A53_DOMAIN BIT(10)
|
||||
#define IMX8M_GPU_A53_DOMAIN BIT(9)
|
||||
#define IMX8M_DDR2_A53_DOMAIN BIT(8)
|
||||
#define IMX8M_DDR1_A53_DOMAIN BIT(7)
|
||||
#define IMX8M_OTG2_A53_DOMAIN BIT(5)
|
||||
#define IMX8M_OTG1_A53_DOMAIN BIT(4)
|
||||
#define IMX8M_PCIE1_A53_DOMAIN BIT(3)
|
||||
#define IMX8M_MIPI_A53_DOMAIN BIT(2)
|
||||
|
||||
#define GPC_PU_PGC_SW_PUP_REQ 0x0f8
|
||||
#define GPC_PU_PGC_SW_PDN_REQ 0x104
|
||||
#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
|
||||
#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
|
||||
#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
|
||||
#define PCIE_PHY_SW_Pxx_REQ BIT(1)
|
||||
#define MIPI_PHY_SW_Pxx_REQ BIT(0)
|
||||
|
||||
#define IMX7_USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
|
||||
#define IMX7_USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
|
||||
#define IMX7_USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
|
||||
#define IMX7_PCIE_PHY_SW_Pxx_REQ BIT(1)
|
||||
#define IMX7_MIPI_PHY_SW_Pxx_REQ BIT(0)
|
||||
|
||||
#define IMX8M_PCIE2_SW_Pxx_REQ BIT(13)
|
||||
#define IMX8M_MIPI_CSI2_SW_Pxx_REQ BIT(12)
|
||||
#define IMX8M_MIPI_CSI1_SW_Pxx_REQ BIT(11)
|
||||
#define IMX8M_DISP_SW_Pxx_REQ BIT(10)
|
||||
#define IMX8M_HDMI_SW_Pxx_REQ BIT(9)
|
||||
#define IMX8M_VPU_SW_Pxx_REQ BIT(8)
|
||||
#define IMX8M_GPU_SW_Pxx_REQ BIT(7)
|
||||
#define IMX8M_DDR2_SW_Pxx_REQ BIT(6)
|
||||
#define IMX8M_DDR1_SW_Pxx_REQ BIT(5)
|
||||
#define IMX8M_OTG2_SW_Pxx_REQ BIT(3)
|
||||
#define IMX8M_OTG1_SW_Pxx_REQ BIT(2)
|
||||
#define IMX8M_PCIE1_SW_Pxx_REQ BIT(1)
|
||||
#define IMX8M_MIPI_SW_Pxx_REQ BIT(0)
|
||||
|
||||
#define GPC_M4_PU_PDN_FLG 0x1bc
|
||||
|
||||
@ -40,9 +71,22 @@
|
||||
* GPC_PGC memory map are incorrect, below offset
|
||||
* values are from design RTL.
|
||||
*/
|
||||
#define PGC_MIPI 16
|
||||
#define PGC_PCIE 17
|
||||
#define PGC_USB_HSIC 20
|
||||
#define IMX7_PGC_MIPI 16
|
||||
#define IMX7_PGC_PCIE 17
|
||||
#define IMX7_PGC_USB_HSIC 20
|
||||
|
||||
#define IMX8M_PGC_MIPI 16
|
||||
#define IMX8M_PGC_PCIE1 17
|
||||
#define IMX8M_PGC_OTG1 18
|
||||
#define IMX8M_PGC_OTG2 19
|
||||
#define IMX8M_PGC_DDR1 21
|
||||
#define IMX8M_PGC_GPU 23
|
||||
#define IMX8M_PGC_VPU 24
|
||||
#define IMX8M_PGC_DISP 26
|
||||
#define IMX8M_PGC_MIPI_CSI1 27
|
||||
#define IMX8M_PGC_MIPI_CSI2 28
|
||||
#define IMX8M_PGC_PCIE2 29
|
||||
|
||||
#define GPC_PGC_CTRL(n) (0x800 + (n) * 0x40)
|
||||
#define GPC_PGC_SR(n) (GPC_PGC_CTRL(n) + 0xc)
|
||||
|
||||
@ -67,6 +111,7 @@ struct imx_pgc_domain {
|
||||
struct imx_pgc_domain_data {
|
||||
const struct imx_pgc_domain *domains;
|
||||
size_t domains_num;
|
||||
const struct regmap_access_table *reg_access_table;
|
||||
};
|
||||
|
||||
static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
|
||||
@ -166,11 +211,11 @@ static const struct imx_pgc_domain imx7_pgc_domains[] = {
|
||||
.name = "mipi-phy",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = MIPI_PHY_SW_Pxx_REQ,
|
||||
.map = MIPI_PHY_A_CORE_DOMAIN,
|
||||
.pxx = IMX7_MIPI_PHY_SW_Pxx_REQ,
|
||||
.map = IMX7_MIPI_PHY_A_CORE_DOMAIN,
|
||||
},
|
||||
.voltage = 1000000,
|
||||
.pgc = PGC_MIPI,
|
||||
.pgc = IMX7_PGC_MIPI,
|
||||
},
|
||||
|
||||
[IMX7_POWER_DOMAIN_PCIE_PHY] = {
|
||||
@ -178,11 +223,11 @@ static const struct imx_pgc_domain imx7_pgc_domains[] = {
|
||||
.name = "pcie-phy",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = PCIE_PHY_SW_Pxx_REQ,
|
||||
.map = PCIE_PHY_A_CORE_DOMAIN,
|
||||
.pxx = IMX7_PCIE_PHY_SW_Pxx_REQ,
|
||||
.map = IMX7_PCIE_PHY_A_CORE_DOMAIN,
|
||||
},
|
||||
.voltage = 1000000,
|
||||
.pgc = PGC_PCIE,
|
||||
.pgc = IMX7_PGC_PCIE,
|
||||
},
|
||||
|
||||
[IMX7_POWER_DOMAIN_USB_HSIC_PHY] = {
|
||||
@ -190,17 +235,195 @@ static const struct imx_pgc_domain imx7_pgc_domains[] = {
|
||||
.name = "usb-hsic-phy",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = USB_HSIC_PHY_SW_Pxx_REQ,
|
||||
.map = USB_HSIC_PHY_A_CORE_DOMAIN,
|
||||
.pxx = IMX7_USB_HSIC_PHY_SW_Pxx_REQ,
|
||||
.map = IMX7_USB_HSIC_PHY_A_CORE_DOMAIN,
|
||||
},
|
||||
.voltage = 1200000,
|
||||
.pgc = PGC_USB_HSIC,
|
||||
.pgc = IMX7_PGC_USB_HSIC,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_range imx7_yes_ranges[] = {
|
||||
regmap_reg_range(GPC_LPCR_A_CORE_BSC,
|
||||
GPC_M4_PU_PDN_FLG),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_MIPI),
|
||||
GPC_PGC_SR(IMX7_PGC_MIPI)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_PCIE),
|
||||
GPC_PGC_SR(IMX7_PGC_PCIE)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_USB_HSIC),
|
||||
GPC_PGC_SR(IMX7_PGC_USB_HSIC)),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table imx7_access_table = {
|
||||
.yes_ranges = imx7_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(imx7_yes_ranges),
|
||||
};
|
||||
|
||||
static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
|
||||
.domains = imx7_pgc_domains,
|
||||
.domains_num = ARRAY_SIZE(imx7_pgc_domains),
|
||||
.reg_access_table = &imx7_access_table,
|
||||
};
|
||||
|
||||
static const struct imx_pgc_domain imx8m_pgc_domains[] = {
|
||||
[IMX8M_POWER_DOMAIN_MIPI] = {
|
||||
.genpd = {
|
||||
.name = "mipi",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_MIPI_SW_Pxx_REQ,
|
||||
.map = IMX8M_MIPI_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_MIPI,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_PCIE1] = {
|
||||
.genpd = {
|
||||
.name = "pcie1",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_PCIE1_SW_Pxx_REQ,
|
||||
.map = IMX8M_PCIE1_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_PCIE1,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_USB_OTG1] = {
|
||||
.genpd = {
|
||||
.name = "usb-otg1",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_OTG1_SW_Pxx_REQ,
|
||||
.map = IMX8M_OTG1_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_OTG1,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_USB_OTG2] = {
|
||||
.genpd = {
|
||||
.name = "usb-otg2",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_OTG2_SW_Pxx_REQ,
|
||||
.map = IMX8M_OTG2_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_OTG2,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_DDR1] = {
|
||||
.genpd = {
|
||||
.name = "ddr1",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_DDR1_SW_Pxx_REQ,
|
||||
.map = IMX8M_DDR2_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_DDR1,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_GPU] = {
|
||||
.genpd = {
|
||||
.name = "gpu",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_GPU_SW_Pxx_REQ,
|
||||
.map = IMX8M_GPU_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_GPU,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_VPU] = {
|
||||
.genpd = {
|
||||
.name = "vpu",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_VPU_SW_Pxx_REQ,
|
||||
.map = IMX8M_VPU_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_VPU,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_DISP] = {
|
||||
.genpd = {
|
||||
.name = "disp",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_DISP_SW_Pxx_REQ,
|
||||
.map = IMX8M_DISP_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_DISP,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_MIPI_CSI1] = {
|
||||
.genpd = {
|
||||
.name = "mipi-csi1",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_MIPI_CSI1_SW_Pxx_REQ,
|
||||
.map = IMX8M_MIPI_CSI1_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_MIPI_CSI1,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_MIPI_CSI2] = {
|
||||
.genpd = {
|
||||
.name = "mipi-csi2",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_MIPI_CSI2_SW_Pxx_REQ,
|
||||
.map = IMX8M_MIPI_CSI2_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_MIPI_CSI2,
|
||||
},
|
||||
|
||||
[IMX8M_POWER_DOMAIN_PCIE2] = {
|
||||
.genpd = {
|
||||
.name = "pcie2",
|
||||
},
|
||||
.bits = {
|
||||
.pxx = IMX8M_PCIE2_SW_Pxx_REQ,
|
||||
.map = IMX8M_PCIE2_A53_DOMAIN,
|
||||
},
|
||||
.pgc = IMX8M_PGC_PCIE2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_range imx8m_yes_ranges[] = {
|
||||
regmap_reg_range(GPC_LPCR_A_CORE_BSC,
|
||||
GPC_M4_PU_PDN_FLG),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI),
|
||||
GPC_PGC_SR(IMX8M_PGC_MIPI)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE1),
|
||||
GPC_PGC_SR(IMX8M_PGC_PCIE1)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG1),
|
||||
GPC_PGC_SR(IMX8M_PGC_OTG1)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG2),
|
||||
GPC_PGC_SR(IMX8M_PGC_OTG2)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DDR1),
|
||||
GPC_PGC_SR(IMX8M_PGC_DDR1)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_GPU),
|
||||
GPC_PGC_SR(IMX8M_PGC_GPU)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_VPU),
|
||||
GPC_PGC_SR(IMX8M_PGC_VPU)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DISP),
|
||||
GPC_PGC_SR(IMX8M_PGC_DISP)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI1),
|
||||
GPC_PGC_SR(IMX8M_PGC_MIPI_CSI1)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI2),
|
||||
GPC_PGC_SR(IMX8M_PGC_MIPI_CSI2)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE2),
|
||||
GPC_PGC_SR(IMX8M_PGC_PCIE2)),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table imx8m_access_table = {
|
||||
.yes_ranges = imx8m_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(imx8m_yes_ranges),
|
||||
};
|
||||
|
||||
static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
|
||||
.domains = imx8m_pgc_domains,
|
||||
.domains_num = ARRAY_SIZE(imx8m_pgc_domains),
|
||||
.reg_access_table = &imx8m_access_table,
|
||||
};
|
||||
|
||||
static int imx_pgc_domain_probe(struct platform_device *pdev)
|
||||
@ -217,7 +440,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
|
||||
dev_err(domain->dev, "Failed to get domain's regulator\n");
|
||||
return PTR_ERR(domain->regulator);
|
||||
}
|
||||
} else {
|
||||
} else if (domain->voltage) {
|
||||
regulator_set_voltage(domain->regulator,
|
||||
domain->voltage, domain->voltage);
|
||||
}
|
||||
@ -265,27 +488,15 @@ builtin_platform_driver(imx_pgc_domain_driver)
|
||||
|
||||
static int imx_gpcv2_probe(struct platform_device *pdev)
|
||||
{
|
||||
static const struct imx_pgc_domain_data *domain_data;
|
||||
static const struct regmap_range yes_ranges[] = {
|
||||
regmap_reg_range(GPC_LPCR_A_CORE_BSC,
|
||||
GPC_M4_PU_PDN_FLG),
|
||||
regmap_reg_range(GPC_PGC_CTRL(PGC_MIPI),
|
||||
GPC_PGC_SR(PGC_MIPI)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(PGC_PCIE),
|
||||
GPC_PGC_SR(PGC_PCIE)),
|
||||
regmap_reg_range(GPC_PGC_CTRL(PGC_USB_HSIC),
|
||||
GPC_PGC_SR(PGC_USB_HSIC)),
|
||||
};
|
||||
static const struct regmap_access_table access_table = {
|
||||
.yes_ranges = yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(yes_ranges),
|
||||
};
|
||||
static const struct regmap_config regmap_config = {
|
||||
const struct imx_pgc_domain_data *domain_data =
|
||||
of_device_get_match_data(&pdev->dev);
|
||||
|
||||
struct regmap_config regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.rd_table = &access_table,
|
||||
.wr_table = &access_table,
|
||||
.rd_table = domain_data->reg_access_table,
|
||||
.wr_table = domain_data->reg_access_table,
|
||||
.max_register = SZ_4K,
|
||||
};
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -313,8 +524,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
domain_data = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
for_each_child_of_node(pgc_np, np) {
|
||||
struct platform_device *pd_pdev;
|
||||
struct imx_pgc_domain *domain;
|
||||
@ -372,6 +581,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id imx_gpcv2_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
|
||||
{ .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,18 @@
|
||||
menu "MediaTek SoC drivers"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
|
||||
config MTK_CMDQ
|
||||
tristate "MediaTek CMDQ Support"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
select MAILBOX
|
||||
select MTK_CMDQ_MBOX
|
||||
select MTK_INFRACFG
|
||||
help
|
||||
Say yes here to add support for the MediaTek Command Queue (CMDQ)
|
||||
driver. The CMDQ is used to help read/write registers with critical
|
||||
time limitation, such as updating display configuration during the
|
||||
vblank.
|
||||
|
||||
config MTK_INFRACFG
|
||||
bool "MediaTek INFRACFG Support"
|
||||
select REGMAP
|
||||
|
@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
|
||||
obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
|
||||
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
|
||||
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
|
||||
|
300
drivers/soc/mediatek/mtk-cmdq-helper.c
Normal file
300
drivers/soc/mediatek/mtk-cmdq-helper.c
Normal file
@ -0,0 +1,300 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Copyright (c) 2018 MediaTek Inc.
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mailbox_controller.h>
|
||||
#include <linux/soc/mediatek/mtk-cmdq.h>
|
||||
|
||||
#define CMDQ_ARG_A_WRITE_MASK 0xffff
|
||||
#define CMDQ_WRITE_ENABLE_MASK BIT(0)
|
||||
#define CMDQ_EOC_IRQ_EN BIT(0)
|
||||
#define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
|
||||
<< 32 | CMDQ_EOC_IRQ_EN)
|
||||
|
||||
static void cmdq_client_timeout(struct timer_list *t)
|
||||
{
|
||||
struct cmdq_client *client = from_timer(client, t, timer);
|
||||
|
||||
dev_err(client->client.dev, "cmdq timeout!\n");
|
||||
}
|
||||
|
||||
struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 timeout)
|
||||
{
|
||||
struct cmdq_client *client;
|
||||
|
||||
client = kzalloc(sizeof(*client), GFP_KERNEL);
|
||||
if (!client)
|
||||
return (struct cmdq_client *)-ENOMEM;
|
||||
|
||||
client->timeout_ms = timeout;
|
||||
if (timeout != CMDQ_NO_TIMEOUT) {
|
||||
spin_lock_init(&client->lock);
|
||||
timer_setup(&client->timer, cmdq_client_timeout, 0);
|
||||
}
|
||||
client->pkt_cnt = 0;
|
||||
client->client.dev = dev;
|
||||
client->client.tx_block = false;
|
||||
client->chan = mbox_request_channel(&client->client, index);
|
||||
|
||||
if (IS_ERR(client->chan)) {
|
||||
long err;
|
||||
|
||||
dev_err(dev, "failed to request channel\n");
|
||||
err = PTR_ERR(client->chan);
|
||||
kfree(client);
|
||||
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_mbox_create);
|
||||
|
||||
void cmdq_mbox_destroy(struct cmdq_client *client)
|
||||
{
|
||||
if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
|
||||
spin_lock(&client->lock);
|
||||
del_timer_sync(&client->timer);
|
||||
spin_unlock(&client->lock);
|
||||
}
|
||||
mbox_free_channel(client->chan);
|
||||
kfree(client);
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_mbox_destroy);
|
||||
|
||||
struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
|
||||
{
|
||||
struct cmdq_pkt *pkt;
|
||||
struct device *dev;
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
|
||||
if (!pkt)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
pkt->va_base = kzalloc(size, GFP_KERNEL);
|
||||
if (!pkt->va_base) {
|
||||
kfree(pkt);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
pkt->buf_size = size;
|
||||
pkt->cl = (void *)client;
|
||||
|
||||
dev = client->chan->mbox->dev;
|
||||
dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dev, dma_addr)) {
|
||||
dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
|
||||
kfree(pkt->va_base);
|
||||
kfree(pkt);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
pkt->pa_base = dma_addr;
|
||||
|
||||
return pkt;
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_pkt_create);
|
||||
|
||||
void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
|
||||
{
|
||||
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
|
||||
|
||||
dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
kfree(pkt->va_base);
|
||||
kfree(pkt);
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_pkt_destroy);
|
||||
|
||||
static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
|
||||
u32 arg_a, u32 arg_b)
|
||||
{
|
||||
u64 *cmd_ptr;
|
||||
|
||||
if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
|
||||
/*
|
||||
* In the case of allocated buffer size (pkt->buf_size) is used
|
||||
* up, the real required size (pkt->cmdq_buf_size) is still
|
||||
* increased, so that the user knows how much memory should be
|
||||
* ultimately allocated after appending all commands and
|
||||
* flushing the command packet. Therefor, the user can call
|
||||
* cmdq_pkt_create() again with the real required buffer size.
|
||||
*/
|
||||
pkt->cmd_buf_size += CMDQ_INST_SIZE;
|
||||
WARN_ONCE(1, "%s: buffer size %u is too small !\n",
|
||||
__func__, (u32)pkt->buf_size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
|
||||
(*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
|
||||
pkt->cmd_buf_size += CMDQ_INST_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
|
||||
{
|
||||
u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
|
||||
(subsys << CMDQ_SUBSYS_SHIFT);
|
||||
|
||||
return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_pkt_write);
|
||||
|
||||
int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
|
||||
u32 subsys, u32 offset, u32 mask)
|
||||
{
|
||||
u32 offset_mask = offset;
|
||||
int err = 0;
|
||||
|
||||
if (mask != 0xffffffff) {
|
||||
err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
|
||||
offset_mask |= CMDQ_WRITE_ENABLE_MASK;
|
||||
}
|
||||
err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_pkt_write_mask);
|
||||
|
||||
int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event)
|
||||
{
|
||||
u32 arg_b;
|
||||
|
||||
if (event >= CMDQ_MAX_EVENT)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* WFE arg_b
|
||||
* bit 0-11: wait value
|
||||
* bit 15: 1 - wait, 0 - no wait
|
||||
* bit 16-27: update value
|
||||
* bit 31: 1 - update, 0 - no update
|
||||
*/
|
||||
arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
|
||||
|
||||
return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_pkt_wfe);
|
||||
|
||||
int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event)
|
||||
{
|
||||
if (event >= CMDQ_MAX_EVENT)
|
||||
return -EINVAL;
|
||||
|
||||
return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
|
||||
CMDQ_WFE_UPDATE);
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_pkt_clear_event);
|
||||
|
||||
static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* insert EOC and generate IRQ for each command iteration */
|
||||
err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, CMDQ_EOC_IRQ_EN);
|
||||
|
||||
/* JUMP to end */
|
||||
err |= cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
|
||||
{
|
||||
struct cmdq_pkt *pkt = (struct cmdq_pkt *)data.data;
|
||||
struct cmdq_task_cb *cb = &pkt->cb;
|
||||
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
|
||||
|
||||
if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
|
||||
unsigned long flags = 0;
|
||||
|
||||
spin_lock_irqsave(&client->lock, flags);
|
||||
if (--client->pkt_cnt == 0)
|
||||
del_timer(&client->timer);
|
||||
else
|
||||
mod_timer(&client->timer, jiffies +
|
||||
msecs_to_jiffies(client->timeout_ms));
|
||||
spin_unlock_irqrestore(&client->lock, flags);
|
||||
}
|
||||
|
||||
dma_sync_single_for_cpu(client->chan->mbox->dev, pkt->pa_base,
|
||||
pkt->cmd_buf_size, DMA_TO_DEVICE);
|
||||
if (cb->cb) {
|
||||
data.data = cb->data;
|
||||
cb->cb(data);
|
||||
}
|
||||
}
|
||||
|
||||
int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
|
||||
void *data)
|
||||
{
|
||||
int err;
|
||||
unsigned long flags = 0;
|
||||
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
|
||||
|
||||
err = cmdq_pkt_finalize(pkt);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
pkt->cb.cb = cb;
|
||||
pkt->cb.data = data;
|
||||
pkt->async_cb.cb = cmdq_pkt_flush_async_cb;
|
||||
pkt->async_cb.data = pkt;
|
||||
|
||||
dma_sync_single_for_device(client->chan->mbox->dev, pkt->pa_base,
|
||||
pkt->cmd_buf_size, DMA_TO_DEVICE);
|
||||
|
||||
if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
|
||||
spin_lock_irqsave(&client->lock, flags);
|
||||
if (client->pkt_cnt++ == 0)
|
||||
mod_timer(&client->timer, jiffies +
|
||||
msecs_to_jiffies(client->timeout_ms));
|
||||
spin_unlock_irqrestore(&client->lock, flags);
|
||||
}
|
||||
|
||||
mbox_send_message(client->chan, pkt);
|
||||
/* We can send next packet immediately, so just call txdone. */
|
||||
mbox_client_txdone(client->chan, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_pkt_flush_async);
|
||||
|
||||
struct cmdq_flush_completion {
|
||||
struct completion cmplt;
|
||||
bool err;
|
||||
};
|
||||
|
||||
static void cmdq_pkt_flush_cb(struct cmdq_cb_data data)
|
||||
{
|
||||
struct cmdq_flush_completion *cmplt;
|
||||
|
||||
cmplt = (struct cmdq_flush_completion *)data.data;
|
||||
if (data.sta != CMDQ_CB_NORMAL)
|
||||
cmplt->err = true;
|
||||
else
|
||||
cmplt->err = false;
|
||||
complete(&cmplt->cmplt);
|
||||
}
|
||||
|
||||
int cmdq_pkt_flush(struct cmdq_pkt *pkt)
|
||||
{
|
||||
struct cmdq_flush_completion cmplt;
|
||||
int err;
|
||||
|
||||
init_completion(&cmplt.cmplt);
|
||||
err = cmdq_pkt_flush_async(pkt, cmdq_pkt_flush_cb, &cmplt);
|
||||
if (err < 0)
|
||||
return err;
|
||||
wait_for_completion(&cmplt.cmplt);
|
||||
|
||||
return cmplt.err ? -EFAULT : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cmdq_pkt_flush);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
@ -75,11 +75,6 @@ config QCOM_QMI_HELPERS
|
||||
tristate
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on NET
|
||||
help
|
||||
Helper library for handling QMI encoded messages. QMI encoded
|
||||
messages are used in communication between the majority of QRTR
|
||||
clients and this helpers provide the common functionality needed for
|
||||
doing this from a kernel driver.
|
||||
|
||||
config QCOM_RMTFS_MEM
|
||||
tristate "Qualcomm Remote Filesystem memory driver"
|
||||
|
@ -101,8 +101,7 @@ static bool cmd_db_magic_matches(const struct cmd_db_header *header)
|
||||
|
||||
static struct cmd_db_header *cmd_db_header;
|
||||
|
||||
|
||||
static inline void *rsc_to_entry_header(struct rsc_hdr *hdr)
|
||||
static inline const void *rsc_to_entry_header(const struct rsc_hdr *hdr)
|
||||
{
|
||||
u16 offset = le16_to_cpu(hdr->header_offset);
|
||||
|
||||
@ -110,7 +109,7 @@ static inline void *rsc_to_entry_header(struct rsc_hdr *hdr)
|
||||
}
|
||||
|
||||
static inline void *
|
||||
rsc_offset(struct rsc_hdr *hdr, struct entry_header *ent)
|
||||
rsc_offset(const struct rsc_hdr *hdr, const struct entry_header *ent)
|
||||
{
|
||||
u16 offset = le16_to_cpu(hdr->data_offset);
|
||||
u16 loffset = le16_to_cpu(ent->offset);
|
||||
@ -134,11 +133,11 @@ int cmd_db_ready(void)
|
||||
}
|
||||
EXPORT_SYMBOL(cmd_db_ready);
|
||||
|
||||
static int cmd_db_get_header(const char *id, struct entry_header *eh,
|
||||
struct rsc_hdr *rh)
|
||||
static int cmd_db_get_header(const char *id, const struct entry_header **eh,
|
||||
const struct rsc_hdr **rh)
|
||||
{
|
||||
struct rsc_hdr *rsc_hdr;
|
||||
struct entry_header *ent;
|
||||
const struct rsc_hdr *rsc_hdr;
|
||||
const struct entry_header *ent;
|
||||
int ret, i, j;
|
||||
u8 query[8];
|
||||
|
||||
@ -146,9 +145,6 @@ static int cmd_db_get_header(const char *id, struct entry_header *eh,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!eh || !rh)
|
||||
return -EINVAL;
|
||||
|
||||
/* Pad out query string to same length as in DB */
|
||||
strncpy(query, id, sizeof(query));
|
||||
|
||||
@ -159,14 +155,13 @@ static int cmd_db_get_header(const char *id, struct entry_header *eh,
|
||||
|
||||
ent = rsc_to_entry_header(rsc_hdr);
|
||||
for (j = 0; j < le16_to_cpu(rsc_hdr->cnt); j++, ent++) {
|
||||
if (memcmp(ent->id, query, sizeof(ent->id)) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j < le16_to_cpu(rsc_hdr->cnt)) {
|
||||
memcpy(eh, ent, sizeof(*ent));
|
||||
memcpy(rh, rsc_hdr, sizeof(*rh));
|
||||
return 0;
|
||||
if (memcmp(ent->id, query, sizeof(ent->id)) == 0) {
|
||||
if (eh)
|
||||
*eh = ent;
|
||||
if (rh)
|
||||
*rh = rsc_hdr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,68 +181,39 @@ static int cmd_db_get_header(const char *id, struct entry_header *eh,
|
||||
u32 cmd_db_read_addr(const char *id)
|
||||
{
|
||||
int ret;
|
||||
struct entry_header ent;
|
||||
struct rsc_hdr rsc_hdr;
|
||||
const struct entry_header *ent;
|
||||
|
||||
ret = cmd_db_get_header(id, &ent, &rsc_hdr);
|
||||
ret = cmd_db_get_header(id, &ent, NULL);
|
||||
|
||||
return ret < 0 ? 0 : le32_to_cpu(ent.addr);
|
||||
return ret < 0 ? 0 : le32_to_cpu(ent->addr);
|
||||
}
|
||||
EXPORT_SYMBOL(cmd_db_read_addr);
|
||||
|
||||
/**
|
||||
* cmd_db_read_aux_data() - Query command db for aux data.
|
||||
*
|
||||
* @id: Resource to retrieve AUX Data on.
|
||||
* @data: Data buffer to copy returned aux data to. Returns size on NULL
|
||||
* @len: Caller provides size of data buffer passed in.
|
||||
* @id: Resource to retrieve AUX Data on
|
||||
* @len: size of data buffer returned
|
||||
*
|
||||
* Return: size of data on success, errno otherwise
|
||||
* Return: pointer to data on success, error pointer otherwise
|
||||
*/
|
||||
int cmd_db_read_aux_data(const char *id, u8 *data, size_t len)
|
||||
const void *cmd_db_read_aux_data(const char *id, size_t *len)
|
||||
{
|
||||
int ret;
|
||||
struct entry_header ent;
|
||||
struct rsc_hdr rsc_hdr;
|
||||
u16 ent_len;
|
||||
|
||||
if (!data)
|
||||
return -EINVAL;
|
||||
const struct entry_header *ent;
|
||||
const struct rsc_hdr *rsc_hdr;
|
||||
|
||||
ret = cmd_db_get_header(id, &ent, &rsc_hdr);
|
||||
if (ret)
|
||||
return ret;
|
||||
return ERR_PTR(ret);
|
||||
|
||||
ent_len = le16_to_cpu(ent.len);
|
||||
if (len < ent_len)
|
||||
return -EINVAL;
|
||||
if (len)
|
||||
*len = le16_to_cpu(ent->len);
|
||||
|
||||
len = min_t(u16, ent_len, len);
|
||||
memcpy(data, rsc_offset(&rsc_hdr, &ent), len);
|
||||
|
||||
return len;
|
||||
return rsc_offset(rsc_hdr, ent);
|
||||
}
|
||||
EXPORT_SYMBOL(cmd_db_read_aux_data);
|
||||
|
||||
/**
|
||||
* cmd_db_read_aux_data_len - Get the length of the auxiliary data stored in DB.
|
||||
*
|
||||
* @id: Resource to retrieve AUX Data.
|
||||
*
|
||||
* Return: size on success, 0 on error
|
||||
*/
|
||||
size_t cmd_db_read_aux_data_len(const char *id)
|
||||
{
|
||||
int ret;
|
||||
struct entry_header ent;
|
||||
struct rsc_hdr rsc_hdr;
|
||||
|
||||
ret = cmd_db_get_header(id, &ent, &rsc_hdr);
|
||||
|
||||
return ret < 0 ? 0 : le16_to_cpu(ent.len);
|
||||
}
|
||||
EXPORT_SYMBOL(cmd_db_read_aux_data_len);
|
||||
|
||||
/**
|
||||
* cmd_db_read_slave_id - Get the slave ID for a given resource address
|
||||
*
|
||||
@ -258,15 +224,14 @@ EXPORT_SYMBOL(cmd_db_read_aux_data_len);
|
||||
enum cmd_db_hw_type cmd_db_read_slave_id(const char *id)
|
||||
{
|
||||
int ret;
|
||||
struct entry_header ent;
|
||||
struct rsc_hdr rsc_hdr;
|
||||
const struct entry_header *ent;
|
||||
u32 addr;
|
||||
|
||||
ret = cmd_db_get_header(id, &ent, &rsc_hdr);
|
||||
ret = cmd_db_get_header(id, &ent, NULL);
|
||||
if (ret < 0)
|
||||
return CMD_DB_HW_INVALID;
|
||||
|
||||
addr = le32_to_cpu(ent.addr);
|
||||
addr = le32_to_cpu(ent->addr);
|
||||
return (addr >> SLAVE_ID_SHIFT) & SLAVE_ID_MASK;
|
||||
}
|
||||
EXPORT_SYMBOL(cmd_db_read_slave_id);
|
||||
|
@ -95,7 +95,8 @@ EXPORT_SYMBOL_GPL(llcc_slice_getd);
|
||||
*/
|
||||
void llcc_slice_putd(struct llcc_slice_desc *desc)
|
||||
{
|
||||
kfree(desc);
|
||||
if (!IS_ERR_OR_NULL(desc))
|
||||
kfree(desc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(llcc_slice_putd);
|
||||
|
||||
@ -142,6 +143,9 @@ int llcc_slice_activate(struct llcc_slice_desc *desc)
|
||||
int ret;
|
||||
u32 act_ctrl_val;
|
||||
|
||||
if (IS_ERR_OR_NULL(desc))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
if (test_bit(desc->slice_id, drv_data->bitmap)) {
|
||||
mutex_unlock(&drv_data->lock);
|
||||
@ -176,6 +180,9 @@ int llcc_slice_deactivate(struct llcc_slice_desc *desc)
|
||||
u32 act_ctrl_val;
|
||||
int ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(desc))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
if (!test_bit(desc->slice_id, drv_data->bitmap)) {
|
||||
mutex_unlock(&drv_data->lock);
|
||||
@ -203,6 +210,9 @@ EXPORT_SYMBOL_GPL(llcc_slice_deactivate);
|
||||
*/
|
||||
int llcc_get_slice_id(struct llcc_slice_desc *desc)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(desc))
|
||||
return -EINVAL;
|
||||
|
||||
return desc->slice_id;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(llcc_get_slice_id);
|
||||
@ -213,6 +223,9 @@ EXPORT_SYMBOL_GPL(llcc_get_slice_id);
|
||||
*/
|
||||
size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(desc))
|
||||
return 0;
|
||||
|
||||
return desc->slice_size;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(llcc_get_slice_size);
|
||||
@ -360,5 +373,5 @@ int qcom_llcc_probe(struct platform_device *pdev,
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_llcc_probe);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Qualcomm Last Level Cache Controller");
|
||||
|
@ -215,6 +215,16 @@ static void geni_se_io_init(void __iomem *base)
|
||||
writel_relaxed(FORCE_DEFAULT, base + GENI_FORCE_DEFAULT_REG);
|
||||
}
|
||||
|
||||
static void geni_se_irq_clear(struct geni_se *se)
|
||||
{
|
||||
writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
|
||||
writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* geni_se_init() - Initialize the GENI serial engine
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
@ -228,6 +238,7 @@ void geni_se_init(struct geni_se *se, u32 rx_wm, u32 rx_rfr)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
geni_se_irq_clear(se);
|
||||
geni_se_io_init(se->base);
|
||||
geni_se_io_set_mode(se->base);
|
||||
|
||||
@ -249,12 +260,7 @@ static void geni_se_select_fifo_mode(struct geni_se *se)
|
||||
u32 proto = geni_se_read_proto(se);
|
||||
u32 val;
|
||||
|
||||
writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
|
||||
writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
|
||||
geni_se_irq_clear(se);
|
||||
|
||||
val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
|
||||
if (proto != GENI_SE_UART) {
|
||||
@ -277,12 +283,7 @@ static void geni_se_select_dma_mode(struct geni_se *se)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
|
||||
writel_relaxed(0xffffffff, se->base + SE_GENI_M_IRQ_CLEAR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_GENI_S_IRQ_CLEAR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_DMA_TX_IRQ_CLR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_DMA_RX_IRQ_CLR);
|
||||
writel_relaxed(0xffffffff, se->base + SE_IRQ_EN);
|
||||
geni_se_irq_clear(se);
|
||||
|
||||
val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
|
||||
val |= GENI_DMA_MODE_EN;
|
||||
|
@ -318,7 +318,7 @@ int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn,
|
||||
txn->dest = c_struct;
|
||||
|
||||
mutex_lock(&qmi->txn_lock);
|
||||
ret = idr_alloc_cyclic(&qmi->txns, txn, 0, INT_MAX, GFP_KERNEL);
|
||||
ret = idr_alloc_cyclic(&qmi->txns, txn, 0, U16_MAX, GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
pr_err("failed to allocate transaction id\n");
|
||||
|
||||
|
@ -227,6 +227,7 @@ static const struct of_device_id qcom_smd_rpm_of_match[] = {
|
||||
{ .compatible = "qcom,rpm-msm8974" },
|
||||
{ .compatible = "qcom,rpm-msm8996" },
|
||||
{ .compatible = "qcom,rpm-msm8998" },
|
||||
{ .compatible = "qcom,rpm-qcs404" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_smd_rpm_of_match);
|
||||
|
@ -28,7 +28,6 @@ static const struct rcar_sysc_area r8a77965_areas[] __initconst = {
|
||||
{ "a2vc1", 0x3c0, 1, R8A77965_PD_A2VC1, R8A77965_PD_A3VC },
|
||||
{ "3dg-a", 0x100, 0, R8A77965_PD_3DG_A, R8A77965_PD_ALWAYS_ON },
|
||||
{ "3dg-b", 0x100, 1, R8A77965_PD_3DG_B, R8A77965_PD_3DG_A },
|
||||
{ "a3ir", 0x180, 0, R8A77965_PD_A3IR, R8A77965_PD_ALWAYS_ON },
|
||||
};
|
||||
|
||||
const struct rcar_sysc_info r8a77965_sysc_info __initconst = {
|
||||
|
@ -20,12 +20,11 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = {
|
||||
PD_CPU_NOCR },
|
||||
{ "ca53-cpu1", 0x200, 1, R8A77970_PD_CA53_CPU1, R8A77970_PD_CA53_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "cr7", 0x240, 0, R8A77970_PD_CR7, R8A77970_PD_ALWAYS_ON },
|
||||
{ "a3ir", 0x180, 0, R8A77970_PD_A3IR, R8A77970_PD_ALWAYS_ON },
|
||||
{ "a2ir0", 0x400, 0, R8A77970_PD_A2IR0, R8A77970_PD_A3IR },
|
||||
{ "a2ir1", 0x400, 1, R8A77970_PD_A2IR1, R8A77970_PD_A3IR },
|
||||
{ "a2ir2", 0x400, 2, R8A77970_PD_A2IR2, R8A77970_PD_A3IR },
|
||||
{ "a2ir3", 0x400, 3, R8A77970_PD_A2IR3, R8A77970_PD_A3IR },
|
||||
{ "a2dp", 0x400, 2, R8A77970_PD_A2DP, R8A77970_PD_A3IR },
|
||||
{ "a2cn", 0x400, 3, R8A77970_PD_A2CN, R8A77970_PD_A3IR },
|
||||
{ "a2sc0", 0x400, 4, R8A77970_PD_A2SC0, R8A77970_PD_A3IR },
|
||||
{ "a2sc1", 0x400, 5, R8A77970_PD_A2SC1, R8A77970_PD_A3IR },
|
||||
};
|
||||
|
@ -38,12 +38,12 @@ static const struct rcar_sysc_area r8a77980_areas[] __initconst = {
|
||||
{ "a2sc2", 0x400, 8, R8A77980_PD_A2SC2, R8A77980_PD_A3IR },
|
||||
{ "a2sc3", 0x400, 9, R8A77980_PD_A2SC3, R8A77980_PD_A3IR },
|
||||
{ "a2sc4", 0x400, 10, R8A77980_PD_A2SC4, R8A77980_PD_A3IR },
|
||||
{ "a2pd0", 0x400, 11, R8A77980_PD_A2PD0, R8A77980_PD_A3IR },
|
||||
{ "a2pd1", 0x400, 12, R8A77980_PD_A2PD1, R8A77980_PD_A3IR },
|
||||
{ "a2dp0", 0x400, 11, R8A77980_PD_A2DP0, R8A77980_PD_A3IR },
|
||||
{ "a2dp1", 0x400, 12, R8A77980_PD_A2DP1, R8A77980_PD_A3IR },
|
||||
{ "a2cn", 0x400, 13, R8A77980_PD_A2CN, R8A77980_PD_A3IR },
|
||||
{ "a3vip", 0x2c0, 0, R8A77980_PD_A3VIP, R8A77980_PD_ALWAYS_ON },
|
||||
{ "a3vip1", 0x300, 0, R8A77980_PD_A3VIP1, R8A77980_PD_A3VIP },
|
||||
{ "a3vip2", 0x280, 0, R8A77980_PD_A3VIP2, R8A77980_PD_A3VIP },
|
||||
{ "a3vip0", 0x2c0, 0, R8A77980_PD_A3VIP0, R8A77980_PD_ALWAYS_ON },
|
||||
{ "a3vip1", 0x300, 0, R8A77980_PD_A3VIP1, R8A77980_PD_ALWAYS_ON },
|
||||
{ "a3vip2", 0x280, 0, R8A77980_PD_A3VIP2, R8A77980_PD_ALWAYS_ON },
|
||||
};
|
||||
|
||||
const struct rcar_sysc_info r8a77980_sysc_info __initconst = {
|
||||
|
@ -28,19 +28,6 @@ static struct rcar_sysc_area r8a77990_areas[] __initdata = {
|
||||
{ "3dg-b", 0x100, 1, R8A77990_PD_3DG_B, R8A77990_PD_3DG_A },
|
||||
};
|
||||
|
||||
static void __init rcar_sysc_fix_parent(struct rcar_sysc_area *areas,
|
||||
unsigned int num_areas, u8 id,
|
||||
int new_parent)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_areas; i++)
|
||||
if (areas[i].isr_bit == id) {
|
||||
areas[i].parent = new_parent;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixups for R-Car E3 ES1.0 revision */
|
||||
static const struct soc_device_attribute r8a77990[] __initconst = {
|
||||
{ .soc_id = "r8a77990", .revision = "ES1.0" },
|
||||
@ -50,12 +37,10 @@ static const struct soc_device_attribute r8a77990[] __initconst = {
|
||||
static int __init r8a77990_sysc_init(void)
|
||||
{
|
||||
if (soc_device_match(r8a77990)) {
|
||||
rcar_sysc_fix_parent(r8a77990_areas,
|
||||
ARRAY_SIZE(r8a77990_areas),
|
||||
R8A77990_PD_3DG_A, R8A77990_PD_3DG_B);
|
||||
rcar_sysc_fix_parent(r8a77990_areas,
|
||||
ARRAY_SIZE(r8a77990_areas),
|
||||
R8A77990_PD_3DG_B, R8A77990_PD_ALWAYS_ON);
|
||||
/* Fix incorrect 3DG hierarchy */
|
||||
swap(r8a77990_areas[7], r8a77990_areas[8]);
|
||||
r8a77990_areas[7].parent = R8A77990_PD_ALWAYS_ON;
|
||||
r8a77990_areas[8].parent = R8A77990_PD_3DG_B;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -105,6 +105,15 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
|
||||
|
||||
spin_lock_irqsave(&rcar_sysc_lock, flags);
|
||||
|
||||
/*
|
||||
* The interrupt source needs to be enabled, but masked, to prevent the
|
||||
* CPU from receiving it.
|
||||
*/
|
||||
iowrite32(ioread32(rcar_sysc_base + SYSCIMR) | isr_mask,
|
||||
rcar_sysc_base + SYSCIMR);
|
||||
iowrite32(ioread32(rcar_sysc_base + SYSCIER) | isr_mask,
|
||||
rcar_sysc_base + SYSCIER);
|
||||
|
||||
iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
|
||||
|
||||
/* Submit power shutoff or resume request until it was accepted */
|
||||
@ -146,16 +155,6 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
|
||||
{
|
||||
return rcar_sysc_power(sysc_ch, false);
|
||||
}
|
||||
|
||||
static int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch)
|
||||
{
|
||||
return rcar_sysc_power(sysc_ch, true);
|
||||
}
|
||||
|
||||
static bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch)
|
||||
{
|
||||
unsigned int st;
|
||||
@ -184,7 +183,7 @@ static int rcar_sysc_pd_power_off(struct generic_pm_domain *genpd)
|
||||
struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
|
||||
|
||||
pr_debug("%s: %s\n", __func__, genpd->name);
|
||||
return rcar_sysc_power_down(&pd->ch);
|
||||
return rcar_sysc_power(&pd->ch, false);
|
||||
}
|
||||
|
||||
static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
|
||||
@ -192,7 +191,7 @@ static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
|
||||
struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
|
||||
|
||||
pr_debug("%s: %s\n", __func__, genpd->name);
|
||||
return rcar_sysc_power_up(&pd->ch);
|
||||
return rcar_sysc_power(&pd->ch, true);
|
||||
}
|
||||
|
||||
static bool has_cpg_mstp;
|
||||
@ -252,7 +251,7 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
|
||||
goto finalize;
|
||||
}
|
||||
|
||||
rcar_sysc_power_up(&pd->ch);
|
||||
rcar_sysc_power(&pd->ch, true);
|
||||
|
||||
finalize:
|
||||
error = pm_genpd_init(genpd, gov, false);
|
||||
@ -334,7 +333,6 @@ static int __init rcar_sysc_pd_init(void)
|
||||
const struct of_device_id *match;
|
||||
struct rcar_pm_domains *domains;
|
||||
struct device_node *np;
|
||||
u32 syscier, syscimr;
|
||||
void __iomem *base;
|
||||
unsigned int i;
|
||||
int error;
|
||||
@ -373,27 +371,6 @@ static int __init rcar_sysc_pd_init(void)
|
||||
domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains);
|
||||
rcar_sysc_onecell_data = &domains->onecell_data;
|
||||
|
||||
for (i = 0, syscier = 0; i < info->num_areas; i++)
|
||||
syscier |= BIT(info->areas[i].isr_bit);
|
||||
|
||||
/*
|
||||
* Mask all interrupt sources to prevent the CPU from receiving them.
|
||||
* Make sure not to clear reserved bits that were set before.
|
||||
*/
|
||||
syscimr = ioread32(base + SYSCIMR);
|
||||
syscimr |= syscier;
|
||||
pr_debug("%pOF: syscimr = 0x%08x\n", np, syscimr);
|
||||
iowrite32(syscimr, base + SYSCIMR);
|
||||
|
||||
/*
|
||||
* SYSC needs all interrupt sources enabled to control power.
|
||||
*/
|
||||
pr_debug("%pOF: syscier = 0x%08x\n", np, syscier);
|
||||
iowrite32(syscier, base + SYSCIER);
|
||||
|
||||
/*
|
||||
* First, create all PM domains
|
||||
*/
|
||||
for (i = 0; i < info->num_areas; i++) {
|
||||
const struct rcar_sysc_area *area = &info->areas[i];
|
||||
struct rcar_sysc_pd *pd;
|
||||
@ -421,22 +398,17 @@ static int __init rcar_sysc_pd_init(void)
|
||||
goto out_put;
|
||||
|
||||
domains->domains[area->isr_bit] = &pd->genpd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Second, link all PM domains to their parents
|
||||
*/
|
||||
for (i = 0; i < info->num_areas; i++) {
|
||||
const struct rcar_sysc_area *area = &info->areas[i];
|
||||
|
||||
if (!area->name || area->parent < 0)
|
||||
if (area->parent < 0)
|
||||
continue;
|
||||
|
||||
error = pm_genpd_add_subdomain(domains->domains[area->parent],
|
||||
domains->domains[area->isr_bit]);
|
||||
if (error)
|
||||
&pd->genpd);
|
||||
if (error) {
|
||||
pr_warn("Failed to add PM subdomain %s to parent %u\n",
|
||||
area->name, area->parent);
|
||||
goto out_put;
|
||||
}
|
||||
}
|
||||
|
||||
error = of_genpd_add_provider_onecell(np, &domains->onecell_data);
|
||||
@ -478,8 +450,7 @@ static int rcar_sysc_power_cpu(unsigned int idx, bool on)
|
||||
if (!(pd->flags & PD_CPU) || pd->ch.chan_bit != idx)
|
||||
continue;
|
||||
|
||||
return on ? rcar_sysc_power_up(&pd->ch)
|
||||
: rcar_sysc_power_down(&pd->ch);
|
||||
return rcar_sysc_power(&pd->ch, on);
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
|
@ -21,7 +21,9 @@
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <dt-bindings/power/px30-power.h>
|
||||
#include <dt-bindings/power/rk3036-power.h>
|
||||
#include <dt-bindings/power/rk3066-power.h>
|
||||
#include <dt-bindings/power/rk3128-power.h>
|
||||
#include <dt-bindings/power/rk3188-power.h>
|
||||
#include <dt-bindings/power/rk3228-power.h>
|
||||
#include <dt-bindings/power/rk3288-power.h>
|
||||
#include <dt-bindings/power/rk3328-power.h>
|
||||
@ -737,6 +739,14 @@ static const struct rockchip_domain_info rk3036_pm_domains[] = {
|
||||
[RK3036_PD_SYS] = DOMAIN_RK3036(8, 22, 29, false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3066_pm_domains[] = {
|
||||
[RK3066_PD_GPU] = DOMAIN(9, 9, 3, 24, 29, false),
|
||||
[RK3066_PD_VIDEO] = DOMAIN(8, 8, 4, 23, 28, false),
|
||||
[RK3066_PD_VIO] = DOMAIN(7, 7, 5, 22, 27, false),
|
||||
[RK3066_PD_PERI] = DOMAIN(6, 6, 2, 25, 30, false),
|
||||
[RK3066_PD_CPU] = DOMAIN(-1, 5, 1, 26, 31, false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3128_pm_domains[] = {
|
||||
[RK3128_PD_CORE] = DOMAIN_RK3288(0, 0, 4, false),
|
||||
[RK3128_PD_MSCH] = DOMAIN_RK3288(-1, -1, 6, true),
|
||||
@ -745,6 +755,14 @@ static const struct rockchip_domain_info rk3128_pm_domains[] = {
|
||||
[RK3128_PD_GPU] = DOMAIN_RK3288(1, 1, 3, false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3188_pm_domains[] = {
|
||||
[RK3188_PD_GPU] = DOMAIN(9, 9, 3, 24, 29, false),
|
||||
[RK3188_PD_VIDEO] = DOMAIN(8, 8, 4, 23, 28, false),
|
||||
[RK3188_PD_VIO] = DOMAIN(7, 7, 5, 22, 27, false),
|
||||
[RK3188_PD_PERI] = DOMAIN(6, 6, 2, 25, 30, false),
|
||||
[RK3188_PD_CPU] = DOMAIN(5, 5, 1, 26, 31, false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3228_pm_domains[] = {
|
||||
[RK3228_PD_CORE] = DOMAIN_RK3036(0, 0, 16, true),
|
||||
[RK3228_PD_MSCH] = DOMAIN_RK3036(1, 1, 17, true),
|
||||
@ -846,6 +864,17 @@ static const struct rockchip_pmu_info rk3036_pmu = {
|
||||
.domain_info = rk3036_pm_domains,
|
||||
};
|
||||
|
||||
static const struct rockchip_pmu_info rk3066_pmu = {
|
||||
.pwr_offset = 0x08,
|
||||
.status_offset = 0x0c,
|
||||
.req_offset = 0x38, /* PMU_MISC_CON1 */
|
||||
.idle_offset = 0x0c,
|
||||
.ack_offset = 0x0c,
|
||||
|
||||
.num_domains = ARRAY_SIZE(rk3066_pm_domains),
|
||||
.domain_info = rk3066_pm_domains,
|
||||
};
|
||||
|
||||
static const struct rockchip_pmu_info rk3128_pmu = {
|
||||
.pwr_offset = 0x04,
|
||||
.status_offset = 0x08,
|
||||
@ -857,6 +886,17 @@ static const struct rockchip_pmu_info rk3128_pmu = {
|
||||
.domain_info = rk3128_pm_domains,
|
||||
};
|
||||
|
||||
static const struct rockchip_pmu_info rk3188_pmu = {
|
||||
.pwr_offset = 0x08,
|
||||
.status_offset = 0x0c,
|
||||
.req_offset = 0x38, /* PMU_MISC_CON1 */
|
||||
.idle_offset = 0x0c,
|
||||
.ack_offset = 0x0c,
|
||||
|
||||
.num_domains = ARRAY_SIZE(rk3188_pm_domains),
|
||||
.domain_info = rk3188_pm_domains,
|
||||
};
|
||||
|
||||
static const struct rockchip_pmu_info rk3228_pmu = {
|
||||
.req_offset = 0x40c,
|
||||
.idle_offset = 0x488,
|
||||
@ -948,10 +988,18 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
|
||||
.compatible = "rockchip,rk3036-power-controller",
|
||||
.data = (void *)&rk3036_pmu,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3066-power-controller",
|
||||
.data = (void *)&rk3066_pmu,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3128-power-controller",
|
||||
.data = (void *)&rk3128_pmu,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3188-power-controller",
|
||||
.data = (void *)&rk3188_pmu,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3228-power-controller",
|
||||
.data = (void *)&rk3228_pmu,
|
||||
|
@ -155,17 +155,7 @@ static int sunxi_sram_show(struct seq_file *s, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sunxi_sram_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, sunxi_sram_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations sunxi_sram_fops = {
|
||||
.open = sunxi_sram_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(sunxi_sram);
|
||||
|
||||
static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data *data)
|
||||
{
|
||||
@ -300,6 +290,10 @@ static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
|
||||
/* Nothing special */
|
||||
};
|
||||
|
||||
static const struct sunxi_sramc_variant sun8i_h3_sramc_variant = {
|
||||
.has_emac_clock = true,
|
||||
};
|
||||
|
||||
static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
|
||||
.has_emac_clock = true,
|
||||
};
|
||||
@ -379,7 +373,7 @@ static const struct of_device_id sunxi_sram_dt_match[] = {
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun8i-h3-system-control",
|
||||
.data = &sun4i_a10_sramc_variant,
|
||||
.data = &sun8i_h3_sramc_variant,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun50i-a64-sram-controller",
|
||||
@ -389,6 +383,10 @@ static const struct of_device_id sunxi_sram_dt_match[] = {
|
||||
.compatible = "allwinner,sun50i-a64-system-control",
|
||||
.data = &sun50i_a64_sramc_variant,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun50i-h5-system-control",
|
||||
.data = &sun50i_a64_sramc_variant,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);
|
||||
|
@ -22,11 +22,15 @@ static const struct of_device_id tegra_machine_match[] = {
|
||||
|
||||
bool soc_is_tegra(void)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct device_node *root;
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
if (!root)
|
||||
return false;
|
||||
|
||||
return of_match_node(tegra_machine_match, root) != NULL;
|
||||
match = of_match_node(tegra_machine_match, root);
|
||||
of_node_put(root);
|
||||
|
||||
return match != NULL;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
* drivers/soc/tegra/pmc.c
|
||||
*
|
||||
* Copyright (c) 2010 Google, Inc
|
||||
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Author:
|
||||
* Colin Cross <ccross@google.com>
|
||||
@ -29,9 +30,12 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
@ -48,7 +52,10 @@
|
||||
#include <soc/tegra/fuse.h>
|
||||
#include <soc/tegra/pmc.h>
|
||||
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
|
||||
#include <dt-bindings/gpio/tegra186-gpio.h>
|
||||
#include <dt-bindings/gpio/tegra194-gpio.h>
|
||||
|
||||
#define PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
|
||||
@ -92,7 +99,6 @@
|
||||
#define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2)
|
||||
#define PMC_SENSOR_CTRL_ENABLE_RST BIT(1)
|
||||
|
||||
#define PMC_RST_STATUS 0x1b4
|
||||
#define PMC_RST_STATUS_POR 0
|
||||
#define PMC_RST_STATUS_WATCHDOG 1
|
||||
#define PMC_RST_STATUS_SENSOR 2
|
||||
@ -126,6 +132,16 @@
|
||||
#define GPU_RG_CNTRL 0x2d4
|
||||
|
||||
/* Tegra186 and later */
|
||||
#define WAKE_AOWAKE_CNTRL(x) (0x000 + ((x) << 2))
|
||||
#define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3)
|
||||
#define WAKE_AOWAKE_MASK_W(x) (0x180 + ((x) << 2))
|
||||
#define WAKE_AOWAKE_MASK_R(x) (0x300 + ((x) << 2))
|
||||
#define WAKE_AOWAKE_STATUS_W(x) (0x30c + ((x) << 2))
|
||||
#define WAKE_AOWAKE_STATUS_R(x) (0x48c + ((x) << 2))
|
||||
#define WAKE_AOWAKE_TIER0_ROUTING(x) (0x4b4 + ((x) << 2))
|
||||
#define WAKE_AOWAKE_TIER1_ROUTING(x) (0x4c0 + ((x) << 2))
|
||||
#define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2))
|
||||
|
||||
#define WAKE_AOWAKE_CTRL 0x4f4
|
||||
#define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
|
||||
|
||||
@ -151,8 +167,45 @@ struct tegra_pmc_regs {
|
||||
unsigned int dpd_status;
|
||||
unsigned int dpd2_req;
|
||||
unsigned int dpd2_status;
|
||||
unsigned int rst_status;
|
||||
unsigned int rst_source_shift;
|
||||
unsigned int rst_source_mask;
|
||||
unsigned int rst_level_shift;
|
||||
unsigned int rst_level_mask;
|
||||
};
|
||||
|
||||
struct tegra_wake_event {
|
||||
const char *name;
|
||||
unsigned int id;
|
||||
unsigned int irq;
|
||||
struct {
|
||||
unsigned int instance;
|
||||
unsigned int pin;
|
||||
} gpio;
|
||||
};
|
||||
|
||||
#define TEGRA_WAKE_IRQ(_name, _id, _irq) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.id = _id, \
|
||||
.irq = _irq, \
|
||||
.gpio = { \
|
||||
.instance = UINT_MAX, \
|
||||
.pin = UINT_MAX, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define TEGRA_WAKE_GPIO(_name, _id, _instance, _pin) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.id = _id, \
|
||||
.irq = 0, \
|
||||
.gpio = { \
|
||||
.instance = _instance, \
|
||||
.pin = _pin, \
|
||||
}, \
|
||||
}
|
||||
|
||||
struct tegra_pmc_soc {
|
||||
unsigned int num_powergates;
|
||||
const char *const *powergates;
|
||||
@ -175,6 +228,45 @@ struct tegra_pmc_soc {
|
||||
void (*setup_irq_polarity)(struct tegra_pmc *pmc,
|
||||
struct device_node *np,
|
||||
bool invert);
|
||||
|
||||
const char * const *reset_sources;
|
||||
unsigned int num_reset_sources;
|
||||
const char * const *reset_levels;
|
||||
unsigned int num_reset_levels;
|
||||
|
||||
const struct tegra_wake_event *wake_events;
|
||||
unsigned int num_wake_events;
|
||||
};
|
||||
|
||||
static const char * const tegra186_reset_sources[] = {
|
||||
"SYS_RESET",
|
||||
"AOWDT",
|
||||
"MCCPLEXWDT",
|
||||
"BPMPWDT",
|
||||
"SCEWDT",
|
||||
"SPEWDT",
|
||||
"APEWDT",
|
||||
"BCCPLEXWDT",
|
||||
"SENSOR",
|
||||
"AOTAG",
|
||||
"VFSENSOR",
|
||||
"SWREST",
|
||||
"SC7",
|
||||
"HSM",
|
||||
"CORESIGHT"
|
||||
};
|
||||
|
||||
static const char * const tegra186_reset_levels[] = {
|
||||
"L0", "L1", "L2", "WARM"
|
||||
};
|
||||
|
||||
static const char * const tegra30_reset_sources[] = {
|
||||
"POWER_ON_RESET",
|
||||
"WATCHDOG",
|
||||
"SENSOR",
|
||||
"SW_MAIN",
|
||||
"LP0",
|
||||
"AOTAG"
|
||||
};
|
||||
|
||||
/**
|
||||
@ -230,6 +322,9 @@ struct tegra_pmc {
|
||||
struct mutex powergates_lock;
|
||||
|
||||
struct pinctrl_dev *pctl_dev;
|
||||
|
||||
struct irq_domain *domain;
|
||||
struct irq_chip irq;
|
||||
};
|
||||
|
||||
static struct tegra_pmc *pmc = &(struct tegra_pmc) {
|
||||
@ -538,16 +633,10 @@ EXPORT_SYMBOL(tegra_powergate_power_off);
|
||||
*/
|
||||
int tegra_powergate_is_powered(unsigned int id)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!tegra_powergate_is_valid(id))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&pmc->powergates_lock);
|
||||
status = tegra_powergate_state(id);
|
||||
mutex_unlock(&pmc->powergates_lock);
|
||||
|
||||
return status;
|
||||
return tegra_powergate_state(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -717,17 +806,7 @@ static int powergate_show(struct seq_file *s, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int powergate_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, powergate_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations powergate_fops = {
|
||||
.open = powergate_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(powergate);
|
||||
|
||||
static int tegra_powergate_debugfs_init(void)
|
||||
{
|
||||
@ -847,22 +926,6 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
|
||||
goto remove_resets;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: If XHCI is enabled for Tegra, then power-up the XUSB
|
||||
* host and super-speed partitions. Once the XHCI driver
|
||||
* manages the partitions itself this code can be removed. Note
|
||||
* that we don't register these partitions with the genpd core
|
||||
* to avoid it from powering down the partitions as they appear
|
||||
* to be unused.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_USB_XHCI_TEGRA) &&
|
||||
(id == TEGRA_POWERGATE_XUSBA || id == TEGRA_POWERGATE_XUSBC)) {
|
||||
if (off)
|
||||
WARN_ON(tegra_powergate_power_up(pg, true));
|
||||
|
||||
goto remove_resets;
|
||||
}
|
||||
|
||||
err = pm_genpd_init(&pg->genpd, NULL, off);
|
||||
if (err < 0) {
|
||||
pr_err("failed to initialise PM domain %pOFn: %d\n", np,
|
||||
@ -1543,6 +1606,225 @@ static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc)
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t reset_reason_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
u32 value, rst_src;
|
||||
|
||||
value = tegra_pmc_readl(pmc->soc->regs->rst_status);
|
||||
rst_src = (value & pmc->soc->regs->rst_source_mask) >>
|
||||
pmc->soc->regs->rst_source_shift;
|
||||
|
||||
return sprintf(buf, "%s\n", pmc->soc->reset_sources[rst_src]);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(reset_reason);
|
||||
|
||||
static ssize_t reset_level_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
u32 value, rst_lvl;
|
||||
|
||||
value = tegra_pmc_readl(pmc->soc->regs->rst_status);
|
||||
rst_lvl = (value & pmc->soc->regs->rst_level_mask) >>
|
||||
pmc->soc->regs->rst_level_shift;
|
||||
|
||||
return sprintf(buf, "%s\n", pmc->soc->reset_levels[rst_lvl]);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(reset_level);
|
||||
|
||||
static void tegra_pmc_reset_sysfs_init(struct tegra_pmc *pmc)
|
||||
{
|
||||
struct device *dev = pmc->dev;
|
||||
int err = 0;
|
||||
|
||||
if (pmc->soc->reset_sources) {
|
||||
err = device_create_file(dev, &dev_attr_reset_reason);
|
||||
if (err < 0)
|
||||
dev_warn(dev,
|
||||
"failed to create attr \"reset_reason\": %d\n",
|
||||
err);
|
||||
}
|
||||
|
||||
if (pmc->soc->reset_levels) {
|
||||
err = device_create_file(dev, &dev_attr_reset_level);
|
||||
if (err < 0)
|
||||
dev_warn(dev,
|
||||
"failed to create attr \"reset_level\": %d\n",
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
static int tegra_pmc_irq_translate(struct irq_domain *domain,
|
||||
struct irq_fwspec *fwspec,
|
||||
unsigned long *hwirq,
|
||||
unsigned int *type)
|
||||
{
|
||||
if (WARN_ON(fwspec->param_count < 2))
|
||||
return -EINVAL;
|
||||
|
||||
*hwirq = fwspec->param[0];
|
||||
*type = fwspec->param[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
unsigned int num_irqs, void *data)
|
||||
{
|
||||
struct tegra_pmc *pmc = domain->host_data;
|
||||
const struct tegra_pmc_soc *soc = pmc->soc;
|
||||
struct irq_fwspec *fwspec = data;
|
||||
unsigned int i;
|
||||
int err = 0;
|
||||
|
||||
for (i = 0; i < soc->num_wake_events; i++) {
|
||||
const struct tegra_wake_event *event = &soc->wake_events[i];
|
||||
|
||||
if (fwspec->param_count == 2) {
|
||||
struct irq_fwspec spec;
|
||||
|
||||
if (event->id != fwspec->param[0])
|
||||
continue;
|
||||
|
||||
err = irq_domain_set_hwirq_and_chip(domain, virq,
|
||||
event->id,
|
||||
&pmc->irq, pmc);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
spec.fwnode = &pmc->dev->of_node->fwnode;
|
||||
spec.param_count = 3;
|
||||
spec.param[0] = GIC_SPI;
|
||||
spec.param[1] = event->irq;
|
||||
spec.param[2] = fwspec->param[1];
|
||||
|
||||
err = irq_domain_alloc_irqs_parent(domain, virq,
|
||||
num_irqs, &spec);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (fwspec->param_count == 3) {
|
||||
if (event->gpio.instance != fwspec->param[0] ||
|
||||
event->gpio.pin != fwspec->param[1])
|
||||
continue;
|
||||
|
||||
err = irq_domain_set_hwirq_and_chip(domain, virq,
|
||||
event->id,
|
||||
&pmc->irq, pmc);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == soc->num_wake_events)
|
||||
err = irq_domain_set_hwirq_and_chip(domain, virq, ULONG_MAX,
|
||||
&pmc->irq, pmc);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops tegra_pmc_irq_domain_ops = {
|
||||
.translate = tegra_pmc_irq_translate,
|
||||
.alloc = tegra_pmc_irq_alloc,
|
||||
};
|
||||
|
||||
static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
|
||||
{
|
||||
struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
|
||||
unsigned int offset, bit;
|
||||
u32 value;
|
||||
|
||||
offset = data->hwirq / 32;
|
||||
bit = data->hwirq % 32;
|
||||
|
||||
/* clear wake status */
|
||||
writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(data->hwirq));
|
||||
|
||||
/* route wake to tier 2 */
|
||||
value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
|
||||
|
||||
if (!on)
|
||||
value &= ~(1 << bit);
|
||||
else
|
||||
value |= 1 << bit;
|
||||
|
||||
writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
|
||||
|
||||
/* enable wakeup event */
|
||||
writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(data->hwirq));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_pmc_irq_set_type(struct irq_data *data, unsigned int type)
|
||||
{
|
||||
struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
|
||||
u32 value;
|
||||
|
||||
if (data->hwirq == ULONG_MAX)
|
||||
return 0;
|
||||
|
||||
value = readl(pmc->wake + WAKE_AOWAKE_CNTRL(data->hwirq));
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
value |= WAKE_AOWAKE_CNTRL_LEVEL;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
value &= ~WAKE_AOWAKE_CNTRL_LEVEL;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING:
|
||||
value ^= WAKE_AOWAKE_CNTRL_LEVEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(value, pmc->wake + WAKE_AOWAKE_CNTRL(data->hwirq));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_pmc_irq_init(struct tegra_pmc *pmc)
|
||||
{
|
||||
struct irq_domain *parent = NULL;
|
||||
struct device_node *np;
|
||||
|
||||
np = of_irq_find_parent(pmc->dev->of_node);
|
||||
if (np) {
|
||||
parent = irq_find_host(np);
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
if (!parent)
|
||||
return 0;
|
||||
|
||||
pmc->irq.name = dev_name(pmc->dev);
|
||||
pmc->irq.irq_mask = irq_chip_mask_parent;
|
||||
pmc->irq.irq_unmask = irq_chip_unmask_parent;
|
||||
pmc->irq.irq_eoi = irq_chip_eoi_parent;
|
||||
pmc->irq.irq_set_affinity = irq_chip_set_affinity_parent;
|
||||
pmc->irq.irq_set_type = tegra_pmc_irq_set_type;
|
||||
pmc->irq.irq_set_wake = tegra_pmc_irq_set_wake;
|
||||
|
||||
pmc->domain = irq_domain_add_hierarchy(parent, 0, 96, pmc->dev->of_node,
|
||||
&tegra_pmc_irq_domain_ops, pmc);
|
||||
if (!pmc->domain) {
|
||||
dev_err(pmc->dev, "failed to allocate domain\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_pmc_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *base;
|
||||
@ -1612,6 +1894,8 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||
|
||||
tegra_pmc_init_tsense_reset(pmc);
|
||||
|
||||
tegra_pmc_reset_sysfs_init(pmc);
|
||||
|
||||
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
|
||||
err = tegra_powergate_debugfs_init();
|
||||
if (err < 0)
|
||||
@ -1629,6 +1913,10 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||
if (err)
|
||||
goto cleanup_restart_handler;
|
||||
|
||||
err = tegra_pmc_irq_init(pmc);
|
||||
if (err < 0)
|
||||
goto cleanup_restart_handler;
|
||||
|
||||
mutex_lock(&pmc->powergates_lock);
|
||||
iounmap(pmc->base);
|
||||
pmc->base = base;
|
||||
@ -1678,6 +1966,11 @@ static const struct tegra_pmc_regs tegra20_pmc_regs = {
|
||||
.dpd_status = 0x1bc,
|
||||
.dpd2_req = 0x1c0,
|
||||
.dpd2_status = 0x1c4,
|
||||
.rst_status = 0x1b4,
|
||||
.rst_source_shift = 0x0,
|
||||
.rst_source_mask = 0x7,
|
||||
.rst_level_shift = 0x0,
|
||||
.rst_level_mask = 0x0,
|
||||
};
|
||||
|
||||
static void tegra20_pmc_init(struct tegra_pmc *pmc)
|
||||
@ -1735,6 +2028,10 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
|
||||
.regs = &tegra20_pmc_regs,
|
||||
.init = tegra20_pmc_init,
|
||||
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
|
||||
.reset_sources = NULL,
|
||||
.num_reset_sources = 0,
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
};
|
||||
|
||||
static const char * const tegra30_powergates[] = {
|
||||
@ -1776,6 +2073,10 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
|
||||
.regs = &tegra20_pmc_regs,
|
||||
.init = tegra20_pmc_init,
|
||||
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
|
||||
.reset_sources = tegra30_reset_sources,
|
||||
.num_reset_sources = 5,
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
};
|
||||
|
||||
static const char * const tegra114_powergates[] = {
|
||||
@ -1821,6 +2122,10 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
|
||||
.regs = &tegra20_pmc_regs,
|
||||
.init = tegra20_pmc_init,
|
||||
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
|
||||
.reset_sources = tegra30_reset_sources,
|
||||
.num_reset_sources = 5,
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
};
|
||||
|
||||
static const char * const tegra124_powergates[] = {
|
||||
@ -1926,6 +2231,10 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
|
||||
.regs = &tegra20_pmc_regs,
|
||||
.init = tegra20_pmc_init,
|
||||
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
|
||||
.reset_sources = tegra30_reset_sources,
|
||||
.num_reset_sources = 5,
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
};
|
||||
|
||||
static const char * const tegra210_powergates[] = {
|
||||
@ -2027,6 +2336,10 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
|
||||
.regs = &tegra20_pmc_regs,
|
||||
.init = tegra20_pmc_init,
|
||||
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
|
||||
.reset_sources = tegra30_reset_sources,
|
||||
.num_reset_sources = 5,
|
||||
.reset_levels = NULL,
|
||||
.num_reset_levels = 0,
|
||||
};
|
||||
|
||||
#define TEGRA186_IO_PAD_TABLE(_pad) \
|
||||
@ -2084,6 +2397,11 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = {
|
||||
.dpd_status = 0x78,
|
||||
.dpd2_req = 0x7c,
|
||||
.dpd2_status = 0x80,
|
||||
.rst_status = 0x70,
|
||||
.rst_source_shift = 0x2,
|
||||
.rst_source_mask = 0x3C,
|
||||
.rst_level_shift = 0x0,
|
||||
.rst_level_mask = 0x3,
|
||||
};
|
||||
|
||||
static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
|
||||
@ -2121,6 +2439,11 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
|
||||
iounmap(wake);
|
||||
}
|
||||
|
||||
static const struct tegra_wake_event tegra186_wake_events[] = {
|
||||
TEGRA_WAKE_GPIO("power", 29, 1, TEGRA_AON_GPIO(FF, 0)),
|
||||
TEGRA_WAKE_IRQ("rtc", 73, 10),
|
||||
};
|
||||
|
||||
static const struct tegra_pmc_soc tegra186_pmc_soc = {
|
||||
.num_powergates = 0,
|
||||
.powergates = NULL,
|
||||
@ -2136,10 +2459,87 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
|
||||
.regs = &tegra186_pmc_regs,
|
||||
.init = NULL,
|
||||
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
|
||||
.reset_sources = tegra186_reset_sources,
|
||||
.num_reset_sources = 14,
|
||||
.reset_levels = tegra186_reset_levels,
|
||||
.num_reset_levels = 3,
|
||||
.num_wake_events = ARRAY_SIZE(tegra186_wake_events),
|
||||
.wake_events = tegra186_wake_events,
|
||||
};
|
||||
|
||||
static const struct tegra_io_pad_soc tegra194_io_pads[] = {
|
||||
{ .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK_BIAS, .dpd = 4, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK3, .dpd = 5, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 7, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_EQOS, .dpd = 8, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK2_BIAS, .dpd = 9, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 10, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_DAP3, .dpd = 11, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_DAP5, .dpd = 12, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PWR_CTL, .dpd = 15, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SOC_GPIO53, .dpd = 16, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_GP_PWM2, .dpd = 18, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_GP_PWM3, .dpd = 19, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SOC_GPIO12, .dpd = 20, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SOC_GPIO13, .dpd = 21, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SOC_GPIO10, .dpd = 22, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_UART4, .dpd = 23, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_UART5, .dpd = 24, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_HDMI_DP3, .dpd = 26, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_HDMI_DP2, .dpd = 27, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_HDMI_DP0, .dpd = 28, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_HDMI_DP1, .dpd = 29, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_CTL2, .dpd = 33, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_L0_RST_N, .dpd = 34, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_L1_RST_N, .dpd = 35, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SDMMC4, .dpd = 36, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_PEX_L5_RST_N, .dpd = 37, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIC, .dpd = 43, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSID, .dpd = 44, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIE, .dpd = 45, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIF, .dpd = 46, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SPI, .dpd = 47, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_UFS, .dpd = 49, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIG, .dpd = 50, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CSIH, .dpd = 51, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_EDP, .dpd = 53, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SDMMC1_HV, .dpd = 55, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_SDMMC3_HV, .dpd = 56, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_CONN, .dpd = 60, .voltage = UINT_MAX },
|
||||
{ .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = UINT_MAX },
|
||||
};
|
||||
|
||||
static const struct tegra_wake_event tegra194_wake_events[] = {
|
||||
TEGRA_WAKE_GPIO("power", 29, 1, TEGRA194_AON_GPIO(EE, 4)),
|
||||
TEGRA_WAKE_IRQ("rtc", 73, 10),
|
||||
};
|
||||
|
||||
static const struct tegra_pmc_soc tegra194_pmc_soc = {
|
||||
.num_powergates = 0,
|
||||
.powergates = NULL,
|
||||
.num_cpu_powergates = 0,
|
||||
.cpu_powergates = NULL,
|
||||
.has_tsense_reset = false,
|
||||
.has_gpu_clamps = false,
|
||||
.num_io_pads = ARRAY_SIZE(tegra194_io_pads),
|
||||
.io_pads = tegra194_io_pads,
|
||||
.regs = &tegra186_pmc_regs,
|
||||
.init = NULL,
|
||||
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
|
||||
.num_wake_events = ARRAY_SIZE(tegra194_wake_events),
|
||||
.wake_events = tegra194_wake_events,
|
||||
};
|
||||
|
||||
static const struct of_device_id tegra_pmc_match[] = {
|
||||
{ .compatible = "nvidia,tegra194-pmc", .data = &tegra186_pmc_soc },
|
||||
{ .compatible = "nvidia,tegra194-pmc", .data = &tegra194_pmc_soc },
|
||||
{ .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc },
|
||||
{ .compatible = "nvidia,tegra210-pmc", .data = &tegra210_pmc_soc },
|
||||
{ .compatible = "nvidia,tegra132-pmc", .data = &tegra124_pmc_soc },
|
||||
|
@ -57,6 +57,7 @@
|
||||
static struct wkup_m3_ipc *m3_ipc_state;
|
||||
|
||||
static const struct wkup_m3_wakeup_src wakeups[] = {
|
||||
{.irq_nr = 16, .src = "PRCM"},
|
||||
{.irq_nr = 35, .src = "USB0_PHY"},
|
||||
{.irq_nr = 36, .src = "USB1_PHY"},
|
||||
{.irq_nr = 40, .src = "I2C0"},
|
||||
|
559
include/dt-bindings/firmware/imx/rsrc.h
Normal file
559
include/dt-bindings/firmware/imx/rsrc.h
Normal file
@ -0,0 +1,559 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017-2018 NXP
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_RSCRC_IMX_H
|
||||
#define __DT_BINDINGS_RSCRC_IMX_H
|
||||
|
||||
/*
|
||||
* These defines are used to indicate a resource. Resources include peripherals
|
||||
* and bus masters (but not memory regions). Note items from list should
|
||||
* never be changed or removed (only added to at the end of the list).
|
||||
*/
|
||||
|
||||
#define IMX_SC_R_A53 0
|
||||
#define IMX_SC_R_A53_0 1
|
||||
#define IMX_SC_R_A53_1 2
|
||||
#define IMX_SC_R_A53_2 3
|
||||
#define IMX_SC_R_A53_3 4
|
||||
#define IMX_SC_R_A72 5
|
||||
#define IMX_SC_R_A72_0 6
|
||||
#define IMX_SC_R_A72_1 7
|
||||
#define IMX_SC_R_A72_2 8
|
||||
#define IMX_SC_R_A72_3 9
|
||||
#define IMX_SC_R_CCI 10
|
||||
#define IMX_SC_R_DB 11
|
||||
#define IMX_SC_R_DRC_0 12
|
||||
#define IMX_SC_R_DRC_1 13
|
||||
#define IMX_SC_R_GIC_SMMU 14
|
||||
#define IMX_SC_R_IRQSTR_M4_0 15
|
||||
#define IMX_SC_R_IRQSTR_M4_1 16
|
||||
#define IMX_SC_R_SMMU 17
|
||||
#define IMX_SC_R_GIC 18
|
||||
#define IMX_SC_R_DC_0_BLIT0 19
|
||||
#define IMX_SC_R_DC_0_BLIT1 20
|
||||
#define IMX_SC_R_DC_0_BLIT2 21
|
||||
#define IMX_SC_R_DC_0_BLIT_OUT 22
|
||||
#define IMX_SC_R_DC_0_CAPTURE0 23
|
||||
#define IMX_SC_R_DC_0_CAPTURE1 24
|
||||
#define IMX_SC_R_DC_0_WARP 25
|
||||
#define IMX_SC_R_DC_0_INTEGRAL0 26
|
||||
#define IMX_SC_R_DC_0_INTEGRAL1 27
|
||||
#define IMX_SC_R_DC_0_VIDEO0 28
|
||||
#define IMX_SC_R_DC_0_VIDEO1 29
|
||||
#define IMX_SC_R_DC_0_FRAC0 30
|
||||
#define IMX_SC_R_DC_0_FRAC1 31
|
||||
#define IMX_SC_R_DC_0 32
|
||||
#define IMX_SC_R_GPU_2_PID0 33
|
||||
#define IMX_SC_R_DC_0_PLL_0 34
|
||||
#define IMX_SC_R_DC_0_PLL_1 35
|
||||
#define IMX_SC_R_DC_1_BLIT0 36
|
||||
#define IMX_SC_R_DC_1_BLIT1 37
|
||||
#define IMX_SC_R_DC_1_BLIT2 38
|
||||
#define IMX_SC_R_DC_1_BLIT_OUT 39
|
||||
#define IMX_SC_R_DC_1_CAPTURE0 40
|
||||
#define IMX_SC_R_DC_1_CAPTURE1 41
|
||||
#define IMX_SC_R_DC_1_WARP 42
|
||||
#define IMX_SC_R_DC_1_INTEGRAL0 43
|
||||
#define IMX_SC_R_DC_1_INTEGRAL1 44
|
||||
#define IMX_SC_R_DC_1_VIDEO0 45
|
||||
#define IMX_SC_R_DC_1_VIDEO1 46
|
||||
#define IMX_SC_R_DC_1_FRAC0 47
|
||||
#define IMX_SC_R_DC_1_FRAC1 48
|
||||
#define IMX_SC_R_DC_1 49
|
||||
#define IMX_SC_R_GPU_3_PID0 50
|
||||
#define IMX_SC_R_DC_1_PLL_0 51
|
||||
#define IMX_SC_R_DC_1_PLL_1 52
|
||||
#define IMX_SC_R_SPI_0 53
|
||||
#define IMX_SC_R_SPI_1 54
|
||||
#define IMX_SC_R_SPI_2 55
|
||||
#define IMX_SC_R_SPI_3 56
|
||||
#define IMX_SC_R_UART_0 57
|
||||
#define IMX_SC_R_UART_1 58
|
||||
#define IMX_SC_R_UART_2 59
|
||||
#define IMX_SC_R_UART_3 60
|
||||
#define IMX_SC_R_UART_4 61
|
||||
#define IMX_SC_R_EMVSIM_0 62
|
||||
#define IMX_SC_R_EMVSIM_1 63
|
||||
#define IMX_SC_R_DMA_0_CH0 64
|
||||
#define IMX_SC_R_DMA_0_CH1 65
|
||||
#define IMX_SC_R_DMA_0_CH2 66
|
||||
#define IMX_SC_R_DMA_0_CH3 67
|
||||
#define IMX_SC_R_DMA_0_CH4 68
|
||||
#define IMX_SC_R_DMA_0_CH5 69
|
||||
#define IMX_SC_R_DMA_0_CH6 70
|
||||
#define IMX_SC_R_DMA_0_CH7 71
|
||||
#define IMX_SC_R_DMA_0_CH8 72
|
||||
#define IMX_SC_R_DMA_0_CH9 73
|
||||
#define IMX_SC_R_DMA_0_CH10 74
|
||||
#define IMX_SC_R_DMA_0_CH11 75
|
||||
#define IMX_SC_R_DMA_0_CH12 76
|
||||
#define IMX_SC_R_DMA_0_CH13 77
|
||||
#define IMX_SC_R_DMA_0_CH14 78
|
||||
#define IMX_SC_R_DMA_0_CH15 79
|
||||
#define IMX_SC_R_DMA_0_CH16 80
|
||||
#define IMX_SC_R_DMA_0_CH17 81
|
||||
#define IMX_SC_R_DMA_0_CH18 82
|
||||
#define IMX_SC_R_DMA_0_CH19 83
|
||||
#define IMX_SC_R_DMA_0_CH20 84
|
||||
#define IMX_SC_R_DMA_0_CH21 85
|
||||
#define IMX_SC_R_DMA_0_CH22 86
|
||||
#define IMX_SC_R_DMA_0_CH23 87
|
||||
#define IMX_SC_R_DMA_0_CH24 88
|
||||
#define IMX_SC_R_DMA_0_CH25 89
|
||||
#define IMX_SC_R_DMA_0_CH26 90
|
||||
#define IMX_SC_R_DMA_0_CH27 91
|
||||
#define IMX_SC_R_DMA_0_CH28 92
|
||||
#define IMX_SC_R_DMA_0_CH29 93
|
||||
#define IMX_SC_R_DMA_0_CH30 94
|
||||
#define IMX_SC_R_DMA_0_CH31 95
|
||||
#define IMX_SC_R_I2C_0 96
|
||||
#define IMX_SC_R_I2C_1 97
|
||||
#define IMX_SC_R_I2C_2 98
|
||||
#define IMX_SC_R_I2C_3 99
|
||||
#define IMX_SC_R_I2C_4 100
|
||||
#define IMX_SC_R_ADC_0 101
|
||||
#define IMX_SC_R_ADC_1 102
|
||||
#define IMX_SC_R_FTM_0 103
|
||||
#define IMX_SC_R_FTM_1 104
|
||||
#define IMX_SC_R_CAN_0 105
|
||||
#define IMX_SC_R_CAN_1 106
|
||||
#define IMX_SC_R_CAN_2 107
|
||||
#define IMX_SC_R_DMA_1_CH0 108
|
||||
#define IMX_SC_R_DMA_1_CH1 109
|
||||
#define IMX_SC_R_DMA_1_CH2 110
|
||||
#define IMX_SC_R_DMA_1_CH3 111
|
||||
#define IMX_SC_R_DMA_1_CH4 112
|
||||
#define IMX_SC_R_DMA_1_CH5 113
|
||||
#define IMX_SC_R_DMA_1_CH6 114
|
||||
#define IMX_SC_R_DMA_1_CH7 115
|
||||
#define IMX_SC_R_DMA_1_CH8 116
|
||||
#define IMX_SC_R_DMA_1_CH9 117
|
||||
#define IMX_SC_R_DMA_1_CH10 118
|
||||
#define IMX_SC_R_DMA_1_CH11 119
|
||||
#define IMX_SC_R_DMA_1_CH12 120
|
||||
#define IMX_SC_R_DMA_1_CH13 121
|
||||
#define IMX_SC_R_DMA_1_CH14 122
|
||||
#define IMX_SC_R_DMA_1_CH15 123
|
||||
#define IMX_SC_R_DMA_1_CH16 124
|
||||
#define IMX_SC_R_DMA_1_CH17 125
|
||||
#define IMX_SC_R_DMA_1_CH18 126
|
||||
#define IMX_SC_R_DMA_1_CH19 127
|
||||
#define IMX_SC_R_DMA_1_CH20 128
|
||||
#define IMX_SC_R_DMA_1_CH21 129
|
||||
#define IMX_SC_R_DMA_1_CH22 130
|
||||
#define IMX_SC_R_DMA_1_CH23 131
|
||||
#define IMX_SC_R_DMA_1_CH24 132
|
||||
#define IMX_SC_R_DMA_1_CH25 133
|
||||
#define IMX_SC_R_DMA_1_CH26 134
|
||||
#define IMX_SC_R_DMA_1_CH27 135
|
||||
#define IMX_SC_R_DMA_1_CH28 136
|
||||
#define IMX_SC_R_DMA_1_CH29 137
|
||||
#define IMX_SC_R_DMA_1_CH30 138
|
||||
#define IMX_SC_R_DMA_1_CH31 139
|
||||
#define IMX_SC_R_UNUSED1 140
|
||||
#define IMX_SC_R_UNUSED2 141
|
||||
#define IMX_SC_R_UNUSED3 142
|
||||
#define IMX_SC_R_UNUSED4 143
|
||||
#define IMX_SC_R_GPU_0_PID0 144
|
||||
#define IMX_SC_R_GPU_0_PID1 145
|
||||
#define IMX_SC_R_GPU_0_PID2 146
|
||||
#define IMX_SC_R_GPU_0_PID3 147
|
||||
#define IMX_SC_R_GPU_1_PID0 148
|
||||
#define IMX_SC_R_GPU_1_PID1 149
|
||||
#define IMX_SC_R_GPU_1_PID2 150
|
||||
#define IMX_SC_R_GPU_1_PID3 151
|
||||
#define IMX_SC_R_PCIE_A 152
|
||||
#define IMX_SC_R_SERDES_0 153
|
||||
#define IMX_SC_R_MATCH_0 154
|
||||
#define IMX_SC_R_MATCH_1 155
|
||||
#define IMX_SC_R_MATCH_2 156
|
||||
#define IMX_SC_R_MATCH_3 157
|
||||
#define IMX_SC_R_MATCH_4 158
|
||||
#define IMX_SC_R_MATCH_5 159
|
||||
#define IMX_SC_R_MATCH_6 160
|
||||
#define IMX_SC_R_MATCH_7 161
|
||||
#define IMX_SC_R_MATCH_8 162
|
||||
#define IMX_SC_R_MATCH_9 163
|
||||
#define IMX_SC_R_MATCH_10 164
|
||||
#define IMX_SC_R_MATCH_11 165
|
||||
#define IMX_SC_R_MATCH_12 166
|
||||
#define IMX_SC_R_MATCH_13 167
|
||||
#define IMX_SC_R_MATCH_14 168
|
||||
#define IMX_SC_R_PCIE_B 169
|
||||
#define IMX_SC_R_SATA_0 170
|
||||
#define IMX_SC_R_SERDES_1 171
|
||||
#define IMX_SC_R_HSIO_GPIO 172
|
||||
#define IMX_SC_R_MATCH_15 173
|
||||
#define IMX_SC_R_MATCH_16 174
|
||||
#define IMX_SC_R_MATCH_17 175
|
||||
#define IMX_SC_R_MATCH_18 176
|
||||
#define IMX_SC_R_MATCH_19 177
|
||||
#define IMX_SC_R_MATCH_20 178
|
||||
#define IMX_SC_R_MATCH_21 179
|
||||
#define IMX_SC_R_MATCH_22 180
|
||||
#define IMX_SC_R_MATCH_23 181
|
||||
#define IMX_SC_R_MATCH_24 182
|
||||
#define IMX_SC_R_MATCH_25 183
|
||||
#define IMX_SC_R_MATCH_26 184
|
||||
#define IMX_SC_R_MATCH_27 185
|
||||
#define IMX_SC_R_MATCH_28 186
|
||||
#define IMX_SC_R_LCD_0 187
|
||||
#define IMX_SC_R_LCD_0_PWM_0 188
|
||||
#define IMX_SC_R_LCD_0_I2C_0 189
|
||||
#define IMX_SC_R_LCD_0_I2C_1 190
|
||||
#define IMX_SC_R_PWM_0 191
|
||||
#define IMX_SC_R_PWM_1 192
|
||||
#define IMX_SC_R_PWM_2 193
|
||||
#define IMX_SC_R_PWM_3 194
|
||||
#define IMX_SC_R_PWM_4 195
|
||||
#define IMX_SC_R_PWM_5 196
|
||||
#define IMX_SC_R_PWM_6 197
|
||||
#define IMX_SC_R_PWM_7 198
|
||||
#define IMX_SC_R_GPIO_0 199
|
||||
#define IMX_SC_R_GPIO_1 200
|
||||
#define IMX_SC_R_GPIO_2 201
|
||||
#define IMX_SC_R_GPIO_3 202
|
||||
#define IMX_SC_R_GPIO_4 203
|
||||
#define IMX_SC_R_GPIO_5 204
|
||||
#define IMX_SC_R_GPIO_6 205
|
||||
#define IMX_SC_R_GPIO_7 206
|
||||
#define IMX_SC_R_GPT_0 207
|
||||
#define IMX_SC_R_GPT_1 208
|
||||
#define IMX_SC_R_GPT_2 209
|
||||
#define IMX_SC_R_GPT_3 210
|
||||
#define IMX_SC_R_GPT_4 211
|
||||
#define IMX_SC_R_KPP 212
|
||||
#define IMX_SC_R_MU_0A 213
|
||||
#define IMX_SC_R_MU_1A 214
|
||||
#define IMX_SC_R_MU_2A 215
|
||||
#define IMX_SC_R_MU_3A 216
|
||||
#define IMX_SC_R_MU_4A 217
|
||||
#define IMX_SC_R_MU_5A 218
|
||||
#define IMX_SC_R_MU_6A 219
|
||||
#define IMX_SC_R_MU_7A 220
|
||||
#define IMX_SC_R_MU_8A 221
|
||||
#define IMX_SC_R_MU_9A 222
|
||||
#define IMX_SC_R_MU_10A 223
|
||||
#define IMX_SC_R_MU_11A 224
|
||||
#define IMX_SC_R_MU_12A 225
|
||||
#define IMX_SC_R_MU_13A 226
|
||||
#define IMX_SC_R_MU_5B 227
|
||||
#define IMX_SC_R_MU_6B 228
|
||||
#define IMX_SC_R_MU_7B 229
|
||||
#define IMX_SC_R_MU_8B 230
|
||||
#define IMX_SC_R_MU_9B 231
|
||||
#define IMX_SC_R_MU_10B 232
|
||||
#define IMX_SC_R_MU_11B 233
|
||||
#define IMX_SC_R_MU_12B 234
|
||||
#define IMX_SC_R_MU_13B 235
|
||||
#define IMX_SC_R_ROM_0 236
|
||||
#define IMX_SC_R_FSPI_0 237
|
||||
#define IMX_SC_R_FSPI_1 238
|
||||
#define IMX_SC_R_IEE 239
|
||||
#define IMX_SC_R_IEE_R0 240
|
||||
#define IMX_SC_R_IEE_R1 241
|
||||
#define IMX_SC_R_IEE_R2 242
|
||||
#define IMX_SC_R_IEE_R3 243
|
||||
#define IMX_SC_R_IEE_R4 244
|
||||
#define IMX_SC_R_IEE_R5 245
|
||||
#define IMX_SC_R_IEE_R6 246
|
||||
#define IMX_SC_R_IEE_R7 247
|
||||
#define IMX_SC_R_SDHC_0 248
|
||||
#define IMX_SC_R_SDHC_1 249
|
||||
#define IMX_SC_R_SDHC_2 250
|
||||
#define IMX_SC_R_ENET_0 251
|
||||
#define IMX_SC_R_ENET_1 252
|
||||
#define IMX_SC_R_MLB_0 253
|
||||
#define IMX_SC_R_DMA_2_CH0 254
|
||||
#define IMX_SC_R_DMA_2_CH1 255
|
||||
#define IMX_SC_R_DMA_2_CH2 256
|
||||
#define IMX_SC_R_DMA_2_CH3 257
|
||||
#define IMX_SC_R_DMA_2_CH4 258
|
||||
#define IMX_SC_R_USB_0 259
|
||||
#define IMX_SC_R_USB_1 260
|
||||
#define IMX_SC_R_USB_0_PHY 261
|
||||
#define IMX_SC_R_USB_2 262
|
||||
#define IMX_SC_R_USB_2_PHY 263
|
||||
#define IMX_SC_R_DTCP 264
|
||||
#define IMX_SC_R_NAND 265
|
||||
#define IMX_SC_R_LVDS_0 266
|
||||
#define IMX_SC_R_LVDS_0_PWM_0 267
|
||||
#define IMX_SC_R_LVDS_0_I2C_0 268
|
||||
#define IMX_SC_R_LVDS_0_I2C_1 269
|
||||
#define IMX_SC_R_LVDS_1 270
|
||||
#define IMX_SC_R_LVDS_1_PWM_0 271
|
||||
#define IMX_SC_R_LVDS_1_I2C_0 272
|
||||
#define IMX_SC_R_LVDS_1_I2C_1 273
|
||||
#define IMX_SC_R_LVDS_2 274
|
||||
#define IMX_SC_R_LVDS_2_PWM_0 275
|
||||
#define IMX_SC_R_LVDS_2_I2C_0 276
|
||||
#define IMX_SC_R_LVDS_2_I2C_1 277
|
||||
#define IMX_SC_R_M4_0_PID0 278
|
||||
#define IMX_SC_R_M4_0_PID1 279
|
||||
#define IMX_SC_R_M4_0_PID2 280
|
||||
#define IMX_SC_R_M4_0_PID3 281
|
||||
#define IMX_SC_R_M4_0_PID4 282
|
||||
#define IMX_SC_R_M4_0_RGPIO 283
|
||||
#define IMX_SC_R_M4_0_SEMA42 284
|
||||
#define IMX_SC_R_M4_0_TPM 285
|
||||
#define IMX_SC_R_M4_0_PIT 286
|
||||
#define IMX_SC_R_M4_0_UART 287
|
||||
#define IMX_SC_R_M4_0_I2C 288
|
||||
#define IMX_SC_R_M4_0_INTMUX 289
|
||||
#define IMX_SC_R_M4_0_SIM 290
|
||||
#define IMX_SC_R_M4_0_WDOG 291
|
||||
#define IMX_SC_R_M4_0_MU_0B 292
|
||||
#define IMX_SC_R_M4_0_MU_0A0 293
|
||||
#define IMX_SC_R_M4_0_MU_0A1 294
|
||||
#define IMX_SC_R_M4_0_MU_0A2 295
|
||||
#define IMX_SC_R_M4_0_MU_0A3 296
|
||||
#define IMX_SC_R_M4_0_MU_1A 297
|
||||
#define IMX_SC_R_M4_1_PID0 298
|
||||
#define IMX_SC_R_M4_1_PID1 299
|
||||
#define IMX_SC_R_M4_1_PID2 300
|
||||
#define IMX_SC_R_M4_1_PID3 301
|
||||
#define IMX_SC_R_M4_1_PID4 302
|
||||
#define IMX_SC_R_M4_1_RGPIO 303
|
||||
#define IMX_SC_R_M4_1_SEMA42 304
|
||||
#define IMX_SC_R_M4_1_TPM 305
|
||||
#define IMX_SC_R_M4_1_PIT 306
|
||||
#define IMX_SC_R_M4_1_UART 307
|
||||
#define IMX_SC_R_M4_1_I2C 308
|
||||
#define IMX_SC_R_M4_1_INTMUX 309
|
||||
#define IMX_SC_R_M4_1_SIM 310
|
||||
#define IMX_SC_R_M4_1_WDOG 311
|
||||
#define IMX_SC_R_M4_1_MU_0B 312
|
||||
#define IMX_SC_R_M4_1_MU_0A0 313
|
||||
#define IMX_SC_R_M4_1_MU_0A1 314
|
||||
#define IMX_SC_R_M4_1_MU_0A2 315
|
||||
#define IMX_SC_R_M4_1_MU_0A3 316
|
||||
#define IMX_SC_R_M4_1_MU_1A 317
|
||||
#define IMX_SC_R_SAI_0 318
|
||||
#define IMX_SC_R_SAI_1 319
|
||||
#define IMX_SC_R_SAI_2 320
|
||||
#define IMX_SC_R_IRQSTR_SCU2 321
|
||||
#define IMX_SC_R_IRQSTR_DSP 322
|
||||
#define IMX_SC_R_ELCDIF_PLL 323
|
||||
#define IMX_SC_R_UNUSED6 324
|
||||
#define IMX_SC_R_AUDIO_PLL_0 325
|
||||
#define IMX_SC_R_PI_0 326
|
||||
#define IMX_SC_R_PI_0_PWM_0 327
|
||||
#define IMX_SC_R_PI_0_PWM_1 328
|
||||
#define IMX_SC_R_PI_0_I2C_0 329
|
||||
#define IMX_SC_R_PI_0_PLL 330
|
||||
#define IMX_SC_R_PI_1 331
|
||||
#define IMX_SC_R_PI_1_PWM_0 332
|
||||
#define IMX_SC_R_PI_1_PWM_1 333
|
||||
#define IMX_SC_R_PI_1_I2C_0 334
|
||||
#define IMX_SC_R_PI_1_PLL 335
|
||||
#define IMX_SC_R_SC_PID0 336
|
||||
#define IMX_SC_R_SC_PID1 337
|
||||
#define IMX_SC_R_SC_PID2 338
|
||||
#define IMX_SC_R_SC_PID3 339
|
||||
#define IMX_SC_R_SC_PID4 340
|
||||
#define IMX_SC_R_SC_SEMA42 341
|
||||
#define IMX_SC_R_SC_TPM 342
|
||||
#define IMX_SC_R_SC_PIT 343
|
||||
#define IMX_SC_R_SC_UART 344
|
||||
#define IMX_SC_R_SC_I2C 345
|
||||
#define IMX_SC_R_SC_MU_0B 346
|
||||
#define IMX_SC_R_SC_MU_0A0 347
|
||||
#define IMX_SC_R_SC_MU_0A1 348
|
||||
#define IMX_SC_R_SC_MU_0A2 349
|
||||
#define IMX_SC_R_SC_MU_0A3 350
|
||||
#define IMX_SC_R_SC_MU_1A 351
|
||||
#define IMX_SC_R_SYSCNT_RD 352
|
||||
#define IMX_SC_R_SYSCNT_CMP 353
|
||||
#define IMX_SC_R_DEBUG 354
|
||||
#define IMX_SC_R_SYSTEM 355
|
||||
#define IMX_SC_R_SNVS 356
|
||||
#define IMX_SC_R_OTP 357
|
||||
#define IMX_SC_R_VPU_PID0 358
|
||||
#define IMX_SC_R_VPU_PID1 359
|
||||
#define IMX_SC_R_VPU_PID2 360
|
||||
#define IMX_SC_R_VPU_PID3 361
|
||||
#define IMX_SC_R_VPU_PID4 362
|
||||
#define IMX_SC_R_VPU_PID5 363
|
||||
#define IMX_SC_R_VPU_PID6 364
|
||||
#define IMX_SC_R_VPU_PID7 365
|
||||
#define IMX_SC_R_VPU_UART 366
|
||||
#define IMX_SC_R_VPUCORE 367
|
||||
#define IMX_SC_R_VPUCORE_0 368
|
||||
#define IMX_SC_R_VPUCORE_1 369
|
||||
#define IMX_SC_R_VPUCORE_2 370
|
||||
#define IMX_SC_R_VPUCORE_3 371
|
||||
#define IMX_SC_R_DMA_4_CH0 372
|
||||
#define IMX_SC_R_DMA_4_CH1 373
|
||||
#define IMX_SC_R_DMA_4_CH2 374
|
||||
#define IMX_SC_R_DMA_4_CH3 375
|
||||
#define IMX_SC_R_DMA_4_CH4 376
|
||||
#define IMX_SC_R_ISI_CH0 377
|
||||
#define IMX_SC_R_ISI_CH1 378
|
||||
#define IMX_SC_R_ISI_CH2 379
|
||||
#define IMX_SC_R_ISI_CH3 380
|
||||
#define IMX_SC_R_ISI_CH4 381
|
||||
#define IMX_SC_R_ISI_CH5 382
|
||||
#define IMX_SC_R_ISI_CH6 383
|
||||
#define IMX_SC_R_ISI_CH7 384
|
||||
#define IMX_SC_R_MJPEG_DEC_S0 385
|
||||
#define IMX_SC_R_MJPEG_DEC_S1 386
|
||||
#define IMX_SC_R_MJPEG_DEC_S2 387
|
||||
#define IMX_SC_R_MJPEG_DEC_S3 388
|
||||
#define IMX_SC_R_MJPEG_ENC_S0 389
|
||||
#define IMX_SC_R_MJPEG_ENC_S1 390
|
||||
#define IMX_SC_R_MJPEG_ENC_S2 391
|
||||
#define IMX_SC_R_MJPEG_ENC_S3 392
|
||||
#define IMX_SC_R_MIPI_0 393
|
||||
#define IMX_SC_R_MIPI_0_PWM_0 394
|
||||
#define IMX_SC_R_MIPI_0_I2C_0 395
|
||||
#define IMX_SC_R_MIPI_0_I2C_1 396
|
||||
#define IMX_SC_R_MIPI_1 397
|
||||
#define IMX_SC_R_MIPI_1_PWM_0 398
|
||||
#define IMX_SC_R_MIPI_1_I2C_0 399
|
||||
#define IMX_SC_R_MIPI_1_I2C_1 400
|
||||
#define IMX_SC_R_CSI_0 401
|
||||
#define IMX_SC_R_CSI_0_PWM_0 402
|
||||
#define IMX_SC_R_CSI_0_I2C_0 403
|
||||
#define IMX_SC_R_CSI_1 404
|
||||
#define IMX_SC_R_CSI_1_PWM_0 405
|
||||
#define IMX_SC_R_CSI_1_I2C_0 406
|
||||
#define IMX_SC_R_HDMI 407
|
||||
#define IMX_SC_R_HDMI_I2S 408
|
||||
#define IMX_SC_R_HDMI_I2C_0 409
|
||||
#define IMX_SC_R_HDMI_PLL_0 410
|
||||
#define IMX_SC_R_HDMI_RX 411
|
||||
#define IMX_SC_R_HDMI_RX_BYPASS 412
|
||||
#define IMX_SC_R_HDMI_RX_I2C_0 413
|
||||
#define IMX_SC_R_ASRC_0 414
|
||||
#define IMX_SC_R_ESAI_0 415
|
||||
#define IMX_SC_R_SPDIF_0 416
|
||||
#define IMX_SC_R_SPDIF_1 417
|
||||
#define IMX_SC_R_SAI_3 418
|
||||
#define IMX_SC_R_SAI_4 419
|
||||
#define IMX_SC_R_SAI_5 420
|
||||
#define IMX_SC_R_GPT_5 421
|
||||
#define IMX_SC_R_GPT_6 422
|
||||
#define IMX_SC_R_GPT_7 423
|
||||
#define IMX_SC_R_GPT_8 424
|
||||
#define IMX_SC_R_GPT_9 425
|
||||
#define IMX_SC_R_GPT_10 426
|
||||
#define IMX_SC_R_DMA_2_CH5 427
|
||||
#define IMX_SC_R_DMA_2_CH6 428
|
||||
#define IMX_SC_R_DMA_2_CH7 429
|
||||
#define IMX_SC_R_DMA_2_CH8 430
|
||||
#define IMX_SC_R_DMA_2_CH9 431
|
||||
#define IMX_SC_R_DMA_2_CH10 432
|
||||
#define IMX_SC_R_DMA_2_CH11 433
|
||||
#define IMX_SC_R_DMA_2_CH12 434
|
||||
#define IMX_SC_R_DMA_2_CH13 435
|
||||
#define IMX_SC_R_DMA_2_CH14 436
|
||||
#define IMX_SC_R_DMA_2_CH15 437
|
||||
#define IMX_SC_R_DMA_2_CH16 438
|
||||
#define IMX_SC_R_DMA_2_CH17 439
|
||||
#define IMX_SC_R_DMA_2_CH18 440
|
||||
#define IMX_SC_R_DMA_2_CH19 441
|
||||
#define IMX_SC_R_DMA_2_CH20 442
|
||||
#define IMX_SC_R_DMA_2_CH21 443
|
||||
#define IMX_SC_R_DMA_2_CH22 444
|
||||
#define IMX_SC_R_DMA_2_CH23 445
|
||||
#define IMX_SC_R_DMA_2_CH24 446
|
||||
#define IMX_SC_R_DMA_2_CH25 447
|
||||
#define IMX_SC_R_DMA_2_CH26 448
|
||||
#define IMX_SC_R_DMA_2_CH27 449
|
||||
#define IMX_SC_R_DMA_2_CH28 450
|
||||
#define IMX_SC_R_DMA_2_CH29 451
|
||||
#define IMX_SC_R_DMA_2_CH30 452
|
||||
#define IMX_SC_R_DMA_2_CH31 453
|
||||
#define IMX_SC_R_ASRC_1 454
|
||||
#define IMX_SC_R_ESAI_1 455
|
||||
#define IMX_SC_R_SAI_6 456
|
||||
#define IMX_SC_R_SAI_7 457
|
||||
#define IMX_SC_R_AMIX 458
|
||||
#define IMX_SC_R_MQS_0 459
|
||||
#define IMX_SC_R_DMA_3_CH0 460
|
||||
#define IMX_SC_R_DMA_3_CH1 461
|
||||
#define IMX_SC_R_DMA_3_CH2 462
|
||||
#define IMX_SC_R_DMA_3_CH3 463
|
||||
#define IMX_SC_R_DMA_3_CH4 464
|
||||
#define IMX_SC_R_DMA_3_CH5 465
|
||||
#define IMX_SC_R_DMA_3_CH6 466
|
||||
#define IMX_SC_R_DMA_3_CH7 467
|
||||
#define IMX_SC_R_DMA_3_CH8 468
|
||||
#define IMX_SC_R_DMA_3_CH9 469
|
||||
#define IMX_SC_R_DMA_3_CH10 470
|
||||
#define IMX_SC_R_DMA_3_CH11 471
|
||||
#define IMX_SC_R_DMA_3_CH12 472
|
||||
#define IMX_SC_R_DMA_3_CH13 473
|
||||
#define IMX_SC_R_DMA_3_CH14 474
|
||||
#define IMX_SC_R_DMA_3_CH15 475
|
||||
#define IMX_SC_R_DMA_3_CH16 476
|
||||
#define IMX_SC_R_DMA_3_CH17 477
|
||||
#define IMX_SC_R_DMA_3_CH18 478
|
||||
#define IMX_SC_R_DMA_3_CH19 479
|
||||
#define IMX_SC_R_DMA_3_CH20 480
|
||||
#define IMX_SC_R_DMA_3_CH21 481
|
||||
#define IMX_SC_R_DMA_3_CH22 482
|
||||
#define IMX_SC_R_DMA_3_CH23 483
|
||||
#define IMX_SC_R_DMA_3_CH24 484
|
||||
#define IMX_SC_R_DMA_3_CH25 485
|
||||
#define IMX_SC_R_DMA_3_CH26 486
|
||||
#define IMX_SC_R_DMA_3_CH27 487
|
||||
#define IMX_SC_R_DMA_3_CH28 488
|
||||
#define IMX_SC_R_DMA_3_CH29 489
|
||||
#define IMX_SC_R_DMA_3_CH30 490
|
||||
#define IMX_SC_R_DMA_3_CH31 491
|
||||
#define IMX_SC_R_AUDIO_PLL_1 492
|
||||
#define IMX_SC_R_AUDIO_CLK_0 493
|
||||
#define IMX_SC_R_AUDIO_CLK_1 494
|
||||
#define IMX_SC_R_MCLK_OUT_0 495
|
||||
#define IMX_SC_R_MCLK_OUT_1 496
|
||||
#define IMX_SC_R_PMIC_0 497
|
||||
#define IMX_SC_R_PMIC_1 498
|
||||
#define IMX_SC_R_SECO 499
|
||||
#define IMX_SC_R_CAAM_JR1 500
|
||||
#define IMX_SC_R_CAAM_JR2 501
|
||||
#define IMX_SC_R_CAAM_JR3 502
|
||||
#define IMX_SC_R_SECO_MU_2 503
|
||||
#define IMX_SC_R_SECO_MU_3 504
|
||||
#define IMX_SC_R_SECO_MU_4 505
|
||||
#define IMX_SC_R_HDMI_RX_PWM_0 506
|
||||
#define IMX_SC_R_A35 507
|
||||
#define IMX_SC_R_A35_0 508
|
||||
#define IMX_SC_R_A35_1 509
|
||||
#define IMX_SC_R_A35_2 510
|
||||
#define IMX_SC_R_A35_3 511
|
||||
#define IMX_SC_R_DSP 512
|
||||
#define IMX_SC_R_DSP_RAM 513
|
||||
#define IMX_SC_R_CAAM_JR1_OUT 514
|
||||
#define IMX_SC_R_CAAM_JR2_OUT 515
|
||||
#define IMX_SC_R_CAAM_JR3_OUT 516
|
||||
#define IMX_SC_R_VPU_DEC_0 517
|
||||
#define IMX_SC_R_VPU_ENC_0 518
|
||||
#define IMX_SC_R_CAAM_JR0 519
|
||||
#define IMX_SC_R_CAAM_JR0_OUT 520
|
||||
#define IMX_SC_R_PMIC_2 521
|
||||
#define IMX_SC_R_DBLOGIC 522
|
||||
#define IMX_SC_R_HDMI_PLL_1 523
|
||||
#define IMX_SC_R_BOARD_R0 524
|
||||
#define IMX_SC_R_BOARD_R1 525
|
||||
#define IMX_SC_R_BOARD_R2 526
|
||||
#define IMX_SC_R_BOARD_R3 527
|
||||
#define IMX_SC_R_BOARD_R4 528
|
||||
#define IMX_SC_R_BOARD_R5 529
|
||||
#define IMX_SC_R_BOARD_R6 530
|
||||
#define IMX_SC_R_BOARD_R7 531
|
||||
#define IMX_SC_R_MJPEG_DEC_MP 532
|
||||
#define IMX_SC_R_MJPEG_ENC_MP 533
|
||||
#define IMX_SC_R_VPU_TS_0 534
|
||||
#define IMX_SC_R_VPU_MU_0 535
|
||||
#define IMX_SC_R_VPU_MU_1 536
|
||||
#define IMX_SC_R_VPU_MU_2 537
|
||||
#define IMX_SC_R_VPU_MU_3 538
|
||||
#define IMX_SC_R_VPU_ENC_1 539
|
||||
#define IMX_SC_R_VPU 540
|
||||
#define IMX_SC_R_LAST 541
|
||||
|
||||
#endif /* __DT_BINDINGS_RSCRC_IMX_H */
|
21
include/dt-bindings/power/imx8mq-power.h
Normal file
21
include/dt-bindings/power/imx8mq-power.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
|
||||
/*
|
||||
* Copyright (C) 2018 Pengutronix, Lucas Stach <kernel@pengutronix.de>
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_IMX8MQ_POWER_H__
|
||||
#define __DT_BINDINGS_IMX8MQ_POWER_H__
|
||||
|
||||
#define IMX8M_POWER_DOMAIN_MIPI 0
|
||||
#define IMX8M_POWER_DOMAIN_PCIE1 1
|
||||
#define IMX8M_POWER_DOMAIN_USB_OTG1 2
|
||||
#define IMX8M_POWER_DOMAIN_USB_OTG2 3
|
||||
#define IMX8M_POWER_DOMAIN_DDR1 4
|
||||
#define IMX8M_POWER_DOMAIN_GPU 5
|
||||
#define IMX8M_POWER_DOMAIN_VPU 6
|
||||
#define IMX8M_POWER_DOMAIN_DISP 7
|
||||
#define IMX8M_POWER_DOMAIN_MIPI_CSI1 8
|
||||
#define IMX8M_POWER_DOMAIN_MIPI_CSI2 9
|
||||
#define IMX8M_POWER_DOMAIN_PCIE2 10
|
||||
|
||||
#endif
|
@ -16,13 +16,12 @@
|
||||
|
||||
#define R8A77970_PD_CA53_CPU0 5
|
||||
#define R8A77970_PD_CA53_CPU1 6
|
||||
#define R8A77970_PD_CR7 13
|
||||
#define R8A77970_PD_CA53_SCU 21
|
||||
#define R8A77970_PD_A2IR0 23
|
||||
#define R8A77970_PD_A3IR 24
|
||||
#define R8A77970_PD_A3IR 24
|
||||
#define R8A77970_PD_A2IR1 27
|
||||
#define R8A77970_PD_A2IR2 28
|
||||
#define R8A77970_PD_A2IR3 29
|
||||
#define R8A77970_PD_A2DP 28
|
||||
#define R8A77970_PD_A2CN 29
|
||||
#define R8A77970_PD_A2SC0 30
|
||||
#define R8A77970_PD_A2SC1 31
|
||||
|
||||
|
@ -15,14 +15,14 @@
|
||||
#define R8A77980_PD_A2SC2 0
|
||||
#define R8A77980_PD_A2SC3 1
|
||||
#define R8A77980_PD_A2SC4 2
|
||||
#define R8A77980_PD_A2PD0 3
|
||||
#define R8A77980_PD_A2PD1 4
|
||||
#define R8A77980_PD_A2DP0 3
|
||||
#define R8A77980_PD_A2DP1 4
|
||||
#define R8A77980_PD_CA53_CPU0 5
|
||||
#define R8A77980_PD_CA53_CPU1 6
|
||||
#define R8A77980_PD_CA53_CPU2 7
|
||||
#define R8A77980_PD_CA53_CPU3 8
|
||||
#define R8A77980_PD_A2CN 10
|
||||
#define R8A77980_PD_A3VIP 11
|
||||
#define R8A77980_PD_A3VIP0 11
|
||||
#define R8A77980_PD_A2IR5 12
|
||||
#define R8A77980_PD_CR7 13
|
||||
#define R8A77980_PD_A2IR4 15
|
||||
|
@ -1,9 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright © 2015 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H
|
||||
|
22
include/dt-bindings/power/rk3066-power.h
Normal file
22
include/dt-bindings/power/rk3066-power.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_BINDINGS_POWER_RK3066_POWER_H__
|
||||
#define __DT_BINDINGS_POWER_RK3066_POWER_H__
|
||||
|
||||
/* VD_CORE */
|
||||
#define RK3066_PD_A9_0 0
|
||||
#define RK3066_PD_A9_1 1
|
||||
#define RK3066_PD_DBG 4
|
||||
#define RK3066_PD_SCU 5
|
||||
|
||||
/* VD_LOGIC */
|
||||
#define RK3066_PD_VIDEO 6
|
||||
#define RK3066_PD_VIO 7
|
||||
#define RK3066_PD_GPU 8
|
||||
#define RK3066_PD_PERI 9
|
||||
#define RK3066_PD_CPU 10
|
||||
#define RK3066_PD_ALIVE 11
|
||||
|
||||
/* VD_PMU */
|
||||
#define RK3066_PD_RTC 12
|
||||
|
||||
#endif
|
24
include/dt-bindings/power/rk3188-power.h
Normal file
24
include/dt-bindings/power/rk3188-power.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_BINDINGS_POWER_RK3188_POWER_H__
|
||||
#define __DT_BINDINGS_POWER_RK3188_POWER_H__
|
||||
|
||||
/* VD_CORE */
|
||||
#define RK3188_PD_A9_0 0
|
||||
#define RK3188_PD_A9_1 1
|
||||
#define RK3188_PD_A9_2 2
|
||||
#define RK3188_PD_A9_3 3
|
||||
#define RK3188_PD_DBG 4
|
||||
#define RK3188_PD_SCU 5
|
||||
|
||||
/* VD_LOGIC */
|
||||
#define RK3188_PD_VIDEO 6
|
||||
#define RK3188_PD_VIO 7
|
||||
#define RK3188_PD_GPU 8
|
||||
#define RK3188_PD_PERI 9
|
||||
#define RK3188_PD_CPU 10
|
||||
#define RK3188_PD_ALIVE 11
|
||||
|
||||
/* VD_PMU */
|
||||
#define RK3188_PD_RTC 12
|
||||
|
||||
#endif
|
@ -23,15 +23,4 @@ struct pxad_param {
|
||||
enum pxad_chan_prio prio;
|
||||
};
|
||||
|
||||
struct dma_chan;
|
||||
|
||||
#ifdef CONFIG_PXA_DMA
|
||||
bool pxad_filter_fn(struct dma_chan *chan, void *param);
|
||||
#else
|
||||
static inline bool pxad_filter_fn(struct dma_chan *chan, void *param)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PXA_DMA_H_ */
|
||||
|
@ -14,4 +14,5 @@
|
||||
#include <linux/firmware/imx/types.h>
|
||||
|
||||
#include <linux/firmware/imx/svc/misc.h>
|
||||
#include <linux/firmware/imx/svc/pm.h>
|
||||
#endif /* _SC_SCI_H */
|
||||
|
85
include/linux/firmware/imx/svc/pm.h
Normal file
85
include/linux/firmware/imx/svc/pm.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2017-2018 NXP
|
||||
*
|
||||
* Header file containing the public API for the System Controller (SC)
|
||||
* Power Management (PM) function. This includes functions for power state
|
||||
* control, clock control, reset control, and wake-up event control.
|
||||
*
|
||||
* PM_SVC (SVC) Power Management Service
|
||||
*
|
||||
* Module for the Power Management (PM) service.
|
||||
*/
|
||||
|
||||
#ifndef _SC_PM_API_H
|
||||
#define _SC_PM_API_H
|
||||
|
||||
#include <linux/firmware/imx/sci.h>
|
||||
|
||||
/*
|
||||
* This type is used to indicate RPC PM function calls.
|
||||
*/
|
||||
enum imx_sc_pm_func {
|
||||
IMX_SC_PM_FUNC_UNKNOWN = 0,
|
||||
IMX_SC_PM_FUNC_SET_SYS_POWER_MODE = 19,
|
||||
IMX_SC_PM_FUNC_SET_PARTITION_POWER_MODE = 1,
|
||||
IMX_SC_PM_FUNC_GET_SYS_POWER_MODE = 2,
|
||||
IMX_SC_PM_FUNC_SET_RESOURCE_POWER_MODE = 3,
|
||||
IMX_SC_PM_FUNC_GET_RESOURCE_POWER_MODE = 4,
|
||||
IMX_SC_PM_FUNC_REQ_LOW_POWER_MODE = 16,
|
||||
IMX_SC_PM_FUNC_SET_CPU_RESUME_ADDR = 17,
|
||||
IMX_SC_PM_FUNC_REQ_SYS_IF_POWER_MODE = 18,
|
||||
IMX_SC_PM_FUNC_SET_CLOCK_RATE = 5,
|
||||
IMX_SC_PM_FUNC_GET_CLOCK_RATE = 6,
|
||||
IMX_SC_PM_FUNC_CLOCK_ENABLE = 7,
|
||||
IMX_SC_PM_FUNC_SET_CLOCK_PARENT = 14,
|
||||
IMX_SC_PM_FUNC_GET_CLOCK_PARENT = 15,
|
||||
IMX_SC_PM_FUNC_RESET = 13,
|
||||
IMX_SC_PM_FUNC_RESET_REASON = 10,
|
||||
IMX_SC_PM_FUNC_BOOT = 8,
|
||||
IMX_SC_PM_FUNC_REBOOT = 9,
|
||||
IMX_SC_PM_FUNC_REBOOT_PARTITION = 12,
|
||||
IMX_SC_PM_FUNC_CPU_START = 11,
|
||||
};
|
||||
|
||||
/*
|
||||
* Defines for ALL parameters
|
||||
*/
|
||||
#define IMX_SC_PM_CLK_ALL UINT8_MAX /* All clocks */
|
||||
|
||||
/*
|
||||
* Defines for SC PM Power Mode
|
||||
*/
|
||||
#define IMX_SC_PM_PW_MODE_OFF 0 /* Power off */
|
||||
#define IMX_SC_PM_PW_MODE_STBY 1 /* Power in standby */
|
||||
#define IMX_SC_PM_PW_MODE_LP 2 /* Power in low-power */
|
||||
#define IMX_SC_PM_PW_MODE_ON 3 /* Power on */
|
||||
|
||||
/*
|
||||
* Defines for SC PM CLK
|
||||
*/
|
||||
#define IMX_SC_PM_CLK_SLV_BUS 0 /* Slave bus clock */
|
||||
#define IMX_SC_PM_CLK_MST_BUS 1 /* Master bus clock */
|
||||
#define IMX_SC_PM_CLK_PER 2 /* Peripheral clock */
|
||||
#define IMX_SC_PM_CLK_PHY 3 /* Phy clock */
|
||||
#define IMX_SC_PM_CLK_MISC 4 /* Misc clock */
|
||||
#define IMX_SC_PM_CLK_MISC0 0 /* Misc 0 clock */
|
||||
#define IMX_SC_PM_CLK_MISC1 1 /* Misc 1 clock */
|
||||
#define IMX_SC_PM_CLK_MISC2 2 /* Misc 2 clock */
|
||||
#define IMX_SC_PM_CLK_MISC3 3 /* Misc 3 clock */
|
||||
#define IMX_SC_PM_CLK_MISC4 4 /* Misc 4 clock */
|
||||
#define IMX_SC_PM_CLK_CPU 2 /* CPU clock */
|
||||
#define IMX_SC_PM_CLK_PLL 4 /* PLL */
|
||||
#define IMX_SC_PM_CLK_BYPASS 4 /* Bypass clock */
|
||||
|
||||
/*
|
||||
* Defines for SC PM CLK Parent
|
||||
*/
|
||||
#define IMX_SC_PM_PARENT_XTAL 0 /* Parent is XTAL. */
|
||||
#define IMX_SC_PM_PARENT_PLL0 1 /* Parent is PLL0 */
|
||||
#define IMX_SC_PM_PARENT_PLL1 2 /* Parent is PLL1 or PLL0/2 */
|
||||
#define IMX_SC_PM_PARENT_PLL2 3 /* Parent in PLL2 or PLL0/4 */
|
||||
#define IMX_SC_PM_PARENT_BYPS 4 /* Parent is a bypass clock. */
|
||||
|
||||
#endif /* _SC_PM_API_H */
|
@ -9,558 +9,6 @@
|
||||
#ifndef _SC_TYPES_H
|
||||
#define _SC_TYPES_H
|
||||
|
||||
/*
|
||||
* This type is used to indicate a resource. Resources include peripherals
|
||||
* and bus masters (but not memory regions). Note items from list should
|
||||
* never be changed or removed (only added to at the end of the list).
|
||||
*/
|
||||
enum imx_sc_rsrc {
|
||||
IMX_SC_R_A53 = 0,
|
||||
IMX_SC_R_A53_0 = 1,
|
||||
IMX_SC_R_A53_1 = 2,
|
||||
IMX_SC_R_A53_2 = 3,
|
||||
IMX_SC_R_A53_3 = 4,
|
||||
IMX_SC_R_A72 = 5,
|
||||
IMX_SC_R_A72_0 = 6,
|
||||
IMX_SC_R_A72_1 = 7,
|
||||
IMX_SC_R_A72_2 = 8,
|
||||
IMX_SC_R_A72_3 = 9,
|
||||
IMX_SC_R_CCI = 10,
|
||||
IMX_SC_R_DB = 11,
|
||||
IMX_SC_R_DRC_0 = 12,
|
||||
IMX_SC_R_DRC_1 = 13,
|
||||
IMX_SC_R_GIC_SMMU = 14,
|
||||
IMX_SC_R_IRQSTR_M4_0 = 15,
|
||||
IMX_SC_R_IRQSTR_M4_1 = 16,
|
||||
IMX_SC_R_SMMU = 17,
|
||||
IMX_SC_R_GIC = 18,
|
||||
IMX_SC_R_DC_0_BLIT0 = 19,
|
||||
IMX_SC_R_DC_0_BLIT1 = 20,
|
||||
IMX_SC_R_DC_0_BLIT2 = 21,
|
||||
IMX_SC_R_DC_0_BLIT_OUT = 22,
|
||||
IMX_SC_R_DC_0_CAPTURE0 = 23,
|
||||
IMX_SC_R_DC_0_CAPTURE1 = 24,
|
||||
IMX_SC_R_DC_0_WARP = 25,
|
||||
IMX_SC_R_DC_0_INTEGRAL0 = 26,
|
||||
IMX_SC_R_DC_0_INTEGRAL1 = 27,
|
||||
IMX_SC_R_DC_0_VIDEO0 = 28,
|
||||
IMX_SC_R_DC_0_VIDEO1 = 29,
|
||||
IMX_SC_R_DC_0_FRAC0 = 30,
|
||||
IMX_SC_R_DC_0_FRAC1 = 31,
|
||||
IMX_SC_R_DC_0 = 32,
|
||||
IMX_SC_R_GPU_2_PID0 = 33,
|
||||
IMX_SC_R_DC_0_PLL_0 = 34,
|
||||
IMX_SC_R_DC_0_PLL_1 = 35,
|
||||
IMX_SC_R_DC_1_BLIT0 = 36,
|
||||
IMX_SC_R_DC_1_BLIT1 = 37,
|
||||
IMX_SC_R_DC_1_BLIT2 = 38,
|
||||
IMX_SC_R_DC_1_BLIT_OUT = 39,
|
||||
IMX_SC_R_DC_1_CAPTURE0 = 40,
|
||||
IMX_SC_R_DC_1_CAPTURE1 = 41,
|
||||
IMX_SC_R_DC_1_WARP = 42,
|
||||
IMX_SC_R_DC_1_INTEGRAL0 = 43,
|
||||
IMX_SC_R_DC_1_INTEGRAL1 = 44,
|
||||
IMX_SC_R_DC_1_VIDEO0 = 45,
|
||||
IMX_SC_R_DC_1_VIDEO1 = 46,
|
||||
IMX_SC_R_DC_1_FRAC0 = 47,
|
||||
IMX_SC_R_DC_1_FRAC1 = 48,
|
||||
IMX_SC_R_DC_1 = 49,
|
||||
IMX_SC_R_GPU_3_PID0 = 50,
|
||||
IMX_SC_R_DC_1_PLL_0 = 51,
|
||||
IMX_SC_R_DC_1_PLL_1 = 52,
|
||||
IMX_SC_R_SPI_0 = 53,
|
||||
IMX_SC_R_SPI_1 = 54,
|
||||
IMX_SC_R_SPI_2 = 55,
|
||||
IMX_SC_R_SPI_3 = 56,
|
||||
IMX_SC_R_UART_0 = 57,
|
||||
IMX_SC_R_UART_1 = 58,
|
||||
IMX_SC_R_UART_2 = 59,
|
||||
IMX_SC_R_UART_3 = 60,
|
||||
IMX_SC_R_UART_4 = 61,
|
||||
IMX_SC_R_EMVSIM_0 = 62,
|
||||
IMX_SC_R_EMVSIM_1 = 63,
|
||||
IMX_SC_R_DMA_0_CH0 = 64,
|
||||
IMX_SC_R_DMA_0_CH1 = 65,
|
||||
IMX_SC_R_DMA_0_CH2 = 66,
|
||||
IMX_SC_R_DMA_0_CH3 = 67,
|
||||
IMX_SC_R_DMA_0_CH4 = 68,
|
||||
IMX_SC_R_DMA_0_CH5 = 69,
|
||||
IMX_SC_R_DMA_0_CH6 = 70,
|
||||
IMX_SC_R_DMA_0_CH7 = 71,
|
||||
IMX_SC_R_DMA_0_CH8 = 72,
|
||||
IMX_SC_R_DMA_0_CH9 = 73,
|
||||
IMX_SC_R_DMA_0_CH10 = 74,
|
||||
IMX_SC_R_DMA_0_CH11 = 75,
|
||||
IMX_SC_R_DMA_0_CH12 = 76,
|
||||
IMX_SC_R_DMA_0_CH13 = 77,
|
||||
IMX_SC_R_DMA_0_CH14 = 78,
|
||||
IMX_SC_R_DMA_0_CH15 = 79,
|
||||
IMX_SC_R_DMA_0_CH16 = 80,
|
||||
IMX_SC_R_DMA_0_CH17 = 81,
|
||||
IMX_SC_R_DMA_0_CH18 = 82,
|
||||
IMX_SC_R_DMA_0_CH19 = 83,
|
||||
IMX_SC_R_DMA_0_CH20 = 84,
|
||||
IMX_SC_R_DMA_0_CH21 = 85,
|
||||
IMX_SC_R_DMA_0_CH22 = 86,
|
||||
IMX_SC_R_DMA_0_CH23 = 87,
|
||||
IMX_SC_R_DMA_0_CH24 = 88,
|
||||
IMX_SC_R_DMA_0_CH25 = 89,
|
||||
IMX_SC_R_DMA_0_CH26 = 90,
|
||||
IMX_SC_R_DMA_0_CH27 = 91,
|
||||
IMX_SC_R_DMA_0_CH28 = 92,
|
||||
IMX_SC_R_DMA_0_CH29 = 93,
|
||||
IMX_SC_R_DMA_0_CH30 = 94,
|
||||
IMX_SC_R_DMA_0_CH31 = 95,
|
||||
IMX_SC_R_I2C_0 = 96,
|
||||
IMX_SC_R_I2C_1 = 97,
|
||||
IMX_SC_R_I2C_2 = 98,
|
||||
IMX_SC_R_I2C_3 = 99,
|
||||
IMX_SC_R_I2C_4 = 100,
|
||||
IMX_SC_R_ADC_0 = 101,
|
||||
IMX_SC_R_ADC_1 = 102,
|
||||
IMX_SC_R_FTM_0 = 103,
|
||||
IMX_SC_R_FTM_1 = 104,
|
||||
IMX_SC_R_CAN_0 = 105,
|
||||
IMX_SC_R_CAN_1 = 106,
|
||||
IMX_SC_R_CAN_2 = 107,
|
||||
IMX_SC_R_DMA_1_CH0 = 108,
|
||||
IMX_SC_R_DMA_1_CH1 = 109,
|
||||
IMX_SC_R_DMA_1_CH2 = 110,
|
||||
IMX_SC_R_DMA_1_CH3 = 111,
|
||||
IMX_SC_R_DMA_1_CH4 = 112,
|
||||
IMX_SC_R_DMA_1_CH5 = 113,
|
||||
IMX_SC_R_DMA_1_CH6 = 114,
|
||||
IMX_SC_R_DMA_1_CH7 = 115,
|
||||
IMX_SC_R_DMA_1_CH8 = 116,
|
||||
IMX_SC_R_DMA_1_CH9 = 117,
|
||||
IMX_SC_R_DMA_1_CH10 = 118,
|
||||
IMX_SC_R_DMA_1_CH11 = 119,
|
||||
IMX_SC_R_DMA_1_CH12 = 120,
|
||||
IMX_SC_R_DMA_1_CH13 = 121,
|
||||
IMX_SC_R_DMA_1_CH14 = 122,
|
||||
IMX_SC_R_DMA_1_CH15 = 123,
|
||||
IMX_SC_R_DMA_1_CH16 = 124,
|
||||
IMX_SC_R_DMA_1_CH17 = 125,
|
||||
IMX_SC_R_DMA_1_CH18 = 126,
|
||||
IMX_SC_R_DMA_1_CH19 = 127,
|
||||
IMX_SC_R_DMA_1_CH20 = 128,
|
||||
IMX_SC_R_DMA_1_CH21 = 129,
|
||||
IMX_SC_R_DMA_1_CH22 = 130,
|
||||
IMX_SC_R_DMA_1_CH23 = 131,
|
||||
IMX_SC_R_DMA_1_CH24 = 132,
|
||||
IMX_SC_R_DMA_1_CH25 = 133,
|
||||
IMX_SC_R_DMA_1_CH26 = 134,
|
||||
IMX_SC_R_DMA_1_CH27 = 135,
|
||||
IMX_SC_R_DMA_1_CH28 = 136,
|
||||
IMX_SC_R_DMA_1_CH29 = 137,
|
||||
IMX_SC_R_DMA_1_CH30 = 138,
|
||||
IMX_SC_R_DMA_1_CH31 = 139,
|
||||
IMX_SC_R_UNUSED1 = 140,
|
||||
IMX_SC_R_UNUSED2 = 141,
|
||||
IMX_SC_R_UNUSED3 = 142,
|
||||
IMX_SC_R_UNUSED4 = 143,
|
||||
IMX_SC_R_GPU_0_PID0 = 144,
|
||||
IMX_SC_R_GPU_0_PID1 = 145,
|
||||
IMX_SC_R_GPU_0_PID2 = 146,
|
||||
IMX_SC_R_GPU_0_PID3 = 147,
|
||||
IMX_SC_R_GPU_1_PID0 = 148,
|
||||
IMX_SC_R_GPU_1_PID1 = 149,
|
||||
IMX_SC_R_GPU_1_PID2 = 150,
|
||||
IMX_SC_R_GPU_1_PID3 = 151,
|
||||
IMX_SC_R_PCIE_A = 152,
|
||||
IMX_SC_R_SERDES_0 = 153,
|
||||
IMX_SC_R_MATCH_0 = 154,
|
||||
IMX_SC_R_MATCH_1 = 155,
|
||||
IMX_SC_R_MATCH_2 = 156,
|
||||
IMX_SC_R_MATCH_3 = 157,
|
||||
IMX_SC_R_MATCH_4 = 158,
|
||||
IMX_SC_R_MATCH_5 = 159,
|
||||
IMX_SC_R_MATCH_6 = 160,
|
||||
IMX_SC_R_MATCH_7 = 161,
|
||||
IMX_SC_R_MATCH_8 = 162,
|
||||
IMX_SC_R_MATCH_9 = 163,
|
||||
IMX_SC_R_MATCH_10 = 164,
|
||||
IMX_SC_R_MATCH_11 = 165,
|
||||
IMX_SC_R_MATCH_12 = 166,
|
||||
IMX_SC_R_MATCH_13 = 167,
|
||||
IMX_SC_R_MATCH_14 = 168,
|
||||
IMX_SC_R_PCIE_B = 169,
|
||||
IMX_SC_R_SATA_0 = 170,
|
||||
IMX_SC_R_SERDES_1 = 171,
|
||||
IMX_SC_R_HSIO_GPIO = 172,
|
||||
IMX_SC_R_MATCH_15 = 173,
|
||||
IMX_SC_R_MATCH_16 = 174,
|
||||
IMX_SC_R_MATCH_17 = 175,
|
||||
IMX_SC_R_MATCH_18 = 176,
|
||||
IMX_SC_R_MATCH_19 = 177,
|
||||
IMX_SC_R_MATCH_20 = 178,
|
||||
IMX_SC_R_MATCH_21 = 179,
|
||||
IMX_SC_R_MATCH_22 = 180,
|
||||
IMX_SC_R_MATCH_23 = 181,
|
||||
IMX_SC_R_MATCH_24 = 182,
|
||||
IMX_SC_R_MATCH_25 = 183,
|
||||
IMX_SC_R_MATCH_26 = 184,
|
||||
IMX_SC_R_MATCH_27 = 185,
|
||||
IMX_SC_R_MATCH_28 = 186,
|
||||
IMX_SC_R_LCD_0 = 187,
|
||||
IMX_SC_R_LCD_0_PWM_0 = 188,
|
||||
IMX_SC_R_LCD_0_I2C_0 = 189,
|
||||
IMX_SC_R_LCD_0_I2C_1 = 190,
|
||||
IMX_SC_R_PWM_0 = 191,
|
||||
IMX_SC_R_PWM_1 = 192,
|
||||
IMX_SC_R_PWM_2 = 193,
|
||||
IMX_SC_R_PWM_3 = 194,
|
||||
IMX_SC_R_PWM_4 = 195,
|
||||
IMX_SC_R_PWM_5 = 196,
|
||||
IMX_SC_R_PWM_6 = 197,
|
||||
IMX_SC_R_PWM_7 = 198,
|
||||
IMX_SC_R_GPIO_0 = 199,
|
||||
IMX_SC_R_GPIO_1 = 200,
|
||||
IMX_SC_R_GPIO_2 = 201,
|
||||
IMX_SC_R_GPIO_3 = 202,
|
||||
IMX_SC_R_GPIO_4 = 203,
|
||||
IMX_SC_R_GPIO_5 = 204,
|
||||
IMX_SC_R_GPIO_6 = 205,
|
||||
IMX_SC_R_GPIO_7 = 206,
|
||||
IMX_SC_R_GPT_0 = 207,
|
||||
IMX_SC_R_GPT_1 = 208,
|
||||
IMX_SC_R_GPT_2 = 209,
|
||||
IMX_SC_R_GPT_3 = 210,
|
||||
IMX_SC_R_GPT_4 = 211,
|
||||
IMX_SC_R_KPP = 212,
|
||||
IMX_SC_R_MU_0A = 213,
|
||||
IMX_SC_R_MU_1A = 214,
|
||||
IMX_SC_R_MU_2A = 215,
|
||||
IMX_SC_R_MU_3A = 216,
|
||||
IMX_SC_R_MU_4A = 217,
|
||||
IMX_SC_R_MU_5A = 218,
|
||||
IMX_SC_R_MU_6A = 219,
|
||||
IMX_SC_R_MU_7A = 220,
|
||||
IMX_SC_R_MU_8A = 221,
|
||||
IMX_SC_R_MU_9A = 222,
|
||||
IMX_SC_R_MU_10A = 223,
|
||||
IMX_SC_R_MU_11A = 224,
|
||||
IMX_SC_R_MU_12A = 225,
|
||||
IMX_SC_R_MU_13A = 226,
|
||||
IMX_SC_R_MU_5B = 227,
|
||||
IMX_SC_R_MU_6B = 228,
|
||||
IMX_SC_R_MU_7B = 229,
|
||||
IMX_SC_R_MU_8B = 230,
|
||||
IMX_SC_R_MU_9B = 231,
|
||||
IMX_SC_R_MU_10B = 232,
|
||||
IMX_SC_R_MU_11B = 233,
|
||||
IMX_SC_R_MU_12B = 234,
|
||||
IMX_SC_R_MU_13B = 235,
|
||||
IMX_SC_R_ROM_0 = 236,
|
||||
IMX_SC_R_FSPI_0 = 237,
|
||||
IMX_SC_R_FSPI_1 = 238,
|
||||
IMX_SC_R_IEE = 239,
|
||||
IMX_SC_R_IEE_R0 = 240,
|
||||
IMX_SC_R_IEE_R1 = 241,
|
||||
IMX_SC_R_IEE_R2 = 242,
|
||||
IMX_SC_R_IEE_R3 = 243,
|
||||
IMX_SC_R_IEE_R4 = 244,
|
||||
IMX_SC_R_IEE_R5 = 245,
|
||||
IMX_SC_R_IEE_R6 = 246,
|
||||
IMX_SC_R_IEE_R7 = 247,
|
||||
IMX_SC_R_SDHC_0 = 248,
|
||||
IMX_SC_R_SDHC_1 = 249,
|
||||
IMX_SC_R_SDHC_2 = 250,
|
||||
IMX_SC_R_ENET_0 = 251,
|
||||
IMX_SC_R_ENET_1 = 252,
|
||||
IMX_SC_R_MLB_0 = 253,
|
||||
IMX_SC_R_DMA_2_CH0 = 254,
|
||||
IMX_SC_R_DMA_2_CH1 = 255,
|
||||
IMX_SC_R_DMA_2_CH2 = 256,
|
||||
IMX_SC_R_DMA_2_CH3 = 257,
|
||||
IMX_SC_R_DMA_2_CH4 = 258,
|
||||
IMX_SC_R_USB_0 = 259,
|
||||
IMX_SC_R_USB_1 = 260,
|
||||
IMX_SC_R_USB_0_PHY = 261,
|
||||
IMX_SC_R_USB_2 = 262,
|
||||
IMX_SC_R_USB_2_PHY = 263,
|
||||
IMX_SC_R_DTCP = 264,
|
||||
IMX_SC_R_NAND = 265,
|
||||
IMX_SC_R_LVDS_0 = 266,
|
||||
IMX_SC_R_LVDS_0_PWM_0 = 267,
|
||||
IMX_SC_R_LVDS_0_I2C_0 = 268,
|
||||
IMX_SC_R_LVDS_0_I2C_1 = 269,
|
||||
IMX_SC_R_LVDS_1 = 270,
|
||||
IMX_SC_R_LVDS_1_PWM_0 = 271,
|
||||
IMX_SC_R_LVDS_1_I2C_0 = 272,
|
||||
IMX_SC_R_LVDS_1_I2C_1 = 273,
|
||||
IMX_SC_R_LVDS_2 = 274,
|
||||
IMX_SC_R_LVDS_2_PWM_0 = 275,
|
||||
IMX_SC_R_LVDS_2_I2C_0 = 276,
|
||||
IMX_SC_R_LVDS_2_I2C_1 = 277,
|
||||
IMX_SC_R_M4_0_PID0 = 278,
|
||||
IMX_SC_R_M4_0_PID1 = 279,
|
||||
IMX_SC_R_M4_0_PID2 = 280,
|
||||
IMX_SC_R_M4_0_PID3 = 281,
|
||||
IMX_SC_R_M4_0_PID4 = 282,
|
||||
IMX_SC_R_M4_0_RGPIO = 283,
|
||||
IMX_SC_R_M4_0_SEMA42 = 284,
|
||||
IMX_SC_R_M4_0_TPM = 285,
|
||||
IMX_SC_R_M4_0_PIT = 286,
|
||||
IMX_SC_R_M4_0_UART = 287,
|
||||
IMX_SC_R_M4_0_I2C = 288,
|
||||
IMX_SC_R_M4_0_INTMUX = 289,
|
||||
IMX_SC_R_M4_0_SIM = 290,
|
||||
IMX_SC_R_M4_0_WDOG = 291,
|
||||
IMX_SC_R_M4_0_MU_0B = 292,
|
||||
IMX_SC_R_M4_0_MU_0A0 = 293,
|
||||
IMX_SC_R_M4_0_MU_0A1 = 294,
|
||||
IMX_SC_R_M4_0_MU_0A2 = 295,
|
||||
IMX_SC_R_M4_0_MU_0A3 = 296,
|
||||
IMX_SC_R_M4_0_MU_1A = 297,
|
||||
IMX_SC_R_M4_1_PID0 = 298,
|
||||
IMX_SC_R_M4_1_PID1 = 299,
|
||||
IMX_SC_R_M4_1_PID2 = 300,
|
||||
IMX_SC_R_M4_1_PID3 = 301,
|
||||
IMX_SC_R_M4_1_PID4 = 302,
|
||||
IMX_SC_R_M4_1_RGPIO = 303,
|
||||
IMX_SC_R_M4_1_SEMA42 = 304,
|
||||
IMX_SC_R_M4_1_TPM = 305,
|
||||
IMX_SC_R_M4_1_PIT = 306,
|
||||
IMX_SC_R_M4_1_UART = 307,
|
||||
IMX_SC_R_M4_1_I2C = 308,
|
||||
IMX_SC_R_M4_1_INTMUX = 309,
|
||||
IMX_SC_R_M4_1_SIM = 310,
|
||||
IMX_SC_R_M4_1_WDOG = 311,
|
||||
IMX_SC_R_M4_1_MU_0B = 312,
|
||||
IMX_SC_R_M4_1_MU_0A0 = 313,
|
||||
IMX_SC_R_M4_1_MU_0A1 = 314,
|
||||
IMX_SC_R_M4_1_MU_0A2 = 315,
|
||||
IMX_SC_R_M4_1_MU_0A3 = 316,
|
||||
IMX_SC_R_M4_1_MU_1A = 317,
|
||||
IMX_SC_R_SAI_0 = 318,
|
||||
IMX_SC_R_SAI_1 = 319,
|
||||
IMX_SC_R_SAI_2 = 320,
|
||||
IMX_SC_R_IRQSTR_SCU2 = 321,
|
||||
IMX_SC_R_IRQSTR_DSP = 322,
|
||||
IMX_SC_R_UNUSED5 = 323,
|
||||
IMX_SC_R_UNUSED6 = 324,
|
||||
IMX_SC_R_AUDIO_PLL_0 = 325,
|
||||
IMX_SC_R_PI_0 = 326,
|
||||
IMX_SC_R_PI_0_PWM_0 = 327,
|
||||
IMX_SC_R_PI_0_PWM_1 = 328,
|
||||
IMX_SC_R_PI_0_I2C_0 = 329,
|
||||
IMX_SC_R_PI_0_PLL = 330,
|
||||
IMX_SC_R_PI_1 = 331,
|
||||
IMX_SC_R_PI_1_PWM_0 = 332,
|
||||
IMX_SC_R_PI_1_PWM_1 = 333,
|
||||
IMX_SC_R_PI_1_I2C_0 = 334,
|
||||
IMX_SC_R_PI_1_PLL = 335,
|
||||
IMX_SC_R_SC_PID0 = 336,
|
||||
IMX_SC_R_SC_PID1 = 337,
|
||||
IMX_SC_R_SC_PID2 = 338,
|
||||
IMX_SC_R_SC_PID3 = 339,
|
||||
IMX_SC_R_SC_PID4 = 340,
|
||||
IMX_SC_R_SC_SEMA42 = 341,
|
||||
IMX_SC_R_SC_TPM = 342,
|
||||
IMX_SC_R_SC_PIT = 343,
|
||||
IMX_SC_R_SC_UART = 344,
|
||||
IMX_SC_R_SC_I2C = 345,
|
||||
IMX_SC_R_SC_MU_0B = 346,
|
||||
IMX_SC_R_SC_MU_0A0 = 347,
|
||||
IMX_SC_R_SC_MU_0A1 = 348,
|
||||
IMX_SC_R_SC_MU_0A2 = 349,
|
||||
IMX_SC_R_SC_MU_0A3 = 350,
|
||||
IMX_SC_R_SC_MU_1A = 351,
|
||||
IMX_SC_R_SYSCNT_RD = 352,
|
||||
IMX_SC_R_SYSCNT_CMP = 353,
|
||||
IMX_SC_R_DEBUG = 354,
|
||||
IMX_SC_R_SYSTEM = 355,
|
||||
IMX_SC_R_SNVS = 356,
|
||||
IMX_SC_R_OTP = 357,
|
||||
IMX_SC_R_VPU_PID0 = 358,
|
||||
IMX_SC_R_VPU_PID1 = 359,
|
||||
IMX_SC_R_VPU_PID2 = 360,
|
||||
IMX_SC_R_VPU_PID3 = 361,
|
||||
IMX_SC_R_VPU_PID4 = 362,
|
||||
IMX_SC_R_VPU_PID5 = 363,
|
||||
IMX_SC_R_VPU_PID6 = 364,
|
||||
IMX_SC_R_VPU_PID7 = 365,
|
||||
IMX_SC_R_VPU_UART = 366,
|
||||
IMX_SC_R_VPUCORE = 367,
|
||||
IMX_SC_R_VPUCORE_0 = 368,
|
||||
IMX_SC_R_VPUCORE_1 = 369,
|
||||
IMX_SC_R_VPUCORE_2 = 370,
|
||||
IMX_SC_R_VPUCORE_3 = 371,
|
||||
IMX_SC_R_DMA_4_CH0 = 372,
|
||||
IMX_SC_R_DMA_4_CH1 = 373,
|
||||
IMX_SC_R_DMA_4_CH2 = 374,
|
||||
IMX_SC_R_DMA_4_CH3 = 375,
|
||||
IMX_SC_R_DMA_4_CH4 = 376,
|
||||
IMX_SC_R_ISI_CH0 = 377,
|
||||
IMX_SC_R_ISI_CH1 = 378,
|
||||
IMX_SC_R_ISI_CH2 = 379,
|
||||
IMX_SC_R_ISI_CH3 = 380,
|
||||
IMX_SC_R_ISI_CH4 = 381,
|
||||
IMX_SC_R_ISI_CH5 = 382,
|
||||
IMX_SC_R_ISI_CH6 = 383,
|
||||
IMX_SC_R_ISI_CH7 = 384,
|
||||
IMX_SC_R_MJPEG_DEC_S0 = 385,
|
||||
IMX_SC_R_MJPEG_DEC_S1 = 386,
|
||||
IMX_SC_R_MJPEG_DEC_S2 = 387,
|
||||
IMX_SC_R_MJPEG_DEC_S3 = 388,
|
||||
IMX_SC_R_MJPEG_ENC_S0 = 389,
|
||||
IMX_SC_R_MJPEG_ENC_S1 = 390,
|
||||
IMX_SC_R_MJPEG_ENC_S2 = 391,
|
||||
IMX_SC_R_MJPEG_ENC_S3 = 392,
|
||||
IMX_SC_R_MIPI_0 = 393,
|
||||
IMX_SC_R_MIPI_0_PWM_0 = 394,
|
||||
IMX_SC_R_MIPI_0_I2C_0 = 395,
|
||||
IMX_SC_R_MIPI_0_I2C_1 = 396,
|
||||
IMX_SC_R_MIPI_1 = 397,
|
||||
IMX_SC_R_MIPI_1_PWM_0 = 398,
|
||||
IMX_SC_R_MIPI_1_I2C_0 = 399,
|
||||
IMX_SC_R_MIPI_1_I2C_1 = 400,
|
||||
IMX_SC_R_CSI_0 = 401,
|
||||
IMX_SC_R_CSI_0_PWM_0 = 402,
|
||||
IMX_SC_R_CSI_0_I2C_0 = 403,
|
||||
IMX_SC_R_CSI_1 = 404,
|
||||
IMX_SC_R_CSI_1_PWM_0 = 405,
|
||||
IMX_SC_R_CSI_1_I2C_0 = 406,
|
||||
IMX_SC_R_HDMI = 407,
|
||||
IMX_SC_R_HDMI_I2S = 408,
|
||||
IMX_SC_R_HDMI_I2C_0 = 409,
|
||||
IMX_SC_R_HDMI_PLL_0 = 410,
|
||||
IMX_SC_R_HDMI_RX = 411,
|
||||
IMX_SC_R_HDMI_RX_BYPASS = 412,
|
||||
IMX_SC_R_HDMI_RX_I2C_0 = 413,
|
||||
IMX_SC_R_ASRC_0 = 414,
|
||||
IMX_SC_R_ESAI_0 = 415,
|
||||
IMX_SC_R_SPDIF_0 = 416,
|
||||
IMX_SC_R_SPDIF_1 = 417,
|
||||
IMX_SC_R_SAI_3 = 418,
|
||||
IMX_SC_R_SAI_4 = 419,
|
||||
IMX_SC_R_SAI_5 = 420,
|
||||
IMX_SC_R_GPT_5 = 421,
|
||||
IMX_SC_R_GPT_6 = 422,
|
||||
IMX_SC_R_GPT_7 = 423,
|
||||
IMX_SC_R_GPT_8 = 424,
|
||||
IMX_SC_R_GPT_9 = 425,
|
||||
IMX_SC_R_GPT_10 = 426,
|
||||
IMX_SC_R_DMA_2_CH5 = 427,
|
||||
IMX_SC_R_DMA_2_CH6 = 428,
|
||||
IMX_SC_R_DMA_2_CH7 = 429,
|
||||
IMX_SC_R_DMA_2_CH8 = 430,
|
||||
IMX_SC_R_DMA_2_CH9 = 431,
|
||||
IMX_SC_R_DMA_2_CH10 = 432,
|
||||
IMX_SC_R_DMA_2_CH11 = 433,
|
||||
IMX_SC_R_DMA_2_CH12 = 434,
|
||||
IMX_SC_R_DMA_2_CH13 = 435,
|
||||
IMX_SC_R_DMA_2_CH14 = 436,
|
||||
IMX_SC_R_DMA_2_CH15 = 437,
|
||||
IMX_SC_R_DMA_2_CH16 = 438,
|
||||
IMX_SC_R_DMA_2_CH17 = 439,
|
||||
IMX_SC_R_DMA_2_CH18 = 440,
|
||||
IMX_SC_R_DMA_2_CH19 = 441,
|
||||
IMX_SC_R_DMA_2_CH20 = 442,
|
||||
IMX_SC_R_DMA_2_CH21 = 443,
|
||||
IMX_SC_R_DMA_2_CH22 = 444,
|
||||
IMX_SC_R_DMA_2_CH23 = 445,
|
||||
IMX_SC_R_DMA_2_CH24 = 446,
|
||||
IMX_SC_R_DMA_2_CH25 = 447,
|
||||
IMX_SC_R_DMA_2_CH26 = 448,
|
||||
IMX_SC_R_DMA_2_CH27 = 449,
|
||||
IMX_SC_R_DMA_2_CH28 = 450,
|
||||
IMX_SC_R_DMA_2_CH29 = 451,
|
||||
IMX_SC_R_DMA_2_CH30 = 452,
|
||||
IMX_SC_R_DMA_2_CH31 = 453,
|
||||
IMX_SC_R_ASRC_1 = 454,
|
||||
IMX_SC_R_ESAI_1 = 455,
|
||||
IMX_SC_R_SAI_6 = 456,
|
||||
IMX_SC_R_SAI_7 = 457,
|
||||
IMX_SC_R_AMIX = 458,
|
||||
IMX_SC_R_MQS_0 = 459,
|
||||
IMX_SC_R_DMA_3_CH0 = 460,
|
||||
IMX_SC_R_DMA_3_CH1 = 461,
|
||||
IMX_SC_R_DMA_3_CH2 = 462,
|
||||
IMX_SC_R_DMA_3_CH3 = 463,
|
||||
IMX_SC_R_DMA_3_CH4 = 464,
|
||||
IMX_SC_R_DMA_3_CH5 = 465,
|
||||
IMX_SC_R_DMA_3_CH6 = 466,
|
||||
IMX_SC_R_DMA_3_CH7 = 467,
|
||||
IMX_SC_R_DMA_3_CH8 = 468,
|
||||
IMX_SC_R_DMA_3_CH9 = 469,
|
||||
IMX_SC_R_DMA_3_CH10 = 470,
|
||||
IMX_SC_R_DMA_3_CH11 = 471,
|
||||
IMX_SC_R_DMA_3_CH12 = 472,
|
||||
IMX_SC_R_DMA_3_CH13 = 473,
|
||||
IMX_SC_R_DMA_3_CH14 = 474,
|
||||
IMX_SC_R_DMA_3_CH15 = 475,
|
||||
IMX_SC_R_DMA_3_CH16 = 476,
|
||||
IMX_SC_R_DMA_3_CH17 = 477,
|
||||
IMX_SC_R_DMA_3_CH18 = 478,
|
||||
IMX_SC_R_DMA_3_CH19 = 479,
|
||||
IMX_SC_R_DMA_3_CH20 = 480,
|
||||
IMX_SC_R_DMA_3_CH21 = 481,
|
||||
IMX_SC_R_DMA_3_CH22 = 482,
|
||||
IMX_SC_R_DMA_3_CH23 = 483,
|
||||
IMX_SC_R_DMA_3_CH24 = 484,
|
||||
IMX_SC_R_DMA_3_CH25 = 485,
|
||||
IMX_SC_R_DMA_3_CH26 = 486,
|
||||
IMX_SC_R_DMA_3_CH27 = 487,
|
||||
IMX_SC_R_DMA_3_CH28 = 488,
|
||||
IMX_SC_R_DMA_3_CH29 = 489,
|
||||
IMX_SC_R_DMA_3_CH30 = 490,
|
||||
IMX_SC_R_DMA_3_CH31 = 491,
|
||||
IMX_SC_R_AUDIO_PLL_1 = 492,
|
||||
IMX_SC_R_AUDIO_CLK_0 = 493,
|
||||
IMX_SC_R_AUDIO_CLK_1 = 494,
|
||||
IMX_SC_R_MCLK_OUT_0 = 495,
|
||||
IMX_SC_R_MCLK_OUT_1 = 496,
|
||||
IMX_SC_R_PMIC_0 = 497,
|
||||
IMX_SC_R_PMIC_1 = 498,
|
||||
IMX_SC_R_SECO = 499,
|
||||
IMX_SC_R_CAAM_JR1 = 500,
|
||||
IMX_SC_R_CAAM_JR2 = 501,
|
||||
IMX_SC_R_CAAM_JR3 = 502,
|
||||
IMX_SC_R_SECO_MU_2 = 503,
|
||||
IMX_SC_R_SECO_MU_3 = 504,
|
||||
IMX_SC_R_SECO_MU_4 = 505,
|
||||
IMX_SC_R_HDMI_RX_PWM_0 = 506,
|
||||
IMX_SC_R_A35 = 507,
|
||||
IMX_SC_R_A35_0 = 508,
|
||||
IMX_SC_R_A35_1 = 509,
|
||||
IMX_SC_R_A35_2 = 510,
|
||||
IMX_SC_R_A35_3 = 511,
|
||||
IMX_SC_R_DSP = 512,
|
||||
IMX_SC_R_DSP_RAM = 513,
|
||||
IMX_SC_R_CAAM_JR1_OUT = 514,
|
||||
IMX_SC_R_CAAM_JR2_OUT = 515,
|
||||
IMX_SC_R_CAAM_JR3_OUT = 516,
|
||||
IMX_SC_R_VPU_DEC_0 = 517,
|
||||
IMX_SC_R_VPU_ENC_0 = 518,
|
||||
IMX_SC_R_CAAM_JR0 = 519,
|
||||
IMX_SC_R_CAAM_JR0_OUT = 520,
|
||||
IMX_SC_R_PMIC_2 = 521,
|
||||
IMX_SC_R_DBLOGIC = 522,
|
||||
IMX_SC_R_HDMI_PLL_1 = 523,
|
||||
IMX_SC_R_BOARD_R0 = 524,
|
||||
IMX_SC_R_BOARD_R1 = 525,
|
||||
IMX_SC_R_BOARD_R2 = 526,
|
||||
IMX_SC_R_BOARD_R3 = 527,
|
||||
IMX_SC_R_BOARD_R4 = 528,
|
||||
IMX_SC_R_BOARD_R5 = 529,
|
||||
IMX_SC_R_BOARD_R6 = 530,
|
||||
IMX_SC_R_BOARD_R7 = 531,
|
||||
IMX_SC_R_MJPEG_DEC_MP = 532,
|
||||
IMX_SC_R_MJPEG_ENC_MP = 533,
|
||||
IMX_SC_R_VPU_TS_0 = 534,
|
||||
IMX_SC_R_VPU_MU_0 = 535,
|
||||
IMX_SC_R_VPU_MU_1 = 536,
|
||||
IMX_SC_R_VPU_MU_2 = 537,
|
||||
IMX_SC_R_VPU_MU_3 = 538,
|
||||
IMX_SC_R_VPU_ENC_1 = 539,
|
||||
IMX_SC_R_VPU = 540,
|
||||
IMX_SC_R_LAST
|
||||
};
|
||||
|
||||
/* NOTE - please add by replacing some of the UNUSED from above! */
|
||||
|
||||
/*
|
||||
* This type is used to indicate a control.
|
||||
*/
|
||||
|
30
include/linux/pl353-smc.h
Normal file
30
include/linux/pl353-smc.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* ARM PL353 SMC Driver Header
|
||||
*
|
||||
* Copyright (C) 2012 - 2018 Xilinx, Inc
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_PL353_SMC_H
|
||||
#define __LINUX_PL353_SMC_H
|
||||
|
||||
enum pl353_smc_ecc_mode {
|
||||
PL353_SMC_ECCMODE_BYPASS = 0,
|
||||
PL353_SMC_ECCMODE_APB = 1,
|
||||
PL353_SMC_ECCMODE_MEM = 2
|
||||
};
|
||||
|
||||
enum pl353_smc_mem_width {
|
||||
PL353_SMC_MEM_WIDTH_8 = 0,
|
||||
PL353_SMC_MEM_WIDTH_16 = 1
|
||||
};
|
||||
|
||||
u32 pl353_smc_get_ecc_val(int ecc_reg);
|
||||
bool pl353_smc_ecc_is_busy(void);
|
||||
int pl353_smc_get_nand_int_status_raw(void);
|
||||
void pl353_smc_clr_nand_int(void);
|
||||
int pl353_smc_set_ecc_mode(enum pl353_smc_ecc_mode mode);
|
||||
int pl353_smc_set_ecc_pg_size(unsigned int pg_sz);
|
||||
int pl353_smc_set_buswidth(unsigned int bw);
|
||||
void pl353_smc_set_cycles(u32 timings[]);
|
||||
#endif
|
@ -67,6 +67,9 @@ extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
|
||||
extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
|
||||
extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
|
||||
#else
|
||||
|
||||
#include <linux/errno.h>
|
||||
|
||||
static inline
|
||||
int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
|
||||
{
|
||||
|
133
include/linux/soc/mediatek/mtk-cmdq.h
Normal file
133
include/linux/soc/mediatek/mtk-cmdq.h
Normal file
@ -0,0 +1,133 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2018 MediaTek Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MTK_CMDQ_H__
|
||||
#define __MTK_CMDQ_H__
|
||||
|
||||
#include <linux/mailbox_client.h>
|
||||
#include <linux/mailbox/mtk-cmdq-mailbox.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#define CMDQ_NO_TIMEOUT 0xffffffffu
|
||||
|
||||
/** cmdq event maximum */
|
||||
#define CMDQ_MAX_EVENT 0x3ff
|
||||
|
||||
struct cmdq_pkt;
|
||||
|
||||
struct cmdq_client {
|
||||
spinlock_t lock;
|
||||
u32 pkt_cnt;
|
||||
struct mbox_client client;
|
||||
struct mbox_chan *chan;
|
||||
struct timer_list timer;
|
||||
u32 timeout_ms; /* in unit of microsecond */
|
||||
};
|
||||
|
||||
/**
|
||||
* cmdq_mbox_create() - create CMDQ mailbox client and channel
|
||||
* @dev: device of CMDQ mailbox client
|
||||
* @index: index of CMDQ mailbox channel
|
||||
* @timeout: timeout of a pkt execution by GCE, in unit of microsecond, set
|
||||
* CMDQ_NO_TIMEOUT if a timer is not used.
|
||||
*
|
||||
* Return: CMDQ mailbox client pointer
|
||||
*/
|
||||
struct cmdq_client *cmdq_mbox_create(struct device *dev, int index,
|
||||
u32 timeout);
|
||||
|
||||
/**
|
||||
* cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel
|
||||
* @client: the CMDQ mailbox client
|
||||
*/
|
||||
void cmdq_mbox_destroy(struct cmdq_client *client);
|
||||
|
||||
/**
|
||||
* cmdq_pkt_create() - create a CMDQ packet
|
||||
* @client: the CMDQ mailbox client
|
||||
* @size: required CMDQ buffer size
|
||||
*
|
||||
* Return: CMDQ packet pointer
|
||||
*/
|
||||
struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
|
||||
|
||||
/**
|
||||
* cmdq_pkt_destroy() - destroy the CMDQ packet
|
||||
* @pkt: the CMDQ packet
|
||||
*/
|
||||
void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
|
||||
|
||||
/**
|
||||
* cmdq_pkt_write() - append write command to the CMDQ packet
|
||||
* @pkt: the CMDQ packet
|
||||
* @value: the specified target register value
|
||||
* @subsys: the CMDQ sub system code
|
||||
* @offset: register offset from CMDQ sub system
|
||||
*
|
||||
* Return: 0 for success; else the error code is returned
|
||||
*/
|
||||
int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset);
|
||||
|
||||
/**
|
||||
* cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
|
||||
* @pkt: the CMDQ packet
|
||||
* @value: the specified target register value
|
||||
* @subsys: the CMDQ sub system code
|
||||
* @offset: register offset from CMDQ sub system
|
||||
* @mask: the specified target register mask
|
||||
*
|
||||
* Return: 0 for success; else the error code is returned
|
||||
*/
|
||||
int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
|
||||
u32 subsys, u32 offset, u32 mask);
|
||||
|
||||
/**
|
||||
* cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
|
||||
* @pkt: the CMDQ packet
|
||||
* @event: the desired event type to "wait and CLEAR"
|
||||
*
|
||||
* Return: 0 for success; else the error code is returned
|
||||
*/
|
||||
int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event);
|
||||
|
||||
/**
|
||||
* cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
|
||||
* @pkt: the CMDQ packet
|
||||
* @event: the desired event to be cleared
|
||||
*
|
||||
* Return: 0 for success; else the error code is returned
|
||||
*/
|
||||
int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event);
|
||||
|
||||
/**
|
||||
* cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
|
||||
* packet and call back at the end of done packet
|
||||
* @pkt: the CMDQ packet
|
||||
* @cb: called at the end of done packet
|
||||
* @data: this data will pass back to cb
|
||||
*
|
||||
* Return: 0 for success; else the error code is returned
|
||||
*
|
||||
* Trigger CMDQ to asynchronously execute the CMDQ packet and call back
|
||||
* at the end of done packet. Note that this is an ASYNC function. When the
|
||||
* function returned, it may or may not be finished.
|
||||
*/
|
||||
int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* cmdq_pkt_flush() - trigger CMDQ to execute the CMDQ packet
|
||||
* @pkt: the CMDQ packet
|
||||
*
|
||||
* Return: 0 for success; else the error code is returned
|
||||
*
|
||||
* Trigger CMDQ to execute the CMDQ packet. Note that this is a
|
||||
* synchronous flush function. When the function returned, the recorded
|
||||
* commands have been done.
|
||||
*/
|
||||
int cmdq_pkt_flush(struct cmdq_pkt *pkt);
|
||||
|
||||
#endif /* __MTK_CMDQ_H__ */
|
@ -166,7 +166,7 @@ struct qmi_ops {
|
||||
struct qmi_txn {
|
||||
struct qmi_handle *qmi;
|
||||
|
||||
int id;
|
||||
u16 id;
|
||||
|
||||
struct mutex lock;
|
||||
struct completion completion;
|
||||
|
@ -1,9 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright © 2015 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_RASPBERRY_FIRMWARE_H__
|
||||
|
@ -18,9 +18,7 @@ enum cmd_db_hw_type {
|
||||
#if IS_ENABLED(CONFIG_QCOM_COMMAND_DB)
|
||||
u32 cmd_db_read_addr(const char *resource_id);
|
||||
|
||||
int cmd_db_read_aux_data(const char *resource_id, u8 *data, size_t len);
|
||||
|
||||
size_t cmd_db_read_aux_data_len(const char *resource_id);
|
||||
const void *cmd_db_read_aux_data(const char *resource_id, size_t *len);
|
||||
|
||||
enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id);
|
||||
|
||||
@ -29,12 +27,8 @@ int cmd_db_ready(void);
|
||||
static inline u32 cmd_db_read_addr(const char *resource_id)
|
||||
{ return 0; }
|
||||
|
||||
static inline int cmd_db_read_aux_data(const char *resource_id, u8 *data,
|
||||
size_t len)
|
||||
{ return -ENODEV; }
|
||||
|
||||
static inline size_t cmd_db_read_aux_data_len(const char *resource_id)
|
||||
{ return -ENODEV; }
|
||||
static inline const void *cmd_db_read_aux_data(const char *resource_id, size_t *len)
|
||||
{ return ERR_PTR(-ENODEV); }
|
||||
|
||||
static inline enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id)
|
||||
{ return -ENODEV; }
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -129,6 +129,7 @@ int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
|
||||
tegra_bpmp_mrq_handler_t handler, void *data);
|
||||
void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
|
||||
void *data);
|
||||
bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq);
|
||||
#else
|
||||
static inline struct tegra_bpmp *tegra_bpmp_get(struct device *dev)
|
||||
{
|
||||
@ -164,6 +165,12 @@ static inline void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp,
|
||||
unsigned int mrq, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp,
|
||||
unsigned int mrq)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_CLK_TEGRA_BPMP)
|
||||
|
@ -60,7 +60,6 @@ struct tegra_sku_info {
|
||||
|
||||
u32 tegra_read_straps(void);
|
||||
u32 tegra_read_ram_code(void);
|
||||
u32 tegra_read_chipid(void);
|
||||
int tegra_fuse_readl(unsigned long offset, u32 *value);
|
||||
|
||||
extern struct tegra_sku_info tegra_sku_info;
|
||||
|
@ -90,6 +90,10 @@ enum tegra_io_pad {
|
||||
TEGRA_IO_PAD_CSID,
|
||||
TEGRA_IO_PAD_CSIE,
|
||||
TEGRA_IO_PAD_CSIF,
|
||||
TEGRA_IO_PAD_CSIG,
|
||||
TEGRA_IO_PAD_CSIH,
|
||||
TEGRA_IO_PAD_DAP3,
|
||||
TEGRA_IO_PAD_DAP5,
|
||||
TEGRA_IO_PAD_DBG,
|
||||
TEGRA_IO_PAD_DEBUG_NONAO,
|
||||
TEGRA_IO_PAD_DMIC,
|
||||
@ -102,10 +106,15 @@ enum tegra_io_pad {
|
||||
TEGRA_IO_PAD_EDP,
|
||||
TEGRA_IO_PAD_EMMC,
|
||||
TEGRA_IO_PAD_EMMC2,
|
||||
TEGRA_IO_PAD_EQOS,
|
||||
TEGRA_IO_PAD_GPIO,
|
||||
TEGRA_IO_PAD_GP_PWM2,
|
||||
TEGRA_IO_PAD_GP_PWM3,
|
||||
TEGRA_IO_PAD_HDMI,
|
||||
TEGRA_IO_PAD_HDMI_DP0,
|
||||
TEGRA_IO_PAD_HDMI_DP1,
|
||||
TEGRA_IO_PAD_HDMI_DP2,
|
||||
TEGRA_IO_PAD_HDMI_DP3,
|
||||
TEGRA_IO_PAD_HSIC,
|
||||
TEGRA_IO_PAD_HV,
|
||||
TEGRA_IO_PAD_LVDS,
|
||||
@ -115,8 +124,14 @@ enum tegra_io_pad {
|
||||
TEGRA_IO_PAD_PEX_CLK_BIAS,
|
||||
TEGRA_IO_PAD_PEX_CLK1,
|
||||
TEGRA_IO_PAD_PEX_CLK2,
|
||||
TEGRA_IO_PAD_PEX_CLK2_BIAS,
|
||||
TEGRA_IO_PAD_PEX_CLK3,
|
||||
TEGRA_IO_PAD_PEX_CNTRL,
|
||||
TEGRA_IO_PAD_PEX_CTL2,
|
||||
TEGRA_IO_PAD_PEX_L0_RST_N,
|
||||
TEGRA_IO_PAD_PEX_L1_RST_N,
|
||||
TEGRA_IO_PAD_PEX_L5_RST_N,
|
||||
TEGRA_IO_PAD_PWR_CTL,
|
||||
TEGRA_IO_PAD_SDMMC1,
|
||||
TEGRA_IO_PAD_SDMMC1_HV,
|
||||
TEGRA_IO_PAD_SDMMC2,
|
||||
@ -124,10 +139,16 @@ enum tegra_io_pad {
|
||||
TEGRA_IO_PAD_SDMMC3,
|
||||
TEGRA_IO_PAD_SDMMC3_HV,
|
||||
TEGRA_IO_PAD_SDMMC4,
|
||||
TEGRA_IO_PAD_SOC_GPIO10,
|
||||
TEGRA_IO_PAD_SOC_GPIO12,
|
||||
TEGRA_IO_PAD_SOC_GPIO13,
|
||||
TEGRA_IO_PAD_SOC_GPIO53,
|
||||
TEGRA_IO_PAD_SPI,
|
||||
TEGRA_IO_PAD_SPI_HV,
|
||||
TEGRA_IO_PAD_SYS_DDC,
|
||||
TEGRA_IO_PAD_UART,
|
||||
TEGRA_IO_PAD_UART4,
|
||||
TEGRA_IO_PAD_UART5,
|
||||
TEGRA_IO_PAD_UFS,
|
||||
TEGRA_IO_PAD_USB0,
|
||||
TEGRA_IO_PAD_USB1,
|
||||
|
Loading…
Reference in New Issue
Block a user