Skip to content

Commit

Permalink
Merge tag 'mmc-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/ulfh/mmc

Pull MMC updates from Ulf Hansson:
 "MMC core:
   - Continue to refactor the mmc block code to prepare for blkmq
   - Move mmc block debugfs into block module
   - Next step for eMMC CMDQ by adding a new mmc host interface for it
   - Move Kconfig option MMC_DEBUG from core to host
   - Some additional minor improvements

  MMC host:
   - Declare structs as const when applicable
   - Explicitly request exclusive reset control when applicable
   - Improve some error paths and other various cleanups
   - sdhci: Preparations to support SDHCI OMAP
   - sdhci: Improve some PM related code
   - sdhci: Re-factoring and modernizations
   - sdhci-xenon: Add runtime PM and system sleep support
   - sdhci-xenon: Add support for eMMC HS400 Enhanced Strobe
   - sdhci-cadence: Add system sleep support
   - sdhci-of-at91: Improve system sleep support
   - dw_mmc: Add support for Hisilicon hi3660
   - sunxi: Add support for A83T eMMC
   - sunxi: Add support for DDR52 mode
   - meson-gx: Add support for UHS-I SD-cards
   - meson-gx: Cleanups and improvements
   - tmio: Fix CMD12 (STOP) handling
   - tmio: Cleanups and improvements
   - renesas_sdhi: Add r8a7743/5 support
   - renesas-sdhi: Add support for R-Car Gen3 SDHI DMAC
   - renesas_sdhi: Cleanups and improvements"

* tag 'mmc-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (145 commits)
  mmc: renesas_sdhi: Add r8a7743/5 support
  mmc: meson-gx: fix __ffsdi2 undefined on arm32
  mmc: sdhci-xenon: add runtime pm support and reimplement standby
  mmc: core: Move mmc_start_areq() declaration
  mmc: mmci: stop building qcom dml as module
  mmc: sunxi: Reset the device at probe time
  clk: sunxi-ng: Provide a default reset hook
  mmc: meson-gx: rework tuning function
  mmc: meson-gx: change default tx phase
  mmc: meson-gx: implement voltage switch callback
  mmc: meson-gx: use CCF to handle the clock phases
  mmc: meson-gx: implement card_busy callback
  mmc: meson-gx: simplify interrupt handler
  mmc: meson-gx: work around clk-stop issue
  mmc: meson-gx: fix dual data rate mode frequencies
  mmc: meson-gx: rework clock init function
  mmc: meson-gx: rework clk_set function
  mmc: meson-gx: rework set_ios function
  mmc: meson-gx: cfg init overwrite values
  mmc: meson-gx: initialize sane clk default before clock register
  ...
  • Loading branch information
torvalds committed Sep 7, 2017
2 parents a0725ab + c16a854 commit 15d8ffc
Show file tree
Hide file tree
Showing 91 changed files with 2,559 additions and 997 deletions.
4 changes: 3 additions & 1 deletion Documentation/devicetree/bindings/mmc/renesas,mmcif.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Required properties:
- "renesas,mmcif-r7s72100" for the MMCIF found in r7s72100 SoCs
- "renesas,mmcif-r8a73a4" for the MMCIF found in r8a73a4 SoCs
- "renesas,mmcif-r8a7740" for the MMCIF found in r8a7740 SoCs
- "renesas,mmcif-r8a7743" for the MMCIF found in r8a7743 SoCs
- "renesas,mmcif-r8a7745" for the MMCIF found in r8a7745 SoCs
- "renesas,mmcif-r8a7778" for the MMCIF found in r8a7778 SoCs
- "renesas,mmcif-r8a7790" for the MMCIF found in r8a7790 SoCs
- "renesas,mmcif-r8a7791" for the MMCIF found in r8a7791 SoCs
Expand All @@ -21,7 +23,7 @@ Required properties:
- interrupts: Some SoCs have only 1 shared interrupt, while others have either
2 or 3 individual interrupts (error, int, card detect). Below is the number
of interrupts for each SoC:
1: r8a73a4, r8a7778, r8a7790, r8a7791, r8a7793, r8a7794
1: r8a73a4, r8a7743, r8a7745, r8a7778, r8a7790, r8a7791, r8a7793, r8a7794
2: r8a7740, sh73a0
3: r7s72100

