diff mbox

[v5,01/15] platforms/firenze: Fix I2C clock source frequency

Message ID 1430115993-20560-2-git-send-email-gwshan@linux.vnet.ibm.com
State Superseded
Delegated to: Benjamin Herrenschmidt
Headers show

Commit Message

Gavin Shan April 27, 2015, 6:26 a.m. UTC
The I2C master clock source frequency is hardcoded to wrong value.
The correct frequency should be the nest clock frequency divided
by 16 as Ben said. The patch fixes I2C master resource frequency
with the help of additional properties "nest-frequency" and
"bus-frequency" to root and xscom device node separately.

Suggested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 hdata/spira.c               | 19 +++++++++++++++++++
 hdata/spira.h               |  8 ++++++--
 platforms/ibm-fsp/firenze.c | 11 ++++++++++-
 3 files changed, 35 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/hdata/spira.c b/hdata/spira.c
index 8dd9a78..d76b69f 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -181,6 +181,7 @@  static struct dt_node *add_xscom_node(uint64_t base, uint32_t hw_id,
 {
 	struct dt_node *node;
 	uint64_t addr, size;
+	uint64_t freq;
 
 	addr = base | ((uint64_t)hw_id << PPC_BITLSHIFT(28));
 	size = (u64)1 << PPC_BITLSHIFT(28);
@@ -212,6 +213,13 @@  static struct dt_node *add_xscom_node(uint64_t base, uint32_t hw_id,
 	}
 	dt_add_property_u64s(node, "reg", addr, size);
 
+	/* Derive bus frquency */
+	freq = dt_prop_get_u64_def(dt_root, "nest-frequency", 0);
+	freq /= 4;
+	if (freq)
+		dt_add_property_cells(node, "bus-frequency",
+				      hi32(freq), lo32(freq));
+
 	return node;
 }
 
@@ -692,6 +700,8 @@  static void add_iplparams_sys_params(const void *iplp, struct dt_node *node)
 	const struct iplparams_sysparams *p;
 	u32 sys_type;
 	const char *sys_family;
+	const struct HDIF_common_hdr *hdif = iplp;
+	u16 version = be16_to_cpu(hdif->version);
 
 	p = HDIF_get_idata(iplp, IPLPARAMS_SYSPARAMS, NULL);
 	if (!CHECK_SPPTR(p)) {
@@ -731,6 +741,15 @@  static void add_iplparams_sys_params(const void *iplp, struct dt_node *node)
 	}
 	dt_add_property_strings(dt_root, "compatible", "ibm,powernv",
 				sys_family);
+
+	/* Grab nest frequency when available */
+	if (version >= 0x005b) {
+		u64 freq = be32_to_cpu(p->nest_freq_mhz);
+
+		freq *= 1000000;
+		dt_add_property_cells(dt_root, "nest-frquency",
+				      hi32(freq), lo32(freq));
+	}
 }
 
 static void add_iplparams_ipl_params(const void *iplp, struct dt_node *node)
diff --git a/hdata/spira.h b/hdata/spira.h
index a1ed79d..53f87ab 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -239,9 +239,13 @@  struct iplparams_sysparams {
 	__be32		sys_attributes;
 	__be32		mem_scrubbing;
 	__be16		cur_spl_value;
-	uint8_t		pump_mode;
+	uint8_t		pump_mode;		/* Reserved */
 	uint8_t		use_pore_sleep;
-	__be32		pore_image_size;
+	__be32		pore_image_size;	/* Reserved */
+	uint8_t		vtpm_enabled;
+	uint8_t		hw_page_table_size;	/* >= 0x59 */
+	__be16		hv_disp_wheel;		/* >= 0x58 */
+	__be32		nest_freq_mhz;		/* >= 0x5b */
 } __packed;
 
 /* Idata index 1: IPL parameters */
diff --git a/platforms/ibm-fsp/firenze.c b/platforms/ibm-fsp/firenze.c
index d473875..373ba93 100644
--- a/platforms/ibm-fsp/firenze.c
+++ b/platforms/ibm-fsp/firenze.c
@@ -52,6 +52,7 @@  static unsigned int fsp_pcie_inv_alloc_count;
 static struct dt_node *dt_create_i2c_master(struct dt_node *n, uint32_t eng_id)
 {
 	struct dt_node *i2cm;
+	uint64_t freq;
 
 	/* Each master registers set is of length 0x20 */
 	i2cm = dt_new_addr(n, "i2cm", 0xa0000 + eng_id * 0x20);
@@ -62,11 +63,19 @@  static struct dt_node *dt_create_i2c_master(struct dt_node *n, uint32_t eng_id)
 			       "ibm,power8-i2cm");
 	dt_add_property_cells(i2cm, "reg", 0xa0000 + eng_id * 0x20,
 			      0x20);
-	dt_add_property_cells(i2cm, "clock-frequency", 50000000);
 	dt_add_property_cells(i2cm, "chip-engine#", eng_id);
 	dt_add_property_cells(i2cm, "#address-cells", 1);
 	dt_add_property_cells(i2cm, "#size-cells", 0);
 
+	/* Derive the clock source frequency */
+	freq = dt_prop_get_u64_def(n, "bus-frequency", 0);
+	freq /= 4;
+	if (freq)
+		dt_add_property_cells(i2cm, "clock-frequency",
+				      hi32(freq), lo32(freq));
+	else
+		dt_add_property_cells(i2cm, "clock-frequency",
+				      125000000);
 	return i2cm;
 }