mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
Second Round of Renesas ARM Based SoC R-Car SYSC Updates for v4.7
Introduce a DT-based driver for the R-Car System Controller, as found on Renesas R-Car H1, R-Car Gen2, and R-Car Gen3 SoCs. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXHryuAAoJENfPZGlqN0++Zq4QAJkrqIK774IUSa58+U4bMG2h ceRhG+uqr5AGoQJ/pEpFZjgaLe7hmrgKQmF2Uh1uWns633o2t6N2rR6gM36/BTqh HyyCMKT4vUoU6lyZ7qnB8LOxRj4oRa5J2C82rROWRx9m7TNmyHpA05KZUW2sUMmi 6/g+YF0wT8XbwSjUskxFSwO8TeKNcOSpFi0wWVR1WUh2RhVNbGXhyUSxxGTD3Ojt X6f1YmrfJmwzI0cY8AZScOr7WCU0HFk8IZRkEbg8t39TVOrEL5o97Ki9QK6WaGf8 uKA7gA1eDhO8DSXX1ycawx8uh4AxRGgYSZFc0Lq7E08k+VTn7D7qDsk4DDz+JnpH aLy95N4lDuQf9iiKFWEECc2OK3hxAnJb8c4yU2pS7tg1K4JNMT0iUkp2Ha+/RLrd +FcWYcerXLziBItseM0caDPyv7PXpNLpLnqfgYPAOcP4h5+tT8burH9Ic5zHdFgZ JAD30KBYH8xB7wRisf4S/MP6sHFD8XQl6WdQK1Vwl1oPitRRdgDIxaFhyDszli3O /mX5+iMavM/s36MZwAgck2nTNTal1CHqupzkvWzttee3sZXzmK8QuiYLqI8iqz2i HPxXM90IjzfQNtBZH6ZVdL3xCh8HKkzQdD6wb7I2nP7clMHJlNmQwanXcSw6vcvB /Jx3o0v31gXfdUx3lgCy =Lg0X -----END PGP SIGNATURE----- Merge tag 'renesas-rcar-sysc2-for-v4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/drivers Merge "Second Round of Renesas ARM Based SoC R-Car SYSC Updates for v4.7" from Simon Horman: Introduce a DT-based driver for the R-Car System Controller, as found on Renesas R-Car H1, R-Car Gen2, and R-Car Gen3 SoCs. * tag 'renesas-rcar-sysc2-for-v4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas: (30 commits) soc: renesas: rcar-sysc: Add support for R-Car H3 power areas soc: renesas: rcar-sysc: Add support for R-Car E2 power areas soc: renesas: rcar-sysc: Add support for R-Car M2-N power areas soc: renesas: rcar-sysc: Add support for R-Car M2-W power areas soc: renesas: rcar-sysc: Add support for R-Car H2 power areas soc: renesas: rcar-sysc: Add support for R-Car H1 power areas soc: renesas: rcar-sysc: Enable Clock Domain for I/O devices soc: renesas: rcar-sysc: Make rcar_sysc_power_is_off() static soc: renesas: rcar-sysc: Add DT support for SYSC PM domains soc: renesas: rcar-sysc: Improve rcar_sysc_power() debug info soc: renesas: Move pm-rcar to drivers/soc/renesas/rcar-sysc clk: renesas: cpg-mssr: Export cpg_mssr_{at,de}tach_dev() clk: renesas: mstp: Provide dummy attach/detach_dev callbacks clk: renesas: Provide Kconfig symbols for CPG/MSSR and CPG/MSTP support soc: renesas: Add r8a7795 SYSC PM Domain Binding Definitions soc: renesas: Add r8a7794 SYSC PM Domain Binding Definitions soc: renesas: Add r8a7793 SYSC PM Domain Binding Definitions soc: renesas: Add r8a7791 SYSC PM Domain Binding Definitions soc: renesas: Add r8a7790 SYSC PM Domain Binding Definitions soc: renesas: Add r8a7779 SYSC PM Domain Binding Definitions ...
This commit is contained in:
commit
a183d7f846
@ -0,0 +1,48 @@
|
||||
DT bindings for the Renesas R-Car System Controller
|
||||
|
||||
== System Controller Node ==
|
||||
|
||||
The R-Car System Controller provides power management for the CPU cores and
|
||||
various coprocessors.
|
||||
|
||||
Required properties:
|
||||
- compatible: Must contain exactly one of the following:
|
||||
- "renesas,r8a7779-sysc" (R-Car H1)
|
||||
- "renesas,r8a7790-sysc" (R-Car H2)
|
||||
- "renesas,r8a7791-sysc" (R-Car M2-W)
|
||||
- "renesas,r8a7792-sysc" (R-Car V2H)
|
||||
- "renesas,r8a7793-sysc" (R-Car M2-N)
|
||||
- "renesas,r8a7794-sysc" (R-Car E2)
|
||||
- "renesas,r8a7795-sysc" (R-Car H3)
|
||||
- reg: Address start and address range for the device.
|
||||
- #power-domain-cells: Must be 1.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
sysc: system-controller@e6180000 {
|
||||
compatible = "renesas,r8a7791-sysc";
|
||||
reg = <0 0xe6180000 0 0x0200>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
|
||||
== PM Domain Consumers ==
|
||||
|
||||
Devices residing in a power area must refer to that power area, as documented
|
||||
by the generic PM domain bindings in
|
||||
Documentation/devicetree/bindings/power/power_domain.txt.
|
||||
|
||||
Required properties:
|
||||
- power-domains: A phandle and symbolic PM domain specifier, as defined in
|
||||
<dt-bindings/power/r8a77*-sysc.h>.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
L2_CA15: cache-controller@0 {
|
||||
compatible = "cache";
|
||||
power-domains = <&sysc R8A7791_PD_CA15_SCU>;
|
||||
cache-unified;
|
||||
cache-level = <2>;
|
||||
};
|
@ -1494,6 +1494,8 @@ Q: http://patchwork.kernel.org/project/linux-renesas-soc/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
|
||||
S: Supported
|
||||
F: arch/arm64/boot/dts/renesas/
|
||||
F: drivers/soc/renesas/
|
||||
F: include/linux/soc/renesas/
|
||||
|
||||
ARM/RISCPC ARCHITECTURE
|
||||
M: Russell King <linux@arm.linux.org.uk>
|
||||
@ -1607,6 +1609,8 @@ F: arch/arm/configs/shmobile_defconfig
|
||||
F: arch/arm/include/debug/renesas-scif.S
|
||||
F: arch/arm/mach-shmobile/
|
||||
F: drivers/sh/
|
||||
F: drivers/soc/renesas/
|
||||
F: include/linux/soc/renesas/
|
||||
|
||||
ARM/SOCFPGA ARCHITECTURE
|
||||
M: Dinh Nguyen <dinguyen@opensource.altera.com>
|
||||
|
@ -4,11 +4,6 @@ config ARCH_SHMOBILE
|
||||
config ARCH_SHMOBILE_MULTI
|
||||
bool
|
||||
|
||||
config PM_RCAR
|
||||
bool
|
||||
select PM
|
||||
select PM_GENERIC_DOMAINS
|
||||
|
||||
config PM_RMOBILE
|
||||
bool
|
||||
select PM
|
||||
@ -16,13 +11,15 @@ config PM_RMOBILE
|
||||
|
||||
config ARCH_RCAR_GEN1
|
||||
bool
|
||||
select PM_RCAR
|
||||
select PM
|
||||
select PM_GENERIC_DOMAINS
|
||||
select RENESAS_INTC_IRQPIN
|
||||
select SYS_SUPPORTS_SH_TMU
|
||||
|
||||
config ARCH_RCAR_GEN2
|
||||
bool
|
||||
select PM_RCAR
|
||||
select PM
|
||||
select PM_GENERIC_DOMAINS
|
||||
select RENESAS_IRQC
|
||||
select SYS_SUPPORTS_SH_CMT
|
||||
select PCI_DOMAINS if PCI
|
||||
|
@ -39,7 +39,6 @@ smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o
|
||||
# PM objects
|
||||
obj-$(CONFIG_SUSPEND) += suspend.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_PM_RCAR) += pm-rcar.o
|
||||
obj-$(CONFIG_PM_RMOBILE) += pm-rmobile.o
|
||||
obj-$(CONFIG_ARCH_RCAR_GEN2) += pm-rcar-gen2.o
|
||||
|
||||
|
@ -9,9 +9,10 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/soc/renesas/rcar-sysc.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "pm-rcar.h"
|
||||
#include "r8a7779.h"
|
||||
|
||||
/* SYSC */
|
||||
|
@ -13,9 +13,9 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/soc/renesas/rcar-sysc.h>
|
||||
#include <asm/io.h>
|
||||
#include "common.h"
|
||||
#include "pm-rcar.h"
|
||||
#include "rcar-gen2.h"
|
||||
|
||||
/* RST */
|
||||
|
@ -1,164 +0,0 @@
|
||||
/*
|
||||
* R-Car SYSC Power management support
|
||||
*
|
||||
* Copyright (C) 2014 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include "pm-rcar.h"
|
||||
|
||||
/* SYSC Common */
|
||||
#define SYSCSR 0x00 /* SYSC Status Register */
|
||||
#define SYSCISR 0x04 /* Interrupt Status Register */
|
||||
#define SYSCISCR 0x08 /* Interrupt Status Clear Register */
|
||||
#define SYSCIER 0x0c /* Interrupt Enable Register */
|
||||
#define SYSCIMR 0x10 /* Interrupt Mask Register */
|
||||
|
||||
/* SYSC Status Register */
|
||||
#define SYSCSR_PONENB 1 /* Ready for power resume requests */
|
||||
#define SYSCSR_POFFENB 0 /* Ready for power shutoff requests */
|
||||
|
||||
/*
|
||||
* Power Control Register Offsets inside the register block for each domain
|
||||
* Note: The "CR" registers for ARM cores exist on H1 only
|
||||
* Use WFI to power off, CPG/APMU to resume ARM cores on R-Car Gen2
|
||||
*/
|
||||
#define PWRSR_OFFS 0x00 /* Power Status Register */
|
||||
#define PWROFFCR_OFFS 0x04 /* Power Shutoff Control Register */
|
||||
#define PWROFFSR_OFFS 0x08 /* Power Shutoff Status Register */
|
||||
#define PWRONCR_OFFS 0x0c /* Power Resume Control Register */
|
||||
#define PWRONSR_OFFS 0x10 /* Power Resume Status Register */
|
||||
#define PWRER_OFFS 0x14 /* Power Shutoff/Resume Error */
|
||||
|
||||
|
||||
#define SYSCSR_RETRIES 100
|
||||
#define SYSCSR_DELAY_US 1
|
||||
|
||||
#define PWRER_RETRIES 100
|
||||
#define PWRER_DELAY_US 1
|
||||
|
||||
#define SYSCISR_RETRIES 1000
|
||||
#define SYSCISR_DELAY_US 1
|
||||
|
||||
static void __iomem *rcar_sysc_base;
|
||||
static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
|
||||
|
||||
static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
|
||||
{
|
||||
unsigned int sr_bit, reg_offs;
|
||||
int k;
|
||||
|
||||
if (on) {
|
||||
sr_bit = SYSCSR_PONENB;
|
||||
reg_offs = PWRONCR_OFFS;
|
||||
} else {
|
||||
sr_bit = SYSCSR_POFFENB;
|
||||
reg_offs = PWROFFCR_OFFS;
|
||||
}
|
||||
|
||||
/* Wait until SYSC is ready to accept a power request */
|
||||
for (k = 0; k < SYSCSR_RETRIES; k++) {
|
||||
if (ioread32(rcar_sysc_base + SYSCSR) & BIT(sr_bit))
|
||||
break;
|
||||
udelay(SYSCSR_DELAY_US);
|
||||
}
|
||||
|
||||
if (k == SYSCSR_RETRIES)
|
||||
return -EAGAIN;
|
||||
|
||||
/* Submit power shutoff or power resume request */
|
||||
iowrite32(BIT(sysc_ch->chan_bit),
|
||||
rcar_sysc_base + sysc_ch->chan_offs + reg_offs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
|
||||
{
|
||||
unsigned int isr_mask = BIT(sysc_ch->isr_bit);
|
||||
unsigned int chan_mask = BIT(sysc_ch->chan_bit);
|
||||
unsigned int status;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
int k;
|
||||
|
||||
spin_lock_irqsave(&rcar_sysc_lock, flags);
|
||||
|
||||
iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
|
||||
|
||||
/* Submit power shutoff or resume request until it was accepted */
|
||||
for (k = 0; k < PWRER_RETRIES; k++) {
|
||||
ret = rcar_sysc_pwr_on_off(sysc_ch, on);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
status = ioread32(rcar_sysc_base +
|
||||
sysc_ch->chan_offs + PWRER_OFFS);
|
||||
if (!(status & chan_mask))
|
||||
break;
|
||||
|
||||
udelay(PWRER_DELAY_US);
|
||||
}
|
||||
|
||||
if (k == PWRER_RETRIES) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wait until the power shutoff or resume request has completed * */
|
||||
for (k = 0; k < SYSCISR_RETRIES; k++) {
|
||||
if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask)
|
||||
break;
|
||||
udelay(SYSCISR_DELAY_US);
|
||||
}
|
||||
|
||||
if (k == SYSCISR_RETRIES)
|
||||
ret = -EIO;
|
||||
|
||||
iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&rcar_sysc_lock, flags);
|
||||
|
||||
pr_debug("sysc power domain %d: %08x -> %d\n",
|
||||
sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
|
||||
{
|
||||
return rcar_sysc_power(sysc_ch, false);
|
||||
}
|
||||
|
||||
int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch)
|
||||
{
|
||||
return rcar_sysc_power(sysc_ch, true);
|
||||
}
|
||||
|
||||
bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch)
|
||||
{
|
||||
unsigned int st;
|
||||
|
||||
st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS);
|
||||
if (st & BIT(sysc_ch->chan_bit))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void __iomem *rcar_sysc_init(phys_addr_t base)
|
||||
{
|
||||
rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
|
||||
if (!rcar_sysc_base)
|
||||
panic("unable to ioremap R-Car SYSC hardware block\n");
|
||||
|
||||
return rcar_sysc_base;
|
||||
}
|
@ -19,13 +19,13 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/soc/renesas/rcar-sysc.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/smp_scu.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "pm-rcar.h"
|
||||
#include "r8a7779.h"
|
||||
|
||||
#define AVECR IOMEM(0xfe700040)
|
||||
|
@ -17,12 +17,12 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/soc/renesas/rcar-sysc.h>
|
||||
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "platsmp-apmu.h"
|
||||
#include "pm-rcar.h"
|
||||
#include "rcar-gen2.h"
|
||||
#include "r8a7790.h"
|
||||
|
||||
|
@ -201,6 +201,7 @@ source "drivers/clk/bcm/Kconfig"
|
||||
source "drivers/clk/hisilicon/Kconfig"
|
||||
source "drivers/clk/mvebu/Kconfig"
|
||||
source "drivers/clk/qcom/Kconfig"
|
||||
source "drivers/clk/renesas/Kconfig"
|
||||
source "drivers/clk/samsung/Kconfig"
|
||||
source "drivers/clk/tegra/Kconfig"
|
||||
source "drivers/clk/ti/Kconfig"
|
||||
|
16
drivers/clk/renesas/Kconfig
Normal file
16
drivers/clk/renesas/Kconfig
Normal file
@ -0,0 +1,16 @@
|
||||
config CLK_RENESAS_CPG_MSSR
|
||||
bool
|
||||
default y if ARCH_R8A7795
|
||||
|
||||
config CLK_RENESAS_CPG_MSTP
|
||||
bool
|
||||
default y if ARCH_R7S72100
|
||||
default y if ARCH_R8A73A4
|
||||
default y if ARCH_R8A7740
|
||||
default y if ARCH_R8A7778
|
||||
default y if ARCH_R8A7779
|
||||
default y if ARCH_R8A7790
|
||||
default y if ARCH_R8A7791
|
||||
default y if ARCH_R8A7793
|
||||
default y if ARCH_R8A7794
|
||||
default y if ARCH_SH73A0
|
@ -1,13 +1,15 @@
|
||||
obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o
|
||||
obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o clk-mstp.o
|
||||
obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o clk-mstp.o
|
||||
obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o clk-mstp.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7795) += renesas-cpg-mssr.o \
|
||||
r8a7795-cpg-mssr.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o
|
||||
obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o
|
||||
obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o
|
||||
obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o
|
||||
|
||||
obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o
|
||||
obj-$(CONFIG_CLK_RENESAS_CPG_MSTP) += clk-mstp.o
|
||||
|
@ -243,9 +243,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
|
||||
}
|
||||
CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
|
||||
|
||||
|
||||
#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
|
||||
int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
|
||||
int cpg_mstp_attach_dev(struct generic_pm_domain *unused, struct device *dev)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
struct of_phandle_args clkspec;
|
||||
@ -297,7 +295,7 @@ fail_put:
|
||||
return error;
|
||||
}
|
||||
|
||||
void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev)
|
||||
void cpg_mstp_detach_dev(struct generic_pm_domain *unused, struct device *dev)
|
||||
{
|
||||
if (!list_empty(&dev->power.subsys_data->clock_list))
|
||||
pm_clk_destroy(dev);
|
||||
@ -326,4 +324,3 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np)
|
||||
|
||||
of_genpd_add_provider_simple(np, pd);
|
||||
}
|
||||
#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
@ -26,6 +27,7 @@
|
||||
|
||||
#include "renesas-cpg-mssr.h"
|
||||
|
||||
#define CPG_RCKCR 0x240
|
||||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
@ -50,6 +52,7 @@ enum clk_ids {
|
||||
CLK_S3,
|
||||
CLK_SDSRC,
|
||||
CLK_SSPSRC,
|
||||
CLK_RINT,
|
||||
|
||||
/* Module Clocks */
|
||||
MOD_CLK_BASE
|
||||
@ -63,8 +66,12 @@ enum r8a7795_clk_types {
|
||||
CLK_TYPE_GEN3_PLL3,
|
||||
CLK_TYPE_GEN3_PLL4,
|
||||
CLK_TYPE_GEN3_SD,
|
||||
CLK_TYPE_GEN3_R,
|
||||
};
|
||||
|
||||
#define DEF_GEN3_SD(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
|
||||
|
||||
static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
@ -102,10 +109,10 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074),
|
||||
DEF_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078),
|
||||
DEF_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268),
|
||||
DEF_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c),
|
||||
DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074),
|
||||
DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078),
|
||||
DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268),
|
||||
DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c),
|
||||
|
||||
DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
@ -113,6 +120,11 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014),
|
||||
DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250),
|
||||
DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
|
||||
|
||||
DEF_DIV6_RO("osc", R8A7795_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8),
|
||||
DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32),
|
||||
|
||||
DEF_BASE("r", R8A7795_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
|
||||
};
|
||||
|
||||
static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
@ -139,6 +151,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("rwdt0", 402, R8A7795_CLK_R),
|
||||
DEF_MOD("intc-ex", 407, R8A7795_CLK_CP),
|
||||
DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4),
|
||||
@ -148,6 +161,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("pwm", 523, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvd2", 601, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvd1", 602, R8A7795_CLK_S2D1),
|
||||
@ -578,6 +592,18 @@ struct clk * __init r8a7795_cpg_clk_register(struct device *dev,
|
||||
case CLK_TYPE_GEN3_SD:
|
||||
return cpg_sd_clk_register(core, base, __clk_get_name(parent));
|
||||
|
||||
case CLK_TYPE_GEN3_R:
|
||||
/* RINT is default. Only if EXTALR is populated, we switch to it */
|
||||
value = readl(base + CPG_RCKCR) & 0x3f;
|
||||
|
||||
if (clk_get_rate(clks[CLK_EXTALR])) {
|
||||
parent = clks[CLK_EXTALR];
|
||||
value |= BIT(15);
|
||||
}
|
||||
|
||||
writel(value, base + CPG_RCKCR);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
@ -253,7 +254,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
||||
{
|
||||
struct clk *clk = NULL, *parent;
|
||||
struct device *dev = priv->dev;
|
||||
unsigned int id = core->id;
|
||||
unsigned int id = core->id, div = core->div;
|
||||
const char *parent_name;
|
||||
|
||||
WARN_DEBUG(id >= priv->num_core_clks);
|
||||
@ -266,6 +267,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
||||
|
||||
case CLK_TYPE_FF:
|
||||
case CLK_TYPE_DIV6P1:
|
||||
case CLK_TYPE_DIV6_RO:
|
||||
WARN_DEBUG(core->parent >= priv->num_core_clks);
|
||||
parent = priv->clks[core->parent];
|
||||
if (IS_ERR(parent)) {
|
||||
@ -274,13 +276,18 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
||||
}
|
||||
|
||||
parent_name = __clk_get_name(parent);
|
||||
if (core->type == CLK_TYPE_FF) {
|
||||
clk = clk_register_fixed_factor(NULL, core->name,
|
||||
parent_name, 0,
|
||||
core->mult, core->div);
|
||||
} else {
|
||||
|
||||
if (core->type == CLK_TYPE_DIV6_RO)
|
||||
/* Multiply with the DIV6 register value */
|
||||
div *= (readl(priv->base + core->offset) & 0x3f) + 1;
|
||||
|
||||
if (core->type == CLK_TYPE_DIV6P1) {
|
||||
clk = cpg_div6_register(core->name, 1, &parent_name,
|
||||
priv->base + core->offset);
|
||||
} else {
|
||||
clk = clk_register_fixed_factor(NULL, core->name,
|
||||
parent_name, 0,
|
||||
core->mult, div);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -375,8 +382,6 @@ fail:
|
||||
kfree(clock);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
|
||||
struct cpg_mssr_clk_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
struct device_node *np;
|
||||
@ -384,6 +389,8 @@ struct cpg_mssr_clk_domain {
|
||||
unsigned int core_pm_clks[0];
|
||||
};
|
||||
|
||||
static struct cpg_mssr_clk_domain *cpg_mssr_clk_domain;
|
||||
|
||||
static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec,
|
||||
struct cpg_mssr_clk_domain *pd)
|
||||
{
|
||||
@ -407,17 +414,20 @@ static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec,
|
||||
}
|
||||
}
|
||||
|
||||
static int cpg_mssr_attach_dev(struct generic_pm_domain *genpd,
|
||||
struct device *dev)
|
||||
int cpg_mssr_attach_dev(struct generic_pm_domain *unused, struct device *dev)
|
||||
{
|
||||
struct cpg_mssr_clk_domain *pd =
|
||||
container_of(genpd, struct cpg_mssr_clk_domain, genpd);
|
||||
struct cpg_mssr_clk_domain *pd = cpg_mssr_clk_domain;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct of_phandle_args clkspec;
|
||||
struct clk *clk;
|
||||
int i = 0;
|
||||
int error;
|
||||
|
||||
if (!pd) {
|
||||
dev_dbg(dev, "CPG/MSSR clock domain not yet available\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
|
||||
&clkspec)) {
|
||||
if (cpg_mssr_is_pm_clk(&clkspec, pd))
|
||||
@ -457,8 +467,7 @@ fail_put:
|
||||
return error;
|
||||
}
|
||||
|
||||
static void cpg_mssr_detach_dev(struct generic_pm_domain *genpd,
|
||||
struct device *dev)
|
||||
void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev)
|
||||
{
|
||||
if (!list_empty(&dev->power.subsys_data->clock_list))
|
||||
pm_clk_destroy(dev);
|
||||
@ -487,19 +496,11 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
|
||||
pm_genpd_init(genpd, &simple_qos_governor, false);
|
||||
genpd->attach_dev = cpg_mssr_attach_dev;
|
||||
genpd->detach_dev = cpg_mssr_detach_dev;
|
||||
cpg_mssr_clk_domain = pd;
|
||||
|
||||
of_genpd_add_provider_simple(np, genpd);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int cpg_mssr_add_clk_domain(struct device *dev,
|
||||
const unsigned int *core_pm_clks,
|
||||
unsigned int num_core_pm_clks)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */
|
||||
|
||||
|
||||
static const struct of_device_id cpg_mssr_match[] = {
|
||||
#ifdef CONFIG_ARCH_R8A7795
|
||||
|
@ -37,6 +37,7 @@ enum clk_types {
|
||||
CLK_TYPE_IN, /* External Clock Input */
|
||||
CLK_TYPE_FF, /* Fixed Factor Clock */
|
||||
CLK_TYPE_DIV6P1, /* DIV6 Clock with 1 parent clock */
|
||||
CLK_TYPE_DIV6_RO, /* DIV6 Clock read only with extra divisor */
|
||||
|
||||
/* Custom definitions start here */
|
||||
CLK_TYPE_CUSTOM,
|
||||
@ -53,9 +54,8 @@ enum clk_types {
|
||||
DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
|
||||
#define DEF_DIV6P1(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset)
|
||||
#define DEF_SD(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
|
||||
|
||||
#define DEF_DIV6_RO(_name, _id, _parent, _offset, _div) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1)
|
||||
|
||||
/*
|
||||
* Definitions of Module Clocks
|
||||
|
@ -9,7 +9,8 @@ obj-$(CONFIG_MACH_DOVE) += dove/
|
||||
obj-y += fsl/
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_ARCH_QCOM) += qcom/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_ARCH_RENESAS) += renesas/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_SOC_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
|
7
drivers/soc/renesas/Makefile
Normal file
7
drivers/soc/renesas/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
obj-$(CONFIG_ARCH_R8A7779) += rcar-sysc.o r8a7779-sysc.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += rcar-sysc.o r8a7790-sysc.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += rcar-sysc.o r8a7791-sysc.o
|
||||
# R-Car M2-N is identical to R-Car M2-W w.r.t. power domains.
|
||||
obj-$(CONFIG_ARCH_R8A7793) += rcar-sysc.o r8a7791-sysc.o
|
||||
obj-$(CONFIG_ARCH_R8A7794) += rcar-sysc.o r8a7794-sysc.o
|
||||
obj-$(CONFIG_ARCH_R8A7795) += rcar-sysc.o r8a7795-sysc.o
|
34
drivers/soc/renesas/r8a7779-sysc.c
Normal file
34
drivers/soc/renesas/r8a7779-sysc.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Renesas R-Car H1 System Controller
|
||||
*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <dt-bindings/power/r8a7779-sysc.h>
|
||||
|
||||
#include "rcar-sysc.h"
|
||||
|
||||
static const struct rcar_sysc_area r8a7779_areas[] __initconst = {
|
||||
{ "always-on", 0, 0, R8A7779_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
||||
{ "arm1", 0x40, 1, R8A7779_PD_ARM1, R8A7779_PD_ALWAYS_ON,
|
||||
PD_CPU_CR },
|
||||
{ "arm2", 0x40, 2, R8A7779_PD_ARM2, R8A7779_PD_ALWAYS_ON,
|
||||
PD_CPU_CR },
|
||||
{ "arm3", 0x40, 3, R8A7779_PD_ARM3, R8A7779_PD_ALWAYS_ON,
|
||||
PD_CPU_CR },
|
||||
{ "sgx", 0xc0, 0, R8A7779_PD_SGX, R8A7779_PD_ALWAYS_ON },
|
||||
{ "vdp", 0x100, 0, R8A7779_PD_VDP, R8A7779_PD_ALWAYS_ON },
|
||||
{ "imp", 0x140, 0, R8A7779_PD_IMP, R8A7779_PD_ALWAYS_ON },
|
||||
};
|
||||
|
||||
const struct rcar_sysc_info r8a7779_sysc_info __initconst = {
|
||||
.areas = r8a7779_areas,
|
||||
.num_areas = ARRAY_SIZE(r8a7779_areas),
|
||||
};
|
48
drivers/soc/renesas/r8a7790-sysc.c
Normal file
48
drivers/soc/renesas/r8a7790-sysc.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Renesas R-Car H2 System Controller
|
||||
*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <dt-bindings/power/r8a7790-sysc.h>
|
||||
|
||||
#include "rcar-sysc.h"
|
||||
|
||||
static const struct rcar_sysc_area r8a7790_areas[] __initconst = {
|
||||
{ "always-on", 0, 0, R8A7790_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
||||
{ "ca15-scu", 0x180, 0, R8A7790_PD_CA15_SCU, R8A7790_PD_ALWAYS_ON,
|
||||
PD_SCU },
|
||||
{ "ca15-cpu0", 0x40, 0, R8A7790_PD_CA15_CPU0, R8A7790_PD_CA15_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca15-cpu1", 0x40, 1, R8A7790_PD_CA15_CPU1, R8A7790_PD_CA15_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca15-cpu2", 0x40, 2, R8A7790_PD_CA15_CPU2, R8A7790_PD_CA15_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca15-cpu3", 0x40, 3, R8A7790_PD_CA15_CPU3, R8A7790_PD_CA15_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca7-scu", 0x100, 0, R8A7790_PD_CA7_SCU, R8A7790_PD_ALWAYS_ON,
|
||||
PD_SCU },
|
||||
{ "ca7-cpu0", 0x1c0, 0, R8A7790_PD_CA7_CPU0, R8A7790_PD_CA7_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca7-cpu1", 0x1c0, 1, R8A7790_PD_CA7_CPU1, R8A7790_PD_CA7_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca7-cpu2", 0x1c0, 2, R8A7790_PD_CA7_CPU2, R8A7790_PD_CA7_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca7-cpu3", 0x1c0, 3, R8A7790_PD_CA7_CPU3, R8A7790_PD_CA7_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "sh-4a", 0x80, 0, R8A7790_PD_SH_4A, R8A7790_PD_ALWAYS_ON },
|
||||
{ "rgx", 0xc0, 0, R8A7790_PD_RGX, R8A7790_PD_ALWAYS_ON },
|
||||
{ "imp", 0x140, 0, R8A7790_PD_IMP, R8A7790_PD_ALWAYS_ON },
|
||||
};
|
||||
|
||||
const struct rcar_sysc_info r8a7790_sysc_info __initconst = {
|
||||
.areas = r8a7790_areas,
|
||||
.num_areas = ARRAY_SIZE(r8a7790_areas),
|
||||
};
|
33
drivers/soc/renesas/r8a7791-sysc.c
Normal file
33
drivers/soc/renesas/r8a7791-sysc.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Renesas R-Car M2-W/N System Controller
|
||||
*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <dt-bindings/power/r8a7791-sysc.h>
|
||||
|
||||
#include "rcar-sysc.h"
|
||||
|
||||
static const struct rcar_sysc_area r8a7791_areas[] __initconst = {
|
||||
{ "always-on", 0, 0, R8A7791_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
||||
{ "ca15-scu", 0x180, 0, R8A7791_PD_CA15_SCU, R8A7791_PD_ALWAYS_ON,
|
||||
PD_SCU },
|
||||
{ "ca15-cpu0", 0x40, 0, R8A7791_PD_CA15_CPU0, R8A7791_PD_CA15_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca15-cpu1", 0x40, 1, R8A7791_PD_CA15_CPU1, R8A7791_PD_CA15_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "sh-4a", 0x80, 0, R8A7791_PD_SH_4A, R8A7791_PD_ALWAYS_ON },
|
||||
{ "sgx", 0xc0, 0, R8A7791_PD_SGX, R8A7791_PD_ALWAYS_ON },
|
||||
};
|
||||
|
||||
const struct rcar_sysc_info r8a7791_sysc_info __initconst = {
|
||||
.areas = r8a7791_areas,
|
||||
.num_areas = ARRAY_SIZE(r8a7791_areas),
|
||||
};
|
33
drivers/soc/renesas/r8a7794-sysc.c
Normal file
33
drivers/soc/renesas/r8a7794-sysc.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Renesas R-Car E2 System Controller
|
||||
*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <dt-bindings/power/r8a7794-sysc.h>
|
||||
|
||||
#include "rcar-sysc.h"
|
||||
|
||||
static const struct rcar_sysc_area r8a7794_areas[] __initconst = {
|
||||
{ "always-on", 0, 0, R8A7794_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
||||
{ "ca7-scu", 0x100, 0, R8A7794_PD_CA7_SCU, R8A7794_PD_ALWAYS_ON,
|
||||
PD_SCU },
|
||||
{ "ca7-cpu0", 0x1c0, 0, R8A7794_PD_CA7_CPU0, R8A7794_PD_CA7_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca7-cpu1", 0x1c0, 1, R8A7794_PD_CA7_CPU1, R8A7794_PD_CA7_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "sh-4a", 0x80, 0, R8A7794_PD_SH_4A, R8A7794_PD_ALWAYS_ON },
|
||||
{ "sgx", 0xc0, 0, R8A7794_PD_SGX, R8A7794_PD_ALWAYS_ON },
|
||||
};
|
||||
|
||||
const struct rcar_sysc_info r8a7794_sysc_info __initconst = {
|
||||
.areas = r8a7794_areas,
|
||||
.num_areas = ARRAY_SIZE(r8a7794_areas),
|
||||
};
|
56
drivers/soc/renesas/r8a7795-sysc.c
Normal file
56
drivers/soc/renesas/r8a7795-sysc.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Renesas R-Car H3 System Controller
|
||||
*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <dt-bindings/power/r8a7795-sysc.h>
|
||||
|
||||
#include "rcar-sysc.h"
|
||||
|
||||
static const struct rcar_sysc_area r8a7795_areas[] __initconst = {
|
||||
{ "always-on", 0, 0, R8A7795_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
||||
{ "ca57-scu", 0x1c0, 0, R8A7795_PD_CA57_SCU, R8A7795_PD_ALWAYS_ON,
|
||||
PD_SCU },
|
||||
{ "ca57-cpu0", 0x80, 0, R8A7795_PD_CA57_CPU0, R8A7795_PD_CA57_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca57-cpu1", 0x80, 1, R8A7795_PD_CA57_CPU1, R8A7795_PD_CA57_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca57-cpu2", 0x80, 2, R8A7795_PD_CA57_CPU2, R8A7795_PD_CA57_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca57-cpu3", 0x80, 3, R8A7795_PD_CA57_CPU3, R8A7795_PD_CA57_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca53-scu", 0x140, 0, R8A7795_PD_CA53_SCU, R8A7795_PD_ALWAYS_ON,
|
||||
PD_SCU },
|
||||
{ "ca53-cpu0", 0x200, 0, R8A7795_PD_CA53_CPU0, R8A7795_PD_CA53_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca53-cpu1", 0x200, 1, R8A7795_PD_CA53_CPU1, R8A7795_PD_CA53_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca53-cpu2", 0x200, 2, R8A7795_PD_CA53_CPU2, R8A7795_PD_CA53_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "ca53-cpu3", 0x200, 3, R8A7795_PD_CA53_CPU3, R8A7795_PD_CA53_SCU,
|
||||
PD_CPU_NOCR },
|
||||
{ "a3vp", 0x340, 0, R8A7795_PD_A3VP, R8A7795_PD_ALWAYS_ON },
|
||||
{ "cr7", 0x240, 0, R8A7795_PD_CR7, R8A7795_PD_ALWAYS_ON },
|
||||
{ "a3vc", 0x380, 0, R8A7795_PD_A3VC, R8A7795_PD_ALWAYS_ON },
|
||||
{ "a2vc0", 0x3c0, 0, R8A7795_PD_A2VC0, R8A7795_PD_A3VC },
|
||||
{ "a2vc1", 0x3c0, 1, R8A7795_PD_A2VC1, R8A7795_PD_A3VC },
|
||||
{ "3dg-a", 0x100, 0, R8A7795_PD_3DG_A, R8A7795_PD_ALWAYS_ON },
|
||||
{ "3dg-b", 0x100, 1, R8A7795_PD_3DG_B, R8A7795_PD_3DG_A },
|
||||
{ "3dg-c", 0x100, 2, R8A7795_PD_3DG_C, R8A7795_PD_3DG_B },
|
||||
{ "3dg-d", 0x100, 3, R8A7795_PD_3DG_D, R8A7795_PD_3DG_C },
|
||||
{ "3dg-e", 0x100, 4, R8A7795_PD_3DG_E, R8A7795_PD_3DG_D },
|
||||
{ "a3ir", 0x180, 0, R8A7795_PD_A3IR, R8A7795_PD_ALWAYS_ON },
|
||||
};
|
||||
|
||||
const struct rcar_sysc_info r8a7795_sysc_info __initconst = {
|
||||
.areas = r8a7795_areas,
|
||||
.num_areas = ARRAY_SIZE(r8a7795_areas),
|
||||
};
|
401
drivers/soc/renesas/rcar-sysc.c
Normal file
401
drivers/soc/renesas/rcar-sysc.c
Normal file
@ -0,0 +1,401 @@
|
||||
/*
|
||||
* R-Car SYSC Power management support
|
||||
*
|
||||
* Copyright (C) 2014 Magnus Damm
|
||||
* Copyright (C) 2015-2016 Glider bvba
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/soc/renesas/rcar-sysc.h>
|
||||
|
||||
#include "rcar-sysc.h"
|
||||
|
||||
/* SYSC Common */
|
||||
#define SYSCSR 0x00 /* SYSC Status Register */
|
||||
#define SYSCISR 0x04 /* Interrupt Status Register */
|
||||
#define SYSCISCR 0x08 /* Interrupt Status Clear Register */
|
||||
#define SYSCIER 0x0c /* Interrupt Enable Register */
|
||||
#define SYSCIMR 0x10 /* Interrupt Mask Register */
|
||||
|
||||
/* SYSC Status Register */
|
||||
#define SYSCSR_PONENB 1 /* Ready for power resume requests */
|
||||
#define SYSCSR_POFFENB 0 /* Ready for power shutoff requests */
|
||||
|
||||
/*
|
||||
* Power Control Register Offsets inside the register block for each domain
|
||||
* Note: The "CR" registers for ARM cores exist on H1 only
|
||||
* Use WFI to power off, CPG/APMU to resume ARM cores on R-Car Gen2
|
||||
* Use PSCI on R-Car Gen3
|
||||
*/
|
||||
#define PWRSR_OFFS 0x00 /* Power Status Register */
|
||||
#define PWROFFCR_OFFS 0x04 /* Power Shutoff Control Register */
|
||||
#define PWROFFSR_OFFS 0x08 /* Power Shutoff Status Register */
|
||||
#define PWRONCR_OFFS 0x0c /* Power Resume Control Register */
|
||||
#define PWRONSR_OFFS 0x10 /* Power Resume Status Register */
|
||||
#define PWRER_OFFS 0x14 /* Power Shutoff/Resume Error */
|
||||
|
||||
|
||||
#define SYSCSR_RETRIES 100
|
||||
#define SYSCSR_DELAY_US 1
|
||||
|
||||
#define PWRER_RETRIES 100
|
||||
#define PWRER_DELAY_US 1
|
||||
|
||||
#define SYSCISR_RETRIES 1000
|
||||
#define SYSCISR_DELAY_US 1
|
||||
|
||||
#define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */
|
||||
|
||||
static void __iomem *rcar_sysc_base;
|
||||
static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
|
||||
|
||||
static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
|
||||
{
|
||||
unsigned int sr_bit, reg_offs;
|
||||
int k;
|
||||
|
||||
if (on) {
|
||||
sr_bit = SYSCSR_PONENB;
|
||||
reg_offs = PWRONCR_OFFS;
|
||||
} else {
|
||||
sr_bit = SYSCSR_POFFENB;
|
||||
reg_offs = PWROFFCR_OFFS;
|
||||
}
|
||||
|
||||
/* Wait until SYSC is ready to accept a power request */
|
||||
for (k = 0; k < SYSCSR_RETRIES; k++) {
|
||||
if (ioread32(rcar_sysc_base + SYSCSR) & BIT(sr_bit))
|
||||
break;
|
||||
udelay(SYSCSR_DELAY_US);
|
||||
}
|
||||
|
||||
if (k == SYSCSR_RETRIES)
|
||||
return -EAGAIN;
|
||||
|
||||
/* Submit power shutoff or power resume request */
|
||||
iowrite32(BIT(sysc_ch->chan_bit),
|
||||
rcar_sysc_base + sysc_ch->chan_offs + reg_offs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
|
||||
{
|
||||
unsigned int isr_mask = BIT(sysc_ch->isr_bit);
|
||||
unsigned int chan_mask = BIT(sysc_ch->chan_bit);
|
||||
unsigned int status;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
int k;
|
||||
|
||||
spin_lock_irqsave(&rcar_sysc_lock, flags);
|
||||
|
||||
iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
|
||||
|
||||
/* Submit power shutoff or resume request until it was accepted */
|
||||
for (k = 0; k < PWRER_RETRIES; k++) {
|
||||
ret = rcar_sysc_pwr_on_off(sysc_ch, on);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
status = ioread32(rcar_sysc_base +
|
||||
sysc_ch->chan_offs + PWRER_OFFS);
|
||||
if (!(status & chan_mask))
|
||||
break;
|
||||
|
||||
udelay(PWRER_DELAY_US);
|
||||
}
|
||||
|
||||
if (k == PWRER_RETRIES) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wait until the power shutoff or resume request has completed * */
|
||||
for (k = 0; k < SYSCISR_RETRIES; k++) {
|
||||
if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask)
|
||||
break;
|
||||
udelay(SYSCISR_DELAY_US);
|
||||
}
|
||||
|
||||
if (k == SYSCISR_RETRIES)
|
||||
ret = -EIO;
|
||||
|
||||
iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&rcar_sysc_lock, flags);
|
||||
|
||||
pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off",
|
||||
sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
|
||||
{
|
||||
return rcar_sysc_power(sysc_ch, false);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS);
|
||||
if (st & BIT(sysc_ch->chan_bit))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void __iomem *rcar_sysc_init(phys_addr_t base)
|
||||
{
|
||||
rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
|
||||
if (!rcar_sysc_base)
|
||||
panic("unable to ioremap R-Car SYSC hardware block\n");
|
||||
|
||||
return rcar_sysc_base;
|
||||
}
|
||||
|
||||
struct rcar_sysc_pd {
|
||||
struct generic_pm_domain genpd;
|
||||
struct rcar_sysc_ch ch;
|
||||
unsigned int flags;
|
||||
char name[0];
|
||||
};
|
||||
|
||||
static inline struct rcar_sysc_pd *to_rcar_pd(struct generic_pm_domain *d)
|
||||
{
|
||||
return container_of(d, struct rcar_sysc_pd, genpd);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (pd->flags & PD_NO_CR) {
|
||||
pr_debug("%s: Cannot control %s\n", __func__, genpd->name);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (pd->flags & PD_BUSY) {
|
||||
pr_debug("%s: %s busy\n", __func__, genpd->name);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return rcar_sysc_power_down(&pd->ch);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (pd->flags & PD_NO_CR) {
|
||||
pr_debug("%s: Cannot control %s\n", __func__, genpd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rcar_sysc_power_up(&pd->ch);
|
||||
}
|
||||
|
||||
static bool has_cpg_mstp;
|
||||
|
||||
static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
|
||||
{
|
||||
struct generic_pm_domain *genpd = &pd->genpd;
|
||||
const char *name = pd->genpd.name;
|
||||
struct dev_power_governor *gov = &simple_qos_governor;
|
||||
|
||||
if (pd->flags & PD_CPU) {
|
||||
/*
|
||||
* This domain contains a CPU core and therefore it should
|
||||
* only be turned off if the CPU is not in use.
|
||||
*/
|
||||
pr_debug("PM domain %s contains %s\n", name, "CPU");
|
||||
pd->flags |= PD_BUSY;
|
||||
gov = &pm_domain_always_on_gov;
|
||||
} else if (pd->flags & PD_SCU) {
|
||||
/*
|
||||
* This domain contains an SCU and cache-controller, and
|
||||
* therefore it should only be turned off if the CPU cores are
|
||||
* not in use.
|
||||
*/
|
||||
pr_debug("PM domain %s contains %s\n", name, "SCU");
|
||||
pd->flags |= PD_BUSY;
|
||||
gov = &pm_domain_always_on_gov;
|
||||
} else if (pd->flags & PD_NO_CR) {
|
||||
/*
|
||||
* This domain cannot be turned off.
|
||||
*/
|
||||
pd->flags |= PD_BUSY;
|
||||
gov = &pm_domain_always_on_gov;
|
||||
}
|
||||
|
||||
if (!(pd->flags & (PD_CPU | PD_SCU))) {
|
||||
/* Enable Clock Domain for I/O devices */
|
||||
genpd->flags = GENPD_FLAG_PM_CLK;
|
||||
if (has_cpg_mstp) {
|
||||
genpd->attach_dev = cpg_mstp_attach_dev;
|
||||
genpd->detach_dev = cpg_mstp_detach_dev;
|
||||
} else {
|
||||
genpd->attach_dev = cpg_mssr_attach_dev;
|
||||
genpd->detach_dev = cpg_mssr_detach_dev;
|
||||
}
|
||||
}
|
||||
|
||||
genpd->power_off = rcar_sysc_pd_power_off;
|
||||
genpd->power_on = rcar_sysc_pd_power_on;
|
||||
|
||||
if (pd->flags & (PD_CPU | PD_NO_CR)) {
|
||||
/* Skip CPUs (handled by SMP code) and areas without control */
|
||||
pr_debug("%s: Not touching %s\n", __func__, genpd->name);
|
||||
goto finalize;
|
||||
}
|
||||
|
||||
if (!rcar_sysc_power_is_off(&pd->ch)) {
|
||||
pr_debug("%s: %s is already powered\n", __func__, genpd->name);
|
||||
goto finalize;
|
||||
}
|
||||
|
||||
rcar_sysc_power_up(&pd->ch);
|
||||
|
||||
finalize:
|
||||
pm_genpd_init(genpd, gov, false);
|
||||
}
|
||||
|
||||
static const struct of_device_id rcar_sysc_matches[] = {
|
||||
#ifdef CONFIG_ARCH_R8A7779
|
||||
{ .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_R8A7790
|
||||
{ .compatible = "renesas,r8a7790-sysc", .data = &r8a7790_sysc_info },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_R8A7791
|
||||
{ .compatible = "renesas,r8a7791-sysc", .data = &r8a7791_sysc_info },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_R8A7793
|
||||
/* R-Car M2-N is identical to R-Car M2-W w.r.t. power domains. */
|
||||
{ .compatible = "renesas,r8a7793-sysc", .data = &r8a7791_sysc_info },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_R8A7794
|
||||
{ .compatible = "renesas,r8a7794-sysc", .data = &r8a7794_sysc_info },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_R8A7795
|
||||
{ .compatible = "renesas,r8a7795-sysc", .data = &r8a7795_sysc_info },
|
||||
#endif
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
struct rcar_pm_domains {
|
||||
struct genpd_onecell_data onecell_data;
|
||||
struct generic_pm_domain *domains[RCAR_PD_ALWAYS_ON + 1];
|
||||
};
|
||||
|
||||
static int __init rcar_sysc_pd_init(void)
|
||||
{
|
||||
const struct rcar_sysc_info *info;
|
||||
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;
|
||||
|
||||
np = of_find_matching_node_and_match(NULL, rcar_sysc_matches, &match);
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
info = match->data;
|
||||
|
||||
has_cpg_mstp = of_find_compatible_node(NULL, NULL,
|
||||
"renesas,cpg-mstp-clocks");
|
||||
|
||||
base = of_iomap(np, 0);
|
||||
if (!base) {
|
||||
pr_warn("%s: Cannot map regs\n", np->full_name);
|
||||
error = -ENOMEM;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
rcar_sysc_base = base;
|
||||
|
||||
domains = kzalloc(sizeof(*domains), GFP_KERNEL);
|
||||
if (!domains) {
|
||||
error = -ENOMEM;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
domains->onecell_data.domains = domains->domains;
|
||||
domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains);
|
||||
|
||||
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("%s: syscimr = 0x%08x\n", np->full_name, syscimr);
|
||||
iowrite32(syscimr, base + SYSCIMR);
|
||||
|
||||
/*
|
||||
* SYSC needs all interrupt sources enabled to control power.
|
||||
*/
|
||||
pr_debug("%s: syscier = 0x%08x\n", np->full_name, syscier);
|
||||
iowrite32(syscier, base + SYSCIER);
|
||||
|
||||
for (i = 0; i < info->num_areas; i++) {
|
||||
const struct rcar_sysc_area *area = &info->areas[i];
|
||||
struct rcar_sysc_pd *pd;
|
||||
|
||||
pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
|
||||
if (!pd) {
|
||||
error = -ENOMEM;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
strcpy(pd->name, area->name);
|
||||
pd->genpd.name = pd->name;
|
||||
pd->ch.chan_offs = area->chan_offs;
|
||||
pd->ch.chan_bit = area->chan_bit;
|
||||
pd->ch.isr_bit = area->isr_bit;
|
||||
pd->flags = area->flags;
|
||||
|
||||
rcar_sysc_pd_setup(pd);
|
||||
if (area->parent >= 0)
|
||||
pm_genpd_add_subdomain(domains->domains[area->parent],
|
||||
&pd->genpd);
|
||||
|
||||
domains->domains[area->isr_bit] = &pd->genpd;
|
||||
}
|
||||
|
||||
of_genpd_add_provider_onecell(np, &domains->onecell_data);
|
||||
|
||||
out_put:
|
||||
of_node_put(np);
|
||||
return error;
|
||||
}
|
||||
early_initcall(rcar_sysc_pd_init);
|
58
drivers/soc/renesas/rcar-sysc.h
Normal file
58
drivers/soc/renesas/rcar-sysc.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Renesas R-Car System Controller
|
||||
*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
#ifndef __SOC_RENESAS_RCAR_SYSC_H__
|
||||
#define __SOC_RENESAS_RCAR_SYSC_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
|
||||
/*
|
||||
* Power Domain flags
|
||||
*/
|
||||
#define PD_CPU BIT(0) /* Area contains main CPU core */
|
||||
#define PD_SCU BIT(1) /* Area contains SCU and L2 cache */
|
||||
#define PD_NO_CR BIT(2) /* Area lacks PWR{ON,OFF}CR registers */
|
||||
|
||||
#define PD_BUSY BIT(3) /* Busy, for internal use only */
|
||||
|
||||
#define PD_CPU_CR PD_CPU /* CPU area has CR (R-Car H1) */
|
||||
#define PD_CPU_NOCR PD_CPU | PD_NO_CR /* CPU area lacks CR (R-Car Gen2/3) */
|
||||
#define PD_ALWAYS_ON PD_NO_CR /* Always-on area */
|
||||
|
||||
|
||||
/*
|
||||
* Description of a Power Area
|
||||
*/
|
||||
|
||||
struct rcar_sysc_area {
|
||||
const char *name;
|
||||
u16 chan_offs; /* Offset of PWRSR register for this area */
|
||||
u8 chan_bit; /* Bit in PWR* (except for PWRUP in PWRSR) */
|
||||
u8 isr_bit; /* Bit in SYSCI*R */
|
||||
int parent; /* -1 if none */
|
||||
unsigned int flags; /* See PD_* */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* SoC-specific Power Area Description
|
||||
*/
|
||||
|
||||
struct rcar_sysc_info {
|
||||
const struct rcar_sysc_area *areas;
|
||||
unsigned int num_areas;
|
||||
};
|
||||
|
||||
extern const struct rcar_sysc_info r8a7779_sysc_info;
|
||||
extern const struct rcar_sysc_info r8a7790_sysc_info;
|
||||
extern const struct rcar_sysc_info r8a7791_sysc_info;
|
||||
extern const struct rcar_sysc_info r8a7794_sysc_info;
|
||||
extern const struct rcar_sysc_info r8a7795_sysc_info;
|
||||
#endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
|
27
include/dt-bindings/power/r8a7779-sysc.h
Normal file
27
include/dt-bindings/power/r8a7779-sysc.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_R8A7779_SYSC_H__
|
||||
#define __DT_BINDINGS_POWER_R8A7779_SYSC_H__
|
||||
|
||||
/*
|
||||
* These power domain indices match the numbers of the interrupt bits
|
||||
* representing the power areas in the various Interrupt Registers
|
||||
* (e.g. SYSCISR, Interrupt Status Register)
|
||||
*/
|
||||
|
||||
#define R8A7779_PD_ARM1 1
|
||||
#define R8A7779_PD_ARM2 2
|
||||
#define R8A7779_PD_ARM3 3
|
||||
#define R8A7779_PD_SGX 20
|
||||
#define R8A7779_PD_VDP 21
|
||||
#define R8A7779_PD_IMP 24
|
||||
|
||||
/* Always-on power area */
|
||||
#define R8A7779_PD_ALWAYS_ON 32
|
||||
|
||||
#endif /* __DT_BINDINGS_POWER_R8A7779_SYSC_H__ */
|
34
include/dt-bindings/power/r8a7790-sysc.h
Normal file
34
include/dt-bindings/power/r8a7790-sysc.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_R8A7790_SYSC_H__
|
||||
#define __DT_BINDINGS_POWER_R8A7790_SYSC_H__
|
||||
|
||||
/*
|
||||
* These power domain indices match the numbers of the interrupt bits
|
||||
* representing the power areas in the various Interrupt Registers
|
||||
* (e.g. SYSCISR, Interrupt Status Register)
|
||||
*/
|
||||
|
||||
#define R8A7790_PD_CA15_CPU0 0
|
||||
#define R8A7790_PD_CA15_CPU1 1
|
||||
#define R8A7790_PD_CA15_CPU2 2
|
||||
#define R8A7790_PD_CA15_CPU3 3
|
||||
#define R8A7790_PD_CA7_CPU0 5
|
||||
#define R8A7790_PD_CA7_CPU1 6
|
||||
#define R8A7790_PD_CA7_CPU2 7
|
||||
#define R8A7790_PD_CA7_CPU3 8
|
||||
#define R8A7790_PD_CA15_SCU 12
|
||||
#define R8A7790_PD_SH_4A 16
|
||||
#define R8A7790_PD_RGX 20
|
||||
#define R8A7790_PD_CA7_SCU 21
|
||||
#define R8A7790_PD_IMP 24
|
||||
|
||||
/* Always-on power area */
|
||||
#define R8A7790_PD_ALWAYS_ON 32
|
||||
|
||||
#endif /* __DT_BINDINGS_POWER_R8A7790_SYSC_H__ */
|
26
include/dt-bindings/power/r8a7791-sysc.h
Normal file
26
include/dt-bindings/power/r8a7791-sysc.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_R8A7791_SYSC_H__
|
||||
#define __DT_BINDINGS_POWER_R8A7791_SYSC_H__
|
||||
|
||||
/*
|
||||
* These power domain indices match the numbers of the interrupt bits
|
||||
* representing the power areas in the various Interrupt Registers
|
||||
* (e.g. SYSCISR, Interrupt Status Register)
|
||||
*/
|
||||
|
||||
#define R8A7791_PD_CA15_CPU0 0
|
||||
#define R8A7791_PD_CA15_CPU1 1
|
||||
#define R8A7791_PD_CA15_SCU 12
|
||||
#define R8A7791_PD_SH_4A 16
|
||||
#define R8A7791_PD_SGX 20
|
||||
|
||||
/* Always-on power area */
|
||||
#define R8A7791_PD_ALWAYS_ON 32
|
||||
|
||||
#endif /* __DT_BINDINGS_POWER_R8A7791_SYSC_H__ */
|
28
include/dt-bindings/power/r8a7793-sysc.h
Normal file
28
include/dt-bindings/power/r8a7793-sysc.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_R8A7793_SYSC_H__
|
||||
#define __DT_BINDINGS_POWER_R8A7793_SYSC_H__
|
||||
|
||||
/*
|
||||
* These power domain indices match the numbers of the interrupt bits
|
||||
* representing the power areas in the various Interrupt Registers
|
||||
* (e.g. SYSCISR, Interrupt Status Register)
|
||||
*
|
||||
* Note that R-Car M2-N is identical to R-Car M2-W w.r.t. power domains.
|
||||
*/
|
||||
|
||||
#define R8A7793_PD_CA15_CPU0 0
|
||||
#define R8A7793_PD_CA15_CPU1 1
|
||||
#define R8A7793_PD_CA15_SCU 12
|
||||
#define R8A7793_PD_SH_4A 16
|
||||
#define R8A7793_PD_SGX 20
|
||||
|
||||
/* Always-on power area */
|
||||
#define R8A7793_PD_ALWAYS_ON 32
|
||||
|
||||
#endif /* __DT_BINDINGS_POWER_R8A7793_SYSC_H__ */
|
26
include/dt-bindings/power/r8a7794-sysc.h
Normal file
26
include/dt-bindings/power/r8a7794-sysc.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_R8A7794_SYSC_H__
|
||||
#define __DT_BINDINGS_POWER_R8A7794_SYSC_H__
|
||||
|
||||
/*
|
||||
* These power domain indices match the numbers of the interrupt bits
|
||||
* representing the power areas in the various Interrupt Registers
|
||||
* (e.g. SYSCISR, Interrupt Status Register)
|
||||
*/
|
||||
|
||||
#define R8A7794_PD_CA7_CPU0 5
|
||||
#define R8A7794_PD_CA7_CPU1 6
|
||||
#define R8A7794_PD_SH_4A 16
|
||||
#define R8A7794_PD_SGX 20
|
||||
#define R8A7794_PD_CA7_SCU 21
|
||||
|
||||
/* Always-on power area */
|
||||
#define R8A7794_PD_ALWAYS_ON 32
|
||||
|
||||
#endif /* __DT_BINDINGS_POWER_R8A7794_SYSC_H__ */
|
42
include/dt-bindings/power/r8a7795-sysc.h
Normal file
42
include/dt-bindings/power/r8a7795-sysc.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_R8A7795_SYSC_H__
|
||||
#define __DT_BINDINGS_POWER_R8A7795_SYSC_H__
|
||||
|
||||
/*
|
||||
* These power domain indices match the numbers of the interrupt bits
|
||||
* representing the power areas in the various Interrupt Registers
|
||||
* (e.g. SYSCISR, Interrupt Status Register)
|
||||
*/
|
||||
|
||||
#define R8A7795_PD_CA57_CPU0 0
|
||||
#define R8A7795_PD_CA57_CPU1 1
|
||||
#define R8A7795_PD_CA57_CPU2 2
|
||||
#define R8A7795_PD_CA57_CPU3 3
|
||||
#define R8A7795_PD_CA53_CPU0 5
|
||||
#define R8A7795_PD_CA53_CPU1 6
|
||||
#define R8A7795_PD_CA53_CPU2 7
|
||||
#define R8A7795_PD_CA53_CPU3 8
|
||||
#define R8A7795_PD_A3VP 9
|
||||
#define R8A7795_PD_CA57_SCU 12
|
||||
#define R8A7795_PD_CR7 13
|
||||
#define R8A7795_PD_A3VC 14
|
||||
#define R8A7795_PD_3DG_A 17
|
||||
#define R8A7795_PD_3DG_B 18
|
||||
#define R8A7795_PD_3DG_C 19
|
||||
#define R8A7795_PD_3DG_D 20
|
||||
#define R8A7795_PD_CA53_SCU 21
|
||||
#define R8A7795_PD_3DG_E 22
|
||||
#define R8A7795_PD_A3IR 24
|
||||
#define R8A7795_PD_A2VC0 25
|
||||
#define R8A7795_PD_A2VC1 26
|
||||
|
||||
/* Always-on power area */
|
||||
#define R8A7795_PD_ALWAYS_ON 32
|
||||
|
||||
#endif /* __DT_BINDINGS_POWER_R8A7795_SYSC_H__ */
|
@ -24,12 +24,20 @@ void r8a7778_clocks_init(u32 mode);
|
||||
void r8a7779_clocks_init(u32 mode);
|
||||
void rcar_gen2_clocks_init(u32 mode);
|
||||
|
||||
#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
|
||||
void cpg_mstp_add_clk_domain(struct device_node *np);
|
||||
int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev);
|
||||
void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev);
|
||||
#ifdef CONFIG_CLK_RENESAS_CPG_MSTP
|
||||
int cpg_mstp_attach_dev(struct generic_pm_domain *unused, struct device *dev);
|
||||
void cpg_mstp_detach_dev(struct generic_pm_domain *unused, struct device *dev);
|
||||
#else
|
||||
static inline void cpg_mstp_add_clk_domain(struct device_node *np) {}
|
||||
#define cpg_mstp_attach_dev NULL
|
||||
#define cpg_mstp_detach_dev NULL
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLK_RENESAS_CPG_MSSR
|
||||
int cpg_mssr_attach_dev(struct generic_pm_domain *unused, struct device *dev);
|
||||
void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev);
|
||||
#else
|
||||
#define cpg_mssr_attach_dev NULL
|
||||
#define cpg_mssr_detach_dev NULL
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,5 +1,7 @@
|
||||
#ifndef PM_RCAR_H
|
||||
#define PM_RCAR_H
|
||||
#ifndef __LINUX_SOC_RENESAS_RCAR_SYSC_H__
|
||||
#define __LINUX_SOC_RENESAS_RCAR_SYSC_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct rcar_sysc_ch {
|
||||
u16 chan_offs;
|
||||
@ -9,7 +11,6 @@ struct rcar_sysc_ch {
|
||||
|
||||
int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch);
|
||||
int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch);
|
||||
bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch);
|
||||
void __iomem *rcar_sysc_init(phys_addr_t base);
|
||||
|
||||
#endif /* PM_RCAR_H */
|
||||
#endif /* __LINUX_SOC_RENESAS_RCAR_SYSC_H__ */
|
Loading…
Reference in New Issue
Block a user