clk: qoriq: Move chip-specific knowledge into driver
Subsystems (10)
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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v3 2/5 clk: qoriq: Move chip-specific knowledge into driver
In reply to Scott WoodThe 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
@@ -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
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
Signed-off-by Scott Wood <[email protected]>---
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH v3 3/5 clk: qoriq: Add ls2080a support.
In reply to Scott WoodLS2080A 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
@@ -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
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.
Signed-off-by Scott Wood <[email protected]>---
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH v3 4/5 clk: Add consumer APIs for discovering possible parent clocks
In reply to Scott WoodCommit 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
@@ -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
@@ -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
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()andclk_hw_get_parent_by_index(), leaving only true provider API versions that operate on structclk_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
Signed-off-by Scott Wood <[email protected]>---
v3: new patchdrivers/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@@ -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@@ -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_enablehelps cases usingclk_enablein non-atomic context.
*/
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()andclk_hw_get_parent_by_index(), leaving only true provider API versions that operate on structclk_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.Signed-off-by Scott Wood <[email protected]>---
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@@ -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@@ -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_enablehelps cases usingclk_enablein non-atomic context.
PATCH v3 5/5 cpufreq: qoriq: Don't look at clock implementation details
In reply to Scott WoodGet 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
@@ -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
Viresh Kumar
maintainerPATCH 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 thefreq_maskused 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
Signed-off-by Scott Wood <[email protected]>---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usagedrivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++---------------------------- 1 file changed, 40 insertions(+), 97 deletions(-)
Signature · 1 line
viresh
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 thefreq_maskused 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.Signed-off-by Scott Wood <[email protected]>---
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(-)Acked-by Viresh Kumar <[email protected]>
I'm wondering who's supposed to be merging this set?
Rafael
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 thefreq_maskused 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.Signed-off-by Scott Wood <[email protected]>---
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(-)Acked-by Viresh Kumar <[email protected]>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
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 thefreq_maskused 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.Signed-off-by Scott Wood <[email protected]>---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usagedrivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++--------------------- ------- 1 file changed, 40 insertions(+), 97 deletions(-)
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
Acked-by Viresh Kumar <[email protected]>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
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 thefreq_maskused 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
Signed-off-by Scott Wood <[email protected]>---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usagedrivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++--------------------- ------- 1 file changed, 40 insertions(+), 97 deletions(-)Acked-by Viresh Kumar <[email protected]>
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
Scott Wood
maintainerPATCH 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 thefreq_maskused 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.Signed-off-by Scott Wood <[email protected]>---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usageQuoted 8 lines
Quoted 6 lines
Quoted 4 lines
drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++--------------- ------ ------- 1 file changed, 40 insertions(+), 97 deletions(-)Acked-by Viresh Kumar <[email protected]>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
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 thefreq_maskused 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.Signed-off-by Scott Wood <[email protected]>---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes to clk api usagedrivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++--------------- ------ ------- 1 file changed, 40 insertions(+), 97 deletions(-)Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Acked-by Viresh Kumar <[email protected]>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
Scott Wood
maintainerPATCH 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 thefreq_maskused 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.Signed-off-by Scott Wood <[email protected]>---
v3: was patch 1/5 and patch 4/5, plus blacklist e6500 and changes
to clk api usageQuoted 7 lines
Quoted 5 lines
drivers/cpufreq/qoriq-cpufreq.c | 137 ++++++++++++----------- ---- ------ ------- 1 file changed, 40 insertions(+), 97 deletions(-)Acked-by Viresh Kumar <[email protected]>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
v3 cover clk: qoriq: Move chip-specific knowledge into driver
In reply to Scott WoodQuoted 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: Movefsl_guts.hout ofarch/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