Skip to contentSkip to conversation

clk: qoriq: Move chip-specific knowledge into driver

PATCH Superseded Scott Wood 6 participants 19 messages Sep 20, 2015 – Feb 26, 2016

Subsystems (10)
lore
Share & tools
lore

Scott Wood

author
#0 lore raw

v3 cover clk: qoriq: Move chip-specific knowledge into driver

The existing device tree bindings are error-prone and inflexible. Correct the mistake by moving the knowledge into the driver, which has more flexibility in describing the quirks of each chip. This leaves the device tree to its proper role of identifying a programming interface rather than describing its individual registers.

For more detail, see the commit message of patch 2.

As there are both ARM and PPC patches that depend on this patchset, I'm requesting ACKs from clk and cpufreq in order to put this into a topic branch that both ARM and PPC can pull.

Scott Wood (5):
powerpc/fsl: Move fsl_guts.h out of arch/powerpc
clk: qoriq: Move chip-specific knowledge into driver
clk: qoriq: Add ls2080a support.
clk: Add consumer APIs for discovering possible parent clocks
cpufreq: qoriq: Don't look at clock implementation details

 .../devicetree/bindings/clock/qoriq-clock.txt      |   61 +-
 arch/powerpc/include/asm/fsl_guts.h                |  192 ---
 arch/powerpc/platforms/85xx/mpc85xx_mds.c          |    2 +-
 arch/powerpc/platforms/85xx/mpc85xx_rdb.c          |    2 +-
 arch/powerpc/platforms/85xx/p1022_ds.c             |    2 +-
 arch/powerpc/platforms/85xx/p1022_rdk.c            |    2 +-
 arch/powerpc/platforms/85xx/smp.c                  |    2 +-
 arch/powerpc/platforms/85xx/twr_p102x.c            |    2 +-
 arch/powerpc/platforms/86xx/mpc8610_hpcd.c         |    2 +-
 drivers/clk/Kconfig                                |    2 +-
 drivers/clk/clk-qoriq.c                            | 1316 ++++++++++++++++----
 drivers/clk/clk.c                                  |   19 +
 drivers/cpufreq/qoriq-cpufreq.c                    |  137 +-
 drivers/iommu/fsl_pamu.c                           |    2 +-
 include/linux/clk.h                                |   31 +
 include/linux/fsl/guts.h                           |  192 +++
 sound/soc/fsl/mpc8610_hpcd.c                       |    2 +-
 sound/soc/fsl/p1022_ds.c                           |    2 +-
 sound/soc/fsl/p1022_rdk.c                          |    2 +-
 19 files changed, 1441 insertions(+), 531 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/fsl_guts.h
 create mode 100644 include/linux/fsl/guts.h
Signature · 1 line
2.1.4
author
#1 lore raw

PATCH v3 1/5 powerpc/fsl: Move fsl_guts.h out of arch/powerpc

Freescale's Layerscape ARM chips use the same structure.

---
v3: was patch 2/5

 arch/powerpc/include/asm/fsl_guts.h        | 192 -----------------------------
 arch/powerpc/platforms/85xx/mpc85xx_mds.c  |   2 +-
 arch/powerpc/platforms/85xx/mpc85xx_rdb.c  |   2 +-
 arch/powerpc/platforms/85xx/p1022_ds.c     |   2 +-
 arch/powerpc/platforms/85xx/p1022_rdk.c    |   2 +-
 arch/powerpc/platforms/85xx/smp.c          |   2 +-
 arch/powerpc/platforms/85xx/twr_p102x.c    |   2 +-
 arch/powerpc/platforms/86xx/mpc8610_hpcd.c |   2 +-
 drivers/iommu/fsl_pamu.c                   |   2 +-
 include/linux/fsl/guts.h                   | 192 +++++++++++++++++++++++++++++
 sound/soc/fsl/mpc8610_hpcd.c               |   2 +-
 sound/soc/fsl/p1022_ds.c                   |   2 +-
 sound/soc/fsl/p1022_rdk.c                  |   2 +-
 13 files changed, 203 insertions(+), 203 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/fsl_guts.h
 create mode 100644 include/linux/fsl/guts.h