Expand Down
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Required Properties:
- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
- "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RV1108
- "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036
- "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK322x
- "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3328
- "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368
- "rockchip,rk3399-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3399
Expand Down
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Required properties:
* "allwinner,sun4i-a10-mmc"
* "allwinner,sun5i-a13-mmc"
* "allwinner,sun7i-a20-mmc"
* "allwinner,sun8i-a83t-emmc"
* "allwinner,sun9i-a80-mmc"
* "allwinner,sun50i-a64-emmc"
* "allwinner,sun50i-a64-mmc"
Expand Down
8 changes: 4 additions & 4 deletions Documentation/devicetree/bindings/mmc/tmio_mmc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Required properties:
"renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC
"renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC
"renesas,sdhi-r8a7740" - SDHI IP on R8A7740 SoC
"renesas,sdhi-r8a7743" - SDHI IP on R8A7743 SoC
"renesas,sdhi-r8a7745" - SDHI IP on R8A7745 SoC
"renesas,sdhi-r8a7778" - SDHI IP on R8A7778 SoC
"renesas,sdhi-r8a7779" - SDHI IP on R8A7779 SoC
"renesas,sdhi-r8a7790" - SDHI IP on R8A7790 SoC
Expand All @@ -33,10 +35,8 @@ Required properties:
If 2 clocks are specified by the hardware, you must name them as
"core" and "cd". If the controller only has 1 clock, naming is not
required.
Below is the number clocks for each supported SoC:
1: SH73A0, R8A73A4, R8A7740, R8A7778, R8A7779, R8A7790
R8A7791, R8A7792, R8A7793, R8A7794, R8A7795, R8A7796
2: R7S72100
Devices which have more than 1 clock are listed below:
2: R7S72100

Optional properties:
- toshiba,mmc-wrprotect-disable: write-protect detection is unavailable
Expand Down
1 change: 0 additions & 1 deletion arch/arc/boot/dts/axs10x_mb.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@
mmc@0x15000 {
compatible = "altr,socfpga-dw-mshc";
reg = < 0x15000 0x400 >;
num-slots = < 1 >;
fifo-depth = < 16 >;
card-detect-delay = < 200 >;
clocks = <&apbclk>, <&mmcclk>;
Expand Down
1 change: 0 additions & 1 deletion arch/arc/boot/dts/vdk_axs10x_mb.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
mmc@0x15000 {
compatible = "snps,dw-mshc";
reg = <0x15000 0x400>;
num-slots = <1>;
fifo-depth = <1024>;
card-detect-delay = <200>;
clocks = <&apbclk>, <&mmcclk>;
Expand Down
1 change: 1 addition & 0 deletions drivers/clk/sunxi-ng/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Common objects
lib-$(CONFIG_SUNXI_CCU) += ccu_common.o
lib-$(CONFIG_SUNXI_CCU) += ccu_mmc_timing.o
lib-$(CONFIG_SUNXI_CCU) += ccu_reset.o

# Base clock types
Expand Down
10 changes: 2 additions & 8 deletions drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,14 +418,8 @@ static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1-sample", "mmc1",
static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1-output", "mmc1",
0x08c, 8, 3, 0);

/* TODO Support MMC2 clock's new timing mode. */
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
0x090,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_MMC_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
0x090, 0);

static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2-sample", "mmc2",
0x090, 20, 3, 0);
Expand Down
4 changes: 4 additions & 0 deletions drivers/clk/sunxi-ng/ccu_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#define CCU_FEATURE_FIXED_POSTDIV BIT(3)
#define CCU_FEATURE_ALL_PREDIV BIT(4)
#define CCU_FEATURE_LOCK_REG BIT(5)
#define CCU_FEATURE_MMC_TIMING_SWITCH BIT(6)

/* MMC timing mode switch bit */
#define CCU_MMC_NEW_TIMING_MODE BIT(30)

struct device_node;

Expand Down
70 changes: 70 additions & 0 deletions drivers/clk/sunxi-ng/ccu_mmc_timing.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/clk-provider.h>
#include <linux/clk/sunxi-ng.h>

#include "ccu_common.h"

/**
* sunxi_ccu_set_mmc_timing_mode: Configure the MMC clock timing mode
* @clk: clock to be configured
* @new_mode: true for new timing mode introduced in A83T and later
*
* Returns 0 on success, -ENOTSUPP if the clock does not support
* switching modes.
*/
int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode)
{
struct clk_hw *hw = __clk_get_hw(clk);
struct ccu_common *cm = hw_to_ccu_common(hw);
unsigned long flags;
u32 val;

if (!(cm->features & CCU_FEATURE_MMC_TIMING_SWITCH))
return -ENOTSUPP;

spin_lock_irqsave(cm->lock, flags);

val = readl(cm->base + cm->reg);
if (new_mode)
val |= CCU_MMC_NEW_TIMING_MODE;
else
val &= ~CCU_MMC_NEW_TIMING_MODE;
writel(val, cm->base + cm->reg);

spin_unlock_irqrestore(cm->lock, flags);

return 0;
}
EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode);

/**
* sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode
* @clk: clock to query
*
* Returns 0 if the clock is in old timing mode, > 0 if it is in
* new timing mode, and -ENOTSUPP if the clock does not support
* this function.
*/
int sunxi_ccu_get_mmc_timing_mode(struct clk *clk)
{
struct clk_hw *hw = __clk_get_hw(clk);
struct ccu_common *cm = hw_to_ccu_common(hw);

if (!(cm->features & CCU_FEATURE_MMC_TIMING_SWITCH))
return -ENOTSUPP;

return !!(readl(cm->base + cm->reg) & CCU_MMC_NEW_TIMING_MODE);
}
EXPORT_SYMBOL_GPL(sunxi_ccu_get_mmc_timing_mode);
80 changes: 80 additions & 0 deletions drivers/clk/sunxi-ng/ccu_mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,83 @@ const struct clk_ops ccu_mp_ops = {
.recalc_rate = ccu_mp_recalc_rate,
.set_rate = ccu_mp_set_rate,
};

/*
* Support for MMC timing mode switching
*
* The MMC clocks on some SoCs support switching between old and
* new timing modes. A platform specific API is provided to query
* and set the timing mode on supported SoCs.
*
* In addition, a special class of ccu_mp_ops is provided, which
* takes in to account the timing mode switch. When the new timing
* mode is active, the clock output rate is halved. This new class
* is a wrapper around the generic ccu_mp_ops. When clock rates
* are passed through to ccu_mp_ops callbacks, they are doubled
* if the new timing mode bit is set, to account for the post
* divider. Conversely, when clock rates are passed back, they
* are halved if the mode bit is set.
*/

static unsigned long ccu_mp_mmc_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
unsigned long rate = ccu_mp_recalc_rate(hw, parent_rate);
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val = readl(cm->base + cm->reg);

if (val & CCU_MMC_NEW_TIMING_MODE)
return rate / 2;
return rate;
}

static int ccu_mp_mmc_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val = readl(cm->base + cm->reg);
int ret;

/* adjust the requested clock rate */
if (val & CCU_MMC_NEW_TIMING_MODE) {
req->rate *= 2;
req->min_rate *= 2;
req->max_rate *= 2;
}

ret = ccu_mp_determine_rate(hw, req);

/* re-adjust the requested clock rate back */
if (val & CCU_MMC_NEW_TIMING_MODE) {
req->rate /= 2;
req->min_rate /= 2;
req->max_rate /= 2;
}

return ret;
}

static int ccu_mp_mmc_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val = readl(cm->base + cm->reg);

if (val & CCU_MMC_NEW_TIMING_MODE)
rate *= 2;

return ccu_mp_set_rate(hw, rate, parent_rate);
}

const struct clk_ops ccu_mp_mmc_ops = {
.disable = ccu_mp_disable,
.enable = ccu_mp_enable,
.is_enabled = ccu_mp_is_enabled,

.get_parent = ccu_mp_get_parent,
.set_parent = ccu_mp_set_parent,

.determine_rate = ccu_mp_mmc_determine_rate,
.recalc_rate = ccu_mp_mmc_recalc_rate,
.set_rate = ccu_mp_mmc_set_rate,
};
30 changes: 30 additions & 0 deletions drivers/clk/sunxi-ng/ccu_mp.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#ifndef _CCU_MP_H_
#define _CCU_MP_H_

#include <linux/bitops.h>
#include <linux/clk-provider.h>

#include "ccu_common.h"
Expand Down Expand Up @@ -74,4 +75,33 @@ static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw)

extern const struct clk_ops ccu_mp_ops;

/*
* Special class of M-P clock that supports MMC timing modes
*
* Since the MMC clock registers all follow the same layout, we can
* simplify the macro for this particular case. In addition, as
* switching modes also affects the output clock rate, we need to
* have CLK_GET_RATE_NOCACHE for all these types of clocks.
*/

#define SUNXI_CCU_MP_MMC_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
_flags) \
struct ccu_mp _struct = { \
.enable = BIT(31), \
.m = _SUNXI_CCU_DIV(0, 4), \
.p = _SUNXI_CCU_DIV(16, 2), \
.mux = _SUNXI_CCU_MUX(24, 2), \
.common = { \
.reg = _reg, \
.features = CCU_FEATURE_MMC_TIMING_SWITCH, \
.hw.init = CLK_HW_INIT_PARENTS(_name, \
_parents, \
&ccu_mp_mmc_ops, \
CLK_GET_RATE_NOCACHE | \
_flags), \
} \
}

extern const struct clk_ops ccu_mp_mmc_ops;

#endif /* _CCU_MP_H_ */
12 changes: 12 additions & 0 deletions drivers/clk/sunxi-ng/ccu_reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* the License, or (at your option) any later version.
*/

#include <linux/delay.h>
#include <linux/io.h>
#include <linux/reset-controller.h>

Expand Down Expand Up @@ -49,7 +50,18 @@ static int ccu_reset_deassert(struct reset_controller_dev *rcdev,
return 0;
}

static int ccu_reset_reset(struct reset_controller_dev *rcdev,
unsigned long id)
{
ccu_reset_assert(rcdev, id);
udelay(10);
ccu_reset_deassert(rcdev, id);

return 0;
}

const struct reset_control_ops ccu_reset_ops = {
.assert = ccu_reset_assert,
.deassert = ccu_reset_deassert,
.reset = ccu_reset_reset,
};
7 changes: 0 additions & 7 deletions drivers/mmc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@ menuconfig MMC
If you want MMC/SD/SDIO support, you should say Y here and
also to your specific host controller driver.

config MMC_DEBUG
bool "MMC debugging"
depends on MMC != n
help
This is an option for use by developers; most people should
say N here. This enables MMC core and driver debugging.

if MMC

source "drivers/mmc/core/Kconfig"
Expand Down
2 changes: 0 additions & 2 deletions drivers/mmc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@
# Makefile for the kernel mmc device drivers.
#

subdir-ccflags-$(CONFIG_MMC_DEBUG) := -DDEBUG

obj-$(CONFIG_MMC) += core/
obj-$(subst m,y,$(CONFIG_MMC)) += host/
Loading

0 comments on commit 15d8ffc

Please sign in to comment.