diff options
Diffstat (limited to 'target/linux/ramips/patches-5.4')
69 files changed, 0 insertions, 8893 deletions
diff --git a/target/linux/ramips/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch b/target/linux/ramips/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch deleted file mode 100644 index eedc7498be..0000000000 --- a/target/linux/ramips/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch +++ /dev/null @@ -1,192 +0,0 @@ -From: Paul Burton <paul.burton@mips.com> -Date: Wed, 9 Oct 2019 23:09:45 +0000 -Subject: MIPS: cmdline: Clean up boot_command_line initialization - -Our current code to initialize boot_command_line is a mess. Some of this -is due to the addition of too many options over the years, and some of -this is due to workarounds for early_init_dt_scan_chosen() performing -actions specific to options from other architectures that probably -shouldn't be in generic code. - -Clean this up by introducing a new bootcmdline_init() function that -simplifies the initialization somewhat. The major changes are: - -- Because bootcmdline_init() is a function it can return early in the - CONFIG_CMDLINE_OVERRIDE case. - -- We clear boot_command_line rather than inheriting whatever - early_init_dt_scan_chosen() may have left us. This means we no longer - need to set boot_command_line to a space character in an attempt to - prevent early_init_dt_scan_chosen() from copying CONFIG_CMDLINE into - boot_command_line without us knowing about it. - -- Indirection via USE_PROM_CMDLINE, USE_DTB_CMDLINE, EXTEND_WITH_PROM & - BUILTIN_EXTEND_WITH_PROM macros is removed; they seemingly served only - to obfuscate the code. - -- The logic is cleaner, clearer & commented. - -Two minor drawbacks of this approach are: - -1) We call of_scan_flat_dt(), which means we scan through the DT again. - The overhead is fairly minimal & shouldn't be noticeable. - -2) cmdline_scan_chosen() duplicates a small amount of the logic from - early_init_dt_scan_chosen(). Alternatives might be to allow the - generic FDT code to keep & expose a copy of the arguments taken from - the /chosen node's bootargs property, or to introduce a function like - early_init_dt_scan_chosen() that retrieves them without modification - to handle CONFIG_CMDLINE. Neither of these sounds particularly - cleaner though, and this way we at least keep the extra work in - arch/mips. - -Origin: upstream, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7784cac697351f0cc0a4bb619594c0c99348c5aa -Signed-off-by: Paul Burton <paul.burton@mips.com> -Cc: linux-mips@vger.kernel.org - ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -538,11 +538,88 @@ static void __init check_kernel_sections - } - } - --#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) --#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) --#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) --#define BUILTIN_EXTEND_WITH_PROM \ -- IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND) -+static void __init bootcmdline_append(const char *s, size_t max) -+{ -+ if (!s[0] || !max) -+ return; -+ -+ if (boot_command_line[0]) -+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); -+ -+ strlcat(boot_command_line, s, max); -+} -+ -+static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname, -+ int depth, void *data) -+{ -+ bool *dt_bootargs = data; -+ const char *p; -+ int l; -+ -+ if (depth != 1 || !data || -+ (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) -+ return 0; -+ -+ p = of_get_flat_dt_prop(node, "bootargs", &l); -+ if (p != NULL && l > 0) { -+ bootcmdline_append(p, min(l, COMMAND_LINE_SIZE)); -+ *dt_bootargs = true; -+ } -+ -+ return 1; -+} -+ -+static void __init bootcmdline_init(char **cmdline_p) -+{ -+ bool dt_bootargs = false; -+ -+ /* -+ * If CMDLINE_OVERRIDE is enabled then initializing the command line is -+ * trivial - we simply use the built-in command line unconditionally & -+ * unmodified. -+ */ -+ if (IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) { -+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); -+ return; -+ } -+ -+ /* -+ * If the user specified a built-in command line & -+ * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is -+ * prepended to arguments from the bootloader or DT so we'll copy them -+ * to the start of boot_command_line here. Otherwise, empty -+ * boot_command_line to undo anything early_init_dt_scan_chosen() did. -+ */ -+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)) -+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); -+ else -+ boot_command_line[0] = 0; -+ -+ /* -+ * If we're configured to take boot arguments from DT, look for those -+ * now. -+ */ -+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)) -+ of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs); -+ -+ /* -+ * If we didn't get any arguments from DT (regardless of whether that's -+ * because we weren't configured to look for them, or because we looked -+ * & found none) then we'll take arguments from the bootloader. -+ * plat_mem_setup() should have filled arcs_cmdline with arguments from -+ * the bootloader. -+ */ -+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) || !dt_bootargs) -+ bootcmdline_append(arcs_cmdline, COMMAND_LINE_SIZE); -+ -+ /* -+ * If the user specified a built-in command line & we didn't already -+ * prepend it, we append it to boot_command_line here. -+ */ -+ if (IS_ENABLED(CONFIG_CMDLINE_BOOL) && -+ !IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)) -+ bootcmdline_append(builtin_cmdline, COMMAND_LINE_SIZE); -+} - - /* - * arch_mem_init - initialize memory management subsystem -@@ -570,48 +647,12 @@ static void __init arch_mem_init(char ** - { - extern void plat_mem_setup(void); - -- /* -- * Initialize boot_command_line to an innocuous but non-empty string in -- * order to prevent early_init_dt_scan_chosen() from copying -- * CONFIG_CMDLINE into it without our knowledge. We handle -- * CONFIG_CMDLINE ourselves below & don't want to duplicate its -- * content because repeating arguments can be problematic. -- */ -- strlcpy(boot_command_line, " ", COMMAND_LINE_SIZE); -- - /* call board setup routine */ - plat_mem_setup(); - memblock_set_bottom_up(true); - --#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE) -- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); --#else -- if ((USE_PROM_CMDLINE && arcs_cmdline[0]) || -- (USE_DTB_CMDLINE && !boot_command_line[0])) -- strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); -- -- if (EXTEND_WITH_PROM && arcs_cmdline[0]) { -- if (boot_command_line[0]) -- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); -- strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); -- } -- --#if defined(CONFIG_CMDLINE_BOOL) -- if (builtin_cmdline[0]) { -- if (boot_command_line[0]) -- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); -- strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); -- } -- -- if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) { -- if (boot_command_line[0]) -- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); -- strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); -- } --#endif --#endif -+ bootcmdline_init(cmdline_p); - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); -- - *cmdline_p = command_line; - - parse_early_param(); diff --git a/target/linux/ramips/patches-5.4/0002-MIPS-Always-define-builtin_cmdline.patch b/target/linux/ramips/patches-5.4/0002-MIPS-Always-define-builtin_cmdline.patch deleted file mode 100644 index 03124d07d1..0000000000 --- a/target/linux/ramips/patches-5.4/0002-MIPS-Always-define-builtin_cmdline.patch +++ /dev/null @@ -1,44 +0,0 @@ -From b7340422cc16c5deff100812f38114bb5ec81203 Mon Sep 17 00:00:00 2001 -From: Paul Burton <paul.burton@mips.com> -Date: Sat, 12 Oct 2019 20:43:36 +0000 -Subject: [PATCH] MIPS: Always define builtin_cmdline - -Commit 7784cac69735 ("MIPS: cmdline: Clean up boot_command_line -initialization") made use of builtin_cmdline conditional upon plain C if -statements rather than preprocessor #ifdef's. This caused build failures -for configurations with CONFIG_CMDLINE_BOOL=n where builtin_cmdline -wasn't defined, for example: - - arch/mips/kernel/setup.c: In function 'bootcmdline_init': ->> arch/mips/kernel/setup.c:582:30: error: 'builtin_cmdline' undeclared - (first use in this function); did you mean 'builtin_driver'? - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); - ^~~~~~~~~~~~~~~ - builtin_driver - arch/mips/kernel/setup.c:582:30: note: each undeclared identifier is - reported only once for each function it appears in - -Fix this by defining builtin_cmdline as an empty string in the affected -configurations. All of the paths that use it should be optimized out -anyway so the data itself gets optimized away too. - -Signed-off-by: Paul Burton <paul.burton@mips.com> -Fixes: 7784cac69735 ("MIPS: cmdline: Clean up boot_command_line initialization") -Reported-by: kbuild test robot <lkp@intel.com> -Reported-by: Nathan Chancellor <natechancellor@gmail.com> -Cc: linux-mips@vger.kernel.org ---- - arch/mips/kernel/setup.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -68,6 +68,8 @@ char __initdata arcs_cmdline[COMMAND_LIN - - #ifdef CONFIG_CMDLINE_BOOL - static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; -+#else -+static const char builtin_cmdline[] __initconst = ""; - #endif - - /* diff --git a/target/linux/ramips/patches-5.4/0003-MIPS-Fix-memory-reservation-in-bootmem_init-for-cert.patch b/target/linux/ramips/patches-5.4/0003-MIPS-Fix-memory-reservation-in-bootmem_init-for-cert.patch deleted file mode 100644 index 63429f49b0..0000000000 --- a/target/linux/ramips/patches-5.4/0003-MIPS-Fix-memory-reservation-in-bootmem_init-for-cert.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Tobias Wolf <dev-NTEO@vplace.de> -Subject: [v2] MIPS: Fix memory reservation in bootmem_init for certain non-usermem setups - -Commit 67a3ba25aa95 ("MIPS: Fix incorrect mem=X@Y handling") introduced a new -issue for rt288x where "PHYS_OFFSET" is 0x0 but the calculated "ramstart" is -not. As the prerequisite of custom memory map has been removed, this results -in the full memory range of 0x0 - 0x8000000 to be marked as reserved for this -platform. - -v2: Correctly compare that usermem is not null. - -This patch adds the originally intended prerequisite again. - -Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de> ---- - ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -287,6 +287,8 @@ static unsigned long __init init_initrd( - * Initialize the bootmem allocator. It also setup initrd related data - * if needed. - */ -+static int usermem __initdata; -+ - #if defined(CONFIG_SGI_IP27) || (defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_NUMA)) - - static void __init bootmem_init(void) -@@ -325,7 +327,7 @@ static void __init bootmem_init(void) - /* - * Reserve any memory between the start of RAM and PHYS_OFFSET - */ -- if (ramstart > PHYS_OFFSET) -+ if (usermem && ramstart > PHYS_OFFSET) - memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET); - - if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) { -@@ -386,8 +388,6 @@ static void __init bootmem_init(void) - - #endif /* CONFIG_SGI_IP27 */ - --static int usermem __initdata; -- - static int __init early_parse_mem(char *p) - { - phys_addr_t start, size; diff --git a/target/linux/ramips/patches-5.4/0005-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch b/target/linux/ramips/patches-5.4/0005-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch deleted file mode 100644 index 773c74f4e9..0000000000 --- a/target/linux/ramips/patches-5.4/0005-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch +++ /dev/null @@ -1,82 +0,0 @@ -From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sun, 14 Jul 2013 23:08:11 +0200 -Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k - irq - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - arch/mips/ralink/Kconfig | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -1,12 +1,17 @@ - # SPDX-License-Identifier: GPL-2.0 - if RALINK - -+config CEVT_SYSTICK_QUIRK -+ bool -+ default n -+ - config CLKEVT_RT3352 - bool - depends on SOC_RT305X || SOC_MT7620 - default y - select TIMER_OF - select CLKSRC_MMIO -+ select CEVT_SYSTICK_QUIRK - - config RALINK_ILL_ACC - bool ---- a/arch/mips/kernel/cevt-r4k.c -+++ b/arch/mips/kernel/cevt-r4k.c -@@ -15,6 +15,26 @@ - #include <asm/time.h> - #include <asm/cevt-r4k.h> - -+static int mips_state_oneshot(struct clock_event_device *evt) -+{ -+ if (!cp0_timer_irq_installed) { -+ cp0_timer_irq_installed = 1; -+ setup_irq(evt->irq, &c0_compare_irqaction); -+ } -+ -+ return 0; -+} -+ -+static int mips_state_shutdown(struct clock_event_device *evt) -+{ -+ if (cp0_timer_irq_installed) { -+ cp0_timer_irq_installed = 0; -+ remove_irq(evt->irq, &c0_compare_irqaction); -+ } -+ -+ return 0; -+} -+ - static int mips_next_event(unsigned long delta, - struct clock_event_device *evt) - { -@@ -281,17 +301,21 @@ int r4k_clockevent_init(void) - cd->rating = 300; - cd->irq = irq; - cd->cpumask = cpumask_of(cpu); -+ cd->set_state_shutdown = mips_state_shutdown; -+ cd->set_state_oneshot = mips_state_oneshot; - cd->set_next_event = mips_next_event; - cd->event_handler = mips_event_handler; - - clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff); - -+#ifndef CONFIG_CEVT_SYSTICK_QUIRK - if (cp0_timer_irq_installed) - return 0; - - cp0_timer_irq_installed = 1; - - setup_irq(irq, &c0_compare_irqaction); -+#endif - - return 0; - } diff --git a/target/linux/ramips/patches-5.4/0006-MIPS-ralink-add-cpu-frequency-scaling.patch b/target/linux/ramips/patches-5.4/0006-MIPS-ralink-add-cpu-frequency-scaling.patch deleted file mode 100644 index a3b8e4d250..0000000000 --- a/target/linux/ramips/patches-5.4/0006-MIPS-ralink-add-cpu-frequency-scaling.patch +++ /dev/null @@ -1,200 +0,0 @@ -From bd30f19a006fb52bac80c6463c49dd2f4159f4ac Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sun, 28 Jul 2013 16:26:41 +0200 -Subject: [PATCH 06/53] MIPS: ralink: add cpu frequency scaling - -This feature will break udelay() and cause the delay loop to have longer delays -when the frequency is scaled causing a performance hit. - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - arch/mips/ralink/cevt-rt3352.c | 38 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - ---- a/arch/mips/ralink/cevt-rt3352.c -+++ b/arch/mips/ralink/cevt-rt3352.c -@@ -29,6 +29,10 @@ - /* enable the counter */ - #define CFG_CNT_EN 0x1 - -+/* mt7620 frequency scaling defines */ -+#define CLK_LUT_CFG 0x40 -+#define SLEEP_EN BIT(31) -+ - struct systick_device { - void __iomem *membase; - struct clock_event_device dev; -@@ -36,21 +40,53 @@ struct systick_device { - int freq_scale; - }; - -+static void (*systick_freq_scaling)(struct systick_device *sdev, int status); -+ - static int systick_set_oneshot(struct clock_event_device *evt); - static int systick_shutdown(struct clock_event_device *evt); - -+static inline void mt7620_freq_scaling(struct systick_device *sdev, int status) -+{ -+ if (sdev->freq_scale == status) -+ return; -+ -+ sdev->freq_scale = status; -+ -+ pr_info("%s: %s autosleep mode\n", sdev->dev.name, -+ (status) ? ("enable") : ("disable")); -+ if (status) -+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG); -+ else -+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG); -+} -+ -+static inline unsigned int read_count(struct systick_device *sdev) -+{ -+ return ioread32(sdev->membase + SYSTICK_COUNT); -+} -+ -+static inline unsigned int read_compare(struct systick_device *sdev) -+{ -+ return ioread32(sdev->membase + SYSTICK_COMPARE); -+} -+ -+static inline void write_compare(struct systick_device *sdev, unsigned int val) -+{ -+ iowrite32(val, sdev->membase + SYSTICK_COMPARE); -+} -+ - static int systick_next_event(unsigned long delta, - struct clock_event_device *evt) - { - struct systick_device *sdev; -- u32 count; -+ int res; - - sdev = container_of(evt, struct systick_device, dev); -- count = ioread32(sdev->membase + SYSTICK_COUNT); -- count = (count + delta) % SYSTICK_FREQ; -- iowrite32(count, sdev->membase + SYSTICK_COMPARE); -+ delta += read_count(sdev); -+ write_compare(sdev, delta); -+ res = ((int)(read_count(sdev) - delta) >= 0) ? -ETIME : 0; - -- return 0; -+ return res; - } - - static void systick_event_handler(struct clock_event_device *dev) -@@ -60,20 +96,25 @@ static void systick_event_handler(struct - - static irqreturn_t systick_interrupt(int irq, void *dev_id) - { -- struct clock_event_device *dev = (struct clock_event_device *) dev_id; -+ int ret = 0; -+ struct clock_event_device *cdev; -+ struct systick_device *sdev; - -- dev->event_handler(dev); -+ if (read_c0_cause() & STATUSF_IP7) { -+ cdev = (struct clock_event_device *) dev_id; -+ sdev = container_of(cdev, struct systick_device, dev); -+ -+ /* Clear Count/Compare Interrupt */ -+ write_compare(sdev, read_compare(sdev)); -+ cdev->event_handler(cdev); -+ ret = 1; -+ } - -- return IRQ_HANDLED; -+ return IRQ_RETVAL(ret); - } - - static struct systick_device systick = { - .dev = { -- /* -- * cevt-r4k uses 300, make sure systick -- * gets used if available -- */ -- .rating = 310, - .features = CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = systick_next_event, - .set_state_shutdown = systick_shutdown, -@@ -95,9 +136,15 @@ static int systick_shutdown(struct clock - sdev = container_of(evt, struct systick_device, dev); - - if (sdev->irq_requested) -- free_irq(systick.dev.irq, &systick_irqaction); -+ remove_irq(systick.dev.irq, &systick_irqaction); - sdev->irq_requested = 0; -- iowrite32(0, systick.membase + SYSTICK_CONFIG); -+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG); -+ -+ if (systick_freq_scaling) -+ systick_freq_scaling(sdev, 0); -+ -+ if (systick_freq_scaling) -+ systick_freq_scaling(sdev, 1); - - return 0; - } -@@ -117,34 +164,48 @@ static int systick_set_oneshot(struct cl - return 0; - } - -+static const struct of_device_id systick_match[] = { -+ { .compatible = "ralink,mt7620a-systick", .data = mt7620_freq_scaling}, -+ {}, -+}; -+ - static int __init ralink_systick_init(struct device_node *np) - { -+ const struct of_device_id *match; -+ int rating = 200; - int ret; - - systick.membase = of_iomap(np, 0); - if (!systick.membase) - return -ENXIO; - -- systick_irqaction.name = np->name; -- systick.dev.name = np->name; -- clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60); -- systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev); -- systick.dev.max_delta_ticks = 0x7fff; -- systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev); -- systick.dev.min_delta_ticks = 0x3; -+ match = of_match_node(systick_match, np); -+ if (match) { -+ systick_freq_scaling = match->data; -+ /* -+ * cevt-r4k uses 300, make sure systick -+ * gets used if available -+ */ -+ rating = 310; -+ } -+ -+ /* enable counter than register clock source */ -+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG); -+ clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name, -+ SYSTICK_FREQ, rating, 16, clocksource_mmio_readl_up); -+ -+ /* register clock event */ - systick.dev.irq = irq_of_parse_and_map(np, 0); - if (!systick.dev.irq) { - pr_err("%pOFn: request_irq failed", np); - return -EINVAL; - } - -- ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name, -- SYSTICK_FREQ, 301, 16, -- clocksource_mmio_readl_up); -- if (ret) -- return ret; -- -- clockevents_register_device(&systick.dev); -+ systick_irqaction.name = np->name; -+ systick.dev.name = np->name; -+ systick.dev.rating = rating; -+ systick.dev.cpumask = cpumask_of(0); -+ clockevents_config_and_register(&systick.dev, SYSTICK_FREQ, 0x3, 0x7fff); - - pr_info("%pOFn: running - mult: %d, shift: %d\n", - np, systick.dev.mult, systick.dev.shift); diff --git a/target/linux/ramips/patches-5.4/0007-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch b/target/linux/ramips/patches-5.4/0007-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch deleted file mode 100644 index c05ee8018d..0000000000 --- a/target/linux/ramips/patches-5.4/0007-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 67b7bff0fd364c194e653f69baa623ba2141bd4c Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 4 Aug 2014 18:46:02 +0200 -Subject: [PATCH 07/53] MIPS: ralink: copy the commandline from the devicetree - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - arch/mips/ralink/of.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/mips/ralink/of.c -+++ b/arch/mips/ralink/of.c -@@ -82,6 +82,8 @@ void __init plat_mem_setup(void) - - __dt_setup_arch(dtb); - -+ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); -+ - of_scan_flat_dt(early_init_dt_find_memory, NULL); - if (memory_dtb) - of_scan_flat_dt(early_init_dt_scan_memory, NULL); diff --git a/target/linux/ramips/patches-5.4/0010-MIPS-add-bootargs-override-property.patch b/target/linux/ramips/patches-5.4/0010-MIPS-add-bootargs-override-property.patch deleted file mode 100644 index c19a0fb480..0000000000 --- a/target/linux/ramips/patches-5.4/0010-MIPS-add-bootargs-override-property.patch +++ /dev/null @@ -1,63 +0,0 @@ -From f15d27f9c90ede4b16eb37f9ae573ef81c2b6996 Mon Sep 17 00:00:00 2001 -From: David Bauer <mail@david-bauer.net> -Date: Thu, 31 Dec 2020 18:49:12 +0100 -Subject: [PATCH] MIPS: add bootargs-override property - -Add support for the bootargs-override property to the chosen node -similar to the one used on ipq806x or mpc85xx. - -This is necessary, as the U-Boot used on some boards, notably the -Ubiquiti UniFi 6 Lite, overwrite the bootargs property of the chosen -node leading to a kernel panic when loading OpenWrt. - -Signed-off-by: David Bauer <mail@david-bauer.net> ---- - arch/mips/kernel/setup.c | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -571,8 +571,28 @@ static int __init bootcmdline_scan_chose - return 1; - } - -+static int __init bootcmdline_scan_chosen_override(unsigned long node, const char *uname, -+ int depth, void *data) -+{ -+ bool *dt_bootargs = data; -+ const char *p; -+ int l; -+ -+ if (depth != 1 || !data || strcmp(uname, "chosen") != 0) -+ return 0; -+ -+ p = of_get_flat_dt_prop(node, "bootargs-override", &l); -+ if (p != NULL && l > 0) { -+ strlcpy(boot_command_line, p, COMMAND_LINE_SIZE); -+ *dt_bootargs = true; -+ } -+ -+ return 1; -+} -+ - static void __init bootcmdline_init(char **cmdline_p) - { -+ bool dt_bootargs_override = false; - bool dt_bootargs = false; - - /* -@@ -586,6 +606,14 @@ static void __init bootcmdline_init(char - } - - /* -+ * If bootargs-override in the chosen node is set, use this as the -+ * command line -+ */ -+ of_scan_flat_dt(bootcmdline_scan_chosen_override, &dt_bootargs_override); -+ if (dt_bootargs_override) -+ return; -+ -+ /* - * If the user specified a built-in command line & - * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is - * prepended to arguments from the bootloader or DT so we'll copy them diff --git a/target/linux/ramips/patches-5.4/0013-owrt-hack-fix-mt7688-cache-issue.patch b/target/linux/ramips/patches-5.4/0013-owrt-hack-fix-mt7688-cache-issue.patch deleted file mode 100644 index bedea14506..0000000000 --- a/target/linux/ramips/patches-5.4/0013-owrt-hack-fix-mt7688-cache-issue.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 5ede027f6c4a57ed25da872420508b7f1168b36b Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 7 Dec 2015 17:15:32 +0100 -Subject: [PATCH 13/53] owrt: hack: fix mt7688 cache issue - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - arch/mips/kernel/setup.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -723,8 +723,6 @@ static void __init arch_mem_init(char ** - memblock_reserve(crashk_res.start, - crashk_res.end - crashk_res.start + 1); - #endif -- device_tree_init(); -- - /* - * In order to reduce the possibility of kernel panic when failed to - * get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate -@@ -841,6 +839,7 @@ void __init setup_arch(char **cmdline_p) - - cpu_cache_init(); - paging_init(); -+ device_tree_init(); - } - - unsigned long kernelsp[NR_CPUS]; diff --git a/target/linux/ramips/patches-5.4/0015-arch-mips-do-not-select-illegal-access-driver-by-def.patch b/target/linux/ramips/patches-5.4/0015-arch-mips-do-not-select-illegal-access-driver-by-def.patch deleted file mode 100644 index 1dc54ccf23..0000000000 --- a/target/linux/ramips/patches-5.4/0015-arch-mips-do-not-select-illegal-access-driver-by-def.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 9e6ce539092a1dd605a20bf73c655a9de58d8641 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 7 Dec 2015 17:18:05 +0100 -Subject: [PATCH 15/53] arch: mips: do not select illegal access driver by - default - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - arch/mips/ralink/Kconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -14,9 +14,9 @@ config CLKEVT_RT3352 - select CEVT_SYSTICK_QUIRK - - config RALINK_ILL_ACC -- bool -+ bool "illegal access irq" - depends on SOC_RT305X -- default y -+ default n - - config IRQ_INTC - bool diff --git a/target/linux/ramips/patches-5.4/0024-GPIO-add-named-gpio-exports.patch b/target/linux/ramips/patches-5.4/0024-GPIO-add-named-gpio-exports.patch deleted file mode 100644 index 805836fcca..0000000000 --- a/target/linux/ramips/patches-5.4/0024-GPIO-add-named-gpio-exports.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Tue, 12 Aug 2014 20:49:27 +0200 -Subject: [PATCH 24/53] GPIO: add named gpio exports - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++ - drivers/gpio/gpiolib-sysfs.c | 10 +++++- - include/asm-generic/gpio.h | 6 ++++ - include/linux/gpio/consumer.h | 8 +++++ - 4 files changed, 91 insertions(+), 1 deletion(-) - ---- a/drivers/gpio/gpiolib-of.c -+++ b/drivers/gpio/gpiolib-of.c -@@ -19,6 +19,8 @@ - #include <linux/pinctrl/pinctrl.h> - #include <linux/slab.h> - #include <linux/gpio/machine.h> -+#include <linux/init.h> -+#include <linux/platform_device.h> - - #include "gpiolib.h" - #include "gpiolib-of.h" -@@ -915,3 +917,68 @@ void of_gpiochip_remove(struct gpio_chip - { - of_node_put(chip->of_node); - } -+ -+static struct of_device_id gpio_export_ids[] = { -+ { .compatible = "gpio-export" }, -+ { /* sentinel */ } -+}; -+ -+static int of_gpio_export_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device_node *cnp; -+ u32 val; -+ int nb = 0; -+ -+ for_each_child_of_node(np, cnp) { -+ const char *name = NULL; -+ int gpio; -+ bool dmc; -+ int max_gpio = 1; -+ int i; -+ -+ of_property_read_string(cnp, "gpio-export,name", &name); -+ -+ if (!name) -+ max_gpio = of_gpio_count(cnp); -+ -+ for (i = 0; i < max_gpio; i++) { -+ unsigned flags = 0; -+ enum of_gpio_flags of_flags; -+ -+ gpio = of_get_gpio_flags(cnp, i, &of_flags); -+ if (!gpio_is_valid(gpio)) -+ return gpio; -+ -+ if (of_flags == OF_GPIO_ACTIVE_LOW) -+ flags |= GPIOF_ACTIVE_LOW; -+ -+ if (!of_property_read_u32(cnp, "gpio-export,output", &val)) -+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; -+ else -+ flags |= GPIOF_IN; -+ -+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np))) -+ continue; -+ -+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change"); -+ gpio_export_with_name(gpio, dmc, name); -+ nb++; -+ } -+ } -+ -+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb); -+ -+ return 0; -+} -+ -+static struct platform_driver gpio_export_driver = { -+ .driver = { -+ .name = "gpio-export", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(gpio_export_ids), -+ }, -+ .probe = of_gpio_export_probe, -+}; -+ -+module_platform_driver(gpio_export_driver); ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -571,7 +571,7 @@ static struct class gpio_class = { - * - * Returns zero on success, else an error. - */ --int gpiod_export(struct gpio_desc *desc, bool direction_may_change) -+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name) - { - struct gpio_chip *chip; - struct gpio_device *gdev; -@@ -633,6 +633,8 @@ int gpiod_export(struct gpio_desc *desc, - offset = gpio_chip_hwgpio(desc); - if (chip->names && chip->names[offset]) - ioname = chip->names[offset]; -+ if (name) -+ ioname = name; - - dev = device_create_with_groups(&gpio_class, &gdev->dev, - MKDEV(0, 0), data, gpio_groups, -@@ -654,6 +656,12 @@ err_unlock: - gpiod_dbg(desc, "%s: status %d\n", __func__, status); - return status; - } -+EXPORT_SYMBOL_GPL(__gpiod_export); -+ -+int gpiod_export(struct gpio_desc *desc, bool direction_may_change) -+{ -+ return __gpiod_export(desc, direction_may_change, NULL); -+} - EXPORT_SYMBOL_GPL(gpiod_export); - - static int match_export(struct device *dev, const void *desc) ---- a/include/asm-generic/gpio.h -+++ b/include/asm-generic/gpio.h -@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g - return gpiod_export(gpio_to_desc(gpio), direction_may_change); - } - -+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); -+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name) -+{ -+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name); -+} -+ - static inline int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) - { ---- a/include/linux/gpio/consumer.h -+++ b/include/linux/gpio/consumer.h -@@ -668,6 +668,7 @@ static inline void devm_acpi_dev_remove_ - - #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) - -+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); - int gpiod_export(struct gpio_desc *desc, bool direction_may_change); - int gpiod_export_link(struct device *dev, const char *name, - struct gpio_desc *desc); -@@ -675,6 +676,13 @@ void gpiod_unexport(struct gpio_desc *de - - #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ - -+static inline int _gpiod_export(struct gpio_desc *desc, -+ bool direction_may_change, -+ const char *name) -+{ -+ return -ENOSYS; -+} -+ - static inline int gpiod_export(struct gpio_desc *desc, - bool direction_may_change) - { diff --git a/target/linux/ramips/patches-5.4/0026-DT-Add-documentation-for-gpio-ralink.patch b/target/linux/ramips/patches-5.4/0026-DT-Add-documentation-for-gpio-ralink.patch deleted file mode 100644 index 93dabf8776..0000000000 --- a/target/linux/ramips/patches-5.4/0026-DT-Add-documentation-for-gpio-ralink.patch +++ /dev/null @@ -1,59 +0,0 @@ -From d410e5478c622c01fcf31427533df5f433df9146 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sun, 28 Jul 2013 19:45:30 +0200 -Subject: [PATCH 26/53] DT: Add documentation for gpio-ralink - -Describe gpio-ralink binding. - -Signed-off-by: John Crispin <blogic@openwrt.org> -Cc: linux-mips@linux-mips.org -Cc: devicetree@vger.kernel.org -Cc: linux-gpio@vger.kernel.org ---- - .../devicetree/bindings/gpio/gpio-ralink.txt | 40 ++++++++++++++++++++ - 1 file changed, 40 insertions(+) - create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt -@@ -0,0 +1,40 @@ -+Ralink SoC GPIO controller bindings -+ -+Required properties: -+- compatible: -+ - "ralink,rt2880-gpio" for Ralink controllers -+- #gpio-cells : Should be two. -+ - first cell is the pin number -+ - second cell is used to specify optional parameters (unused) -+- gpio-controller : Marks the device node as a GPIO controller -+- reg : Physical base address and length of the controller's registers -+- interrupt-parent: phandle to the INTC device node -+- interrupts : Specify the INTC interrupt number -+- ngpios : Specify the number of GPIOs -+- ralink,register-map : The register layout depends on the GPIO bank and actual -+ SoC type. Register offsets need to be in this order. -+ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ] -+ -+Optional properties: -+- ralink,gpio-base : Specify the GPIO chips base number -+ -+Example: -+ -+ gpio0: gpio@600 { -+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio"; -+ -+ #gpio-cells = <2>; -+ gpio-controller; -+ -+ reg = <0x600 0x34>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <6>; -+ -+ ngpios = <24>; -+ ralink,gpio-base = <0>; -+ ralink,register-map = [ 00 04 08 0c -+ 20 24 28 2c -+ 30 34 ]; -+ -+ }; diff --git a/target/linux/ramips/patches-5.4/0027-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch b/target/linux/ramips/patches-5.4/0027-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch deleted file mode 100644 index 525c1976f9..0000000000 --- a/target/linux/ramips/patches-5.4/0027-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch +++ /dev/null @@ -1,416 +0,0 @@ -From 69fdd2c4f937796b934e89c33acde9d082e27bfd Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 4 Aug 2014 20:36:29 +0200 -Subject: [PATCH 27/53] GPIO: MIPS: ralink: add gpio driver for ralink SoC - -Add gpio driver for Ralink SoC. This driver makes the gpio core on -RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work. - -Signed-off-by: John Crispin <blogic@openwrt.org> -Cc: linux-mips@linux-mips.org -Cc: linux-gpio@vger.kernel.org ---- - arch/mips/include/asm/mach-ralink/gpio.h | 24 ++ - drivers/gpio/Kconfig | 6 + - drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-ralink.c | 355 ++++++++++++++++++++++++++++++ - 4 files changed, 386 insertions(+) - create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h - create mode 100644 drivers/gpio/gpio-ralink.c - ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/gpio.h -@@ -0,0 +1,24 @@ -+/* -+ * Ralink SoC GPIO API support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@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. -+ * -+ */ -+ -+#ifndef __ASM_MACH_RALINK_GPIO_H -+#define __ASM_MACH_RALINK_GPIO_H -+ -+#define ARCH_NR_GPIOS 128 -+#include <asm-generic/gpio.h> -+ -+#define gpio_get_value __gpio_get_value -+#define gpio_set_value __gpio_set_value -+#define gpio_cansleep __gpio_cansleep -+#define gpio_to_irq __gpio_to_irq -+ -+#endif /* __ASM_MACH_RALINK_GPIO_H */ ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -471,6 +471,12 @@ config GPIO_SNPS_CREG - where only several fields in register belong to GPIO lines and - each GPIO line owns a field with different length and on/off value. - -+config GPIO_RALINK -+ bool "Ralink GPIO Support" -+ depends on RALINK -+ help -+ Say yes here to support the Ralink SoC GPIO device -+ - config GPIO_SPEAR_SPICS - bool "ST SPEAr13xx SPI Chip Select as GPIO support" - depends on PLAT_SPEAR ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -112,6 +112,7 @@ obj-$(CONFIG_GPIO_PISOSR) += gpio-pisos - obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o - obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o - obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o -+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o - obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o - obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o - obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o ---- /dev/null -+++ b/drivers/gpio/gpio-ralink.c -@@ -0,0 +1,341 @@ -+/* -+ * 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. -+ * -+ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org> -+ */ -+ -+#include <linux/module.h> -+#include <linux/io.h> -+#include <linux/gpio.h> -+#include <linux/spinlock.h> -+#include <linux/platform_device.h> -+#include <linux/of_irq.h> -+#include <linux/irqdomain.h> -+#include <linux/interrupt.h> -+ -+enum ralink_gpio_reg { -+ GPIO_REG_INT = 0, -+ GPIO_REG_EDGE, -+ GPIO_REG_RENA, -+ GPIO_REG_FENA, -+ GPIO_REG_DATA, -+ GPIO_REG_DIR, -+ GPIO_REG_POL, -+ GPIO_REG_SET, -+ GPIO_REG_RESET, -+ GPIO_REG_TOGGLE, -+ GPIO_REG_MAX -+}; -+ -+struct ralink_gpio_chip { -+ struct gpio_chip chip; -+ u8 regs[GPIO_REG_MAX]; -+ -+ spinlock_t lock; -+ void __iomem *membase; -+ struct irq_domain *domain; -+ int irq; -+ -+ u32 rising; -+ u32 falling; -+}; -+ -+#define MAP_MAX 4 -+static struct irq_domain *irq_map[MAP_MAX]; -+static int irq_map_count; -+static atomic_t irq_refcount = ATOMIC_INIT(0); -+ -+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip) -+{ -+ struct ralink_gpio_chip *rg; -+ -+ rg = container_of(chip, struct ralink_gpio_chip, chip); -+ -+ return rg; -+} -+ -+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val) -+{ -+ iowrite32(val, rg->membase + rg->regs[reg]); -+} -+ -+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg) -+{ -+ return ioread32(rg->membase + rg->regs[reg]); -+} -+ -+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ -+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset)); -+} -+ -+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ -+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset)); -+} -+ -+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ unsigned long flags; -+ u32 t; -+ -+ spin_lock_irqsave(&rg->lock, flags); -+ t = rt_gpio_r32(rg, GPIO_REG_DIR); -+ t &= ~BIT(offset); -+ rt_gpio_w32(rg, GPIO_REG_DIR, t); -+ spin_unlock_irqrestore(&rg->lock, flags); -+ -+ return 0; -+} -+ -+static int ralink_gpio_direction_output(struct gpio_chip *chip, -+ unsigned offset, int value) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ unsigned long flags; -+ u32 t; -+ -+ spin_lock_irqsave(&rg->lock, flags); -+ ralink_gpio_set(chip, offset, value); -+ t = rt_gpio_r32(rg, GPIO_REG_DIR); -+ t |= BIT(offset); -+ rt_gpio_w32(rg, GPIO_REG_DIR, t); -+ spin_unlock_irqrestore(&rg->lock, flags); -+ -+ return 0; -+} -+ -+static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ -+ if (rg->irq < 1) -+ return -1; -+ -+ return irq_create_mapping(rg->domain, pin); -+} -+ -+static void ralink_gpio_irq_handler(struct irq_desc *desc) -+{ -+ int i; -+ -+ for (i = 0; i < irq_map_count; i++) { -+ struct irq_domain *domain = irq_map[i]; -+ struct ralink_gpio_chip *rg; -+ unsigned long pending; -+ int bit; -+ -+ rg = (struct ralink_gpio_chip *) domain->host_data; -+ pending = rt_gpio_r32(rg, GPIO_REG_INT); -+ -+ for_each_set_bit(bit, &pending, rg->chip.ngpio) { -+ u32 map = irq_find_mapping(domain, bit); -+ generic_handle_irq(map); -+ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit)); -+ } -+ } -+} -+ -+static void ralink_gpio_irq_unmask(struct irq_data *d) -+{ -+ struct ralink_gpio_chip *rg; -+ unsigned long flags; -+ u32 rise, fall; -+ -+ rg = (struct ralink_gpio_chip *) d->domain->host_data; -+ rise = rt_gpio_r32(rg, GPIO_REG_RENA); -+ fall = rt_gpio_r32(rg, GPIO_REG_FENA); -+ -+ spin_lock_irqsave(&rg->lock, flags); -+ rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising)); -+ rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling)); -+ spin_unlock_irqrestore(&rg->lock, flags); -+} -+ -+static void ralink_gpio_irq_mask(struct irq_data *d) -+{ -+ struct ralink_gpio_chip *rg; -+ unsigned long flags; -+ u32 rise, fall; -+ -+ rg = (struct ralink_gpio_chip *) d->domain->host_data; -+ rise = rt_gpio_r32(rg, GPIO_REG_RENA); -+ fall = rt_gpio_r32(rg, GPIO_REG_FENA); -+ -+ spin_lock_irqsave(&rg->lock, flags); -+ rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq)); -+ rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq)); -+ spin_unlock_irqrestore(&rg->lock, flags); -+} -+ -+static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type) -+{ -+ struct ralink_gpio_chip *rg; -+ u32 mask = BIT(d->hwirq); -+ -+ rg = (struct ralink_gpio_chip *) d->domain->host_data; -+ -+ if (type == IRQ_TYPE_PROBE) { -+ if ((rg->rising | rg->falling) & mask) -+ return 0; -+ -+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; -+ } -+ -+ if (type & IRQ_TYPE_EDGE_RISING) -+ rg->rising |= mask; -+ else -+ rg->rising &= ~mask; -+ -+ if (type & IRQ_TYPE_EDGE_FALLING) -+ rg->falling |= mask; -+ else -+ rg->falling &= ~mask; -+ -+ return 0; -+} -+ -+static struct irq_chip ralink_gpio_irq_chip = { -+ .name = "GPIO", -+ .irq_unmask = ralink_gpio_irq_unmask, -+ .irq_mask = ralink_gpio_irq_mask, -+ .irq_mask_ack = ralink_gpio_irq_mask, -+ .irq_set_type = ralink_gpio_irq_type, -+}; -+ -+static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) -+{ -+ irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq); -+ irq_set_handler_data(irq, d); -+ -+ return 0; -+} -+ -+static const struct irq_domain_ops irq_domain_ops = { -+ .xlate = irq_domain_xlate_onecell, -+ .map = gpio_map, -+}; -+ -+static void ralink_gpio_irq_init(struct device_node *np, -+ struct ralink_gpio_chip *rg) -+{ -+ if (irq_map_count >= MAP_MAX) -+ return; -+ -+ rg->irq = irq_of_parse_and_map(np, 0); -+ if (!rg->irq) -+ return; -+ -+ rg->domain = irq_domain_add_linear(np, rg->chip.ngpio, -+ &irq_domain_ops, rg); -+ if (!rg->domain) { -+ dev_err(rg->chip.parent, "irq_domain_add_linear failed\n"); -+ return; -+ } -+ -+ irq_map[irq_map_count++] = rg->domain; -+ -+ rt_gpio_w32(rg, GPIO_REG_RENA, 0x0); -+ rt_gpio_w32(rg, GPIO_REG_FENA, 0x0); -+ -+ if (!atomic_read(&irq_refcount)) -+ irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler); -+ atomic_inc(&irq_refcount); -+ -+ dev_info(rg->chip.parent, "registering %d irq handlers\n", rg->chip.ngpio); -+} -+ -+static int ralink_gpio_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ struct ralink_gpio_chip *rg; -+ const __be32 *ngpio, *gpiobase; -+ -+ if (!res) { -+ dev_err(&pdev->dev, "failed to find resource\n"); -+ return -ENOMEM; -+ } -+ -+ rg = devm_kzalloc(&pdev->dev, -+ sizeof(struct ralink_gpio_chip), GFP_KERNEL); -+ if (!rg) -+ return -ENOMEM; -+ -+ rg->membase = devm_ioremap_resource(&pdev->dev, res); -+ if (!rg->membase) { -+ dev_err(&pdev->dev, "cannot remap I/O memory region\n"); -+ return -ENOMEM; -+ } -+ -+ if (of_property_read_u8_array(np, "ralink,register-map", -+ rg->regs, GPIO_REG_MAX)) { -+ dev_err(&pdev->dev, "failed to read register definition\n"); -+ return -EINVAL; -+ } -+ -+ ngpio = of_get_property(np, "ngpios", NULL); -+ if (!ngpio) { -+ dev_err(&pdev->dev, "failed to read number of pins\n"); -+ return -EINVAL; -+ } -+ -+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL); -+ if (gpiobase) -+ rg->chip.base = be32_to_cpu(*gpiobase); -+ else -+ rg->chip.base = -1; -+ -+ spin_lock_init(&rg->lock); -+ -+ rg->chip.parent = &pdev->dev; -+ rg->chip.label = dev_name(&pdev->dev); -+ rg->chip.of_node = np; -+ rg->chip.ngpio = be32_to_cpu(*ngpio); -+ rg->chip.direction_input = ralink_gpio_direction_input; -+ rg->chip.direction_output = ralink_gpio_direction_output; -+ rg->chip.get = ralink_gpio_get; -+ rg->chip.set = ralink_gpio_set; -+ rg->chip.request = gpiochip_generic_request; -+ rg->chip.to_irq = ralink_gpio_to_irq; -+ rg->chip.free = gpiochip_generic_free; -+ -+ /* set polarity to low for all lines */ -+ rt_gpio_w32(rg, GPIO_REG_POL, 0); -+ -+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio); -+ -+ ralink_gpio_irq_init(np, rg); -+ -+ return gpiochip_add(&rg->chip); -+} -+ -+static const struct of_device_id ralink_gpio_match[] = { -+ { .compatible = "ralink,rt2880-gpio" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ralink_gpio_match); -+ -+static struct platform_driver ralink_gpio_driver = { -+ .probe = ralink_gpio_probe, -+ .driver = { -+ .name = "rt2880_gpio", -+ .owner = THIS_MODULE, -+ .of_match_table = ralink_gpio_match, -+ }, -+}; -+ -+static int __init ralink_gpio_init(void) -+{ -+ return platform_driver_register(&ralink_gpio_driver); -+} -+ -+subsys_initcall(ralink_gpio_init); diff --git a/target/linux/ramips/patches-5.4/0029-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch b/target/linux/ramips/patches-5.4/0029-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch deleted file mode 100644 index 8520ce32ff..0000000000 --- a/target/linux/ramips/patches-5.4/0029-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 57fa7f2f4ef6f78ce1d30509c0d111aa3791b524 Mon Sep 17 00:00:00 2001 -From: Daniel Santos <daniel.santos@pobox.com> -Date: Sun, 4 Nov 2018 20:24:32 -0600 -Subject: gpio-ralink: Add support for GPIO as interrupt-controller - -Signed-off-by: Daniel Santos <daniel.santos@pobox.com> ---- - Documentation/devicetree/bindings/gpio/gpio-ralink.txt | 6 ++++++ - drivers/gpio/gpio-ralink.c | 2 +- - 2 files changed, 7 insertions(+), 1 deletion(-) - ---- a/Documentation/devicetree/bindings/gpio/gpio-ralink.txt -+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt -@@ -17,6 +17,9 @@ Required properties: - - Optional properties: - - ralink,gpio-base : Specify the GPIO chips base number -+- interrupt-controller : marks this as an interrupt controller -+- #interrupt-cells : a standard two-cell interrupt flag, see -+ interrupt-controller/interrupts.txt - - Example: - -@@ -28,6 +31,9 @@ Example: - - reg = <0x600 0x34>; - -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ - interrupt-parent = <&intc>; - interrupts = <6>; - ---- a/drivers/gpio/gpio-ralink.c -+++ b/drivers/gpio/gpio-ralink.c -@@ -220,7 +220,7 @@ static int gpio_map(struct irq_domain *d - } - - static const struct irq_domain_ops irq_domain_ops = { -- .xlate = irq_domain_xlate_onecell, -+ .xlate = irq_domain_xlate_twocell, - .map = gpio_map, - }; - diff --git a/target/linux/ramips/patches-5.4/0031-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-5.4/0031-uvc-add-iPassion-iP2970-support.patch deleted file mode 100644 index f088babc4e..0000000000 --- a/target/linux/ramips/patches-5.4/0031-uvc-add-iPassion-iP2970-support.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 975e76214cd2516eb6cfff4c3eec581872645e88 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Thu, 19 Sep 2013 01:50:59 +0200 -Subject: [PATCH 31/53] uvc: add iPassion iP2970 support - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - drivers/media/usb/uvc/uvc_driver.c | 12 +++ - drivers/media/usb/uvc/uvc_status.c | 2 + - drivers/media/usb/uvc/uvc_video.c | 147 ++++++++++++++++++++++++++++++++++++ - drivers/media/usb/uvc/uvcvideo.h | 5 +- - 4 files changed, 165 insertions(+), 1 deletion(-) - ---- a/drivers/media/usb/uvc/uvc_driver.c -+++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -2916,6 +2916,18 @@ static const struct usb_device_id uvc_id - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, -+ /* iPassion iP2970 */ -+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE -+ | USB_DEVICE_ID_MATCH_INT_INFO, -+ .idVendor = 0x1B3B, -+ .idProduct = 0x2970, -+ .bInterfaceClass = USB_CLASS_VIDEO, -+ .bInterfaceSubClass = 1, -+ .bInterfaceProtocol = 0, -+ .driver_info = UVC_QUIRK_PROBE_MINMAX -+ | UVC_QUIRK_STREAM_NO_FID -+ | UVC_QUIRK_MOTION -+ | UVC_QUIRK_SINGLE_ISO }, - /* Generic USB Video Class */ - { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, - { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, ---- a/drivers/media/usb/uvc/uvc_status.c -+++ b/drivers/media/usb/uvc/uvc_status.c -@@ -223,6 +223,7 @@ static void uvc_status_complete(struct u - if (uvc_event_control(urb, status, len)) - /* The URB will be resubmitted in work context. */ - return; -+ dev->motion = 1; - break; - } - -@@ -271,6 +272,7 @@ int uvc_status_init(struct uvc_device *d - } - - pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); -+ dev->motion = 0; - - /* For high-speed interrupt endpoints, the bInterval value is used as - * an exponent of two. Some developers forgot about it. ---- a/drivers/media/usb/uvc/uvc_video.c -+++ b/drivers/media/usb/uvc/uvc_video.c -@@ -16,6 +16,11 @@ - #include <linux/wait.h> - #include <linux/atomic.h> - #include <asm/unaligned.h> -+#include <linux/skbuff.h> -+#include <linux/kobject.h> -+#include <linux/netlink.h> -+#include <linux/kobject.h> -+#include <linux/workqueue.h> - - #include <media/v4l2-common.h> - -@@ -1188,9 +1193,149 @@ static void uvc_video_decode_data(struct - uvc_urb->async_operations++; - } - -+struct bh_priv { -+ unsigned long seen; -+}; -+ -+struct bh_event { -+ const char *name; -+ struct sk_buff *skb; -+ struct work_struct work; -+}; -+ -+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args ) -+#define BH_DBG(fmt, args...) do {} while (0) -+#define BH_SKB_SIZE 2048 -+ -+extern u64 uevent_next_seqnum(void); -+static int seen = 0; -+ -+static int bh_event_add_var(struct bh_event *event, int argv, -+ const char *format, ...) -+{ -+ static char buf[128]; -+ char *s; -+ va_list args; -+ int len; -+ -+ if (argv) -+ return 0; -+ -+ va_start(args, format); -+ len = vsnprintf(buf, sizeof(buf), format, args); -+ va_end(args); -+ -+ if (len >= sizeof(buf)) { -+ BH_ERR("buffer size too small\n"); -+ WARN_ON(1); -+ return -ENOMEM; -+ } -+ -+ s = skb_put(event->skb, len + 1); -+ strcpy(s, buf); -+ -+ BH_DBG("added variable '%s'\n", s); -+ -+ return 0; -+} -+ -+static int motion_hotplug_fill_event(struct bh_event *event) -+{ -+ int s = jiffies; -+ int ret; -+ -+ if (!seen) -+ seen = jiffies; -+ -+ ret = bh_event_add_var(event, 0, "HOME=%s", "/"); -+ if (ret) -+ return ret; -+ -+ ret = bh_event_add_var(event, 0, "PATH=%s", -+ "/sbin:/bin:/usr/sbin:/usr/bin"); -+ if (ret) -+ return ret; -+ -+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb"); -+ if (ret) -+ return ret; -+ -+ ret = bh_event_add_var(event, 0, "ACTION=motion"); -+ if (ret) -+ return ret; -+ -+ ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen); -+ if (ret) -+ return ret; -+ seen = s; -+ -+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum()); -+ -+ return ret; -+} -+ -+static void motion_hotplug_work(struct work_struct *work) -+{ -+ struct bh_event *event = container_of(work, struct bh_event, work); -+ int ret = 0; -+ -+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL); -+ if (!event->skb) -+ goto out_free_event; -+ -+ ret = bh_event_add_var(event, 0, "%s@", "add"); -+ if (ret) -+ goto out_free_skb; -+ -+ ret = motion_hotplug_fill_event(event); -+ if (ret) -+ goto out_free_skb; -+ -+ NETLINK_CB(event->skb).dst_group = 1; -+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL); -+ -+out_free_skb: -+ if (ret) { -+ BH_ERR("work error %d\n", ret); -+ kfree_skb(event->skb); -+ } -+out_free_event: -+ kfree(event); -+} -+ -+static int motion_hotplug_create_event(void) -+{ -+ struct bh_event *event; -+ -+ event = kzalloc(sizeof(*event), GFP_KERNEL); -+ if (!event) -+ return -ENOMEM; -+ -+ event->name = "motion"; -+ -+ INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work); -+ schedule_work(&event->work); -+ -+ return 0; -+} -+ -+#define MOTION_FLAG_OFFSET 4 - static void uvc_video_decode_end(struct uvc_streaming *stream, - struct uvc_buffer *buf, const u8 *data, int len) - { -+ if ((stream->dev->quirks & UVC_QUIRK_MOTION) && -+ (data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) { -+ u8 *mem; -+ buf->state = UVC_BUF_STATE_READY; -+ mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET); -+ if ( stream->dev->motion ) { -+ stream->dev->motion = 0; -+ motion_hotplug_create_event(); -+ } else { -+ *mem &= 0x7f; -+ } -+ } -+ - /* Mark the buffer as done if the EOF marker is set. */ - if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) { - uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n"); -@@ -1747,6 +1892,8 @@ static int uvc_init_video_isoc(struct uv - if (npackets == 0) - return -ENOMEM; - -+ if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO) -+ npackets = 1; - size = npackets * psize; - - for_each_uvc_urb(uvc_urb, stream) { ---- a/drivers/media/usb/uvc/uvcvideo.h -+++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -199,7 +199,9 @@ - #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400 - #define UVC_QUIRK_FORCE_Y8 0x00000800 - #define UVC_QUIRK_FORCE_BPP 0x00001000 -- -+#define UVC_QUIRK_MOTION 0x00001000 -+#define UVC_QUIRK_SINGLE_ISO 0x00002000 -+ - /* Format flags */ - #define UVC_FMT_FLAG_COMPRESSED 0x00000001 - #define UVC_FMT_FLAG_STREAM 0x00000002 -@@ -666,6 +668,7 @@ struct uvc_device { - u8 *status; - struct input_dev *input; - char input_phys[64]; -+ int motion; - - struct uvc_ctrl_work { - struct work_struct work; diff --git a/target/linux/ramips/patches-5.4/0037-mtd-cfi-cmdset-0002-force-word-write.patch b/target/linux/ramips/patches-5.4/0037-mtd-cfi-cmdset-0002-force-word-write.patch deleted file mode 100644 index 7011bbe50b..0000000000 --- a/target/linux/ramips/patches-5.4/0037-mtd-cfi-cmdset-0002-force-word-write.patch +++ /dev/null @@ -1,20 +0,0 @@ -From ee9081b2726a5ca8cde5497afdc5425e21ff8f8b Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 15 Jul 2013 00:39:21 +0200 -Subject: [PATCH 37/53] mtd: cfi cmdset 0002 force word write - ---- - drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -40,7 +40,7 @@ - #include <linux/mtd/xip.h> - - #define AMD_BOOTLOC_BUG --#define FORCE_WORD_WRITE 0 -+#define FORCE_WORD_WRITE 1 - - #define MAX_RETRIES 3 - diff --git a/target/linux/ramips/patches-5.4/0041-DT-Add-documentation-for-spi-rt2880.patch b/target/linux/ramips/patches-5.4/0041-DT-Add-documentation-for-spi-rt2880.patch deleted file mode 100644 index e2643e3f25..0000000000 --- a/target/linux/ramips/patches-5.4/0041-DT-Add-documentation-for-spi-rt2880.patch +++ /dev/null @@ -1,44 +0,0 @@ -From da6015e7f19d749f135f7ac55c4ec47b06faa868 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Fri, 9 Aug 2013 20:12:59 +0200 -Subject: [PATCH 41/53] DT: Add documentation for spi-rt2880 - -Describe the SPI master found on the MIPS based Ralink RT2880 SoC. - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - .../devicetree/bindings/spi/spi-rt2880.txt | 28 ++++++++++++++++++++ - 1 file changed, 28 insertions(+) - create mode 100644 Documentation/devicetree/bindings/spi/spi-rt2880.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/spi/spi-rt2880.txt -@@ -0,0 +1,28 @@ -+Ralink SoC RT2880 SPI master controller. -+ -+This SPI controller is found on most wireless SoCs made by ralink. -+ -+Required properties: -+- compatible : "ralink,rt2880-spi" -+- reg : The register base for the controller. -+- #address-cells : <1>, as required by generic SPI binding. -+- #size-cells : <0>, also as required by generic SPI binding. -+ -+Child nodes as per the generic SPI binding. -+ -+Example: -+ -+ spi@b00 { -+ compatible = "ralink,rt2880-spi"; -+ reg = <0xb00 0x100>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ m25p80@0 { -+ compatible = "m25p80"; -+ reg = <0>; -+ spi-max-frequency = <10000000>; -+ }; -+ }; -+ diff --git a/target/linux/ramips/patches-5.4/0042-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-5.4/0042-SPI-ralink-add-Ralink-SoC-spi-driver.patch deleted file mode 100644 index 652371617a..0000000000 --- a/target/linux/ramips/patches-5.4/0042-SPI-ralink-add-Ralink-SoC-spi-driver.patch +++ /dev/null @@ -1,574 +0,0 @@ -From 683af4ebb91a1600df1946ac4769d916b8a1be65 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sun, 27 Jul 2014 11:15:12 +0100 -Subject: [PATCH 42/53] SPI: ralink: add Ralink SoC spi driver - -Add the driver needed to make SPI work on Ralink SoC. - -Signed-off-by: Gabor Juhos <juhosg@openwrt.org> -Acked-by: John Crispin <blogic@openwrt.org> ---- - drivers/spi/Kconfig | 6 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-rt2880.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 537 insertions(+) - create mode 100644 drivers/spi/spi-rt2880.c - ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -605,6 +605,12 @@ config SPI_QCOM_GENI - This driver can also be built as a module. If so, the module - will be called spi-geni-qcom. - -+config SPI_RT2880 -+ tristate "Ralink RT288x SPI Controller" -+ depends on RALINK -+ help -+ This selects a driver for the Ralink RT288x/RT305x SPI Controller. -+ - config SPI_S3C24XX - tristate "Samsung S3C24XX series SPI" - depends on ARCH_S3C24XX ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -87,6 +87,7 @@ obj-$(CONFIG_SPI_QUP) += spi-qup.o - obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o - obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o - obj-$(CONFIG_SPI_RSPI) += spi-rspi.o -+obj-$(CONFIG_SPI_RT2880) += spi-rt2880.o - obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o - spi-s3c24xx-hw-y := spi-s3c24xx.o - spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o ---- /dev/null -+++ b/drivers/spi/spi-rt2880.c -@@ -0,0 +1,530 @@ -+/* -+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver -+ * -+ * Copyright (C) 2011 Sergiy <piratfm@gmail.com> -+ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org> -+ * -+ * Some parts are based on spi-orion.c: -+ * Author: Shadi Ammouri <shadi@marvell.com> -+ * Copyright (C) 2007-2008 Marvell Ltd. -+ * -+ * 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/init.h> -+#include <linux/module.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/delay.h> -+#include <linux/io.h> -+#include <linux/reset.h> -+#include <linux/spi/spi.h> -+#include <linux/platform_device.h> -+#include <linux/gpio.h> -+ -+#define DRIVER_NAME "spi-rt2880" -+ -+#define RAMIPS_SPI_STAT 0x00 -+#define RAMIPS_SPI_CFG 0x10 -+#define RAMIPS_SPI_CTL 0x14 -+#define RAMIPS_SPI_DATA 0x20 -+#define RAMIPS_SPI_ADDR 0x24 -+#define RAMIPS_SPI_BS 0x28 -+#define RAMIPS_SPI_USER 0x2C -+#define RAMIPS_SPI_TXFIFO 0x30 -+#define RAMIPS_SPI_RXFIFO 0x34 -+#define RAMIPS_SPI_FIFO_STAT 0x38 -+#define RAMIPS_SPI_MODE 0x3C -+#define RAMIPS_SPI_DEV_OFFSET 0x40 -+#define RAMIPS_SPI_DMA 0x80 -+#define RAMIPS_SPI_DMASTAT 0x84 -+#define RAMIPS_SPI_ARBITER 0xF0 -+ -+/* SPISTAT register bit field */ -+#define SPISTAT_BUSY BIT(0) -+ -+/* SPICFG register bit field */ -+#define SPICFG_ADDRMODE BIT(12) -+#define SPICFG_RXENVDIS BIT(11) -+#define SPICFG_RXCAP BIT(10) -+#define SPICFG_SPIENMODE BIT(9) -+#define SPICFG_MSBFIRST BIT(8) -+#define SPICFG_SPICLKPOL BIT(6) -+#define SPICFG_RXCLKEDGE_FALLING BIT(5) -+#define SPICFG_TXCLKEDGE_FALLING BIT(4) -+#define SPICFG_HIZSPI BIT(3) -+#define SPICFG_SPICLK_PRESCALE_MASK 0x7 -+#define SPICFG_SPICLK_DIV2 0 -+#define SPICFG_SPICLK_DIV4 1 -+#define SPICFG_SPICLK_DIV8 2 -+#define SPICFG_SPICLK_DIV16 3 -+#define SPICFG_SPICLK_DIV32 4 -+#define SPICFG_SPICLK_DIV64 5 -+#define SPICFG_SPICLK_DIV128 6 -+#define SPICFG_SPICLK_DISABLE 7 -+ -+/* SPICTL register bit field */ -+#define SPICTL_START BIT(4) -+#define SPICTL_HIZSDO BIT(3) -+#define SPICTL_STARTWR BIT(2) -+#define SPICTL_STARTRD BIT(1) -+#define SPICTL_SPIENA BIT(0) -+ -+/* SPIUSER register bit field */ -+#define SPIUSER_USERMODE BIT(21) -+#define SPIUSER_INSTR_PHASE BIT(20) -+#define SPIUSER_ADDR_PHASE_MASK 0x7 -+#define SPIUSER_ADDR_PHASE_OFFSET 17 -+#define SPIUSER_MODE_PHASE BIT(16) -+#define SPIUSER_DUMMY_PHASE_MASK 0x3 -+#define SPIUSER_DUMMY_PHASE_OFFSET 14 -+#define SPIUSER_DATA_PHASE_MASK 0x3 -+#define SPIUSER_DATA_PHASE_OFFSET 12 -+#define SPIUSER_DATA_READ (BIT(0) << SPIUSER_DATA_PHASE_OFFSET) -+#define SPIUSER_DATA_WRITE (BIT(1) << SPIUSER_DATA_PHASE_OFFSET) -+#define SPIUSER_ADDR_TYPE_OFFSET 9 -+#define SPIUSER_MODE_TYPE_OFFSET 6 -+#define SPIUSER_DUMMY_TYPE_OFFSET 3 -+#define SPIUSER_DATA_TYPE_OFFSET 0 -+#define SPIUSER_TRANSFER_MASK 0x7 -+#define SPIUSER_TRANSFER_SINGLE BIT(0) -+#define SPIUSER_TRANSFER_DUAL BIT(1) -+#define SPIUSER_TRANSFER_QUAD BIT(2) -+ -+#define SPIUSER_TRANSFER_TYPE(type) ( \ -+ (type << SPIUSER_ADDR_TYPE_OFFSET) | \ -+ (type << SPIUSER_MODE_TYPE_OFFSET) | \ -+ (type << SPIUSER_DUMMY_TYPE_OFFSET) | \ -+ (type << SPIUSER_DATA_TYPE_OFFSET) \ -+) -+ -+/* SPIFIFOSTAT register bit field */ -+#define SPIFIFOSTAT_TXEMPTY BIT(19) -+#define SPIFIFOSTAT_RXEMPTY BIT(18) -+#define SPIFIFOSTAT_TXFULL BIT(17) -+#define SPIFIFOSTAT_RXFULL BIT(16) -+#define SPIFIFOSTAT_FIFO_MASK 0xff -+#define SPIFIFOSTAT_TX_OFFSET 8 -+#define SPIFIFOSTAT_RX_OFFSET 0 -+ -+#define SPI_FIFO_DEPTH 16 -+ -+/* SPIMODE register bit field */ -+#define SPIMODE_MODE_OFFSET 24 -+#define SPIMODE_DUMMY_OFFSET 0 -+ -+/* SPIARB register bit field */ -+#define SPICTL_ARB_EN BIT(31) -+#define SPICTL_CSCTL1 BIT(16) -+#define SPI1_POR BIT(1) -+#define SPI0_POR BIT(0) -+ -+#define RT2880_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \ -+ SPI_CS_HIGH) -+ -+static atomic_t hw_reset_count = ATOMIC_INIT(0); -+ -+struct rt2880_spi { -+ struct spi_master *master; -+ void __iomem *base; -+ u32 speed; -+ u16 wait_loops; -+ u16 mode; -+ struct clk *clk; -+}; -+ -+static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi) -+{ -+ return spi_master_get_devdata(spi->master); -+} -+ -+static inline u32 rt2880_spi_read(struct rt2880_spi *rs, u32 reg) -+{ -+ return ioread32(rs->base + reg); -+} -+ -+static inline void rt2880_spi_write(struct rt2880_spi *rs, u32 reg, -+ const u32 val) -+{ -+ iowrite32(val, rs->base + reg); -+} -+ -+static inline void rt2880_spi_setbits(struct rt2880_spi *rs, u32 reg, u32 mask) -+{ -+ void __iomem *addr = rs->base + reg; -+ -+ iowrite32((ioread32(addr) | mask), addr); -+} -+ -+static inline void rt2880_spi_clrbits(struct rt2880_spi *rs, u32 reg, u32 mask) -+{ -+ void __iomem *addr = rs->base + reg; -+ -+ iowrite32((ioread32(addr) & ~mask), addr); -+} -+ -+static u32 rt2880_spi_baudrate_get(struct spi_device *spi, unsigned int speed) -+{ -+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); -+ u32 rate; -+ u32 prescale; -+ -+ /* -+ * the supported rates are: 2, 4, 8, ... 128 -+ * round up as we look for equal or less speed -+ */ -+ rate = DIV_ROUND_UP(clk_get_rate(rs->clk), speed); -+ rate = roundup_pow_of_two(rate); -+ -+ /* Convert the rate to SPI clock divisor value. */ -+ prescale = ilog2(rate / 2); -+ -+ /* some tolerance. double and add 100 */ -+ rs->wait_loops = (8 * HZ * loops_per_jiffy) / -+ (clk_get_rate(rs->clk) / rate); -+ rs->wait_loops = (rs->wait_loops << 1) + 100; -+ rs->speed = speed; -+ -+ dev_dbg(&spi->dev, "speed: %lu/%u, rate: %u, prescal: %u, loops: %hu\n", -+ clk_get_rate(rs->clk) / rate, speed, rate, prescale, -+ rs->wait_loops); -+ -+ return prescale; -+} -+ -+static u32 get_arbiter_offset(struct spi_master *master) -+{ -+ u32 offset; -+ -+ offset = RAMIPS_SPI_ARBITER; -+ if (master->bus_num == 1) -+ offset -= RAMIPS_SPI_DEV_OFFSET; -+ -+ return offset; -+} -+ -+static void rt2880_spi_set_cs(struct spi_device *spi, bool enable) -+{ -+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); -+ -+ if (enable) -+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); -+ else -+ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); -+} -+ -+static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len) -+{ -+ int loop = rs->wait_loops * len; -+ -+ while ((rt2880_spi_read(rs, RAMIPS_SPI_STAT) & SPISTAT_BUSY) && --loop) -+ cpu_relax(); -+ -+ if (loop) -+ return 0; -+ -+ return -ETIMEDOUT; -+} -+ -+static void rt2880_dump_reg(struct spi_master *master) -+{ -+ struct rt2880_spi *rs = spi_master_get_devdata(master); -+ -+ dev_dbg(&master->dev, "stat: %08x, cfg: %08x, ctl: %08x, " \ -+ "data: %08x, arb: %08x\n", -+ rt2880_spi_read(rs, RAMIPS_SPI_STAT), -+ rt2880_spi_read(rs, RAMIPS_SPI_CFG), -+ rt2880_spi_read(rs, RAMIPS_SPI_CTL), -+ rt2880_spi_read(rs, RAMIPS_SPI_DATA), -+ rt2880_spi_read(rs, get_arbiter_offset(master))); -+} -+ -+static int rt2880_spi_transfer_one(struct spi_master *master, -+ struct spi_device *spi, struct spi_transfer *xfer) -+{ -+ struct rt2880_spi *rs = spi_master_get_devdata(master); -+ unsigned len; -+ const u8 *tx = xfer->tx_buf; -+ u8 *rx = xfer->rx_buf; -+ int err = 0; -+ -+ /* change clock speed */ -+ if (unlikely(rs->speed != xfer->speed_hz)) { -+ u32 reg; -+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG); -+ reg &= ~SPICFG_SPICLK_PRESCALE_MASK; -+ reg |= rt2880_spi_baudrate_get(spi, xfer->speed_hz); -+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg); -+ } -+ -+ if (tx) { -+ len = xfer->len; -+ while (len-- > 0) { -+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, *tx++); -+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR); -+ err = rt2880_spi_wait_ready(rs, 1); -+ if (err) { -+ dev_err(&spi->dev, "TX failed, err=%d\n", err); -+ goto out; -+ } -+ } -+ } -+ -+ if (rx) { -+ len = xfer->len; -+ while (len-- > 0) { -+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD); -+ err = rt2880_spi_wait_ready(rs, 1); -+ if (err) { -+ dev_err(&spi->dev, "RX failed, err=%d\n", err); -+ goto out; -+ } -+ *rx++ = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA); -+ } -+ } -+ -+out: -+ return err; -+} -+ -+/* copy from spi.c */ -+static void spi_set_cs(struct spi_device *spi, bool enable) -+{ -+ if (spi->mode & SPI_CS_HIGH) -+ enable = !enable; -+ -+ if (spi->cs_gpio >= 0) -+ gpio_set_value(spi->cs_gpio, !enable); -+ else if (spi->master->set_cs) -+ spi->master->set_cs(spi, !enable); -+} -+ -+static int rt2880_spi_setup(struct spi_device *spi) -+{ -+ struct spi_master *master = spi->master; -+ struct rt2880_spi *rs = spi_master_get_devdata(master); -+ u32 reg, old_reg, arbit_off; -+ -+ if ((spi->max_speed_hz > master->max_speed_hz) || -+ (spi->max_speed_hz < master->min_speed_hz)) { -+ dev_err(&spi->dev, "invalide requested speed %d Hz\n", -+ spi->max_speed_hz); -+ return -EINVAL; -+ } -+ -+ if (!(master->bits_per_word_mask & -+ BIT(spi->bits_per_word - 1))) { -+ dev_err(&spi->dev, "invalide bits_per_word %d\n", -+ spi->bits_per_word); -+ return -EINVAL; -+ } -+ -+ /* the hardware seems can't work on mode0 force it to mode3 */ -+ if ((spi->mode & (SPI_CPOL | SPI_CPHA)) == SPI_MODE_0) { -+ dev_warn(&spi->dev, "force spi mode3\n"); -+ spi->mode |= SPI_MODE_3; -+ } -+ -+ /* chip polarity */ -+ arbit_off = get_arbiter_offset(master); -+ reg = old_reg = rt2880_spi_read(rs, arbit_off); -+ if (spi->mode & SPI_CS_HIGH) { -+ switch (master->bus_num) { -+ case 1: -+ reg |= SPI1_POR; -+ break; -+ default: -+ reg |= SPI0_POR; -+ break; -+ } -+ } else { -+ switch (master->bus_num) { -+ case 1: -+ reg &= ~SPI1_POR; -+ break; -+ default: -+ reg &= ~SPI0_POR; -+ break; -+ } -+ } -+ -+ /* enable spi1 */ -+ if (master->bus_num == 1) -+ reg |= SPICTL_ARB_EN; -+ -+ if (reg != old_reg) -+ rt2880_spi_write(rs, arbit_off, reg); -+ -+ /* deselected the spi device */ -+ spi_set_cs(spi, false); -+ -+ rt2880_dump_reg(master); -+ -+ return 0; -+} -+ -+static int rt2880_spi_prepare_message(struct spi_master *master, -+ struct spi_message *msg) -+{ -+ struct rt2880_spi *rs = spi_master_get_devdata(master); -+ struct spi_device *spi = msg->spi; -+ u32 reg; -+ -+ if ((rs->mode == spi->mode) && (rs->speed == spi->max_speed_hz)) -+ return 0; -+ -+#if 0 -+ /* set spido to tri-state */ -+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO); -+#endif -+ -+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG); -+ -+ reg &= ~(SPICFG_MSBFIRST | SPICFG_SPICLKPOL | -+ SPICFG_RXCLKEDGE_FALLING | -+ SPICFG_TXCLKEDGE_FALLING | -+ SPICFG_SPICLK_PRESCALE_MASK); -+ -+ /* MSB */ -+ if (!(spi->mode & SPI_LSB_FIRST)) -+ reg |= SPICFG_MSBFIRST; -+ -+ /* spi mode */ -+ switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { -+ case SPI_MODE_0: -+ reg |= SPICFG_TXCLKEDGE_FALLING; -+ break; -+ case SPI_MODE_1: -+ reg |= SPICFG_RXCLKEDGE_FALLING; -+ break; -+ case SPI_MODE_2: -+ reg |= SPICFG_SPICLKPOL | SPICFG_RXCLKEDGE_FALLING; -+ break; -+ case SPI_MODE_3: -+ reg |= SPICFG_SPICLKPOL | SPICFG_TXCLKEDGE_FALLING; -+ break; -+ } -+ rs->mode = spi->mode; -+ -+#if 0 -+ /* set spiclk and spiena to tri-state */ -+ reg |= SPICFG_HIZSPI; -+#endif -+ -+ /* clock divide */ -+ reg |= rt2880_spi_baudrate_get(spi, spi->max_speed_hz); -+ -+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg); -+ -+ return 0; -+} -+ -+static int rt2880_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct rt2880_spi *rs; -+ void __iomem *base; -+ struct resource *r; -+ struct clk *clk; -+ int ret; -+ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ base = devm_ioremap_resource(&pdev->dev, r); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(clk)) { -+ dev_err(&pdev->dev, "unable to get SYS clock\n"); -+ return PTR_ERR(clk); -+ } -+ -+ ret = clk_prepare_enable(clk); -+ if (ret) -+ goto err_clk; -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(*rs)); -+ if (master == NULL) { -+ dev_dbg(&pdev->dev, "master allocation failed\n"); -+ ret = -ENOMEM; -+ goto err_clk; -+ } -+ -+ master->dev.of_node = pdev->dev.of_node; -+ master->mode_bits = RT2880_SPI_MODE_BITS; -+ master->bits_per_word_mask = SPI_BPW_MASK(8); -+ master->min_speed_hz = clk_get_rate(clk) / 128; -+ master->max_speed_hz = clk_get_rate(clk) / 2; -+ master->flags = SPI_MASTER_HALF_DUPLEX; -+ master->setup = rt2880_spi_setup; -+ master->prepare_message = rt2880_spi_prepare_message; -+ master->set_cs = rt2880_spi_set_cs; -+ master->transfer_one = rt2880_spi_transfer_one, -+ -+ dev_set_drvdata(&pdev->dev, master); -+ -+ rs = spi_master_get_devdata(master); -+ rs->master = master; -+ rs->base = base; -+ rs->clk = clk; -+ -+ if (atomic_inc_return(&hw_reset_count) == 1) -+ device_reset(&pdev->dev); -+ -+ ret = devm_spi_register_master(&pdev->dev, master); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "devm_spi_register_master error.\n"); -+ goto err_master; -+ } -+ -+ return ret; -+ -+err_master: -+ spi_master_put(master); -+ kfree(master); -+err_clk: -+ clk_disable_unprepare(clk); -+ -+ return ret; -+} -+ -+static int rt2880_spi_remove(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct rt2880_spi *rs; -+ -+ master = dev_get_drvdata(&pdev->dev); -+ rs = spi_master_get_devdata(master); -+ -+ clk_disable_unprepare(rs->clk); -+ atomic_dec(&hw_reset_count); -+ -+ return 0; -+} -+ -+MODULE_ALIAS("platform:" DRIVER_NAME); -+ -+static const struct of_device_id rt2880_spi_match[] = { -+ { .compatible = "ralink,rt2880-spi" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rt2880_spi_match); -+ -+static struct platform_driver rt2880_spi_driver = { -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = rt2880_spi_match, -+ }, -+ .probe = rt2880_spi_probe, -+ .remove = rt2880_spi_remove, -+}; -+ -+module_platform_driver(rt2880_spi_driver); -+ -+MODULE_DESCRIPTION("Ralink SPI driver"); -+MODULE_AUTHOR("Sergiy <piratfm@gmail.com>"); -+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/ramips/patches-5.4/0044-i2c-MIPS-adds-ralink-I2C-driver.patch b/target/linux/ramips/patches-5.4/0044-i2c-MIPS-adds-ralink-I2C-driver.patch deleted file mode 100644 index e3bb7f2488..0000000000 --- a/target/linux/ramips/patches-5.4/0044-i2c-MIPS-adds-ralink-I2C-driver.patch +++ /dev/null @@ -1,507 +0,0 @@ -From 723b8beaabf3c3c4b1ce69480141f1e926f3f3b2 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sun, 27 Jul 2014 09:52:56 +0100 -Subject: [PATCH 44/53] i2c: MIPS: adds ralink I2C driver - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - .../devicetree/bindings/i2c/i2c-ralink.txt | 27 ++ - drivers/i2c/busses/Kconfig | 4 + - drivers/i2c/busses/Makefile | 1 + - drivers/i2c/busses/i2c-ralink.c | 327 ++++++++++++++++++++ - 4 files changed, 359 insertions(+) - create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ralink.txt - create mode 100644 drivers/i2c/busses/i2c-ralink.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt -@@ -0,0 +1,27 @@ -+I2C for Ralink platforms -+ -+Required properties : -+- compatible : Must be "link,rt3052-i2c" -+- reg: physical base address of the controller and length of memory mapped -+ region. -+- #address-cells = <1>; -+- #size-cells = <0>; -+ -+Optional properties: -+- Child nodes conforming to i2c bus binding -+ -+Example : -+ -+palmbus@10000000 { -+ i2c@900 { -+ compatible = "link,rt3052-i2c"; -+ reg = <0x900 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hwmon@4b { -+ compatible = "national,lm92"; -+ reg = <0x4b>; -+ }; -+ }; -+}; ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -922,6 +922,11 @@ config I2C_RK3X - This driver can also be built as a module. If so, the module will - be called i2c-rk3x. - -+config I2C_RALINK -+ tristate "Ralink I2C Controller" -+ depends on RALINK && !SOC_MT7621 -+ select OF_I2C -+ - config HAVE_S3C2410_I2C - bool - help ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -91,6 +91,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o - obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o - obj-$(CONFIG_I2C_PXA) += i2c-pxa.o - obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o -+obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o - obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-geni.o - obj-$(CONFIG_I2C_QUP) += i2c-qup.o - obj-$(CONFIG_I2C_RIIC) += i2c-riic.o ---- /dev/null -+++ b/drivers/i2c/busses/i2c-ralink.c -@@ -0,0 +1,435 @@ -+/* -+ * drivers/i2c/busses/i2c-ralink.c -+ * -+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com> -+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com> -+ * -+ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus. -+ * (C) 2014 Sittisak <sittisaks@hotmail.com> -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include <linux/interrupt.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/reset.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/platform_device.h> -+#include <linux/of_platform.h> -+#include <linux/i2c.h> -+#include <linux/io.h> -+#include <linux/err.h> -+#include <linux/clk.h> -+ -+#define REG_CONFIG_REG 0x00 -+#define REG_CLKDIV_REG 0x04 -+#define REG_DEVADDR_REG 0x08 -+#define REG_ADDR_REG 0x0C -+#define REG_DATAOUT_REG 0x10 -+#define REG_DATAIN_REG 0x14 -+#define REG_STATUS_REG 0x18 -+#define REG_STARTXFR_REG 0x1C -+#define REG_BYTECNT_REG 0x20 -+ -+/* REG_CONFIG_REG */ -+#define I2C_ADDRLEN_OFFSET 5 -+#define I2C_DEVADLEN_OFFSET 2 -+#define I2C_ADDRLEN_MASK 0x3 -+#define I2C_ADDR_DIS BIT(1) -+#define I2C_DEVADDR_DIS BIT(0) -+#define I2C_ADDRLEN_8 (7 << I2C_ADDRLEN_OFFSET) -+#define I2C_DEVADLEN_7 (6 << I2C_DEVADLEN_OFFSET) -+#define I2C_CONF_DEFAULT (I2C_ADDRLEN_8 | I2C_DEVADLEN_7) -+ -+/* REG_CLKDIV_REG */ -+#define I2C_CLKDIV_MASK 0xffff -+ -+/* REG_DEVADDR_REG */ -+#define I2C_DEVADDR_MASK 0x7f -+ -+/* REG_ADDR_REG */ -+#define I2C_ADDR_MASK 0xff -+ -+/* REG_STATUS_REG */ -+#define I2C_STARTERR BIT(4) -+#define I2C_ACKERR BIT(3) -+#define I2C_DATARDY BIT(2) -+#define I2C_SDOEMPTY BIT(1) -+#define I2C_BUSY BIT(0) -+ -+/* REG_STARTXFR_REG */ -+#define NOSTOP_CMD BIT(2) -+#define NODATA_CMD BIT(1) -+#define READ_CMD BIT(0) -+ -+/* REG_BYTECNT_REG */ -+#define BYTECNT_MAX 64 -+#define SET_BYTECNT(x) (x - 1) -+ -+/* timeout waiting for I2C devices to respond (clock streching) */ -+#define TIMEOUT_MS 1000 -+#define DELAY_INTERVAL_US 100 -+ -+struct rt_i2c { -+ void __iomem *base; -+ struct clk *clk; -+ struct device *dev; -+ struct i2c_adapter adap; -+ u32 cur_clk; -+ u32 clk_div; -+ u32 flags; -+}; -+ -+static void rt_i2c_w32(struct rt_i2c *i2c, u32 val, unsigned reg) -+{ -+ iowrite32(val, i2c->base + reg); -+} -+ -+static u32 rt_i2c_r32(struct rt_i2c *i2c, unsigned reg) -+{ -+ return ioread32(i2c->base + reg); -+} -+ -+static int poll_down_timeout(void __iomem *addr, u32 mask) -+{ -+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); -+ -+ do { -+ if (!(readl_relaxed(addr) & mask)) -+ return 0; -+ -+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); -+ } while (time_before(jiffies, timeout)); -+ -+ return (readl_relaxed(addr) & mask) ? -EAGAIN : 0; -+} -+ -+static int rt_i2c_wait_idle(struct rt_i2c *i2c) -+{ -+ int ret; -+ -+ ret = poll_down_timeout(i2c->base + REG_STATUS_REG, I2C_BUSY); -+ if (ret < 0) -+ dev_dbg(i2c->dev, "idle err(%d)\n", ret); -+ -+ return ret; -+} -+ -+static int poll_up_timeout(void __iomem *addr, u32 mask) -+{ -+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); -+ u32 status; -+ -+ do { -+ status = readl_relaxed(addr); -+ -+ /* check error status */ -+ if (status & I2C_STARTERR) -+ return -EAGAIN; -+ else if (status & I2C_ACKERR) -+ return -ENXIO; -+ else if (status & mask) -+ return 0; -+ -+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); -+ } while (time_before(jiffies, timeout)); -+ -+ return -ETIMEDOUT; -+} -+ -+static int rt_i2c_wait_rx_done(struct rt_i2c *i2c) -+{ -+ int ret; -+ -+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_DATARDY); -+ if (ret < 0) -+ dev_dbg(i2c->dev, "rx err(%d)\n", ret); -+ -+ return ret; -+} -+ -+static int rt_i2c_wait_tx_done(struct rt_i2c *i2c) -+{ -+ int ret; -+ -+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_SDOEMPTY); -+ if (ret < 0) -+ dev_dbg(i2c->dev, "tx err(%d)\n", ret); -+ -+ return ret; -+} -+ -+static void rt_i2c_reset(struct rt_i2c *i2c) -+{ -+ device_reset(i2c->adap.dev.parent); -+ barrier(); -+ rt_i2c_w32(i2c, i2c->clk_div, REG_CLKDIV_REG); -+} -+ -+static void rt_i2c_dump_reg(struct rt_i2c *i2c) -+{ -+ dev_dbg(i2c->dev, "conf %08x, clkdiv %08x, devaddr %08x, " \ -+ "addr %08x, dataout %08x, datain %08x, " \ -+ "status %08x, startxfr %08x, bytecnt %08x\n", -+ rt_i2c_r32(i2c, REG_CONFIG_REG), -+ rt_i2c_r32(i2c, REG_CLKDIV_REG), -+ rt_i2c_r32(i2c, REG_DEVADDR_REG), -+ rt_i2c_r32(i2c, REG_ADDR_REG), -+ rt_i2c_r32(i2c, REG_DATAOUT_REG), -+ rt_i2c_r32(i2c, REG_DATAIN_REG), -+ rt_i2c_r32(i2c, REG_STATUS_REG), -+ rt_i2c_r32(i2c, REG_STARTXFR_REG), -+ rt_i2c_r32(i2c, REG_BYTECNT_REG)); -+} -+ -+static int rt_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, -+ int num) -+{ -+ struct rt_i2c *i2c; -+ struct i2c_msg *pmsg; -+ unsigned char addr; -+ int i, j, ret; -+ u32 cmd; -+ -+ i2c = i2c_get_adapdata(adap); -+ -+ for (i = 0; i < num; i++) { -+ pmsg = &msgs[i]; -+ if (i == (num - 1)) -+ cmd = 0; -+ else -+ cmd = NOSTOP_CMD; -+ -+ dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x, stop: %d\n", -+ pmsg->addr, pmsg->len, pmsg->flags, -+ (cmd == 0)? 1 : 0); -+ -+ /* wait hardware idle */ -+ if ((ret = rt_i2c_wait_idle(i2c))) -+ goto err_timeout; -+ -+ if (pmsg->flags & I2C_M_TEN) { -+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT, REG_CONFIG_REG); -+ /* 10 bits address */ -+ addr = 0x78 | ((pmsg->addr >> 8) & 0x03); -+ rt_i2c_w32(i2c, addr & I2C_DEVADDR_MASK, -+ REG_DEVADDR_REG); -+ rt_i2c_w32(i2c, pmsg->addr & I2C_ADDR_MASK, -+ REG_ADDR_REG); -+ } else { -+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT | I2C_ADDR_DIS, -+ REG_CONFIG_REG); -+ /* 7 bits address */ -+ rt_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK, -+ REG_DEVADDR_REG); -+ } -+ -+ /* buffer length */ -+ if (pmsg->len == 0) -+ cmd |= NODATA_CMD; -+ else -+ rt_i2c_w32(i2c, SET_BYTECNT(pmsg->len), -+ REG_BYTECNT_REG); -+ -+ j = 0; -+ if (pmsg->flags & I2C_M_RD) { -+ cmd |= READ_CMD; -+ /* start transfer */ -+ barrier(); -+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG); -+ do { -+ /* wait */ -+ if ((ret = rt_i2c_wait_rx_done(i2c))) -+ goto err_timeout; -+ /* read data */ -+ if (pmsg->len) -+ pmsg->buf[j] = rt_i2c_r32(i2c, -+ REG_DATAIN_REG); -+ j++; -+ } while (j < pmsg->len); -+ } else { -+ do { -+ /* write data */ -+ if (pmsg->len) -+ rt_i2c_w32(i2c, pmsg->buf[j], -+ REG_DATAOUT_REG); -+ /* start transfer */ -+ if (j == 0) { -+ barrier(); -+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG); -+ } -+ /* wait */ -+ if ((ret = rt_i2c_wait_tx_done(i2c))) -+ goto err_timeout; -+ j++; -+ } while (j < pmsg->len); -+ } -+ } -+ /* the return value is number of executed messages */ -+ ret = i; -+ -+ return ret; -+ -+err_timeout: -+ rt_i2c_dump_reg(i2c); -+ rt_i2c_reset(i2c); -+ return ret; -+} -+ -+static u32 rt_i2c_func(struct i2c_adapter *a) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static const struct i2c_algorithm rt_i2c_algo = { -+ .master_xfer = rt_i2c_master_xfer, -+ .functionality = rt_i2c_func, -+}; -+ -+static const struct of_device_id i2c_rt_dt_ids[] = { -+ { .compatible = "ralink,rt2880-i2c" }, -+ { /* sentinel */ } -+}; -+ -+MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids); -+ -+static struct i2c_adapter_quirks rt_i2c_quirks = { -+ .max_write_len = BYTECNT_MAX, -+ .max_read_len = BYTECNT_MAX, -+}; -+ -+static int rt_i2c_init(struct rt_i2c *i2c) -+{ -+ u32 reg; -+ -+ /* i2c_sclk = periph_clk / ((2 * clk_div) + 5) */ -+ i2c->clk_div = (clk_get_rate(i2c->clk) - (5 * i2c->cur_clk)) / -+ (2 * i2c->cur_clk); -+ if (i2c->clk_div < 8) -+ i2c->clk_div = 8; -+ if (i2c->clk_div > I2C_CLKDIV_MASK) -+ i2c->clk_div = I2C_CLKDIV_MASK; -+ -+ /* check support combinde/repeated start message */ -+ rt_i2c_w32(i2c, NOSTOP_CMD, REG_STARTXFR_REG); -+ reg = rt_i2c_r32(i2c, REG_STARTXFR_REG) & NOSTOP_CMD; -+ -+ rt_i2c_reset(i2c); -+ -+ return reg; -+} -+ -+static int rt_i2c_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ struct rt_i2c *i2c; -+ struct i2c_adapter *adap; -+ const struct of_device_id *match; -+ int ret, restart; -+ -+ match = of_match_device(i2c_rt_dt_ids, &pdev->dev); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resource found\n"); -+ return -ENODEV; -+ } -+ -+ i2c = devm_kzalloc(&pdev->dev, sizeof(struct rt_i2c), GFP_KERNEL); -+ if (!i2c) { -+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n"); -+ return -ENOMEM; -+ } -+ -+ i2c->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(i2c->base)) -+ return PTR_ERR(i2c->base); -+ -+ i2c->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(i2c->clk)) { -+ dev_err(&pdev->dev, "no clock defined\n"); -+ return -ENODEV; -+ } -+ clk_prepare_enable(i2c->clk); -+ i2c->dev = &pdev->dev; -+ -+ if (of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &i2c->cur_clk)) -+ i2c->cur_clk = 100000; -+ -+ adap = &i2c->adap; -+ adap->owner = THIS_MODULE; -+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; -+ adap->algo = &rt_i2c_algo; -+ adap->retries = 3; -+ adap->dev.parent = &pdev->dev; -+ i2c_set_adapdata(adap, i2c); -+ adap->dev.of_node = pdev->dev.of_node; -+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); -+ adap->quirks = &rt_i2c_quirks; -+ -+ platform_set_drvdata(pdev, i2c); -+ -+ restart = rt_i2c_init(i2c); -+ -+ ret = i2c_add_adapter(adap); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "failed to add adapter\n"); -+ clk_disable_unprepare(i2c->clk); -+ return ret; -+ } -+ -+ dev_info(&pdev->dev, "clock %uKHz, re-start %ssupport\n", -+ i2c->cur_clk/1000, restart ? "" : "not "); -+ -+ return ret; -+} -+ -+static int rt_i2c_remove(struct platform_device *pdev) -+{ -+ struct rt_i2c *i2c = platform_get_drvdata(pdev); -+ -+ i2c_del_adapter(&i2c->adap); -+ clk_disable_unprepare(i2c->clk); -+ -+ return 0; -+} -+ -+static struct platform_driver rt_i2c_driver = { -+ .probe = rt_i2c_probe, -+ .remove = rt_i2c_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "i2c-ralink", -+ .of_match_table = i2c_rt_dt_ids, -+ }, -+}; -+ -+static int __init i2c_rt_init (void) -+{ -+ return platform_driver_register(&rt_i2c_driver); -+} -+subsys_initcall(i2c_rt_init); -+ -+static void __exit i2c_rt_exit (void) -+{ -+ platform_driver_unregister(&rt_i2c_driver); -+} -+module_exit(i2c_rt_exit); -+ -+MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>"); -+MODULE_DESCRIPTION("Ralink I2c host driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:Ralink-I2C"); diff --git a/target/linux/ramips/patches-5.4/0046-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch b/target/linux/ramips/patches-5.4/0046-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch deleted file mode 100644 index f3912a1054..0000000000 --- a/target/linux/ramips/patches-5.4/0046-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 23147af14531cbdada194b94120ef8774f46292d Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Thu, 13 Nov 2014 19:08:40 +0100 -Subject: [PATCH 46/53] mmc: MIPS: ralink: add sdhci for mt7620a SoC - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - drivers/mmc/host/Kconfig | 2 + - drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/mtk-mmc/Kconfig | 16 + - drivers/mmc/host/mtk-mmc/Makefile | 42 + - drivers/mmc/host/mtk-mmc/board.h | 137 ++ - drivers/mmc/host/mtk-mmc/dbg.c | 347 ++++ - drivers/mmc/host/mtk-mmc/dbg.h | 156 ++ - drivers/mmc/host/mtk-mmc/mt6575_sd.h | 1001 +++++++++++ - drivers/mmc/host/mtk-mmc/sd.c | 3060 ++++++++++++++++++++++++++++++++++ - 9 files changed, 4762 insertions(+) - create mode 100644 drivers/mmc/host/mtk-mmc/Kconfig - create mode 100644 drivers/mmc/host/mtk-mmc/Makefile - create mode 100644 drivers/mmc/host/mtk-mmc/board.h - create mode 100644 drivers/mmc/host/mtk-mmc/dbg.c - create mode 100644 drivers/mmc/host/mtk-mmc/dbg.h - create mode 100644 drivers/mmc/host/mtk-mmc/mt6575_sd.h - create mode 100644 drivers/mmc/host/mtk-mmc/sd.c - ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -1019,3 +1019,5 @@ config MMC_SDHCI_AM654 - If you have a controller with this interface, say Y or M here. - - If unsure, say N. -+ -+source "drivers/mmc/host/mtk-mmc/Kconfig" ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -3,6 +3,7 @@ - # Makefile for MMC/SD host controller drivers - # - -+obj-$(CONFIG_MTK_MMC) += mtk-mmc/ - obj-$(CONFIG_MMC_ARMMMCI) += armmmci.o - armmmci-y := mmci.o - armmmci-$(CONFIG_MMC_QCOM_DML) += mmci_qcom_dml.o diff --git a/target/linux/ramips/patches-5.4/0048-asoc-add-mt7620-support.patch b/target/linux/ramips/patches-5.4/0048-asoc-add-mt7620-support.patch deleted file mode 100644 index 4b9c877a7f..0000000000 --- a/target/linux/ramips/patches-5.4/0048-asoc-add-mt7620-support.patch +++ /dev/null @@ -1,1028 +0,0 @@ -From 7f29222b1731e8182ba94a331531dec18865a1e4 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sun, 27 Jul 2014 09:31:47 +0100 -Subject: [PATCH 48/53] asoc: add mt7620 support - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - arch/mips/ralink/of.c | 2 + - sound/soc/Kconfig | 1 + - sound/soc/Makefile | 1 + - sound/soc/ralink/Kconfig | 15 ++ - sound/soc/ralink/Makefile | 11 + - sound/soc/ralink/mt7620-i2s.c | 436 ++++++++++++++++++++++++++++++++++++++ - sound/soc/ralink/mt7620-wm8960.c | 233 ++++++++++++++++++++ - 7 files changed, 699 insertions(+) - create mode 100644 sound/soc/ralink/Kconfig - create mode 100644 sound/soc/ralink/Makefile - create mode 100644 sound/soc/ralink/mt7620-i2s.c - create mode 100644 sound/soc/ralink/mt7620-wm8960.c - ---- a/sound/soc/Kconfig -+++ b/sound/soc/Kconfig -@@ -60,6 +60,7 @@ source "sound/soc/mxs/Kconfig" - source "sound/soc/pxa/Kconfig" - source "sound/soc/qcom/Kconfig" - source "sound/soc/rockchip/Kconfig" -+source "sound/soc/ralink/Kconfig" - source "sound/soc/samsung/Kconfig" - source "sound/soc/sh/Kconfig" - source "sound/soc/sirf/Kconfig" ---- a/sound/soc/Makefile -+++ b/sound/soc/Makefile -@@ -43,6 +43,7 @@ obj-$(CONFIG_SND_SOC) += kirkwood/ - obj-$(CONFIG_SND_SOC) += pxa/ - obj-$(CONFIG_SND_SOC) += qcom/ - obj-$(CONFIG_SND_SOC) += rockchip/ -+obj-$(CONFIG_SND_SOC) += ralink/ - obj-$(CONFIG_SND_SOC) += samsung/ - obj-$(CONFIG_SND_SOC) += sh/ - obj-$(CONFIG_SND_SOC) += sirf/ ---- /dev/null -+++ b/sound/soc/ralink/Kconfig -@@ -0,0 +1,8 @@ -+config SND_RALINK_SOC_I2S -+ depends on RALINK && SND_SOC && !SOC_RT288X -+ select SND_SOC_GENERIC_DMAENGINE_PCM -+ select REGMAP_MMIO -+ tristate "SoC Audio (I2S protocol) for Ralink SoC" -+ help -+ Say Y if you want to use I2S protocol and I2S codec on Ralink/MediaTek -+ based boards. ---- /dev/null -+++ b/sound/soc/ralink/Makefile -@@ -0,0 +1,6 @@ -+# -+# Ralink/MediaTek Platform Support -+# -+snd-soc-ralink-i2s-objs := ralink-i2s.o -+ -+obj-$(CONFIG_SND_RALINK_SOC_I2S) += snd-soc-ralink-i2s.o ---- /dev/null -+++ b/sound/soc/ralink/ralink-i2s.c -@@ -0,0 +1,965 @@ -+/* -+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> -+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com> -+ * -+ * 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. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/clk.h> -+#include <linux/regmap.h> -+#include <linux/reset.h> -+#include <linux/debugfs.h> -+#include <linux/of_device.h> -+#include <sound/pcm_params.h> -+#include <sound/dmaengine_pcm.h> -+ -+#include <asm/mach-ralink/ralink_regs.h> -+ -+#define DRV_NAME "ralink-i2s" -+ -+#define I2S_REG_CFG0 0x00 -+#define I2S_REG_INT_STATUS 0x04 -+#define I2S_REG_INT_EN 0x08 -+#define I2S_REG_FF_STATUS 0x0c -+#define I2S_REG_WREG 0x10 -+#define I2S_REG_RREG 0x14 -+#define I2S_REG_CFG1 0x18 -+#define I2S_REG_DIVCMP 0x20 -+#define I2S_REG_DIVINT 0x24 -+ -+/* I2S_REG_CFG0 */ -+#define I2S_REG_CFG0_EN BIT(31) -+#define I2S_REG_CFG0_DMA_EN BIT(30) -+#define I2S_REG_CFG0_BYTE_SWAP BIT(28) -+#define I2S_REG_CFG0_TX_EN BIT(24) -+#define I2S_REG_CFG0_RX_EN BIT(20) -+#define I2S_REG_CFG0_SLAVE BIT(16) -+#define I2S_REG_CFG0_RX_THRES 12 -+#define I2S_REG_CFG0_TX_THRES 4 -+#define I2S_REG_CFG0_THRES_MASK (0xf << I2S_REG_CFG0_RX_THRES) | \ -+ (4 << I2S_REG_CFG0_TX_THRES) -+#define I2S_REG_CFG0_DFT_THRES (4 << I2S_REG_CFG0_RX_THRES) | \ -+ (4 << I2S_REG_CFG0_TX_THRES) -+/* RT305x */ -+#define I2S_REG_CFG0_CLK_DIS BIT(8) -+#define I2S_REG_CFG0_TXCH_SWAP BIT(3) -+#define I2S_REG_CFG0_TXCH1_OFF BIT(2) -+#define I2S_REG_CFG0_TXCH0_OFF BIT(1) -+#define I2S_REG_CFG0_SLAVE_EN BIT(0) -+/* RT3883 */ -+#define I2S_REG_CFG0_RXCH_SWAP BIT(11) -+#define I2S_REG_CFG0_RXCH1_OFF BIT(10) -+#define I2S_REG_CFG0_RXCH0_OFF BIT(9) -+#define I2S_REG_CFG0_WS_INV BIT(0) -+/* MT7628 */ -+#define I2S_REG_CFG0_FMT_LE BIT(29) -+#define I2S_REG_CFG0_SYS_BE BIT(28) -+#define I2S_REG_CFG0_NORM_24 BIT(18) -+#define I2S_REG_CFG0_DATA_24 BIT(17) -+ -+/* I2S_REG_INT_STATUS */ -+#define I2S_REG_INT_RX_FAULT BIT(7) -+#define I2S_REG_INT_RX_OVRUN BIT(6) -+#define I2S_REG_INT_RX_UNRUN BIT(5) -+#define I2S_REG_INT_RX_THRES BIT(4) -+#define I2S_REG_INT_TX_FAULT BIT(3) -+#define I2S_REG_INT_TX_OVRUN BIT(2) -+#define I2S_REG_INT_TX_UNRUN BIT(1) -+#define I2S_REG_INT_TX_THRES BIT(0) -+#define I2S_REG_INT_TX_MASK 0xf -+#define I2S_REG_INT_RX_MASK 0xf0 -+ -+/* I2S_REG_INT_STATUS */ -+#define I2S_RX_AVCNT(x) ((x >> 4) & 0xf) -+#define I2S_TX_AVCNT(x) (x & 0xf) -+/* MT7628 */ -+#define MT7628_I2S_RX_AVCNT(x) ((x >> 8) & 0x1f) -+#define MT7628_I2S_TX_AVCNT(x) (x & 0x1f) -+ -+/* I2S_REG_CFG1 */ -+#define I2S_REG_CFG1_LBK BIT(31) -+#define I2S_REG_CFG1_EXTLBK BIT(30) -+/* RT3883 */ -+#define I2S_REG_CFG1_LEFT_J BIT(0) -+#define I2S_REG_CFG1_RIGHT_J BIT(1) -+#define I2S_REG_CFG1_FMT_MASK 0x3 -+ -+/* I2S_REG_DIVCMP */ -+#define I2S_REG_DIVCMP_CLKEN BIT(31) -+#define I2S_REG_DIVCMP_DIVCOMP_MASK 0x1ff -+ -+/* I2S_REG_DIVINT */ -+#define I2S_REG_DIVINT_MASK 0x3ff -+ -+/* BCLK dividers */ -+#define RALINK_I2S_DIVCMP 0 -+#define RALINK_I2S_DIVINT 1 -+ -+/* FIFO */ -+#define RALINK_I2S_FIFO_SIZE 32 -+ -+/* feature flags */ -+#define RALINK_FLAGS_TXONLY BIT(0) -+#define RALINK_FLAGS_LEFT_J BIT(1) -+#define RALINK_FLAGS_RIGHT_J BIT(2) -+#define RALINK_FLAGS_ENDIAN BIT(3) -+#define RALINK_FLAGS_24BIT BIT(4) -+ -+#define RALINK_I2S_INT_EN 0 -+ -+struct ralink_i2s_stats { -+ u32 dmafault; -+ u32 overrun; -+ u32 underrun; -+ u32 belowthres; -+}; -+ -+struct ralink_i2s { -+ struct device *dev; -+ void __iomem *regs; -+ struct clk *clk; -+ struct regmap *regmap; -+ u32 flags; -+ unsigned int fmt; -+ u16 txdma_req; -+ u16 rxdma_req; -+ -+ struct snd_dmaengine_dai_dma_data playback_dma_data; -+ struct snd_dmaengine_dai_dma_data capture_dma_data; -+ -+ struct dentry *dbg_dir; -+ struct dentry *dbg_stats; -+ struct ralink_i2s_stats txstats; -+ struct ralink_i2s_stats rxstats; -+}; -+ -+static void ralink_i2s_dump_regs(struct ralink_i2s *i2s) -+{ -+ u32 buf[10]; -+ int ret; -+ -+ ret = regmap_bulk_read(i2s->regmap, I2S_REG_CFG0, -+ buf, ARRAY_SIZE(buf)); -+ -+ dev_dbg(i2s->dev, "CFG0: %08x, INTSTAT: %08x, INTEN: %08x, " \ -+ "FFSTAT: %08x, WREG: %08x, RREG: %08x, " \ -+ "CFG1: %08x, DIVCMP: %08x, DIVINT: %08x\n", -+ buf[0], buf[1], buf[2], buf[3], buf[4], -+ buf[5], buf[6], buf[8], buf[9]); -+} -+ -+static int ralink_i2s_set_sysclk(struct snd_soc_dai *dai, -+ int clk_id, unsigned int freq, int dir) -+{ -+ return 0; -+} -+ -+static int ralink_i2s_set_sys_bclk(struct snd_soc_dai *dai, int width, int rate) -+{ -+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); -+ unsigned long clk = clk_get_rate(i2s->clk); -+ int div; -+ uint32_t data; -+ -+ /* disable clock at slave mode */ -+ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) == -+ SND_SOC_DAIFMT_CBM_CFM) { -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_CLK_DIS, -+ I2S_REG_CFG0_CLK_DIS); -+ return 0; -+ } -+ -+ /* FREQOUT = FREQIN / (I2S_CLK_DIV + 1) */ -+ div = (clk / rate ) - 1; -+ -+ data = rt_sysc_r32(0x30); -+ data &= (0xff << 8); -+ data |= (0x1 << 15) | (div << 8); -+ rt_sysc_w32(data, 0x30); -+ -+ /* enable clock */ -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_CLK_DIS, 0); -+ -+ dev_dbg(i2s->dev, "clk: %lu, rate: %u, div: %d\n", -+ clk, rate, div); -+ -+ return 0; -+} -+ -+static int ralink_i2s_set_bclk(struct snd_soc_dai *dai, int width, int rate) -+{ -+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); -+ unsigned long clk = clk_get_rate(i2s->clk); -+ int divint, divcomp; -+ -+ /* disable clock at slave mode */ -+ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) == -+ SND_SOC_DAIFMT_CBM_CFM) { -+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, -+ I2S_REG_DIVCMP_CLKEN, 0); -+ return 0; -+ } -+ -+ /* FREQOUT = FREQIN * (1/2) * (1/(DIVINT + DIVCOMP/512)) */ -+ clk = clk / (2 * 2 * width); -+ divint = clk / rate; -+ divcomp = ((clk % rate) * 512) / rate; -+ -+ if ((divint > I2S_REG_DIVINT_MASK) || -+ (divcomp > I2S_REG_DIVCMP_DIVCOMP_MASK)) -+ return -EINVAL; -+ -+ regmap_update_bits(i2s->regmap, I2S_REG_DIVINT, -+ I2S_REG_DIVINT_MASK, divint); -+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, -+ I2S_REG_DIVCMP_DIVCOMP_MASK, divcomp); -+ -+ /* enable clock */ -+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, I2S_REG_DIVCMP_CLKEN, -+ I2S_REG_DIVCMP_CLKEN); -+ -+ dev_dbg(i2s->dev, "clk: %lu, rate: %u, int: %d, comp: %d\n", -+ clk_get_rate(i2s->clk), rate, divint, divcomp); -+ -+ return 0; -+} -+ -+static int ralink_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -+{ -+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); -+ unsigned int cfg0 = 0, cfg1 = 0; -+ -+ /* set master/slave audio interface */ -+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBM_CFM: -+ if (i2s->flags & RALINK_FLAGS_TXONLY) -+ cfg0 |= I2S_REG_CFG0_SLAVE_EN; -+ else -+ cfg0 |= I2S_REG_CFG0_SLAVE; -+ break; -+ case SND_SOC_DAIFMT_CBS_CFS: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* interface format */ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_I2S: -+ break; -+ case SND_SOC_DAIFMT_RIGHT_J: -+ if (i2s->flags & RALINK_FLAGS_RIGHT_J) { -+ cfg1 |= I2S_REG_CFG1_RIGHT_J; -+ break; -+ } -+ return -EINVAL; -+ case SND_SOC_DAIFMT_LEFT_J: -+ if (i2s->flags & RALINK_FLAGS_LEFT_J) { -+ cfg1 |= I2S_REG_CFG1_LEFT_J; -+ break; -+ } -+ return -EINVAL; -+ default: -+ return -EINVAL; -+ } -+ -+ /* clock inversion */ -+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { -+ case SND_SOC_DAIFMT_NB_NF: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (i2s->flags & RALINK_FLAGS_TXONLY) { -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_SLAVE_EN, cfg0); -+ } else { -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_SLAVE, cfg0); -+ } -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG1, -+ I2S_REG_CFG1_FMT_MASK, cfg1); -+ i2s->fmt = fmt; -+ -+ return 0; -+} -+ -+static int ralink_i2s_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); -+ -+ if (dai->active) -+ return 0; -+ -+ /* setup status interrupt */ -+#if (RALINK_I2S_INT_EN) -+ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0xff); -+#else -+ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0x0); -+#endif -+ -+ /* enable */ -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN | -+ I2S_REG_CFG0_THRES_MASK, -+ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN | -+ I2S_REG_CFG0_DFT_THRES); -+ -+ return 0; -+} -+ -+static void ralink_i2s_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); -+ -+ /* If both streams are stopped, disable module and clock */ -+ if (dai->active) -+ return; -+ -+ /* -+ * datasheet mention when disable all control regs are cleared -+ * to initial values. need reinit at startup. -+ */ -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_EN, 0); -+} -+ -+static int ralink_i2s_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -+{ -+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); -+ int width; -+ int ret; -+ -+ width = params_width(params); -+ switch (width) { -+ case 16: -+ if (i2s->flags & RALINK_FLAGS_24BIT) -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_DATA_24, 0); -+ break; -+ case 24: -+ if (i2s->flags & RALINK_FLAGS_24BIT) { -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_DATA_24, -+ I2S_REG_CFG0_DATA_24); -+ break; -+ } -+ return -EINVAL; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (params_channels(params)) { -+ case 2: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (i2s->flags & RALINK_FLAGS_ENDIAN) { -+ /* system endian */ -+#ifdef SNDRV_LITTLE_ENDIAN -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_SYS_BE, 0); -+#else -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_SYS_BE, -+ I2S_REG_CFG0_SYS_BE); -+#endif -+ -+ /* data endian */ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ case SNDRV_PCM_FORMAT_S24_LE: -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_FMT_LE, -+ I2S_REG_CFG0_FMT_LE); -+ break; -+ case SNDRV_PCM_FORMAT_S16_BE: -+ case SNDRV_PCM_FORMAT_S24_BE: -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, -+ I2S_REG_CFG0_FMT_LE, 0); -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ /* setup bclk rate */ -+ if (i2s->flags & RALINK_FLAGS_TXONLY) -+ ret = ralink_i2s_set_sys_bclk(dai, width, params_rate(params)); -+ else -+ ret = ralink_i2s_set_bclk(dai, width, params_rate(params)); -+ -+ return ret; -+} -+ -+static int ralink_i2s_trigger(struct snd_pcm_substream *substream, int cmd, -+ struct snd_soc_dai *dai) -+{ -+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); -+ unsigned int mask, val; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ mask = I2S_REG_CFG0_TX_EN; -+ else -+ mask = I2S_REG_CFG0_RX_EN; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ case SNDRV_PCM_TRIGGER_RESUME: -+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ val = mask; -+ break; -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ val = 0; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, mask, val); -+ -+ return 0; -+} -+ -+static void ralink_i2s_init_dma_data(struct ralink_i2s *i2s, -+ struct resource *res) -+{ -+ struct snd_dmaengine_dai_dma_data *dma_data; -+ -+ /* Playback */ -+ dma_data = &i2s->playback_dma_data; -+ dma_data->addr = res->start + I2S_REG_WREG; -+ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ dma_data->maxburst = 1; -+ dma_data->slave_id = i2s->txdma_req; -+ -+ if (i2s->flags & RALINK_FLAGS_TXONLY) -+ return; -+ -+ /* Capture */ -+ dma_data = &i2s->capture_dma_data; -+ dma_data->addr = res->start + I2S_REG_RREG; -+ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ dma_data->maxburst = 1; -+ dma_data->slave_id = i2s->rxdma_req; -+} -+ -+static int ralink_i2s_dai_probe(struct snd_soc_dai *dai) -+{ -+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); -+ -+ snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, -+ &i2s->capture_dma_data); -+ -+ return 0; -+} -+ -+static int ralink_i2s_dai_remove(struct snd_soc_dai *dai) -+{ -+ return 0; -+} -+ -+static const struct snd_soc_dai_ops ralink_i2s_dai_ops = { -+ .set_sysclk = ralink_i2s_set_sysclk, -+ .set_fmt = ralink_i2s_set_fmt, -+ .startup = ralink_i2s_startup, -+ .shutdown = ralink_i2s_shutdown, -+ .hw_params = ralink_i2s_hw_params, -+ .trigger = ralink_i2s_trigger, -+}; -+ -+static struct snd_soc_dai_driver ralink_i2s_dai = { -+ .name = DRV_NAME, -+ .probe = ralink_i2s_dai_probe, -+ .remove = ralink_i2s_dai_remove, -+ .ops = &ralink_i2s_dai_ops, -+ .capture = { -+ .stream_name = "I2S Capture", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rate_min = 5512, -+ .rate_max = 192000, -+ .rates = SNDRV_PCM_RATE_CONTINUOUS, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE, -+ }, -+ .playback = { -+ .stream_name = "I2S Playback", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rate_min = 5512, -+ .rate_max = 192000, -+ .rates = SNDRV_PCM_RATE_CONTINUOUS, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE, -+ }, -+ .symmetric_rates = 1, -+}; -+ -+static struct snd_pcm_hardware ralink_pcm_hardware = { -+ .info = SNDRV_PCM_INFO_MMAP | -+ SNDRV_PCM_INFO_MMAP_VALID | -+ SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_BLOCK_TRANSFER, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE, -+ .channels_min = 2, -+ .channels_max = 2, -+ .period_bytes_min = PAGE_SIZE, -+ .period_bytes_max = PAGE_SIZE * 2, -+ .periods_min = 2, -+ .periods_max = 128, -+ .buffer_bytes_max = 128 * 1024, -+ .fifo_size = RALINK_I2S_FIFO_SIZE, -+}; -+ -+static const struct snd_dmaengine_pcm_config ralink_dmaengine_pcm_config = { -+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, -+ .pcm_hardware = &ralink_pcm_hardware, -+ .prealloc_buffer_size = 256 * PAGE_SIZE, -+}; -+ -+static const struct snd_soc_component_driver ralink_i2s_component = { -+ .name = DRV_NAME, -+}; -+ -+static bool ralink_i2s_readable_reg(struct device *dev, unsigned int reg) -+{ -+ return true; -+} -+ -+static bool ralink_i2s_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case I2S_REG_INT_STATUS: -+ case I2S_REG_FF_STATUS: -+ return true; -+ } -+ return false; -+} -+ -+static bool ralink_i2s_writeable_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case I2S_REG_FF_STATUS: -+ case I2S_REG_RREG: -+ return false; -+ } -+ return true; -+} -+ -+static const struct regmap_config ralink_i2s_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .writeable_reg = ralink_i2s_writeable_reg, -+ .readable_reg = ralink_i2s_readable_reg, -+ .volatile_reg = ralink_i2s_volatile_reg, -+ .max_register = I2S_REG_DIVINT, -+}; -+ -+#if (RALINK_I2S_INT_EN) -+static irqreturn_t ralink_i2s_irq(int irq, void *devid) -+{ -+ struct ralink_i2s *i2s = devid; -+ u32 status; -+ -+ regmap_read(i2s->regmap, I2S_REG_INT_STATUS, &status); -+ if (unlikely(!status)) -+ return IRQ_NONE; -+ -+ /* tx stats */ -+ if (status & I2S_REG_INT_TX_MASK) { -+ if (status & I2S_REG_INT_TX_THRES) -+ i2s->txstats.belowthres++; -+ if (status & I2S_REG_INT_TX_UNRUN) -+ i2s->txstats.underrun++; -+ if (status & I2S_REG_INT_TX_OVRUN) -+ i2s->txstats.overrun++; -+ if (status & I2S_REG_INT_TX_FAULT) -+ i2s->txstats.dmafault++; -+ } -+ -+ /* rx stats */ -+ if (status & I2S_REG_INT_RX_MASK) { -+ if (status & I2S_REG_INT_RX_THRES) -+ i2s->rxstats.belowthres++; -+ if (status & I2S_REG_INT_RX_UNRUN) -+ i2s->rxstats.underrun++; -+ if (status & I2S_REG_INT_RX_OVRUN) -+ i2s->rxstats.overrun++; -+ if (status & I2S_REG_INT_RX_FAULT) -+ i2s->rxstats.dmafault++; -+ } -+ -+ /* clean status bits */ -+ regmap_write(i2s->regmap, I2S_REG_INT_STATUS, status); -+ -+ return IRQ_HANDLED; -+} -+#endif -+ -+#if IS_ENABLED(CONFIG_DEBUG_FS) -+static int ralink_i2s_stats_show(struct seq_file *s, void *unused) -+{ -+ struct ralink_i2s *i2s = s->private; -+ -+ seq_printf(s, "tx stats\n"); -+ seq_printf(s, "\tbelow threshold\t%u\n", i2s->txstats.belowthres); -+ seq_printf(s, "\tunder run\t%u\n", i2s->txstats.underrun); -+ seq_printf(s, "\tover run\t%u\n", i2s->txstats.overrun); -+ seq_printf(s, "\tdma fault\t%u\n", i2s->txstats.dmafault); -+ -+ seq_printf(s, "rx stats\n"); -+ seq_printf(s, "\tbelow threshold\t%u\n", i2s->rxstats.belowthres); -+ seq_printf(s, "\tunder run\t%u\n", i2s->rxstats.underrun); -+ seq_printf(s, "\tover run\t%u\n", i2s->rxstats.overrun); -+ seq_printf(s, "\tdma fault\t%u\n", i2s->rxstats.dmafault); -+ -+ ralink_i2s_dump_regs(i2s); -+ -+ return 0; -+} -+ -+static int ralink_i2s_stats_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, ralink_i2s_stats_show, inode->i_private); -+} -+ -+static const struct file_operations ralink_i2s_stats_ops = { -+ .open = ralink_i2s_stats_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s) -+{ -+ i2s->dbg_dir = debugfs_create_dir(dev_name(i2s->dev), NULL); -+ if (!i2s->dbg_dir) -+ return -ENOMEM; -+ -+ i2s->dbg_stats = debugfs_create_file("stats", S_IRUGO, -+ i2s->dbg_dir, i2s, &ralink_i2s_stats_ops); -+ if (!i2s->dbg_stats) { -+ debugfs_remove(i2s->dbg_dir); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s) -+{ -+ debugfs_remove(i2s->dbg_stats); -+ debugfs_remove(i2s->dbg_dir); -+} -+#else -+static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s) -+{ -+ return 0; -+} -+ -+static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s) -+{ -+} -+#endif -+ -+/* -+ * TODO: these refclk setup functions should use -+ * clock framework instead. hardcode it now. -+ */ -+static void rt3350_refclk_setup(void) -+{ -+ uint32_t data; -+ -+ /* set refclk output 12Mhz clock */ -+ data = rt_sysc_r32(0x2c); -+ data |= (0x1 << 8); -+ rt_sysc_w32(data, 0x2c); -+} -+ -+static void rt3883_refclk_setup(void) -+{ -+ uint32_t data; -+ -+ /* set refclk output 12Mhz clock */ -+ data = rt_sysc_r32(0x2c); -+ data &= ~(0x3 << 13); -+ data |= (0x1 << 13); -+ rt_sysc_w32(data, 0x2c); -+} -+ -+static void rt3552_refclk_setup(void) -+{ -+ uint32_t data; -+ -+ /* set refclk output 12Mhz clock */ -+ data = rt_sysc_r32(0x2c); -+ data &= ~(0xf << 8); -+ data |= (0x3 << 8); -+ rt_sysc_w32(data, 0x2c); -+} -+ -+static void mt7620_refclk_setup(void) -+{ -+ uint32_t data; -+ -+ /* set refclk output 12Mhz clock */ -+ data = rt_sysc_r32(0x2c); -+ data &= ~(0x7 << 9); -+ data |= 0x1 << 9; -+ rt_sysc_w32(data, 0x2c); -+} -+ -+static void mt7621_refclk_setup(void) -+{ -+ uint32_t data; -+ -+ /* set refclk output 12Mhz clock */ -+ data = rt_sysc_r32(0x2c); -+ data &= ~(0x1f << 18); -+ data |= (0x19 << 18); -+ data &= ~(0x1f << 12); -+ data |= (0x1 << 12); -+ data &= ~(0x7 << 9); -+ data |= (0x5 << 9); -+ rt_sysc_w32(data, 0x2c); -+} -+ -+static void mt7628_refclk_setup(void) -+{ -+ uint32_t data; -+ -+ /* set i2s and refclk digital pad */ -+ data = rt_sysc_r32(0x3c); -+ data |= 0x1f; -+ rt_sysc_w32(data, 0x3c); -+ -+ /* Adjust REFCLK0's driving strength */ -+ data = rt_sysc_r32(0x1354); -+ data &= ~(0x1 << 5); -+ rt_sysc_w32(data, 0x1354); -+ data = rt_sysc_r32(0x1364); -+ data |= ~(0x1 << 5); -+ rt_sysc_w32(data, 0x1364); -+ -+ /* set refclk output 12Mhz clock */ -+ data = rt_sysc_r32(0x2c); -+ data &= ~(0x7 << 9); -+ data |= 0x1 << 9; -+ rt_sysc_w32(data, 0x2c); -+} -+ -+struct rt_i2s_data { -+ u32 flags; -+ void (*refclk_setup)(void); -+}; -+ -+struct rt_i2s_data rt3050_i2s_data = { .flags = RALINK_FLAGS_TXONLY }; -+struct rt_i2s_data rt3350_i2s_data = { .flags = RALINK_FLAGS_TXONLY, -+ .refclk_setup = rt3350_refclk_setup }; -+struct rt_i2s_data rt3883_i2s_data = { -+ .flags = (RALINK_FLAGS_LEFT_J | RALINK_FLAGS_RIGHT_J), -+ .refclk_setup = rt3883_refclk_setup }; -+struct rt_i2s_data rt3352_i2s_data = { .refclk_setup = rt3552_refclk_setup}; -+struct rt_i2s_data mt7620_i2s_data = { .refclk_setup = mt7620_refclk_setup}; -+struct rt_i2s_data mt7621_i2s_data = { .refclk_setup = mt7621_refclk_setup}; -+struct rt_i2s_data mt7628_i2s_data = { -+ .flags = (RALINK_FLAGS_ENDIAN | RALINK_FLAGS_24BIT | -+ RALINK_FLAGS_LEFT_J), -+ .refclk_setup = mt7628_refclk_setup}; -+ -+static const struct of_device_id ralink_i2s_match_table[] = { -+ { .compatible = "ralink,rt3050-i2s", -+ .data = (void *)&rt3050_i2s_data }, -+ { .compatible = "ralink,rt3350-i2s", -+ .data = (void *)&rt3350_i2s_data }, -+ { .compatible = "ralink,rt3883-i2s", -+ .data = (void *)&rt3883_i2s_data }, -+ { .compatible = "ralink,rt3352-i2s", -+ .data = (void *)&rt3352_i2s_data }, -+ { .compatible = "mediatek,mt7620-i2s", -+ .data = (void *)&mt7620_i2s_data }, -+ { .compatible = "mediatek,mt7621-i2s", -+ .data = (void *)&mt7621_i2s_data }, -+ { .compatible = "mediatek,mt7628-i2s", -+ .data = (void *)&mt7628_i2s_data }, -+}; -+MODULE_DEVICE_TABLE(of, ralink_i2s_match_table); -+ -+static int ralink_i2s_probe(struct platform_device *pdev) -+{ -+ const struct of_device_id *match; -+ struct device_node *np = pdev->dev.of_node; -+ struct ralink_i2s *i2s; -+ struct resource *res; -+ int irq, ret; -+ u32 dma_req; -+ struct rt_i2s_data *data; -+ -+ i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); -+ if (!i2s) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, i2s); -+ i2s->dev = &pdev->dev; -+ -+ match = of_match_device(ralink_i2s_match_table, &pdev->dev); -+ if (!match) -+ return -EINVAL; -+ data = (struct rt_i2s_data *)match->data; -+ i2s->flags = data->flags; -+ /* setup out 12Mhz refclk to codec as mclk */ -+ if (data->refclk_setup) -+ data->refclk_setup(); -+ -+ if (of_property_read_u32(np, "txdma-req", &dma_req)) { -+ dev_err(&pdev->dev, "no txdma-req define\n"); -+ return -EINVAL; -+ } -+ i2s->txdma_req = (u16)dma_req; -+ if (!(i2s->flags & RALINK_FLAGS_TXONLY)) { -+ if (of_property_read_u32(np, "rxdma-req", &dma_req)) { -+ dev_err(&pdev->dev, "no rxdma-req define\n"); -+ return -EINVAL; -+ } -+ i2s->rxdma_req = (u16)dma_req; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ i2s->regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(i2s->regs)) -+ return PTR_ERR(i2s->regs); -+ -+ i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->regs, -+ &ralink_i2s_regmap_config); -+ if (IS_ERR(i2s->regmap)) { -+ dev_err(&pdev->dev, "regmap init failed\n"); -+ return PTR_ERR(i2s->regmap); -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(&pdev->dev, "failed to get irq\n"); -+ return -EINVAL; -+ } -+ -+#if (RALINK_I2S_INT_EN) -+ ret = devm_request_irq(&pdev->dev, irq, ralink_i2s_irq, -+ 0, dev_name(&pdev->dev), i2s); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to request irq\n"); -+ return ret; -+ } -+#endif -+ -+ i2s->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(i2s->clk)) { -+ dev_err(&pdev->dev, "no clock defined\n"); -+ return PTR_ERR(i2s->clk); -+ } -+ -+ ret = clk_prepare_enable(i2s->clk); -+ if (ret) -+ return ret; -+ -+ ralink_i2s_init_dma_data(i2s, res); -+ -+ device_reset(&pdev->dev); -+ -+ ret = ralink_i2s_debugfs_create(i2s); -+ if (ret) { -+ dev_err(&pdev->dev, "create debugfs failed\n"); -+ goto err_clk_disable; -+ } -+ -+ /* enable 24bits support */ -+ if (i2s->flags & RALINK_FLAGS_24BIT) { -+ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S24_LE; -+ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S24_LE; -+ } -+ -+ /* enable big endian support */ -+ if (i2s->flags & RALINK_FLAGS_ENDIAN) { -+ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S16_BE; -+ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S16_BE; -+ ralink_pcm_hardware.formats |= SNDRV_PCM_FMTBIT_S16_BE; -+ if (i2s->flags & RALINK_FLAGS_24BIT) { -+ ralink_i2s_dai.capture.formats |= -+ SNDRV_PCM_FMTBIT_S24_BE; -+ ralink_i2s_dai.playback.formats |= -+ SNDRV_PCM_FMTBIT_S24_BE; -+ ralink_pcm_hardware.formats |= -+ SNDRV_PCM_FMTBIT_S24_BE; -+ } -+ } -+ -+ /* disable capture support */ -+ if (i2s->flags & RALINK_FLAGS_TXONLY) -+ memset(&ralink_i2s_dai.capture, sizeof(ralink_i2s_dai.capture), -+ 0); -+ -+ ret = devm_snd_soc_register_component(&pdev->dev, &ralink_i2s_component, -+ &ralink_i2s_dai, 1); -+ if (ret) -+ goto err_debugfs; -+ -+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, -+ &ralink_dmaengine_pcm_config, -+ SND_DMAENGINE_PCM_FLAG_COMPAT); -+ if (ret) -+ goto err_debugfs; -+ -+ dev_info(i2s->dev, "mclk %luMHz\n", clk_get_rate(i2s->clk) / 1000000); -+ -+ return 0; -+ -+err_debugfs: -+ ralink_i2s_debugfs_remove(i2s); -+ -+err_clk_disable: -+ clk_disable_unprepare(i2s->clk); -+ -+ return ret; -+} -+ -+static int ralink_i2s_remove(struct platform_device *pdev) -+{ -+ struct ralink_i2s *i2s = platform_get_drvdata(pdev); -+ -+ ralink_i2s_debugfs_remove(i2s); -+ clk_disable_unprepare(i2s->clk); -+ -+ return 0; -+} -+ -+static struct platform_driver ralink_i2s_driver = { -+ .probe = ralink_i2s_probe, -+ .remove = ralink_i2s_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .of_match_table = ralink_i2s_match_table, -+ }, -+}; -+module_platform_driver(ralink_i2s_driver); -+ -+MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>"); -+MODULE_DESCRIPTION("Ralink/MediaTek I2S driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:" DRV_NAME); diff --git a/target/linux/ramips/patches-5.4/0051-serial-add-ugly-custom-baud-rate-hack.patch b/target/linux/ramips/patches-5.4/0051-serial-add-ugly-custom-baud-rate-hack.patch deleted file mode 100644 index 7192d61323..0000000000 --- a/target/linux/ramips/patches-5.4/0051-serial-add-ugly-custom-baud-rate-hack.patch +++ /dev/null @@ -1,22 +0,0 @@ -From a7eb46e0ea4a11e4dfb56ab129bf816d1059a6c5 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 7 Dec 2015 17:31:08 +0100 -Subject: [PATCH 51/53] serial: add ugly custom baud rate hack - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - drivers/tty/serial/serial_core.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/tty/serial/serial_core.c -+++ b/drivers/tty/serial/serial_core.c -@@ -423,6 +423,9 @@ uart_get_baud_rate(struct uart_port *por - break; - } - -+ if (tty_termios_baud_rate(termios) == 2500000) -+ return 250000; -+ - for (try = 0; try < 2; try++) { - baud = tty_termios_baud_rate(termios); - diff --git a/target/linux/ramips/patches-5.4/0052-pwm-add-mediatek-support.patch b/target/linux/ramips/patches-5.4/0052-pwm-add-mediatek-support.patch deleted file mode 100644 index d2c5724c06..0000000000 --- a/target/linux/ramips/patches-5.4/0052-pwm-add-mediatek-support.patch +++ /dev/null @@ -1,217 +0,0 @@ -From fc8f96309c21c1bc3276427309cd7d361347d66e Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 7 Dec 2015 17:16:50 +0100 -Subject: [PATCH 52/53] pwm: add mediatek support - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - drivers/pwm/Kconfig | 9 +++ - drivers/pwm/Makefile | 1 + - drivers/pwm/pwm-mediatek.c | 173 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 183 insertions(+) - create mode 100644 drivers/pwm/pwm-mediatek.c - ---- a/drivers/pwm/Kconfig -+++ b/drivers/pwm/Kconfig -@@ -316,6 +316,15 @@ config PWM_MEDIATEK - To compile this driver as a module, choose M here: the module - will be called pwm-mediatek. - -+config PWM_MEDIATEK_RAMIPS -+ tristate "Mediatek PWM support" -+ depends on RALINK && OF -+ help -+ Generic PWM framework driver for Mediatek ARM SoC. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called pwm-mxs. -+ - config PWM_MXS - tristate "Freescale MXS PWM support" - depends on ARCH_MXS && OF ---- a/drivers/pwm/Makefile -+++ b/drivers/pwm/Makefile -@@ -29,6 +29,7 @@ obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-p - obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o - obj-$(CONFIG_PWM_MESON) += pwm-meson.o - obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o -+obj-$(CONFIG_PWM_MEDIATEK_RAMIPS) += pwm-mediatek-ramips.o - obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o - obj-$(CONFIG_PWM_MXS) += pwm-mxs.o - obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o ---- /dev/null -+++ b/drivers/pwm/pwm-mediatek-ramips.c -@@ -0,0 +1,173 @@ -+/* -+ * Mediatek Pulse Width Modulator driver -+ * -+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org> -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/ioport.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/platform_device.h> -+#include <linux/pwm.h> -+#include <linux/slab.h> -+#include <linux/types.h> -+ -+#define NUM_PWM 4 -+ -+/* PWM registers and bits definitions */ -+#define PWMCON 0x00 -+#define PWMHDUR 0x04 -+#define PWMLDUR 0x08 -+#define PWMGDUR 0x0c -+#define PWMWAVENUM 0x28 -+#define PWMDWIDTH 0x2c -+#define PWMTHRES 0x30 -+ -+/** -+ * struct mtk_pwm_chip - struct representing pwm chip -+ * -+ * @mmio_base: base address of pwm chip -+ * @chip: linux pwm chip representation -+ */ -+struct mtk_pwm_chip { -+ void __iomem *mmio_base; -+ struct pwm_chip chip; -+}; -+ -+static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip) -+{ -+ return container_of(chip, struct mtk_pwm_chip, chip); -+} -+ -+static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num, -+ unsigned long offset) -+{ -+ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset); -+} -+ -+static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip, -+ unsigned int num, unsigned long offset, -+ unsigned long val) -+{ -+ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset); -+} -+ -+static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, -+ int duty_ns, int period_ns) -+{ -+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); -+ u32 resolution = 100 / 4; -+ u32 clkdiv = 0; -+ -+ while (period_ns / resolution > 8191) { -+ clkdiv++; -+ resolution *= 2; -+ } -+ -+ if (clkdiv > 7) -+ return -1; -+ -+ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv); -+ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution); -+ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution); -+ return 0; -+} -+ -+static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); -+ u32 val; -+ -+ val = ioread32(pc->mmio_base); -+ val |= BIT(pwm->hwpwm); -+ iowrite32(val, pc->mmio_base); -+ -+ return 0; -+} -+ -+static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); -+ u32 val; -+ -+ val = ioread32(pc->mmio_base); -+ val &= ~BIT(pwm->hwpwm); -+ iowrite32(val, pc->mmio_base); -+} -+ -+static const struct pwm_ops mtk_pwm_ops = { -+ .config = mtk_pwm_config, -+ .enable = mtk_pwm_enable, -+ .disable = mtk_pwm_disable, -+ .owner = THIS_MODULE, -+}; -+ -+static int mtk_pwm_probe(struct platform_device *pdev) -+{ -+ struct mtk_pwm_chip *pc; -+ struct resource *r; -+ int ret; -+ -+ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); -+ if (!pc) -+ return -ENOMEM; -+ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); -+ if (IS_ERR(pc->mmio_base)) -+ return PTR_ERR(pc->mmio_base); -+ -+ platform_set_drvdata(pdev, pc); -+ -+ pc->chip.dev = &pdev->dev; -+ pc->chip.ops = &mtk_pwm_ops; -+ pc->chip.base = -1; -+ pc->chip.npwm = NUM_PWM; -+ -+ ret = pwmchip_add(&pc->chip); -+ if (ret < 0) -+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int mtk_pwm_remove(struct platform_device *pdev) -+{ -+ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev); -+ int i; -+ -+ for (i = 0; i < NUM_PWM; i++) -+ pwm_disable(&pc->chip.pwms[i]); -+ -+ return pwmchip_remove(&pc->chip); -+} -+ -+static const struct of_device_id mtk_pwm_of_match[] = { -+ { .compatible = "mediatek,mt7628-pwm" }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(of, mtk_pwm_of_match); -+ -+static struct platform_driver mtk_pwm_driver = { -+ .driver = { -+ .name = "mtk-pwm", -+ .owner = THIS_MODULE, -+ .of_match_table = mtk_pwm_of_match, -+ }, -+ .probe = mtk_pwm_probe, -+ .remove = mtk_pwm_remove, -+}; -+ -+module_platform_driver(mtk_pwm_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); -+MODULE_ALIAS("platform:mtk-pwm"); diff --git a/target/linux/ramips/patches-5.4/0069-awake-rt305x-dwc2-controller.patch b/target/linux/ramips/patches-5.4/0069-awake-rt305x-dwc2-controller.patch deleted file mode 100644 index 7110a5b808..0000000000 --- a/target/linux/ramips/patches-5.4/0069-awake-rt305x-dwc2-controller.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/drivers/usb/dwc2/platform.c -+++ b/drivers/usb/dwc2/platform.c -@@ -431,6 +431,12 @@ static int dwc2_driver_probe(struct plat - if (retval) - return retval; - -+ /* Enable USB port before any regs access */ -+ if (readl(hsotg->regs + PCGCTL) & 0x0f) { -+ writel(0x00, hsotg->regs + PCGCTL); -+ /* TODO: mdelay(25) here? vendor driver don't use it */ -+ } -+ - hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg); - - retval = dwc2_get_dr_mode(hsotg); diff --git a/target/linux/ramips/patches-5.4/0070-weak_reordering.patch b/target/linux/ramips/patches-5.4/0070-weak_reordering.patch deleted file mode 100644 index fe3fdec289..0000000000 --- a/target/linux/ramips/patches-5.4/0070-weak_reordering.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -57,6 +57,7 @@ choice - select COMMON_CLK - select CLKSRC_MIPS_GIC - select HAVE_PCI if PCI_MT7621 -+ select WEAK_REORDERING_BEYOND_LLSC - endchoice - - choice diff --git a/target/linux/ramips/patches-5.4/0098-disable_cm.patch b/target/linux/ramips/patches-5.4/0098-disable_cm.patch deleted file mode 100644 index 1f3367568f..0000000000 --- a/target/linux/ramips/patches-5.4/0098-disable_cm.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/arch/mips/kernel/mips-cm.c -+++ b/arch/mips/kernel/mips-cm.c -@@ -232,6 +232,7 @@ int mips_cm_probe(void) - - /* disable CM regions */ - write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR); -+ /* - write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK); - write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR); - write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK); -@@ -239,7 +240,7 @@ int mips_cm_probe(void) - write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK); - write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR); - write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK); -- -+*/ - /* probe for an L2-only sync region */ - mips_cm_probe_l2sync(); - diff --git a/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch b/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch deleted file mode 100644 index b9bcd63488..0000000000 --- a/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch +++ /dev/null @@ -1,133 +0,0 @@ -From b327cd58c3fec1c6382128e929eab9bc0d68e912 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Sun, 8 Mar 2020 10:19:27 +0100 -Subject: [PATCH] staging: mt7621-pci: simplify - 'mt7621_pcie_init_virtual_bridges' function - -Function 'mt7621_pcie_init_virtual_bridges' is a bit mess and can be -refactorized properly in a cleaner way. Introduce new 'pcie_rmw' inline -function helper to do clear and set the correct bits this function needs -to work. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200308091928.17177-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 85 +++++++++++++-------------------- - 1 file changed, 33 insertions(+), 52 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -57,13 +57,13 @@ - #define RALINK_PCI_IOBASE 0x002C - - /* PCICFG virtual bridges */ --#define MT7621_BR0_MASK GENMASK(19, 16) --#define MT7621_BR1_MASK GENMASK(23, 20) --#define MT7621_BR2_MASK GENMASK(27, 24) --#define MT7621_BR_ALL_MASK GENMASK(27, 16) --#define MT7621_BR0_SHIFT 16 --#define MT7621_BR1_SHIFT 20 --#define MT7621_BR2_SHIFT 24 -+#define PCIE_P2P_MAX 3 -+#define PCIE_P2P_BR_DEVNUM_SHIFT(p) (16 + (p) * 4) -+#define PCIE_P2P_BR_DEVNUM0_SHIFT PCIE_P2P_BR_DEVNUM_SHIFT(0) -+#define PCIE_P2P_BR_DEVNUM1_SHIFT PCIE_P2P_BR_DEVNUM_SHIFT(1) -+#define PCIE_P2P_BR_DEVNUM2_SHIFT PCIE_P2P_BR_DEVNUM_SHIFT(2) -+#define PCIE_P2P_BR_DEVNUM_MASK 0xf -+#define PCIE_P2P_BR_DEVNUM_MASK_FULL (0xfff << PCIE_P2P_BR_DEVNUM0_SHIFT) - - /* PCIe RC control registers */ - #define MT7621_PCIE_OFFSET 0x2000 -@@ -154,6 +154,15 @@ static inline void pcie_write(struct mt7 - writel(val, pcie->base + reg); - } - -+static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) -+{ -+ u32 val = readl(pcie->base + reg); -+ -+ val &= ~clr; -+ val |= set; -+ writel(val, pcie->base + reg); -+} -+ - static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) - { - return readl(port->base + reg); -@@ -554,7 +563,9 @@ static void mt7621_pcie_enable_ports(str - static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie) - { - u32 pcie_link_status = 0; -- u32 val = 0; -+ u32 n; -+ int i; -+ u32 p2p_br_devnum[PCIE_P2P_MAX]; - struct mt7621_pcie_port *port; - - list_for_each_entry(port, &pcie->ports, list) { -@@ -567,50 +578,20 @@ static int mt7621_pcie_init_virtual_brid - if (pcie_link_status == 0) - return -1; - -- /* -- * pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num -- * 3'b000 x x x -- * 3'b001 x x 0 -- * 3'b010 x 0 x -- * 3'b011 x 1 0 -- * 3'b100 0 x x -- * 3'b101 1 x 0 -- * 3'b110 1 0 x -- * 3'b111 2 1 0 -- */ -- switch (pcie_link_status) { -- case 2: -- val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR); -- val &= ~(MT7621_BR0_MASK | MT7621_BR1_MASK); -- val |= 0x1 << MT7621_BR0_SHIFT; -- val |= 0x0 << MT7621_BR1_SHIFT; -- pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR); -- break; -- case 4: -- val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR); -- val &= ~MT7621_BR_ALL_MASK; -- val |= 0x1 << MT7621_BR0_SHIFT; -- val |= 0x2 << MT7621_BR1_SHIFT; -- val |= 0x0 << MT7621_BR2_SHIFT; -- pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR); -- break; -- case 5: -- val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR); -- val &= ~MT7621_BR_ALL_MASK; -- val |= 0x0 << MT7621_BR0_SHIFT; -- val |= 0x2 << MT7621_BR1_SHIFT; -- val |= 0x1 << MT7621_BR2_SHIFT; -- pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR); -- break; -- case 6: -- val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR); -- val &= ~MT7621_BR_ALL_MASK; -- val |= 0x2 << MT7621_BR0_SHIFT; -- val |= 0x0 << MT7621_BR1_SHIFT; -- val |= 0x1 << MT7621_BR2_SHIFT; -- pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR); -- break; -- } -+ n = 0; -+ for (i = 0; i < PCIE_P2P_MAX; i++) -+ if (pcie_link_status & BIT(i)) -+ p2p_br_devnum[i] = n++; -+ -+ for (i = 0; i < PCIE_P2P_MAX; i++) -+ if ((pcie_link_status & BIT(i)) == 0) -+ p2p_br_devnum[i] = n++; -+ -+ pcie_rmw(pcie, RALINK_PCI_CONFIG_ADDR, -+ PCIE_P2P_BR_DEVNUM_MASK_FULL, -+ (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) | -+ (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) | -+ (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT)); - - return 0; - } diff --git a/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch b/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch deleted file mode 100644 index 3939280a16..0000000000 --- a/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 550fabd71d7fcdfe099bbf41e00e28719737161e Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Tue, 10 Mar 2020 12:34:59 +0100 -Subject: [PATCH] staging: mt7621-pci: enable clock bit for each port - -The clock related code concerns me from the very beginning because -there are some set ups got from legacy driver that are not documented -anywhere. According to the programming guide 0x7c is 'CPE_ROSC_SEL1' -register and 0x80 is 'CPU_CPE_CN'. I do think this set up is not needed -at all and the proper thing to do is just enable the clock bit for each -pcie port. Hence remove useless code and do the right thing which is -setting up the clock bit for each port enabled. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200310113459.30539-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 17 ++++++----------- - 1 file changed, 6 insertions(+), 11 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -45,8 +45,6 @@ - - /* rt_sysc_membase relative registers */ - #define RALINK_CLKCFG1 0x30 --#define RALINK_PCIE_CLK_GEN 0x7c --#define RALINK_PCIE_CLK_GEN1 0x80 - - /* Host-PCI bridge registers */ - #define RALINK_PCI_PCICFG_ADDR 0x0000 -@@ -85,10 +83,6 @@ - #define PCIE_PORT_CLK_EN(x) BIT(24 + (x)) - #define PCIE_PORT_LINKUP BIT(0) - --#define PCIE_CLK_GEN_EN BIT(31) --#define PCIE_CLK_GEN_DIS 0 --#define PCIE_CLK_GEN1_DIS GENMASK(30, 24) --#define PCIE_CLK_GEN1_EN (BIT(27) | BIT(25)) - #define MEMORY_BASE 0x0 - #define PERST_MODE_MASK GENMASK(11, 10) - #define PERST_MODE_GPIO BIT(10) -@@ -233,6 +227,11 @@ static inline bool mt7621_pcie_port_is_l - return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; - } - -+static inline void mt7621_pcie_port_clk_enable(struct mt7621_pcie_port *port) -+{ -+ rt_sysc_m32(0, PCIE_PORT_CLK_EN(port->slot), RALINK_CLKCFG1); -+} -+ - static inline void mt7621_pcie_port_clk_disable(struct mt7621_pcie_port *port) - { - rt_sysc_m32(PCIE_PORT_CLK_EN(port->slot), 0, RALINK_CLKCFG1); -@@ -501,11 +500,6 @@ static void mt7621_pcie_init_ports(struc - } - } - -- rt_sysc_m32(0x30, 2 << 4, SYSC_REG_SYSTEM_CONFIG1); -- rt_sysc_m32(PCIE_CLK_GEN_EN, PCIE_CLK_GEN_DIS, RALINK_PCIE_CLK_GEN); -- rt_sysc_m32(PCIE_CLK_GEN1_DIS, PCIE_CLK_GEN1_EN, RALINK_PCIE_CLK_GEN1); -- rt_sysc_m32(PCIE_CLK_GEN_DIS, PCIE_CLK_GEN_EN, RALINK_PCIE_CLK_GEN); -- msleep(50); - reset_control_deassert(pcie->rst); - } - -@@ -542,6 +536,7 @@ static void mt7621_pcie_enable_ports(str - - list_for_each_entry(port, &pcie->ports, list) { - if (port->enabled) { -+ mt7621_pcie_port_clk_enable(port); - mt7621_pcie_enable_port(port); - dev_info(dev, "PCIE%d enabled\n", num_slots_enabled); - num_slots_enabled++; diff --git a/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch b/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch deleted file mode 100644 index 1b7828f1e6..0000000000 --- a/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 227a8bf421ff8b085444e51e471ef06a87228cfd Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 13 Mar 2020 21:09:08 +0100 -Subject: [PATCH] staging: mt7621-pci: use gpios for properly reset - -Original driver code was using three gpio's for reset -asserts and deasserts the pcis. Instead of using that -a general reset control with a perst gpio was introduced -and it seems it is partially working but sometimes there -are some unexpected hangs on boot. This commit make use of -the three original gpios using 'reset-gpios' property of -the device tree and removes the reset line and perst gpio. -According to the mediatek aplication note v0.1 there are -three gpios used for pcie ports reset control: gpio#19, -gpio#8 and gpio#7 for slots 0, 1 and 2 respectively. -This schema can be used separately for mt7621A but in some -boards due to pin share issue, if the PCM and I2S function -are enable at the same time, there are no enough GPIO to -control per-port PCIe reset. In those cases gpio#19 is enought -for reset the three ports together. Because of this we just -try to get the three gpios but if some of them fail we are not -failing in boot process, just prints a kernel notice and take -after into account if the descriptor is or not valid in order -to use it. All of them are set as GPIO output low configuration. -The gpio descriptor's API takes device tree property into account -and invert value if the pin is configured as active low. -So we also have to properly request pins from device tree -and set values correct in assert and deassert functions. -After this changes the order to make all assert and -deassert in the 'probe' process makes more sense: -* Parse device tree. -* make assert of the RC's and EP's before doing anything else. -* make deassert of the RC's before initializing the phy. -* Init the phy. -* make deassert of the EP's before initialize pci ports. -* Normal PCI initialization. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200313200913.24321-2-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 84 ++++++++++++++++++++------------- - 1 file changed, 51 insertions(+), 33 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -95,6 +95,7 @@ - * @pcie: pointer to PCIe host info - * @phy: pointer to PHY control block - * @pcie_rst: pointer to port reset control -+ * @gpio_rst: gpio reset - * @slot: port slot - * @enabled: indicates if port is enabled - */ -@@ -104,6 +105,7 @@ struct mt7621_pcie_port { - struct mt7621_pcie *pcie; - struct phy *phy; - struct reset_control *pcie_rst; -+ struct gpio_desc *gpio_rst; - u32 slot; - bool enabled; - }; -@@ -117,8 +119,6 @@ struct mt7621_pcie_port { - * @offset: IO / Memory offset - * @dev: Pointer to PCIe device - * @ports: pointer to PCIe port information -- * @perst: gpio reset -- * @rst: pointer to pcie reset - * @resets_inverted: depends on chip revision - * reset lines are inverted. - */ -@@ -133,8 +133,6 @@ struct mt7621_pcie { - resource_size_t io; - } offset; - struct list_head ports; -- struct gpio_desc *perst; -- struct reset_control *rst; - bool resets_inverted; - }; - -@@ -210,16 +208,16 @@ static void write_config(struct mt7621_p - pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); - } - --static inline void mt7621_perst_gpio_pcie_assert(struct mt7621_pcie *pcie) -+static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) - { -- gpiod_set_value(pcie->perst, 0); -- mdelay(PERST_DELAY_US); -+ if (port->gpio_rst) -+ gpiod_set_value(port->gpio_rst, 1); - } - --static inline void mt7621_perst_gpio_pcie_deassert(struct mt7621_pcie *pcie) -+static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) - { -- gpiod_set_value(pcie->perst, 1); -- mdelay(PERST_DELAY_US); -+ if (port->gpio_rst) -+ gpiod_set_value(port->gpio_rst, 0); - } - - static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) -@@ -367,6 +365,13 @@ static int mt7621_pcie_parse_port(struct - if (IS_ERR(port->phy)) - return PTR_ERR(port->phy); - -+ port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, -+ GPIOD_OUT_LOW); -+ if (IS_ERR(port->gpio_rst)) { -+ dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot); -+ return PTR_ERR(port->gpio_rst); -+ } -+ - port->slot = slot; - port->pcie = pcie; - -@@ -383,12 +388,6 @@ static int mt7621_pcie_parse_dt(struct m - struct resource regs; - int err; - -- pcie->perst = devm_gpiod_get(dev, "perst", GPIOD_OUT_HIGH); -- if (IS_ERR(pcie->perst)) { -- dev_err(dev, "failed to get gpio perst\n"); -- return PTR_ERR(pcie->perst); -- } -- - err = of_address_to_resource(node, 0, ®s); - if (err) { - dev_err(dev, "missing \"reg\" property\n"); -@@ -399,12 +398,6 @@ static int mt7621_pcie_parse_dt(struct m - if (IS_ERR(pcie->base)) - return PTR_ERR(pcie->base); - -- pcie->rst = devm_reset_control_get_exclusive(dev, "pcie"); -- if (PTR_ERR(pcie->rst) == -EPROBE_DEFER) { -- dev_err(dev, "failed to get pcie reset control\n"); -- return PTR_ERR(pcie->rst); -- } -- - for_each_available_child_of_node(node, child) { - int slot; - -@@ -458,16 +451,49 @@ static int mt7621_pcie_init_port(struct - return 0; - } - -+static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie) -+{ -+ struct mt7621_pcie_port *port; -+ -+ list_for_each_entry(port, &pcie->ports, list) { -+ /* PCIe RC reset assert */ -+ mt7621_control_assert(port); -+ -+ /* PCIe EP reset assert */ -+ mt7621_rst_gpio_pcie_assert(port); -+ } -+ -+ mdelay(PERST_DELAY_US); -+} -+ -+static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) -+{ -+ struct mt7621_pcie_port *port; -+ -+ list_for_each_entry(port, &pcie->ports, list) -+ mt7621_control_deassert(port); -+} -+ -+static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) -+{ -+ struct mt7621_pcie_port *port; -+ -+ list_for_each_entry(port, &pcie->ports, list) -+ mt7621_rst_gpio_pcie_deassert(port); -+ -+ mdelay(PERST_DELAY_US); -+} -+ - static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) - { - struct device *dev = pcie->dev; - struct mt7621_pcie_port *port, *tmp; -- u32 val = 0; - int err; - - rt_sysc_m32(PERST_MODE_MASK, PERST_MODE_GPIO, MT7621_GPIO_MODE); - -- mt7621_perst_gpio_pcie_assert(pcie); -+ mt7621_pcie_reset_assert(pcie); -+ mt7621_pcie_reset_rc_deassert(pcie); - - list_for_each_entry_safe(port, tmp, &pcie->ports, list) { - u32 slot = port->slot; -@@ -476,16 +502,10 @@ static void mt7621_pcie_init_ports(struc - if (err) { - dev_err(dev, "Initiating port %d failed\n", slot); - list_del(&port->list); -- } else { -- val = read_config(pcie, slot, PCIE_FTS_NUM); -- dev_info(dev, "Port %d N_FTS = %x\n", slot, -- (unsigned int)val); - } - } - -- reset_control_assert(pcie->rst); -- -- mt7621_perst_gpio_pcie_deassert(pcie); -+ mt7621_pcie_reset_ep_deassert(pcie); - - list_for_each_entry(port, &pcie->ports, list) { - u32 slot = port->slot; -@@ -499,8 +519,6 @@ static void mt7621_pcie_init_ports(struc - port->enabled = false; - } - } -- -- reset_control_deassert(pcie->rst); - } - - static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) diff --git a/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch b/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch deleted file mode 100644 index 3d86355b29..0000000000 --- a/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch +++ /dev/null @@ -1,45 +0,0 @@ -From e462e7d3211479df42357a620fa788a2257556b7 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 13 Mar 2020 21:09:09 +0100 -Subject: [PATCH] staging: mt7621-pci: change value for 'PERST_DELAY_MS' - -Value of 'PERST_DELAY_MS' is too high and it is ok just -to set up to 100 ms. Update also define name from -'PERST_DELAY_US' into 'PERST_DELAY_MS' - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200313200913.24321-3-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -86,7 +86,7 @@ - #define MEMORY_BASE 0x0 - #define PERST_MODE_MASK GENMASK(11, 10) - #define PERST_MODE_GPIO BIT(10) --#define PERST_DELAY_US 1000 -+#define PERST_DELAY_MS 100 - - /** - * struct mt7621_pcie_port - PCIe port information -@@ -463,7 +463,7 @@ static void mt7621_pcie_reset_assert(str - mt7621_rst_gpio_pcie_assert(port); - } - -- mdelay(PERST_DELAY_US); -+ mdelay(PERST_DELAY_MS); - } - - static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) -@@ -481,7 +481,7 @@ static void mt7621_pcie_reset_ep_deasser - list_for_each_entry(port, &pcie->ports, list) - mt7621_rst_gpio_pcie_deassert(port); - -- mdelay(PERST_DELAY_US); -+ mdelay(PERST_DELAY_MS); - } - - static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) diff --git a/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch b/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch deleted file mode 100644 index f24bf833c9..0000000000 --- a/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 4d6a758f2cd2122a7d895f913854c13da62ba6df Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 13 Mar 2020 21:09:12 +0100 -Subject: [PATCH] staging: mt7621-pci: release gpios after pci initialization - -R3G's LEDs fail to initialize because one of them uses GPIO8 -Hence, release the GPIO resources after PCIe initialization -and properly release also in driver error path. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200313200913.24321-6-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 23 ++++++++++++++++++----- - 1 file changed, 18 insertions(+), 5 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -484,6 +484,15 @@ static void mt7621_pcie_reset_ep_deasser - mdelay(PERST_DELAY_MS); - } - -+static void mt7621_pcie_release_gpios(struct mt7621_pcie *pcie) -+{ -+ struct mt7621_pcie_port *port; -+ -+ list_for_each_entry(port, &pcie->ports, list) -+ if (port->gpio_rst) -+ gpiod_put(port->gpio_rst); -+} -+ - static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) - { - struct device *dev = pcie->dev; -@@ -683,7 +692,8 @@ static int mt7621_pci_probe(struct platf - err = mt7621_pcie_init_virtual_bridges(pcie); - if (err) { - dev_err(dev, "Nothing is connected in virtual bridges. Exiting..."); -- return 0; -+ err = 0; -+ goto out_release_gpios; - } - - mt7621_pcie_enable_ports(pcie); -@@ -691,7 +701,7 @@ static int mt7621_pci_probe(struct platf - err = mt7621_pci_parse_request_of_pci_ranges(pcie); - if (err) { - dev_err(dev, "Error requesting pci resources from ranges"); -- return err; -+ goto out_release_gpios; - } - - setup_cm_memory_region(pcie); -@@ -699,16 +709,19 @@ static int mt7621_pci_probe(struct platf - err = mt7621_pcie_request_resources(pcie, &res); - if (err) { - dev_err(dev, "Error requesting resources\n"); -- return err; -+ goto out_release_gpios; - } - - err = mt7621_pcie_register_host(bridge, &res); - if (err) { - dev_err(dev, "Error registering host\n"); -- return err; -+ goto out_release_gpios; - } - -- return 0; -+out_release_gpios: -+ mt7621_pcie_release_gpios(pcie); -+ -+ return err; - } - - static const struct of_device_id mt7621_pci_ids[] = { diff --git a/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch b/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch deleted file mode 100644 index fc509e945b..0000000000 --- a/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 4be54c3a495f08c05a8e485566e5b88cd3537f16 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 13 Mar 2020 21:09:13 +0100 -Subject: [PATCH] staging: mt7621-pci: delete no more needed - 'mt7621_reset_port' - -After review all the resets at the beggining the function -'mt7621_reset_port' is not needed anymore. Hence delete it -and its uses. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200313200913.24321-7-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 13 ------------- - 1 file changed, 13 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -255,13 +255,6 @@ static inline void mt7621_control_deasse - reset_control_assert(port->pcie_rst); - } - --static void mt7621_reset_port(struct mt7621_pcie_port *port) --{ -- mt7621_control_assert(port); -- msleep(100); -- mt7621_control_deassert(port); --} -- - static void setup_cm_memory_region(struct mt7621_pcie *pcie) - { - struct resource *mem_resource = &pcie->mem; -@@ -427,12 +420,6 @@ static int mt7621_pcie_init_port(struct - u32 slot = port->slot; - int err; - -- /* -- * Any MT7621 Ralink pcie controller that doesn't have 0x0101 at -- * the end of the chip_id has inverted PCI resets. -- */ -- mt7621_reset_port(port); -- - err = phy_init(port->phy); - if (err) { - dev_err(dev, "failed to initialize port%d phy\n", slot); diff --git a/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch b/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch deleted file mode 100644 index 234af32308..0000000000 --- a/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch +++ /dev/null @@ -1,234 +0,0 @@ -From bf0c6782e5b9a6deee4e223655325dc004fae8dd Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Sun, 15 Mar 2020 17:01:54 +0100 -Subject: [PATCH] staging: mt7621-pci-phy: add 'mt7621_phy_rmw' to simplify - code - -In order to simplify driver code and decrease a bit LOC add new -function 'mt7621_phy_rmw' where clear and set bits are passed as -arguments. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200315160154.10292-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 158 +++++++++++------------- - 1 file changed, 71 insertions(+), 87 deletions(-) - ---- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c -+++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c -@@ -120,17 +120,25 @@ static inline void phy_write(struct mt76 - regmap_write(phy->regmap, reg, val); - } - -+static inline void mt7621_phy_rmw(struct mt7621_pci_phy *phy, -+ u32 reg, u32 clr, u32 set) -+{ -+ u32 val = phy_read(phy, reg); -+ -+ val &= ~clr; -+ val |= set; -+ phy_write(phy, val, reg); -+} -+ - static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy, - struct mt7621_pci_phy_instance *instance) - { - u32 offset = (instance->index != 1) ? - RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH; -- u32 reg; - -- reg = phy_read(phy, offset); -- reg &= ~(RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); -- reg |= (RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); -- phy_write(phy, reg, offset); -+ mt7621_phy_rmw(phy, offset, -+ RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC, -+ RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); - } - - static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy, -@@ -139,97 +147,77 @@ static void mt7621_set_phy_for_ssc(struc - struct device *dev = phy->dev; - u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); - u32 offset; -- u32 val; - - reg = (reg >> 6) & 0x7; - /* Set PCIe Port PHY to disable SSC */ - /* Debug Xtal Type */ -- val = phy_read(phy, RG_PE1_FRC_H_XTAL_REG); -- val &= ~(RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE); -- val |= RG_PE1_FRC_H_XTAL_TYPE; -- val |= RG_PE1_H_XTAL_TYPE_VAL(0x00); -- phy_write(phy, val, RG_PE1_FRC_H_XTAL_REG); -+ mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG, -+ RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE, -+ RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00)); - - /* disable port */ - offset = (instance->index != 1) ? - RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; -- val = phy_read(phy, offset); -- val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); -- val |= RG_PE1_FRC_PHY_EN; -- phy_write(phy, val, offset); -- -- /* Set Pre-divider ratio (for host mode) */ -- val = phy_read(phy, RG_PE1_H_PLL_REG); -- val &= ~(RG_PE1_H_PLL_PREDIV); -+ mt7621_phy_rmw(phy, offset, -+ RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); - - if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ -- val |= RG_PE1_H_PLL_PREDIV_VAL(0x01); -- phy_write(phy, val, RG_PE1_H_PLL_REG); -+ /* Set Pre-divider ratio (for host mode) */ -+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, -+ RG_PE1_H_PLL_PREDIV, -+ RG_PE1_H_PLL_PREDIV_VAL(0x01)); - dev_info(dev, "Xtal is 40MHz\n"); -- } else { /* 25MHz | 20MHz Xtal */ -- val |= RG_PE1_H_PLL_PREDIV_VAL(0x00); -- phy_write(phy, val, RG_PE1_H_PLL_REG); -- if (reg >= 6) { -- dev_info(dev, "Xtal is 25MHz\n"); -- -- /* Select feedback clock */ -- val = phy_read(phy, RG_PE1_H_PLL_FBKSEL_REG); -- val &= ~(RG_PE1_H_PLL_FBKSEL); -- val |= RG_PE1_H_PLL_FBKSEL_VAL(0x01); -- phy_write(phy, val, RG_PE1_H_PLL_FBKSEL_REG); -- -- /* DDS NCPO PCW (for host mode) */ -- val = phy_read(phy, RG_PE1_H_LCDDS_SSC_PRD_REG); -- val &= ~(RG_PE1_H_LCDDS_SSC_PRD); -- val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000); -- phy_write(phy, val, RG_PE1_H_LCDDS_SSC_PRD_REG); -- -- /* DDS SSC dither period control */ -- val = phy_read(phy, RG_PE1_H_LCDDS_SSC_PRD_REG); -- val &= ~(RG_PE1_H_LCDDS_SSC_PRD); -- val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d); -- phy_write(phy, val, RG_PE1_H_LCDDS_SSC_PRD_REG); -- -- /* DDS SSC dither amplitude control */ -- val = phy_read(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG); -- val &= ~(RG_PE1_H_LCDDS_SSC_DELTA | -- RG_PE1_H_LCDDS_SSC_DELTA1); -- val |= RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a); -- val |= RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a); -- phy_write(phy, val, RG_PE1_H_LCDDS_SSC_DELTA_REG); -- } else { -- dev_info(dev, "Xtal is 20MHz\n"); -- } -+ } else if (reg >= 6) { /* 25MHz Xal */ -+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, -+ RG_PE1_H_PLL_PREDIV, -+ RG_PE1_H_PLL_PREDIV_VAL(0x00)); -+ /* Select feedback clock */ -+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_FBKSEL_REG, -+ RG_PE1_H_PLL_FBKSEL, -+ RG_PE1_H_PLL_FBKSEL_VAL(0x01)); -+ /* DDS NCPO PCW (for host mode) */ -+ mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG, -+ RG_PE1_H_LCDDS_SSC_PRD, -+ RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000)); -+ /* DDS SSC dither period control */ -+ mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG, -+ RG_PE1_H_LCDDS_SSC_PRD, -+ RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d)); -+ /* DDS SSC dither amplitude control */ -+ mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG, -+ RG_PE1_H_LCDDS_SSC_DELTA | -+ RG_PE1_H_LCDDS_SSC_DELTA1, -+ RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a) | -+ RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a)); -+ dev_info(dev, "Xtal is 25MHz\n"); -+ } else { /* 20MHz Xtal */ -+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, -+ RG_PE1_H_PLL_PREDIV, -+ RG_PE1_H_PLL_PREDIV_VAL(0x00)); -+ -+ dev_info(dev, "Xtal is 20MHz\n"); - } - - /* DDS clock inversion */ -- val = phy_read(phy, RG_PE1_LCDDS_CLK_PH_INV_REG); -- val &= ~(RG_PE1_LCDDS_CLK_PH_INV); -- val |= RG_PE1_LCDDS_CLK_PH_INV; -- phy_write(phy, val, RG_PE1_LCDDS_CLK_PH_INV_REG); -+ mt7621_phy_rmw(phy, RG_PE1_LCDDS_CLK_PH_INV_REG, -+ RG_PE1_LCDDS_CLK_PH_INV, RG_PE1_LCDDS_CLK_PH_INV); - - /* Set PLL bits */ -- val = phy_read(phy, RG_PE1_H_PLL_REG); -- val &= ~(RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR | -- RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN); -- val |= RG_PE1_H_PLL_BC_VAL(0x02); -- val |= RG_PE1_H_PLL_BP_VAL(0x06); -- val |= RG_PE1_H_PLL_IR_VAL(0x02); -- val |= RG_PE1_H_PLL_IC_VAL(0x01); -- val |= RG_PE1_PLL_DIVEN_VAL(0x02); -- phy_write(phy, val, RG_PE1_H_PLL_REG); -- -- val = phy_read(phy, RG_PE1_H_PLL_BR_REG); -- val &= ~(RG_PE1_H_PLL_BR); -- val |= RG_PE1_H_PLL_BR_VAL(0x00); -- phy_write(phy, val, RG_PE1_H_PLL_BR_REG); -+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, -+ RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR | -+ RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN, -+ RG_PE1_H_PLL_BC_VAL(0x02) | RG_PE1_H_PLL_BP_VAL(0x06) | -+ RG_PE1_H_PLL_IR_VAL(0x02) | RG_PE1_H_PLL_IC_VAL(0x01) | -+ RG_PE1_PLL_DIVEN_VAL(0x02)); -+ -+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG, -+ RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00)); - - if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ - /* set force mode enable of da_pe1_mstckdiv */ -- val = phy_read(phy, RG_PE1_MSTCKDIV_REG); -- val &= ~(RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV); -- val |= (RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV); -- phy_write(phy, val, RG_PE1_MSTCKDIV_REG); -+ mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG, -+ RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV, -+ RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV); - } - } - -@@ -252,13 +240,11 @@ static int mt7621_pci_phy_power_on(struc - struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); - u32 offset = (instance->index != 1) ? - RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; -- u32 val; - - /* Enable PHY and disable force mode */ -- val = phy_read(mphy, offset); -- val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); -- val |= (RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); -- phy_write(mphy, val, offset); -+ mt7621_phy_rmw(mphy, offset, -+ RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, -+ RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); - - return 0; - } -@@ -269,13 +255,11 @@ static int mt7621_pci_phy_power_off(stru - struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); - u32 offset = (instance->index != 1) ? - RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; -- u32 val; - - /* Disable PHY */ -- val = phy_read(mphy, offset); -- val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); -- val |= RG_PE1_FRC_PHY_EN; -- phy_write(mphy, val, offset); -+ mt7621_phy_rmw(mphy, offset, -+ RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, -+ RG_PE1_FRC_PHY_EN); - - return 0; - } diff --git a/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch b/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch deleted file mode 100644 index 393fd4d5dd..0000000000 --- a/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 3faf4e1c537de86058fc22a851cd979489b9185e Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Wed, 18 Mar 2020 10:44:45 +0100 -Subject: [PATCH] staging: mt7621-pci: fix io space and properly set resource - limits - -Function 'mt7621_pci_parse_request_of_pci_ranges' is using -'of_pci_range_to_resource' to get both mem and io resources. -Internally this function calls to 'pci_address_to_pio' which -returns -1 if io space address is an address > IO_SPACE_LIMIT -which is 0xFFFF for mips. This mt7621 soc has io space in physical -address 0x1e160000. In order to fix this, overwrite invalid io -0xffffffff with properly values from the device tree and set -mapped address of this resource as io port base memory address -calling 'set_io_port_base' function. There is also need to properly -setup resource limits and io and memory windows with properly -parsed values instead of set them as 'no limit' which it is wrong. -For any reason I don't really know legacy driver sets up mem window -as 0xFFFFFFFF and any other value seems to does not work as expected, -so set up also here with same values. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200318094445.19669-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 43 +++++++++++++++++++-------------- - 1 file changed, 25 insertions(+), 18 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -118,6 +118,7 @@ struct mt7621_pcie_port { - * @busn: bus range - * @offset: IO / Memory offset - * @dev: Pointer to PCIe device -+ * @io_map_base: virtual memory base address for io - * @ports: pointer to PCIe port information - * @resets_inverted: depends on chip revision - * reset lines are inverted. -@@ -132,6 +133,7 @@ struct mt7621_pcie { - resource_size_t mem; - resource_size_t io; - } offset; -+ unsigned long io_map_base; - struct list_head ports; - bool resets_inverted; - }; -@@ -291,22 +293,21 @@ static int mt7621_pci_parse_request_of_p - } - - for_each_of_pci_range(&parser, &range) { -- struct resource *res = NULL; -- - switch (range.flags & IORESOURCE_TYPE_BITS) { - case IORESOURCE_IO: -- ioremap(range.cpu_addr, range.size); -- res = &pcie->io; -+ pcie->io_map_base = -+ (unsigned long)ioremap(range.cpu_addr, -+ range.size); -+ of_pci_range_to_resource(&range, node, &pcie->io); -+ pcie->io.start = range.cpu_addr; -+ pcie->io.end = range.cpu_addr + range.size - 1; - pcie->offset.io = 0x00000000UL; - break; - case IORESOURCE_MEM: -- res = &pcie->mem; -+ of_pci_range_to_resource(&range, node, &pcie->mem); - pcie->offset.mem = 0x00000000UL; - break; - } -- -- if (res) -- of_pci_range_to_resource(&range, node, res); - } - - err = of_pci_parse_bus_range(node, &pcie->busn); -@@ -318,6 +319,8 @@ static int mt7621_pci_parse_request_of_p - pcie->busn.flags = IORESOURCE_BUS; - } - -+ set_io_port_base(pcie->io_map_base); -+ - return 0; - } - -@@ -548,6 +551,10 @@ static void mt7621_pcie_enable_ports(str - u32 slot; - u32 val; - -+ /* Setup MEMWIN and IOWIN */ -+ pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); -+ pcie_write(pcie, pcie->io.start, RALINK_PCI_IOBASE); -+ - list_for_each_entry(port, &pcie->ports, list) { - if (port->enabled) { - mt7621_pcie_port_clk_enable(port); -@@ -668,11 +675,17 @@ static int mt7621_pci_probe(struct platf - return err; - } - -+ err = mt7621_pci_parse_request_of_pci_ranges(pcie); -+ if (err) { -+ dev_err(dev, "Error requesting pci resources from ranges"); -+ goto out_release_gpios; -+ } -+ - /* set resources limits */ -- iomem_resource.start = 0; -- iomem_resource.end = ~0UL; /* no limit */ -- ioport_resource.start = 0; -- ioport_resource.end = ~0UL; /* no limit */ -+ iomem_resource.start = pcie->mem.start; -+ iomem_resource.end = pcie->mem.end; -+ ioport_resource.start = pcie->io.start; -+ ioport_resource.end = pcie->io.end; - - mt7621_pcie_init_ports(pcie); - -@@ -685,12 +698,6 @@ static int mt7621_pci_probe(struct platf - - mt7621_pcie_enable_ports(pcie); - -- err = mt7621_pci_parse_request_of_pci_ranges(pcie); -- if (err) { -- dev_err(dev, "Error requesting pci resources from ranges"); -- goto out_release_gpios; -- } -- - setup_cm_memory_region(pcie); - - err = mt7621_pcie_request_resources(pcie, &res); diff --git a/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch b/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch deleted file mode 100644 index 5b4c461b2f..0000000000 --- a/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0a3085ae142d8f5cf905b104bc66db3721a2fa33 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Thu, 19 Mar 2020 10:57:33 +0100 -Subject: [PATCH] staging: mt7621-pci: fix register to set up virtual bridges - -Instead of being using PCI Configuration and Status Register to -set up virtual bridges we are using CONFIG_ADDR Register which is -wrong. Hence, set the correct value. - -Fixes: 9a5e71a68d20 ("staging: mt7621-pci: simplify 'mt7621_pcie_init_virtual_bridges' function") -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200319095733.1557-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -603,7 +603,7 @@ static int mt7621_pcie_init_virtual_brid - if ((pcie_link_status & BIT(i)) == 0) - p2p_br_devnum[i] = n++; - -- pcie_rmw(pcie, RALINK_PCI_CONFIG_ADDR, -+ pcie_rmw(pcie, RALINK_PCI_PCICFG_ADDR, - PCIE_P2P_BR_DEVNUM_MASK_FULL, - (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) | - (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) | diff --git a/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch b/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch deleted file mode 100644 index 55abb8999f..0000000000 --- a/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 23a788c23ed10e0d79092fcb693dcf0e357e1f7e Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Thu, 19 Mar 2020 17:14:16 +0100 -Subject: [PATCH] staging: mt7621-pci: don't return if get gpio fails - -In some platforms gpio's are not used for reset but -for other purposes. Because of that when we try to -get them are valid gpio's but are already assigned -to do other function. To avoid those kind of problems -in those platforms just notice the fail in the kernel -but continue doing normal boot. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200319161416.19033-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -363,10 +363,8 @@ static int mt7621_pcie_parse_port(struct - - port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, - GPIOD_OUT_LOW); -- if (IS_ERR(port->gpio_rst)) { -- dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot); -- return PTR_ERR(port->gpio_rst); -- } -+ if (IS_ERR(port->gpio_rst)) -+ dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot); - - port->slot = slot; - port->pcie = pcie; diff --git a/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch b/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch deleted file mode 100644 index 6d84bfdd5b..0000000000 --- a/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch +++ /dev/null @@ -1,272 +0,0 @@ -From 91eb47531421f0e8c9bc4594b4a7caa0e59dc83e Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 20 Mar 2020 12:01:19 +0100 -Subject: [PATCH] staging: mt7621-pci-phy: avoid to create to different phys - for a dual port one - -This soc has two phy's for the pcie one of them using just a different -register for settig it up but sharing all the rest of the config. Until -now we was presenting this schema as three different phy's in the device -tree using the 'phy-cells' node property to discriminate an index and -setting up a complete phy for the dual port index. This sometimes worked -properly but reconfiguring the same registers twice presents sometimes -some unstable pcie links and the ports was not properly being detected. -The problems only appears on hard resets and soft resets was properly -working. Instead of having this schema just set two phy's in the device -ree and use the 'phy-cells' property to say if the port has or not a dual -port. Doing this configuration and set up becomes easier, LOC is decreased -and the behaviour also gets deterministic with properly and stable pcie -links in both hard and soft resets. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200320110123.9907-2-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 144 ++++++++++-------------- - 1 file changed, 59 insertions(+), 85 deletions(-) - ---- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c -+++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c -@@ -78,31 +78,21 @@ - #define MAX_PHYS 2 - - /** -- * struct mt7621_pci_phy_instance - Mt7621 Pcie PHY device -- * @phy: pointer to the kernel PHY device -- * @port_base: base register -- * @index: internal ID to identify the Mt7621 PCIe PHY -- */ --struct mt7621_pci_phy_instance { -- struct phy *phy; -- void __iomem *port_base; -- u32 index; --}; -- --/** - * struct mt7621_pci_phy - Mt7621 Pcie PHY core - * @dev: pointer to device - * @regmap: kernel regmap pointer -- * @phys: pointer to Mt7621 PHY device -- * @nphys: number of PHY devices for this core -+ * @phy: pointer to the kernel PHY device -+ * @port_base: base register -+ * @has_dual_port: if the phy has dual ports. - * @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst' - * needs to be executed. Depends on chip revision. - */ - struct mt7621_pci_phy { - struct device *dev; - struct regmap *regmap; -- struct mt7621_pci_phy_instance **phys; -- int nphys; -+ struct phy *phy; -+ void __iomem *port_base; -+ bool has_dual_port; - bool bypass_pipe_rst; - }; - -@@ -130,23 +120,23 @@ static inline void mt7621_phy_rmw(struct - phy_write(phy, val, reg); - } - --static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy, -- struct mt7621_pci_phy_instance *instance) -+static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy) - { -- u32 offset = (instance->index != 1) ? -- RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH; -+ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_RST); -+ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_CMD_FRC); - -- mt7621_phy_rmw(phy, offset, -- RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC, -- RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC); -+ if (phy->has_dual_port) { -+ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH, -+ 0, RG_PE1_PIPE_RST); -+ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH, -+ 0, RG_PE1_PIPE_CMD_FRC); -+ } - } - --static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy, -- struct mt7621_pci_phy_instance *instance) -+static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy) - { - struct device *dev = phy->dev; - u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); -- u32 offset; - - reg = (reg >> 6) & 0x7; - /* Set PCIe Port PHY to disable SSC */ -@@ -156,10 +146,13 @@ static void mt7621_set_phy_for_ssc(struc - RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00)); - - /* disable port */ -- offset = (instance->index != 1) ? -- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; -- mt7621_phy_rmw(phy, offset, -- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); -+ mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG, -+ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); -+ -+ if (phy->has_dual_port) { -+ mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, -+ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); -+ } - - if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ - /* Set Pre-divider ratio (for host mode) */ -@@ -223,43 +216,44 @@ static void mt7621_set_phy_for_ssc(struc - - static int mt7621_pci_phy_init(struct phy *phy) - { -- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); -- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); -+ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); - - if (mphy->bypass_pipe_rst) -- mt7621_bypass_pipe_rst(mphy, instance); -+ mt7621_bypass_pipe_rst(mphy); - -- mt7621_set_phy_for_ssc(mphy, instance); -+ mt7621_set_phy_for_ssc(mphy); - - return 0; - } - - static int mt7621_pci_phy_power_on(struct phy *phy) - { -- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); -- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); -- u32 offset = (instance->index != 1) ? -- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; -+ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); - - /* Enable PHY and disable force mode */ -- mt7621_phy_rmw(mphy, offset, -- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, -- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN); -+ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG, -+ RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN); -+ -+ if (mphy->has_dual_port) { -+ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, -+ RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN); -+ } - - return 0; - } - - static int mt7621_pci_phy_power_off(struct phy *phy) - { -- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy); -- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent); -- u32 offset = (instance->index != 1) ? -- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH; -+ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy); - - /* Disable PHY */ -- mt7621_phy_rmw(mphy, offset, -- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, -- RG_PE1_FRC_PHY_EN); -+ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG, -+ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); -+ -+ if (mphy->has_dual_port) { -+ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH, -+ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); -+ } - - return 0; - } -@@ -282,13 +276,15 @@ static struct phy *mt7621_pcie_phy_of_xl - { - struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev); - -- if (args->args_count == 0) -- return mt7621_phy->phys[0]->phy; -- - if (WARN_ON(args->args[0] >= MAX_PHYS)) - return ERR_PTR(-ENODEV); - -- return mt7621_phy->phys[args->args[0]]->phy; -+ mt7621_phy->has_dual_port = args->args[0]; -+ -+ dev_info(dev, "PHY for 0x%08x (dual port = %d)\n", -+ (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port); -+ -+ return mt7621_phy->phy; - } - - static const struct soc_device_attribute mt7621_pci_quirks_match[] = { -@@ -309,19 +305,11 @@ static int mt7621_pci_phy_probe(struct p - struct phy_provider *provider; - struct mt7621_pci_phy *phy; - struct resource *res; -- int port; -- void __iomem *port_base; - - phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - -- phy->nphys = MAX_PHYS; -- phy->phys = devm_kcalloc(dev, phy->nphys, -- sizeof(*phy->phys), GFP_KERNEL); -- if (!phy->phys) -- return -ENOMEM; -- - attr = soc_device_match(mt7621_pci_quirks_match); - if (attr) - phy->bypass_pipe_rst = true; -@@ -335,39 +323,25 @@ static int mt7621_pci_phy_probe(struct p - return -ENXIO; - } - -- port_base = devm_ioremap_resource(dev, res); -- if (IS_ERR(port_base)) { -+ phy->port_base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(phy->port_base)) { - dev_err(dev, "failed to remap phy regs\n"); -- return PTR_ERR(port_base); -+ return PTR_ERR(phy->port_base); - } - -- phy->regmap = devm_regmap_init_mmio(phy->dev, port_base, -+ phy->regmap = devm_regmap_init_mmio(phy->dev, phy->port_base, - &mt7621_pci_phy_regmap_config); - if (IS_ERR(phy->regmap)) - return PTR_ERR(phy->regmap); - -- for (port = 0; port < MAX_PHYS; port++) { -- struct mt7621_pci_phy_instance *instance; -- struct phy *pphy; -- -- instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); -- if (!instance) -- return -ENOMEM; -- -- phy->phys[port] = instance; -- -- pphy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops); -- if (IS_ERR(phy)) { -- dev_err(dev, "failed to create phy\n"); -- return PTR_ERR(phy); -- } -- -- instance->port_base = port_base; -- instance->phy = pphy; -- instance->index = port; -- phy_set_drvdata(pphy, instance); -+ phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops); -+ if (IS_ERR(phy)) { -+ dev_err(dev, "failed to create phy\n"); -+ return PTR_ERR(phy); - } - -+ phy_set_drvdata(phy->phy, phy); -+ - provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate); - - return PTR_ERR_OR_ZERO(provider); diff --git a/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch b/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch deleted file mode 100644 index 61aa80eb76..0000000000 --- a/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch +++ /dev/null @@ -1,42 +0,0 @@ -From c752b54bda4d772426c5eeb56978d2e41bd525b4 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 20 Mar 2020 12:01:21 +0100 -Subject: [PATCH] staging: mt7621-pci: use only two phys from device tree - -In order to align work with the mt7621-pci-phy part of -the driver and device tree which is now using only two -real phys one of them dual ported properly parse the -device tree and don't call phy initialization for the -slot 1 because is being taking into account when the -phy for the slot 0 is instantiated. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200320110123.9907-4-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -358,7 +358,7 @@ static int mt7621_pcie_parse_port(struct - - snprintf(name, sizeof(name), "pcie-phy%d", slot); - port->phy = devm_phy_get(dev, name); -- if (IS_ERR(port->phy)) -+ if (IS_ERR(port->phy) && slot != 1) - return PTR_ERR(port->phy); - - port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, -@@ -495,6 +495,11 @@ static void mt7621_pcie_init_ports(struc - list_for_each_entry_safe(port, tmp, &pcie->ports, list) { - u32 slot = port->slot; - -+ if (slot == 1) { -+ port->enabled = true; -+ continue; -+ } -+ - err = mt7621_pcie_init_port(port); - if (err) { - dev_err(dev, "Initiating port %d failed\n", slot); diff --git a/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch b/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch deleted file mode 100644 index 383c896a3e..0000000000 --- a/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b59343b7de448c30e5b098484a7c7c5cb300df2f Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 20 Mar 2020 12:01:22 +0100 -Subject: [PATCH] staging: mt7621-pci: change variable to print for slot - -We are using the counter to print the slot which has been -enabled. Use the correct associated slot for the port instead. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200320110123.9907-5-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -562,7 +562,7 @@ static void mt7621_pcie_enable_ports(str - if (port->enabled) { - mt7621_pcie_port_clk_enable(port); - mt7621_pcie_enable_port(port); -- dev_info(dev, "PCIE%d enabled\n", num_slots_enabled); -+ dev_info(dev, "PCIE%d enabled\n", port->slot); - num_slots_enabled++; - } - } diff --git a/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch b/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch deleted file mode 100644 index bf6fdf1d49..0000000000 --- a/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 87068309300c707d659ce79232eae827604804a4 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 20 Mar 2020 12:01:23 +0100 -Subject: [PATCH] staging: mt7621-pci: be sure gpio descriptor is null on fails - -Function 'devm_gpiod_get_index_optional' returns NULL if the -descriptor is invalid and the error associated for the error -pointer is ENOENT. Sometimes if the pin is just assigned the -error associated for the pointer might not be ENOENT but other. -In order to avoid weirds behaviours if this happen set descriptor -to NULL in the driver port structure. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200320110123.9907-6-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -363,8 +363,10 @@ static int mt7621_pcie_parse_port(struct - - port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, - GPIOD_OUT_LOW); -- if (IS_ERR(port->gpio_rst)) -+ if (IS_ERR(port->gpio_rst)) { - dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot); -+ port->gpio_rst = NULL; -+ } - - port->slot = slot; - port->pcie = pcie; diff --git a/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch b/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch deleted file mode 100644 index d733e58537..0000000000 --- a/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch +++ /dev/null @@ -1,79 +0,0 @@ -From d81fe3c13aa6f4ab1ec318212d2007175e6d05aa Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Fri, 20 Mar 2020 16:38:37 +0100 -Subject: [PATCH] staging: mt7621-pci: avoid to poweroff the phy for slot one - -Phy for slot 0 and 1 is shared and handled properly in slot 0. -If there is only one port in use,(slot 0) we shall not call the -'phy_power_off' function with an invalid slot because kernel -will crash with an unaligned access fault like the following: - -mt7621-pci 1e140000.pcie: Error applying setting, reverse things back -mt7621-pci-phy 1e149000.pcie-phy: PHY for 0xbe149000 (dual port = 1) -mt7621-pci-phy 1e14a000.pcie-phy: PHY for 0xbe14a000 (dual port = 0) -mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz -mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz -mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK) -Unhandled kernel unaligned access[#1]: -CPU: 3 PID: 111 Comm: kworker/3:2 Not tainted 5.6.0-rc3-00347-g825c6f470c62-dirty #9 -Workqueue: events deferred_probe_work_func -$ 0 : 00000000 00000001 5f60d043 8fe1ba80 -$ 4 : 0000010d 01eb9000 00000000 00000000 -$ 8 : 294b4c00 80940000 00000008 000000ce -$12 : 2e303030 00000000 00000000 65696370 -$16 : ffffffed 0000010d 8e373cd0 8214c1e0 -$20 : 00000000 82144c80 82144680 8214c250 -$24 : 00000018 803ef8f4 -$28 : 8e372000 8e373c60 8214c080 803940e8 -Hi : 00000125 -Lo : 122f2000 -epc : 807b3328 mutex_lock+0x8/0x44 -ra : 803940e8 phy_power_off+0x28/0xb0 -Status: 1100fc03 KERNEL EXL IE -Cause : 00800010 (ExcCode 04) -BadVA : 0000010d -PrId : 0001992f (MIPS 1004Kc) -Modules linked in: -Process kworker/3:2 (pid: 111, threadinfo=(ptrval), task=(ptrval), tls=00000000) -Stack : 8e373cd0 803fe4f4 8e372000 8e373c90 8214c080 804fde1c 8e373c98 808d62f4 - 8e373c78 00000000 8214c254 804fe648 1e160000 804f27b8 00000001 808d62f4 - 00000000 00000001 8214c228 808d62f4 80930000 809a0000 8fd47e10 808d63d4 - 808d62d4 8fd47e10 808d0000 808d0000 8e373cd0 8e373cd0 809e2a74 809db510 - 809db510 00000006 00000001 00000000 00000000 00000000 01000000 1e1440ff - ... -Call Trace: -[<807b3328>] mutex_lock+0x8/0x44 -[<803940e8>] phy_power_off+0x28/0xb0 -[<804fe648>] mt7621_pci_probe+0xc20/0xd18 -[<80402ab8>] platform_drv_probe+0x40/0x94 -[<80400a74>] really_probe+0x104/0x364 -[<803feb74>] bus_for_each_drv+0x84/0xdc -[<80400924>] __device_attach+0xdc/0x120 -[<803ffb5c>] bus_probe_device+0xa0/0xbc -[<80400124>] deferred_probe_work_func+0x7c/0xbc -[<800420e8>] process_one_work+0x230/0x450 -[<80042638>] worker_thread+0x330/0x5fc -[<80048eb0>] kthread+0x12c/0x134 -[<80007438>] ret_from_kernel_thread+0x14/0x1c -Code: 24050002 27bdfff8 8f830000 <c0850000> 14a00005 00000000 00600825 e0810000 1020fffa - -Fixes: bf516f413f4e ("staging: mt7621-pci: use only two phys from device tree") -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200320153837.20415-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -517,7 +517,8 @@ static void mt7621_pcie_init_ports(struc - if (!mt7621_pcie_port_is_linkup(port)) { - dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", - slot); -- phy_power_off(port->phy); -+ if (slot != 1) -+ phy_power_off(port->phy); - mt7621_control_assert(port); - mt7621_pcie_port_clk_disable(port); - port->enabled = false; diff --git a/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch b/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch deleted file mode 100644 index 5bfd205691..0000000000 --- a/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 9d789a7728c37e8730b6a9cca60cf155f18537ea Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Sat, 21 Mar 2020 08:26:50 +0100 -Subject: [PATCH] staging: mt7621-pci: delete release gpios related code - -Making gpio8 and gpio9 vendor specific and putting them -into the specific dts file makes not needed to release -gpios anymore because we are not occupying those pins -in the first place if it is not necessary. When the -device tree is parsed we can also check and return for -the error because we rely in the fact that the related -device for the board is correct. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200321072650.7784-3-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 27 +++++++-------------------- - 1 file changed, 7 insertions(+), 20 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -364,8 +364,8 @@ static int mt7621_pcie_parse_port(struct - port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, - GPIOD_OUT_LOW); - if (IS_ERR(port->gpio_rst)) { -- dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot); -- port->gpio_rst = NULL; -+ dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot); -+ return PTR_ERR(port->gpio_rst); - } - - port->slot = slot; -@@ -474,15 +474,6 @@ static void mt7621_pcie_reset_ep_deasser - mdelay(PERST_DELAY_MS); - } - --static void mt7621_pcie_release_gpios(struct mt7621_pcie *pcie) --{ -- struct mt7621_pcie_port *port; -- -- list_for_each_entry(port, &pcie->ports, list) -- if (port->gpio_rst) -- gpiod_put(port->gpio_rst); --} -- - static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) - { - struct device *dev = pcie->dev; -@@ -684,7 +675,7 @@ static int mt7621_pci_probe(struct platf - err = mt7621_pci_parse_request_of_pci_ranges(pcie); - if (err) { - dev_err(dev, "Error requesting pci resources from ranges"); -- goto out_release_gpios; -+ return err; - } - - /* set resources limits */ -@@ -698,8 +689,7 @@ static int mt7621_pci_probe(struct platf - err = mt7621_pcie_init_virtual_bridges(pcie); - if (err) { - dev_err(dev, "Nothing is connected in virtual bridges. Exiting..."); -- err = 0; -- goto out_release_gpios; -+ return 0; - } - - mt7621_pcie_enable_ports(pcie); -@@ -709,19 +699,16 @@ static int mt7621_pci_probe(struct platf - err = mt7621_pcie_request_resources(pcie, &res); - if (err) { - dev_err(dev, "Error requesting resources\n"); -- goto out_release_gpios; -+ return err; - } - - err = mt7621_pcie_register_host(bridge, &res); - if (err) { - dev_err(dev, "Error registering host\n"); -- goto out_release_gpios; -+ return err; - } - --out_release_gpios: -- mt7621_pcie_release_gpios(pcie); -- -- return err; -+ return 0; - } - - static const struct of_device_id mt7621_pci_ids[] = { diff --git a/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch b/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch deleted file mode 100644 index b333bb326b..0000000000 --- a/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 60a15339ceab9fc2a6cdc85fd54b66b2c947ab4e Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Sat, 21 Mar 2020 14:36:21 +0100 -Subject: [PATCH] staging: mt7621-pci: use builtin_platform_driver() - -Macro builtin_platform_driver can be used for builtin drivers -that don't do anything in driver init. So, use the macro -builtin_platform_driver and remove some boilerplate code. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200321133624.31388-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -725,9 +725,4 @@ static struct platform_driver mt7621_pci - }, - }; - --static int __init mt7621_pci_init(void) --{ -- return platform_driver_register(&mt7621_pci_driver); --} -- --module_init(mt7621_pci_init); -+builtin_platform_driver(mt7621_pci_driver); diff --git a/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch b/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch deleted file mode 100644 index e55def40f5..0000000000 --- a/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch +++ /dev/null @@ -1,32 +0,0 @@ -From ffe3dee4081055b4f58bc50dd3f5c97de42cf126 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Sat, 21 Mar 2020 14:36:23 +0100 -Subject: [PATCH] staging: mt7621-pci-phy: use builtin_platform_driver() - -Macro builtin_platform_driver can be used for builtin drivers -that don't do anything in driver init. So, use the macro -builtin_platform_driver and remove some boilerplate code. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200321133624.31388-3-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - ---- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c -+++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c -@@ -361,12 +361,7 @@ static struct platform_driver mt7621_pci - }, - }; - --static int __init mt7621_pci_phy_drv_init(void) --{ -- return platform_driver_register(&mt7621_pci_phy_driver); --} -- --module_init(mt7621_pci_phy_drv_init); -+builtin_platform_driver(mt7621_pci_phy_driver); - - MODULE_AUTHOR("Sergio Paracuellos <sergio.paracuellos@gmail.com>"); - MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver"); diff --git a/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch b/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch deleted file mode 100644 index 9eb8345144..0000000000 --- a/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch +++ /dev/null @@ -1,68 +0,0 @@ -From ff83e3023cb8fc3b5dfc12e0c91bf1eb9dc4c4c6 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Sat, 21 Mar 2020 14:36:24 +0100 -Subject: [PATCH] staging: mt7621-pci-phy: re-do 'xtal_mode' detection - -Detection of the Xtal mode is using magic numbers that -can be avoided using properly some definitions and a more -accurate variable name from 'reg' into 'xtal_mode'. This -increase readability. - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200321133624.31388-4-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - ---- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c -+++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c -@@ -75,6 +75,9 @@ - - #define RG_PE1_FRC_MSTCKDIV BIT(5) - -+#define XTAL_MODE_SEL_SHIFT 6 -+#define XTAL_MODE_SEL_MASK 0x7 -+ - #define MAX_PHYS 2 - - /** -@@ -136,9 +139,11 @@ static void mt7621_bypass_pipe_rst(struc - static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy) - { - struct device *dev = phy->dev; -- u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); -+ u32 xtal_mode; -+ -+ xtal_mode = (rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0) -+ >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK; - -- reg = (reg >> 6) & 0x7; - /* Set PCIe Port PHY to disable SSC */ - /* Debug Xtal Type */ - mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG, -@@ -154,13 +159,13 @@ static void mt7621_set_phy_for_ssc(struc - RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN); - } - -- if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ -+ if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */ - /* Set Pre-divider ratio (for host mode) */ - mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, - RG_PE1_H_PLL_PREDIV, - RG_PE1_H_PLL_PREDIV_VAL(0x01)); - dev_info(dev, "Xtal is 40MHz\n"); -- } else if (reg >= 6) { /* 25MHz Xal */ -+ } else if (xtal_mode >= 6) { /* 25MHz Xal */ - mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG, - RG_PE1_H_PLL_PREDIV, - RG_PE1_H_PLL_PREDIV_VAL(0x00)); -@@ -206,7 +211,7 @@ static void mt7621_set_phy_for_ssc(struc - mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG, - RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00)); - -- if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */ -+ if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */ - /* set force mode enable of da_pe1_mstckdiv */ - mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG, - RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV, diff --git a/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch b/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch deleted file mode 100644 index 9af46f4196..0000000000 --- a/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 4f0f36b67564311a4ce4441510ef94848febbab2 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Sun, 22 Mar 2020 08:21:28 +0100 -Subject: [PATCH] staging: mt7621-pci: avoid to set 'iomem_resource' addresses - -Setting up kernel resource 'iomem_resource' for PCI with -addresses parsed from device tree gots into a conflict within -the usb xhci driver: - -xhci-mtk 1e1c0000.xhci: can't request region for resource [mem 0x1e1c0000-0x1e1c0fff] -xhci-mtk: probe of 1e1c0000.xhci failed with error -16 - -Don't assign it and maintain the default addresses for this -resource seems to fix the problem. Checking legacy driver it -is being only setting the 'ioport_resource'. - -Fixes: 09dd629eeabb ("staging: mt7621-pci: fix io space and properly set resource limits") -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200322072128.4454-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -679,8 +679,6 @@ static int mt7621_pci_probe(struct platf - } - - /* set resources limits */ -- iomem_resource.start = pcie->mem.start; -- iomem_resource.end = pcie->mem.end; - ioport_resource.start = pcie->io.start; - ioport_resource.end = pcie->io.end; - diff --git a/target/linux/ramips/patches-5.4/0120-staging-mt7621-pci-properly-power-off-dual-ported-pc.patch b/target/linux/ramips/patches-5.4/0120-staging-mt7621-pci-properly-power-off-dual-ported-pc.patch deleted file mode 100644 index 9efcb8011a..0000000000 --- a/target/linux/ramips/patches-5.4/0120-staging-mt7621-pci-properly-power-off-dual-ported-pc.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 5fcded5e857cf66c9592e4be28c4dab4520c9177 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Thu, 9 Apr 2020 13:16:52 +0200 -Subject: [PATCH] staging: mt7621-pci: properly power off dual-ported pcie phy - -Pcie phy for pcie0 and pcie1 is shared using a dual ported -one. Current code was assuming that if nothing is connected -in pcie0 it won't be also nothing connected in pcie1. This -assumtion is wrong for some devices such us 'Mikrotik rbm33g' -and 'ZyXEL LTE3301-PLUS' where only connecting a card to the -second bus on the phy is possible. For such devices kernel -hangs in the same point because of the wrong poweroff of the -phy getting the following trace: - -mt7621-pci-phy 1e149000.pcie-phy: PHY for 0xbe149000 (dual port = 1) -mt7621-pci-phy 1e14a000.pcie-phy: PHY for 0xbe14a000 (dual port = 0) -mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz -mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz -mt7621-pci 1e140000.pcie: pcie0 no card, disable it (RST & CLK) -[hangs] - -The wrong assumption is located in the 'mt7621_pcie_init_ports' -function where we are just making a power off of the phy for -slots 0 and 2 if nothing is connected in them. Hence, only -poweroff the phy if nothing is connected in both slot 0 and -slot 1 avoiding the kernel to hang. - -Fixes: 5737cfe87a9c ("staging: mt7621-pci: avoid to poweroff the phy for slot one") -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200409111652.30964-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-pci/pci-mt7621.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -502,17 +502,25 @@ static void mt7621_pcie_init_ports(struc - - mt7621_pcie_reset_ep_deassert(pcie); - -+ tmp = NULL; - list_for_each_entry(port, &pcie->ports, list) { - u32 slot = port->slot; - - if (!mt7621_pcie_port_is_linkup(port)) { - dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", - slot); -- if (slot != 1) -- phy_power_off(port->phy); - mt7621_control_assert(port); - mt7621_pcie_port_clk_disable(port); - port->enabled = false; -+ -+ if (slot == 0) { -+ tmp = port; -+ continue; -+ } -+ -+ if (slot == 1 && tmp && !tmp->enabled) -+ phy_power_off(tmp->phy); -+ - } - } - } diff --git a/target/linux/ramips/patches-5.4/0121-staging-mt7621-pci-fix-PCIe-interrupt-mapping.patch b/target/linux/ramips/patches-5.4/0121-staging-mt7621-pci-fix-PCIe-interrupt-mapping.patch deleted file mode 100644 index 68de6df2db..0000000000 --- a/target/linux/ramips/patches-5.4/0121-staging-mt7621-pci-fix-PCIe-interrupt-mapping.patch +++ /dev/null @@ -1,157 +0,0 @@ -From fab6710e4c51f4eb622f95a08322ab5fdbe3f295 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Mon, 13 Apr 2020 07:59:42 +0200 -Subject: [PATCH] staging: mt7621-pci: fix PCIe interrupt mapping - -MT7621 has three assigned interrupts for the pcie. This -interrupts should properly being mapped taking into account -which devices are finally connected in which bus according -to link status. So the irq mappings should be as follows -according to link status (three bits indicating which devices -are link up): - -* For PCIe Bus 1 slot 0: - - status = 0x2 || status = 0x6 => IRQ = pcie1_irq (24). - - status = 0x4 => IRQ = pcie2_irq (25). - - default => IRQ = pcie0_irq (23). -* For PCIe Bus 2 slot 0: - - status = 0x5 || status = 0x6 => IRQ = pcie2_irq (25). - - default => IRQ = pcie1_irq (24). -* For PCIe Bus 2 slot 1: - - status = 0x5 || status = 0x6 => IRQ = pcie2_irq (25). - - default => IRQ = pcie1_irq (24). -* For PCIe Bus 3 any slot: - - default => IRQ = pcie2_irq (25). - -Because of this, the function 'of_irq_parse_and_map_pci' cannot -be used and we need to change device tree information from using -the 'interrupt-map' and 'interrupt-map-mask' properties into an -'interrupts' property to be able to get irq information from the -ports using the 'platform_get_irq' and storing an 'irq-map' into -the pcie driver data node to properly map correct irq using a -new 'mt7621_map_irq' function where this map will be read and the -correct irq returned. - -Fixes: 46d093124df4 ("staging: mt7621-pci: improve interrupt mapping") -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Link: https://lore.kernel.org/r/20200413055942.2714-1-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/staging/mt7621-dts/mt7621.dtsi | 9 +++---- - drivers/staging/mt7621-pci/pci-mt7621.c | 36 +++++++++++++++++++++++-- - 2 files changed, 38 insertions(+), 7 deletions(-) - ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ b/drivers/staging/mt7621-pci/pci-mt7621.c -@@ -97,6 +97,7 @@ - * @pcie_rst: pointer to port reset control - * @gpio_rst: gpio reset - * @slot: port slot -+ * @irq: GIC irq - * @enabled: indicates if port is enabled - */ - struct mt7621_pcie_port { -@@ -107,6 +108,7 @@ struct mt7621_pcie_port { - struct reset_control *pcie_rst; - struct gpio_desc *gpio_rst; - u32 slot; -+ int irq; - bool enabled; - }; - -@@ -120,6 +122,7 @@ struct mt7621_pcie_port { - * @dev: Pointer to PCIe device - * @io_map_base: virtual memory base address for io - * @ports: pointer to PCIe port information -+ * @irq_map: irq mapping info according pcie link status - * @resets_inverted: depends on chip revision - * reset lines are inverted. - */ -@@ -135,6 +138,7 @@ struct mt7621_pcie { - } offset; - unsigned long io_map_base; - struct list_head ports; -+ int irq_map[PCIE_P2P_MAX]; - bool resets_inverted; - }; - -@@ -279,6 +283,16 @@ static void setup_cm_memory_region(struc - } - } - -+static int mt7621_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) -+{ -+ struct mt7621_pcie *pcie = pdev->bus->sysdata; -+ struct device *dev = pcie->dev; -+ int irq = pcie->irq_map[slot]; -+ -+ dev_info(dev, "bus=%d slot=%d irq=%d\n", pdev->bus->number, slot, irq); -+ return irq; -+} -+ - static int mt7621_pci_parse_request_of_pci_ranges(struct mt7621_pcie *pcie) - { - struct device *dev = pcie->dev; -@@ -330,6 +344,7 @@ static int mt7621_pcie_parse_port(struct - { - struct mt7621_pcie_port *port; - struct device *dev = pcie->dev; -+ struct platform_device *pdev = to_platform_device(dev); - struct device_node *pnode = dev->of_node; - struct resource regs; - char name[10]; -@@ -371,6 +386,12 @@ static int mt7621_pcie_parse_port(struct - port->slot = slot; - port->pcie = pcie; - -+ port->irq = platform_get_irq(pdev, slot); -+ if (port->irq < 0) { -+ dev_err(dev, "Failed to get IRQ for PCIe%d\n", slot); -+ return -ENXIO; -+ } -+ - INIT_LIST_HEAD(&port->list); - list_add_tail(&port->list, &pcie->ports); - -@@ -585,13 +606,15 @@ static int mt7621_pcie_init_virtual_brid - { - u32 pcie_link_status = 0; - u32 n; -- int i; -+ int i = 0; - u32 p2p_br_devnum[PCIE_P2P_MAX]; -+ int irqs[PCIE_P2P_MAX]; - struct mt7621_pcie_port *port; - - list_for_each_entry(port, &pcie->ports, list) { - u32 slot = port->slot; - -+ irqs[i++] = port->irq; - if (port->enabled) - pcie_link_status |= BIT(slot); - } -@@ -614,6 +637,15 @@ static int mt7621_pcie_init_virtual_brid - (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) | - (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT)); - -+ /* Assign IRQs */ -+ n = 0; -+ for (i = 0; i < PCIE_P2P_MAX; i++) -+ if (pcie_link_status & BIT(i)) -+ pcie->irq_map[n++] = irqs[i]; -+ -+ for (i = n; i < PCIE_P2P_MAX; i++) -+ pcie->irq_map[i] = -1; -+ - return 0; - } - -@@ -638,7 +670,7 @@ static int mt7621_pcie_register_host(str - host->busnr = pcie->busn.start; - host->dev.parent = pcie->dev; - host->ops = &mt7621_pci_ops; -- host->map_irq = of_irq_parse_and_map_pci; -+ host->map_irq = mt7621_map_irq; - host->swizzle_irq = pci_common_swizzle; - host->sysdata = pcie; - diff --git a/target/linux/ramips/patches-5.4/0122-mips-ralink-enable-zboot-support.patch b/target/linux/ramips/patches-5.4/0122-mips-ralink-enable-zboot-support.patch deleted file mode 100644 index 1123cce3a5..0000000000 --- a/target/linux/ramips/patches-5.4/0122-mips-ralink-enable-zboot-support.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 1f0400d0e2c410b04f246aefb2e9b5155eb4b0bf Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo <gch981213@gmail.com> -Date: Tue, 13 Oct 2020 10:05:47 +0800 -Subject: mips: ralink: enable zboot support - -Some of these ralink devices come with an ancient u-boot which can't -extract LZMA properly when image gets too big. -Enable zboot support to get a self-extracting kernel instead of relying -on broken u-boot support. - -Signed-off-by: Chuanhong Guo <gch981213@gmail.com> -Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> ---- - arch/mips/Kconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -631,6 +631,7 @@ config RALINK - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_MIPS16 -+ select SYS_SUPPORTS_ZBOOT - select SYS_HAS_EARLY_PRINTK - select CLKDEV_LOOKUP - select ARCH_HAS_RESET_CONTROLLER diff --git a/target/linux/ramips/patches-5.4/0123-mips-ralink-manage-low-reset-lines.patch b/target/linux/ramips/patches-5.4/0123-mips-ralink-manage-low-reset-lines.patch deleted file mode 100644 index bdf98f223c..0000000000 --- a/target/linux/ramips/patches-5.4/0123-mips-ralink-manage-low-reset-lines.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3f9ef7785a9cd69cb75f5e2ea4ca79a24752e496 Mon Sep 17 00:00:00 2001 -From: Sander Vanheule <sander@svanheule.net> -Date: Wed, 3 Feb 2021 10:21:41 +0100 -Subject: MIPS: ralink: manage low reset lines - -Reset lines with indices smaller than 8 are currently considered invalid -by the rt2880-reset reset controller. - -The MT7621 SoC uses a number of these low reset lines. The DTS defines -reset lines "hsdma", "fe", and "mcm" with respective values 5, 6, and 2. -As a result of the above restriction, these resets cannot be asserted or -de-asserted by the reset controller. In cases where the bootloader does -not de-assert these lines, this results in e.g. the MT7621's internal -switch staying in reset. - -Change the reset controller to only ignore the system reset, so all -reset lines with index greater than 0 are considered valid. - -Signed-off-by: Sander Vanheule <sander@svanheule.net> -Acked-by: John Crispin <john@phrozen.org> -Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> ---- - arch/mips/ralink/reset.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/mips/ralink/reset.c -+++ b/arch/mips/ralink/reset.c -@@ -27,7 +27,7 @@ static int ralink_assert_device(struct r - { - u32 val; - -- if (id < 8) -+ if (id == 0) - return -1; - - val = rt_sysc_r32(SYSC_REG_RESET_CTRL); -@@ -42,7 +42,7 @@ static int ralink_deassert_device(struct - { - u32 val; - -- if (id < 8) -+ if (id == 0) - return -1; - - val = rt_sysc_r32(SYSC_REG_RESET_CTRL); diff --git a/target/linux/ramips/patches-5.4/0200-linkit_bootstrap.patch b/target/linux/ramips/patches-5.4/0200-linkit_bootstrap.patch deleted file mode 100644 index 9142faaf43..0000000000 --- a/target/linux/ramips/patches-5.4/0200-linkit_bootstrap.patch +++ /dev/null @@ -1,97 +0,0 @@ ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -52,6 +52,7 @@ obj-$(CONFIG_ECHO) += echo/ - obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o - obj-$(CONFIG_CXL_BASE) += cxl/ - obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o -+obj-$(CONFIG_SOC_MT7620) += linkit.o - obj-$(CONFIG_OCXL) += ocxl/ - obj-y += cardreader/ - obj-$(CONFIG_PVPANIC) += pvpanic.o ---- /dev/null -+++ b/drivers/misc/linkit.c -@@ -0,0 +1,84 @@ -+/* -+ * 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 -+ * publishhed by the Free Software Foundation. -+ * -+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org> -+ */ -+ -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/of.h> -+#include <linux/mtd/mtd.h> -+#include <linux/gpio.h> -+ -+#define LINKIT_LATCH_GPIO 11 -+ -+struct linkit_hw_data { -+ char board[16]; -+ char rev[16]; -+}; -+ -+static void sanify_string(char *s) -+{ -+ int i; -+ -+ for (i = 0; i < 15; i++) -+ if (s[i] <= 0x20) -+ s[i] = '\0'; -+ s[15] = '\0'; -+} -+ -+static int linkit_probe(struct platform_device *pdev) -+{ -+ struct linkit_hw_data hw; -+ struct mtd_info *mtd; -+ size_t retlen; -+ int ret; -+ -+ mtd = get_mtd_device_nm("factory"); -+ if (IS_ERR(mtd)) -+ return PTR_ERR(mtd); -+ -+ ret = mtd_read(mtd, 0x400, sizeof(hw), &retlen, (u_char *) &hw); -+ put_mtd_device(mtd); -+ -+ sanify_string(hw.board); -+ sanify_string(hw.rev); -+ -+ dev_info(&pdev->dev, "Version : %s\n", hw.board); -+ dev_info(&pdev->dev, "Revision : %s\n", hw.rev); -+ -+ if (!strcmp(hw.board, "LINKITS7688")) { -+ dev_info(&pdev->dev, "setting up bootstrap latch\n"); -+ -+ if (devm_gpio_request(&pdev->dev, LINKIT_LATCH_GPIO, "bootstrap")) { -+ dev_err(&pdev->dev, "failed to setup bootstrap gpio\n"); -+ return -1; -+ } -+ gpio_direction_output(LINKIT_LATCH_GPIO, 0); -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id linkit_match[] = { -+ { .compatible = "mediatek,linkit" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, linkit_match); -+ -+static struct platform_driver linkit_driver = { -+ .probe = linkit_probe, -+ .driver = { -+ .name = "mtk-linkit", -+ .owner = THIS_MODULE, -+ .of_match_table = linkit_match, -+ }, -+}; -+ -+int __init linkit_init(void) -+{ -+ return platform_driver_register(&linkit_driver); -+} -+late_initcall_sync(linkit_init); diff --git a/target/linux/ramips/patches-5.4/0300-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch b/target/linux/ramips/patches-5.4/0300-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch deleted file mode 100644 index ba844fed0f..0000000000 --- a/target/linux/ramips/patches-5.4/0300-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch +++ /dev/null @@ -1,1400 +0,0 @@ -From e84e2430ee0e483842b4ff013ae8a6e7e2fa2734 Mon Sep 17 00:00:00 2001 -From: Weijie Gao <weijie.gao@mediatek.com> -Date: Wed, 1 Apr 2020 02:07:58 +0800 -Subject: [PATCH 1/2] mtd: rawnand: add driver support for MT7621 nand - flash controller - -This patch adds NAND flash controller driver for MediaTek MT7621 SoC. - -The NAND flash controller is similar with controllers described in -mtk_nand.c, except that the controller from MT7621 doesn't support DMA -transmission, and some registers' offset and fields are different. - -Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> ---- - drivers/mtd/nand/raw/Kconfig | 8 + - drivers/mtd/nand/raw/Makefile | 1 + - drivers/mtd/nand/raw/mt7621_nand.c | 1348 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 1357 insertions(+) - create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c - ---- a/drivers/mtd/nand/raw/Kconfig -+++ b/drivers/mtd/nand/raw/Kconfig -@@ -391,6 +391,14 @@ config MTD_NAND_QCOM - Enables support for NAND flash chips on SoCs containing the EBI2 NAND - controller. This controller is found on IPQ806x SoC. - -+config MTD_NAND_MT7621 -+ tristate "MT7621 NAND controller" -+ depends on SOC_MT7621 || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ Enables support for NAND controller on MT7621 SoC. -+ This driver uses PIO mode for data transmission instead of DMA mode. -+ - config MTD_NAND_MTK - tristate "MTK NAND controller" - depends on ARCH_MEDIATEK || COMPILE_TEST ---- a/drivers/mtd/nand/raw/Makefile -+++ b/drivers/mtd/nand/raw/Makefile -@@ -52,6 +52,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n - obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o - obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ - obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o -+obj-$(CONFIG_MTD_NAND_MT7621) += mt7621_nand.o - obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o - obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o - obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o ---- /dev/null -+++ b/drivers/mtd/nand/raw/mt7621_nand.c -@@ -0,0 +1,1350 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * MediaTek MT7621 NAND Flash Controller driver -+ * -+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved. -+ * -+ * Author: Weijie Gao <weijie.gao@mediatek.com> -+ */ -+ -+#include <linux/io.h> -+#include <linux/clk.h> -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/sizes.h> -+#include <linux/iopoll.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/rawnand.h> -+#include <linux/mtd/partitions.h> -+#include <linux/platform_device.h> -+#include <asm/addrspace.h> -+ -+/* NFI core registers */ -+#define NFI_CNFG 0x000 -+#define CNFG_OP_MODE_S 12 -+#define CNFG_OP_MODE_M GENMASK(14, 12) -+#define CNFG_OP_CUSTOM 6 -+#define CNFG_AUTO_FMT_EN BIT(9) -+#define CNFG_HW_ECC_EN BIT(8) -+#define CNFG_BYTE_RW BIT(6) -+#define CNFG_READ_MODE BIT(1) -+ -+#define NFI_PAGEFMT 0x004 -+#define PAGEFMT_FDM_ECC_S 12 -+#define PAGEFMT_FDM_ECC_M GENMASK(15, 12) -+#define PAGEFMT_FDM_S 8 -+#define PAGEFMT_FDM_M GENMASK(11, 8) -+#define PAGEFMT_SPARE_S 4 -+#define PAGEFMT_SPARE_M GENMASK(5, 4) -+#define PAGEFMT_PAGE_S 0 -+#define PAGEFMT_PAGE_M GENMASK(1, 0) -+ -+#define NFI_CON 0x008 -+#define CON_NFI_SEC_S 12 -+#define CON_NFI_SEC_M GENMASK(15, 12) -+#define CON_NFI_BWR BIT(9) -+#define CON_NFI_BRD BIT(8) -+#define CON_NFI_RST BIT(1) -+#define CON_FIFO_FLUSH BIT(0) -+ -+#define NFI_ACCCON 0x00c -+#define ACCCON_POECS_S 28 -+#define ACCCON_POECS_MAX 0x0f -+#define ACCCON_POECS_DEF 3 -+#define ACCCON_PRECS_S 22 -+#define ACCCON_PRECS_MAX 0x3f -+#define ACCCON_PRECS_DEF 3 -+#define ACCCON_C2R_S 16 -+#define ACCCON_C2R_MAX 0x3f -+#define ACCCON_C2R_DEF 7 -+#define ACCCON_W2R_S 12 -+#define ACCCON_W2R_MAX 0x0f -+#define ACCCON_W2R_DEF 7 -+#define ACCCON_WH_S 8 -+#define ACCCON_WH_MAX 0x0f -+#define ACCCON_WH_DEF 15 -+#define ACCCON_WST_S 4 -+#define ACCCON_WST_MAX 0x0f -+#define ACCCON_WST_DEF 15 -+#define ACCCON_WST_MIN 3 -+#define ACCCON_RLT_S 0 -+#define ACCCON_RLT_MAX 0x0f -+#define ACCCON_RLT_DEF 15 -+#define ACCCON_RLT_MIN 3 -+ -+#define NFI_CMD 0x020 -+ -+#define NFI_ADDRNOB 0x030 -+#define ADDR_ROW_NOB_S 4 -+#define ADDR_ROW_NOB_M GENMASK(6, 4) -+#define ADDR_COL_NOB_S 0 -+#define ADDR_COL_NOB_M GENMASK(2, 0) -+ -+#define NFI_COLADDR 0x034 -+#define NFI_ROWADDR 0x038 -+ -+#define NFI_STRDATA 0x040 -+#define STR_DATA BIT(0) -+ -+#define NFI_CNRNB 0x044 -+#define CB2R_TIME_S 4 -+#define CB2R_TIME_M GENMASK(7, 4) -+#define STR_CNRNB BIT(0) -+ -+#define NFI_DATAW 0x050 -+#define NFI_DATAR 0x054 -+ -+#define NFI_PIO_DIRDY 0x058 -+#define PIO_DIRDY BIT(0) -+ -+#define NFI_STA 0x060 -+#define STA_NFI_FSM_S 16 -+#define STA_NFI_FSM_M GENMASK(19, 16) -+#define STA_FSM_CUSTOM_DATA 14 -+#define STA_BUSY BIT(8) -+#define STA_ADDR BIT(1) -+#define STA_CMD BIT(0) -+ -+#define NFI_ADDRCNTR 0x070 -+#define SEC_CNTR_S 12 -+#define SEC_CNTR_M GENMASK(15, 12) -+#define SEC_ADDR_S 0 -+#define SEC_ADDR_M GENMASK(9, 0) -+ -+#define NFI_CSEL 0x090 -+#define CSEL_S 0 -+#define CSEL_M GENMASK(1, 0) -+ -+#define NFI_FDM0L 0x0a0 -+#define NFI_FDML(n) (0x0a0 + ((n) << 3)) -+ -+#define NFI_FDM0M 0x0a4 -+#define NFI_FDMM(n) (0x0a4 + ((n) << 3)) -+ -+#define NFI_MASTER_STA 0x210 -+#define MAS_ADDR GENMASK(11, 9) -+#define MAS_RD GENMASK(8, 6) -+#define MAS_WR GENMASK(5, 3) -+#define MAS_RDDLY GENMASK(2, 0) -+ -+/* ECC engine registers */ -+#define ECC_ENCCON 0x000 -+#define ENC_EN BIT(0) -+ -+#define ECC_ENCCNFG 0x004 -+#define ENC_CNFG_MSG_S 16 -+#define ENC_CNFG_MSG_M GENMASK(28, 16) -+#define ENC_MODE_S 4 -+#define ENC_MODE_M GENMASK(5, 4) -+#define ENC_MODE_NFI 1 -+#define ENC_TNUM_S 0 -+#define ENC_TNUM_M GENMASK(2, 0) -+ -+#define ECC_ENCIDLE 0x00c -+#define ENC_IDLE BIT(0) -+ -+#define ECC_DECCON 0x100 -+#define DEC_EN BIT(0) -+ -+#define ECC_DECCNFG 0x104 -+#define DEC_EMPTY_EN BIT(31) -+#define DEC_CS_S 16 -+#define DEC_CS_M GENMASK(28, 16) -+#define DEC_CON_S 12 -+#define DEC_CON_M GENMASK(13, 12) -+#define DEC_CON_EL 2 -+#define DEC_MODE_S 4 -+#define DEC_MODE_M GENMASK(5, 4) -+#define DEC_MODE_NFI 1 -+#define DEC_TNUM_S 0 -+#define DEC_TNUM_M GENMASK(2, 0) -+ -+#define ECC_DECIDLE 0x10c -+#define DEC_IDLE BIT(1) -+ -+#define ECC_DECENUM 0x114 -+#define ERRNUM_S 2 -+#define ERRNUM_M GENMASK(3, 0) -+ -+#define ECC_DECDONE 0x118 -+#define DEC_DONE7 BIT(7) -+#define DEC_DONE6 BIT(6) -+#define DEC_DONE5 BIT(5) -+#define DEC_DONE4 BIT(4) -+#define DEC_DONE3 BIT(3) -+#define DEC_DONE2 BIT(2) -+#define DEC_DONE1 BIT(1) -+#define DEC_DONE0 BIT(0) -+ -+#define ECC_DECEL(n) (0x11c + (n) * 4) -+#define DEC_EL_ODD_S 16 -+#define DEC_EL_EVEN_S 0 -+#define DEC_EL_M 0x1fff -+#define DEC_EL_BYTE_POS_S 3 -+#define DEC_EL_BIT_POS_M GENMASK(3, 0) -+ -+#define ECC_FDMADDR 0x13c -+ -+/* ENCIDLE and DECIDLE */ -+#define ECC_IDLE BIT(0) -+ -+#define ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt) \ -+ ((tpoecs) << ACCCON_POECS_S | (tprecs) << ACCCON_PRECS_S | \ -+ (tc2r) << ACCCON_C2R_S | (tw2r) << ACCCON_W2R_S | \ -+ (twh) << ACCCON_WH_S | (twst) << ACCCON_WST_S | (trlt)) -+ -+#define MASTER_STA_MASK (MAS_ADDR | MAS_RD | MAS_WR | \ -+ MAS_RDDLY) -+#define NFI_RESET_TIMEOUT 1000000 -+#define NFI_CORE_TIMEOUT 500000 -+#define ECC_ENGINE_TIMEOUT 500000 -+ -+#define ECC_SECTOR_SIZE 512 -+#define ECC_PARITY_BITS 13 -+ -+#define NFI_FDM_SIZE 8 -+ -+#define MT7621_NFC_NAME "mt7621-nand" -+ -+struct mt7621_nfc { -+ struct nand_controller controller; -+ struct nand_chip nand; -+ struct clk *nfi_clk; -+ struct device *dev; -+ -+ void __iomem *nfi_regs; -+ void __iomem *ecc_regs; -+ -+ u32 spare_per_sector; -+}; -+ -+static const u16 mt7621_nfi_page_size[] = { SZ_512, SZ_2K, SZ_4K }; -+static const u8 mt7621_nfi_spare_size[] = { 16, 26, 27, 28 }; -+static const u8 mt7621_ecc_strength[] = { 4, 6, 8, 10, 12 }; -+ -+static inline u32 nfi_read32(struct mt7621_nfc *nfc, u32 reg) -+{ -+ return readl(nfc->nfi_regs + reg); -+} -+ -+static inline void nfi_write32(struct mt7621_nfc *nfc, u32 reg, u32 val) -+{ -+ writel(val, nfc->nfi_regs + reg); -+} -+ -+static inline u16 nfi_read16(struct mt7621_nfc *nfc, u32 reg) -+{ -+ return readw(nfc->nfi_regs + reg); -+} -+ -+static inline void nfi_write16(struct mt7621_nfc *nfc, u32 reg, u16 val) -+{ -+ writew(val, nfc->nfi_regs + reg); -+} -+ -+static inline void ecc_write16(struct mt7621_nfc *nfc, u32 reg, u16 val) -+{ -+ writew(val, nfc->ecc_regs + reg); -+} -+ -+static inline u32 ecc_read32(struct mt7621_nfc *nfc, u32 reg) -+{ -+ return readl(nfc->ecc_regs + reg); -+} -+ -+static inline void ecc_write32(struct mt7621_nfc *nfc, u32 reg, u32 val) -+{ -+ return writel(val, nfc->ecc_regs + reg); -+} -+ -+static inline u8 *oob_fdm_ptr(struct nand_chip *nand, int sect) -+{ -+ return nand->oob_poi + sect * NFI_FDM_SIZE; -+} -+ -+static inline u8 *oob_ecc_ptr(struct mt7621_nfc *nfc, int sect) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ -+ return nand->oob_poi + nand->ecc.steps * NFI_FDM_SIZE + -+ sect * (nfc->spare_per_sector - NFI_FDM_SIZE); -+} -+ -+static inline u8 *page_data_ptr(struct nand_chip *nand, const u8 *buf, -+ int sect) -+{ -+ return (u8 *)buf + sect * nand->ecc.size; -+} -+ -+static int mt7621_ecc_wait_idle(struct mt7621_nfc *nfc, u32 reg) -+{ -+ struct device *dev = nfc->dev; -+ u32 val; -+ int ret; -+ -+ ret = readw_poll_timeout_atomic(nfc->ecc_regs + reg, val, -+ val & ECC_IDLE, 10, -+ ECC_ENGINE_TIMEOUT); -+ if (ret) { -+ dev_warn(dev, "ECC engine timed out entering idle mode\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int mt7621_ecc_decoder_wait_done(struct mt7621_nfc *nfc, u32 sect) -+{ -+ struct device *dev = nfc->dev; -+ u32 val; -+ int ret; -+ -+ ret = readw_poll_timeout_atomic(nfc->ecc_regs + ECC_DECDONE, val, -+ val & (1 << sect), 10, -+ ECC_ENGINE_TIMEOUT); -+ -+ if (ret) { -+ dev_warn(dev, "ECC decoder for sector %d timed out\n", -+ sect); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static void mt7621_ecc_encoder_op(struct mt7621_nfc *nfc, bool enable) -+{ -+ mt7621_ecc_wait_idle(nfc, ECC_ENCIDLE); -+ ecc_write16(nfc, ECC_ENCCON, enable ? ENC_EN : 0); -+} -+ -+static void mt7621_ecc_decoder_op(struct mt7621_nfc *nfc, bool enable) -+{ -+ mt7621_ecc_wait_idle(nfc, ECC_DECIDLE); -+ ecc_write16(nfc, ECC_DECCON, enable ? DEC_EN : 0); -+} -+ -+static int mt7621_ecc_correct_check(struct mt7621_nfc *nfc, u8 *sector_buf, -+ u8 *fdm_buf, u32 sect) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ u32 decnum, num_error_bits, fdm_end_bits; -+ u32 error_locations, error_bit_loc; -+ u32 error_byte_pos, error_bit_pos; -+ int bitflips = 0; -+ u32 i; -+ -+ decnum = ecc_read32(nfc, ECC_DECENUM); -+ num_error_bits = (decnum >> (sect << ERRNUM_S)) & ERRNUM_M; -+ fdm_end_bits = (nand->ecc.size + NFI_FDM_SIZE) << 3; -+ -+ if (!num_error_bits) -+ return 0; -+ -+ if (num_error_bits == ERRNUM_M) -+ return -1; -+ -+ for (i = 0; i < num_error_bits; i++) { -+ error_locations = ecc_read32(nfc, ECC_DECEL(i / 2)); -+ error_bit_loc = (error_locations >> ((i % 2) * DEC_EL_ODD_S)) & -+ DEC_EL_M; -+ error_byte_pos = error_bit_loc >> DEC_EL_BYTE_POS_S; -+ error_bit_pos = error_bit_loc & DEC_EL_BIT_POS_M; -+ -+ if (error_bit_loc < (nand->ecc.size << 3)) { -+ if (sector_buf) { -+ sector_buf[error_byte_pos] ^= -+ (1 << error_bit_pos); -+ } -+ } else if (error_bit_loc < fdm_end_bits) { -+ if (fdm_buf) { -+ fdm_buf[error_byte_pos - nand->ecc.size] ^= -+ (1 << error_bit_pos); -+ } -+ } -+ -+ bitflips++; -+ } -+ -+ return bitflips; -+} -+ -+static int mt7621_nfc_wait_write_completion(struct mt7621_nfc *nfc, -+ struct nand_chip *nand) -+{ -+ struct device *dev = nfc->dev; -+ u16 val; -+ int ret; -+ -+ ret = readw_poll_timeout_atomic(nfc->nfi_regs + NFI_ADDRCNTR, val, -+ ((val & SEC_CNTR_M) >> SEC_CNTR_S) >= nand->ecc.steps, 10, -+ NFI_CORE_TIMEOUT); -+ -+ if (ret) { -+ dev_warn(dev, "NFI core write operation timed out\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return ret; -+} -+ -+static void mt7621_nfc_hw_reset(struct mt7621_nfc *nfc) -+{ -+ u32 val; -+ int ret; -+ -+ /* reset all registers and force the NFI master to terminate */ -+ nfi_write16(nfc, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST); -+ -+ /* wait for the master to finish the last transaction */ -+ ret = readw_poll_timeout(nfc->nfi_regs + NFI_MASTER_STA, val, -+ !(val & MASTER_STA_MASK), 50, -+ NFI_RESET_TIMEOUT); -+ if (ret) { -+ dev_warn(nfc->dev, "Failed to reset NFI master in %dms\n", -+ NFI_RESET_TIMEOUT); -+ } -+ -+ /* ensure any status register affected by the NFI master is reset */ -+ nfi_write16(nfc, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST); -+ nfi_write16(nfc, NFI_STRDATA, 0); -+} -+ -+static inline void mt7621_nfc_hw_init(struct mt7621_nfc *nfc) -+{ -+ u32 acccon; -+ -+ /* -+ * CNRNB: nand ready/busy register -+ * ------------------------------- -+ * 7:4: timeout register for polling the NAND busy/ready signal -+ * 0 : poll the status of the busy/ready signal after [7:4]*16 cycles. -+ */ -+ nfi_write16(nfc, NFI_CNRNB, CB2R_TIME_M | STR_CNRNB); -+ -+ mt7621_nfc_hw_reset(nfc); -+ -+ /* Apply default access timing */ -+ acccon = ACCTIMING(ACCCON_POECS_DEF, ACCCON_PRECS_DEF, ACCCON_C2R_DEF, -+ ACCCON_W2R_DEF, ACCCON_WH_DEF, ACCCON_WST_DEF, -+ ACCCON_RLT_DEF); -+ -+ nfi_write32(nfc, NFI_ACCCON, acccon); -+} -+ -+static int mt7621_nfc_send_command(struct mt7621_nfc *nfc, u8 command) -+{ -+ struct device *dev = nfc->dev; -+ u32 val; -+ int ret; -+ -+ nfi_write32(nfc, NFI_CMD, command); -+ -+ ret = readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val, -+ !(val & STA_CMD), 10, -+ NFI_CORE_TIMEOUT); -+ if (ret) { -+ dev_warn(dev, "NFI core timed out entering command mode\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int mt7621_nfc_send_address_byte(struct mt7621_nfc *nfc, int addr) -+{ -+ struct device *dev = nfc->dev; -+ u32 val; -+ int ret; -+ -+ nfi_write32(nfc, NFI_COLADDR, addr); -+ nfi_write32(nfc, NFI_ROWADDR, 0); -+ nfi_write16(nfc, NFI_ADDRNOB, 1); -+ -+ ret = readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val, -+ !(val & STA_ADDR), 10, -+ NFI_CORE_TIMEOUT); -+ if (ret) { -+ dev_warn(dev, "NFI core timed out entering address mode\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int mt7621_nfc_send_address(struct mt7621_nfc *nfc, const u8 *addr, -+ unsigned int naddrs) -+{ -+ int ret; -+ -+ while (naddrs) { -+ ret = mt7621_nfc_send_address_byte(nfc, *addr); -+ if (ret) -+ return ret; -+ -+ addr++; -+ naddrs--; -+ } -+ -+ return 0; -+} -+ -+static void mt7621_nfc_wait_pio_ready(struct mt7621_nfc *nfc) -+{ -+ struct device *dev = nfc->dev; -+ int ret; -+ u16 val; -+ -+ ret = readw_poll_timeout_atomic(nfc->nfi_regs + NFI_PIO_DIRDY, val, -+ val & PIO_DIRDY, 10, -+ NFI_CORE_TIMEOUT); -+ if (ret < 0) -+ dev_err(dev, "NFI core PIO mode not ready\n"); -+} -+ -+static u32 mt7621_nfc_pio_read(struct mt7621_nfc *nfc, bool br) -+{ -+ u32 reg; -+ -+ /* after each byte read, the NFI_STA reg is reset by the hardware */ -+ reg = (nfi_read32(nfc, NFI_STA) & STA_NFI_FSM_M) >> STA_NFI_FSM_S; -+ if (reg != STA_FSM_CUSTOM_DATA) { -+ reg = nfi_read16(nfc, NFI_CNFG); -+ reg |= CNFG_READ_MODE | CNFG_BYTE_RW; -+ if (!br) -+ reg &= ~CNFG_BYTE_RW; -+ nfi_write16(nfc, NFI_CNFG, reg); -+ -+ /* -+ * set to max sector to allow the HW to continue reading over -+ * unaligned accesses -+ */ -+ nfi_write16(nfc, NFI_CON, CON_NFI_SEC_M | CON_NFI_BRD); -+ -+ /* trigger to fetch data */ -+ nfi_write16(nfc, NFI_STRDATA, STR_DATA); -+ } -+ -+ mt7621_nfc_wait_pio_ready(nfc); -+ -+ return nfi_read32(nfc, NFI_DATAR); -+} -+ -+static void mt7621_nfc_read_data(struct mt7621_nfc *nfc, u8 *buf, u32 len) -+{ -+ while (((uintptr_t)buf & 3) && len) { -+ *buf = mt7621_nfc_pio_read(nfc, true); -+ buf++; -+ len--; -+ } -+ -+ while (len >= 4) { -+ *(u32 *)buf = mt7621_nfc_pio_read(nfc, false); -+ buf += 4; -+ len -= 4; -+ } -+ -+ while (len) { -+ *buf = mt7621_nfc_pio_read(nfc, true); -+ buf++; -+ len--; -+ } -+} -+ -+static void mt7621_nfc_read_data_discard(struct mt7621_nfc *nfc, u32 len) -+{ -+ while (len >= 4) { -+ mt7621_nfc_pio_read(nfc, false); -+ len -= 4; -+ } -+ -+ while (len) { -+ mt7621_nfc_pio_read(nfc, true); -+ len--; -+ } -+} -+ -+static void mt7621_nfc_pio_write(struct mt7621_nfc *nfc, u32 val, bool bw) -+{ -+ u32 reg; -+ -+ reg = (nfi_read32(nfc, NFI_STA) & STA_NFI_FSM_M) >> STA_NFI_FSM_S; -+ if (reg != STA_FSM_CUSTOM_DATA) { -+ reg = nfi_read16(nfc, NFI_CNFG); -+ reg &= ~(CNFG_READ_MODE | CNFG_BYTE_RW); -+ if (bw) -+ reg |= CNFG_BYTE_RW; -+ nfi_write16(nfc, NFI_CNFG, reg); -+ -+ nfi_write16(nfc, NFI_CON, CON_NFI_SEC_M | CON_NFI_BWR); -+ nfi_write16(nfc, NFI_STRDATA, STR_DATA); -+ } -+ -+ mt7621_nfc_wait_pio_ready(nfc); -+ nfi_write32(nfc, NFI_DATAW, val); -+} -+ -+static void mt7621_nfc_write_data(struct mt7621_nfc *nfc, const u8 *buf, -+ u32 len) -+{ -+ while (((uintptr_t)buf & 3) && len) { -+ mt7621_nfc_pio_write(nfc, *buf, true); -+ buf++; -+ len--; -+ } -+ -+ while (len >= 4) { -+ mt7621_nfc_pio_write(nfc, *(const u32 *)buf, false); -+ buf += 4; -+ len -= 4; -+ } -+ -+ while (len) { -+ mt7621_nfc_pio_write(nfc, *buf, true); -+ buf++; -+ len--; -+ } -+} -+ -+static void mt7621_nfc_write_data_empty(struct mt7621_nfc *nfc, u32 len) -+{ -+ while (len >= 4) { -+ mt7621_nfc_pio_write(nfc, 0xffffffff, false); -+ len -= 4; -+ } -+ -+ while (len) { -+ mt7621_nfc_pio_write(nfc, 0xff, true); -+ len--; -+ } -+} -+ -+static int mt7621_nfc_dev_ready(struct mt7621_nfc *nfc, -+ unsigned int timeout_ms) -+{ -+ u32 val; -+ -+ return readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val, -+ !(val & STA_BUSY), 10, -+ timeout_ms * 1000); -+} -+ -+static int mt7621_nfc_exec_instr(struct nand_chip *nand, -+ const struct nand_op_instr *instr) -+{ -+ struct mt7621_nfc *nfc = nand_get_controller_data(nand); -+ -+ switch (instr->type) { -+ case NAND_OP_CMD_INSTR: -+ mt7621_nfc_hw_reset(nfc); -+ nfi_write16(nfc, NFI_CNFG, CNFG_OP_CUSTOM << CNFG_OP_MODE_S); -+ return mt7621_nfc_send_command(nfc, instr->ctx.cmd.opcode); -+ case NAND_OP_ADDR_INSTR: -+ return mt7621_nfc_send_address(nfc, instr->ctx.addr.addrs, -+ instr->ctx.addr.naddrs); -+ case NAND_OP_DATA_IN_INSTR: -+ mt7621_nfc_read_data(nfc, instr->ctx.data.buf.in, -+ instr->ctx.data.len); -+ return 0; -+ case NAND_OP_DATA_OUT_INSTR: -+ mt7621_nfc_write_data(nfc, instr->ctx.data.buf.out, -+ instr->ctx.data.len); -+ return 0; -+ case NAND_OP_WAITRDY_INSTR: -+ return mt7621_nfc_dev_ready(nfc, -+ instr->ctx.waitrdy.timeout_ms); -+ default: -+ WARN_ONCE(1, "unsupported NAND instruction type: %d\n", -+ instr->type); -+ -+ return -EINVAL; -+ } -+} -+ -+static int mt7621_nfc_exec_op(struct nand_chip *nand, -+ const struct nand_operation *op, bool check_only) -+{ -+ struct mt7621_nfc *nfc = nand_get_controller_data(nand); -+ int i, ret; -+ -+ if (check_only) -+ return 0; -+ -+ /* Only CS0 available */ -+ nfi_write16(nfc, NFI_CSEL, 0); -+ -+ for (i = 0; i < op->ninstrs; i++) { -+ ret = mt7621_nfc_exec_instr(nand, &op->instrs[i]); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int mt7621_nfc_setup_data_interface(struct nand_chip *nand, int csline, -+ const struct nand_data_interface *conf) -+{ -+ struct mt7621_nfc *nfc = nand_get_controller_data(nand); -+ const struct nand_sdr_timings *timings; -+ u32 acccon, temp, rate, tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt; -+ -+ if (!nfc->nfi_clk) -+ return -ENOTSUPP; -+ -+ timings = nand_get_sdr_timings(conf); -+ if (IS_ERR(timings)) -+ return -ENOTSUPP; -+ -+ rate = clk_get_rate(nfc->nfi_clk); -+ -+ /* turn clock rate into KHZ */ -+ rate /= 1000; -+ -+ tpoecs = max(timings->tALH_min, timings->tCLH_min) / 1000; -+ tpoecs = DIV_ROUND_UP(tpoecs * rate, 1000000); -+ tpoecs = min_t(u32, tpoecs, ACCCON_POECS_MAX); -+ -+ tprecs = max(timings->tCLS_min, timings->tALS_min) / 1000; -+ tprecs = DIV_ROUND_UP(tprecs * rate, 1000000); -+ tprecs = min_t(u32, tprecs, ACCCON_PRECS_MAX); -+ -+ /* sdr interface has no tCR which means CE# low to RE# low */ -+ tc2r = 0; -+ -+ tw2r = timings->tWHR_min / 1000; -+ tw2r = DIV_ROUND_UP(tw2r * rate, 1000000); -+ tw2r = DIV_ROUND_UP(tw2r - 1, 2); -+ tw2r = min_t(u32, tw2r, ACCCON_W2R_MAX); -+ -+ twh = max(timings->tREH_min, timings->tWH_min) / 1000; -+ twh = DIV_ROUND_UP(twh * rate, 1000000) - 1; -+ twh = min_t(u32, twh, ACCCON_WH_MAX); -+ -+ /* Calculate real WE#/RE# hold time in nanosecond */ -+ temp = (twh + 1) * 1000000 / rate; -+ /* nanosecond to picosecond */ -+ temp *= 1000; -+ -+ /* -+ * WE# low level time should be expaned to meet WE# pulse time -+ * and WE# cycle time at the same time. -+ */ -+ if (temp < timings->tWC_min) -+ twst = timings->tWC_min - temp; -+ else -+ twst = 0; -+ twst = max(timings->tWP_min, twst) / 1000; -+ twst = DIV_ROUND_UP(twst * rate, 1000000) - 1; -+ twst = min_t(u32, twst, ACCCON_WST_MAX); -+ -+ /* -+ * RE# low level time should be expaned to meet RE# pulse time -+ * and RE# cycle time at the same time. -+ */ -+ if (temp < timings->tRC_min) -+ trlt = timings->tRC_min - temp; -+ else -+ trlt = 0; -+ trlt = max(trlt, timings->tRP_min) / 1000; -+ trlt = DIV_ROUND_UP(trlt * rate, 1000000) - 1; -+ trlt = min_t(u32, trlt, ACCCON_RLT_MAX); -+ -+ if (csline == NAND_DATA_IFACE_CHECK_ONLY) { -+ if (twst < ACCCON_WST_MIN || trlt < ACCCON_RLT_MIN) -+ return -ENOTSUPP; -+ } -+ -+ acccon = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt); -+ -+ dev_info(nfc->dev, "Using programmed access timing: %08x\n", acccon); -+ -+ nfi_write32(nfc, NFI_ACCCON, acccon); -+ -+ return 0; -+} -+ -+static int mt7621_nfc_calc_ecc_strength(struct mt7621_nfc *nfc, -+ u32 avail_ecc_bytes) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ struct mtd_info *mtd = nand_to_mtd(nand); -+ u32 strength; -+ int i; -+ -+ strength = avail_ecc_bytes * 8 / ECC_PARITY_BITS; -+ -+ /* Find the closest supported ecc strength */ -+ for (i = ARRAY_SIZE(mt7621_ecc_strength) - 1; i >= 0; i--) { -+ if (mt7621_ecc_strength[i] <= strength) -+ break; -+ } -+ -+ if (unlikely(i < 0)) { -+ dev_err(nfc->dev, "OOB size (%u) is not supported\n", -+ mtd->oobsize); -+ return -EINVAL; -+ } -+ -+ nand->ecc.strength = mt7621_ecc_strength[i]; -+ nand->ecc.bytes = -+ DIV_ROUND_UP(nand->ecc.strength * ECC_PARITY_BITS, 8); -+ -+ dev_info(nfc->dev, "ECC strength adjusted to %u bits\n", -+ nand->ecc.strength); -+ -+ return i; -+} -+ -+static int mt7621_nfc_set_spare_per_sector(struct mt7621_nfc *nfc) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ struct mtd_info *mtd = nand_to_mtd(nand); -+ u32 size; -+ int i; -+ -+ size = nand->ecc.bytes + NFI_FDM_SIZE; -+ -+ /* Find the closest supported spare size */ -+ for (i = 0; i < ARRAY_SIZE(mt7621_nfi_spare_size); i++) { -+ if (mt7621_nfi_spare_size[i] >= size) -+ break; -+ } -+ -+ if (unlikely(i >= ARRAY_SIZE(mt7621_nfi_spare_size))) { -+ dev_err(nfc->dev, "OOB size (%u) is not supported\n", -+ mtd->oobsize); -+ return -EINVAL; -+ } -+ -+ nfc->spare_per_sector = mt7621_nfi_spare_size[i]; -+ -+ return i; -+} -+ -+static int mt7621_nfc_ecc_init(struct mt7621_nfc *nfc) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ struct mtd_info *mtd = nand_to_mtd(nand); -+ u32 spare_per_sector, encode_block_size, decode_block_size; -+ u32 ecc_enccfg, ecc_deccfg; -+ int ecc_cap; -+ -+ /* Only hardware ECC mode is supported */ -+ if (nand->ecc.mode != NAND_ECC_HW_SYNDROME) { -+ dev_err(nfc->dev, "Only hardware ECC mode is supported\n"); -+ return -EINVAL; -+ } -+ -+ nand->ecc.size = ECC_SECTOR_SIZE; -+ nand->ecc.steps = mtd->writesize / nand->ecc.size; -+ -+ spare_per_sector = mtd->oobsize / nand->ecc.steps; -+ -+ ecc_cap = mt7621_nfc_calc_ecc_strength(nfc, -+ spare_per_sector - NFI_FDM_SIZE); -+ if (ecc_cap < 0) -+ return ecc_cap; -+ -+ /* Sector + FDM */ -+ encode_block_size = (nand->ecc.size + NFI_FDM_SIZE) * 8; -+ ecc_enccfg = ecc_cap | (ENC_MODE_NFI << ENC_MODE_S) | -+ (encode_block_size << ENC_CNFG_MSG_S); -+ -+ /* Sector + FDM + ECC parity bits */ -+ decode_block_size = ((nand->ecc.size + NFI_FDM_SIZE) * 8) + -+ nand->ecc.strength * ECC_PARITY_BITS; -+ ecc_deccfg = ecc_cap | (DEC_MODE_NFI << DEC_MODE_S) | -+ (decode_block_size << DEC_CS_S) | -+ (DEC_CON_EL << DEC_CON_S) | DEC_EMPTY_EN; -+ -+ mt7621_ecc_encoder_op(nfc, false); -+ ecc_write32(nfc, ECC_ENCCNFG, ecc_enccfg); -+ -+ mt7621_ecc_decoder_op(nfc, false); -+ ecc_write32(nfc, ECC_DECCNFG, ecc_deccfg); -+ -+ return 0; -+} -+ -+static int mt7621_nfc_set_page_format(struct mt7621_nfc *nfc) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ struct mtd_info *mtd = nand_to_mtd(nand); -+ int i, spare_size; -+ u32 pagefmt; -+ -+ spare_size = mt7621_nfc_set_spare_per_sector(nfc); -+ if (spare_size < 0) -+ return spare_size; -+ -+ for (i = 0; i < ARRAY_SIZE(mt7621_nfi_page_size); i++) { -+ if (mt7621_nfi_page_size[i] == mtd->writesize) -+ break; -+ } -+ -+ if (unlikely(i >= ARRAY_SIZE(mt7621_nfi_page_size))) { -+ dev_err(nfc->dev, "Page size (%u) is not supported\n", -+ mtd->writesize); -+ return -EINVAL; -+ } -+ -+ pagefmt = i | (spare_size << PAGEFMT_SPARE_S) | -+ (NFI_FDM_SIZE << PAGEFMT_FDM_S) | -+ (NFI_FDM_SIZE << PAGEFMT_FDM_ECC_S); -+ -+ nfi_write16(nfc, NFI_PAGEFMT, pagefmt); -+ -+ return 0; -+} -+ -+static int mt7621_nfc_attach_chip(struct nand_chip *nand) -+{ -+ struct mt7621_nfc *nfc = nand_get_controller_data(nand); -+ int ret; -+ -+ if (nand->options & NAND_BUSWIDTH_16) { -+ dev_err(nfc->dev, "16-bit buswidth is not supported"); -+ return -EINVAL; -+ } -+ -+ ret = mt7621_nfc_ecc_init(nfc); -+ if (ret) -+ return ret; -+ -+ return mt7621_nfc_set_page_format(nfc); -+} -+ -+static const struct nand_controller_ops mt7621_nfc_controller_ops = { -+ .attach_chip = mt7621_nfc_attach_chip, -+ .exec_op = mt7621_nfc_exec_op, -+ .setup_data_interface = mt7621_nfc_setup_data_interface, -+}; -+ -+static int mt7621_nfc_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oob_region) -+{ -+ struct nand_chip *nand = mtd_to_nand(mtd); -+ -+ if (section >= nand->ecc.steps) -+ return -ERANGE; -+ -+ oob_region->length = NFI_FDM_SIZE - 1; -+ oob_region->offset = section * NFI_FDM_SIZE + 1; -+ -+ return 0; -+} -+ -+static int mt7621_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oob_region) -+{ -+ struct nand_chip *nand = mtd_to_nand(mtd); -+ -+ if (section) -+ return -ERANGE; -+ -+ oob_region->offset = NFI_FDM_SIZE * nand->ecc.steps; -+ oob_region->length = mtd->oobsize - oob_region->offset; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops mt7621_nfc_ooblayout_ops = { -+ .free = mt7621_nfc_ooblayout_free, -+ .ecc = mt7621_nfc_ooblayout_ecc, -+}; -+ -+static void mt7621_nfc_write_fdm(struct mt7621_nfc *nfc) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ u32 vall, valm; -+ u8 *oobptr; -+ int i, j; -+ -+ for (i = 0; i < nand->ecc.steps; i++) { -+ vall = 0; -+ valm = 0; -+ oobptr = oob_fdm_ptr(nand, i); -+ -+ for (j = 0; j < 4; j++) -+ vall |= (u32)oobptr[j] << (j * 8); -+ -+ for (j = 0; j < 4; j++) -+ valm |= (u32)oobptr[j + 4] << ((j - 4) * 8); -+ -+ nfi_write32(nfc, NFI_FDML(i), vall); -+ nfi_write32(nfc, NFI_FDMM(i), valm); -+ } -+} -+ -+static void mt7621_nfc_read_sector_fdm(struct mt7621_nfc *nfc, u32 sect) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ u32 vall, valm; -+ u8 *oobptr; -+ int i; -+ -+ vall = nfi_read32(nfc, NFI_FDML(sect)); -+ valm = nfi_read32(nfc, NFI_FDMM(sect)); -+ oobptr = oob_fdm_ptr(nand, sect); -+ -+ for (i = 0; i < 4; i++) -+ oobptr[i] = (vall >> (i * 8)) & 0xff; -+ -+ for (i = 0; i < 4; i++) -+ oobptr[i + 4] = (valm >> (i * 8)) & 0xff; -+} -+ -+static int mt7621_nfc_read_page_hwecc(struct nand_chip *nand, uint8_t *buf, -+ int oob_required, int page) -+{ -+ struct mt7621_nfc *nfc = nand_get_controller_data(nand); -+ struct mtd_info *mtd = nand_to_mtd(nand); -+ int bitflips = 0; -+ int rc, i; -+ -+ nand_read_page_op(nand, page, 0, NULL, 0); -+ -+ nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) | -+ CNFG_READ_MODE | CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); -+ -+ mt7621_ecc_decoder_op(nfc, true); -+ -+ nfi_write16(nfc, NFI_CON, -+ CON_NFI_BRD | (nand->ecc.steps << CON_NFI_SEC_S)); -+ -+ for (i = 0; i < nand->ecc.steps; i++) { -+ if (buf) -+ mt7621_nfc_read_data(nfc, page_data_ptr(nand, buf, i), -+ nand->ecc.size); -+ else -+ mt7621_nfc_read_data_discard(nfc, nand->ecc.size); -+ -+ rc = mt7621_ecc_decoder_wait_done(nfc, i); -+ -+ mt7621_nfc_read_sector_fdm(nfc, i); -+ -+ if (rc < 0) { -+ bitflips = -EIO; -+ continue; -+ } -+ -+ rc = mt7621_ecc_correct_check(nfc, -+ buf ? page_data_ptr(nand, buf, i) : NULL, -+ oob_fdm_ptr(nand, i), i); -+ -+ if (rc < 0) { -+ dev_warn(nfc->dev, -+ "Uncorrectable ECC error at page %d.%d\n", -+ page, i); -+ bitflips = -EBADMSG; -+ mtd->ecc_stats.failed++; -+ } else if (bitflips >= 0) { -+ bitflips += rc; -+ mtd->ecc_stats.corrected += rc; -+ } -+ } -+ -+ mt7621_ecc_decoder_op(nfc, false); -+ -+ nfi_write16(nfc, NFI_CON, 0); -+ -+ return bitflips; -+} -+ -+static int mt7621_nfc_read_page_raw(struct nand_chip *nand, uint8_t *buf, -+ int oob_required, int page) -+{ -+ struct mt7621_nfc *nfc = nand_get_controller_data(nand); -+ int i; -+ -+ nand_read_page_op(nand, page, 0, NULL, 0); -+ -+ nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) | -+ CNFG_READ_MODE); -+ -+ nfi_write16(nfc, NFI_CON, -+ CON_NFI_BRD | (nand->ecc.steps << CON_NFI_SEC_S)); -+ -+ for (i = 0; i < nand->ecc.steps; i++) { -+ /* Read data */ -+ if (buf) -+ mt7621_nfc_read_data(nfc, page_data_ptr(nand, buf, i), -+ nand->ecc.size); -+ else -+ mt7621_nfc_read_data_discard(nfc, nand->ecc.size); -+ -+ /* Read FDM */ -+ mt7621_nfc_read_data(nfc, oob_fdm_ptr(nand, i), NFI_FDM_SIZE); -+ -+ /* Read ECC parity data */ -+ mt7621_nfc_read_data(nfc, oob_ecc_ptr(nfc, i), -+ nfc->spare_per_sector - NFI_FDM_SIZE); -+ } -+ -+ nfi_write16(nfc, NFI_CON, 0); -+ -+ return 0; -+} -+ -+static int mt7621_nfc_read_oob_hwecc(struct nand_chip *nand, int page) -+{ -+ return mt7621_nfc_read_page_hwecc(nand, NULL, 1, page); -+} -+ -+static int mt7621_nfc_read_oob_raw(struct nand_chip *nand, int page) -+{ -+ return mt7621_nfc_read_page_raw(nand, NULL, 1, page); -+} -+ -+static int mt7621_nfc_check_empty_page(struct nand_chip *nand, const u8 *buf) -+{ -+ struct mtd_info *mtd = nand_to_mtd(nand); -+ uint32_t i, j; -+ u8 *oobptr; -+ -+ if (buf) { -+ for (i = 0; i < mtd->writesize; i++) -+ if (buf[i] != 0xff) -+ return 0; -+ } -+ -+ for (i = 0; i < nand->ecc.steps; i++) { -+ oobptr = oob_fdm_ptr(nand, i); -+ for (j = 0; j < NFI_FDM_SIZE; j++) -+ if (oobptr[j] != 0xff) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int mt7621_nfc_write_page_hwecc(struct nand_chip *nand, -+ const uint8_t *buf, int oob_required, -+ int page) -+{ -+ struct mt7621_nfc *nfc = nand_get_controller_data(nand); -+ struct mtd_info *mtd = nand_to_mtd(nand); -+ -+ if (mt7621_nfc_check_empty_page(nand, buf)) { -+ /* -+ * MT7621 ECC engine always generates parity code for input -+ * pages, even for empty pages. Doing so will write back ECC -+ * parity code to the oob region, which means such pages will -+ * no longer be empty pages. -+ * -+ * To avoid this, stop write operation if current page is an -+ * empty page. -+ */ -+ return 0; -+ } -+ -+ nand_prog_page_begin_op(nand, page, 0, NULL, 0); -+ -+ nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) | -+ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); -+ -+ mt7621_ecc_encoder_op(nfc, true); -+ -+ mt7621_nfc_write_fdm(nfc); -+ -+ nfi_write16(nfc, NFI_CON, -+ CON_NFI_BWR | (nand->ecc.steps << CON_NFI_SEC_S)); -+ -+ if (buf) -+ mt7621_nfc_write_data(nfc, buf, mtd->writesize); -+ else -+ mt7621_nfc_write_data_empty(nfc, mtd->writesize); -+ -+ mt7621_nfc_wait_write_completion(nfc, nand); -+ -+ mt7621_ecc_encoder_op(nfc, false); -+ -+ nfi_write16(nfc, NFI_CON, 0); -+ -+ return nand_prog_page_end_op(nand); -+} -+ -+static int mt7621_nfc_write_page_raw(struct nand_chip *nand, -+ const uint8_t *buf, int oob_required, -+ int page) -+{ -+ struct mt7621_nfc *nfc = nand_get_controller_data(nand); -+ int i; -+ -+ nand_prog_page_begin_op(nand, page, 0, NULL, 0); -+ -+ nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S)); -+ -+ nfi_write16(nfc, NFI_CON, -+ CON_NFI_BWR | (nand->ecc.steps << CON_NFI_SEC_S)); -+ -+ for (i = 0; i < nand->ecc.steps; i++) { -+ /* Write data */ -+ if (buf) -+ mt7621_nfc_write_data(nfc, page_data_ptr(nand, buf, i), -+ nand->ecc.size); -+ else -+ mt7621_nfc_write_data_empty(nfc, nand->ecc.size); -+ -+ /* Write FDM */ -+ mt7621_nfc_write_data(nfc, oob_fdm_ptr(nand, i), -+ NFI_FDM_SIZE); -+ -+ /* Write dummy ECC parity data */ -+ mt7621_nfc_write_data_empty(nfc, nfc->spare_per_sector - -+ NFI_FDM_SIZE); -+ } -+ -+ mt7621_nfc_wait_write_completion(nfc, nand); -+ -+ nfi_write16(nfc, NFI_CON, 0); -+ -+ return nand_prog_page_end_op(nand); -+} -+ -+static int mt7621_nfc_write_oob_hwecc(struct nand_chip *nand, int page) -+{ -+ return mt7621_nfc_write_page_hwecc(nand, NULL, 1, page); -+} -+ -+static int mt7621_nfc_write_oob_raw(struct nand_chip *nand, int page) -+{ -+ return mt7621_nfc_write_page_raw(nand, NULL, 1, page); -+} -+ -+static int mt7621_nfc_init_chip(struct mt7621_nfc *nfc) -+{ -+ struct nand_chip *nand = &nfc->nand; -+ struct mtd_info *mtd; -+ int ret; -+ -+ nand->controller = &nfc->controller; -+ nand_set_controller_data(nand, (void *)nfc); -+ nand_set_flash_node(nand, nfc->dev->of_node); -+ -+ nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_NO_SUBPAGE_WRITE; -+ if (!nfc->nfi_clk) -+ nand->options |= NAND_KEEP_TIMINGS; -+ -+ nand->ecc.mode = NAND_ECC_HW_SYNDROME; -+ nand->ecc.read_page = mt7621_nfc_read_page_hwecc; -+ nand->ecc.read_page_raw = mt7621_nfc_read_page_raw; -+ nand->ecc.write_page = mt7621_nfc_write_page_hwecc; -+ nand->ecc.write_page_raw = mt7621_nfc_write_page_raw; -+ nand->ecc.read_oob = mt7621_nfc_read_oob_hwecc; -+ nand->ecc.read_oob_raw = mt7621_nfc_read_oob_raw; -+ nand->ecc.write_oob = mt7621_nfc_write_oob_hwecc; -+ nand->ecc.write_oob_raw = mt7621_nfc_write_oob_raw; -+ -+ mtd = nand_to_mtd(nand); -+ mtd->owner = THIS_MODULE; -+ mtd->dev.parent = nfc->dev; -+ mtd->name = MT7621_NFC_NAME; -+ mtd_set_ooblayout(mtd, &mt7621_nfc_ooblayout_ops); -+ -+ mt7621_nfc_hw_init(nfc); -+ -+ ret = nand_scan(nand, 1); -+ if (ret) -+ return ret; -+ -+ ret = mtd_device_register(mtd, NULL, 0); -+ if (ret) { -+ dev_err(nfc->dev, "Failed to register MTD: %d\n", ret); -+ nand_release(nand); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int mt7621_nfc_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct mt7621_nfc *nfc; -+ struct resource *res; -+ int ret; -+ -+ nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); -+ if (!nfc) -+ return -ENOMEM; -+ -+ nand_controller_init(&nfc->controller); -+ nfc->controller.ops = &mt7621_nfc_controller_ops; -+ nfc->dev = dev; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nfi"); -+ nfc->nfi_regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(nfc->nfi_regs)) { -+ ret = PTR_ERR(nfc->nfi_regs); -+ return ret; -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecc"); -+ nfc->ecc_regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(nfc->ecc_regs)) { -+ ret = PTR_ERR(nfc->ecc_regs); -+ return ret; -+ } -+ -+ nfc->nfi_clk = devm_clk_get(dev, "nfi_clk"); -+ if (IS_ERR(nfc->nfi_clk)) { -+ dev_warn(dev, "nfi clk not provided\n"); -+ nfc->nfi_clk = NULL; -+ } else { -+ ret = clk_prepare_enable(nfc->nfi_clk); -+ if (ret) { -+ dev_err(dev, "Failed to enable nfi core clock\n"); -+ return ret; -+ } -+ } -+ -+ platform_set_drvdata(pdev, nfc); -+ -+ ret = mt7621_nfc_init_chip(nfc); -+ if (ret) { -+ dev_err(dev, "Failed to initialize nand chip\n"); -+ goto clk_disable; -+ } -+ -+ return 0; -+ -+clk_disable: -+ clk_disable_unprepare(nfc->nfi_clk); -+ -+ return ret; -+} -+ -+static int mt7621_nfc_remove(struct platform_device *pdev) -+{ -+ struct mt7621_nfc *nfc = platform_get_drvdata(pdev); -+ -+ nand_release(&nfc->nand); -+ clk_disable_unprepare(nfc->nfi_clk); -+ -+ return 0; -+} -+ -+static const struct of_device_id mt7621_nfc_id_table[] = { -+ { .compatible = "mediatek,mt7621-nfc" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, match); -+ -+static struct platform_driver mt7621_nfc_driver = { -+ .probe = mt7621_nfc_probe, -+ .remove = mt7621_nfc_remove, -+ .driver = { -+ .name = MT7621_NFC_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = mt7621_nfc_id_table, -+ }, -+}; -+module_platform_driver(mt7621_nfc_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Weijie Gao <weijie.gao@mediatek.com>"); -+MODULE_DESCRIPTION("MediaTek MT7621 NAND Flash Controller driver"); diff --git a/target/linux/ramips/patches-5.4/0301-dt-bindings-add-documentation-for-mt7621-nand-driver.patch b/target/linux/ramips/patches-5.4/0301-dt-bindings-add-documentation-for-mt7621-nand-driver.patch deleted file mode 100644 index 3d122c10c0..0000000000 --- a/target/linux/ramips/patches-5.4/0301-dt-bindings-add-documentation-for-mt7621-nand-driver.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 3d5f4da8296b23eb3abf8b13122b0d06a215e79c Mon Sep 17 00:00:00 2001 -From: Weijie Gao <weijie.gao@mediatek.com> -Date: Wed, 1 Apr 2020 02:07:59 +0800 -Subject: [PATCH 2/2] dt-bindings: add documentation for mt7621-nand driver - -This patch adds documentation for MediaTek MT7621 NAND flash controller -driver. - -Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> ---- - .../bindings/mtd/mediatek,mt7621-nfc.yaml | 68 ++++++++++++++++++++++ - 1 file changed, 68 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml -@@ -0,0 +1,68 @@ -+# SPDX-License-Identifier: GPL-2.0 -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/mtd/mediatek,mt7621-nfc.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: MediaTek MT7621 SoC NAND Flash Controller (NFC) DT binding -+ -+maintainers: -+ - Weijie Gao <weijie.gao@mediatek.com> -+ -+description: | -+ This driver uses a single node to describe both NAND Flash controller -+ interface (NFI) and ECC engine for MT7621 SoC. -+ MT7621 supports only one chip select. -+ -+properties: -+ "#address-cells": false -+ "#size-cells": false -+ -+ compatible: -+ enum: -+ - mediatek,mt7621-nfc -+ -+ reg: -+ items: -+ - description: Register base of NFI core -+ - description: Register base of ECC engine -+ -+ reg-names: -+ items: -+ - const: nfi -+ - const: ecc -+ -+ clocks: -+ items: -+ - description: Source clock for NFI core, fixed 125MHz -+ -+ clock-names: -+ items: -+ - const: nfi_clk -+ -+required: -+ - compatible -+ - reg -+ - reg-names -+ - clocks -+ - clock-names -+ -+examples: -+ - | -+ nficlock: nficlock { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ -+ clock-frequency = <125000000>; -+ }; -+ -+ nand@1e003000 { -+ compatible = "mediatek,mt7621-nfc"; -+ -+ reg = <0x1e003000 0x800 -+ 0x1e003800 0x800>; -+ reg-names = "nfi", "ecc"; -+ -+ clocks = <&nficlock>; -+ clock-names = "nfi_clk"; -+ }; diff --git a/target/linux/ramips/patches-5.4/100-mt7621-core-detect-hack.patch b/target/linux/ramips/patches-5.4/100-mt7621-core-detect-hack.patch deleted file mode 100644 index 1c8b61f8ef..0000000000 --- a/target/linux/ramips/patches-5.4/100-mt7621-core-detect-hack.patch +++ /dev/null @@ -1,61 +0,0 @@ -There is a variant of MT7621 which contains only one CPU core instead of 2. -This is not reflected in the config register, so the kernel detects more -physical cores, which leads to a hang on SMP bringup. -Add a hack to detect missing cores. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> - ---- a/arch/mips/kernel/smp-cps.c -+++ b/arch/mips/kernel/smp-cps.c -@@ -43,6 +43,11 @@ static unsigned core_vpe_count(unsigned - return mips_cps_numvps(cluster, core); - } - -+bool __weak plat_cpu_core_present(int core) -+{ -+ return true; -+} -+ - static void __init cps_smp_setup(void) - { - unsigned int nclusters, ncores, nvpes, core_vpes; -@@ -60,6 +65,8 @@ static void __init cps_smp_setup(void) - - ncores = mips_cps_numcores(cl); - for (c = 0; c < ncores; c++) { -+ if (!plat_cpu_core_present(c)) -+ continue; - core_vpes = core_vpe_count(cl, c); - - if (c > 0) ---- a/arch/mips/ralink/mt7621.c -+++ b/arch/mips/ralink/mt7621.c -@@ -13,6 +13,7 @@ - #include <asm/mips-cps.h> - #include <asm/mach-ralink/ralink_regs.h> - #include <asm/mach-ralink/mt7621.h> -+#include <asm/mips-boards/launch.h> - - #include <pinmux.h> - -@@ -160,6 +161,20 @@ void __init ralink_of_remap(void) - panic("Failed to remap core resources"); - } - -+bool plat_cpu_core_present(int core) -+{ -+ struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); -+ -+ if (!core) -+ return true; -+ launch += core * 2; /* 2 VPEs per core */ -+ if (!(launch->flags & LAUNCH_FREADY)) -+ return false; -+ if (launch->flags & (LAUNCH_FGO | LAUNCH_FGONE)) -+ return false; -+ return true; -+} -+ - void prom_soc_init(struct ralink_soc_info *soc_info) - { - void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE); diff --git a/target/linux/ramips/patches-5.4/101-mt7621-timer.patch b/target/linux/ramips/patches-5.4/101-mt7621-timer.patch deleted file mode 100644 index 8528b71c88..0000000000 --- a/target/linux/ramips/patches-5.4/101-mt7621-timer.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- a/arch/mips/ralink/mt7621.c -+++ b/arch/mips/ralink/mt7621.c -@@ -7,6 +7,7 @@ - - #include <linux/kernel.h> - #include <linux/init.h> -+#include <linux/jiffies.h> - - #include <asm/mipsregs.h> - #include <asm/smp-ops.h> -@@ -14,6 +15,7 @@ - #include <asm/mach-ralink/ralink_regs.h> - #include <asm/mach-ralink/mt7621.h> - #include <asm/mips-boards/launch.h> -+#include <asm/delay.h> - - #include <pinmux.h> - -@@ -175,6 +177,58 @@ bool plat_cpu_core_present(int core) - return true; - } - -+#define LPS_PREC 8 -+/* -+* Re-calibration lpj(loop-per-jiffy). -+* (derived from kernel/calibrate.c) -+*/ -+static int udelay_recal(void) -+{ -+ unsigned int i, lpj = 0; -+ unsigned long ticks, loopbit; -+ int lps_precision = LPS_PREC; -+ -+ lpj = (1<<12); -+ -+ while ((lpj <<= 1) != 0) { -+ /* wait for "start of" clock tick */ -+ ticks = jiffies; -+ while (ticks == jiffies) -+ /* nothing */; -+ -+ /* Go .. */ -+ ticks = jiffies; -+ __delay(lpj); -+ ticks = jiffies - ticks; -+ if (ticks) -+ break; -+ } -+ -+ /* -+ * Do a binary approximation to get lpj set to -+ * equal one clock (up to lps_precision bits) -+ */ -+ lpj >>= 1; -+ loopbit = lpj; -+ while (lps_precision-- && (loopbit >>= 1)) { -+ lpj |= loopbit; -+ ticks = jiffies; -+ while (ticks == jiffies) -+ /* nothing */; -+ ticks = jiffies; -+ __delay(lpj); -+ if (jiffies != ticks) /* longer than 1 tick */ -+ lpj &= ~loopbit; -+ } -+ printk(KERN_INFO "%d CPUs re-calibrate udelay(lpj = %d)\n", NR_CPUS, lpj); -+ -+ for(i=0; i< NR_CPUS; i++) -+ cpu_data[i].udelay_val = lpj; -+ -+ return 0; -+} -+device_initcall(udelay_recal); -+ - void prom_soc_init(struct ralink_soc_info *soc_info) - { - void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE); ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -58,6 +58,7 @@ choice - select CLKSRC_MIPS_GIC - select HAVE_PCI if PCI_MT7621 - select WEAK_REORDERING_BEYOND_LLSC -+ select GENERIC_CLOCKEVENTS_BROADCAST - endchoice - - choice diff --git a/target/linux/ramips/patches-5.4/102-mt7621-fix-cpu-clk-add-clkdev.patch b/target/linux/ramips/patches-5.4/102-mt7621-fix-cpu-clk-add-clkdev.patch deleted file mode 100644 index 0c997a3f28..0000000000 --- a/target/linux/ramips/patches-5.4/102-mt7621-fix-cpu-clk-add-clkdev.patch +++ /dev/null @@ -1,224 +0,0 @@ ---- a/arch/mips/include/asm/mach-ralink/mt7621.h -+++ b/arch/mips/include/asm/mach-ralink/mt7621.h -@@ -17,6 +17,10 @@ - #define SYSC_REG_CHIP_REV 0x0c - #define SYSC_REG_SYSTEM_CONFIG0 0x10 - #define SYSC_REG_SYSTEM_CONFIG1 0x14 -+#define SYSC_REG_CLKCFG0 0x2c -+#define SYSC_REG_CUR_CLK_STS 0x44 -+ -+#define MEMC_REG_CPU_PLL 0x648 - - #define CHIP_REV_PKG_MASK 0x1 - #define CHIP_REV_PKG_SHIFT 16 -@@ -24,6 +28,22 @@ - #define CHIP_REV_VER_SHIFT 8 - #define CHIP_REV_ECO_MASK 0xf - -+#define XTAL_MODE_SEL_MASK 0x7 -+#define XTAL_MODE_SEL_SHIFT 6 -+ -+#define CPU_CLK_SEL_MASK 0x3 -+#define CPU_CLK_SEL_SHIFT 30 -+ -+#define CUR_CPU_FDIV_MASK 0x1f -+#define CUR_CPU_FDIV_SHIFT 8 -+#define CUR_CPU_FFRAC_MASK 0x1f -+#define CUR_CPU_FFRAC_SHIFT 0 -+ -+#define CPU_PLL_PREDIV_MASK 0x3 -+#define CPU_PLL_PREDIV_SHIFT 12 -+#define CPU_PLL_FBDIV_MASK 0x7f -+#define CPU_PLL_FBDIV_SHIFT 4 -+ - #define MT7621_DRAM_BASE 0x0 - #define MT7621_DDR2_SIZE_MIN 32 - #define MT7621_DDR2_SIZE_MAX 256 ---- a/arch/mips/ralink/mt7621.c -+++ b/arch/mips/ralink/mt7621.c -@@ -8,6 +8,10 @@ - #include <linux/kernel.h> - #include <linux/init.h> - #include <linux/jiffies.h> -+#include <linux/clk.h> -+#include <linux/clkdev.h> -+#include <linux/clk-provider.h> -+#include <dt-bindings/clock/mt7621-clk.h> - - #include <asm/mipsregs.h> - #include <asm/smp-ops.h> -@@ -16,16 +20,12 @@ - #include <asm/mach-ralink/mt7621.h> - #include <asm/mips-boards/launch.h> - #include <asm/delay.h> -+#include <asm/time.h> - - #include <pinmux.h> - - #include "common.h" - --#define SYSC_REG_SYSCFG 0x10 --#define SYSC_REG_CPLL_CLKCFG0 0x2c --#define SYSC_REG_CUR_CLK_STS 0x44 --#define CPU_CLK_SEL (BIT(30) | BIT(31)) -- - #define MT7621_GPIO_MODE_UART1 1 - #define MT7621_GPIO_MODE_I2C 2 - #define MT7621_GPIO_MODE_UART3_MASK 0x3 -@@ -111,49 +111,89 @@ static struct rt2880_pmx_group mt7621_pi - { 0 } - }; - -+static struct clk *clks[MT7621_CLK_MAX]; -+static struct clk_onecell_data clk_data = { -+ .clks = clks, -+ .clk_num = ARRAY_SIZE(clks), -+}; -+ - phys_addr_t mips_cpc_default_phys_base(void) - { - panic("Cannot detect cpc address"); - } - --void __init ralink_clk_init(void) -+static struct clk *__init mt7621_add_sys_clkdev( -+ const char *id, unsigned long rate) - { -- int cpu_fdiv = 0; -- int cpu_ffrac = 0; -- int fbdiv = 0; -- u32 clk_sts, syscfg; -- u8 clk_sel = 0, xtal_mode; -- u32 cpu_clk; -+ struct clk *clk; -+ int err; -+ -+ clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate); -+ if (IS_ERR(clk)) -+ panic("failed to allocate %s clock structure", id); -+ -+ err = clk_register_clkdev(clk, id, NULL); -+ if (err) -+ panic("unable to register %s clock device", id); - -- if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0) -- clk_sel = 1; -+ return clk; -+} -+ -+void __init ralink_clk_init(void) -+{ -+ u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac; -+ u32 pll, prediv, fbdiv; -+ u32 xtal_clk, cpu_clk, bus_clk; -+ const static u32 prediv_tbl[] = {0, 1, 2, 2}; -+ -+ syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); -+ xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK; -+ -+ clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0); -+ clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK; -+ -+ curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS); -+ ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK; -+ ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK; -+ -+ if (xtal_sel <= 2) -+ xtal_clk = 20 * 1000 * 1000; -+ else if (xtal_sel <= 5) -+ xtal_clk = 40 * 1000 * 1000; -+ else -+ xtal_clk = 25 * 1000 * 1000; - - switch (clk_sel) { - case 0: -- clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS); -- cpu_fdiv = ((clk_sts >> 8) & 0x1F); -- cpu_ffrac = (clk_sts & 0x1F); -- cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000; -+ cpu_clk = 500 * 1000 * 1000; - break; -- - case 1: -- fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1; -- syscfg = rt_sysc_r32(SYSC_REG_SYSCFG); -- xtal_mode = (syscfg >> 6) & 0x7; -- if (xtal_mode >= 6) { -- /* 25Mhz Xtal */ -- cpu_clk = 25 * fbdiv * 1000 * 1000; -- } else if (xtal_mode >= 3) { -- /* 40Mhz Xtal */ -- cpu_clk = 40 * fbdiv * 1000 * 1000; -- } else { -- /* 20Mhz Xtal */ -- cpu_clk = 20 * fbdiv * 1000 * 1000; -- } -+ pll = rt_memc_r32(MEMC_REG_CPU_PLL); -+ fbdiv = (pll >> CPU_PLL_FBDIV_SHIFT) & CPU_PLL_FBDIV_MASK; -+ prediv = (pll >> CPU_PLL_PREDIV_SHIFT) & CPU_PLL_PREDIV_MASK; -+ cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv]; - break; -+ default: -+ cpu_clk = xtal_clk; - } -+ -+ cpu_clk = cpu_clk / ffiv * ffrac; -+ bus_clk = cpu_clk / 4; -+ -+ clks[MT7621_CLK_CPU] = mt7621_add_sys_clkdev("cpu", cpu_clk); -+ clks[MT7621_CLK_BUS] = mt7621_add_sys_clkdev("bus", bus_clk); -+ -+ pr_info("CPU Clock: %dMHz\n", cpu_clk / 1000000); -+ mips_hpt_frequency = cpu_clk / 2; - } - -+static void __init mt7621_clocks_init_dt(struct device_node *np) -+{ -+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -+} -+ -+CLK_OF_DECLARE(ar7100, "mediatek,mt7621-pll", mt7621_clocks_init_dt); -+ - void __init ralink_of_remap(void) - { - rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc"); ---- a/arch/mips/ralink/timer-gic.c -+++ b/arch/mips/ralink/timer-gic.c -@@ -9,14 +9,14 @@ - - #include <linux/of.h> - #include <linux/clk-provider.h> --#include <linux/clocksource.h> -+#include <asm/time.h> - - #include "common.h" - - void __init plat_time_init(void) - { - ralink_of_remap(); -- -+ ralink_clk_init(); - of_clk_init(NULL); - timer_probe(); - } ---- /dev/null -+++ b/include/dt-bindings/clock/mt7621-clk.h -@@ -0,0 +1,18 @@ -+/* -+ * Copyright (C) 2018 Weijie Gao <hackpascal@gmail.com> -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __DT_BINDINGS_MT7621_CLK_H -+#define __DT_BINDINGS_MT7621_CLK_H -+ -+#define MT7621_CLK_CPU 0 -+#define MT7621_CLK_BUS 1 -+ -+#define MT7621_CLK_MAX 2 -+ -+#endif /* __DT_BINDINGS_MT7621_CLK_H */ diff --git a/target/linux/ramips/patches-5.4/105-mt7621-memory-detect.patch b/target/linux/ramips/patches-5.4/105-mt7621-memory-detect.patch deleted file mode 100644 index 277d2aa43c..0000000000 --- a/target/linux/ramips/patches-5.4/105-mt7621-memory-detect.patch +++ /dev/null @@ -1,125 +0,0 @@ -From b5a52351a66f3c2a7a207548aa87d78ff2d336c0 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo <gch981213@gmail.com> -Date: Wed, 10 Jul 2019 00:24:48 +0800 -Subject: [PATCH] MIPS: ralink: mt7621: add memory detection support - -mt7621 has the following memory map: -0x0-0x1c000000: lower 448m memory -0x1c000000-0x2000000: peripheral registers -0x20000000-0x2400000: higher 64m memory - -detect_memory_region in arch/mips/kernel/setup.c only add the first -memory region and isn't suitable for 512m memory detection because -it may accidentally read the memory area for peripheral registers. - -This commit adds memory detection capability for mt7621: -1. add the highmem area when 512m is detected. -2. guard memcmp from accessing peripheral registers: - This only happens when some weird user decided to change - kernel load address to 256m or higher address. Since this - is a quite unusual case, we just skip 512m testing and return - 256m as memory size. - -Signed-off-by: Chuanhong Guo <gch981213@gmail.com> ---- - arch/mips/include/asm/mach-ralink/mt7621.h | 7 ++--- - arch/mips/ralink/mt7621.c | 30 +++++++++++++++++++--- - 2 files changed, 30 insertions(+), 7 deletions(-) - ---- a/arch/mips/include/asm/mach-ralink/mt7621.h -+++ b/arch/mips/include/asm/mach-ralink/mt7621.h -@@ -44,9 +44,10 @@ - #define CPU_PLL_FBDIV_MASK 0x7f - #define CPU_PLL_FBDIV_SHIFT 4 - --#define MT7621_DRAM_BASE 0x0 --#define MT7621_DDR2_SIZE_MIN 32 --#define MT7621_DDR2_SIZE_MAX 256 -+#define MT7621_LOWMEM_BASE 0x0 -+#define MT7621_LOWMEM_MAX_SIZE 0x1C000000 -+#define MT7621_HIGHMEM_BASE 0x20000000 -+#define MT7621_HIGHMEM_SIZE 0x4000000 - - #define MT7621_CHIP_NAME0 0x3637544D - #define MT7621_CHIP_NAME1 0x20203132 ---- a/arch/mips/ralink/mt7621.c -+++ b/arch/mips/ralink/mt7621.c -@@ -13,6 +13,7 @@ - #include <linux/clk-provider.h> - #include <dt-bindings/clock/mt7621-clk.h> - -+#include <asm/bootinfo.h> - #include <asm/mipsregs.h> - #include <asm/smp-ops.h> - #include <asm/mips-cps.h> -@@ -55,6 +56,8 @@ - #define MT7621_GPIO_MODE_SDHCI_SHIFT 18 - #define MT7621_GPIO_MODE_SDHCI_GPIO 1 - -+static void *detect_magic __initdata = detect_memory_region; -+ - static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) }; - static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) }; - static struct rt2880_pmx_func uart3_grp[] = { -@@ -139,6 +142,28 @@ static struct clk *__init mt7621_add_sys - return clk; - } - -+void __init mt7621_memory_detect(void) -+{ -+ void *dm = &detect_magic; -+ phys_addr_t size; -+ -+ for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) { -+ if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic))) -+ break; -+ } -+ -+ if ((size == 256 * SZ_1M) && -+ (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) && -+ __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) { -+ add_memory_region(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE, -+ BOOT_MEM_RAM); -+ add_memory_region(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE, -+ BOOT_MEM_RAM); -+ } else { -+ add_memory_region(MT7621_LOWMEM_BASE, size, BOOT_MEM_RAM); -+ } -+} -+ - void __init ralink_clk_init(void) - { - u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac; -@@ -317,10 +342,7 @@ void prom_soc_init(struct ralink_soc_inf - (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK, - (rev & CHIP_REV_ECO_MASK)); - -- soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN; -- soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX; -- soc_info->mem_base = MT7621_DRAM_BASE; -- -+ soc_info->mem_detect = mt7621_memory_detect; - rt2880_pinmux_data = mt7621_pinmux_data; - - ---- a/arch/mips/ralink/common.h -+++ b/arch/mips/ralink/common.h -@@ -17,6 +17,7 @@ struct ralink_soc_info { - unsigned long mem_size; - unsigned long mem_size_min; - unsigned long mem_size_max; -+ void (*mem_detect)(void); - }; - extern struct ralink_soc_info soc_info; - ---- a/arch/mips/ralink/of.c -+++ b/arch/mips/ralink/of.c -@@ -87,6 +87,8 @@ void __init plat_mem_setup(void) - of_scan_flat_dt(early_init_dt_find_memory, NULL); - if (memory_dtb) - of_scan_flat_dt(early_init_dt_scan_memory, NULL); -+ else if (soc_info.mem_detect) -+ soc_info.mem_detect(); - else if (soc_info.mem_size) - add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, - BOOT_MEM_RAM); diff --git a/target/linux/ramips/patches-5.4/110-mt7621-perfctr-fix.patch b/target/linux/ramips/patches-5.4/110-mt7621-perfctr-fix.patch deleted file mode 100644 index dfeac7eb99..0000000000 --- a/target/linux/ramips/patches-5.4/110-mt7621-perfctr-fix.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/arch/mips/ralink/irq-gic.c -+++ b/arch/mips/ralink/irq-gic.c -@@ -13,6 +13,12 @@ - - int get_c0_perfcount_int(void) - { -+ /* -+ * Performance counter events are routed through GIC. -+ * Prevent them from firing on CPU IRQ7 as well -+ */ -+ clear_c0_status(IE_SW0 << 7); -+ - return gic_get_c0_perfcount_int(); - } - EXPORT_SYMBOL_GPL(get_c0_perfcount_int); diff --git a/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch b/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch deleted file mode 100644 index fdb89d0902..0000000000 --- a/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 5d7b644aad721ecca20bd8976b38fb243fdc84f9 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo <gch981213@gmail.com> -Date: Sun, 15 Mar 2020 20:13:37 +0800 -Subject: [PATCH] gpio: mmio: introduce BGPIOF_NO_SET_ON_INPUT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some gpio controllers ignores pin value writing when that pin is -configured as input mode. As a result, bgpio_dir_out should set -pin to output before configuring pin values or gpio pin values -can't be set up properly. -Introduce two variants of bgpio_dir_out: bgpio_dir_out_val_first -and bgpio_dir_out_dir_first, and assign direction_output according -to a new flag: BGPIOF_NO_SET_ON_INPUT. - -Signed-off-by: Chuanhong Guo <gch981213@gmail.com> -Tested-by: René van Dorst <opensource@vdorst.com> -Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> ---- - drivers/gpio/gpio-mmio.c | 23 +++++++++++++++++++---- - include/linux/gpio/driver.h | 1 + - 2 files changed, 20 insertions(+), 4 deletions(-) - ---- a/drivers/gpio/gpio-mmio.c -+++ b/drivers/gpio/gpio-mmio.c -@@ -381,12 +381,10 @@ static int bgpio_get_dir(struct gpio_chi - return 1; - } - --static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -+static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) - { - unsigned long flags; - -- gc->set(gc, gpio, val); -- - spin_lock_irqsave(&gc->bgpio_lock, flags); - - gc->bgpio_dir |= bgpio_line2mask(gc, gpio); -@@ -397,7 +395,21 @@ static int bgpio_dir_out(struct gpio_chi - gc->write_reg(gc->reg_dir_out, gc->bgpio_dir); - - spin_unlock_irqrestore(&gc->bgpio_lock, flags); -+} - -+static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio, -+ int val) -+{ -+ bgpio_dir_out(gc, gpio, val); -+ gc->set(gc, gpio, val); -+ return 0; -+} -+ -+static int bgpio_dir_out_val_first(struct gpio_chip *gc, unsigned int gpio, -+ int val) -+{ -+ gc->set(gc, gpio, val); -+ bgpio_dir_out(gc, gpio, val); - return 0; - } - -@@ -530,7 +542,10 @@ static int bgpio_setup_direction(struct - if (dirout || dirin) { - gc->reg_dir_out = dirout; - gc->reg_dir_in = dirin; -- gc->direction_output = bgpio_dir_out; -+ if (flags & BGPIOF_NO_SET_ON_INPUT) -+ gc->direction_output = bgpio_dir_out_dir_first; -+ else -+ gc->direction_output = bgpio_dir_out_val_first; - gc->direction_input = bgpio_dir_in; - gc->get_direction = bgpio_get_dir; - } else { ---- a/include/linux/gpio/driver.h -+++ b/include/linux/gpio/driver.h -@@ -567,6 +567,7 @@ int bgpio_init(struct gpio_chip *gc, str - #define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3) - #define BGPIOF_READ_OUTPUT_REG_SET BIT(4) /* reg_set stores output value */ - #define BGPIOF_NO_OUTPUT BIT(5) /* only input */ -+#define BGPIOF_NO_SET_ON_INPUT BIT(6) - - int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq); diff --git a/target/linux/ramips/patches-5.4/112-gpio-mt7621-add-BGPIOF_NO_SET_ON_INPUT-flag.patch b/target/linux/ramips/patches-5.4/112-gpio-mt7621-add-BGPIOF_NO_SET_ON_INPUT-flag.patch deleted file mode 100644 index 862f9adb47..0000000000 --- a/target/linux/ramips/patches-5.4/112-gpio-mt7621-add-BGPIOF_NO_SET_ON_INPUT-flag.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ad65f02fd73e9a700f1693a4513ae923ca07beb0 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo <gch981213@gmail.com> -Date: Sun, 15 Mar 2020 20:13:38 +0800 -Subject: [PATCH] gpio: mt7621: add BGPIOF_NO_SET_ON_INPUT flag -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -DSET/DCLR registers only works on output pins. Add corresponding -BGPIOF_NO_SET_ON_INPUT flag to bgpio_init call to fix direction_out -behavior. - -Signed-off-by: Chuanhong Guo <gch981213@gmail.com> -Tested-by: René van Dorst <opensource@vdorst.com> -Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> ---- - drivers/gpio/gpio-mt7621.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/gpio/gpio-mt7621.c -+++ b/drivers/gpio/gpio-mt7621.c -@@ -227,8 +227,8 @@ mediatek_gpio_bank_probe(struct device * - ctrl = mtk->base + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_STRIDE); - diro = mtk->base + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_STRIDE); - -- ret = bgpio_init(&rg->chip, dev, 4, -- dat, set, ctrl, diro, NULL, 0); -+ ret = bgpio_init(&rg->chip, dev, 4, dat, set, ctrl, diro, NULL, -+ BGPIOF_NO_SET_ON_INPUT); - if (ret) { - dev_err(dev, "bgpio_init() failed\n"); - return ret; diff --git a/target/linux/ramips/patches-5.4/200-add-ralink-eth.patch b/target/linux/ramips/patches-5.4/200-add-ralink-eth.patch deleted file mode 100644 index 79e7c2309b..0000000000 --- a/target/linux/ramips/patches-5.4/200-add-ralink-eth.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/drivers/net/ethernet/Kconfig -+++ b/drivers/net/ethernet/Kconfig -@@ -160,6 +160,7 @@ source "drivers/net/ethernet/pasemi/Kcon - source "drivers/net/ethernet/pensando/Kconfig" - source "drivers/net/ethernet/qlogic/Kconfig" - source "drivers/net/ethernet/qualcomm/Kconfig" -+source "drivers/net/ethernet/ralink/Kconfig" - source "drivers/net/ethernet/rdc/Kconfig" - source "drivers/net/ethernet/realtek/Kconfig" - source "drivers/net/ethernet/renesas/Kconfig" ---- a/drivers/net/ethernet/Makefile -+++ b/drivers/net/ethernet/Makefile -@@ -72,6 +72,7 @@ obj-$(CONFIG_NET_VENDOR_PACKET_ENGINES) - obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ - obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/ - obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/ -+obj-$(CONFIG_NET_VENDOR_RALINK) += ralink/ - obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ - obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/ - obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ diff --git a/target/linux/ramips/patches-5.4/300-mt7620-export-chip-version-and-pkg.patch b/target/linux/ramips/patches-5.4/300-mt7620-export-chip-version-and-pkg.patch deleted file mode 100644 index 8b4335eb03..0000000000 --- a/target/linux/ramips/patches-5.4/300-mt7620-export-chip-version-and-pkg.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/arch/mips/include/asm/mach-ralink/mt7620.h -+++ b/arch/mips/include/asm/mach-ralink/mt7620.h -@@ -135,4 +135,16 @@ static inline int mt7620_get_eco(void) - return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK; - } - -+static inline int mt7620_get_chipver(void) -+{ -+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_VER_SHIFT) & -+ CHIP_REV_VER_MASK; -+} -+ -+static inline int mt7620_get_pkg(void) -+{ -+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_PKG_SHIFT) & -+ CHIP_REV_PKG_MASK; -+} -+ - #endif diff --git a/target/linux/ramips/patches-5.4/301-MIPS-ralink-mt7621-introduce-soc_device-initializati.patch b/target/linux/ramips/patches-5.4/301-MIPS-ralink-mt7621-introduce-soc_device-initializati.patch deleted file mode 100644 index dc3dd0d1ec..0000000000 --- a/target/linux/ramips/patches-5.4/301-MIPS-ralink-mt7621-introduce-soc_device-initializati.patch +++ /dev/null @@ -1,89 +0,0 @@ -From f798b7588bd7397bbab958281ca6c88d08714941 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Date: Thu, 12 Mar 2020 12:29:15 +0100 -Subject: [PATCH] MIPS: ralink: mt7621: introduce 'soc_device' initialization - -mt7621 SoC has its own 'ralink_soc_info' structure with some -information about the soc itself. Pcie controller and pcie phy -drivers for this soc which are still in staging git tree make uses -of 'soc_device_attribute' looking for revision 'E2' in order to -know if reset lines are or not inverted. This way of doing things -seems to be necessary in order to make things clean and properly. -Hence, introduce this 'soc_device' to be able to properly use those -attributes in drivers. Also set 'data' pointer points to the struct -'ralink_soc_info' to be able to export also current soc information -using this mechanism. - -Cc: Paul Burton <paul.burton@mips.com> -Cc: ralf@linux-mips.org -Cc: jhogan@kernel.org -Cc: john@phrozen.org -Cc: NeilBrown <neil@brown.name> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: linux-mips@vger.kernel.org - -Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> -Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> ---- - arch/mips/ralink/mt7621.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - ---- a/arch/mips/ralink/mt7621.c -+++ b/arch/mips/ralink/mt7621.c -@@ -7,6 +7,8 @@ - - #include <linux/kernel.h> - #include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/sys_soc.h> - #include <linux/jiffies.h> - #include <linux/clk.h> - #include <linux/clkdev.h> -@@ -294,6 +296,33 @@ static int udelay_recal(void) - } - device_initcall(udelay_recal); - -+static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev) -+{ -+ struct soc_device *soc_dev; -+ struct soc_device_attribute *soc_dev_attr; -+ -+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); -+ if (!soc_dev_attr) -+ return; -+ -+ soc_dev_attr->soc_id = "mt7621"; -+ soc_dev_attr->family = "Ralink"; -+ -+ if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 && -+ (rev & CHIP_REV_ECO_MASK) == 1) -+ soc_dev_attr->revision = "E2"; -+ else -+ soc_dev_attr->revision = "E1"; -+ -+ soc_dev_attr->data = soc_info; -+ -+ soc_dev = soc_device_register(soc_dev_attr); -+ if (IS_ERR(soc_dev)) { -+ kfree(soc_dev_attr); -+ return; -+ } -+} -+ - void prom_soc_init(struct ralink_soc_info *soc_info) - { - void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE); -@@ -345,11 +374,12 @@ void prom_soc_init(struct ralink_soc_inf - soc_info->mem_detect = mt7621_memory_detect; - rt2880_pinmux_data = mt7621_pinmux_data; - -- - if (!register_cps_smp_ops()) - return; - if (!register_cmp_smp_ops()) - return; - if (!register_vsmp_smp_ops()) - return; -+ -+ soc_dev_init(soc_info, rev); - } diff --git a/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch b/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch deleted file mode 100644 index d5de4e45bc..0000000000 --- a/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -2306,6 +2306,11 @@ static const struct flash_info spi_nor_i - SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - .fixups = &gd25q256_fixups, - }, -+ { -+ "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES) -+ }, - - /* Intel/Numonyx -- xxxs33b */ - { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, diff --git a/target/linux/ramips/patches-5.4/401-net-ethernet-mediatek-support-net-labels.patch b/target/linux/ramips/patches-5.4/401-net-ethernet-mediatek-support-net-labels.patch deleted file mode 100644 index be453a6d7a..0000000000 --- a/target/linux/ramips/patches-5.4/401-net-ethernet-mediatek-support-net-labels.patch +++ /dev/null @@ -1,34 +0,0 @@ -From bd0f89de5476ca25e73fae829ba3e1dafae1d90d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com> -Date: Fri, 21 Jun 2019 10:04:05 +0200 -Subject: [PATCH] net: ethernet: mediatek: support net-labels - -With this patch, device name can be set within dts file in the same way as dsa -port can. -Add: label = "wan"; to GMAC node. - -Signed-off-by: René van Dorst <opensource@vdorst.com> ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2940,6 +2940,7 @@ static const struct net_device_ops mtk_n - - static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - { -+ const char *name = of_get_property(np, "label", NULL); - const __be32 *_id = of_get_property(np, "reg", NULL); - struct phylink *phylink; - int phy_mode, id, err; -@@ -3032,6 +3033,9 @@ static int mtk_add_mac(struct mtk_eth *e - - eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN; - -+ if (name) -+ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ); -+ - return 0; - - free_netdev: diff --git a/target/linux/ramips/patches-5.4/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch b/target/linux/ramips/patches-5.4/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch deleted file mode 100644 index 728876322c..0000000000 --- a/target/linux/ramips/patches-5.4/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 52d14545d2fc276b1bf9ccf48d4612fab6edfb6a Mon Sep 17 00:00:00 2001 -From: David Bauer <mail@david-bauer.net> -Date: Thu, 6 May 2021 17:49:55 +0200 -Subject: [PATCH] mtd: spi-nor: Add support for BoHong bh25q128as - -Add MTD support for the BoHong bh25q128as SPI NOR chip. -The chip has 16MB of total capacity, divided into a total of 256 -sectors, each 64KB sized. The chip also supports 4KB sectors. -Additionally, it supports dual and quad read modes. - -Functionality was verified on an Tenbay WR1800K / MTK MT7621 board. - -Signed-off-by: David Bauer <mail@david-bauer.net> ---- - drivers/mtd/spi-nor/Makefile | 1 + - drivers/mtd/spi-nor/bohong.c | 21 +++++++++++++++++++++ - drivers/mtd/spi-nor/core.c | 1 + - drivers/mtd/spi-nor/core.h | 1 + - 4 files changed, 24 insertions(+) - create mode 100644 drivers/mtd/spi-nor/bohong.c - ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -2233,6 +2233,10 @@ static const struct flash_info spi_nor_i - - { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, - -+ /* BoHong Microelectronics */ -+ { "bh25q128as", INFO(0x684018, 0, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ - /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, diff --git a/target/linux/ramips/patches-5.4/804-staging-mt7621-pinctrl-use-ngpios-not-num-gpios.patch b/target/linux/ramips/patches-5.4/804-staging-mt7621-pinctrl-use-ngpios-not-num-gpios.patch deleted file mode 100644 index 0d62bd8b03..0000000000 --- a/target/linux/ramips/patches-5.4/804-staging-mt7621-pinctrl-use-ngpios-not-num-gpios.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c -+++ b/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c -@@ -354,7 +354,7 @@ static int rt2880_pinmux_probe(struct pl - if (!of_device_is_available(np)) - continue; - -- ngpio = of_get_property(np, "ralink,num-gpios", NULL); -+ ngpio = of_get_property(np, "ngpios", NULL); - gpiobase = of_get_property(np, "ralink,gpio-base", NULL); - if (!ngpio || !gpiobase) { - dev_err(&pdev->dev, "failed to load chip info\n"); diff --git a/target/linux/ramips/patches-5.4/805-pinctrl-AW9523.patch b/target/linux/ramips/patches-5.4/805-pinctrl-AW9523.patch deleted file mode 100644 index d8e17a671a..0000000000 --- a/target/linux/ramips/patches-5.4/805-pinctrl-AW9523.patch +++ /dev/null @@ -1,72 +0,0 @@ -From: AngeloGioacchino Del Regno - <angelogioacchino.delregno@somainline.org> -To: linus.walleij@linaro.org -Cc: linux-kernel@vger.kernel.org, konrad.dybcio@somainline.org, - marijn.suijten@somainline.org, martin.botka@somainline.org, - phone-devel@vger.kernel.org, linux-gpio@vger.kernel.org, - devicetree@vger.kernel.org, robh+dt@kernel.org, - AngeloGioacchino Del Regno - <angelogioacchino.delregno@somainline.org> -Subject: [PATCH v5 1/2] pinctrl: Add driver for Awinic AW9523/B I2C GPIO - Expander -Date: Mon, 25 Jan 2021 19:22:18 +0100 - -The Awinic AW9523(B) is a multi-function I2C gpio expander in a -TQFN-24L package, featuring PWM (max 37mA per pin, or total max -power 3.2Watts) for LED driving capability. - -It has two ports with 8 pins per port (for a total of 16 pins), -configurable as either PWM with 1/256 stepping or GPIO input/output, -1.8V logic input; each GPIO can be configured as input or output -independently from each other. - -This IC also has an internal interrupt controller, which is capable -of generating an interrupt for each GPIO, depending on the -configuration, and will raise an interrupt on the INTN pin to -advertise this to an external interrupt controller. - -Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org> ---- - drivers/pinctrl/Kconfig | 17 + - drivers/pinctrl/Makefile | 1 + - drivers/pinctrl/pinctrl-aw9523.c | 1122 ++++++++++++++++++++++++++++++ - 3 files changed, 1140 insertions(+) - create mode 100644 drivers/pinctrl/pinctrl-aw9523.c - ---- a/drivers/pinctrl/Kconfig -+++ b/drivers/pinctrl/Kconfig -@@ -109,6 +109,24 @@ config PINCTRL_AMD - Requires ACPI/FDT device enumeration code to set up a platform - device. - -+config PINCTRL_AW9523 -+ bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver" -+ depends on OF && I2C -+ select PINMUX -+ select PINCONF -+ select GENERIC_PINCONF -+ select GPIOLIB -+ select GPIOLIB_IRQCHIP -+ select REGMAP -+ select REGMAP_I2C -+ help -+ The Awinic AW9523/AW9523B is a multi-function I2C GPIO -+ expander with PWM functionality. This driver bundles a -+ pinctrl driver to select the function muxing and a GPIO -+ driver to handle GPIO, when the GPIO function is selected. -+ -+ Say yes to enable pinctrl and GPIO support for the AW9523(B). -+ - config PINCTRL_BM1880 - bool "Bitmain BM1880 Pinctrl driver" - depends on OF && (ARCH_BITMAIN || COMPILE_TEST) ---- a/drivers/pinctrl/Makefile -+++ b/drivers/pinctrl/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_AXP209) += pinctrl- - obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o - obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o - obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o -+obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o - obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o - obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o - obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o diff --git a/target/linux/ramips/patches-5.4/990-NET-no-auto-carrier-off-support.patch b/target/linux/ramips/patches-5.4/990-NET-no-auto-carrier-off-support.patch deleted file mode 100644 index 8b95eacab1..0000000000 --- a/target/linux/ramips/patches-5.4/990-NET-no-auto-carrier-off-support.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0b6eb1e68290243d439ee330ea8d0b239a5aec69 Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Sun, 27 Jul 2014 09:38:50 +0100 -Subject: [PATCH 34/53] NET: multi phy support - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - drivers/net/phy/phy.c | 9 ++++++--- - include/linux/phy.h | 1 + - 2 files changed, 7 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -549,7 +549,10 @@ static int phy_check_link_status(struct - phy_link_up(phydev); - } else if (!phydev->link && phydev->state != PHY_NOLINK) { - phydev->state = PHY_NOLINK; -- phy_link_down(phydev, true); -+ if (!phydev->no_auto_carrier_off) -+ phy_link_down(phydev, true); -+ else -+ phy_link_down(phydev, false); - } - - return 0; -@@ -947,7 +950,10 @@ void phy_state_machine(struct work_struc - case PHY_HALTED: - if (phydev->link) { - phydev->link = 0; -- phy_link_down(phydev, true); -+ if (!phydev->no_auto_carrier_off) -+ phy_link_down(phydev, true); -+ else -+ phy_link_down(phydev, false); - } - do_suspend = true; - break; ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -381,6 +381,7 @@ struct phy_device { - unsigned suspended_by_mdio_bus:1; - unsigned sysfs_links:1; - unsigned loopback_enabled:1; -+ unsigned no_auto_carrier_off:1; - - unsigned autoneg:1; - /* The most recently read link state */ diff --git a/target/linux/ramips/patches-5.4/991-at803x.patch b/target/linux/ramips/patches-5.4/991-at803x.patch deleted file mode 100644 index a0d9a03fcf..0000000000 --- a/target/linux/ramips/patches-5.4/991-at803x.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 924453aa9d2324e5611f8e2b71df746d8f0c79f1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com> -Date: Fri, 13 Nov 2020 16:11:32 +0100 -Subject: [PATCH] net: phy: at803x: add support for SFP module in - RGMII-to-x-base mode -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: René van Dorst <opensource@vdorst.com> ---- - drivers/net/phy/at803x.c | 91 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 91 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -14,6 +14,8 @@ - #include <linux/etherdevice.h> - #include <linux/of_gpio.h> - #include <linux/gpio/consumer.h> -+#include <linux/sfp.h> -+#include <linux/phylink.h> - - #define AT803X_SPECIFIC_STATUS 0x11 - #define AT803X_SS_SPEED_MASK (3 << 14) -@@ -52,9 +54,18 @@ - - #define AT803X_MODE_CFG_MASK 0x0F - #define AT803X_MODE_CFG_SGMII 0x01 -+#define AT803X_MODE_CFG_BX1000_RGMII_50 0x02 -+#define AT803X_MODE_CFG_BX1000_RGMII_75 0x03 -+#define AT803X_MODE_FIBER 0x01 -+#define AT803X_MODE_COPPER 0x00 - - #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ - #define AT803X_PSSR_MR_AN_COMPLETE 0x0200 -+#define PSSR_LINK BIT(10) -+#define PSSR_SYNC_STATUS BIT(8) -+#define PSSR_DUPLEX BIT(13) -+#define PSSR_SPEED_1000 BIT(15) -+#define PSSR_SPEED_100 BIT(14) - - #define AT803X_DEBUG_REG_0 0x00 - #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) -@@ -274,18 +285,80 @@ static int at803x_resume(struct phy_devi - return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); - } - -+static int at803x_mode(struct phy_device *phydev) -+{ -+ int mode; -+ -+ mode = phy_read(phydev, AT803X_REG_CHIP_CONFIG) & AT803X_MODE_CFG_MASK; -+ -+ if (mode == AT803X_MODE_CFG_BX1000_RGMII_50 || -+ mode == AT803X_MODE_CFG_BX1000_RGMII_75) -+ return AT803X_MODE_FIBER; -+ return AT803X_MODE_COPPER; -+} -+ -+static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(at803x_support) = { 0, }; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; -+ struct phy_device *phydev = upstream; -+ phy_interface_t iface; -+ -+ phylink_set(at803x_support, 1000baseX_Full); -+ /* AT803x only support 1000baseX but SGMII works fine when module runs -+ * at 1Gbit. -+ */ -+ phylink_set(at803x_support, 1000baseT_Full); -+ -+ sfp_parse_support(phydev->sfp_bus, id, support); -+ -+ // Limit to interfaces that both sides support -+ linkmode_and(support, support, at803x_support); -+ -+ if (linkmode_empty(support)) -+ goto unsupported_mode; -+ -+ iface = sfp_select_interface(phydev->sfp_bus, support); -+ -+ if (iface != PHY_INTERFACE_MODE_SGMII && -+ iface != PHY_INTERFACE_MODE_1000BASEX) -+ goto unsupported_mode; -+ -+ dev_info(&phydev->mdio.dev, "SFP interface %s", phy_modes(iface)); -+ -+ return 0; -+ -+unsupported_mode: -+ dev_info(&phydev->mdio.dev, "incompatible SFP module inserted;" -+ "Only SGMII at 1Gbit/1000BASEX are supported!\n"); -+ return -EINVAL; -+} -+ -+static const struct sfp_upstream_ops at803x_sfp_ops = { -+ .attach = phy_sfp_attach, -+ .detach = phy_sfp_detach, -+ .module_insert = at803x_sfp_insert, -+}; -+ - static int at803x_probe(struct phy_device *phydev) - { - struct device *dev = &phydev->mdio.dev; - struct at803x_priv *priv; - int ret = 0; - -+ if (at803x_mode(phydev) == AT803X_MODE_FIBER) { -+ ret = phy_sfp_probe(phydev, &at803x_sfp_ops); -+ if (ret < 0) -+ return ret; -+ } -+ - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - phydev->priv = priv; - -+#if 0 - /* Some bootloaders leave the fiber page selected. - * Switch to the copper page, as otherwise we read - * the PHY capabilities from the fiber side. -@@ -295,6 +368,7 @@ static int at803x_probe(struct phy_devic - ret = at803x_write_page(phydev, AT803X_PAGE_COPPER); - mutex_unlock(&phydev->mdio.bus->mdio_lock); - } -+#endif - - return ret; - } -@@ -419,6 +493,7 @@ static int at803x_get_features(struct ph - if (err) - return err; - -+#if 0 - if (!(phydev->phy_id & phydev->drv->phy_id_mask) == (ATH8031_PHY_ID & phydev->drv->phy_id_mask)) - return 0; - -@@ -436,6 +511,7 @@ static int at803x_get_features(struct ph - */ - linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, - phydev->supported); -+#endif - return 0; - } - -@@ -443,6 +519,10 @@ static int at803x_read_status(struct phy - { - int ss, err, old_link = phydev->link; - -+ /* Handle (Fiber) SGMII to RGMII mode */ -+ if (at803x_mode(phydev) == AT803X_MODE_FIBER) -+ return genphy_c37_read_status(phydev); -+ - /* Update the link, but return if there was an error */ - err = genphy_update_link(phydev); - if (err) -@@ -497,6 +577,19 @@ static int at803x_read_status(struct phy - return 0; - } - -+static int at803x_config_aneg(struct phy_device *phydev) -+{ -+ /* Handle (Fiber) SerDes to RGMII mode */ -+ if (at803x_mode(phydev) == AT803X_MODE_FIBER) { -+ pr_warn("%s: fiber\n", __func__); -+ return genphy_c37_config_aneg(phydev); -+ } -+ -+ pr_warn("%s: enter\n", __func__); -+ -+ return genphy_config_aneg(phydev); -+} -+ - static struct phy_driver at803x_driver[] = { - { - /* ATHEROS 8035 */ -@@ -532,6 +625,7 @@ static struct phy_driver at803x_driver[] - /* ATHEROS 8031 */ - .phy_id = ATH8031_PHY_ID, - .name = "Atheros 8031 ethernet", -+ .config_aneg = at803x_config_aneg, - .phy_id_mask = AT803X_PHY_ID_MASK, - .probe = at803x_probe, - .config_init = at803x_config_init, |