aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/oxnas/files/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/oxnas/files/drivers')
-rw-r--r--target/linux/oxnas/files/drivers/ata/sata_oxnas.c38
-rw-r--r--target/linux/oxnas/files/drivers/clk/clk-oxnas.c297
-rw-r--r--target/linux/oxnas/files/drivers/clocksource/oxnas_rps_timer.c96
-rw-r--r--target/linux/oxnas/files/drivers/irqchip/irq-rps.c145
-rw-r--r--target/linux/oxnas/files/drivers/mtd/nand/oxnas_nand.c206
-rw-r--r--target/linux/oxnas/files/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c145
-rw-r--r--target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c276
-rw-r--r--target/linux/oxnas/files/drivers/pinctrl/pinctrl-oxnas.c1461
-rw-r--r--target/linux/oxnas/files/drivers/reset/reset-ox820.c107
-rw-r--r--target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c106
10 files changed, 385 insertions, 2492 deletions
diff --git a/target/linux/oxnas/files/drivers/ata/sata_oxnas.c b/target/linux/oxnas/files/drivers/ata/sata_oxnas.c
index 291a06f959..64afa728a1 100644
--- a/target/linux/oxnas/files/drivers/ata/sata_oxnas.c
+++ b/target/linux/oxnas/files/drivers/ata/sata_oxnas.c
@@ -29,7 +29,35 @@
#include <linux/clk.h>
#include <linux/reset.h>
-#include <mach/utils.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+
+static inline void oxnas_register_clear_mask(void __iomem *p, unsigned mask)
+{
+ u32 val = readl_relaxed(p);
+
+ val &= ~mask;
+ writel_relaxed(val, p);
+}
+
+static inline void oxnas_register_set_mask(void __iomem *p, unsigned mask)
+{
+ u32 val = readl_relaxed(p);
+
+ val |= mask;
+ writel_relaxed(val, p);
+}
+
+static inline void oxnas_register_value_mask(void __iomem *p,
+ unsigned mask, unsigned new_value)
+{
+ /* TODO sanity check mask & new_value = new_value */
+ u32 val = readl_relaxed(p);
+
+ val &= ~mask;
+ val |= new_value;
+ writel_relaxed(val, p);
+}
/* sgdma request structure */
struct sgdma_request {
@@ -848,7 +876,7 @@ wait_for_lock:
* list so want to give reentrant accessors a chance to get
* access ASAP
*/
- if (!list_empty(&hd->scsi_wait_queue.task_list))
+ if (!list_empty(&hd->scsi_wait_queue.head))
wake_up(&hd->scsi_wait_queue);
}
@@ -867,7 +895,7 @@ int sata_core_has_fast_waiters(struct ata_host *ah)
struct sata_oxnas_host_priv *hd = ah->private_data;
spin_lock_irqsave(&hd->core_lock, flags);
- has_waiters = !list_empty(&hd->fast_wait_queue.task_list);
+ has_waiters = !list_empty(&hd->fast_wait_queue.head);
spin_unlock_irqrestore(&hd->core_lock, flags);
return has_waiters;
@@ -882,7 +910,7 @@ int sata_core_has_scsi_waiters(struct ata_host *ah)
spin_lock_irqsave(&hd->core_lock, flags);
has_waiters = hd->scsi_nonblocking_attempts ||
- !list_empty(&hd->scsi_wait_queue.task_list);
+ !list_empty(&hd->scsi_wait_queue.head);
spin_unlock_irqrestore(&hd->core_lock, flags);
return has_waiters;
@@ -954,7 +982,7 @@ static void sata_oxnas_release_hw(struct ata_port *ap)
hd->locker_uid = 0;
hd->core_locked = 0;
released = 1;
- wake_up(!list_empty(&hd->scsi_wait_queue.task_list) ?
+ wake_up(!list_empty(&hd->scsi_wait_queue.head) ?
&hd->scsi_wait_queue :
&hd->fast_wait_queue);
}
diff --git a/target/linux/oxnas/files/drivers/clk/clk-oxnas.c b/target/linux/oxnas/files/drivers/clk/clk-oxnas.c
deleted file mode 100644
index 4dc6c44992..0000000000
--- a/target/linux/oxnas/files/drivers/clk/clk-oxnas.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2010 Broadcom
- * Copyright (C) 2012 Stephen Warren
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/delay.h>
-#include <linux/stringify.h>
-#include <linux/reset.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <mach/utils.h>
-
-#define MHZ (1000 * 1000)
-
-struct clk_oxnas_pllb {
- struct clk_hw hw;
- struct device_node *devnode;
- struct reset_control *rstc;
-};
-
-#define to_clk_oxnas_pllb(_hw) container_of(_hw, struct clk_oxnas_pllb, hw)
-
-static unsigned long plla_clk_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- unsigned long fin = parent_rate;
- unsigned long pll0;
- unsigned long fbdiv, refdiv, outdiv;
-
- pll0 = readl_relaxed(SYS_CTRL_PLLA_CTRL0);
- refdiv = (pll0 >> PLLA_REFDIV_SHIFT) & PLLA_REFDIV_MASK;
- refdiv += 1;
- outdiv = (pll0 >> PLLA_OUTDIV_SHIFT) & PLLA_OUTDIV_MASK;
- outdiv += 1;
- fbdiv = readl_relaxed(SYS_CTRL_PLLA_CTRL1);
-
- /* seems we will not be here when pll is bypassed, so ignore this
- * case */
-
- return fin / MHZ * fbdiv / (refdiv * outdiv) / 32768 * MHZ;
-}
-
-static const char *pll_clk_parents[] = {
- "oscillator",
-};
-
-static struct clk_ops plla_ops = {
- .recalc_rate = plla_clk_recalc_rate,
-};
-
-static struct clk_init_data clk_plla_init = {
- .name = "plla",
- .ops = &plla_ops,
- .parent_names = pll_clk_parents,
- .num_parents = ARRAY_SIZE(pll_clk_parents),
-};
-
-static struct clk_hw plla_hw = {
- .init = &clk_plla_init,
-};
-
-static int pllb_clk_is_prepared(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- return !!pllb->rstc;
-}
-
-static int pllb_clk_prepare(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- pllb->rstc = of_reset_control_get(pllb->devnode, NULL);
-
- return IS_ERR(pllb->rstc) ? PTR_ERR(pllb->rstc) : 0;
-}
-
-static void pllb_clk_unprepare(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- BUG_ON(IS_ERR(pllb->rstc));
-
- reset_control_put(pllb->rstc);
- pllb->rstc = NULL;
-}
-
-static int pllb_clk_enable(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- BUG_ON(IS_ERR(pllb->rstc));
-
- /* put PLL into bypass */
- oxnas_register_set_mask(SEC_CTRL_PLLB_CTRL0, BIT(PLLB_BYPASS));
- wmb();
- udelay(10);
- reset_control_assert(pllb->rstc);
- udelay(10);
- /* set PLL B control information */
- writel((1 << PLLB_ENSAT) | (1 << PLLB_OUTDIV) | (2 << PLLB_REFDIV),
- SEC_CTRL_PLLB_CTRL0);
- reset_control_deassert(pllb->rstc);
- udelay(100);
- oxnas_register_clear_mask(SEC_CTRL_PLLB_CTRL0, BIT(PLLB_BYPASS));
-
- return 0;
-}
-
-static void pllb_clk_disable(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- BUG_ON(IS_ERR(pllb->rstc));
-
- /* put PLL into bypass */
- oxnas_register_set_mask(SEC_CTRL_PLLB_CTRL0, BIT(PLLB_BYPASS));
- wmb();
- udelay(10);
-
- reset_control_assert(pllb->rstc);
-}
-
-static struct clk_ops pllb_ops = {
- .prepare = pllb_clk_prepare,
- .unprepare = pllb_clk_unprepare,
- .is_prepared = pllb_clk_is_prepared,
- .enable = pllb_clk_enable,
- .disable = pllb_clk_disable,
-};
-
-static struct clk_init_data clk_pllb_init = {
- .name = "pllb",
- .ops = &pllb_ops,
- .parent_names = pll_clk_parents,
- .num_parents = ARRAY_SIZE(pll_clk_parents),
-};
-
-
-/* standard gate clock */
-struct clk_std {
- struct clk_hw hw;
- signed char bit;
-};
-
-#define NUM_STD_CLKS 17
-#define to_stdclk(_hw) container_of(_hw, struct clk_std, hw)
-
-static int std_clk_is_enabled(struct clk_hw *hw)
-{
- struct clk_std *std = to_stdclk(hw);
-
- return readl_relaxed(SYSCTRL_CLK_STAT) & BIT(std->bit);
-}
-
-static int std_clk_enable(struct clk_hw *hw)
-{
- struct clk_std *std = to_stdclk(hw);
-
- writel(BIT(std->bit), SYS_CTRL_CLK_SET_CTRL);
- return 0;
-}
-
-static void std_clk_disable(struct clk_hw *hw)
-{
- struct clk_std *std = to_stdclk(hw);
-
- writel(BIT(std->bit), SYS_CTRL_CLK_CLR_CTRL);
-}
-
-static struct clk_ops std_clk_ops = {
- .enable = std_clk_enable,
- .disable = std_clk_disable,
- .is_enabled = std_clk_is_enabled,
-};
-
-static const char *std_clk_parents[] = {
- "oscillator",
-};
-
-static const char *eth_parents[] = {
- "gmacclk",
-};
-
-#define DECLARE_STD_CLKP(__clk, __bit, __parent) \
-static struct clk_init_data clk_##__clk##_init = { \
- .name = __stringify(__clk), \
- .ops = &std_clk_ops, \
- .parent_names = __parent, \
- .num_parents = ARRAY_SIZE(__parent), \
-}; \
- \
-static struct clk_std clk_##__clk = { \
- .bit = __bit, \
- .hw = { \
- .init = &clk_##__clk##_init, \
- }, \
-}
-
-#define DECLARE_STD_CLK(__clk, __bit) DECLARE_STD_CLKP(__clk, __bit, \
- std_clk_parents)
-
-DECLARE_STD_CLK(leon, 0);
-DECLARE_STD_CLK(dma_sgdma, 1);
-DECLARE_STD_CLK(cipher, 2);
-DECLARE_STD_CLK(sd, 3);
-DECLARE_STD_CLK(sata, 4);
-DECLARE_STD_CLK(audio, 5);
-DECLARE_STD_CLK(usbmph, 6);
-DECLARE_STD_CLKP(etha, 7, eth_parents);
-DECLARE_STD_CLK(pciea, 8);
-DECLARE_STD_CLK(static, 9);
-DECLARE_STD_CLK(ethb, 10);
-DECLARE_STD_CLK(pcieb, 11);
-DECLARE_STD_CLK(ref600, 12);
-DECLARE_STD_CLK(usbdev, 13);
-
-struct clk_hw *std_clk_hw_tbl[] = {
- &clk_leon.hw,
- &clk_dma_sgdma.hw,
- &clk_cipher.hw,
- &clk_sd.hw,
- &clk_sata.hw,
- &clk_audio.hw,
- &clk_usbmph.hw,
- &clk_etha.hw,
- &clk_pciea.hw,
- &clk_static.hw,
- &clk_ethb.hw,
- &clk_pcieb.hw,
- &clk_ref600.hw,
- &clk_usbdev.hw,
-};
-
-struct clk *std_clk_tbl[ARRAY_SIZE(std_clk_hw_tbl)];
-
-static struct clk_onecell_data std_clk_data;
-
-void __init oxnas_init_stdclk(struct device_node *np)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(std_clk_hw_tbl); i++) {
- std_clk_tbl[i] = clk_register(NULL, std_clk_hw_tbl[i]);
- BUG_ON(IS_ERR(std_clk_tbl[i]));
- }
- std_clk_data.clks = std_clk_tbl;
- std_clk_data.clk_num = ARRAY_SIZE(std_clk_tbl);
- of_clk_add_provider(np, of_clk_src_onecell_get, &std_clk_data);
-}
-CLK_OF_DECLARE(oxnas_pllstd, "plxtech,nas782x-stdclk", oxnas_init_stdclk);
-
-void __init oxnas_init_plla(struct device_node *np)
-{
- struct clk *clk;
-
- clk = clk_register(NULL, &plla_hw);
- BUG_ON(IS_ERR(clk));
- /* mark it as enabled */
- clk_prepare_enable(clk);
- of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(oxnas_plla, "plxtech,nas782x-plla", oxnas_init_plla);
-
-void __init oxnas_init_pllb(struct device_node *np)
-{
- struct clk *clk;
- struct clk_oxnas_pllb *pllb;
-
- pllb = kmalloc(sizeof(*pllb), GFP_KERNEL);
- BUG_ON(!pllb);
-
- pllb->hw.init = &clk_pllb_init;
- pllb->devnode = np;
- pllb->rstc = NULL;
-
- clk = clk_register(NULL, &pllb->hw);
- BUG_ON(IS_ERR(clk));
- of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(oxnas_pllb, "plxtech,nas782x-pllb", oxnas_init_pllb);
diff --git a/target/linux/oxnas/files/drivers/clocksource/oxnas_rps_timer.c b/target/linux/oxnas/files/drivers/clocksource/oxnas_rps_timer.c
deleted file mode 100644
index 7c8c4cf435..0000000000
--- a/target/linux/oxnas/files/drivers/clocksource/oxnas_rps_timer.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * arch/arm/mach-ox820/rps-time.c
- *
- * Copyright (C) 2009 Oxford Semiconductor Ltd
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/clockchips.h>
-#include <linux/clk.h>
-#include <linux/of_irq.h>
-#include <linux/of_address.h>
-#include <linux/sched_clock.h>
-#include <mach/hardware.h>
-
-enum {
- TIMER_LOAD = 0,
- TIMER_CURR = 4,
- TIMER_CTRL = 8,
- TIMER_CLRINT = 0xC,
-
- TIMER_BITS = 24,
-
- TIMER_MAX_VAL = (1 << TIMER_BITS) - 1,
-
- TIMER_PERIODIC = (1 << 6),
- TIMER_ENABLE = (1 << 7),
-
- TIMER_DIV1 = (0 << 2),
- TIMER_DIV16 = (1 << 2),
- TIMER_DIV256 = (2 << 2),
-
- TIMER1_OFFSET = 0,
- TIMER2_OFFSET = 0x20,
-
-};
-
-static u64 notrace rps_read_sched_clock(void)
-{
- return ~readl_relaxed(RPSA_TIMER2_VAL);
-}
-
-static void __init rps_clocksource_init(void __iomem *base, ulong ref_rate)
-{
- int ret;
- ulong clock_rate;
- /* use prescale 16 */
- clock_rate = ref_rate / 16;
-
- iowrite32(TIMER_MAX_VAL, base + TIMER_LOAD);
- iowrite32(TIMER_PERIODIC | TIMER_ENABLE | TIMER_DIV16,
- base + TIMER_CTRL);
-
- ret = clocksource_mmio_init(base + TIMER_CURR, "rps_clocksource_timer",
- clock_rate, 250, TIMER_BITS,
- clocksource_mmio_readl_down);
- if (ret)
- panic("can't register clocksource\n");
-
- sched_clock_register(rps_read_sched_clock, TIMER_BITS, clock_rate);
-}
-
-static void __init rps_timer_init(struct device_node *np)
-{
- struct clk *refclk;
- unsigned long ref_rate;
- void __iomem *base;
-
- refclk = of_clk_get(np, 0);
-
- if (IS_ERR(refclk) || clk_prepare_enable(refclk))
- panic("rps_timer_init: failed to get refclk\n");
- ref_rate = clk_get_rate(refclk);
-
- base = of_iomap(np, 0);
- if (!base)
- panic("rps_timer_init: failed to map io\n");
-
- rps_clocksource_init(base + TIMER2_OFFSET, ref_rate);
-}
-
-CLOCKSOURCE_OF_DECLARE(nas782x, "plxtech,nas782x-rps-timer", rps_timer_init);
diff --git a/target/linux/oxnas/files/drivers/irqchip/irq-rps.c b/target/linux/oxnas/files/drivers/irqchip/irq-rps.c
deleted file mode 100644
index f2b0829de6..0000000000
--- a/target/linux/oxnas/files/drivers/irqchip/irq-rps.c
+++ /dev/null
@@ -1,145 +0,0 @@
-#include <linux/irqdomain.h>
-#include <linux/irq.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/irqchip.h>
-
-struct rps_chip_data {
- void __iomem *base;
- struct irq_chip chip;
- struct irq_domain *domain;
-} rps_data;
-
-enum {
- RPS_IRQ_BASE = 64,
- RPS_IRQ_COUNT = 32,
- PRS_HWIRQ_BASE = 0,
-
- RPS_STATUS = 0,
- RPS_RAW_STATUS = 4,
- RPS_UNMASK = 8,
- RPS_MASK = 0xc,
-};
-
-/*
- * Routines to acknowledge, disable and enable interrupts
- */
-static void rps_mask_irq(struct irq_data *d)
-{
- struct rps_chip_data *chip_data = irq_data_get_irq_chip_data(d);
- u32 mask = BIT(d->hwirq);
-
- iowrite32(mask, chip_data->base + RPS_MASK);
-}
-
-static void rps_unmask_irq(struct irq_data *d)
-{
- struct rps_chip_data *chip_data = irq_data_get_irq_chip_data(d);
- u32 mask = BIT(d->hwirq);
-
- iowrite32(mask, chip_data->base + RPS_UNMASK);
-}
-
-static struct irq_chip rps_chip = {
- .name = "RPS",
- .irq_mask = rps_mask_irq,
- .irq_unmask = rps_unmask_irq,
-};
-
-static int rps_irq_domain_xlate(struct irq_domain *d,
- struct device_node *controller,
- const u32 *intspec, unsigned int intsize,
- unsigned long *out_hwirq,
- unsigned int *out_type)
-{
- if (irq_domain_get_of_node(d) != controller)
- return -EINVAL;
- if (intsize < 1)
- return -EINVAL;
-
- *out_hwirq = intspec[0];
- /* Honestly I do not know the type */
- *out_type = IRQ_TYPE_LEVEL_HIGH;
-
- return 0;
-}
-
-static int rps_irq_domain_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hw)
-{
- irq_set_chip_and_handler(irq, &rps_chip, handle_level_irq);
- irq_set_probe(irq);
- irq_set_chip_data(irq, d->host_data);
- return 0;
-}
-
-const struct irq_domain_ops rps_irq_domain_ops = {
- .map = rps_irq_domain_map,
- .xlate = rps_irq_domain_xlate,
-};
-
-static void rps_handle_cascade_irq(struct irq_desc *desc)
-{
- struct rps_chip_data *chip_data = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
- unsigned int cascade_irq, rps_irq;
- u32 status;
-
- chained_irq_enter(chip, desc);
-
- status = ioread32(chip_data->base + RPS_STATUS);
- rps_irq = __ffs(status);
- cascade_irq = irq_find_mapping(chip_data->domain, rps_irq);
-
- if (unlikely(rps_irq >= RPS_IRQ_COUNT))
- handle_bad_irq(desc);
- else
- generic_handle_irq(cascade_irq);
-
- chained_irq_exit(chip, desc);
-}
-
-#ifdef CONFIG_OF
-int __init rps_of_init(struct device_node *node, struct device_node *parent)
-{
- void __iomem *rps_base;
- int irq_start = RPS_IRQ_BASE;
- int irq_base;
- int irq;
-
- if (WARN_ON(!node))
- return -ENODEV;
-
- rps_base = of_iomap(node, 0);
- WARN(!rps_base, "unable to map rps registers\n");
- rps_data.base = rps_base;
-
- irq_base = irq_alloc_descs(irq_start, 0, RPS_IRQ_COUNT, numa_node_id());
- if (IS_ERR_VALUE(irq_base)) {
- WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
- irq_start);
- irq_base = irq_start;
- }
-
- rps_data.domain = irq_domain_add_legacy(node, RPS_IRQ_COUNT, irq_base,
- PRS_HWIRQ_BASE, &rps_irq_domain_ops, &rps_data);
-
- if (WARN_ON(!rps_data.domain))
- return -ENOMEM;
-
- if (parent) {
- irq = irq_of_parse_and_map(node, 0);
- if (irq_set_handler_data(irq, &rps_data) != 0)
- BUG();
- irq_set_chained_handler(irq, rps_handle_cascade_irq);
- }
- return 0;
-
-}
-
-IRQCHIP_DECLARE(nas782x, "plxtech,nas782x-rps", rps_of_init);
-#endif
diff --git a/target/linux/oxnas/files/drivers/mtd/nand/oxnas_nand.c b/target/linux/oxnas/files/drivers/mtd/nand/oxnas_nand.c
deleted file mode 100644
index 36807b7767..0000000000
--- a/target/linux/oxnas/files/drivers/mtd/nand/oxnas_nand.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Oxford Semiconductor OXNAS NAND driver
-
- * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
- * Heavily based on plat_nand.c :
- * Author: Vitaly Wool <vitalywool@gmail.com>
- * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
- * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
- *
- * 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/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/reset.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/of.h>
-
-/* Nand commands */
-#define OXNAS_NAND_CMD_ALE BIT(18)
-#define OXNAS_NAND_CMD_CLE BIT(19)
-
-#define OXNAS_NAND_MAX_CHIPS 1
-
-struct oxnas_nand {
- struct nand_hw_control base;
- void __iomem *io_base;
- struct clk *clk;
- struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS];
- unsigned long ctrl;
- struct mtd_partition *partitions;
- int nr_partitions;
-};
-
-static uint8_t oxnas_nand_read_byte(struct mtd_info *mtd)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct oxnas_nand *oxnas = nand_get_controller_data(chip);
-
- return readb(oxnas->io_base);
-}
-
-static void oxnas_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct oxnas_nand *oxnas = nand_get_controller_data(chip);
-
- ioread8_rep(oxnas->io_base, buf, len);
-}
-
-static void oxnas_nand_write_buf(struct mtd_info *mtd,
- const uint8_t *buf, int len)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct oxnas_nand *oxnas = nand_get_controller_data(chip);
-
- iowrite8_rep(oxnas->io_base + oxnas->ctrl, buf, len);
-}
-
-/* Single CS command control */
-static void oxnas_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
- unsigned int ctrl)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct oxnas_nand *oxnas = nand_get_controller_data(chip);
-
- if (ctrl & NAND_CTRL_CHANGE) {
- if (ctrl & NAND_CLE)
- oxnas->ctrl = OXNAS_NAND_CMD_CLE;
- else if (ctrl & NAND_ALE)
- oxnas->ctrl = OXNAS_NAND_CMD_ALE;
- else
- oxnas->ctrl = 0;
- }
-
- if (cmd != NAND_CMD_NONE)
- writeb(cmd, oxnas->io_base + oxnas->ctrl);
-}
-
-/*
- * Probe for the NAND device.
- */
-static int oxnas_nand_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct device_node *nand_np;
- struct oxnas_nand *oxnas;
- struct nand_chip *chip;
- struct mtd_info *mtd;
- struct resource *res;
- int nchips = 0;
- int count = 0;
- int err = 0;
-
- /* Allocate memory for the device structure (and zero it) */
- oxnas = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
- GFP_KERNEL);
- if (!oxnas)
- return -ENOMEM;
-
- nand_hw_control_init(&oxnas->base);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- oxnas->io_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(oxnas->io_base))
- return PTR_ERR(oxnas->io_base);
-
- oxnas->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(oxnas->clk))
- oxnas->clk = NULL;
-
- /* Only a single chip node is supported */
- count = of_get_child_count(np);
- if (count > 1)
- return -EINVAL;
-
- clk_prepare_enable(oxnas->clk);
- device_reset_optional(&pdev->dev);
-
- for_each_child_of_node(np, nand_np) {
- chip = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
- GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- chip->controller = &oxnas->base;
-
- nand_set_flash_node(chip, nand_np);
- nand_set_controller_data(chip, oxnas);
-
- mtd = nand_to_mtd(chip);
- mtd->dev.parent = &pdev->dev;
- mtd->priv = chip;
-
- chip->cmd_ctrl = oxnas_nand_cmd_ctrl;
- chip->read_buf = oxnas_nand_read_buf;
- chip->read_byte = oxnas_nand_read_byte;
- chip->write_buf = oxnas_nand_write_buf;
- chip->chip_delay = 30;
-
- /* Scan to find existence of the device */
- err = nand_scan(mtd, 1);
- if (err)
- return err;
-
- err = mtd_device_register(mtd, NULL, 0);
- if (err) {
- nand_release(mtd);
- return err;
- }
-
- oxnas->chips[nchips] = chip;
- ++nchips;
- }
-
- /* Exit if no chips found */
- if (!nchips)
- return -ENODEV;
-
- platform_set_drvdata(pdev, oxnas);
-
- return 0;
-}
-
-static int oxnas_nand_remove(struct platform_device *pdev)
-{
- struct oxnas_nand *oxnas = platform_get_drvdata(pdev);
-
- if (oxnas->chips[0])
- nand_release(nand_to_mtd(oxnas->chips[0]));
-
- clk_disable_unprepare(oxnas->clk);
-
- return 0;
-}
-
-static const struct of_device_id oxnas_nand_match[] = {
- { .compatible = "oxsemi,ox820-nand" },
- {},
-};
-MODULE_DEVICE_TABLE(of, oxnas_nand_match);
-
-static struct platform_driver oxnas_nand_driver = {
- .probe = oxnas_nand_probe,
- .remove = oxnas_nand_remove,
- .driver = {
- .name = "oxnas_nand",
- .of_match_table = oxnas_nand_match,
- },
-};
-
-module_platform_driver(oxnas_nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
-MODULE_DESCRIPTION("Oxnas NAND driver");
-MODULE_ALIAS("platform:oxnas_nand");
diff --git a/target/linux/oxnas/files/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/target/linux/oxnas/files/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
deleted file mode 100644
index aafb118144..0000000000
--- a/target/linux/oxnas/files/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Copyright OpenWrt.org (C) 2015.
- * Copyright Altera Corporation (C) 2014. All rights reserved.
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Adopted from dwmac-socfpga.c
- * Based on code found in mach-oxnas.c
- */
-
-#include <linux/mfd/syscon.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_net.h>
-#include <linux/phy.h>
-#include <linux/regmap.h>
-#include <linux/reset.h>
-#include <linux/stmmac.h>
-
-#include <mach/hardware.h>
-
-#include "stmmac.h"
-#include "stmmac_platform.h"
-
-struct oxnas_gmac {
- struct clk *clk;
-};
-
-static int oxnas_gmac_init(struct platform_device *pdev, void *priv)
-{
- struct oxnas_gmac *bsp_priv = priv;
- int ret = 0;
- unsigned value;
-
- ret = device_reset(&pdev->dev);
- if (ret)
- return ret;
-
- if (IS_ERR(bsp_priv->clk))
- return PTR_ERR(bsp_priv->clk);
- clk_prepare_enable(bsp_priv->clk);
-
- value = readl(SYS_CTRL_GMAC_CTRL);
-
- /* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
- value |= BIT(SYS_CTRL_GMAC_CKEN_GTX);
- /* Use simple mux for 25/125 Mhz clock switching */
- value |= BIT(SYS_CTRL_GMAC_SIMPLE_MUX);
- /* set auto switch tx clock source */
- value |= BIT(SYS_CTRL_GMAC_AUTO_TX_SOURCE);
- /* enable tx & rx vardelay */
- value |= BIT(SYS_CTRL_GMAC_CKEN_TX_OUT);
- value |= BIT(SYS_CTRL_GMAC_CKEN_TXN_OUT);
- value |= BIT(SYS_CTRL_GMAC_CKEN_TX_IN);
- value |= BIT(SYS_CTRL_GMAC_CKEN_RX_OUT);
- value |= BIT(SYS_CTRL_GMAC_CKEN_RXN_OUT);
- value |= BIT(SYS_CTRL_GMAC_CKEN_RX_IN);
- writel(value, SYS_CTRL_GMAC_CTRL);
-
- /* set tx & rx vardelay */
- value = 0;
- value |= SYS_CTRL_GMAC_TX_VARDELAY(4);
- value |= SYS_CTRL_GMAC_TXN_VARDELAY(2);
- value |= SYS_CTRL_GMAC_RX_VARDELAY(10);
- value |= SYS_CTRL_GMAC_RXN_VARDELAY(8);
- writel(value, SYS_CTRL_GMAC_DELAY_CTRL);
-
- return 0;
-}
-
-static void oxnas_gmac_exit(struct platform_device *pdev, void *priv)
-{
- struct reset_control *rstc;
-
- clk_disable_unprepare(priv);
- devm_clk_put(&pdev->dev, priv);
-
- rstc = reset_control_get(&pdev->dev, NULL);
- if (!IS_ERR(rstc)) {
- reset_control_assert(rstc);
- reset_control_put(rstc);
- }
-}
-
-static int oxnas_gmac_probe(struct platform_device *pdev)
-{
- struct plat_stmmacenet_data *plat_dat;
- struct stmmac_resources stmmac_res;
- int ret;
- struct device *dev = &pdev->dev;
- struct oxnas_gmac *bsp_priv;
-
- bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
- if (!bsp_priv)
- return -ENOMEM;
- bsp_priv->clk = devm_clk_get(dev, "gmac");
- if (IS_ERR(bsp_priv->clk))
- return PTR_ERR(bsp_priv->clk);
-
- ret = stmmac_get_platform_resources(pdev, &stmmac_res);
- if (ret)
- return ret;
-
- plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
- if (IS_ERR(plat_dat))
- return PTR_ERR(plat_dat);
-
- plat_dat->bsp_priv = bsp_priv;
- plat_dat->init = oxnas_gmac_init;
- plat_dat->exit = oxnas_gmac_exit;
-
- ret = oxnas_gmac_init(pdev, bsp_priv);
- if (ret)
- return ret;
-
- return stmmac_dvr_probe(dev, plat_dat, &stmmac_res);
-}
-
-static const struct of_device_id oxnas_gmac_match[] = {
- { .compatible = "plxtech,nas782x-gmac" },
- { }
-};
-MODULE_DEVICE_TABLE(of, oxnas_gmac_match);
-
-static struct platform_driver oxnas_gmac_driver = {
- .probe = oxnas_gmac_probe,
- .remove = stmmac_pltfr_remove,
- .driver = {
- .name = "oxnas-gmac",
- .pm = &stmmac_pltfr_pm_ops,
- .of_match_table = oxnas_gmac_match,
- },
-};
-module_platform_driver(oxnas_gmac_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c b/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c
index 9e8d6d9f93..7cf3ad1670 100644
--- a/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c
+++ b/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c
@@ -22,9 +22,279 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/reset.h>
-#include <mach/iomap.h>
-#include <mach/hardware.h>
-#include <mach/utils.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+
+#define OXNAS_UART1_BASE 0x44200000
+#define OXNAS_UART1_SIZE SZ_32
+#define OXNAS_UART1_BASE_VA 0xF0000000
+
+#define OXNAS_UART2_BASE 0x44300000
+#define OXNAS_UART2_SIZE SZ_32
+
+#define OXNAS_PERCPU_BASE 0x47000000
+#define OXNAS_PERCPU_SIZE SZ_8K
+#define OXNAS_PERCPU_BASE_VA 0xF0002000
+
+#define OXNAS_SYSCRTL_BASE 0x44E00000
+#define OXNAS_SYSCRTL_SIZE SZ_4K
+#define OXNAS_SYSCRTL_BASE_VA 0xF0004000
+
+#define OXNAS_SECCRTL_BASE 0x44F00000
+#define OXNAS_SECCRTL_SIZE SZ_4K
+#define OXNAS_SECCRTL_BASE_VA 0xF0005000
+
+#define OXNAS_RPSA_BASE 0x44400000
+#define OXNAS_RPSA_SIZE SZ_4K
+#define OXNAS_RPSA_BASE_VA 0xF0006000
+
+#define OXNAS_RPSC_BASE 0x44500000
+#define OXNAS_RPSC_SIZE SZ_4K
+#define OXNAS_RPSC_BASE_VA 0xF0007000
+
+
+/*
+ * Location of flags and vectors in SRAM for controlling the booting of the
+ * secondary ARM11 processors.
+ */
+
+#define OXNAS_SCU_BASE_VA OXNAS_PERCPU_BASE_VA
+#define OXNAS_GICN_BASE_VA(n) (OXNAS_PERCPU_BASE_VA + 0x200 + n*0x100)
+
+#define HOLDINGPEN_CPU IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc8)
+#define HOLDINGPEN_LOCATION IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc4)
+
+/**
+ * System block reset and clock control
+ */
+#define SYS_CTRL_PCI_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x20)
+#define SYSCTRL_CLK_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x24)
+#define SYS_CTRL_CLK_SET_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x2C)
+#define SYS_CTRL_CLK_CLR_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x30)
+#define SYS_CTRL_RST_SET_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x34)
+#define SYS_CTRL_RST_CLR_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x38)
+
+#define SYS_CTRL_PLLSYS_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x48)
+#define SYS_CTRL_CLK_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x64)
+#define SYS_CTRL_PLLSYS_KEY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x6C)
+#define SYS_CTRL_GMAC_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x78)
+#define SYS_CTRL_GMAC_DELAY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x100)
+
+/* Scratch registers */
+#define SYS_CTRL_SCRATCHWORD0 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc4)
+#define SYS_CTRL_SCRATCHWORD1 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc8)
+#define SYS_CTRL_SCRATCHWORD2 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xcc)
+#define SYS_CTRL_SCRATCHWORD3 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xd0)
+
+#define SYS_CTRL_PLLA_CTRL0 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F0)
+#define SYS_CTRL_PLLA_CTRL1 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F4)
+#define SYS_CTRL_PLLA_CTRL2 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F8)
+#define SYS_CTRL_PLLA_CTRL3 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1FC)
+
+#define SYS_CTRL_USBHSMPH_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x40)
+#define SYS_CTRL_USBHSMPH_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x44)
+#define SYS_CTRL_REF300_DIV IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xF8)
+#define SYS_CTRL_USBHSPHY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x84)
+#define SYS_CTRL_USB_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x90)
+
+/* pcie */
+#define SYS_CTRL_HCSL_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x114)
+
+/* System control multi-function pin function selection */
+#define SYS_CTRL_SECONDARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x14)
+#define SYS_CTRL_TERTIARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x8c)
+#define SYS_CTRL_QUATERNARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x94)
+#define SYS_CTRL_DEBUG_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x9c)
+#define SYS_CTRL_ALTERNATIVE_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xa4)
+#define SYS_CTRL_PULLUP_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xac)
+
+/* Secure control multi-function pin function selection */
+#define SEC_CTRL_SECONDARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x14)
+#define SEC_CTRL_TERTIARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x8c)
+#define SEC_CTRL_QUATERNARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x94)
+#define SEC_CTRL_DEBUG_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x9c)
+#define SEC_CTRL_ALTERNATIVE_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xa4)
+#define SEC_CTRL_PULLUP_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xac)
+
+#define SEC_CTRL_COPRO_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x68)
+#define SEC_CTRL_SECURE_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x98)
+#define SEC_CTRL_LEON_DEBUG IOMEM(OXNAS_SECCRTL_BASE_VA + 0xF0)
+#define SEC_CTRL_PLLB_DIV_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xF8)
+#define SEC_CTRL_PLLB_CTRL0 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F0)
+#define SEC_CTRL_PLLB_CTRL1 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F4)
+#define SEC_CTRL_PLLB_CTRL8 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F4)
+
+#define RPSA_IRQ_SOFT IOMEM(OXNAS_RPSA_BASE_VA + 0x10)
+#define RPSA_FIQ_ENABLE IOMEM(OXNAS_RPSA_BASE_VA + 0x108)
+#define RPSA_FIQ_DISABLE IOMEM(OXNAS_RPSA_BASE_VA + 0x10C)
+#define RPSA_FIQ_IRQ_TO_FIQ IOMEM(OXNAS_RPSA_BASE_VA + 0x1FC)
+
+#define RPSC_IRQ_SOFT IOMEM(OXNAS_RPSC_BASE_VA + 0x10)
+#define RPSC_FIQ_ENABLE IOMEM(OXNAS_RPSC_BASE_VA + 0x108)
+#define RPSC_FIQ_DISABLE IOMEM(OXNAS_RPSC_BASE_VA + 0x10C)
+#define RPSC_FIQ_IRQ_TO_FIQ IOMEM(OXNAS_RPSC_BASE_VA + 0x1FC)
+
+#define RPSA_TIMER2_VAL IOMEM(OXNAS_RPSA_BASE_VA + 0x224)
+
+#define REF300_DIV_INT_SHIFT 8
+#define REF300_DIV_FRAC_SHIFT 0
+#define REF300_DIV_INT(val) ((val) << REF300_DIV_INT_SHIFT)
+#define REF300_DIV_FRAC(val) ((val) << REF300_DIV_FRAC_SHIFT)
+
+#define USBHSPHY_SUSPENDM_MANUAL_ENABLE 16
+#define USBHSPHY_SUSPENDM_MANUAL_STATE 15
+#define USBHSPHY_ATE_ESET 14
+#define USBHSPHY_TEST_DIN 6
+#define USBHSPHY_TEST_ADD 2
+#define USBHSPHY_TEST_DOUT_SEL 1
+#define USBHSPHY_TEST_CLK 0
+
+#define USB_CTRL_USBAPHY_CKSEL_SHIFT 5
+#define USB_CLK_XTAL0_XTAL1 (0 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+#define USB_CLK_XTAL0 (1 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+#define USB_CLK_INTERNAL (2 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+
+#define USBAMUX_DEVICE BIT(4)
+
+#define USBPHY_REFCLKDIV_SHIFT 2
+#define USB_PHY_REF_12MHZ (0 << USBPHY_REFCLKDIV_SHIFT)
+#define USB_PHY_REF_24MHZ (1 << USBPHY_REFCLKDIV_SHIFT)
+#define USB_PHY_REF_48MHZ (2 << USBPHY_REFCLKDIV_SHIFT)
+
+#define USB_CTRL_USB_CKO_SEL_BIT 0
+
+#define USB_INT_CLK_XTAL 0
+#define USB_INT_CLK_REF300 2
+#define USB_INT_CLK_PLLB 3
+
+#define SYS_CTRL_GMAC_CKEN_RX_IN 14
+#define SYS_CTRL_GMAC_CKEN_RXN_OUT 13
+#define SYS_CTRL_GMAC_CKEN_RX_OUT 12
+#define SYS_CTRL_GMAC_CKEN_TX_IN 10
+#define SYS_CTRL_GMAC_CKEN_TXN_OUT 9
+#define SYS_CTRL_GMAC_CKEN_TX_OUT 8
+#define SYS_CTRL_GMAC_RX_SOURCE 7
+#define SYS_CTRL_GMAC_TX_SOURCE 6
+#define SYS_CTRL_GMAC_LOW_TX_SOURCE 4
+#define SYS_CTRL_GMAC_AUTO_TX_SOURCE 3
+#define SYS_CTRL_GMAC_RGMII 2
+#define SYS_CTRL_GMAC_SIMPLE_MUX 1
+#define SYS_CTRL_GMAC_CKEN_GTX 0
+#define SYS_CTRL_GMAC_TX_VARDELAY_SHIFT 0
+#define SYS_CTRL_GMAC_TXN_VARDELAY_SHIFT 8
+#define SYS_CTRL_GMAC_RX_VARDELAY_SHIFT 16
+#define SYS_CTRL_GMAC_RXN_VARDELAY_SHIFT 24
+#define SYS_CTRL_GMAC_TX_VARDELAY(d) ((d)<<SYS_CTRL_GMAC_TX_VARDELAY_SHIFT)
+#define SYS_CTRL_GMAC_TXN_VARDELAY(d) ((d)<<SYS_CTRL_GMAC_TXN_VARDELAY_SHIFT)
+#define SYS_CTRL_GMAC_RX_VARDELAY(d) ((d)<<SYS_CTRL_GMAC_RX_VARDELAY_SHIFT)
+#define SYS_CTRL_GMAC_RXN_VARDELAY(d) ((d)<<SYS_CTRL_GMAC_RXN_VARDELAY_SHIFT)
+
+#define PLLB_BYPASS 1
+#define PLLB_ENSAT 3
+#define PLLB_OUTDIV 4
+#define PLLB_REFDIV 8
+#define PLLB_DIV_INT_SHIFT 8
+#define PLLB_DIV_FRAC_SHIFT 0
+#define PLLB_DIV_INT(val) ((val) << PLLB_DIV_INT_SHIFT)
+#define PLLB_DIV_FRAC(val) ((val) << PLLB_DIV_FRAC_SHIFT)
+
+#define SYS_CTRL_CKCTRL_PCI_DIV_BIT 0
+#define SYS_CTRL_CKCTRL_SLOW_BIT 8
+
+#define SYS_CTRL_UART2_DEQ_EN 0
+#define SYS_CTRL_UART3_DEQ_EN 1
+#define SYS_CTRL_UART3_IQ_EN 2
+#define SYS_CTRL_UART4_IQ_EN 3
+#define SYS_CTRL_UART4_NOT_PCI_MODE 4
+
+#define SYS_CTRL_PCI_CTRL1_PCI_STATIC_RQ_BIT 11
+
+#define PLLA_REFDIV_MASK 0x3F
+#define PLLA_REFDIV_SHIFT 8
+#define PLLA_OUTDIV_MASK 0x7
+#define PLLA_OUTDIV_SHIFT 4
+
+/* bit numbers of clock control register */
+#define SYS_CTRL_CLK_COPRO 0
+#define SYS_CTRL_CLK_DMA 1
+#define SYS_CTRL_CLK_CIPHER 2
+#define SYS_CTRL_CLK_SD 3
+#define SYS_CTRL_CLK_SATA 4
+#define SYS_CTRL_CLK_I2S 5
+#define SYS_CTRL_CLK_USBHS 6
+#define SYS_CTRL_CLK_MACA 7
+#define SYS_CTRL_CLK_MAC SYS_CTRL_CLK_MACA
+#define SYS_CTRL_CLK_PCIEA 8
+#define SYS_CTRL_CLK_STATIC 9
+#define SYS_CTRL_CLK_MACB 10
+#define SYS_CTRL_CLK_PCIEB 11
+#define SYS_CTRL_CLK_REF600 12
+#define SYS_CTRL_CLK_USBDEV 13
+#define SYS_CTRL_CLK_DDR 14
+#define SYS_CTRL_CLK_DDRPHY 15
+#define SYS_CTRL_CLK_DDRCK 16
+
+
+/* bit numbers of reset control register */
+#define SYS_CTRL_RST_SCU 0
+#define SYS_CTRL_RST_COPRO 1
+#define SYS_CTRL_RST_ARM0 2
+#define SYS_CTRL_RST_ARM1 3
+#define SYS_CTRL_RST_USBHS 4
+#define SYS_CTRL_RST_USBHSPHYA 5
+#define SYS_CTRL_RST_MACA 6
+#define SYS_CTRL_RST_MAC SYS_CTRL_RST_MACA
+#define SYS_CTRL_RST_PCIEA 7
+#define SYS_CTRL_RST_SGDMA 8
+#define SYS_CTRL_RST_CIPHER 9
+#define SYS_CTRL_RST_DDR 10
+#define SYS_CTRL_RST_SATA 11
+#define SYS_CTRL_RST_SATA_LINK 12
+#define SYS_CTRL_RST_SATA_PHY 13
+#define SYS_CTRL_RST_PCIEPHY 14
+#define SYS_CTRL_RST_STATIC 15
+#define SYS_CTRL_RST_GPIO 16
+#define SYS_CTRL_RST_UART1 17
+#define SYS_CTRL_RST_UART2 18
+#define SYS_CTRL_RST_MISC 19
+#define SYS_CTRL_RST_I2S 20
+#define SYS_CTRL_RST_SD 21
+#define SYS_CTRL_RST_MACB 22
+#define SYS_CTRL_RST_PCIEB 23
+#define SYS_CTRL_RST_VIDEO 24
+#define SYS_CTRL_RST_DDR_PHY 25
+#define SYS_CTRL_RST_USBHSPHYB 26
+#define SYS_CTRL_RST_USBDEV 27
+#define SYS_CTRL_RST_ARMDBG 29
+#define SYS_CTRL_RST_PLLA 30
+#define SYS_CTRL_RST_PLLB 31
+
+static inline void oxnas_register_clear_mask(void __iomem *p, unsigned mask)
+{
+ u32 val = readl_relaxed(p);
+
+ val &= ~mask;
+ writel_relaxed(val, p);
+}
+
+static inline void oxnas_register_set_mask(void __iomem *p, unsigned mask)
+{
+ u32 val = readl_relaxed(p);
+
+ val |= mask;
+ writel_relaxed(val, p);
+}
+
+static inline void oxnas_register_value_mask(void __iomem *p,
+ unsigned mask, unsigned new_value)
+{
+ /* TODO sanity check mask & new_value = new_value */
+ u32 val = readl_relaxed(p);
+
+ val &= ~mask;
+ val |= new_value;
+ writel_relaxed(val, p);
+}
#define VERSION_ID_MAGIC 0x082510b5
#define LINK_UP_TIMEOUT_SECONDS 1
diff --git a/target/linux/oxnas/files/drivers/pinctrl/pinctrl-oxnas.c b/target/linux/oxnas/files/drivers/pinctrl/pinctrl-oxnas.c
deleted file mode 100644
index 38a8cbb451..0000000000
--- a/target/linux/oxnas/files/drivers/pinctrl/pinctrl-oxnas.c
+++ /dev/null
@@ -1,1461 +0,0 @@
-/*
- * oxnas pinctrl driver based on at91 pinctrl driver
- *
- * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * Under GPLv2 only
- */
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-/* Since we request GPIOs from ourself */
-#include <linux/pinctrl/consumer.h>
-#include <linux/spinlock.h>
-
-#include "core.h"
-
-#include <mach/utils.h>
-
-#define MAX_NB_GPIO_PER_BANK 32
-#define MAX_GPIO_BANKS 2
-
-struct oxnas_gpio_chip {
- struct gpio_chip chip;
- struct pinctrl_gpio_range range;
- void __iomem *regbase; /* GPIOA/B virtual address */
- void __iomem *ctrlbase; /* SYS/SEC_CTRL virtual address */
- struct irq_domain *domain; /* associated irq domain */
- spinlock_t lock;
-};
-
-#define to_oxnas_gpio_chip(c) container_of(c, struct oxnas_gpio_chip, chip)
-
-static struct oxnas_gpio_chip *gpio_chips[MAX_GPIO_BANKS];
-
-static int gpio_banks;
-
-#define PULL_UP (1 << 0)
-#define PULL_DOWN (1 << 1)
-#define DEBOUNCE (1 << 2)
-
-/**
- * struct oxnas_pmx_func - describes pinmux functions
- * @name: the name of this specific function
- * @groups: corresponding pin groups
- * @ngroups: the number of groups
- */
-struct oxnas_pmx_func {
- const char *name;
- const char **groups;
- unsigned ngroups;
-};
-
-enum oxnas_mux {
- OXNAS_PINMUX_GPIO,
- OXNAS_PINMUX_FUNC2,
- OXNAS_PINMUX_FUNC3,
- OXNAS_PINMUX_FUNC4,
- OXNAS_PINMUX_DEBUG,
- OXNAS_PINMUX_ALT,
-};
-
-enum {
- INPUT_VALUE = 0,
- OUTPUT_ENABLE = 4,
- IRQ_PENDING = 0xC,
- OUTPUT_VALUE = 0x10,
- OUTPUT_SET = 0x14,
- OUTPUT_CLEAR = 0x18,
- OUTPUT_EN_SET = 0x1C,
- OUTPUT_EN_CLEAR = 0x20,
- DEBOUNCE_ENABLE = 0x24,
- RE_IRQ_ENABLE = 0x28, /* rising edge */
- FE_IRQ_ENABLE = 0x2C, /* falling edge */
- RE_IRQ_PENDING = 0x30, /* rising edge */
- FE_IRQ_PENDING = 0x34, /* falling edge */
- CLOCK_DIV = 0x48,
- PULL_ENABLE = 0x50,
- PULL_SENSE = 0x54, /* 1 up, 0 down */
-
-
- DEBOUNCE_MASK = 0x3FFF0000,
- /* put hw debounce and soft config at same bit position*/
- DEBOUNCE_SHIFT = 16
-};
-
-enum {
- PINMUX_SECONDARY_SEL = 0x14,
- PINMUX_TERTIARY_SEL = 0x8c,
- PINMUX_QUATERNARY_SEL = 0x94,
- PINMUX_DEBUG_SEL = 0x9c,
- PINMUX_ALTERNATIVE_SEL = 0xa4,
- PINMUX_PULLUP_SEL = 0xac,
-};
-
-/**
- * struct oxnas_pmx_pin - describes an pin mux
- * @bank: the bank of the pin
- * @pin: the pin number in the @bank
- * @mux: the mux mode : gpio or periph_x of the pin i.e. alternate function.
- * @conf: the configuration of the pin: PULL_UP, MULTIDRIVE etc...
- */
-struct oxnas_pmx_pin {
- uint32_t bank;
- uint32_t pin;
- enum oxnas_mux mux;
- unsigned long conf;
-};
-
-/**
- * struct oxnas_pin_group - describes an pin group
- * @name: the name of this specific pin group
- * @pins_conf: the mux mode for each pin in this group. The size of this
- * array is the same as pins.
- * @pins: an array of discrete physical pins used in this group, taken
- * from the driver-local pin enumeration space
- * @npins: the number of pins in this group array, i.e. the number of
- * elements in .pins so we can iterate over that array
- */
-struct oxnas_pin_group {
- const char *name;
- struct oxnas_pmx_pin *pins_conf;
- unsigned int *pins;
- unsigned npins;
-};
-
-struct oxnas_pinctrl {
- struct device *dev;
- struct pinctrl_dev *pctl;
-
- int nbanks;
-
- uint32_t *mux_mask;
- int nmux;
-
- struct oxnas_pmx_func *functions;
- int nfunctions;
-
- struct oxnas_pin_group *groups;
- int ngroups;
-};
-
-static const inline struct oxnas_pin_group *oxnas_pinctrl_find_group_by_name(
- const struct oxnas_pinctrl *info,
- const char *name)
-{
- const struct oxnas_pin_group *grp = NULL;
- int i;
-
- for (i = 0; i < info->ngroups; i++) {
- if (strcmp(info->groups[i].name, name))
- continue;
-
- grp = &info->groups[i];
- dev_dbg(info->dev, "%s: %d 0:%d\n", name, grp->npins,
- grp->pins[0]);
- break;
- }
-
- return grp;
-}
-
-static int oxnas_get_groups_count(struct pinctrl_dev *pctldev)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- return info->ngroups;
-}
-
-static const char *oxnas_get_group_name(struct pinctrl_dev *pctldev,
- unsigned selector)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- return info->groups[selector].name;
-}
-
-static int oxnas_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
- const unsigned **pins,
- unsigned *npins)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- if (selector >= info->ngroups)
- return -EINVAL;
-
- *pins = info->groups[selector].pins;
- *npins = info->groups[selector].npins;
-
- return 0;
-}
-
-static void oxnas_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
- unsigned offset)
-{
- seq_printf(s, "%s", dev_name(pctldev->dev));
-}
-
-static int oxnas_dt_node_to_map(struct pinctrl_dev *pctldev,
- struct device_node *np,
- struct pinctrl_map **map, unsigned *num_maps)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- const struct oxnas_pin_group *grp;
- struct pinctrl_map *new_map;
- struct device_node *parent;
- int map_num = 1;
- int i;
-
- /*
- * first find the group of this node and check if we need create
- * config maps for pins
- */
- grp = oxnas_pinctrl_find_group_by_name(info, np->name);
- if (!grp) {
- dev_err(info->dev, "unable to find group for node %s\n",
- np->name);
- return -EINVAL;
- }
-
- map_num += grp->npins;
- new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num,
- GFP_KERNEL);
- if (!new_map)
- return -ENOMEM;
-
- *map = new_map;
- *num_maps = map_num;
-
- /* create mux map */
- parent = of_get_parent(np);
- if (!parent) {
- devm_kfree(pctldev->dev, new_map);
- return -EINVAL;
- }
- new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
- new_map[0].data.mux.function = parent->name;
- new_map[0].data.mux.group = np->name;
- of_node_put(parent);
-
- /* create config map */
- new_map++;
- for (i = 0; i < grp->npins; i++) {
- new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
- new_map[i].data.configs.group_or_pin =
- pin_get_name(pctldev, grp->pins[i]);
- new_map[i].data.configs.configs = &grp->pins_conf[i].conf;
- new_map[i].data.configs.num_configs = 1;
- }
-
- dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
- (*map)->data.mux.function, (*map)->data.mux.group, map_num);
-
- return 0;
-}
-
-static void oxnas_dt_free_map(struct pinctrl_dev *pctldev,
- struct pinctrl_map *map, unsigned num_maps)
-{
-}
-
-static const struct pinctrl_ops oxnas_pctrl_ops = {
- .get_groups_count = oxnas_get_groups_count,
- .get_group_name = oxnas_get_group_name,
- .get_group_pins = oxnas_get_group_pins,
- .pin_dbg_show = oxnas_pin_dbg_show,
- .dt_node_to_map = oxnas_dt_node_to_map,
- .dt_free_map = oxnas_dt_free_map,
-};
-
-static void __iomem *pin_to_gpioctrl(struct oxnas_pinctrl *info,
- unsigned int bank)
-{
- return gpio_chips[bank]->regbase;
-}
-
-static void __iomem *pin_to_muxctrl(struct oxnas_pinctrl *info,
- unsigned int bank)
-{
- return gpio_chips[bank]->ctrlbase;
-}
-
-
-static inline int pin_to_bank(unsigned pin)
-{
- return pin / MAX_NB_GPIO_PER_BANK;
-}
-
-static unsigned pin_to_mask(unsigned int pin)
-{
- return 1 << pin;
-}
-
-static void oxnas_mux_disable_interrupt(void __iomem *pio, unsigned mask)
-{
- oxnas_register_clear_mask(pio + RE_IRQ_ENABLE, mask);
- oxnas_register_clear_mask(pio + FE_IRQ_ENABLE, mask);
-}
-
-static unsigned oxnas_mux_get_pullup(void __iomem *pio, unsigned pin)
-{
- return (readl_relaxed(pio + PULL_ENABLE) & BIT(pin)) &&
- (readl_relaxed(pio + PULL_SENSE) & BIT(pin));
-}
-
-static void oxnas_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
-{
- if (on) {
- oxnas_register_set_mask(pio + PULL_SENSE, mask);
- oxnas_register_set_mask(pio + PULL_ENABLE, mask);
- } else {
- oxnas_register_clear_mask(pio + PULL_ENABLE, mask);
- }
-}
-
-static bool oxnas_mux_get_pulldown(void __iomem *pio, unsigned pin)
-{
- return (readl_relaxed(pio + PULL_ENABLE) & BIT(pin)) &&
- (!(readl_relaxed(pio + PULL_SENSE) & BIT(pin)));
-}
-
-static void oxnas_mux_set_pulldown(void __iomem *pio, unsigned mask, bool on)
-{
- if (on) {
- oxnas_register_clear_mask(pio + PULL_SENSE, mask);
- oxnas_register_set_mask(pio + PULL_ENABLE, mask);
- } else {
- oxnas_register_clear_mask(pio + PULL_ENABLE, mask);
- };
-}
-
-/* unfortunately debounce control are shared */
-static bool oxnas_mux_get_debounce(void __iomem *pio, unsigned pin, u32 *div)
-{
- *div = __raw_readl(pio + CLOCK_DIV) & DEBOUNCE_MASK;
- return __raw_readl(pio + DEBOUNCE_ENABLE) & BIT(pin);
-}
-
-static void oxnas_mux_set_debounce(void __iomem *pio, unsigned mask,
- bool is_on, u32 div)
-{
- if (is_on) {
- oxnas_register_value_mask(pio + CLOCK_DIV, DEBOUNCE_MASK, div);
- oxnas_register_set_mask(pio + DEBOUNCE_ENABLE, mask);
- } else {
- oxnas_register_clear_mask(pio + DEBOUNCE_ENABLE, mask);
- }
-}
-
-
-static void oxnas_mux_set_func2(void __iomem *cio, unsigned mask)
-{
-/* in fact, SECONDARY takes precedence, so clear others is not necessary */
- oxnas_register_set_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_func3(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_set_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_func4(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_set_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_func_dbg(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_set_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_func_alt(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_set_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_gpio(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static enum oxnas_mux oxnas_mux_get_func(void __iomem *cio, unsigned mask)
-{
- if (readl_relaxed(cio + PINMUX_SECONDARY_SEL) & mask)
- return OXNAS_PINMUX_FUNC2;
- if (readl_relaxed(cio + PINMUX_TERTIARY_SEL) & mask)
- return OXNAS_PINMUX_FUNC3;
- if (readl_relaxed(cio + PINMUX_QUATERNARY_SEL) & mask)
- return OXNAS_PINMUX_FUNC4;
- if (readl_relaxed(cio + PINMUX_DEBUG_SEL) & mask)
- return OXNAS_PINMUX_DEBUG;
- if (readl_relaxed(cio + PINMUX_ALTERNATIVE_SEL) & mask)
- return OXNAS_PINMUX_ALT;
- return OXNAS_PINMUX_GPIO;
-}
-
-
-static void oxnas_pin_dbg(const struct device *dev,
- const struct oxnas_pmx_pin *pin)
-{
- if (pin->mux) {
- dev_dbg(dev,
- "MF_%c%d configured as periph%c with conf = 0x%lu\n",
- pin->bank + 'A', pin->pin, pin->mux - 1 + 'A',
- pin->conf);
- } else {
- dev_dbg(dev, "MF_%c%d configured as gpio with conf = 0x%lu\n",
- pin->bank + 'A', pin->pin, pin->conf);
- }
-}
-
-static int pin_check_config(struct oxnas_pinctrl *info, const char *name,
- int index, const struct oxnas_pmx_pin *pin)
-{
- int mux;
-
- /* check if it's a valid config */
- if (pin->bank >= info->nbanks) {
- dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n",
- name, index, pin->bank, info->nbanks);
- return -EINVAL;
- }
-
- if (pin->pin >= MAX_NB_GPIO_PER_BANK) {
- dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n",
- name, index, pin->pin, MAX_NB_GPIO_PER_BANK);
- return -EINVAL;
- }
- /* gpio always allowed */
- if (!pin->mux)
- return 0;
-
- mux = pin->mux - 1;
-
- if (mux >= info->nmux) {
- dev_err(info->dev, "%s: pin conf %d mux_id %d >= nmux %d\n",
- name, index, mux, info->nmux);
- return -EINVAL;
- }
-
- if (!(info->mux_mask[pin->bank * info->nmux + mux] & 1 << pin->pin)) {
- dev_err(info->dev, "%s: pin conf %d mux_id %d not supported for MF_%c%d\n",
- name, index, mux, pin->bank + 'A', pin->pin);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void oxnas_mux_gpio_enable(void __iomem *cio, void __iomem *pio,
- unsigned mask, bool input)
-{
- oxnas_mux_set_gpio(cio, mask);
- if (input)
- writel_relaxed(mask, pio + OUTPUT_EN_CLEAR);
- else
- writel_relaxed(mask, pio + OUTPUT_EN_SET);
-}
-
-static void oxnas_mux_gpio_disable(void __iomem *cio, void __iomem *pio,
- unsigned mask)
-{
- /* when switch to other function, gpio is disabled automatically */
- return;
-}
-
-static int oxnas_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- const struct oxnas_pmx_pin *pins_conf = info->groups[group].pins_conf;
- const struct oxnas_pmx_pin *pin;
- uint32_t npins = info->groups[group].npins;
- int i, ret;
- unsigned mask;
- void __iomem *pio;
- void __iomem *cio;
-
- dev_dbg(info->dev, "enable function %s group %s\n",
- info->functions[selector].name, info->groups[group].name);
-
- /* first check that all the pins of the group are valid with a valid
- * paramter */
- for (i = 0; i < npins; i++) {
- pin = &pins_conf[i];
- ret = pin_check_config(info, info->groups[group].name, i, pin);
- if (ret)
- return ret;
- }
-
- for (i = 0; i < npins; i++) {
- pin = &pins_conf[i];
- oxnas_pin_dbg(info->dev, pin);
-
- pio = pin_to_gpioctrl(info, pin->bank);
- cio = pin_to_muxctrl(info, pin->bank);
-
- mask = pin_to_mask(pin->pin);
- oxnas_mux_disable_interrupt(pio, mask);
-
- switch (pin->mux) {
- case OXNAS_PINMUX_GPIO:
- oxnas_mux_gpio_enable(cio, pio, mask, 1);
- break;
- case OXNAS_PINMUX_FUNC2:
- oxnas_mux_set_func2(cio, mask);
- break;
- case OXNAS_PINMUX_FUNC3:
- oxnas_mux_set_func3(cio, mask);
- break;
- case OXNAS_PINMUX_FUNC4:
- oxnas_mux_set_func4(cio, mask);
- break;
- case OXNAS_PINMUX_DEBUG:
- oxnas_mux_set_func_dbg(cio, mask);
- break;
- case OXNAS_PINMUX_ALT:
- oxnas_mux_set_func_alt(cio, mask);
- break;
- }
- if (pin->mux)
- oxnas_mux_gpio_disable(cio, pio, mask);
- }
-
- return 0;
-}
-
-static int oxnas_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- return info->nfunctions;
-}
-
-static const char *oxnas_pmx_get_func_name(struct pinctrl_dev *pctldev,
- unsigned selector)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- return info->functions[selector].name;
-}
-
-static int oxnas_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
- const char * const **groups,
- unsigned * const num_groups)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- *groups = info->functions[selector].groups;
- *num_groups = info->functions[selector].ngroups;
-
- return 0;
-}
-
-static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range,
- unsigned offset)
-{
- struct oxnas_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
- struct oxnas_gpio_chip *oxnas_chip;
- struct gpio_chip *chip;
- unsigned mask;
-
- if (!range) {
- dev_err(npct->dev, "invalid range\n");
- return -EINVAL;
- }
- if (!range->gc) {
- dev_err(npct->dev, "missing GPIO chip in range\n");
- return -EINVAL;
- }
- chip = range->gc;
- oxnas_chip = container_of(chip, struct oxnas_gpio_chip, chip);
-
- dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
-
- mask = 1 << (offset - chip->base);
-
- dev_dbg(npct->dev, "enable pin %u as MF_%c%d 0x%x\n",
- offset, 'A' + range->id, offset - chip->base, mask);
-
- oxnas_mux_set_gpio(oxnas_chip->ctrlbase, mask);
-
- return 0;
-}
-
-static void oxnas_gpio_disable_free(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range,
- unsigned offset)
-{
- struct oxnas_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
- dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
- /* Set the pin to some default state, GPIO is usually default */
-}
-
-static const struct pinmux_ops oxnas_pmx_ops = {
- .get_functions_count = oxnas_pmx_get_funcs_count,
- .get_function_name = oxnas_pmx_get_func_name,
- .get_function_groups = oxnas_pmx_get_groups,
- .set_mux = oxnas_pmx_set_mux,
- .gpio_request_enable = oxnas_gpio_request_enable,
- .gpio_disable_free = oxnas_gpio_disable_free,
-};
-
-static int oxnas_pinconf_get(struct pinctrl_dev *pctldev,
- unsigned pin_id, unsigned long *config)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- void __iomem *pio;
- unsigned pin;
- int div;
-
- dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__,
- __LINE__, pin_id, *config);
- pio = pin_to_gpioctrl(info, pin_to_bank(pin_id));
- pin = pin_id % MAX_NB_GPIO_PER_BANK;
-
- if (oxnas_mux_get_pullup(pio, pin))
- *config |= PULL_UP;
-
- if (oxnas_mux_get_pulldown(pio, pin))
- *config |= PULL_DOWN;
-
- if (oxnas_mux_get_debounce(pio, pin, &div))
- *config |= DEBOUNCE | div;
- return 0;
-}
-
-static int oxnas_pinconf_set(struct pinctrl_dev *pctldev,
- unsigned pin_id, unsigned long *configs,
- unsigned num_configs)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- unsigned mask;
- void __iomem *pio;
- int i;
- unsigned long config;
-
- pio = pin_to_gpioctrl(info, pin_to_bank(pin_id));
- mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK);
-
- for (i = 0; i < num_configs; i++) {
- config = configs[i];
-
- dev_dbg(info->dev,
- "%s:%d, pin_id=%d, config=0x%lx",
- __func__, __LINE__, pin_id, config);
-
- if ((config & PULL_UP) && (config & PULL_DOWN))
- return -EINVAL;
-
- oxnas_mux_set_pullup(pio, mask, config & PULL_UP);
- oxnas_mux_set_pulldown(pio, mask, config & PULL_DOWN);
- oxnas_mux_set_debounce(pio, mask, config & DEBOUNCE,
- config & DEBOUNCE_MASK);
-
- } /* for each config */
-
- return 0;
-}
-
-static void oxnas_pinconf_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s, unsigned pin_id)
-{
-
-}
-
-static void oxnas_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s, unsigned group)
-{
-}
-
-static const struct pinconf_ops oxnas_pinconf_ops = {
- .pin_config_get = oxnas_pinconf_get,
- .pin_config_set = oxnas_pinconf_set,
- .pin_config_dbg_show = oxnas_pinconf_dbg_show,
- .pin_config_group_dbg_show = oxnas_pinconf_group_dbg_show,
-};
-
-static struct pinctrl_desc oxnas_pinctrl_desc = {
- .pctlops = &oxnas_pctrl_ops,
- .pmxops = &oxnas_pmx_ops,
- .confops = &oxnas_pinconf_ops,
- .owner = THIS_MODULE,
-};
-
-static const char *gpio_compat = "plxtech,nas782x-gpio";
-
-static void oxnas_pinctrl_child_count(struct oxnas_pinctrl *info,
- struct device_node *np)
-{
- struct device_node *child;
-
- for_each_child_of_node(np, child) {
- if (of_device_is_compatible(child, gpio_compat)) {
- info->nbanks++;
- } else {
- info->nfunctions++;
- info->ngroups += of_get_child_count(child);
- }
- }
-}
-
-static int oxnas_pinctrl_mux_mask(struct oxnas_pinctrl *info,
- struct device_node *np)
-{
- int ret = 0;
- int size;
- const __be32 *list;
-
- list = of_get_property(np, "plxtech,mux-mask", &size);
- if (!list) {
- dev_err(info->dev, "can not read the mux-mask of %d\n", size);
- return -EINVAL;
- }
-
- size /= sizeof(*list);
- if (!size || size % info->nbanks) {
- dev_err(info->dev, "wrong mux mask array should be by %d\n",
- info->nbanks);
- return -EINVAL;
- }
- info->nmux = size / info->nbanks;
-
- info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL);
- if (!info->mux_mask) {
- dev_err(info->dev, "could not alloc mux_mask\n");
- return -ENOMEM;
- }
-
- ret = of_property_read_u32_array(np, "plxtech,mux-mask",
- info->mux_mask, size);
- if (ret)
- dev_err(info->dev, "can not read the mux-mask of %d\n", size);
- return ret;
-}
-
-static int oxnas_pinctrl_parse_groups(struct device_node *np,
- struct oxnas_pin_group *grp,
- struct oxnas_pinctrl *info, u32 index)
-{
- struct oxnas_pmx_pin *pin;
- int size;
- const __be32 *list;
- int i, j;
-
- dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
-
- /* Initialise group */
- grp->name = np->name;
-
- /*
- * the binding format is plxtech,pins = <bank pin mux CONFIG ...>,
- * do sanity check and calculate pins number
- */
- list = of_get_property(np, "plxtech,pins", &size);
- /* we do not check return since it's safe node passed down */
- size /= sizeof(*list);
- if (!size || size % 4) {
- dev_err(info->dev, "wrong pins number or pins and configs"
- " should be divisible by 4\n");
- return -EINVAL;
- }
-
- grp->npins = size / 4;
- pin = grp->pins_conf = devm_kzalloc(info->dev,
- grp->npins * sizeof(struct oxnas_pmx_pin),
- GFP_KERNEL);
- grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
- GFP_KERNEL);
- if (!grp->pins_conf || !grp->pins)
- return -ENOMEM;
-
- for (i = 0, j = 0; i < size; i += 4, j++) {
- pin->bank = be32_to_cpu(*list++);
- pin->pin = be32_to_cpu(*list++);
- grp->pins[j] = pin->bank * MAX_NB_GPIO_PER_BANK + pin->pin;
- pin->mux = be32_to_cpu(*list++);
- pin->conf = be32_to_cpu(*list++);
-
- oxnas_pin_dbg(info->dev, pin);
- pin++;
- }
-
- return 0;
-}
-
-static int oxnas_pinctrl_parse_functions(struct device_node *np,
- struct oxnas_pinctrl *info, u32 index)
-{
- struct device_node *child;
- struct oxnas_pmx_func *func;
- struct oxnas_pin_group *grp;
- int ret;
- static u32 grp_index;
- u32 i = 0;
-
- dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
-
- func = &info->functions[index];
-
- /* Initialise function */
- func->name = np->name;
- func->ngroups = of_get_child_count(np);
- if (func->ngroups <= 0) {
- dev_err(info->dev, "no groups defined\n");
- return -EINVAL;
- }
- func->groups = devm_kzalloc(info->dev,
- func->ngroups * sizeof(char *), GFP_KERNEL);
- if (!func->groups)
- return -ENOMEM;
-
- for_each_child_of_node(np, child) {
- func->groups[i] = child->name;
- grp = &info->groups[grp_index++];
- ret = oxnas_pinctrl_parse_groups(child, grp, info, i++);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static struct of_device_id oxnas_pinctrl_of_match[] = {
- { .compatible = "plxtech,nas782x-pinctrl"},
- { /* sentinel */ }
-};
-
-static int oxnas_pinctrl_probe_dt(struct platform_device *pdev,
- struct oxnas_pinctrl *info)
-{
- int ret = 0;
- int i, j;
- uint32_t *tmp;
- struct device_node *np = pdev->dev.of_node;
- struct device_node *child;
-
- if (!np)
- return -ENODEV;
-
- info->dev = &pdev->dev;
-
- oxnas_pinctrl_child_count(info, np);
-
- if (info->nbanks < 1) {
- dev_err(&pdev->dev, "you need to specify atleast one gpio-controller\n");
- return -EINVAL;
- }
-
- ret = oxnas_pinctrl_mux_mask(info, np);
- if (ret)
- return ret;
-
- dev_dbg(&pdev->dev, "nmux = %d\n", info->nmux);
-
- dev_dbg(&pdev->dev, "mux-mask\n");
- tmp = info->mux_mask;
- for (i = 0; i < info->nbanks; i++)
- for (j = 0; j < info->nmux; j++, tmp++)
- dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]);
-
- dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
- dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
- info->functions = devm_kzalloc(&pdev->dev, info->nfunctions *
- sizeof(struct oxnas_pmx_func),
- GFP_KERNEL);
- if (!info->functions)
- return -ENOMEM;
-
- info->groups = devm_kzalloc(&pdev->dev, info->ngroups *
- sizeof(struct oxnas_pin_group),
- GFP_KERNEL);
- if (!info->groups)
- return -ENOMEM;
-
- dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks);
- dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
- dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
-
- i = 0;
-
- for_each_child_of_node(np, child) {
- if (of_device_is_compatible(child, gpio_compat))
- continue;
- ret = oxnas_pinctrl_parse_functions(child, info, i++);
- if (ret) {
- dev_err(&pdev->dev, "failed to parse function\n");
- return ret;
- }
- }
-
- return 0;
-}
-
-static int oxnas_pinctrl_probe(struct platform_device *pdev)
-{
- struct oxnas_pinctrl *info;
- struct pinctrl_pin_desc *pdesc;
- int ret, i, j, k;
-
- info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- ret = oxnas_pinctrl_probe_dt(pdev, info);
- if (ret)
- return ret;
-
- /*
- * We need all the GPIO drivers to probe FIRST, or we will not be able
- * to obtain references to the struct gpio_chip * for them, and we
- * need this to proceed.
- */
- for (i = 0; i < info->nbanks; i++) {
- if (!gpio_chips[i]) {
- dev_warn(&pdev->dev,
- "GPIO chip %d not registered yet\n", i);
- devm_kfree(&pdev->dev, info);
- return -EPROBE_DEFER;
- }
- }
-
- oxnas_pinctrl_desc.name = dev_name(&pdev->dev);
- oxnas_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK;
- oxnas_pinctrl_desc.pins = pdesc =
- devm_kzalloc(&pdev->dev, sizeof(*pdesc) *
- oxnas_pinctrl_desc.npins, GFP_KERNEL);
-
- if (!oxnas_pinctrl_desc.pins)
- return -ENOMEM;
-
- for (i = 0 , k = 0; i < info->nbanks; i++) {
- for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) {
- pdesc->number = k;
- pdesc->name = kasprintf(GFP_KERNEL, "MF_%c%d", i + 'A',
- j);
- pdesc++;
- }
- }
-
- platform_set_drvdata(pdev, info);
- info->pctl = pinctrl_register(&oxnas_pinctrl_desc, &pdev->dev, info);
-
- if (!info->pctl) {
- dev_err(&pdev->dev, "could not register OX820 pinctrl driver\n");
- ret = -EINVAL;
- goto err;
- }
-
- /* We will handle a range of GPIO pins */
- for (i = 0; i < info->nbanks; i++)
- pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range);
-
- dev_info(&pdev->dev, "initialized OX820 pinctrl driver\n");
-
- return 0;
-
-err:
- return ret;
-}
-
-static int oxnas_pinctrl_remove(struct platform_device *pdev)
-{
- struct oxnas_pinctrl *info = platform_get_drvdata(pdev);
-
- pinctrl_unregister(info->pctl);
-
- return 0;
-}
-
-static int oxnas_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
- /*
- * Map back to global GPIO space and request muxing, the direction
- * parameter does not matter for this controller.
- */
- int gpio = chip->base + offset;
- int bank = chip->base / chip->ngpio;
-
- dev_dbg(chip->dev, "%s:%d MF_%c%d(%d)\n", __func__, __LINE__,
- 'A' + bank, offset, gpio);
-
- return pinctrl_request_gpio(gpio);
-}
-
-static void oxnas_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
- int gpio = chip->base + offset;
-
- pinctrl_free_gpio(gpio);
-}
-
-static int oxnas_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
-
- writel_relaxed(BIT(offset), pio + OUTPUT_EN_CLEAR);
- return 0;
-}
-
-static int oxnas_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
- unsigned mask = 1 << offset;
- u32 pdsr;
-
- pdsr = readl_relaxed(pio + INPUT_VALUE);
- return (pdsr & mask) != 0;
-}
-
-static void oxnas_gpio_set(struct gpio_chip *chip, unsigned offset,
- int val)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
-
- if (val)
- writel_relaxed(BIT(offset), pio + OUTPUT_SET);
- else
- writel_relaxed(BIT(offset), pio + OUTPUT_CLEAR);
-
-}
-
-static int oxnas_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
- int val)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
-
- if (val)
- writel_relaxed(BIT(offset), pio + OUTPUT_SET);
- else
- writel_relaxed(BIT(offset), pio + OUTPUT_CLEAR);
-
- writel_relaxed(BIT(offset), pio + OUTPUT_EN_SET);
-
- return 0;
-}
-
-static int oxnas_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- int virq;
-
- if (offset < chip->ngpio)
- virq = irq_create_mapping(oxnas_gpio->domain, offset);
- else
- virq = -ENXIO;
-
- dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
- chip->label, offset + chip->base, virq);
- return virq;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static void oxnas_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
- enum oxnas_mux mode;
- int i;
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
- void __iomem *cio = oxnas_gpio->ctrlbase;
-
- for (i = 0; i < chip->ngpio; i++) {
- unsigned pin = chip->base + i;
- unsigned mask = pin_to_mask(pin);
- const char *gpio_label;
- u32 pdsr;
-
- gpio_label = gpiochip_is_requested(chip, i);
- if (!gpio_label)
- continue;
- /* FIXME */
- mode = oxnas_mux_get_func(cio, mask);
- seq_printf(s, "[%s] GPIO%s%d: ",
- gpio_label, chip->label, i);
- if (mode == OXNAS_PINMUX_GPIO) {
- pdsr = readl_relaxed(pio + INPUT_VALUE);
-
- seq_printf(s, "[gpio] %s\n",
- pdsr & mask ?
- "set" : "clear");
- } else {
- seq_printf(s, "[periph %c]\n",
- mode + 'A' - 1);
- }
- }
-}
-#else
-#define oxnas_gpio_dbg_show NULL
-#endif
-
-/* Several AIC controller irqs are dispatched through this GPIO handler.
- * To use any AT91_PIN_* as an externally triggered IRQ, first call
- * oxnas_set_gpio_input() then maybe enable its glitch filter.
- * Then just request_irq() with the pin ID; it works like any ARM IRQ
- * handler.
- */
-
-static void gpio_irq_mask(struct irq_data *d)
-{
- struct oxnas_gpio_chip *oxnas_gpio = irq_data_get_irq_chip_data(d);
- void __iomem *pio = oxnas_gpio->regbase;
- unsigned mask = 1 << d->hwirq;
- unsigned type = irqd_get_trigger_type(d);
- unsigned long flags;
-
- if (!(type & IRQ_TYPE_EDGE_BOTH))
- return;
-
- spin_lock_irqsave(&oxnas_gpio->lock, flags);
- if (type & IRQ_TYPE_EDGE_RISING)
- oxnas_register_clear_mask(pio + RE_IRQ_ENABLE, mask);
- if (type & IRQ_TYPE_EDGE_FALLING)
- oxnas_register_clear_mask(pio + FE_IRQ_ENABLE, mask);
- spin_unlock_irqrestore(&oxnas_gpio->lock, flags);
-}
-
-static void gpio_irq_unmask(struct irq_data *d)
-{
- struct oxnas_gpio_chip *oxnas_gpio = irq_data_get_irq_chip_data(d);
- void __iomem *pio = oxnas_gpio->regbase;
- unsigned mask = 1 << d->hwirq;
- unsigned type = irqd_get_trigger_type(d);
- unsigned long flags;
-
- if (!(type & IRQ_TYPE_EDGE_BOTH))
- return;
-
- spin_lock_irqsave(&oxnas_gpio->lock, flags);
- if (type & IRQ_TYPE_EDGE_RISING)
- oxnas_register_set_mask(pio + RE_IRQ_ENABLE, mask);
- if (type & IRQ_TYPE_EDGE_FALLING)
- oxnas_register_set_mask(pio + FE_IRQ_ENABLE, mask);
- spin_unlock_irqrestore(&oxnas_gpio->lock, flags);
-}
-
-
-static int gpio_irq_type(struct irq_data *d, unsigned type)
-{
- if ((type & IRQ_TYPE_EDGE_BOTH) == 0) {
- pr_warn("OX820: Unsupported type for irq %d\n",
- gpio_to_irq(d->irq));
- return -EINVAL;
- }
- /* seems no way to set trigger type without enable irq, so leave it to unmask time */
-
- return 0;
-}
-
-static struct irq_chip gpio_irqchip = {
- .name = "GPIO",
- .irq_disable = gpio_irq_mask,
- .irq_mask = gpio_irq_mask,
- .irq_unmask = gpio_irq_unmask,
- .irq_set_type = gpio_irq_type,
-};
-
-static void gpio_irq_handler(struct irq_desc *desc)
-{
- struct irq_chip *chip = irq_desc_get_chip(desc);
- struct irq_data *idata = irq_desc_get_irq_data(desc);
- struct oxnas_gpio_chip *oxnas_gpio = irq_data_get_irq_chip_data(idata);
- void __iomem *pio = oxnas_gpio->regbase;
- unsigned long isr;
- int n;
-
- chained_irq_enter(chip, desc);
- for (;;) {
- /* TODO: see if it works */
- isr = readl_relaxed(pio + IRQ_PENDING);
- if (!isr)
- break;
- /* acks pending interrupts */
- writel_relaxed(isr, pio + IRQ_PENDING);
-
- for_each_set_bit(n, &isr, BITS_PER_LONG) {
- generic_handle_irq(irq_find_mapping(oxnas_gpio->domain,
- n));
- }
- }
- chained_irq_exit(chip, desc);
- /* now it may re-trigger */
-}
-
-/*
- * This lock class tells lockdep that GPIO irqs are in a different
- * category than their parents, so it won't report false recursion.
- */
-static struct lock_class_key gpio_lock_class;
-
-static int oxnas_gpio_irq_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct oxnas_gpio_chip *oxnas_gpio = h->host_data;
-
- irq_set_lockdep_class(virq, &gpio_lock_class);
-
- irq_set_chip_and_handler(virq, &gpio_irqchip, handle_edge_irq);
- irq_set_chip_data(virq, oxnas_gpio);
-
- return 0;
-}
-
-static int oxnas_gpio_irq_domain_xlate(struct irq_domain *d,
- struct device_node *ctrlr,
- const u32 *intspec,
- unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_type)
-{
- struct oxnas_gpio_chip *oxnas_gpio = d->host_data;
- int ret;
- int pin = oxnas_gpio->chip.base + intspec[0];
-
- if (WARN_ON(intsize < 2))
- return -EINVAL;
- *out_hwirq = intspec[0];
- *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
-
- ret = gpio_request(pin, ctrlr->full_name);
- if (ret)
- return ret;
-
- ret = gpio_direction_input(pin);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static struct irq_domain_ops oxnas_gpio_ops = {
- .map = oxnas_gpio_irq_map,
- .xlate = oxnas_gpio_irq_domain_xlate,
-};
-
-static int oxnas_gpio_of_irq_setup(struct device_node *node,
- struct oxnas_gpio_chip *oxnas_gpio,
- unsigned int irq)
-{
- /* Disable irqs of this controller */
- writel_relaxed(0, oxnas_gpio->regbase + RE_IRQ_ENABLE);
- writel_relaxed(0, oxnas_gpio->regbase + FE_IRQ_ENABLE);
-
- /* Setup irq domain */
- oxnas_gpio->domain = irq_domain_add_linear(node, oxnas_gpio->chip.ngpio,
- &oxnas_gpio_ops, oxnas_gpio);
- if (!oxnas_gpio->domain)
- panic("oxnas_gpio: couldn't allocate irq domain (DT).\n");
-
- irq_set_chip_data(irq, oxnas_gpio);
- irq_set_chained_handler(irq, gpio_irq_handler);
-
- return 0;
-}
-
-/* This structure is replicated for each GPIO block allocated at probe time */
-static struct gpio_chip oxnas_gpio_template = {
- .request = oxnas_gpio_request,
- .free = oxnas_gpio_free,
- .direction_input = oxnas_gpio_direction_input,
- .get = oxnas_gpio_get,
- .direction_output = oxnas_gpio_direction_output,
- .set = oxnas_gpio_set,
- .to_irq = oxnas_gpio_to_irq,
- .dbg_show = oxnas_gpio_dbg_show,
- .can_sleep = 0,
- .ngpio = MAX_NB_GPIO_PER_BANK,
-};
-
-static struct of_device_id oxnas_gpio_of_match[] = {
- { .compatible = "plxtech,nas782x-gpio"},
- { /* sentinel */ }
-};
-
-static int oxnas_gpio_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct resource *res;
- struct oxnas_gpio_chip *oxnas_chip = NULL;
- struct gpio_chip *chip;
- struct pinctrl_gpio_range *range;
- int ret = 0;
- int irq, i;
- int alias_idx = of_alias_get_id(np, "gpio");
- uint32_t ngpio;
- char **names;
-
- BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips));
- if (gpio_chips[alias_idx]) {
- ret = -EBUSY;
- goto err;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto err;
- }
-
- oxnas_chip = devm_kzalloc(&pdev->dev, sizeof(*oxnas_chip), GFP_KERNEL);
- if (!oxnas_chip) {
- ret = -ENOMEM;
- goto err;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- oxnas_chip->regbase = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(oxnas_chip->regbase)) {
- ret = PTR_ERR(oxnas_chip->regbase);
- goto err;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- oxnas_chip->ctrlbase = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(oxnas_chip->ctrlbase)) {
- ret = PTR_ERR(oxnas_chip->ctrlbase);
- goto err;
- }
-
- oxnas_chip->chip = oxnas_gpio_template;
-
- spin_lock_init(&oxnas_chip->lock);
-
- chip = &oxnas_chip->chip;
- chip->of_node = np;
- chip->label = dev_name(&pdev->dev);
- chip->dev = &pdev->dev;
- chip->owner = THIS_MODULE;
- chip->base = alias_idx * MAX_NB_GPIO_PER_BANK;
-
- if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) {
- if (ngpio > MAX_NB_GPIO_PER_BANK)
- pr_err("oxnas_gpio.%d, gpio-nb >= %d failback to %d\n",
- alias_idx, MAX_NB_GPIO_PER_BANK,
- MAX_NB_GPIO_PER_BANK);
- else
- chip->ngpio = ngpio;
- }
-
- names = devm_kzalloc(&pdev->dev, sizeof(char *) * chip->ngpio,
- GFP_KERNEL);
-
- if (!names) {
- ret = -ENOMEM;
- goto err;
- }
-
- for (i = 0; i < chip->ngpio; i++)
- names[i] = kasprintf(GFP_KERNEL, "MF_%c%d", alias_idx + 'A', i);
-
- chip->names = (const char *const *)names;
-
- range = &oxnas_chip->range;
- range->name = chip->label;
- range->id = alias_idx;
- range->pin_base = range->base = range->id * MAX_NB_GPIO_PER_BANK;
-
- range->npins = chip->ngpio;
- range->gc = chip;
-
- ret = gpiochip_add(chip);
- if (ret)
- goto err;
-
- gpio_chips[alias_idx] = oxnas_chip;
- gpio_banks = max(gpio_banks, alias_idx + 1);
-
- oxnas_gpio_of_irq_setup(np, oxnas_chip, irq);
-
- dev_info(&pdev->dev, "at address %p\n", oxnas_chip->regbase);
-
- return 0;
-err:
- dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx);
-
- return ret;
-}
-
-static struct platform_driver oxnas_gpio_driver = {
- .driver = {
- .name = "gpio-oxnas",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(oxnas_gpio_of_match),
- },
- .probe = oxnas_gpio_probe,
-};
-
-static struct platform_driver oxnas_pinctrl_driver = {
- .driver = {
- .name = "pinctrl-oxnas",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(oxnas_pinctrl_of_match),
- },
- .probe = oxnas_pinctrl_probe,
- .remove = oxnas_pinctrl_remove,
-};
-
-static int __init oxnas_pinctrl_init(void)
-{
- int ret;
-
- ret = platform_driver_register(&oxnas_gpio_driver);
- if (ret)
- return ret;
- return platform_driver_register(&oxnas_pinctrl_driver);
-}
-arch_initcall(oxnas_pinctrl_init);
-
-static void __exit oxnas_pinctrl_exit(void)
-{
- platform_driver_unregister(&oxnas_pinctrl_driver);
-}
-
-module_exit(oxnas_pinctrl_exit);
-MODULE_AUTHOR("Ma Hajun <mahaijuns@gmail.com>");
-MODULE_DESCRIPTION("Plxtech Nas782x pinctrl driver");
-MODULE_LICENSE("GPL v2");
diff --git a/target/linux/oxnas/files/drivers/reset/reset-ox820.c b/target/linux/oxnas/files/drivers/reset/reset-ox820.c
deleted file mode 100644
index 0a28de55f4..0000000000
--- a/target/linux/oxnas/files/drivers/reset/reset-ox820.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/reset-controller.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <mach/hardware.h>
-
-static int ox820_reset_reset(struct reset_controller_dev *rcdev,
- unsigned long id)
-{
- writel(BIT(id), SYS_CTRL_RST_SET_CTRL);
- writel(BIT(id), SYS_CTRL_RST_CLR_CTRL);
- return 0;
-}
-
-static int ox820_reset_assert(struct reset_controller_dev *rcdev,
- unsigned long id)
-{
- writel(BIT(id), SYS_CTRL_RST_SET_CTRL);
-
- return 0;
-}
-
-static int ox820_reset_deassert(struct reset_controller_dev *rcdev,
- unsigned long id)
-{
- writel(BIT(id), SYS_CTRL_RST_CLR_CTRL);
-
- return 0;
-}
-
-static struct reset_control_ops ox820_reset_ops = {
- .reset = ox820_reset_reset,
- .assert = ox820_reset_assert,
- .deassert = ox820_reset_deassert,
-};
-
-static const struct of_device_id ox820_reset_dt_ids[] = {
- { .compatible = "plxtech,nas782x-reset", },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, ox820_reset_dt_ids);
-
-struct reset_controller_dev rcdev;
-
-static int ox820_reset_probe(struct platform_device *pdev)
-{
- struct reset_controller_dev *rcdev;
-
- rcdev = devm_kzalloc(&pdev->dev, sizeof(*rcdev), GFP_KERNEL);
- if (!rcdev)
- return -ENOMEM;
-
- /* note: reset controller is statically mapped */
-
- rcdev->owner = THIS_MODULE;
- rcdev->nr_resets = 32;
- rcdev->ops = &ox820_reset_ops;
- rcdev->of_node = pdev->dev.of_node;
- reset_controller_register(rcdev);
- platform_set_drvdata(pdev, rcdev);
-
- return 0;
-}
-
-static int ox820_reset_remove(struct platform_device *pdev)
-{
- struct reset_controller_dev *rcdev = platform_get_drvdata(pdev);
-
- reset_controller_unregister(rcdev);
-
- return 0;
-}
-
-static struct platform_driver ox820_reset_driver = {
- .probe = ox820_reset_probe,
- .remove = ox820_reset_remove,
- .driver = {
- .name = "ox820-reset",
- .owner = THIS_MODULE,
- .of_match_table = ox820_reset_dt_ids,
- },
-};
-
-static int __init ox820_reset_init(void)
-{
- return platform_driver_probe(&ox820_reset_driver,
- ox820_reset_probe);
-}
-/*
- * reset controller does not support probe deferral, so it has to be
- * initialized before any user, in particular, PCIE uses subsys_initcall.
- */
-arch_initcall(ox820_reset_init);
-
-MODULE_AUTHOR("Ma Haijun");
-MODULE_LICENSE("GPL");
diff --git a/target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c b/target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c
index 15578a3027..79c4fa3a95 100644
--- a/target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c
+++ b/target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c
@@ -14,13 +14,59 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
+#include <linux/mfd/syscon.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
+#include <linux/regmap.h>
#include <linux/reset.h>
-#include <mach/hardware.h>
-#include <mach/utils.h>
+
+#define USBHSMPH_CTRL_REGOFFSET 0x40
+#define USBHSMPH_STAT_REGOFFSET 0x44
+#define REF300_DIV_REGOFFSET 0xF8
+#define USBHSPHY_CTRL_REGOFFSET 0x84
+#define USB_CTRL_REGOFFSET 0x90
+#define PLLB_DIV_CTRL_REGOFFSET 0x1000F8
+#define USBHSPHY_SUSPENDM_MANUAL_ENABLE 16
+#define USBHSPHY_SUSPENDM_MANUAL_STATE 15
+#define USBHSPHY_ATE_ESET 14
+#define USBHSPHY_TEST_DIN 6
+#define USBHSPHY_TEST_ADD 2
+#define USBHSPHY_TEST_DOUT_SEL 1
+#define USBHSPHY_TEST_CLK 0
+
+#define USB_CTRL_USBAPHY_CKSEL_SHIFT 5
+#define USB_CLK_XTAL0_XTAL1 (0 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+#define USB_CLK_XTAL0 (1 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+#define USB_CLK_INTERNAL (2 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+
+#define USBAMUX_DEVICE BIT(4)
+
+#define USBPHY_REFCLKDIV_SHIFT 2
+#define USB_PHY_REF_12MHZ (0 << USBPHY_REFCLKDIV_SHIFT)
+#define USB_PHY_REF_24MHZ (1 << USBPHY_REFCLKDIV_SHIFT)
+#define USB_PHY_REF_48MHZ (2 << USBPHY_REFCLKDIV_SHIFT)
+
+#define USB_CTRL_USB_CKO_SEL_BIT 0
+
+#define USB_INT_CLK_XTAL 0
+#define USB_INT_CLK_REF300 2
+#define USB_INT_CLK_PLLB 3
+
+#define REF300_DIV_INT_SHIFT 8
+#define REF300_DIV_FRAC_SHIFT 0
+#define REF300_DIV_INT(val) ((val) << REF300_DIV_INT_SHIFT)
+#define REF300_DIV_FRAC(val) ((val) << REF300_DIV_FRAC_SHIFT)
+
+#define PLLB_BYPASS 1
+#define PLLB_ENSAT 3
+#define PLLB_OUTDIV 4
+#define PLLB_REFDIV 8
+#define PLLB_DIV_INT_SHIFT 8
+#define PLLB_DIV_FRAC_SHIFT 0
+#define PLLB_DIV_INT(val) ((val) << PLLB_DIV_INT_SHIFT)
+#define PLLB_DIV_FRAC(val) ((val) << PLLB_DIV_FRAC_SHIFT)
#include "ehci.h"
@@ -33,6 +79,7 @@ struct oxnas_hcd {
struct reset_control *rst_host;
struct reset_control *rst_phya;
struct reset_control *rst_phyb;
+ struct regmap *syscon;
};
#define DRIVER_DESC "Oxnas On-Chip EHCI Host Controller"
@@ -41,21 +88,16 @@ static struct hc_driver __read_mostly oxnas_hc_driver;
static void start_oxnas_usb_ehci(struct oxnas_hcd *oxnas)
{
- u32 reg;
-
if (oxnas->use_pllb) {
/* enable pllb */
clk_prepare_enable(oxnas->refsrc);
/* enable ref600 */
clk_prepare_enable(oxnas->phyref);
/* 600MHz pllb divider for 12MHz */
- writel(PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0),
- SEC_CTRL_PLLB_DIV_CTRL);
-
+ regmap_write_bits(oxnas->syscon, PLLB_DIV_CTRL_REGOFFSET, 0xffff, PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0));
} else {
/* ref 300 divider for 12MHz */
- writel(REF300_DIV_INT(25) | REF300_DIV_FRAC(0),
- SYS_CTRL_REF300_DIV);
+ regmap_write_bits(oxnas->syscon, REF300_DIV_REGOFFSET, 0xffff, REF300_DIV_INT(25) | REF300_DIV_FRAC(0));
}
/* Ensure the USB block is properly reset */
@@ -65,31 +107,34 @@ static void start_oxnas_usb_ehci(struct oxnas_hcd *oxnas)
/* Force the high speed clock to be generated all the time, via serial
programming of the USB HS PHY */
- writel((2UL << USBHSPHY_TEST_ADD) |
- (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
+ regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
+ (2UL << USBHSPHY_TEST_ADD) |
+ (0xe0UL << USBHSPHY_TEST_DIN));
- writel((1UL << USBHSPHY_TEST_CLK) |
- (2UL << USBHSPHY_TEST_ADD) |
- (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
+ regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
+ (1UL << USBHSPHY_TEST_CLK) |
+ (2UL << USBHSPHY_TEST_ADD) |
+ (0xe0UL << USBHSPHY_TEST_DIN));
- writel((0xfUL << USBHSPHY_TEST_ADD) |
- (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
+ regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
+ (0xfUL << USBHSPHY_TEST_ADD) |
+ (0xaaUL << USBHSPHY_TEST_DIN));
- writel((1UL << USBHSPHY_TEST_CLK) |
- (0xfUL << USBHSPHY_TEST_ADD) |
- (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
+ regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
+ (1UL << USBHSPHY_TEST_CLK) |
+ (0xfUL << USBHSPHY_TEST_ADD) |
+ (0xaaUL << USBHSPHY_TEST_DIN));
if (oxnas->use_pllb) /* use pllb clock */
- writel(USB_CLK_INTERNAL | USB_INT_CLK_PLLB, SYS_CTRL_USB_CTRL);
+ regmap_write_bits(oxnas->syscon, USB_CTRL_REGOFFSET, 0xffff,
+ USB_CLK_INTERNAL | USB_INT_CLK_PLLB);
else /* use ref300 derived clock */
- writel(USB_CLK_INTERNAL | USB_INT_CLK_REF300,
- SYS_CTRL_USB_CTRL);
+ regmap_write_bits(oxnas->syscon, USB_CTRL_REGOFFSET, 0xffff,
+ USB_CLK_INTERNAL | USB_INT_CLK_REF300);
if (oxnas->use_phya) {
/* Configure USB PHYA as a host */
- reg = readl(SYS_CTRL_USB_CTRL);
- reg &= ~USBAMUX_DEVICE;
- writel(reg, SYS_CTRL_USB_CTRL);
+ regmap_update_bits(oxnas->syscon, USB_CTRL_REGOFFSET, USBAMUX_DEVICE, 0);
}
/* Enable the clock to the USB block */
@@ -172,8 +217,14 @@ static int ehci_oxnas_drv_probe(struct platform_device *ofdev)
oxnas = (struct oxnas_hcd *)hcd_to_ehci(hcd)->priv;
- oxnas->use_pllb = of_property_read_bool(np, "plxtech,ehci_use_pllb");
- oxnas->use_phya = of_property_read_bool(np, "plxtech,ehci_use_phya");
+ oxnas->use_pllb = of_property_read_bool(np, "oxsemi,ehci_use_pllb");
+ oxnas->use_phya = of_property_read_bool(np, "oxsemi,ehci_use_phya");
+
+ oxnas->syscon = syscon_regmap_lookup_by_phandle(np, "oxsemi,sys-ctrl");
+ if (IS_ERR(oxnas->syscon)) {
+ err = PTR_ERR(oxnas->syscon);
+ goto err_syscon;
+ }
oxnas->clk = of_clk_get_by_name(np, "usb");
if (IS_ERR(oxnas->clk)) {
@@ -249,6 +300,7 @@ err_phyref:
clk_put(oxnas->refsrc);
err_refsrc:
clk_put(oxnas->clk);
+err_syscon:
err_clk:
err_ioremap:
err_res: