// SPDX-License-Identifier: GPL-2.0-only /* * linux/arch/arm/mach-omap1/clock_data.c * * Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc * * To do: * - Clocks that are only available on some chips should be marked with the * chips that they are present on.
*/
staticstruct omap1_clk ck_dpll1 = {
.hw.init = CLK_HW_INIT("ck_dpll1", "ck_ref", &omap1_clk_rate_ops, /* * force recursive refresh of rates of the clock * and its children when clk_get_rate() is called
*/
CLK_GET_RATE_NOCACHE),
};
/* * FIXME: This clock seems to be necessary but no-one has asked for its * activation. [ FIX: SoSSI, SSR ]
*/ staticstruct arm_idlect1_clk ck_dpll1out = {
.clk = {
.hw.init = CLK_HW_INIT("ck_dpll1out", "ck_dpll1", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic,
.flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_CKOUT_ARM,
},
.idlect_shift = IDL_CLKOUT_ARM_SHIFT,
};
staticstruct omap1_clk arminth_ck16xx = {
.hw.init = CLK_HW_INIT("arminth_ck", "arm_ck", &omap1_clk_null_ops, 0), /* Note: On 16xx the frequency can be divided by 2 by programming * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 * * 1510 version is in TC clocks.
*/
};
staticstruct omap1_clk arminth_ck1510 = {
.hw.init = CLK_HW_INIT("arminth_ck", "tc_ck", &omap1_clk_null_ops, 0), /* Note: On 1510 the frequency follows TC_CK * * 16xx version is in MPU clocks.
*/
};
/* * XXX The enable_bit here is misused - it simply switches between 12MHz * and 48MHz. Reimplement with clk_mux. * * XXX does this need SYSC register handling?
*/ staticstruct omap1_clk uart1_1510 = { /* Direct from ULPD, no real parent */
.hw.init = CLK_HW_INIT("uart1_ck", "armper_ck", &omap1_clk_full_ops, 0),
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART1_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
/* * XXX The enable_bit here is misused - it simply switches between 12MHz * and 48MHz. Reimplement with clk_mux. * * XXX SYSC register handling does not belong in the clock framework
*/ staticstruct uart_clk uart1_16xx = {
.clk = {
.ops = &clkops_uart_16xx, /* Direct from ULPD, no real parent */
.hw.init = CLK_HW_INIT("uart1_ck", "armper_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART1_CLK_MODE_R,
},
.sysc_addr = 0xfffb0054,
};
/* * XXX The enable_bit here is misused - it simply switches between 12MHz * and 48MHz. Reimplement with clk_mux. * * XXX does this need SYSC register handling?
*/ staticstruct omap1_clk uart2_ck = { /* Direct from ULPD, no real parent */
.hw.init = CLK_HW_INIT("uart2_ck", "armper_ck", &omap1_clk_full_ops, 0),
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART2_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
/* * XXX The enable_bit here is misused - it simply switches between 12MHz * and 48MHz. Reimplement with clk_mux. * * XXX does this need SYSC register handling?
*/ staticstruct omap1_clk uart3_1510 = { /* Direct from ULPD, no real parent */
.hw.init = CLK_HW_INIT("uart3_ck", "armper_ck", &omap1_clk_full_ops, 0),
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART3_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
/* * XXX The enable_bit here is misused - it simply switches between 12MHz * and 48MHz. Reimplement with clk_mux. * * XXX SYSC register handling does not belong in the clock framework
*/ staticstruct uart_clk uart3_16xx = {
.clk = {
.ops = &clkops_uart_16xx, /* Direct from ULPD, no real parent */
.hw.init = CLK_HW_INIT("uart3_ck", "armper_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART3_CLK_MODE_R,
},
.sysc_addr = 0xfffb9854,
};
staticstruct omap1_clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
.ops = &clkops_generic, /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_clko", &omap1_clk_full_ops, 0),
.rate = 6000000,
.flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
.enable_bit = USB_MCLK_EN_BIT,
};
staticstruct omap1_clk usb_dc_ck = {
.ops = &clkops_generic, /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_dc_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
};
staticstruct omap1_clk uart1_7xx = {
.ops = &clkops_generic, /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("uart1_ck", &omap1_clk_full_ops, 0),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 9,
};
staticstruct omap1_clk uart2_7xx = {
.ops = &clkops_generic, /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("uart2_ck", &omap1_clk_full_ops, 0),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 11,
};
staticstruct omap1_clk mclk_1510 = {
.ops = &clkops_generic, /* Direct from ULPD, no parent. May be enabled by ext hardware. */
.hw.init = CLK_HW_INIT_NO_PARENT("mclk", &omap1_clk_full_ops, 0),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
};
staticstruct omap1_clk mclk_16xx = {
.ops = &clkops_generic, /* Direct from ULPD, no parent. May be enabled by ext hardware. */
.hw.init = CLK_HW_INIT_NO_PARENT("mclk", &omap1_clk_full_ops, 0),
.enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
.enable_bit = COM_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate,
.round_rate = &omap1_round_ext_clk_rate,
.init = &omap1_init_ext_clk,
};
staticstruct omap1_clk bclk_1510 = { /* Direct from ULPD, no parent. May be enabled by ext hardware. */
.hw.init = CLK_HW_INIT_NO_PARENT("bclk", &omap1_clk_rate_ops, 0),
.rate = 12000000,
};
staticstruct omap1_clk bclk_16xx = {
.ops = &clkops_generic, /* Direct from ULPD, no parent. May be enabled by ext hardware. */
.hw.init = CLK_HW_INIT_NO_PARENT("bclk", &omap1_clk_full_ops, 0),
.enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
.enable_bit = SWD_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate,
.round_rate = &omap1_round_ext_clk_rate,
.init = &omap1_init_ext_clk,
};
staticstruct omap1_clk virtual_ck_mpu = { /* Is smarter alias for arm_ck */
.hw.init = CLK_HW_INIT("mpu", "arm_ck", &omap1_clk_rate_ops, 0),
.recalc = &followparent_recalc,
.set_rate = &omap1_select_table_rate,
.round_rate = &omap1_round_to_table_rate,
};
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
remains active during MPU idle whenever this is enabled */ staticstruct omap1_clk i2c_fck = {
.hw.init = CLK_HW_INIT("i2c_fck", "armxor_ck", &omap1_clk_gate_ops, 0),
.flags = CLOCK_NO_IDLE_PARENT,
};
int __init omap1_clk_init(void)
{ struct omap_clk *c;
u32 reg;
#ifdef CONFIG_DEBUG_LL /* Make sure UART clocks are enabled early */ if (cpu_is_omap16xx())
omap_writel(omap_readl(MOD_CONF_CTRL_0) |
CONF_MOD_UART1_CLK_MODE_R |
CONF_MOD_UART3_CLK_MODE_R, MOD_CONF_CTRL_0); #endif
/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
reg = omap_readw(SOFT_REQ_REG) & (1 << 4);
omap_writew(reg, SOFT_REQ_REG); if (!cpu_is_omap15xx())
omap_writew(0, SOFT_REQ_REG2);
/* By default all idlect1 clocks are allowed to idle */
arm_idlect1_mask = ~0;
cpu_mask = 0; if (cpu_is_omap1710())
cpu_mask |= CK_1710; if (cpu_is_omap16xx())
cpu_mask |= CK_16XX; if (cpu_is_omap1510())
cpu_mask |= CK_1510; if (cpu_is_omap310())
cpu_mask |= CK_310;
/* Pointers to these clocks are needed by code in clock.c */
api_ck_p = &api_ck.clk;
ck_dpll1_p = &ck_dpll1;
ck_ref_p = &ck_ref;
/* We want to be in synchronous scalable mode */
omap_writew(0x1000, ARM_SYSST);
/* * Initially use the values set by bootloader. Determine PLL rate and * recalculate dependent clocks as if kernel had changed PLL or * divisors. See also omap1_clk_late_init() that can reprogram dpll1 * after the SRAM is initialized.
*/
{ unsigned pll_ctl_val = omap_readw(DPLL_CTL);
/* Amstrad Delta wants BCLK high when inactive */ if (machine_is_ams_delta())
omap_writel(omap_readl(ULPD_CLOCK_CTRL) |
(1 << SDW_MCLK_INV_BIT),
ULPD_CLOCK_CTRL);
/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
/* Put DSP/MPUI into reset until needed */
omap_writew(0, ARM_RSTCT1);
omap_writew(1, ARM_RSTCT2);
omap_writew(0x400, ARM_IDLECT1);
/* * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8) * of the ARM_IDLECT2 register must be set to zero. The power-on * default value of this bit is one.
*/
omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) { if (!(c->cpu & cpu_mask)) continue;
if (c->lk.clk_hw->init) { /* NULL if provider already registered */ conststruct clk_init_data *init = c->lk.clk_hw->init; constchar *name = c->lk.clk_hw->init->name; int err;
err = clk_hw_register(NULL, c->lk.clk_hw); if (err < 0) {
pr_err("failed to register clock \"%s\"! (%d)\n", name, err); /* may be tried again, restore init data */
c->lk.clk_hw->init = init; continue;
}
}
/* Find the highest supported frequency and enable it */ if (omap1_select_table_rate(&virtual_ck_mpu, ~0, arm_ck.rate)) {
pr_err("System frequencies not set, using default. Check your config.\n"); /* * Reprogramming the DPLL is tricky, it must be done from SRAM.
*/
omap_sram_reprogram_clock(0x2290, 0x0005);
ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE;
}
propagate_rate(&ck_dpll1);
omap1_show_rates();
loops_per_jiffy = cpufreq_scale(loops_per_jiffy, rate, ck_dpll1.rate);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.