Watch
1
Fork
You've already forked kernel_a52xq
0
mirror of https://github.com/a52xq-dev/kernel.git synced 2026-10-18 21:58:11 +07:00

ARM: SoC driver updates

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)
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJYrM7/AAoJEIwa5zzehBx3qisP/18NwvbYvC3rMza7k+TEU66n
 vuEF9KW5GhUpQPbNIsTer5qHhC7ZgL7RoR/H7mpZcCxfhYiNXuUaOv8TMGK+WTLQ
 HH6QTs4mARLh1IrRcog1hoElzzqMVxaQgODeaaG1DcPvTqHWsQurbXsf17tCQOri
 nWKyxFpLNlu0kktkGb5JWrM4XBjU9KsW7LME9H86wG8HmB6+mcT5ddeYwW5nD8cG
 txXgmMjdTEKcpbeTg3cAzL4504auhIl4R9uK+8dc1sw+e9T0nXNDS9IkmLPwWtSR
 u8q6zQ3zReoDw4jGUgPP0ILHudfQsiMdWS+P2hw/krpbtLlQ+irHDVa1VA3NLiUT
 9aG9cNTYRMo3ct22YEeWsnAC04XOxpCsqHTR+UWuZaBmf3eoMIXnsafTuwLzqKlQ
 Ent/4eFPInMAzDH8Kaf1Hh0918qkgF2bNlshem11TccQKvHP+qCoHk6mKGxwEj5k
 E1UEG4S6k6zNqjLwmTBBbk8sLMl/WVo6RMSMz+JflatgPmVZco4EX2O73iKGAJVU
 5GfHIUG9Yl4+aTIUORu59cWxOCApK0kqERrFKe412BMurXlLfqVcr/H2tiiuWnn1
 cEJ9d+uBd8IxTIQX0iEYGUAkX97mhxGUYdqGQuGJSV+MOfWX1zNP1sI4EscLGKQj
 sDDZScCaguM4xE20Jum1
 =od7u
 -----END PGP SIGNATURE-----

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
  ...
This commit is contained in:
Linus Torvalds 2017-02-23 15:57:04 -08:00
commit b2e3c4319d
54 changed files with 1481 additions and 288 deletions

View file

@ -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

View file

@ -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 */
...
};

View file

@ -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 */
>;
};
};

View file

@ -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:

View file

@ -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>;
};

View file

@ -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.

View file

@ -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.

View file

@ -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>;
};

View file

@ -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>

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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.
*/
do {
ret = ahci_do_hardreset(link, class, deadline, &online);
if (online)
return ret;
} while (retry--);
return ret;
}
static struct ata_port_operations ahci_da850_port_ops = {
.inherits = &ahci_platform_ops,
.softreset = ahci_da850_softreset,
/*
* No need to override .pmp_softreset - it's only used for actual
* PMP-enabled ports.
*/
.hardreset = ahci_da850_hardreset,
.pmp_hardreset = ahci_da850_hardreset,
};
static const struct ata_port_info ahci_da850_port_info = {
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_platform_ops,
.port_ops = &ahci_da850_port_ops,
};
static struct scsi_host_template ahci_platform_sht = {
@ -69,14 +165,52 @@ static int ahci_da850_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
struct resource *res;
void __iomem *pwrdn_reg;
struct resource *res;
struct clk *clk;
u32 mpy;
int rc;
hpriv = ahci_platform_get_resources(pdev);
if (IS_ERR(hpriv))
return PTR_ERR(hpriv);
/*
* Internally ahci_platform_get_resources() calls clk_get(dev, NULL)
* when trying to obtain the functional clock. This SATA controller
* uses two clocks for which we specify two connection ids. If we don't
* have the functional clock at this point - call clk_get() again with
* con_id = "fck".
*/
if (!hpriv->clks[0]) {
clk = clk_get(dev, "fck");
if (IS_ERR(clk))
return PTR_ERR(clk);
hpriv->clks[0] = clk;
}
/*
* The second clock used by ahci-da850 is the external REFCLK. If we
* didn't get it from ahci_platform_get_resources(), let's try to
* specify the con_id in clk_get().
*/
if (!hpriv->clks[1]) {
clk = clk_get(dev, "refclk");
if (IS_ERR(clk)) {
dev_err(dev, "unable to obtain the reference clock");
return -ENODEV;
}
hpriv->clks[1] = clk;
}
mpy = ahci_da850_calculate_mpy(clk_get_rate(hpriv->clks[1]));
if (mpy == 0) {
dev_err(dev, "invalid REFCLK multiplier value: 0x%x", mpy);
return -EINVAL;
}
rc = ahci_platform_enable_resources(hpriv);
if (rc)
return rc;
@ -89,7 +223,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
if (!pwrdn_reg)
goto disable_resources;
da850_sata_init(dev, pwrdn_reg, hpriv->mmio);
da850_sata_init(dev, pwrdn_reg, hpriv->mmio, mpy);
rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info,
&ahci_platform_sht);
@ -105,11 +239,18 @@ disable_resources:
static SIMPLE_DEV_PM_OPS(ahci_da850_pm_ops, ahci_platform_suspend,
ahci_platform_resume);
static const struct of_device_id ahci_da850_of_match[] = {
{ .compatible = "ti,da850-ahci", },
{ },
};
MODULE_DEVICE_TABLE(of, ahci_da850_of_match);
static struct platform_driver ahci_da850_driver = {
.probe = ahci_da850_probe,
.remove = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = ahci_da850_of_match,
.pm = &ahci_da850_pm_ops,
},
};

