Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
0004  */
0005 
0006 #include <linux/clk-provider.h>
0007 #include <linux/clk/sunxi-ng.h>
0008 #include <linux/io.h>
0009 
0010 #include "ccu_common.h"
0011 
0012 /**
0013  * sunxi_ccu_set_mmc_timing_mode: Configure the MMC clock timing mode
0014  * @clk: clock to be configured
0015  * @new_mode: true for new timing mode introduced in A83T and later
0016  *
0017  * Returns 0 on success, -ENOTSUPP if the clock does not support
0018  * switching modes.
0019  */
0020 int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode)
0021 {
0022     struct clk_hw *hw = __clk_get_hw(clk);
0023     struct ccu_common *cm = hw_to_ccu_common(hw);
0024     unsigned long flags;
0025     u32 val;
0026 
0027     if (!(cm->features & CCU_FEATURE_MMC_TIMING_SWITCH))
0028         return -ENOTSUPP;
0029 
0030     spin_lock_irqsave(cm->lock, flags);
0031 
0032     val = readl(cm->base + cm->reg);
0033     if (new_mode)
0034         val |= CCU_MMC_NEW_TIMING_MODE;
0035     else
0036         val &= ~CCU_MMC_NEW_TIMING_MODE;
0037     writel(val, cm->base + cm->reg);
0038 
0039     spin_unlock_irqrestore(cm->lock, flags);
0040 
0041     return 0;
0042 }
0043 EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode);
0044 
0045 /**
0046  * sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode
0047  * @clk: clock to query
0048  *
0049  * Returns 0 if the clock is in old timing mode, > 0 if it is in
0050  * new timing mode, and -ENOTSUPP if the clock does not support
0051  * this function.
0052  */
0053 int sunxi_ccu_get_mmc_timing_mode(struct clk *clk)
0054 {
0055     struct clk_hw *hw = __clk_get_hw(clk);
0056     struct ccu_common *cm = hw_to_ccu_common(hw);
0057 
0058     if (!(cm->features & CCU_FEATURE_MMC_TIMING_SWITCH))
0059         return -ENOTSUPP;
0060 
0061     return !!(readl(cm->base + cm->reg) & CCU_MMC_NEW_TIMING_MODE);
0062 }
0063 EXPORT_SYMBOL_GPL(sunxi_ccu_get_mmc_timing_mode);