diff options
Diffstat (limited to 'target/linux/gemini')
18 files changed, 1631 insertions, 0 deletions
diff --git a/target/linux/gemini/patches-4.19/0001-pinctrl-gemini-Mask-and-set-properly.patch b/target/linux/gemini/patches-4.19/0001-pinctrl-gemini-Mask-and-set-properly.patch new file mode 100644 index 0000000000..3cc7bad8b8 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0001-pinctrl-gemini-Mask-and-set-properly.patch @@ -0,0 +1,36 @@ +From f8ac3d3472a8dc99c8647a637611d146d88be8cb Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Tue, 9 Oct 2018 10:09:14 +0200 +Subject: [PATCH 01/18] pinctrl: gemini: Mask and set properly + +The code was written under the assumption that the +regmap_update_bits() would mask the bits in the mask and +set the bits in the value. + +It missed the points that it will not set bits in the value +unless these are also masked in the mask. Set value bits +that are not in the mask will simply be ignored. + +Fixes: 06351d133dea ("pinctrl: add a Gemini SoC pin controller") +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/pinctrl/pinctrl-gemini.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/pinctrl-gemini.c b/drivers/pinctrl/pinctrl-gemini.c +index fa7d998e1d5a..1e484a36ff07 100644 +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -2184,7 +2184,8 @@ static int gemini_pmx_set_mux(struct pinctrl_dev *pctldev, + func->name, grp->name); + + regmap_read(pmx->map, GLOBAL_MISC_CTRL, &before); +- regmap_update_bits(pmx->map, GLOBAL_MISC_CTRL, grp->mask, ++ regmap_update_bits(pmx->map, GLOBAL_MISC_CTRL, ++ grp->mask | grp->value, + grp->value); + regmap_read(pmx->map, GLOBAL_MISC_CTRL, &after); + +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0002-pinctrl-gemini-Fix-up-TVC-clock-group.patch b/target/linux/gemini/patches-4.19/0002-pinctrl-gemini-Fix-up-TVC-clock-group.patch new file mode 100644 index 0000000000..b6435f373d --- /dev/null +++ b/target/linux/gemini/patches-4.19/0002-pinctrl-gemini-Fix-up-TVC-clock-group.patch @@ -0,0 +1,146 @@ +From ce81398dccb984855de606b75db25eddecdaa9e5 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Wed, 10 Oct 2018 20:25:39 +0200 +Subject: [PATCH 02/18] pinctrl: gemini: Fix up TVC clock group + +The previous fix made the TVC clock get muxed in on the +D-Link DIR-685 instead of giving nagging warnings of this +not working. Not good. We didn't want that, as it breaks +video. + +Create a specific group for the TVC CLK, and break out +a specific GPIO group for it on the SL3516 so we can use +that line as GPIO if we don't need the TVC CLK. + +Fixes: d17f477c5bc6 ("pinctrl: gemini: Mask and set properly") +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/pinctrl/pinctrl-gemini.c | 44 ++++++++++++++++++++++++++------ + 1 file changed, 36 insertions(+), 8 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-gemini.c b/drivers/pinctrl/pinctrl-gemini.c +index 1e484a36ff07..3535f9841861 100644 +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -591,13 +591,16 @@ static const unsigned int tvc_3512_pins[] = { + 319, /* TVC_DATA[1] */ + 301, /* TVC_DATA[2] */ + 283, /* TVC_DATA[3] */ +- 265, /* TVC_CLK */ + 320, /* TVC_DATA[4] */ + 302, /* TVC_DATA[5] */ + 284, /* TVC_DATA[6] */ + 266, /* TVC_DATA[7] */ + }; + ++static const unsigned int tvc_clk_3512_pins[] = { ++ 265, /* TVC_CLK */ ++}; ++ + /* NAND flash pins */ + static const unsigned int nflash_3512_pins[] = { + 199, 200, 201, 202, 216, 217, 218, 219, 220, 234, 235, 236, 237, 252, +@@ -629,7 +632,7 @@ static const unsigned int pflash_3512_pins_extended[] = { + /* Serial flash pins CE0, CE1, DI, DO, CK */ + static const unsigned int sflash_3512_pins[] = { 230, 231, 232, 233, 211 }; + +-/* The GPIO0A (0) pin overlap with TVC and extended parallel flash */ ++/* The GPIO0A (0) pin overlap with TVC CLK and extended parallel flash */ + static const unsigned int gpio0a_3512_pins[] = { 265 }; + + /* The GPIO0B (1-4) pins overlap with TVC and ICE */ +@@ -823,7 +826,13 @@ static const struct gemini_pin_group gemini_3512_pin_groups[] = { + .num_pins = ARRAY_SIZE(tvc_3512_pins), + /* Conflict with character LCD and ICE */ + .mask = LCD_PADS_ENABLE, +- .value = TVC_PADS_ENABLE | TVC_CLK_PAD_ENABLE, ++ .value = TVC_PADS_ENABLE, ++ }, ++ { ++ .name = "tvcclkgrp", ++ .pins = tvc_clk_3512_pins, ++ .num_pins = ARRAY_SIZE(tvc_clk_3512_pins), ++ .value = TVC_CLK_PAD_ENABLE, + }, + /* + * The construction is done such that it is possible to use a serial +@@ -860,8 +869,8 @@ static const struct gemini_pin_group gemini_3512_pin_groups[] = { + .name = "gpio0agrp", + .pins = gpio0a_3512_pins, + .num_pins = ARRAY_SIZE(gpio0a_3512_pins), +- /* Conflict with TVC */ +- .mask = TVC_PADS_ENABLE, ++ /* Conflict with TVC CLK */ ++ .mask = TVC_CLK_PAD_ENABLE, + }, + { + .name = "gpio0bgrp", +@@ -1531,13 +1540,16 @@ static const unsigned int tvc_3516_pins[] = { + 311, /* TVC_DATA[1] */ + 394, /* TVC_DATA[2] */ + 374, /* TVC_DATA[3] */ +- 333, /* TVC_CLK */ + 354, /* TVC_DATA[4] */ + 395, /* TVC_DATA[5] */ + 312, /* TVC_DATA[6] */ + 334, /* TVC_DATA[7] */ + }; + ++static const unsigned int tvc_clk_3516_pins[] = { ++ 333, /* TVC_CLK */ ++}; ++ + /* NAND flash pins */ + static const unsigned int nflash_3516_pins[] = { + 243, 260, 261, 224, 280, 262, 281, 264, 300, 263, 282, 301, 320, 283, +@@ -1570,7 +1582,7 @@ static const unsigned int pflash_3516_pins_extended[] = { + static const unsigned int sflash_3516_pins[] = { 296, 338, 295, 359, 339 }; + + /* The GPIO0A (0-4) pins overlap with TVC and extended parallel flash */ +-static const unsigned int gpio0a_3516_pins[] = { 333, 354, 395, 312, 334 }; ++static const unsigned int gpio0a_3516_pins[] = { 354, 395, 312, 334 }; + + /* The GPIO0B (5-7) pins overlap with ICE */ + static const unsigned int gpio0b_3516_pins[] = { 375, 396, 376 }; +@@ -1602,6 +1614,9 @@ static const unsigned int gpio0j_3516_pins[] = { 359, 339 }; + /* The GPIO0K (30,31) pins overlap with NAND flash */ + static const unsigned int gpio0k_3516_pins[] = { 275, 298 }; + ++/* The GPIO0L (0) pins overlap with TVC_CLK */ ++static const unsigned int gpio0l_3516_pins[] = { 333 }; ++ + /* The GPIO1A (0-4) pins that overlap with IDE and parallel flash */ + static const unsigned int gpio1a_3516_pins[] = { 221, 200, 222, 201, 220 }; + +@@ -1761,7 +1776,13 @@ static const struct gemini_pin_group gemini_3516_pin_groups[] = { + .num_pins = ARRAY_SIZE(tvc_3516_pins), + /* Conflict with character LCD */ + .mask = LCD_PADS_ENABLE, +- .value = TVC_PADS_ENABLE | TVC_CLK_PAD_ENABLE, ++ .value = TVC_PADS_ENABLE, ++ }, ++ { ++ .name = "tvcclkgrp", ++ .pins = tvc_clk_3516_pins, ++ .num_pins = ARRAY_SIZE(tvc_clk_3516_pins), ++ .value = TVC_CLK_PAD_ENABLE, + }, + /* + * The construction is done such that it is possible to use a serial +@@ -1872,6 +1893,13 @@ static const struct gemini_pin_group gemini_3516_pin_groups[] = { + /* Conflict with parallel and NAND flash */ + .value = PFLASH_PADS_DISABLE | NAND_PADS_DISABLE, + }, ++ { ++ .name = "gpio0lgrp", ++ .pins = gpio0l_3516_pins, ++ .num_pins = ARRAY_SIZE(gpio0l_3516_pins), ++ /* Conflict with TVE CLK */ ++ .mask = TVC_CLK_PAD_ENABLE, ++ }, + { + .name = "gpio1agrp", + .pins = gpio1a_3516_pins, +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0003-pinctrl-gemini-Drop-noisy-debug-prints.patch b/target/linux/gemini/patches-4.19/0003-pinctrl-gemini-Drop-noisy-debug-prints.patch new file mode 100644 index 0000000000..d01eaf3947 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0003-pinctrl-gemini-Drop-noisy-debug-prints.patch @@ -0,0 +1,87 @@ +From 5d1bd9669ddcd26384672891c37110046e1ac8e8 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Tue, 9 Oct 2018 10:12:24 +0200 +Subject: [PATCH 03/18] pinctrl: gemini: Drop noisy debug prints + +The dev_info() in the pin control driver is really just good +for debug, so drop it. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/pinctrl/pinctrl-gemini.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-gemini.c b/drivers/pinctrl/pinctrl-gemini.c +index 3535f9841861..f75bf6f16a2e 100644 +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -2207,9 +2207,9 @@ static int gemini_pmx_set_mux(struct pinctrl_dev *pctldev, + return -ENODEV; + } + +- dev_info(pmx->dev, +- "ACTIVATE function \"%s\" with group \"%s\"\n", +- func->name, grp->name); ++ dev_dbg(pmx->dev, ++ "ACTIVATE function \"%s\" with group \"%s\"\n", ++ func->name, grp->name); + + regmap_read(pmx->map, GLOBAL_MISC_CTRL, &before); + regmap_update_bits(pmx->map, GLOBAL_MISC_CTRL, +@@ -2240,10 +2240,10 @@ static int gemini_pmx_set_mux(struct pinctrl_dev *pctldev, + "GLOBAL MISC CTRL before: %08x, after %08x, expected %08x\n", + before, after, expected); + } else { +- dev_info(pmx->dev, +- "padgroup %s %s\n", +- gemini_padgroups[i], +- enabled ? "enabled" : "disabled"); ++ dev_dbg(pmx->dev, ++ "padgroup %s %s\n", ++ gemini_padgroups[i], ++ enabled ? "enabled" : "disabled"); + } + } + +@@ -2262,10 +2262,10 @@ static int gemini_pmx_set_mux(struct pinctrl_dev *pctldev, + "GLOBAL MISC CTRL before: %08x, after %08x, expected %08x\n", + before, after, expected); + } else { +- dev_info(pmx->dev, +- "padgroup %s %s\n", +- gemini_padgroups[i], +- enabled ? "enabled" : "disabled"); ++ dev_dbg(pmx->dev, ++ "padgroup %s %s\n", ++ gemini_padgroups[i], ++ enabled ? "enabled" : "disabled"); + } + } + +@@ -2492,9 +2492,9 @@ static int gemini_pinconf_group_set(struct pinctrl_dev *pctldev, + regmap_update_bits(pmx->map, GLOBAL_IODRIVE, + grp->driving_mask, + val); +- dev_info(pmx->dev, +- "set group %s to %d mA drive strength mask %08x val %08x\n", +- grp->name, arg, grp->driving_mask, val); ++ dev_dbg(pmx->dev, ++ "set group %s to %d mA drive strength mask %08x val %08x\n", ++ grp->name, arg, grp->driving_mask, val); + break; + default: + dev_err(pmx->dev, "invalid config param %04x\n", param); +@@ -2585,8 +2585,8 @@ static int gemini_pmx_probe(struct platform_device *pdev) + /* Print initial state */ + tmp = val; + for_each_set_bit(i, &tmp, PADS_MAXBIT) { +- dev_info(dev, "pad group %s %s\n", gemini_padgroups[i], +- (val & BIT(i)) ? "enabled" : "disabled"); ++ dev_dbg(dev, "pad group %s %s\n", gemini_padgroups[i], ++ (val & BIT(i)) ? "enabled" : "disabled"); + } + + /* Check if flash pin is set */ +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0004-boot-sq201-from-sda1.patch b/target/linux/gemini/patches-4.19/0004-boot-sq201-from-sda1.patch new file mode 100644 index 0000000000..c81efd2076 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0004-boot-sq201-from-sda1.patch @@ -0,0 +1,25 @@ +From 95be54e285767c5209bb51df923373f78b8c4099 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Mon, 16 Jul 2018 23:36:30 +0200 +Subject: [PATCH 04/18] boot sq201 from sda1 + +--- + arch/arm/boot/dts/gemini-sq201.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts +index 3787cf3763c4..66e2845a3edb 100644 +--- a/arch/arm/boot/dts/gemini-sq201.dts ++++ b/arch/arm/boot/dts/gemini-sq201.dts +@@ -20,7 +20,7 @@ + }; + + chosen { +- bootargs = "console=ttyS0,115200n8"; ++ bootargs = "console=ttyS0,115200n8 root=/dev/sda1 rw rootwait"; + stdout-path = &uart0; + }; + +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0005-mtd-physmap_of-Move-custom-initialization.patch b/target/linux/gemini/patches-4.19/0005-mtd-physmap_of-Move-custom-initialization.patch new file mode 100644 index 0000000000..f192ed7f9e --- /dev/null +++ b/target/linux/gemini/patches-4.19/0005-mtd-physmap_of-Move-custom-initialization.patch @@ -0,0 +1,52 @@ +From 58ecb60d53d43e8d584708722a2cf851ba88f9e1 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Thu, 11 Oct 2018 19:53:40 +0200 +Subject: [PATCH 05/18] mtd: physmap_of: Move custom initialization + +In order to be able to assign custom complex mappings +to the physmap_of plugin for Gemini, move the initialization +so that the simple map is initialized before we enter the +platform-specific functions so the latter can override +them. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/mtd/maps/physmap_of_core.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/drivers/mtd/maps/physmap_of_core.c b/drivers/mtd/maps/physmap_of_core.c +index 4129535b8e46..74ad753265f3 100644 +--- a/drivers/mtd/maps/physmap_of_core.c ++++ b/drivers/mtd/maps/physmap_of_core.c +@@ -239,13 +239,6 @@ static int of_flash_probe(struct platform_device *dev) + else if (of_property_read_bool(dp, "little-endian")) + info->list[i].map.swap = CFI_LITTLE_ENDIAN; + +- err = of_flash_probe_gemini(dev, dp, &info->list[i].map); +- if (err) +- goto err_out; +- err = of_flash_probe_versatile(dev, dp, &info->list[i].map); +- if (err) +- goto err_out; +- + err = -ENOMEM; + info->list[i].map.virt = ioremap(info->list[i].map.phys, + info->list[i].map.size); +@@ -257,6 +250,14 @@ static int of_flash_probe(struct platform_device *dev) + + simple_map_init(&info->list[i].map); + ++ /* Variants can override map accessors */ ++ err = of_flash_probe_gemini(dev, dp, &info->list[i].map); ++ if (err) ++ goto err_out; ++ err = of_flash_probe_versatile(dev, dp, &info->list[i].map); ++ if (err) ++ goto err_out; ++ + /* + * On some platforms (e.g. MPC5200) a direct 1:1 mapping + * may cause problems with JFFS2 usage, as the local bus (LPB) +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0006-mtd-physmap_of_gemini-Handle-pin-control.patch b/target/linux/gemini/patches-4.19/0006-mtd-physmap_of_gemini-Handle-pin-control.patch new file mode 100644 index 0000000000..47aa38a6ab --- /dev/null +++ b/target/linux/gemini/patches-4.19/0006-mtd-physmap_of_gemini-Handle-pin-control.patch @@ -0,0 +1,194 @@ +From 8e5e628a9de439d02914b85a48e1ac3e04ea486a Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Thu, 11 Oct 2018 20:03:49 +0200 +Subject: [PATCH 06/18] mtd: physmap_of_gemini: Handle pin control + +This enables the complex mapping for the Gemini and kicks in +custom read/write functions that will wrap the existing +simple functions in calls to enable/disable the parallel +flash pins using pin controls. + +This is necessary on some hardware such as the D-Link +DIR-685 where all flash pins are patched in/out at the same +time, but some of the flash pins are in practice unused by +the flash and have anyway been reused as GPIO. + +This concerns specifically CE1 on the Gemini. There is only +one flash chip, so only CE0 is used, and the line for CE1 +has been reused as chip select for the emulated SPI port +connected to the display. If we try to use the same lines +for flash and GPIO at the same time, one of them will loose: +the GPIO line will disappear because it gets disconnected +from the pin when the flash group is muxed out. + +Fix this by introducing two pin control states named simply +"enabled" and "disabled" and only enable the flash lines +when absolutely necessary (during read/write/copy). This +way, they are available for GPIO at all other times and +the display works. + +Collect all the state variables in a struct named +struct gemini_flash and allocate this struct at probe +time. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/mtd/maps/Kconfig | 1 + + drivers/mtd/maps/physmap_of_gemini.c | 105 ++++++++++++++++++++++++++- + 2 files changed, 105 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig +index afb36bff13a7..00efbf246849 100644 +--- a/drivers/mtd/maps/Kconfig ++++ b/drivers/mtd/maps/Kconfig +@@ -89,6 +89,7 @@ config MTD_PHYSMAP_OF_GEMINI + depends on MTD_PHYSMAP_OF + depends on MFD_SYSCON + default ARCH_GEMINI ++ select MTD_COMPLEX_MAPPINGS + help + This provides some extra DT physmap parsing for the Gemini + platforms, some detection and setting up parallel mode on the +diff --git a/drivers/mtd/maps/physmap_of_gemini.c b/drivers/mtd/maps/physmap_of_gemini.c +index 830b1b7e702b..7c2b67460192 100644 +--- a/drivers/mtd/maps/physmap_of_gemini.c ++++ b/drivers/mtd/maps/physmap_of_gemini.c +@@ -10,9 +10,11 @@ + #include <linux/of.h> + #include <linux/of_device.h> + #include <linux/mtd/map.h> ++#include <linux/mtd/xip.h> + #include <linux/mfd/syscon.h> + #include <linux/regmap.h> + #include <linux/bitops.h> ++#include <linux/pinctrl/consumer.h> + #include "physmap_of_gemini.h" + + /* +@@ -49,6 +51,77 @@ static const struct of_device_id syscon_match[] = { + { }, + }; + ++struct gemini_flash { ++ struct device *dev; ++ struct pinctrl *p; ++ struct pinctrl_state *enabled_state; ++ struct pinctrl_state *disabled_state; ++}; ++ ++/* Static local state */ ++static struct gemini_flash *gf; ++ ++static void gemini_flash_enable_pins(void) ++{ ++ int ret; ++ ++ if (IS_ERR(gf->enabled_state)) ++ return; ++ ret = pinctrl_select_state(gf->p, gf->enabled_state); ++ if (ret) ++ dev_err(gf->dev, "failed to enable pins\n"); ++} ++ ++static void gemini_flash_disable_pins(void) ++{ ++ int ret; ++ ++ if (IS_ERR(gf->disabled_state)) ++ return; ++ ret = pinctrl_select_state(gf->p, gf->disabled_state); ++ if (ret) ++ dev_err(gf->dev, "failed to disable pins\n"); ++} ++ ++static map_word __xipram gemini_flash_map_read(struct map_info *map, ++ unsigned long ofs) ++{ ++ map_word __xipram ret; ++ ++ gemini_flash_enable_pins(); ++ ret = inline_map_read(map, ofs); ++ gemini_flash_disable_pins(); ++ ++ return ret; ++} ++ ++static void __xipram gemini_flash_map_write(struct map_info *map, ++ const map_word datum, ++ unsigned long ofs) ++{ ++ gemini_flash_enable_pins(); ++ inline_map_write(map, datum, ofs); ++ gemini_flash_disable_pins(); ++} ++ ++static void __xipram gemini_flash_map_copy_from(struct map_info *map, ++ void *to, unsigned long from, ++ ssize_t len) ++{ ++ gemini_flash_enable_pins(); ++ inline_map_copy_from(map, to, from, len); ++ gemini_flash_disable_pins(); ++} ++ ++static void __xipram gemini_flash_map_copy_to(struct map_info *map, ++ unsigned long to, ++ const void *from, ssize_t len) ++{ ++ gemini_flash_enable_pins(); ++ inline_map_copy_to(map, to, from, len); ++ gemini_flash_disable_pins(); ++} ++ + int of_flash_probe_gemini(struct platform_device *pdev, + struct device_node *np, + struct map_info *map) +@@ -62,6 +135,11 @@ int of_flash_probe_gemini(struct platform_device *pdev, + if (!of_device_is_compatible(np, "cortina,gemini-flash")) + return 0; + ++ gf = devm_kzalloc(dev, sizeof(*gf), GFP_KERNEL); ++ if (!gf) ++ return -ENOMEM; ++ gf->dev = dev; ++ + rmap = syscon_regmap_lookup_by_phandle(np, "syscon"); + if (IS_ERR(rmap)) { + dev_err(dev, "no syscon\n"); +@@ -96,7 +174,32 @@ int of_flash_probe_gemini(struct platform_device *pdev, + map->bankwidth * 8); + } + +- dev_info(&pdev->dev, "initialized Gemini-specific physmap control\n"); ++ gf->p = devm_pinctrl_get(dev); ++ if (IS_ERR(gf->p)) { ++ dev_err(dev, "no pinctrl handle\n"); ++ ret = PTR_ERR(gf->p); ++ return ret; ++ } ++ ++ gf->enabled_state = pinctrl_lookup_state(gf->p, "enabled"); ++ if (IS_ERR(gf->enabled_state)) ++ dev_err(dev, "no enabled pin control state\n"); ++ ++ gf->disabled_state = pinctrl_lookup_state(gf->p, "disabled"); ++ if (IS_ERR(gf->enabled_state)) { ++ dev_err(dev, "no disabled pin control state\n"); ++ } else { ++ ret = pinctrl_select_state(gf->p, gf->disabled_state); ++ if (ret) ++ dev_err(gf->dev, "failed to disable pins\n"); ++ } ++ ++ map->read = gemini_flash_map_read; ++ map->write = gemini_flash_map_write; ++ map->copy_from = gemini_flash_map_copy_from; ++ map->copy_to = gemini_flash_map_copy_to; ++ ++ dev_info(dev, "initialized Gemini-specific physmap control\n"); + + return 0; + } +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0007-ARM-dts-Fix-up-the-D-Link-DIR-685-MTD-partition-info.patch b/target/linux/gemini/patches-4.19/0007-ARM-dts-Fix-up-the-D-Link-DIR-685-MTD-partition-info.patch new file mode 100644 index 0000000000..2e4377ec02 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0007-ARM-dts-Fix-up-the-D-Link-DIR-685-MTD-partition-info.patch @@ -0,0 +1,71 @@ +From 0f6c4817471faf572b5273cdf90160790b0c3b29 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Thu, 17 May 2018 17:00:10 +0200 +Subject: [PATCH 07/18] ARM: dts: Fix up the D-Link DIR-685 MTD partition info + +The vendor firmware was analyzed to get the right idea about +this flash layout. /proc/mtd contains: + +dev: size erasesize name +mtd0: 01e7ff40 00020000 "rootfs" +mtd1: 01f40000 00020000 "upgrade" +mtd2: 00040000 00020000 "rgdb" +mtd3: 00020000 00020000 "nvram" +mtd4: 00040000 00020000 "RedBoot" +mtd5: 00020000 00020000 "LangPack" +mtd6: 02000000 00020000 "flash" + +Here "flash" is obviously the whole device and we know "rootfs" +is a bogus hack to point to a squashfs rootfs inside of the main +"upgrade partition". We know "RedBoot" is the first 0x40000 of +the flash and the "upgrade" partition follows from 0x40000 to +0x1f8000. So we have mtd0, 1, 4 and 6 covered. + +Remains: +mtd2: 00040000 00020000 "rgdb" +mtd3: 00020000 00020000 "nvram" +mtd5: 00020000 00020000 "LangPack" + +Inspecting the flash at 0x1f8000 and 0x1fa000 reveals each of +these starting with "RGCFG1" so we assume 0x1f8000-1fbfff is +"rgdb" of 0x40000. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + arch/arm/boot/dts/gemini-dlink-dir-685.dts | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +index 6f258b50eb44..502a361d1fe9 100644 +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -274,20 +274,16 @@ + read-only; + }; + /* +- * Between the boot loader and the rootfs is the kernel +- * in a custom Storlink format flashed from the boot +- * menu. The rootfs is in squashfs format. ++ * This firmware image contains the kernel catenated ++ * with the squashfs root filesystem. For some reason ++ * this is called "upgrade" on the vendor system. + */ +- partition@1800c0 { +- label = "rootfs"; +- reg = <0x001800c0 0x01dbff40>; +- read-only; +- }; +- partition@1f40000 { ++ partition@40000 { + label = "upgrade"; +- reg = <0x01f40000 0x00040000>; ++ reg = <0x00040000 0x01f40000>; + read-only; + }; ++ /* RGDB, Residental Gateway Database? */ + partition@1f80000 { + label = "rgdb"; + reg = <0x01f80000 0x00040000>; +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0008-ARM-dts-Enable-Gemini-flash-access.patch b/target/linux/gemini/patches-4.19/0008-ARM-dts-Enable-Gemini-flash-access.patch new file mode 100644 index 0000000000..0fde9197b6 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0008-ARM-dts-Enable-Gemini-flash-access.patch @@ -0,0 +1,169 @@ +From 74631102645df8984acbdf67b731e4d437f27fed Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Thu, 11 Oct 2018 20:06:23 +0200 +Subject: [PATCH 08/18] ARM: dts: Enable Gemini flash access + +Some Gemini platforms have a parallel NOR flash which conflicts +with use cases reusing some of the flash lines (such as CE1) +for GPIO. + +Fix this on the D-Link DIR-685 and Itian SQ201 by creating +"enabled" and "disabled" states for the flash pin control +handle, and rely on the flash handling code to switch this +in and out when accessed so these lines can be used +for GPIO when flash is not accessed, and enable flash +access. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + arch/arm/boot/dts/gemini-dlink-dir-685.dts | 35 +++++++++++++++------- + arch/arm/boot/dts/gemini-sq201.dts | 31 ++++++++++--------- + 2 files changed, 41 insertions(+), 25 deletions(-) + +diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +index 502a361d1fe9..318e9b2ba7dc 100644 +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -64,7 +64,6 @@ + gpio-sck = <&gpio1 5 GPIO_ACTIVE_HIGH>; + gpio-miso = <&gpio1 8 GPIO_ACTIVE_HIGH>; + gpio-mosi = <&gpio1 7 GPIO_ACTIVE_HIGH>; +- /* Collides with pflash CE1, not so cool */ + cs-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; + num-chipselects = <1>; + +@@ -253,15 +252,18 @@ + soc { + flash@30000000 { + /* +- * Flash access is by default disabled, because it +- * collides with the Chip Enable signal for the display +- * panel, that reuse the parallel flash Chip Select 1 +- * (CS1). Enabling flash makes graphics stop working. +- * +- * We might be able to hack around this by letting +- * GPIO poke around in the flash controller registers. ++ * Flash access collides with the Chip Enable signal for ++ * the display panel, that reuse the parallel flash Chip ++ * Select 1 (CS1). We switch the pin control state so we ++ * enable these pins for flash access only when we need ++ * then, and when disabled they can be used for GPIO which ++ * is what the display panel needs. + */ +- /* status = "okay"; */ ++ status = "okay"; ++ pinctrl-names = "enabled", "disabled"; ++ pinctrl-0 = <&pflash_default_pins>; ++ pinctrl-1 = <&pflash_disabled_pins>; ++ + /* 32MB of flash */ + reg = <0x30000000 0x02000000>; + +@@ -327,7 +329,6 @@ + "gpio0cgrp", + "gpio0egrp", + "gpio0fgrp", +- "gpio0ggrp", + "gpio0hgrp"; + }; + }; +@@ -342,6 +343,18 @@ + groups = "gpio1bgrp"; + }; + }; ++ /* ++ * These GPIO groups will be mapped in over some ++ * of the flash pins when the flash is not in ++ * active use. ++ */ ++ pflash_disabled_pins: pinctrl-pflash-disabled { ++ mux { ++ function = "gpio0"; ++ groups = "gpio0ggrp", "gpio0igrp", "gpio0jgrp", ++ "gpio0kgrp"; ++ }; ++ }; + pinctrl-gmii { + mux { + function = "gmii"; +@@ -430,7 +443,7 @@ + }; + + display-controller@6a000000 { +- status = "okay"; ++ status = "disabled"; + + port@0 { + reg = <0>; +diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts +index 66e2845a3edb..79df6ce5bc6a 100644 +--- a/arch/arm/boot/dts/gemini-sq201.dts ++++ b/arch/arm/boot/dts/gemini-sq201.dts +@@ -41,14 +41,12 @@ + compatible = "gpio-leds"; + led-green-info { + label = "sq201:green:info"; +- /* Conflict with parallel flash */ + gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + led-green-usb { + label = "sq201:green:usb"; +- /* Conflict with parallel and NAND flash */ + gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; + default-state = "off"; + linux,default-trigger = "usb-host"; +@@ -126,15 +124,10 @@ + + soc { + flash@30000000 { +- /* +- * Flash access can be enabled, with the side effect +- * of disabling access to GPIO LED on GPIO0[20] which +- * reuse one of the parallel flash chip select lines. +- * Also the default firmware on the machine has the +- * problem that since it uses the flash, the two LEDS +- * on the right become numb. +- */ +- /* status = "okay"; */ ++ status = "okay"; ++ pinctrl-names = "enabled", "disabled"; ++ pinctrl-0 = <&pflash_default_pins>; ++ pinctrl-1 = <&pflash_disabled_pins>; + /* 16MB of flash */ + reg = <0x30000000 0x01000000>; + +@@ -184,9 +177,7 @@ + mux { + function = "gpio0"; + groups = "gpio0fgrp", +- "gpio0ggrp", +- "gpio0hgrp", +- "gpio0kgrp"; ++ "gpio0hgrp"; + }; + }; + /* +@@ -199,6 +190,18 @@ + groups = "gpio1dgrp"; + }; + }; ++ /* ++ * These GPIO groups will be mapped in over some ++ * of the flash pins when the flash is not in ++ * active use. ++ */ ++ pflash_disabled_pins: pinctrl-pflash-disabled { ++ mux { ++ function = "gpio0"; ++ groups = "gpio0ggrp", "gpio0igrp", "gpio0jgrp", ++ "gpio0kgrp"; ++ }; ++ }; + pinctrl-gmii { + mux { + function = "gmii"; +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0009-mtd-partitions-Add-RedBoot-FIS-DT-bindings.patch b/target/linux/gemini/patches-4.19/0009-mtd-partitions-Add-RedBoot-FIS-DT-bindings.patch new file mode 100644 index 0000000000..afcf5111d8 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0009-mtd-partitions-Add-RedBoot-FIS-DT-bindings.patch @@ -0,0 +1,51 @@ +From 3dfe7ff875a64b83de21dad6365225f41f3cdb17 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Fri, 19 Oct 2018 08:22:18 +0200 +Subject: [PATCH 09/18] mtd: partitions: Add RedBoot FIS DT bindings + +This adds device tree bindings for the RedBoot FIS partition +format. + +Cc: devicetree@vger.kernel.org +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + .../bindings/mtd/partitions/redboot-fis.txt | 27 +++++++++++++++++++ + 1 file changed, 27 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt + +diff --git a/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt +new file mode 100644 +index 000000000000..fd0ebe4e3415 +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt +@@ -0,0 +1,27 @@ ++RedBoot FLASH Image System (FIS) Partitions ++=========================================== ++ ++The FLASH Image System (FIS) directory is a flash description ++format closely associated with the RedBoot boot loader. ++ ++It uses one single flash eraseblock in the flash to store an index of ++all images in the flash. ++ ++This block size will vary depending on flash but is typically ++32 KB in size. ++ ++Required properties: ++- compatible : (required) must be "redboot-fis" ++- fis-index-block : (required) a index to the eraseblock containing ++ the FIS directory on this device. On a flash memory with 32KB ++ eraseblocks, 0 means the first eraseblock at 0x00000000, 1 means the ++ second eraseblock at 0x00008000 and so on. ++ ++Example: ++ ++flash@0 { ++ partitions { ++ compatible = "redboot-fis"; ++ fis-index-block = <0>; ++ }; ++}; +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0010-mtd-partitions-Add-second-compatible-for-redboot.patch b/target/linux/gemini/patches-4.19/0010-mtd-partitions-Add-second-compatible-for-redboot.patch new file mode 100644 index 0000000000..451ba3af8b --- /dev/null +++ b/target/linux/gemini/patches-4.19/0010-mtd-partitions-Add-second-compatible-for-redboot.patch @@ -0,0 +1,77 @@ +From e1b9d122030220d8b8176d9e23568e26fa2f9d23 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Fri, 19 Oct 2018 08:56:41 +0200 +Subject: [PATCH 10/18] mtd: partitions: Add second compatible for redboot + +Simple backport of the upstream redboot partition table +bindings that are used in the mainline Linux kernel. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/mtd/redboot.c | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c +index fe3df7437483..e9c21579ba35 100644 +--- a/drivers/mtd/redboot.c ++++ b/drivers/mtd/redboot.c +@@ -25,7 +25,7 @@ + #include <linux/slab.h> + #include <linux/init.h> + #include <linux/vmalloc.h> +- ++#include <linux/of.h> + #include <linux/mtd/mtd.h> + #include <linux/mtd/partitions.h> + #include <linux/module.h> +@@ -56,6 +56,31 @@ static inline int redboot_checksum(struct fis_image_desc *img) + return 1; + } + ++#ifdef CONFIG_OF ++static void parse_redboot_of(struct mtd_info *master) ++{ ++ struct device_node *np; ++ u32 dirblock; ++ int ret; ++ ++ np = mtd_get_of_node(master); ++ if (!np) ++ return; ++ ret = of_property_read_u32(np, "fis-index-block", &dirblock); ++ if (ret) ++ return; ++ /* ++ * Assign the block found in the device tree to the local ++ * directory block pointer. ++ */ ++ directory = dirblock; ++} ++#else ++static void parse_redboot_of(struct mtd_info *master) ++{ ++} ++#endif ++ + static int parse_redboot_partitions(struct mtd_info *master, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +@@ -75,6 +100,7 @@ static int parse_redboot_partitions(struct mtd_info *master, + #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + static char nullstring[] = "unallocated"; + #endif ++ parse_redboot_of(master); + + if ( directory < 0 ) { + offset = master->size + directory * master->erasesize; +@@ -298,6 +324,7 @@ static int parse_redboot_partitions(struct mtd_info *master, + + static const struct of_device_id redboot_parser_of_match_table[] = { + { .compatible = "ecoscentric,redboot-fis-partitions" }, ++ { .compatible = "redboot-fis" }, + {}, + }; + MODULE_DEVICE_TABLE(of, redboot_parser_of_match_table); +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0011-ARM-dts-Fix-up-SQ201-flash-access.patch b/target/linux/gemini/patches-4.19/0011-ARM-dts-Fix-up-SQ201-flash-access.patch new file mode 100644 index 0000000000..2b72dcd63d --- /dev/null +++ b/target/linux/gemini/patches-4.19/0011-ARM-dts-Fix-up-SQ201-flash-access.patch @@ -0,0 +1,73 @@ +From 186692e51e6c40d8ebd05d25f009098eb00f8110 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Fri, 19 Oct 2018 09:00:51 +0200 +Subject: [PATCH 11/18] ARM: dts: Fix up SQ201 flash access + +This sets the partition information on the SQ201 to be read +out from the RedBoot partition table, removes the static +partition table and sets our boot options to mount root from +/dev/mtdblock2 where the initramfs resides. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + arch/arm/boot/dts/gemini-sq201.dts | 37 ++++-------------------------- + 1 file changed, 5 insertions(+), 32 deletions(-) + +diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts +index 79df6ce5bc6a..c5bb24102b75 100644 +--- a/arch/arm/boot/dts/gemini-sq201.dts ++++ b/arch/arm/boot/dts/gemini-sq201.dts +@@ -20,7 +20,7 @@ + }; + + chosen { +- bootargs = "console=ttyS0,115200n8 root=/dev/sda1 rw rootwait"; ++ bootargs = "console=ttyS0,115200n8 root=/dev/mtdblock2 rw rootfstype=squashfs,jffs2 rootwait"; + stdout-path = &uart0; + }; + +@@ -131,37 +131,10 @@ + /* 16MB of flash */ + reg = <0x30000000 0x01000000>; + +- partition@0 { +- label = "RedBoot"; +- reg = <0x00000000 0x00120000>; +- read-only; +- }; +- partition@120000 { +- label = "Kernel"; +- reg = <0x00120000 0x00200000>; +- }; +- partition@320000 { +- label = "Ramdisk"; +- reg = <0x00320000 0x00600000>; +- }; +- partition@920000 { +- label = "Application"; +- reg = <0x00920000 0x00600000>; +- }; +- partition@f20000 { +- label = "VCTL"; +- reg = <0x00f20000 0x00020000>; +- read-only; +- }; +- partition@f40000 { +- label = "CurConf"; +- reg = <0x00f40000 0x000a0000>; +- read-only; +- }; +- partition@fe0000 { +- label = "FIS directory"; +- reg = <0x00fe0000 0x00020000>; +- read-only; ++ partitions { ++ compatible = "redboot-fis"; ++ /* Eraseblock at 0xfe0000 */ ++ fis-index-block = <0x1fc>; + }; + }; + +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0012-ARM-dts-Blank-D-Link-DIR-685-console.patch b/target/linux/gemini/patches-4.19/0012-ARM-dts-Blank-D-Link-DIR-685-console.patch new file mode 100644 index 0000000000..d1b3085a40 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0012-ARM-dts-Blank-D-Link-DIR-685-console.patch @@ -0,0 +1,30 @@ +From ec8b953c92c1dd0e0f1450f4b9a32c60125d4510 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Mon, 27 Aug 2018 00:10:39 +0200 +Subject: [PATCH 12/18] ARM: dts: Blank D-Link DIR-685 console + +Leaving this NAS with display and backlight on heats it up +and dissipates power. Turn off the screen after 4 minutes, +it comes back on when a user touches the keys. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + arch/arm/boot/dts/gemini-dlink-dir-685.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +index 318e9b2ba7dc..850a605124eb 100644 +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -20,7 +20,7 @@ + }; + + chosen { +- bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait"; ++ bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait consoleblank=300"; + stdout-path = "uart0:19200n8"; + }; + +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0013-usb-host-fotg2-add-silicon-clock-handling.patch b/target/linux/gemini/patches-4.19/0013-usb-host-fotg2-add-silicon-clock-handling.patch new file mode 100644 index 0000000000..041717c299 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0013-usb-host-fotg2-add-silicon-clock-handling.patch @@ -0,0 +1,123 @@ +From e76906e8e9dfaeeb22a37706aca493b86e4367bd Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Fri, 21 Apr 2017 20:46:12 +0200 +Subject: [PATCH 13/18] usb: host: fotg2: add silicon clock handling + +When used in a system with software-controlled silicon clocks, +the FOTG210 needs to grab, prepare and enable the clock. + +This is needed on for example the Cortina Gemini, where the +platform will by default gate off the clock unless the +peripheral (in this case the USB driver) grabs and enables +the clock. + +If there is no clock available on the platform, we live +without it. Make sure to percolate probe deferrals. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- +ChangeLog v1->v2: +- Handle probe deferrals on the clock controller, no matter + how unlikely they are. +- Send the patch to get Gemini USB rolling and try to get some + stuff upstream, this patch should be fine on its own. +--- + drivers/usb/host/fotg210-hcd.c | 33 +++++++++++++++++++++++++++++---- + drivers/usb/host/fotg210.h | 3 +++ + 2 files changed, 32 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c +index e64eb47770c8..058ff82ea789 100644 +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -31,6 +31,7 @@ + #include <linux/uaccess.h> + #include <linux/platform_device.h> + #include <linux/io.h> ++#include <linux/clk.h> + + #include <asm/byteorder.h> + #include <asm/irq.h> +@@ -5596,7 +5597,7 @@ static int fotg210_hcd_probe(struct platform_device *pdev) + hcd->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(hcd->regs)) { + retval = PTR_ERR(hcd->regs); +- goto failed; ++ goto failed_put_hcd; + } + + hcd->rsrc_start = res->start; +@@ -5606,22 +5607,42 @@ static int fotg210_hcd_probe(struct platform_device *pdev) + + fotg210->caps = hcd->regs; + ++ /* It's OK not to supply this clock */ ++ fotg210->pclk = clk_get(dev, "PCLK"); ++ if (!IS_ERR(fotg210->pclk)) { ++ retval = clk_prepare_enable(fotg210->pclk); ++ if (retval) { ++ dev_err(dev, "failed to enable PCLK\n"); ++ goto failed_put_hcd; ++ } ++ } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) { ++ /* ++ * Percolate deferrals, for anything else, ++ * just live without the clocking. ++ */ ++ retval = PTR_ERR(fotg210->pclk); ++ goto failed_dis_clk; ++ } ++ + retval = fotg210_setup(hcd); + if (retval) +- goto failed; ++ goto failed_dis_clk; + + fotg210_init(fotg210); + + retval = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (retval) { + dev_err(dev, "failed to add hcd with err %d\n", retval); +- goto failed; ++ goto failed_dis_clk; + } + device_wakeup_enable(hcd->self.controller); + + return retval; + +-failed: ++failed_dis_clk: ++ if (!IS_ERR(fotg210->pclk)) ++ clk_disable_unprepare(fotg210->pclk); ++failed_put_hcd: + usb_put_hcd(hcd); + fail_create_hcd: + dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval); +@@ -5637,6 +5658,10 @@ static int fotg210_hcd_remove(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = dev_get_drvdata(dev); ++ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd); ++ ++ if (!IS_ERR(fotg210->pclk)) ++ clk_disable_unprepare(fotg210->pclk); + + if (!hcd) + return 0; +diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h +index 7fcd785c7bc8..28f6467c0cbf 100644 +--- a/drivers/usb/host/fotg210.h ++++ b/drivers/usb/host/fotg210.h +@@ -182,6 +182,9 @@ struct fotg210_hcd { /* one per controller */ + # define COUNT(x) + #endif + ++ /* silicon clock */ ++ struct clk *pclk; ++ + /* debug files */ + struct dentry *debug_dir; + }; +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0014-usb-host-add-DT-bindings-for-faraday-fotg2.patch b/target/linux/gemini/patches-4.19/0014-usb-host-add-DT-bindings-for-faraday-fotg2.patch new file mode 100644 index 0000000000..7e321f1f8f --- /dev/null +++ b/target/linux/gemini/patches-4.19/0014-usb-host-add-DT-bindings-for-faraday-fotg2.patch @@ -0,0 +1,69 @@ +From f9cfc45c57227448d4239e9582258587aacf34e7 Mon Sep 17 00:00:00 2001 +From: Hans Ulli Kroll <ulli.kroll@googlemail.com> +Date: Wed, 8 Feb 2017 21:00:09 +0100 +Subject: [PATCH 14/18] usb: host: add DT bindings for faraday fotg2 + +This adds device tree bindings for the Faraday FOTG2 +dual-mode host controller. + +Cc: devicetree@vger.kernel.org +Signed-off-by: Hans Ulli Kroll <ulli.kroll@googlemail.com> +Acked-by: Rob Herring <robh@kernel.org> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- +ChangeLog v1->v2: +- Changed "OTH" to "OTG" +- Collected Rob's ACK. +- I don't see any problem with these bindings, but IIRC Hans + had some reservations for the OTG mode, maybe we can strip + some properties like the mini-usb thing and use as a starter + so we can add host mode at least? +--- + .../bindings/usb/faraday,fotg210.txt | 35 +++++++++++++++++++ + 1 file changed, 35 insertions(+) + create mode 100644 Documentation/devicetree/bindings/usb/faraday,fotg210.txt + +diff --git a/Documentation/devicetree/bindings/usb/faraday,fotg210.txt b/Documentation/devicetree/bindings/usb/faraday,fotg210.txt +new file mode 100644 +index 000000000000..06a2286e2054 +--- /dev/null ++++ b/Documentation/devicetree/bindings/usb/faraday,fotg210.txt +@@ -0,0 +1,35 @@ ++Faraday FOTG Host controller ++ ++This OTG-capable USB host controller is found in Cortina Systems ++Gemini and other SoC products. ++ ++Required properties: ++- compatible: should be one of: ++ "faraday,fotg210" ++ "cortina,gemini-usb", "faraday,fotg210" ++- reg: should contain one register range i.e. start and length ++- interrupts: description of the interrupt line ++ ++Optional properties: ++- clocks: should contain the IP block clock ++- clock-names: should be "PCLK" for the IP block clock ++ ++Required properties for "cortina,gemini-usb" compatible: ++- syscon: a phandle to the system controller to access PHY registers ++ ++Optional properties for "cortina,gemini-usb" compatible: ++- cortina,gemini-mini-b: boolean property that indicates that a Mini-B ++ OTG connector is in use ++- wakeup-source: see power/wakeup-source.txt ++ ++Example for Gemini: ++ ++usb@68000000 { ++ compatible = "cortina,gemini-usb", "faraday,fotg210"; ++ reg = <0x68000000 0x1000>; ++ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cc 12>; ++ clock-names = "PCLK"; ++ syscon = <&syscon>; ++ wakeup-source; ++}; +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0015-usb-host-fotg2-add-device-tree-probing.patch b/target/linux/gemini/patches-4.19/0015-usb-host-fotg2-add-device-tree-probing.patch new file mode 100644 index 0000000000..5673352f14 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0015-usb-host-fotg2-add-device-tree-probing.patch @@ -0,0 +1,48 @@ +From 8f45c69ba80a993a6dba2397825b27e11fa9dea7 Mon Sep 17 00:00:00 2001 +From: Hans Ulli Kroll <ulli.kroll@googlemail.com> +Date: Thu, 9 Feb 2017 15:20:49 +0100 +Subject: [PATCH 15/18] usb: host: fotg2: add device tree probing + +Add device tree probing to the fotg2 driver. + +Signed-off-by: Hans Ulli Kroll <ulli.kroll@googlemail.com> +[Drop DMA mask coercion, drivers/of/platform.c does the job] +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/usb/host/fotg210-hcd.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c +index 058ff82ea789..6e4b40cd5916 100644 +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -10,6 +10,7 @@ + * Most of code borrowed from the Linux-3.7 EHCI driver + */ + #include <linux/module.h> ++#include <linux/of.h> + #include <linux/device.h> + #include <linux/dmapool.h> + #include <linux/kernel.h> +@@ -5672,9 +5673,18 @@ static int fotg210_hcd_remove(struct platform_device *pdev) + return 0; + } + ++#ifdef CONFIG_OF ++static const struct of_device_id fotg210_of_match[] = { ++ { .compatible = "faraday,fotg210" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, fotg210_of_match); ++#endif ++ + static struct platform_driver fotg210_hcd_driver = { + .driver = { + .name = "fotg210-hcd", ++ .of_match_table = of_match_ptr(fotg210_of_match), + }, + .probe = fotg210_hcd_probe, + .remove = fotg210_hcd_remove, +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0016-usb-host-fotg2-add-Gemini-specific-handling.patch b/target/linux/gemini/patches-4.19/0016-usb-host-fotg2-add-Gemini-specific-handling.patch new file mode 100644 index 0000000000..55d44b0e10 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0016-usb-host-fotg2-add-Gemini-specific-handling.patch @@ -0,0 +1,138 @@ +From b331ae758123ba20ba41199e007ac33fc0f242e3 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Fri, 21 Apr 2017 22:19:00 +0200 +Subject: [PATCH 16/18] usb: host: fotg2: add Gemini-specific handling + +The Cortina Systems Gemini has bolted on a PHY inside the +silicon that can be handled by six bits in a MISC register in +the system controller. + +If we are running on Gemini, look up a syscon regmap through +a phandle and enable VBUS and optionally the Mini-B connector. + +If the device is flagged as "wakeup-source" using the standard +DT bindings, we also enable this in the global controller for +respective port. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/usb/host/Kconfig | 1 + + drivers/usb/host/fotg210-hcd.c | 76 ++++++++++++++++++++++++++++++++++ + 2 files changed, 77 insertions(+) + +diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +index 1a4ea98cac2a..308d514c9a2a 100644 +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -372,6 +372,7 @@ config USB_ISP1362_HCD + config USB_FOTG210_HCD + tristate "FOTG210 HCD support" + depends on USB && HAS_DMA && HAS_IOMEM ++ select MFD_SYSCON + ---help--- + Faraday FOTG210 is an OTG controller which can be configured as + an USB2.0 host. It is designed to meet USB2.0 EHCI specification +diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c +index 6e4b40cd5916..5abb07f4136f 100644 +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -33,6 +33,10 @@ + #include <linux/platform_device.h> + #include <linux/io.h> + #include <linux/clk.h> ++#include <linux/bitops.h> ++/* For Cortina Gemini */ ++#include <linux/mfd/syscon.h> ++#include <linux/regmap.h> + + #include <asm/byteorder.h> + #include <asm/irq.h> +@@ -5554,6 +5558,72 @@ static void fotg210_init(struct fotg210_hcd *fotg210) + iowrite32(value, &fotg210->regs->otgcsr); + } + ++/* ++ * Gemini-specific initialization function, only executed on the ++ * Gemini SoC using the global misc control register. ++ */ ++#define GEMINI_GLOBAL_MISC_CTRL 0x30 ++#define GEMINI_MISC_USB0_WAKEUP BIT(14) ++#define GEMINI_MISC_USB1_WAKEUP BIT(15) ++#define GEMINI_MISC_USB0_VBUS_ON BIT(22) ++#define GEMINI_MISC_USB1_VBUS_ON BIT(23) ++#define GEMINI_MISC_USB0_MINI_B BIT(29) ++#define GEMINI_MISC_USB1_MINI_B BIT(30) ++ ++static int fotg210_gemini_init(struct device *dev, struct usb_hcd *hcd) ++{ ++ struct device_node *np = dev->of_node; ++ struct regmap *map; ++ bool mini_b; ++ bool wakeup; ++ u32 mask, val; ++ int ret; ++ ++ map = syscon_regmap_lookup_by_phandle(np, "syscon"); ++ if (IS_ERR(map)) { ++ dev_err(dev, "no syscon\n"); ++ return PTR_ERR(map); ++ } ++ mini_b = of_property_read_bool(np, "cortina,gemini-mini-b"); ++ wakeup = of_property_read_bool(np, "wakeup-source"); ++ ++ /* ++ * Figure out if this is USB0 or USB1 by simply checking the ++ * physical base address. ++ */ ++ mask = 0; ++ if (hcd->rsrc_start == 0x69000000) { ++ val = GEMINI_MISC_USB1_VBUS_ON; ++ if (mini_b) ++ val |= GEMINI_MISC_USB1_MINI_B; ++ else ++ mask |= GEMINI_MISC_USB1_MINI_B; ++ if (wakeup) ++ val |= GEMINI_MISC_USB1_WAKEUP; ++ else ++ mask |= GEMINI_MISC_USB1_WAKEUP; ++ } else { ++ val = GEMINI_MISC_USB0_VBUS_ON; ++ if (mini_b) ++ val |= GEMINI_MISC_USB0_MINI_B; ++ else ++ mask |= GEMINI_MISC_USB0_MINI_B; ++ if (wakeup) ++ val |= GEMINI_MISC_USB0_WAKEUP; ++ else ++ mask |= GEMINI_MISC_USB0_WAKEUP; ++ } ++ ++ ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, mask, val); ++ if (ret) { ++ dev_err(dev, "failed to initialize Gemini PHY\n"); ++ return ret; ++ } ++ ++ dev_info(dev, "initialized Gemini PHY\n"); ++ return 0; ++} ++ + /** + * fotg210_hcd_probe - initialize faraday FOTG210 HCDs + * +@@ -5631,6 +5701,12 @@ static int fotg210_hcd_probe(struct platform_device *pdev) + + fotg210_init(fotg210); + ++ if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) { ++ retval = fotg210_gemini_init(dev, hcd); ++ if (retval) ++ goto failed_dis_clk; ++ } ++ + retval = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (retval) { + dev_err(dev, "failed to add hcd with err %d\n", retval); +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0017-usb-host-fotg2-restart-hcd-after-port-reset.patch b/target/linux/gemini/patches-4.19/0017-usb-host-fotg2-restart-hcd-after-port-reset.patch new file mode 100644 index 0000000000..c0dc9201b9 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0017-usb-host-fotg2-restart-hcd-after-port-reset.patch @@ -0,0 +1,32 @@ +From b9d300b5aea18f2e992201d182d939030130aab2 Mon Sep 17 00:00:00 2001 +From: Hans Ulli Kroll <ulli.kroll@googlemail.com> +Date: Sat, 14 Apr 2018 18:49:57 +0200 +Subject: [PATCH 17/18] usb: host: fotg2: restart hcd after port reset + +on Gemini SoC FOTG2 stalls after port reset +rerstart the hcd. + +Signed-off-by: Hans Ulli Kroll <ulli.kroll@googlemail.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/usb/host/fotg210-hcd.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c +index 5abb07f4136f..d15e835c4b1f 100644 +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -1633,6 +1633,10 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + /* see what we found out */ + temp = check_reset_complete(fotg210, wIndex, status_reg, + fotg210_readl(fotg210, status_reg)); ++ ++ /* restart schedule */ ++ fotg210->command |= CMD_RUN; ++ fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command); + } + + if (!(temp & (PORT_RESUME|PORT_RESET))) { +-- +2.19.2 + diff --git a/target/linux/gemini/patches-4.19/0018-ARM-dts-Add-the-FOTG210-USB-host-to-Gemini-boards.patch b/target/linux/gemini/patches-4.19/0018-ARM-dts-Add-the-FOTG210-USB-host-to-Gemini-boards.patch new file mode 100644 index 0000000000..9247f0b421 --- /dev/null +++ b/target/linux/gemini/patches-4.19/0018-ARM-dts-Add-the-FOTG210-USB-host-to-Gemini-boards.patch @@ -0,0 +1,210 @@ +From 1ff9a279dbeb0034929042faef186ce934474c2b Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Fri, 21 Apr 2017 20:50:22 +0200 +Subject: [PATCH 18/18] ARM: dts: Add the FOTG210 USB host to Gemini boards + +This adds the FOTG210 USB host controller to the Gemini +device trees. In the main SoC DTSI it is flagged as disabled +and then it is selectively enabled on the devices that utilize +it. + +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- +ChangeLog v1->v2: +- Rebased to kernel v4.19-rc1 +- Drop pinctrl-0 handle from the second USB port +- Add comment on how to deal with the USB pin control +--- + arch/arm/boot/dts/gemini-dlink-dir-685.dts | 8 ++++++ + arch/arm/boot/dts/gemini-nas4220b.dts | 8 ++++++ + arch/arm/boot/dts/gemini-rut1xx.dts | 20 ++++++++++++++ + arch/arm/boot/dts/gemini-sl93512r.dts | 8 ++++++ + arch/arm/boot/dts/gemini-sq201.dts | 8 ++++++ + arch/arm/boot/dts/gemini-wbd111.dts | 8 ++++++ + arch/arm/boot/dts/gemini-wbd222.dts | 8 ++++++ + arch/arm/boot/dts/gemini.dtsi | 32 ++++++++++++++++++++++ + 8 files changed, 100 insertions(+) + +diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +index 850a605124eb..848b16375873 100644 +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -452,5 +452,13 @@ + }; + }; + }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts +index 963ea890c87f..53b65ebe8454 100644 +--- a/arch/arm/boot/dts/gemini-nas4220b.dts ++++ b/arch/arm/boot/dts/gemini-nas4220b.dts +@@ -204,5 +204,13 @@ + ata@63400000 { + status = "okay"; + }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/gemini-rut1xx.dts b/arch/arm/boot/dts/gemini-rut1xx.dts +index eb4f0bf074da..b2354c215a84 100644 +--- a/arch/arm/boot/dts/gemini-rut1xx.dts ++++ b/arch/arm/boot/dts/gemini-rut1xx.dts +@@ -124,5 +124,25 @@ + /* Not used in this platform */ + }; + }; ++ ++ ethernet@60000000 { ++ status = "okay"; ++ ++ ethernet-port@0 { ++ phy-mode = "rgmii"; ++ phy-handle = <&phy0>; ++ }; ++ ethernet-port@1 { ++ /* Not used in this platform */ ++ }; ++ }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/gemini-sl93512r.dts b/arch/arm/boot/dts/gemini-sl93512r.dts +index ebefb7297379..2bb953440793 100644 +--- a/arch/arm/boot/dts/gemini-sl93512r.dts ++++ b/arch/arm/boot/dts/gemini-sl93512r.dts +@@ -324,5 +324,13 @@ + ata@63400000 { + status = "okay"; + }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts +index c5bb24102b75..ecbc27d93b2d 100644 +--- a/arch/arm/boot/dts/gemini-sq201.dts ++++ b/arch/arm/boot/dts/gemini-sq201.dts +@@ -292,5 +292,13 @@ + ata@63000000 { + status = "okay"; + }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/gemini-wbd111.dts b/arch/arm/boot/dts/gemini-wbd111.dts +index 29af86cd10f7..6831d2aed17a 100644 +--- a/arch/arm/boot/dts/gemini-wbd111.dts ++++ b/arch/arm/boot/dts/gemini-wbd111.dts +@@ -171,5 +171,13 @@ + /* Not used in this platform */ + }; + }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/gemini-wbd222.dts b/arch/arm/boot/dts/gemini-wbd222.dts +index 24e6ae3616f7..ed38d48ef5f6 100644 +--- a/arch/arm/boot/dts/gemini-wbd222.dts ++++ b/arch/arm/boot/dts/gemini-wbd222.dts +@@ -183,5 +183,13 @@ + phy-handle = <&phy1>; + }; + }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi +index eb752e9495de..8cf67b11751f 100644 +--- a/arch/arm/boot/dts/gemini.dtsi ++++ b/arch/arm/boot/dts/gemini.dtsi +@@ -409,5 +409,37 @@ + #size-cells = <0>; + status = "disabled"; + }; ++ ++ usb@68000000 { ++ compatible = "cortina,gemini-usb", "faraday,fotg210"; ++ reg = <0x68000000 0x1000>; ++ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>; ++ resets = <&syscon GEMINI_RESET_USB0>; ++ clocks = <&syscon GEMINI_CLK_GATE_USB0>; ++ clock-names = "PCLK"; ++ /* ++ * This will claim pins for USB0 and USB1 at the same ++ * time as they are using some common pins. If you for ++ * some reason have a system using USB1 at 96000000 but ++ * NOT using USB0 at 68000000 you wll have to add the ++ * usb_default_pins to the USB controller at 96000000 ++ * in your .dts for the board. ++ */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb_default_pins>; ++ syscon = <&syscon>; ++ status = "disabled"; ++ }; ++ ++ usb@69000000 { ++ compatible = "cortina,gemini-usb", "faraday,fotg210"; ++ reg = <0x69000000 0x1000>; ++ interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; ++ resets = <&syscon GEMINI_RESET_USB1>; ++ clocks = <&syscon GEMINI_CLK_GATE_USB1>; ++ clock-names = "PCLK"; ++ syscon = <&syscon>; ++ status = "disabled"; ++ }; + }; + }; +-- +2.19.2 + |