arch/powerpc/include/asm/fsl_guts.h deleted +0 -192
deleted file mode 100644
index 43b6bb1..0000000
@@ -1,192 +0,0 @@
-/**
- * Freecale 85xx and 86xx Global Utilties register set
- *
- * Authors: Jeff Brown
- *          Timur Tabi <[email protected]>
- *
- * Copyright 2004,2007,2012 Freescale Semiconductor, Inc
- *
- * 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;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __ASM_POWERPC_FSL_GUTS_H__
-#define __ASM_POWERPC_FSL_GUTS_H__
-#ifdef __KERNEL__
-
-/**
- * Global Utility Registers.
- *
- * Not all registers defined in this structure are available on all chips, so
- * you are expected to know whether a given register actually exists on your
- * chip before you access it.
- *
- * Also, some registers are similar on different chips but have slightly
- * different names.  In these cases, one name is chosen to avoid extraneous
- * #ifdefs.
- */
-struct ccsr_guts {
-	__be32	porpllsr;	/* 0x.0000 - POR PLL Ratio Status Register */
-	__be32	porbmsr;	/* 0x.0004 - POR Boot Mode Status Register */
-	__be32	porimpscr;	/* 0x.0008 - POR I/O Impedance Status and Control Register */
-	__be32	pordevsr;	/* 0x.000c - POR I/O Device Status Register */
-	__be32	pordbgmsr;	/* 0x.0010 - POR Debug Mode Status Register */
-	__be32	pordevsr2;	/* 0x.0014 - POR device status register 2 */
-	u8	res018[0x20 - 0x18];
-	__be32	porcir;		/* 0x.0020 - POR Configuration Information Register */
-	u8	res024[0x30 - 0x24];
-	__be32	gpiocr;		/* 0x.0030 - GPIO Control Register */
-	u8	res034[0x40 - 0x34];
-	__be32	gpoutdr;	/* 0x.0040 - General-Purpose Output Data Register */
-	u8	res044[0x50 - 0x44];
-	__be32	gpindr;		/* 0x.0050 - General-Purpose Input Data Register */
-	u8	res054[0x60 - 0x54];
-	__be32	pmuxcr;		/* 0x.0060 - Alternate Function Signal Multiplex Control */
-        __be32  pmuxcr2;	/* 0x.0064 - Alternate function signal multiplex control 2 */
-        __be32  dmuxcr;		/* 0x.0068 - DMA Mux Control Register */
-        u8	res06c[0x70 - 0x6c];
-	__be32	devdisr;	/* 0x.0070 - Device Disable Control */
-#define CCSR_GUTS_DEVDISR_TB1	0x00001000
-#define CCSR_GUTS_DEVDISR_TB0	0x00004000
-	__be32	devdisr2;	/* 0x.0074 - Device Disable Control 2 */
-	u8	res078[0x7c - 0x78];
-	__be32  pmjcr;		/* 0x.007c - 4 Power Management Jog Control Register */
-	__be32	powmgtcsr;	/* 0x.0080 - Power Management Status and Control Register */
-	__be32  pmrccr;		/* 0x.0084 - Power Management Reset Counter Configuration Register */
-	__be32  pmpdccr;	/* 0x.0088 - Power Management Power Down Counter Configuration Register */
-	__be32  pmcdr;		/* 0x.008c - 4Power management clock disable register */
-	__be32	mcpsumr;	/* 0x.0090 - Machine Check Summary Register */
-	__be32	rstrscr;	/* 0x.0094 - Reset Request Status and Control Register */
-	__be32  ectrstcr;	/* 0x.0098 - Exception reset control register */
-	__be32  autorstsr;	/* 0x.009c - Automatic reset status register */
-	__be32	pvr;		/* 0x.00a0 - Processor Version Register */
-	__be32	svr;		/* 0x.00a4 - System Version Register */
-	u8	res0a8[0xb0 - 0xa8];
-	__be32	rstcr;		/* 0x.00b0 - Reset Control Register */
-	u8	res0b4[0xc0 - 0xb4];
-	__be32  iovselsr;	/* 0x.00c0 - I/O voltage select status register
-					     Called 'elbcvselcr' on 86xx SOCs */
-	u8	res0c4[0x100 - 0xc4];
-	__be32	rcwsr[16];	/* 0x.0100 - Reset Control Word Status registers
-					     There are 16 registers */
-	u8	res140[0x224 - 0x140];
-	__be32  iodelay1;	/* 0x.0224 - IO delay control register 1 */
-	__be32  iodelay2;	/* 0x.0228 - IO delay control register 2 */
-	u8	res22c[0x604 - 0x22c];
-	__be32	pamubypenr; 	/* 0x.604 - PAMU bypass enable register */
-	u8	res608[0x800 - 0x608];
-	__be32	clkdvdr;	/* 0x.0800 - Clock Divide Register */
-	u8	res804[0x900 - 0x804];
-	__be32	ircr;		/* 0x.0900 - Infrared Control Register */
-	u8	res904[0x908 - 0x904];
-	__be32	dmacr;		/* 0x.0908 - DMA Control Register */
-	u8	res90c[0x914 - 0x90c];
-	__be32	elbccr;		/* 0x.0914 - eLBC Control Register */
-	u8	res918[0xb20 - 0x918];
-	__be32	ddr1clkdr;	/* 0x.0b20 - DDR1 Clock Disable Register */
-	__be32	ddr2clkdr;	/* 0x.0b24 - DDR2 Clock Disable Register */
-	__be32	ddrclkdr;	/* 0x.0b28 - DDR Clock Disable Register */
-	u8	resb2c[0xe00 - 0xb2c];
-	__be32	clkocr;		/* 0x.0e00 - Clock Out Select Register */
-	u8	rese04[0xe10 - 0xe04];
-	__be32	ddrdllcr;	/* 0x.0e10 - DDR DLL Control Register */
-	u8	rese14[0xe20 - 0xe14];
-	__be32	lbcdllcr;	/* 0x.0e20 - LBC DLL Control Register */
-	__be32  cpfor;		/* 0x.0e24 - L2 charge pump fuse override register */
-	u8	rese28[0xf04 - 0xe28];
-	__be32	srds1cr0;	/* 0x.0f04 - SerDes1 Control Register 0 */
-	__be32	srds1cr1;	/* 0x.0f08 - SerDes1 Control Register 0 */
-	u8	resf0c[0xf2c - 0xf0c];
-	__be32  itcr;		/* 0x.0f2c - Internal transaction control register */
-	u8	resf30[0xf40 - 0xf30];
-	__be32	srds2cr0;	/* 0x.0f40 - SerDes2 Control Register 0 */
-	__be32	srds2cr1;	/* 0x.0f44 - SerDes2 Control Register 0 */
-} __attribute__ ((packed));
-
-
-/* Alternate function signal multiplex control */
-#define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
-
-#ifdef CONFIG_PPC_86xx
-
-#define CCSR_GUTS_DMACR_DEV_SSI	0	/* DMA controller/channel set to SSI */
-#define CCSR_GUTS_DMACR_DEV_IR	1	/* DMA controller/channel set to IR */
-
-/*
- * Set the DMACR register in the GUTS
- *
- * The DMACR register determines the source of initiated transfers for each
- * channel on each DMA controller.  Rather than have a bunch of repetitive
- * macros for the bit patterns, we just have a function that calculates
- * them.
- *
- * guts: Pointer to GUTS structure
- * co: The DMA controller (0 or 1)
- * ch: The channel on the DMA controller (0, 1, 2, or 3)
- * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx)
- */
-static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
-	unsigned int co, unsigned int ch, unsigned int device)
-{
-	unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
-
-	clrsetbits_be32(&guts->dmacr, 3 << shift, device << shift);
-}
-
-#define CCSR_GUTS_PMUXCR_LDPSEL		0x00010000
-#define CCSR_GUTS_PMUXCR_SSI1_MASK	0x0000C000	/* Bitmask for SSI1 */
-#define CCSR_GUTS_PMUXCR_SSI1_LA	0x00000000	/* Latched address */
-#define CCSR_GUTS_PMUXCR_SSI1_HI	0x00004000	/* High impedance */
-#define CCSR_GUTS_PMUXCR_SSI1_SSI	0x00008000	/* Used for SSI1 */
-#define CCSR_GUTS_PMUXCR_SSI2_MASK	0x00003000	/* Bitmask for SSI2 */
-#define CCSR_GUTS_PMUXCR_SSI2_LA	0x00000000	/* Latched address */
-#define CCSR_GUTS_PMUXCR_SSI2_HI	0x00001000	/* High impedance */
-#define CCSR_GUTS_PMUXCR_SSI2_SSI	0x00002000	/* Used for SSI2 */
-#define CCSR_GUTS_PMUXCR_LA_22_25_LA	0x00000000	/* Latched Address */
-#define CCSR_GUTS_PMUXCR_LA_22_25_HI	0x00000400	/* High impedance */
-#define CCSR_GUTS_PMUXCR_DBGDRV		0x00000200	/* Signals not driven */
-#define CCSR_GUTS_PMUXCR_DMA2_0		0x00000008
-#define CCSR_GUTS_PMUXCR_DMA2_3		0x00000004
-#define CCSR_GUTS_PMUXCR_DMA1_0		0x00000002
-#define CCSR_GUTS_PMUXCR_DMA1_3		0x00000001
-
-/*
- * Set the DMA external control bits in the GUTS
- *
- * The DMA external control bits in the PMUXCR are only meaningful for
- * channels 0 and 3.  Any other channels are ignored.
- *
- * guts: Pointer to GUTS structure
- * co: The DMA controller (0 or 1)
- * ch: The channel on the DMA controller (0, 1, 2, or 3)
- * value: the new value for the bit (0 or 1)
- */
-static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
-	unsigned int co, unsigned int ch, unsigned int value)
-{
-	if ((ch == 0) || (ch == 3)) {
-		unsigned int shift = 2 * (co + 1) - (ch & 1) - 1;
-
-		clrsetbits_be32(&guts->pmuxcr, 1 << shift, value << shift);
-	}
-}
-
-#define CCSR_GUTS_CLKDVDR_PXCKEN	0x80000000
-#define CCSR_GUTS_CLKDVDR_SSICKEN	0x20000000
-#define CCSR_GUTS_CLKDVDR_PXCKINV	0x10000000
-#define CCSR_GUTS_CLKDVDR_PXCKDLY_SHIFT 25
-#define CCSR_GUTS_CLKDVDR_PXCKDLY_MASK	0x06000000
-#define CCSR_GUTS_CLKDVDR_PXCKDLY(x) \
-	(((x) & 3) << CCSR_GUTS_CLKDVDR_PXCKDLY_SHIFT)
-#define CCSR_GUTS_CLKDVDR_PXCLK_SHIFT	16
-#define CCSR_GUTS_CLKDVDR_PXCLK_MASK	0x001F0000
-#define CCSR_GUTS_CLKDVDR_PXCLK(x) (((x) & 31) << CCSR_GUTS_CLKDVDR_PXCLK_SHIFT)
-#define CCSR_GUTS_CLKDVDR_SSICLK_MASK	0x000000FF
-#define CCSR_GUTS_CLKDVDR_SSICLK(x) ((x) & CCSR_GUTS_CLKDVDR_SSICLK_MASK)
-
-#endif
-
-#endif
-#endif
arch/powerpc/platforms/85xx/mpc85xx_mds.c +1 -1
index a392e94..f0be439 100644
@@ -34,6 +34,7 @@
 #include <linux/of_device.h>
 #include <linux/phy.h>
 #include <linux/memblock.h>
