Move architecture timer setup to platform-specific code

At present, bl1_arch_setup() and bl31_arch_setup() program the counter
frequency using a value from the memory mapped generic timer. The
generic timer however is not necessarily present on all ARM systems
(although it is architected to be present on all server systems).

This patch moves the timer setup to platform-specific code and updates
the relevant documentation. Also, CNTR.FCREQ is set as the specification
requires the bit corresponding to the counter's frequency to be set when
enabling. Since we intend to use the base frequency, set bit 8.

Fixes ARM-software/tf-issues#24

Change-Id: I32c52cf882253e01f49056f47c58c23e6f422652
diff --git a/bl1/aarch64/bl1_arch_setup.c b/bl1/aarch64/bl1_arch_setup.c
index 3a528e1..e82ad09 100644
--- a/bl1/aarch64/bl1_arch_setup.c
+++ b/bl1/aarch64/bl1_arch_setup.c
@@ -39,7 +39,6 @@
 void bl1_arch_setup(void)
 {
 	unsigned long tmp_reg = 0;
-	unsigned int counter_base_frequency;
 
 	/* Enable alignment checks and set the exception endianess to LE */
 	tmp_reg = read_sctlr();
@@ -61,13 +60,6 @@
 	enable_serror();
 	enable_debug_exceptions();
 
-	/* Read the frequency from Frequency modes table */
-	counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
-	/* The first entry of the frequency modes table must not be 0 */
-	assert(counter_base_frequency != 0);
-
-	/* Program the counter frequency */
-	write_cntfrq_el0(counter_base_frequency);
 	return;
 }
 
diff --git a/bl31/aarch64/bl31_arch_setup.c b/bl31/aarch64/bl31_arch_setup.c
index 03b9623..faeccf3 100644
--- a/bl31/aarch64/bl31_arch_setup.c
+++ b/bl31/aarch64/bl31_arch_setup.c
@@ -40,7 +40,6 @@
 void bl31_arch_setup(void)
 {
 	unsigned long tmp_reg = 0;
-	unsigned int counter_base_frequency;
 
 	/* Enable alignment checks and set the exception endianness to LE */
 	tmp_reg = read_sctlr();
@@ -62,13 +61,6 @@
 	enable_serror();
 	enable_debug_exceptions();
 
-	/* Read the frequency from Frequency modes table */
-	counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
-	/* The first entry of the frequency modes table must not be 0 */
-	assert(counter_base_frequency != 0);
-
-	/* Program the counter frequency */
-	write_cntfrq_el0(counter_base_frequency);
 	return;
 }
 
diff --git a/docs/firmware-design.md b/docs/firmware-design.md
index 11d6f1d..1f799b6 100644
--- a/docs/firmware-design.md
+++ b/docs/firmware-design.md
@@ -151,19 +151,16 @@
         and Advanced SIMD execution are configured to not trap to EL3 by
         clearing the `CPTR_EL3.TFP` bit.
 
-    -   `CNTFRQ_EL0`. The `CNTFRQ_EL0` register is programmed with the base
-        frequency of the system counter, which is retrieved from the first entry
-        in the frequency modes table.
-
-    -   Generic Timer. The system level implementation of the generic timer is
-        enabled through the memory mapped interface.
-
 #### Platform initialization
 
-BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests from
-the CCI-400 slave interface corresponding to the cluster that includes the
-primary CPU. BL1 also initializes UART0 (PL011 console), which enables access to
-the `printf` family of functions.
+BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests
+from the CCI-400 slave interface corresponding to the cluster that includes
+the primary CPU. BL1 also initializes UART0 (PL011 console), which enables
+access to the `printf` family of functions. The `CNTFRQ_EL0` register is
+programmed with the base frequency of the system counter, which is retrieved
+from the first entry in the frequency modes table. The system level
+implementation of the generic timer is enabled through the memory mapped
+interface.
 
 #### BL2 image load and execution
 
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 56467fb..6bba360 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -446,8 +446,9 @@
 for performing any remaining platform-specific setup that can occur after the
 MMU and data cache have been enabled.
 
-In the ARM FVP port, it zeros out the ZI section and enables the system level
-implementation of the generic timer counter.
+In the ARM FVP port, this function enables system-level implementation of the
+generic timer counter. It also initializes counter frequency for CPU's generic
+timers.
 
 This function is also responsible for initializing the storage abstraction layer
 which is used to load further bootloader images.
@@ -771,6 +772,7 @@
 The ARM FVP port does the following:
 *   Initializes the generic interrupt controller.
 *   Configures the CLCD controller.
+*   Initializes counter frequency for CPU's generic timer
 *   Grants access to the system counter timer module
 *   Initializes the FVP power controller device
 *   Detects the system topology.
diff --git a/plat/fvp/bl1_plat_setup.c b/plat/fvp/bl1_plat_setup.c
index d4fd81b..b0c011e 100644
--- a/plat/fvp/bl1_plat_setup.c
+++ b/plat/fvp/bl1_plat_setup.c
@@ -112,11 +112,25 @@
  ******************************************************************************/
 void bl1_platform_setup(void)
 {
+	unsigned int counter_base_frequency;
+
 	/* Initialise the IO layer and register platform IO devices */
 	io_setup();
 
+	/*
+	 * Enable and initialize the System level generic timer. Choose base
+	 * frequency for the timer
+	 */
+	mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
+
+	/* Read the frequency from Frequency modes table */
+	counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
+
+	/* The first entry of the frequency modes table must not be 0 */
+	assert(counter_base_frequency != 0);
+
-	/* Enable and initialize the System level generic timer */
-	mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_EN);
+	/* Program the counter frequency */
+	write_cntfrq_el0(counter_base_frequency);
 }
 
 
diff --git a/plat/fvp/bl31_plat_setup.c b/plat/fvp/bl31_plat_setup.c
index 01b0a45..1b24687 100644
--- a/plat/fvp/bl31_plat_setup.c
+++ b/plat/fvp/bl31_plat_setup.c
@@ -30,7 +30,8 @@
 
 #include <platform.h>
 #include <fvp_pwrc.h>
-#include <bl_common.h>
+#include <assert.h>
+#include <arch_helpers.h>
 
 /*******************************************************************************
  * Declarations of linker defined symbols which will help us find the layout
@@ -125,6 +126,7 @@
 void bl31_platform_setup()
 {
 	unsigned int reg_val;
+	unsigned int counter_base_frequency;
 
 	/* Initialize the gic cpu and distributor interfaces */
 	gic_setup();
@@ -138,6 +140,15 @@
 	mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGCTRL,
 		      (1ull << 31) | (1 << 30) | (7 << 20) | (0 << 16));
 
+	/* Read the frequency from Frequency modes table */
+	counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
+
+	/* The first entry of the frequency modes table must not be 0 */
+	assert(counter_base_frequency != 0);
+
+	/* Program the counter frequency */
+	write_cntfrq_el0(counter_base_frequency);
+
 	/* Allow access to the System counter timer module */
 	reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
 	reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);