summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-23 15:57:04 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-23 15:57:04 -0800
commitb2e3c4319d40c9055c3c587cdb82ba69b50e919d (patch)
tree223bc161e96a5d39752dc056fed8d412c291e72a
parentc61c15e08abb4365f100e411604b57a03ee5ae90 (diff)
parentdb27dd05b1da6e658494a2570680f8d0ddbc578c (diff)
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Arnd Bergmann: "Driver updates for ARM SoCs. A handful of driver changes this time around. The larger changes are: - Reset drivers for hi3660 and zx2967 - AHCI driver for Davinci, acked by Tejun and brought in here due to platform dependencies - Cleanups of atmel-ebi (External Bus Interface) - Tweaks for Rockchip GRF (General Register File) usage (kitchensink misc register range on the SoCs) - PM domains changes for support of two new ZTE SoCs (zx296718 and zx2967)" * tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (53 commits) soc: samsung: pmu: Add register defines for pad retention control reset: make zx2967 explicitly non-modular reset: core: fix reset_control_put soc: samsung: pm_domains: Read domain name from the new label property soc: samsung: pm_domains: Remove message about failed memory allocation soc: samsung: pm_domains: Remove unused name field soc: samsung: pm_domains: Use full names in subdomains registration log sata: ahci-da850: un-hardcode the MPY bits sata: ahci-da850: add a workaround for controller instability sata: ahci: export ahci_do_hardreset() locally sata: ahci-da850: implement a workaround for the softreset quirk sata: ahci-da850: add device tree match table sata: ahci-da850: get the sata clock using a connection id soc: samsung: pmu: Remove duplicated define for ARM_L2_OPTION register memory: atmel-ebi: Enable the SMC clock if specified soc: samsung: pmu: Remove unused and duplicated defines memory: atmel-ebi: Properly handle multiple reference to the same CS memory: atmel-ebi: Fix the test to enable generic SMC logic soc: samsung: pm_domains: Add new Exynos5433 compatible soc: samsung: pmu: Add dummy support for Exynos5433 SoC ...
-rw-r--r--Documentation/devicetree/bindings/power/pd-samsung.txt5
-rw-r--r--Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt43
-rw-r--r--Documentation/devicetree/bindings/reset/ti-syscon-reset.txt8
-rw-r--r--Documentation/devicetree/bindings/reset/uniphier-reset.txt47
-rw-r--r--Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt20
-rw-r--r--Documentation/devicetree/bindings/soc/rockchip/grf.txt4
-rw-r--r--Documentation/devicetree/bindings/soc/rockchip/power_domain.txt3
-rw-r--r--Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt19
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/arm/mach-exynos/suspend.c6
-rw-r--r--arch/arm/mach-rockchip/rockchip.c12
-rw-r--r--drivers/ata/ahci.h3
-rw-r--r--drivers/ata/ahci_da850.c175
-rw-r--r--drivers/ata/libahci.c18
-rw-r--r--drivers/bus/Kconfig1
-rw-r--r--drivers/firmware/qcom_scm-32.c18
-rw-r--r--drivers/firmware/qcom_scm-64.c16
-rw-r--r--drivers/firmware/qcom_scm.c8
-rw-r--r--drivers/firmware/qcom_scm.h2
-rw-r--r--drivers/memory/atmel-ebi.c126
-rw-r--r--drivers/memory/tegra/tegra124-emc.c5
-rw-r--r--drivers/reset/Kconfig6
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/core.c55
-rw-r--r--drivers/reset/hisilicon/Kconfig7
-rw-r--r--drivers/reset/hisilicon/Makefile1
-rw-r--r--drivers/reset/hisilicon/reset-hi3660.c126
-rw-r--r--drivers/reset/reset-ti-syscon.c6
-rw-r--r--drivers/reset/reset-uniphier.c4
-rw-r--r--drivers/reset/reset-zx2967.c99
-rw-r--r--drivers/soc/Kconfig1
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/rockchip/Kconfig10
-rw-r--r--drivers/soc/rockchip/Makefile1
-rw-r--r--drivers/soc/rockchip/grf.c134
-rw-r--r--drivers/soc/rockchip/pm_domains.c63
-rw-r--r--drivers/soc/samsung/exynos-pmu.c6
-rw-r--r--drivers/soc/samsung/exynos5250-pmu.c2
-rw-r--r--drivers/soc/samsung/exynos5420-pmu.c4
-rw-r--r--drivers/soc/samsung/pm_domains.c31
-rw-r--r--drivers/soc/ti/knav_dma.c4
-rw-r--r--drivers/soc/ti/knav_qmss_acc.c15
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c25
-rw-r--r--drivers/soc/ti/wkup_m3_ipc.c2
-rw-r--r--drivers/soc/zte/Kconfig13
-rw-r--r--drivers/soc/zte/Makefile5
-rw-r--r--drivers/soc/zte/zx296718_pm_domains.c182
-rw-r--r--drivers/soc/zte/zx2967_pm_domains.c143
-rw-r--r--drivers/soc/zte/zx2967_pm_domains.h44
-rw-r--r--include/dt-bindings/power/rk3328-power.h18
-rw-r--r--include/dt-bindings/soc/zte,pm_domains.h24
-rw-r--r--include/linux/qcom_scm.h54
-rw-r--r--include/linux/reset.h45
-rw-r--r--include/linux/soc/samsung/exynos-regs-pmu.h91
54 files changed, 1481 insertions, 288 deletions
diff --git a/Documentation/devicetree/bindings/power/pd-samsung.txt b/Documentation/devicetree/bindings/power/pd-samsung.txt
index 4e947372a693..7eb9674e9687 100644
--- a/Documentation/devicetree/bindings/power/pd-samsung.txt
+++ b/Documentation/devicetree/bindings/power/pd-samsung.txt
@@ -6,12 +6,15 @@ to gate power to one or more peripherals on the processor.
Required Properties:
- compatible: should be one of the following.
* samsung,exynos4210-pd - for exynos4210 type power domain.
+ * samsung,exynos5433-pd - for exynos5433 type power domain.
- reg: physical base address of the controller and length of memory mapped
region.
- #power-domain-cells: number of cells in power domain specifier;
must be 0.
Optional Properties:
+- label: Human readable string with domain name. Will be visible in userspace
+ to let user to distinguish between multiple domains in SoC.
- clocks: List of clock handles. The parent clocks of the input clocks to the
devices in this power domain are set to oscclk before power gating
and restored back after powering on a domain. This is required for
@@ -38,6 +41,7 @@ Example:
compatible = "samsung,exynos4210-pd";
reg = <0x10023C00 0x10>;
#power-domain-cells = <0>;
+ label = "LCD0";
};
mfc_pd: power-domain@10044060 {
@@ -46,6 +50,7 @@ Example:
clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_USER_ACLK333>;
clock-names = "oscclk", "clk0";
#power-domain-cells = <0>;
+ label = "MFC";
};
See Documentation/devicetree/bindings/power/power_domain.txt for description
diff --git a/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
new file mode 100644
index 000000000000..2bf3344b2a02
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/hisilicon,hi3660-reset.txt
@@ -0,0 +1,43 @@
+Hisilicon System Reset Controller
+======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+The reset controller registers are part of the system-ctl block on
+hi3660 SoC.
+
+Required properties:
+- compatible: should be
+ "hisilicon,hi3660-reset"
+- hisi,rst-syscon: phandle of the reset's syscon.
+- #reset-cells : Specifies the number of cells needed to encode a
+ reset source. The type shall be a <u32> and the value shall be 2.
+
+ Cell #1 : offset of the reset assert control
+ register from the syscon register base
+ offset + 4: deassert control register
+ offset + 8: status control register
+ Cell #2 : bit position of the reset in the reset control register
+
+Example:
+ iomcu: iomcu@ffd7e000 {
+ compatible = "hisilicon,hi3660-iomcu", "syscon";
+ reg = <0x0 0xffd7e000 0x0 0x1000>;
+ };
+
+ iomcu_rst: iomcu_rst_controller {
+ compatible = "hisilicon,hi3660-reset";
+ hisi,rst-syscon = <&iomcu>;
+ #reset-cells = <2>;
+ };
+
+Specifying reset lines connected to IP modules
+==============================================
+example:
+
+ i2c0: i2c@..... {
+ ...
+ resets = <&iomcu_rst 0x20 3>; /* offset: 0x20; bit: 3 */
+ ...
+ };
diff --git a/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt b/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt
index 164c7f34c451..c516d24959f2 100644
--- a/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt
+++ b/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt
@@ -63,7 +63,7 @@ Example:
--------
The following example demonstrates a syscon node, the reset controller node
using the syscon node, and a consumer (a DSP device) on the TI Keystone 2
-Edison SoC.
+66AK2E SoC.
/ {
soc {
@@ -71,13 +71,13 @@ Edison SoC.
compatible = "syscon", "simple-mfd";
reg = <0x02350000 0x1000>;
- pscrst: psc-reset {
+ pscrst: reset-controller {
compatible = "ti,k2e-pscrst", "ti,syscon-reset";
#reset-cells = <1>;
ti,reset-bits = <
- 0xa3c 8 0xa3c 8 0x83c 8 (ASSERT_SET|DEASSERT_CLEAR|STATUS_SET) /* 0: pcrst-dsp0 */
- 0xa40 5 0xa44 3 0 0 (ASSERT_SET|DEASSERT_CLEAR|STATUS_NONE) /* 1: pcrst-example */
+ 0xa3c 8 0xa3c 8 0x83c 8 (ASSERT_CLEAR | DEASSERT_SET | STATUS_CLEAR) /* 0: dsp0 */
+ 0xa40 5 0xa44 3 0 0 (ASSERT_SET | DEASSERT_CLEAR | STATUS_NONE) /* 1: example */
>;
};
};
diff --git a/Documentation/devicetree/bindings/reset/uniphier-reset.txt b/Documentation/devicetree/bindings/reset/uniphier-reset.txt
index 5020524cddeb..83ab0f599c40 100644
--- a/Documentation/devicetree/bindings/reset/uniphier-reset.txt
+++ b/Documentation/devicetree/bindings/reset/uniphier-reset.txt
@@ -6,14 +6,14 @@ System reset
Required properties:
- compatible: should be one of the following:
- "socionext,uniphier-sld3-reset" - for sLD3 SoC.
- "socionext,uniphier-ld4-reset" - for LD4 SoC.
- "socionext,uniphier-pro4-reset" - for Pro4 SoC.
- "socionext,uniphier-sld8-reset" - for sLD8 SoC.
- "socionext,uniphier-pro5-reset" - for Pro5 SoC.
- "socionext,uniphier-pxs2-reset" - for PXs2/LD6b SoC.
- "socionext,uniphier-ld11-reset" - for LD11 SoC.
- "socionext,uniphier-ld20-reset" - for LD20 SoC.
+ "socionext,uniphier-sld3-reset" - for sLD3 SoC
+ "socionext,uniphier-ld4-reset" - for LD4 SoC
+ "socionext,uniphier-pro4-reset" - for Pro4 SoC
+ "socionext,uniphier-sld8-reset" - for sLD8 SoC
+ "socionext,uniphier-pro5-reset" - for Pro5 SoC
+ "socionext,uniphier-pxs2-reset" - for PXs2/LD6b SoC
+ "socionext,uniphier-ld11-reset" - for LD11 SoC
+ "socionext,uniphier-ld20-reset" - for LD20 SoC
- #reset-cells: should be 1.
Example:
@@ -37,14 +37,15 @@ Media I/O (MIO) reset, SD reset
Required properties:
- compatible: should be one of the following:
- "socionext,uniphier-sld3-mio-reset" - for sLD3 SoC.
- "socionext,uniphier-ld4-mio-reset" - for LD4 SoC.
- "socionext,uniphier-pro4-mio-reset" - for Pro4 SoC.
- "socionext,uniphier-sld8-mio-reset" - for sLD8 SoC.
- "socionext,uniphier-pro5-sd-reset" - for Pro5 SoC.
- "socionext,uniphier-pxs2-sd-reset" - for PXs2/LD6b SoC.
- "socionext,uniphier-ld11-mio-reset" - for LD11 SoC.
- "socionext,uniphier-ld20-sd-reset" - for LD20 SoC.
+ "socionext,uniphier-sld3-mio-reset" - for sLD3 SoC
+ "socionext,uniphier-ld4-mio-reset" - for LD4 SoC
+ "socionext,uniphier-pro4-mio-reset" - for Pro4 SoC
+ "socionext,uniphier-sld8-mio-reset" - for sLD8 SoC
+ "socionext,uniphier-pro5-sd-reset" - for Pro5 SoC
+ "socionext,uniphier-pxs2-sd-reset" - for PXs2/LD6b SoC
+ "socionext,uniphier-ld11-mio-reset" - for LD11 SoC (MIO)
+ "socionext,uniphier-ld11-sd-reset" - for LD11 SoC (SD)
+ "socionext,uniphier-ld20-sd-reset" - for LD20 SoC
- #reset-cells: should be 1.
Example:
@@ -68,13 +69,13 @@ Peripheral reset
Required properties:
- compatible: should be one of the following:
- "socionext,uniphier-ld4-peri-reset" - for LD4 SoC.
- "socionext,uniphier-pro4-peri-reset" - for Pro4 SoC.
- "socionext,uniphier-sld8-peri-reset" - for sLD8 SoC.
- "socionext,uniphier-pro5-peri-reset" - for Pro5 SoC.
- "socionext,uniphier-pxs2-peri-reset" - for PXs2/LD6b SoC.
- "socionext,uniphier-ld11-peri-reset" - for LD11 SoC.
- "socionext,uniphier-ld20-peri-reset" - for LD20 SoC.
+ "socionext,uniphier-ld4-peri-reset" - for LD4 SoC
+ "socionext,uniphier-pro4-peri-reset" - for Pro4 SoC
+ "socionext,uniphier-sld8-peri-reset" - for sLD8 SoC
+ "socionext,uniphier-pro5-peri-reset" - for Pro5 SoC
+ "socionext,uniphier-pxs2-peri-reset" - for PXs2/LD6b SoC
+ "socionext,uniphier-ld11-peri-reset" - for LD11 SoC
+ "socionext,uniphier-ld20-peri-reset" - for LD20 SoC
- #reset-cells: should be 1.
Example:
diff --git a/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
new file mode 100644
index 000000000000..b015508f9780
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
@@ -0,0 +1,20 @@
+ZTE zx2967 SoCs Reset Controller
+=======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: should be one of the following.
+ * zte,zx296718-reset
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- #reset-cells: must be 1.
+
+example:
+
+ reset: reset-controller@1461060 {
+ compatible = "zte,zx296718-reset";
+ reg = <0x01461060 0x8>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.txt b/Documentation/devicetree/bindings/soc/rockchip/grf.txt
index 013e71a2cdc7..c6e62cb30712 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/grf.txt
+++ b/Documentation/devicetree/bindings/soc/rockchip/grf.txt
@@ -5,11 +5,13 @@ is composed of many registers for system control.
From RK3368 SoCs, the GRF is divided into two sections,
- GRF, used for general non-secure system,
+- SGRF, used for general secure system,
- PMUGRF, used for always on system
Required Properties:
- compatible: GRF should be one of the followings
+ - "rockchip,rk3036-grf", "syscon": for rk3036
- "rockchip,rk3066-grf", "syscon": for rk3066
- "rockchip,rk3188-grf", "syscon": for rk3188
- "rockchip,rk3228-grf", "syscon": for rk3228
@@ -19,6 +21,8 @@ Required Properties:
- compatible: PMUGRF should be one of the followings
- "rockchip,rk3368-pmugrf", "syscon": for rk3368
- "rockchip,rk3399-pmugrf", "syscon": for rk3399
+- compatible: SGRF should be one of the following
+ - "rockchip,rk3288-sgrf", "syscon": for rk3288
- reg: physical base address of the controller and length of memory mapped
region.
diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
index f909ce06afc4..01bfb6745fbd 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
+++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
@@ -6,6 +6,7 @@ powered up/down by software based on different application scenes to save power.
Required properties for power domain controller:
- compatible: Should be one of the following.
"rockchip,rk3288-power-controller" - for RK3288 SoCs.
+ "rockchip,rk3328-power-controller" - for RK3328 SoCs.
"rockchip,rk3368-power-controller" - for RK3368 SoCs.
"rockchip,rk3399-power-controller" - for RK3399 SoCs.
- #power-domain-cells: Number of cells in a power-domain specifier.
@@ -16,6 +17,7 @@ Required properties for power domain controller:
Required properties for power domain sub nodes:
- reg: index of the power domain, should use macros in:
"include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
+ "include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain.
"include/dt-bindings/power/rk3368-power.h" - for RK3368 type power domain.
"include/dt-bindings/power/rk3399-power.h" - for RK3399 type power domain.
- clocks (optional): phandles to clocks which need to be enabled while power domain
@@ -90,6 +92,7 @@ containing a phandle to the power device node and an index specifying which
power domain to use.
The index should use macros in:
"include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain.
+ "include/dt-bindings/power/rk3328-power.h" - for rk3328 type power domain.
"include/dt-bindings/power/rk3368-power.h" - for rk3368 type power domain.
"include/dt-bindings/power/rk3399-power.h" - for rk3399 type power domain.
diff --git a/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt b/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt
new file mode 100644
index 000000000000..7629de1c2c72
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt
@@ -0,0 +1,19 @@
+* ZTE zx2967 family Power Domains
+
+zx2967 family includes support for multiple power domains which are used
+to gate power to one or more peripherals on the processor.
+
+Required Properties:
+ - compatible: should be one of the following.
+ * zte,zx296718-pcu - for zx296718 power domain.
+ - reg: physical base address of the controller and length of memory mapped
+ region.
+ - #power-domain-cells: Must be 1.
+
+Example:
+
+ pcu_domain: pcu@117000 {
+ compatible = "zte,zx296718-pcu";
+ reg = <0x00117000 0x1000>;
+ #power-domain-cells = <1>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 3ac9346cf6a8..1b3a9cb8d7f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1633,6 +1633,7 @@ F: arch/arm64/boot/dts/qcom/*
F: drivers/i2c/busses/i2c-qup.c
F: drivers/clk/qcom/
F: drivers/pinctrl/qcom/
+F: drivers/dma/qcom/
F: drivers/soc/qcom/
F: drivers/spi/spi-qup.c
F: drivers/tty/serial/msm_serial.h
@@ -1987,12 +1988,18 @@ F: arch/arm/mach-pxa/include/mach/z2.h
ARM/ZTE ARCHITECTURE
M: Jun Nie <jun.nie@linaro.org>
+M: Baoyou Xie <baoyou.xie@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-zx/
F: drivers/clk/zte/
+F: drivers/reset/reset-zx2967.c
+F: drivers/soc/zte/
F: Documentation/devicetree/bindings/arm/zte.txt
F: Documentation/devicetree/bindings/clock/zx296702-clk.txt
+F: Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
+F: Documentation/devicetree/bindings/soc/zte/
+F: include/dt-bindings/soc/zx*.h
ARM/ZYNQ ARCHITECTURE
M: Michal Simek <michal.simek@xilinx.com>
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index 312d3a886e92..adf4e8f182bd 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -345,9 +345,9 @@ static void exynos5420_pm_prepare(void)
if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0);
- tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION);
- tmp &= ~EXYNOS5_USE_RETENTION;
- pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION);
+ tmp = pmu_raw_readl(EXYNOS_L2_OPTION(0));
+ tmp &= ~EXYNOS_L2_USE_RETENTION;
+ pmu_raw_writel(tmp, EXYNOS_L2_OPTION(0));
tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
tmp |= EXYNOS5420_UFS;
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index a7ab9ec141f8..ef0500a4c8ad 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -29,13 +29,11 @@
#include "core.h"
#include "pm.h"
-#define RK3288_GRF_SOC_CON0 0x244
#define RK3288_TIMER6_7_PHYS 0xff810000
static void __init rockchip_timer_init(void)
{
if (of_machine_is_compatible("rockchip,rk3288")) {
- struct regmap *grf;
void __iomem *reg_base;
/*
@@ -54,16 +52,6 @@ static void __init rockchip_timer_init(void)
} else {
pr_err("rockchip: could not map timer7 registers\n");
}
-
- /*
- * Disable auto jtag/sdmmc switching that causes issues
- * with the mmc controllers making them unreliable
- */
- grf = syscon_regmap_lookup_by_compatible("rockchip,rk3288-grf");
- if (!IS_ERR(grf))
- regmap_write(grf, RK3288_GRF_SOC_CON0, 0x10000000);
- else
- pr_err("rockchip: could not get grf syscon\n");
}
of_clk_init(NULL);
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 0cc08f892fea..5db6ab261643 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -398,6 +398,9 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
int pmp, unsigned long deadline,
int (*check_ready)(struct ata_link *link));
+int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline, bool *online);
+
unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
int ahci_stop_engine(struct ata_port *ap);
void ahci_start_fis_rx(struct ata_port *ap);
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 267a3d3e79f4..1a50cd3b4233 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -16,7 +16,8 @@
#include <linux/ahci_platform.h>
#include "ahci.h"
-#define DRV_NAME "ahci_da850"
+#define DRV_NAME "ahci_da850"
+#define HARDRESET_RETRIES 5
/* SATA PHY Control Register offset from AHCI base */
#define SATA_P0PHYCR_REG 0x178
@@ -28,17 +29,8 @@
#define SATA_PHY_TXSWING(x) ((x) << 19)
#define SATA_PHY_ENPLL(x) ((x) << 31)
-/*
- * The multiplier needed for 1.5GHz PLL output.
- *
- * NOTE: This is currently hardcoded to be suitable for 100MHz crystal
- * frequency (which is used by DA850 EVM board) and may need to be changed
- * if you would like to use this driver on some other board.
- */
-#define DA850_SATA_CLK_MULTIPLIER 7
-
static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg,
- void __iomem *ahci_base)
+ void __iomem *ahci_base, u32 mpy)
{
unsigned int val;
@@ -47,18 +39,122 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg,
val &= ~BIT(0);
writel(val, pwrdn_reg);
- val = SATA_PHY_MPY(DA850_SATA_CLK_MULTIPLIER + 1) | SATA_PHY_LOS(1) |
- SATA_PHY_RXCDR(4) | SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) |
- SATA_PHY_ENPLL(1);
+ val = SATA_PHY_MPY(mpy) | SATA_PHY_LOS(1) | SATA_PHY_RXCDR(4) |
+ SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) | SATA_PHY_ENPLL(1);
writel(val, ahci_base + SATA_P0PHYCR_REG);
}
+static u32 ahci_da850_calculate_mpy(unsigned long refclk_rate)
+{
+ u32 pll_output = 1500000000, needed;
+
+ /*
+ * We need to determine the value of the multiplier (MPY) bits.
+ * In order to include the 12.5 multiplier we need to first divide
+ * the refclk rate by ten.
+ *
+ * __div64_32() turned out to be unreliable, sometimes returning
+ * false results.
+ */
+ WARN((refclk_rate % 10) != 0, "refclk must be divisible by 10");
+ needed = pll_output / (refclk_rate / 10);
+
+ /*
+ * What we have now is (multiplier * 10).
+ *
+ * Let's determine the actual register value we need to write.
+ */
+
+ switch (needed) {
+ case 50:
+ return 0x1;
+ case 60:
+ return 0x2;
+ case 80:
+ return 0x4;
+ case 100:
+ return 0x5;
+ case 120:
+ return 0x6;
+ case 125:
+ return 0x7;
+ case 150:
+ return 0x8;
+ case 200:
+ return 0x9;
+ case 250:
+ return 0xa;
+ default:
+ /*
+ * We should have divided evenly - if not, return an invalid
+ * value.
+ */
+ return 0;
+ }
+}
+
+static int ahci_da850_softreset(struct ata_link *link,
+ unsigned int *class, unsigned long deadline)
+{
+ int pmp, ret;
+
+ pmp = sata_srst_pmp(link);
+
+ /*
+ * There's an issue with the SATA controller on da850 SoCs: if we
+ * enable Port Multiplier support, but the drive is connected directly
+ * to the board, it can't be detected. As a workaround: if PMP is
+ * enabled, we first call ahci_do_softreset() and pass it the result of
+ * sata_srst_pmp(). If this call fails, we retry with pmp = 0.
+ */
+ ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
+ if (pmp && ret == -EBUSY)
+ return ahci_do_softreset(link, class, 0,
+ deadline, ahci_check_ready);
+
+ return ret;
+}
+
+static int ahci_da850_hardreset(struct ata_link *link,
+ unsigned int *class, unsigned long deadline)
+{
+ int ret, retry = HARDRESET_RETRIES;
+ bool online;
+
+ /*
+ * In order to correctly service the LCD controller of the da850 SoC,
+ * we increased the PLL0 frequency to 456MHz from the default 300MHz.
+ *
+ * This made the SATA controller unstable and the hardreset operation
+ * does not always succeed the first time. Before really giving up to
+ * bring up the link, retry the reset a couple times.