* [PATCH] arm: exynos: Support cluster power off on exynos5420/5800
@ 2014-06-18 15:18 ` Abhilash Kesavan
0 siblings, 0 replies; 12+ messages in thread
From: Abhilash Kesavan @ 2014-06-18 15:18 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc, kgene.kim, nicolas.pitre
Cc: kesavan.abhilash, abrestic
Turning off a cluster when all 4 cores of the cluster are powered off
saves power significantly. Powering off the A15 L2 alone gives around
100mW in savings. Add support for powering off the A15/A7 clusters on
exynos5420/5800.
The patch enables specific register bits which ensure that:
- cluster L2 will be turned on before the first man is powered up.
- last man will be turned off before the cluster L2 is turned off.
- core is powered down before powering it up.
Remove the exynos_cluster_power_control function completely as we can
rely on the above mentioned bits rather than polling the cluster power
status register.
Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
---
The patch is based on Linux-next 20140618. It has been tested on an
exynos5420-based chromebook using the "/dev/bL_switcher" interface as
well as the script provided by Nicolas Pitre and Dave Martin [1].
Patch depends on:
[v2] ARM: EXYNOS: mcpm: Don't rely on firmware's secondary_cpu_start
[1] http://www.spinics.net/lists/linux-samsung-soc/msg31257.html
arch/arm/mach-exynos/mcpm-exynos.c | 66 ++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 35 deletions(-)
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index ace0ed6..95b5acf 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -26,6 +26,10 @@
#define EXYNOS5420_CPUS_PER_CLUSTER 4
#define EXYNOS5420_NR_CLUSTERS 2
+#define EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN BIT(9)
+#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
+#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
+
/*
* The common v7_exit_coherency_flush API could not be used because of the
* Erratum 799270 workaround. This macro is the same as the common one (in
@@ -73,36 +77,9 @@ cpu_use_count[EXYNOS5420_CPUS_PER_CLUSTER][EXYNOS5420_NR_CLUSTERS];
#define exynos_cluster_unused(cluster) !exynos_cluster_usecnt(cluster)
-static int exynos_cluster_power_control(unsigned int cluster, int enable)
-{
- unsigned int tries = 100;
- unsigned int val;
-
- if (enable) {
- exynos_cluster_power_up(cluster);
- val = S5P_CORE_LOCAL_PWR_EN;
- } else {
- exynos_cluster_power_down(cluster);
- val = 0;
- }
-
- /* Wait until cluster power control is applied */
- while (tries--) {
- if (exynos_cluster_power_state(cluster) == val)
- return 0;
-
- cpu_relax();
- }
- pr_debug("timed out waiting for cluster %u to power %s\n", cluster,
- enable ? "on" : "off");
-
- return -ETIMEDOUT;
-}
-
static int exynos_power_up(unsigned int cpu, unsigned int cluster)
{
unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER);
- int err = 0;
pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER ||
@@ -126,12 +103,9 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
* cores.
*/
if (was_cluster_down)
- err = exynos_cluster_power_control(cluster, 1);
+ exynos_cluster_power_up(cluster);
- if (!err)
- exynos_cpu_power_up(cpunr);
- else
- exynos_cluster_power_control(cluster, 0);
+ exynos_cpu_power_up(cpunr);
} else if (cpu_use_count[cpu][cluster] != 2) {
/*
* The only possible values are:
@@ -147,7 +121,7 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
arch_spin_unlock(&exynos_mcpm_lock);
local_irq_enable();
- return err;
+ return 0;
}
/*
@@ -178,9 +152,10 @@ static void exynos_power_down(void)
if (cpu_use_count[cpu][cluster] == 0) {
exynos_cpu_power_down(cpunr);
- if (exynos_cluster_unused(cluster))
- /* TODO: Turn off the cluster here to save power. */
+ if (exynos_cluster_unused(cluster)) {
+ exynos_cluster_power_down(cluster);
last_man = true;
+ }
} else if (cpu_use_count[cpu][cluster] == 1) {
/*
* A power_up request went ahead of us.
@@ -299,6 +274,7 @@ static int __init exynos_mcpm_init(void)
{
struct device_node *node;
void __iomem *ns_sram_base_addr;
+ unsigned int value, i;
int ret;
node = of_find_matching_node(NULL, exynos_dt_mcpm_match);
@@ -342,6 +318,26 @@ static int __init exynos_mcpm_init(void)
pr_info("Exynos MCPM support installed\n");
/*
+ * On Exynos5420/5800 for the A15 and A7 clusters:
+ *
+ * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
+ * in a cluster are turned off before turning off the cluster L2.
+ *
+ * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
+ * off before waking it up.
+ *
+ * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
+ * turned on before the first man is powered up.
+ */
+ for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
+ value = __raw_readl(EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
+ value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
+ EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
+ EXYNOS5420_USE_L2_COMMON_UP_STATE;
+ __raw_writel(value, EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
+ }
+
+ /*
* U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
* as part of secondary_cpu_start(). Let's redirect it to the
* mcpm_entry_point().
--
2.0.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH] arm: exynos: Support cluster power off on exynos5420/5800
@ 2014-06-18 15:18 ` Abhilash Kesavan
0 siblings, 0 replies; 12+ messages in thread
From: Abhilash Kesavan @ 2014-06-18 15:18 UTC (permalink / raw)
To: linux-arm-kernel
Turning off a cluster when all 4 cores of the cluster are powered off
saves power significantly. Powering off the A15 L2 alone gives around
100mW in savings. Add support for powering off the A15/A7 clusters on
exynos5420/5800.
The patch enables specific register bits which ensure that:
- cluster L2 will be turned on before the first man is powered up.
- last man will be turned off before the cluster L2 is turned off.
- core is powered down before powering it up.
Remove the exynos_cluster_power_control function completely as we can
rely on the above mentioned bits rather than polling the cluster power
status register.
Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
---
The patch is based on Linux-next 20140618. It has been tested on an
exynos5420-based chromebook using the "/dev/bL_switcher" interface as
well as the script provided by Nicolas Pitre and Dave Martin [1].
Patch depends on:
[v2] ARM: EXYNOS: mcpm: Don't rely on firmware's secondary_cpu_start
[1] http://www.spinics.net/lists/linux-samsung-soc/msg31257.html
arch/arm/mach-exynos/mcpm-exynos.c | 66 ++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 35 deletions(-)
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index ace0ed6..95b5acf 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -26,6 +26,10 @@
#define EXYNOS5420_CPUS_PER_CLUSTER 4
#define EXYNOS5420_NR_CLUSTERS 2
+#define EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN BIT(9)
+#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
+#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
+
/*
* The common v7_exit_coherency_flush API could not be used because of the
* Erratum 799270 workaround. This macro is the same as the common one (in
@@ -73,36 +77,9 @@ cpu_use_count[EXYNOS5420_CPUS_PER_CLUSTER][EXYNOS5420_NR_CLUSTERS];
#define exynos_cluster_unused(cluster) !exynos_cluster_usecnt(cluster)
-static int exynos_cluster_power_control(unsigned int cluster, int enable)
-{
- unsigned int tries = 100;
- unsigned int val;
-
- if (enable) {
- exynos_cluster_power_up(cluster);
- val = S5P_CORE_LOCAL_PWR_EN;
- } else {
- exynos_cluster_power_down(cluster);
- val = 0;
- }
-
- /* Wait until cluster power control is applied */
- while (tries--) {
- if (exynos_cluster_power_state(cluster) == val)
- return 0;
-
- cpu_relax();
- }
- pr_debug("timed out waiting for cluster %u to power %s\n", cluster,
- enable ? "on" : "off");
-
- return -ETIMEDOUT;
-}
-
static int exynos_power_up(unsigned int cpu, unsigned int cluster)
{
unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER);
- int err = 0;
pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER ||
@@ -126,12 +103,9 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
* cores.
*/
if (was_cluster_down)
- err = exynos_cluster_power_control(cluster, 1);
+ exynos_cluster_power_up(cluster);
- if (!err)
- exynos_cpu_power_up(cpunr);
- else
- exynos_cluster_power_control(cluster, 0);
+ exynos_cpu_power_up(cpunr);
} else if (cpu_use_count[cpu][cluster] != 2) {
/*
* The only possible values are:
@@ -147,7 +121,7 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
arch_spin_unlock(&exynos_mcpm_lock);
local_irq_enable();
- return err;
+ return 0;
}
/*
@@ -178,9 +152,10 @@ static void exynos_power_down(void)
if (cpu_use_count[cpu][cluster] == 0) {
exynos_cpu_power_down(cpunr);
- if (exynos_cluster_unused(cluster))
- /* TODO: Turn off the cluster here to save power. */
+ if (exynos_cluster_unused(cluster)) {
+ exynos_cluster_power_down(cluster);
last_man = true;
+ }
} else if (cpu_use_count[cpu][cluster] == 1) {
/*
* A power_up request went ahead of us.
@@ -299,6 +274,7 @@ static int __init exynos_mcpm_init(void)
{
struct device_node *node;
void __iomem *ns_sram_base_addr;
+ unsigned int value, i;
int ret;
node = of_find_matching_node(NULL, exynos_dt_mcpm_match);
@@ -342,6 +318,26 @@ static int __init exynos_mcpm_init(void)
pr_info("Exynos MCPM support installed\n");
/*
+ * On Exynos5420/5800 for the A15 and A7 clusters:
+ *
+ * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
+ * in a cluster are turned off before turning off the cluster L2.
+ *
+ * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
+ * off before waking it up.
+ *
+ * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
+ * turned on before the first man is powered up.
+ */
+ for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
+ value = __raw_readl(EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
+ value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
+ EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
+ EXYNOS5420_USE_L2_COMMON_UP_STATE;
+ __raw_writel(value, EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
+ }
+
+ /*
* U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
* as part of secondary_cpu_start(). Let's redirect it to the
* mcpm_entry_point().
--
2.0.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] arm: exynos: Support cluster power off on exynos5420/5800
2014-06-18 15:18 ` Abhilash Kesavan
@ 2014-06-18 15:40 ` Nicolas Pitre
-1 siblings, 0 replies; 12+ messages in thread
From: Nicolas Pitre @ 2014-06-18 15:40 UTC (permalink / raw)
To: Abhilash Kesavan
Cc: linux-arm-kernel, linux-samsung-soc, kgene.kim, kesavan.abhilash,
abrestic
On Wed, 18 Jun 2014, Abhilash Kesavan wrote:
> Turning off a cluster when all 4 cores of the cluster are powered off
> saves power significantly. Powering off the A15 L2 alone gives around
> 100mW in savings. Add support for powering off the A15/A7 clusters on
> exynos5420/5800.
>
> The patch enables specific register bits which ensure that:
> - cluster L2 will be turned on before the first man is powered up.
> - last man will be turned off before the cluster L2 is turned off.
> - core is powered down before powering it up.
>
> Remove the exynos_cluster_power_control function completely as we can
> rely on the above mentioned bits rather than polling the cluster power
> status register.
>
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
Minor nit below:
> @@ -342,6 +318,26 @@ static int __init exynos_mcpm_init(void)
> pr_info("Exynos MCPM support installed\n");
>
> /*
> + * On Exynos5420/5800 for the A15 and A7 clusters:
> + *
> + * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
> + * in a cluster are turned off before turning off the cluster L2.
> + *
> + * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
> + * off before waking it up.
> + *
> + * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
> + * turned on before the first man is powered up.
> + */
> + for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
> + value = __raw_readl(EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
> + value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
> + EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
> + EXYNOS5420_USE_L2_COMMON_UP_STATE;
> + __raw_writel(value, EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
Surely you can add another define in mach-exynos/regs-pmu.h to better
identify this register instead of EXYNOS_COMMON_CONFIGURATION()+8 ?
After that, you may add:
Acked-by: Nicolas Pitre <nico@linaro.org>
Nicolas
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: exynos: Support cluster power off on exynos5420/5800
@ 2014-06-18 15:40 ` Nicolas Pitre
0 siblings, 0 replies; 12+ messages in thread
From: Nicolas Pitre @ 2014-06-18 15:40 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, 18 Jun 2014, Abhilash Kesavan wrote:
> Turning off a cluster when all 4 cores of the cluster are powered off
> saves power significantly. Powering off the A15 L2 alone gives around
> 100mW in savings. Add support for powering off the A15/A7 clusters on
> exynos5420/5800.
>
> The patch enables specific register bits which ensure that:
> - cluster L2 will be turned on before the first man is powered up.
> - last man will be turned off before the cluster L2 is turned off.
> - core is powered down before powering it up.
>
> Remove the exynos_cluster_power_control function completely as we can
> rely on the above mentioned bits rather than polling the cluster power
> status register.
>
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
Minor nit below:
> @@ -342,6 +318,26 @@ static int __init exynos_mcpm_init(void)
> pr_info("Exynos MCPM support installed\n");
>
> /*
> + * On Exynos5420/5800 for the A15 and A7 clusters:
> + *
> + * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
> + * in a cluster are turned off before turning off the cluster L2.
> + *
> + * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
> + * off before waking it up.
> + *
> + * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
> + * turned on before the first man is powered up.
> + */
> + for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
> + value = __raw_readl(EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
> + value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
> + EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
> + EXYNOS5420_USE_L2_COMMON_UP_STATE;
> + __raw_writel(value, EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
Surely you can add another define in mach-exynos/regs-pmu.h to better
identify this register instead of EXYNOS_COMMON_CONFIGURATION()+8 ?
After that, you may add:
Acked-by: Nicolas Pitre <nico@linaro.org>
Nicolas
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] arm: exynos: Support cluster power off on exynos5420/5800
2014-06-18 15:40 ` Nicolas Pitre
@ 2014-06-19 12:23 ` Abhilash Kesavan
-1 siblings, 0 replies; 12+ messages in thread
From: Abhilash Kesavan @ 2014-06-19 12:23 UTC (permalink / raw)
To: Nicolas Pitre
Cc: linux-arm-kernel, linux-samsung-soc, Kukjin Kim, Andrew Bresticker
Hi Nicolas,
On Wed, Jun 18, 2014 at 9:10 PM, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> On Wed, 18 Jun 2014, Abhilash Kesavan wrote:
>
>> Turning off a cluster when all 4 cores of the cluster are powered off
>> saves power significantly. Powering off the A15 L2 alone gives around
>> 100mW in savings. Add support for powering off the A15/A7 clusters on
>> exynos5420/5800.
>>
>> The patch enables specific register bits which ensure that:
>> - cluster L2 will be turned on before the first man is powered up.
>> - last man will be turned off before the cluster L2 is turned off.
>> - core is powered down before powering it up.
>>
>> Remove the exynos_cluster_power_control function completely as we can
>> rely on the above mentioned bits rather than polling the cluster power
>> status register.
>>
>> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
>
> Minor nit below:
>
>> @@ -342,6 +318,26 @@ static int __init exynos_mcpm_init(void)
>> pr_info("Exynos MCPM support installed\n");
>>
>> /*
>> + * On Exynos5420/5800 for the A15 and A7 clusters:
>> + *
>> + * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
>> + * in a cluster are turned off before turning off the cluster L2.
>> + *
>> + * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
>> + * off before waking it up.
>> + *
>> + * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
>> + * turned on before the first man is powered up.
>> + */
>> + for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
>> + value = __raw_readl(EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
>> + value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
>> + EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
>> + EXYNOS5420_USE_L2_COMMON_UP_STATE;
>> + __raw_writel(value, EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
>
> Surely you can add another define in mach-exynos/regs-pmu.h to better
> identify this register instead of EXYNOS_COMMON_CONFIGURATION()+8 ?
>
> After that, you may add:
>
> Acked-by: Nicolas Pitre <nico@linaro.org>
Thanks. Will fix and post v2 with your ack.
Regards,
Abhilash
>
>
> Nicolas
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] arm: exynos: Support cluster power off on exynos5420/5800
@ 2014-06-19 12:23 ` Abhilash Kesavan
0 siblings, 0 replies; 12+ messages in thread
From: Abhilash Kesavan @ 2014-06-19 12:23 UTC (permalink / raw)
To: linux-arm-kernel
Hi Nicolas,
On Wed, Jun 18, 2014 at 9:10 PM, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> On Wed, 18 Jun 2014, Abhilash Kesavan wrote:
>
>> Turning off a cluster when all 4 cores of the cluster are powered off
>> saves power significantly. Powering off the A15 L2 alone gives around
>> 100mW in savings. Add support for powering off the A15/A7 clusters on
>> exynos5420/5800.
>>
>> The patch enables specific register bits which ensure that:
>> - cluster L2 will be turned on before the first man is powered up.
>> - last man will be turned off before the cluster L2 is turned off.
>> - core is powered down before powering it up.
>>
>> Remove the exynos_cluster_power_control function completely as we can
>> rely on the above mentioned bits rather than polling the cluster power
>> status register.
>>
>> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
>
> Minor nit below:
>
>> @@ -342,6 +318,26 @@ static int __init exynos_mcpm_init(void)
>> pr_info("Exynos MCPM support installed\n");
>>
>> /*
>> + * On Exynos5420/5800 for the A15 and A7 clusters:
>> + *
>> + * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
>> + * in a cluster are turned off before turning off the cluster L2.
>> + *
>> + * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
>> + * off before waking it up.
>> + *
>> + * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
>> + * turned on before the first man is powered up.
>> + */
>> + for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
>> + value = __raw_readl(EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
>> + value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
>> + EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
>> + EXYNOS5420_USE_L2_COMMON_UP_STATE;
>> + __raw_writel(value, EXYNOS_COMMON_CONFIGURATION(i) + 0x8);
>
> Surely you can add another define in mach-exynos/regs-pmu.h to better
> identify this register instead of EXYNOS_COMMON_CONFIGURATION()+8 ?
>
> After that, you may add:
>
> Acked-by: Nicolas Pitre <nico@linaro.org>
Thanks. Will fix and post v2 with your ack.
Regards,
Abhilash
>
>
> Nicolas
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] arm: exynos: Support cluster power off on exynos5420/5800
2014-06-18 15:18 ` Abhilash Kesavan
@ 2014-06-19 12:40 ` Abhilash Kesavan
-1 siblings, 0 replies; 12+ messages in thread
From: Abhilash Kesavan @ 2014-06-19 12:40 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc, kgene.kim, nicolas.pitre
Cc: kesavan.abhilash, abrestic
Turning off a cluster when all 4 cores of the cluster are powered off
saves power significantly. Powering off the A15 L2 alone gives around
100mW in savings. Add support for powering off the A15/A7 clusters on
exynos5420/5800.
The patch enables specific register bits which ensure that:
- cluster L2 will be turned on before the first man is powered up.
- last man will be turned off before the cluster L2 is turned off.
- core is powered down before powering it up.
Remove the exynos_cluster_power_control function completely as we can
rely on the above mentioned bits rather than polling the cluster power
status register.
Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
---
Change in v2:
Added a macro for the COMMON_OPTION register and used it in the MCPM
back-end.
The patch is based on Linux-next 20140619. It has been tested on an
exynos5420-based chromebook using the "/dev/bL_switcher" interface as
well as the script provided by Nicolas Pitre and Dave Martin [1].
Patch depends on:
[v2] ARM: EXYNOS: mcpm: Don't rely on firmware's secondary_cpu_start
[1] http://www.spinics.net/lists/linux-samsung-soc/msg31257.html
arch/arm/mach-exynos/mcpm-exynos.c | 66 +++++++++++++++++-------------------
arch/arm/mach-exynos/regs-pmu.h | 2 ++
2 files changed, 33 insertions(+), 35 deletions(-)
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index ace0ed6..619cbc6 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -26,6 +26,10 @@
#define EXYNOS5420_CPUS_PER_CLUSTER 4
#define EXYNOS5420_NR_CLUSTERS 2
+#define EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN BIT(9)
+#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
+#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
+
/*
* The common v7_exit_coherency_flush API could not be used because of the
* Erratum 799270 workaround. This macro is the same as the common one (in
@@ -73,36 +77,9 @@ cpu_use_count[EXYNOS5420_CPUS_PER_CLUSTER][EXYNOS5420_NR_CLUSTERS];
#define exynos_cluster_unused(cluster) !exynos_cluster_usecnt(cluster)
-static int exynos_cluster_power_control(unsigned int cluster, int enable)
-{
- unsigned int tries = 100;
- unsigned int val;
-
- if (enable) {
- exynos_cluster_power_up(cluster);
- val = S5P_CORE_LOCAL_PWR_EN;
- } else {
- exynos_cluster_power_down(cluster);
- val = 0;
- }
-
- /* Wait until cluster power control is applied */
- while (tries--) {
- if (exynos_cluster_power_state(cluster) == val)
- return 0;
-
- cpu_relax();
- }
- pr_debug("timed out waiting for cluster %u to power %s\n", cluster,
- enable ? "on" : "off");
-
- return -ETIMEDOUT;
-}
-
static int exynos_power_up(unsigned int cpu, unsigned int cluster)
{
unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER);
- int err = 0;
pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER ||
@@ -126,12 +103,9 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
* cores.
*/
if (was_cluster_down)
- err = exynos_cluster_power_control(cluster, 1);
+ exynos_cluster_power_up(cluster);
- if (!err)
- exynos_cpu_power_up(cpunr);
- else
- exynos_cluster_power_control(cluster, 0);
+ exynos_cpu_power_up(cpunr);
} else if (cpu_use_count[cpu][cluster] != 2) {
/*
* The only possible values are:
@@ -147,7 +121,7 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
arch_spin_unlock(&exynos_mcpm_lock);
local_irq_enable();
- return err;
+ return 0;
}
/*
@@ -178,9 +152,10 @@ static void exynos_power_down(void)
if (cpu_use_count[cpu][cluster] == 0) {
exynos_cpu_power_down(cpunr);
- if (exynos_cluster_unused(cluster))
- /* TODO: Turn off the cluster here to save power. */
+ if (exynos_cluster_unused(cluster)) {
+ exynos_cluster_power_down(cluster);
last_man = true;
+ }
} else if (cpu_use_count[cpu][cluster] == 1) {
/*
* A power_up request went ahead of us.
@@ -299,6 +274,7 @@ static int __init exynos_mcpm_init(void)
{
struct device_node *node;
void __iomem *ns_sram_base_addr;
+ unsigned int value, i;
int ret;
node = of_find_matching_node(NULL, exynos_dt_mcpm_match);
@@ -342,6 +318,26 @@ static int __init exynos_mcpm_init(void)
pr_info("Exynos MCPM support installed\n");
/*
+ * On Exynos5420/5800 for the A15 and A7 clusters:
+ *
+ * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
+ * in a cluster are turned off before turning off the cluster L2.
+ *
+ * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
+ * off before waking it up.
+ *
+ * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
+ * turned on before the first man is powered up.
+ */
+ for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
+ value = __raw_readl(EXYNOS_COMMON_OPTION(i));
+ value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
+ EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
+ EXYNOS5420_USE_L2_COMMON_UP_STATE;
+ __raw_writel(value, EXYNOS_COMMON_OPTION(i));
+ }
+
+ /*
* U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
* as part of secondary_cpu_start(). Let's redirect it to the
* mcpm_entry_point().
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
index 1d13b08..bda8df0 100644
--- a/arch/arm/mach-exynos/regs-pmu.h
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -117,6 +117,8 @@
(EXYNOS_ARM_COMMON_CONFIGURATION + (0x80 * (_nr)))
#define EXYNOS_COMMON_STATUS(_nr) \
(EXYNOS_COMMON_CONFIGURATION(_nr) + 0x4)
+#define EXYNOS_COMMON_OPTION(_nr) \
+ (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8)
#define S5P_PAD_RET_MAUDIO_OPTION S5P_PMUREG(0x3028)
#define S5P_PAD_RET_GPIO_OPTION S5P_PMUREG(0x3108)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2] arm: exynos: Support cluster power off on exynos5420/5800
@ 2014-06-19 12:40 ` Abhilash Kesavan
0 siblings, 0 replies; 12+ messages in thread
From: Abhilash Kesavan @ 2014-06-19 12:40 UTC (permalink / raw)
To: linux-arm-kernel
Turning off a cluster when all 4 cores of the cluster are powered off
saves power significantly. Powering off the A15 L2 alone gives around
100mW in savings. Add support for powering off the A15/A7 clusters on
exynos5420/5800.
The patch enables specific register bits which ensure that:
- cluster L2 will be turned on before the first man is powered up.
- last man will be turned off before the cluster L2 is turned off.
- core is powered down before powering it up.
Remove the exynos_cluster_power_control function completely as we can
rely on the above mentioned bits rather than polling the cluster power
status register.
Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
---
Change in v2:
Added a macro for the COMMON_OPTION register and used it in the MCPM
back-end.
The patch is based on Linux-next 20140619. It has been tested on an
exynos5420-based chromebook using the "/dev/bL_switcher" interface as
well as the script provided by Nicolas Pitre and Dave Martin [1].
Patch depends on:
[v2] ARM: EXYNOS: mcpm: Don't rely on firmware's secondary_cpu_start
[1] http://www.spinics.net/lists/linux-samsung-soc/msg31257.html
arch/arm/mach-exynos/mcpm-exynos.c | 66 +++++++++++++++++-------------------
arch/arm/mach-exynos/regs-pmu.h | 2 ++
2 files changed, 33 insertions(+), 35 deletions(-)
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index ace0ed6..619cbc6 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -26,6 +26,10 @@
#define EXYNOS5420_CPUS_PER_CLUSTER 4
#define EXYNOS5420_NR_CLUSTERS 2
+#define EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN BIT(9)
+#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
+#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
+
/*
* The common v7_exit_coherency_flush API could not be used because of the
* Erratum 799270 workaround. This macro is the same as the common one (in
@@ -73,36 +77,9 @@ cpu_use_count[EXYNOS5420_CPUS_PER_CLUSTER][EXYNOS5420_NR_CLUSTERS];
#define exynos_cluster_unused(cluster) !exynos_cluster_usecnt(cluster)
-static int exynos_cluster_power_control(unsigned int cluster, int enable)
-{
- unsigned int tries = 100;
- unsigned int val;
-
- if (enable) {
- exynos_cluster_power_up(cluster);
- val = S5P_CORE_LOCAL_PWR_EN;
- } else {
- exynos_cluster_power_down(cluster);
- val = 0;
- }
-
- /* Wait until cluster power control is applied */
- while (tries--) {
- if (exynos_cluster_power_state(cluster) == val)
- return 0;
-
- cpu_relax();
- }
- pr_debug("timed out waiting for cluster %u to power %s\n", cluster,
- enable ? "on" : "off");
-
- return -ETIMEDOUT;
-}
-
static int exynos_power_up(unsigned int cpu, unsigned int cluster)
{
unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER);
- int err = 0;
pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER ||
@@ -126,12 +103,9 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
* cores.
*/
if (was_cluster_down)
- err = exynos_cluster_power_control(cluster, 1);
+ exynos_cluster_power_up(cluster);
- if (!err)
- exynos_cpu_power_up(cpunr);
- else
- exynos_cluster_power_control(cluster, 0);
+ exynos_cpu_power_up(cpunr);
} else if (cpu_use_count[cpu][cluster] != 2) {
/*
* The only possible values are:
@@ -147,7 +121,7 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
arch_spin_unlock(&exynos_mcpm_lock);
local_irq_enable();
- return err;
+ return 0;
}
/*
@@ -178,9 +152,10 @@ static void exynos_power_down(void)
if (cpu_use_count[cpu][cluster] == 0) {
exynos_cpu_power_down(cpunr);
- if (exynos_cluster_unused(cluster))
- /* TODO: Turn off the cluster here to save power. */
+ if (exynos_cluster_unused(cluster)) {
+ exynos_cluster_power_down(cluster);
last_man = true;
+ }
} else if (cpu_use_count[cpu][cluster] == 1) {
/*
* A power_up request went ahead of us.
@@ -299,6 +274,7 @@ static int __init exynos_mcpm_init(void)
{
struct device_node *node;
void __iomem *ns_sram_base_addr;
+ unsigned int value, i;
int ret;
node = of_find_matching_node(NULL, exynos_dt_mcpm_match);
@@ -342,6 +318,26 @@ static int __init exynos_mcpm_init(void)
pr_info("Exynos MCPM support installed\n");
/*
+ * On Exynos5420/5800 for the A15 and A7 clusters:
+ *
+ * EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
+ * in a cluster are turned off before turning off the cluster L2.
+ *
+ * EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
+ * off before waking it up.
+ *
+ * EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
+ * turned on before the first man is powered up.
+ */
+ for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
+ value = __raw_readl(EXYNOS_COMMON_OPTION(i));
+ value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
+ EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
+ EXYNOS5420_USE_L2_COMMON_UP_STATE;
+ __raw_writel(value, EXYNOS_COMMON_OPTION(i));
+ }
+
+ /*
* U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
* as part of secondary_cpu_start(). Let's redirect it to the
* mcpm_entry_point().
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
index 1d13b08..bda8df0 100644
--- a/arch/arm/mach-exynos/regs-pmu.h
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -117,6 +117,8 @@
(EXYNOS_ARM_COMMON_CONFIGURATION + (0x80 * (_nr)))
#define EXYNOS_COMMON_STATUS(_nr) \
(EXYNOS_COMMON_CONFIGURATION(_nr) + 0x4)
+#define EXYNOS_COMMON_OPTION(_nr) \
+ (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8)
#define S5P_PAD_RET_MAUDIO_OPTION S5P_PMUREG(0x3028)
#define S5P_PAD_RET_GPIO_OPTION S5P_PMUREG(0x3108)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2] arm: exynos: Support cluster power off on exynos5420/5800
2014-06-19 12:40 ` Abhilash Kesavan
@ 2014-06-19 20:34 ` Kevin Hilman
-1 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2014-06-19 20:34 UTC (permalink / raw)
To: Abhilash Kesavan
Cc: linux-arm-kernel, linux-samsung-soc, kgene.kim, nicolas.pitre,
kesavan.abhilash, abrestic
Abhilash Kesavan <a.kesavan@samsung.com> writes:
> Turning off a cluster when all 4 cores of the cluster are powered off
> saves power significantly. Powering off the A15 L2 alone gives around
> 100mW in savings. Add support for powering off the A15/A7 clusters on
> exynos5420/5800.
>
> The patch enables specific register bits which ensure that:
> - cluster L2 will be turned on before the first man is powered up.
> - last man will be turned off before the cluster L2 is turned off.
> - core is powered down before powering it up.
>
> Remove the exynos_cluster_power_control function completely as we can
> rely on the above mentioned bits rather than polling the cluster power
> status register.
>
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> Acked-by: Nicolas Pitre <nico@linaro.org>
> ---
> Change in v2:
> Added a macro for the COMMON_OPTION register and used it in the MCPM
> back-end.
>
> The patch is based on Linux-next 20140619. It has been tested on an
> exynos5420-based chromebook using the "/dev/bL_switcher" interface as
> well as the script provided by Nicolas Pitre and Dave Martin [1].
>
> Patch depends on:
> [v2] ARM: EXYNOS: mcpm: Don't rely on firmware's secondary_cpu_start
>
> [1] http://www.spinics.net/lists/linux-samsung-soc/msg31257.html
Tested on exynos5800/Chromebook2 along with the dependency patch and using
the script from Dave and Nico.
Tested-by: Kevin Hilman <khilman@linaro.org>
Kevin
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] arm: exynos: Support cluster power off on exynos5420/5800
@ 2014-06-19 20:34 ` Kevin Hilman
0 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2014-06-19 20:34 UTC (permalink / raw)
To: linux-arm-kernel
Abhilash Kesavan <a.kesavan@samsung.com> writes:
> Turning off a cluster when all 4 cores of the cluster are powered off
> saves power significantly. Powering off the A15 L2 alone gives around
> 100mW in savings. Add support for powering off the A15/A7 clusters on
> exynos5420/5800.
>
> The patch enables specific register bits which ensure that:
> - cluster L2 will be turned on before the first man is powered up.
> - last man will be turned off before the cluster L2 is turned off.
> - core is powered down before powering it up.
>
> Remove the exynos_cluster_power_control function completely as we can
> rely on the above mentioned bits rather than polling the cluster power
> status register.
>
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> Acked-by: Nicolas Pitre <nico@linaro.org>
> ---
> Change in v2:
> Added a macro for the COMMON_OPTION register and used it in the MCPM
> back-end.
>
> The patch is based on Linux-next 20140619. It has been tested on an
> exynos5420-based chromebook using the "/dev/bL_switcher" interface as
> well as the script provided by Nicolas Pitre and Dave Martin [1].
>
> Patch depends on:
> [v2] ARM: EXYNOS: mcpm: Don't rely on firmware's secondary_cpu_start
>
> [1] http://www.spinics.net/lists/linux-samsung-soc/msg31257.html
Tested on exynos5800/Chromebook2 along with the dependency patch and using
the script from Dave and Nico.
Tested-by: Kevin Hilman <khilman@linaro.org>
Kevin
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v2] arm: exynos: Support cluster power off on exynos5420/5800
2014-06-19 20:34 ` Kevin Hilman
@ 2014-06-25 10:14 ` Kukjin Kim
-1 siblings, 0 replies; 12+ messages in thread
From: Kukjin Kim @ 2014-06-25 10:14 UTC (permalink / raw)
To: 'Kevin Hilman', 'Abhilash Kesavan'
Cc: linux-arm-kernel, linux-samsung-soc, nicolas.pitre,
kesavan.abhilash, abrestic
Kevin Hilman wrote:
>
> Abhilash Kesavan <a.kesavan@samsung.com> writes:
>
Hi,
> > Turning off a cluster when all 4 cores of the cluster are powered off
> > saves power significantly. Powering off the A15 L2 alone gives around
> > 100mW in savings. Add support for powering off the A15/A7 clusters on
> > exynos5420/5800.
> >
> > The patch enables specific register bits which ensure that:
> > - cluster L2 will be turned on before the first man is powered up.
> > - last man will be turned off before the cluster L2 is turned off.
> > - core is powered down before powering it up.
> >
> > Remove the exynos_cluster_power_control function completely as we can
> > rely on the above mentioned bits rather than polling the cluster power
> > status register.
> >
> > Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> > Acked-by: Nicolas Pitre <nico@linaro.org>
> > ---
> > Change in v2:
> > Added a macro for the COMMON_OPTION register and used it in the MCPM
> > back-end.
> >
> > The patch is based on Linux-next 20140619. It has been tested on an
> > exynos5420-based chromebook using the "/dev/bL_switcher" interface as
> > well as the script provided by Nicolas Pitre and Dave Martin [1].
> >
> > Patch depends on:
> > [v2] ARM: EXYNOS: mcpm: Don't rely on firmware's secondary_cpu_start
> >
> > [1] http://www.spinics.net/lists/linux-samsung-soc/msg31257.html
>
> Tested on exynos5800/Chromebook2 along with the dependency patch and using
> the script from Dave and Nico.
>
> Tested-by: Kevin Hilman <khilman@linaro.org>
>
Kevin, thanks for your test on the board ;-)
Applied into samsung tree.
Thanks,
Kukjin
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] arm: exynos: Support cluster power off on exynos5420/5800
@ 2014-06-25 10:14 ` Kukjin Kim
0 siblings, 0 replies; 12+ messages in thread
From: Kukjin Kim @ 2014-06-25 10:14 UTC (permalink / raw)
To: linux-arm-kernel
Kevin Hilman wrote:
>
> Abhilash Kesavan <a.kesavan@samsung.com> writes:
>
Hi,
> > Turning off a cluster when all 4 cores of the cluster are powered off
> > saves power significantly. Powering off the A15 L2 alone gives around
> > 100mW in savings. Add support for powering off the A15/A7 clusters on
> > exynos5420/5800.
> >
> > The patch enables specific register bits which ensure that:
> > - cluster L2 will be turned on before the first man is powered up.
> > - last man will be turned off before the cluster L2 is turned off.
> > - core is powered down before powering it up.
> >
> > Remove the exynos_cluster_power_control function completely as we can
> > rely on the above mentioned bits rather than polling the cluster power
> > status register.
> >
> > Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> > Acked-by: Nicolas Pitre <nico@linaro.org>
> > ---
> > Change in v2:
> > Added a macro for the COMMON_OPTION register and used it in the MCPM
> > back-end.
> >
> > The patch is based on Linux-next 20140619. It has been tested on an
> > exynos5420-based chromebook using the "/dev/bL_switcher" interface as
> > well as the script provided by Nicolas Pitre and Dave Martin [1].
> >
> > Patch depends on:
> > [v2] ARM: EXYNOS: mcpm: Don't rely on firmware's secondary_cpu_start
> >
> > [1] http://www.spinics.net/lists/linux-samsung-soc/msg31257.html
>
> Tested on exynos5800/Chromebook2 along with the dependency patch and using
> the script from Dave and Nico.
>
> Tested-by: Kevin Hilman <khilman@linaro.org>
>
Kevin, thanks for your test on the board ;-)
Applied into samsung tree.
Thanks,
Kukjin
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2014-06-25 10:14 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-18 15:18 [PATCH] arm: exynos: Support cluster power off on exynos5420/5800 Abhilash Kesavan
2014-06-18 15:18 ` Abhilash Kesavan
2014-06-18 15:40 ` Nicolas Pitre
2014-06-18 15:40 ` Nicolas Pitre
2014-06-19 12:23 ` Abhilash Kesavan
2014-06-19 12:23 ` Abhilash Kesavan
2014-06-19 12:40 ` [PATCH v2] " Abhilash Kesavan
2014-06-19 12:40 ` Abhilash Kesavan
2014-06-19 20:34 ` Kevin Hilman
2014-06-19 20:34 ` Kevin Hilman
2014-06-25 10:14 ` Kukjin Kim
2014-06-25 10:14 ` Kukjin Kim
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.