+#include <linux/fsl/guts.h>
 
 #include <linux/atomic.h>
 #include <asm/time.h>
@@ -51,7 +52,6 @@
 #include <asm/qe_ic.h>
 #include <asm/mpic.h>
 #include <asm/swiotlb.h>
-#include <asm/fsl_guts.h>
 #include "smp.h"
 
 #include "mpc85xx.h"
arch/powerpc/platforms/85xx/mpc85xx_rdb.c +1 -1
index e358bed..50dcc00 100644
@@ -17,6 +17,7 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/of_platform.h>
+#include <linux/fsl/guts.h>
 
 #include <asm/time.h>
 #include <asm/machdep.h>
@@ -27,7 +28,6 @@
 #include <asm/mpic.h>
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
-#include <asm/fsl_guts.h>
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
arch/powerpc/platforms/85xx/p1022_ds.c +1 -1
index 6ac986d3..371df82 100644
@@ -16,6 +16,7 @@
  * kind, whether express or implied.
  */
 
+#include <linux/fsl/guts.h>
 #include <linux/pci.h>
 #include <linux/of_platform.h>
 #include <asm/div64.h>
@@ -25,7 +26,6 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 #include <asm/udbg.h>
-#include <asm/fsl_guts.h>
 #include <asm/fsl_lbc.h>
 #include "smp.h"
 
arch/powerpc/platforms/85xx/p1022_rdk.c +1 -1
index 680232d..5087bec 100644
@@ -12,6 +12,7 @@
  * kind, whether express or implied.
  */
 
+#include <linux/fsl/guts.h>
 #include <linux/pci.h>
 #include <linux/of_platform.h>
 #include <asm/div64.h>
@@ -21,7 +22,6 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 #include <asm/udbg.h>
-#include <asm/fsl_guts.h>
 #include "smp.h"
 
 #include "mpc85xx.h"
arch/powerpc/platforms/85xx/smp.c +1 -1
index b8b8216..6ac7786 100644
@@ -19,6 +19,7 @@
 #include <linux/kexec.h>
 #include <linux/highmem.h>
 #include <linux/cpu.h>
+#include <linux/fsl/guts.h>
 
 #include <asm/machdep.h>
 #include <asm/pgtable.h>
@@ -26,7 +27,6 @@
 #include <asm/mpic.h>
 #include <asm/cacheflush.h>
 #include <asm/dbell.h>
-#include <asm/fsl_guts.h>
 #include <asm/code-patching.h>
 #include <asm/cputhreads.h>
 
arch/powerpc/platforms/85xx/twr_p102x.c +1 -1
index 30e002f..892e613 100644
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/fsl/guts.h>
 #include <linux/pci.h>
 #include <linux/of_platform.h>
 
@@ -23,7 +24,6 @@
 #include <asm/mpic.h>
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
-#include <asm/fsl_guts.h>
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
arch/powerpc/platforms/86xx/mpc8610_hpcd.c +1 -1
index 55413a5..437a9c3 100644
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/of.h>
+#include <linux/fsl/guts.h>
 
 #include <asm/time.h>
 #include <asm/machdep.h>
@@ -38,7 +39,6 @@
 #include <sysdev/fsl_pci.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/simple_gpio.h>
-#include <asm/fsl_guts.h>
 
 #include "mpc86xx.h"
 
drivers/iommu/fsl_pamu.c +1 -1
index 2570f2a2..a34355f 100644
@@ -20,11 +20,11 @@
 
 #include "fsl_pamu.h"
 
+#include <linux/fsl/guts.h>
 #include <linux/interrupt.h>
 #include <linux/genalloc.h>
 
 #include <asm/mpc85xx.h>
-#include <asm/fsl_guts.h>
 
 /* define indexes for each operation mapping scenario */
 #define OMI_QMAN        0x00
include/linux/fsl/guts.h new file +192 -0

192 lines not on this page · raw message

sound/soc/fsl/mpc8610_hpcd.c +1 -1
index 9621b91..6f236f1 100644
@@ -12,11 +12,11 @@
 
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/fsl/guts.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
 #include <sound/soc.h>
-#include <asm/fsl_guts.h>
 
 #include "fsl_dma.h"
 #include "fsl_ssi.h"
sound/soc/fsl/p1022_ds.c +1 -1
index 71c1a7d..747aab0 100644
@@ -11,12 +11,12 @@
  */
 
 #include <linux/module.h>
+#include <linux/fsl/guts.h>
 #include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
 #include <sound/soc.h>
-#include <asm/fsl_guts.h>
 
 #include "fsl_dma.h"
 #include "fsl_ssi.h"
sound/soc/fsl/p1022_rdk.c +1 -1
index ee29048..1dd49e5 100644
@@ -18,12 +18,12 @@
  */
 
 #include <linux/module.h>
+#include <linux/fsl/guts.h>
 #include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
 #include <sound/soc.h>
-#include <asm/fsl_guts.h>
 
 #include "fsl_dma.h"
 #include "fsl_ssi.h"
Signature · 1 line
2.1.4
author
#2 lore raw

PATCH v3 2/5 clk: qoriq: Move chip-specific knowledge into driver

In reply to Scott Wood

The device tree should describe the chips (or chip-like subblocks) in the system, but it generally does not describe individual registers -- it should identify, rather than describe, a programming interface.

This has not been the case with the QorIQ clockgen nodes. The knowledge of what each bit setting of CLKCnCSR means is encoded in three places (binding, pll node, and mux node), and the last also needs to know which options are valid on a particular chip. All three of these locations are considered stable ABI, making it difficult to fix mistakes (of which I have found several), much less refactor the abstraction to be able to address problems, limitations, or new chips.

Under the current binding, a pll clock specifier of 2 means that the PLL is divided by 4 -- and the driver implements this, unless there happen to be four clock-output-names rather than 3, in which case it interprets it as PLL divided by 3. This does not appear in the binding documentation at all. That hack is now considered stable ABI.

The current device tree nodes contain errors, such as saying that T1040 can set a core clock to PLL/4 when only PLL and PLL/2 are options. The current binding also ignores some restrictions on clock selection, such as p5020's requirement that if a core uses the "wrong" PLL, that PLL must be clocked lower than the "correct" PLL and be at most 80% of the rated CPU frequency.

