summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2017-02-16 17:15:39 +0100
committerArnd Bergmann <arnd@arndb.de>2017-02-16 17:15:39 +0100
commitaf1d09eefa72089300ddde13bbaf9af1a82c6be1 (patch)
tree001a2680400ab2ae8cfb99b72c0dfa41c0e79f25 /arch
parentc6057e101a2d09d24d84a3d2d701fd5e71f5e26a (diff)
parenta3035886852cd859e371550fe726da08b85c67d0 (diff)
Merge tag 'davinci-for-v4.11/soc-2' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci into next/soc
Pull "SoC updates needed for SATA support on DA850" from Sekhar Nori: This includes a merge of non-critical-fixes branch already queued for v4.11 because SATA clock addition conflicts with the fix-up done earlier. * tag 'davinci-for-v4.11/soc-2' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci: ARM: davinci: remove BUG_ON() from da850_register_sata() ARM: davinci: da850: model the SATA refclk ARM: davinci: da850: add con_id for the SATA clock ARM: davinci: da8xx-dt: add OF_DEV_AUXDATA entry for SATA ARM: davinci: add skeleton for pdata-quirks bus: da850-mstpri: fix my e-mail address ARM: davinci: da850: fix da850_set_pll0rate() ARM: davinci: da850: coding style fix
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-davinci/Makefile2
-rw-r--r--arch/arm/mach-davinci/da850.c24
-rw-r--r--arch/arm/mach-davinci/da8xx-dt.c10
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c30
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h2
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h1
-rw-r--r--arch/arm/mach-davinci/pdata-quirks.c39
7 files changed, 100 insertions, 8 deletions
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 0a2e6da45f28..df96ca9eab6d 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_AINTC) += irq.o
obj-$(CONFIG_CP_INTC) += cp_intc.o
# Board specific
-obj-$(CONFIG_MACH_DA8XX_DT) += da8xx-dt.o
+obj-$(CONFIG_MACH_DA8XX_DT) += da8xx-dt.o pdata-quirks.o
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o
obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 1d873d15b545..d09765ba246b 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -571,7 +571,7 @@ static struct clk_lookup da850_clks[] = {
CLK("spi_davinci.0", NULL, &spi0_clk),
CLK("spi_davinci.1", NULL, &spi1_clk),
CLK("vpif", NULL, &vpif_clk),
- CLK("ahci_da850", NULL, &sata_clk),
+ CLK("ahci_da850", "fck", &sata_clk),
CLK("davinci-rproc.0", NULL, &dsp_clk),
CLK(NULL, NULL, &ehrpwm_clk),
CLK("ehrpwm.0", "fck", &ehrpwm0_clk),
@@ -1202,14 +1202,28 @@ static int da850_set_armrate(struct clk *clk, unsigned long index)
return clk_set_rate(pllclk, index);
}
-static int da850_set_pll0rate(struct clk *clk, unsigned long index)
+static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
{
- unsigned int prediv, mult, postdiv;
- struct da850_opp *opp;
struct pll_data *pll = clk->pll_data;
+ struct cpufreq_frequency_table *freq;
+ unsigned int prediv, mult, postdiv;
+ struct da850_opp *opp = NULL;
int ret;
- opp = (struct da850_opp *) cpufreq_info.freq_table[index].driver_data;
+ rate /= 1000;
+
+ for (freq = da850_freq_table;
+ freq->frequency != CPUFREQ_TABLE_END; freq++) {
+ /* rate is in Hz, freq->frequency is in KHz */
+ if (freq->frequency == rate) {
+ opp = (struct da850_opp *)freq->driver_data;
+ break;
+ }
+ }
+
+ if (!opp)
+ return -EINVAL;
+
prediv = opp->prediv;
mult = opp->mult;
postdiv = opp->postdiv;
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index 9ee44da6eb7b..071933b16a0c 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -42,6 +42,7 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci-da8xx", NULL),
OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
+ OF_DEV_AUXDATA("ti,da850-ahci", 0x01e18000, "ahci_da850", NULL),
{}
};
@@ -49,6 +50,9 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
static void __init da850_init_machine(void)
{
+ /* All existing boards use 100MHz SATA refclkpn */
+ static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
+
int ret;
ret = da8xx_register_usb20_phy_clk(false);
@@ -60,8 +64,14 @@ static void __init da850_init_machine(void)
pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
__func__, ret);
+ ret = da850_register_sata_refclk(sata_refclkpn);
+ if (ret)
+ pr_warn("%s: registering SATA REFCLK failed: %d",
+ __func__, ret);
+
of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
davinci_pm_init();
+ pdata_quirks_init();
}
static const char *const da850_boards_compat[] __initconst = {
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index c2457b3fdb5f..7cf529ffbe5a 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -24,6 +24,7 @@
#include <mach/common.h>
#include <mach/time.h>
#include <mach/da8xx.h>
+#include <mach/clock.h>
#include "cpuidle.h"
#include "sram.h"
@@ -1023,6 +1024,28 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
}
#ifdef CONFIG_ARCH_DAVINCI_DA850
+static struct clk sata_refclk = {
+ .name = "sata_refclk",
+ .set_rate = davinci_simple_set_rate,
+};
+
+static struct clk_lookup sata_refclk_lookup =
+ CLK("ahci_da850", "refclk", &sata_refclk);
+
+int __init da850_register_sata_refclk(int rate)
+{
+ int ret;
+
+ sata_refclk.rate = rate;
+ ret = clk_register(&sata_refclk);
+ if (ret)
+ return ret;
+
+ clkdev_add(&sata_refclk_lookup);
+
+ return 0;
+}
+
static struct resource da850_sata_resources[] = {
{
.start = DA850_SATA_BASE,
@@ -1055,8 +1078,11 @@ static struct platform_device da850_sata_device = {
int __init da850_register_sata(unsigned long refclkpn)
{
- /* please see comment in drivers/ata/ahci_da850.c */
- BUG_ON(refclkpn != 100 * 1000 * 1000);
+ int ret;
+
+ ret = da850_register_sata_refclk(refclkpn);
+ if (ret)
+ return ret;
return platform_device_register(&da850_sata_device);
}
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 0b3c169758ed..037aa66bcac1 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -102,6 +102,8 @@ int davinci_pm_init(void);
static inline int davinci_pm_init(void) { return 0; }
#endif
+void __init pdata_quirks_init(void);
+
#define SRAM_SIZE SZ_128K
#endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 85ff2183b6db..7e464228948b 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -95,6 +95,7 @@ int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
int da8xx_register_usb_refclkin(int rate);
int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
+int da850_register_sata_refclk(int rate);
int da8xx_register_emac(void);
int da8xx_register_uio_pruss(void);
int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
diff --git a/arch/arm/mach-davinci/pdata-quirks.c b/arch/arm/mach-davinci/pdata-quirks.c
new file mode 100644
index 000000000000..5b57da475065
--- /dev/null
+++ b/arch/arm/mach-davinci/pdata-quirks.c
@@ -0,0 +1,39 @@
+/*
+ * Legacy platform_data quirks
+ *
+ * Copyright (C) 2016 BayLibre, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/of_platform.h>
+
+#include <mach/common.h>
+
+struct pdata_init {
+ const char *compatible;
+ void (*fn)(void);
+};
+
+static void pdata_quirks_check(struct pdata_init *quirks)
+{
+ while (quirks->compatible) {
+ if (of_machine_is_compatible(quirks->compatible)) {
+ if (quirks->fn)
+ quirks->fn();
+ break;
+ }
+ quirks++;
+ }
+}
+
+static struct pdata_init pdata_quirks[] __initdata = {
+ { /* sentinel */ },
+};
+
+void __init pdata_quirks_init(void)
+{
+ pdata_quirks_check(pdata_quirks);
+}