19c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2f6f64ed8SChen-Yu Tsai /* 3f6f64ed8SChen-Yu Tsai * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved. 4f6f64ed8SChen-Yu Tsai */ 5f6f64ed8SChen-Yu Tsai 6f6f64ed8SChen-Yu Tsai #include <linux/clk-provider.h> 7f6f64ed8SChen-Yu Tsai #include <linux/clk/sunxi-ng.h> 862e59c4eSStephen Boyd #include <linux/io.h> 9f6f64ed8SChen-Yu Tsai 10f6f64ed8SChen-Yu Tsai #include "ccu_common.h" 11f6f64ed8SChen-Yu Tsai 12f6f64ed8SChen-Yu Tsai /** 135dc64702SRandy Dunlap * sunxi_ccu_set_mmc_timing_mode - Configure the MMC clock timing mode 14f6f64ed8SChen-Yu Tsai * @clk: clock to be configured 15f6f64ed8SChen-Yu Tsai * @new_mode: true for new timing mode introduced in A83T and later 16f6f64ed8SChen-Yu Tsai * 175dc64702SRandy Dunlap * Return: %0 on success, %-ENOTSUPP if the clock does not support 18f6f64ed8SChen-Yu Tsai * switching modes. 19f6f64ed8SChen-Yu Tsai */ sunxi_ccu_set_mmc_timing_mode(struct clk * clk,bool new_mode)20f6f64ed8SChen-Yu Tsaiint sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode) 21f6f64ed8SChen-Yu Tsai { 22f6f64ed8SChen-Yu Tsai struct clk_hw *hw = __clk_get_hw(clk); 23f6f64ed8SChen-Yu Tsai struct ccu_common *cm = hw_to_ccu_common(hw); 24f6f64ed8SChen-Yu Tsai unsigned long flags; 25f6f64ed8SChen-Yu Tsai u32 val; 26f6f64ed8SChen-Yu Tsai 27f6f64ed8SChen-Yu Tsai if (!(cm->features & CCU_FEATURE_MMC_TIMING_SWITCH)) 28f6f64ed8SChen-Yu Tsai return -ENOTSUPP; 29f6f64ed8SChen-Yu Tsai 30f6f64ed8SChen-Yu Tsai spin_lock_irqsave(cm->lock, flags); 31f6f64ed8SChen-Yu Tsai 32f6f64ed8SChen-Yu Tsai val = readl(cm->base + cm->reg); 33f6f64ed8SChen-Yu Tsai if (new_mode) 34f6f64ed8SChen-Yu Tsai val |= CCU_MMC_NEW_TIMING_MODE; 35f6f64ed8SChen-Yu Tsai else 36f6f64ed8SChen-Yu Tsai val &= ~CCU_MMC_NEW_TIMING_MODE; 37f6f64ed8SChen-Yu Tsai writel(val, cm->base + cm->reg); 38f6f64ed8SChen-Yu Tsai 39f6f64ed8SChen-Yu Tsai spin_unlock_irqrestore(cm->lock, flags); 40f6f64ed8SChen-Yu Tsai 41f6f64ed8SChen-Yu Tsai return 0; 42f6f64ed8SChen-Yu Tsai } 43f6f64ed8SChen-Yu Tsai EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode); 44f6f64ed8SChen-Yu Tsai 45f6f64ed8SChen-Yu Tsai /** 46*075d9ca5SZhang Jianhua * sunxi_ccu_get_mmc_timing_mode: Get the current MMC clock timing mode 47f6f64ed8SChen-Yu Tsai * @clk: clock to query 48f6f64ed8SChen-Yu Tsai * 495dc64702SRandy Dunlap * Return: %0 if the clock is in old timing mode, > %0 if it is in 505dc64702SRandy Dunlap * new timing mode, and %-ENOTSUPP if the clock does not support 51f6f64ed8SChen-Yu Tsai * this function. 52f6f64ed8SChen-Yu Tsai */ sunxi_ccu_get_mmc_timing_mode(struct clk * clk)53f6f64ed8SChen-Yu Tsaiint sunxi_ccu_get_mmc_timing_mode(struct clk *clk) 54f6f64ed8SChen-Yu Tsai { 55f6f64ed8SChen-Yu Tsai struct clk_hw *hw = __clk_get_hw(clk); 56f6f64ed8SChen-Yu Tsai struct ccu_common *cm = hw_to_ccu_common(hw); 57f6f64ed8SChen-Yu Tsai 58f6f64ed8SChen-Yu Tsai if (!(cm->features & CCU_FEATURE_MMC_TIMING_SWITCH)) 59f6f64ed8SChen-Yu Tsai return -ENOTSUPP; 60f6f64ed8SChen-Yu Tsai 61f6f64ed8SChen-Yu Tsai return !!(readl(cm->base + cm->reg) & CCU_MMC_NEW_TIMING_MODE); 62f6f64ed8SChen-Yu Tsai } 63f6f64ed8SChen-Yu Tsai EXPORT_SYMBOL_GPL(sunxi_ccu_get_mmc_timing_mode); 64