Possibly because of the lack of the ability to express such nuance in the binding, some valid options are omitted from the device trees, such as the ability on p4080 to run cores 0-3 from PLL3 and cores 4-7 from PLL1 (again, only if they are at most 80% of rated CPU frequency). This omission, combined with excessive caution in the cpufreq driver (addressed in a subsequent patch), means that currently on a 1500 MHz p4080 with typical PLL configuration, cpufreq can lower the frequency to 1200 MHz on half the CPUs and do nothing on the others. With this patchset, all CPUs can be lowered to 1200 MHz on a rev2 p4080, and on a rev3 p4080 half can be lowered to 750 MHz and the other half to 600 MHz.

The current binding only deals with CPU clocks. To describe FMan in the device tree, we need to describe its clock. Some chips have additional muxes that work like the CPU muxes, but are not described in the device tree. Others require inspecting the Reset Control Word to determine which PLL is used. Rather than continue to extend this mess, replace it. Have the driver bind to the chip-specific clockgen compatible, and keep the detailed description of quirky chip variations in the driver, where it can be easily fixed, refactored, and extended.

Older device trees will continue to work (including a workaround for old ls1021a device trees that are missing compatible and reg in the clockgen node, which even the old binding required). The pll/mux details in old device trees will be ignored, but "clocks" properties pointing at the old nodes will still work, and be directed at the corresponding new clock.

---
v2: was patch 3/5

Added missing initialization of hwc->cg.

 .../devicetree/bindings/clock/qoriq-clock.txt      |   61 +-
 drivers/clk/clk-qoriq.c                            | 1261 ++++++++++++++++----
 2 files changed, 1090 insertions(+), 232 deletions(-)
Documentation/devicetree/bindings/clock/qoriq-clock.txt +50 -11
index df4a259..16a3ec4 100644
@@ -1,6 +1,6 @@
 * Clock Block on Freescale QorIQ Platforms
 
-Freescale qoriq chips take primary clocking input from the external
+Freescale QorIQ chips take primary clocking input from the external
 SYSCLK signal. The SYSCLK input (frequency) is multiplied using
 multiple phase locked loops (PLL) to create a variety of frequencies
 which can then be passed to a variety of internal logic, including
@@ -13,14 +13,16 @@ which the chip complies.
 Chassis Version		Example Chips
 ---------------		-------------
 1.0			p4080, p5020, p5040
-2.0			t4240, b4860, t1040
+2.0			t4240, b4860
 
 1. Clock Block Binding
 
 Required properties:
-- compatible: Should contain a specific clock block compatible string
-	and a single chassis clock compatible string.
-	Clock block strings include, but not limited to, one of the:
+- compatible: Should contain a chip-specific clock block compatible
+	string and (if applicable) may contain a chassis-version clock
+	compatible string.
+
+	Chip-specific strings are of the form "fsl,<chip>-clockgen", such as:
 	* "fsl,p2041-clockgen"
 	* "fsl,p3041-clockgen"
 	* "fsl,p4080-clockgen"
@@ -30,15 +32,14 @@ Required properties:
 	* "fsl,b4420-clockgen"
 	* "fsl,b4860-clockgen"
 	* "fsl,ls1021a-clockgen"
-	Chassis clock strings include:
+	Chassis-version clock strings include:
 	* "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
 	* "fsl,qoriq-clockgen-2.0": for chassis 2.0 clocks
 - reg: Describes the address of the device's resources within the
 	address space defined by its parent bus, and resource zero
 	represents the clock register set
-- clock-frequency: Input system clock frequency
 
-Recommended properties:
+Optional properties:
 - ranges: Allows valid translation between child's address space and
 	parent's. Must be present if the device has sub-nodes.
 - #address-cells: Specifies the number of cells used to represent
@@ -47,8 +48,46 @@ Recommended properties:
 - #size-cells: Specifies the number of cells used to represent
 	the size of an address. Must be present if the device has
 	sub-nodes and set to 1 if present
+- clock-frequency: Input system clock frequency (SYSCLK)
+- clocks: If clock-frequency is not specified, sysclk may be provided
+	as an input clock.  Either clock-frequency or clocks must be
+	provided.
+
+2. Clock Provider
+
+The clockgen node should act as a clock provider, though in older device
+trees the children of the clockgen node are the clock providers.
+
+When the clockgen node is a clock provider, #clock-cells = <2>.
+The first cell of the clock specifier is the clock type, and the
+second cell is the clock index for the specified type.
+
+	Type#	Name		Index Cell
+	0	sysclk		must be 0
+	1	cmux		index (n in CLKCnCSR)
+	2	hwaccel		index (n in CLKCGnHWACSR)
+	3	fman		0 for fm1, 1 for fm2
+	4	platform pll	0=pll, 1=pll/2, 2=pll/3, 3=pll/4
+
+3. Example
+
+	clockgen: global-utilities at e1000 {
+		compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
+		clock-frequency = <133333333>;
+		reg = <0xe1000 0x1000>;
+		#clock-cells = <2>;
+	};
+
+	fman at 400000 {
+		...
+		clocks = <&clockgen 3 0>;
+		...
+	};
+}
+4. Legacy Child Nodes
 