View file

@ -1519,8 +1519,8 @@ static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class,
return rc;
}
static int ahci_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline, bool *online)
{
const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
struct ata_port *ap = link->ap;
@ -1528,7 +1528,6 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
struct ahci_host_priv *hpriv = ap->host->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
bool online;
int rc;
DPRINTK("ENTER\n");
@ -1540,17 +1539,26 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
tf.command = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
rc = sata_link_hardreset(link, timing, deadline, &online,
rc = sata_link_hardreset(link, timing, deadline, online,
ahci_check_ready);
hpriv->start_engine(ap);
if (online)
if (*online)
*class = ahci_dev_classify(ap);
DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
return rc;
}
EXPORT_SYMBOL_GPL(ahci_do_hardreset);
static int ahci_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
bool online;
return ahci_do_hardreset(link, class, deadline, &online);
}
static void ahci_postreset(struct ata_link *link, unsigned int *class)
{

View file

@ -112,6 +112,7 @@ config QCOM_EBI2
bool "Qualcomm External Bus Interface 2 (EBI2)"
depends on HAS_IOMEM
depends on ARCH_QCOM || COMPILE_TEST
default ARCH_QCOM
help
Say y here to enable support for the Qualcomm External Bus
Interface 2, which can be used to connect things like NAND Flash,

View file

@ -560,3 +560,21 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
return ret ? : le32_to_cpu(out);
}
int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
{
struct {
__le32 state;
__le32 id;
} req;
__le32 scm_ret = 0;
int ret;
req.state = cpu_to_le32(state);
req.id = cpu_to_le32(id);
ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
&req, sizeof(req), &scm_ret, sizeof(scm_ret));
return ret ? : le32_to_cpu(scm_ret);
}

View file

@ -365,3 +365,19 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
return ret ? : res.a1;
}
int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
{
struct qcom_scm_desc desc = {0};
struct arm_smccc_res res;
int ret;
desc.args[0] = state;
desc.args[1] = id;
desc.arginfo = QCOM_SCM_ARGS(2);
ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
&desc, &res);
return ret ? : res.a1;
}

View file

