You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'clk-for-linus-3.18' of git://git.linaro.org/people/mike.turquette/linux
Pull clock tree updates from Mike Turquette: "The clk tree changes for 3.18 are dominated by clock drivers. Mostly fixes and enhancements to existing drivers as well as new drivers. This tag contains a bit more arch code than I usually take due to some OMAP2+ changes. Additionally it contains the restart notifier handlers which are merged as a dependency into several trees. The PXA changes are the only messy part. Due to having a stable tree I had to revert one patch and follow up with one more fix near the tip of this tag. Some dead code is introduced but it will soon become live code after 3.18-rc1 is released as the rest of the PXA family is converted over to the common clock framework. Another trend in this tag is that multiple vendors have started to push the complexity of changing their CPU frequency into the clock driver, whereas this used to be done in CPUfreq drivers. Changes to the clk core include a generic gpio-clock type and a clk_set_phase() function added to the top-level clk.h api. Due to some confusion on the fbdev mailing list the kernel boot parameters documentation was updated to further explain the clk_ignore_unused parameter, which is often required by users of the simplefb driver. Finally some fixes to the locking around the clock debugfs stuff was done to prevent deadlocks when interacting with other subsystems." * tag 'clk-for-linus-3.18' of git://git.linaro.org/people/mike.turquette/linux: (99 commits) clk: pxa clocks build system fix Revert "arm: pxa: Transition pxa27x to clk framework" clk: samsung: register restart handlers for s3c2412 and s3c2443 clk: rockchip: add restart handler clk: rockchip: rk3288: i2s_frac adds flag to set parent's rate doc/kernel-parameters.txt: clarify clk_ignore_unused arm: pxa: Transition pxa27x to clk framework dts: add devicetree bindings for pxa27x clocks clk: add pxa27x clock drivers arm: pxa: add clock pll selection bits clk: dts: document pxa clock binding clk: add pxa clocks infrastructure clk: gpio-gate: Ensure gpiod_ APIs are prototyped clk: ti: dra7-atl-clock: Mark the device as pm_runtime_irq_safe clk: ti: LLVMLinux: Move __init outside of type definition clk: ti: consider the fact that of_clk_get() might return an error clk: ti: dra7-atl-clock: fix a memory leak clk: ti: change clock init to use generic of_clk_init clk: hix5hd2: add I2C clocks clk: hix5hd2: add watchdog0 clocks ...
This commit is contained in:
@@ -7,6 +7,8 @@ Required Properties:
|
||||
|
||||
- compatible: should be one of the following.
|
||||
- "samsung,exynos3250-cmu" - controller compatible with Exynos3250 SoC.
|
||||
- "samsung,exynos3250-cmu-dmc" - controller compatible with
|
||||
Exynos3250 SoC for Dynamic Memory Controller domain.
|
||||
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
@@ -20,7 +22,7 @@ All available clocks are defined as preprocessor macros in
|
||||
dt-bindings/clock/exynos3250.h header and can be used in device
|
||||
tree sources.
|
||||
|
||||
Example 1: An example of a clock controller node is listed below.
|
||||
Example 1: Examples of clock controller nodes are listed below.
|
||||
|
||||
cmu: clock-controller@10030000 {
|
||||
compatible = "samsung,exynos3250-cmu";
|
||||
@@ -28,6 +30,12 @@ Example 1: An example of a clock controller node is listed below.
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
cmu_dmc: clock-controller@105C0000 {
|
||||
compatible = "samsung,exynos3250-cmu-dmc";
|
||||
reg = <0x105C0000 0x2000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
Example 2: UART controller node that consumes the clock generated by the clock
|
||||
controller. Refer to the standard clock bindings for information
|
||||
about 'clocks' and 'clock-names' property.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
Binding for simple gpio gated clock.
|
||||
|
||||
This binding uses the common clock binding[1].
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be "gpio-gate-clock".
|
||||
- #clock-cells : from common clock binding; shall be set to 0.
|
||||
- enable-gpios : GPIO reference for enabling and disabling the clock.
|
||||
|
||||
Optional properties:
|
||||
- clocks: Maximum of one parent clock is supported.
|
||||
|
||||
Example:
|
||||
clock {
|
||||
compatible = "gpio-gate-clock";
|
||||
clocks = <&parentclk>;
|
||||
#clock-cells = <0>;
|
||||
enable-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
@@ -9,13 +9,21 @@ The MAX77686 contains three 32.768khz clock outputs that can be controlled
|
||||
Following properties should be presend in main device node of the MFD chip.
|
||||
|
||||
Required properties:
|
||||
- #clock-cells: simple one-cell clock specifier format is used, where the
|
||||
only cell is used as an index of the clock inside the provider. Following
|
||||
indices are allowed:
|
||||
|
||||
- #clock-cells: from common clock binding; shall be set to 1.
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names: From common clock binding.
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. Following indices are allowed:
|
||||
- 0: 32khz_ap clock,
|
||||
- 1: 32khz_cp clock,
|
||||
- 2: 32khz_pmic clock.
|
||||
|
||||
Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77686.h
|
||||
header and can be used in device tree sources.
|
||||
|
||||
Example: Node of the MFD chip
|
||||
|
||||
max77686: max77686@09 {
|
||||
@@ -34,5 +42,5 @@ Example: Clock consumer node
|
||||
compatible = "bar,foo";
|
||||
/* ... */
|
||||
clock-names = "my-clock";
|
||||
clocks = <&max77686 2>;
|
||||
clocks = <&max77686 MAX77686_CLK_PMIC>;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
Binding for Maxim MAX77802 32k clock generator block
|
||||
|
||||
This is a part of device tree bindings of MAX77802 multi-function device.
|
||||
More information can be found in bindings/mfd/max77802.txt file.
|
||||
|
||||
The MAX77802 contains two 32.768khz clock outputs that can be controlled
|
||||
(gated/ungated) over I2C.
|
||||
|
||||
Following properties should be present in main device node of the MFD chip.
|
||||
|
||||
Required properties:
|
||||
- #clock-cells: From common clock binding; shall be set to 1.
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names: From common clock binding.
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. Following indices are allowed:
|
||||
- 0: 32khz_ap clock,
|
||||
- 1: 32khz_cp clock.
|
||||
|
||||
Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77802.h
|
||||
header and can be used in device tree sources.
|
||||
|
||||
Example: Node of the MFD chip
|
||||
|
||||
max77802: max77802@09 {
|
||||
compatible = "maxim,max77802";
|
||||
interrupt-parent = <&wakeup_eint>;
|
||||
interrupts = <26 0>;
|
||||
reg = <0x09>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
/* ... */
|
||||
};
|
||||
|
||||
Example: Clock consumer node
|
||||
|
||||
foo@0 {
|
||||
compatible = "bar,foo";
|
||||
/* ... */
|
||||
clock-names = "my-clock";
|
||||
clocks = <&max77802 MAX77802_CLK_32K_AP>;
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
* Clock bindings for Marvell PXA chips
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "marvell,pxa-clocks"
|
||||
- #clock-cells: Should be <1>
|
||||
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell (see include/.../pxa-clock.h).
|
||||
|
||||
Examples:
|
||||
|
||||
pxa2xx_clks: pxa2xx_clks@41300004 {
|
||||
compatible = "marvell,pxa-clocks";
|
||||
#clock-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -15,6 +15,7 @@ Required Properties:
|
||||
- "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks
|
||||
- "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
|
||||
- "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
|
||||
- "renesas,r8a7794-mstp-clocks" for R8A7794 (R-Car E2) MSTP gate clocks
|
||||
- "renesas,sh73a0-mstp-clocks" for SH73A0 (SH-MobileAG5) MSTP gate clocks
|
||||
- "renesas,cpg-mstp-clock" for generic MSTP gate clocks
|
||||
- reg: Base address and length of the I/O mapped registers used by the MSTP
|
||||
|
||||
@@ -8,6 +8,7 @@ Required Properties:
|
||||
- compatible: Must be one of
|
||||
- "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
|
||||
- "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG
|
||||
- "renesas,r8a7794-cpg-clocks" for the r8a7794 CPG
|
||||
- "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG
|
||||
|
||||
- reg: Base address and length of the memory resource used by the CPG
|
||||
|
||||
@@ -46,7 +46,11 @@ Required properties:
|
||||
"allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
|
||||
"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
|
||||
"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
|
||||
"allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13
|
||||
"allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10
|
||||
"allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10
|
||||
"allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
|
||||
"allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23
|
||||
"allwinner,sun7i-a20-out-clk" - for the external output clocks
|
||||
"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
|
||||
"allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
|
||||
|
||||
@@ -605,11 +605,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
See Documentation/s390/CommonIO for details.
|
||||
clk_ignore_unused
|
||||
[CLK]
|
||||
Keep all clocks already enabled by bootloader on,
|
||||
even if no driver has claimed them. This is useful
|
||||
for debug and development, but should not be
|
||||
needed on a platform with proper driver support.
|
||||
For more information, see Documentation/clk.txt.
|
||||
Prevents the clock framework from automatically gating
|
||||
clocks that have not been explicitly enabled by a Linux
|
||||
device driver but are enabled in hardware at reset or
|
||||
by the bootloader/firmware. Note that this does not
|
||||
force such clocks to be always-on nor does it reserve
|
||||
those clocks in any way. This parameter is useful for
|
||||
debug and development, but should not be needed on a
|
||||
platform with proper driver support. For more
|
||||
information, see Documentation/clk.txt.
|
||||
|
||||
clock= [BUGS=X86-32, HW] gettimeofday clocksource override.
|
||||
[Deprecated]
|
||||
|
||||
@@ -169,6 +169,12 @@
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
cmu_dmc: clock-controller@105C0000 {
|
||||
compatible = "samsung,exynos3250-cmu-dmc";
|
||||
reg = <0x105C0000 0x2000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
rtc: rtc@10070000 {
|
||||
compatible = "samsung,exynos3250-rtc";
|
||||
reg = <0x10070000 0x100>;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* The pxa3xx skeleton simply augments the 2xx version */
|
||||
/include/ "pxa2xx.dtsi"
|
||||
#include "pxa2xx.dtsi"
|
||||
#include "dt-bindings/clock/pxa2xx-clock.h"
|
||||
|
||||
/ {
|
||||
model = "Marvell PXA27x familiy SoC";
|
||||
@@ -35,4 +36,21 @@
|
||||
#pwm-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
/*
|
||||
* The muxing of external clocks/internal dividers for osc* clock
|
||||
* sources has been hidden under the carpet by now.
|
||||
*/
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
pxa2xx_clks: pxa2xx_clks@41300004 {
|
||||
compatible = "marvell,pxa-clocks";
|
||||
#clock-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -287,7 +287,7 @@
|
||||
|
||||
mbus_clk: clk@01c2015c {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-mod0-clk";
|
||||
compatible = "allwinner,sun5i-a13-mbus-clk";
|
||||
reg = <0x01c2015c 0x4>;
|
||||
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
|
||||
clock-output-names = "mbus";
|
||||
|
||||
@@ -285,7 +285,7 @@
|
||||
|
||||
mbus_clk: clk@01c2015c {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-mod0-clk";
|
||||
compatible = "allwinner,sun5i-a13-mbus-clk";
|
||||
reg = <0x01c2015c 0x4>;
|
||||
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
|
||||
clock-output-names = "mbus";
|
||||
|
||||
@@ -382,7 +382,7 @@
|
||||
|
||||
mbus_clk: clk@01c2015c {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-mod0-clk";
|
||||
compatible = "allwinner,sun5i-a13-mbus-clk";
|
||||
reg = <0x01c2015c 0x4>;
|
||||
clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
|
||||
clock-output-names = "mbus";
|
||||
|
||||
@@ -723,8 +723,16 @@ int __init omap_clk_init(void)
|
||||
ti_clk_init_features();
|
||||
|
||||
ret = of_prcm_init();
|
||||
if (!ret)
|
||||
ret = omap_clk_soc_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
of_clk_init(NULL);
|
||||
|
||||
ti_dt_clk_init_retry_clks();
|
||||
|
||||
ti_dt_clockdomains_setup();
|
||||
|
||||
ret = omap_clk_soc_init();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -525,8 +525,6 @@ int __init of_prcm_init(void)
|
||||
memmap_index++;
|
||||
}
|
||||
|
||||
ti_dt_clockdomains_setup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +143,16 @@
|
||||
#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */
|
||||
#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */
|
||||
|
||||
#define CCCR_CPDIS_BIT (31)
|
||||
#define CCCR_PPDIS_BIT (30)
|
||||
#define CCCR_LCD_26_BIT (27)
|
||||
#define CCCR_A_BIT (25)
|
||||
|
||||
#define CCSR_N2_MASK CCCR_N_MASK
|
||||
#define CCSR_M_MASK CCCR_M_MASK
|
||||
#define CCSR_L_MASK CCCR_L_MASK
|
||||
#define CCSR_N2_SHIFT 7
|
||||
|
||||
#define CKEN_AC97CONF (31) /* AC97 Controller Configuration */
|
||||
#define CKEN_CAMERA (24) /* Camera Interface Clock Enable */
|
||||
#define CKEN_SSP1 (23) /* SSP1 Unit Clock Enable */
|
||||
|
||||
@@ -32,12 +32,23 @@ config COMMON_CLK_WM831X
|
||||
|
||||
source "drivers/clk/versatile/Kconfig"
|
||||
|
||||
config COMMON_CLK_MAX_GEN
|
||||
bool
|
||||
|
||||
config COMMON_CLK_MAX77686
|
||||
tristate "Clock driver for Maxim 77686 MFD"
|
||||
depends on MFD_MAX77686
|
||||
select COMMON_CLK_MAX_GEN
|
||||
---help---
|
||||
This driver supports Maxim 77686 crystal oscillator clock.
|
||||
|
||||
config COMMON_CLK_MAX77802
|
||||
tristate "Clock driver for Maxim 77802 PMIC"
|
||||
depends on MFD_MAX77686
|
||||
select COMMON_CLK_MAX_GEN
|
||||
---help---
|
||||
This driver supports Maxim 77802 crystal oscillator clock.
|
||||
|
||||
config COMMON_CLK_RK808
|
||||
tristate "Clock driver for RK808"
|
||||
depends on MFD_RK808
|
||||
@@ -118,6 +129,11 @@ config COMMON_CLK_PALMAS
|
||||
This driver supports TI Palmas devices 32KHz output KG and KG_AUDIO
|
||||
using common clock framework.
|
||||
|
||||
config COMMON_CLK_PXA
|
||||
def_bool COMMON_CLK && ARCH_PXA
|
||||
---help---
|
||||
Sypport for the Marvell PXA SoC.
|
||||
|
||||
source "drivers/clk/qcom/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -9,6 +9,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-gate.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-mux.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-composite.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-gpio-gate.o
|
||||
ifeq ($(CONFIG_OF), y)
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-conf.o
|
||||
endif
|
||||
@@ -22,7 +23,9 @@ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
|
||||
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
|
||||
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
|
||||
obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
|
||||
obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o
|
||||
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
|
||||
obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o
|
||||
obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
|
||||
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
|
||||
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
|
||||
@@ -49,6 +52,7 @@ obj-$(CONFIG_ARCH_MMP) += mmp/
|
||||
endif
|
||||
obj-$(CONFIG_PLAT_ORION) += mvebu/
|
||||
obj-$(CONFIG_ARCH_MXS) += mxs/
|
||||
obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
|
||||
obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
|
||||
|
||||
+83
-81
@@ -15,6 +15,7 @@
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -29,9 +30,12 @@
|
||||
#define PLL_DIV(reg) ((reg) & PLL_DIV_MASK)
|
||||
#define PLL_MUL(reg, layout) (((reg) >> (layout)->mul_shift) & \
|
||||
(layout)->mul_mask)
|
||||
#define PLL_MUL_MIN 2
|
||||
#define PLL_MUL_MASK(layout) ((layout)->mul_mask)
|
||||
#define PLL_MUL_MAX(layout) (PLL_MUL_MASK(layout) + 1)
|
||||
#define PLL_ICPR_SHIFT(id) ((id) * 16)
|
||||
#define PLL_ICPR_MASK(id) (0xffff << PLL_ICPR_SHIFT(id))
|
||||
#define PLL_MAX_COUNT 0x3ff
|
||||
#define PLL_MAX_COUNT 0x3f
|
||||
#define PLL_COUNT_SHIFT 8
|
||||
#define PLL_OUT_SHIFT 14
|
||||
#define PLL_MAX_ID 1
|
||||
@@ -147,115 +151,113 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
const struct clk_pll_layout *layout = pll->layout;
|
||||
struct at91_pmc *pmc = pll->pmc;
|
||||
int offset = PLL_REG(pll->id);
|
||||
u32 tmp = pmc_read(pmc, offset) & layout->pllr_mask;
|
||||
u8 div = PLL_DIV(tmp);
|
||||
u16 mul = PLL_MUL(tmp, layout);
|
||||
if (!div || !mul)
|
||||
|
||||
if (!pll->div || !pll->mul)
|
||||
return 0;
|
||||
|
||||
return (parent_rate * (mul + 1)) / div;
|
||||
return (parent_rate / pll->div) * (pll->mul + 1);
|
||||
}
|
||||
|
||||
static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
u32 *div, u32 *mul,
|
||||
u32 *index) {
|
||||
unsigned long maxrate;
|
||||
unsigned long minrate;
|
||||
unsigned long divrate;
|
||||
unsigned long bestdiv = 1;
|
||||
unsigned long bestmul;
|
||||
unsigned long tmpdiv;
|
||||
unsigned long roundup;
|
||||
unsigned long rounddown;
|
||||
unsigned long remainder;
|
||||
unsigned long bestremainder;
|
||||
unsigned long maxmul;
|
||||
unsigned long maxdiv;
|
||||
unsigned long mindiv;
|
||||
int i = 0;
|
||||
const struct clk_pll_layout *layout = pll->layout;
|
||||
const struct clk_pll_characteristics *characteristics =
|
||||
pll->characteristics;
|
||||
unsigned long bestremainder = ULONG_MAX;
|
||||
unsigned long maxdiv, mindiv, tmpdiv;
|
||||
long bestrate = -ERANGE;
|
||||
unsigned long bestdiv;
|
||||
unsigned long bestmul;
|
||||
int i = 0;
|
||||
|
||||
/* Minimum divider = 1 */
|
||||
/* Maximum multiplier = max_mul */
|
||||
maxmul = layout->mul_mask + 1;
|
||||
maxrate = (parent_rate * maxmul) / 1;
|
||||
|
||||
/* Maximum divider = max_div */
|
||||
/* Minimum multiplier = 2 */
|
||||
maxdiv = PLL_DIV_MAX;
|
||||
minrate = (parent_rate * 2) / maxdiv;
|
||||
|
||||
/* Check if parent_rate is a valid input rate */
|
||||
if (parent_rate < characteristics->input.min ||
|
||||
parent_rate < characteristics->input.max)
|
||||
parent_rate > characteristics->input.max)
|
||||
return -ERANGE;
|
||||
|
||||
if (parent_rate < minrate || parent_rate > maxrate)
|
||||
return -ERANGE;
|
||||
/*
|
||||
* Calculate minimum divider based on the minimum multiplier, the
|
||||
* parent_rate and the requested rate.
|
||||
* Should always be 2 according to the input and output characteristics
|
||||
* of the PLL blocks.
|
||||
*/
|
||||
mindiv = (parent_rate * PLL_MUL_MIN) / rate;
|
||||
if (!mindiv)
|
||||
mindiv = 1;
|
||||
|
||||
/*
|
||||
* Calculate the maximum divider which is limited by PLL register
|
||||
* layout (limited by the MUL or DIV field size).
|
||||
*/
|
||||
maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX(layout), rate);
|
||||
if (maxdiv > PLL_DIV_MAX)
|
||||
maxdiv = PLL_DIV_MAX;
|
||||
|
||||
/*
|
||||
* Iterate over the acceptable divider values to find the best
|
||||
* divider/multiplier pair (the one that generates the closest
|
||||
* rate to the requested one).
|
||||
*/
|
||||
for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) {
|
||||
unsigned long remainder;
|
||||
unsigned long tmprate;
|
||||
unsigned long tmpmul;
|
||||
|
||||
/*
|
||||
* Calculate the multiplier associated with the current
|
||||
* divider that provide the closest rate to the requested one.
|
||||
*/
|
||||
tmpmul = DIV_ROUND_CLOSEST(rate, parent_rate / tmpdiv);
|
||||
tmprate = (parent_rate / tmpdiv) * tmpmul;
|
||||
if (tmprate > rate)
|
||||
remainder = tmprate - rate;
|
||||
else
|
||||
remainder = rate - tmprate;
|
||||
|
||||
/*
|
||||
* Compare the remainder with the best remainder found until
|
||||
* now and elect a new best multiplier/divider pair if the
|
||||
* current remainder is smaller than the best one.
|
||||
*/
|
||||
if (remainder < bestremainder) {
|
||||
bestremainder = remainder;
|
||||
bestdiv = tmpdiv;
|
||||
bestmul = tmpmul;
|
||||
bestrate = tmprate;
|
||||
}
|
||||
|
||||
/*
|
||||
* We've found a perfect match!
|
||||
* Stop searching now and use this multiplier/divider pair.
|
||||
*/
|
||||
if (!remainder)
|
||||
break;
|
||||
}
|
||||
|
||||
/* We haven't found any multiplier/divider pair => return -ERANGE */
|
||||
if (bestrate < 0)
|
||||
return bestrate;
|
||||
|
||||
/* Check if bestrate is a valid output rate */
|
||||
for (i = 0; i < characteristics->num_output; i++) {
|
||||
if (parent_rate >= characteristics->output[i].min &&
|
||||
parent_rate <= characteristics->output[i].max)
|
||||
if (bestrate >= characteristics->output[i].min &&
|
||||
bestrate <= characteristics->output[i].max)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= characteristics->num_output)
|
||||
return -ERANGE;
|
||||
|
||||
bestmul = rate / parent_rate;
|
||||
rounddown = parent_rate % rate;
|
||||
roundup = rate - rounddown;
|
||||
bestremainder = roundup < rounddown ? roundup : rounddown;
|
||||
|
||||
if (!bestremainder) {
|
||||
if (div)
|
||||
*div = bestdiv;
|
||||
if (mul)
|
||||
*mul = bestmul;
|
||||
if (index)
|
||||
*index = i;
|
||||
return rate;
|
||||
}
|
||||
|
||||
maxdiv = 255 / (bestmul + 1);
|
||||
if (parent_rate / maxdiv < characteristics->input.min)
|
||||
maxdiv = parent_rate / characteristics->input.min;
|
||||
mindiv = parent_rate / characteristics->input.max;
|
||||
if (parent_rate % characteristics->input.max)
|
||||
mindiv++;
|
||||
|
||||
for (tmpdiv = mindiv; tmpdiv < maxdiv; tmpdiv++) {
|
||||
divrate = parent_rate / tmpdiv;
|
||||
|
||||
rounddown = rate % divrate;
|
||||
roundup = divrate - rounddown;
|
||||
remainder = roundup < rounddown ? roundup : rounddown;
|
||||
|
||||
if (remainder < bestremainder) {
|
||||
bestremainder = remainder;
|
||||
bestmul = rate / divrate;
|
||||
bestdiv = tmpdiv;
|
||||
}
|
||||
|
||||
if (!remainder)
|
||||
break;
|
||||
}
|
||||
|
||||
rate = (parent_rate / bestdiv) * bestmul;
|
||||
|
||||
if (div)
|
||||
*div = bestdiv;
|
||||
if (mul)
|
||||
*mul = bestmul;
|
||||
*mul = bestmul - 1;
|
||||
if (index)
|
||||
*index = i;
|
||||
|
||||
return rate;
|
||||
return bestrate;
|
||||
}
|
||||
|
||||
static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user