-2. Clock Provider/Consumer Binding
+NOTE: These nodes are deprecated.  Kernels should continue to support
+device trees with these nodes, but new device trees should not use them.
 
 Most of the bindings are from the common clock binding[1].
  [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -82,7 +121,7 @@ Recommended properties:
 - reg: Should be the offset and length of clock block base address.
 	The length should be 4.
 
-Example for clock block and clock provider:
+Legacy Example:
 / {
 	clockgen: global-utilities at e1000 {
 		compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
@@ -142,7 +181,7 @@ Example for clock block and clock provider:
 	};
 };
 
-Example for clock consumer:
+Example for legacy clock consumer:
 
 / {
 	cpu0: PowerPC,e5500 at 0 {
drivers/clk/clk-qoriq.c +1040 -221

1,385 lines not on this page · raw message

Signature · 1 line
2.1.4
#3 lore raw

PATCH v3 2/5 clk: qoriq: Move chip-specific knowledge into driver

Quoted 53 lines · Scott Wood

The device tree should describe the chips (or chip-like subblocks) in the system, but it generally does not describe individual registers -- it should identify, rather than describe, a programming interface.

This has not been the case with the QorIQ clockgen nodes. The knowledge of what each bit setting of CLKCnCSR means is encoded in three places (binding, pll node, and mux node), and the last also needs to know which options are valid on a particular chip. All three of these locations are considered stable ABI, making it difficult to fix mistakes (of which I have found several), much less refactor the abstraction to be able to address problems, limitations, or new chips.

Under the current binding, a pll clock specifier of 2 means that the PLL is divided by 4 -- and the driver implements this, unless there happen to be four clock-output-names rather than 3, in which case it interprets it as PLL divided by 3. This does not appear in the binding documentation at all. That hack is now considered stable ABI.

The current device tree nodes contain errors, such as saying that T1040 can set a core clock to PLL/4 when only PLL and PLL/2 are options. The current binding also ignores some restrictions on clock selection, such as p5020's requirement that if a core uses the "wrong" PLL, that PLL must be clocked lower than the "correct" PLL and be at most 80% of the rated CPU frequency.

Possibly because of the lack of the ability to express such nuance in the binding, some valid options are omitted from the device trees, such as the ability on p4080 to run cores 0-3 from PLL3 and cores 4-7 from PLL1 (again, only if they are at most 80% of rated CPU frequency). This omission, combined with excessive caution in the cpufreq driver (addressed in a subsequent patch), means that currently on a 1500 MHz p4080 with typical PLL configuration, cpufreq can lower the frequency to 1200 MHz on half the CPUs and do nothing on the others. With this patchset, all CPUs can be lowered to 1200 MHz on a rev2 p4080, and on a rev3 p4080 half can be lowered to 750 MHz and the other half to 600 MHz.

The current binding only deals with CPU clocks. To describe FMan in the device tree, we need to describe its clock. Some chips have additional muxes that work like the CPU muxes, but are not described in the device tree. Others require inspecting the Reset Control Word to determine which PLL is used. Rather than continue to extend this mess, replace it. Have the driver bind to the chip-specific clockgen compatible, and keep the detailed description of quirky chip variations in the driver, where it can be easily fixed, refactored, and extended.

Older device trees will continue to work (including a workaround for old ls1021a device trees that are missing compatible and reg in the clockgen node, which even the old binding required). The pll/mux details in old device trees will be ignored, but "clocks" properties pointing at the old nodes will still work, and be directed at the corresponding new clock.

Quoted 2 lines

---

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
author
#4 lore raw

PATCH v3 3/5 clk: qoriq: Add ls2080a support.

In reply to Scott Wood

LS2080A is the first implementation of the chassis 3 clockgen, which has a different register layout than previous chips. It is also little endian, unlike previous chips.

---
v3: new patch

 drivers/clk/Kconfig     |  2 +-
 drivers/clk/clk-qoriq.c | 77 +++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 69 insertions(+), 10 deletions(-)
drivers/clk/Kconfig +1 -1
index 42f7120..9f1970c 100644
@@ -121,7 +121,7 @@ config COMMON_CLK_AXI_CLKGEN
 
 config CLK_QORIQ
 	bool "Clock driver for Freescale QorIQ platforms"
-	depends on (PPC_E500MC || ARM) && OF
+	depends on (PPC_E500MC || ARM || ARM64) && OF
 	---help---
 	  This adds the clock driver support for Freescale QorIQ platforms
 	  using common clock framework.
drivers/clk/clk-qoriq.c +68 -9

134 lines not on this page · raw message

Signature · 1 line
2.1.4
#5 lore raw

PATCH v3 3/5 clk: qoriq: Add ls2080a support.

Quoted 6 lines · Scott Wood

LS2080A is the first implementation of the chassis 3 clockgen, which has a different register layout than previous chips. It is also little endian, unlike previous chips.

---

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
author
#6 lore raw

PATCH v3 4/5 clk: Add consumer APIs for discovering possible parent clocks

In reply to Scott Wood

Commit fc4a05d4b0eb ("clk: Remove unused provider APIs") removed __clk_get_num_parents() and clk_hw_get_parent_by_index(), leaving only true provider API versions that operate on struct clk_hw.

qoriq-cpufreq needs these functions in order to determine the options it has for calling clk_set_parent() and thus populate the cpufreq table, so revive them as legitimate consumer APIs.

---
v3: new patch

 drivers/clk/clk.c   | 19 +++++++++++++++++++
 include/linux/clk.h | 31 +++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)
drivers/clk/clk.c +19 -0
index 43e2c3a..9436356 100644
@@ -290,6 +290,12 @@ struct clk_hw *__clk_get_hw(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(__clk_get_hw);
 
+unsigned int clk_get_num_parents(struct clk *clk)
+{
+	return !clk ? 0 : clk->core->num_parents;
+}
+EXPORT_SYMBOL_GPL(clk_get_num_parents);
+
 unsigned int clk_hw_get_num_parents(const struct clk_hw *hw)
 {
 	return hw->core->num_parents;
@@ -359,6 +365,19 @@ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
 		return core->parents[index];
 }
 
+struct clk *clk_get_parent_by_index(struct clk *clk, unsigned int index)
+{
+	struct clk_core *parent;
+
+	if (!clk)
+		return NULL;
+
+	parent = clk_core_get_parent_by_index(clk->core, index);
+
+	return !parent ? NULL : parent->hw->clk;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent_by_index);
+
 struct clk_hw *
 clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index)
 {
include/linux/clk.h +31 -0
index 0df4a51..937de0e 100644
@@ -392,6 +392,26 @@ int clk_set_parent(struct clk *clk, struct clk *parent);
 struct clk *clk_get_parent(struct clk *clk);
 
 /**
+ * clk_get_parent_by_index - get a possible parent clock by index
+ * @clk: clock source
+ * @index: index into the array of possible parents of this clock
+ *
+ * Returns struct clk corresponding to the requested possible
+ * parent clock source, or NULL.
+ */
+struct clk *clk_get_parent_by_index(struct clk *clk,
+				    unsigned int index);
+
+/**
+ * clk_get_num_parents - get number of possible parents
+ * @clk: clock source
+ *
+ * Returns the number of possible parents of this clock,
+ * which can then be enumerated using clk_get_parent_by_index().
+ */
+unsigned int clk_get_num_parents(struct clk *clk);
+
+/**
  * clk_get_sys - get a clock based upon the device name
  * @dev_id: device name
  * @con_id: connection ID
@@ -461,6 +481,17 @@ static inline struct clk *clk_get_parent(struct clk *clk)
 	return NULL;
 }
 
+struct clk *clk_get_parent_by_index(struct clk *clk,
+				    unsigned int index)
+{
+	return NULL;
+}
+
+unsigned int clk_get_num_parents(struct clk *clk)
+{
+	return 0;
+}
+
 #endif
 
 /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
Signature · 1 line
2.1.4
author
#7 lore raw

PATCH v3 4/5 clk: Add consumer APIs for discovering possible parent clocks

Quoted 8 lines · Scott Wood

Commit fc4a05d4b0eb ("clk: Remove unused provider APIs") removed __clk_get_num_parents() and clk_hw_get_parent_by_index(), leaving only true provider API versions that operate on struct clk_hw.

qoriq-cpufreq needs these functions in order to determine the options it has for calling clk_set_parent() and thus populate the cpufreq table, so revive them as legitimate consumer APIs.

Quoted 7 lines

---
v3: new patch

 drivers/clk/clk.c   | 19 +++++++++++++++++++
 include/linux/clk.h | 31 +++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

Russell, could you ACK this if there are no objections?

Thanks,
Scott

Quoted 91 lines
drivers/clk/clk.c +19 -0
index 43e2c3a..9436356 100644
@@ -290,6 +290,12 @@ struct clk_hw *__clk_get_hw(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(__clk_get_hw);
 
+unsigned int clk_get_num_parents(struct clk *clk)
+{
+     return !clk ? 0 : clk->core->num_parents;
+}
+EXPORT_SYMBOL_GPL(clk_get_num_parents);
+
 unsigned int clk_hw_get_num_parents(const struct clk_hw *hw)
 {
      return hw->core->num_parents;
@@ -359,6 +365,19 @@ static struct clk_core 
 *clk_core_get_parent_by_index(struct clk_core *core,
              return core->parents[index];
 }
 
+struct clk *clk_get_parent_by_index(struct clk *clk, unsigned int index)
+{
+     struct clk_core *parent;
+
+     if (!clk)
+             return NULL;
+
+     parent = clk_core_get_parent_by_index(clk->core, index);
+
+     return !parent ? NULL : parent->hw->clk;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent_by_index);
+
 struct clk_hw *
 clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index)

{

include/linux/clk.h +20 -0
index 0df4a51..937de0e 100644
@@ -392,6 +392,26 @@ int clk_set_parent(struct clk *clk, struct clk 
 *parent);
 struct clk *clk_get_parent(struct clk *clk);
 
 /**
+ * clk_get_parent_by_index - get a possible parent clock by index
+ * @clk: clock source
+ * @index: index into the array of possible parents of this clock
+ *
+ * Returns struct clk corresponding to the requested possible
+ * parent clock source, or NULL.
+ */
+struct clk *clk_get_parent_by_index(struct clk *clk,
+                                 unsigned int index);
+
+/**
+ * clk_get_num_parents - get number of possible parents
+ * @clk: clock source
+ *
+ * Returns the number of possible parents of this clock,
+ * which can then be enumerated using clk_get_parent_by_index().
+ */
+unsigned int clk_get_num_parents(struct clk *clk);
+
+/**
  * clk_get_sys - get a clock based upon the device name
  * @dev_id: device name

* @con_id: connection ID

include/linux/clk.h +11 -0
@@ -461,6 +481,17 @@ static inline struct clk *clk_get_parent(struct clk 
 *clk)
      return NULL;
 }
 
+struct clk *clk_get_parent_by_index(struct clk *clk,
+                                 unsigned int index)
+{
+     return NULL;
+}
+
+unsigned int clk_get_num_parents(struct clk *clk)
+{
+     return 0;
+}
+
 #endif
 

/* clk_prepare_enable helps cases using clk_enable in non-atomic context.
*/

author
#8 lore raw

PATCH v3 4/5 clk: Add consumer APIs for discovering possible parent clocks

Quoted 13 lines · Scott Wood
Quoted 12 lines · Scott Wood

Commit fc4a05d4b0eb ("clk: Remove unused provider APIs") removed __clk_get_num_parents() and clk_hw_get_parent_by_index(), leaving only true provider API versions that operate on struct clk_hw.

qoriq-cpufreq needs these functions in order to determine the options it has for calling clk_set_parent() and thus populate the cpufreq table, so revive them as legitimate consumer APIs.

---
v3: new patch

Quoted 8 lines
Quoted 3 lines
 drivers/clk/clk.c   | 19 +++++++++++++++++++
 include/linux/clk.h | 31 +++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

Russell, could you ACK this if there are no objections?

Thanks,
Scott

ping?

-Scott

Quoted 91 lines
Quoted 91 lines
drivers/clk/clk.c +19 -0
index 43e2c3a..9436356 100644
@@ -290,6 +290,12 @@ struct clk_hw *__clk_get_hw(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(__clk_get_hw);
 
+unsigned int clk_get_num_parents(struct clk *clk)
+{
+     return !clk ? 0 : clk->core->num_parents;
+}
+EXPORT_SYMBOL_GPL(clk_get_num_parents);
+
 unsigned int clk_hw_get_num_parents(const struct clk_hw *hw)
 {
      return hw->core->num_parents;
@@ -359,6 +365,19 @@ static struct clk_core 
 *clk_core_get_parent_by_index(struct clk_core *core,
              return core->parents[index];
 }
 
+struct clk *clk_get_parent_by_index(struct clk *clk, unsigned int index)
+{
+     struct clk_core *parent;
+
+     if (!clk)
+             return NULL;
+
+     parent = clk_core_get_parent_by_index(clk->core, index);
+
+     return !parent ? NULL : parent->hw->clk;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent_by_index);
+
 struct clk_hw *
 clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index)

{

include/linux/clk.h +20 -0
index 0df4a51..937de0e 100644
@@ -392,6 +392,26 @@ int clk_set_parent(struct clk *clk, struct clk 
 *parent);
 struct clk *clk_get_parent(struct clk *clk);
 
 /**
+ * clk_get_parent_by_index - get a possible parent clock by index
+ * @clk: clock source
+ * @index: index into the array of possible parents of this clock
+ *
+ * Returns struct clk corresponding to the requested possible
+ * parent clock source, or NULL.
+ */
+struct clk *clk_get_parent_by_index(struct clk *clk,
+                                 unsigned int index);
+
+/**
+ * clk_get_num_parents - get number of possible parents
+ * @clk: clock source
+ *
+ * Returns the number of possible parents of this clock,
+ * which can then be enumerated using clk_get_parent_by_index().
+ */
+unsigned int clk_get_num_parents(struct clk *clk);
+
+/**
  * clk_get_sys - get a clock based upon the device name
  * @dev_id: device name

* @con_id: connection ID

include/linux/clk.h +11 -0
@@ -461,6 +481,17 @@ static inline struct clk *clk_get_parent(struct clk 
 *clk)
      return NULL;
 }
 
+struct clk *clk_get_parent_by_index(struct clk *clk,
+                                 unsigned int index)
+{
+     return NULL;
+}
+
+unsigned int clk_get_num_parents(struct clk *clk)
+{
+     return 0;
+}
+
 #endif
 

/* clk_prepare_enable helps cases using clk_enable in non-atomic context.

author
#9 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

In reply to Scott Wood

Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options.

We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid.

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usage

 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++----------------------------
 1 file changed, 40 insertions(+), 97 deletions(-)
drivers/cpufreq/qoriq-cpufreq.c +40 -97
index 358f075..4f53fa2 100644
@@ -35,53 +35,20 @@ struct cpu_data {
 	struct cpufreq_frequency_table *table;
 };
 
+/*
+ * Don't use cpufreq on this SoC -- used when the SoC would have otherwise
+ * matched a more generic compatible.
+ */
+#define SOC_BLACKLIST		1
+
 /**
  * struct soc_data - SoC specific data
- * @freq_mask: mask the disallowed frequencies
- * @flag: unique flags
+ * @flags: SOC_xxx
  */
 struct soc_data {
-	u32 freq_mask[4];
-	u32 flag;
-};
-
-#define FREQ_MASK	1
-/* see hardware specification for the allowed frqeuencies */
-static const struct soc_data sdata[] = {
-	{ /* used by p2041 and p3041 */
-		.freq_mask = {0x8, 0x8, 0x2, 0x2},
-		.flag = FREQ_MASK,
-	},
-	{ /* used by p5020 */
-		.freq_mask = {0x8, 0x2},
-		.flag = FREQ_MASK,
-	},
-	{ /* used by p4080, p5040 */
-		.freq_mask = {0},
-		.flag = 0,
-	},
+	u32 flags;
 };
 
-/*
- * the minimum allowed core frequency, in Hz
- * for chassis v1.0, >= platform frequency
- * for chassis v2.0, >= platform frequency / 2
- */
-static u32 min_cpufreq;
-static const u32 *fmask;
-
-#if defined(CONFIG_ARM)
-static int get_cpu_physical_id(int cpu)
-{
-	return topology_core_id(cpu);
-}
-#else
-static int get_cpu_physical_id(int cpu)
-{
-	return get_hard_smp_processor_id(cpu);
-}
-#endif
-
 static u32 get_bus_freq(void)
 {
 	struct device_node *soc;
@@ -99,9 +66,10 @@ static u32 get_bus_freq(void)
 	return sysfreq;
 }
 
-static struct device_node *cpu_to_clk_node(int cpu)
+static struct clk *cpu_to_clk(int cpu)
 {
-	struct device_node *np, *clk_np;
+	struct device_node *np;
+	struct clk *clk;
 
 	if (!cpu_present(cpu))
 		return NULL;
@@ -110,37 +78,28 @@ static struct device_node *cpu_to_clk_node(int cpu)
 	if (!np)
 		return NULL;
 
-	clk_np = of_parse_phandle(np, "clocks", 0);
-	if (!clk_np)
-		return NULL;
-
+	clk = of_clk_get(np, 0);
 	of_node_put(np);
-
-	return clk_np;
+	return clk;
 }
 
 /* traverse cpu nodes to get cpu mask of sharing clock wire */
 static void set_affected_cpus(struct cpufreq_policy *policy)
 {
-	struct device_node *np, *clk_np;
 	struct cpumask *dstp = policy->cpus;
+	struct clk *clk;
 	int i;
 
-	np = cpu_to_clk_node(policy->cpu);
-	if (!np)
-		return;
-
 	for_each_present_cpu(i) {
-		clk_np = cpu_to_clk_node(i);
-		if (!clk_np)
+		clk = cpu_to_clk(i);
+		if (IS_ERR(clk)) {
+			pr_err("%s: no clock for cpu %d\n", __func__, i);
 			continue;
+		}
 
-		if (clk_np == np)
+		if (clk_is_match(policy->clk, clk))
 			cpumask_set_cpu(i, dstp);
-
-		of_node_put(clk_np);
 	}
-	of_node_put(np);
 }
 
 /* reduce the duplicated frequencies in frequency table */
@@ -198,7 +157,7 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
 	struct device_node *np, *pnode;
 	int i, count, ret;
-	u32 freq, mask;
+	u32 freq;
 	struct clk *clk;
 	struct cpufreq_frequency_table *table;
 	struct cpu_data *data;
@@ -219,17 +178,12 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
 		goto err_nomem2;
 	}
 
-	pnode = of_parse_phandle(np, "clocks", 0);
-	if (!pnode) {
-		pr_err("%s: could not get clock information\n", __func__);
-		goto err_nomem2;
-	}
+	count = clk_get_num_parents(policy->clk);
 
-	count = of_property_count_strings(pnode, "clock-names");
 	data->pclk = kcalloc(count, sizeof(struct clk *), GFP_KERNEL);
 	if (!data->pclk) {
 		pr_err("%s: no memory\n", __func__);
-		goto err_node;
+		goto err_nomem2;
 	}
 
 	table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL);
@@ -238,23 +192,11 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
 		goto err_pclk;
 	}
 
-	if (fmask)
-		mask = fmask[get_cpu_physical_id(cpu)];
-	else
-		mask = 0x0;
-
 	for (i = 0; i < count; i++) {
-		clk = of_clk_get(pnode, i);
+		clk = clk_get_parent_by_index(policy->clk, i);
 		data->pclk[i] = clk;
 		freq = clk_get_rate(clk);
-		/*
-		 * the clock is valid if its frequency is not masked
-		 * and large than minimum allowed frequency.
-		 */
-		if (freq < min_cpufreq || (mask & (1 << i)))
-			table[i].frequency = CPUFREQ_ENTRY_INVALID;
-		else
-			table[i].frequency = freq / 1000;
+		table[i].frequency = freq / 1000;
 		table[i].driver_data = i;
 	}
 	freq_table_redup(table, count);
@@ -288,10 +230,7 @@ err_nomem1:
 	kfree(table);
 err_pclk:
 	kfree(data->pclk);
-err_node:
-	of_node_put(pnode);
 err_nomem2:
-	policy->driver_data = NULL;
 	kfree(data);
 err_np:
 	of_node_put(np);
@@ -332,12 +271,20 @@ static struct cpufreq_driver qoriq_cpufreq_driver = {
 	.attr		= cpufreq_generic_attr,
 };
 
+static const struct soc_data blacklist = {
+	.flags = SOC_BLACKLIST,
+};
+
 static const struct of_device_id node_matches[] __initconst = {
-	{ .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
-	{ .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
-	{ .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
-	{ .compatible = "fsl,p4080-clockgen", .data = &sdata[2], },
-	{ .compatible = "fsl,p5040-clockgen", .data = &sdata[2], },
+	/* e6500 cannot use cpufreq due to erratum A-008083 */
+	{ .compatible = "fsl,b4420-clockgen", &blacklist },
+	{ .compatible = "fsl,b4860-clockgen", &blacklist },
+	{ .compatible = "fsl,t2080-clockgen", &blacklist },
+	{ .compatible = "fsl,t4240-clockgen", &blacklist },
+
+	{ .compatible = "fsl,ls1021a-clockgen", },
+	{ .compatible = "fsl,p4080-clockgen", },
+	{ .compatible = "fsl,qoriq-clockgen-1.0", },
 	{ .compatible = "fsl,qoriq-clockgen-2.0", },
 	{}
 };
@@ -355,16 +302,12 @@ static int __init qoriq_cpufreq_init(void)
 
 	match = of_match_node(node_matches, np);
 	data = match->data;
-	if (data) {
-		if (data->flag)
-			fmask = data->freq_mask;
-		min_cpufreq = get_bus_freq();
-	} else {
-		min_cpufreq = get_bus_freq() / 2;
-	}
 
 	of_node_put(np);
 
+	if (data && data->flags & SOC_BLACKLIST)
+		return -ENODEV;
+
 	ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
 	if (!ret)
 		pr_info("Freescale QorIQ CPU frequency scaling driver\n");
Signature · 1 line
2.1.4
maintainer
#10 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

Quoted 19 lines · Scott Wood

Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options.

We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid.

Quoted 7 lines

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usage

 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++----------------------------
 1 file changed, 40 insertions(+), 97 deletions(-)
Signature · 1 line
viresh
#11 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

Quoted 25 lines · Viresh Kumar
Quoted 24 lines · Scott Wood

Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options.

We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid.

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usage

Quoted 4 lines
Quoted 2 lines
 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++----------------------------
 1 file changed, 40 insertions(+), 97 deletions(-)

I'm wondering who's supposed to be merging this set?

Rafael

author
#12 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

Quoted 26 lines · Rafael J. Wysocki
Quoted 25 lines · Viresh Kumar
Quoted 24 lines · Scott Wood

Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options.

We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid.

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usage

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++---------------------
-------
 1 file changed, 40 insertions(+), 97 deletions(-)

I'm wondering who's supposed to be merging this set?

As I noted in the cover letter, I'm looking for acks so that I can apply these to a topic branch which can be pulled through the PPC and ARM trees, each of which will have patches that depend on it.

-Scott

#13 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

Quoted 31 lines · Scott Wood
Quoted 30 lines · Rafael J. Wysocki
Quoted 29 lines · Viresh Kumar
Quoted 27 lines · Scott Wood

Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options.

We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid.

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usage

 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++---------------------
-------
 1 file changed, 40 insertions(+), 97 deletions(-)
Quoted 7 lines
Quoted 3 lines
Quoted 1 line

I'm wondering who's supposed to be merging this set?

As I noted in the cover letter, I'm looking for acks so that I can apply these to a topic branch which can be pulled through the PPC and ARM trees, each of which will have patches that depend on it.

OK, so no objections from the cpufreq side and you have the ACK from Viresh.

Thanks,
Rafael

#14 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

Quoted 34 lines · Rafael J. Wysocki
Quoted 33 lines · Scott Wood
Quoted 32 lines · Rafael J. Wysocki
Quoted 30 lines · Viresh Kumar
Quoted 19 lines · Scott Wood

Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options.

We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid.

Quoted 8 lines

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usage

 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++---------------------
-------
 1 file changed, 40 insertions(+), 97 deletions(-)
Quoted 7 lines
Quoted 5 lines
Quoted 1 line

I'm wondering who's supposed to be merging this set?

As I noted in the cover letter, I'm looking for acks so that I can apply these to a topic branch which can be pulled through the PPC and ARM trees, each of which will have patches that depend on it.

OK, so no objections from the cpufreq side and you have the ACK from Viresh.

Hi Scott,

Did you drop this patch later? I can not find it in 4.5-rc still.

Regards,
Leo

maintainer
#15 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

Quoted 51 lines · Li Yang
Quoted 49 lines · Rafael J. Wysocki
Quoted 47 lines · Scott Wood
Quoted 33 lines · Rafael J. Wysocki
Quoted 32 lines · Viresh Kumar
Quoted 31 lines · Scott Wood

Get the CPU clock's potential parent clocks from the clock interface
itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that
those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the clock
driver's knowledge of the chip rather than a fragile device-tree description of the mux options.

We can now rely on the clock driver to ensure that the mux only exposes
options that are valid. The cpufreq driver was currently being overly
conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on
the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that
are no longer valid.

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usage

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++---------------
------
-------
 1 file changed, 40 insertions(+), 97 deletions(-)

I'm wondering who's supposed to be merging this set?

As I noted in the cover letter, I'm looking for acks so that I can apply these to a topic branch which can be pulled through the PPC and ARM trees,
each of which will have patches that depend on it.

Quoted 6 lines
Quoted 2 lines

OK, so no objections from the cpufreq side and you have the ACK from Viresh.

Hi Scott,

Did you drop this patch later? I can not find it in 4.5-rc still.

I was asked to get an ack from Russell King patch 4/5, which this patch requires. Despite repeated pings, I could not get a reply from Russell King.

-Scott

#16 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

Quoted 55 lines · Scott Wood
Quoted 54 lines · Li Yang
Quoted 51 lines · Rafael J. Wysocki
Quoted 39 lines · Scott Wood
Quoted 38 lines · Rafael J. Wysocki
Quoted 37 lines · Viresh Kumar
Quoted 35 lines · Scott Wood

Get the CPU clock's potential parent clocks from the clock interface
itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that
those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the clock
driver's knowledge of the chip rather than a fragile device-tree description of the mux options.

We can now rely on the clock driver to ensure that the mux only exposes
options that are valid. The cpufreq driver was currently being overly
conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on
the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that
are no longer valid.

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usage

 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++---------------
------
-------
 1 file changed, 40 insertions(+), 97 deletions(-)
Quoted 8 lines
Quoted 3 lines
Quoted 1 line

I'm wondering who's supposed to be merging this set?

As I noted in the cover letter, I'm looking for acks so that I can apply these to a topic branch which can be pulled through the PPC and ARM trees,
each of which will have patches that depend on it.

OK, so no objections from the cpufreq side and you have the ACK from Viresh.

Quoted 6 lines
Quoted 3 lines

Hi Scott,

Did you drop this patch later? I can not find it in 4.5-rc still.

I was asked to get an ack from Russell King patch 4/5, which this patch requires. Despite repeated pings, I could not get a reply from Russell King.

This patch? I think you should try to get ACK from clock maintainers
instead of Russell.

Commit fc4a05d4b0eb ("clk: Remove unused provider APIs") removed __clk_get_num_parents() and clk_hw_get_parent_by_index(), leaving only true provider API versions that operate on struct clk_hw.

qoriq-cpufreq needs these functions in order to determine the options it has for calling clk_set_parent() and thus populate the cpufreq table, so revive them as legitimate consumer APIs.

---
v3: new patch

 drivers/clk/clk.c   | 19 +++++++++++++++++++
 include/linux/clk.h | 31 +++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

Regards,
Leo

maintainer
#17 lore raw

PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details

Quoted 69 lines · Li Yang
Quoted 68 lines · Scott Wood
Quoted 67 lines · Li Yang
Quoted 54 lines · Rafael J. Wysocki
Quoted 53 lines · Scott Wood
Quoted 51 lines · Rafael J. Wysocki
Quoted 41 lines · Viresh Kumar
Quoted 40 lines · Scott Wood

Get the CPU clock's potential parent clocks from the clock interface
itself, rather than manually parsing the clocks property to find a
phandle, looking at the clock-names property of that, and assuming
that
those are valid parent clocks for the cpu clock.

This is necessary now that the clocks are generated based on the
clock
driver's knowledge of the chip rather than a fragile device -tree
description of the mux options.

We can now rely on the clock driver to ensure that the mux only
exposes
options that are valid. The cpufreq driver was currently being
overly
conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on
the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask
mechanism made assumptions about particular parent clock indices
that
are no longer valid.

---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes
to clk api usage

Quoted 7 lines
Quoted 5 lines
 drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++-----------
----
------
-------
 1 file changed, 40 insertions(+), 97 deletions(-)

I'm wondering who's supposed to be merging this set?

Quoted 8 lines
Quoted 5 lines

As I noted in the cover letter, I'm looking for acks so that I can apply
these to a topic branch which can be pulled through the PPC and ARM trees,
each of which will have patches that depend on it.

OK, so no objections from the cpufreq side and you have the ACK from Viresh.

Hi Scott,

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Did you drop this patch later? I can not find it in 4.5-rc still.

I was asked to get an ack from Russell King patch 4/5, which this patch requires. Despite repeated pings, I could not get a reply from Russell King.

This patch? I think you should try to get ACK from clock maintainers
instead of Russell.

A clock maintainer was who asked me to get an ACK from Russell.

-Scott

author
#18 lore raw

v3 cover clk: qoriq: Move chip-specific knowledge into driver

In reply to Scott Wood
Quoted 12 lines · Scott Wood

The existing device tree bindings are error-prone and inflexible. Correct the mistake by moving the knowledge into the driver, which has more flexibility in describing the quirks of each chip. This leaves the device tree to its proper role of identifying a programming interface rather than describing its individual registers.

For more detail, see the commit message of patch 2.

As there are both ARM and PPC patches that depend on this patchset, I'm requesting ACKs from clk and cpufreq in order to put this into a topic branch that both ARM and PPC can pull.

Quoted 6 lines

Scott Wood (5):
powerpc/fsl: Move fsl_guts.h out of arch/powerpc
clk: qoriq: Move chip-specific knowledge into driver
clk: qoriq: Add ls2080a support.
clk: Add consumer APIs for discovering possible parent clocks
cpufreq: qoriq: Don't look at clock implementation details

I've applied the first three patches plus
http://patchwork.ozlabs.org/patch/534739/ to the clock branch of scottwood/linux.git to be used as a basis for PPC and ARM device tree patches.

Note that there is a trivial merge conflict with commit 4a7748c3d6419bb8178748 ("clk: Allow drivers to build if COMPILE_TEST is enabled"). Another option is for these patches to go via the clk tree, and the device tree patches will ust go separately. This would result in intermediate commits where the device tree contains clock information that the clock driver can't handle, but it would be resolved by -rc1 -- and it seems that one of the ARM device tree patches ("dts/ls2080a: Update DTSI to add support of various peripherals") was already merged without waiting for the clock driver patch. I could still wait until next merge window to rip out the legacy stuff from existing device trees, so it would only affect new functionality.

Patch 4 is still waiting for an ack from Russell King, but it appears that patch 5 (which depends on patch 4) can probably wait until the next merge window. Without those patches, qoriq-cpufreq should still mostly work, as long as the old device trees are used. Patches 4 and 5 will be needed to make qoriq-cpufreq continue to work with device trees using the new binding.

-Scott