@ -324,6 +324,12 @@ bool qcom_scm_is_available(void)
}
EXPORT_SYMBOL(qcom_scm_is_available);
int qcom_scm_set_remote_state(u32 state, u32 id)
{
return __qcom_scm_set_remote_state(__scm->dev, state, id);
}
EXPORT_SYMBOL(qcom_scm_set_remote_state);
static int qcom_scm_probe(struct platform_device *pdev)
{
struct qcom_scm *scm;
@ -387,7 +393,7 @@ static int qcom_scm_probe(struct platform_device *pdev)
static const struct of_device_id qcom_scm_dt_match[] = {
{ .compatible = "qcom,scm-apq8064",
.data = (void *) SCM_HAS_CORE_CLK,
/* FIXME: This should have .data = (void *) SCM_HAS_CORE_CLK */
},
{ .compatible = "qcom,scm-msm8660",
.data = (void *) SCM_HAS_CORE_CLK,

View file

@ -15,6 +15,8 @@
#define QCOM_SCM_SVC_BOOT 0x1
#define QCOM_SCM_BOOT_ADDR 0x1
#define QCOM_SCM_BOOT_ADDR_MC 0x11
#define QCOM_SCM_SET_REMOTE_STATE 0xa
extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id);
#define QCOM_SCM_FLAG_HLOS 0x01
#define QCOM_SCM_FLAG_COLDBOOT_MC 0x02

View file

@ -76,9 +76,11 @@ struct at91_ebi_caps {
struct at91_ebi {
struct clk *clk;
struct regmap *smc;
struct regmap *matrix;
struct {
struct regmap *regmap;
struct clk *clk;
} smc;
struct regmap_field *ebi_csa;
struct device *dev;
@ -93,7 +95,7 @@ static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid,
struct at91_ebi_dev_config *conf)
{
struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9;
unsigned int clk_rate = clk_get_rate(ebid->ebi->clk);
unsigned int clk_period = NSEC_PER_SEC / clk_get_rate(ebid->ebi->clk);
struct at91sam9_ebi_dev_config *config = &conf->sam9;
struct at91sam9_smc_timings *timings = &config->timings;
unsigned int val;
@ -102,43 +104,43 @@ static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid,
config->mode = val & ~AT91_SMC_TDF;
val = (val & AT91_SMC_TDF) >> 16;
timings->tdf_ns = clk_rate * val;
timings->tdf_ns = clk_period * val;
regmap_fields_read(fields->setup, conf->cs, &val);
timings->ncs_rd_setup_ns = (val >> 24) & 0x1f;
timings->ncs_rd_setup_ns += ((val >> 29) & 0x1) * 128;
timings->ncs_rd_setup_ns *= clk_rate;
timings->ncs_rd_setup_ns *= clk_period;
timings->nrd_setup_ns = (val >> 16) & 0x1f;
timings->nrd_setup_ns += ((val >> 21) & 0x1) * 128;
timings->nrd_setup_ns *= clk_rate;
timings->nrd_setup_ns *= clk_period;
timings->ncs_wr_setup_ns = (val >> 8) & 0x1f;
timings->ncs_wr_setup_ns += ((val >> 13) & 0x1) * 128;
timings->ncs_wr_setup_ns *= clk_rate;
timings->ncs_wr_setup_ns *= clk_period;
timings->nwe_setup_ns = val & 0x1f;
timings->nwe_setup_ns += ((val >> 5) & 0x1) * 128;
timings->nwe_setup_ns *= clk_rate;
timings->nwe_setup_ns *= clk_period;
regmap_fields_read(fields->pulse, conf->cs, &val);
timings->ncs_rd_pulse_ns = (val >> 24) & 0x3f;
timings->ncs_rd_pulse_ns += ((val >> 30) & 0x1) * 256;
timings->ncs_rd_pulse_ns *= clk_rate;
timings->ncs_rd_pulse_ns *= clk_period;
timings->nrd_pulse_ns = (val >> 16) & 0x3f;
timings->nrd_pulse_ns += ((val >> 22) & 0x1) * 256;
timings->nrd_pulse_ns *= clk_rate;
timings->nrd_pulse_ns *= clk_period;
timings->ncs_wr_pulse_ns = (val >> 8) & 0x3f;
timings->ncs_wr_pulse_ns += ((val >> 14) & 0x1) * 256;
timings->ncs_wr_pulse_ns *= clk_rate;
timings->ncs_wr_pulse_ns *= clk_period;
timings->nwe_pulse_ns = val & 0x3f;
timings->nwe_pulse_ns += ((val >> 6) & 0x1) * 256;
timings->nwe_pulse_ns *= clk_rate;
timings->nwe_pulse_ns *= clk_period;
regmap_fields_read(fields->cycle, conf->cs, &val);
timings->nrd_cycle_ns = (val >> 16) & 0x7f;
timings->nrd_cycle_ns += ((val >> 23) & 0x3) * 256;
timings->nrd_cycle_ns *= clk_rate;
timings->nrd_cycle_ns *= clk_period;
timings->nwe_cycle_ns = val & 0x7f;
timings->nwe_cycle_ns += ((val >> 7) & 0x3) * 256;
timings->nwe_cycle_ns *= clk_rate;
timings->nwe_cycle_ns *= clk_period;
}
static int at91_xlate_timing(struct device_node *np, const char *prop,
@ -334,6 +336,7 @@ static int at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid,
struct at91_ebi_dev_config *conf)
{
unsigned int clk_rate = clk_get_rate(ebid->ebi->clk);
unsigned int clk_period = NSEC_PER_SEC / clk_rate;
struct at91sam9_ebi_dev_config *config = &conf->sam9;
struct at91sam9_smc_timings *timings = &config->timings;
struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9;
@ -376,7 +379,7 @@ static int at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid,
val |= AT91SAM9_SMC_NWECYCLE(coded_val);
regmap_fields_write(fields->cycle, conf->cs, val);
val = DIV_ROUND_UP(timings->tdf_ns, clk_rate);
val = DIV_ROUND_UP(timings->tdf_ns, clk_period);
if (val > AT91_SMC_TDF_MAX)
val = AT91_SMC_TDF_MAX;
regmap_fields_write(fields->mode, conf->cs,
@ -394,22 +397,26 @@ static int at91sam9_ebi_init(struct at91_ebi *ebi)
field.id_offset = AT91SAM9_SMC_GENERIC_BLK_SZ;
field.reg = AT91SAM9_SMC_SETUP(AT91SAM9_SMC_GENERIC);
fields->setup = devm_regmap_field_alloc(ebi->dev, ebi->smc, field);
fields->setup = devm_regmap_field_alloc(ebi->dev, ebi->smc.regmap,
field);
if (IS_ERR(fields->setup))
return PTR_ERR(fields->setup);
field.reg = AT91SAM9_SMC_PULSE(AT91SAM9_SMC_GENERIC);
fields->pulse = devm_regmap_field_alloc(ebi->dev, ebi->smc, field);
fields->pulse = devm_regmap_field_alloc(ebi->dev, ebi->smc.regmap,
field);
if (IS_ERR(fields->pulse))
return PTR_ERR(fields->pulse);
field.reg = AT91SAM9_SMC_CYCLE(AT91SAM9_SMC_GENERIC);
fields->cycle = devm_regmap_field_alloc(ebi->dev, ebi->smc, field);
fields->cycle = devm_regmap_field_alloc(ebi->dev, ebi->smc.regmap,
field);
if (IS_ERR(fields->cycle))
return PTR_ERR(fields->cycle);
field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC);
fields->mode = devm_regmap_field_alloc(ebi->dev, ebi->smc, field);
fields->mode = devm_regmap_field_alloc(ebi->dev, ebi->smc.regmap,
field);
return PTR_ERR_OR_ZERO(fields->mode);
}
@ -422,22 +429,26 @@ static int sama5d3_ebi_init(struct at91_ebi *ebi)
field.id_offset = SAMA5_SMC_GENERIC_BLK_SZ;
field.reg = AT91SAM9_SMC_SETUP(SAMA5_SMC_GENERIC);
fields->setup = devm_regmap_field_alloc(ebi->dev, ebi->smc, field);
fields->setup = devm_regmap_field_alloc(ebi->dev, ebi->smc.regmap,
field);
if (IS_ERR(fields->setup))
return PTR_ERR(fields->setup);
field.reg = AT91SAM9_SMC_PULSE(SAMA5_SMC_GENERIC);
fields->pulse = devm_regmap_field_alloc(ebi->dev, ebi->smc, field);
fields->pulse = devm_regmap_field_alloc(ebi->dev, ebi->smc.regmap,
field);
if (IS_ERR(fields->pulse))
return PTR_ERR(fields->pulse);
field.reg = AT91SAM9_SMC_CYCLE(SAMA5_SMC_GENERIC);
fields->cycle = devm_regmap_field_alloc(ebi->dev, ebi->smc, field);
fields->cycle = devm_regmap_field_alloc(ebi->dev, ebi->smc.regmap,
field);
if (IS_ERR(fields->cycle))
return PTR_ERR(fields->cycle);
field.reg = SAMA5_SMC_MODE(SAMA5_SMC_GENERIC);
fields->mode = devm_regmap_field_alloc(ebi->dev, ebi->smc, field);
fields->mode = devm_regmap_field_alloc(ebi->dev, ebi->smc.regmap,
field);
return PTR_ERR_OR_ZERO(fields->mode);
}
@ -448,12 +459,31 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np,
struct at91_ebi_dev_config conf = { };
struct device *dev = ebi->dev;
struct at91_ebi_dev *ebid;
int ret, numcs = 0, i;
unsigned long cslines = 0;
int ret, numcs = 0, nentries, i;
bool apply = false;
u32 cs;
numcs = of_property_count_elems_of_size(np, "reg",
reg_cells * sizeof(u32));
if (numcs <= 0) {
nentries = of_property_count_elems_of_size(np, "reg",
reg_cells * sizeof(u32));
for (i = 0; i < nentries; i++) {
ret = of_property_read_u32_index(np, "reg", i * reg_cells,
&cs);
if (ret)
return ret;
if (cs >= AT91_MATRIX_EBI_NUM_CS ||
!(ebi->caps->available_cs & BIT(cs))) {
dev_err(dev, "invalid reg property in %s\n",
np->full_name);
return -EINVAL;
}
if (!test_and_set_bit(cs, &cslines))
numcs++;
}
if (!numcs) {
dev_err(dev, "invalid reg property in %s\n", np->full_name);
return -EINVAL;
}
@ -472,21 +502,8 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np,
else if (ret)
apply = true;
for (i = 0; i < numcs; i++) {
u32 cs;
ret = of_property_read_u32_index(np, "reg", i * reg_cells,
&cs);
if (ret)
return ret;
if (cs > AT91_MATRIX_EBI_NUM_CS ||
!(ebi->caps->available_cs & BIT(cs))) {
dev_err(dev, "invalid reg property in %s\n",
np->full_name);
return -EINVAL;
}
i = 0;
for_each_set_bit(cs, &cslines, AT91_MATRIX_EBI_NUM_CS) {
ebid->configs[i].cs = cs;
if (apply) {
@ -502,9 +519,11 @@ static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np,
* Attach the EBI device to the generic SMC logic if at least
* one "atmel,smc-" property is present.
*/
if (ebi->ebi_csa && ret)
if (ebi->ebi_csa && apply)
regmap_field_update_bits(ebi->ebi_csa,
BIT(cs), 0);
i++;
}
list_add_tail(&ebid->node, &ebi->devs);
@ -668,7 +687,7 @@ static int at91_ebi_dev_disable(struct at91_ebi *ebi, struct device_node *np)
static int at91_ebi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *child, *np = dev->of_node;
struct device_node *child, *np = dev->of_node, *smc_np;
const struct of_device_id *match;
struct at91_ebi *ebi;
int ret, reg_cells;
@ -693,9 +712,22 @@ static int at91_ebi_probe(struct platform_device *pdev)
ebi->clk = clk;
ebi->smc = syscon_regmap_lookup_by_phandle(np, "atmel,smc");
if (IS_ERR(ebi->smc))
return PTR_ERR(ebi->smc);
smc_np = of_parse_phandle(dev->of_node, "atmel,smc", 0);
ebi->smc.regmap = syscon_node_to_regmap(smc_np);
if (IS_ERR(ebi->smc.regmap))
return PTR_ERR(ebi->smc.regmap);
ebi->smc.clk = of_clk_get(smc_np, 0);
if (IS_ERR(ebi->smc.clk)) {
if (PTR_ERR(ebi->smc.clk) != -ENOENT)
return PTR_ERR(ebi->smc.clk);
ebi->smc.clk = NULL;
}
ret = clk_prepare_enable(ebi->smc.clk);
if (ret)
return ret;
/*
* The sama5d3 does not provide an EBICSA register and thus does need

Some files were not shown because too many files have changed in this diff Show more