Merge branches 'clk-nvidia', 'clk-rockchip', 'clk-at91' and 'clk-vc5' into clk-next
- Support the SD/OE pin on IDT VersaClock 5 and 6 clock generators * clk-nvidia: clk: tegra: fix old-style declaration clk: tegra: Remove CLK_IS_CRITICAL flag from fuse clock soc/tegra: fuse: Enable fuse clock on suspend for Tegra124 soc/tegra: fuse: Add runtime PM support soc/tegra: fuse: Clear fuse->clk on driver probe failure soc/tegra: pmc: Prevent racing with cpuilde driver soc/tegra: bpmp: Remove unused including <linux/version.h> * clk-rockchip: clk: rockchip: make rk3308 ddrphy4x clock critical clk: rockchip: drop GRF dependency for rk3328/rk3036 pll types dt-bindings: clk: Convert rockchip,rk3399-cru to DT schema clk: rockchip: Add support for hclk_sfc on rk3036 clk: rockchip: rk3036: fix up the sclk_sfc parent error clk: rockchip: add dt-binding clkid for hclk_sfc on rk3036 * clk-at91: clk: at91: clk-generated: Limit the requested rate to our range * clk-vc5: clk: vc5: Add properties for configuring SD/OE behavior clk: vc5: Use dev_err_probe dt-bindings: clk: vc5: Add properties for configuring the SD/OE pin
This commit is contained in:
Коммит
8fb59ce15c
|
@ -30,6 +30,20 @@ description: |
|
||||||
3 -- OUT3
|
3 -- OUT3
|
||||||
4 -- OUT4
|
4 -- OUT4
|
||||||
|
|
||||||
|
The idt,shutdown and idt,output-enable-active properties control the
|
||||||
|
SH (en_global_shutdown) and SP bits of the Primary Source and Shutdown
|
||||||
|
Register, respectively. Their behavior is summarized by the following
|
||||||
|
table:
|
||||||
|
|
||||||
|
SH SP Output when the SD/OE pin is Low/High
|
||||||
|
== == =====================================
|
||||||
|
0 0 Active/Inactive
|
||||||
|
0 1 Inactive/Active
|
||||||
|
1 0 Active/Shutdown
|
||||||
|
1 1 Inactive/Shutdown
|
||||||
|
|
||||||
|
The case where SH and SP are both 1 is likely not very interesting.
|
||||||
|
|
||||||
maintainers:
|
maintainers:
|
||||||
- Luca Ceresoli <luca@lucaceresoli.net>
|
- Luca Ceresoli <luca@lucaceresoli.net>
|
||||||
|
|
||||||
|
@ -64,6 +78,26 @@ properties:
|
||||||
maximum: 22760
|
maximum: 22760
|
||||||
description: Optional load capacitor for XTAL1 and XTAL2
|
description: Optional load capacitor for XTAL1 and XTAL2
|
||||||
|
|
||||||
|
idt,shutdown:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
enum: [0, 1]
|
||||||
|
description: |
|
||||||
|
If 1, this enables the shutdown functionality: the chip will be
|
||||||
|
shut down if the SD/OE pin is driven high. If 0, this disables the
|
||||||
|
shutdown functionality: the chip will never be shut down based on
|
||||||
|
the value of the SD/OE pin. This property corresponds to the SH
|
||||||
|
bit of the Primary Source and Shutdown Register.
|
||||||
|
|
||||||
|
idt,output-enable-active:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
enum: [0, 1]
|
||||||
|
description: |
|
||||||
|
If 1, this enables output when the SD/OE pin is high, and disables
|
||||||
|
output when the SD/OE pin is low. If 0, this disables output when
|
||||||
|
the SD/OE pin is high, and enables output when the SD/OE pin is
|
||||||
|
low. This corresponds to the SP bit of the Primary Source and
|
||||||
|
Shutdown Register.
|
||||||
|
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^OUT[1-4]$":
|
"^OUT[1-4]$":
|
||||||
type: object
|
type: object
|
||||||
|
@ -90,6 +124,8 @@ required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
- '#clock-cells'
|
- '#clock-cells'
|
||||||
|
- idt,shutdown
|
||||||
|
- idt,output-enable-active
|
||||||
|
|
||||||
allOf:
|
allOf:
|
||||||
- if:
|
- if:
|
||||||
|
@ -139,6 +175,10 @@ examples:
|
||||||
clocks = <&ref25m>;
|
clocks = <&ref25m>;
|
||||||
clock-names = "xin";
|
clock-names = "xin";
|
||||||
|
|
||||||
|
/* Set the SD/OE pin's settings */
|
||||||
|
idt,shutdown = <0>;
|
||||||
|
idt,output-enable-active = <0>;
|
||||||
|
|
||||||
OUT1 {
|
OUT1 {
|
||||||
idt,mode = <VC5_CMOSD>;
|
idt,mode = <VC5_CMOSD>;
|
||||||
idt,voltage-microvolt = <1800000>;
|
idt,voltage-microvolt = <1800000>;
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
* Rockchip RK3399 Clock and Reset Unit
|
|
||||||
|
|
||||||
The RK3399 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: PMU for CRU should be "rockchip,rk3399-pmucru"
|
|
||||||
- compatible: CRU should be "rockchip,rk3399-cru"
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files".
|
|
||||||
It is used for GRF muxes, if missing any muxes present in the GRF will not
|
|
||||||
be available.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be
|
|
||||||
used in device tree sources. Similar macros exist for the reset sources in
|
|
||||||
these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "xin32k" - rtc clock - optional,
|
|
||||||
- "clkin_gmac" - external GMAC clock - optional,
|
|
||||||
- "clkin_i2s" - external I2S clock - optional,
|
|
||||||
- "pclkin_cif" - external ISP clock - optional,
|
|
||||||
- "clk_usbphy0_480m" - output clock of the pll in the usbphy0
|
|
||||||
- "clk_usbphy1_480m" - output clock of the pll in the usbphy1
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
pmucru: pmu-clock-controller@ff750000 {
|
|
||||||
compatible = "rockchip,rk3399-pmucru";
|
|
||||||
reg = <0x0 0xff750000 0x0 0x1000>;
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
cru: clock-controller@ff760000 {
|
|
||||||
compatible = "rockchip,rk3399-cru";
|
|
||||||
reg = <0x0 0xff760000 0x0 0x1000>;
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@ff1a0000 {
|
|
||||||
compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
|
|
||||||
reg = <0x0 0xff180000 0x0 0x100>;
|
|
||||||
clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
|
|
||||||
clock-names = "baudclk", "apb_pclk";
|
|
||||||
interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <4>;
|
|
||||||
};
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,rk3399-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip RK3399 Clock and Reset Unit
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Xing Zheng <zhengxing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The RK3399 clock controller generates and supplies clock to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be
|
||||||
|
used in device tree sources. Similar macros exist for the reset sources in
|
||||||
|
these files.
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required,
|
||||||
|
- "xin32k" - rtc clock - optional,
|
||||||
|
- "clkin_gmac" - external GMAC clock - optional,
|
||||||
|
- "clkin_i2s" - external I2S clock - optional,
|
||||||
|
- "pclkin_cif" - external ISP clock - optional,
|
||||||
|
- "clk_usbphy0_480m" - output clock of the pll in the usbphy0
|
||||||
|
- "clk_usbphy1_480m" - output clock of the pll in the usbphy1
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,rk3399-pmucru
|
||||||
|
- rockchip,rk3399-cru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
minItems: 1
|
||||||
|
|
||||||
|
assigned-clocks:
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 64
|
||||||
|
|
||||||
|
assigned-clock-parents:
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 64
|
||||||
|
|
||||||
|
assigned-clock-rates:
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 64
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description: >
|
||||||
|
phandle to the syscon managing the "general register files". It is used
|
||||||
|
for GRF muxes, if missing any muxes present in the GRF will not be
|
||||||
|
available.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
pmucru: pmu-clock-controller@ff750000 {
|
||||||
|
compatible = "rockchip,rk3399-pmucru";
|
||||||
|
reg = <0xff750000 0x1000>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
||||||
|
- |
|
||||||
|
cru: clock-controller@ff760000 {
|
||||||
|
compatible = "rockchip,rk3399-cru";
|
||||||
|
reg = <0xff760000 0x1000>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
|
@ -403,7 +403,7 @@ static const struct platform_suspend_ops tegra_suspend_ops = {
|
||||||
.enter = tegra_suspend_enter,
|
.enter = tegra_suspend_enter,
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init tegra_init_suspend(void)
|
void tegra_pm_init_suspend(void)
|
||||||
{
|
{
|
||||||
enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
|
enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,4 @@ void tegra30_sleep_core_init(void);
|
||||||
|
|
||||||
extern void (*tegra_tear_down_cpu)(void);
|
extern void (*tegra_tear_down_cpu)(void);
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
|
||||||
void tegra_init_suspend(void);
|
|
||||||
#else
|
|
||||||
static inline void tegra_init_suspend(void) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _MACH_TEGRA_PM_H_ */
|
#endif /* _MACH_TEGRA_PM_H_ */
|
||||||
|
|
|
@ -84,8 +84,6 @@ static void __init tegra_dt_init(void)
|
||||||
|
|
||||||
static void __init tegra_dt_init_late(void)
|
static void __init tegra_dt_init_late(void)
|
||||||
{
|
{
|
||||||
tegra_init_suspend();
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
|
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
|
||||||
of_machine_is_compatible("compal,paz00"))
|
of_machine_is_compatible("compal,paz00"))
|
||||||
tegra_paz00_wifikill_init();
|
tegra_paz00_wifikill_init();
|
||||||
|
|
|
@ -128,6 +128,12 @@ static int clk_generated_determine_rate(struct clk_hw *hw,
|
||||||
int i;
|
int i;
|
||||||
u32 div;
|
u32 div;
|
||||||
|
|
||||||
|
/* do not look for a rate that is outside of our range */
|
||||||
|
if (gck->range.max && req->rate > gck->range.max)
|
||||||
|
req->rate = gck->range.max;
|
||||||
|
if (gck->range.min && req->rate < gck->range.min)
|
||||||
|
req->rate = gck->range.min;
|
||||||
|
|
||||||
for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
|
for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
|
||||||
if (gck->chg_pid == i)
|
if (gck->chg_pid == i)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -907,6 +907,7 @@ static const struct of_device_id clk_vc5_of_match[];
|
||||||
|
|
||||||
static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
|
unsigned int oe, sd, src_mask = 0, src_val = 0;
|
||||||
struct vc5_driver_data *vc5;
|
struct vc5_driver_data *vc5;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
const char *parent_names[2];
|
const char *parent_names[2];
|
||||||
|
@ -930,11 +931,33 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
|
vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
|
||||||
if (IS_ERR(vc5->regmap)) {
|
if (IS_ERR(vc5->regmap))
|
||||||
dev_err(&client->dev, "failed to allocate register map\n");
|
return dev_err_probe(&client->dev, PTR_ERR(vc5->regmap),
|
||||||
return PTR_ERR(vc5->regmap);
|
"failed to allocate register map\n");
|
||||||
|
|
||||||
|
ret = of_property_read_u32(client->dev.of_node, "idt,shutdown", &sd);
|
||||||
|
if (!ret) {
|
||||||
|
src_mask |= VC5_PRIM_SRC_SHDN_EN_GBL_SHDN;
|
||||||
|
if (sd)
|
||||||
|
src_val |= VC5_PRIM_SRC_SHDN_EN_GBL_SHDN;
|
||||||
|
} else if (ret != -EINVAL) {
|
||||||
|
return dev_err_probe(&client->dev, ret,
|
||||||
|
"could not read idt,shutdown\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = of_property_read_u32(client->dev.of_node,
|
||||||
|
"idt,output-enable-active", &oe);
|
||||||
|
if (!ret) {
|
||||||
|
src_mask |= VC5_PRIM_SRC_SHDN_SP;
|
||||||
|
if (oe)
|
||||||
|
src_val |= VC5_PRIM_SRC_SHDN_SP;
|
||||||
|
} else if (ret != -EINVAL) {
|
||||||
|
return dev_err_probe(&client->dev, ret,
|
||||||
|
"could not read idt,output-enable-active\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, src_mask, src_val);
|
||||||
|
|
||||||
/* Register clock input mux */
|
/* Register clock input mux */
|
||||||
memset(&init, 0, sizeof(init));
|
memset(&init, 0, sizeof(init));
|
||||||
|
|
||||||
|
@ -957,10 +980,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||||
__clk_get_name(vc5->pin_clkin);
|
__clk_get_name(vc5->pin_clkin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!init.num_parents) {
|
if (!init.num_parents)
|
||||||
dev_err(&client->dev, "no input clock specified!\n");
|
return dev_err_probe(&client->dev, -EINVAL,
|
||||||
return -EINVAL;
|
"no input clock specified!\n");
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure Optional Loading Capacitance for external XTAL */
|
/* Configure Optional Loading Capacitance for external XTAL */
|
||||||
if (!(vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)) {
|
if (!(vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)) {
|
||||||
|
@ -1099,14 +1121,16 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||||
|
|
||||||
ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
|
ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&client->dev, "unable to add clk provider\n");
|
dev_err_probe(&client->dev, ret,
|
||||||
|
"unable to add clk provider\n");
|
||||||
goto err_clk;
|
goto err_clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_clk_register:
|
err_clk_register:
|
||||||
dev_err(&client->dev, "unable to register %s\n", init.name);
|
dev_err_probe(&client->dev, ret,
|
||||||
|
"unable to register %s\n", init.name);
|
||||||
kfree(init.name); /* clock framework made a copy of the name */
|
kfree(init.name); /* clock framework made a copy of the name */
|
||||||
err_clk:
|
err_clk:
|
||||||
if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
|
if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
|
||||||
|
|
|
@ -940,7 +940,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
|
||||||
switch (pll_type) {
|
switch (pll_type) {
|
||||||
case pll_rk3036:
|
case pll_rk3036:
|
||||||
case pll_rk3328:
|
case pll_rk3328:
|
||||||
if (!pll->rate_table || IS_ERR(ctx->grf))
|
if (!pll->rate_table)
|
||||||
init.ops = &rockchip_rk3036_pll_clk_norate_ops;
|
init.ops = &rockchip_rk3036_pll_clk_norate_ops;
|
||||||
else
|
else
|
||||||
init.ops = &rockchip_rk3036_pll_clk_ops;
|
init.ops = &rockchip_rk3036_pll_clk_ops;
|
||||||
|
|
|
@ -121,6 +121,7 @@ PNAME(mux_pll_src_3plls_p) = { "apll", "dpll", "gpll" };
|
||||||
PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" };
|
PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" };
|
||||||
|
|
||||||
PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll", "usb480m" };
|
PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll", "usb480m" };
|
||||||
|
PNAME(mux_pll_src_dmyapll_dpll_gpll_xin24_p) = { "dummy_apll", "dpll", "gpll", "xin24m" };
|
||||||
|
|
||||||
PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" };
|
PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" };
|
||||||
PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
|
PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
|
||||||
|
@ -340,7 +341,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
|
||||||
RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS,
|
RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS,
|
||||||
RK2928_CLKGATE_CON(10), 4, GFLAGS),
|
RK2928_CLKGATE_CON(10), 4, GFLAGS),
|
||||||
|
|
||||||
COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_apll_dpll_gpll_usb480m_p, 0,
|
COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_dmyapll_dpll_gpll_xin24_p, 0,
|
||||||
RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS,
|
RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS,
|
||||||
RK2928_CLKGATE_CON(10), 5, GFLAGS),
|
RK2928_CLKGATE_CON(10), 5, GFLAGS),
|
||||||
|
|
||||||
|
@ -403,7 +404,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
|
||||||
GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS),
|
GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS),
|
||||||
GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS),
|
GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS),
|
||||||
GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
|
GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
|
||||||
GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS),
|
GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS),
|
||||||
GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
|
GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
|
||||||
|
|
||||||
/* pclk_peri gates */
|
/* pclk_peri gates */
|
||||||
|
|
|
@ -911,6 +911,7 @@ static const char *const rk3308_critical_clocks[] __initconst = {
|
||||||
"hclk_audio",
|
"hclk_audio",
|
||||||
"pclk_audio",
|
"pclk_audio",
|
||||||
"sclk_ddrc",
|
"sclk_ddrc",
|
||||||
|
"clk_ddrphy4x",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __init rk3308_clk_init(struct device_node *np)
|
static void __init rk3308_clk_init(struct device_node *np)
|
||||||
|
|
|
@ -1377,7 +1377,7 @@ static void dfll_debug_init(struct tegra_dfll *td)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static void inline dfll_debug_init(struct tegra_dfll *td) { }
|
static inline void dfll_debug_init(struct tegra_dfll *td) { }
|
||||||
#endif /* CONFIG_DEBUG_FS */
|
#endif /* CONFIG_DEBUG_FS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -777,11 +777,7 @@ static struct tegra_periph_init_data gate_clks[] = {
|
||||||
GATE("ahbdma", "hclk", 33, 0, tegra_clk_ahbdma, 0),
|
GATE("ahbdma", "hclk", 33, 0, tegra_clk_ahbdma, 0),
|
||||||
GATE("apbdma", "pclk", 34, 0, tegra_clk_apbdma, 0),
|
GATE("apbdma", "pclk", 34, 0, tegra_clk_apbdma, 0),
|
||||||
GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0),
|
GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0),
|
||||||
/*
|
GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0),
|
||||||
* Critical for RAM re-repair operation, which must occur on resume
|
|
||||||
* from LP1 system suspend and as part of CCPLEX cluster switching.
|
|
||||||
*/
|
|
||||||
GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, CLK_IS_CRITICAL),
|
|
||||||
GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0),
|
GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0),
|
||||||
GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0),
|
GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0),
|
||||||
GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0),
|
GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0),
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/sys_soc.h>
|
#include <linux/sys_soc.h>
|
||||||
|
|
||||||
|
@ -210,6 +211,8 @@ static int tegra_fuse_probe(struct platform_device *pdev)
|
||||||
platform_set_drvdata(pdev, fuse);
|
platform_set_drvdata(pdev, fuse);
|
||||||
fuse->dev = &pdev->dev;
|
fuse->dev = &pdev->dev;
|
||||||
|
|
||||||
|
pm_runtime_enable(&pdev->dev);
|
||||||
|
|
||||||
if (fuse->soc->probe) {
|
if (fuse->soc->probe) {
|
||||||
err = fuse->soc->probe(fuse);
|
err = fuse->soc->probe(fuse);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -246,14 +249,71 @@ static int tegra_fuse_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
restore:
|
restore:
|
||||||
|
fuse->clk = NULL;
|
||||||
fuse->base = base;
|
fuse->base = base;
|
||||||
|
pm_runtime_disable(&pdev->dev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __maybe_unused tegra_fuse_runtime_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = clk_prepare_enable(fuse->clk);
|
||||||
|
if (err < 0) {
|
||||||
|
dev_err(dev, "failed to enable FUSE clock: %d\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __maybe_unused tegra_fuse_runtime_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
clk_disable_unprepare(fuse->clk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __maybe_unused tegra_fuse_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Critical for RAM re-repair operation, which must occur on resume
|
||||||
|
* from LP1 system suspend and as part of CCPLEX cluster switching.
|
||||||
|
*/
|
||||||
|
if (fuse->soc->clk_suspend_on)
|
||||||
|
ret = pm_runtime_resume_and_get(dev);
|
||||||
|
else
|
||||||
|
ret = pm_runtime_force_suspend(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __maybe_unused tegra_fuse_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (fuse->soc->clk_suspend_on)
|
||||||
|
pm_runtime_put(dev);
|
||||||
|
else
|
||||||
|
ret = pm_runtime_force_resume(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dev_pm_ops tegra_fuse_pm = {
|
||||||
|
SET_RUNTIME_PM_OPS(tegra_fuse_runtime_suspend, tegra_fuse_runtime_resume,
|
||||||
|
NULL)
|
||||||
|
SET_SYSTEM_SLEEP_PM_OPS(tegra_fuse_suspend, tegra_fuse_resume)
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_driver tegra_fuse_driver = {
|
static struct platform_driver tegra_fuse_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "tegra-fuse",
|
.name = "tegra-fuse",
|
||||||
.of_match_table = tegra_fuse_match,
|
.of_match_table = tegra_fuse_match,
|
||||||
|
.pm = &tegra_fuse_pm,
|
||||||
.suppress_bind_attrs = true,
|
.suppress_bind_attrs = true,
|
||||||
},
|
},
|
||||||
.probe = tegra_fuse_probe,
|
.probe = tegra_fuse_probe,
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <linux/kobject.h>
|
#include <linux/kobject.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
|
|
||||||
#include <soc/tegra/fuse.h>
|
#include <soc/tegra/fuse.h>
|
||||||
|
@ -46,6 +47,10 @@ static u32 tegra20_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
err = pm_runtime_resume_and_get(fuse->dev);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
mutex_lock(&fuse->apbdma.lock);
|
mutex_lock(&fuse->apbdma.lock);
|
||||||
|
|
||||||
fuse->apbdma.config.src_addr = fuse->phys + FUSE_BEGIN + offset;
|
fuse->apbdma.config.src_addr = fuse->phys + FUSE_BEGIN + offset;
|
||||||
|
@ -66,8 +71,6 @@ static u32 tegra20_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
|
||||||
|
|
||||||
reinit_completion(&fuse->apbdma.wait);
|
reinit_completion(&fuse->apbdma.wait);
|
||||||
|
|
||||||
clk_prepare_enable(fuse->clk);
|
|
||||||
|
|
||||||
dmaengine_submit(dma_desc);
|
dmaengine_submit(dma_desc);
|
||||||
dma_async_issue_pending(fuse->apbdma.chan);
|
dma_async_issue_pending(fuse->apbdma.chan);
|
||||||
time_left = wait_for_completion_timeout(&fuse->apbdma.wait,
|
time_left = wait_for_completion_timeout(&fuse->apbdma.wait,
|
||||||
|
@ -78,10 +81,9 @@ static u32 tegra20_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
|
||||||
else
|
else
|
||||||
value = *fuse->apbdma.virt;
|
value = *fuse->apbdma.virt;
|
||||||
|
|
||||||
clk_disable_unprepare(fuse->clk);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&fuse->apbdma.lock);
|
mutex_unlock(&fuse->apbdma.lock);
|
||||||
|
pm_runtime_put(fuse->dev);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,4 +167,5 @@ const struct tegra_fuse_soc tegra20_fuse_soc = {
|
||||||
.probe = tegra20_fuse_probe,
|
.probe = tegra20_fuse_probe,
|
||||||
.info = &tegra20_fuse_info,
|
.info = &tegra20_fuse_info,
|
||||||
.soc_attr_group = &tegra_soc_attr_group,
|
.soc_attr_group = &tegra_soc_attr_group,
|
||||||
|
.clk_suspend_on = false,
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
|
|
||||||
#include <soc/tegra/fuse.h>
|
#include <soc/tegra/fuse.h>
|
||||||
|
@ -52,15 +53,13 @@ static u32 tegra30_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
|
||||||
u32 value;
|
u32 value;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = clk_prepare_enable(fuse->clk);
|
err = pm_runtime_resume_and_get(fuse->dev);
|
||||||
if (err < 0) {
|
if (err)
|
||||||
dev_err(fuse->dev, "failed to enable FUSE clock: %d\n", err);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
value = readl_relaxed(fuse->base + FUSE_BEGIN + offset);
|
value = readl_relaxed(fuse->base + FUSE_BEGIN + offset);
|
||||||
|
|
||||||
clk_disable_unprepare(fuse->clk);
|
pm_runtime_put(fuse->dev);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +112,7 @@ const struct tegra_fuse_soc tegra30_fuse_soc = {
|
||||||
.speedo_init = tegra30_init_speedo_data,
|
.speedo_init = tegra30_init_speedo_data,
|
||||||
.info = &tegra30_fuse_info,
|
.info = &tegra30_fuse_info,
|
||||||
.soc_attr_group = &tegra_soc_attr_group,
|
.soc_attr_group = &tegra_soc_attr_group,
|
||||||
|
.clk_suspend_on = false,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -128,6 +128,7 @@ const struct tegra_fuse_soc tegra114_fuse_soc = {
|
||||||
.speedo_init = tegra114_init_speedo_data,
|
.speedo_init = tegra114_init_speedo_data,
|
||||||
.info = &tegra114_fuse_info,
|
.info = &tegra114_fuse_info,
|
||||||
.soc_attr_group = &tegra_soc_attr_group,
|
.soc_attr_group = &tegra_soc_attr_group,
|
||||||
|
.clk_suspend_on = false,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -209,6 +210,7 @@ const struct tegra_fuse_soc tegra124_fuse_soc = {
|
||||||
.lookups = tegra124_fuse_lookups,
|
.lookups = tegra124_fuse_lookups,
|
||||||
.num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
|
.num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
|
||||||
.soc_attr_group = &tegra_soc_attr_group,
|
.soc_attr_group = &tegra_soc_attr_group,
|
||||||
|
.clk_suspend_on = true,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -295,6 +297,7 @@ const struct tegra_fuse_soc tegra210_fuse_soc = {
|
||||||
.lookups = tegra210_fuse_lookups,
|
.lookups = tegra210_fuse_lookups,
|
||||||
.num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
|
.num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
|
||||||
.soc_attr_group = &tegra_soc_attr_group,
|
.soc_attr_group = &tegra_soc_attr_group,
|
||||||
|
.clk_suspend_on = false,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -325,6 +328,7 @@ const struct tegra_fuse_soc tegra186_fuse_soc = {
|
||||||
.lookups = tegra186_fuse_lookups,
|
.lookups = tegra186_fuse_lookups,
|
||||||
.num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
|
.num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
|
||||||
.soc_attr_group = &tegra_soc_attr_group,
|
.soc_attr_group = &tegra_soc_attr_group,
|
||||||
|
.clk_suspend_on = false,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -355,6 +359,7 @@ const struct tegra_fuse_soc tegra194_fuse_soc = {
|
||||||
.lookups = tegra194_fuse_lookups,
|
.lookups = tegra194_fuse_lookups,
|
||||||
.num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
|
.num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
|
||||||
.soc_attr_group = &tegra194_soc_attr_group,
|
.soc_attr_group = &tegra194_soc_attr_group,
|
||||||
|
.clk_suspend_on = false,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -385,5 +390,6 @@ const struct tegra_fuse_soc tegra234_fuse_soc = {
|
||||||
.lookups = tegra234_fuse_lookups,
|
.lookups = tegra234_fuse_lookups,
|
||||||
.num_lookups = ARRAY_SIZE(tegra234_fuse_lookups),
|
.num_lookups = ARRAY_SIZE(tegra234_fuse_lookups),
|
||||||
.soc_attr_group = &tegra194_soc_attr_group,
|
.soc_attr_group = &tegra194_soc_attr_group,
|
||||||
|
.clk_suspend_on = false,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,6 +34,8 @@ struct tegra_fuse_soc {
|
||||||
unsigned int num_lookups;
|
unsigned int num_lookups;
|
||||||
|
|
||||||
const struct attribute_group *soc_attr_group;
|
const struct attribute_group *soc_attr_group;
|
||||||
|
|
||||||
|
bool clk_suspend_on;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tegra_fuse {
|
struct tegra_fuse {
|
||||||
|
|
|
@ -436,7 +436,7 @@ struct tegra_pmc {
|
||||||
|
|
||||||
static struct tegra_pmc *pmc = &(struct tegra_pmc) {
|
static struct tegra_pmc *pmc = &(struct tegra_pmc) {
|
||||||
.base = NULL,
|
.base = NULL,
|
||||||
.suspend_mode = TEGRA_SUSPEND_NONE,
|
.suspend_mode = TEGRA_SUSPEND_NOT_READY,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct tegra_powergate *
|
static inline struct tegra_powergate *
|
||||||
|
@ -1812,6 +1812,7 @@ static int tegra_pmc_parse_dt(struct tegra_pmc *pmc, struct device_node *np)
|
||||||
u32 value, values[2];
|
u32 value, values[2];
|
||||||
|
|
||||||
if (of_property_read_u32(np, "nvidia,suspend-mode", &value)) {
|
if (of_property_read_u32(np, "nvidia,suspend-mode", &value)) {
|
||||||
|
pmc->suspend_mode = TEGRA_SUSPEND_NONE;
|
||||||
} else {
|
} else {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -2785,6 +2786,11 @@ static int tegra_pmc_regmap_init(struct tegra_pmc *pmc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tegra_pmc_reset_suspend_mode(void *data)
|
||||||
|
{
|
||||||
|
pmc->suspend_mode = TEGRA_SUSPEND_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
static int tegra_pmc_probe(struct platform_device *pdev)
|
static int tegra_pmc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
|
@ -2803,6 +2809,11 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
err = devm_add_action_or_reset(&pdev->dev, tegra_pmc_reset_suspend_mode,
|
||||||
|
NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* take over the memory region from the early initialization */
|
/* take over the memory region from the early initialization */
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
base = devm_ioremap_resource(&pdev->dev, res);
|
base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
@ -2909,6 +2920,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
tegra_pmc_clock_register(pmc, pdev->dev.of_node);
|
tegra_pmc_clock_register(pmc, pdev->dev.of_node);
|
||||||
platform_set_drvdata(pdev, pmc);
|
platform_set_drvdata(pdev, pmc);
|
||||||
|
tegra_pm_init_suspend();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pm_domain.h>
|
#include <linux/pm_domain.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/version.h>
|
|
||||||
|
|
||||||
#include <soc/tegra/bpmp.h>
|
#include <soc/tegra/bpmp.h>
|
||||||
#include <soc/tegra/bpmp-abi.h>
|
#include <soc/tegra/bpmp-abi.h>
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
#define HCLK_OTG0 449
|
#define HCLK_OTG0 449
|
||||||
#define HCLK_OTG1 450
|
#define HCLK_OTG1 450
|
||||||
#define HCLK_NANDC 453
|
#define HCLK_NANDC 453
|
||||||
|
#define HCLK_SFC 454
|
||||||
#define HCLK_SDMMC 456
|
#define HCLK_SDMMC 456
|
||||||
#define HCLK_SDIO 457
|
#define HCLK_SDIO 457
|
||||||
#define HCLK_EMMC 459
|
#define HCLK_EMMC 459
|
||||||
|
|
|
@ -14,6 +14,7 @@ enum tegra_suspend_mode {
|
||||||
TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */
|
TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */
|
||||||
TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */
|
TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */
|
||||||
TEGRA_MAX_SUSPEND_MODE,
|
TEGRA_MAX_SUSPEND_MODE,
|
||||||
|
TEGRA_SUSPEND_NOT_READY,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
|
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
|
||||||
|
@ -28,6 +29,7 @@ void tegra_pm_clear_cpu_in_lp2(void);
|
||||||
void tegra_pm_set_cpu_in_lp2(void);
|
void tegra_pm_set_cpu_in_lp2(void);
|
||||||
int tegra_pm_enter_lp2(void);
|
int tegra_pm_enter_lp2(void);
|
||||||
int tegra_pm_park_secondary_cpu(unsigned long cpu);
|
int tegra_pm_park_secondary_cpu(unsigned long cpu);
|
||||||
|
void tegra_pm_init_suspend(void);
|
||||||
#else
|
#else
|
||||||
static inline enum tegra_suspend_mode
|
static inline enum tegra_suspend_mode
|
||||||
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
|
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
|
||||||
|
@ -61,6 +63,10 @@ static inline int tegra_pm_park_secondary_cpu(unsigned long cpu)
|
||||||
{
|
{
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void tegra_pm_init_suspend(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif /* CONFIG_PM_SLEEP */
|
#endif /* CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
#endif /* __SOC_TEGRA_PM_H__ */
|
#endif /* __SOC_TEGRA_PM_H__ */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче