Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1426898 > unrolled thread
| Started by | Douglas Anderson <dianders@chromium.org> |
|---|---|
| First post | 2016-06-20 20:10 +0200 |
| Last post | 2016-06-22 17:30 +0200 |
| Articles | 20 on this page of 21 — 6 participants |
Back to article view | Back to linux.kernel
[PATCH v3 0/15] Changes to support 150 MHz eMMC on rk3399 Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:10 +0200
[PATCH v3 06/15] mmc: sdhci-of-arasan: Always power the PHY off/on when clock changes Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:10 +0200
Re: [PATCH v3 06/15] mmc: sdhci-of-arasan: Always power the PHY off/on when clock changes Adrian Hunter <adrian.hunter@intel.com> - 2016-06-22 14:40 +0200
[PATCH v3 08/15] mmc: sdhci-of-arasan: Properly set corecfg_baseclkfreq on rk3399 Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:20 +0200
Re: [PATCH v3 08/15] mmc: sdhci-of-arasan: Properly set corecfg_baseclkfreq on rk3399 Adrian Hunter <adrian.hunter@intel.com> - 2016-06-22 14:40 +0200
Re: [PATCH v3 0/15] Changes to support 150 MHz eMMC on rk3399 Heiko Stübner <heiko@sntech.de> - 2016-06-20 20:20 +0200
[PATCH v3 14/15] phy: rockchip-emmc: Set phyctrl_frqsel based on card clock Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:20 +0200
Re: [PATCH v3 14/15] phy: rockchip-emmc: Set phyctrl_frqsel based on card clock Heiko Stübner <heiko@sntech.de> - 2016-06-20 20:20 +0200
[PATCH v3 09/15] arm64: dts: rockchip: Add soc-ctl-syscon to sdhci for rk3399 Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:30 +0200
Re: [PATCH v3 09/15] arm64: dts: rockchip: Add soc-ctl-syscon to sdhci for rk3399 Heiko Stübner <heiko@sntech.de> - 2016-06-22 18:40 +0200
[PATCH v3 13/15] phy: rockchip-emmc: Minor code cleanup in rockchip_emmc_phy_power_on/off() Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:40 +0200
[PATCH v3 10/15] Documentation: mmc: sdhci-of-arasan: Add ability to export card clock Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:40 +0200
[PATCH v3 02/15] phy: rockchip-emmc: configure frequency range and drive impedance Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:40 +0200
[PATCH v3 04/15] phy: rockchip-emmc: reindent the register definitions Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:40 +0200
[PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready Douglas Anderson <dianders@chromium.org> - 2016-06-20 20:40 +0200
Re: [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready Guenter Roeck <groeck@google.com> - 2016-06-20 21:30 +0200
Re: [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready Doug Anderson <dianders@chromium.org> - 2016-06-20 21:40 +0200
Re: [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready Doug Anderson <dianders@chromium.org> - 2016-06-20 21:40 +0200
Re: [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready Guenter Roeck <groeck@google.com> - 2016-06-20 21:50 +0200
[PATCH v3 07/15] Documentation: mmc: sdhci-of-arasan: Add soc-ctl-syscon for corecfg regs Douglas Anderson <dianders@chromium.org> - 2016-06-20 22:00 +0200
Re: [PATCH v3 0/15] Changes to support 150 MHz eMMC on rk3399 Ulf Hansson <ulf.hansson@linaro.org> - 2016-06-22 17:30 +0200
Page 1 of 2 [1] 2 Next page →
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:10 +0200 |
| Subject | [PATCH v3 0/15] Changes to support 150 MHz eMMC on rk3399 |
| Message-ID | <rMbO2-3aM-21@gated-at.bofh.it> |
The theme of this series of patches is to try to allow running the eMMC
at 150 MHz on the rk3399 SoC, though the changes should still be correct
and have merit on their own. The motivation for running at 150 MHz is
that doing so improves signal integrity and (with some eMMC devices)
doesn't affect throughput.
These patches have been structured to keep things as separate as
possible, but nevertheless there are still some dependencies between
patches. It probably makes the most sense for all of the non-device
tree patches to go through a single tree. PHY patches now have Acks
from Kishon so that means things should be clear for all non-DTS patches
to go through the MMC tree if Ulf agrees. Device tree patches should be
able to be landed separately and the worst what would happen is a
warning in the kernel log if you have the code without the device tree.
The code patches are based on Ulf's mmc-next. In v3 of the series I've
pulled in the latest version of a previous PHY series posted by Brian
Norris.
The device tree patches are based on Heiko's v4.8-armsoc/dts64.
Changes in v3:
- Add Brian's PHY patches into my series
- Add collected tags
- Add dependency on COMMON_CLK (actually in v2.1) (Guenter Roeck)
- Use phy_init / phy_exit (Heiko)
- Add Kishon's Ack
Changes in v2:
- Drop 170 MHz comment (only applicable to a subtly different Arasan PHY)
- Indicate that 5.1 ms is calculated (Shawn).
- Clean up description of rk3399 PHY (Shawn)
- Add Rob Herring's Ack.
- Reorder includes (Shawn)
- Adjust commit message wording (Rob)
- List out clocks and clock names (Rob)
- Move code cleanup before set phyctrl_frqsel based on card clock (Shawn)
- Warn if we're more than 15 MHz from ideal rate (Shawn)
- Fix typo USB => SDHCI (Shawn)
Brian Norris (2):
phy: rockchip-emmc: configure default output tap delay
phy: rockchip-emmc: reindent the register definitions
Douglas Anderson (11):
phy: rockchip-emmc: Increase lock time allowance
mmc: sdhci-of-arasan: Always power the PHY off/on when clock changes
Documentation: mmc: sdhci-of-arasan: Add soc-ctl-syscon for corecfg
regs
mmc: sdhci-of-arasan: Properly set corecfg_baseclkfreq on rk3399
arm64: dts: rockchip: Add soc-ctl-syscon to sdhci for rk3399
Documentation: mmc: sdhci-of-arasan: Add ability to export card clock
mmc: sdhci-of-arasan: Add ability to export card clock
Documentation: phy: Let the rockchip eMMC PHY get an exported card
clock
phy: rockchip-emmc: Minor code cleanup in
rockchip_emmc_phy_power_on/off()
phy: rockchip-emmc: Set phyctrl_frqsel based on card clock
arm64: dts: rockchip: Provide emmcclk to PHY for rk3399
Shawn Lin (2):
phy: rockchip-emmc: give DLL some extra time to be ready
phy: rockchip-emmc: configure frequency range and drive impedance
.../devicetree/bindings/mmc/arasan,sdhci.txt | 35 ++-
.../devicetree/bindings/phy/rockchip-emmc-phy.txt | 9 +
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 5 +
drivers/mmc/host/Kconfig | 1 +
drivers/mmc/host/sdhci-of-arasan.c | 333 +++++++++++++++++++--
drivers/phy/phy-rockchip-emmc.c | 216 ++++++++++---
6 files changed, 525 insertions(+), 74 deletions(-)
--
2.8.0.rc3.226.g39d4020
[toc] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:10 +0200 |
| Subject | [PATCH v3 06/15] mmc: sdhci-of-arasan: Always power the PHY off/on when clock changes |
| Message-ID | <rMbO2-3aM-39@gated-at.bofh.it> |
| In reply to | #1426898 |
In commit 802ac39a5566 ("mmc: sdhci-of-arasan: fix set_clock when a phy
is supported") we added code to power the PHY off and on whenever the
clock was changed but we avoided doing the power cycle code when the
clock was low speed. Let's now do it always.
Although there may be other reasons for power cycling the PHY when the
clock changes, one of the main reasons is that we need to give the DLL a
chance to re-lock with the new clock.
One of the things that the DLL is for is tuning the Receive Clock in
HS200 mode and STRB in HS400 mode. Thus it is clear that we should make
sure we power cycle the PHY (and wait for the DLL to lock) when we know
we'll be in one of these two speed modes. That's what the original code
did, though it used the clock rate rather than the speed mode. However,
even in speed modes other than HS200,/HS400 the DLL is used for
something since it can be clearly observed that the PHY doesn't function
properly if you leave the DLL off.
Although it appears less important to power cycle the PHY and wait for
the DLL to lock when not in HS200/HS400 modes (no bugs were reported),
it still seems wise to let the locking always happen nevertheless.
Note: as part of this, we make sure that we never try to turn the PHY on
when the clock is off (when the clock rate is 0). The PHY cannot work
when the clock is off since its DLL can't lock.
This change requires ("phy: rockchip-emmc: Increase lock time
allowance") and will cause problems if picked without that change.
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
Changes in v3:
- Add collected tags
Changes in v2: None
drivers/mmc/host/sdhci-of-arasan.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 533e2bcb10bc..3ff1711077c2 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -35,11 +35,13 @@
/**
* struct sdhci_arasan_data
* @clk_ahb: Pointer to the AHB clock
- * @phy: Pointer to the generic phy
+ * @phy: Pointer to the generic phy
+ * @phy_on: True if the PHY is turned on.
*/
struct sdhci_arasan_data {
struct clk *clk_ahb;
struct phy *phy;
+ bool phy_on;
};
static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
@@ -61,12 +63,10 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
- bool ctrl_phy = false;
- if (clock > MMC_HIGH_52_MAX_DTR && (!IS_ERR(sdhci_arasan->phy)))
- ctrl_phy = true;
+ if (sdhci_arasan->phy_on && !IS_ERR(sdhci_arasan->phy)) {
+ sdhci_arasan->phy_on = false;
- if (ctrl_phy) {
spin_unlock_irq(&host->lock);
phy_power_off(sdhci_arasan->phy);
spin_lock_irq(&host->lock);
@@ -74,7 +74,9 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock)
sdhci_set_clock(host, clock);
- if (ctrl_phy) {
+ if (host->mmc->actual_clock && !IS_ERR(sdhci_arasan->phy)) {
+ sdhci_arasan->phy_on = true;
+
spin_unlock_irq(&host->lock);
phy_power_on(sdhci_arasan->phy);
spin_lock_irq(&host->lock);
@@ -257,12 +259,6 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
goto clk_disable_all;
}
- ret = phy_power_on(sdhci_arasan->phy);
- if (ret < 0) {
- dev_err(&pdev->dev, "phy_power_on err.\n");
- goto err_phy_power;
- }
-
host->mmc_host_ops.hs400_enhanced_strobe =
sdhci_arasan_hs400_enhanced_strobe;
}
@@ -275,9 +271,6 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
err_add_host:
if (!IS_ERR(sdhci_arasan->phy))
- phy_power_off(sdhci_arasan->phy);
-err_phy_power:
- if (!IS_ERR(sdhci_arasan->phy))
phy_exit(sdhci_arasan->phy);
clk_disable_all:
clk_disable_unprepare(clk_xin);
--
2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2016-06-22 14:40 +0200 |
| Subject | Re: [PATCH v3 06/15] mmc: sdhci-of-arasan: Always power the PHY off/on when clock changes |
| Message-ID | <rMPBM-3lU-15@gated-at.bofh.it> |
| In reply to | #1426899 |
On 20/06/16 20:56, Douglas Anderson wrote:
> In commit 802ac39a5566 ("mmc: sdhci-of-arasan: fix set_clock when a phy
> is supported") we added code to power the PHY off and on whenever the
> clock was changed but we avoided doing the power cycle code when the
> clock was low speed. Let's now do it always.
>
> Although there may be other reasons for power cycling the PHY when the
> clock changes, one of the main reasons is that we need to give the DLL a
> chance to re-lock with the new clock.
>
> One of the things that the DLL is for is tuning the Receive Clock in
> HS200 mode and STRB in HS400 mode. Thus it is clear that we should make
> sure we power cycle the PHY (and wait for the DLL to lock) when we know
> we'll be in one of these two speed modes. That's what the original code
> did, though it used the clock rate rather than the speed mode. However,
> even in speed modes other than HS200,/HS400 the DLL is used for
> something since it can be clearly observed that the PHY doesn't function
> properly if you leave the DLL off.
>
> Although it appears less important to power cycle the PHY and wait for
> the DLL to lock when not in HS200/HS400 modes (no bugs were reported),
> it still seems wise to let the locking always happen nevertheless.
>
> Note: as part of this, we make sure that we never try to turn the PHY on
> when the clock is off (when the clock rate is 0). The PHY cannot work
> when the clock is off since its DLL can't lock.
>
> This change requires ("phy: rockchip-emmc: Increase lock time
> allowance") and will cause problems if picked without that change.
>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
> Tested-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:20 +0200 |
| Subject | [PATCH v3 08/15] mmc: sdhci-of-arasan: Properly set corecfg_baseclkfreq on rk3399 |
| Message-ID | <rMbXH-3fW-13@gated-at.bofh.it> |
| In reply to | #1426898 |
In the the earlier change in this series ("Documentation: mmc:
sdhci-of-arasan: Add soc-ctl-syscon for corecfg regs") we can see the
mechansim for specifying a syscon to properly set corecfg registers in
sdhci-of-arasan. Now let's use this mechanism to properly set
corecfg_baseclkfreq on rk3399.
From [1] the corecfg_baseclkfreq is supposed to be set to:
Base Clock Frequency for SD Clock.
This is the frequency of the xin_clk.
This is a relatively easy thing to do. Note that we assume that xin_clk
is not dynamic and we can check the clock at probe time. If any real
devices have a dynamic xin_clk future patches could register for
notifiers for the clock.
At the moment, setting corecfg_baseclkfreq is only supported for rk3399
since we need a specific map for each implementation. The code is
written in a generic way that should make this easy to extend to other
SoCs. Note that a specific compatible string for rk3399 is already in
use and so we add that to the table to match rk3399.
[1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
Changes in v3:
- Add collected tags
Changes in v2:
- Reorder includes (Shawn)
drivers/mmc/host/sdhci-of-arasan.c | 189 ++++++++++++++++++++++++++++++++++---
1 file changed, 178 insertions(+), 11 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 3ff1711077c2..1286fe8905dc 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -19,9 +19,11 @@
* your option) any later version.
*/
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/phy/phy.h>
+#include <linux/regmap.h>
#include "sdhci-pltfm.h"
#define SDHCI_ARASAN_CLK_CTRL_OFFSET 0x2c
@@ -32,18 +34,115 @@
#define CLK_CTRL_TIMEOUT_MASK (0xf << CLK_CTRL_TIMEOUT_SHIFT)
#define CLK_CTRL_TIMEOUT_MIN_EXP 13
+/*
+ * On some SoCs the syscon area has a feature where the upper 16-bits of
+ * each 32-bit register act as a write mask for the lower 16-bits. This allows
+ * atomic updates of the register without locking. This macro is used on SoCs
+ * that have that feature.
+ */
+#define HIWORD_UPDATE(val, mask, shift) \
+ ((val) << (shift) | (mask) << ((shift) + 16))
+
+/**
+ * struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map
+ *
+ * @reg: Offset within the syscon of the register containing this field
+ * @width: Number of bits for this field
+ * @shift: Bit offset within @reg of this field (or -1 if not avail)
+ */
+struct sdhci_arasan_soc_ctl_field {
+ u32 reg;
+ u16 width;
+ s16 shift;
+};
+
+/**
+ * struct sdhci_arasan_soc_ctl_map - Map in syscon to corecfg registers
+ *
+ * It's up to the licensee of the Arsan IP block to make these available
+ * somewhere if needed. Presumably these will be scattered somewhere that's
+ * accessible via the syscon API.
+ *
+ * @baseclkfreq: Where to find corecfg_baseclkfreq
+ * @hiword_update: If true, use HIWORD_UPDATE to access the syscon
+ */
+struct sdhci_arasan_soc_ctl_map {
+ struct sdhci_arasan_soc_ctl_field baseclkfreq;
+ bool hiword_update;
+};
+
/**
* struct sdhci_arasan_data
- * @clk_ahb: Pointer to the AHB clock
- * @phy: Pointer to the generic phy
- * @phy_on: True if the PHY is turned on.
+ * @clk_ahb: Pointer to the AHB clock
+ * @phy: Pointer to the generic phy
+ * @phy_on: True if the PHY is turned on.
+ * @soc_ctl_base: Pointer to regmap for syscon for soc_ctl registers.
+ * @soc_ctl_map: Map to get offsets into soc_ctl registers.
*/
struct sdhci_arasan_data {
struct clk *clk_ahb;
struct phy *phy;
bool phy_on;
+
+ struct regmap *soc_ctl_base;
+ const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
+};
+
+static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = {
+ .baseclkfreq = { .reg = 0xf000, .width = 8, .shift = 8 },
+ .hiword_update = true,
};
+/**
+ * sdhci_arasan_syscon_write - Write to a field in soc_ctl registers
+ *
+ * This function allows writing to fields in sdhci_arasan_soc_ctl_map.
+ * Note that if a field is specified as not available (shift < 0) then
+ * this function will silently return an error code. It will be noisy
+ * and print errors for any other (unexpected) errors.
+ *
+ * @host: The sdhci_host
+ * @fld: The field to write to
+ * @val: The value to write
+ */
+static int sdhci_arasan_syscon_write(struct sdhci_host *host,
+ const struct sdhci_arasan_soc_ctl_field *fld,
+ u32 val)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
+ struct regmap *soc_ctl_base = sdhci_arasan->soc_ctl_base;
+ u32 reg = fld->reg;
+ u16 width = fld->width;
+ s16 shift = fld->shift;
+ int ret;
+
+ /*
+ * Silently return errors for shift < 0 so caller doesn't have
+ * to check for fields which are optional. For fields that
+ * are required then caller needs to do something special
+ * anyway.
+ */
+ if (shift < 0)
+ return -EINVAL;
+
+ if (sdhci_arasan->soc_ctl_map->hiword_update)
+ ret = regmap_write(soc_ctl_base, reg,
+ HIWORD_UPDATE(val, GENMASK(width, 0),
+ shift));
+ else
+ ret = regmap_update_bits(soc_ctl_base, reg,
+ GENMASK(shift + width, shift),
+ val << shift);
+
+ /* Yell about (unexpected) regmap errors */
+ if (ret)
+ pr_warn("%s: Regmap write fail: %d\n",
+ mmc_hostname(host->mmc), ret);
+
+ return ret;
+}
+
static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
{
u32 div;
@@ -191,9 +290,66 @@ static int sdhci_arasan_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(sdhci_arasan_dev_pm_ops, sdhci_arasan_suspend,
sdhci_arasan_resume);
+static const struct of_device_id sdhci_arasan_of_match[] = {
+ /* SoC-specific compatible strings w/ soc_ctl_map */
+ {
+ .compatible = "rockchip,rk3399-sdhci-5.1",
+ .data = &rk3399_soc_ctl_map,
+ },
+
+ /* Generic compatible below here */
+ { .compatible = "arasan,sdhci-8.9a" },
+ { .compatible = "arasan,sdhci-5.1" },
+ { .compatible = "arasan,sdhci-4.9a" },
+
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
+
+/**
+ * sdhci_arasan_update_baseclkfreq - Set corecfg_baseclkfreq
+ *
+ * The corecfg_baseclkfreq is supposed to contain the MHz of clk_xin. This
+ * function can be used to make that happen.
+ *
+ * NOTES:
+ * - Many existing devices don't seem to do this and work fine. To keep
+ * compatibility for old hardware where the device tree doesn't provide a
+ * register map, this function is a noop if a soc_ctl_map hasn't been provided
+ * for this platform.
+ * - It's assumed that clk_xin is not dynamic and that we use the SDHCI divider
+ * to achieve lower clock rates. That means that this function is called once
+ * at probe time and never called again.
+ *
+ * @host: The sdhci_host
+ */
+static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
+ const struct sdhci_arasan_soc_ctl_map *soc_ctl_map =
+ sdhci_arasan->soc_ctl_map;
+ u32 mhz = DIV_ROUND_CLOSEST(clk_get_rate(pltfm_host->clk), 1000000);
+
+ /* Having a map is optional */
+ if (!soc_ctl_map)
+ return;
+
+ /* If we have a map, we expect to have a syscon */
+ if (!sdhci_arasan->soc_ctl_base) {
+ pr_warn("%s: Have regmap, but no soc-ctl-syscon\n",
+ mmc_hostname(host->mmc));
+ return;
+ }
+
+ sdhci_arasan_syscon_write(host, &soc_ctl_map->baseclkfreq, mhz);
+}
+
static int sdhci_arasan_probe(struct platform_device *pdev)
{
int ret;
+ const struct of_device_id *match;
+ struct device_node *node;
struct clk *clk_xin;
struct sdhci_host *host;
struct sdhci_pltfm_host *pltfm_host;
@@ -207,6 +363,23 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);
sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
+ match = of_match_node(sdhci_arasan_of_match, pdev->dev.of_node);
+ sdhci_arasan->soc_ctl_map = match->data;
+
+ node = of_parse_phandle(pdev->dev.of_node, "arasan,soc-ctl-syscon", 0);
+ if (node) {
+ sdhci_arasan->soc_ctl_base = syscon_node_to_regmap(node);
+ of_node_put(node);
+
+ if (IS_ERR(sdhci_arasan->soc_ctl_base)) {
+ ret = PTR_ERR(sdhci_arasan->soc_ctl_base);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Can't get syscon: %d\n",
+ ret);
+ goto err_pltfm_free;
+ }
+ }
+
sdhci_arasan->clk_ahb = devm_clk_get(&pdev->dev, "clk_ahb");
if (IS_ERR(sdhci_arasan->clk_ahb)) {
dev_err(&pdev->dev, "clk_ahb clock not found.\n");
@@ -236,6 +409,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
sdhci_get_of_property(pdev);
pltfm_host->clk = clk_xin;
+ sdhci_arasan_update_baseclkfreq(host);
+
ret = mmc_of_parse(host->mmc);
if (ret) {
dev_err(&pdev->dev, "parsing dt failed (%u)\n", ret);
@@ -301,14 +476,6 @@ static int sdhci_arasan_remove(struct platform_device *pdev)
return ret;
}
-static const struct of_device_id sdhci_arasan_of_match[] = {
- { .compatible = "arasan,sdhci-8.9a" },
- { .compatible = "arasan,sdhci-5.1" },
- { .compatible = "arasan,sdhci-4.9a" },
- { }
-};
-MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
-
static struct platform_driver sdhci_arasan_driver = {
.driver = {
.name = "sdhci-arasan",
--
2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2016-06-22 14:40 +0200 |
| Subject | Re: [PATCH v3 08/15] mmc: sdhci-of-arasan: Properly set corecfg_baseclkfreq on rk3399 |
| Message-ID | <rMPBM-3lU-29@gated-at.bofh.it> |
| In reply to | #1426901 |
On 20/06/16 20:56, Douglas Anderson wrote:
> In the the earlier change in this series ("Documentation: mmc:
> sdhci-of-arasan: Add soc-ctl-syscon for corecfg regs") we can see the
> mechansim for specifying a syscon to properly set corecfg registers in
> sdhci-of-arasan. Now let's use this mechanism to properly set
> corecfg_baseclkfreq on rk3399.
>
>>From [1] the corecfg_baseclkfreq is supposed to be set to:
> Base Clock Frequency for SD Clock.
> This is the frequency of the xin_clk.
>
> This is a relatively easy thing to do. Note that we assume that xin_clk
> is not dynamic and we can check the clock at probe time. If any real
> devices have a dynamic xin_clk future patches could register for
> notifiers for the clock.
>
> At the moment, setting corecfg_baseclkfreq is only supported for rk3399
> since we need a specific map for each implementation. The code is
> written in a generic way that should make this easy to extend to other
> SoCs. Note that a specific compatible string for rk3399 is already in
> use and so we add that to the table to match rk3399.
>
> [1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf
>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
> Tested-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
[toc] | [prev] | [next] | [standalone]
| From | Heiko Stübner <heiko@sntech.de> |
|---|---|
| Date | 2016-06-20 20:20 +0200 |
| Message-ID | <rMbXI-3fW-17@gated-at.bofh.it> |
| In reply to | #1426898 |
Am Montag, 20. Juni 2016, 10:56:39 schrieb Douglas Anderson: > The theme of this series of patches is to try to allow running the eMMC > at 150 MHz on the rk3399 SoC, though the changes should still be correct > and have merit on their own. The motivation for running at 150 MHz is > that doing so improves signal integrity and (with some eMMC devices) > doesn't affect throughput. > > These patches have been structured to keep things as separate as > possible, but nevertheless there are still some dependencies between > patches. It probably makes the most sense for all of the non-device > tree patches to go through a single tree. PHY patches now have Acks > from Kishon so that means things should be clear for all non-DTS patches > to go through the MMC tree if Ulf agrees. Device tree patches should be > able to be landed separately and the worst what would happen is a > warning in the kernel log if you have the code without the device tree. > > The code patches are based on Ulf's mmc-next. In v3 of the series I've > pulled in the latest version of a previous PHY series posted by Brian > Norris. > > The device tree patches are based on Heiko's v4.8-armsoc/dts64. just so it doesn't get lost from v2->v3, I plan on picking up the dts patches 9 and 15 after the rest landed in the mmc tree - as they will only apply on top of my general dts branch. Heiko
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:20 +0200 |
| Subject | [PATCH v3 14/15] phy: rockchip-emmc: Set phyctrl_frqsel based on card clock |
| Message-ID | <rMbXI-3fW-21@gated-at.bofh.it> |
| In reply to | #1426898 |
The "phyctrl_frqsel" is described in the Arasan datasheet [1] as "the
frequency range of DLL operation". Although the Rockchip variant of
this PHY has different ranges than the reference Arasan PHY it appears
as if the functionality is similar. We should set this phyctrl field
properly.
Note: as per Rockchip engineers, apparently the "phyctrl_frqsel" is
actually only useful in HS200 / HS400 modes even though the DLL itself
it used for some purposes in all modes. See the discussion in the
earlier change in this series: ("mmc: sdhci-of-arasan: Always power the
PHY off/on when clock changes"). In any case, it shouldn't hurt to set
this always.
Note that this change should allow boards to run at HS200 / HS400 speed
modes while running at 100 MHz or 150 MHz. In fact, running HS400 at
150 MHz (giving 300 MB/s) is the main motivation of this series, since
performance is still good but signal integrity problems are less
prevelant at 150 MHz.
[1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
---
Changes in v3:
- Use phy_init / phy_exit (Heiko)
- Add Kishon's Ack
Changes in v2:
- Warn if we're more than 15 MHz from ideal rate (Shawn)
- Move code cleanup before set phyctrl_frqsel based on card clock (Shawn)
- Fix typo USB => SDHCI (Shawn)
drivers/phy/phy-rockchip-emmc.c | 101 +++++++++++++++++++++++++++++++++++-----
1 file changed, 89 insertions(+), 12 deletions(-)
diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c
index 23fe50864526..9dce958233a0 100644
--- a/drivers/phy/phy-rockchip-emmc.c
+++ b/drivers/phy/phy-rockchip-emmc.c
@@ -14,6 +14,7 @@
* GNU General Public License for more details.
*/
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
@@ -78,15 +79,53 @@
struct rockchip_emmc_phy {
unsigned int reg_offset;
struct regmap *reg_base;
+ struct clk *emmcclk;
};
-static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
- bool on_off)
+static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
{
+ struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
unsigned int caldone;
unsigned int dllrdy;
+ unsigned int freqsel = PHYCTRL_FREQSEL_200M;
unsigned long timeout;
+ if (rk_phy->emmcclk != NULL) {
+ unsigned long rate = clk_get_rate(rk_phy->emmcclk);
+ unsigned long ideal_rate;
+ unsigned long diff;
+
+ switch (rate) {
+ case 0 ... 74999999:
+ ideal_rate = 50000000;
+ freqsel = PHYCTRL_FREQSEL_50M;
+ break;
+ case 75000000 ... 124999999:
+ ideal_rate = 100000000;
+ freqsel = PHYCTRL_FREQSEL_100M;
+ break;
+ case 125000000 ... 174999999:
+ ideal_rate = 150000000;
+ freqsel = PHYCTRL_FREQSEL_150M;
+ break;
+ default:
+ ideal_rate = 200000000;
+ break;
+ };
+
+ diff = (rate > ideal_rate) ?
+ rate - ideal_rate : ideal_rate - rate;
+
+ /*
+ * In order for tuning delays to be accurate we need to be
+ * pretty spot on for the DLL range, so warn if we're too
+ * far off. Also warn if we're above the 200 MHz max. Don't
+ * warn for really slow rates since we won't be tuning then.
+ */
+ if ((rate > 50000000 && diff > 15000000) || (rate > 200000000))
+ dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
+ }
+
/*
* Keep phyctrl_pdb and phyctrl_endll low to allow
* initialization of CALIO state M/C DFFs
@@ -132,6 +171,13 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
return -ETIMEDOUT;
}
+ /* Set the frequency of the DLL operation */
+ regmap_write(rk_phy->reg_base,
+ rk_phy->reg_offset + GRF_EMMCPHY_CON0,
+ HIWORD_UPDATE(freqsel, PHYCTRL_FREQSEL_MASK,
+ PHYCTRL_FREQSEL_SHIFT));
+
+ /* Turn on the DLL */
regmap_write(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_CON6,
HIWORD_UPDATE(PHYCTRL_ENDLL_ENABLE,
@@ -166,25 +212,54 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
return 0;
}
-static int rockchip_emmc_phy_power_off(struct phy *phy)
+static int rockchip_emmc_phy_init(struct phy *phy)
+{
+ struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
+ int ret = 0;
+
+ /*
+ * We purposely get the clock here and not in probe to avoid the
+ * circular dependency problem. We expect:
+ * - PHY driver to probe
+ * - SDHCI driver to start probe
+ * - SDHCI driver to register it's clock
+ * - SDHCI driver to get the PHY
+ * - SDHCI driver to init the PHY
+ *
+ * The clock is optional, so upon any error we just set to NULL.
+ *
+ * NOTE: we don't do anything special for EPROBE_DEFER here. Given the
+ * above expected use case, EPROBE_DEFER isn't sensible to expect, so
+ * it's just like any other error.
+ */
+ rk_phy->emmcclk = clk_get(&phy->dev, "emmcclk");
+ if (IS_ERR(rk_phy->emmcclk)) {
+ dev_dbg(&phy->dev, "Error getting emmcclk: %d\n", ret);
+ rk_phy->emmcclk = NULL;
+ }
+
+ return ret;
+}
+
+static int rockchip_emmc_phy_exit(struct phy *phy)
{
struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
+ clk_put(rk_phy->emmcclk);
+
+ return 0;
+}
+
+static int rockchip_emmc_phy_power_off(struct phy *phy)
+{
/* Power down emmc phy analog blocks */
- return rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_OFF);
+ return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_OFF);
}
static int rockchip_emmc_phy_power_on(struct phy *phy)
{
struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
- /* DLL operation: 200 MHz */
- regmap_write(rk_phy->reg_base,
- rk_phy->reg_offset + GRF_EMMCPHY_CON0,
- HIWORD_UPDATE(PHYCTRL_FREQSEL_200M,
- PHYCTRL_FREQSEL_MASK,
- PHYCTRL_FREQSEL_SHIFT));
-
/* Drive impedance: 50 Ohm */
regmap_write(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_CON6,
@@ -207,10 +282,12 @@ static int rockchip_emmc_phy_power_on(struct phy *phy)
PHYCTRL_OTAPDLYSEL_SHIFT));
/* Power up emmc phy analog blocks */
- return rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_ON);
+ return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_ON);
}
static const struct phy_ops ops = {
+ .init = rockchip_emmc_phy_init,
+ .exit = rockchip_emmc_phy_exit,
.power_on = rockchip_emmc_phy_power_on,
.power_off = rockchip_emmc_phy_power_off,
.owner = THIS_MODULE,
--
2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Heiko Stübner <heiko@sntech.de> |
|---|---|
| Date | 2016-06-20 20:20 +0200 |
| Subject | Re: [PATCH v3 14/15] phy: rockchip-emmc: Set phyctrl_frqsel based on card clock |
| Message-ID | <rMbXI-3fW-19@gated-at.bofh.it> |
| In reply to | #1426903 |
Am Montag, 20. Juni 2016, 10:56:53 schrieb Douglas Anderson:
> The "phyctrl_frqsel" is described in the Arasan datasheet [1] as "the
> frequency range of DLL operation". Although the Rockchip variant of
> this PHY has different ranges than the reference Arasan PHY it appears
> as if the functionality is similar. We should set this phyctrl field
> properly.
>
> Note: as per Rockchip engineers, apparently the "phyctrl_frqsel" is
> actually only useful in HS200 / HS400 modes even though the DLL itself
> it used for some purposes in all modes. See the discussion in the
> earlier change in this series: ("mmc: sdhci-of-arasan: Always power the
> PHY off/on when clock changes"). In any case, it shouldn't hurt to set
> this always.
>
> Note that this change should allow boards to run at HS200 / HS400 speed
> modes while running at 100 MHz or 150 MHz. In fact, running HS400 at
> 150 MHz (giving 300 MB/s) is the main motivation of this series, since
> performance is still good but signal integrity problems are less
> prevelant at 150 MHz.
>
> [1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf
>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> Changes in v3:
> - Use phy_init / phy_exit (Heiko)
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:30 +0200 |
| Subject | [PATCH v3 09/15] arm64: dts: rockchip: Add soc-ctl-syscon to sdhci for rk3399 |
| Message-ID | <rMc7n-3jw-13@gated-at.bofh.it> |
| In reply to | #1426898 |
On rk3399 we'd like to be able to properly set corecfg registers in the Arasan SDHCI component. Specify the syscon to enable that. Signed-off-by: Douglas Anderson <dianders@chromium.org> Tested-by: Heiko Stuebner <heiko@sntech.de> --- Changes in v3: - Add collected tags Changes in v2: None arch/arm64/boot/dts/rockchip/rk3399.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index a4383f359264..1b57e92e0093 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -220,6 +220,7 @@ compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1"; reg = <0x0 0xfe330000 0x0 0x10000>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + arasan,soc-ctl-syscon = <&grf>; assigned-clocks = <&cru SCLK_EMMC>; assigned-clock-rates = <200000000>; clocks = <&cru SCLK_EMMC>, <&cru ACLK_EMMC>; -- 2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Heiko Stübner <heiko@sntech.de> |
|---|---|
| Date | 2016-06-22 18:40 +0200 |
| Subject | Re: [PATCH v3 09/15] arm64: dts: rockchip: Add soc-ctl-syscon to sdhci for rk3399 |
| Message-ID | <rMTm2-5QR-19@gated-at.bofh.it> |
| In reply to | #1426909 |
Am Montag, 20. Juni 2016, 10:56:48 schrieb Douglas Anderson: > On rk3399 we'd like to be able to properly set corecfg registers in the > Arasan SDHCI component. Specify the syscon to enable that. > > Signed-off-by: Douglas Anderson <dianders@chromium.org> > Tested-by: Heiko Stuebner <heiko@sntech.de> applied to my dts64-branch for 4.8 Thanks Heiko
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:40 +0200 |
| Subject | [PATCH v3 13/15] phy: rockchip-emmc: Minor code cleanup in rockchip_emmc_phy_power_on/off() |
| Message-ID | <rMch3-3oI-23@gated-at.bofh.it> |
| In reply to | #1426898 |
There's no reason to store the return value of rockchip_emmc_phy_power()
in a variable nor to check it. Just return it.
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
Changes in v3:
- Add collected tags
Changes in v2:
- Move code cleanup before set phyctrl_frqsel based on card clock (Shawn)
drivers/phy/phy-rockchip-emmc.c | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c
index 2d059c046978..23fe50864526 100644
--- a/drivers/phy/phy-rockchip-emmc.c
+++ b/drivers/phy/phy-rockchip-emmc.c
@@ -169,20 +169,14 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
static int rockchip_emmc_phy_power_off(struct phy *phy)
{
struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
- int ret = 0;
/* Power down emmc phy analog blocks */
- ret = rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_OFF);
- if (ret)
- return ret;
-
- return 0;
+ return rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_OFF);
}
static int rockchip_emmc_phy_power_on(struct phy *phy)
{
struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
- int ret = 0;
/* DLL operation: 200 MHz */
regmap_write(rk_phy->reg_base,
@@ -213,11 +207,7 @@ static int rockchip_emmc_phy_power_on(struct phy *phy)
PHYCTRL_OTAPDLYSEL_SHIFT));
/* Power up emmc phy analog blocks */
- ret = rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_ON);
- if (ret)
- return ret;
-
- return 0;
+ return rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_ON);
}
static const struct phy_ops ops = {
--
2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:40 +0200 |
| Subject | [PATCH v3 10/15] Documentation: mmc: sdhci-of-arasan: Add ability to export card clock |
| Message-ID | <rMch4-3oI-31@gated-at.bofh.it> |
| In reply to | #1426898 |
Some SD/eMMC PHYs (like the PHY from Arasan that is designed to work
with arasan,sdhci-5.1) need to know the card clock frequency in order to
function properly. Physically in a SoC this clock is exported from the
SDHCI IP block to the PHY IP block and the PHY needs to know the speed.
Let's export the SDHCI card clock using a standard device tree mechanism
so that the PHY can get access to it and query the card clock frequency.
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
---
Changes in v3:
- Add collected tags
Changes in v2:
- Adjust commit message wording (Rob)
- Add Rob Herring's Ack.
Documentation/devicetree/bindings/mmc/arasan,sdhci.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
index 476604e6ce2a..3404afa9b938 100644
--- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
@@ -30,6 +30,12 @@ Optional Properties:
- arasan,soc-ctl-syscon: A phandle to a syscon device (see ../mfd/syscon.txt)
used to access core corecfg registers. Offsets of registers in this
syscon are determined based on the main compatible string for the device.
+ - clock-output-names: If specified, this will be the name of the card clock
+ which will be exposed by this device. Required if #clock-cells is
+ specified.
+ - #clock-cells: If specified this should be the value <0>. With this property
+ in place we will export a clock representing the Card Clock. This clock
+ is expected to be consumed by our PHY. You must also specify
Example:
sdhci@e0100000 {
@@ -61,7 +67,9 @@ Example:
arasan,soc-ctl-syscon = <&grf>;
assigned-clocks = <&cru SCLK_EMMC>;
assigned-clock-rates = <200000000>;
+ clock-output-names = "emmc_cardclock";
phys = <&emmc_phy>;
phy-names = "phy_arasan";
+ #clock-cells = <0>;
status = "disabled";
};
--
2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:40 +0200 |
| Subject | [PATCH v3 02/15] phy: rockchip-emmc: configure frequency range and drive impedance |
| Message-ID | <rMch4-3oI-33@gated-at.bofh.it> |
| In reply to | #1426898 |
From: Shawn Lin <shawn.lin@rock-chips.com>
Signal integrity analysis has suggested we set these values. Do this in
power_on(), so that they get reconfigured after suspend/resume.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
Changes in v3:
- Add Brian's PHY patches into my series
Changes in v2:
- Drop 170 MHz comment (only applicable to a subtly different Arasan PHY)
drivers/phy/phy-rockchip-emmc.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c
index 48cbe691a889..f2f75cf69af1 100644
--- a/drivers/phy/phy-rockchip-emmc.c
+++ b/drivers/phy/phy-rockchip-emmc.c
@@ -56,6 +56,19 @@
#define PHYCTRL_DLLRDY_SHIFT 0x5
#define PHYCTRL_DLLRDY_DONE 0x1
#define PHYCTRL_DLLRDY_GOING 0x0
+#define PHYCTRL_FREQSEL_200M 0x0
+#define PHYCTRL_FREQSEL_50M 0x1
+#define PHYCTRL_FREQSEL_100M 0x2
+#define PHYCTRL_FREQSEL_150M 0x3
+#define PHYCTRL_FREQSEL_MASK 0x3
+#define PHYCTRL_FREQSEL_SHIFT 0xc
+#define PHYCTRL_DR_MASK 0x7
+#define PHYCTRL_DR_SHIFT 0x4
+#define PHYCTRL_DR_50OHM 0x0
+#define PHYCTRL_DR_33OHM 0x1
+#define PHYCTRL_DR_66OHM 0x2
+#define PHYCTRL_DR_100OHM 0x3
+#define PHYCTRL_DR_40OHM 0x4
struct rockchip_emmc_phy {
unsigned int reg_offset;
@@ -154,6 +167,20 @@ static int rockchip_emmc_phy_power_on(struct phy *phy)
struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
int ret = 0;
+ /* DLL operation: 200 MHz */
+ regmap_write(rk_phy->reg_base,
+ rk_phy->reg_offset + GRF_EMMCPHY_CON0,
+ HIWORD_UPDATE(PHYCTRL_FREQSEL_200M,
+ PHYCTRL_FREQSEL_MASK,
+ PHYCTRL_FREQSEL_SHIFT));
+
+ /* Drive impedance: 50 Ohm */
+ regmap_write(rk_phy->reg_base,
+ rk_phy->reg_offset + GRF_EMMCPHY_CON6,
+ HIWORD_UPDATE(PHYCTRL_DR_50OHM,
+ PHYCTRL_DR_MASK,
+ PHYCTRL_DR_SHIFT));
+
/* Power up emmc phy analog blocks */
ret = rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_ON);
if (ret)
--
2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:40 +0200 |
| Subject | [PATCH v3 04/15] phy: rockchip-emmc: reindent the register definitions |
| Message-ID | <rMch4-3oI-37@gated-at.bofh.it> |
| In reply to | #1426898 |
From: Brian Norris <briannorris@chromium.org> Some of the spacing was wrong (spaces instead of tabs), and due to longer entries added later, the columns weren't aligned. Let's get everything consistent. Signed-off-by: Brian Norris <briannorris@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Kishon Vijay Abraham I <kishon@ti.com> Reviewed-by: Heiko Stuebner <heiko@sntech.de> --- Changes in v3: - Add Brian's PHY patches into my series Changes in v2: None drivers/phy/phy-rockchip-emmc.c | 76 ++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c index a0b87cc6c818..a69f53630e67 100644 --- a/drivers/phy/phy-rockchip-emmc.c +++ b/drivers/phy/phy-rockchip-emmc.c @@ -31,44 +31,44 @@ ((val) << (shift) | (mask) << ((shift) + 16)) /* Register definition */ -#define GRF_EMMCPHY_CON0 0x0 -#define GRF_EMMCPHY_CON1 0x4 -#define GRF_EMMCPHY_CON2 0x8 -#define GRF_EMMCPHY_CON3 0xc -#define GRF_EMMCPHY_CON4 0x10 -#define GRF_EMMCPHY_CON5 0x14 -#define GRF_EMMCPHY_CON6 0x18 -#define GRF_EMMCPHY_STATUS 0x20 - -#define PHYCTRL_PDB_MASK 0x1 -#define PHYCTRL_PDB_SHIFT 0x0 -#define PHYCTRL_PDB_PWR_ON 0x1 -#define PHYCTRL_PDB_PWR_OFF 0x0 -#define PHYCTRL_ENDLL_MASK 0x1 -#define PHYCTRL_ENDLL_SHIFT 0x1 -#define PHYCTRL_ENDLL_ENABLE 0x1 -#define PHYCTRL_ENDLL_DISABLE 0x0 -#define PHYCTRL_CALDONE_MASK 0x1 -#define PHYCTRL_CALDONE_SHIFT 0x6 -#define PHYCTRL_CALDONE_DONE 0x1 -#define PHYCTRL_CALDONE_GOING 0x0 -#define PHYCTRL_DLLRDY_MASK 0x1 -#define PHYCTRL_DLLRDY_SHIFT 0x5 -#define PHYCTRL_DLLRDY_DONE 0x1 -#define PHYCTRL_DLLRDY_GOING 0x0 -#define PHYCTRL_FREQSEL_200M 0x0 -#define PHYCTRL_FREQSEL_50M 0x1 -#define PHYCTRL_FREQSEL_100M 0x2 -#define PHYCTRL_FREQSEL_150M 0x3 -#define PHYCTRL_FREQSEL_MASK 0x3 -#define PHYCTRL_FREQSEL_SHIFT 0xc -#define PHYCTRL_DR_MASK 0x7 -#define PHYCTRL_DR_SHIFT 0x4 -#define PHYCTRL_DR_50OHM 0x0 -#define PHYCTRL_DR_33OHM 0x1 -#define PHYCTRL_DR_66OHM 0x2 -#define PHYCTRL_DR_100OHM 0x3 -#define PHYCTRL_DR_40OHM 0x4 +#define GRF_EMMCPHY_CON0 0x0 +#define GRF_EMMCPHY_CON1 0x4 +#define GRF_EMMCPHY_CON2 0x8 +#define GRF_EMMCPHY_CON3 0xc +#define GRF_EMMCPHY_CON4 0x10 +#define GRF_EMMCPHY_CON5 0x14 +#define GRF_EMMCPHY_CON6 0x18 +#define GRF_EMMCPHY_STATUS 0x20 + +#define PHYCTRL_PDB_MASK 0x1 +#define PHYCTRL_PDB_SHIFT 0x0 +#define PHYCTRL_PDB_PWR_ON 0x1 +#define PHYCTRL_PDB_PWR_OFF 0x0 +#define PHYCTRL_ENDLL_MASK 0x1 +#define PHYCTRL_ENDLL_SHIFT 0x1 +#define PHYCTRL_ENDLL_ENABLE 0x1 +#define PHYCTRL_ENDLL_DISABLE 0x0 +#define PHYCTRL_CALDONE_MASK 0x1 +#define PHYCTRL_CALDONE_SHIFT 0x6 +#define PHYCTRL_CALDONE_DONE 0x1 +#define PHYCTRL_CALDONE_GOING 0x0 +#define PHYCTRL_DLLRDY_MASK 0x1 +#define PHYCTRL_DLLRDY_SHIFT 0x5 +#define PHYCTRL_DLLRDY_DONE 0x1 +#define PHYCTRL_DLLRDY_GOING 0x0 +#define PHYCTRL_FREQSEL_200M 0x0 +#define PHYCTRL_FREQSEL_50M 0x1 +#define PHYCTRL_FREQSEL_100M 0x2 +#define PHYCTRL_FREQSEL_150M 0x3 +#define PHYCTRL_FREQSEL_MASK 0x3 +#define PHYCTRL_FREQSEL_SHIFT 0xc +#define PHYCTRL_DR_MASK 0x7 +#define PHYCTRL_DR_SHIFT 0x4 +#define PHYCTRL_DR_50OHM 0x0 +#define PHYCTRL_DR_33OHM 0x1 +#define PHYCTRL_DR_66OHM 0x2 +#define PHYCTRL_DR_100OHM 0x3 +#define PHYCTRL_DR_40OHM 0x4 #define PHYCTRL_OTAPDLYENA 0x1 #define PHYCTRL_OTAPDLYENA_MASK 0x1 #define PHYCTRL_OTAPDLYENA_SHIFT 0xb -- 2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 20:40 +0200 |
| Subject | [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready |
| Message-ID | <rMch4-3oI-51@gated-at.bofh.it> |
| In reply to | #1426898 |
From: Shawn Lin <shawn.lin@rock-chips.com> According to the databook, 10.2us is the max time for dll to be ready to work. However in testing, some chips need 20us for dll to be ready. This patch adds some extra margin for dllrdy to be ready, fixing our -ETIMEDOUT issues. Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Brian Norris <briannorris@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Kishon Vijay Abraham I <kishon@ti.com> Tested-by: Heiko Stuebner <heiko@sntech.de> --- Changes in v3: - Add Brian's PHY patches into my series Changes in v2: None drivers/phy/phy-rockchip-emmc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c index 6ebcf3e41c46..48cbe691a889 100644 --- a/drivers/phy/phy-rockchip-emmc.c +++ b/drivers/phy/phy-rockchip-emmc.c @@ -119,10 +119,11 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy, PHYCTRL_ENDLL_MASK, PHYCTRL_ENDLL_SHIFT)); /* - * After enable analog DLL circuits, we need extra 10.2us - * for dll to be ready for work. + * After enable analog DLL circuits, we need an extra 10.2us + * for dll to be ready for work. But according to testing, we + * find some chips need more than 25us. */ - udelay(11); + udelay(30); regmap_read(rk_phy->reg_base, rk_phy->reg_offset + GRF_EMMCPHY_STATUS, &dllrdy); -- 2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
| From | Guenter Roeck <groeck@google.com> |
|---|---|
| Date | 2016-06-20 21:30 +0200 |
| Subject | Re: [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready |
| Message-ID | <rMd3s-3UC-27@gated-at.bofh.it> |
| In reply to | #1426925 |
On Mon, Jun 20, 2016 at 10:56 AM, Douglas Anderson <dianders@chromium.org> wrote: > From: Shawn Lin <shawn.lin@rock-chips.com> > > According to the databook, 10.2us is the max time for dll to be ready to > work. However in testing, some chips need 20us for dll to be ready. This Nitpick, but description (20uS) and code (more than 25 uS) don't match. > patch adds some extra margin for dllrdy to be ready, fixing our > -ETIMEDOUT issues. > > Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> > Signed-off-by: Brian Norris <briannorris@chromium.org> > Signed-off-by: Douglas Anderson <dianders@chromium.org> > Acked-by: Kishon Vijay Abraham I <kishon@ti.com> > Tested-by: Heiko Stuebner <heiko@sntech.de> > --- > Changes in v3: > - Add Brian's PHY patches into my series > > Changes in v2: None > > drivers/phy/phy-rockchip-emmc.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c > index 6ebcf3e41c46..48cbe691a889 100644 > --- a/drivers/phy/phy-rockchip-emmc.c > +++ b/drivers/phy/phy-rockchip-emmc.c > @@ -119,10 +119,11 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy, > PHYCTRL_ENDLL_MASK, > PHYCTRL_ENDLL_SHIFT)); > /* > - * After enable analog DLL circuits, we need extra 10.2us > - * for dll to be ready for work. > + * After enable analog DLL circuits, we need an extra 10.2us > + * for dll to be ready for work. But according to testing, we > + * find some chips need more than 25us. > */ > - udelay(11); > + udelay(30); > regmap_read(rk_phy->reg_base, > rk_phy->reg_offset + GRF_EMMCPHY_STATUS, > &dllrdy); > -- > 2.8.0.rc3.226.g39d4020 >
[toc] | [prev] | [next] | [standalone]
| From | Doug Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 21:40 +0200 |
| Subject | Re: [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready |
| Message-ID | <rMdd7-3XL-3@gated-at.bofh.it> |
| In reply to | #1426955 |
Hi, On Mon, Jun 20, 2016 at 12:36 PM, Guenter Roeck <groeck@google.com> wrote: > On Mon, Jun 20, 2016 at 12:30 PM, Doug Anderson <dianders@chromium.org> wrote: >> Hi, >> >> On Mon, Jun 20, 2016 at 12:23 PM, Guenter Roeck <groeck@google.com> wrote: >>> On Mon, Jun 20, 2016 at 10:56 AM, Douglas Anderson >>> <dianders@chromium.org> wrote: >>>> From: Shawn Lin <shawn.lin@rock-chips.com> >>>> >>>> According to the databook, 10.2us is the max time for dll to be ready to >>>> work. However in testing, some chips need 20us for dll to be ready. This >>> >>> Nitpick, but description (20uS) and code (more than 25 uS) don't match. >> >> Good catch. If I spin the series I'll fix this, otherwise I'll assume >> that the person applying this (Ulf?) can fix the description at their >> discretion. >> > > Not that it matters much, as the code is replaced in a later patch > anyway. It might make more sense to merge the two patches into one. Yes. At the time I wrote it it was unclear what the status of the original patch was (whether it would be applied sooner vs. later). At this point it seemed expedient to continue to keep the patches separate since they had been reviewed and tested separately. Earlier I made the offer to combine and re-spin and I'm happy to do that if requested. -Doug
[toc] | [prev] | [next] | [standalone]
| From | Doug Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 21:40 +0200 |
| Subject | Re: [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready |
| Message-ID | <rMdd7-3XL-5@gated-at.bofh.it> |
| In reply to | #1426955 |
Hi, On Mon, Jun 20, 2016 at 12:23 PM, Guenter Roeck <groeck@google.com> wrote: > On Mon, Jun 20, 2016 at 10:56 AM, Douglas Anderson > <dianders@chromium.org> wrote: >> From: Shawn Lin <shawn.lin@rock-chips.com> >> >> According to the databook, 10.2us is the max time for dll to be ready to >> work. However in testing, some chips need 20us for dll to be ready. This > > Nitpick, but description (20uS) and code (more than 25 uS) don't match. Good catch. If I spin the series I'll fix this, otherwise I'll assume that the person applying this (Ulf?) can fix the description at their discretion. -Doug
[toc] | [prev] | [next] | [standalone]
| From | Guenter Roeck <groeck@google.com> |
|---|---|
| Date | 2016-06-20 21:50 +0200 |
| Subject | Re: [PATCH v3 01/15] phy: rockchip-emmc: give DLL some extra time to be ready |
| Message-ID | <rMdd7-3XL-7@gated-at.bofh.it> |
| In reply to | #1426963 |
On Mon, Jun 20, 2016 at 12:30 PM, Doug Anderson <dianders@chromium.org> wrote: > Hi, > > On Mon, Jun 20, 2016 at 12:23 PM, Guenter Roeck <groeck@google.com> wrote: >> On Mon, Jun 20, 2016 at 10:56 AM, Douglas Anderson >> <dianders@chromium.org> wrote: >>> From: Shawn Lin <shawn.lin@rock-chips.com> >>> >>> According to the databook, 10.2us is the max time for dll to be ready to >>> work. However in testing, some chips need 20us for dll to be ready. This >> >> Nitpick, but description (20uS) and code (more than 25 uS) don't match. > > Good catch. If I spin the series I'll fix this, otherwise I'll assume > that the person applying this (Ulf?) can fix the description at their > discretion. > Not that it matters much, as the code is replaced in a later patch anyway. It might make more sense to merge the two patches into one. Guenter
[toc] | [prev] | [next] | [standalone]
| From | Douglas Anderson <dianders@chromium.org> |
|---|---|
| Date | 2016-06-20 22:00 +0200 |
| Subject | [PATCH v3 07/15] Documentation: mmc: sdhci-of-arasan: Add soc-ctl-syscon for corecfg regs |
| Message-ID | <rMdwu-44L-41@gated-at.bofh.it> |
| In reply to | #1426898 |
As can be seen in Arasan's datasheet [1] there are several "corecfg"
settings in their SDHCI IP Block that are supposed to be controlled by
software. Although the datasheet referenced is a bit vague about how to
access corecfg, in Figure 5 you can see that for Arasan's PHY (a
separate component than their SDHCI component) they describe the
"phyctrl" registers as being "FROM SOC CTL REG", implying that it's up
to the licensee of the Arasan IP block to implement these registers. It
seems sane to assume that the "corecfg" registers in their SDHCI IP
block works in a similar way for all licensees of the IP Block.
Device tree has a model that allows a device to get a reference to
random registers located elsewhere in the SoC: sysctl. Let's leverage
this model and allow adding a sysctl reference to access the control
registers for the Arasan SDHCI PHYs.
Having a reference to the control registers doesn't do much for us on
its own since the Arasan spec doesn't specify how these corecfg values
are laid out in memory. In the SDHCI driver we'll need a map detailing
where each corecfg can be found in each implementation. This map can be
found using the primary compatible string of the SDHCI device. In that
spirit, document that existing rk3399 device trees already have a
specific compatible string, though up to now they've always been relying
on the driver supporting the generic.
Note that since existing devices seem to work fairly well as-is, we'll
list the syscon reference as "optional", but it's likely that we'll run
into much fewer problems if we can actually set the proper values in the
syscon, so it is strongly suggested that any SoCs where we have a map to
set the corecfg also include a reference to the syscon.
[1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v3:
- Add collected tags
Changes in v2:
- Clean up description of rk3399 PHY (Shawn)
- Add Rob Herring's Ack.
.../devicetree/bindings/mmc/arasan,sdhci.txt | 27 ++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
index 31b35c3a5e47..476604e6ce2a 100644
--- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
@@ -9,8 +9,12 @@ Device Tree Bindings for the Arasan SDHCI Controller
[4] Documentation/devicetree/bindings/phy/phy-bindings.txt
Required Properties:
- - compatible: Compatibility string. Must be 'arasan,sdhci-8.9a' or
- 'arasan,sdhci-4.9a' or 'arasan,sdhci-5.1'
+ - compatible: Compatibility string. One of:
+ - "arasan,sdhci-8.9a": generic Arasan SDHCI 8.9a PHY
+ - "arasan,sdhci-4.9a": generic Arasan SDHCI 4.9a PHY
+ - "arasan,sdhci-5.1": generic Arasan SDHCI 5.1 PHY
+ - "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1": rk3399 eMMC PHY
+ For this device it is strongly suggested to include arasan,soc-ctl-syscon.
- reg: From mmc bindings: Register location and length.
- clocks: From clock bindings: Handles to clock inputs.
- clock-names: From clock bindings: Tuple including "clk_xin" and "clk_ahb"
@@ -22,6 +26,11 @@ Required Properties for "arasan,sdhci-5.1":
- phys: From PHY bindings: Phandle for the Generic PHY for arasan.
- phy-names: MUST be "phy_arasan".
+Optional Properties:
+ - arasan,soc-ctl-syscon: A phandle to a syscon device (see ../mfd/syscon.txt)
+ used to access core corecfg registers. Offsets of registers in this
+ syscon are determined based on the main compatible string for the device.
+
Example:
sdhci@e0100000 {
compatible = "arasan,sdhci-8.9a";
@@ -42,3 +51,17 @@ Example:
phys = <&emmc_phy>;
phy-names = "phy_arasan";
} ;
+
+ sdhci: sdhci@fe330000 {
+ compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
+ reg = <0x0 0xfe330000 0x0 0x10000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_EMMC>, <&cru ACLK_EMMC>;
+ clock-names = "clk_xin", "clk_ahb";
+ arasan,soc-ctl-syscon = <&grf>;
+ assigned-clocks = <&cru SCLK_EMMC>;
+ assigned-clock-rates = <200000000>;
+ phys = <&emmc_phy>;
+ phy-names = "phy_arasan";
+ status = "disabled";
+ };
--
2.8.0.rc3.226.g39d4020
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web