mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
Convert the OMAP2+ clock code and data to rely on the common
clock framework for internal bookkeeping and the driver API. Basic test logs for this branch on top of Tony's cleanup-prcm branch at commitc9d501e5cb
are here: http://www.pwsan.com/omap/testlogs/common_clk_devel_3.8_rebase/20121112192516/ However, cleanup-prcm atc9d501e5
does not include some fixes that are needed for a successful test. With several reverts, fixes, and workarounds applied, the following test logs were obtained: http://www.pwsan.com/omap/testlogs/TEST_common_clk_devel_3.8_rebase/20121112192300/ which indicate that the series tests cleanly. N.B. The common clock data addition patches result in many checkpatch warnings of the form "WARNING: static const char * array should probably be static const char * const". However, it appears that resolving these would require changes to the CCF itself. So the resolution of these warnings is being postponed until that can be coordinated. These patches result in a ~55KiB increase in runtime kernel memory usage when booting omap2plus_defconfig kernels. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJQonKoAAoJEMePsQ0LvSpLjesQAKwgh4WWzYGnlysAJ+QBUS0d Gx4mmHLIFIhz0j/8Wh7NISjhjfqvT/JgPzszMUB9QGIZALhqjVlSeOs4AdcwPEvI YJhrE5osBQl2IufcflHgZzhlSqSNWczrECZQCQ+lWbBoibGB3g936l7YxFg4G1ua kjvaF7afDnVEuQ276276gA4JHWsd0BITe/qUfDFiBOQRqdKN+TanWSqyc+3j+hws 7fTaQLE+B/Okoiye4iycaJUL++pCquJIVklewaCOyQhtQ0MsCfIDVvn/amd8Xh6V pEFuXaGK8O4C/CaLIvsee/+/86A4pJo5ahh42Q3a3jE/hBP6Fa2JKWE+hFd3owdc FMAOoSBtxXrHXSiempkHnYM5lXdTZImW0DTfSKuc6V1plRT4cbxuC9a2IHOP3otU b669JE3xg/xYBqWIwDFHWFiPkBchO1UOH1q/Rieb7NYsYwx8yzNIp6oNxbPqCsy3 pmWWMxSrGm0/H/uvQHzHBCW8q4Qp4cFTiewPJz53t5W9wUw4L/AkL1uRsmu4I7Xy fdceSnhq1/fud02RCBrpt5PW9PAeLit9AU6IQxx8HTZCsrUU0r580dxVhJwwjX8I CmGJ1iNS7vhaf0Q7asdvIRg7e9DrM/RWdJ4UU0+Dki7S2WUPrrlA5pAZtRtivP1Y KCT3xkyLdIdEVXYVtiBD =VWPp -----END PGP SIGNATURE----- Merge tag 'omap-cleanup-c-for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v3.8/clock Convert the OMAP2+ clock code and data to rely on the common clock framework for internal bookkeeping and the driver API. Basic test logs for this branch on top of Tony's cleanup-prcm branch at commitc9d501e5cb
are here: http://www.pwsan.com/omap/testlogs/common_clk_devel_3.8_rebase/20121112192516/ However, cleanup-prcm atc9d501e5
does not include some fixes that are needed for a successful test. With several reverts, fixes, and workarounds applied, the following test logs were obtained: http://www.pwsan.com/omap/testlogs/TEST_common_clk_devel_3.8_rebase/20121112192300/ which indicate that the series tests cleanly. N.B. The common clock data addition patches result in many checkpatch warnings of the form "WARNING: static const char * array should probably be static const char * const". However, it appears that resolving these would require changes to the CCF itself. So the resolution of these warnings is being postponed until that can be coordinated. These patches result in a ~55KiB increase in runtime kernel memory usage when booting omap2plus_defconfig kernels. Conflicts: arch/arm/mach-omap2/clock33xx_data.c arch/arm/mach-omap2/clock3xxx_data.c arch/arm/mach-omap2/clock44xx_data.c
This commit is contained in:
commit
558a0780b0
48 changed files with 11521 additions and 13499 deletions
|
@ -34,6 +34,7 @@ config ARCH_OMAP2
|
|||
select CPU_V6
|
||||
select MULTI_IRQ_HANDLER
|
||||
select SOC_HAS_OMAP2_SDRC
|
||||
select COMMON_CLK
|
||||
|
||||
config ARCH_OMAP3
|
||||
bool "TI OMAP3"
|
||||
|
@ -47,6 +48,7 @@ config ARCH_OMAP3
|
|||
select PM_OPP if PM
|
||||
select PM_RUNTIME if CPU_IDLE
|
||||
select SOC_HAS_OMAP2_SDRC
|
||||
select COMMON_CLK
|
||||
select USB_ARCH_HAS_EHCI if USB_SUPPORT
|
||||
|
||||
config ARCH_OMAP4
|
||||
|
@ -68,6 +70,7 @@ config ARCH_OMAP4
|
|||
select PM_OPP if PM
|
||||
select PM_RUNTIME if CPU_IDLE
|
||||
select USB_ARCH_HAS_EHCI if USB_SUPPORT
|
||||
select COMMON_CLK
|
||||
|
||||
config SOC_OMAP5
|
||||
bool "TI OMAP5"
|
||||
|
@ -77,6 +80,7 @@ config SOC_OMAP5
|
|||
select CPU_V7
|
||||
select HAVE_SMP
|
||||
select SOC_HAS_REALTIME_COUNTER
|
||||
select COMMON_CLK
|
||||
|
||||
comment "OMAP Core Type"
|
||||
depends on ARCH_OMAP2
|
||||
|
@ -111,6 +115,7 @@ config SOC_AM33XX
|
|||
select ARM_CPU_SUSPEND if PM
|
||||
select CPU_V7
|
||||
select MULTI_IRQ_HANDLER
|
||||
select COMMON_CLK
|
||||
|
||||
config OMAP_PACKAGE_ZAF
|
||||
bool
|
||||
|
|
|
@ -158,17 +158,17 @@ obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
|
|||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
|
||||
obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2420) += cclock2420_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o cclock2430_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o cclock3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) cclock44xx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += clock33xx_data.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += cclock33xx_data.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += $(clock-common)
|
||||
obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o
|
||||
|
||||
|
|
1950
arch/arm/mach-omap2/cclock2420_data.c
Normal file
1950
arch/arm/mach-omap2/cclock2420_data.c
Normal file
File diff suppressed because it is too large
Load diff
2065
arch/arm/mach-omap2/cclock2430_data.c
Normal file
2065
arch/arm/mach-omap2/cclock2430_data.c
Normal file
File diff suppressed because it is too large
Load diff
961
arch/arm/mach-omap2/cclock33xx_data.c
Normal file
961
arch/arm/mach-omap2/cclock33xx_data.c
Normal file
|
@ -0,0 +1,961 @@
|
|||
/*
|
||||
* AM33XX Clock data
|
||||
*
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Vaibhav Hiremath <hvaibhav@ti.com>
|
||||
*
|
||||
* 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 version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/clk-private.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "am33xx.h"
|
||||
#include "soc.h"
|
||||
#include "iomap.h"
|
||||
#include "clock.h"
|
||||
#include "control.h"
|
||||
#include "cm.h"
|
||||
#include "cm33xx.h"
|
||||
#include "cm-regbits-33xx.h"
|
||||
#include "prm.h"
|
||||
|
||||
/* Modulemode control */
|
||||
#define AM33XX_MODULEMODE_HWCTRL_SHIFT 0
|
||||
#define AM33XX_MODULEMODE_SWCTRL_SHIFT 1
|
||||
|
||||
/*LIST_HEAD(clocks);*/
|
||||
|
||||
/* Root clocks */
|
||||
|
||||
/* RTC 32k */
|
||||
DEFINE_CLK_FIXED_RATE(clk_32768_ck, CLK_IS_ROOT, 32768, 0x0);
|
||||
|
||||
/* On-Chip 32KHz RC OSC */
|
||||
DEFINE_CLK_FIXED_RATE(clk_rc32k_ck, CLK_IS_ROOT, 32000, 0x0);
|
||||
|
||||
/* Crystal input clks */
|
||||
DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0);
|
||||
|
||||
DEFINE_CLK_FIXED_RATE(virt_24000000_ck, CLK_IS_ROOT, 24000000, 0x0);
|
||||
|
||||
DEFINE_CLK_FIXED_RATE(virt_25000000_ck, CLK_IS_ROOT, 25000000, 0x0);
|
||||
|
||||
DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0);
|
||||
|
||||
/* Oscillator clock */
|
||||
/* 19.2, 24, 25 or 26 MHz */
|
||||
static const char *sys_clkin_ck_parents[] = {
|
||||
"virt_19200000_ck", "virt_24000000_ck", "virt_25000000_ck",
|
||||
"virt_26000000_ck",
|
||||
};
|
||||
|
||||
/*
|
||||
* sys_clk in: input to the dpll and also used as funtional clock for,
|
||||
* adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse
|
||||
*
|
||||
*/
|
||||
DEFINE_CLK_MUX(sys_clkin_ck, sys_clkin_ck_parents, NULL, 0x0,
|
||||
AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS),
|
||||
AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT,
|
||||
AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH,
|
||||
0, NULL);
|
||||
|
||||
/* External clock - 12 MHz */
|
||||
DEFINE_CLK_FIXED_RATE(tclkin_ck, CLK_IS_ROOT, 12000000, 0x0);
|
||||
|
||||
/* Module clocks and DPLL outputs */
|
||||
|
||||
/* DPLL_CORE */
|
||||
static struct dpll_data dpll_core_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_CORE,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_CORE,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_CORE,
|
||||
.mult_mask = AM33XX_DPLL_MULT_MASK,
|
||||
.div1_mask = AM33XX_DPLL_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
};
|
||||
|
||||
/* CLKDCOLDO output */
|
||||
static const char *dpll_core_ck_parents[] = {
|
||||
"sys_clkin_ck",
|
||||
};
|
||||
|
||||
static struct clk dpll_core_ck;
|
||||
|
||||
static const struct clk_ops dpll_core_ck_ops = {
|
||||
.recalc_rate = &omap3_dpll_recalc,
|
||||
.get_parent = &omap2_init_dpll_parent,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap dpll_core_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_core_ck,
|
||||
},
|
||||
.dpll_data = &dpll_core_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_core_ck, dpll_core_ck_parents, dpll_core_ck_ops);
|
||||
|
||||
static const char *dpll_core_x2_ck_parents[] = {
|
||||
"dpll_core_ck",
|
||||
};
|
||||
|
||||
static struct clk dpll_core_x2_ck;
|
||||
|
||||
static const struct clk_ops dpll_x2_ck_ops = {
|
||||
.recalc_rate = &omap3_clkoutx2_recalc,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap dpll_core_x2_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_core_x2_ck,
|
||||
},
|
||||
.flags = CLOCK_CLKOUTX2,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_core_x2_ck, dpll_core_x2_ck_parents, dpll_x2_ck_ops);
|
||||
|
||||
DEFINE_CLK_DIVIDER(dpll_core_m4_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
|
||||
0x0, AM33XX_CM_DIV_M4_DPLL_CORE,
|
||||
AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT,
|
||||
AM33XX_HSDIVIDER_CLKOUT1_DIV_WIDTH, CLK_DIVIDER_ONE_BASED,
|
||||
NULL);
|
||||
|
||||
DEFINE_CLK_DIVIDER(dpll_core_m5_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
|
||||
0x0, AM33XX_CM_DIV_M5_DPLL_CORE,
|
||||
AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT,
|
||||
AM33XX_HSDIVIDER_CLKOUT2_DIV_WIDTH,
|
||||
CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
DEFINE_CLK_DIVIDER(dpll_core_m6_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
|
||||
0x0, AM33XX_CM_DIV_M6_DPLL_CORE,
|
||||
AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT,
|
||||
AM33XX_HSDIVIDER_CLKOUT3_DIV_WIDTH,
|
||||
CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
|
||||
/* DPLL_MPU */
|
||||
static struct dpll_data dpll_mpu_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_MPU,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_MPU,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_MPU,
|
||||
.mult_mask = AM33XX_DPLL_MULT_MASK,
|
||||
.div1_mask = AM33XX_DPLL_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
};
|
||||
|
||||
/* CLKOUT: fdpll/M2 */
|
||||
static struct clk dpll_mpu_ck;
|
||||
|
||||
static const struct clk_ops dpll_mpu_ck_ops = {
|
||||
.enable = &omap3_noncore_dpll_enable,
|
||||
.disable = &omap3_noncore_dpll_disable,
|
||||
.recalc_rate = &omap3_dpll_recalc,
|
||||
.round_rate = &omap2_dpll_round_rate,
|
||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||
.get_parent = &omap2_init_dpll_parent,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap dpll_mpu_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_mpu_ck,
|
||||
},
|
||||
.dpll_data = &dpll_mpu_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_mpu_ck, dpll_core_ck_parents, dpll_mpu_ck_ops);
|
||||
|
||||
/*
|
||||
* TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
|
||||
* and ALT_CLK1/2)
|
||||
*/
|
||||
DEFINE_CLK_DIVIDER(dpll_mpu_m2_ck, "dpll_mpu_ck", &dpll_mpu_ck,
|
||||
0x0, AM33XX_CM_DIV_M2_DPLL_MPU, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
|
||||
AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
/* DPLL_DDR */
|
||||
static struct dpll_data dpll_ddr_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_DDR,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_DDR,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_DDR,
|
||||
.mult_mask = AM33XX_DPLL_MULT_MASK,
|
||||
.div1_mask = AM33XX_DPLL_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
};
|
||||
|
||||
/* CLKOUT: fdpll/M2 */
|
||||
static struct clk dpll_ddr_ck;
|
||||
|
||||
static const struct clk_ops dpll_ddr_ck_ops = {
|
||||
.recalc_rate = &omap3_dpll_recalc,
|
||||
.get_parent = &omap2_init_dpll_parent,
|
||||
.round_rate = &omap2_dpll_round_rate,
|
||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap dpll_ddr_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_ddr_ck,
|
||||
},
|
||||
.dpll_data = &dpll_ddr_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_ddr_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
|
||||
|
||||
/*
|
||||
* TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
|
||||
* and ALT_CLK1/2)
|
||||
*/
|
||||
DEFINE_CLK_DIVIDER(dpll_ddr_m2_ck, "dpll_ddr_ck", &dpll_ddr_ck,
|
||||
0x0, AM33XX_CM_DIV_M2_DPLL_DDR,
|
||||
AM33XX_DPLL_CLKOUT_DIV_SHIFT, AM33XX_DPLL_CLKOUT_DIV_WIDTH,
|
||||
CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
/* emif_fck functional clock */
|
||||
DEFINE_CLK_FIXED_FACTOR(dpll_ddr_m2_div2_ck, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck,
|
||||
0x0, 1, 2);
|
||||
|
||||
/* DPLL_DISP */
|
||||
static struct dpll_data dpll_disp_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_DISP,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_DISP,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_DISP,
|
||||
.mult_mask = AM33XX_DPLL_MULT_MASK,
|
||||
.div1_mask = AM33XX_DPLL_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
};
|
||||
|
||||
/* CLKOUT: fdpll/M2 */
|
||||
static struct clk dpll_disp_ck;
|
||||
|
||||
static struct clk_hw_omap dpll_disp_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_disp_ck,
|
||||
},
|
||||
.dpll_data = &dpll_disp_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_disp_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
|
||||
|
||||
/*
|
||||
* TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
|
||||
* and ALT_CLK1/2)
|
||||
*/
|
||||
DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck, 0x0,
|
||||
AM33XX_CM_DIV_M2_DPLL_DISP, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
|
||||
AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
/* DPLL_PER */
|
||||
static struct dpll_data dpll_per_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_PERIPH,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_PER,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_PER,
|
||||
.mult_mask = AM33XX_DPLL_MULT_PERIPH_MASK,
|
||||
.div1_mask = AM33XX_DPLL_PER_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
.flags = DPLL_J_TYPE,
|
||||
};
|
||||
|
||||
/* CLKDCOLDO */
|
||||
static struct clk dpll_per_ck;
|
||||
|
||||
static struct clk_hw_omap dpll_per_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_per_ck,
|
||||
},
|
||||
.dpll_data = &dpll_per_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_per_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
|
||||
|
||||
/* CLKOUT: fdpll/M2 */
|
||||
DEFINE_CLK_DIVIDER(dpll_per_m2_ck, "dpll_per_ck", &dpll_per_ck, 0x0,
|
||||
AM33XX_CM_DIV_M2_DPLL_PER, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
|
||||
AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED,
|
||||
NULL);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(dpll_per_m2_div4_wkupdm_ck, "dpll_per_m2_ck",
|
||||
&dpll_per_m2_ck, 0x0, 1, 4);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(dpll_per_m2_div4_ck, "dpll_per_m2_ck",
|
||||
&dpll_per_m2_ck, 0x0, 1, 4);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(dpll_core_m4_div2_ck, "dpll_core_m4_ck",
|
||||
&dpll_core_m4_ck, 0x0, 1, 2);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(l4_rtc_gclk, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
|
||||
1, 2);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(clk_24mhz, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1,
|
||||
8);
|
||||
|
||||
/*
|
||||
* Below clock nodes describes clockdomains derived out
|
||||
* of core clock.
|
||||
*/
|
||||
static const struct clk_ops clk_ops_null = {
|
||||
};
|
||||
|
||||
static const char *l3_gclk_parents[] = {
|
||||
"dpll_core_m4_ck"
|
||||
};
|
||||
|
||||
static struct clk l3_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l3_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l3_gclk, l3_gclk_parents, clk_ops_null);
|
||||
|
||||
static struct clk l4hs_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l4hs_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l4hs_gclk, l3_gclk_parents, clk_ops_null);
|
||||
|
||||
static const char *l3s_gclk_parents[] = {
|
||||
"dpll_core_m4_div2_ck"
|
||||
};
|
||||
|
||||
static struct clk l3s_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l3s_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l3s_gclk, l3s_gclk_parents, clk_ops_null);
|
||||
|
||||
static struct clk l4fw_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l4fw_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l4fw_gclk, l3s_gclk_parents, clk_ops_null);
|
||||
|
||||
static struct clk l4ls_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l4ls_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l4ls_gclk, l3s_gclk_parents, clk_ops_null);
|
||||
|
||||
static struct clk sysclk_div_ck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(sysclk_div_ck, NULL);
|
||||
DEFINE_STRUCT_CLK(sysclk_div_ck, l3_gclk_parents, clk_ops_null);
|
||||
|
||||
/*
|
||||
* In order to match the clock domain with hwmod clockdomain entry,
|
||||
* separate clock nodes is required for the modules which are
|
||||
* directly getting their funtioncal clock from sys_clkin.
|
||||
*/
|
||||
static struct clk adc_tsc_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(adc_tsc_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(adc_tsc_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk dcan0_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(dcan0_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(dcan0_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk dcan1_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(dcan1_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(dcan1_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk mcasp0_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(mcasp0_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(mcasp0_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk mcasp1_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(mcasp1_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(mcasp1_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk smartreflex0_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(smartreflex0_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(smartreflex0_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk smartreflex1_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(smartreflex1_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(smartreflex1_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
/*
|
||||
* Modules clock nodes
|
||||
*
|
||||
* The following clock leaf nodes are added for the moment because:
|
||||
*
|
||||
* - hwmod data is not present for these modules, either hwmod
|
||||
* control is not required or its not populated.
|
||||
* - Driver code is not yet migrated to use hwmod/runtime pm
|
||||
* - Modules outside kernel access (to disable them by default)
|
||||
*
|
||||
* - debugss
|
||||
* - mmu (gfx domain)
|
||||
* - cefuse
|
||||
* - usbotg_fck (its additional clock and not really a modulemode)
|
||||
* - ieee5000
|
||||
*/
|
||||
DEFINE_CLK_GATE(debugss_ick, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
|
||||
AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(mmu_fck, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
|
||||
AM33XX_CM_GFX_MMUDATA_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(cefuse_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0,
|
||||
AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
/*
|
||||
* clkdiv32 is generated from fixed division of 732.4219
|
||||
*/
|
||||
DEFINE_CLK_FIXED_FACTOR(clkdiv32k_ck, "clk_24mhz", &clk_24mhz, 0x0, 1, 732);
|
||||
|
||||
DEFINE_CLK_GATE(clkdiv32k_ick, "clkdiv32k_ck", &clkdiv32k_ck, 0x0,
|
||||
AM33XX_CM_PER_CLKDIV32K_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
/* "usbotg_fck" is an additional clock and not really a modulemode */
|
||||
DEFINE_CLK_GATE(usbotg_fck, "dpll_per_ck", &dpll_per_ck, 0x0,
|
||||
AM33XX_CM_CLKDCOLDO_DPLL_PER, AM33XX_ST_DPLL_CLKDCOLDO_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(ieee5000_fck, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck,
|
||||
0x0, AM33XX_CM_PER_IEEE5000_CLKCTRL,
|
||||
AM33XX_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
|
||||
|
||||
/* Timers */
|
||||
static const struct clksel timer1_clkmux_sel[] = {
|
||||
{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates },
|
||||
{ .parent = &tclkin_ck, .rates = div_1_2_rates },
|
||||
{ .parent = &clk_rc32k_ck, .rates = div_1_3_rates },
|
||||
{ .parent = &clk_32768_ck, .rates = div_1_4_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static const char *timer1_ck_parents[] = {
|
||||
"sys_clkin_ck", "clkdiv32k_ick", "tclkin_ck", "clk_rc32k_ck",
|
||||
"clk_32768_ck",
|
||||
};
|
||||
|
||||
static struct clk timer1_fck;
|
||||
|
||||
static const struct clk_ops timer1_fck_ops = {
|
||||
.recalc_rate = &omap2_clksel_recalc,
|
||||
.get_parent = &omap2_clksel_find_parent_index,
|
||||
.set_parent = &omap2_clksel_set_parent,
|
||||
.init = &omap2_init_clk_clkdm,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap timer1_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer1_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer1_clkmux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER1MS_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_2_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer1_fck, timer1_ck_parents, timer1_fck_ops);
|
||||
|
||||
static const struct clksel timer2_to_7_clk_sel[] = {
|
||||
{ .parent = &tclkin_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &sys_clkin_ck, .rates = div_1_1_rates },
|
||||
{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static const char *timer2_to_7_ck_parents[] = {
|
||||
"tclkin_ck", "sys_clkin_ck", "clkdiv32k_ick",
|
||||
};
|
||||
|
||||
static struct clk timer2_fck;
|
||||
|
||||
static struct clk_hw_omap timer2_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer2_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER2_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer2_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer3_fck;
|
||||
|
||||
static struct clk_hw_omap timer3_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer3_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER3_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer3_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer4_fck;
|
||||
|
||||
static struct clk_hw_omap timer4_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer4_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER4_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer4_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer5_fck;
|
||||
|
||||
static struct clk_hw_omap timer5_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer5_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER5_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer5_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer6_fck;
|
||||
|
||||
static struct clk_hw_omap timer6_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer6_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER6_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer6_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer7_fck;
|
||||
|
||||
static struct clk_hw_omap timer7_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer7_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER7_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer7_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(cpsw_125mhz_gclk,
|
||||
"dpll_core_m5_ck",
|
||||
&dpll_core_m5_ck,
|
||||
0x0,
|
||||
1, 2);
|
||||
|
||||
static const struct clk_ops cpsw_fck_ops = {
|
||||
.recalc_rate = &omap2_clksel_recalc,
|
||||
.get_parent = &omap2_clksel_find_parent_index,
|
||||
.set_parent = &omap2_clksel_set_parent,
|
||||
};
|
||||
|
||||
static const struct clksel cpsw_cpts_rft_clkmux_sel[] = {
|
||||
{ .parent = &dpll_core_m5_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &dpll_core_m4_ck, .rates = div_1_1_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static const char *cpsw_cpts_rft_ck_parents[] = {
|
||||
"dpll_core_m5_ck", "dpll_core_m4_ck",
|
||||
};
|
||||
|
||||
static struct clk cpsw_cpts_rft_clk;
|
||||
|
||||
static struct clk_hw_omap cpsw_cpts_rft_clk_hw = {
|
||||
.hw = {
|
||||
.clk = &cpsw_cpts_rft_clk,
|
||||
},
|
||||
.clkdm_name = "cpsw_125mhz_clkdm",
|
||||
.clksel = cpsw_cpts_rft_clkmux_sel,
|
||||
.clksel_reg = AM33XX_CM_CPTS_RFT_CLKSEL,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_0_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(cpsw_cpts_rft_clk, cpsw_cpts_rft_ck_parents, cpsw_fck_ops);
|
||||
|
||||
|
||||
/* gpio */
|
||||
static const char *gpio0_ck_parents[] = {
|
||||
"clk_rc32k_ck", "clk_32768_ck", "clkdiv32k_ick",
|
||||
};
|
||||
|
||||
static const struct clksel gpio0_dbclk_mux_sel[] = {
|
||||
{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &clk_32768_ck, .rates = div_1_1_rates },
|
||||
{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static const struct clk_ops gpio_fck_ops = {
|
||||
.recalc_rate = &omap2_clksel_recalc,
|
||||
.get_parent = &omap2_clksel_find_parent_index,
|
||||
.set_parent = &omap2_clksel_set_parent,
|
||||
.init = &omap2_init_clk_clkdm,
|
||||
};
|
||||
|
||||
static struct clk gpio0_dbclk_mux_ck;
|
||||
|
||||
static struct clk_hw_omap gpio0_dbclk_mux_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &gpio0_dbclk_mux_ck,
|
||||
},
|
||||
.clkdm_name = "l4_wkup_clkdm",
|
||||
.clksel = gpio0_dbclk_mux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_GPIO0_DBCLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(gpio0_dbclk_mux_ck, gpio0_ck_parents, gpio_fck_ops);
|
||||
|
||||
DEFINE_CLK_GATE(gpio0_dbclk, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck, 0x0,
|
||||
AM33XX_CM_WKUP_GPIO0_CLKCTRL,
|
||||
AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT, 0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(gpio1_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
|
||||
AM33XX_CM_PER_GPIO1_CLKCTRL,
|
||||
AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT, 0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(gpio2_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
|
||||
AM33XX_CM_PER_GPIO2_CLKCTRL,
|
||||
AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT, 0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(gpio3_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
|
||||
AM33XX_CM_PER_GPIO3_CLKCTRL,
|
||||
AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT, 0x0, NULL);
|
||||
|
||||
|
||||
static const char *pruss_ck_parents[] = {
|
||||
"l3_gclk", "dpll_disp_m2_ck",
|
||||
};
|
||||
|
||||
static const struct clksel pruss_ocp_clk_mux_sel[] = {
|
||||
{ .parent = &l3_gclk, .rates = div_1_0_rates },
|
||||
{ .parent = &dpll_disp_m2_ck, .rates = div_1_1_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk pruss_ocp_gclk;
|
||||
|
||||
static struct clk_hw_omap pruss_ocp_gclk_hw = {
|
||||
.hw = {
|
||||
.clk = &pruss_ocp_gclk,
|
||||
},
|
||||
.clkdm_name = "pruss_ocp_clkdm",
|
||||
.clksel = pruss_ocp_clk_mux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_PRUSS_OCP_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_0_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(pruss_ocp_gclk, pruss_ck_parents, gpio_fck_ops);
|
||||
|
||||
static const char *lcd_ck_parents[] = {
|
||||
"dpll_disp_m2_ck", "dpll_core_m5_ck", "dpll_per_m2_ck",
|
||||
};
|
||||
|
||||
static const struct clksel lcd_clk_mux_sel[] = {
|
||||
{ .parent = &dpll_disp_m2_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &dpll_core_m5_ck, .rates = div_1_1_rates },
|
||||
{ .parent = &dpll_per_m2_ck, .rates = div_1_2_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk lcd_gclk;
|
||||
|
||||
static struct clk_hw_omap lcd_gclk_hw = {
|
||||
.hw = {
|
||||
.clk = &lcd_gclk,
|
||||
},
|
||||
.clkdm_name = "lcdc_clkdm",
|
||||
.clksel = lcd_clk_mux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_LCDC_PIXEL_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(lcd_gclk, lcd_ck_parents, gpio_fck_ops);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(mmc_clk, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1, 2);
|
||||
|
||||
static const char *gfx_ck_parents[] = {
|
||||
"dpll_core_m4_ck", "dpll_per_m2_ck",
|
||||
};
|
||||
|
||||
static const struct clksel gfx_clksel_sel[] = {
|
||||
{ .parent = &dpll_core_m4_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &dpll_per_m2_ck, .rates = div_1_1_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk gfx_fclk_clksel_ck;
|
||||
|
||||
static struct clk_hw_omap gfx_fclk_clksel_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &gfx_fclk_clksel_ck,
|
||||
},
|
||||
.clksel = gfx_clksel_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_GFX_FCLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_GFX_FCLK_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(gfx_fclk_clksel_ck, gfx_ck_parents, gpio_fck_ops);
|
||||
|
||||
static const struct clk_div_table div_1_0_2_1_rates[] = {
|
||||
{ .div = 1, .val = 0, },
|
||||
{ .div = 2, .val = 1, },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
DEFINE_CLK_DIVIDER_TABLE(gfx_fck_div_ck, "gfx_fclk_clksel_ck",
|
||||
&gfx_fclk_clksel_ck, 0x0, AM33XX_CLKSEL_GFX_FCLK,
|
||||
AM33XX_CLKSEL_0_0_SHIFT, AM33XX_CLKSEL_0_0_WIDTH,
|
||||
0x0, div_1_0_2_1_rates, NULL);
|
||||
|
||||
static const char *sysclkout_ck_parents[] = {
|
||||
"clk_32768_ck", "l3_gclk", "dpll_ddr_m2_ck", "dpll_per_m2_ck",
|
||||
"lcd_gclk",
|
||||
};
|
||||
|
||||
static const struct clksel sysclkout_pre_sel[] = {
|
||||
{ .parent = &clk_32768_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &l3_gclk, .rates = div_1_1_rates },
|
||||
{ .parent = &dpll_ddr_m2_ck, .rates = div_1_2_rates },
|
||||
{ .parent = &dpll_per_m2_ck, .rates = div_1_3_rates },
|
||||
{ .parent = &lcd_gclk, .rates = div_1_4_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk sysclkout_pre_ck;
|
||||
|
||||
static struct clk_hw_omap sysclkout_pre_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &sysclkout_pre_ck,
|
||||
},
|
||||
.clksel = sysclkout_pre_sel,
|
||||
.clksel_reg = AM33XX_CM_CLKOUT_CTRL,
|
||||
.clksel_mask = AM33XX_CLKOUT2SOURCE_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(sysclkout_pre_ck, sysclkout_ck_parents, gpio_fck_ops);
|
||||
|
||||
/* Divide by 8 clock rates with default clock is 1/1*/
|
||||
static const struct clk_div_table div8_rates[] = {
|
||||
{ .div = 1, .val = 0, },
|
||||
{ .div = 2, .val = 1, },
|
||||
{ .div = 3, .val = 2, },
|
||||
{ .div = 4, .val = 3, },
|
||||
{ .div = 5, .val = 4, },
|
||||
{ .div = 6, .val = 5, },
|
||||
{ .div = 7, .val = 6, },
|
||||
{ .div = 8, .val = 7, },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
DEFINE_CLK_DIVIDER_TABLE(clkout2_div_ck, "sysclkout_pre_ck", &sysclkout_pre_ck,
|
||||
0x0, AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2DIV_SHIFT,
|
||||
AM33XX_CLKOUT2DIV_WIDTH, 0x0, div8_rates, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(clkout2_ck, "clkout2_div_ck", &clkout2_div_ck, 0x0,
|
||||
AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2EN_SHIFT, 0x0, NULL);
|
||||
|
||||
static const char *wdt_ck_parents[] = {
|
||||
"clk_rc32k_ck", "clkdiv32k_ick",
|
||||
};
|
||||
|
||||
static const struct clksel wdt_clkmux_sel[] = {
|
||||
{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk wdt1_fck;
|
||||
|
||||
static struct clk_hw_omap wdt1_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &wdt1_fck,
|
||||
},
|
||||
.clkdm_name = "l4_wkup_clkdm",
|
||||
.clksel = wdt_clkmux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_WDT1_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(wdt1_fck, wdt_ck_parents, gpio_fck_ops);
|
||||
|
||||
/*
|
||||
* clkdev
|
||||
*/
|
||||
static struct omap_clk am33xx_clks[] = {
|
||||
CLK(NULL, "clk_32768_ck", &clk_32768_ck, CK_AM33XX),
|
||||
CLK(NULL, "clk_rc32k_ck", &clk_rc32k_ck, CK_AM33XX),
|
||||
CLK(NULL, "virt_19200000_ck", &virt_19200000_ck, CK_AM33XX),
|
||||
CLK(NULL, "virt_24000000_ck", &virt_24000000_ck, CK_AM33XX),
|
||||
CLK(NULL, "virt_25000000_ck", &virt_25000000_ck, CK_AM33XX),
|
||||
CLK(NULL, "virt_26000000_ck", &virt_26000000_ck, CK_AM33XX),
|
||||
CLK(NULL, "sys_clkin_ck", &sys_clkin_ck, CK_AM33XX),
|
||||
CLK(NULL, "tclkin_ck", &tclkin_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_m4_ck", &dpll_core_m4_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_m5_ck", &dpll_core_m5_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_m6_ck", &dpll_core_m6_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_AM33XX),
|
||||
CLK("cpu0", NULL, &dpll_mpu_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_ddr_ck", &dpll_ddr_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_ddr_m2_div2_ck", &dpll_ddr_m2_div2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_disp_ck", &dpll_disp_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_disp_m2_ck", &dpll_disp_m2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_per_ck", &dpll_per_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_per_m2_div4_wkupdm_ck", &dpll_per_m2_div4_wkupdm_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_per_m2_div4_ck", &dpll_per_m2_div4_ck, CK_AM33XX),
|
||||
CLK(NULL, "adc_tsc_fck", &adc_tsc_fck, CK_AM33XX),
|
||||
CLK(NULL, "cefuse_fck", &cefuse_fck, CK_AM33XX),
|
||||
CLK(NULL, "clkdiv32k_ck", &clkdiv32k_ck, CK_AM33XX),
|
||||
CLK(NULL, "clkdiv32k_ick", &clkdiv32k_ick, CK_AM33XX),
|
||||
CLK(NULL, "dcan0_fck", &dcan0_fck, CK_AM33XX),
|
||||
CLK("481cc000.d_can", NULL, &dcan0_fck, CK_AM33XX),
|
||||
CLK(NULL, "dcan1_fck", &dcan1_fck, CK_AM33XX),
|
||||
CLK("481d0000.d_can", NULL, &dcan1_fck, CK_AM33XX),
|
||||
CLK(NULL, "debugss_ick", &debugss_ick, CK_AM33XX),
|
||||
CLK(NULL, "pruss_ocp_gclk", &pruss_ocp_gclk, CK_AM33XX),
|
||||
CLK(NULL, "mcasp0_fck", &mcasp0_fck, CK_AM33XX),
|
||||
CLK(NULL, "mcasp1_fck", &mcasp1_fck, CK_AM33XX),
|
||||
CLK(NULL, "mmu_fck", &mmu_fck, CK_AM33XX),
|
||||
CLK(NULL, "smartreflex0_fck", &smartreflex0_fck, CK_AM33XX),
|
||||
CLK(NULL, "smartreflex1_fck", &smartreflex1_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer1_fck", &timer1_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer2_fck", &timer2_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer3_fck", &timer3_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer4_fck", &timer4_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer5_fck", &timer5_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer6_fck", &timer6_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer7_fck", &timer7_fck, CK_AM33XX),
|
||||
CLK(NULL, "usbotg_fck", &usbotg_fck, CK_AM33XX),
|
||||
CLK(NULL, "ieee5000_fck", &ieee5000_fck, CK_AM33XX),
|
||||
CLK(NULL, "wdt1_fck", &wdt1_fck, CK_AM33XX),
|
||||
CLK(NULL, "l4_rtc_gclk", &l4_rtc_gclk, CK_AM33XX),
|
||||
CLK(NULL, "l3_gclk", &l3_gclk, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck, CK_AM33XX),
|
||||
CLK(NULL, "l4hs_gclk", &l4hs_gclk, CK_AM33XX),
|
||||
CLK(NULL, "l3s_gclk", &l3s_gclk, CK_AM33XX),
|
||||
CLK(NULL, "l4fw_gclk", &l4fw_gclk, CK_AM33XX),
|
||||
CLK(NULL, "l4ls_gclk", &l4ls_gclk, CK_AM33XX),
|
||||
CLK(NULL, "clk_24mhz", &clk_24mhz, CK_AM33XX),
|
||||
CLK(NULL, "sysclk_div_ck", &sysclk_div_ck, CK_AM33XX),
|
||||
CLK(NULL, "cpsw_125mhz_gclk", &cpsw_125mhz_gclk, CK_AM33XX),
|
||||
CLK(NULL, "cpsw_cpts_rft_clk", &cpsw_cpts_rft_clk, CK_AM33XX),
|
||||
CLK(NULL, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck, CK_AM33XX),
|
||||
CLK(NULL, "gpio0_dbclk", &gpio0_dbclk, CK_AM33XX),
|
||||
CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_AM33XX),
|
||||
CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_AM33XX),
|
||||
CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_AM33XX),
|
||||
CLK(NULL, "lcd_gclk", &lcd_gclk, CK_AM33XX),
|
||||
CLK(NULL, "mmc_clk", &mmc_clk, CK_AM33XX),
|
||||
CLK(NULL, "gfx_fclk_clksel_ck", &gfx_fclk_clksel_ck, CK_AM33XX),
|
||||
CLK(NULL, "gfx_fck_div_ck", &gfx_fck_div_ck, CK_AM33XX),
|
||||
CLK(NULL, "sysclkout_pre_ck", &sysclkout_pre_ck, CK_AM33XX),
|
||||
CLK(NULL, "clkout2_div_ck", &clkout2_div_ck, CK_AM33XX),
|
||||
CLK(NULL, "timer_32k_ck", &clkdiv32k_ick, CK_AM33XX),
|
||||
CLK(NULL, "timer_sys_ck", &sys_clkin_ck, CK_AM33XX),
|
||||
};
|
||||
|
||||
|
||||
static const char *enable_init_clks[] = {
|
||||
"dpll_ddr_m2_ck",
|
||||
"dpll_mpu_m2_ck",
|
||||
"l3_gclk",
|
||||
"l4hs_gclk",
|
||||
"l4fw_gclk",
|
||||
"l4ls_gclk",
|
||||
};
|
||||
|
||||
int __init am33xx_clk_init(void)
|
||||
{
|
||||
struct omap_clk *c;
|
||||
u32 cpu_clkflg;
|
||||
|
||||
if (soc_is_am33xx()) {
|
||||
cpu_mask = RATE_IN_AM33XX;
|
||||
cpu_clkflg = CK_AM33XX;
|
||||
}
|
||||
|
||||
for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) {
|
||||
if (c->cpu & cpu_clkflg) {
|
||||
clkdev_add(&c->lk);
|
||||
if (!__clk_init(NULL, c->lk.clk))
|
||||
omap2_init_clk_hw_omap_clocks(c->lk.clk);
|
||||
}
|
||||
}
|
||||
|
||||
omap2_clk_disable_autoidle_all();
|
||||
|
||||
omap2_clk_enable_init_clocks(enable_init_clks,
|
||||
ARRAY_SIZE(enable_init_clks));
|
||||
|
||||
/* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always
|
||||
* physically present, in such a case HWMOD enabling of
|
||||
* clock would be failure with default parent. And timer
|
||||
* probe thinks clock is already enabled, this leads to
|
||||
* crash upon accessing timer 3 & 6 registers in probe.
|
||||
* Fix by setting parent of both these timers to master
|
||||
* oscillator clock.
|
||||
*/
|
||||
|
||||
clk_set_parent(&timer3_fck, &sys_clkin_ck);
|
||||
clk_set_parent(&timer6_fck, &sys_clkin_ck);
|
||||
|
||||
return 0;
|
||||
}
|
3595
arch/arm/mach-omap2/cclock3xxx_data.c
Normal file
3595
arch/arm/mach-omap2/cclock3xxx_data.c
Normal file
File diff suppressed because it is too large
Load diff
1987
arch/arm/mach-omap2/cclock44xx_data.c
Normal file
1987
arch/arm/mach-omap2/cclock44xx_data.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -38,62 +38,88 @@
|
|||
|
||||
/* Private functions */
|
||||
|
||||
static int _apll96_enable(struct clk *clk)
|
||||
/**
|
||||
* omap2xxx_clk_apll_locked - is the APLL locked?
|
||||
* @hw: struct clk_hw * of the APLL to check
|
||||
*
|
||||
* If the APLL IP block referred to by @hw indicates that it's locked,
|
||||
* return true; otherwise, return false.
|
||||
*/
|
||||
static bool omap2xxx_clk_apll_locked(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 r, apll_mask;
|
||||
|
||||
apll_mask = EN_APLL_LOCKED << clk->enable_bit;
|
||||
|
||||
r = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
|
||||
return ((r & apll_mask) == apll_mask) ? true : false;
|
||||
}
|
||||
|
||||
int omap2_clk_apll96_enable(struct clk_hw *hw)
|
||||
{
|
||||
return omap2xxx_cm_apll96_enable();
|
||||
}
|
||||
|
||||
static int _apll54_enable(struct clk *clk)
|
||||
int omap2_clk_apll54_enable(struct clk_hw *hw)
|
||||
{
|
||||
return omap2xxx_cm_apll54_enable();
|
||||
}
|
||||
|
||||
static void _apll96_allow_idle(struct clk *clk)
|
||||
static void _apll96_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
omap2xxx_cm_set_apll96_auto_low_power_stop();
|
||||
}
|
||||
|
||||
static void _apll96_deny_idle(struct clk *clk)
|
||||
static void _apll96_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
omap2xxx_cm_set_apll96_disable_autoidle();
|
||||
}
|
||||
|
||||
static void _apll54_allow_idle(struct clk *clk)
|
||||
static void _apll54_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
omap2xxx_cm_set_apll54_auto_low_power_stop();
|
||||
}
|
||||
|
||||
static void _apll54_deny_idle(struct clk *clk)
|
||||
static void _apll54_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
omap2xxx_cm_set_apll54_disable_autoidle();
|
||||
}
|
||||
|
||||
static void _apll96_disable(struct clk *clk)
|
||||
void omap2_clk_apll96_disable(struct clk_hw *hw)
|
||||
{
|
||||
omap2xxx_cm_apll96_disable();
|
||||
}
|
||||
|
||||
static void _apll54_disable(struct clk *clk)
|
||||
void omap2_clk_apll54_disable(struct clk_hw *hw)
|
||||
{
|
||||
omap2xxx_cm_apll54_disable();
|
||||
}
|
||||
|
||||
unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return (omap2xxx_clk_apll_locked(hw)) ? 54000000 : 0;
|
||||
}
|
||||
|
||||
unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return (omap2xxx_clk_apll_locked(hw)) ? 96000000 : 0;
|
||||
}
|
||||
|
||||
/* Public data */
|
||||
|
||||
const struct clkops clkops_apll96 = {
|
||||
.enable = _apll96_enable,
|
||||
.disable = _apll96_disable,
|
||||
.allow_idle = _apll96_allow_idle,
|
||||
.deny_idle = _apll96_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_apll54 = {
|
||||
.enable = _apll54_enable,
|
||||
.disable = _apll54_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_apll54 = {
|
||||
.allow_idle = _apll54_allow_idle,
|
||||
.deny_idle = _apll54_deny_idle,
|
||||
};
|
||||
|
||||
const struct clk_hw_omap_ops clkhwops_apll96 = {
|
||||
.allow_idle = _apll96_allow_idle,
|
||||
.deny_idle = _apll96_deny_idle,
|
||||
};
|
||||
|
||||
/* Public functions */
|
||||
|
||||
u32 omap2xxx_get_apll_clkin(void)
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
|
||||
* instead. Add some mechanism to optionally enter this mode.
|
||||
*/
|
||||
static void _allow_idle(struct clk *clk)
|
||||
static void _allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
if (!clk || !clk->dpll_data)
|
||||
return;
|
||||
|
@ -43,7 +43,7 @@ static void _allow_idle(struct clk *clk)
|
|||
*
|
||||
* Disable DPLL automatic idle control. No return value.
|
||||
*/
|
||||
static void _deny_idle(struct clk *clk)
|
||||
static void _deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
if (!clk || !clk->dpll_data)
|
||||
return;
|
||||
|
@ -53,9 +53,7 @@ static void _deny_idle(struct clk *clk)
|
|||
|
||||
|
||||
/* Public data */
|
||||
|
||||
const struct clkops clkops_omap2xxx_dpll_ops = {
|
||||
const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll = {
|
||||
.allow_idle = _allow_idle,
|
||||
.deny_idle = _deny_idle,
|
||||
};
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
* (currently defined as "dpll_ck" in the OMAP2xxx clock tree). Set
|
||||
* during dpll_ck init and used later by omap2xxx_clk_get_core_rate().
|
||||
*/
|
||||
static struct clk *dpll_core_ck;
|
||||
static struct clk_hw_omap *dpll_core_ck;
|
||||
|
||||
/**
|
||||
* omap2xxx_clk_get_core_rate - return the CORE_CLK rate
|
||||
|
@ -105,13 +105,16 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
|
|||
|
||||
}
|
||||
|
||||
unsigned long omap2_dpllcore_recalc(struct clk *clk)
|
||||
unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return omap2xxx_clk_get_core_rate();
|
||||
}
|
||||
|
||||
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
|
||||
int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 cur_rate, low, mult, div, valid_rate, done_rate;
|
||||
u32 bypass = 0;
|
||||
struct prcm_config tmpset;
|
||||
|
@ -189,8 +192,8 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
|
|||
* statically defined, this code may need to change to increment some
|
||||
* kind of use count on dpll_ck.
|
||||
*/
|
||||
void omap2xxx_clkt_dpllcore_init(struct clk *clk)
|
||||
void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw)
|
||||
{
|
||||
WARN(dpll_core_ck, "dpll_core_ck already set - should never happen");
|
||||
dpll_core_ck = clk;
|
||||
dpll_core_ck = to_clk_hw_omap(hw);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
* clk_enable/clk_disable()-based usecounting for osc_ck should be
|
||||
* replaced with autoidle-based usecounting.
|
||||
*/
|
||||
static int omap2_enable_osc_ck(struct clk *clk)
|
||||
int omap2_enable_osc_ck(struct clk_hw *clk)
|
||||
{
|
||||
u32 pcc;
|
||||
|
||||
|
@ -53,7 +53,7 @@ static int omap2_enable_osc_ck(struct clk *clk)
|
|||
* clk_enable/clk_disable()-based usecounting for osc_ck should be
|
||||
* replaced with autoidle-based usecounting.
|
||||
*/
|
||||
static void omap2_disable_osc_ck(struct clk *clk)
|
||||
void omap2_disable_osc_ck(struct clk_hw *clk)
|
||||
{
|
||||
u32 pcc;
|
||||
|
||||
|
@ -62,13 +62,8 @@ static void omap2_disable_osc_ck(struct clk *clk)
|
|||
__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
|
||||
}
|
||||
|
||||
const struct clkops clkops_oscck = {
|
||||
.enable = omap2_enable_osc_ck,
|
||||
.disable = omap2_disable_osc_ck,
|
||||
};
|
||||
|
||||
unsigned long omap2_osc_clk_recalc(struct clk *clk)
|
||||
unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,9 +40,8 @@ u32 omap2xxx_get_sysclkdiv(void)
|
|||
return div;
|
||||
}
|
||||
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return clk->parent->rate / omap2xxx_get_sysclkdiv();
|
||||
return parent_rate / omap2xxx_get_sysclkdiv();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ static unsigned long sys_ck_rate;
|
|||
*
|
||||
* Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
|
||||
*/
|
||||
unsigned long omap2_table_mpu_recalc(struct clk *clk)
|
||||
unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return curr_prcm_set->mpu_speed;
|
||||
}
|
||||
|
@ -71,7 +72,8 @@ unsigned long omap2_table_mpu_recalc(struct clk *clk)
|
|||
* Some might argue L3-DDR, others ARM, others IVA. This code is simple and
|
||||
* just uses the ARM rates.
|
||||
*/
|
||||
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
|
||||
long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
const struct prcm_config *ptr;
|
||||
long highest_rate;
|
||||
|
@ -94,7 +96,8 @@ long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
|
|||
}
|
||||
|
||||
/* Sets basic clocks based on the specified rate */
|
||||
int omap2_select_table_rate(struct clk *clk, unsigned long rate)
|
||||
int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
u32 cur_rate, done_rate, bypass = 0, tmp;
|
||||
const struct prcm_config *prcm;
|
||||
|
|
|
@ -45,8 +45,10 @@
|
|||
* Program the DPLL M2 divider with the rounded target rate. Returns
|
||||
* -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
|
||||
int omap3_core_dpll_m2_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 new_div = 0;
|
||||
u32 unlock_dll = 0;
|
||||
u32 c;
|
||||
|
@ -64,7 +66,7 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
|
|||
return -EINVAL;
|
||||
|
||||
sdrcrate = __clk_get_rate(sdrc_ick_p);
|
||||
clkrate = __clk_get_rate(clk);
|
||||
clkrate = __clk_get_rate(hw->clk);
|
||||
if (rate > clkrate)
|
||||
sdrcrate <<= ((rate / clkrate) >> 1);
|
||||
else
|
||||
|
@ -113,8 +115,6 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
|
|||
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
|
||||
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
|
||||
0, 0, 0, 0);
|
||||
clk->rate = rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
|
@ -58,11 +58,14 @@
|
|||
* the element associated with the supplied parent clock address.
|
||||
* Returns a pointer to the struct clksel on success or NULL on error.
|
||||
*/
|
||||
static const struct clksel *_get_clksel_by_parent(struct clk *clk,
|
||||
static const struct clksel *_get_clksel_by_parent(struct clk_hw_omap *clk,
|
||||
struct clk *src_clk)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
|
||||
if (!src_clk)
|
||||
return NULL;
|
||||
|
||||
for (clks = clk->clksel; clks->parent; clks++)
|
||||
if (clks->parent == src_clk)
|
||||
break; /* Found the requested parent */
|
||||
|
@ -70,71 +73,13 @@ static const struct clksel *_get_clksel_by_parent(struct clk *clk,
|
|||
if (!clks->parent) {
|
||||
/* This indicates a data problem */
|
||||
WARN(1, "clock: %s: could not find parent clock %s in clksel array\n",
|
||||
__clk_get_name(clk), __clk_get_name(src_clk));
|
||||
__clk_get_name(clk->hw.clk), __clk_get_name(src_clk));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return clks;
|
||||
}
|
||||
|
||||
/**
|
||||
* _get_div_and_fieldval() - find the new clksel divisor and field value to use
|
||||
* @src_clk: planned new parent struct clk *
|
||||
* @clk: struct clk * that is being reparented
|
||||
* @field_val: pointer to a u32 to contain the register data for the divisor
|
||||
*
|
||||
* Given an intended new parent struct clk * @src_clk, and the struct
|
||||
* clk * @clk to the clock that is being reparented, find the
|
||||
* appropriate rate divisor for the new clock (returned as the return
|
||||
* value), and the corresponding register bitfield data to program to
|
||||
* reach that divisor (returned in the u32 pointed to by @field_val).
|
||||
* Returns 0 on error, or returns the newly-selected divisor upon
|
||||
* success (in this latter case, the corresponding register bitfield
|
||||
* value is passed back in the variable pointed to by @field_val)
|
||||
*/
|
||||
static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
|
||||
u32 *field_val)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr, *max_clkr = NULL;
|
||||
u8 max_div = 0;
|
||||
|
||||
clks = _get_clksel_by_parent(clk, src_clk);
|
||||
if (!clks)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Find the highest divisor (e.g., the one resulting in the
|
||||
* lowest rate) to use as the default. This should avoid
|
||||
* clock rates that are too high for the device. XXX A better
|
||||
* solution here would be to try to determine if there is a
|
||||
* divisor matching the original clock rate before the parent
|
||||
* switch, and if it cannot be found, to fall back to the
|
||||
* highest divisor.
|
||||
*/
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if (!(clkr->flags & cpu_mask))
|
||||
continue;
|
||||
|
||||
if (clkr->div > max_div) {
|
||||
max_div = clkr->div;
|
||||
max_clkr = clkr;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_div == 0) {
|
||||
/* This indicates an error in the clksel data */
|
||||
WARN(1, "clock: %s: could not find divisor for parent %s\n",
|
||||
__clk_get_name(clk),
|
||||
__clk_get_name(__clk_get_parent(src_clk)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
*field_val = max_clkr->val;
|
||||
|
||||
return max_div;
|
||||
}
|
||||
|
||||
/**
|
||||
* _write_clksel_reg() - program a clock's clksel register in hardware
|
||||
* @clk: struct clk * to program
|
||||
|
@ -148,7 +93,7 @@ static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
|
|||
* take into account any time the hardware might take to switch the
|
||||
* clock source.
|
||||
*/
|
||||
static void _write_clksel_reg(struct clk *clk, u32 field_val)
|
||||
static void _write_clksel_reg(struct clk_hw_omap *clk, u32 field_val)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
|
@ -171,13 +116,14 @@ static void _write_clksel_reg(struct clk *clk, u32 field_val)
|
|||
* before calling. Returns 0 on error or returns the actual integer divisor
|
||||
* upon success.
|
||||
*/
|
||||
static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
|
||||
static u32 _clksel_to_divisor(struct clk_hw_omap *clk, u32 field_val)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
struct clk *parent;
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
parent = __clk_get_parent(clk->hw.clk);
|
||||
|
||||
clks = _get_clksel_by_parent(clk, parent);
|
||||
if (!clks)
|
||||
return 0;
|
||||
|
@ -193,7 +139,8 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
|
|||
if (!clkr->div) {
|
||||
/* This indicates a data error */
|
||||
WARN(1, "clock: %s: could not find fieldval %d for parent %s\n",
|
||||
__clk_get_name(clk), field_val, __clk_get_name(parent));
|
||||
__clk_get_name(clk->hw.clk), field_val,
|
||||
__clk_get_name(parent));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -210,7 +157,7 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
|
|||
* register field value _before_ left-shifting (i.e., LSB is at bit
|
||||
* 0); or returns 0xFFFFFFFF (~0) upon error.
|
||||
*/
|
||||
static u32 _divisor_to_clksel(struct clk *clk, u32 div)
|
||||
static u32 _divisor_to_clksel(struct clk_hw_omap *clk, u32 div)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
|
@ -219,7 +166,7 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
|
|||
/* should never happen */
|
||||
WARN_ON(div == 0);
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
parent = __clk_get_parent(clk->hw.clk);
|
||||
clks = _get_clksel_by_parent(clk, parent);
|
||||
if (!clks)
|
||||
return ~0;
|
||||
|
@ -234,7 +181,8 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
|
|||
|
||||
if (!clkr->div) {
|
||||
pr_err("clock: %s: could not find divisor %d for parent %s\n",
|
||||
__clk_get_name(clk), div, __clk_get_name(parent));
|
||||
__clk_get_name(clk->hw.clk), div,
|
||||
__clk_get_name(parent));
|
||||
return ~0;
|
||||
}
|
||||
|
||||
|
@ -249,7 +197,7 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
|
|||
* into the hardware, convert it into the actual divisor value, and
|
||||
* return it; or return 0 on error.
|
||||
*/
|
||||
static u32 _read_divisor(struct clk *clk)
|
||||
static u32 _read_divisor(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
|
@ -277,7 +225,8 @@ static u32 _read_divisor(struct clk *clk)
|
|||
*
|
||||
* Returns the rounded clock rate or returns 0xffffffff on error.
|
||||
*/
|
||||
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
||||
u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk,
|
||||
unsigned long target_rate,
|
||||
u32 *new_div)
|
||||
{
|
||||
unsigned long test_rate;
|
||||
|
@ -288,9 +237,9 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
|||
unsigned long parent_rate;
|
||||
const char *clk_name;
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
parent = __clk_get_parent(clk->hw.clk);
|
||||
clk_name = __clk_get_name(clk->hw.clk);
|
||||
parent_rate = __clk_get_rate(parent);
|
||||
clk_name = __clk_get_name(clk);
|
||||
|
||||
if (!clk->clksel || !clk->clksel_mask)
|
||||
return ~0;
|
||||
|
@ -341,27 +290,35 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
|||
*/
|
||||
|
||||
/**
|
||||
* omap2_init_clksel_parent() - set a clksel clk's parent field from the hdwr
|
||||
* @clk: OMAP clock struct ptr to use
|
||||
* omap2_clksel_find_parent_index() - return the array index of the current
|
||||
* hardware parent of @hw
|
||||
* @hw: struct clk_hw * to find the current hardware parent of
|
||||
*
|
||||
* Given a pointer @clk to a source-selectable struct clk, read the
|
||||
* hardware register and determine what its parent is currently set
|
||||
* to. Update @clk's .parent field with the appropriate clk ptr. No
|
||||
* return value.
|
||||
* Given a struct clk_hw pointer @hw to the 'hw' member of a struct
|
||||
* clk_hw_omap record representing a source-selectable hardware clock,
|
||||
* read the hardware register and determine what its parent is
|
||||
* currently set to. Intended to be called only by the common clock
|
||||
* framework struct clk_hw_ops.get_parent function pointer. Return
|
||||
* the array index of this parent clock upon success -- there is no
|
||||
* way to return an error, so if we encounter an error, just WARN()
|
||||
* and pretend that we know that we're doing.
|
||||
*/
|
||||
void omap2_init_clksel_parent(struct clk *clk)
|
||||
u8 omap2_clksel_find_parent_index(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
u32 r, found = 0;
|
||||
struct clk *parent;
|
||||
const char *clk_name;
|
||||
int ret = 0, f = 0;
|
||||
|
||||
if (!clk->clksel || !clk->clksel_mask)
|
||||
return;
|
||||
parent = __clk_get_parent(hw->clk);
|
||||
clk_name = __clk_get_name(hw->clk);
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
clk_name = __clk_get_name(clk);
|
||||
/* XXX should be able to return an error */
|
||||
WARN((!clk->clksel || !clk->clksel_mask),
|
||||
"clock: %s: attempt to call on a non-clksel clock", clk_name);
|
||||
|
||||
r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
|
||||
r >>= __ffs(clk->clksel_mask);
|
||||
|
@ -372,27 +329,21 @@ void omap2_init_clksel_parent(struct clk *clk)
|
|||
continue;
|
||||
|
||||
if (clkr->val == r) {
|
||||
if (parent != clks->parent) {
|
||||
pr_debug("clock: %s: inited parent to %s (was %s)\n",
|
||||
clk_name,
|
||||
__clk_get_name(clks->parent),
|
||||
((parent) ?
|
||||
__clk_get_name(parent) :
|
||||
"NULL"));
|
||||
clk_reparent(clk, clks->parent);
|
||||
}
|
||||
found = 1;
|
||||
ret = f;
|
||||
}
|
||||
}
|
||||
f++;
|
||||
}
|
||||
|
||||
/* This indicates a data error */
|
||||
WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
|
||||
clk_name, r);
|
||||
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omap2_clksel_recalc() - function ptr to pass via struct clk .recalc field
|
||||
* @clk: struct clk *
|
||||
|
@ -402,21 +353,23 @@ void omap2_init_clksel_parent(struct clk *clk)
|
|||
* function. Returns the clock's current rate, based on its parent's rate
|
||||
* and its current divisor setting in the hardware.
|
||||
*/
|
||||
unsigned long omap2_clksel_recalc(struct clk *clk)
|
||||
unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
unsigned long rate;
|
||||
u32 div = 0;
|
||||
struct clk *parent;
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
|
||||
if (!parent_rate)
|
||||
return 0;
|
||||
|
||||
div = _read_divisor(clk);
|
||||
if (div == 0)
|
||||
return __clk_get_rate(clk);
|
||||
if (!div)
|
||||
rate = parent_rate;
|
||||
else
|
||||
rate = parent_rate / div;
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
rate = __clk_get_rate(parent) / div;
|
||||
|
||||
pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n",
|
||||
__clk_get_name(clk), rate, div);
|
||||
pr_debug("%s: recalc'd %s's rate to %lu (div %d)\n", __func__,
|
||||
__clk_get_name(hw->clk), rate, div);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
@ -432,8 +385,10 @@ unsigned long omap2_clksel_recalc(struct clk *clk)
|
|||
*
|
||||
* Returns the rounded clock rate or returns 0xffffffff on error.
|
||||
*/
|
||||
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 new_div;
|
||||
|
||||
return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
|
||||
|
@ -454,8 +409,10 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
|
|||
* is changed, they will all be affected without any notification.
|
||||
* Returns -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
||||
int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 field_val, validrate, new_div = 0;
|
||||
|
||||
if (!clk->clksel || !clk->clksel_mask)
|
||||
|
@ -471,10 +428,8 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
|||
|
||||
_write_clksel_reg(clk, field_val);
|
||||
|
||||
clk->rate = __clk_get_rate(__clk_get_parent(clk)) / new_div;
|
||||
|
||||
pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(clk),
|
||||
__clk_get_rate(clk));
|
||||
pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(hw->clk),
|
||||
__clk_get_rate(hw->clk));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -499,32 +454,13 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
|||
* affected without any notification. Returns -EINVAL upon error, or
|
||||
* 0 upon success.
|
||||
*/
|
||||
int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val)
|
||||
{
|
||||
u32 field_val = 0;
|
||||
u32 parent_div;
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
|
||||
if (!clk->clksel || !clk->clksel_mask)
|
||||
return -EINVAL;
|
||||
|
||||
parent_div = _get_div_and_fieldval(new_parent, clk, &field_val);
|
||||
if (!parent_div)
|
||||
return -EINVAL;
|
||||
|
||||
_write_clksel_reg(clk, field_val);
|
||||
|
||||
clk_reparent(clk, new_parent);
|
||||
|
||||
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
|
||||
clk->rate = __clk_get_rate(new_parent);
|
||||
|
||||
if (parent_div > 0)
|
||||
__clk_get_rate(clk) /= parent_div;
|
||||
|
||||
pr_debug("clock: %s: set parent to %s (new rate %ld)\n",
|
||||
__clk_get_name(clk),
|
||||
__clk_get_name(__clk_get_parent(clk)),
|
||||
__clk_get_rate(clk));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
|
@ -76,7 +76,7 @@
|
|||
* (assuming that it is counting N upwards), or -2 if the enclosing loop
|
||||
* should skip to the next iteration (again assuming N is increasing).
|
||||
*/
|
||||
static int _dpll_test_fint(struct clk *clk, u8 n)
|
||||
static int _dpll_test_fint(struct clk_hw_omap *clk, u8 n)
|
||||
{
|
||||
struct dpll_data *dd;
|
||||
long fint, fint_min, fint_max;
|
||||
|
@ -85,7 +85,7 @@ static int _dpll_test_fint(struct clk *clk, u8 n)
|
|||
dd = clk->dpll_data;
|
||||
|
||||
/* DPLL divider must result in a valid jitter correction val */
|
||||
fint = __clk_get_rate(__clk_get_parent(clk)) / n;
|
||||
fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n;
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
/* Should not be called for OMAP2, so warn if it is called */
|
||||
|
@ -186,15 +186,15 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
|
|||
}
|
||||
|
||||
/* Public functions */
|
||||
|
||||
void omap2_init_dpll_parent(struct clk *clk)
|
||||
u8 omap2_init_dpll_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 v;
|
||||
struct dpll_data *dd;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= dd->enable_mask;
|
||||
|
@ -204,18 +204,18 @@ void omap2_init_dpll_parent(struct clk *clk)
|
|||
if (cpu_is_omap24xx()) {
|
||||
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
return 1;
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
return 1;
|
||||
} else if (soc_is_am33xx() || cpu_is_omap44xx()) {
|
||||
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
return 1;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +232,7 @@ void omap2_init_dpll_parent(struct clk *clk)
|
|||
* locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
|
||||
* if the clock @clk is not a DPLL.
|
||||
*/
|
||||
u32 omap2_get_dpll_rate(struct clk *clk)
|
||||
unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
|
||||
{
|
||||
long long dpll_clk;
|
||||
u32 dpll_mult, dpll_div, v;
|
||||
|
@ -288,8 +288,10 @@ u32 omap2_get_dpll_rate(struct clk *clk)
|
|||
* (expensive) function again. Returns ~0 if the target rate cannot
|
||||
* be rounded, or the rounded rate upon success.
|
||||
*/
|
||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
int m, n, r, scaled_max_m;
|
||||
unsigned long scaled_rt_rp;
|
||||
unsigned long new_rate = 0;
|
||||
|
@ -303,7 +305,7 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
|||
dd = clk->dpll_data;
|
||||
|
||||
ref_rate = __clk_get_rate(dd->clk_ref);
|
||||
clk_name = __clk_get_name(clk);
|
||||
clk_name = __clk_get_name(hw->clk);
|
||||
pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
|
||||
clk_name, target_rate);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
|||
/* Private functions */
|
||||
|
||||
/* XXX */
|
||||
void omap2_clkt_iclk_allow_idle(struct clk *clk)
|
||||
void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v, r;
|
||||
|
||||
|
@ -35,7 +35,7 @@ void omap2_clkt_iclk_allow_idle(struct clk *clk)
|
|||
}
|
||||
|
||||
/* XXX */
|
||||
void omap2_clkt_iclk_deny_idle(struct clk *clk)
|
||||
void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v, r;
|
||||
|
||||
|
@ -48,33 +48,17 @@ void omap2_clkt_iclk_deny_idle(struct clk *clk)
|
|||
|
||||
/* Public data */
|
||||
|
||||
const struct clkops clkops_omap2_iclk_dflt_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_iclk = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
const struct clk_hw_omap_ops clkhwops_iclk_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = omap2_clk_dflt_find_idlest,
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap2_iclk_dflt = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap2_iclk_idle_only = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap2_mdmclk_dflt_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.find_idlest = omap2_clk_dflt_find_idlest,
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,6 +20,7 @@
|
|||
#include <linux/list.h>
|
||||
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
struct omap_clk {
|
||||
u16 cpu;
|
||||
|
@ -52,44 +53,85 @@ struct omap_clk {
|
|||
#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS)
|
||||
#define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX)
|
||||
|
||||
struct module;
|
||||
struct clk;
|
||||
struct clockdomain;
|
||||
#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
|
||||
|
||||
/* Temporary, needed during the common clock framework conversion */
|
||||
#define __clk_get_name(clk) (clk->name)
|
||||
#define __clk_get_parent(clk) (clk->parent)
|
||||
#define __clk_get_rate(clk) (clk->rate)
|
||||
|
||||
/**
|
||||
* struct clkops - some clock function pointers
|
||||
* @enable: fn ptr that enables the current clock in hardware
|
||||
* @disable: fn ptr that enables the current clock in hardware
|
||||
* @find_idlest: function returning the IDLEST register for the clock's IP blk
|
||||
* @find_companion: function returning the "companion" clk reg for the clock
|
||||
* @allow_idle: fn ptr that enables autoidle for the current clock in hardware
|
||||
* @deny_idle: fn ptr that disables autoidle for the current clock in hardware
|
||||
*
|
||||
* A "companion" clk is an accompanying clock to the one being queried
|
||||
* that must be enabled for the IP module connected to the clock to
|
||||
* become accessible by the hardware. Neither @find_idlest nor
|
||||
* @find_companion should be needed; that information is IP
|
||||
* block-specific; the hwmod code has been created to handle this, but
|
||||
* until hwmod data is ready and drivers have been converted to use PM
|
||||
* runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
|
||||
* @find_companion must, unfortunately, remain.
|
||||
*/
|
||||
struct clkops {
|
||||
int (*enable)(struct clk *);
|
||||
void (*disable)(struct clk *);
|
||||
void (*find_idlest)(struct clk *, void __iomem **,
|
||||
u8 *, u8 *);
|
||||
void (*find_companion)(struct clk *, void __iomem **,
|
||||
u8 *);
|
||||
void (*allow_idle)(struct clk *);
|
||||
void (*deny_idle)(struct clk *);
|
||||
#define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \
|
||||
static struct clk _name = { \
|
||||
.name = #_name, \
|
||||
.hw = &_name##_hw.hw, \
|
||||
.parent_names = _parent_array_name, \
|
||||
.num_parents = ARRAY_SIZE(_parent_array_name), \
|
||||
.ops = &_clkops_name, \
|
||||
};
|
||||
|
||||
#define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \
|
||||
static struct clk_hw_omap _name##_hw = { \
|
||||
.hw = { \
|
||||
.clk = &_name, \
|
||||
}, \
|
||||
.clkdm_name = _clkdm_name, \
|
||||
};
|
||||
|
||||
#define DEFINE_CLK_OMAP_MUX(_name, _clkdm_name, _clksel, \
|
||||
_clksel_reg, _clksel_mask, \
|
||||
_parent_names, _ops) \
|
||||
static struct clk _name; \
|
||||
static struct clk_hw_omap _name##_hw = { \
|
||||
.hw = { \
|
||||
.clk = &_name, \
|
||||
}, \
|
||||
.clksel = _clksel, \
|
||||
.clksel_reg = _clksel_reg, \
|
||||
.clksel_mask = _clksel_mask, \
|
||||
.clkdm_name = _clkdm_name, \
|
||||
}; \
|
||||
DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
|
||||
|
||||
#define DEFINE_CLK_OMAP_MUX_GATE(_name, _clkdm_name, _clksel, \
|
||||
_clksel_reg, _clksel_mask, \
|
||||
_enable_reg, _enable_bit, \
|
||||
_hwops, _parent_names, _ops) \
|
||||
static struct clk _name; \
|
||||
static struct clk_hw_omap _name##_hw = { \
|
||||
.hw = { \
|
||||
.clk = &_name, \
|
||||
}, \
|
||||
.ops = _hwops, \
|
||||
.enable_reg = _enable_reg, \
|
||||
.enable_bit = _enable_bit, \
|
||||
.clksel = _clksel, \
|
||||
.clksel_reg = _clksel_reg, \
|
||||
.clksel_mask = _clksel_mask, \
|
||||
.clkdm_name = _clkdm_name, \
|
||||
}; \
|
||||
DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
|
||||
|
||||
#define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name, \
|
||||
_parent_ptr, _flags, \
|
||||
_clksel_reg, _clksel_mask) \
|
||||
static const struct clksel _name##_div[] = { \
|
||||
{ \
|
||||
.parent = _parent_ptr, \
|
||||
.rates = div31_1to31_rates \
|
||||
}, \
|
||||
{ .parent = NULL }, \
|
||||
}; \
|
||||
static struct clk _name; \
|
||||
static const char *_name##_parent_names[] = { \
|
||||
_parent_name, \
|
||||
}; \
|
||||
static struct clk_hw_omap _name##_hw = { \
|
||||
.hw = { \
|
||||
.clk = &_name, \
|
||||
}, \
|
||||
.clksel = _name##_div, \
|
||||
.clksel_reg = _clksel_reg, \
|
||||
.clksel_mask = _clksel_mask, \
|
||||
.ops = &clkhwops_omap4_dpllmx, \
|
||||
}; \
|
||||
DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops);
|
||||
|
||||
/* struct clksel_rate.flags possibilities */
|
||||
#define RATE_IN_242X (1 << 0)
|
||||
#define RATE_IN_243X (1 << 1)
|
||||
|
@ -229,22 +271,10 @@ struct dpll_data {
|
|||
#define CLOCK_CLKOUTX2 (1 << 5)
|
||||
|
||||
/**
|
||||
* struct clk - OMAP struct clk
|
||||
* struct clk_hw_omap - OMAP struct clk
|
||||
* @node: list_head connecting this clock into the full clock list
|
||||
* @ops: struct clkops * for this clock
|
||||
* @name: the name of the clock in the hardware (used in hwmod data and debug)
|
||||
* @parent: pointer to this clock's parent struct clk
|
||||
* @children: list_head connecting to the child clks' @sibling list_heads
|
||||
* @sibling: list_head connecting this clk to its parent clk's @children
|
||||
* @rate: current clock rate
|
||||
* @enable_reg: register to write to enable the clock (see @enable_bit)
|
||||
* @recalc: fn ptr that returns the clock's current rate
|
||||
* @set_rate: fn ptr that can change the clock's current rate
|
||||
* @round_rate: fn ptr that can round the clock's current rate
|
||||
* @init: fn ptr to do clock-specific initialization
|
||||
* @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
|
||||
* @usecount: number of users that have requested this clock to be enabled
|
||||
* @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
|
||||
* @flags: see "struct clk.flags possibilities" above
|
||||
* @clksel_reg: for clksel clks, register va containing src/divisor select
|
||||
* @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
|
||||
|
@ -258,39 +288,17 @@ struct dpll_data {
|
|||
* XXX @rate_offset, @src_offset should probably be removed and OMAP1
|
||||
* clock code converted to use clksel.
|
||||
*
|
||||
* XXX @usecount is poorly named. It should be "enable_count" or
|
||||
* something similar. "users" in the description refers to kernel
|
||||
* code (core code or drivers) that have called clk_enable() and not
|
||||
* yet called clk_disable(); the usecount of parent clocks is also
|
||||
* incremented by the clock code when clk_enable() is called on child
|
||||
* clocks and decremented by the clock code when clk_disable() is
|
||||
* called on child clocks.
|
||||
*
|
||||
* XXX @clkdm, @usecount, @children, @sibling should be marked for
|
||||
* internal use only.
|
||||
*
|
||||
* @children and @sibling are used to optimize parent-to-child clock
|
||||
* tree traversals. (child-to-parent traversals use @parent.)
|
||||
*
|
||||
* XXX The notion of the clock's current rate probably needs to be
|
||||
* separated from the clock's target rate.
|
||||
*/
|
||||
struct clk {
|
||||
|
||||
struct clk_hw_omap_ops;
|
||||
|
||||
struct clk_hw_omap {
|
||||
struct clk_hw hw;
|
||||
struct list_head node;
|
||||
const struct clkops *ops;
|
||||
const char *name;
|
||||
struct clk *parent;
|
||||
struct list_head children;
|
||||
struct list_head sibling; /* node for children */
|
||||
unsigned long rate;
|
||||
void __iomem *enable_reg;
|
||||
unsigned long (*recalc)(struct clk *);
|
||||
int (*set_rate)(struct clk *, unsigned long);
|
||||
long (*round_rate)(struct clk *, unsigned long);
|
||||
void (*init)(struct clk *);
|
||||
u8 enable_bit;
|
||||
s8 usecount;
|
||||
unsigned long fixed_rate;
|
||||
u8 fixed_div;
|
||||
void __iomem *enable_reg;
|
||||
u8 enable_bit;
|
||||
u8 flags;
|
||||
void __iomem *clksel_reg;
|
||||
u32 clksel_mask;
|
||||
|
@ -298,42 +306,22 @@ struct clk {
|
|||
struct dpll_data *dpll_data;
|
||||
const char *clkdm_name;
|
||||
struct clockdomain *clkdm;
|
||||
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||
struct dentry *dent; /* For visible tree hierarchy */
|
||||
#endif
|
||||
const struct clk_hw_omap_ops *ops;
|
||||
};
|
||||
|
||||
struct clk_functions {
|
||||
int (*clk_enable)(struct clk *clk);
|
||||
void (*clk_disable)(struct clk *clk);
|
||||
long (*clk_round_rate)(struct clk *clk, unsigned long rate);
|
||||
int (*clk_set_rate)(struct clk *clk, unsigned long rate);
|
||||
int (*clk_set_parent)(struct clk *clk, struct clk *parent);
|
||||
void (*clk_allow_idle)(struct clk *clk);
|
||||
void (*clk_deny_idle)(struct clk *clk);
|
||||
void (*clk_disable_unused)(struct clk *clk);
|
||||
struct clk_hw_omap_ops {
|
||||
void (*find_idlest)(struct clk_hw_omap *oclk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit, u8 *idlest_val);
|
||||
void (*find_companion)(struct clk_hw_omap *oclk,
|
||||
void __iomem **other_reg,
|
||||
u8 *other_bit);
|
||||
void (*allow_idle)(struct clk_hw_omap *oclk);
|
||||
void (*deny_idle)(struct clk_hw_omap *oclk);
|
||||
};
|
||||
|
||||
extern int mpurate;
|
||||
|
||||
extern int clk_init(struct clk_functions *custom_clocks);
|
||||
extern void clk_preinit(struct clk *clk);
|
||||
extern int clk_register(struct clk *clk);
|
||||
extern void clk_reparent(struct clk *child, struct clk *parent);
|
||||
extern void clk_unregister(struct clk *clk);
|
||||
extern void propagate_rate(struct clk *clk);
|
||||
extern void recalculate_root_clocks(void);
|
||||
extern unsigned long followparent_recalc(struct clk *clk);
|
||||
extern void clk_enable_init_clocks(void);
|
||||
unsigned long omap_fixed_divisor_recalc(struct clk *clk);
|
||||
extern struct clk *omap_clk_get_by_name(const char *name);
|
||||
extern int omap_clk_enable_autoidle_all(void);
|
||||
extern int omap_clk_disable_autoidle_all(void);
|
||||
|
||||
extern const struct clkops clkops_null;
|
||||
|
||||
extern struct clk dummy_ck;
|
||||
|
||||
unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
|
||||
/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
|
||||
#define CORE_CLK_SRC_32K 0x0
|
||||
|
@ -364,57 +352,62 @@ extern struct clk dummy_ck;
|
|||
/* DPLL Type and DCO Selection Flags */
|
||||
#define DPLL_J_TYPE 0x1
|
||||
|
||||
int omap2_clk_enable(struct clk *clk);
|
||||
void omap2_clk_disable(struct clk *clk);
|
||||
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
|
||||
int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
|
||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
|
||||
unsigned long omap3_dpll_recalc(struct clk *clk);
|
||||
unsigned long omap3_clkoutx2_recalc(struct clk *clk);
|
||||
void omap3_dpll_allow_idle(struct clk *clk);
|
||||
void omap3_dpll_deny_idle(struct clk *clk);
|
||||
u32 omap3_dpll_autoidle_read(struct clk *clk);
|
||||
int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_noncore_dpll_enable(struct clk *clk);
|
||||
void omap3_noncore_dpll_disable(struct clk *clk);
|
||||
int omap4_dpllmx_gatectrl_read(struct clk *clk);
|
||||
void omap4_dpllmx_allow_gatectrl(struct clk *clk);
|
||||
void omap4_dpllmx_deny_gatectrl(struct clk *clk);
|
||||
long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate);
|
||||
unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk);
|
||||
long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
|
||||
unsigned long *parent_rate);
|
||||
unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
|
||||
int omap3_noncore_dpll_enable(struct clk_hw *hw);
|
||||
void omap3_noncore_dpll_disable(struct clk_hw *hw);
|
||||
int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
|
||||
void omap3_dpll_allow_idle(struct clk_hw_omap *clk);
|
||||
void omap3_dpll_deny_idle(struct clk_hw_omap *clk);
|
||||
unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk);
|
||||
void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk);
|
||||
void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk);
|
||||
unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
|
||||
unsigned long target_rate,
|
||||
unsigned long *parent_rate);
|
||||
|
||||
#ifdef CONFIG_OMAP_RESET_CLOCKS
|
||||
void omap2_clk_disable_unused(struct clk *clk);
|
||||
#else
|
||||
#define omap2_clk_disable_unused NULL
|
||||
#endif
|
||||
|
||||
void omap2_init_clk_clkdm(struct clk *clk);
|
||||
void omap2_init_clk_clkdm(struct clk_hw *clk);
|
||||
void __init omap2_clk_disable_clkdm_control(void);
|
||||
|
||||
/* clkt_clksel.c public functions */
|
||||
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
||||
u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk,
|
||||
unsigned long target_rate,
|
||||
u32 *new_div);
|
||||
void omap2_init_clksel_parent(struct clk *clk);
|
||||
unsigned long omap2_clksel_recalc(struct clk *clk);
|
||||
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
|
||||
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
|
||||
u8 omap2_clksel_find_parent_index(struct clk_hw *hw);
|
||||
unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate);
|
||||
long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
|
||||
unsigned long *parent_rate);
|
||||
int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val);
|
||||
|
||||
/* clkt_iclk.c public functions */
|
||||
extern void omap2_clkt_iclk_allow_idle(struct clk *clk);
|
||||
extern void omap2_clkt_iclk_deny_idle(struct clk *clk);
|
||||
extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk);
|
||||
extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk);
|
||||
|
||||
u32 omap2_get_dpll_rate(struct clk *clk);
|
||||
void omap2_init_dpll_parent(struct clk *clk);
|
||||
u8 omap2_init_dpll_parent(struct clk_hw *hw);
|
||||
unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
|
||||
|
||||
int omap2_dflt_clk_enable(struct clk *clk);
|
||||
void omap2_dflt_clk_disable(struct clk *clk);
|
||||
void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
|
||||
int omap2_dflt_clk_enable(struct clk_hw *hw);
|
||||
void omap2_dflt_clk_disable(struct clk_hw *hw);
|
||||
int omap2_dflt_clk_is_enabled(struct clk_hw *hw);
|
||||
void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
|
||||
void __iomem **other_reg,
|
||||
u8 *other_bit);
|
||||
void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
|
||||
void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit, u8 *idlest_val);
|
||||
void omap2_init_clk_hw_omap_clocks(struct clk *clk);
|
||||
int omap2_clk_enable_autoidle_all(void);
|
||||
int omap2_clk_disable_autoidle_all(void);
|
||||
void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
|
||||
int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
|
||||
void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
|
||||
const char *core_ck_name,
|
||||
|
@ -432,28 +425,38 @@ extern const struct clksel_rate gpt_32k_rates[];
|
|||
extern const struct clksel_rate gpt_sys_rates[];
|
||||
extern const struct clksel_rate gfx_l3_rates[];
|
||||
extern const struct clksel_rate dsp_ick_rates[];
|
||||
extern struct clk dummy_ck;
|
||||
|
||||
extern const struct clkops clkops_omap2_iclk_dflt_wait;
|
||||
extern const struct clkops clkops_omap2_iclk_dflt;
|
||||
extern const struct clkops clkops_omap2_iclk_idle_only;
|
||||
extern const struct clkops clkops_omap2_mdmclk_dflt_wait;
|
||||
extern const struct clkops clkops_omap2xxx_dpll_ops;
|
||||
extern const struct clkops clkops_omap3_noncore_dpll_ops;
|
||||
extern const struct clkops clkops_omap3_core_dpll_ops;
|
||||
extern const struct clkops clkops_omap4_dpllmx_ops;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;
|
||||
extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
|
||||
extern const struct clk_hw_omap_ops clkhwops_iclk;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_apll54;
|
||||
extern const struct clk_hw_omap_ops clkhwops_apll96;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait;
|
||||
|
||||
/* clksel_rate blocks shared between OMAP44xx and AM33xx */
|
||||
extern const struct clksel_rate div_1_0_rates[];
|
||||
extern const struct clksel_rate div3_1to4_rates[];
|
||||
extern const struct clksel_rate div_1_1_rates[];
|
||||
extern const struct clksel_rate div_1_2_rates[];
|
||||
extern const struct clksel_rate div_1_3_rates[];
|
||||
extern const struct clksel_rate div_1_4_rates[];
|
||||
extern const struct clksel_rate div31_1to31_rates[];
|
||||
|
||||
/* clocks shared between various OMAP SoCs */
|
||||
extern struct clk virt_19200000_ck;
|
||||
extern struct clk virt_26000000_ck;
|
||||
|
||||
extern int am33xx_clk_init(void);
|
||||
|
||||
extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
|
||||
extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -40,7 +40,7 @@
|
|||
* passes back the correct CM_IDLEST register address for I2CHS
|
||||
* modules. No return value.
|
||||
*/
|
||||
static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
|
||||
static void omap2430_clk_i2chs_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -51,9 +51,7 @@ static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
|
|||
}
|
||||
|
||||
/* 2430 I2CHS has non-standard IDLEST register */
|
||||
const struct clkops clkops_omap2430_i2chs_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = {
|
||||
.find_idlest = omap2430_clk_i2chs_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,6 +28,7 @@
|
|||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
struct clk_hw *dclk_hw;
|
||||
/*
|
||||
* Omap24xx specific clock functions
|
||||
*/
|
||||
|
|
|
@ -8,18 +8,32 @@
|
|||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
|
||||
|
||||
unsigned long omap2_table_mpu_recalc(struct clk *clk);
|
||||
int omap2_select_table_rate(struct clk *clk, unsigned long rate);
|
||||
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk *clk);
|
||||
unsigned long omap2_osc_clk_recalc(struct clk *clk);
|
||||
unsigned long omap2_dpllcore_recalc(struct clk *clk);
|
||||
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
|
||||
#include <linux/clk-provider.h>
|
||||
#include "clock.h"
|
||||
|
||||
unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate);
|
||||
int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate);
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate);
|
||||
unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate);
|
||||
unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
|
||||
unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
unsigned long omap2xxx_clk_get_core_rate(void);
|
||||
u32 omap2xxx_get_apll_clkin(void);
|
||||
u32 omap2xxx_get_sysclkdiv(void);
|
||||
void omap2xxx_clk_prepare_for_reboot(void);
|
||||
void omap2xxx_clkt_dpllcore_init(struct clk *clk);
|
||||
void omap2xxx_clkt_vps_check_bootloader_rates(void);
|
||||
void omap2xxx_clkt_vps_late_init(void);
|
||||
|
||||
|
@ -37,9 +51,12 @@ int omap2430_clk_init(void);
|
|||
|
||||
extern void __iomem *prcm_clksrc_ctrl;
|
||||
|
||||
extern const struct clkops clkops_omap2430_i2chs_wait;
|
||||
extern const struct clkops clkops_oscck;
|
||||
extern const struct clkops clkops_apll96;
|
||||
extern const struct clkops clkops_apll54;
|
||||
extern struct clk_hw *dclk_hw;
|
||||
int omap2_enable_osc_ck(struct clk_hw *hw);
|
||||
void omap2_disable_osc_ck(struct clk_hw *hw);
|
||||
int omap2_clk_apll96_enable(struct clk_hw *hw);
|
||||
int omap2_clk_apll54_enable(struct clk_hw *hw);
|
||||
void omap2_clk_apll96_disable(struct clk_hw *hw);
|
||||
void omap2_clk_apll54_disable(struct clk_hw *hw);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -37,7 +37,7 @@
|
|||
* from the CM_{I,F}CLKEN bit. Pass back the correct info via
|
||||
* @idlest_reg and @idlest_bit. No return value.
|
||||
*/
|
||||
static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
|
||||
static void omap3430es2_clk_ssi_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -49,21 +49,16 @@ static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
|
|||
*idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
|
||||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_ssi_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait = {
|
||||
.find_idlest = omap3430es2_clk_ssi_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap3430es2_iclk_ssi_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = omap3430es2_clk_ssi_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = omap3430es2_clk_ssi_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -80,7 +75,7 @@ const struct clkops clkops_omap3430es2_iclk_ssi_wait = {
|
|||
* default find_idlest code assumes that they are at the same
|
||||
* position.) No return value.
|
||||
*/
|
||||
static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
|
||||
static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -94,20 +89,16 @@ static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
|
|||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait = {
|
||||
.find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -121,7 +112,7 @@ const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait = {
|
|||
* shift from the CM_{I,F}CLKEN bit. Pass back the correct info via
|
||||
* @idlest_reg and @idlest_bit. No return value.
|
||||
*/
|
||||
static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
|
||||
static void omap3430es2_clk_hsotgusb_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -134,18 +125,14 @@ static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
|
|||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_hsotgusb_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait = {
|
||||
.find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
* in the enable register itsel at a bit offset of 4 from the enable
|
||||
* bit. A value of 1 indicates that clock is enabled.
|
||||
*/
|
||||
static void am35xx_clk_find_idlest(struct clk *clk,
|
||||
static void am35xx_clk_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -71,7 +71,8 @@ static void am35xx_clk_find_idlest(struct clk *clk,
|
|||
* associate this type of code with per-module data structures to
|
||||
* avoid this issue, and remove the casts. No return value.
|
||||
*/
|
||||
static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
|
||||
static void am35xx_clk_find_companion(struct clk_hw_omap *clk,
|
||||
void __iomem **other_reg,
|
||||
u8 *other_bit)
|
||||
{
|
||||
*other_reg = (__force void __iomem *)(clk->enable_reg);
|
||||
|
@ -80,10 +81,7 @@ static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
|
|||
else
|
||||
*other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
|
||||
}
|
||||
|
||||
const struct clkops clkops_am35xx_ipss_module_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait = {
|
||||
.find_idlest = am35xx_clk_find_idlest,
|
||||
.find_companion = am35xx_clk_find_companion,
|
||||
};
|
||||
|
@ -99,7 +97,7 @@ const struct clkops clkops_am35xx_ipss_module_wait = {
|
|||
* CM_{I,F}CLKEN bit. Pass back the correct info via @idlest_reg
|
||||
* and @idlest_bit. No return value.
|
||||
*/
|
||||
static void am35xx_clk_ipss_find_idlest(struct clk *clk,
|
||||
static void am35xx_clk_ipss_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -112,13 +110,9 @@ static void am35xx_clk_ipss_find_idlest(struct clk *clk,
|
|||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_am35xx_ipss_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = am35xx_clk_ipss_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = am35xx_clk_ipss_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -37,34 +37,32 @@
|
|||
* (Any other value different from the Read value) to the
|
||||
* corresponding CM_CLKSEL register will refresh the dividers.
|
||||
*/
|
||||
static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
|
||||
int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk)
|
||||
{
|
||||
struct clk_hw_omap *parent;
|
||||
struct clk_hw *parent_hw;
|
||||
u32 dummy_v, orig_v, clksel_shift;
|
||||
int ret;
|
||||
|
||||
/* Clear PWRDN bit of HSDIVIDER */
|
||||
ret = omap2_dflt_clk_enable(clk);
|
||||
|
||||
parent_hw = __clk_get_hw(__clk_get_parent(clk->clk));
|
||||
parent = to_clk_hw_omap(parent_hw);
|
||||
|
||||
/* Restore the dividers */
|
||||
if (!ret) {
|
||||
clksel_shift = __ffs(clk->parent->clksel_mask);
|
||||
orig_v = __raw_readl(clk->parent->clksel_reg);
|
||||
clksel_shift = __ffs(parent->clksel_mask);
|
||||
orig_v = __raw_readl(parent->clksel_reg);
|
||||
dummy_v = orig_v;
|
||||
|
||||
/* Write any other value different from the Read value */
|
||||
dummy_v ^= (1 << clksel_shift);
|
||||
__raw_writel(dummy_v, clk->parent->clksel_reg);
|
||||
__raw_writel(dummy_v, parent->clksel_reg);
|
||||
|
||||
/* Write the original divider */
|
||||
__raw_writel(orig_v, clk->parent->clksel_reg);
|
||||
__raw_writel(orig_v, parent->clksel_reg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = {
|
||||
.enable = omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.find_idlest = omap2_clk_dflt_find_idlest,
|
||||
};
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
|
||||
|
||||
extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
extern int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *hw);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
|
||||
/* needed by omap3_core_dpll_m2_set_rate() */
|
||||
struct clk *sdrc_ick_p, *arm_fck_p;
|
||||
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
|
||||
int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
/*
|
||||
* According to the 12-5 CDP code from TI, "Limitation 2.5"
|
||||
|
@ -51,7 +51,7 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return omap3_noncore_dpll_set_rate(clk, rate);
|
||||
return omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
|
||||
}
|
||||
|
||||
void __init omap3_clk_lock_dpll5(void)
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
|
||||
|
||||
int omap3xxx_clk_init(void);
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
void omap3_clk_lock_dpll5(void);
|
||||
|
||||
extern struct clk *sdrc_ick_p;
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -16,6 +16,7 @@
|
|||
* OMAP3xxx clock definition files.
|
||||
*/
|
||||
|
||||
#include <linux/clk-private.h>
|
||||
#include "clock.h"
|
||||
|
||||
/* clksel_rate data common to 24xx/343x */
|
||||
|
@ -52,6 +53,13 @@ const struct clksel_rate div_1_0_rates[] = {
|
|||
{ .div = 0 },
|
||||
};
|
||||
|
||||
const struct clksel_rate div3_1to4_rates[] = {
|
||||
{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
|
||||
{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
|
||||
{ .div = 4, .val = 2, .flags = RATE_IN_4430 },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
const struct clksel_rate div_1_1_rates[] = {
|
||||
{ .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
|
||||
{ .div = 0 },
|
||||
|
@ -109,14 +117,10 @@ const struct clksel_rate div31_1to31_rates[] = {
|
|||
|
||||
/* Clocks shared between various OMAP SoCs */
|
||||
|
||||
struct clk virt_19200000_ck = {
|
||||
.name = "virt_19200000_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 19200000,
|
||||
};
|
||||
static struct clk_ops dummy_ck_ops = {};
|
||||
|
||||
struct clk virt_26000000_ck = {
|
||||
.name = "virt_26000000_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 26000000,
|
||||
struct clk dummy_ck = {
|
||||
.name = "dummy_clk",
|
||||
.ops = &dummy_ck_ops,
|
||||
.flags = CLK_IS_BASIC,
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
|
@ -947,35 +948,6 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&clkdm->lock, flags);
|
||||
|
||||
if (atomic_read(&clkdm->usecount) == 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
WARN_ON(1); /* underflow */
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (atomic_dec_return(&clkdm->usecount) > 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_clkdm->clkdm_clk_disable(clkdm);
|
||||
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
|
||||
pr_debug("clockdomain: %s: disabled\n", clkdm->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clkdm_clk_enable - add an enabled downstream clock to this clkdm
|
||||
* @clkdm: struct clockdomain *
|
||||
|
@ -1018,15 +990,37 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
|
|||
*/
|
||||
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
|
||||
{
|
||||
/*
|
||||
* XXX Rewrite this code to maintain a list of enabled
|
||||
* downstream clocks for debugging purposes?
|
||||
*/
|
||||
unsigned long flags;
|
||||
|
||||
if (!clk)
|
||||
if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
|
||||
return -EINVAL;
|
||||
|
||||
return _clkdm_clk_hwmod_disable(clkdm);
|
||||
spin_lock_irqsave(&clkdm->lock, flags);
|
||||
|
||||
/* corner case: disabling unused clocks */
|
||||
if (__clk_get_enable_count(clk) == 0)
|
||||
goto ccd_exit;
|
||||
|
||||
if (atomic_read(&clkdm->usecount) == 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
WARN_ON(1); /* underflow */
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (atomic_dec_return(&clkdm->usecount) > 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_clkdm->clkdm_clk_disable(clkdm);
|
||||
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||
|
||||
pr_debug("clockdomain: %s: disabled\n", clkdm->name);
|
||||
|
||||
ccd_exit:
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1077,6 +1071,8 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
|
|||
*/
|
||||
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* The clkdm attribute does not exist yet prior OMAP4 */
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx())
|
||||
return 0;
|
||||
|
@ -1086,9 +1082,28 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
|
|||
* downstream hwmods for debugging purposes?
|
||||
*/
|
||||
|
||||
if (!oh)
|
||||
if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
|
||||
return -EINVAL;
|
||||
|
||||
return _clkdm_clk_hwmod_disable(clkdm);
|
||||
spin_lock_irqsave(&clkdm->lock, flags);
|
||||
|
||||
if (atomic_read(&clkdm->usecount) == 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
WARN_ON(1); /* underflow */
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (atomic_dec_return(&clkdm->usecount) > 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_clkdm->clkdm_clk_disable(clkdm);
|
||||
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
|
||||
pr_debug("clockdomain: %s: disabled\n", clkdm->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
/* CM_CLKSEL_MPU */
|
||||
#define OMAP24XX_CLKSEL_MPU_SHIFT 0
|
||||
#define OMAP24XX_CLKSEL_MPU_MASK (0x1f << 0)
|
||||
#define OMAP24XX_CLKSEL_MPU_WIDTH 5
|
||||
|
||||
/* CM_CLKSTCTRL_MPU */
|
||||
#define OMAP24XX_AUTOSTATE_MPU_SHIFT 0
|
||||
|
@ -237,8 +238,10 @@
|
|||
#define OMAP24XX_CLKSEL_DSS1_MASK (0x1f << 8)
|
||||
#define OMAP24XX_CLKSEL_L4_SHIFT 5
|
||||
#define OMAP24XX_CLKSEL_L4_MASK (0x3 << 5)
|
||||
#define OMAP24XX_CLKSEL_L4_WIDTH 2
|
||||
#define OMAP24XX_CLKSEL_L3_SHIFT 0
|
||||
#define OMAP24XX_CLKSEL_L3_MASK (0x1f << 0)
|
||||
#define OMAP24XX_CLKSEL_L3_WIDTH 5
|
||||
|
||||
/* CM_CLKSEL2_CORE */
|
||||
#define OMAP24XX_CLKSEL_GPT12_SHIFT 22
|
||||
|
@ -363,8 +366,10 @@
|
|||
#define OMAP24XX_DPLL_DIV_MASK (0xf << 8)
|
||||
#define OMAP24XX_54M_SOURCE_SHIFT 5
|
||||
#define OMAP24XX_54M_SOURCE_MASK (1 << 5)
|
||||
#define OMAP24XX_54M_SOURCE_WIDTH 1
|
||||
#define OMAP2430_96M_SOURCE_SHIFT 4
|
||||
#define OMAP2430_96M_SOURCE_MASK (1 << 4)
|
||||
#define OMAP2430_96M_SOURCE_WIDTH 1
|
||||
#define OMAP24XX_48M_SOURCE_SHIFT 3
|
||||
#define OMAP24XX_48M_SOURCE_MASK (1 << 3)
|
||||
#define OMAP2430_ALTCLK_SOURCE_SHIFT 0
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
/* CM_CLKSEL1_PLL_IVA2 */
|
||||
#define OMAP3430_IVA2_CLK_SRC_SHIFT 19
|
||||
#define OMAP3430_IVA2_CLK_SRC_MASK (0x7 << 19)
|
||||
#define OMAP3430_IVA2_CLK_SRC_WIDTH 3
|
||||
#define OMAP3430_IVA2_DPLL_MULT_SHIFT 8
|
||||
#define OMAP3430_IVA2_DPLL_MULT_MASK (0x7ff << 8)
|
||||
#define OMAP3430_IVA2_DPLL_DIV_SHIFT 0
|
||||
|
@ -89,6 +90,7 @@
|
|||
/* CM_CLKSEL2_PLL_IVA2 */
|
||||
#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT 0
|
||||
#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
|
||||
#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_WIDTH 5
|
||||
|
||||
/* CM_CLKSTCTRL_IVA2 */
|
||||
#define OMAP3430_CLKTRCTRL_IVA2_SHIFT 0
|
||||
|
@ -118,6 +120,7 @@
|
|||
/* CM_IDLEST_PLL_MPU */
|
||||
#define OMAP3430_ST_MPU_CLK_SHIFT 0
|
||||
#define OMAP3430_ST_MPU_CLK_MASK (1 << 0)
|
||||
#define OMAP3430_ST_MPU_CLK_WIDTH 1
|
||||
|
||||
/* CM_AUTOIDLE_PLL_MPU */
|
||||
#define OMAP3430_AUTO_MPU_DPLL_SHIFT 0
|
||||
|
@ -126,6 +129,7 @@
|
|||
/* CM_CLKSEL1_PLL_MPU */
|
||||
#define OMAP3430_MPU_CLK_SRC_SHIFT 19
|
||||
#define OMAP3430_MPU_CLK_SRC_MASK (0x7 << 19)
|
||||
#define OMAP3430_MPU_CLK_SRC_WIDTH 3
|
||||
#define OMAP3430_MPU_DPLL_MULT_SHIFT 8
|
||||
#define OMAP3430_MPU_DPLL_MULT_MASK (0x7ff << 8)
|
||||
#define OMAP3430_MPU_DPLL_DIV_SHIFT 0
|
||||
|
@ -134,6 +138,7 @@
|
|||
/* CM_CLKSEL2_PLL_MPU */
|
||||
#define OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT 0
|
||||
#define OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
|
||||
#define OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH 5
|
||||
|
||||
/* CM_CLKSTCTRL_MPU */
|
||||
#define OMAP3430_CLKTRCTRL_MPU_SHIFT 0
|
||||
|
@ -345,10 +350,13 @@
|
|||
#define OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK (0x3 << 4)
|
||||
#define OMAP3430_CLKSEL_L4_SHIFT 2
|
||||
#define OMAP3430_CLKSEL_L4_MASK (0x3 << 2)
|
||||
#define OMAP3430_CLKSEL_L4_WIDTH 2
|
||||
#define OMAP3430_CLKSEL_L3_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_L3_MASK (0x3 << 0)
|
||||
#define OMAP3430_CLKSEL_L3_WIDTH 2
|
||||
#define OMAP3630_CLKSEL_96M_SHIFT 12
|
||||
#define OMAP3630_CLKSEL_96M_MASK (0x3 << 12)
|
||||
#define OMAP3630_CLKSEL_96M_WIDTH 2
|
||||
|
||||
/* CM_CLKSTCTRL_CORE */
|
||||
#define OMAP3430ES1_CLKTRCTRL_D2D_SHIFT 4
|
||||
|
@ -452,6 +460,7 @@
|
|||
#define OMAP3430ES2_CLKSEL_USIMOCP_MASK (0xf << 3)
|
||||
#define OMAP3430_CLKSEL_RM_SHIFT 1
|
||||
#define OMAP3430_CLKSEL_RM_MASK (0x3 << 1)
|
||||
#define OMAP3430_CLKSEL_RM_WIDTH 2
|
||||
#define OMAP3430_CLKSEL_GPT1_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_GPT1_MASK (1 << 0)
|
||||
|
||||
|
@ -520,14 +529,17 @@
|
|||
/* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */
|
||||
#define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27
|
||||
#define OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK (0x1f << 27)
|
||||
#define OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH 5
|
||||
#define OMAP3430_CORE_DPLL_MULT_SHIFT 16
|
||||
#define OMAP3430_CORE_DPLL_MULT_MASK (0x7ff << 16)
|
||||
#define OMAP3430_CORE_DPLL_DIV_SHIFT 8
|
||||
#define OMAP3430_CORE_DPLL_DIV_MASK (0x7f << 8)
|
||||
#define OMAP3430_SOURCE_96M_SHIFT 6
|
||||
#define OMAP3430_SOURCE_96M_MASK (1 << 6)
|
||||
#define OMAP3430_SOURCE_96M_WIDTH 1
|
||||
#define OMAP3430_SOURCE_54M_SHIFT 5
|
||||
#define OMAP3430_SOURCE_54M_MASK (1 << 5)
|
||||
#define OMAP3430_SOURCE_54M_WIDTH 1
|
||||
#define OMAP3430_SOURCE_48M_SHIFT 3
|
||||
#define OMAP3430_SOURCE_48M_MASK (1 << 3)
|
||||
|
||||
|
@ -545,7 +557,9 @@
|
|||
/* CM_CLKSEL3_PLL */
|
||||
#define OMAP3430_DIV_96M_SHIFT 0
|
||||
#define OMAP3430_DIV_96M_MASK (0x1f << 0)
|
||||
#define OMAP3430_DIV_96M_WIDTH 5
|
||||
#define OMAP3630_DIV_96M_MASK (0x3f << 0)
|
||||
#define OMAP3630_DIV_96M_WIDTH 6
|
||||
|
||||
/* CM_CLKSEL4_PLL */
|
||||
#define OMAP3430ES2_PERIPH2_DPLL_MULT_SHIFT 8
|
||||
|
@ -556,12 +570,14 @@
|
|||
/* CM_CLKSEL5_PLL */
|
||||
#define OMAP3430ES2_DIV_120M_SHIFT 0
|
||||
#define OMAP3430ES2_DIV_120M_MASK (0x1f << 0)
|
||||
#define OMAP3430ES2_DIV_120M_WIDTH 5
|
||||
|
||||
/* CM_CLKOUT_CTRL */
|
||||
#define OMAP3430_CLKOUT2_EN_SHIFT 7
|
||||
#define OMAP3430_CLKOUT2_EN_MASK (1 << 7)
|
||||
#define OMAP3430_CLKOUT2_DIV_SHIFT 3
|
||||
#define OMAP3430_CLKOUT2_DIV_MASK (0x7 << 3)
|
||||
#define OMAP3430_CLKOUT2_DIV_WIDTH 3
|
||||
#define OMAP3430_CLKOUT2SOURCE_SHIFT 0
|
||||
#define OMAP3430_CLKOUT2SOURCE_MASK (0x3 << 0)
|
||||
|
||||
|
@ -592,10 +608,14 @@
|
|||
/* CM_CLKSEL_DSS */
|
||||
#define OMAP3430_CLKSEL_TV_SHIFT 8
|
||||
#define OMAP3430_CLKSEL_TV_MASK (0x1f << 8)
|
||||
#define OMAP3430_CLKSEL_TV_WIDTH 5
|
||||
#define OMAP3630_CLKSEL_TV_MASK (0x3f << 8)
|
||||
#define OMAP3630_CLKSEL_TV_WIDTH 6
|
||||
#define OMAP3430_CLKSEL_DSS1_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_DSS1_MASK (0x1f << 0)
|
||||
#define OMAP3430_CLKSEL_DSS1_WIDTH 5
|
||||
#define OMAP3630_CLKSEL_DSS1_MASK (0x3f << 0)
|
||||
#define OMAP3630_CLKSEL_DSS1_WIDTH 6
|
||||
|
||||
/* CM_SLEEPDEP_DSS specific bits */
|
||||
|
||||
|
@ -623,7 +643,9 @@
|
|||
/* CM_CLKSEL_CAM */
|
||||
#define OMAP3430_CLKSEL_CAM_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_CAM_MASK (0x1f << 0)
|
||||
#define OMAP3430_CLKSEL_CAM_WIDTH 5
|
||||
#define OMAP3630_CLKSEL_CAM_MASK (0x3f << 0)
|
||||
#define OMAP3630_CLKSEL_CAM_WIDTH 6
|
||||
|
||||
/* CM_SLEEPDEP_CAM specific bits */
|
||||
|
||||
|
@ -721,21 +743,30 @@
|
|||
/* CM_CLKSEL1_EMU */
|
||||
#define OMAP3430_DIV_DPLL4_SHIFT 24
|
||||
#define OMAP3430_DIV_DPLL4_MASK (0x1f << 24)
|
||||
#define OMAP3430_DIV_DPLL4_WIDTH 5
|
||||
#define OMAP3630_DIV_DPLL4_MASK (0x3f << 24)
|
||||
#define OMAP3630_DIV_DPLL4_WIDTH 6
|
||||
#define OMAP3430_DIV_DPLL3_SHIFT 16
|
||||
#define OMAP3430_DIV_DPLL3_MASK (0x1f << 16)
|
||||
#define OMAP3430_DIV_DPLL3_WIDTH 5
|
||||
#define OMAP3430_CLKSEL_TRACECLK_SHIFT 11
|
||||
#define OMAP3430_CLKSEL_TRACECLK_MASK (0x7 << 11)
|
||||
#define OMAP3430_CLKSEL_TRACECLK_WIDTH 3
|
||||
#define OMAP3430_CLKSEL_PCLK_SHIFT 8
|
||||
#define OMAP3430_CLKSEL_PCLK_MASK (0x7 << 8)
|
||||
#define OMAP3430_CLKSEL_PCLK_WIDTH 3
|
||||
#define OMAP3430_CLKSEL_PCLKX2_SHIFT 6
|
||||
#define OMAP3430_CLKSEL_PCLKX2_MASK (0x3 << 6)
|
||||
#define OMAP3430_CLKSEL_PCLKX2_WIDTH 2
|
||||
#define OMAP3430_CLKSEL_ATCLK_SHIFT 4
|
||||
#define OMAP3430_CLKSEL_ATCLK_MASK (0x3 << 4)
|
||||
#define OMAP3430_CLKSEL_ATCLK_WIDTH 2
|
||||
#define OMAP3430_TRACE_MUX_CTRL_SHIFT 2
|
||||
#define OMAP3430_TRACE_MUX_CTRL_MASK (0x3 << 2)
|
||||
#define OMAP3430_TRACE_MUX_CTRL_WIDTH 2
|
||||
#define OMAP3430_MUX_CTRL_SHIFT 0
|
||||
#define OMAP3430_MUX_CTRL_MASK (0x3 << 0)
|
||||
#define OMAP3430_MUX_CTRL_WIDTH 2
|
||||
|
||||
/* CM_CLKSTCTRL_EMU */
|
||||
#define OMAP3430_CLKTRCTRL_EMU_SHIFT 0
|
||||
|
|
|
@ -108,6 +108,7 @@ extern void omap2xxx_cm_apll96_disable(void);
|
|||
/* CM_CLKSEL_GFX */
|
||||
#define OMAP_CLKSEL_GFX_SHIFT 0
|
||||
#define OMAP_CLKSEL_GFX_MASK (0x7 << 0)
|
||||
#define OMAP_CLKSEL_GFX_WIDTH 3
|
||||
|
||||
/* CM_ICLKEN_GFX */
|
||||
#define OMAP_EN_GFX_SHIFT 0
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/clkdev.h>
|
||||
|
||||
#include "soc.h"
|
||||
#include "clockdomain.h"
|
||||
#include "clock.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
@ -42,7 +43,7 @@
|
|||
/* Private functions */
|
||||
|
||||
/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
|
||||
static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
|
||||
static void _omap3_dpll_write_clken(struct clk_hw_omap *clk, u8 clken_bits)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u32 v;
|
||||
|
@ -56,7 +57,7 @@ static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
|
|||
}
|
||||
|
||||
/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
|
||||
static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
|
||||
static int _omap3_wait_dpll_status(struct clk_hw_omap *clk, u8 state)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
int i = 0;
|
||||
|
@ -64,7 +65,7 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
|
|||
const char *clk_name;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
clk_name = __clk_get_name(clk);
|
||||
clk_name = __clk_get_name(clk->hw.clk);
|
||||
|
||||
state <<= __ffs(dd->idlest_mask);
|
||||
|
||||
|
@ -88,7 +89,7 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
|
|||
}
|
||||
|
||||
/* From 3430 TRM ES2 4.7.6.2 */
|
||||
static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
|
||||
static u16 _omap3_dpll_compute_freqsel(struct clk_hw_omap *clk, u8 n)
|
||||
{
|
||||
unsigned long fint;
|
||||
u16 f = 0;
|
||||
|
@ -133,14 +134,14 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
|
|||
* locked successfully, return 0; if the DPLL did not lock in the time
|
||||
* allotted, or DPLL3 was passed in, return -EINVAL.
|
||||
*/
|
||||
static int _omap3_noncore_dpll_lock(struct clk *clk)
|
||||
static int _omap3_noncore_dpll_lock(struct clk_hw_omap *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u8 ai;
|
||||
u8 state = 1;
|
||||
int r = 0;
|
||||
|
||||
pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk));
|
||||
pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk->hw.clk));
|
||||
|
||||
dd = clk->dpll_data;
|
||||
state <<= __ffs(dd->idlest_mask);
|
||||
|
@ -178,7 +179,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
|
|||
* DPLL3 was passed in, or the DPLL does not support low-power bypass,
|
||||
* return -EINVAL.
|
||||
*/
|
||||
static int _omap3_noncore_dpll_bypass(struct clk *clk)
|
||||
static int _omap3_noncore_dpll_bypass(struct clk_hw_omap *clk)
|
||||
{
|
||||
int r;
|
||||
u8 ai;
|
||||
|
@ -187,7 +188,7 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk)
|
|||
return -EINVAL;
|
||||
|
||||
pr_debug("clock: configuring DPLL %s for low-power bypass\n",
|
||||
__clk_get_name(clk));
|
||||
__clk_get_name(clk->hw.clk));
|
||||
|
||||
ai = omap3_dpll_autoidle_read(clk);
|
||||
|
||||
|
@ -210,14 +211,14 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk)
|
|||
* code. If DPLL3 was passed in, or the DPLL does not support
|
||||
* low-power stop, return -EINVAL; otherwise, return 0.
|
||||
*/
|
||||
static int _omap3_noncore_dpll_stop(struct clk *clk)
|
||||
static int _omap3_noncore_dpll_stop(struct clk_hw_omap *clk)
|
||||
{
|
||||
u8 ai;
|
||||
|
||||
if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
|
||||
return -EINVAL;
|
||||
|
||||
pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk));
|
||||
pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk->hw.clk));
|
||||
|
||||
ai = omap3_dpll_autoidle_read(clk);
|
||||
|
||||
|
@ -241,11 +242,11 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
|
|||
* XXX This code is not needed for 3430/AM35xx; can it be optimized
|
||||
* out in non-multi-OMAP builds for those chips?
|
||||
*/
|
||||
static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
|
||||
static void _lookup_dco(struct clk_hw_omap *clk, u8 *dco, u16 m, u8 n)
|
||||
{
|
||||
unsigned long fint, clkinp; /* watch out for overflow */
|
||||
|
||||
clkinp = __clk_get_rate(__clk_get_parent(clk));
|
||||
clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk));
|
||||
fint = (clkinp / n) * m;
|
||||
|
||||
if (fint < 1000000000)
|
||||
|
@ -266,12 +267,12 @@ static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
|
|||
* XXX This code is not needed for 3430/AM35xx; can it be optimized
|
||||
* out in non-multi-OMAP builds for those chips?
|
||||
*/
|
||||
static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
|
||||
static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n)
|
||||
{
|
||||
unsigned long clkinp, sd; /* watch out for overflow */
|
||||
int mod1, mod2;
|
||||
|
||||
clkinp = __clk_get_rate(__clk_get_parent(clk));
|
||||
clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk));
|
||||
|
||||
/*
|
||||
* target sigma-delta to near 250MHz
|
||||
|
@ -298,7 +299,8 @@ static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
|
|||
* Program the DPLL with the supplied M, N values, and wait for the DPLL to
|
||||
* lock.. Returns -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
||||
static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 m, u8 n,
|
||||
u16 freqsel)
|
||||
{
|
||||
struct dpll_data *dd = clk->dpll_data;
|
||||
u8 dco, sd_div;
|
||||
|
@ -355,8 +357,10 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
|||
*
|
||||
* Recalculate and propagate the DPLL rate.
|
||||
*/
|
||||
unsigned long omap3_dpll_recalc(struct clk *clk)
|
||||
unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
|
||||
return omap2_get_dpll_rate(clk);
|
||||
}
|
||||
|
||||
|
@ -376,8 +380,9 @@ unsigned long omap3_dpll_recalc(struct clk *clk)
|
|||
* support low-power stop, or if the DPLL took too long to enter
|
||||
* bypass or lock, return -EINVAL; otherwise, return 0.
|
||||
*/
|
||||
int omap3_noncore_dpll_enable(struct clk *clk)
|
||||
int omap3_noncore_dpll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
int r;
|
||||
struct dpll_data *dd;
|
||||
struct clk *parent;
|
||||
|
@ -386,22 +391,26 @@ int omap3_noncore_dpll_enable(struct clk *clk)
|
|||
if (!dd)
|
||||
return -EINVAL;
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
if (clk->clkdm) {
|
||||
r = clkdm_clk_enable(clk->clkdm, hw->clk);
|
||||
if (r) {
|
||||
WARN(1,
|
||||
"%s: could not enable %s's clockdomain %s: %d\n",
|
||||
__func__, __clk_get_name(hw->clk),
|
||||
clk->clkdm->name, r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (__clk_get_rate(clk) == __clk_get_rate(dd->clk_bypass)) {
|
||||
parent = __clk_get_parent(hw->clk);
|
||||
|
||||
if (__clk_get_rate(hw->clk) == __clk_get_rate(dd->clk_bypass)) {
|
||||
WARN_ON(parent != dd->clk_bypass);
|
||||
r = _omap3_noncore_dpll_bypass(clk);
|
||||
} else {
|
||||
WARN_ON(parent != dd->clk_ref);
|
||||
r = _omap3_noncore_dpll_lock(clk);
|
||||
}
|
||||
/*
|
||||
*FIXME: this is dubious - if clk->rate has changed, what about
|
||||
* propagating?
|
||||
*/
|
||||
if (!r)
|
||||
clk->rate = (clk->recalc) ? clk->recalc(clk) :
|
||||
omap2_get_dpll_rate(clk);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -413,9 +422,13 @@ int omap3_noncore_dpll_enable(struct clk *clk)
|
|||
* Instructs a non-CORE DPLL to enter low-power stop. This function is
|
||||
* intended for use in struct clkops. No return value.
|
||||
*/
|
||||
void omap3_noncore_dpll_disable(struct clk *clk)
|
||||
void omap3_noncore_dpll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
|
||||
_omap3_noncore_dpll_stop(clk);
|
||||
if (clk->clkdm)
|
||||
clkdm_clk_disable(clk->clkdm, hw->clk);
|
||||
}
|
||||
|
||||
|
||||
|
@ -432,80 +445,72 @@ void omap3_noncore_dpll_disable(struct clk *clk)
|
|||
* target rate if it hasn't been done already, then program and lock
|
||||
* the DPLL. Returns -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
|
||||
int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
struct clk *new_parent = NULL;
|
||||
unsigned long hw_rate, bypass_rate;
|
||||
u16 freqsel = 0;
|
||||
struct dpll_data *dd;
|
||||
int ret;
|
||||
|
||||
if (!clk || !rate)
|
||||
if (!hw || !rate)
|
||||
return -EINVAL;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return -EINVAL;
|
||||
|
||||
hw_rate = (clk->recalc) ? clk->recalc(clk) : omap2_get_dpll_rate(clk);
|
||||
if (rate == hw_rate)
|
||||
return 0;
|
||||
__clk_prepare(dd->clk_bypass);
|
||||
clk_enable(dd->clk_bypass);
|
||||
__clk_prepare(dd->clk_ref);
|
||||
clk_enable(dd->clk_ref);
|
||||
|
||||
/*
|
||||
* Ensure both the bypass and ref clocks are enabled prior to
|
||||
* doing anything; we need the bypass clock running to reprogram
|
||||
* the DPLL.
|
||||
*/
|
||||
omap2_clk_enable(dd->clk_bypass);
|
||||
omap2_clk_enable(dd->clk_ref);
|
||||
|
||||
bypass_rate = __clk_get_rate(dd->clk_bypass);
|
||||
if (bypass_rate == rate &&
|
||||
(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
|
||||
pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
|
||||
if (__clk_get_rate(dd->clk_bypass) == rate &&
|
||||
(dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
|
||||
pr_debug("%s: %s: set rate: entering bypass.\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
|
||||
ret = _omap3_noncore_dpll_bypass(clk);
|
||||
if (!ret)
|
||||
new_parent = dd->clk_bypass;
|
||||
} else {
|
||||
if (dd->last_rounded_rate != rate)
|
||||
rate = clk->round_rate(clk, rate);
|
||||
rate = __clk_round_rate(hw->clk, rate);
|
||||
|
||||
if (dd->last_rounded_rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* No freqsel on OMAP4 and OMAP3630 */
|
||||
if (!soc_is_am33xx() && !cpu_is_omap44xx() && !cpu_is_omap3630()) {
|
||||
if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
|
||||
freqsel = _omap3_dpll_compute_freqsel(clk,
|
||||
dd->last_rounded_n);
|
||||
if (!freqsel)
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
pr_debug("clock: %s: set rate: locking rate to %lu.\n",
|
||||
__clk_get_name(clk), rate);
|
||||
pr_debug("%s: %s: set rate: locking rate to %lu.\n",
|
||||
__func__, __clk_get_name(hw->clk), rate);
|
||||
|
||||
ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
|
||||
dd->last_rounded_n, freqsel);
|
||||
if (!ret)
|
||||
new_parent = dd->clk_ref;
|
||||
}
|
||||
if (!ret) {
|
||||
/*
|
||||
* Switch the parent clock in the hierarchy, and make sure
|
||||
* that the new parent's usecount is correct. Note: we
|
||||
* enable the new parent before disabling the old to avoid
|
||||
* any unnecessary hardware disable->enable transitions.
|
||||
* FIXME - this is all wrong. common code handles reparenting and
|
||||
* migrating prepare/enable counts. dplls should be a multiplexer
|
||||
* clock and this should be a set_parent operation so that all of that
|
||||
* stuff is inherited for free
|
||||
*/
|
||||
if (clk->usecount) {
|
||||
omap2_clk_enable(new_parent);
|
||||
omap2_clk_disable(clk->parent);
|
||||
}
|
||||
clk_reparent(clk, new_parent);
|
||||
clk->rate = rate;
|
||||
}
|
||||
omap2_clk_disable(dd->clk_ref);
|
||||
omap2_clk_disable(dd->clk_bypass);
|
||||
|
||||
if (!ret)
|
||||
__clk_reparent(hw->clk, new_parent);
|
||||
|
||||
clk_disable(dd->clk_ref);
|
||||
__clk_unprepare(dd->clk_ref);
|
||||
clk_disable(dd->clk_bypass);
|
||||
__clk_unprepare(dd->clk_bypass);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -520,7 +525,7 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
|
|||
* -EINVAL if passed a null pointer or if the struct clk does not
|
||||
* appear to refer to a DPLL.
|
||||
*/
|
||||
u32 omap3_dpll_autoidle_read(struct clk *clk)
|
||||
u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u32 v;
|
||||
|
@ -549,7 +554,7 @@ u32 omap3_dpll_autoidle_read(struct clk *clk)
|
|||
* OMAP3430. The DPLL will enter low-power stop when its downstream
|
||||
* clocks are gated. No return value.
|
||||
*/
|
||||
void omap3_dpll_allow_idle(struct clk *clk)
|
||||
void omap3_dpll_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u32 v;
|
||||
|
@ -559,11 +564,8 @@ void omap3_dpll_allow_idle(struct clk *clk)
|
|||
|
||||
dd = clk->dpll_data;
|
||||
|
||||
if (!dd->autoidle_reg) {
|
||||
pr_debug("clock: DPLL %s: autoidle not supported\n",
|
||||
__clk_get_name(clk));
|
||||
if (!dd->autoidle_reg)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* REVISIT: CORE DPLL can optionally enter low-power bypass
|
||||
|
@ -583,7 +585,7 @@ void omap3_dpll_allow_idle(struct clk *clk)
|
|||
*
|
||||
* Disable DPLL automatic idle control. No return value.
|
||||
*/
|
||||
void omap3_dpll_deny_idle(struct clk *clk)
|
||||
void omap3_dpll_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u32 v;
|
||||
|
@ -593,11 +595,8 @@ void omap3_dpll_deny_idle(struct clk *clk)
|
|||
|
||||
dd = clk->dpll_data;
|
||||
|
||||
if (!dd->autoidle_reg) {
|
||||
pr_debug("clock: DPLL %s: autoidle not supported\n",
|
||||
__clk_get_name(clk));
|
||||
if (!dd->autoidle_reg)
|
||||
return;
|
||||
}
|
||||
|
||||
v = __raw_readl(dd->autoidle_reg);
|
||||
v &= ~dd->autoidle_mask;
|
||||
|
@ -615,18 +614,25 @@ void omap3_dpll_deny_idle(struct clk *clk)
|
|||
* Using parent clock DPLL data, look up DPLL state. If locked, set our
|
||||
* rate to the dpll_clk * 2; otherwise, just use dpll_clk.
|
||||
*/
|
||||
unsigned long omap3_clkoutx2_recalc(struct clk *clk)
|
||||
unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
unsigned long rate;
|
||||
u32 v;
|
||||
struct clk *pclk;
|
||||
unsigned long parent_rate;
|
||||
struct clk_hw_omap *pclk = NULL;
|
||||
struct clk *parent;
|
||||
|
||||
/* Walk up the parents of clk, looking for a DPLL */
|
||||
pclk = __clk_get_parent(clk);
|
||||
while (pclk && !pclk->dpll_data)
|
||||
pclk = __clk_get_parent(pclk);
|
||||
do {
|
||||
do {
|
||||
parent = __clk_get_parent(hw->clk);
|
||||
hw = __clk_get_hw(parent);
|
||||
} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
|
||||
if (!hw)
|
||||
break;
|
||||
pclk = to_clk_hw_omap(hw);
|
||||
} while (pclk && !pclk->dpll_data);
|
||||
|
||||
/* clk does not have a DPLL as a parent? error in the clock data */
|
||||
if (!pclk) {
|
||||
|
@ -638,7 +644,6 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
|
|||
|
||||
WARN_ON(!dd->enable_mask);
|
||||
|
||||
parent_rate = __clk_get_rate(__clk_get_parent(clk));
|
||||
v = __raw_readl(dd->control_reg) & dd->enable_mask;
|
||||
v >>= __ffs(dd->enable_mask);
|
||||
if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
|
||||
|
@ -649,15 +654,7 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
|
|||
}
|
||||
|
||||
/* OMAP3/4 non-CORE DPLL clkops */
|
||||
|
||||
const struct clkops clkops_omap3_noncore_dpll_ops = {
|
||||
.enable = omap3_noncore_dpll_enable,
|
||||
.disable = omap3_noncore_dpll_disable,
|
||||
.allow_idle = omap3_dpll_allow_idle,
|
||||
.deny_idle = omap3_dpll_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap3_core_dpll_ops = {
|
||||
const struct clk_hw_omap_ops clkhwops_omap3_dpll = {
|
||||
.allow_idle = omap3_dpll_allow_idle,
|
||||
.deny_idle = omap3_dpll_deny_idle,
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "cm-regbits-44xx.h"
|
||||
|
||||
/* Supported only on OMAP4 */
|
||||
int omap4_dpllmx_gatectrl_read(struct clk *clk)
|
||||
int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v;
|
||||
u32 mask;
|
||||
|
@ -40,7 +40,7 @@ int omap4_dpllmx_gatectrl_read(struct clk *clk)
|
|||
return v;
|
||||
}
|
||||
|
||||
void omap4_dpllmx_allow_gatectrl(struct clk *clk)
|
||||
void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v;
|
||||
u32 mask;
|
||||
|
@ -58,7 +58,7 @@ void omap4_dpllmx_allow_gatectrl(struct clk *clk)
|
|||
__raw_writel(v, clk->clksel_reg);
|
||||
}
|
||||
|
||||
void omap4_dpllmx_deny_gatectrl(struct clk *clk)
|
||||
void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v;
|
||||
u32 mask;
|
||||
|
@ -76,7 +76,7 @@ void omap4_dpllmx_deny_gatectrl(struct clk *clk)
|
|||
__raw_writel(v, clk->clksel_reg);
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap4_dpllmx_ops = {
|
||||
const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = {
|
||||
.allow_idle = omap4_dpllmx_allow_gatectrl,
|
||||
.deny_idle = omap4_dpllmx_deny_gatectrl,
|
||||
};
|
||||
|
@ -90,8 +90,10 @@ const struct clkops clkops_omap4_dpllmx_ops = {
|
|||
* OMAP4 ABE DPLL. Returns the DPLL's output rate (before M-dividers)
|
||||
* upon success, or 0 upon error.
|
||||
*/
|
||||
unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk)
|
||||
unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 v;
|
||||
unsigned long rate;
|
||||
struct dpll_data *dd;
|
||||
|
@ -123,8 +125,11 @@ unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk)
|
|||
* M-dividers) upon success, -EINVAL if @clk is null or not a DPLL, or
|
||||
* ~0 if an error occurred in omap2_dpll_round_rate().
|
||||
*/
|
||||
long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
|
||||
unsigned long target_rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 v;
|
||||
struct dpll_data *dd;
|
||||
long r;
|
||||
|
@ -140,7 +145,7 @@ long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
|
|||
if (v)
|
||||
target_rate = target_rate / OMAP4430_REGM4XEN_MULT;
|
||||
|
||||
r = omap2_dpll_round_rate(clk, target_rate);
|
||||
r = omap2_dpll_round_rate(hw, target_rate, NULL);
|
||||
if (r == ~0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -407,6 +407,7 @@ void __init omap2420_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap2_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -436,6 +437,7 @@ void __init omap2430_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap2_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -509,6 +511,7 @@ void __init omap3_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init omap3430_init_late(void)
|
||||
|
@ -516,6 +519,7 @@ void __init omap3430_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init omap35xx_init_late(void)
|
||||
|
@ -523,6 +527,7 @@ void __init omap35xx_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init omap3630_init_late(void)
|
||||
|
@ -530,6 +535,7 @@ void __init omap3630_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init am35xx_init_late(void)
|
||||
|
@ -537,6 +543,7 @@ void __init am35xx_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init ti81xx_init_late(void)
|
||||
|
@ -544,6 +551,7 @@ void __init ti81xx_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -597,6 +605,7 @@ void __init omap4430_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap4_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/list.h>
|
||||
|
@ -614,6 +614,19 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
|
||||
{
|
||||
struct clk_hw_omap *clk;
|
||||
|
||||
if (oh->clkdm) {
|
||||
return oh->clkdm;
|
||||
} else if (oh->_clk) {
|
||||
clk = to_clk_hw_omap(__clk_get_hw(oh->_clk));
|
||||
return clk->clkdm;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active
|
||||
* @oh: struct omap_hwmod *
|
||||
|
@ -629,13 +642,18 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
|
|||
*/
|
||||
static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
|
||||
{
|
||||
if (!oh->_clk)
|
||||
struct clockdomain *clkdm, *init_clkdm;
|
||||
|
||||
clkdm = _get_clkdm(oh);
|
||||
init_clkdm = _get_clkdm(init_oh);
|
||||
|
||||
if (!clkdm || !init_clkdm)
|
||||
return -EINVAL;
|
||||
|
||||
if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
|
||||
if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
|
||||
return 0;
|
||||
|
||||
return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
|
||||
return clkdm_add_sleepdep(clkdm, init_clkdm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -653,13 +671,18 @@ static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
|
|||
*/
|
||||
static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
|
||||
{
|
||||
if (!oh->_clk)
|
||||
struct clockdomain *clkdm, *init_clkdm;
|
||||
|
||||
clkdm = _get_clkdm(oh);
|
||||
init_clkdm = _get_clkdm(init_oh);
|
||||
|
||||
if (!clkdm || !init_clkdm)
|
||||
return -EINVAL;
|
||||
|
||||
if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
|
||||
if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
|
||||
return 0;
|
||||
|
||||
return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
|
||||
return clkdm_del_sleepdep(clkdm, init_clkdm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -693,7 +716,7 @@ static int _init_main_clk(struct omap_hwmod *oh)
|
|||
*/
|
||||
clk_prepare(oh->_clk);
|
||||
|
||||
if (!oh->_clk->clkdm)
|
||||
if (!_get_clkdm(oh))
|
||||
pr_debug("omap_hwmod: %s: missing clockdomain for %s.\n",
|
||||
oh->name, oh->main_clk);
|
||||
|
||||
|
@ -1276,6 +1299,7 @@ static void _enable_sysc(struct omap_hwmod *oh)
|
|||
u8 idlemode, sf;
|
||||
u32 v;
|
||||
bool clkdm_act;
|
||||
struct clockdomain *clkdm;
|
||||
|
||||
if (!oh->class->sysc)
|
||||
return;
|
||||
|
@ -1283,11 +1307,9 @@ static void _enable_sysc(struct omap_hwmod *oh)
|
|||
v = oh->_sysc_cache;
|
||||
sf = oh->class->sysc->sysc_flags;
|
||||
|
||||
clkdm = _get_clkdm(oh);
|
||||
if (sf & SYSC_HAS_SIDLEMODE) {
|
||||
clkdm_act = ((oh->clkdm &&
|
||||
oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) ||
|
||||
(oh->_clk && oh->_clk->clkdm &&
|
||||
oh->_clk->clkdm->flags & CLKDM_ACTIVE_WITH_MPU));
|
||||
clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
|
||||
if (clkdm_act && !(oh->class->sysc->idlemodes &
|
||||
(SIDLE_SMART | SIDLE_SMART_WKUP)))
|
||||
idlemode = HWMOD_IDLEMODE_FORCE;
|
||||
|
@ -1489,11 +1511,12 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)
|
|||
|
||||
pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
|
||||
|
||||
if (soc_ops.init_clkdm)
|
||||
ret |= soc_ops.init_clkdm(oh);
|
||||
|
||||
ret |= _init_main_clk(oh);
|
||||
ret |= _init_interface_clks(oh);
|
||||
ret |= _init_opt_clks(oh);
|
||||
if (soc_ops.init_clkdm)
|
||||
ret |= soc_ops.init_clkdm(oh);
|
||||
|
||||
if (!ret)
|
||||
oh->_state = _HWMOD_STATE_CLKS_INITED;
|
||||
|
@ -3556,10 +3579,15 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
|
|||
{
|
||||
struct clk *c;
|
||||
struct omap_hwmod_ocp_if *oi;
|
||||
struct clockdomain *clkdm;
|
||||
struct clk_hw_omap *clk;
|
||||
|
||||
if (!oh)
|
||||
return NULL;
|
||||
|
||||
if (oh->clkdm)
|
||||
return oh->clkdm->pwrdm.ptr;
|
||||
|
||||
if (oh->_clk) {
|
||||
c = oh->_clk;
|
||||
} else {
|
||||
|
@ -3569,11 +3597,12 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
|
|||
c = oi->_clk;
|
||||
}
|
||||
|
||||
if (!c->clkdm)
|
||||
clk = to_clk_hw_omap(__clk_get_hw(c));
|
||||
clkdm = clk->clkdm;
|
||||
if (!clkdm)
|
||||
return NULL;
|
||||
|
||||
return c->clkdm->pwrdm.ptr;
|
||||
|
||||
return clkdm->pwrdm.ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1410,7 +1410,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = {
|
|||
static struct omap_hwmod omap34xx_sr1_hwmod = {
|
||||
.name = "smartreflex_mpu_iva",
|
||||
.class = &omap34xx_smartreflex_hwmod_class,
|
||||
.main_clk = "smartreflex_mpu_iva_fck",
|
||||
.main_clk = "sr1_fck",
|
||||
.prcm = {
|
||||
.omap2 = {
|
||||
.prcm_reg_id = 1,
|
||||
|
@ -1428,7 +1428,7 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
|
|||
static struct omap_hwmod omap36xx_sr1_hwmod = {
|
||||
.name = "smartreflex_mpu_iva",
|
||||
.class = &omap36xx_smartreflex_hwmod_class,
|
||||
.main_clk = "smartreflex_mpu_iva_fck",
|
||||
.main_clk = "sr1_fck",
|
||||
.prcm = {
|
||||
.omap2 = {
|
||||
.prcm_reg_id = 1,
|
||||
|
@ -1455,7 +1455,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = {
|
|||
static struct omap_hwmod omap34xx_sr2_hwmod = {
|
||||
.name = "smartreflex_core",
|
||||
.class = &omap34xx_smartreflex_hwmod_class,
|
||||
.main_clk = "smartreflex_core_fck",
|
||||
.main_clk = "sr2_fck",
|
||||
.prcm = {
|
||||
.omap2 = {
|
||||
.prcm_reg_id = 1,
|
||||
|
@ -1473,7 +1473,7 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
|
|||
static struct omap_hwmod omap36xx_sr2_hwmod = {
|
||||
.name = "smartreflex_core",
|
||||
.class = &omap36xx_smartreflex_hwmod_class,
|
||||
.main_clk = "smartreflex_core_fck",
|
||||
.main_clk = "sr2_fck",
|
||||
.prcm = {
|
||||
.omap2 = {
|
||||
.prcm_reg_id = 1,
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <linux/sysfs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/gpio.h>
|
||||
|
@ -202,7 +202,7 @@ static int omap2_can_sleep(void)
|
|||
{
|
||||
if (omap2_fclks_active())
|
||||
return 0;
|
||||
if (osc_ck->usecount > 1)
|
||||
if (__clk_is_enabled(osc_ck))
|
||||
return 0;
|
||||
if (omap_dma_running())
|
||||
return 0;
|
||||
|
|
|
@ -107,12 +107,14 @@
|
|||
#define OMAP2420_CLKOUT2_EN_MASK (1 << 15)
|
||||
#define OMAP2420_CLKOUT2_DIV_SHIFT 11
|
||||
#define OMAP2420_CLKOUT2_DIV_MASK (0x7 << 11)
|
||||
#define OMAP2420_CLKOUT2_DIV_WIDTH 3
|
||||
#define OMAP2420_CLKOUT2_SOURCE_SHIFT 8
|
||||
#define OMAP2420_CLKOUT2_SOURCE_MASK (0x3 << 8)
|
||||
#define OMAP24XX_CLKOUT_EN_SHIFT 7
|
||||
#define OMAP24XX_CLKOUT_EN_MASK (1 << 7)
|
||||
#define OMAP24XX_CLKOUT_DIV_SHIFT 3
|
||||
#define OMAP24XX_CLKOUT_DIV_MASK (0x7 << 3)
|
||||
#define OMAP24XX_CLKOUT_DIV_WIDTH 3
|
||||
#define OMAP24XX_CLKOUT_SOURCE_SHIFT 0
|
||||
#define OMAP24XX_CLKOUT_SOURCE_MASK (0x3 << 0)
|
||||
|
||||
|
|
|
@ -384,6 +384,7 @@
|
|||
/* PRM_CLKSEL */
|
||||
#define OMAP3430_SYS_CLKIN_SEL_SHIFT 0
|
||||
#define OMAP3430_SYS_CLKIN_SEL_MASK (0x7 << 0)
|
||||
#define OMAP3430_SYS_CLKIN_SEL_WIDTH 3
|
||||
|
||||
/* PRM_CLKOUT_CTRL */
|
||||
#define OMAP3430_CLKOUT_EN_MASK (1 << 7)
|
||||
|
|
|
@ -152,6 +152,7 @@ extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
|
|||
/* Named PRCM_CLKSRC_CTRL on the 24XX */
|
||||
#define OMAP_SYSCLKDIV_SHIFT 6
|
||||
#define OMAP_SYSCLKDIV_MASK (0x3 << 6)
|
||||
#define OMAP_SYSCLKDIV_WIDTH 2
|
||||
#define OMAP_AUTOEXTCLKMODE_SHIFT 3
|
||||
#define OMAP_AUTOEXTCLKMODE_MASK (0x3 << 3)
|
||||
#define OMAP_SYSCLKSEL_SHIFT 0
|
||||
|
|
|
@ -127,12 +127,14 @@
|
|||
/* AUXCLKREQ0 */
|
||||
#define OMAP4_MAPPING_SHIFT 2
|
||||
#define OMAP4_MAPPING_MASK (0x7 << 2)
|
||||
#define OMAP4_MAPPING_WIDTH 3
|
||||
#define OMAP4_ACCURACY_SHIFT 1
|
||||
#define OMAP4_ACCURACY_MASK (1 << 1)
|
||||
|
||||
/* AUXCLK0 */
|
||||
#define OMAP4_CLKDIV_SHIFT 16
|
||||
#define OMAP4_CLKDIV_MASK (0xf << 16)
|
||||
#define OMAP4_CLKDIV_WIDTH 4
|
||||
#define OMAP4_DISABLECLK_SHIFT 9
|
||||
#define OMAP4_DISABLECLK_MASK (1 << 9)
|
||||
#define OMAP4_ENABLE_SHIFT 8
|
||||
|
|
Loading…
Reference in a new issue