^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * OMAP2/3 interface clock control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011 Nokia Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Paul Walmsley
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk/ti.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "clock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define OMAP24XX_CM_FCLKEN2 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define CM_AUTOIDLE 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define CM_ICLKEN 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define CM_IDLEST 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define OMAP24XX_CM_IDLEST_VAL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Private functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* XXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct clk_omap_reg r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) memcpy(&r, &clk->enable_reg, sizeof(r));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) r.offset ^= (CM_AUTOIDLE ^ CM_ICLKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) v = ti_clk_ll_ops->clk_readl(&r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) v |= (1 << clk->enable_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ti_clk_ll_ops->clk_writel(v, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* XXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct clk_omap_reg r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) memcpy(&r, &clk->enable_reg, sizeof(r));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) r.offset ^= (CM_AUTOIDLE ^ CM_ICLKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) v = ti_clk_ll_ops->clk_readl(&r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) v &= ~(1 << clk->enable_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ti_clk_ll_ops->clk_writel(v, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @clk: struct clk * being enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * passes back the correct CM_IDLEST register address for I2CHS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * modules. No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static void omap2430_clk_i2chs_find_idlest(struct clk_hw_omap *clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct clk_omap_reg *idlest_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u8 *idlest_bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u8 *idlest_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) idlest_reg->offset ^= (OMAP24XX_CM_FCLKEN2 ^ CM_IDLEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *idlest_bit = clk->enable_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *idlest_val = OMAP24XX_CM_IDLEST_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Public data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) const struct clk_hw_omap_ops clkhwops_iclk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .allow_idle = omap2_clkt_iclk_allow_idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .deny_idle = omap2_clkt_iclk_deny_idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) const struct clk_hw_omap_ops clkhwops_iclk_wait = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .allow_idle = omap2_clkt_iclk_allow_idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .deny_idle = omap2_clkt_iclk_deny_idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .find_idlest = omap2_clk_dflt_find_idlest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .find_companion = omap2_clk_dflt_find_companion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* 2430 I2CHS has non-standard IDLEST register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .find_idlest = omap2430_clk_i2chs_find_idlest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .find_companion = omap2_clk_dflt_find_companion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };