From e985e89cae379aad706654f2275a70caab3542e8 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Tue, 22 May 2018 18:44:30 +0800 Subject: [PATCH] update linux target patch --- .../ath79/base-files/etc/board.d/01_leds | 11 + .../ath79/base-files/etc/board.d/02_network | 15 + target/linux/ath79/base-files/etc/diag.sh | 4 + .../etc/hotplug.d/firmware/10-ath9k-eeprom | 21 + .../ath79/base-files/lib/upgrade/platform.sh | 208 +- target/linux/ath79/config-4.14 | 13 +- target/linux/ath79/dts/ar7241_ubnt-xm.dts | 13 - ...-bullet-m.dts => ar7241_ubnt_bullet-m.dts} | 4 +- ...ubnt-nano-m.dts => ar7241_ubnt_nano-m.dts} | 4 +- ...-rocket-m.dts => ar7241_ubnt_rocket-m.dts} | 4 +- ...1_ubnt-unifi.dts => ar7241_ubnt_unifi.dts} | 0 ...r7241_ubnt-xm.dtsi => ar7241_ubnt_xm.dtsi} | 0 .../linux/ath79/dts/ar7242_avm_fritz300e.dts | 169 + target/linux/ath79/dts/ar724x.dtsi | 5 +- target/linux/ath79/dts/ar9132.dtsi | 4 + ...0_gl_ar150.dts => ar9330_glinet_ar150.dts} | 2 +- target/linux/ath79/dts/ar9331_dpt_module.dts | 2 +- .../linux/ath79/dts/ar9331_dragino_ms14.dts | 2 +- ....dts => ar9331_embeddedwireless_dorin.dts} | 2 +- target/linux/ath79/dts/ar9331_omega.dts | 2 +- target/linux/ath79/dts/ar9331_tl_mr3020.dts | 2 +- ...ac.dts => qca9558_openmesh_om5p-ac-v2.dts} | 0 target/linux/ath79/generic/config-default | 8 +- target/linux/ath79/image/Makefile | 22 +- .../image/{tp-link.mk => generic-tp-link.mk} | 62 +- target/linux/ath79/image/generic-ubnt.mk | 228 +- target/linux/ath79/image/generic.mk | 79 +- target/linux/ath79/image/legacy.mk | 1058 ----- .../902-at803x-add-reset-gpio-pdata.patch | 68 - target/linux/gemini/Makefile | 17 +- .../lib/preinit/05_set_ether_mac_gemini | 25 +- target/linux/gemini/config-4.14 | 445 ++ target/linux/gemini/config-4.4 | 165 - .../arch/arm/mach-gemini/include/mach/gmac.h | 21 - .../gemini/files/arch/arm/mach-gemini/pci.c | 318 -- .../gemini/files/drivers/ata/pata_gemini.c | 234 - .../files/drivers/net/ethernet/gemini/Kconfig | 31 - .../drivers/net/ethernet/gemini/Makefile | 5 - .../drivers/net/ethernet/gemini/sl351x.c | 2340 --------- .../drivers/net/ethernet/gemini/sl351x_hw.h | 1436 ------ .../files/drivers/usb/host/ehci-fotg2.c | 258 - .../files/drivers/watchdog/gemini_wdt.c | 378 -- target/linux/gemini/image/Makefile | 185 +- .../0001-cache-patch-from-OpenWRT.patch} | 9 + ...pinctrl-gemini-Add-missing-functions.patch | 33 + ...ts-Add-TVE200-to-the-Gemini-SoC-DTSI.patch | 51 + ...d-skew-delay-pin-config-and-bindings.patch | 73 + ...pinctrl-gemini-Use-generic-DT-parser.patch | 112 + ...ni-Implement-clock-skew-delay-config.patch | 280 ++ .../0007-pinctrl-gemini-Fix-GMAC-groups.patch | 186 + ...-gemini-Fix-missing-pad-descriptions.patch | 27 + ...l-gemini-Add-two-missing-GPIO-groups.patch | 25 + ...ctrl-gemini-Fix-usage-of-3512-groups.patch | 25 + ...emini-Support-drive-strength-setting.patch | 198 + ...ernet-PHYs-to-the-a-bunch-of-Geminis.patch | 113 + ...-basic-devicetree-for-D-Link-DNS-313.patch | 272 ++ ...s-Flags-D-Link-DIR-685-I2C-bus-gpios.patch | 27 + ...ARM-dts-Add-PCI-to-WBD111-and-WBD222.patch | 74 + ...TVE-TVC-and-ILI9322-panel-to-DIR-685.patch | 113 + ...g-gemini-ftwdt010-rename-DT-bindings.patch | 88 + ...i-ftwdt010-rename-driver-and-symbols.patch | 527 ++ ...dog-ftwdt010-Make-interrupt-optional.patch | 93 + .../0020-soc-Add-SoC-driver-for-Gemini.patch | 113 + ...-DT-bindings-for-the-Gemini-ethernet.patch | 119 + ...-a-driver-for-Gemini-gigabit-etherne.patch | 3661 ++++++++++++++ ...M-dts-Add-ethernet-to-the-Gemini-SoC.patch | 74 + .../0024-net-gemini-Depend-on-HAS_IOMEM.patch | 30 + ...Set-D-Link-DNS-313-SATA-to-muxmode-0.patch | 36 + ...ini-poweroff-Avoid-spurious-poweroff.patch | 80 + ...st-add-DT-bindings-for-faraday-fotg2.patch | 65 + ...b-host-fotg2-add-device-tree-probing.patch | 61 + ...ost-fotg2-add-silicon-clock-handling.patch | 99 + ...t-fotg2-add-Gemini-specific-handling.patch | 131 + ...s-Add-the-FOTG210-USB-host-to-Gemini.patch | 178 + ...t-fotg2-restart-hcd-after-port-reset.patch | 26 + ...x-bootargs-for-Gemini-D-Link-devices.patch | 38 + ...Add-ethernet-to-a-bunch-of-platforms.patch | 116 + ...-add-openwrt-partitions-for-nas4220b.patch | 17 + ...dts-gemini-fix-ethernet-for-nas4220b.patch | 69 + ...s-gemini-add-second-ata-for-nas4220b.patch | 13 + ...emini-disable-usb-port-1-until-fixed.patch | 11 + ...ix-uninitialized-struct-member-usage.patch | 23 + ...s-gemini-dlink-dir-685-add-rtl8366rb.patch | 82 + .../gemini/patches-4.4/050-gpio-to-irq.patch | 21 - .../110-watchdog-add-gemini_wdt-driver.patch | 29 - .../111-arm-gemini-add-watchdog-device.patch | 33 - ...arm-gemini-register-watchdog-devices.patch | 40 - .../120-net-add-gemini-gmac-driver.patch | 20 - .../121-arm-gemini-add-gmac-device.patch | 85 - .../122-arm-gemini-register-ethernet.patch | 227 - .../130-usb-ehci-add-fot2g-driver.patch | 133 - .../131-arm-gemini-add-usb-device.patch | 77 - .../132-arm-gemini-register-usb.patch | 65 - .../140-arm-gemini-add-pci-support.patch | 66 - .../gemini/patches-4.4/150-gemini-pata.patch | 192 - target/linux/gemini/raidsonic/config-default | 5 - target/linux/gemini/raidsonic/target.mk | 17 - target/linux/gemini/wiligear/target.mk | 10 - ...ption-fix-dwm-158-3g-modem-interface.patch | 42 + ...port-for-host-mode-external-vbus-sup.patch | 109 + ...wc2_vbus_supply_init-fix-error-check.patch | 55 + ...ding-registering-partitions-to-the-p.patch | 168 + ...improve-handling-TRX-partition-size.patch} | 7 +- ...es-explicit-nft_set_pktinfo-call-fr.patch} | 0 ...ly-allow-one-nat-hook-per-hook-poin.patch} | 0 ...es_inet-don-t-use-multihook-infrast.patch} | 0 ...es-remove-multihook-chains-and-fami.patch} | 0 ...ecksum-indirection-to-struct-nf_ipv.patch} | 0 ...ecksum_partial-indirection-to-struc.patch} | 0 ...saveroute-indirection-in-struct-nf_.patch} | 0 ...ute-indirection-to-struct-nf_ipv6_o.patch} | 0 ...route-indirection-to-struct-nf_ipv6.patch} | 0 ...route_key_size-field-in-struct-nf_a.patch} | 0 ...struct-nf_afinfo-and-its-helper-fun.patch} | 0 ..._tables_arp-don-t-set-forward-chain.patch} | 0 ...es-remove-hooks-from-family-definit.patch} | 0 ...defensive-check-on-malformed-packet.patch} | 0 ...4.16-netfilter-meta-secpath-support.patch} | 0 ...ck-move-nf_ct_netns_-get-put-to-cor.patch} | 0 ...onntrack-add-IPS_OFFLOAD-status-bit.patch} | 0 ...les-add-flow-table-netlink-frontend.patch} | 0 ...d-generic-flow-table-infrastructure.patch} | 0 ...tfilter-flow-table-support-for-IPv4.patch} | 0 ...tfilter-flow-table-support-for-IPv6.patch} | 0 ...ble-support-for-the-mixed-IPv4-IPv6.patch} | 0 ...r-nf_tables-flow-offload-expression.patch} | 0 ...es-remove-nhooks-field-from-struct-.patch} | 0 ...es-fix-a-typo-in-nf_tables_getflowt.patch} | 0 ...ove-flow-table-Kconfig-dependencies.patch} | 0 ...es-remove-flag-field-from-struct-nf.patch} | 0 ...es-no-need-for-struct-nft_af_info-t.patch} | 0 ...es-remove-struct-nft_af_info-parame.patch} | 0 ...es-fix-potential-NULL-ptr-deref-in-.patch} | 0 ...es-add-single-table-list-for-all-fa.patch} | 0 ...filter-exit_net-cleanup-check-added.patch} | 0 ...f_tables-get-rid-of-pernet-families.patch} | 0 ...es-get-rid-of-struct-nft_af_info-ab.patch} | 0 ...w_offload-wait-for-garbage-collecto.patch} | 0 ...w_offload-no-need-to-flush-entries-.patch} | 0 ...w_offload-move-flowtable-cleanup-ro.patch} | 0 ...filter-nf_tables-fix-flowtable-free.patch} | 0 ...es-allocate-handle-and-delete-objec.patch} | 0 ..._offload-fix-use-after-free-and-a-r.patch} | 0 ...le-infrastructure-depends-on-NETFIL.patch} | 0 ...netfilter-remove-duplicated-include.patch} | 0 ..._table-use-IP_CT_DIR_-values-for-FL.patch} | 0 ...w_table-clean-up-flow_offload_alloc.patch} | 0 ...pv6-make-ip6_dst_mtu_forward-inline.patch} | 0 ..._table-cache-mtu-in-struct-flow_off.patch} | 0 ..._table-rename-nf_flow_table.c-to-nf.patch} | 0 ..._table-move-ipv4-offload-hook-code-.patch} | 0 ..._table-move-ip-header-check-out-of-.patch} | 0 ..._table-move-ipv6-offload-hook-code-.patch} | 0 ..._table-relax-mixed-ipv4-ipv6-flowta.patch} | 0 ..._table-move-init-code-to-nf_flow_ta.patch} | 0 ..._table-fix-priv-pointer-for-netdev-.patch} | 0 ..._table-track-flow-tables-in-nf_flow.patch} | 0 ..._table-make-flow_offload_dead-inlin.patch} | 0 ..._table-add-a-new-flow-state-for-tea.patch} | 0 ..._table-in-flow_offload_lookup-skip-.patch} | 0 ..._table-add-support-for-sending-flow.patch} | 0 ..._table-tear-down-TCP-flows-if-RST-o.patch} | 0 ..._table-fix-checksum-when-handling-D.patch} | 0 ..._table-add-missing-condition-for-TC.patch} | 0 ..._table-fix-offloading-connections-w.patch} | 0 target/linux/generic/config-4.14 | 12 +- ...orruption-related-to-cache-coherence.patch | 90 + ...-generic-parsing-of-linux-part-probe.patch | 8 +- .../400-mtd-add-rootfs-split-support.patch | 6 +- ...for-different-partition-parser-types.patch | 2 +- ...arsers-for-rootfs-and-firmware-split.patch | 6 +- .../404-mtd-add-more-helper-functions.patch | 4 +- .../411-mtd-partial_eraseblock_write.patch | 2 +- .../479-mtd-spi-nor-add-eon-en25qh32.patch | 10 + ...-support-hardware-flow-table-offload.patch | 17 +- ...-support-hardware-flow-table-offload.patch | 12 +- ...-support-hardware-flow-table-offload.patch | 29 +- ...ng-with-source-address-failed-policy.patch | 22 +- .../ramips/base-files/etc/board.d/02_network | 5 +- target/linux/ramips/base-files/etc/diag.sh | 3 +- target/linux/ramips/base-files/lib/ramips.sh | 6 +- .../ramips/base-files/lib/upgrade/platform.sh | 5 +- .../ramips/base-files/sbin/fixup-mac-address | 3 +- target/linux/ramips/dts/BOCCO.dts | 162 + target/linux/ramips/dts/MT7628.dts | 2 +- target/linux/ramips/dts/WD03.dts | 112 + target/linux/ramips/dts/WITI-256M.dts | 13 + target/linux/ramips/dts/WITI-512M.dts | 13 + .../linux/ramips/dts/{WITI.dts => WITI.dtsi} | 6 - target/linux/ramips/dts/mt7620n.dtsi | 23 + target/linux/ramips/dts/mt7621.dtsi | 9 +- .../files-4.14/arch/mips/pci/pci-mt7621.c | 698 +++ .../drivers/mmc/host/mtk-mmc/board.h | 82 +- .../files-4.14/drivers/mmc/host/mtk-mmc/dbg.c | 388 +- .../files-4.14/drivers/mmc/host/mtk-mmc/dbg.h | 93 +- .../drivers/mmc/host/mtk-mmc/mt6575_sd.h | 1070 ++--- .../files-4.14/drivers/mmc/host/mtk-mmc/sd.c | 4225 +++++++---------- .../drivers/net/ethernet/mtk/esw_rt3050.c | 4 +- .../drivers/net/ethernet/mtk/gsw_mt7620.c | 4 +- .../drivers/net/ethernet/mtk/gsw_mt7621.c | 4 +- .../drivers/net/ethernet/mtk/mdio.c | 4 +- .../drivers/net/ethernet/mtk/mtk_eth_soc.c | 2 +- target/linux/ramips/image/mt7620.mk | 15 + target/linux/ramips/image/mt7621.mk | 19 +- target/linux/ramips/image/mt76x8.mk | 1 + target/linux/ramips/image/rt288x.mk | 4 +- target/linux/ramips/mt7620/config-4.14 | 7 - target/linux/ramips/mt76x8/config-4.14 | 7 - ...4-MIPS-ralink-add-MT7621-pcie-driver.patch | 843 +--- .../0032-USB-dwc2-add-device_reset.patch | 2 +- .../0039-mtd-add-mt7621-nand-support.patch | 13 +- .../0040-nand-hack-restore-write_page.patch | 42 - .../ramips/patches-4.14/0040-nand-hack.patch | 61 +- .../0043-spi-add-mt7621-support.patch | 8 +- target/linux/ramips/rt288x/config-4.14 | 7 - target/linux/ramips/rt3883/config-4.14 | 7 - 216 files changed, 12531 insertions(+), 12300 deletions(-) mode change 100644 => 100755 target/linux/ath79/base-files/etc/board.d/01_leds mode change 100644 => 100755 target/linux/ath79/base-files/etc/board.d/02_network delete mode 100644 target/linux/ath79/dts/ar7241_ubnt-xm.dts rename target/linux/ath79/dts/{ar7241_ubnt-bullet-m.dts => ar7241_ubnt_bullet-m.dts} (64%) rename target/linux/ath79/dts/{ar7241_ubnt-nano-m.dts => ar7241_ubnt_nano-m.dts} (58%) rename target/linux/ath79/dts/{ar7241_ubnt-rocket-m.dts => ar7241_ubnt_rocket-m.dts} (72%) rename target/linux/ath79/dts/{ar7241_ubnt-unifi.dts => ar7241_ubnt_unifi.dts} (100%) rename target/linux/ath79/dts/{ar7241_ubnt-xm.dtsi => ar7241_ubnt_xm.dtsi} (100%) create mode 100644 target/linux/ath79/dts/ar7242_avm_fritz300e.dts rename target/linux/ath79/dts/{ar9330_gl_ar150.dts => ar9330_glinet_ar150.dts} (98%) rename target/linux/ath79/dts/{ar9331_ew_dorin.dts => ar9331_embeddedwireless_dorin.dts} (97%) rename target/linux/ath79/dts/{qca9558_om5p_ac.dts => qca9558_openmesh_om5p-ac-v2.dts} (100%) rename target/linux/ath79/image/{tp-link.mk => generic-tp-link.mk} (56%) delete mode 100644 target/linux/ath79/image/legacy.mk delete mode 100644 target/linux/ath79/patches-4.14/902-at803x-add-reset-gpio-pdata.patch create mode 100644 target/linux/gemini/config-4.14 delete mode 100644 target/linux/gemini/config-4.4 delete mode 100644 target/linux/gemini/files/arch/arm/mach-gemini/include/mach/gmac.h delete mode 100644 target/linux/gemini/files/arch/arm/mach-gemini/pci.c delete mode 100644 target/linux/gemini/files/drivers/ata/pata_gemini.c delete mode 100644 target/linux/gemini/files/drivers/net/ethernet/gemini/Kconfig delete mode 100644 target/linux/gemini/files/drivers/net/ethernet/gemini/Makefile delete mode 100644 target/linux/gemini/files/drivers/net/ethernet/gemini/sl351x.c delete mode 100644 target/linux/gemini/files/drivers/net/ethernet/gemini/sl351x_hw.h delete mode 100644 target/linux/gemini/files/drivers/usb/host/ehci-fotg2.c delete mode 100644 target/linux/gemini/files/drivers/watchdog/gemini_wdt.c rename target/linux/gemini/{patches-4.4/060-cache-fa.patch => patches-4.14/0001-cache-patch-from-OpenWRT.patch} (79%) create mode 100644 target/linux/gemini/patches-4.14/0002-pinctrl-gemini-Add-missing-functions.patch create mode 100644 target/linux/gemini/patches-4.14/0003-ARM-dts-Add-TVE200-to-the-Gemini-SoC-DTSI.patch create mode 100644 target/linux/gemini/patches-4.14/0004-pinctrl-Add-skew-delay-pin-config-and-bindings.patch create mode 100644 target/linux/gemini/patches-4.14/0005-pinctrl-gemini-Use-generic-DT-parser.patch create mode 100644 target/linux/gemini/patches-4.14/0006-pinctrl-gemini-Implement-clock-skew-delay-config.patch create mode 100644 target/linux/gemini/patches-4.14/0007-pinctrl-gemini-Fix-GMAC-groups.patch create mode 100644 target/linux/gemini/patches-4.14/0008-pinctrl-gemini-Fix-missing-pad-descriptions.patch create mode 100644 target/linux/gemini/patches-4.14/0009-pinctrl-gemini-Add-two-missing-GPIO-groups.patch create mode 100644 target/linux/gemini/patches-4.14/0010-pinctrl-gemini-Fix-usage-of-3512-groups.patch create mode 100644 target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch create mode 100644 target/linux/gemini/patches-4.14/0012-ARM-dts-Add-ethernet-PHYs-to-the-a-bunch-of-Geminis.patch create mode 100644 target/linux/gemini/patches-4.14/0013-ARM-dts-Add-basic-devicetree-for-D-Link-DNS-313.patch create mode 100644 target/linux/gemini/patches-4.14/0014-ARM-dts-Flags-D-Link-DIR-685-I2C-bus-gpios.patch create mode 100644 target/linux/gemini/patches-4.14/0015-ARM-dts-Add-PCI-to-WBD111-and-WBD222.patch create mode 100644 target/linux/gemini/patches-4.14/0016-ARM-dts-Add-TVE-TVC-and-ILI9322-panel-to-DIR-685.patch create mode 100644 target/linux/gemini/patches-4.14/0017-watchdog-gemini-ftwdt010-rename-DT-bindings.patch create mode 100644 target/linux/gemini/patches-4.14/0018-watchdog-gemini-ftwdt010-rename-driver-and-symbols.patch create mode 100644 target/linux/gemini/patches-4.14/0019-watchdog-ftwdt010-Make-interrupt-optional.patch create mode 100644 target/linux/gemini/patches-4.14/0020-soc-Add-SoC-driver-for-Gemini.patch create mode 100644 target/linux/gemini/patches-4.14/0021-net-ethernet-Add-DT-bindings-for-the-Gemini-ethernet.patch create mode 100644 target/linux/gemini/patches-4.14/0022-net-ethernet-Add-a-driver-for-Gemini-gigabit-etherne.patch create mode 100644 target/linux/gemini/patches-4.14/0023-ARM-dts-Add-ethernet-to-the-Gemini-SoC.patch create mode 100644 target/linux/gemini/patches-4.14/0024-net-gemini-Depend-on-HAS_IOMEM.patch create mode 100644 target/linux/gemini/patches-4.14/0025-ARM-dts-Set-D-Link-DNS-313-SATA-to-muxmode-0.patch create mode 100644 target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch create mode 100644 target/linux/gemini/patches-4.14/0027-usb-host-add-DT-bindings-for-faraday-fotg2.patch create mode 100644 target/linux/gemini/patches-4.14/0028-usb-host-fotg2-add-device-tree-probing.patch create mode 100644 target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch create mode 100644 target/linux/gemini/patches-4.14/0030-usb-host-fotg2-add-Gemini-specific-handling.patch create mode 100644 target/linux/gemini/patches-4.14/0031-ARM-dts-Add-the-FOTG210-USB-host-to-Gemini.patch create mode 100644 target/linux/gemini/patches-4.14/0032-usb-host-fotg2-restart-hcd-after-port-reset.patch create mode 100644 target/linux/gemini/patches-4.14/0033-ARM-dts-Fix-bootargs-for-Gemini-D-Link-devices.patch create mode 100644 target/linux/gemini/patches-4.14/0034-ARM-dts-Add-ethernet-to-a-bunch-of-platforms.patch create mode 100644 target/linux/gemini/patches-4.14/0900-arm-dts-gemini-add-openwrt-partitions-for-nas4220b.patch create mode 100644 target/linux/gemini/patches-4.14/0901-arm-dts-gemini-fix-ethernet-for-nas4220b.patch create mode 100644 target/linux/gemini/patches-4.14/0902-arm-dts-gemini-add-second-ata-for-nas4220b.patch create mode 100644 target/linux/gemini/patches-4.14/0903-arm-dts-gemini-disable-usb-port-1-until-fixed.patch create mode 100644 target/linux/gemini/patches-4.14/0904-net-cortina-fix-uninitialized-struct-member-usage.patch create mode 100644 target/linux/gemini/patches-4.14/0905-arm-dts-gemini-dlink-dir-685-add-rtl8366rb.patch delete mode 100644 target/linux/gemini/patches-4.4/050-gpio-to-irq.patch delete mode 100644 target/linux/gemini/patches-4.4/110-watchdog-add-gemini_wdt-driver.patch delete mode 100644 target/linux/gemini/patches-4.4/111-arm-gemini-add-watchdog-device.patch delete mode 100644 target/linux/gemini/patches-4.4/112-arm-gemini-register-watchdog-devices.patch delete mode 100644 target/linux/gemini/patches-4.4/120-net-add-gemini-gmac-driver.patch delete mode 100644 target/linux/gemini/patches-4.4/121-arm-gemini-add-gmac-device.patch delete mode 100644 target/linux/gemini/patches-4.4/122-arm-gemini-register-ethernet.patch delete mode 100644 target/linux/gemini/patches-4.4/130-usb-ehci-add-fot2g-driver.patch delete mode 100644 target/linux/gemini/patches-4.4/131-arm-gemini-add-usb-device.patch delete mode 100644 target/linux/gemini/patches-4.4/132-arm-gemini-register-usb.patch delete mode 100644 target/linux/gemini/patches-4.4/140-arm-gemini-add-pci-support.patch delete mode 100644 target/linux/gemini/patches-4.4/150-gemini-pata.patch delete mode 100644 target/linux/gemini/raidsonic/config-default delete mode 100644 target/linux/gemini/raidsonic/target.mk delete mode 100644 target/linux/gemini/wiligear/target.mk create mode 100644 target/linux/generic/backport-4.14/030-USB-serial-option-fix-dwm-158-3g-modem-interface.patch create mode 100644 target/linux/generic/backport-4.14/030-v4.17-0001-usb-dwc2-add-support-for-host-mode-external-vbus-sup.patch create mode 100644 target/linux/generic/backport-4.14/030-v4.17-0002-usb-dwc2-dwc2_vbus_supply_init-fix-error-check.patch create mode 100644 target/linux/generic/backport-4.14/042-v4.18-0001-mtd-move-code-adding-registering-partitions-to-the-p.patch rename target/linux/generic/{pending-4.14/142-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch => backport-4.14/043-v4.18-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch} (88%) rename target/linux/generic/backport-4.14/{300-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch => 300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch} (100%) rename target/linux/generic/backport-4.14/{301-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch => 301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch} (100%) rename target/linux/generic/backport-4.14/{302-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch => 302-v4.16-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch} (100%) rename target/linux/generic/backport-4.14/{303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch => 303-v4.16-netfilter-nf_tables-remove-multihook-chains-and-fami.patch} (100%) rename target/linux/generic/backport-4.14/{304-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch => 304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch} (100%) rename target/linux/generic/backport-4.14/{305-netfilter-move-checksum_partial-indirection-to-struc.patch => 305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch} (100%) rename target/linux/generic/backport-4.14/{306-netfilter-remove-saveroute-indirection-in-struct-nf_.patch => 306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch} (100%) rename target/linux/generic/backport-4.14/{307-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch => 307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch} (100%) rename target/linux/generic/backport-4.14/{308-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch => 308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch} (100%) rename target/linux/generic/backport-4.14/{309-netfilter-remove-route_key_size-field-in-struct-nf_a.patch => 309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch} (100%) rename target/linux/generic/backport-4.14/{310-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch => 310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch} (100%) rename target/linux/generic/backport-4.14/{311-netfilter-nf_tables_arp-don-t-set-forward-chain.patch => 311-v4.16-netfilter-nf_tables_arp-don-t-set-forward-chain.patch} (100%) rename target/linux/generic/backport-4.14/{312-netfilter-nf_tables-remove-hooks-from-family-definit.patch => 312-v4.16-netfilter-nf_tables-remove-hooks-from-family-definit.patch} (100%) rename target/linux/generic/backport-4.14/{313-netfilter-remove-defensive-check-on-malformed-packet.patch => 313-v4.16-netfilter-remove-defensive-check-on-malformed-packet.patch} (100%) rename target/linux/generic/backport-4.14/{314-netfilter-meta-secpath-support.patch => 314-v4.16-netfilter-meta-secpath-support.patch} (100%) rename target/linux/generic/backport-4.14/{315-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch => 315-v4.15-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch} (100%) rename target/linux/generic/backport-4.14/{320-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch => 320-v4.16-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch} (100%) rename target/linux/generic/backport-4.14/{321-netfilter-nf_tables-add-flow-table-netlink-frontend.patch => 321-v4.16-netfilter-nf_tables-add-flow-table-netlink-frontend.patch} (100%) rename target/linux/generic/backport-4.14/{322-netfilter-add-generic-flow-table-infrastructure.patch => 322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch} (100%) rename target/linux/generic/backport-4.14/{323-netfilter-flow-table-support-for-IPv4.patch => 323-v4.16-netfilter-flow-table-support-for-IPv4.patch} (100%) rename target/linux/generic/backport-4.14/{324-netfilter-flow-table-support-for-IPv6.patch => 324-v4.16-netfilter-flow-table-support-for-IPv6.patch} (100%) rename target/linux/generic/backport-4.14/{325-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch => 325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch} (100%) rename target/linux/generic/backport-4.14/{326-netfilter-nf_tables-flow-offload-expression.patch => 326-v4.16-netfilter-nf_tables-flow-offload-expression.patch} (100%) rename target/linux/generic/backport-4.14/{327-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch => 327-v4.16-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch} (100%) rename target/linux/generic/backport-4.14/{328-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch => 328-v4.16-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch} (100%) rename target/linux/generic/backport-4.14/{329-netfilter-improve-flow-table-Kconfig-dependencies.patch => 329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch} (100%) rename target/linux/generic/backport-4.14/{330-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch => 330-v4.16-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch} (100%) rename target/linux/generic/backport-4.14/{331-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch => 331-v4.16-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch} (100%) rename target/linux/generic/backport-4.14/{332-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch => 332-v4.16-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch} (100%) rename target/linux/generic/backport-4.14/{334-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch => 334-v4.15-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch} (100%) rename target/linux/generic/backport-4.14/{335-netfilter-nf_tables-add-single-table-list-for-all-fa.patch => 335-v4.16-netfilter-nf_tables-add-single-table-list-for-all-fa.patch} (100%) rename target/linux/generic/backport-4.14/{336-netfilter-exit_net-cleanup-check-added.patch => 336-v4.15-netfilter-exit_net-cleanup-check-added.patch} (100%) rename target/linux/generic/backport-4.14/{337-netfilter-nf_tables-get-rid-of-pernet-families.patch => 337-v4.16-netfilter-nf_tables-get-rid-of-pernet-families.patch} (100%) rename target/linux/generic/backport-4.14/{338-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch => 338-v4.16-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch} (100%) rename target/linux/generic/backport-4.14/{339-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch => 339-v4.16-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch} (100%) rename target/linux/generic/backport-4.14/{340-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch => 340-v4.16-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch} (100%) rename target/linux/generic/backport-4.14/{341-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch => 341-v4.16-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch} (100%) rename target/linux/generic/backport-4.14/{342-netfilter-nf_tables-fix-flowtable-free.patch => 342-v4.16-netfilter-nf_tables-fix-flowtable-free.patch} (100%) rename target/linux/generic/backport-4.14/{344-netfilter-nf_tables-allocate-handle-and-delete-objec.patch => 344-v4.16-netfilter-nf_tables-allocate-handle-and-delete-objec.patch} (100%) rename target/linux/generic/backport-4.14/{345-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch => 345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch} (100%) rename target/linux/generic/backport-4.14/{346-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch => 346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch} (100%) rename target/linux/generic/backport-4.14/{347-netfilter-remove-duplicated-include.patch => 347-v4.16-netfilter-remove-duplicated-include.patch} (100%) rename target/linux/generic/backport-4.14/{348-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch => 348-v4.18-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch} (100%) rename target/linux/generic/backport-4.14/{349-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch => 349-v4.18-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch} (100%) rename target/linux/generic/backport-4.14/{350-ipv6-make-ip6_dst_mtu_forward-inline.patch => 350-v4.18-ipv6-make-ip6_dst_mtu_forward-inline.patch} (100%) rename target/linux/generic/backport-4.14/{351-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch => 351-v4.18-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch} (100%) rename target/linux/generic/backport-4.14/{352-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch => 352-v4.18-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch} (100%) rename target/linux/generic/backport-4.14/{353-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch => 353-v4.18-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch} (100%) rename target/linux/generic/backport-4.14/{354-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch => 354-v4.18-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch} (100%) rename target/linux/generic/backport-4.14/{355-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch => 355-v4.18-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch} (100%) rename target/linux/generic/backport-4.14/{356-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch => 356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch} (100%) rename target/linux/generic/backport-4.14/{357-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch => 357-v4.18-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch} (100%) rename target/linux/generic/backport-4.14/{358-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch => 358-v4.18-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch} (100%) rename target/linux/generic/backport-4.14/{359-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch => 359-v4.18-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch} (100%) rename target/linux/generic/backport-4.14/{360-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch => 360-v4.18-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch} (100%) rename target/linux/generic/backport-4.14/{361-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch => 361-v4.18-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch} (100%) rename target/linux/generic/backport-4.14/{362-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch => 362-v4.18-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch} (100%) rename target/linux/generic/backport-4.14/{363-netfilter-nf_flow_table-add-support-for-sending-flow.patch => 363-v4.18-netfilter-nf_flow_table-add-support-for-sending-flow.patch} (100%) rename target/linux/generic/backport-4.14/{364-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch => 364-v4.18-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch} (100%) rename target/linux/generic/backport-4.14/{365-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch => 365-v4.16-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch} (100%) rename target/linux/generic/backport-4.14/{367-netfilter-nf_flow_table-add-missing-condition-for-TC.patch => 367-v4.18-netfilter-nf_flow_table-add-missing-condition-for-TC.patch} (100%) rename target/linux/generic/backport-4.14/{368-netfilter-nf_flow_table-fix-offloading-connections-w.patch => 368-v4.18-netfilter-nf_flow_table-fix-offloading-connections-w.patch} (100%) create mode 100644 target/linux/generic/pending-4.14/103-MIPS-c-r4k-fix-data-corruption-related-to-cache-coherence.patch create mode 100644 target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh32.patch create mode 100644 target/linux/ramips/dts/BOCCO.dts create mode 100644 target/linux/ramips/dts/WD03.dts create mode 100644 target/linux/ramips/dts/WITI-256M.dts create mode 100644 target/linux/ramips/dts/WITI-512M.dts rename target/linux/ramips/dts/{WITI.dts => WITI.dtsi} (95%) create mode 100644 target/linux/ramips/files-4.14/arch/mips/pci/pci-mt7621.c delete mode 100644 target/linux/ramips/patches-4.14/0040-nand-hack-restore-write_page.patch diff --git a/target/linux/ath79/base-files/etc/board.d/01_leds b/target/linux/ath79/base-files/etc/board.d/01_leds old mode 100644 new mode 100755 index 9d4286193..70d27bc29 --- a/target/linux/ath79/base-files/etc/board.d/01_leds +++ b/target/linux/ath79/base-files/etc/board.d/01_leds @@ -5,8 +5,19 @@ board_config_update board=$(board_name) +boardname="${board##*,}" case "$board" in +"avm,fritz300e") + ucidef_set_led_netdev "lan" "LAN" "$boardname:green:lan" "eth0" + ucidef_set_led_wlan "wlan" "WLAN" "$boardname:green:wlan" "phy0tpt" + ucidef_set_rssimon "wlan0" "200000" "1" + ucidef_set_led_rssi "rssilow" "RSSILOW" "$boardname:green:rssi0" "wlan0" "1" "100" + ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "$boardname:green:rssi1" "wlan0" "20" "100" + ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "$boardname:green:rssi2" "wlan0" "40" "100" + ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "$boardname:green:rssi3" "wlan0" "60" "100" + ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "$boardname:green:rssi4" "wlan0" "80" "100" + ;; "glinet,ar150") ucidef_set_led_wlan "wlan" "WLAN" "gl-ar150:orange:wlan" "phy0tpt" ;; diff --git a/target/linux/ath79/base-files/etc/board.d/02_network b/target/linux/ath79/base-files/etc/board.d/02_network old mode 100644 new mode 100755 index 941d2ab51..19361f161 --- a/target/linux/ath79/base-files/etc/board.d/02_network +++ b/target/linux/ath79/base-files/etc/board.d/02_network @@ -8,6 +8,7 @@ ath79_setup_interfaces() local board="$1" case "$board" in + "avm,fritz300e"|\ "ubnt,unifi") ucidef_set_interface_lan "eth0" ;; @@ -36,9 +37,23 @@ ath79_setup_interfaces() esac } +ath79_setup_macs() +{ + local board="$1" + + case "$board" in + avm,fritz300e) + lan_mac=$(fritz_tffs -n maca -i $(find_mtd_part "tffs (1)")) + ;; + esac + + [ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac +} + board_config_update board=$(board_name) ath79_setup_interfaces $board +ath79_setup_macs $board board_config_flush exit 0 diff --git a/target/linux/ath79/base-files/etc/diag.sh b/target/linux/ath79/base-files/etc/diag.sh index c9b32df94..802215137 100644 --- a/target/linux/ath79/base-files/etc/diag.sh +++ b/target/linux/ath79/base-files/etc/diag.sh @@ -4,8 +4,12 @@ get_status_led() { local board=$(board_name) + local boardname="${board##*,}" case $board in + "avm,fritz300e") + status_led="${boardname}:green:power" + ;; "glinet,ar150") status_led="gl-ar150:orange:wlan" ;; diff --git a/target/linux/ath79/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/ath79/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom index fc15caea6..c2d87f58d 100644 --- a/target/linux/ath79/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom +++ b/target/linux/ath79/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom @@ -24,11 +24,32 @@ ath9k_eeprom_extract() { ath9k_eeprom_die "failed to extract from $mtd" } +ath9k_eeprom_extract_reverse() { + local part=$1 + local offset=$2 + local count=$3 + local mtd + local reversed + local caldata + + mtd=$(find_mtd_chardev "$part") + reversed=$(hexdump -v -s $offset -n $count -e '/1 "%02x "' $mtd) + + for byte in $reversed; do + caldata="\x${byte}${caldata}" + done + + printf "%b" "$caldata" > /lib/firmware/$FIRMWARE +} + board=$(board_name) case "$FIRMWARE" in "ath9k-eeprom-pci-0000:00:00.0.bin") case $board in + "avm,fritz300e") + ath9k_eeprom_extract_reverse "urloader" 5441 1088 + ;; "ubnt,unifi") ath9k_eeprom_extract "art" 4096 2048 ;; diff --git a/target/linux/ath79/base-files/lib/upgrade/platform.sh b/target/linux/ath79/base-files/lib/upgrade/platform.sh index b2b55e64e..dfcf70487 100644 --- a/target/linux/ath79/base-files/lib/upgrade/platform.sh +++ b/target/linux/ath79/base-files/lib/upgrade/platform.sh @@ -2,205 +2,11 @@ # Copyright (C) 2011 OpenWrt.org # -. /lib/functions/system.sh - PART_NAME=firmware -RAMFS_COPY_BIN='nandwrite' - -CI_BLKSZ=65536 -CI_LDADR=0x80060000 - -PLATFORM_DO_UPGRADE_COMBINED_SEPARATE_MTD=0 - -platform_find_partitions() { - local first dev size erasesize name - while read dev size erasesize name; do - name=${name#'"'}; name=${name%'"'} - case "$name" in - vmlinux.bin.l7|vmlinux|kernel|linux|linux.bin|rootfs|filesystem) - if [ -z "$first" ]; then - first="$name" - else - echo "$erasesize:$first:$name" - break - fi - ;; - esac - done < /proc/mtd -} - -platform_find_kernelpart() { - local part - for part in "${1%:*}" "${1#*:}"; do - case "$part" in - vmlinux.bin.l7|vmlinux|kernel|linux|linux.bin) - echo "$part" - break - ;; - esac - done -} - -platform_find_rootfspart() { - local part - for part in "${1%:*}" "${1#*:}"; do - [ "$part" != "$2" ] && echo "$part" && break - done -} - -platform_do_upgrade_combined() { - local partitions=$(platform_find_partitions) - local kernelpart=$(platform_find_kernelpart "${partitions#*:}") - local erase_size=$((0x${partitions%%:*})); partitions="${partitions#*:}" - local kern_length=0x$(dd if="$1" bs=2 skip=1 count=4 2>/dev/null) - local kern_blocks=$(($kern_length / $CI_BLKSZ)) - local root_blocks=$((0x$(dd if="$1" bs=2 skip=5 count=4 2>/dev/null) / $CI_BLKSZ)) - - if [ -n "$partitions" ] && [ -n "$kernelpart" ] && \ - [ ${kern_blocks:-0} -gt 0 ] && \ - [ ${root_blocks:-0} -gt 0 ] && \ - [ ${erase_size:-0} -gt 0 ]; - then - local rootfspart=$(platform_find_rootfspart "$partitions" "$kernelpart") - local append="" - [ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ] && append="-j $CONF_TAR" - - if [ "$PLATFORM_DO_UPGRADE_COMBINED_SEPARATE_MTD" -ne 1 ]; then - ( dd if="$1" bs=$CI_BLKSZ skip=1 count=$kern_blocks 2>/dev/null; \ - dd if="$1" bs=$CI_BLKSZ skip=$((1+$kern_blocks)) count=$root_blocks 2>/dev/null ) | \ - mtd -r $append -F$kernelpart:$kern_length:$CI_LDADR,rootfs write - $partitions - elif [ -n "$rootfspart" ]; then - dd if="$1" bs=$CI_BLKSZ skip=1 count=$kern_blocks 2>/dev/null | \ - mtd write - $kernelpart - dd if="$1" bs=$CI_BLKSZ skip=$((1+$kern_blocks)) count=$root_blocks 2>/dev/null | \ - mtd -r $append write - $rootfspart - fi - fi - PLATFORM_DO_UPGRADE_COMBINED_SEPARATE_MTD=0 -} - -tplink_get_image_hwid() { - get_image "$@" | dd bs=4 count=1 skip=16 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -} - -tplink_get_image_mid() { - get_image "$@" | dd bs=4 count=1 skip=17 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -} - -tplink_get_image_boot_size() { - get_image "$@" | dd bs=4 count=1 skip=37 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -} - -tplink_pharos_check_image() { - local magic_long="$(get_magic_long "$1")" - [ "$magic_long" != "7f454c46" ] && { - echo "Invalid image magic '$magic_long'" - return 1 - } - - local model_string="$(tplink_pharos_get_model_string)" - local line - - # Here $1 is given to dd directly instead of get_image as otherwise the skip - # will take almost a second (as dd can't seek then) - # - # This will fail if the image isn't local, but that's fine: as the - # read loop won't be executed at all, it will return true, so the image - # is accepted (loading the first 1.5M of a remote image for this check seems - # a bit extreme) - dd if="$1" bs=1 skip=1511432 count=1024 2>/dev/null | while read line; do - [ "$line" = "$model_string" ] && break - done || { - echo "Unsupported image (model not in support-list)" - return 1 - } - - return 0 -} - -seama_get_type_magic() { - get_image "$@" | dd bs=1 count=4 skip=53 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -} - -wrgg_get_image_magic() { - get_image "$@" | dd bs=4 count=1 skip=8 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -} - -cybertan_get_image_magic() { - get_image "$@" | dd bs=8 count=1 skip=0 2>/dev/null | hexdump -v -n 8 -e '1/1 "%02x"' -} - -cybertan_check_image() { - local magic="$(cybertan_get_image_magic "$1")" - local fw_magic="$(cybertan_get_hw_magic)" - - [ "$fw_magic" != "$magic" ] && { - echo "Invalid image, ID mismatch, got:$magic, but need:$fw_magic" - return 1 - } - - return 0 -} - -platform_do_upgrade_compex() { - local fw_file=$1 - local fw_part=$PART_NAME - local fw_mtd=$(find_mtd_part $fw_part) - local fw_length=0x$(dd if="$fw_file" bs=2 skip=1 count=4 2>/dev/null) - local fw_blocks=$(($fw_length / 65536)) - - if [ -n "$fw_mtd" ] && [ ${fw_blocks:-0} -gt 0 ]; then - local append="" - [ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ] && append="-j $CONF_TAR" - - sync - dd if="$fw_file" bs=64k skip=1 count=$fw_blocks 2>/dev/null | \ - mtd $append write - "$fw_part" - fi -} - -alfa_check_image() { - local magic_long="$(get_magic_long "$1")" - local fw_part_size=$(mtd_get_part_size firmware) - - case "$magic_long" in - "27051956") - [ "$fw_part_size" != "16318464" ] && { - echo "Invalid image magic \"$magic_long\" for $fw_part_size bytes" - return 1 - } - ;; - "68737173") - [ "$fw_part_size" != "7929856" ] && { - echo "Invalid image magic \"$magic_long\" for $fw_part_size bytes" - return 1 - } - ;; - esac - - return 0 -} +REQUIRE_IMAGE_METADATA=1 platform_check_image() { - local board=$(board_name) - local magic="$(get_magic_word "$1")" - local magic_long="$(get_magic_long "$1")" - - [ "$#" -gt 1 ] && return 1 - - case "$board" in - "ubnt,unifi") - [ "$magic" != "2705" ] && { - echo "Invalid image type." - return 1 - } - - return 0 - ;; - esac - - echo "Sysupgrade is not yet supported on $board." - return 1 + return 0 } platform_do_upgrade() { @@ -212,13 +18,3 @@ platform_do_upgrade() { ;; esac } - -disable_watchdog() { - killall watchdog - ( ps | grep -v 'grep' | grep '/dev/watchdog' ) && { - echo 'Could not disable watchdog' - return 1 - } -} - -append sysupgrade_pre_upgrade disable_watchdog diff --git a/target/linux/ath79/config-4.14 b/target/linux/ath79/config-4.14 index f1cdf350f..f64a02b9b 100644 --- a/target/linux/ath79/config-4.14 +++ b/target/linux/ath79/config-4.14 @@ -24,7 +24,6 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_ARCH_USE_QUEUED_RWLOCKS=y CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y CONFIG_AT803X_PHY=y CONFIG_ATH79=y @@ -55,15 +54,10 @@ CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y -# CONFIG_DMA_NOOP_OPS is not set -# CONFIG_DMA_VIRT_OPS is not set -# CONFIG_DRM_LIB_RANDOM is not set CONFIG_DTC=y CONFIG_EARLY_PRINTK=y CONFIG_ETHERNET_PACKET_MANGLE=y -CONFIG_EXPORTFS=y CONFIG_FIXED_PHY=y -CONFIG_FUTEX_PI=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y @@ -132,10 +126,7 @@ CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HW_HAS_PCI=y CONFIG_HZ_PERIODIC=y CONFIG_IMAGE_CMDLINE_HACK=y -CONFIG_INITRAMFS_COMPRESSION="" -CONFIG_INITRAMFS_ROOT_GID=0 -CONFIG_INITRAMFS_ROOT_UID=0 -CONFIG_INITRAMFS_SOURCE="../../root" +CONFIG_INITRAMFS_SOURCE="" CONFIG_IP17XX_PHY=y CONFIG_IRQCHIP=y CONFIG_IRQ_DOMAIN=y @@ -181,6 +172,7 @@ CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPLIT_FIRMWARE=y CONFIG_MTD_SPLIT_LZMA_FW=y CONFIG_MTD_SPLIT_SEAMA_FW=y +CONFIG_MTD_SPLIT_TPLINK_FW=y CONFIG_MTD_SPLIT_UIMAGE_FW=y CONFIG_MTD_SPLIT_WRGG_FW=y CONFIG_MTD_TPLINK_PARTS=y @@ -240,7 +232,6 @@ CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y CONFIG_SYS_SUPPORTS_MIPS16=y CONFIG_SYS_SUPPORTS_ZBOOT=y CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM=y -CONFIG_THIN_ARCHIVES=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TINY_SRCU=y CONFIG_USB_SUPPORT=y diff --git a/target/linux/ath79/dts/ar7241_ubnt-xm.dts b/target/linux/ath79/dts/ar7241_ubnt-xm.dts deleted file mode 100644 index efb01f7b5..000000000 --- a/target/linux/ath79/dts/ar7241_ubnt-xm.dts +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT -/dts-v1/; - -#include "ar7241_ubnt-xm.dtsi" - -/ { - compatible = "ubnt,xm", "qca,ar7241"; - model = "Ubiquiti Networks XM (rev 1.0) board"; -}; - -ð1 { - compatible = "syscon"; -}; diff --git a/target/linux/ath79/dts/ar7241_ubnt-bullet-m.dts b/target/linux/ath79/dts/ar7241_ubnt_bullet-m.dts similarity index 64% rename from target/linux/ath79/dts/ar7241_ubnt-bullet-m.dts rename to target/linux/ath79/dts/ar7241_ubnt_bullet-m.dts index 067c61251..0de97ea93 100644 --- a/target/linux/ath79/dts/ar7241_ubnt-bullet-m.dts +++ b/target/linux/ath79/dts/ar7241_ubnt_bullet-m.dts @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT /dts-v1/; -#include "ar7241_ubnt-xm.dtsi" +#include "ar7241_ubnt_xm.dtsi" / { - compatible = "ubnt,xm", "qca,ar7241"; + compatible = "ubnt,bullet-m", "qca,ar7241"; model = "Ubiquiti Bullet M"; }; diff --git a/target/linux/ath79/dts/ar7241_ubnt-nano-m.dts b/target/linux/ath79/dts/ar7241_ubnt_nano-m.dts similarity index 58% rename from target/linux/ath79/dts/ar7241_ubnt-nano-m.dts rename to target/linux/ath79/dts/ar7241_ubnt_nano-m.dts index 8fbd7a6ee..417e50312 100644 --- a/target/linux/ath79/dts/ar7241_ubnt-nano-m.dts +++ b/target/linux/ath79/dts/ar7241_ubnt_nano-m.dts @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT /dts-v1/; -#include "ar7241_ubnt-xm.dtsi" +#include "ar7241_ubnt_xm.dtsi" / { - compatible = "ubnt,nm", "qca,ar7241"; + compatible = "ubnt,nano-m", "qca,ar7241"; model = "Ubiquiti Nanostation M"; }; diff --git a/target/linux/ath79/dts/ar7241_ubnt-rocket-m.dts b/target/linux/ath79/dts/ar7241_ubnt_rocket-m.dts similarity index 72% rename from target/linux/ath79/dts/ar7241_ubnt-rocket-m.dts rename to target/linux/ath79/dts/ar7241_ubnt_rocket-m.dts index e1ef6d709..36fa2750a 100644 --- a/target/linux/ath79/dts/ar7241_ubnt-rocket-m.dts +++ b/target/linux/ath79/dts/ar7241_ubnt_rocket-m.dts @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT /dts-v1/; -#include "ar7241_ubnt-xm.dtsi" +#include "ar7241_ubnt_xm.dtsi" / { - compatible = "ubnt,rm", "qca,ar7241"; + compatible = "ubnt,rocket-m", "qca,ar7241"; model = "Ubiquiti Rocket M"; }; diff --git a/target/linux/ath79/dts/ar7241_ubnt-unifi.dts b/target/linux/ath79/dts/ar7241_ubnt_unifi.dts similarity index 100% rename from target/linux/ath79/dts/ar7241_ubnt-unifi.dts rename to target/linux/ath79/dts/ar7241_ubnt_unifi.dts diff --git a/target/linux/ath79/dts/ar7241_ubnt-xm.dtsi b/target/linux/ath79/dts/ar7241_ubnt_xm.dtsi similarity index 100% rename from target/linux/ath79/dts/ar7241_ubnt-xm.dtsi rename to target/linux/ath79/dts/ar7241_ubnt_xm.dtsi diff --git a/target/linux/ath79/dts/ar7242_avm_fritz300e.dts b/target/linux/ath79/dts/ar7242_avm_fritz300e.dts new file mode 100644 index 000000000..f1ad138f4 --- /dev/null +++ b/target/linux/ath79/dts/ar7242_avm_fritz300e.dts @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/dts-v1/; + +#include +#include + +#include "ar7242.dtsi" + +/ { + compatible = "avm,fritz300e", "qca,ar7242"; + model = "AVM FRITZ!WLAN Repeater 300E"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + gpio-keys { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + wps { + label = "wps"; + linux,code = ; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + power { + label = "fritz300e:green:power"; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + lan { + label = "fritz300e:green:lan"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + + wlan { + label = "fritz300e:green:wlan"; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + }; + }; + + ath9k-leds { + compatible = "gpio-leds"; + + rssi0 { + label = "fritz300e:green:rssi0"; + gpios = <&ath9k 10 GPIO_ACTIVE_LOW>; + }; + + rssi1 { + label = "fritz300e:green:rssi1"; + gpios = <&ath9k 4 GPIO_ACTIVE_LOW>; + }; + + rssi2 { + label = "fritz300e:green:rssi2"; + gpios = <&ath9k 6 GPIO_ACTIVE_LOW>; + }; + + rssi3 { + label = "fritz300e:green:rssi3"; + gpios = <&ath9k 7 GPIO_ACTIVE_LOW>; + }; + + rssi4 { + label = "fritz300e:green:rssi4"; + gpios = <&ath9k 5 GPIO_ACTIVE_LOW>; + }; + }; + + eth-phy-reset { + compatible = "regulator-fixed"; + + regulator-name = "eth-phy-reset"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio 11 GPIO_ACTIVE_LOW>; + startup-delay-us = <300000>; + enable-active-high; + + regulator-always-on; + }; +}; + +&spi { + status = "okay"; + num-cs = <1>; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x20000>; + label = "urloader"; + read-only; + }; + + partition@20000 { + reg = <0x20000 0xee0000>; + label = "firmware"; + }; + + partition@f00000 { + reg = <0xf00000 0x80000>; + label = "tffs (1)"; + read-only; + }; + + partition@f80000 { + reg = <0xf80000 0x80000>; + label = "tffs (2)"; + read-only; + }; + }; + }; +}; + +&uart { + status = "okay"; +}; + +&pcie { + status = "okay"; + + ath9k: wifi@0000 { + reg = <0x0000 0 0 0 0>; + #gpio-cells = <2>; + gpio-controller; + qca,no-eeprom; + }; +}; + +&mdio0 { + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + phy-mode = "rgmii"; + }; +}; + +ð0 { + status = "okay"; + + phy-mode = "rgmii"; + phy-handle = <&phy0>; + + pll-data = <0x16000000 0x00000101 0x00001313>; +}; diff --git a/target/linux/ath79/dts/ar724x.dtsi b/target/linux/ath79/dts/ar724x.dtsi index 410874511..fe1b4eb68 100644 --- a/target/linux/ath79/dts/ar724x.dtsi +++ b/target/linux/ath79/dts/ar724x.dtsi @@ -65,9 +65,8 @@ }; pll: pll-controller@18050000 { - compatible = "qca,ar7240-pll", - "qca,ar7240-pll"; - reg = <0x18050000 0x20>; + compatible = "qca,ar7240-pll", "syscon"; + reg = <0x18050000 0x3c>; clock-names = "ref"; /* The board must provides the ref clock */ diff --git a/target/linux/ath79/dts/ar9132.dtsi b/target/linux/ath79/dts/ar9132.dtsi index 7a7a5f1b3..4cc4f04a2 100644 --- a/target/linux/ath79/dts/ar9132.dtsi +++ b/target/linux/ath79/dts/ar9132.dtsi @@ -7,6 +7,10 @@ #address-cells = <1>; #size-cells = <1>; + chosen { + bootargs = "console=ttyS0,115200"; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/ath79/dts/ar9330_gl_ar150.dts b/target/linux/ath79/dts/ar9330_glinet_ar150.dts similarity index 98% rename from target/linux/ath79/dts/ar9330_gl_ar150.dts rename to target/linux/ath79/dts/ar9330_glinet_ar150.dts index 97beab149..16d86137c 100644 --- a/target/linux/ath79/dts/ar9330_gl_ar150.dts +++ b/target/linux/ath79/dts/ar9330_glinet_ar150.dts @@ -8,7 +8,7 @@ / { model = "GL.iNet GL-AR150"; - compatible = "glinet,ar150"; + compatible = "glinet,ar150", "qca,ar9330"; aliases { serial0 = &uart; diff --git a/target/linux/ath79/dts/ar9331_dpt_module.dts b/target/linux/ath79/dts/ar9331_dpt_module.dts index bcd863605..dc4df6b27 100644 --- a/target/linux/ath79/dts/ar9331_dpt_module.dts +++ b/target/linux/ath79/dts/ar9331_dpt_module.dts @@ -8,7 +8,7 @@ / { model = "DPTechnics DPT-Module"; - compatible = "dptechnics,dpt-module"; + compatible = "dptechnics,dpt-module", "qca,ar9331"; aliases { serial0 = &uart; diff --git a/target/linux/ath79/dts/ar9331_dragino_ms14.dts b/target/linux/ath79/dts/ar9331_dragino_ms14.dts index e7c446aa7..9fb674eb2 100644 --- a/target/linux/ath79/dts/ar9331_dragino_ms14.dts +++ b/target/linux/ath79/dts/ar9331_dragino_ms14.dts @@ -8,7 +8,7 @@ / { model = "Dragino MS14 (Dragino 2)"; - compatible = "dragino,ms14"; + compatible = "dragino,ms14", "qca,ar9331"; aliases { serial0 = &uart; diff --git a/target/linux/ath79/dts/ar9331_ew_dorin.dts b/target/linux/ath79/dts/ar9331_embeddedwireless_dorin.dts similarity index 97% rename from target/linux/ath79/dts/ar9331_ew_dorin.dts rename to target/linux/ath79/dts/ar9331_embeddedwireless_dorin.dts index fd1859380..4b204b756 100644 --- a/target/linux/ath79/dts/ar9331_ew_dorin.dts +++ b/target/linux/ath79/dts/ar9331_embeddedwireless_dorin.dts @@ -8,7 +8,7 @@ / { model = "Embedded Wireless Dorin"; - compatible = "embeddedwireless,dorin"; + compatible = "embeddedwireless,dorin", "qca,ar9331"; aliases { serial0 = &uart; diff --git a/target/linux/ath79/dts/ar9331_omega.dts b/target/linux/ath79/dts/ar9331_omega.dts index 1225b245f..32551427e 100644 --- a/target/linux/ath79/dts/ar9331_omega.dts +++ b/target/linux/ath79/dts/ar9331_omega.dts @@ -8,7 +8,7 @@ / { model = "Onion Omega"; - compatible = "onion,omega"; + compatible = "onion,omega", "qca,ar9331"; aliases { serial0 = &uart; diff --git a/target/linux/ath79/dts/ar9331_tl_mr3020.dts b/target/linux/ath79/dts/ar9331_tl_mr3020.dts index 7439768a2..34ee805b3 100644 --- a/target/linux/ath79/dts/ar9331_tl_mr3020.dts +++ b/target/linux/ath79/dts/ar9331_tl_mr3020.dts @@ -8,7 +8,7 @@ / { model = "TP-Link TL-MR3020"; - compatible = "tplink,tl-mr3020"; + compatible = "tplink,tl-mr3020", "qca,ar9331"; aliases { serial0 = &uart; diff --git a/target/linux/ath79/dts/qca9558_om5p_ac.dts b/target/linux/ath79/dts/qca9558_openmesh_om5p-ac-v2.dts similarity index 100% rename from target/linux/ath79/dts/qca9558_om5p_ac.dts rename to target/linux/ath79/dts/qca9558_openmesh_om5p-ac-v2.dts diff --git a/target/linux/ath79/generic/config-default b/target/linux/ath79/generic/config-default index bbed97b6b..c174c4e12 100644 --- a/target/linux/ath79/generic/config-default +++ b/target/linux/ath79/generic/config-default @@ -1,7 +1,7 @@ CONFIG_BLK_MQ_PCI=y -CONFIG_HW_HAS_PCI=y +CONFIG_INTEL_XWAY_PHY=y CONFIG_LEDS_RESET=y -# CONFIG_MIPS_MACHINE is not set +CONFIG_MTD_SPLIT_EVA_FW=y CONFIG_OF_ADDRESS_PCI=y CONFIG_OF_PCI=y CONFIG_OF_PCI_IRQ=y @@ -12,5 +12,5 @@ CONFIG_PCI_DISABLE_COMMON_QUIRKS=y CONFIG_PCI_DOMAINS=y CONFIG_PHY_AR7100_USB=y CONFIG_PHY_AR7200_USB=y -# CONFIG_WIRELESS is not set -# CONFIG_WLAN is not set +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y diff --git a/target/linux/ath79/image/Makefile b/target/linux/ath79/image/Makefile index cc71c3199..792548657 100644 --- a/target/linux/ath79/image/Makefile +++ b/target/linux/ath79/image/Makefile @@ -3,14 +3,13 @@ include $(INCLUDE_DIR)/image.mk KERNEL_LOADADDR = 0x80060000 -DEVICE_VARS += CMDLINE CONSOLE IMAGE_SIZE BOARDNAME LOADER_FLASH_OFFS LOADER_TYPE ATH_SOC +DEVICE_VARS += IMAGE_SIZE LOADER_FLASH_OFFS LOADER_TYPE ATH_SOC define Build/loader-common rm -rf $@.src $(MAKE) -C lzma-loader \ PKG_BUILD_DIR="$@.src" \ TARGET_DIR="$(dir $@)" LOADER_NAME="$(notdir $@)" \ - BOARD="$(BOARDNAME)" \ LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ $(1) compile loader.$(LOADER_TYPE) mv "$@.$(LOADER_TYPE)" "$@" @@ -22,12 +21,12 @@ define Build/loader-kernel endef define Build/loader-kernel-cmdline - $(call Build/loader-common,LOADER_DATA="$@" KERNEL_CMDLINE="$(CMDLINE)") + $(call Build/loader-common,LOADER_DATA="$@") endef define Build/loader-okli-compile - $(call Build/loader-common,FLASH_OFFS=$(LOADER_FLASH_OFFS) FLASH_MAX=0 KERNEL_CMDLINE="$(CMDLINE)") + $(call Build/loader-common,FLASH_OFFS=$(LOADER_FLASH_OFFS) FLASH_MAX=0) endef define Build/loader-okli @@ -49,31 +48,26 @@ define Build/relocate-kernel rm -rf $@.relocate endef -define Build/copy-file - cat "$(1)" > "$@" -endef define Device/Default ATH_SOC := - BOARDNAME := - DEVICE_PROFILE = $$(BOARDNAME) DEVICE_DTS_DIR := ../dts DEVICE_DTS = $$(ATH_SOC)_$(1) - PROFILES = Default Minimal $$(DEVICE_PROFILE) + PROFILES = Default MTDPARTS := BLOCKSIZE := 64k - CONSOLE = ttyS0,115200 - CMDLINE = $$(if $$(BOARDNAME),board=$$(BOARDNAME)) $$(if $$(MTDPARTS),mtdparts=$$(MTDPARTS)) $$(if $$(CONSOLE),console=$$(CONSOLE)) KERNEL := kernel-bin | append-dtb | lzma | uImage lzma KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | uImage lzma COMPILE := + SUPPORTED_DEVICES := $(subst _,$(comma),$(1)) IMAGES := sysupgrade.bin - IMAGE/sysupgrade.bin = append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs + IMAGE/sysupgrade.bin = append-kernel | pad-to $$$$(BLOCKSIZE) | \ + append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) endef ifeq ($(SUBTARGET),generic) -include ./tp-link.mk include ./generic.mk +include ./generic-tp-link.mk include ./generic-ubnt.mk endif $(eval $(call BuildImage)) diff --git a/target/linux/ath79/image/tp-link.mk b/target/linux/ath79/image/generic-tp-link.mk similarity index 56% rename from target/linux/ath79/image/tp-link.mk rename to target/linux/ath79/image/generic-tp-link.mk index bbe405414..dd1a983b7 100644 --- a/target/linux/ath79/image/tp-link.mk +++ b/target/linux/ath79/image/generic-tp-link.mk @@ -1,5 +1,9 @@ DEVICE_VARS += TPLINK_HWID TPLINK_HWREV TPLINK_FLASHLAYOUT TPLINK_HEADER_VERSION TPLINK_BOARD_NAME +define rootfs_align +$(patsubst %-256k,0x40000,$(patsubst %-128k,0x20000,$(patsubst %-64k,0x10000,$(patsubst squashfs%,0x4,$(patsubst root.%,%,$(1)))))) +endef + # combine kernel and rootfs into one image # mktplinkfw # is "sysupgrade" or "factory" @@ -35,85 +39,45 @@ define Build/mktplinkfw-combined @mv $@.new $@ endef -# add RE450 and similar header to the kernel image -define Build/mktplinkfw-kernel - $(STAGING_DIR_HOST)/bin/mktplinkfw-kernel \ - -H $(TPLINK_HWID) -N OpenWrt -V $(REVISION) \ - -L $(KERNEL_LOADADDR) -E $(KERNEL_LOADADDR) \ - -k $@ \ - -o $@.new - @mv $@.new $@ -endef - -define Build/uImageArcher - mkimage -A $(LINUX_KARCH) \ - -O linux -T kernel \ - -C $(1) -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ - -n '$(call toupper,$(LINUX_KARCH)) LEDE Linux-$(LINUX_VERSION)' -d $@ $@.new - @mv $@.new $@ -endef - define Device/tplink TPLINK_HWREV := 0x1 TPLINK_HEADER_VERSION := 1 LOADER_TYPE := gz - KERNEL := kernel-bin | patch-cmdline | lzma - KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | mktplinkfw-combined -# IMAGES := sysupgrade.bin + KERNEL := kernel-bin | append-dtb | lzma + KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | tplink-v1-header IMAGES := sysupgrade.bin factory.bin IMAGE/sysupgrade.bin := append-rootfs | mktplinkfw sysupgrade -# IMAGE/factory.bin := append-rootfs | mktplinkfw factory | a + IMAGE/factory.bin := append-rootfs | mktplinkfw factory endef define Device/tplink-nolzma -$(Device/tplink) + $(Device/tplink) LOADER_FLASH_OFFS := 0x22000 COMPILE := loader-$(1).gz COMPILE/loader-$(1).gz := loader-okli-compile - #KERNEL := copy-file $(KDIR)/vmlinux.bin.lzma | uImage lzma -M 0x4f4b4c49 | loader-okli $(1) - KERNEL:= kernel-bin | append-dtb | lzma |uImage lzma -M 0x4f4b4c49 | loader-okli $(1) - KERNEL_INITRAMFS := copy-file $(KDIR)/vmlinux-initramfs.bin.lzma | loader-kernel-cmdline | mktplinkfw-combined + KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49 | loader-okli $(1) + KERNEL_INITRAMFS := kernel-bin | append-dtb | gzip | tplink-v1-header endef define Device/tplink-4m -$(Device/tplink-nolzma) + $(Device/tplink-nolzma) TPLINK_FLASHLAYOUT := 4M IMAGE_SIZE := 3904k endef define Device/tplink-8m -$(Device/tplink-nolzma) + $(Device/tplink-nolzma) TPLINK_FLASHLAYOUT := 8M IMAGE_SIZE := 7936k endef -define Device/tplink-4mlzma -$(Device/tplink) - TPLINK_FLASHLAYOUT := 4Mlzma - IMAGE_SIZE := 3904k -endef - -define Device/tplink-8mlzma -$(Device/tplink) - TPLINK_FLASHLAYOUT := 8Mlzma - IMAGE_SIZE := 7936k -endef - -define Device/tplink-16mlzma -$(Device/tplink) - TPLINK_FLASHLAYOUT := 16Mlzma - IMAGE_SIZE := 15872k -endef - define Device/tl_wr1043nd_v1 $(Device/tplink-8m) ATH_SOC := ar9132 DEVICE_TITLE := TP-LINK TL-WR1043N/ND v1 DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-usb-ledtrig-usbport - BOARDNAME := TL-WR1043ND - DEVICE_PROFILE := TLWR1043 TPLINK_HWID := 0x10430001 + SUPPORTED_DEVICES := tplink,tl-wr1043nd-v1 tl-wr1043nd endef - #TARGET_DEVICES += tl_wr1043nd_v1 diff --git a/target/linux/ath79/image/generic-ubnt.mk b/target/linux/ath79/image/generic-ubnt.mk index 17c89fcb1..1aae93869 100644 --- a/target/linux/ath79/image/generic-ubnt.mk +++ b/target/linux/ath79/image/generic-ubnt.mk @@ -24,252 +24,58 @@ define Build/mkubntimage-split rm $@.old1 $@.old2 ) endef -define Build/mkubntimage2 - -$(STAGING_DIR_HOST)/bin/mkfwimage2 -f 0x9f000000 \ - -v $(UBNT_TYPE).$(UBNT_CHIP).v6.0.0-$(VERSION_DIST)-$(REVISION) \ - -p jffs2:0x50000:0xf60000:0:0:$@ \ - -o $@.new - @mv $@.new $@ -endef - - # UBNT_BOARD e.g. one of (XS2, XS5, RS, XM) # UBNT_TYPE e.g. one of (BZ, XM, XW) # UBNT_CHIP e.g. one of (ar7240, ar933x, ar934x) define Device/ubnt DEVICE_PACKAGES := kmod-usb-core kmod-usb2 - DEVICE_PROFILE := UBNT IMAGE_SIZE := 7552k UBNT_BOARD := XM - IMAGES := sysupgrade.bin factory.bin - IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) - IMAGE/factory.bin := $$(IMAGE/sysupgrade.bin) | mkubntimage-split + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ + append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) | mkubntimage-split endef define Device/ubnt-xm $(Device/ubnt) - DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-usb-ohci + DEVICE_PACKAGES += kmod-usb-ohci UBNT_TYPE := XM UBNT_CHIP := ar7240 ATH_SOC := ar7241 KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma | uImage lzma endef -define Device/ubnt-xw - $(Device/ubnt) - UBNT_TYPE := XW - UBNT_CHIP := ar934x -endef - define Device/ubnt-bz $(Device/ubnt) UBNT_TYPE := BZ UBNT_CHIP := ar7240 + ATH_SOC := ar7241 endef -define Device/rw2458n - $(Device/ubnt-xm) - DEVICE_TITLE := Ubiquiti RW2458N - BOARDNAME := RW2458N -endef -#TARGET_DEVICES += rw2458n - -define Device/ubnt-airrouter - $(Device/ubnt-xm) - DEVICE_TITLE := Ubiquiti AirRouter - BOARDNAME := UBNT-AR -endef -#TARGET_DEVICES += ubnt-airrouter - -define Device/ubnt-bullet-m +define Device/ubnt_bullet-m $(Device/ubnt-xm) DEVICE_TITLE := Ubiquiti Bullet-M - BOARDNAME := UBNT-BM + SUPPORTED_DEVICES += bullet-m endef -TARGET_DEVICES += ubnt-bullet-m +TARGET_DEVICES += ubnt_bullet-m -define Device/ubnt-rocket-m +define Device/ubnt_rocket-m $(Device/ubnt-xm) DEVICE_TITLE := Ubiquiti Rocket-M - BOARDNAME := UBNT-RM + SUPPORTED_DEVICES += rocket-m endef -TARGET_DEVICES += ubnt-rocket-m +TARGET_DEVICES += ubnt_rocket-m -define Device/ubnt-nano-m +define Device/ubnt_nano-m $(Device/ubnt-xm) DEVICE_TITLE := Ubiquiti Nano-M - BOARDNAME := UBNT-NM + SUPPORTED_DEVICES += nano-m endef -TARGET_DEVICES += ubnt-nano-m +TARGET_DEVICES += ubnt_nano-m -define Device/ubnt-unifi +define Device/ubnt_unifi $(Device/ubnt-bz) - ATH_SOC := ar7241 DEVICE_TITLE := Ubiquiti UniFi - BOARDNAME := UBNT-UF - DEVICE_PROFILE += UBNTUNIFI -endef -TARGET_DEVICES += ubnt-unifi - -define Device/ubnt-unifiac - DEVICE_PACKAGES := kmod-usb-core kmod-usb2 - DEVICE_PROFILE := UBNT - IMAGE_SIZE := 7744k - MTDPARTS := spi0.0:384k(u-boot)ro,64k(u-boot-env)ro,7744k(firmware),7744k(ubnt-airos)ro,128k(bs),256k(cfg)ro,64k(EEPROM)ro - IMAGES := sysupgrade.bin - IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) -endef - -define Device/ubnt-unifiac-lite - $(Device/ubnt-unifiac) - DEVICE_TITLE := Ubiquiti UniFi AC-Lite - DEVICE_PACKAGES := kmod-ath10k ath10k-firmware-qca988x - DEVICE_PROFILE += UBNTUNIFIACLITE - BOARDNAME := UBNT-UF-AC-LITE -endef -#TARGET_DEVICES += ubnt-unifiac-lite - -define Device/ubnt-unifiac-mesh - $(Device/ubnt-unifiac-lite) - DEVICE_TITLE := Ubiquiti UniFi AC-Mesh -endef -#TARGET_DEVICES += ubnt-unifiac-mesh - -define Device/ubnt-unifiac-pro - $(Device/ubnt-unifiac) - DEVICE_TITLE := Ubiquiti UniFi AC-Pro - DEVICE_PACKAGES += kmod-ath10k ath10k-firmware-qca988x - DEVICE_PROFILE += UBNTUNIFIACPRO - BOARDNAME := UBNT-UF-AC-PRO -endef -#TARGET_DEVICES += ubnt-unifiac-pro - -define Device/ubnt-unifi-outdoor - $(Device/ubnt-bz) - DEVICE_TITLE := Ubiquiti UniFi Outdoor - BOARDNAME := UBNT-U20 - DEVICE_PROFILE += UBNTUNIFIOUTDOOR -endef -#TARGET_DEVICES += ubnt-unifi-outdoor - -define Device/ubnt-nano-m-xw - $(Device/ubnt-xw) - DEVICE_TITLE := Ubiquiti Nano M XW - BOARDNAME := UBNT-NM-XW -endef -#TARGET_DEVICES += ubnt-nano-m-xw - -define Device/ubnt-loco-m-xw - $(Device/ubnt-xw) - DEVICE_TITLE := Ubiquiti Loco XW - BOARDNAME := UBNT-LOCO-XW -endef -#TARGET_DEVICES += ubnt-loco-m-xw - -define Device/ubnt-rocket-m-xw - $(Device/ubnt-xw) - DEVICE_TITLE := Ubiquiti Rocket M XW - BOARDNAME := UBNT-RM-XW -endef -#TARGET_DEVICES += ubnt-rocket-m-xw - -define Device/ubnt-rocket-m-ti - $(Device/ubnt-xw) - DEVICE_TITLE := Ubiquiti Rocket M TI - BOARDNAME := UBNT-RM-TI - UBNT_TYPE := TI -endef -#TARGET_DEVICES += ubnt-rocket-m-ti - -define Device/ubnt-air-gateway - $(Device/ubnt-xm) - DEVICE_TITLE := Ubiquiti Air Gateway - BOARDNAME := UBNT-AGW - UBNT_TYPE := AirGW - UBNT_CHIP := ar933x - CONSOLE := ttyATH0,115200 -endef -#TARGET_DEVICES += ubnt-air-gateway - -define Device/ubnt-air-gateway-pro - $(Device/ubnt-xm) - DEVICE_TITLE := Ubiquiti Air Gateway Pro - BOARDNAME := UBNT-AGWP - UBNT_TYPE := AirGWP - UBNT_CHIP := ar934x -endef -#TARGET_DEVICES += ubnt-air-gateway-pro - -define Device/ubdev01 - $(Device/ubnt-xm) - DEVICE_TITLE := Ubiquiti ubDEV01 - MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7488k(firmware),64k(certs),256k(cfg)ro,64k(EEPROM)ro - BOARDNAME := UBNT-UF - UBNT_BOARD := UBDEV01 -endef -#TARGET_DEVICES += ubdev01 - -define Device/ubnt-routerstation - DEVICE_PACKAGES := kmod-usb-core kmod-usb-ohci kmod-usb2 - DEVICE_PROFILE := UBNT - IMAGE_SIZE := 16128k - IMAGES := sysupgrade.bin factory.bin - IMAGE/factory.bin := append-rootfs | pad-rootfs | mkubntimage - IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | combined-image | check-size $$$$(IMAGE_SIZE) - KERNEL := kernel-bin | patch-cmdline | lzma | pad-to $$(BLOCKSIZE) -endef - -define Device/ubnt-rs - $(Device/ubnt-routerstation) - DEVICE_TITLE := Ubiquiti RouterStation - BOARDNAME := UBNT-RS - DEVICE_PROFILE += UBNTRS - UBNT_BOARD := RS - UBNT_TYPE := RSx - UBNT_CHIP := ar7100 -endef -#TARGET_DEVICES += ubnt-rs - -define Device/ubnt-rspro - $(Device/ubnt-routerstation) - DEVICE_TITLE := Ubiquiti RouterStation Pro - BOARDNAME := UBNT-RSPRO - DEVICE_PROFILE += UBNTRSPRO - UBNT_BOARD := RSPRO - UBNT_TYPE := RSPRO - UBNT_CHIP := ar7100pro -endef -#TARGET_DEVICES += ubnt-rspro - -define Device/ubnt-ls-sr71 - $(Device/ubnt-routerstation) - DEVICE_TITLE := Ubiquiti LS-SR71 - BOARDNAME := UBNT-LS-SR71 - UBNT_BOARD := LS-SR71 - UBNT_TYPE := LS-SR71 - UBNT_CHIP := ar7100 -endef -#TARGET_DEVICES += ubnt-ls-sr71 - -define Device/ubnt-uap-pro - DEVICE_TITLE := Ubiquiti UAP Pro - KERNEL_SIZE := 1536k - IMAGE_SIZE := 15744k - MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1536k(kernel),14208k(rootfs),256k(cfg)ro,64k(EEPROM)ro,15744k@0x50000(firmware) - UBNT_TYPE := BZ - UBNT_CHIP := ar934x - BOARDNAME := UAP-PRO - DEVICE_PROFILE := UBNT UAPPRO - KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma | jffs2 kernel0 - IMAGES := sysupgrade.bin factory.bin - IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) - IMAGE/factory.bin := $$(IMAGE/sysupgrade.bin) | mkubntimage2 -endef - -define Device/ubnt-unifi-outdoor-plus - $(Device/ubnt-uap-pro) - DEVICE_TITLE := Ubiquiti UniFi Outdoor Plus - UBNT_CHIP := ar7240 - BOARDNAME := UBNT-UOP - DEVICE_PROFILE := UBNT + SUPPORTED_DEVICES += unifi endef +TARGET_DEVICES += ubnt_unifi diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index dab98b722..cb5dc38f6 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -21,73 +21,70 @@ define Build/netgear-uImage $(call Build/uImage,$(1) -M $(NETGEAR_KERNEL_MAGIC)) endef -define Device/ew_dorin + +define Device/avm_fritz300e + ATH_SOC := ar7242 + DEVICE_TITLE := AVM FRITZ!WLAN Repeater 300E + KERNEL := kernel-bin | append-dtb | lzma | eva-image + KERNEL_INITRAMFS := $$(KERNEL) + IMAGE_SIZE := 15232k + IMAGE/sysupgrade.bin := append-kernel | pad-to 64k | \ + append-squashfs-fakeroot-be | pad-to 256 | \ + append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) + DEVICE_PACKAGES := fritz-tffs rssileds -swconfig +endef +TARGET_DEVICES += avm_fritz300e + +define Device/embeddedwireless_dorin ATH_SOC := ar9331 DEVICE_TITLE := Embedded Wireless Dorin DEVICE_PACKAGES := kmod-usb-chipidea2 + IMAGE_SIZE := 16000k + SUPPORTED_DEVICES += ew-dorin endef +TARGET_DEVICES += embeddedwireless_dorin -TARGET_DEVICES += ew_dorin - -define Device/gl_ar150 +define Device/glinet_ar150 ATH_SOC := ar9330 DEVICE_TITLE := GL.iNet GL-AR150 DEVICE_PACKAGES := kmod-usb-chipidea2 IMAGE_SIZE := 16000k + SUPPORTED_DEVICES += gl-ar150 endef -TARGET_DEVICES += gl_ar150 +TARGET_DEVICES += glinet_ar150 -define Device/om5p_ac +define Device/openmesh_om5p-ac-v2 ATH_SOC := qca9558 - DEVICE_TITLE := OpenMesh OM5P-AC - DEVICE_PROFILE := OM5P-AC + DEVICE_TITLE := OpenMesh OM5P-AC v2 DEVICE_PACKAGES := kmod-ath10k ath10k-firmware-qca988x om-watchdog + IMAGE_SIZE := 7808k + SUPPORTED_DEVICES += om5p-acv2 endef - -TARGET_DEVICES += om5p_ac - -define Device/netgear_wndr3700 - ATH_SOC:=ar7100 - DEVICE_TITLE := NETGEAR WNDR3700 - DEVICE_PACKAGES := kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport kmod-leds-reset - NETGEAR_KERNEL_MAGIC := 0x33373030 - NETGEAR_BOARD_ID := WNDR3700 - IMAGE_SIZE := 7680k - IMAGES := sysupgrade.bin factory.img factory-NA.img - KERNEL := kernel-bin | append-dtb | lzma -d20 | netgear-uImage lzma - KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma -d20 | netgear-uImage lzma - IMAGE/default := append-kernel | pad-to $$$$(BLOCKSIZE) | netgear-squashfs | append-rootfs | pad-rootfs - IMAGE/sysupgrade.bin := $$(IMAGE/default) | check-size $$$$(IMAGE_SIZE) - IMAGE/factory.img := $$(IMAGE/default) | netgear-dni | check-size $$$$(IMAGE_SIZE) - IMAGE/factory-NA.img := $$(IMAGE/default) | netgear-dni NA | check-size $$$$(IMAGE_SIZE) -endef -#TARGET_DEVICES += netgear_wndr3700 - -define Device/netgear_wndr3700v2 - $(Device/netgear_wndr3700) - DEVICE_TITLE := NETGEAR WNDR3700 v2 - NETGEAR_BOARD_ID := WNDR3700v2 - NETGEAR_KERNEL_MAGIC := 0x33373031 - NETGEAR_HW_ID := 29763654+16+64 - IMAGE_SIZE := 15872k - IMAGES := sysupgrade.bin factory.img -endef -#TARGET_DEVICES += netgear_wndr3700v2 +TARGET_DEVICES += openmesh_om5p-ac-v2 define Device/netgear_wndr3800 - $(Device/netgear_wndr3700v2) ATH_SOC := ar7161 DEVICE_TITLE := NETGEAR WNDR3800 + NETGEAR_KERNEL_MAGIC := 0x33373031 + KERNEL := kernel-bin | append-dtb | lzma -d20 | netgear-uImage lzma + KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma -d20 | netgear-uImage lzma NETGEAR_BOARD_ID := WNDR3800 NETGEAR_HW_ID := 29763654+16+128 + IMAGE_SIZE := 15872k + IMAGES := sysupgrade.bin factory.img + IMAGE/default := append-kernel | pad-to $$$$(BLOCKSIZE) | netgear-squashfs | append-rootfs | pad-rootfs + IMAGE/sysupgrade.bin := $$(IMAGE/default) | append-metadata | check-size $$$$(IMAGE_SIZE) + IMAGE/factory.img := $$(IMAGE/default) | netgear-dni | check-size $$$$(IMAGE_SIZE) + DEVICE_PACKAGES := kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport kmod-leds-reset + SUPPORTED_DEVICES += wndr3800 endef TARGET_DEVICES += netgear_wndr3800 define Device/buffalo_wzr-hp-g450h ATH_SOC := ar7242 DEVICE_TITLE := Buffalo WZR-HP-G450H - DEVICE_PROFILE := WZR-HP-G450H DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-usb-ledtrig-usbport + IMAGE_SIZE := 32256k + SUPPORTED_DEVICES += wzr-hp-g450h endef - TARGET_DEVICES += buffalo_wzr-hp-g450h diff --git a/target/linux/ath79/image/legacy.mk b/target/linux/ath79/image/legacy.mk deleted file mode 100644 index cbc859dd0..000000000 --- a/target/linux/ath79/image/legacy.mk +++ /dev/null @@ -1,1058 +0,0 @@ -rootfs_type=$(patsubst squashfs-%,squashfs,$(1)) - -# $(1): rootfs type. -# $(2): board name. -define imgname -$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(call rootfs_type,$(1)) -endef - -define rootfs_align -$(patsubst %-256k,0x40000,$(patsubst %-128k,0x20000,$(patsubst %-64k,0x10000,$(patsubst squashfs%,0x4,$(patsubst root.%,%,$(1)))))) -endef - -define sysupname -$(call imgname,$(1),$(2))-sysupgrade.bin -endef - -define factoryname -$(call imgname,$(1),$(2))-factory.bin -endef - -COMMA:=, - -define mkcmdline -$(if $(1),board=$(1) )$(if $(2),console=$(2)$(COMMA)$(3)) -endef - -define mtdpartsize -$(shell sz=`echo '$(2)' | sed -ne 's/.*[:$(COMMA)]\([0-9]*\)k[@]*[0-9a-zx]*($(1)).*/\1/p'`; [ -n "$$sz" ] && echo $$(($$sz * 1024))) -endef - -# $(1) : name of image build method to be used, e.g., AthLzma. -# $(2) : name of the build template to be used, e.g. 64k, 64kraw, 128k, etc. -# $(3) : name of the profile to be defined. -# $(4) : board name. -# $(5)~$(7) : arguments for $(mkcmdline) -# board=$(1) console=$(2),$(3) -# $(8)~$(14): extra arguments. -define SingleProfile - # $(1): action name, e.g. loader, buildkernel, squashfs, etc. - define Image/Build/Profile/$(3) - $$(call Image/Build/Template/$(2)/$$(1),$(1),$(4),$$(call mkcmdline,$(5),$(6),$(7)),$(8),$(9),$(10),$(11),$(12),$(13),$(14)) - endef -endef - -LOADER_MAKE := $(NO_TRACE_MAKE) -C lzma-loader KDIR=$(KDIR) - -VMLINUX:=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux -UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage - -# $(1): input file. -# $(2): output file. -# $(3): extra arguments for lzma. -define CompressLzma - $(STAGING_DIR_HOST)/bin/lzma e $(1) -lc1 -lp2 -pb2 $(3) $(2) -endef - -define PatchKernel - cp $(KDIR)/vmlinux$(3) $(KDIR_TMP)/vmlinux$(3)-$(1) - $(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR_TMP)/vmlinux$(3)-$(1) "$(strip $(2))" -endef - -define PatchKernel/initramfs - $(call PatchKernel,$(1),$(2),-initramfs) - cp $(KDIR_TMP)/vmlinux-initramfs-$(1) $(call imgname,initramfs,$(1)).bin -endef - -# $(1): board name. -# $(2): kernel command line. -# $(3): extra argumetns for lzma. -# $(4): name suffix, e.g. "-initramfs". -define PatchKernelLzma - cp $(KDIR)/vmlinux$(4) $(KDIR_TMP)/vmlinux$(4)-$(1) - $(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR_TMP)/vmlinux$(4)-$(1) "$(strip $(2))" - $(call CompressLzma,$(KDIR_TMP)/vmlinux$(4)-$(1),$(KDIR_TMP)/vmlinux$(4)-$(1).bin.lzma,$(3)) -endef - -define PatchKernelGzip - cp $(KDIR)/vmlinux$(3) $(KDIR_TMP)/vmlinux$(3)-$(1) - $(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR_TMP)/vmlinux$(3)-$(1) "$(strip $(2))" - gzip -9n -c $(KDIR_TMP)/vmlinux$(3)-$(1) > $(KDIR_TMP)/vmlinux$(3)-$(1).bin.gz -endef - -ifneq ($(SUBTARGET),mikrotik) -# $(1): compression method of the data. -# $(2): extra arguments. -# $(3): input data file. -# $(4): output file. -define MkuImage - mkimage -A mips -O linux -T kernel -a 0x80060000 -C $(1) $(2) \ - -e 0x80060000 -n 'MIPS $(VERSION_DIST) Linux-$(LINUX_VERSION)' \ - -d $(3) $(4) -endef - -# $(1): board name. -# $(2): kernel command line. -# $(3): extra arguments for lzma. -# $(4): name suffix, e.g. "-initramfs". -# $(5): extra arguments for mkimage. -define MkuImageLzma - $(call PatchKernelLzma,$(1),$(2),$(3),$(4)) - $(call MkuImage,lzma,$(5),$(KDIR_TMP)/vmlinux$(4)-$(1).bin.lzma,$(KDIR_TMP)/vmlinux$(4)-$(1).uImage) -endef - -define MkuImageLzma/initramfs - $(call PatchKernelLzma,$(1),$(2),$(3),-initramfs) - $(call MkuImage,lzma,$(4),$(KDIR_TMP)/vmlinux-initramfs-$(1).bin.lzma,$(call imgname,initramfs,$(1))-uImage.bin) -endef - -define MkuImageGzip - $(call PatchKernelGzip,$(1),$(2)) - $(call MkuImage,gzip,,$(KDIR_TMP)/vmlinux-$(1).bin.gz,$(KDIR_TMP)/vmlinux-$(1).uImage) -endef - -define MkuImageGzip/initramfs - $(call PatchKernelGzip,$(1),$(2),-initramfs) - $(call MkuImage,gzip,,$(KDIR_TMP)/vmlinux-initramfs-$(1).bin.gz,$(call imgname,initramfs,$(1))-uImage.bin) -endef - -define MkuImageOKLI - $(call MkuImage,lzma,-M 0x4f4b4c49,$(KDIR)/vmlinux.bin.lzma,$(KDIR_TMP)/vmlinux-$(1).okli) -endef -endif - -# $(1): name of the 1st file. -# $(2): size limit of the 1st file if it is greater than 262144, or -# the erase size of the flash if it is greater than zero and less -# than 262144 -# $(3): name of the 2nd file. -# $(4): size limit of the 2nd file if $(2) is greater than 262144, otherwise -# it is the size limit of the output file -# $(5): name of the output file. -# $(6): padding size. -define CatFiles - if [ $(2) -eq 0 ]; then \ - filename="$(3)"; fstype=$${filename##*\.}; \ - case "$${fstype}" in \ - *) bs=`stat -c%s $(1)`;; \ - esac; \ - ( dd if=$(1) bs=$${bs} conv=sync; cat $(3) ) > $(5); \ - if [ -n "$(6)" ]; then \ - case "$${fstype}" in \ - squashfs*) \ - padjffs2 $(5) $(6); \ - ;; \ - esac; \ - fi; \ - if [ `stat -c%s $(5)` -gt $(4) ]; then \ - echo "Warning: $(5) is too big (> $(4) bytes)" >&2; \ - rm -f $(5); \ - fi; \ - else if [ $(2) -gt 262144 ]; then \ - if [ `stat -c%s "$(1)"` -gt $(2) ]; then \ - echo "Warning: $(1) is too big (> $(2) bytes)" >&2; \ - else if [ `stat -c%s $(3)` -gt $(4) ]; then \ - echo "Warning: $(3) is too big (> $(4) bytes)" >&2; \ - else \ - ( dd if=$(1) bs=$(2) conv=sync; dd if=$(3) ) > $(5); \ - fi; fi; \ - else \ - ( dd if=$(1) bs=$(2) conv=sync; dd if=$(3) ) > $(5); \ - if [ `stat -c%s $(5)` -gt $(4) ]; then \ - echo "Warning: $(5) is too big (> $(4) bytes)" >&2; \ - rm -f $(5); \ - fi; \ - fi; fi -endef - -# $(1): rootfs type. -# $(2): board name. -# $(3): kernel image size limit. -# $(4): rootfs image size limit. -# $(5): padding argument for padjffs2. -Sysupgrade/KR=$(call CatFiles,$(2),$(3),$(KDIR)/root.$(1),$(4),$(call sysupname,$(1),$(5))) -Sysupgrade/KRuImage=$(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).uImage,$(3),$(KDIR)/root.$(1),$(4),$(call sysupname,$(1),$(2)),$(5)) -Sysupgrade/RKuImage=$(call CatFiles,$(KDIR)/root.$(1),$(4),$(KDIR_TMP)/vmlinux-$(2).uImage,$(3),$(call sysupname,$(1),$(2))) - -# $(1): ubinize ini file -# $(2): working directory -# $(3): output file -# $(4): physical erase block size -# $(5): minimum I/O unit size -# $(6): custom options -define ubinize - $(CP) $(1) $(2) - ( cd $(2); $(STAGING_DIR_HOST)/bin/ubinize -o $(3) -p $(4) -m $(5) $(6) $(1)) -endef - -# -# Embed lzma-compressed kernel inside lzma-loader. -# -# $(1), suffix of output filename, e.g. generic, lowercase board name, etc. -# $(2), suffix of target file to build, e.g. bin, gz, elf -# $(3), kernel command line to pass from lzma-loader to kernel -# $(4), unused here -# $(5), suffix of kernel filename, e.g. -initramfs, or empty -define Image/BuildLoader - -rm -rf $(KDIR)/lzma-loader - $(LOADER_MAKE) LOADER=loader-$(1).$(2) KERNEL_CMDLINE="$(3)"\ - LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ - LOADER_DATA="$(KDIR)/vmlinux$(5).bin.lzma" BOARD="$(1)" \ - compile loader.$(2) - -$(if $(5),$(CP) $(KDIR)/loader-$(1).$(2) $(KDIR)/loader-$(1)$(5).$(2)) -endef - -# -# Build lzma-loader alone which will search for lzma-compressed kernel identified by -# uImage header with magic "OKLI" at boot time. -# -# $(4), offset into the flash space to start searching uImage magic "OKLI". -# $(5), size of search range starting at $(4). With 0 as the value, uImage -# header is expected to be at precisely $(4) -define Image/BuildLoaderAlone - -rm -rf $(KDIR)/lzma-loader - $(LOADER_MAKE) LOADER=loader-$(1).$(2) KERNEL_CMDLINE="$(3)" \ - LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ - BOARD="$(1)" FLASH_OFFS=$(4) FLASH_MAX=$(5) \ - compile loader.$(2) -endef - -define Build/Clean - $(LOADER_MAKE) clean -endef - -alfa_ap120c_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,13312k(rootfs),1536k(kernel),1152k(unknown)ro,64k(art)ro;spi0.1:-(unknown) -alfa_ap96_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,256k(u-boot-env)ro,13312k(rootfs),2048k(kernel),512k(caldata)ro,15360k@0x80000(firmware) -alfa_mtdlayout_8M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6144k(rootfs),1600k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) -alfa_mtdlayout_16M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,15936k(firmware),64k(nvram),64k(art)ro -all0258n_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),6272k(firmware),1536k(failsafe),64k(art)ro -all0315n_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,256k(u-boot-env),13568k(firmware),2048k(failsafe),256k(art)ro -ap96_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,6144k(rootfs),1728k(kernel),64k(art)ro,7872k@0x40000(firmware) -ap121_mtdlayout_8M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6144k(rootfs),1600k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) -ap121_mtdlayout_16M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,10944k(rootfs),4992k(kernel),64k(nvram),64k(art)ro,15936k@0x50000(firmware) -ap132_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),6400k(rootfs),64k(art)ro,7808k@0x50000(firmware) -ap135_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -ap136_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(mib0),64k(art)ro,7744k@0x50000(firmware) -ap143_mtdlayout_8M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1472k(kernel),64k(art)ro,7744k@0x50000(firmware) -ap143_mtdlayout_16M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -ap147_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -ap152_mtdlayout_16M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -bxu2000n2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),8448k(rootfs),6016k(user),64k(cfg),64k(oem),64k(art)ro -cameo_ap81_mtdlayout=mtdparts=spi0.0:128k(u-boot)ro,64k(config)ro,3840k(firmware),64k(art)ro -cameo_ap91_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,3712k(firmware),64k(mac)ro,64k(art)ro -cameo_ap99_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,3520k(firmware),64k(mac)ro,192k(lp)ro,64k(art)ro -cameo_ap121_mtdlayout=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k(nvram)ro,192k(language)ro,3648k(firmware) -cameo_ap121_mtdlayout_8M=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k(nvram)ro,256k(language)ro,7680k@0x80000(firmware) -cameo_ap123_mtdlayout_4M=mtdparts=spi0.0:64k(u-boot)ro,64k(nvram)ro,3712k(firmware),192k(lang)ro,64k(art)ro -cameo_db120_mtdlayout=mtdparts=spi0.0:64k(uboot)ro,64k(nvram)ro,15936k(firmware),192k(lang)ro,64k(mac)ro,64k(art)ro -cameo_db120_mtdlayout_8M=mtdparts=spi0.0:64k(uboot)ro,64k(nvram)ro,7872k(firmware),128k(lang)ro,64k(art)ro -cap4200ag_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),320k(custom)ro,1536k(kernel),12096k(rootfs),2048k(failsafe),64k(art)ro,13632k@0xa0000(firmware) -eap300v2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),320k(custom),13632k(firmware),2048k(failsafe),64k(art)ro -db120_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) -dgl_5500_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,15296k(firmware),192k(lang)ro,512k(my-dlink)ro,64k(mac)ro,64k(art)ro -dlan_hotspot_mtdlayout=mtdparts=spi0.0:128k(u-boot)ro,64k(Config1)ro,64k(Config2)ro,7872k@0x40000(firmware),64k(art)ro -dlan_pro_500_wp_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,64k(Config1)ro,64k(Config2)ro,7680k@0x70000(firmware),64k(art)ro -dlan_pro_1200_ac_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,64k(Config1)ro,64k(Config2)ro,15872k@0x70000(firmware),64k(art)ro -cameo_ap94_mtdlayout=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,6208k(firmware),64k(caldata)ro,1600k(unknown)ro,64k@0x7f0000(caldata_copy) -cameo_ap94_mtdlayout_fat=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,7808k(firmware),64k(caldata)ro,64k@0x660000(caldata_orig),6208k@0x50000(firmware_orig) -esr900_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),13248k(rootfs),1024k(manufacture)ro,64k(backup)ro,320k(storage)ro,64k(caldata)ro,14656k@0x40000(firmware) -esr1750_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),13248k(rootfs),1024k(manufacture)ro,64k(backup)ro,320k(storage)ro,64k(caldata)ro,14656k@0x40000(firmware) -epg5000_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),13248k(rootfs),1024k(manufacture)ro,64k(backup)ro,320k(storage)ro,64k(caldata)ro,14656k@0x40000(firmware) -f9k1115v2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),14464k(rootfs),1408k(kernel),64k(nvram)ro,64k(envram)ro,64k(art)ro,15872k@0x50000(firmware) -dlrtdev_mtdlayout=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,6208k(firmware),64k(caldata)ro,640k(certs),960k(unknown)ro,64k@0x7f0000(caldata_copy) -dlrtdev_mtdlayout_fat=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,7168k(firmware),640k(certs),64k(caldata)ro,64k@0x660000(caldata_orig),6208k@0x50000(firmware_orig) -planex_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7744k(firmware),128k(art)ro -whrhpg300n_mtdlayout=mtdparts=spi0.0:248k(u-boot)ro,8k(u-boot-env)ro,3712k(firmware),64k(art)ro -wndap360_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7744k(firmware),64k(nvram)ro,64k(art)ro -wnr2200_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7808k(firmware),64k(art)ro -wnr2000_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,3712k(firmware),64k(art)ro -wnr2000v3_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,3712k(firmware),64k(art)ro -wnr2000v4_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,3776k(firmware),64k(art)ro -r6100_mtdlayout=mtdparts=ar934x-nfc:128k(u-boot)ro,256k(caldata)ro,256k(caldata-backup),512k(config),512k(pot),2048k(kernel),122240k(ubi),25600k@0x1a0000(firmware),2048k(language),3072k(traffic_meter) -tew823dru_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,15296k(firmware),192k(lang)ro,512k(my-dlink)ro,64k(mac)ro,64k(art)ro -wndr4300_mtdlayout=mtdparts=ar934x-nfc:256k(u-boot)ro,256k(u-boot-env)ro,256k(caldata)ro,512k(pot),2048k(language),512k(config),3072k(traffic_meter),2048k(kernel),23552k(ubi),25600k@0x6c0000(firmware),256k(caldata_backup),-(reserved) -zcn1523h_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6208k(rootfs),1472k(kernel),64k(configure)ro,64k(mfg)ro,64k(art)ro,7680k@0x50000(firmware) -mynet_rext_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,7808k(firmware),64k(nvram)ro,64k(ART)ro -zyx_nbg6716_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(env)ro,64k(RFdata)ro,-(nbu);ar934x-nfc:2048k(zyxel_rfsd),2048k(romd),1024k(header),2048k(kernel),-(ubi) - -define Image/BuildKernel - cp $(KDIR)/vmlinux.elf $(VMLINUX).elf - cp $(KDIR)/vmlinux $(VMLINUX).bin - dd if=$(KDIR)/vmlinux.bin.lzma of=$(VMLINUX).lzma bs=65536 conv=sync - $(call MkuImage,lzma,,$(KDIR)/vmlinux.bin.lzma,$(UIMAGE)-lzma.bin) - cp $(KDIR)/loader-generic.elf $(VMLINUX)-lzma.elf - -mkdir -p $(KDIR_TMP) -endef - -define Image/BuildKernel/Initramfs - cp $(KDIR)/vmlinux-initramfs.elf $(VMLINUX)-initramfs.elf - cp $(KDIR)/vmlinux-initramfs $(VMLINUX)-initramfs.bin - dd if=$(KDIR)/vmlinux-initramfs.bin.lzma of=$(VMLINUX)-initramfs.lzma bs=65536 conv=sync - $(call MkuImage,lzma,,$(KDIR)/vmlinux-initramfs.bin.lzma,$(UIMAGE)-initramfs-lzma.bin) - cp $(KDIR)/loader-generic-initramfs.elf $(VMLINUX)-initramfs-lzma.elf - $(call Image/Build/Initramfs) -endef - -Image/Build/WRT400N/buildkernel=$(call MkuImageLzma,$(2),$(3)) - -define Image/Build/WRT400N - $(call Sysupgrade/KRuImage,$(1),$(2),1310720,6488064) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - wrt400n $(KDIR_TMP)/vmlinux-$(2).uImage $(KDIR)/root.$(1) $(call factoryname,$(1),$(2)); \ - fi -endef - - -define Image/Build/CameoAP94/buildkernel - $(call MkuImageLzma,$(2),$(3) $(4)) - $(call MkuImageLzma,$(2)-fat,$(3) $(5)) -endef - -define Image/Build/CameoAP94 - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(eval fwsize_fat=$(call mtdpartsize,firmware,$(5))) - $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - ( \ - dd if=$(call sysupname,$(1),$(2)); \ - echo -n "$(6)"; \ - ) > $(call imgname,$(1),$(2))-backup-loader.bin; \ - if [ `stat -c%s $(call sysupname,$(1),$(2))` -gt 4194304 ]; then \ - echo "Warning: $(call sysupname,$(1),$(2)) is too big" >&2; \ - else \ - ( \ - dd if=$(call sysupname,$(1),$(2)) bs=4096k conv=sync; \ - echo -n "$(7)"; \ - ) > $(call factoryname,$(1),$(2)); \ - fi; \ - fi - $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2)-fat.uImage,0,$(KDIR)/root.$(1),$$(($(fwsize_fat)-4*64*1024)),$(KDIR_TMP)/$(2)-fat.bin,64) - if [ -e "$(KDIR_TMP)/$(2)-fat.bin" ]; then \ - echo -n "" > $(KDIR_TMP)/$(2)-fat.dummy; \ - sh $(TOPDIR)/scripts/combined-image.sh \ - "$(KDIR_TMP)/$(2)-fat.bin" \ - "$(KDIR_TMP)/$(2)-fat.dummy" \ - $(call sysupname,$(1),$(2)-fat); \ - fi -endef - -define Image/Build/WZRHP - $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(3)-4*$(4)*1024)),$(4)) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - ( \ - echo -n -e "# Airstation Public Fmt1\x00\x00\x00\x00\x00\x00\x00\x00"; \ - dd if=$(call sysupname,$(1),$(2)); \ - ) > $(call imgname,$(1),$(2))-tftp.bin; \ - buffalo-enc -p $(5) -v 1.99 \ - -i $(call sysupname,$(1),$(2)) \ - -o $(KDIR_TMP)/$(2).enc; \ - buffalo-tag -b $(5) -p $(5) -a ath -v 1.99 -m 1.01 -l mlang8 \ - -w 3 -c 0x80041000 -d 0x801e8000 -f 1 -r M_ \ - -i $(KDIR_TMP)/$(2).enc \ - -o $(call factoryname,$(1),$(2)); \ - fi -endef - -Image/Build/WZRHP64K/buildkernel=$(call MkuImageLzma,$(2),$(3)) -Image/Build/WZRHP64K/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -Image/Build/WZRHP64K=$(call Image/Build/WZRHP,$(1),$(2),33095680,64,$(4)) - -Image/Build/WZRHP128K/buildkernel=$(call MkuImageLzma,$(2),$(3)) -Image/Build/WZRHP128K/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -Image/Build/WZRHP128K=$(call Image/Build/WZRHP,$(1),$(2),33030144,128,$(4)) - - -Image/Build/WHRHPG300N/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/WHRHPG300N/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - -define Image/Build/WHRHPG300N - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - ( \ - echo -n -e "# Airstation Public Fmt1\x00\x00\x00\x00\x00\x00\x00\x00"; \ - dd if=$(call sysupname,$(1),$(2)); \ - ) > $(call imgname,$(1),$(2))-tftp.bin; \ - buffalo-enc -p $(5) -v 1.99 \ - -i $(call sysupname,$(1),$(2)) \ - -o $(KDIR_TMP)/$(2).enc; \ - buffalo-tag -b $(5) -p $(5) -a ath -v 1.99 -m 1.01 -l mlang8 \ - -w 3 -c 0x80041000 -d 0x801e8000 -f 1 -r M_ \ - -i $(KDIR_TMP)/$(2).enc \ - -o $(call factoryname,$(1),$(2)); \ - fi -endef - - -define Image/Build/Cameo - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - factory_size=$$(($(fwsize) - $(6))); \ - ( \ - dd if=$(call sysupname,$(1),$(2)) bs=$${factory_size} conv=sync; \ - echo -n $(5); \ - ) > $(call factoryname,$(1),$(2)); \ - fi -endef - -Image/Build/CameoAP81/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap81_mtdlayout)) -Image/Build/CameoAP81=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap81_mtdlayout),$(4),65536) -Image/Build/CameoAP81/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap81_mtdlayout)) - -Image/Build/CameoAP91/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap91_mtdlayout)) -Image/Build/CameoAP91=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap91_mtdlayout),$(4),65536) -Image/Build/CameoAP91/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap91_mtdlayout)) - -Image/Build/CameoAP99/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap99_mtdlayout)) -Image/Build/CameoAP99=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap99_mtdlayout),$(4),65536) -Image/Build/CameoAP99/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap99_mtdlayout)) - -Image/Build/CameoAP123_4M/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap123_mtdlayout_4M)) -Image/Build/CameoAP123_4M=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap123_mtdlayout_4M),$(4),26) -Image/Build/CameoAP123_4M/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap123_mtdlayout_4M)) - -Image/Build/CameoAP135/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/CameoAP135=$(call Image/Build/Cameo,$(1),$(2),$(3),$(4),$(5),26) -Image/Build/CameoAP135/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - -Image/Build/CameoDB120/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_db120_mtdlayout)) -Image/Build/CameoDB120=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_db120_mtdlayout),$(4),26) -Image/Build/CameoDB120/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_db120_mtdlayout)) - -Image/Build/CameoDB120_8M/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_db120_mtdlayout_8M)) -Image/Build/CameoDB120_8M=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_db120_mtdlayout_8M),$(4),26) -Image/Build/CameoDB120_8M/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_db120_mtdlayout_8M)) - -define Image/Build/CameoHornet - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - for r in $(7); do \ - [ -n "$$r" ] && dashr="-$$r" || dashr=; \ - [ -z "$$r" ] && r="DEF"; \ - mkcameofw -M HORNET -R "$$r" -S $(5) -V $(6) -c \ - -K $(8) -I $(fwsize) \ - -k "$(call sysupname,$(1),$(2))" \ - -o $(call imgname,$(1),$(2))-factory$$dashr.bin; \ - true; \ - done; \ - fi -endef - -Image/Build/CameoAP121/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap121_mtdlayout)) -Image/Build/CameoAP121=$(call Image/Build/CameoHornet,$(1),$(2),$(3),$(cameo_ap121_mtdlayout),$(4),$(5),$(6),0xe0000) -Image/Build/CameoAP121/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap121_mtdlayout)) - -Image/Build/CameoAP121_8M/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap121_mtdlayout_8M)) -Image/Build/CameoAP121_8M=$(call Image/Build/CameoHornet,$(1),$(2),$(3),$(cameo_ap121_mtdlayout_8M),$(4),$(5),$(6),0x100000) -Image/Build/CameoAP121_8M/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap121_mtdlayout_8M)) - -define Image/Build/dLAN - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) - $(eval kernsize=$(call mtdpartsize,kernel,$(4))) - $(call Sysupgrade/$(5),$(1),$(2),$(if $(6),$(6),$(kernsize)),$(if $(rootsize),$(rootsize),$(fwsize))) -endef - -Image/Build/dLANLzma/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/dLANLzma=$(call Image/Build/dLAN,$(1),$(2),$(3),$(4),$(5),$(6),$(7)) -Image/Build/dLANLzma/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - -define Image/Build/Ath - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) - $(eval kernsize=$(call mtdpartsize,kernel,$(4))) - $(call Sysupgrade/$(5),$(1),$(2),$(if $(6),$(6),$(kernsize)),$(if $(rootsize),$(rootsize),$(fwsize))) -endef - -Image/Build/AthGzip/buildkernel=$(call MkuImageGzip,$(2),$(3) $(4)) -Image/Build/AthGzip=$(call Image/Build/Ath,$(1),$(2),$(3),$(4),$(5),$(6),$(7)) -Image/Build/AthGzip/initramfs=$(call MkuImageGzip/initramfs,$(2),$(3) $(4)) - -Image/Build/AthLzma/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/AthLzma=$(call Image/Build/Ath,$(1),$(2),$(3),$(4),$(5),$(6),$(7)) -Image/Build/AthLzma/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - - -Image/Build/Belkin/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/Belkin/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - -define Image/Build/Belkin - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(eval kernsize=$(call mtdpartsize,kernel,$(4))) - $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) - $(call Sysupgrade/RKuImage,$(1),$(2),$(kernsize),$(rootsize)) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - edimax_fw_header -m $(5) -v "$(shell echo -n $(VERSION_DIST)$(REVISION) | cut -c -13)" \ - -n "uImage" \ - -i $(KDIR_TMP)/vmlinux-$(2).uImage \ - -o $(KDIR_TMP)/$(2)-uImage; \ - edimax_fw_header -m $(5) -v "$(shell echo -n $(VERSION_DIST)$(REVISION) | cut -c -13)" \ - -n "rootfs" \ - -i $(KDIR)/root.$(1) \ - -o $(KDIR_TMP)/$(2)-rootfs; \ - ( \ - dd if=$(KDIR_TMP)/$(2)-rootfs; \ - dd if=$(KDIR_TMP)/$(2)-uImage; \ - ) > "$(call factoryname,$(1),$(2))"; \ - fi -endef - -define Image/Build/EnGenius - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) - $(eval kernsize=$(call mtdpartsize,kernel,$(4))) - $(call Sysupgrade/$(5),$(1),$(2),$(if $(6),$(6),$(kernsize)),$(if $(rootsize),$(rootsize),$(fwsize))) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - mksenaofw -e $(call sysupname,$(1),$(2)) \ - -o $(call imgname,$(1),$(2))-factory.dlf \ - -r 0x101 -p $(7) -t 2; \ - fi -endef - -Image/Build/EnGenius/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/EnGenius/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - - -Image/Build/PB4X/buildkernel=$(call PatchKernelLzma,$(2),$(3)) - -define Image/Build/PB4X - dd if=$(KDIR_TMP)/vmlinux-$(2).bin.lzma \ - of=$(call imgname,kernel,$(2)).bin bs=64k conv=sync - dd if=$(KDIR)/root.$(1) \ - of=$(call imgname,$(1),$(2)-rootfs).bin bs=128k conv=sync - -sh $(TOPDIR)/scripts/combined-image.sh \ - "$(call imgname,kernel,$(2)).bin" \ - "$(call imgname,$(1),$(2)-rootfs).bin" \ - $(call sysupname,$(1),$(2)) -endef - - -Image/Build/MyLoader/buildkernel=$(call PatchKernelLzma,$(2),$(3)) -Image/Build/MyLoader/initramfs=$(call PatchKernel/initramfs,$(2),$(3)) - -define Image/Build/MyLoader - $(eval fwsize=$(shell echo $$(($(4)-0x30000-4*64*1024)))) - $(eval fwimage=$(KDIR_TMP)/$(2)-$(5)-firmware.bin) - $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).bin.lzma,65536,$(KDIR)/root.$(1),$(fwsize),$(fwimage)) - if [ -e "$(fwimage)" ]; then \ - $(STAGING_DIR_HOST)/bin/mkmylofw -B $(2) -s $(4) -v \ - -p0x00030000:0:al:0x80060000:firmware:$(fwimage) \ - $(call imgname,$(1),$(2))-$(5)-factory.img; \ - echo -n "" > $(KDIR_TMP)/empty.bin; \ - sh $(TOPDIR)/scripts/combined-image.sh \ - $(fwimage) $(KDIR_TMP)/empty.bin \ - $(call imgname,$(1),$(2))-$(5)-sysupgrade.bin; \ - fi -endef - -Image/Build/Planex/initramfs=$(call MkuImageGzip/initramfs,$(2),$(3) $(planex_mtdlayout)) -Image/Build/Planex/loader=$(call Image/BuildLoaderAlone,$(1),gz,$(2) $(planex_mtdlayout),0x52000,0) - -define Image/Build/Planex/buildkernel - [ -e "$(KDIR)/loader-$(2).gz" ] - $(call MkuImageOKLI,$(2)) - ( \ - dd if=$(KDIR)/loader-$(2).gz bs=8128 count=1 conv=sync; \ - dd if=$(KDIR_TMP)/vmlinux-$(2).okli; \ - ) > $(KDIR_TMP)/kernel-$(2).bin - $(call MkuImage,gzip,,$(KDIR_TMP)/kernel-$(2).bin,$(KDIR_TMP)/vmlinux-$(2).uImage) -endef - -define Image/Build/Planex - $(eval fwsize=$(call mtdpartsize,firmware,$(planex_mtdlayout))) - $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - $(STAGING_DIR_HOST)/bin/mkplanexfw \ - -B $(2) \ - -v 2.00.00 \ - -i $(call sysupname,$(1),$(2)) \ - -o $(call factoryname,$(1),$(2)); \ - fi -endef - - -Image/Build/ALFA/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/ALFA/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - -define Image/Build/ALFA - $(call Sysupgrade/RKuImage,$(1),$(2),$(5),$(6)) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - rm -rf $(KDIR)/$(1); \ - mkdir -p $(KDIR)/$(1); \ - cd $(KDIR)/$(1); \ - cp $(KDIR_TMP)/vmlinux-$(2).uImage $(KDIR)/$(1)/$(7); \ - cp $(KDIR)/root.$(1) $(KDIR)/$(1)/$(8); \ - $(TAR) c \ - $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \ - -C $(KDIR)/$(1) $(7) $(8) \ - | gzip -9nc > $(call factoryname,$(1),$(2)); \ - ( \ - echo WRM7222C | dd bs=32 count=1 conv=sync; \ - echo -ne '\xfe'; \ - ) >> $(call factoryname,$(1),$(2)); \ - fi -endef - - -Image/Build/Senao/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/Senao/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - -define Image/Build/Senao - mkdir -p $(KDIR_TMP)/$(2)/ - touch $(KDIR_TMP)/$(2)/FWINFO-OpenWrt-$(REVISION)-$(2) - -$(CP) ./$(2)/* $(KDIR_TMP)/$(2)/ - dd if=$(KDIR_TMP)/vmlinux-$(2).uImage \ - of=$(KDIR_TMP)/$(2)/openwrt-senao-$(2)-uImage-lzma.bin bs=64k conv=sync - dd if=$(KDIR)/root.$(1) \ - of=$(KDIR_TMP)/$(2)/openwrt-senao-$(2)-root.$(1) bs=64k conv=sync - ( \ - cd $(KDIR_TMP)/$(2)/; \ - $(TAR) -c \ - $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \ - * | gzip -9nc > $(call factoryname,$(1),$(2)) \ - ) - -rm -rf $(KDIR_TMP)/$(2)/ - -sh $(TOPDIR)/scripts/combined-image.sh \ - $(KDIR_TMP)/vmlinux-$(2).uImage \ - $(KDIR)/root.$(1) \ - $(call sysupname,$(1),$(2)) -endef - -define Image/Build/CyberTAN - echo -n '' > $(KDIR_TMP)/empty.bin - -$(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/image.tmp \ - -f $(KDIR_TMP)/vmlinux-$(2).uImage -F $(KDIR_TMP)/empty.bin \ - -x 32 -a 0x10000 -x -32 -f $(KDIR)/root.$(1) && \ - $(STAGING_DIR_HOST)/bin/addpattern -B $(2) -v v$(5) \ - -i $(KDIR)/image.tmp \ - -o $(call sysupname,$(1),$(2)) - -$(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/image.tmp -f $(KDIR_TMP)/vmlinux-$(2).uImage \ - -x 32 -a 0x10000 -x -32 -f $(KDIR)/root.$(1) && \ - $(STAGING_DIR_HOST)/bin/addpattern -B $(2) -v v$(5) -g \ - -i $(KDIR)/image.tmp \ - -o $(call factoryname,$(1),$(2)) - -rm $(KDIR)/image.tmp -endef - -Image/Build/CyberTANGZIP/loader=$(call Image/BuildLoader,$(1),gz,$(2),0x80060000) -Image/Build/CyberTANGZIP/buildkernel=$(call MkuImage,gzip,,$(KDIR)/loader-$(2).gz,$(KDIR_TMP)/vmlinux-$(2).uImage) -Image/Build/CyberTANGZIP=$(call Image/Build/CyberTAN,$(1),$(2),$(3),$(4),$(5)) - -Image/Build/CyberTANLZMA/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/CyberTANLZMA=$(call Image/Build/CyberTAN,$(1),$(2),$(3),$(4),$(5)) - - -Image/Build/Netgear/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4),,-M $(5)) - -define Image/Build/Netgear/buildkernel - $(call MkuImageLzma,$(2),$(3) $(4),-d20,,-M $(5)) - -rm -rf $(KDIR_TMP)/$(2) - mkdir -p $(KDIR_TMP)/$(2)/image - cat $(KDIR_TMP)/vmlinux-$(2).uImage > $(KDIR_TMP)/$(2)/image/uImage - $(STAGING_DIR_HOST)/bin/mksquashfs-lzma \ - $(KDIR_TMP)/$(2) $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs.tmp1 \ - -noappend -root-owned -be -b 65536 \ - $(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH)) - ( \ - cat $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs.tmp1; \ - dd if=/dev/zero bs=1k count=1 \ - ) > $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs.tmp2 - mkimage -A mips -O linux -T filesystem -C none -M $(5) \ - -a 0xbf070000 -e 0xbf070000 \ - -n 'MIPS $(VERSION_DIST) Linux-$(LINUX_VERSION)' \ - -d $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs.tmp2 \ - $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs -endef - -define Image/Build/Netgear - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).uImage.squashfs,0,$(KDIR)/root.$(1),$(fwsize),$(call sysupname,$(1),$(2)),64) - if [ -e $(call sysupname,$(1),$(2)) ]; then \ - for r in $(7) ; do \ - [ -n "$$r" ] && dashr="-$$r" || dashr= ; \ - $(STAGING_DIR_HOST)/bin/mkdniimg \ - -B $(6) -v $(VERSION_DIST).$(REVISION) -r "$$r" $(8) \ - -i $(call sysupname,$(1),$(2)) \ - -o $(call imgname,$(1),$(2))-factory$$dashr.img; \ - done; \ - fi - if [ "$2" = "wnr2000" ]; then \ - dd if=$(KDIR)/root.$(1) \ - of=$(call imgname,$(1),$(2)-rootfs).bin bs=128k conv=sync; \ - fi -endef - - -Image/Build/NetgearLzma/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4),,-M $(5)) -Image/Build/NetgearLzma/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4),-d20,,-M $(5)) - -define Image/Build/NetgearLzma - $(eval fwsize=$(call mtdpartsize,firmware,$(4))) - $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).uImage,0,$(KDIR)/root.$(1),$(fwsize),$(call sysupname,$(1),$(2)),64) -endef - - -Image/Build/NetgearNAND/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4),,-M $(5)) - -# $(1): (empty) -# $(2): Board name (small caps) -# $(3): Kernel board specific cmdline -# $(4): Kernel mtdparts definition -# $(5): U-Boot magic -define Image/Build/NetgearNAND/buildkernel - $(eval kernelsize=$(call mtdpartsize,kernel,$(4))) - $(call PatchKernelLzma,$(2),$(3) $(4),-d20) - dd if=$(KDIR_TMP)/vmlinux-$(2).bin.lzma \ - of=$(KDIR_TMP)/vmlinux-$(2).bin.tmp \ - bs=$$(($(kernelsize)-131072-2*64-1)) \ - count=1 conv=sync - $(call MkuImage,lzma,-M $(5),$(KDIR_TMP)/vmlinux-$(2).bin.tmp,$(KDIR_TMP)/vmlinux-$(2).uImage) - echo -ne '\xff' >> $(KDIR_TMP)/vmlinux-$(2).uImage - # create a fake rootfs image - dd if=/dev/zero of=$(KDIR_TMP)/fakeroot-$(2) bs=131072 count=1 - mkimage -A mips -O linux -T filesystem -C none \ - -a 0xbf070000 -e 0xbf070000 \ - -n 'MIPS $(VERSION_DIST) fakeroot' \ - -d $(KDIR_TMP)/fakeroot-$(2) \ - -M $(5) \ - $(KDIR_TMP)/fakeroot-$(2).uImage - # append the fake rootfs image to the kernel, it will reside in the last - # erase block of the kernel partition - cat $(KDIR_TMP)/fakeroot-$(2).uImage >> $(KDIR_TMP)/vmlinux-$(2).uImage -endef - - -# $(1): rootfs image suffix -# $(2): Board name (small caps) -# $(3): Kernel board specific cmdline -# $(4): Kernel mtdparts definition -# $(5): U-Boot magic -# $(6): Board name (upper caps) -# $(7): firmware region code (not used yet) -# $(8): DNI Hardware version -# $(9): suffix of the configuration file for ubinize -define Image/Build/NetgearNAND - $(eval firmwaresize=$(call mtdpartsize,firmware,$(4))) - $(eval kernelsize=$(call mtdpartsize,kernel,$(4))) - $(eval imageraw=$(KDIR_TMP)/$(2)-raw.img) - $(CP) $(KDIR)/root.squashfs-raw $(KDIR_TMP)/root.squashfs - echo -ne '\xde\xad\xc0\xde' > $(KDIR_TMP)/jffs2.eof - $(call ubinize,ubinize-$(9).ini,$(KDIR_TMP),$(KDIR_TMP)/$(2)-root.ubi,128KiB,2048,-E 5) - ( \ - dd if=$(KDIR_TMP)/vmlinux-$(2).uImage; \ - dd if=$(KDIR_TMP)/$(2)-root.ubi \ - ) > $(imageraw) - $(STAGING_DIR_HOST)/bin/mkdniimg \ - -B $(6) -v $(VERSION_DIST).$(REVISION) -r "$$r" $(8) \ - -i $(imageraw) \ - -o $(call imgname,ubi,$(2))-factory.img - - $(call Image/Build/SysupgradeNAND,$(2),squashfs,$(KDIR_TMP)/vmlinux-$(2).uImage) -endef - -ZYXEL_UBOOT = $(KDIR)/u-boot-nbg460n_550n_550nh.bin -ZYXEL_UBOOT_BIN = $(wildcard $(BIN_DIR)/u-boot-nbg460n_550n_550nh/u-boot.bin) - -Image/Build/ZyXEL/buildkernel=$(call MkuImageLzma,$(2),$(3)) - -define Image/Build/ZyXEL - $(call Sysupgrade/KRuImage,$(1),$(2),917504,2752512) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - if [ ! -f $(ZYXEL_UBOOT) ]; then \ - echo "Warning: $(ZYXEL_UBOOT) not found" >&2; \ - else \ - $(STAGING_DIR_HOST)/bin/mkzynfw \ - -B $(4) \ - -b $(ZYXEL_UBOOT) \ - -r $(call sysupname,$(1),$(2)):0x10000 \ - -o $(call factoryname,$(1),$(2)); \ - fi; fi -endef - -define Image/Build/ZyXELNAND/buildkernel - $(eval kernelsize=$(call mtdpartsize,kernel,$(5))) - $(call MkuImageLzma,$(2),$(3) $(5) $(6)) - mkdir -p $(KDIR_TMP)/$(2)/image/boot - cp $(KDIR_TMP)/vmlinux-$(2).uImage $(KDIR_TMP)/$(2)/image/boot/vmlinux.lzma.uImage - $(STAGING_DIR_HOST)/bin/mkfs.jffs2 \ - --pad=$(kernelsize) --big-endian --squash-uids -v -e 128KiB \ - -o $(KDIR_TMP)/$(2)-kernel.jffs2 \ - -d $(KDIR_TMP)/$(2)/image \ - 2>&1 1>/dev/null | awk '/^.+$$/' - -rm -rf $(KDIR_TMP)/$(2) -endef - -define Image/Build/ZyXELNAND - if [ "$(1)" != "squashfs" ]; then \ - echo Only squashfs is supported; \ - return 0; \ - fi - $(eval firmwaresize=$(call mtdpartsize,firmware,$(4))) - $(eval kernelsize=$(call mtdpartsize,kernel,$(4))) - $(eval imageraw=$(KDIR_TMP)/$(2)-raw.img) - $(CP) $(KDIR)/root.$(1) $(KDIR_TMP)/ubi_root.img - $(call ubinize,ubinize-$(2).ini,$(KDIR_TMP),$(KDIR_TMP)/$(2)-root.ubi,128KiB,2048,-E 5) - ( \ - dd if=$(KDIR_TMP)/$(2)-kernel.jffs2; \ - dd if=$(KDIR_TMP)/$(2)-root.ubi \ - ) > $(imageraw) - dd if=$(imageraw) of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory.bin \ - bs=128k conv=sync - $(call Image/Build/SysupgradeNAND,$(2),squashfs,$(KDIR_TMP)/$(2)-kernel.jffs2) -endef - - -Image/Build/OpenMesh/buildkernel=$(call MkuImageLzma,$(2)) -Image/Build/OpenMesh/initramfs=$(call MkuImageLzma/initramfs,$(2),) - -define Image/Build/OpenMesh - -sh $(TOPDIR)/scripts/om-fwupgradecfg-gen.sh \ - "$(4)" \ - "$(BUILD_DIR)/fwupgrade.cfg-$(4)" \ - "$(KDIR_TMP)/vmlinux-$(2).uImage" \ - "$(KDIR)/root.$(1)" - -sh $(TOPDIR)/scripts/combined-ext-image.sh \ - "$(4)" "$(call factoryname,$(1),$(2))" \ - "$(BUILD_DIR)/fwupgrade.cfg-$(4)" "fwupgrade.cfg" \ - "$(KDIR_TMP)/vmlinux-$(2).uImage" "kernel" \ - "$(KDIR)/root.$(1)" "rootfs" - if [ -e "$(call factoryname,$(1),$(2))" ]; then \ - cp "$(call factoryname,$(1),$(2))" "$(call sysupname,$(1),$(2))"; \ - fi -endef - - -Image/Build/Zcomax/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -Image/Build/Zcomax/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) - -define Image/Build/Zcomax - $(call Sysupgrade/RKuImage,$(1),$(2),1507328,6356992) - if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - $(STAGING_DIR_HOST)/bin/mkzcfw \ - -B $(2) \ - -k $(KDIR_TMP)/vmlinux-$(2).uImage \ - -r $(KDIR)/root.$(1) \ - -o $(call imgname,$(1),$(2))-factory.img; \ - fi -endef - - -# $(1): template name to be defined. -# $(2): squashfs suffix to be used. -define BuildTemplate - # $(1) : name of build method. - # $(2) : board name. - # $(3) : kernel command line. - # $(4)~$(8): extra arguments. - define Image/Build/Template/$(1)/initramfs - $$(call Image/Build/$$(1)/initramfs,initramfs,$$(2),$$(3),$$(4),$$(5),$$(6),$$(7),$$(8),$$(9),$$(10)) - endef - define Image/Build/Template/$(1)/loader - $$(call Image/Build/$$(1)/loader,$$(2),$$(3),$$(4),$$(5),$$(6),$$(7),$$(8),$$(9),$$(10)) - endef - define Image/Build/Template/$(1)/buildkernel - $$(call Image/Build/$$(1)/buildkernel,,$$(2),$$(3),$$(4),$$(5),$$(6),$$(7),$$(8),$$(9),$$(10)) - endef - define Image/Build/Template/$(1)/squashfs - $$(call Image/Build/$$(1),squashfs$(2),$$(2),$$(3),$$(4),$$(5),$$(6),$$(7),$$(8),$$(9),$$(10)) - endef -endef - -$(eval $(call BuildTemplate,squashfs-only)) -$(eval $(call BuildTemplate,64k,-64k)) -$(eval $(call BuildTemplate,64kraw,-raw)) -$(eval $(call BuildTemplate,64kraw-nojffs,-raw)) -$(eval $(call BuildTemplate,128k)) -$(eval $(call BuildTemplate,128kraw,-raw)) -$(eval $(call BuildTemplate,256k)) -$(eval $(call BuildTemplate,all)) - -ifeq ($(SUBTARGET),generic) -$(eval $(call SingleProfile,ALFA,64k,ALFANX,alfa-nx,ALFA-NX,ttyS0,115200,$$(alfa_mtdlayout_8M),1638400,6291456,vmlinux.gz.uImage,pb9x-2.6.31-jffs2)) -$(eval $(call SingleProfile,ALFA,64k,HORNETUB,hornet-ub,HORNET-UB,ttyATH0,115200,$$(alfa_mtdlayout_8M),1638400,6291456,kernel_image,rootfs_image)) -$(eval $(call SingleProfile,ALFA,64k,TUBE2H8M,tube2h-8M,TUBE2H,ttyATH0,115200,$$(alfa_mtdlayout_8M),1638400,6291456,kernel.image,rootfs.image)) - -$(eval $(call SingleProfile,AthGzip,64k,AP96,ap96,AP96,ttyS0,115200,$$(ap96_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthGzip,64k,WNDAP360,wndap360,WNDAP360,ttyS0,9600,$$(wndap360_mtdlayout),KRuImage,65536)) - -$(eval $(call SingleProfile,AthLzma,64k,ALFAAP120C,alfa-ap120c,ALFA-AP120C,ttyS0,115200,$$(alfa_ap120c_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,ALFAAP96,alfa-ap96,ALFA-AP96,ttyS0,115200,$$(alfa_ap96_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,ALL0258N,all0258n,ALL0258N,ttyS0,115200,$$(all0258n_mtdlayout),KRuImage,65536)) -$(eval $(call SingleProfile,AthLzma,256k,ALL0315N,all0315n,ALL0315N,ttyS0,115200,$$(all0315n_mtdlayout),KRuImage,262144)) -$(eval $(call SingleProfile,AthLzma,64k,AP121_8M,ap121-8M,AP121,ttyATH0,115200,$$(ap121_mtdlayout_8M),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP121_16M,ap121-16M,AP121,ttyATH0,115200,$$(ap121_mtdlayout_16M),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP132,ap132,AP132,ttyS0,115200,$$(ap132_mtdlayout),KRuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP135,ap135-020,AP135-020,ttyS0,115200,$$(ap135_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP136_010,ap136-010,AP136-010,ttyS0,115200,$$(ap136_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP136_020,ap136-020,AP136-020,ttyS0,115200,$$(ap136_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP143_8M,ap143-8M,AP143,ttyS0,115200,$$(ap143_mtdlayout_8M),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP143_16M,ap143-16M,AP143,ttyS0,115200,$$(ap143_mtdlayout_16M),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP147_010,ap147-010,AP147-010,ttyS0,115200,$$(ap147_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,AP152_16M,ap152-16M,AP152,ttyS0,115200,$$(ap152_mtdlayout_16M),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,BXU2000N2,bxu2000n-2-a1,BXU2000n-2-A1,ttyS0,115200,$$(bxu2000n2_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,CAP4200AG,cap4200ag,CAP4200AG,ttyS0,115200,$$(cap4200ag_mtdlayout),KRuImage)) -$(eval $(call SingleProfile,AthLzma,64k,DB120,db120,DB120,ttyS0,115200,$$(db120_mtdlayout),RKuImage)) -$(eval $(call SingleProfile,AthLzma,64k,HORNETUBx2,hornet-ub-x2,HORNET-UB,ttyATH0,115200,$$(alfa_mtdlayout_16M),KRuImage,65536)) -$(eval $(call SingleProfile,AthLzma,64k,TUBE2H16M,tube2h-16M,TUBE2H,ttyATH0,115200,$$(alfa_mtdlayout_16M),KRuImage,65536)) - -$(eval $(call SingleProfile,Belkin,64k,F9K1115V2,f9k1115v2,F9K1115V2,ttyS0,115200,$$(f9k1115v2_mtdlayout),BR-6679BAC)) - -$(eval $(call SingleProfile,CameoAP121_8M,64kraw-nojffs,DIR505A1,dir-505-a1,DIR-505-A1,ttyATH0,115200,"HORNET-PACKET-DIR505A1-3",1.99.99,"")) - -$(eval $(call SingleProfile,CameoAP135,64kraw,DGL5500A1,dgl-5500-a1,DGL-5500-A1,ttyS0,115200,$$(dgl_5500_mtdlayout),"00AP135AR9558-RT-130508-00")) -$(eval $(call SingleProfile,CameoAP135,64kraw,TEW823DRU,tew-823dru,TEW-823DRU,ttyS0,115200,$$(tew823dru_mtdlayout) mem=256M,"00AP135AR9558-RT-131129-00")) - -$(eval $(call SingleProfile,CameoDB120,64kraw,DHP1565A1,dhp-1565-a1,DHP-1565-A1,ttyS0,115200,"00DB120AR9344-RT-101214-00")) -$(eval $(call SingleProfile,CameoDB120,64kraw,DIR825C1,dir-825-c1,DIR-825-C1,ttyS0,115200,"00DB120AR9344-RT-101214-00")) -$(eval $(call SingleProfile,CameoDB120,64kraw,DIR835A1,dir-835-a1,DIR-835-A1,ttyS0,115200,"00DB120AR9344-RT-101214-00")) - -$(eval $(call SingleProfile,CameoDB120_8M,64kraw,TEW732BR,tew-732br,TEW-732BR,ttyS0,115200,"00DB120AR9341-RT-120906-NA")) - -$(eval $(call SingleProfile,CyberTANGZIP,64k,E2100L,e2100l,E2100L,ttyS0,115200,,1.00.01)) -$(eval $(call SingleProfile,CyberTANGZIP,64k,WRT160NL,wrt160nl,WRT160NL,ttyS0,115200,,1.00.01)) - -$(eval $(call SingleProfile,CyberTANLZMA,64k,MYNETREXT,mynet-rext,MYNET-REXT,ttyS0,115200,$$(mynet_rext_mtdlayout) root=31:2,1.00.01)) - -$(eval $(call SingleProfile,CameoAP94,64kraw,DIR825B1,dir-825-b1,DIR-825-B1,ttyS0,115200,$$(cameo_ap94_mtdlayout),$$(cameo_ap94_mtdlayout_fat),01AP94-AR7161-RT-080619-00,00AP94-AR7161-RT-080619-00)) -$(eval $(call SingleProfile,CameoAP94,64kraw,TEW673GRU,tew-673gru,TEW-673GRU,ttyS0,115200,$$(cameo_ap94_mtdlayout),$$(cameo_ap94_mtdlayout_fat),01AP94-AR7161-RT-080619-01,00AP94-AR7161-RT-080619-01)) -$(eval $(call SingleProfile,CameoAP94,64kraw,DLRTDEV01,dlrtdev01,DIR-825-B1,ttyS0,115200,$$(dlrtdev_mtdlayout),$$(dlrtdev_mtdlayout_fat),01AP94-AR7161-RT-080619-00,00AP94-AR7161-RT-080619-00)) - -$(eval $(call SingleProfile,dLANLzma,64k,dLAN_Hotspot,dlan-hotspot,dLAN-Hotspot,ttyATH0,115200,$$(dlan_hotspot_mtdlayout) mem=64M,KRuImage,65536)) -$(eval $(call SingleProfile,dLANLzma,64k,dLAN_pro_500_wp,dlan-pro-500-wp,dLAN-pro-500-wp,ttyS0,115200,$$(dlan_pro_500_wp_mtdlayout) mem=128M,KRuImage,65536)) -$(eval $(call SingleProfile,dLANLzma,64k,dLAN_pro_1200_ac,dlan-pro-1200-ac,dLAN-pro-1200-ac,ttyS0,115200,$$(dlan_pro_1200_ac_mtdlayout) mem=128M,KRuImage,65536)) - -$(eval $(call SingleProfile,EnGenius,64k,ESR900,esr900,ESR900,ttyS0,115200,$$(esr900_mtdlayout),KRuImage,,0x4e)) -$(eval $(call SingleProfile,EnGenius,64k,ESR1750,esr1750,ESR1750,ttyS0,115200,$$(esr1750_mtdlayout),KRuImage,,0x61)) -$(eval $(call SingleProfile,EnGenius,64k,EPG5000,epg5000,EPG5000,ttyS0,115200,$$(epg5000_mtdlayout),KRuImage,,0x71)) - -$(eval $(call SingleProfile,MyLoader,64k,WP543_8M,wp543,,ttyS0,115200,0x800000,8M)) -$(eval $(call SingleProfile,MyLoader,64k,WP543_16M,wp543,,ttyS0,115200,0x1000000,16M)) -$(eval $(call SingleProfile,MyLoader,64k,WPE72_8M,wpe72,,ttyS0,115200,0x800000,8M)) -$(eval $(call SingleProfile,MyLoader,64k,WPE72_16M,wpe72,,ttyS0,115200,0x1000000,16M)) - -$(eval $(call SingleProfile,Netgear,64kraw,WNR2200,wnr2200,WNR2200,ttyS0,115200,$$(wnr2200_mtdlayout),0x32323030,wnr2200,"" NA,)) - -$(eval $(call SingleProfile,OpenMesh,squashfs-only,A60,a60,,,,A60)) -$(eval $(call SingleProfile,OpenMesh,squashfs-only,OM2P,om2p,,,,OM2P)) -$(eval $(call SingleProfile,OpenMesh,squashfs-only,OM5P,om5p,,,,OM5P)) -$(eval $(call SingleProfile,OpenMesh,squashfs-only,OM5PAC,om5pac,,,,OM5PAC)) -$(eval $(call SingleProfile,OpenMesh,squashfs-only,MR600,mr600,,,,MR600)) -$(eval $(call SingleProfile,OpenMesh,squashfs-only,MR900,mr900,,,,MR900)) -$(eval $(call SingleProfile,OpenMesh,squashfs-only,MR1750,mr1750,,,,MR1750)) - -$(eval $(call SingleProfile,PB4X,128k,ALL0305,all0305,ALL0305,ttyS0,115200)) -$(eval $(call SingleProfile,PB4X,128k,EAP7660D,eap7660d,EAP7660D,ttyS0,115200)) -$(eval $(call SingleProfile,PB4X,64k,JA76PF,ja76pf,JA76PF,ttyS0,115200)) -$(eval $(call SingleProfile,PB4X,64k,JA76PF2,ja76pf2,JA76PF2,ttyS0,115200)) -$(eval $(call SingleProfile,PB4X,64k,JWAP003,jwap003,JWAP003,ttyS0,115200)) -$(eval $(call SingleProfile,PB4X,64k,PB42,pb42,PB42,ttyS0,115200)) -$(eval $(call SingleProfile,PB4X,64k,PB44,pb44,PB44,ttyS0,115200)) - -$(eval $(call SingleProfile,Planex,64kraw,MZKW04NU,mzk-w04nu,MZK-W04NU,ttyS0,115200)) -$(eval $(call SingleProfile,Planex,64kraw,MZKW300NH,mzk-w300nh,MZK-W300NH,ttyS0,115200)) - -$(eval $(call SingleProfile,Senao,squashfs-only,EAP300V2,eap300v2,EAP300V2,ttyS0,115200,$$(eap300v2_mtdlayout))) - -$(eval $(call SingleProfile,WRT400N,64k,WRT400N,wrt400n,WRT400N,ttyS0,115200)) - -$(eval $(call SingleProfile,WZRHP128K,128kraw,WZRHPG300NH,wzr-hp-g300nh,WZR-HP-G300NH,ttyS0,115200,WZR-HP-G300NH)) -$(eval $(call SingleProfile,WZRHP64K,64kraw,WZRHPG300NH2,wzr-hp-g300nh2,WZR-HP-G300NH2,ttyS0,115200,WZR-HP-G300NH2)) -$(eval $(call SingleProfile,WZRHP64K,64kraw,WZRHPAG300H,wzr-hp-ag300h,WZR-HP-AG300H,ttyS0,115200,WZR-HP-AG300H)) -$(eval $(call SingleProfile,WZRHP64K,64kraw,WZRHPG450H,wzr-hp-g450h,WZR-HP-G450H,ttyS0,115200,WZR-HP-AG450H)) -$(eval $(call SingleProfile,WZRHP64K,64kraw,WZR600DHP,wzr-600dhp,WZR-HP-AG300H,ttyS0,115200,WZR-600DHP)) -$(eval $(call SingleProfile,WZRHP64K,64kraw,WZR450HP2,wzr-450hp2,WZR-450HP2,ttyS0,115200,WZR-450HP2)) - -$(eval $(call SingleProfile,Zcomax,64k,ZCN1523H28,zcn-1523h-2-8,ZCN-1523H-2,ttyS0,115200,$$(zcn1523h_mtdlayout))) -$(eval $(call SingleProfile,Zcomax,64k,ZCN1523H516,zcn-1523h-5-16,ZCN-1523H-5,ttyS0,115200,$$(zcn1523h_mtdlayout))) - -endif # ifeq ($(SUBTARGET),generic) - - -ifeq ($(SUBTARGET),tiny) - -$(eval $(call SingleProfile,CameoAP91,64kraw,DIR600A1,dir-600-a1,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-00")) -$(eval $(call SingleProfile,CameoAP91,64kraw,DIR601A1,dir-601-a1,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-02")) -$(eval $(call SingleProfile,CameoAP91,64kraw,FR54RTR,fr-54rtr,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-01")) - -$(eval $(call SingleProfile,CameoAP99,64kraw,EBR2310C1,ebr-2310-c1,EBR-2310-C1,ttyS0,115200,"AP91-AR7240-RT-090223-03")) -$(eval $(call SingleProfile,CameoAP99,64kraw,DIR615E1,dir-615-e1,DIR-615-E1,ttyS0,115200,"AP93-AR7240-RT-081028-00")) -$(eval $(call SingleProfile,CameoAP99,64kraw,DIR615E4,dir-615-e4,DIR-615-E4,ttyS0,115200,"AP99-AR7240-RT-091105-05")) - -$(eval $(call SingleProfile,CameoAP123_4M,64kraw,DIR615I1,dir-615-i1,DIR-615-I1,ttyS0,115200,"00DB120AR9341-RT-1012I1-00")) -$(eval $(call SingleProfile,CameoAP123_4M,64kraw,DIR615I3,dir-615-i3,DIR-615-I1,ttyS0,115200,"00DB120AR9341-RT-101214-00")) - -$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,A02RBW300N,a02-rb-w300n,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-03")) -$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,DIR615C1,dir-615-c1,DIR-615-C1,ttyS0,115200,"AP81-AR9130-RT-070614-02")) -$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,TEW632BRP,tew-632brp,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-00")) -$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,TEW652BRP_FW,tew-652brp,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-080609-05")) -$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,TEW652BRP_RECOVERY,tew-652brp-recovery,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-02")) - -$(eval $(call SingleProfile,CameoAP121,64kraw-nojffs,TEW712BR,tew-712br,TEW-712BR,ttyATH0,115200,"HORNET-RT-TEW712BR-3",1.99,"")) -$(eval $(call SingleProfile,CameoAP121,64kraw-nojffs,DIR601B1,dir-601-b1,TEW-712BR,ttyATH0,115200,"HORNET-RT-DIR601B1-3",2.99.99,"" "NA")) - -$(eval $(call SingleProfile,MyLoader,64k,WP543_4M,wp543,,ttyS0,115200,0x400000,4M)) -$(eval $(call SingleProfile,MyLoader,64k,WPE72_4M,wpe72,,ttyS0,115200,0x400000,4M)) - -$(eval $(call SingleProfile,Netgear,64kraw,WNR2000V3,wnr2000v3,WNR2000V3,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x32303033,WNR2000V3,"" NA,-H 29763551+04+32)) -$(eval $(call SingleProfile,NetgearLzma,64kraw,WNR2000V4,wnr2000v4,WNR2000V4,ttyS0,115200,$$(wnr2000v4_mtdlayout),0x32303034,WNR2000V4,"" NA,)) -$(eval $(call SingleProfile,Netgear,64kraw,WNR2000,wnr2000,WNR2000,ttyS0,115200,$$(wnr2000_mtdlayout),0x32303031,WNR2000,"" NA,)) -$(eval $(call SingleProfile,Netgear,64kraw,REALWNR612V2,wnr612v2,WNR612V2,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x32303631,WNR612V2,"",)) -$(eval $(call SingleProfile,Netgear,64kraw,N150R,n150r,WNR612V2,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x32303631,N150R,"",)) -$(eval $(call SingleProfile,Netgear,64kraw,REALWNR1000V2,wnr1000v2,WNR1000V2,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x31303031,WNR1000V2,"",)) -$(eval $(call SingleProfile,Netgear,64kraw,WNR1000V2_VC,wnr1000v2-vc,WNR1000V2,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x31303030,WNR1000V2-VC,"",)) -$(eval $(call SingleProfile,Netgear,64kraw,WPN824N,wpn824n,WPN824N,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x31313030,WPN824N,"" NA,)) - -$(eval $(call SingleProfile,WHRHPG300N,64kraw,WHRG301N,whr-g301n,WHR-G301N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-G301N)) -$(eval $(call SingleProfile,WHRHPG300N,64kraw,WHRHPG300N,whr-hp-g300n,WHR-HP-G300N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-HP-G300N)) -$(eval $(call SingleProfile,WHRHPG300N,64kraw,WHRHPGN,whr-hp-gn,WHR-HP-GN,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-HP-GN)) -$(eval $(call SingleProfile,WHRHPG300N,64kraw,WLAEAG300N,wlae-ag300n,WLAE-AG300N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WLAE-AG300N)) - -$(eval $(call SingleProfile,ZyXEL,64k,NBG_460N_550N_550NH,nbg460n_550n_550nh,NBG460N,ttyS0,115200,NBG-460N)) - -endif # ifeq ($(SUBTARGET),tiny) - - -ifeq ($(SUBTARGET),nand) - -$(eval $(call SingleProfile,NetgearNAND,64k,WNDR3700V4,wndr3700v4,WNDR3700_V4,ttyS0,115200,$$(wndr4300_mtdlayout),0x33373033,WNDR3700v4,"",-H 29763948+128+128,wndr4300)) -$(eval $(call SingleProfile,NetgearNAND,64k,WNDR4300V1,wndr4300,WNDR4300,ttyS0,115200,$$(wndr4300_mtdlayout),0x33373033,WNDR4300,"",-H 29763948+0+128+128+2x2+3x3,wndr4300)) -$(eval $(call SingleProfile,NetgearNAND,64k,R6100,r6100,R6100,ttyS0,115200,$$(r6100_mtdlayout),0x36303030,R6100,"",-H 29764434+0+128+128+2x2+2x2,wndr4300)) - -$(eval $(call SingleProfile,ZyXELNAND,128k,NBG6716,nbg6716,NBG6716,ttyS0,115200,NBG6716,$$(zyx_nbg6716_mtdlayout),mem=256M)) - -endif # ifeq ($(SUBTARGET),nand) - -define Image/Build/squashfs - cp $(KDIR)/root.squashfs $(KDIR)/root.squashfs-raw - cp $(KDIR)/root.squashfs $(KDIR)/root.squashfs-64k - $(STAGING_DIR_HOST)/bin/padjffs2 $(KDIR)/root.squashfs-64k 64 - $(call prepare_generic_squashfs,$(KDIR)/root.squashfs) - dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync -endef - -define Image/Prepare - $(if $(wildcard $(ZYXEL_UBOOT_BIN)),cp $(ZYXEL_UBOOT_BIN) $(ZYXEL_UBOOT)) - $(call CompressLzma,$(KDIR)/vmlinux,$(KDIR)/vmlinux.bin.lzma) -ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) - $(call CompressLzma,$(KDIR)/vmlinux-initramfs,$(KDIR)/vmlinux-initramfs.bin.lzma) - $(call Image/BuildLoader,generic,elf,,,-initramfs) -endif - $(call Image/BuildLoader,generic,elf) -endef - -define Image/Prepare/Profile - $(call Image/Build/Profile/$(1),loader) -endef - -define Image/Build/Profile - $(call Image/Build/Profile/$(1),buildkernel) - $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(call Image/Build/Profile/$(1),initramfs)) - $(call Image/Build/Profile/$(1),$(2)) -endef - -# $(1): filesystem type. -define Image/Build - $(call Image/Build/$(call rootfs_type,$(1)),$(1)) -endef diff --git a/target/linux/ath79/patches-4.14/902-at803x-add-reset-gpio-pdata.patch b/target/linux/ath79/patches-4.14/902-at803x-add-reset-gpio-pdata.patch deleted file mode 100644 index cb3ed89e9..000000000 --- a/target/linux/ath79/patches-4.14/902-at803x-add-reset-gpio-pdata.patch +++ /dev/null @@ -1,68 +0,0 @@ -Add support for configuring AT803x GPIO reset via platform data. -This is necessary, because ath79 is not converted to device tree yet. - -Signed-off-by: Felix Fietkau - ---- a/include/linux/platform_data/phy-at803x.h -+++ b/include/linux/platform_data/phy-at803x.h -@@ -6,6 +6,8 @@ struct at803x_platform_data { - int enable_rgmii_tx_delay:1; - int enable_rgmii_rx_delay:1; - int fixup_rgmii_tx_delay:1; -+ int has_reset_gpio:1; -+ int reset_gpio; - }; - - #endif /* _PHY_AT803X_PDATA_H */ ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -264,6 +264,7 @@ static int at803x_resume(struct phy_devi - - static int at803x_probe(struct phy_device *phydev) - { -+ struct at803x_platform_data *pdata; - struct device *dev = &phydev->mdio.dev; - struct at803x_priv *priv; - struct gpio_desc *gpiod_reset; -@@ -276,6 +277,12 @@ static int at803x_probe(struct phy_devic - phydev->drv->phy_id != ATH8032_PHY_ID) - goto does_not_require_reset_workaround; - -+ pdata = dev_get_platdata(dev); -+ if (pdata && pdata->has_reset_gpio) { -+ devm_gpio_request(dev, pdata->reset_gpio, "reset"); -+ gpio_direction_output(pdata->reset_gpio, 1); -+ } -+ - gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(gpiod_reset)) - return PTR_ERR(gpiod_reset); -@@ -407,15 +414,23 @@ static void at803x_link_change_notify(st - * cannot recover from by software. - */ - if (phydev->state == PHY_NOLINK) { -- if (priv->gpiod_reset && !priv->phy_reset) { -+ if ((priv->gpiod_reset || (pdata && pdata->has_reset_gpio)) && -+ !priv->phy_reset) { - struct at803x_context context; - - at803x_context_save(phydev, &context); - -- gpiod_set_value(priv->gpiod_reset, 1); -- msleep(1); -- gpiod_set_value(priv->gpiod_reset, 0); -- msleep(1); -+ if (pdata && pdata->has_reset_gpio) { -+ gpio_set_value_cansleep(pdata->reset_gpio, 0); -+ msleep(1); -+ gpio_set_value_cansleep(pdata->reset_gpio, 1); -+ msleep(1); -+ } else { -+ gpiod_set_value(priv->gpiod_reset, 1); -+ msleep(1); -+ gpiod_set_value(priv->gpiod_reset, 0); -+ msleep(1); -+ } - - at803x_context_restore(phydev, &context); - diff --git a/target/linux/gemini/Makefile b/target/linux/gemini/Makefile index f02e4b179..4b46bc23a 100644 --- a/target/linux/gemini/Makefile +++ b/target/linux/gemini/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009-2013 OpenWrt.org +# Copyright (C) 2009-2018 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -9,15 +9,22 @@ include $(TOPDIR)/rules.mk ARCH:=arm BOARD:=gemini BOARDNAME:=Cortina Systems CS351x -SUBTARGETS:=raidsonic wiligear -FEATURES:=squashfs pci rtc +FEATURES:=squashfs pci rtc usb dt gpio display CPU_TYPE:=fa526 MAINTAINER:=Roman Yeryomin -KERNEL_PATCHVER:=4.4 +KERNEL_PATCHVER:=4.14 -KERNELNAME:=zImage +define Target/Description + Build firmware images for the StorLink/Cortina Gemini CS351x ARM FA526 CPU +endef + +KERNELNAME:=zImage dtbs include $(INCLUDE_DIR)/target.mk +DEFAULT_PACKAGES += \ + kmod-leds-gpio kmod-led-trig-heartbeat \ + kmod-gpio-button-hotplug + $(eval $(call BuildTarget)) diff --git a/target/linux/gemini/base-files/lib/preinit/05_set_ether_mac_gemini b/target/linux/gemini/base-files/lib/preinit/05_set_ether_mac_gemini index 499608120..1ce5c8067 100644 --- a/target/linux/gemini/base-files/lib/preinit/05_set_ether_mac_gemini +++ b/target/linux/gemini/base-files/lib/preinit/05_set_ether_mac_gemini @@ -1,13 +1,28 @@ #!/bin/sh set_ether_mac() { + # Most devices have a standard "VCTL" partition CONFIG_PARTITION="$(grep "VCTL" /proc/mtd | cut -d: -f1)" - MAC1="$(strings /dev/$CONFIG_PARTITION |grep MAC|cut -d: -f2|cut -c3-14|sed -e 's,\(..\),:\1,g' -e 's,^:,,')" - MAC2="$(strings /dev/$CONFIG_PARTITION |grep MAC|cut -d: -f8|cut -c3-14|sed -e 's,\(..\),:\1,g' -e 's,^:,,')" + if [ ! -z $CONFIG_PARTITION ] ; then + MAC1="$(strings /dev/$CONFIG_PARTITION |grep MAC|cut -d: -f2|cut -c3-14|sed -e 's,\(..\),:\1,g' -e 's,^:,,')" + MAC2="$(strings /dev/$CONFIG_PARTITION |grep MAC|cut -d: -f8|cut -c3-14|sed -e 's,\(..\),:\1,g' -e 's,^:,,')" - ifconfig eth0 hw ether $MAC1 2>/dev/null - ifconfig eth1 hw ether $MAC2 2>/dev/null + ifconfig eth0 hw ether $MAC1 2>/dev/null + ifconfig eth1 hw ether $MAC2 2>/dev/null + return 0 + fi + + # The DNS-313 has a special field in its RedBoot + # binary that we need to check + CONFIG_PARTITION="$(grep "RedBoot" /proc/mtd | cut -d: -f1)" + if [ ! -z $CONFIG_PARTITION ] ; then + DEVID="$(dd if=/dev/mtdblock0 bs=1 skip=119508 count=7 2>/dev/null)" + if [ "x$DEVID" = "xdns-313" ] ; then + MAC1="$(dd if=/dev/mtdblock0 bs=1 skip=119540 count=6 2>/dev/null | hexdump -n6 -e '/1 ":%02X"' | sed s/^://g)" + ifconfig eth0 hw ether $MAC1 2>/dev/null + return 0 + fi + fi } boot_hook_add preinit_main set_ether_mac - diff --git a/target/linux/gemini/config-4.14 b/target/linux/gemini/config-4.14 new file mode 100644 index 000000000..7f093ae97 --- /dev/null +++ b/target/linux/gemini/config-4.14 @@ -0,0 +1,445 @@ +CONFIG_ALIGNMENT_TRAP=y +CONFIG_AMBA_PL08X=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_GEMINI=y +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_ARCH_MOXART is not set +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_MULTI_CPU_AUTO is not set +CONFIG_ARCH_MULTI_V4=y +# CONFIG_ARCH_MULTI_V4T is not set +CONFIG_ARCH_MULTI_V4_V5=y +# CONFIG_ARCH_MULTI_V5 is not set +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARM=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_APPENDED_DTB=y +# CONFIG_ARM_ATAG_DTB_COMPAT is not set +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SMMU is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +CONFIG_ARM_UNWIND=y +CONFIG_ATA=y +CONFIG_ATAGS=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BINFMT_MISC=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BOUNCE=y +# CONFIG_BPF_SYSCALL is not set +# CONFIG_CACHE_L2X0 is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="console=ttyS0,19200n8" +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_GEMINI=y +CONFIG_COMPACTION=y +CONFIG_COMPAT_BRK=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_COREDUMP=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_FA=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_FA=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +CONFIG_CPU_FA526=y +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_NO_EFFICIENT_FFS=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_TLB_FA=y +CONFIG_CPU_USE_DOMAINS=y +CONFIG_CRASH_CORE=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CRC_CCITT=y +CONFIG_CRC_ITU_T=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_UART_8250 is not set +# CONFIG_DEBUG_USER is not set +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_LZ4=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEVMEM=y +CONFIG_DMADEVICES=y +CONFIG_DMATEST=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_ENGINE_RAID=y +CONFIG_DMA_OF=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DTC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EEPROM_93CX6=y +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_EXPERT is not set +CONFIG_EXT4_FS=y +CONFIG_FARADAY_FTINTC010=y +CONFIG_FHANDLE=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FPE_FASTFPE is not set +# CONFIG_FPE_NWFPE is not set +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FTTMR010_TIMER=y +CONFIG_FTWDT010_WATCHDOG=y +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +CONFIG_GEMINI_ETHERNET=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GLOB=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_FTGPIO010=y +CONFIG_GPIO_GENERIC=y +# CONFIG_GRO_CELLS is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +# CONFIG_HAVE_ARCH_BITREVERSE is not set +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_HAVE_CC_STACKPROTECTOR=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HWMON=y +CONFIG_HW_CONSOLE=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_GPIO=y +CONFIG_I2C_HELPER_AUTO=y +# CONFIG_INITRAMFS_FORCE is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_IOMMU_HELPER=y +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IPC_NS=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +# CONFIG_ISDN is not set +CONFIG_JBD2=y +CONFIG_KALLSYMS=y +CONFIG_KERNEL_LZMA=y +# CONFIG_KERNEL_XZ is not set +CONFIG_KEXEC=y +CONFIG_KEXEC_CORE=y +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LIBFDT=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MANDATORY_FILE_LOCKING=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_GPIO=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_MIGRATION=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +CONFIG_MTD_CFI_STAA=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF_GEMINI=y +CONFIG_MULTI_IRQ_HANDLER=y +CONFIG_NAMESPACES=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_KUSER_HELPERS=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_DSA=y +CONFIG_NET_NS=y +CONFIG_NET_PACKET_ENGINE=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_VENDOR_CORTINA=y +CONFIG_NLS=y +CONFIG_NO_BOOTMEM=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NVMEM=y +CONFIG_OABI_COMPAT=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_ADDRESS_PCI=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OF_PCI=y +CONFIG_OF_PCI_IRQ=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +# CONFIG_PACKET is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_PATA_FTIDE010=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_FTPCI100=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PID_NS=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_GEMINI=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PM=y +CONFIG_PM_CLK=y +# CONFIG_PM_DEBUG is not set +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GEMINI_POWEROFF=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_RATIONAL=y +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +# CONFIG_RCU_EXPERT is not set +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RD_BZIP2=y +CONFIG_RD_GZIP=y +CONFIG_RD_LZ4=y +CONFIG_RD_LZMA=y +CONFIG_RD_LZO=y +CONFIG_RD_XZ=y +CONFIG_REALTEK_PHY=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_RELAY=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_FTRTC010=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_NVMEM=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_SATA_GEMINI=y +CONFIG_SATA_PMP=y +# CONFIG_SCHED_INFO is not set +CONFIG_SCSI=y +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_PROC_FS is not set +CONFIG_SENSORS_GPIO_FAN=y +CONFIG_SENSORS_LM75=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_EXAR=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIO=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_SERPORT=y +CONFIG_SG_POOL=y +CONFIG_SLUB_DEBUG=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_GPIO=y +CONFIG_SPI_MASTER=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +CONFIG_SRCU=y +# CONFIG_STAGING is not set +# CONFIG_STRICT_KERNEL_RWX is not set +# CONFIG_STRICT_MODULE_RWX is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYNC_FILE=y +# CONFIG_SYN_COOKIES is not set +CONFIG_SYSFS_SYSCALL=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TASKS_RCU=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TREE_SRCU=y +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_FOTG210_HCD=y +CONFIG_USB_SUPPORT=y +# CONFIG_USERIO is not set +CONFIG_USER_NS=y +CONFIG_USE_OF=y +CONFIG_UTS_NS=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_WATCHDOG_CORE=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_X86=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_INFLATE=y diff --git a/target/linux/gemini/config-4.4 b/target/linux/gemini/config-4.4 deleted file mode 100644 index 9572196ae..000000000 --- a/target/linux/gemini/config-4.4 +++ /dev/null @@ -1,165 +0,0 @@ -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y -CONFIG_ARCH_GEMINI=y -CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_REQUIRE_GPIOLIB=y -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -CONFIG_ARCH_USES_GETTIMEOFFSET=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARM=y -# CONFIG_ARM_CPU_SUSPEND is not set -CONFIG_ARM_L1_CACHE_SHIFT=5 -CONFIG_ARM_NR_BANKS=8 -CONFIG_ARM_PATCH_PHYS_VIRT=y -# CONFIG_ARPD is not set -CONFIG_ATA=y -CONFIG_ATAGS=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 noinitrd console=ttyS0,19200 mem=32M" -CONFIG_CMDLINE_FROM_BOOTLOADER=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4=y -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_FA=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_FA=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -# CONFIG_CPU_DCACHE_WRITETHROUGH is not set -CONFIG_CPU_FA526=y -# CONFIG_CPU_ICACHE_DISABLE is not set -CONFIG_CPU_PABRT_LEGACY=y -CONFIG_CPU_TLB_FA=y -CONFIG_CPU_USE_DOMAINS=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -# CONFIG_DEBUG_USER is not set -CONFIG_DEBUG_UART_PHYS=0x42000000 -CONFIG_DEBUG_UART_VIRT=0xf4200000 -CONFIG_DEBUG_UART_8250_SHIFT=2 -# CONFIG_DEBUG_UART_8250_WORD is not set -# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -# CONFIG_DLCI is not set -CONFIG_DMADEVICES=y -CONFIG_DNOTIFY=y -# CONFIG_DW_DMAC_CORE is not set -# CONFIG_DW_DMAC_PCI is not set -CONFIG_FRAME_POINTER=y -CONFIG_GEMINI_MEM_SWAP=y -CONFIG_GEMINI_SL351X=y -CONFIG_GEMINI_WATCHDOG=y -CONFIG_GENERIC_ATOMIC64=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IO=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GPIOLIB=y -CONFIG_GPIO_DEVRES=y -CONFIG_GPIO_SYSFS=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_BPF_JIT=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_DMA_ATTRS=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_GENERIC_HARDIRQS=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -# CONFIG_HSU_DMA_PCI is not set -CONFIG_HWMON=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_IRQ_WORK=y -CONFIG_KTIME_SCALAR=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_MACH_NAS4220B is not set -# CONFIG_MACH_RUT100 is not set -CONFIG_MACH_WBD111=y -CONFIG_MACH_WBD222=y -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BOARDINFO=y -CONFIG_MDIO_GPIO=y -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_PHYSMAP=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_KUSER_HELPERS=y -CONFIG_NEED_MACH_GPIO_H=y -CONFIG_NEED_PER_CPU_KM=y -CONFIG_NET_VENDOR_GEMINI=y -# CONFIG_OF is not set -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PATA_GEMINI=y -CONFIG_PCI=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PHYLIB=y -# CONFIG_PREEMPT_RCU is not set -# CONFIG_RCU_STALL_COMMON is not set -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_GEMINI=y -# CONFIG_SCHED_HRTICK is not set -# CONFIG_SCSI_DMA is not set -CONFIG_SPLIT_PTLOCK_CPUS=999999 -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_UID16=y -CONFIG_UIDGID_CONVERTED=y -CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h" -CONFIG_USB_ARCH_HAS_XHCI=y -CONFIG_USB_SUPPORT=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_WAN=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/gemini/files/arch/arm/mach-gemini/include/mach/gmac.h b/target/linux/gemini/files/arch/arm/mach-gemini/include/mach/gmac.h deleted file mode 100644 index 04ca5699f..000000000 --- a/target/linux/gemini/files/arch/arm/mach-gemini/include/mach/gmac.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Gemini GMAC specific defines - * - * Copyright (C) 2008, Paulius Zaleckas - * - * 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. - */ -#ifndef __NET_GEMINI_PLATFORM_H__ -#define __NET_GEMINI_PLATFORM_H__ - -#include - -struct gemini_gmac_platform_data { - char *bus_id[2]; /* NULL means that this port is not used */ - phy_interface_t interface[2]; -}; - -#endif /* __NET_GEMINI_PLATFORM_H__ */ diff --git a/target/linux/gemini/files/arch/arm/mach-gemini/pci.c b/target/linux/gemini/files/arch/arm/mach-gemini/pci.c deleted file mode 100644 index 51cd44754..000000000 --- a/target/linux/gemini/files/arch/arm/mach-gemini/pci.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Support for Gemini PCI Controller - * - * Copyright (C) 2009 Janos Laube - * Copyright (C) 2009 Paulius Zaleckas - * - * based on SL2312 PCI controller code - * Storlink (C) 2003 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include - -#include - -#include -#include - -#define GEMINI_PCI_IOSIZE_1M 0x0000 - -#define GEMINI_PCI_PMC 0x40 -#define GEMINI_PCI_PMCSR 0x44 -#define GEMINI_PCI_CTRL1 0x48 -#define GEMINI_PCI_CTRL2 0x4C -#define GEMINI_PCI_MEM1_BASE_SIZE 0x50 -#define GEMINI_PCI_MEM2_BASE_SIZE 0x54 -#define GEMINI_PCI_MEM3_BASE_SIZE 0x58 - -#define PCI_CTRL2_INTSTS_OFFSET 28 -#define PCI_CTRL2_INTMASK_OFFSET 22 - -#define GEMINI_PCI_DMA_MASK 0xFFF00000 -#define GEMINI_PCI_DMA_MEM1_BASE 0x00000000 -#define GEMINI_PCI_DMA_MEM2_BASE 0x00000000 -#define GEMINI_PCI_DMA_MEM3_BASE 0x00000000 -#define GEMINI_PCI_DMA_MEM1_SIZE 7 -#define GEMINI_PCI_DMA_MEM2_SIZE 6 -#define GEMINI_PCI_DMA_MEM3_SIZE 6 - -#define PCI_CONF_ENABLE (1 << 31) -#define PCI_CONF_WHERE(r) ((r) & 0xFC) -#define PCI_CONF_BUS(b) (((b) & 0xFF) << 16) -#define PCI_CONF_DEVICE(d) (((d) & 0x1F) << 11) -#define PCI_CONF_FUNCTION(f) (((f) & 0x07) << 8) - -#define PCI_IOSIZE_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE)) -#define PCI_PROT_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x04) -#define PCI_CTRL_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x08) -#define PCI_SOFTRST_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x10) -#define PCI_CONFIG_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x28) -#define PCI_DATA_REG (IO_ADDRESS(GEMINI_PCI_IO_BASE) + 0x2C) - - -static DEFINE_SPINLOCK(gemini_pci_lock); - -static int gemini_pci_read_config(struct pci_bus* bus, unsigned int fn, - int config, int size, u32* value) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&gemini_pci_lock, irq_flags); - - __raw_writel(PCI_CONF_BUS(bus->number) | - PCI_CONF_DEVICE(PCI_SLOT(fn)) | - PCI_CONF_FUNCTION(PCI_FUNC(fn)) | - PCI_CONF_WHERE(config) | - PCI_CONF_ENABLE, - PCI_CONFIG_REG); - - *value = __raw_readl(PCI_DATA_REG); - - if (size == 1) - *value = (*value >> (8 * (config & 3))) & 0xFF; - else if (size == 2) - *value = (*value >> (8 * (config & 3))) & 0xFFFF; - - spin_unlock_irqrestore(&gemini_pci_lock, irq_flags); - - dev_dbg(&bus->dev, - "[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n", - PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value); - - return PCIBIOS_SUCCESSFUL; -} - -static int gemini_pci_write_config(struct pci_bus* bus, unsigned int fn, - int config, int size, u32 value) -{ - unsigned long irq_flags = 0; - int ret = PCIBIOS_SUCCESSFUL; - - dev_dbg(&bus->dev, - "[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n", - PCI_SLOT(fn), PCI_FUNC(fn), config, size, value); - - spin_lock_irqsave(&gemini_pci_lock, irq_flags); - - __raw_writel(PCI_CONF_BUS(bus->number) | - PCI_CONF_DEVICE(PCI_SLOT(fn)) | - PCI_CONF_FUNCTION(PCI_FUNC(fn)) | - PCI_CONF_WHERE(config) | - PCI_CONF_ENABLE, - PCI_CONFIG_REG); - - switch(size) { - case 4: - __raw_writel(value, PCI_DATA_REG); - break; - case 2: - __raw_writew(value, PCI_DATA_REG + (config & 3)); - break; - case 1: - __raw_writeb(value, PCI_DATA_REG + (config & 3)); - break; - default: - ret = PCIBIOS_BAD_REGISTER_NUMBER; - } - - spin_unlock_irqrestore(&gemini_pci_lock, irq_flags); - - return ret; -} - -static struct pci_ops gemini_pci_ops = { - .read = gemini_pci_read_config, - .write = gemini_pci_write_config, -}; - -static struct resource gemini_pci_resource_io = { - .name = "PCI I/O Space", - .start = GEMINI_PCI_IO_BASE, - .end = GEMINI_PCI_IO_BASE + SZ_1M - 1, - .flags = IORESOURCE_IO, -}; - -static struct resource gemini_pci_resource_mem = { - .name = "PCI Memory Space", - .start = GEMINI_PCI_MEM_BASE, - .end = GEMINI_PCI_MEM_BASE + SZ_128M - 1, - .flags = IORESOURCE_MEM, -}; - -static int __init gemini_pci_request_resources(struct pci_sys_data *sys) -{ - if (request_resource(&ioport_resource, &gemini_pci_resource_io)) - goto bad_resources; - if (request_resource(&iomem_resource, &gemini_pci_resource_mem)) - goto bad_resources; - - pci_add_resource(&sys->resources, &gemini_pci_resource_io); - pci_add_resource(&sys->resources, &gemini_pci_resource_mem); - - return 0; - -bad_resources: - pr_err("Gemini PCI: request_resource() failed. " - "Abort PCI bus enumeration.\n"); - return -1; -} - -static int __init gemini_pci_setup(int nr, struct pci_sys_data *sys) -{ - unsigned int cmd; - - pcibios_min_io = 0x100; - pcibios_min_mem = 0; - - if ((nr > 0) || gemini_pci_request_resources(sys)) - return 0; - - /* setup I/O space to 1MB size */ - __raw_writel(GEMINI_PCI_IOSIZE_1M, PCI_IOSIZE_REG); - - /* setup hostbridge */ - cmd = __raw_readl(PCI_CTRL_REG); - cmd |= PCI_COMMAND_IO; - cmd |= PCI_COMMAND_MEMORY; - cmd |= PCI_COMMAND_MASTER; - __raw_writel(cmd, PCI_CTRL_REG); - - return 1; -} - -static struct pci_bus* __init gemini_pci_scan_bus(int nr, struct pci_sys_data* sys) -{ - unsigned int reg = 0; - struct pci_bus* bus = 0; - - bus = pci_scan_bus(nr, &gemini_pci_ops, sys); - if (bus) { - dev_dbg(&bus->dev, "setting up PCI DMA\n"); - reg = (GEMINI_PCI_DMA_MEM1_BASE & GEMINI_PCI_DMA_MASK) - | (GEMINI_PCI_DMA_MEM1_SIZE << 16); - gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM1_BASE_SIZE, 4, reg); - reg = (GEMINI_PCI_DMA_MEM2_BASE & GEMINI_PCI_DMA_MASK) - | (GEMINI_PCI_DMA_MEM2_SIZE << 16); - gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM2_BASE_SIZE, 4, reg); - reg = (GEMINI_PCI_DMA_MEM3_BASE & GEMINI_PCI_DMA_MASK) - | (GEMINI_PCI_DMA_MEM3_SIZE << 16); - gemini_pci_write_config(bus, 0, GEMINI_PCI_MEM3_BASE_SIZE, 4, reg); - } - - return bus; -} - -/* Should work with all boards based on original Storlink EVB */ -static int __init gemini_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - if (slot < 9 || slot > 12) - return -1; - - return PCI_IRQ_BASE + (((slot - 9) + (pin - 1)) & 0x3); -} - -static struct hw_pci gemini_hw_pci __initdata = { - .nr_controllers = 1, - .setup = gemini_pci_setup, - .scan = gemini_pci_scan_bus, - .map_irq = gemini_pci_map_irq, -}; - -/* we need this for muxed PCI interrupts handling */ -static struct pci_bus bogus_pci_bus; - -static void gemini_pci_ack_irq(struct irq_data *d) -{ - unsigned int irq = d->irq; - unsigned int reg; - - gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®); - reg &= ~(0xF << PCI_CTRL2_INTSTS_OFFSET); - reg |= 1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTSTS_OFFSET); - gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg); -} - -static void gemini_pci_mask_irq(struct irq_data *d) -{ - unsigned int irq = d->irq; - unsigned int reg; - - gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®); - reg &= ~((0xF << PCI_CTRL2_INTSTS_OFFSET) - | (1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTMASK_OFFSET))); - gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg); -} - -static void gemini_pci_unmask_irq(struct irq_data *d) -{ - unsigned int irq = d->irq; - unsigned int reg; - - gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®); - reg &= ~(0xF << PCI_CTRL2_INTSTS_OFFSET); - reg |= 1 << (irq - PCI_IRQ_BASE + PCI_CTRL2_INTMASK_OFFSET); - gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, reg); -} - -static void gemini_pci_irq_handler(struct irq_desc *desc) -{ - unsigned int pci_irq_no, irq_stat, reg, i; - - gemini_pci_read_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2, 4, ®); - irq_stat = reg >> PCI_CTRL2_INTSTS_OFFSET; - - for (i = 0; i < 4; i++) { - - if ((irq_stat & (1 << i)) == 0) - continue; - - pci_irq_no = PCI_IRQ_BASE + i; - - BUG_ON(!(irq_desc[pci_irq_no].handle_irq)); - irq_desc[pci_irq_no].handle_irq(&irq_desc[pci_irq_no]); - } -} - -static struct irq_chip gemini_pci_irq_chip = { - .name = "PCI", - .irq_ack = gemini_pci_ack_irq, - .irq_mask = gemini_pci_mask_irq, - .irq_unmask = gemini_pci_unmask_irq, -}; - -static int __init gemini_pci_init(void) -{ - int i; - - for (i = 72; i <= 95; i++) - gpio_request(i, "PCI"); - - /* initialize our bogus bus */ - dev_set_name(&bogus_pci_bus.dev, "PCI IRQ handler"); - bogus_pci_bus.number = 0; - - /* mask and clear all interrupts */ - gemini_pci_write_config(&bogus_pci_bus, 0, GEMINI_PCI_CTRL2 + 2, 2, - 0xF000); - - for (i = PCI_IRQ_BASE; i < PCI_IRQ_BASE + 4; i++) { - irq_set_chip_and_handler(i, &gemini_pci_irq_chip, - handle_level_irq); - } - - irq_set_chained_handler(IRQ_PCI, gemini_pci_irq_handler); - - pci_common_init(&gemini_hw_pci); - - return 0; -} - -subsys_initcall(gemini_pci_init); diff --git a/target/linux/gemini/files/drivers/ata/pata_gemini.c b/target/linux/gemini/files/drivers/ata/pata_gemini.c deleted file mode 100644 index 707e8703b..000000000 --- a/target/linux/gemini/files/drivers/ata/pata_gemini.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Support for Gemini PATA - * - * Copyright (C) 2009 Janos Laube - * Copyright (C) 2010 Frederic Pecourt - * Copyright (C) 2011 Tobias Waldvogel - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* Values of IOMUX - * 26:24 bits is "IDE IO Select" - * 111:100 - Reserved - * 011 - ata0 <-> sata0, sata1; bring out ata1 - * 010 - ata1 <-> sata1, sata0; bring out ata0 - * 001 - ata0 <-> sata0, ata1 <-> sata1; bring out ata1 - * 000 - ata0 <-> sata0, ata1 <-> sata1; bring out ata0 - * - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define DRV_NAME "pata-gemini" - -#define PATA_GEMINI_PORTS 1 - -#define PIO_TIMING_REG 0x10 -#define MDMA_TIMING_REG 0x11 -#define UDMA_TIMING0_REG 0x12 -#define UDMA_TIMING1_REG 0x13 -#define CLK_MOD_REG 0x14 - -#define CLK_MOD_66M_DEV0_BIT 0 -#define CLK_MOD_66M_DEV1_BIT 1 -#define CLK_MOD_UDMA_DEV0_BIT 4 -#define CLK_MOD_UDMA_DEV1_BIT 5 - -#define CLK_MOD_66M_DEV0 (1 << CLK_MOD_66M_DEV0_BIT) -#define CLK_MOD_66M_DEV1 (1 << CLK_MOD_66M_DEV1_BIT) -#define CLK_MOD_UDMA_DEV0 (1 << CLK_MOD_UDMA_DEV0_BIT) -#define CLK_MOD_UDMA_DEV1 (1 << CLK_MOD_UDMA_DEV1_BIT) - -#define SATA_ENABLE_PDEV_MASK 0x01 -#define SATA_ENABLE_PDEV_PM 0x02 -#define SATA_ENABLE_PDEV_ADDED 0x04 -#define SATA_ENABLE_PDEV_REMOVED 0x08 -#define SATA_ENABLE_SDEV_MASK 0x10 -#define SATA_ENABLE_SDEV_PM 0x20 -#define SATA_ENABLE_SDEV_ADDED 0x40 -#define SATA_ENABLE_SDEV_REMOVED 0x80 - -MODULE_AUTHOR("Janos Laube "); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" DRV_NAME); - -static unsigned char PIO_TIMING[5] = { - 0xaa, 0xa3, 0xa1, 0x33, 0x31 -}; - -static unsigned char TIMING_MW_DMA[4][2] = { - { 0x44, 1 }, // 480 4.2 - { 0x42, 1 }, // 150 13.3 - { 0x31, 1 }, // 120 16.7 - { 0x21, 1 }, // 100 20 -}; - -static unsigned char TIMING_UDMA[7][2] = { - { 0x33, 0 }, //240 16.7 - { 0x31, 0 }, //160 25 - { 0x21, 0 }, //120 33.3 - { 0x21, 1 }, //90 44.4 - { 0x11, 1 }, //60 66.7 - { 0x11 | 0x80, 0 }, //40 100 - { 0x11 | 0x80, 1 }, //30 133 -}; - -static struct scsi_host_template pata_gemini_sht = { - ATA_NCQ_SHT(DRV_NAME), - .can_queue = 1, - .sg_tablesize = 128, - .dma_boundary = 0xffffU, -}; - -static void gemini_set_dmamode(struct ata_port *ap, struct ata_device *adev) -{ - void __iomem *clk_reg = ap->ioaddr.bmdma_addr + CLK_MOD_REG; - void __iomem *tim_reg = ap->ioaddr.bmdma_addr + UDMA_TIMING0_REG; - unsigned short udma = adev->dma_mode; - unsigned short speed = udma; - unsigned short devno = adev->devno & 1; - unsigned short i; - u8 mod_udma_mask = 1 << (CLK_MOD_UDMA_DEV0_BIT + devno); - u8 mod_66m_mask = 1 << (CLK_MOD_66M_DEV0_BIT + devno); - u8 clk_mod; - u8 timing; - - clk_mod = ioread8(clk_reg); - clk_mod &= ~mod_udma_mask; - - if (speed & XFER_UDMA_0) { - i = speed & ~XFER_UDMA_0; - timing = TIMING_UDMA[i][0]; - clk_mod |= mod_udma_mask; - if (TIMING_UDMA[i][1]) - clk_mod |= mod_66m_mask; - } else { - i = speed & ~XFER_MW_DMA_0; - timing = TIMING_MW_DMA[i][0]; - clk_mod |= mod_udma_mask; - if (TIMING_MW_DMA[i][1]) - clk_mod |= mod_66m_mask; - } - - iowrite8(clk_mod, clk_reg); - iowrite8(timing, tim_reg + devno); - return; -} - -static void gemini_set_piomode(struct ata_port *ap, struct ata_device *adev) -{ - void __iomem *pio_reg = ap->ioaddr.bmdma_addr + PIO_TIMING_REG; - unsigned int pio = adev->pio_mode - XFER_PIO_0; - - iowrite8(PIO_TIMING[pio], pio_reg); -} - -unsigned int gemini_qc_issue(struct ata_queued_cmd *qc) -{ - ledtrig_ide_activity(); - return ata_bmdma_qc_issue(qc); -} - -static struct ata_port_operations pata_gemini_port_ops = { - .inherits = &ata_bmdma_port_ops, - .set_dmamode = gemini_set_dmamode, - .set_piomode = gemini_set_piomode, - .qc_issue = gemini_qc_issue, -}; - -static struct ata_port_info pata_gemini_portinfo = { - .flags = 0, - .udma_mask = ATA_UDMA6, - .pio_mask = ATA_PIO4, - .port_ops = &pata_gemini_port_ops, -}; - -static const struct ata_port_info *pata_gemini_ports = &pata_gemini_portinfo; - -static int pata_gemini_probe(struct platform_device *pdev) -{ - struct ata_host *host; - struct resource *res; - unsigned int irq, i; - void __iomem *mmio_base; - - /* standard bdma init */ - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - pr_info(DRV_NAME ": irq %d, io base 0x%08x\n", irq, res->start); - - mmio_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - - host = ata_host_alloc_pinfo(&pdev->dev, &pata_gemini_ports, 1); - if (!host) - return -ENOMEM; - - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - struct ata_ioports *ioaddr = &ap->ioaddr; - - ioaddr->bmdma_addr = mmio_base; - ioaddr->cmd_addr = mmio_base + 0x20; - ioaddr->ctl_addr = mmio_base + 0x36; - ioaddr->altstatus_addr = ioaddr->ctl_addr; - ata_sff_std_ports(ioaddr); - host->ports[i]->cbl = ATA_CBL_SATA; - } - - return ata_host_activate(host, irq, ata_bmdma_interrupt, - IRQF_SHARED, &pata_gemini_sht); -} - -static int pata_gemini_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct ata_host *host = dev_get_drvdata(dev); - ata_host_detach(host); - return 0; -} - -static struct platform_driver pata_gemini_driver = { - .probe = pata_gemini_probe, - .remove = pata_gemini_remove, - .driver.owner = THIS_MODULE, - .driver.name = DRV_NAME, -}; - -static int __init pata_gemini_module_init(void) -{ - return platform_driver_probe(&pata_gemini_driver, pata_gemini_probe); -} - -static void __exit pata_gemini_module_exit(void) -{ - platform_driver_unregister(&pata_gemini_driver); -} - -module_init(pata_gemini_module_init); -module_exit(pata_gemini_module_exit); diff --git a/target/linux/gemini/files/drivers/net/ethernet/gemini/Kconfig b/target/linux/gemini/files/drivers/net/ethernet/gemini/Kconfig deleted file mode 100644 index 12d58163d..000000000 --- a/target/linux/gemini/files/drivers/net/ethernet/gemini/Kconfig +++ /dev/null @@ -1,31 +0,0 @@ -# -# Gemini device configuration -# - -config NET_VENDOR_GEMINI - bool "Cortina Gemini devices" - default y - depends on ARCH_GEMINI - ---help--- - If you have a network (Ethernet) card belonging to this class, say Y - and read the Ethernet-HOWTO, available from - . - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about D-Link devices. If you say Y, you will be asked for - your specific card in the following questions. - -if NET_VENDOR_GEMINI - -config GEMINI_SL351X - tristate "StorLink SL351x Gigabit Ethernet support" - depends on ARCH_GEMINI - select PHYLIB - select MDIO_BITBANG - select MDIO_GPIO - select CRC32 - ---help--- - This driver supports StorLink SL351x (Gemini) dual Gigabit Ethernet. - -endif # NET_VENDOR_GEMINI diff --git a/target/linux/gemini/files/drivers/net/ethernet/gemini/Makefile b/target/linux/gemini/files/drivers/net/ethernet/gemini/Makefile deleted file mode 100644 index 3a1987c4f..000000000 --- a/target/linux/gemini/files/drivers/net/ethernet/gemini/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the Cortina Gemini network device drivers. -# - -obj-$(CONFIG_GEMINI_SL351X) += sl351x.o diff --git a/target/linux/gemini/files/drivers/net/ethernet/gemini/sl351x.c b/target/linux/gemini/files/drivers/net/ethernet/gemini/sl351x.c deleted file mode 100644 index 83455c400..000000000 --- a/target/linux/gemini/files/drivers/net/ethernet/gemini/sl351x.c +++ /dev/null @@ -1,2340 +0,0 @@ -/* - * Ethernet device driver for Gemini SoC (SL351x GMAC). - * - * Copyright (C) 2011, Tobias Waldvogel - * - * Based on work by MichaÅ‚ MirosÅ‚aw and - * Paulius Zaleckas and - * Giuseppe De Robertis and - * GPLd spaghetti code from Raidsonic and other Gemini-based NAS vendors. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include "sl351x_hw.h" - -#define DRV_NAME "gmac-gemini" -#define DRV_VERSION "1.0" - -#define HSIZE_8 0b00 -#define HSIZE_16 0b01 -#define HSIZE_32 0b10 - -#define HBURST_SINGLE 0b00 -#define HBURST_INCR 0b01 -#define HBURST_INCR4 0b10 -#define HBURST_INCR8 0b11 - -#define HPROT_DATA_CACHE BIT(0) -#define HPROT_PRIVILIGED BIT(1) -#define HPROT_BUFFERABLE BIT(2) -#define HPROT_CACHABLE BIT(3) - -#define DEFAULT_RX_COALESCE_NSECS 0 -#define DEFAULT_GMAC_RXQ_ORDER 9 -#define DEFAULT_GMAC_TXQ_ORDER 8 -#define DEFAULT_RX_BUF_ORDER 11 -#define DEFAULT_NAPI_WEIGHT 64 -#define TX_MAX_FRAGS 16 -#define TX_QUEUE_NUM 1 /* max: 6 */ -#define RX_MAX_ALLOC_ORDER 2 - -#define GMAC0_IRQ0_2 (GMAC0_TXDERR_INT_BIT|GMAC0_TXPERR_INT_BIT| \ - GMAC0_RXDERR_INT_BIT|GMAC0_RXPERR_INT_BIT) -#define GMAC0_IRQ0_TXQ0_INTS (GMAC0_SWTQ00_EOF_INT_BIT| \ - GMAC0_SWTQ00_FIN_INT_BIT) -#define GMAC0_IRQ4_8 (GMAC0_MIB_INT_BIT|GMAC0_RX_OVERRUN_INT_BIT) - -#define GMAC_OFFLOAD_FEATURES (NETIF_F_SG | NETIF_F_IP_CSUM | \ - NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | \ - NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6) - -MODULE_AUTHOR("Tobias Waldvogel"); -MODULE_DESCRIPTION("StorLink SL351x (Gemini) ethernet driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" DRV_NAME); - -struct toe_private { - void __iomem *iomem; - spinlock_t irq_lock; - - struct net_device *netdev[2]; - __le32 mac_addr[2][3]; - - struct device *dev; - int irq; - - unsigned int freeq_order; - unsigned int freeq_frag_order; - GMAC_RXDESC_T *freeq_ring; - dma_addr_t freeq_dma_base; - struct page **freeq_page_tab; - spinlock_t freeq_lock; -}; - -struct gmac_txq { - GMAC_TXDESC_T *ring; - struct sk_buff **skb; - unsigned int cptr; - unsigned int noirq_packets; -}; - -struct gmac_private { - unsigned int num; - struct toe_private *toe; - void __iomem *ctl_iomem; - void __iomem *dma_iomem; - - void __iomem *rxq_rwptr; - GMAC_RXDESC_T *rxq_ring; - unsigned int rxq_order; - - struct napi_struct napi; - struct hrtimer rx_coalesce_timer; - unsigned int rx_coalesce_nsecs; - unsigned int freeq_refill; - struct gmac_txq txq[TX_QUEUE_NUM]; - unsigned int txq_order; - unsigned int irq_every_tx_packets; - - dma_addr_t rxq_dma_base; - dma_addr_t txq_dma_base; - - unsigned int msg_enable; - spinlock_t config_lock; - - struct u64_stats_sync tx_stats_syncp; - struct u64_stats_sync rx_stats_syncp; - struct u64_stats_sync ir_stats_syncp; - - struct rtnl_link_stats64 stats; - u64 hw_stats[RX_STATS_NUM]; - u64 rx_stats[RX_STATUS_NUM]; - u64 rx_csum_stats[RX_CHKSUM_NUM]; - u64 rx_napi_exits; - u64 tx_frag_stats[TX_MAX_FRAGS]; - u64 tx_frags_linearized; - u64 tx_hw_csummed; -}; - -#define GMAC_STATS_NUM ( \ - RX_STATS_NUM + RX_STATUS_NUM + RX_CHKSUM_NUM + 1 + \ - TX_MAX_FRAGS + 2) - -static const char gmac_stats_strings[GMAC_STATS_NUM][ETH_GSTRING_LEN] = { - "GMAC_IN_DISCARDS", - "GMAC_IN_ERRORS", - "GMAC_IN_MCAST", - "GMAC_IN_BCAST", - "GMAC_IN_MAC1", - "GMAC_IN_MAC2", - "RX_STATUS_GOOD_FRAME", - "RX_STATUS_TOO_LONG_GOOD_CRC", - "RX_STATUS_RUNT_FRAME", - "RX_STATUS_SFD_NOT_FOUND", - "RX_STATUS_CRC_ERROR", - "RX_STATUS_TOO_LONG_BAD_CRC", - "RX_STATUS_ALIGNMENT_ERROR", - "RX_STATUS_TOO_LONG_BAD_ALIGN", - "RX_STATUS_RX_ERR", - "RX_STATUS_DA_FILTERED", - "RX_STATUS_BUFFER_FULL", - "RX_STATUS_11", - "RX_STATUS_12", - "RX_STATUS_13", - "RX_STATUS_14", - "RX_STATUS_15", - "RX_CHKSUM_IP_UDP_TCP_OK", - "RX_CHKSUM_IP_OK_ONLY", - "RX_CHKSUM_NONE", - "RX_CHKSUM_3", - "RX_CHKSUM_IP_ERR_UNKNOWN", - "RX_CHKSUM_IP_ERR", - "RX_CHKSUM_TCP_UDP_ERR", - "RX_CHKSUM_7", - "RX_NAPI_EXITS", - "TX_FRAGS[1]", - "TX_FRAGS[2]", - "TX_FRAGS[3]", - "TX_FRAGS[4]", - "TX_FRAGS[5]", - "TX_FRAGS[6]", - "TX_FRAGS[7]", - "TX_FRAGS[8]", - "TX_FRAGS[9]", - "TX_FRAGS[10]", - "TX_FRAGS[11]", - "TX_FRAGS[12]", - "TX_FRAGS[13]", - "TX_FRAGS[14]", - "TX_FRAGS[15]", - "TX_FRAGS[16+]", - "TX_FRAGS_LINEARIZED", - "TX_HW_CSUMMED", -}; - -static void gmac_dump_dma_state(struct net_device *dev); - -static void gmac_update_config0_reg(struct net_device *dev, u32 val, u32 vmask) -{ - struct gmac_private *gmac = netdev_priv(dev); - unsigned long flags; - u32 reg; - - spin_lock_irqsave(&gmac->config_lock, flags); - - reg = readl(gmac->ctl_iomem + GMAC_CONFIG0); - reg = (reg & ~vmask) | val; - writel(reg, gmac->ctl_iomem + GMAC_CONFIG0); - - spin_unlock_irqrestore(&gmac->config_lock, flags); -} - -static void gmac_enable_tx_rx(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - void __iomem *config0 = gmac->ctl_iomem + GMAC_CONFIG0; - unsigned long flags; - u32 reg; - - spin_lock_irqsave(&gmac->config_lock, flags); - - reg = readl(config0); - reg &= ~CONFIG0_TX_RX_DISABLE; - writel(reg, config0); - - spin_unlock_irqrestore(&gmac->config_lock, flags); -} - -static void gmac_disable_tx_rx(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - void __iomem *config0 = gmac->ctl_iomem + GMAC_CONFIG0; - unsigned long flags; - u32 reg; - - spin_lock_irqsave(&gmac->config_lock, flags); - - reg = readl(config0); - reg |= CONFIG0_TX_RX_DISABLE; - writel(reg, config0); - - spin_unlock_irqrestore(&gmac->config_lock, flags); - - mdelay(10); /* let GMAC consume packet */ -} - -static void gmac_set_flow_control(struct net_device *dev, bool tx, bool rx) -{ - struct gmac_private *gmac = netdev_priv(dev); - void __iomem *config0 = gmac->ctl_iomem + GMAC_CONFIG0; - unsigned long flags; - u32 reg; - - spin_lock_irqsave(&gmac->config_lock, flags); - - reg = readl(config0); - reg &= ~CONFIG0_FLOW_CTL; - if (tx) - reg |= CONFIG0_FLOW_TX; - if (rx) - reg |= CONFIG0_FLOW_RX; - writel(reg, config0); - - spin_unlock_irqrestore(&gmac->config_lock, flags); -} - -static void gmac_update_link_state(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - void __iomem *status_reg = gmac->ctl_iomem + GMAC_STATUS; - struct phy_device *phydev = dev->phydev; - GMAC_STATUS_T status, old_status; - int pause_tx=0, pause_rx=0; - - old_status.bits32 = status.bits32 = readl(status_reg); - - status.bits.link = phydev->link; - status.bits.duplex = phydev->duplex; - - switch (phydev->speed) { - case 1000: - status.bits.speed = GMAC_SPEED_1000; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) - status.bits.mii_rmii = GMAC_PHY_RGMII_1000; - break; - case 100: - status.bits.speed = GMAC_SPEED_100; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) - status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; - break; - case 10: - status.bits.speed = GMAC_SPEED_10; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) - status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; - break; - default: - netdev_warn(dev, "Not supported PHY speed (%d)\n", - phydev->speed); - } - - if (phydev->duplex == DUPLEX_FULL) { - u16 lcladv = phy_read(phydev, MII_ADVERTISE); - u16 rmtadv = phy_read(phydev, MII_LPA); - u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); - - if (cap & FLOW_CTRL_RX) - pause_rx=1; - if (cap & FLOW_CTRL_TX) - pause_tx=1; - } - - gmac_set_flow_control(dev, pause_tx, pause_rx); - - if (old_status.bits32 == status.bits32) - return; - - if (netif_msg_link(gmac)) { - phy_print_status(phydev); - netdev_info(dev, "link flow control: %s\n", - phydev->pause - ? (phydev->asym_pause ? "tx" : "both") - : (phydev->asym_pause ? "rx" : "none") - ); - } - - gmac_disable_tx_rx(dev); - writel(status.bits32, status_reg); - gmac_enable_tx_rx(dev); -} - -static int gmac_setup_phy(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - struct gemini_gmac_platform_data *pdata = toe->dev->platform_data; - GMAC_STATUS_T status = { .bits32 = 0 }; - int num = dev->dev_id; - - dev->phydev = phy_connect(dev, pdata->bus_id[num], - &gmac_update_link_state, pdata->interface[num]); - - if (IS_ERR(dev->phydev)) { - int err = PTR_ERR(dev->phydev); - dev->phydev = NULL; - return err; - } - - dev->phydev->supported &= PHY_GBIT_FEATURES; - dev->phydev->supported |= SUPPORTED_Asym_Pause | SUPPORTED_Pause; - dev->phydev->advertising = dev->phydev->supported; - - /* set PHY interface type */ - switch (dev->phydev->interface) { - case PHY_INTERFACE_MODE_MII: - status.bits.mii_rmii = GMAC_PHY_MII; - break; - case PHY_INTERFACE_MODE_GMII: - status.bits.mii_rmii = GMAC_PHY_GMII; - break; - case PHY_INTERFACE_MODE_RGMII: - status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; - break; - default: - netdev_err(dev, "Unsupported MII interface\n"); - phy_disconnect(dev->phydev); - dev->phydev = NULL; - return -EINVAL; - } - writel(status.bits32, gmac->ctl_iomem + GMAC_STATUS); - - return 0; -} - -static int gmac_pick_rx_max_len(int max_l3_len) -{ - /* index = CONFIG_MAXLEN_XXX values */ - static const int max_len[8] = { - 1536, 1518, 1522, 1542, - 9212, 10236, 1518, 1518 - }; - int i, n = 5; - - max_l3_len += ETH_HLEN + VLAN_HLEN; - - if (max_l3_len > max_len[n]) - return -1; - - for (i = 0; i < 5; ++i) { - if (max_len[i] >= max_l3_len && max_len[i] < max_len[n]) - n = i; - } - - return n; -} - -static int gmac_init(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - u32 val; - - GMAC_CONFIG0_T config0 = { .bits = { - .dis_tx = 1, - .dis_rx = 1, - .ipv4_rx_chksum = 1, - .ipv6_rx_chksum = 1, - .rx_err_detect = 1, - .rgmm_edge = 1, - .port0_chk_hwq = 1, - .port1_chk_hwq = 1, - .port0_chk_toeq = 1, - .port1_chk_toeq = 1, - .port0_chk_classq = 1, - .port1_chk_classq = 1, - } }; - GMAC_AHB_WEIGHT_T ahb_weight = { .bits = { - .rx_weight = 1, - .tx_weight = 1, - .hash_weight = 1, - .pre_req = 0x1f, - .tqDV_threshold = 0, - } }; - GMAC_TX_WCR0_T hw_weigh = { .bits = { - .hw_tq3 = 1, - .hw_tq2 = 1, - .hw_tq1 = 1, - .hw_tq0 = 1, - } }; - GMAC_TX_WCR1_T sw_weigh = { .bits = { - .sw_tq5 = 1, - .sw_tq4 = 1, - .sw_tq3 = 1, - .sw_tq2 = 1, - .sw_tq1 = 1, - .sw_tq0 = 1, - } }; - GMAC_CONFIG1_T config1 = { .bits = { - .set_threshold = 16, - .rel_threshold = 24, - } }; - GMAC_CONFIG2_T config2 = { .bits = { - .set_threshold = 16, - .rel_threshold = 32, - } }; - GMAC_CONFIG3_T config3 = { .bits = { - .set_threshold = 0, - .rel_threshold = 0, - } }; - - config0.bits.max_len = gmac_pick_rx_max_len(dev->mtu); - - val = readl(gmac->ctl_iomem + GMAC_CONFIG0); - config0.bits.reserved = ((GMAC_CONFIG0_T)val).bits.reserved; - writel(config0.bits32, gmac->ctl_iomem + GMAC_CONFIG0); - writel(config1.bits32, gmac->ctl_iomem + GMAC_CONFIG1); - writel(config2.bits32, gmac->ctl_iomem + GMAC_CONFIG2); - writel(config3.bits32, gmac->ctl_iomem + GMAC_CONFIG3); - - val = readl(gmac->dma_iomem + GMAC_AHB_WEIGHT_REG); - writel(ahb_weight.bits32, gmac->dma_iomem + GMAC_AHB_WEIGHT_REG); - - writel(hw_weigh.bits32, - gmac->dma_iomem + GMAC_TX_WEIGHTING_CTRL_0_REG); - writel(sw_weigh.bits32, - gmac->dma_iomem + GMAC_TX_WEIGHTING_CTRL_1_REG); - - gmac->rxq_order = DEFAULT_GMAC_RXQ_ORDER; - gmac->txq_order = DEFAULT_GMAC_TXQ_ORDER; - gmac->rx_coalesce_nsecs = DEFAULT_RX_COALESCE_NSECS; - - /* Mark every quarter of the queue a packet for interrupt - in order to be able to wake up the queue if it was stopped */ - gmac->irq_every_tx_packets = 1 << (gmac->txq_order - 2); - - return 0; -} - -static void gmac_uninit(struct net_device *dev) -{ - if (dev->phydev) - phy_disconnect(dev->phydev); -} - -static int gmac_setup_txqs(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - void __iomem *rwptr_reg = gmac->dma_iomem + GMAC_SW_TX_QUEUE0_PTR_REG; - void __iomem *base_reg = gmac->dma_iomem + GMAC_SW_TX_QUEUE_BASE_REG; - - unsigned int n_txq = dev->num_tx_queues; - size_t entries = 1 <txq_order; - size_t len = n_txq * entries; - struct gmac_txq *txq = gmac->txq; - GMAC_TXDESC_T *desc_ring; - struct sk_buff **skb_tab; - unsigned int r; - int i; - - skb_tab = kzalloc(len * sizeof(*skb_tab), GFP_KERNEL); - if (!skb_tab) - return -ENOMEM; - - desc_ring = dma_alloc_coherent(toe->dev, len * sizeof(*desc_ring), - &gmac->txq_dma_base, GFP_KERNEL); - - if (!desc_ring) { - kfree(skb_tab); - return -ENOMEM; - } - - BUG_ON(gmac->txq_dma_base & ~DMA_Q_BASE_MASK); - - writel(gmac->txq_dma_base | gmac->txq_order, base_reg); - - for (i = 0; i < n_txq; i++) { - txq->ring = desc_ring; - txq->skb = skb_tab; - txq->noirq_packets = 0; - - r = readw(rwptr_reg); - rwptr_reg += 2; - writew(r, rwptr_reg); - rwptr_reg +=2; - txq->cptr = r; - - txq++; - desc_ring += entries; - skb_tab += entries; - } - - return 0; -} - -static void gmac_clean_txq(struct net_device *dev, struct gmac_txq *txq, - unsigned int r) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - unsigned int errs = 0; - unsigned int pkts = 0; - unsigned int hwchksum = 0; - unsigned long bytes = 0; - unsigned int m = (1 << gmac->txq_order) - 1; - unsigned int c = txq->cptr; - GMAC_TXDESC_0_T word0; - GMAC_TXDESC_1_T word1; - unsigned int word3; - dma_addr_t mapping; - GMAC_TXDESC_T *txd; - unsigned short nfrags; - - if (unlikely(c == r)) - return; - - rmb(); - while (c != r) { - txd = txq->ring + c; - word0 = txd->word0; - word1 = txd->word1; - mapping = txd->word2.buf_adr; - word3 = txd->word3.bits32; - - dma_unmap_single(toe->dev, mapping, word0.bits.buffer_size, DMA_TO_DEVICE); - - if (word3 & EOF_BIT) - dev_kfree_skb(txq->skb[c]); - - c++; - c &= m; - - if (!(word3 & SOF_BIT)) - continue; - - if (!word0.bits.status_tx_ok) { - errs++; - continue; - } - - pkts++; - bytes += txd->word1.bits.byte_count; - - if (word1.bits32 & TSS_CHECKUM_ENABLE) - hwchksum++; - - nfrags = word0.bits.desc_count - 1; - if (nfrags) { - if (nfrags >= TX_MAX_FRAGS) - nfrags = TX_MAX_FRAGS - 1; - - u64_stats_update_begin(&gmac->tx_stats_syncp); - gmac->tx_frag_stats[nfrags]++; - u64_stats_update_end(&gmac->ir_stats_syncp); - } - } - - u64_stats_update_begin(&gmac->ir_stats_syncp); - gmac->stats.tx_errors += errs; - gmac->stats.tx_packets += pkts; - gmac->stats.tx_bytes += bytes; - gmac->tx_hw_csummed += hwchksum; - u64_stats_update_end(&gmac->ir_stats_syncp); - - txq->cptr = c; -} - -static void gmac_cleanup_txqs(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - void __iomem *rwptr_reg = gmac->dma_iomem + GMAC_SW_TX_QUEUE0_PTR_REG; - void __iomem *base_reg = gmac->dma_iomem + GMAC_SW_TX_QUEUE_BASE_REG; - - unsigned n_txq = dev->num_tx_queues; - unsigned int r, i; - - for (i = 0; i < n_txq; i++) { - r = readw(rwptr_reg); - rwptr_reg += 2; - writew(r, rwptr_reg); - rwptr_reg += 2; - - gmac_clean_txq(dev, gmac->txq + i, r); - } - writel(0, base_reg); - - kfree(gmac->txq->skb); - dma_free_coherent(toe->dev, - n_txq * sizeof(*gmac->txq->ring) << gmac->txq_order, - gmac->txq->ring, gmac->txq_dma_base); -} - -static int gmac_setup_rxq(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - NONTOE_QHDR_T __iomem *qhdr = toe->iomem + TOE_DEFAULT_Q_HDR_BASE(dev->dev_id); - - gmac->rxq_rwptr = &qhdr->word1; - gmac->rxq_ring = dma_alloc_coherent(toe->dev, - sizeof(*gmac->rxq_ring) << gmac->rxq_order, - &gmac->rxq_dma_base, GFP_KERNEL); - if (!gmac->rxq_ring) - return -ENOMEM; - - BUG_ON(gmac->rxq_dma_base & ~NONTOE_QHDR0_BASE_MASK); - - writel(gmac->rxq_dma_base | gmac->rxq_order, &qhdr->word0); - writel(0, gmac->rxq_rwptr); - return 0; -} - -static void gmac_cleanup_rxq(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - - NONTOE_QHDR_T __iomem *qhdr = toe->iomem + TOE_DEFAULT_Q_HDR_BASE(dev->dev_id); - void __iomem *dma_reg = &qhdr->word0; - void __iomem *ptr_reg = &qhdr->word1; - GMAC_RXDESC_T *rxd = gmac->rxq_ring; - DMA_RWPTR_T rw; - unsigned int r, w; - unsigned int m = (1 <rxq_order) - 1; - struct page *page; - dma_addr_t mapping; - - rw.bits32 = readl(ptr_reg); - r = rw.bits.rptr; - w = rw.bits.wptr; - writew(r, ptr_reg + 2); - - writel(0, dma_reg); - - rmb(); - while (r != w) { - mapping = rxd[r].word2.buf_adr; - r++; - r &= m; - - if (!mapping) - continue; - - page = pfn_to_page(dma_to_pfn(toe->dev, mapping)); - put_page(page); - } - - dma_free_coherent(toe->dev, sizeof(*gmac->rxq_ring) << gmac->rxq_order, - gmac->rxq_ring, gmac->rxq_dma_base); -} - -static struct page *toe_freeq_alloc_map_page(struct toe_private *toe, int pn) -{ - unsigned int fpp_order = PAGE_SHIFT - toe->freeq_frag_order; - unsigned int frag_len = 1 << toe->freeq_frag_order; - GMAC_RXDESC_T *freeq_entry; - dma_addr_t mapping; - struct page *page; - int i; - - page = alloc_page(__GFP_COLD | GFP_ATOMIC); - if (!page) - return NULL; - - mapping = dma_map_single(toe->dev, page_address(page), - PAGE_SIZE, DMA_FROM_DEVICE); - - if (unlikely(dma_mapping_error(toe->dev, mapping) || !mapping)) { - put_page(page); - return NULL; - } - - freeq_entry = toe->freeq_ring + (pn << fpp_order); - for (i = 1 << fpp_order; i > 0; --i) { - freeq_entry->word2.buf_adr = mapping; - freeq_entry++; - mapping += frag_len; - } - - if (toe->freeq_page_tab[pn]) { - mapping = toe->freeq_ring[pn << fpp_order].word2.buf_adr; - dma_unmap_single(toe->dev, mapping, frag_len, DMA_FROM_DEVICE); - put_page(toe->freeq_page_tab[pn]); - } - - toe->freeq_page_tab[pn] = page; - return page; -} - -static unsigned int toe_fill_freeq(struct toe_private *toe, int reset) -{ - void __iomem *rwptr_reg = toe->iomem + GLOBAL_SWFQ_RWPTR_REG; - - DMA_RWPTR_T rw; - unsigned int pn, epn; - unsigned int fpp_order = PAGE_SHIFT - toe->freeq_frag_order; - unsigned int m_pn = (1 << (toe->freeq_order - fpp_order)) - 1; - struct page *page; - unsigned int count = 0; - unsigned long flags; - - spin_lock_irqsave(&toe->freeq_lock, flags); - - rw.bits32 = readl(rwptr_reg); - pn = (reset ? rw.bits.rptr : rw.bits.wptr) >> fpp_order; - epn = (rw.bits.rptr >> fpp_order) - 1; - epn &= m_pn; - - while (pn != epn) { - page = toe->freeq_page_tab[pn]; - - if (atomic_read(&page->_count) > 1) { - unsigned int fl = (pn -epn) & m_pn; - - if (fl > 64 >> fpp_order) - break; - - page = toe_freeq_alloc_map_page(toe, pn); - if (!page) - break; - } - - atomic_add(1 << fpp_order, &page->_count); - count += 1 << fpp_order; - pn++; - pn &= m_pn; - } - - wmb(); - writew(pn << fpp_order, rwptr_reg+2); - - spin_unlock_irqrestore(&toe->freeq_lock, flags); - return count; -} - -static int toe_setup_freeq(struct toe_private *toe) -{ - void __iomem *dma_reg = toe->iomem + GLOBAL_SW_FREEQ_BASE_SIZE_REG; - QUEUE_THRESHOLD_T qt; - DMA_SKB_SIZE_T skbsz; - unsigned int filled; - unsigned int frag_len = 1 << toe->freeq_frag_order; - unsigned int len = 1 << toe->freeq_order; - unsigned int fpp_order = PAGE_SHIFT - toe->freeq_frag_order; - unsigned int pages = len >> fpp_order; - dma_addr_t mapping; - unsigned int pn; - - toe->freeq_ring = dma_alloc_coherent(toe->dev, - sizeof(*toe->freeq_ring) << toe->freeq_order, - &toe->freeq_dma_base, GFP_KERNEL); - if (!toe->freeq_ring) - return -ENOMEM; - - BUG_ON(toe->freeq_dma_base & ~DMA_Q_BASE_MASK); - - toe->freeq_page_tab = kzalloc(pages * sizeof(*toe->freeq_page_tab), - GFP_KERNEL); - if (!toe->freeq_page_tab) - goto err_freeq; - - for (pn = 0; pn < pages; pn++) - if (!toe_freeq_alloc_map_page(toe, pn)) - goto err_freeq_alloc; - - filled = toe_fill_freeq(toe, 1); - if (!filled) - goto err_freeq_alloc; - - qt.bits32 = readl(toe->iomem + GLOBAL_QUEUE_THRESHOLD_REG); - qt.bits.swfq_empty = 32; - writel(qt.bits32, toe->iomem + GLOBAL_QUEUE_THRESHOLD_REG); - - skbsz.bits.sw_skb_size = 1 << toe->freeq_frag_order; - writel(skbsz.bits32, toe->iomem + GLOBAL_DMA_SKB_SIZE_REG); - writel(toe->freeq_dma_base | toe->freeq_order, dma_reg); - - return 0; - -err_freeq_alloc: - while (pn > 0) { - --pn; - mapping = toe->freeq_ring[pn << fpp_order].word2.buf_adr; - dma_unmap_single(toe->dev, mapping, frag_len, DMA_FROM_DEVICE); - put_page(toe->freeq_page_tab[pn]); - } - -err_freeq: - dma_free_coherent(toe->dev, - sizeof(*toe->freeq_ring) << toe->freeq_order, - toe->freeq_ring, toe->freeq_dma_base); - toe->freeq_ring = NULL; - return -ENOMEM; -} - -static void toe_cleanup_freeq(struct toe_private *toe) -{ - void __iomem *dma_reg = toe->iomem + GLOBAL_SW_FREEQ_BASE_SIZE_REG; - void __iomem *ptr_reg = toe->iomem + GLOBAL_SWFQ_RWPTR_REG; - - unsigned int frag_len = 1 << toe->freeq_frag_order; - unsigned int len = 1 << toe->freeq_order; - unsigned int fpp_order = PAGE_SHIFT - toe->freeq_frag_order; - unsigned int pages = len >> fpp_order; - struct page *page; - dma_addr_t mapping; - unsigned int pn; - - writew(readw(ptr_reg), ptr_reg + 2); - writel(0, dma_reg); - - for (pn = 0; pn < pages; pn++) { - mapping = toe->freeq_ring[pn << fpp_order].word2.buf_adr; - dma_unmap_single(toe->dev, mapping, frag_len, DMA_FROM_DEVICE); - - page = toe->freeq_page_tab[pn]; - while (atomic_read(&page->_count) > 0) - put_page(page); - } - - kfree(toe->freeq_page_tab); - - dma_free_coherent(toe->dev, - sizeof(*toe->freeq_ring) << toe->freeq_order, - toe->freeq_ring, toe->freeq_dma_base); -} - -static int toe_resize_freeq(struct toe_private *toe, int changing_dev_id) -{ - void __iomem *irqen_reg = toe->iomem + GLOBAL_INTERRUPT_ENABLE_4_REG; - struct gmac_private *gmac; - struct net_device *other = toe->netdev[1 - changing_dev_id]; - unsigned new_size = 0; - unsigned new_order; - int err; - unsigned long flags; - unsigned en; - - if (other && netif_running(other)) - return -EBUSY; - - if (toe->netdev[0]) { - gmac = netdev_priv(toe->netdev[0]); - new_size = 1 << (gmac->rxq_order + 1); - } - - if (toe->netdev[1]) { - gmac = netdev_priv(toe->netdev[1]); - new_size += 1 << (gmac->rxq_order + 1); - } - - new_order = min(15, ilog2(new_size - 1) + 1); - if (toe->freeq_order == new_order) - return 0; - - spin_lock_irqsave(&toe->irq_lock, flags); - en = readl(irqen_reg); - en &= ~SWFQ_EMPTY_INT_BIT; - writel(en, irqen_reg); - - if (toe->freeq_ring) - toe_cleanup_freeq(toe); - - toe->freeq_order = new_order; - err = toe_setup_freeq(toe); - - en |= SWFQ_EMPTY_INT_BIT; - writel(en, irqen_reg); - spin_unlock_irqrestore(&toe->irq_lock, flags); - - return err; -} - -static void gmac_tx_irq_enable(struct net_device *dev, unsigned txq, int en) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - unsigned val, mask; - - mask = GMAC0_IRQ0_TXQ0_INTS << (6 * dev->dev_id + txq); - - if (en) - writel(mask, toe->iomem + GLOBAL_INTERRUPT_STATUS_0_REG); - - val = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_0_REG); - val = en ? val | mask : val & ~mask; - writel(val, toe->iomem + GLOBAL_INTERRUPT_ENABLE_0_REG); -} - - -static void gmac_tx_irq(struct net_device *dev, unsigned txq_num) -{ - struct netdev_queue *ntxq = netdev_get_tx_queue(dev, txq_num); - - gmac_tx_irq_enable(dev, txq_num, 0); - netif_tx_wake_queue(ntxq); -} - -static int gmac_map_tx_bufs(struct net_device *dev, struct sk_buff *skb, - struct gmac_txq *txq, unsigned short *desc) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - struct skb_shared_info *skb_si = skb_shinfo(skb); - skb_frag_t *skb_frag; - short frag, last_frag = skb_si->nr_frags - 1; - unsigned short m = (1 << gmac->txq_order) -1; - unsigned short w = *desc; - unsigned word1, word3, buflen; - dma_addr_t mapping; - void *buffer; - unsigned short mtu; - GMAC_TXDESC_T *txd; - - mtu = ETH_HLEN; - mtu += dev->mtu; - if (skb->protocol == htons(ETH_P_8021Q)) - mtu += VLAN_HLEN; - - word1 = skb->len; - word3 = SOF_BIT; - - if (word1 > mtu) { - word1 |= TSS_MTU_ENABLE_BIT; - word3 += mtu; - } - - if (skb->ip_summed != CHECKSUM_NONE) { - int tcp = 0; - if (skb->protocol == htons(ETH_P_IP)) { - word1 |= TSS_IP_CHKSUM_BIT; - tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; - } else { /* IPv6 */ - word1 |= TSS_IPV6_ENABLE_BIT; - tcp = ipv6_hdr(skb)->nexthdr == IPPROTO_TCP; - } - - word1 |= tcp ? TSS_TCP_CHKSUM_BIT : TSS_UDP_CHKSUM_BIT; - } - - frag = -1; - while (frag <= last_frag) { - if (frag == -1) { - buffer = skb->data; - buflen = skb_headlen(skb); - } else { - skb_frag = skb_si->frags + frag; - buffer = page_address(skb_frag_page(skb_frag)) + - skb_frag->page_offset; - buflen = skb_frag->size; - } - - if (frag == last_frag) { - word3 |= EOF_BIT; - txq->skb[w] = skb; - } - - mapping = dma_map_single(toe->dev, buffer, buflen, - DMA_TO_DEVICE); - if (dma_mapping_error(toe->dev, mapping) || - !(mapping & PAGE_MASK)) - goto map_error; - - txd = txq->ring + w; - txd->word0.bits32 = buflen; - txd->word1.bits32 = word1; - txd->word2.buf_adr = mapping; - txd->word3.bits32 = word3; - - word3 &= MTU_SIZE_BIT_MASK; - w++; - w &= m; - frag++; - } - - *desc = w; - return 0; - -map_error: - while (w != *desc) { - w--; - w &= m; - - dma_unmap_page(toe->dev, txq->ring[w].word2.buf_adr, - txq->ring[w].word0.bits.buffer_size, DMA_TO_DEVICE); - } - return ENOMEM; -} - -static int gmac_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - - void __iomem *ptr_reg; - struct gmac_txq *txq; - struct netdev_queue *ntxq; - int txq_num, nfrags; - DMA_RWPTR_T rw; - unsigned short r, w, d; - unsigned short m = (1 << gmac->txq_order) - 1; - - SKB_FRAG_ASSERT(skb); - - if (unlikely(skb->len >= 0x10000)) - goto out_drop_free; - - txq_num = skb_get_queue_mapping(skb); - ptr_reg = gmac->dma_iomem + GMAC_SW_TX_QUEUE_PTR_REG(txq_num); - txq = &gmac->txq[txq_num]; - ntxq = netdev_get_tx_queue(dev, txq_num); - nfrags = skb_shinfo(skb)->nr_frags; - - rw.bits32 = readl(ptr_reg); - r = rw.bits.rptr; - w = rw.bits.wptr; - - d = txq->cptr - w - 1; - d &= m; - - if (unlikely(d < nfrags+2)) - { - gmac_clean_txq(dev, txq, r); - d = txq->cptr - w - 1; - d &= m; - - if (unlikely(d < nfrags+2)) { - netif_tx_stop_queue(ntxq); - - d = txq->cptr + nfrags + 16; - d &= m; - txq->ring[d].word3.bits.eofie = 1; - gmac_tx_irq_enable(dev, txq_num, 1); - - u64_stats_update_begin(&gmac->tx_stats_syncp); - dev->stats.tx_fifo_errors++; - u64_stats_update_end(&gmac->tx_stats_syncp); - return NETDEV_TX_BUSY; - } - } - - if (unlikely(gmac_map_tx_bufs(dev, skb, txq, &w))) { - if (skb_linearize(skb)) - goto out_drop; - - if (unlikely(gmac_map_tx_bufs(dev, skb, txq, &w))) - goto out_drop_free; - - u64_stats_update_begin(&gmac->tx_stats_syncp); - gmac->tx_frags_linearized++; - u64_stats_update_end(&gmac->tx_stats_syncp); - } - - writew(w, ptr_reg+2); - - gmac_clean_txq(dev, txq, r); - return NETDEV_TX_OK; - -out_drop_free: - dev_kfree_skb(skb); -out_drop: - u64_stats_update_begin(&gmac->tx_stats_syncp); - gmac->stats.tx_dropped++; - u64_stats_update_end(&gmac->tx_stats_syncp); - return NETDEV_TX_OK; -} - -static void gmac_tx_timeout(struct net_device *dev) -{ - netdev_err(dev, "Tx timeout\n"); - gmac_dump_dma_state(dev); -} - -static void gmac_enable_irq(struct net_device *dev, int enable) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - unsigned long flags; - unsigned val, mask; - - spin_lock_irqsave(&toe->irq_lock, flags); - - mask = GMAC0_IRQ0_2 << (dev->dev_id * 2); - val = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_0_REG); - val = enable ? (val | mask) : (val & ~mask); - writel(val, toe->iomem + GLOBAL_INTERRUPT_ENABLE_0_REG); - - mask = DEFAULT_Q0_INT_BIT << dev->dev_id; - val = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_1_REG); - val = enable ? (val | mask) : (val & ~mask); - writel(val, toe->iomem + GLOBAL_INTERRUPT_ENABLE_1_REG); - - mask = GMAC0_IRQ4_8 << (dev->dev_id * 8); - val = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_4_REG); - val = enable ? (val | mask) : (val & ~mask); - writel(val, toe->iomem + GLOBAL_INTERRUPT_ENABLE_4_REG); - - spin_unlock_irqrestore(&toe->irq_lock, flags); -} - -static void gmac_enable_rx_irq(struct net_device *dev, int enable) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - unsigned long flags; - unsigned val, mask; - - spin_lock_irqsave(&toe->irq_lock, flags); - mask = DEFAULT_Q0_INT_BIT << dev->dev_id; - - val = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_1_REG); - val = enable ? (val | mask) : (val & ~mask); - writel(val, toe->iomem + GLOBAL_INTERRUPT_ENABLE_1_REG); - - spin_unlock_irqrestore(&toe->irq_lock, flags); -} - -static struct sk_buff *gmac_skb_if_good_frame(struct gmac_private *gmac, - GMAC_RXDESC_0_T word0, unsigned frame_len) -{ - struct sk_buff *skb = NULL; - unsigned rx_status = word0.bits.status; - unsigned rx_csum = word0.bits.chksum_status; - - gmac->rx_stats[rx_status]++; - gmac->rx_csum_stats[rx_csum]++; - - if (word0.bits.derr || word0.bits.perr || - rx_status || frame_len < ETH_ZLEN || - rx_csum >= RX_CHKSUM_IP_ERR_UNKNOWN) { - gmac->stats.rx_errors++; - - if (frame_len < ETH_ZLEN || RX_ERROR_LENGTH(rx_status)) - gmac->stats.rx_length_errors++; - if (RX_ERROR_OVER(rx_status)) - gmac->stats.rx_over_errors++; - if (RX_ERROR_CRC(rx_status)) - gmac->stats.rx_crc_errors++; - if (RX_ERROR_FRAME(rx_status)) - gmac->stats.rx_frame_errors++; - - return NULL; - } - - skb = napi_get_frags(&gmac->napi); - if (!skb) - return NULL; - - if (rx_csum == RX_CHKSUM_IP_UDP_TCP_OK) - skb->ip_summed = CHECKSUM_UNNECESSARY; - - gmac->stats.rx_bytes += frame_len; - gmac->stats.rx_packets++; - return skb; -} - -static unsigned gmac_rx(struct net_device *dev, unsigned budget) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - void __iomem *ptr_reg = gmac->rxq_rwptr; - - static struct sk_buff *skb; - - DMA_RWPTR_T rw; - unsigned short r, w; - unsigned short m = (1 << gmac->rxq_order) -1; - GMAC_RXDESC_T *rx = NULL; - struct page* page = NULL; - unsigned page_offs; - unsigned int frame_len, frag_len; - int frag_nr = 0; - - GMAC_RXDESC_0_T word0; - GMAC_RXDESC_1_T word1; - dma_addr_t mapping; - GMAC_RXDESC_3_T word3; - - rw.bits32 = readl(ptr_reg); - /* Reset interrupt as all packages until here are taken into account */ - writel(DEFAULT_Q0_INT_BIT << dev->dev_id, - toe->iomem + GLOBAL_INTERRUPT_STATUS_1_REG); - r = rw.bits.rptr; - w = rw.bits.wptr; - - while (budget && w != r) { - rx = gmac->rxq_ring + r; - word0 = rx->word0; - word1 = rx->word1; - mapping = rx->word2.buf_adr; - word3 = rx->word3; - - r++; - r &= m; - - frag_len = word0.bits.buffer_size; - frame_len =word1.bits.byte_count; - page_offs = mapping & ~PAGE_MASK; - - if (unlikely(!mapping)) { - netdev_err(dev, "rxq[%u]: HW BUG: zero DMA desc\n", r); - goto err_drop; - } - - page = pfn_to_page(dma_to_pfn(toe->dev, mapping)); - - if (word3.bits32 & SOF_BIT) { - if (unlikely(skb)) { - napi_free_frags(&gmac->napi); - gmac->stats.rx_dropped++; - } - - skb = gmac_skb_if_good_frame(gmac, word0, frame_len); - if (unlikely(!skb)) - goto err_drop; - - page_offs += NET_IP_ALIGN; - frag_len -= NET_IP_ALIGN; - frag_nr = 0; - - } else if (!skb) { - put_page(page); - continue; - } - - if (word3.bits32 & EOF_BIT) - frag_len = frame_len - skb->len; - - /* append page frag to skb */ - if (unlikely(frag_nr == MAX_SKB_FRAGS)) - goto err_drop; - - if (frag_len == 0) - netdev_err(dev, "Received fragment with len = 0\n"); - - skb_fill_page_desc(skb, frag_nr, page, page_offs, frag_len); - skb->len += frag_len; - skb->data_len += frag_len; - skb->truesize += frag_len; - frag_nr++; - - if (word3.bits32 & EOF_BIT) { - napi_gro_frags(&gmac->napi); - skb = NULL; - --budget; - } - continue; - -err_drop: - if (skb) { - napi_free_frags(&gmac->napi); - skb = NULL; - } - - if (mapping) - put_page(page); - - gmac->stats.rx_dropped++; - } - - writew(r, ptr_reg); - return budget; -} - -static int gmac_napi_poll(struct napi_struct *napi, int budget) -{ - struct gmac_private *gmac = netdev_priv(napi->dev); - struct toe_private *toe = gmac->toe; - unsigned rx; - unsigned freeq_threshold = 1 << (toe->freeq_order - 1); - - u64_stats_update_begin(&gmac->rx_stats_syncp); - - rx = budget - gmac_rx(napi->dev, budget); - - if (rx == 0) { - napi_gro_flush(napi, false); - __napi_complete(napi); - gmac_enable_rx_irq(napi->dev, 1); - ++gmac->rx_napi_exits; - } - - gmac->freeq_refill += rx; - if (gmac->freeq_refill > freeq_threshold) { - gmac->freeq_refill -= freeq_threshold; - toe_fill_freeq(toe, 0); - } - - u64_stats_update_end(&gmac->rx_stats_syncp); - return budget; -} - -static void gmac_dump_dma_state(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - void __iomem *ptr_reg; - unsigned reg[5]; - - /* Interrupt status */ - reg[0] = readl(toe->iomem + GLOBAL_INTERRUPT_STATUS_0_REG); - reg[1] = readl(toe->iomem + GLOBAL_INTERRUPT_STATUS_1_REG); - reg[2] = readl(toe->iomem + GLOBAL_INTERRUPT_STATUS_2_REG); - reg[3] = readl(toe->iomem + GLOBAL_INTERRUPT_STATUS_3_REG); - reg[4] = readl(toe->iomem + GLOBAL_INTERRUPT_STATUS_4_REG); - netdev_err(dev, "IRQ status: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", - reg[0], reg[1], reg[2], reg[3], reg[4]); - - /* Interrupt enable */ - reg[0] = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_0_REG); - reg[1] = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_1_REG); - reg[2] = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_2_REG); - reg[3] = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_3_REG); - reg[4] = readl(toe->iomem + GLOBAL_INTERRUPT_ENABLE_4_REG); - netdev_err(dev, "IRQ enable: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", - reg[0], reg[1], reg[2], reg[3], reg[4]); - - /* RX DMA status */ - reg[0] = readl(gmac->dma_iomem + GMAC_DMA_RX_FIRST_DESC_REG); - reg[1] = readl(gmac->dma_iomem + GMAC_DMA_RX_CURR_DESC_REG); - reg[2] = GET_RPTR(gmac->rxq_rwptr); - reg[3] = GET_WPTR(gmac->rxq_rwptr); - netdev_err(dev, "RX DMA regs: 0x%08x 0x%08x, ptr: %u %u\n", - reg[0], reg[1], reg[2], reg[3]); - - reg[0] = readl(gmac->dma_iomem + GMAC_DMA_RX_DESC_WORD0_REG); - reg[1] = readl(gmac->dma_iomem + GMAC_DMA_RX_DESC_WORD1_REG); - reg[2] = readl(gmac->dma_iomem + GMAC_DMA_RX_DESC_WORD2_REG); - reg[3] = readl(gmac->dma_iomem + GMAC_DMA_RX_DESC_WORD3_REG); - netdev_err(dev, "RX DMA descriptor: 0x%08x 0x%08x 0x%08x 0x%08x\n", - reg[0], reg[1], reg[2], reg[3]); - - /* TX DMA status */ - ptr_reg = gmac->dma_iomem + GMAC_SW_TX_QUEUE0_PTR_REG; - - reg[0] = readl(gmac->dma_iomem + GMAC_DMA_TX_FIRST_DESC_REG); - reg[1] = readl(gmac->dma_iomem + GMAC_DMA_TX_CURR_DESC_REG); - reg[2] = GET_RPTR(ptr_reg); - reg[3] = GET_WPTR(ptr_reg); - netdev_err(dev, "TX DMA regs: 0x%08x 0x%08x, ptr: %u %u\n", - reg[0], reg[1], reg[2], reg[3]); - - reg[0] = readl(gmac->dma_iomem + GMAC_DMA_TX_DESC_WORD0_REG); - reg[1] = readl(gmac->dma_iomem + GMAC_DMA_TX_DESC_WORD1_REG); - reg[2] = readl(gmac->dma_iomem + GMAC_DMA_TX_DESC_WORD2_REG); - reg[3] = readl(gmac->dma_iomem + GMAC_DMA_TX_DESC_WORD3_REG); - netdev_err(dev, "TX DMA descriptor: 0x%08x 0x%08x 0x%08x 0x%08x\n", - reg[0], reg[1], reg[2], reg[3]); - - /* FREE queues status */ - ptr_reg = toe->iomem + GLOBAL_SWFQ_RWPTR_REG; - - reg[0] = GET_RPTR(ptr_reg); - reg[1] = GET_WPTR(ptr_reg); - - ptr_reg = toe->iomem + GLOBAL_HWFQ_RWPTR_REG; - - reg[2] = GET_RPTR(ptr_reg); - reg[3] = GET_WPTR(ptr_reg); - netdev_err(dev, "FQ SW ptr: %u %u, HW ptr: %u %u\n", - reg[0], reg[1], reg[2], reg[3]); -} - -static void gmac_update_hw_stats(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - unsigned long flags; - unsigned int rx_discards, rx_mcast, rx_bcast; - - spin_lock_irqsave(&toe->irq_lock, flags); - u64_stats_update_begin(&gmac->ir_stats_syncp); - - gmac->hw_stats[0] += rx_discards = readl(gmac->ctl_iomem + GMAC_IN_DISCARDS); - gmac->hw_stats[1] += readl(gmac->ctl_iomem + GMAC_IN_ERRORS); - gmac->hw_stats[2] += rx_mcast = readl(gmac->ctl_iomem + GMAC_IN_MCAST); - gmac->hw_stats[3] += rx_bcast = readl(gmac->ctl_iomem + GMAC_IN_BCAST); - gmac->hw_stats[4] += readl(gmac->ctl_iomem + GMAC_IN_MAC1); - gmac->hw_stats[5] += readl(gmac->ctl_iomem + GMAC_IN_MAC2); - - gmac->stats.rx_missed_errors += rx_discards; - gmac->stats.multicast += rx_mcast; - gmac->stats.multicast += rx_bcast; - - writel(GMAC0_MIB_INT_BIT << (dev->dev_id * 8), - toe->iomem + GLOBAL_INTERRUPT_STATUS_4_REG); - - u64_stats_update_end(&gmac->ir_stats_syncp); - spin_unlock_irqrestore(&toe->irq_lock, flags); -} - -static inline unsigned gmac_get_intr_flags(struct net_device *dev, int i) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - void __iomem *irqif_reg, *irqen_reg; - unsigned offs, val; - - offs = i * (GLOBAL_INTERRUPT_STATUS_1_REG - GLOBAL_INTERRUPT_STATUS_0_REG); - - irqif_reg = toe->iomem + GLOBAL_INTERRUPT_STATUS_0_REG + offs; - irqen_reg = toe->iomem + GLOBAL_INTERRUPT_ENABLE_0_REG + offs; - - val = readl(irqif_reg) & readl(irqen_reg); - return val; -} - -enum hrtimer_restart gmac_coalesce_delay_expired( struct hrtimer *timer ) -{ - struct gmac_private *gmac = container_of(timer, struct gmac_private, rx_coalesce_timer); - - napi_schedule(&gmac->napi); - return HRTIMER_NORESTART; -} - -static irqreturn_t gmac_irq(int irq, void *data) -{ - struct net_device *dev = data; - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - unsigned val, orr = 0; - - orr |= val = gmac_get_intr_flags(dev, 0); - - if (unlikely(val & (GMAC0_IRQ0_2 << (dev->dev_id * 2)))) { - /* oh, crap. */ - netdev_err(dev, "hw failure/sw bug\n"); - gmac_dump_dma_state(dev); - - /* don't know how to recover, just reduce losses */ - gmac_enable_irq(dev, 0); - return IRQ_HANDLED; - } - - if (val & (GMAC0_IRQ0_TXQ0_INTS << (dev->dev_id * 6))) - gmac_tx_irq(dev, 0); - - orr |= val = gmac_get_intr_flags(dev, 1); - - if (val & (DEFAULT_Q0_INT_BIT << dev->dev_id)) { - - gmac_enable_rx_irq(dev, 0); - - if (!gmac->rx_coalesce_nsecs) - napi_schedule(&gmac->napi); - else { - ktime_t ktime; - ktime = ktime_set(0, gmac->rx_coalesce_nsecs); - hrtimer_start(&gmac->rx_coalesce_timer, ktime, HRTIMER_MODE_REL); - } - } - - orr |= val = gmac_get_intr_flags(dev, 4); - - if (unlikely(val & (GMAC0_MIB_INT_BIT << (dev->dev_id * 8)))) - gmac_update_hw_stats(dev); - - if (unlikely(val & (GMAC0_RX_OVERRUN_INT_BIT << (dev->dev_id * 8)))) { - writel(GMAC0_RXDERR_INT_BIT << (dev->dev_id * 8), - toe->iomem + GLOBAL_INTERRUPT_STATUS_4_REG); - - spin_lock(&toe->irq_lock); - u64_stats_update_begin(&gmac->ir_stats_syncp); - ++gmac->stats.rx_fifo_errors; - u64_stats_update_end(&gmac->ir_stats_syncp); - spin_unlock(&toe->irq_lock); - } - - return orr ? IRQ_HANDLED : IRQ_NONE; -} - -static void gmac_start_dma(struct gmac_private *gmac) -{ - void __iomem *dma_ctrl_reg = gmac->dma_iomem + GMAC_DMA_CTRL_REG; - GMAC_DMA_CTRL_T dma_ctrl; - - dma_ctrl.bits32 = readl(dma_ctrl_reg); - dma_ctrl.bits.rd_enable = 1; - dma_ctrl.bits.td_enable = 1; - dma_ctrl.bits.loopback = 0; - dma_ctrl.bits.drop_small_ack = 0; - dma_ctrl.bits.rd_insert_bytes = NET_IP_ALIGN; - dma_ctrl.bits.rd_prot = HPROT_DATA_CACHE | HPROT_PRIVILIGED; - dma_ctrl.bits.rd_burst_size = HBURST_INCR8; - dma_ctrl.bits.rd_bus = HSIZE_8; - dma_ctrl.bits.td_prot = HPROT_DATA_CACHE; - dma_ctrl.bits.td_burst_size = HBURST_INCR8; - dma_ctrl.bits.td_bus = HSIZE_8; - - writel(dma_ctrl.bits32, dma_ctrl_reg); -} - -static void gmac_stop_dma(struct gmac_private *gmac) -{ - void __iomem *dma_ctrl_reg = gmac->dma_iomem + GMAC_DMA_CTRL_REG; - GMAC_DMA_CTRL_T dma_ctrl; - - dma_ctrl.bits32 = readl(dma_ctrl_reg); - dma_ctrl.bits.rd_enable = 0; - dma_ctrl.bits.td_enable = 0; - writel(dma_ctrl.bits32, dma_ctrl_reg); -} - -static int gmac_open(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - int err; - - if (!dev->phydev) { - err = gmac_setup_phy(dev); - if (err) { - netif_err(gmac, ifup, dev, - "PHY init failed: %d\n", err); - return err; - } - } - - err = request_irq(dev->irq, gmac_irq, - IRQF_SHARED, dev->name, dev); - if (unlikely(err)) - return err; - - netif_carrier_off(dev); - phy_start(dev->phydev); - - err = toe_resize_freeq(gmac->toe, dev->dev_id); - if (unlikely(err)) - goto err_stop_phy; - - err = gmac_setup_rxq(dev); - if (unlikely(err)) - goto err_stop_phy; - - err = gmac_setup_txqs(dev); - if (unlikely(err)) { - gmac_cleanup_rxq(dev); - goto err_stop_phy; - } - - napi_enable(&gmac->napi); - - gmac_start_dma(gmac); - gmac_enable_irq(dev, 1); - gmac_enable_tx_rx(dev); - netif_tx_start_all_queues(dev); - - hrtimer_init(&gmac->rx_coalesce_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - gmac->rx_coalesce_timer.function = &gmac_coalesce_delay_expired; - return 0; - -err_stop_phy: - phy_stop(dev->phydev); - free_irq(dev->irq, dev); - return err; -} - -static int gmac_stop(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - - hrtimer_cancel(&gmac->rx_coalesce_timer); - netif_tx_stop_all_queues(dev); - gmac_disable_tx_rx(dev); - gmac_stop_dma(gmac); - napi_disable(&gmac->napi); - - gmac_enable_irq(dev, 0); - gmac_cleanup_rxq(dev); - gmac_cleanup_txqs(dev); - - phy_stop(dev->phydev); - free_irq(dev->irq, dev); - - gmac_update_hw_stats(dev); - return 0; -} - -static void gmac_set_rx_mode(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct netdev_hw_addr *ha; - __u32 mc_filter[2]; - unsigned bit_nr; - GMAC_RX_FLTR_T filter = { .bits = { - .broadcast = 1, - .multicast = 1, - .unicast = 1, - } }; - - mc_filter[1] = mc_filter[0] = 0; - - if (dev->flags & IFF_PROMISC) { - filter.bits.error = 1; - filter.bits.promiscuous = 1; - } else if (!(dev->flags & IFF_ALLMULTI)) { - mc_filter[1] = mc_filter[0] = 0; - netdev_for_each_mc_addr(ha, dev) { - bit_nr = ~crc32_le(~0, ha->addr, ETH_ALEN) & 0x3f; - mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 0x1f); - } - } - - writel(mc_filter[0], gmac->ctl_iomem + GMAC_MCAST_FIL0); - writel(mc_filter[1], gmac->ctl_iomem + GMAC_MCAST_FIL1); - writel(filter.bits32, gmac->ctl_iomem + GMAC_RX_FLTR); -} - -static void __gmac_set_mac_address(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - __le32 addr[3]; - - memset(addr, 0, sizeof(addr)); - memcpy(addr, dev->dev_addr, ETH_ALEN); - - writel(le32_to_cpu(addr[0]), gmac->ctl_iomem + GMAC_STA_ADD0); - writel(le32_to_cpu(addr[1]), gmac->ctl_iomem + GMAC_STA_ADD1); - writel(le32_to_cpu(addr[2]), gmac->ctl_iomem + GMAC_STA_ADD2); -} - -static int gmac_set_mac_address(struct net_device *dev, void *addr) -{ - struct sockaddr *sa = addr; - - memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); - __gmac_set_mac_address(dev); - - return 0; -} - -static void gmac_clear_hw_stats(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - - readl(gmac->ctl_iomem + GMAC_IN_DISCARDS); - readl(gmac->ctl_iomem + GMAC_IN_ERRORS); - readl(gmac->ctl_iomem + GMAC_IN_MCAST); - readl(gmac->ctl_iomem + GMAC_IN_BCAST); - readl(gmac->ctl_iomem + GMAC_IN_MAC1); - readl(gmac->ctl_iomem + GMAC_IN_MAC2); -} - -static struct rtnl_link_stats64 *gmac_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *storage) -{ - struct gmac_private *gmac = netdev_priv(dev); - unsigned int start; - - gmac_update_hw_stats(dev); - - /* racing with RX NAPI */ - do { - start = u64_stats_fetch_begin(&gmac->rx_stats_syncp); - - storage->rx_packets = gmac->stats.rx_packets; - storage->rx_bytes = gmac->stats.rx_bytes; - storage->rx_errors = gmac->stats.rx_errors; - storage->rx_dropped = gmac->stats.rx_dropped; - - storage->rx_length_errors = gmac->stats.rx_length_errors; - storage->rx_over_errors = gmac->stats.rx_over_errors; - storage->rx_crc_errors = gmac->stats.rx_crc_errors; - storage->rx_frame_errors = gmac->stats.rx_frame_errors; - - } while (u64_stats_fetch_retry(&gmac->rx_stats_syncp, start)); - - /* racing with MIB and TX completion interrupts */ - do { - start = u64_stats_fetch_begin(&gmac->ir_stats_syncp); - - storage->tx_errors = gmac->stats.tx_errors; - storage->tx_packets = gmac->stats.tx_packets; - storage->tx_bytes = gmac->stats.tx_bytes; - - storage->multicast = gmac->stats.multicast; - storage->rx_missed_errors = gmac->stats.rx_missed_errors; - storage->rx_fifo_errors = gmac->stats.rx_fifo_errors; - - } while (u64_stats_fetch_retry(&gmac->ir_stats_syncp, start)); - - /* racing with hard_start_xmit */ - do { - start = u64_stats_fetch_begin(&gmac->tx_stats_syncp); - - storage->tx_dropped = gmac->stats.tx_dropped; - - } while (u64_stats_fetch_retry(&gmac->tx_stats_syncp, start)); - - storage->rx_dropped += storage->rx_missed_errors; - - return storage; -} - -static int gmac_change_mtu(struct net_device *dev, int new_mtu) -{ - int max_len = gmac_pick_rx_max_len(new_mtu); - - if (max_len < 0) - return -EINVAL; - - gmac_disable_tx_rx(dev); - - dev->mtu = new_mtu; - gmac_update_config0_reg(dev, - max_len << CONFIG0_MAXLEN_SHIFT, - CONFIG0_MAXLEN_MASK); - - netdev_update_features(dev); - - gmac_enable_tx_rx(dev); - - return 0; -} - -static netdev_features_t gmac_fix_features(struct net_device *dev, netdev_features_t features) -{ - if (dev->mtu + ETH_HLEN + VLAN_HLEN > MTU_SIZE_BIT_MASK) - features &= ~GMAC_OFFLOAD_FEATURES; - - return features; -} - -static int gmac_set_features(struct net_device *dev, netdev_features_t features) -{ - struct gmac_private *gmac = netdev_priv(dev); - int enable = features & NETIF_F_RXCSUM; - unsigned long flags; - u32 reg; - - spin_lock_irqsave(&gmac->config_lock, flags); - - reg = readl(gmac->ctl_iomem + GMAC_CONFIG0); - reg = enable ? reg | CONFIG0_RX_CHKSUM : reg & ~CONFIG0_RX_CHKSUM; - writel(reg, gmac->ctl_iomem + GMAC_CONFIG0); - - spin_unlock_irqrestore(&gmac->config_lock, flags); - return 0; -} - -static int gmac_get_sset_count(struct net_device *dev, int sset) -{ - return sset == ETH_SS_STATS ? GMAC_STATS_NUM : 0; -} - -static void gmac_get_strings(struct net_device *dev, u32 stringset, u8 *data) -{ - if (stringset != ETH_SS_STATS) - return; - - memcpy(data, gmac_stats_strings, sizeof(gmac_stats_strings)); -} - -static void gmac_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *estats, u64 *values) -{ - struct gmac_private *gmac = netdev_priv(dev); - unsigned int start; - u64 *p; - int i; - - gmac_update_hw_stats(dev); - - /* racing with MIB interrupt */ - do { - p = values; - start = u64_stats_fetch_begin(&gmac->ir_stats_syncp); - - for (i = 0; i < RX_STATS_NUM; ++i) - *p++ = gmac->hw_stats[i]; - - } while (u64_stats_fetch_retry(&gmac->ir_stats_syncp, start)); - values = p; - - /* racing with RX NAPI */ - do { - p = values; - start = u64_stats_fetch_begin(&gmac->rx_stats_syncp); - - for (i = 0; i < RX_STATUS_NUM; ++i) - *p++ = gmac->rx_stats[i]; - for (i = 0; i < RX_CHKSUM_NUM; ++i) - *p++ = gmac->rx_csum_stats[i]; - *p++ = gmac->rx_napi_exits; - - } while (u64_stats_fetch_retry(&gmac->rx_stats_syncp, start)); - values = p; - - /* racing with TX start_xmit */ - do { - p = values; - start = u64_stats_fetch_begin(&gmac->tx_stats_syncp); - - for (i = 0; i < TX_MAX_FRAGS; ++i) { - *values++ = gmac->tx_frag_stats[i]; - gmac->tx_frag_stats[i] = 0; - } - *values++ = gmac->tx_frags_linearized; - *values++ = gmac->tx_hw_csummed; - - } while (u64_stats_fetch_retry(&gmac->tx_stats_syncp, start)); -} - -static int gmac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - if (!dev->phydev) - return -ENXIO; - return phy_ethtool_gset(dev->phydev, cmd); -} - -static int gmac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - if (!dev->phydev) - return -ENXIO; - return phy_ethtool_sset(dev->phydev, cmd); -} - -static int gmac_nway_reset(struct net_device *dev) -{ - if (!dev->phydev) - return -ENXIO; - return phy_start_aneg(dev->phydev); -} - -static void gmac_get_pauseparam(struct net_device *dev, - struct ethtool_pauseparam *pparam) -{ - struct gmac_private *gmac = netdev_priv(dev); - GMAC_CONFIG0_T config0; - - config0.bits32 = readl(gmac->ctl_iomem + GMAC_CONFIG0); - - pparam->rx_pause = config0.bits.rx_fc_en; - pparam->tx_pause = config0.bits.tx_fc_en; - pparam->autoneg = true; -} - -static void gmac_get_ringparam(struct net_device *dev, - struct ethtool_ringparam *rp) -{ - struct gmac_private *gmac = netdev_priv(dev); - GMAC_CONFIG0_T config0; - - config0.bits32 = readl(gmac->ctl_iomem + GMAC_CONFIG0); - - rp->rx_max_pending = 1 << 15; - rp->rx_mini_max_pending = 0; - rp->rx_jumbo_max_pending = 0; - rp->tx_max_pending = 1 << 15; - - rp->rx_pending = 1 << gmac->rxq_order; - rp->rx_mini_pending = 0; - rp->rx_jumbo_pending = 0; - rp->tx_pending = 1 << gmac->txq_order; -} - -static int toe_resize_freeq(struct toe_private *toe, int changing_dev_id); - -static int gmac_set_ringparam(struct net_device *dev, - struct ethtool_ringparam *rp) -{ - struct gmac_private *gmac = netdev_priv(dev); - struct toe_private *toe = gmac->toe; - int err = 0; - - if (netif_running(dev)) - return -EBUSY; - - if (rp->rx_pending) { - gmac->rxq_order = min(15, ilog2(rp->rx_pending - 1) + 1); - err = toe_resize_freeq(toe, dev->dev_id); - } - - if (rp->tx_pending) - { - gmac->txq_order = min(15, ilog2(rp->tx_pending - 1) + 1); - gmac->irq_every_tx_packets = 1 << (gmac->txq_order - 2); - } - - return err; -} - -static int gmac_get_coalesce(struct net_device *dev, - struct ethtool_coalesce *ecmd) -{ - struct gmac_private *gmac = netdev_priv(dev); - - ecmd->rx_max_coalesced_frames = 1; - ecmd->tx_max_coalesced_frames = gmac->irq_every_tx_packets; - ecmd->rx_coalesce_usecs = gmac->rx_coalesce_nsecs/1000; - - return 0; -} - -static int gmac_set_coalesce(struct net_device *dev, - struct ethtool_coalesce *ecmd) -{ - struct gmac_private *gmac = netdev_priv(dev); - - if (ecmd->tx_max_coalesced_frames < 1) - return -EINVAL; - if (ecmd->tx_max_coalesced_frames >= 1 << gmac->txq_order) - return -EINVAL; - - gmac->irq_every_tx_packets = ecmd->tx_max_coalesced_frames; - gmac->rx_coalesce_nsecs = ecmd->rx_coalesce_usecs * 1000; - - return 0; -} - -static u32 gmac_get_msglevel(struct net_device *dev) -{ - struct gmac_private *gmac = netdev_priv(dev); - return gmac->msg_enable; -} - -static void gmac_set_msglevel(struct net_device *dev, u32 level) -{ - struct gmac_private *gmac = netdev_priv(dev); - gmac->msg_enable = level; -} - -static void gmac_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, DRV_NAME); - strcpy(info->version, DRV_VERSION); - strcpy(info->bus_info, dev->dev_id ? "1" : "0"); -} - -static const struct net_device_ops gmac_351x_ops = { - .ndo_init = gmac_init, - .ndo_uninit = gmac_uninit, - .ndo_open = gmac_open, - .ndo_stop = gmac_stop, - .ndo_start_xmit = gmac_start_xmit, - .ndo_tx_timeout = gmac_tx_timeout, - .ndo_set_rx_mode = gmac_set_rx_mode, - .ndo_set_mac_address = gmac_set_mac_address, - .ndo_get_stats64 = gmac_get_stats64, - .ndo_change_mtu = gmac_change_mtu, - .ndo_fix_features = gmac_fix_features, - .ndo_set_features = gmac_set_features, -}; - -static const struct ethtool_ops gmac_351x_ethtool_ops = { - .get_sset_count = gmac_get_sset_count, - .get_strings = gmac_get_strings, - .get_ethtool_stats = gmac_get_ethtool_stats, - .get_settings = gmac_get_settings, - .set_settings = gmac_set_settings, - .get_link = ethtool_op_get_link, - .nway_reset = gmac_nway_reset, - .get_pauseparam = gmac_get_pauseparam, - .get_ringparam = gmac_get_ringparam, - .set_ringparam = gmac_set_ringparam, - .get_coalesce = gmac_get_coalesce, - .set_coalesce = gmac_set_coalesce, - .get_msglevel = gmac_get_msglevel, - .set_msglevel = gmac_set_msglevel, - .get_drvinfo = gmac_get_drvinfo, -}; - -static int gmac_init_netdev(struct toe_private *toe, int num, - struct platform_device *pdev) -{ - struct gemini_gmac_platform_data *pdata = pdev->dev.platform_data; - struct gmac_private *gmac; - struct net_device *dev; - int irq, err; - - if (!pdata->bus_id[num]) - return 0; - - irq = platform_get_irq(pdev, num); - if (irq < 0) { - dev_err(toe->dev, "No IRQ for ethernet device #%d\n", num); - return irq; - } - - dev = alloc_etherdev_mq(sizeof(*gmac), TX_QUEUE_NUM); - if (!dev) { - dev_err(toe->dev, "Can't allocate ethernet device #%d\n", num); - return -ENOMEM; - } - - gmac = netdev_priv(dev); - gmac->num = num; - gmac->toe = toe; - SET_NETDEV_DEV(dev, toe->dev); - - toe->netdev[num] = dev; - dev->dev_id = num; - - gmac->ctl_iomem = toe->iomem + TOE_GMAC_BASE(num); - gmac->dma_iomem = toe->iomem + TOE_GMAC_DMA_BASE(num); - dev->irq = irq; - - dev->netdev_ops = &gmac_351x_ops; - dev->ethtool_ops = &gmac_351x_ethtool_ops; - - spin_lock_init(&gmac->config_lock); - gmac_clear_hw_stats(dev); - - dev->hw_features = GMAC_OFFLOAD_FEATURES; - dev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; - - gmac->freeq_refill = 0; - netif_napi_add(dev, &gmac->napi, gmac_napi_poll, DEFAULT_NAPI_WEIGHT); - - if (is_valid_ether_addr((void *)toe->mac_addr[num])) - memcpy(dev->dev_addr, toe->mac_addr[num], ETH_ALEN); - else - random_ether_addr(dev->dev_addr); - __gmac_set_mac_address(dev); - - err = gmac_setup_phy(dev); - if (err) - netif_warn(gmac, probe, dev, - "PHY init failed: %d, deferring to ifup time\n", err); - - err = register_netdev(dev); - if (!err) - { - pr_info(DRV_NAME " %s: irq %d, dma base 0x%p, io base 0x%p\n", - dev->name, irq, gmac->dma_iomem, gmac->ctl_iomem); - return 0; - } - - toe->netdev[num] = NULL; - free_netdev(dev); - return err; -} - -static irqreturn_t toe_irq_thread(int irq, void *data) -{ - struct toe_private *toe = data; - void __iomem *irqen_reg = toe->iomem + GLOBAL_INTERRUPT_ENABLE_4_REG; - void __iomem *irqif_reg = toe->iomem + GLOBAL_INTERRUPT_STATUS_4_REG; - unsigned long irqmask = SWFQ_EMPTY_INT_BIT; - unsigned long flags; - - toe_fill_freeq(toe, 0); - - /* Ack and enable interrupt */ - spin_lock_irqsave(&toe->irq_lock, flags); - writel(irqmask, irqif_reg); - irqmask |= readl(irqen_reg); - writel(irqmask, irqen_reg); - spin_unlock_irqrestore(&toe->irq_lock, flags); - - return IRQ_HANDLED; -} - -static irqreturn_t toe_irq(int irq, void *data) -{ - struct toe_private *toe = data; - void __iomem *irqif_reg = toe->iomem + GLOBAL_INTERRUPT_STATUS_4_REG; - void __iomem *irqen_reg = toe->iomem + GLOBAL_INTERRUPT_ENABLE_4_REG; - unsigned long val, en; - irqreturn_t ret = IRQ_NONE; - - spin_lock(&toe->irq_lock); - - val = readl(irqif_reg); - en = readl(irqen_reg); - - if (val & en & SWFQ_EMPTY_INT_BIT) { - en &= ~(SWFQ_EMPTY_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT - | GMAC1_RX_OVERRUN_INT_BIT); - writel(en, irqen_reg); - ret = IRQ_WAKE_THREAD; - } - - spin_unlock(&toe->irq_lock); - return ret; -} - -static int toe_init(struct toe_private *toe, - struct platform_device *pdev) -{ - int err; - - writel(0, toe->iomem + GLOBAL_SW_FREEQ_BASE_SIZE_REG); - writel(0, toe->iomem + GLOBAL_HW_FREEQ_BASE_SIZE_REG); - writel(0, toe->iomem + GLOBAL_SWFQ_RWPTR_REG); - writel(0, toe->iomem + GLOBAL_HWFQ_RWPTR_REG); - - toe->freeq_frag_order = DEFAULT_RX_BUF_ORDER; - toe->freeq_order = ~0; - - err = request_threaded_irq(toe->irq, toe_irq, - toe_irq_thread, IRQF_SHARED, DRV_NAME " toe", toe); - if (err) - goto err_freeq; - - return 0; - -err_freeq: - toe_cleanup_freeq(toe); - return err; -} - -static void toe_deinit(struct toe_private *toe) -{ - free_irq(toe->irq, toe); - toe_cleanup_freeq(toe); -} - -static int toe_reset(struct toe_private *toe) -{ - unsigned int reg = 0, retry = 5; - - reg = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + - GLOBAL_RESET)); - reg |= RESET_GMAC1 | RESET_GMAC0; - writel(reg, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + - GLOBAL_RESET)); - - do { - udelay(2); - reg = readl((void __iomem*)(toe->iomem + - GLOBAL_TOE_VERSION_REG)); - barrier(); - } while (!reg && --retry); - - return reg ? 0 : -EIO; -} - -/* - * Interrupt config: - * - * GMAC0 intr bits ------> int0 ----> eth0 - * GMAC1 intr bits ------> int1 ----> eth1 - * TOE intr -------------> int1 ----> eth1 - * Classification Intr --> int0 ----> eth0 - * Default Q0 -----------> int0 ----> eth0 - * Default Q1 -----------> int1 ----> eth1 - * FreeQ intr -----------> int1 ----> eth1 - */ -static void toe_init_irq(struct toe_private *toe) -{ - writel(0, toe->iomem + GLOBAL_INTERRUPT_ENABLE_0_REG); - writel(0, toe->iomem + GLOBAL_INTERRUPT_ENABLE_1_REG); - writel(0, toe->iomem + GLOBAL_INTERRUPT_ENABLE_2_REG); - writel(0, toe->iomem + GLOBAL_INTERRUPT_ENABLE_3_REG); - writel(0, toe->iomem + GLOBAL_INTERRUPT_ENABLE_4_REG); - - writel(0xCCFC0FC0, toe->iomem + GLOBAL_INTERRUPT_SELECT_0_REG); - writel(0x00F00002, toe->iomem + GLOBAL_INTERRUPT_SELECT_1_REG); - writel(0xFFFFFFFF, toe->iomem + GLOBAL_INTERRUPT_SELECT_2_REG); - writel(0xFFFFFFFF, toe->iomem + GLOBAL_INTERRUPT_SELECT_3_REG); - writel(0xFF000003, toe->iomem + GLOBAL_INTERRUPT_SELECT_4_REG); - - /* edge-triggered interrupts packed to level-triggered one... */ - writel(~0, toe->iomem + GLOBAL_INTERRUPT_STATUS_0_REG); - writel(~0, toe->iomem + GLOBAL_INTERRUPT_STATUS_1_REG); - writel(~0, toe->iomem + GLOBAL_INTERRUPT_STATUS_2_REG); - writel(~0, toe->iomem + GLOBAL_INTERRUPT_STATUS_3_REG); - writel(~0, toe->iomem + GLOBAL_INTERRUPT_STATUS_4_REG); -} - -static void toe_save_mac_addr(struct toe_private *toe, - struct platform_device *pdev) -{ - struct gemini_gmac_platform_data *pdata = pdev->dev.platform_data; - void __iomem *ctl; - int i; - - for (i = 0; i < 2; i++) { - if (pdata->bus_id[i]) { - ctl = toe->iomem + TOE_GMAC_BASE(i); - toe->mac_addr[i][0] = cpu_to_le32(readl(ctl + GMAC_STA_ADD0)); - toe->mac_addr[i][1] = cpu_to_le32(readl(ctl + GMAC_STA_ADD1)); - toe->mac_addr[i][2] = cpu_to_le32(readl(ctl + GMAC_STA_ADD2)); - } - } -} - -static int gemini_gmac_probe(struct platform_device *pdev) -{ - struct resource *res; - struct toe_private *toe; - int irq, retval; - - if (!pdev->dev.platform_data) - return -EINVAL; - - irq = platform_get_irq(pdev, 1); - if (irq < 0) - return irq; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "can't get device resources\n"); - return -ENODEV; - } - - toe = kzalloc(sizeof(*toe), GFP_KERNEL); - if (!toe) - return -ENOMEM; - - platform_set_drvdata(pdev, toe); - toe->dev = &pdev->dev; - toe->irq = irq; - - toe->iomem = ioremap(res->start, resource_size(res)); - if (!toe->iomem) { - dev_err(toe->dev, "ioremap failed\n"); - retval = -EIO; - goto err_data; - } - - toe_save_mac_addr(toe, pdev); - - retval = toe_reset(toe); - if (retval < 0) - goto err_unmap; - - pr_info(DRV_NAME " toe: irq %d, io base 0x%08x, version %d\n", - irq, res->start, retval); - - spin_lock_init(&toe->irq_lock); - spin_lock_init(&toe->freeq_lock); - - toe_init_irq(toe); - - retval = toe_init(toe, pdev); - if (retval) - goto err_unmap; - - retval = gmac_init_netdev(toe, 0, pdev); - if (retval) - goto err_uninit; - - retval = gmac_init_netdev(toe, 1, pdev); - if (retval) - goto err_uninit; - - return 0; - -err_uninit: - if (toe->netdev[0]) - unregister_netdev(toe->netdev[0]); - toe_deinit(toe); -err_unmap: - iounmap(toe->iomem); -err_data: - kfree(toe); - return retval; -} - -static int gemini_gmac_remove(struct platform_device *pdev) -{ - struct toe_private *toe = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < 2; i++) - if (toe->netdev[i]) - unregister_netdev(toe->netdev[i]); - - toe_init_irq(toe); - toe_deinit(toe); - - iounmap(toe->iomem); - kfree(toe); - - return 0; -} - -static struct platform_driver gemini_gmac_driver = { - .probe = gemini_gmac_probe, - .remove = gemini_gmac_remove, - .driver.name = DRV_NAME, - .driver.owner = THIS_MODULE, -}; - -static int __init gemini_gmac_init(void) -{ -#ifdef CONFIG_MDIO_GPIO_MODULE - request_module("mdio-gpio"); -#endif - return platform_driver_register(&gemini_gmac_driver); -} - -static void __exit gemini_gmac_exit(void) -{ - platform_driver_unregister(&gemini_gmac_driver); -} - -module_init(gemini_gmac_init); -module_exit(gemini_gmac_exit); diff --git a/target/linux/gemini/files/drivers/net/ethernet/gemini/sl351x_hw.h b/target/linux/gemini/files/drivers/net/ethernet/gemini/sl351x_hw.h deleted file mode 100644 index f7bff5ace..000000000 --- a/target/linux/gemini/files/drivers/net/ethernet/gemini/sl351x_hw.h +++ /dev/null @@ -1,1436 +0,0 @@ -/* - * Register definitions for Gemini LEPUS GMAC Ethernet device driver. - * - * Copyright (C) 2006, Storlink, Corp. - * Copyright (C) 2008-2009, Paulius Zaleckas - * Copyright (C) 2010, MichaÅ‚ MirosÅ‚aw - * - * 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. - */ -#ifndef _GMAC_HW_H -#define _GMAC_HW_H - -#include - -/* - * Base Registers - */ -#define TOE_NONTOE_QUE_HDR_BASE 0x2000 -#define TOE_TOE_QUE_HDR_BASE 0x3000 -#define TOE_V_BIT_BASE 0x4000 -#define TOE_A_BIT_BASE 0x6000 -#define TOE_GMAC_DMA_BASE(x) (0x8000 + 0x4000 * (x)) -#define TOE_GMAC_BASE(x) (0xA000 + 0x4000 * (x)) - -/* - * Queue ID - */ -#define TOE_SW_FREE_QID 0x00 -#define TOE_HW_FREE_QID 0x01 -#define TOE_GMAC0_SW_TXQ0_QID 0x02 -#define TOE_GMAC0_SW_TXQ1_QID 0x03 -#define TOE_GMAC0_SW_TXQ2_QID 0x04 -#define TOE_GMAC0_SW_TXQ3_QID 0x05 -#define TOE_GMAC0_SW_TXQ4_QID 0x06 -#define TOE_GMAC0_SW_TXQ5_QID 0x07 -#define TOE_GMAC0_HW_TXQ0_QID 0x08 -#define TOE_GMAC0_HW_TXQ1_QID 0x09 -#define TOE_GMAC0_HW_TXQ2_QID 0x0A -#define TOE_GMAC0_HW_TXQ3_QID 0x0B -#define TOE_GMAC1_SW_TXQ0_QID 0x12 -#define TOE_GMAC1_SW_TXQ1_QID 0x13 -#define TOE_GMAC1_SW_TXQ2_QID 0x14 -#define TOE_GMAC1_SW_TXQ3_QID 0x15 -#define TOE_GMAC1_SW_TXQ4_QID 0x16 -#define TOE_GMAC1_SW_TXQ5_QID 0x17 -#define TOE_GMAC1_HW_TXQ0_QID 0x18 -#define TOE_GMAC1_HW_TXQ1_QID 0x19 -#define TOE_GMAC1_HW_TXQ2_QID 0x1A -#define TOE_GMAC1_HW_TXQ3_QID 0x1B -#define TOE_GMAC0_DEFAULT_QID 0x20 -#define TOE_GMAC1_DEFAULT_QID 0x21 -#define TOE_CLASSIFICATION_QID(x) (0x22 + x) /* 0x22 ~ 0x2F */ -#define TOE_TOE_QID(x) (0x40 + x) /* 0x40 ~ 0x7F */ - -/* - * old info: - * TOE DMA Queue Size should be 2^n, n = 6...12 - * TOE DMA Queues are the following queue types: - * SW Free Queue, HW Free Queue, - * GMAC 0/1 SW TX Q0-5, and GMAC 0/1 HW TX Q0-5 - * The base address and descriptor number are configured at - * DMA Queues Descriptor Ring Base Address/Size Register (offset 0x0004) - */ - -#define GET_WPTR(addr) __raw_readw((addr) + 2) -#define GET_RPTR(addr) __raw_readw((addr)) -#define SET_WPTR(addr, data) __raw_writew((data), (addr) + 2) -#define SET_RPTR(addr, data) __raw_writew((data), (addr)) -#define __RWPTR_NEXT(x, mask) (((unsigned int)(x) + 1) & (mask)) -#define __RWPTR_PREV(x, mask) (((unsigned int)(x) - 1) & (mask)) -#define __RWPTR_DISTANCE(r, w, mask) (((unsigned int)(w) - (r)) & (mask)) -#define __RWPTR_MASK(order) ((1 << (order)) - 1) -#define RWPTR_NEXT(x, order) __RWPTR_NEXT((x), __RWPTR_MASK((order))) -#define RWPTR_PREV(x, order) __RWPTR_PREV((x), __RWPTR_MASK((order))) -#define RWPTR_DISTANCE(r, w, order) __RWPTR_DISTANCE((r), (w), \ - __RWPTR_MASK((order))) - -/* - * Global registers - * #define TOE_GLOBAL_BASE (TOE_BASE + 0x0000) - * Base 0x60000000 - */ -#define GLOBAL_TOE_VERSION_REG 0x0000 -#define GLOBAL_SW_FREEQ_BASE_SIZE_REG 0x0004 -#define GLOBAL_HW_FREEQ_BASE_SIZE_REG 0x0008 -#define GLOBAL_DMA_SKB_SIZE_REG 0x0010 -#define GLOBAL_SWFQ_RWPTR_REG 0x0014 -#define GLOBAL_HWFQ_RWPTR_REG 0x0018 -#define GLOBAL_INTERRUPT_STATUS_0_REG 0x0020 -#define GLOBAL_INTERRUPT_ENABLE_0_REG 0x0024 -#define GLOBAL_INTERRUPT_SELECT_0_REG 0x0028 -#define GLOBAL_INTERRUPT_STATUS_1_REG 0x0030 -#define GLOBAL_INTERRUPT_ENABLE_1_REG 0x0034 -#define GLOBAL_INTERRUPT_SELECT_1_REG 0x0038 -#define GLOBAL_INTERRUPT_STATUS_2_REG 0x0040 -#define GLOBAL_INTERRUPT_ENABLE_2_REG 0x0044 -#define GLOBAL_INTERRUPT_SELECT_2_REG 0x0048 -#define GLOBAL_INTERRUPT_STATUS_3_REG 0x0050 -#define GLOBAL_INTERRUPT_ENABLE_3_REG 0x0054 -#define GLOBAL_INTERRUPT_SELECT_3_REG 0x0058 -#define GLOBAL_INTERRUPT_STATUS_4_REG 0x0060 -#define GLOBAL_INTERRUPT_ENABLE_4_REG 0x0064 -#define GLOBAL_INTERRUPT_SELECT_4_REG 0x0068 -#define GLOBAL_HASH_TABLE_BASE_REG 0x006C -#define GLOBAL_QUEUE_THRESHOLD_REG 0x0070 - -/* - * GMAC 0/1 DMA/TOE register - * #define TOE_GMAC0_DMA_BASE (TOE_BASE + 0x8000) - * #define TOE_GMAC1_DMA_BASE (TOE_BASE + 0xC000) - * Base 0x60008000 or 0x6000C000 - */ -#define GMAC_DMA_CTRL_REG 0x0000 -#define GMAC_TX_WEIGHTING_CTRL_0_REG 0x0004 -#define GMAC_TX_WEIGHTING_CTRL_1_REG 0x0008 -#define GMAC_SW_TX_QUEUE0_PTR_REG 0x000C -#define GMAC_SW_TX_QUEUE1_PTR_REG 0x0010 -#define GMAC_SW_TX_QUEUE2_PTR_REG 0x0014 -#define GMAC_SW_TX_QUEUE3_PTR_REG 0x0018 -#define GMAC_SW_TX_QUEUE4_PTR_REG 0x001C -#define GMAC_SW_TX_QUEUE5_PTR_REG 0x0020 -#define GMAC_SW_TX_QUEUE_PTR_REG(i) (GMAC_SW_TX_QUEUE0_PTR_REG + 4 * (i)) -#define GMAC_HW_TX_QUEUE0_PTR_REG 0x0024 -#define GMAC_HW_TX_QUEUE1_PTR_REG 0x0028 -#define GMAC_HW_TX_QUEUE2_PTR_REG 0x002C -#define GMAC_HW_TX_QUEUE3_PTR_REG 0x0030 -#define GMAC_HW_TX_QUEUE_PTR_REG(i) (GMAC_HW_TX_QUEUE0_PTR_REG + 4 * (i)) -#define GMAC_DMA_TX_FIRST_DESC_REG 0x0038 -#define GMAC_DMA_TX_CURR_DESC_REG 0x003C -#define GMAC_DMA_TX_DESC_WORD0_REG 0x0040 -#define GMAC_DMA_TX_DESC_WORD1_REG 0x0044 -#define GMAC_DMA_TX_DESC_WORD2_REG 0x0048 -#define GMAC_DMA_TX_DESC_WORD3_REG 0x004C -#define GMAC_SW_TX_QUEUE_BASE_REG 0x0050 -#define GMAC_HW_TX_QUEUE_BASE_REG 0x0054 -#define GMAC_DMA_RX_FIRST_DESC_REG 0x0058 -#define GMAC_DMA_RX_CURR_DESC_REG 0x005C -#define GMAC_DMA_RX_DESC_WORD0_REG 0x0060 -#define GMAC_DMA_RX_DESC_WORD1_REG 0x0064 -#define GMAC_DMA_RX_DESC_WORD2_REG 0x0068 -#define GMAC_DMA_RX_DESC_WORD3_REG 0x006C -#define GMAC_HASH_ENGINE_REG0 0x0070 -#define GMAC_HASH_ENGINE_REG1 0x0074 -/* matching rule 0 Control register 0 */ -#define GMAC_MR0CR0 0x0078 -#define GMAC_MR0CR1 0x007C -#define GMAC_MR0CR2 0x0080 -#define GMAC_MR1CR0 0x0084 -#define GMAC_MR1CR1 0x0088 -#define GMAC_MR1CR2 0x008C -#define GMAC_MR2CR0 0x0090 -#define GMAC_MR2CR1 0x0094 -#define GMAC_MR2CR2 0x0098 -#define GMAC_MR3CR0 0x009C -#define GMAC_MR3CR1 0x00A0 -#define GMAC_MR3CR2 0x00A4 -/* Support Protocol Regsister 0 */ -#define GMAC_SPR0 0x00A8 -#define GMAC_SPR1 0x00AC -#define GMAC_SPR2 0x00B0 -#define GMAC_SPR3 0x00B4 -#define GMAC_SPR4 0x00B8 -#define GMAC_SPR5 0x00BC -#define GMAC_SPR6 0x00C0 -#define GMAC_SPR7 0x00C4 -/* GMAC Hash/Rx/Tx AHB Weighting register */ -#define GMAC_AHB_WEIGHT_REG 0x00C8 - -/* - * TOE GMAC 0/1 register - * #define TOE_GMAC0_BASE (TOE_BASE + 0xA000) - * #define TOE_GMAC1_BASE (TOE_BASE + 0xE000) - * Base 0x6000A000 or 0x6000E000 - */ -enum GMAC_REGISTER { - GMAC_STA_ADD0 = 0x0000, - GMAC_STA_ADD1 = 0x0004, - GMAC_STA_ADD2 = 0x0008, - GMAC_RX_FLTR = 0x000c, - GMAC_MCAST_FIL0 = 0x0010, - GMAC_MCAST_FIL1 = 0x0014, - GMAC_CONFIG0 = 0x0018, - GMAC_CONFIG1 = 0x001c, - GMAC_CONFIG2 = 0x0020, - GMAC_CONFIG3 = 0x0024, - GMAC_RESERVED = 0x0028, - GMAC_STATUS = 0x002c, - GMAC_IN_DISCARDS= 0x0030, - GMAC_IN_ERRORS = 0x0034, - GMAC_IN_MCAST = 0x0038, - GMAC_IN_BCAST = 0x003c, - GMAC_IN_MAC1 = 0x0040, /* for STA 1 MAC Address */ - GMAC_IN_MAC2 = 0x0044 /* for STA 2 MAC Address */ -}; - -#define RX_STATS_NUM 6 - -/* - * DMA Queues description Ring Base Address/Size Register (offset 0x0004) - */ -typedef union { - unsigned int bits32; - unsigned int base_size; -} DMA_Q_BASE_SIZE_T; -#define DMA_Q_BASE_MASK (~0x0f) - -/* - * DMA SKB Buffer register (offset 0x0008) - */ -typedef union { - unsigned int bits32; - struct bit_0008 { - unsigned int sw_skb_size : 16; /* SW Free poll SKB Size */ - unsigned int hw_skb_size : 16; /* HW Free poll SKB Size */ - } bits; -} DMA_SKB_SIZE_T; - -/* - * DMA SW Free Queue Read/Write Pointer Register (offset 0x000C) - */ -typedef union { - unsigned int bits32; - struct bit_000c { - unsigned int rptr : 16; /* Read Ptr, RO */ - unsigned int wptr : 16; /* Write Ptr, RW */ - } bits; -} DMA_RWPTR_T; - -/* - * DMA HW Free Queue Read/Write Pointer Register (offset 0x0010) - * see DMA_RWPTR_T structure - */ - -/* - * Interrupt Status Register 0 (offset 0x0020) - * Interrupt Mask Register 0 (offset 0x0024) - * Interrupt Select Register 0 (offset 0x0028) - */ -typedef union { - unsigned int bits32; - struct bit_0020 { - /* GMAC0 SW Tx Queue 0 EOF Interrupt */ - unsigned int swtq00_eof : 1; - unsigned int swtq01_eof : 1; - unsigned int swtq02_eof : 1; - unsigned int swtq03_eof : 1; - unsigned int swtq04_eof : 1; - unsigned int swtq05_eof : 1; - /* GMAC1 SW Tx Queue 0 EOF Interrupt */ - unsigned int swtq10_eof : 1; - unsigned int swtq11_eof : 1; - unsigned int swtq12_eof : 1; - unsigned int swtq13_eof : 1; - unsigned int swtq14_eof : 1; - unsigned int swtq15_eof : 1; - /* GMAC0 SW Tx Queue 0 Finish Interrupt */ - unsigned int swtq00_fin : 1; - unsigned int swtq01_fin : 1; - unsigned int swtq02_fin : 1; - unsigned int swtq03_fin : 1; - unsigned int swtq04_fin : 1; - unsigned int swtq05_fin : 1; - /* GMAC1 SW Tx Queue 0 Finish Interrupt */ - unsigned int swtq10_fin : 1; - unsigned int swtq11_fin : 1; - unsigned int swtq12_fin : 1; - unsigned int swtq13_fin : 1; - unsigned int swtq14_fin : 1; - unsigned int swtq15_fin : 1; - /* GMAC0 Rx Descriptor Protocol Error */ - unsigned int rxPerr0 : 1; - /* GMAC0 AHB Bus Error while Rx */ - unsigned int rxDerr0 : 1; - /* GMAC1 Rx Descriptor Protocol Error */ - unsigned int rxPerr1 : 1; - /* GMAC1 AHB Bus Error while Rx */ - unsigned int rxDerr1 : 1; - /* GMAC0 Tx Descriptor Protocol Error */ - unsigned int txPerr0 : 1; - /* GMAC0 AHB Bus Error while Tx */ - unsigned int txDerr0 : 1; - /* GMAC1 Tx Descriptor Protocol Error */ - unsigned int txPerr1 : 1; - /* GMAC1 AHB Bus Error while Tx */ - unsigned int txDerr1 : 1; - } bits; -} INTR_REG0_T; - -#define GMAC1_TXDERR_INT_BIT BIT(31) -#define GMAC1_TXPERR_INT_BIT BIT(30) -#define GMAC0_TXDERR_INT_BIT BIT(29) -#define GMAC0_TXPERR_INT_BIT BIT(28) -#define GMAC1_RXDERR_INT_BIT BIT(27) -#define GMAC1_RXPERR_INT_BIT BIT(26) -#define GMAC0_RXDERR_INT_BIT BIT(25) -#define GMAC0_RXPERR_INT_BIT BIT(24) -#define GMAC1_SWTQ15_FIN_INT_BIT BIT(23) -#define GMAC1_SWTQ14_FIN_INT_BIT BIT(22) -#define GMAC1_SWTQ13_FIN_INT_BIT BIT(21) -#define GMAC1_SWTQ12_FIN_INT_BIT BIT(20) -#define GMAC1_SWTQ11_FIN_INT_BIT BIT(19) -#define GMAC1_SWTQ10_FIN_INT_BIT BIT(18) -#define GMAC0_SWTQ05_FIN_INT_BIT BIT(17) -#define GMAC0_SWTQ04_FIN_INT_BIT BIT(16) -#define GMAC0_SWTQ03_FIN_INT_BIT BIT(15) -#define GMAC0_SWTQ02_FIN_INT_BIT BIT(14) -#define GMAC0_SWTQ01_FIN_INT_BIT BIT(13) -#define GMAC0_SWTQ00_FIN_INT_BIT BIT(12) -#define GMAC1_SWTQ15_EOF_INT_BIT BIT(11) -#define GMAC1_SWTQ14_EOF_INT_BIT BIT(10) -#define GMAC1_SWTQ13_EOF_INT_BIT BIT(9) -#define GMAC1_SWTQ12_EOF_INT_BIT BIT(8) -#define GMAC1_SWTQ11_EOF_INT_BIT BIT(7) -#define GMAC1_SWTQ10_EOF_INT_BIT BIT(6) -#define GMAC0_SWTQ05_EOF_INT_BIT BIT(5) -#define GMAC0_SWTQ04_EOF_INT_BIT BIT(4) -#define GMAC0_SWTQ03_EOF_INT_BIT BIT(3) -#define GMAC0_SWTQ02_EOF_INT_BIT BIT(2) -#define GMAC0_SWTQ01_EOF_INT_BIT BIT(1) -#define GMAC0_SWTQ00_EOF_INT_BIT BIT(0) - -/* - * Interrupt Status Register 1 (offset 0x0030) - * Interrupt Mask Register 1 (offset 0x0034) - * Interrupt Select Register 1 (offset 0x0038) - */ -typedef union { - unsigned int bits32; - struct bit_0030 { - unsigned int default_q0_eof : 1; /* Default Queue 0 EOF Interrupt */ - unsigned int default_q1_eof : 1; /* Default Queue 1 EOF Interrupt */ - unsigned int class_rx : 14; /* Classification Queue Rx Interrupt */ - unsigned int hwtq00_eof : 1; /* GMAC0 HW Tx Queue0 EOF Interrupt */ - unsigned int hwtq01_eof : 1; /* GMAC0 HW Tx Queue1 EOF Interrupt */ - unsigned int hwtq02_eof : 1; /* GMAC0 HW Tx Queue2 EOF Interrupt */ - unsigned int hwtq03_eof : 1; /* GMAC0 HW Tx Queue3 EOF Interrupt */ - unsigned int hwtq10_eof : 1; /* GMAC1 HW Tx Queue0 EOF Interrupt */ - unsigned int hwtq11_eof : 1; /* GMAC1 HW Tx Queue1 EOF Interrupt */ - unsigned int hwtq12_eof : 1; /* GMAC1 HW Tx Queue2 EOF Interrupt */ - unsigned int hwtq13_eof : 1; /* GMAC1 HW Tx Queue3 EOF Interrupt */ - unsigned int toe_iq0_intr : 1; /* TOE Interrupt Queue 0 with Interrupts */ - unsigned int toe_iq1_intr : 1; /* TOE Interrupt Queue 1 with Interrupts */ - unsigned int toe_iq2_intr : 1; /* TOE Interrupt Queue 2 with Interrupts */ - unsigned int toe_iq3_intr : 1; /* TOE Interrupt Queue 3 with Interrupts */ - unsigned int toe_iq0_full : 1; /* TOE Interrupt Queue 0 Full Interrupt */ - unsigned int toe_iq1_full : 1; /* TOE Interrupt Queue 1 Full Interrupt */ - unsigned int toe_iq2_full : 1; /* TOE Interrupt Queue 2 Full Interrupt */ - unsigned int toe_iq3_full : 1; /* TOE Interrupt Queue 3 Full Interrupt */ - } bits; -} INTR_REG1_T; - -#define TOE_IQ3_FULL_INT_BIT BIT(31) -#define TOE_IQ2_FULL_INT_BIT BIT(30) -#define TOE_IQ1_FULL_INT_BIT BIT(29) -#define TOE_IQ0_FULL_INT_BIT BIT(28) -#define TOE_IQ3_INT_BIT BIT(27) -#define TOE_IQ2_INT_BIT BIT(26) -#define TOE_IQ1_INT_BIT BIT(25) -#define TOE_IQ0_INT_BIT BIT(24) -#define GMAC1_HWTQ13_EOF_INT_BIT BIT(23) -#define GMAC1_HWTQ12_EOF_INT_BIT BIT(22) -#define GMAC1_HWTQ11_EOF_INT_BIT BIT(21) -#define GMAC1_HWTQ10_EOF_INT_BIT BIT(20) -#define GMAC0_HWTQ03_EOF_INT_BIT BIT(19) -#define GMAC0_HWTQ02_EOF_INT_BIT BIT(18) -#define GMAC0_HWTQ01_EOF_INT_BIT BIT(17) -#define GMAC0_HWTQ00_EOF_INT_BIT BIT(16) -#define CLASS_RX_INT_BIT(x) BIT((x + 2)) -#define DEFAULT_Q1_INT_BIT BIT(1) -#define DEFAULT_Q0_INT_BIT BIT(0) - -#define TOE_IQ_INT_BITS (TOE_IQ0_INT_BIT | TOE_IQ1_INT_BIT | \ - TOE_IQ2_INT_BIT | TOE_IQ3_INT_BIT) -#define TOE_IQ_FULL_BITS (TOE_IQ0_FULL_INT_BIT | TOE_IQ1_FULL_INT_BIT | \ - TOE_IQ2_FULL_INT_BIT | TOE_IQ3_FULL_INT_BIT) -#define TOE_IQ_ALL_BITS (TOE_IQ_INT_BITS | TOE_IQ_FULL_BITS) -#define TOE_CLASS_RX_INT_BITS 0xfffc - -/* - * Interrupt Status Register 2 (offset 0x0040) - * Interrupt Mask Register 2 (offset 0x0044) - * Interrupt Select Register 2 (offset 0x0048) - */ -typedef union { - unsigned int bits32; - struct bit_0040 { - unsigned int toe_q0_full : 1; /* bit 0 TOE Queue 0 Full Interrupt */ - unsigned int toe_q1_full : 1; /* bit 1 TOE Queue 1 Full Interrupt */ - unsigned int toe_q2_full : 1; /* bit 2 TOE Queue 2 Full Interrupt */ - unsigned int toe_q3_full : 1; /* bit 3 TOE Queue 3 Full Interrupt */ - unsigned int toe_q4_full : 1; /* bit 4 TOE Queue 4 Full Interrupt */ - unsigned int toe_q5_full : 1; /* bit 5 TOE Queue 5 Full Interrupt */ - unsigned int toe_q6_full : 1; /* bit 6 TOE Queue 6 Full Interrupt */ - unsigned int toe_q7_full : 1; /* bit 7 TOE Queue 7 Full Interrupt */ - unsigned int toe_q8_full : 1; /* bit 8 TOE Queue 8 Full Interrupt */ - unsigned int toe_q9_full : 1; /* bit 9 TOE Queue 9 Full Interrupt */ - unsigned int toe_q10_full : 1; /* bit 10 TOE Queue 10 Full Interrupt */ - unsigned int toe_q11_full : 1; /* bit 11 TOE Queue 11 Full Interrupt */ - unsigned int toe_q12_full : 1; /* bit 12 TOE Queue 12 Full Interrupt */ - unsigned int toe_q13_full : 1; /* bit 13 TOE Queue 13 Full Interrupt */ - unsigned int toe_q14_full : 1; /* bit 14 TOE Queue 14 Full Interrupt */ - unsigned int toe_q15_full : 1; /* bit 15 TOE Queue 15 Full Interrupt */ - unsigned int toe_q16_full : 1; /* bit 16 TOE Queue 16 Full Interrupt */ - unsigned int toe_q17_full : 1; /* bit 17 TOE Queue 17 Full Interrupt */ - unsigned int toe_q18_full : 1; /* bit 18 TOE Queue 18 Full Interrupt */ - unsigned int toe_q19_full : 1; /* bit 19 TOE Queue 19 Full Interrupt */ - unsigned int toe_q20_full : 1; /* bit 20 TOE Queue 20 Full Interrupt */ - unsigned int toe_q21_full : 1; /* bit 21 TOE Queue 21 Full Interrupt */ - unsigned int toe_q22_full : 1; /* bit 22 TOE Queue 22 Full Interrupt */ - unsigned int toe_q23_full : 1; /* bit 23 TOE Queue 23 Full Interrupt */ - unsigned int toe_q24_full : 1; /* bit 24 TOE Queue 24 Full Interrupt */ - unsigned int toe_q25_full : 1; /* bit 25 TOE Queue 25 Full Interrupt */ - unsigned int toe_q26_full : 1; /* bit 26 TOE Queue 26 Full Interrupt */ - unsigned int toe_q27_full : 1; /* bit 27 TOE Queue 27 Full Interrupt */ - unsigned int toe_q28_full : 1; /* bit 28 TOE Queue 28 Full Interrupt */ - unsigned int toe_q29_full : 1; /* bit 29 TOE Queue 29 Full Interrupt */ - unsigned int toe_q30_full : 1; /* bit 30 TOE Queue 30 Full Interrupt */ - unsigned int toe_q31_full : 1; /* bit 31 TOE Queue 31 Full Interrupt */ - } bits; -} INTR_REG2_T; - -#define TOE_QL_FULL_INT_BIT(x) BIT(x) - -/* - * Interrupt Status Register 3 (offset 0x0050) - * Interrupt Mask Register 3 (offset 0x0054) - * Interrupt Select Register 3 (offset 0x0058) - */ -typedef union { - unsigned int bits32; - struct bit_0050 { - unsigned int toe_q32_full : 1; /* bit 32 TOE Queue 32 Full Interrupt */ - unsigned int toe_q33_full : 1; /* bit 33 TOE Queue 33 Full Interrupt */ - unsigned int toe_q34_full : 1; /* bit 34 TOE Queue 34 Full Interrupt */ - unsigned int toe_q35_full : 1; /* bit 35 TOE Queue 35 Full Interrupt */ - unsigned int toe_q36_full : 1; /* bit 36 TOE Queue 36 Full Interrupt */ - unsigned int toe_q37_full : 1; /* bit 37 TOE Queue 37 Full Interrupt */ - unsigned int toe_q38_full : 1; /* bit 38 TOE Queue 38 Full Interrupt */ - unsigned int toe_q39_full : 1; /* bit 39 TOE Queue 39 Full Interrupt */ - unsigned int toe_q40_full : 1; /* bit 40 TOE Queue 40 Full Interrupt */ - unsigned int toe_q41_full : 1; /* bit 41 TOE Queue 41 Full Interrupt */ - unsigned int toe_q42_full : 1; /* bit 42 TOE Queue 42 Full Interrupt */ - unsigned int toe_q43_full : 1; /* bit 43 TOE Queue 43 Full Interrupt */ - unsigned int toe_q44_full : 1; /* bit 44 TOE Queue 44 Full Interrupt */ - unsigned int toe_q45_full : 1; /* bit 45 TOE Queue 45 Full Interrupt */ - unsigned int toe_q46_full : 1; /* bit 46 TOE Queue 46 Full Interrupt */ - unsigned int toe_q47_full : 1; /* bit 47 TOE Queue 47 Full Interrupt */ - unsigned int toe_q48_full : 1; /* bit 48 TOE Queue 48 Full Interrupt */ - unsigned int toe_q49_full : 1; /* bit 49 TOE Queue 49 Full Interrupt */ - unsigned int toe_q50_full : 1; /* bit 50 TOE Queue 50 Full Interrupt */ - unsigned int toe_q51_full : 1; /* bit 51 TOE Queue 51 Full Interrupt */ - unsigned int toe_q52_full : 1; /* bit 52 TOE Queue 52 Full Interrupt */ - unsigned int toe_q53_full : 1; /* bit 53 TOE Queue 53 Full Interrupt */ - unsigned int toe_q54_full : 1; /* bit 54 TOE Queue 54 Full Interrupt */ - unsigned int toe_q55_full : 1; /* bit 55 TOE Queue 55 Full Interrupt */ - unsigned int toe_q56_full : 1; /* bit 56 TOE Queue 56 Full Interrupt */ - unsigned int toe_q57_full : 1; /* bit 57 TOE Queue 57 Full Interrupt */ - unsigned int toe_q58_full : 1; /* bit 58 TOE Queue 58 Full Interrupt */ - unsigned int toe_q59_full : 1; /* bit 59 TOE Queue 59 Full Interrupt */ - unsigned int toe_q60_full : 1; /* bit 60 TOE Queue 60 Full Interrupt */ - unsigned int toe_q61_full : 1; /* bit 61 TOE Queue 61 Full Interrupt */ - unsigned int toe_q62_full : 1; /* bit 62 TOE Queue 62 Full Interrupt */ - unsigned int toe_q63_full : 1; /* bit 63 TOE Queue 63 Full Interrupt */ - } bits; -} INTR_REG3_T; - -#define TOE_QH_FULL_INT_BIT(x) BIT(x-32) - -/* - * Interrupt Status Register 4 (offset 0x0060) - * Interrupt Mask Register 4 (offset 0x0064) - * Interrupt Select Register 4 (offset 0x0068) - */ -typedef union { - unsigned char byte; - struct bit_0060 { - unsigned char status_changed : 1; /* Status Changed Intr for RGMII Mode */ - unsigned char rx_overrun : 1; /* GMAC Rx FIFO overrun interrupt */ - unsigned char tx_pause_off : 1; /* received pause off frame interrupt */ - unsigned char rx_pause_off : 1; /* received pause off frame interrupt */ - unsigned char tx_pause_on : 1; /* transmit pause on frame interrupt */ - unsigned char rx_pause_on : 1; /* received pause on frame interrupt */ - unsigned char cnt_full : 1; /* MIB counters half full interrupt */ - unsigned char reserved : 1; /* */ - } __packed bits; -} __packed GMAC_INTR_T; - -typedef union { - unsigned int bits32; - struct bit_0060_2 { - unsigned int swfq_empty : 1; /* bit 0 Software Free Queue Empty Intr. */ - unsigned int hwfq_empty : 1; /* bit 1 Hardware Free Queue Empty Intr. */ - unsigned int class_qf_int : 14; /* bit 15:2 Classification Rx Queue13-0 Full Intr. */ - GMAC_INTR_T gmac0; - GMAC_INTR_T gmac1; - } bits; -} INTR_REG4_T; - -#define GMAC1_RESERVED_INT_BIT BIT(31) -#define GMAC1_MIB_INT_BIT BIT(30) -#define GMAC1_RX_PAUSE_ON_INT_BIT BIT(29) -#define GMAC1_TX_PAUSE_ON_INT_BIT BIT(28) -#define GMAC1_RX_PAUSE_OFF_INT_BIT BIT(27) -#define GMAC1_TX_PAUSE_OFF_INT_BIT BIT(26) -#define GMAC1_RX_OVERRUN_INT_BIT BIT(25) -#define GMAC1_STATUS_CHANGE_INT_BIT BIT(24) -#define GMAC0_RESERVED_INT_BIT BIT(23) -#define GMAC0_MIB_INT_BIT BIT(22) -#define GMAC0_RX_PAUSE_ON_INT_BIT BIT(21) -#define GMAC0_TX_PAUSE_ON_INT_BIT BIT(20) -#define GMAC0_RX_PAUSE_OFF_INT_BIT BIT(19) -#define GMAC0_TX_PAUSE_OFF_INT_BIT BIT(18) -#define GMAC0_RX_OVERRUN_INT_BIT BIT(17) -#define GMAC0_STATUS_CHANGE_INT_BIT BIT(16) -#define CLASS_RX_FULL_INT_BIT(x) BIT((x+2)) -#define HWFQ_EMPTY_INT_BIT BIT(1) -#define SWFQ_EMPTY_INT_BIT BIT(0) - -#define GMAC0_INT_BITS (GMAC0_RESERVED_INT_BIT | GMAC0_MIB_INT_BIT | \ - GMAC0_RX_PAUSE_ON_INT_BIT | GMAC0_TX_PAUSE_ON_INT_BIT | \ - GMAC0_RX_PAUSE_OFF_INT_BIT | GMAC0_TX_PAUSE_OFF_INT_BIT | \ - GMAC0_RX_OVERRUN_INT_BIT | GMAC0_STATUS_CHANGE_INT_BIT) -#define GMAC1_INT_BITS (GMAC1_RESERVED_INT_BIT | GMAC1_MIB_INT_BIT | \ - GMAC1_RX_PAUSE_ON_INT_BIT | GMAC1_TX_PAUSE_ON_INT_BIT | \ - GMAC1_RX_PAUSE_OFF_INT_BIT | GMAC1_TX_PAUSE_OFF_INT_BIT | \ - GMAC1_RX_OVERRUN_INT_BIT | GMAC1_STATUS_CHANGE_INT_BIT) - -#define CLASS_RX_FULL_INT_BITS 0xfffc - -/* - * GLOBAL_QUEUE_THRESHOLD_REG (offset 0x0070) - */ -typedef union { - unsigned int bits32; - struct bit_0070_2 { - unsigned int swfq_empty : 8; /* 7:0 Software Free Queue Empty Threshold */ - unsigned int hwfq_empty : 8; /* 15:8 Hardware Free Queue Empty Threshold */ - unsigned int intrq : 8; /* 23:16 */ - unsigned int toe_class : 8; /* 31:24 */ - } bits; -} QUEUE_THRESHOLD_T; - - -/* - * GMAC DMA Control Register - * GMAC0 offset 0x8000 - * GMAC1 offset 0xC000 - */ -typedef union { - unsigned int bits32; - struct bit_8000 { - unsigned int td_bus : 2; /* bit 1:0 Peripheral Bus Width */ - unsigned int td_burst_size : 2; /* bit 3:2 TxDMA max burst size for every AHB request */ - unsigned int td_prot : 4; /* bit 7:4 TxDMA protection control */ - unsigned int rd_bus : 2; /* bit 9:8 Peripheral Bus Width */ - unsigned int rd_burst_size : 2; /* bit 11:10 DMA max burst size for every AHB request */ - unsigned int rd_prot : 4; /* bit 15:12 DMA Protection Control */ - unsigned int rd_insert_bytes : 2; /* bit 17:16 */ - unsigned int reserved : 10; /* bit 27:18 */ - unsigned int drop_small_ack : 1; /* bit 28 1: Drop, 0: Accept */ - unsigned int loopback : 1; /* bit 29 Loopback TxDMA to RxDMA */ - unsigned int td_enable : 1; /* bit 30 Tx DMA Enable */ - unsigned int rd_enable : 1; /* bit 31 Rx DMA Enable */ - } bits; -} GMAC_DMA_CTRL_T; - -/* - * GMAC Tx Weighting Control Register 0 - * GMAC0 offset 0x8004 - * GMAC1 offset 0xC004 - */ -typedef union { - unsigned int bits32; - struct bit_8004 { - unsigned int hw_tq0 : 6; /* bit 5:0 HW TX Queue 3 */ - unsigned int hw_tq1 : 6; /* bit 11:6 HW TX Queue 2 */ - unsigned int hw_tq2 : 6; /* bit 17:12 HW TX Queue 1 */ - unsigned int hw_tq3 : 6; /* bit 23:18 HW TX Queue 0 */ - unsigned int reserved : 8; /* bit 31:24 */ - } bits; -} GMAC_TX_WCR0_T; /* Weighting Control Register 0 */ - -/* - * GMAC Tx Weighting Control Register 1 - * GMAC0 offset 0x8008 - * GMAC1 offset 0xC008 - */ -typedef union { - unsigned int bits32; - struct bit_8008 { - unsigned int sw_tq0 : 5; /* bit 4:0 SW TX Queue 0 */ - unsigned int sw_tq1 : 5; /* bit 9:5 SW TX Queue 1 */ - unsigned int sw_tq2 : 5; /* bit 14:10 SW TX Queue 2 */ - unsigned int sw_tq3 : 5; /* bit 19:15 SW TX Queue 3 */ - unsigned int sw_tq4 : 5; /* bit 24:20 SW TX Queue 4 */ - unsigned int sw_tq5 : 5; /* bit 29:25 SW TX Queue 5 */ - unsigned int reserved : 2; /* bit 31:30 */ - } bits; -} GMAC_TX_WCR1_T; /* Weighting Control Register 1 */ - -/* - * Queue Read/Write Pointer - * GMAC SW TX Queue 0~5 Read/Write Pointer register - * GMAC0 offset 0x800C ~ 0x8020 - * GMAC1 offset 0xC00C ~ 0xC020 - * GMAC HW TX Queue 0~3 Read/Write Pointer register - * GMAC0 offset 0x8024 ~ 0x8030 - * GMAC1 offset 0xC024 ~ 0xC030 - * - * see DMA_RWPTR_T structure - */ - -/* - * GMAC DMA Tx First Description Address Register - * GMAC0 offset 0x8038 - * GMAC1 offset 0xC038 - */ -typedef union { - unsigned int bits32; - struct bit_8038 { - unsigned int reserved : 3; - unsigned int td_busy : 1; /* bit 3 1: TxDMA busy; 0: TxDMA idle */ - unsigned int td_first_des_ptr : 28; /* bit 31:4 first descriptor address */ - } bits; -} GMAC_TXDMA_FIRST_DESC_T; - -/* - * GMAC DMA Tx Current Description Address Register - * GMAC0 offset 0x803C - * GMAC1 offset 0xC03C - */ -typedef union { - unsigned int bits32; - struct bit_803C { - unsigned int reserved : 4; - unsigned int td_curr_desc_ptr : 28; /* bit 31:4 current descriptor address */ - } bits; -} GMAC_TXDMA_CURR_DESC_T; - -/* - * GMAC DMA Tx Description Word 0 Register - * GMAC0 offset 0x8040 - * GMAC1 offset 0xC040 - */ -typedef union { - unsigned int bits32; - struct bit_8040 { - unsigned int buffer_size : 16; /* bit 15:0 Transfer size */ - unsigned int desc_count : 6; /* bit 21:16 number of descriptors used for the current frame */ - unsigned int status_tx_ok : 1; /* bit 22 Tx Status, 1: Successful 0: Failed */ - unsigned int status_rvd : 6; /* bit 28:23 Tx Status, Reserved bits */ - unsigned int perr : 1; /* bit 29 protocol error during processing this descriptor */ - unsigned int derr : 1; /* bit 30 data error during processing this descriptor */ - unsigned int reserved : 1; /* bit 31 */ - } bits; -} GMAC_TXDESC_0_T; - -/* - * GMAC DMA Tx Description Word 1 Register - * GMAC0 offset 0x8044 - * GMAC1 offset 0xC044 - */ -typedef union { - unsigned int bits32; - struct txdesc_word1 { - unsigned int byte_count : 16; /* bit 15: 0 Tx Frame Byte Count */ - unsigned int mtu_enable : 1; /* bit 16 TSS segmentation use MTU setting */ - unsigned int ip_chksum : 1; /* bit 17 IPV4 Header Checksum Enable */ - unsigned int ipv6_enable : 1; /* bit 18 IPV6 Tx Enable */ - unsigned int tcp_chksum : 1; /* bit 19 TCP Checksum Enable */ - unsigned int udp_chksum : 1; /* bit 20 UDP Checksum Enable */ - unsigned int bypass_tss : 1; /* bit 21 Bypass HW offload engine */ - unsigned int ip_fixed_len : 1; /* bit 22 Don't update IP length field */ - unsigned int reserved : 9; /* bit 31:23 Tx Flag, Reserved */ - } bits; -} GMAC_TXDESC_1_T; - -#define TSS_IP_FIXED_LEN_BIT BIT(22) -#define TSS_BYPASS_BIT BIT(21) -#define TSS_UDP_CHKSUM_BIT BIT(20) -#define TSS_TCP_CHKSUM_BIT BIT(19) -#define TSS_IPV6_ENABLE_BIT BIT(18) -#define TSS_IP_CHKSUM_BIT BIT(17) -#define TSS_MTU_ENABLE_BIT BIT(16) - -#define TSS_CHECKUM_ENABLE \ - (TSS_IP_CHKSUM_BIT|TSS_IPV6_ENABLE_BIT| \ - TSS_TCP_CHKSUM_BIT|TSS_UDP_CHKSUM_BIT) - -/* - * GMAC DMA Tx Description Word 2 Register - * GMAC0 offset 0x8048 - * GMAC1 offset 0xC048 - */ -typedef union { - unsigned int bits32; - unsigned int buf_adr; -} GMAC_TXDESC_2_T; - -/* - * GMAC DMA Tx Description Word 3 Register - * GMAC0 offset 0x804C - * GMAC1 offset 0xC04C - */ -typedef union { - unsigned int bits32; - struct txdesc_word3 { - unsigned int mtu_size : 13; /* bit 12: 0 Tx Frame Byte Count */ - unsigned int reserved : 16; /* bit 28:13 */ - unsigned int eofie : 1; /* bit 29 End of frame interrupt enable */ - unsigned int sof_eof : 2; /* bit 31:30 11: only one, 10: first, 01: last, 00: linking */ - } bits; -} GMAC_TXDESC_3_T; -#define SOF_EOF_BIT_MASK 0x3fffffff -#define SOF_BIT 0x80000000 -#define EOF_BIT 0x40000000 -#define EOFIE_BIT BIT(29) -#define MTU_SIZE_BIT_MASK 0x1fff - -/* - * GMAC Tx Descriptor - */ -typedef struct { - GMAC_TXDESC_0_T word0; - GMAC_TXDESC_1_T word1; - GMAC_TXDESC_2_T word2; - GMAC_TXDESC_3_T word3; -} GMAC_TXDESC_T; - -/* - * GMAC DMA Rx First Description Address Register - * GMAC0 offset 0x8058 - * GMAC1 offset 0xC058 - */ -typedef union { - unsigned int bits32; - struct bit_8058 { - unsigned int reserved : 3; /* bit 2:0 */ - unsigned int rd_busy : 1; /* bit 3 1-RxDMA busy; 0-RxDMA idle */ - unsigned int rd_first_des_ptr : 28; /* bit 31:4 first descriptor address */ - } bits; -} GMAC_RXDMA_FIRST_DESC_T; - -/* - * GMAC DMA Rx Current Description Address Register - * GMAC0 offset 0x805C - * GMAC1 offset 0xC05C - */ -typedef union { - unsigned int bits32; - struct bit_805C { - unsigned int reserved : 4; /* bit 3:0 */ - unsigned int rd_curr_des_ptr : 28; /* bit 31:4 current descriptor address */ - } bits; -} GMAC_RXDMA_CURR_DESC_T; - -/* - * GMAC DMA Rx Description Word 0 Register - * GMAC0 offset 0x8060 - * GMAC1 offset 0xC060 - */ -typedef union { - unsigned int bits32; - struct bit_8060 { - unsigned int buffer_size : 16; /* bit 15:0 number of descriptors used for the current frame */ - unsigned int desc_count : 6; /* bit 21:16 number of descriptors used for the current frame */ - unsigned int status : 4; /* bit 24:22 Status of rx frame */ - unsigned int chksum_status : 3; /* bit 28:26 Check Sum Status */ - unsigned int perr : 1; /* bit 29 protocol error during processing this descriptor */ - unsigned int derr : 1; /* bit 30 data error during processing this descriptor */ - unsigned int drop : 1; /* bit 31 TOE/CIS Queue Full dropped packet to default queue */ - } bits; -} GMAC_RXDESC_0_T; - -#define GMAC_RXDESC_0_T_derr BIT(30) -#define GMAC_RXDESC_0_T_perr BIT(29) -#define GMAC_RXDESC_0_T_chksum_status(x) BIT((x+26)) -#define GMAC_RXDESC_0_T_status(x) BIT((x+22)) -#define GMAC_RXDESC_0_T_desc_count(x) BIT((x+16)) - -#define RX_CHKSUM_IP_UDP_TCP_OK 0 -#define RX_CHKSUM_IP_OK_ONLY 1 -#define RX_CHKSUM_NONE 2 -#define RX_CHKSUM_IP_ERR_UNKNOWN 4 -#define RX_CHKSUM_IP_ERR 5 -#define RX_CHKSUM_TCP_UDP_ERR 6 -#define RX_CHKSUM_NUM 8 - -#define RX_STATUS_GOOD_FRAME 0 -#define RX_STATUS_TOO_LONG_GOOD_CRC 1 -#define RX_STATUS_RUNT_FRAME 2 -#define RX_STATUS_SFD_NOT_FOUND 3 -#define RX_STATUS_CRC_ERROR 4 -#define RX_STATUS_TOO_LONG_BAD_CRC 5 -#define RX_STATUS_ALIGNMENT_ERROR 6 -#define RX_STATUS_TOO_LONG_BAD_ALIGN 7 -#define RX_STATUS_RX_ERR 8 -#define RX_STATUS_DA_FILTERED 9 -#define RX_STATUS_BUFFER_FULL 10 -#define RX_STATUS_NUM 16 - -#define RX_ERROR_LENGTH(s) \ - ((s) == RX_STATUS_TOO_LONG_GOOD_CRC || \ - (s) == RX_STATUS_TOO_LONG_BAD_CRC || \ - (s) == RX_STATUS_TOO_LONG_BAD_ALIGN) -#define RX_ERROR_OVER(s) \ - ((s) == RX_STATUS_BUFFER_FULL) -#define RX_ERROR_CRC(s) \ - ((s) == RX_STATUS_CRC_ERROR || \ - (s) == RX_STATUS_TOO_LONG_BAD_CRC) -#define RX_ERROR_FRAME(s) \ - ((s) == RX_STATUS_ALIGNMENT_ERROR || \ - (s) == RX_STATUS_TOO_LONG_BAD_ALIGN) -#define RX_ERROR_FIFO(s) \ - (0) - -/* - * GMAC DMA Rx Description Word 1 Register - * GMAC0 offset 0x8064 - * GMAC1 offset 0xC064 - */ -typedef union { - unsigned int bits32; - struct rxdesc_word1 { - unsigned int byte_count : 16; /* bit 15: 0 Rx Frame Byte Count */ - unsigned int sw_id : 16; /* bit 31:16 Software ID */ - } bits; -} GMAC_RXDESC_1_T; - -/* - * GMAC DMA Rx Description Word 2 Register - * GMAC0 offset 0x8068 - * GMAC1 offset 0xC068 - */ -typedef union { - unsigned int bits32; - unsigned int buf_adr; -} GMAC_RXDESC_2_T; - -#define RX_INSERT_NONE 0 -#define RX_INSERT_1_BYTE 1 -#define RX_INSERT_2_BYTE 2 -#define RX_INSERT_3_BYTE 3 - -/* - * GMAC DMA Rx Description Word 3 Register - * GMAC0 offset 0x806C - * GMAC1 offset 0xC06C - */ -typedef union { - unsigned int bits32; - struct rxdesc_word3 { - unsigned int l3_offset : 8; /* bit 7: 0 L3 data offset */ - unsigned int l4_offset : 8; /* bit 15: 8 L4 data offset */ - unsigned int l7_offset : 8; /* bit 23: 16 L7 data offset */ - unsigned int dup_ack : 1; /* bit 24 Duplicated ACK detected */ - unsigned int abnormal : 1; /* bit 25 abnormal case found */ - unsigned int option : 1; /* bit 26 IPV4 option or IPV6 extension header */ - unsigned int out_of_seq : 1; /* bit 27 Out of Sequence packet */ - unsigned int ctrl_flag : 1; /* bit 28 Control Flag is present */ - unsigned int eofie : 1; /* bit 29 End of frame interrupt enable */ - unsigned int sof_eof : 2; /* bit 31:30 11: only one, 10: first, 01: last, 00: linking */ - } bits; -} GMAC_RXDESC_3_T; - -/* - * GMAC Rx Descriptor - */ -typedef struct { - GMAC_RXDESC_0_T word0; - GMAC_RXDESC_1_T word1; - GMAC_RXDESC_2_T word2; - GMAC_RXDESC_3_T word3; -} GMAC_RXDESC_T; - -/* - * GMAC Hash Engine Enable/Action Register 0 Offset Register - * GMAC0 offset 0x8070 - * GMAC1 offset 0xC070 - */ -typedef union { - unsigned int bits32; - struct bit_8070 { - unsigned int mr0hel : 6; /* bit 5:0 match rule 0 hash entry size */ - unsigned int mr0_action : 5; /* bit 10:6 Matching Rule 0 action offset */ - unsigned int reserved0 : 4; /* bit 14:11 */ - unsigned int mr0en : 1; /* bit 15 Enable Matching Rule 0 */ - unsigned int mr1hel : 6; /* bit 21:16 match rule 1 hash entry size */ - unsigned int mr1_action : 5; /* bit 26:22 Matching Rule 1 action offset */ - unsigned int timing : 3; /* bit 29:27 */ - unsigned int reserved1 : 1; /* bit 30 */ - unsigned int mr1en : 1; /* bit 31 Enable Matching Rule 1 */ - } bits; -} GMAC_HASH_ENABLE_REG0_T; - -/* - * GMAC Hash Engine Enable/Action Register 1 Offset Register - * GMAC0 offset 0x8074 - * GMAC1 offset 0xC074 - */ -typedef union { - unsigned int bits32; - struct bit_8074 { - unsigned int mr2hel : 6; /* bit 5:0 match rule 2 hash entry size */ - unsigned int mr2_action : 5; /* bit 10:6 Matching Rule 2 action offset */ - unsigned int reserved2 : 4; /* bit 14:11 */ - unsigned int mr2en : 1; /* bit 15 Enable Matching Rule 2 */ - unsigned int mr3hel : 6; /* bit 21:16 match rule 3 hash entry size */ - unsigned int mr3_action : 5; /* bit 26:22 Matching Rule 3 action offset */ - unsigned int reserved1 : 4; /* bit 30:27 */ - unsigned int mr3en : 1; /* bit 31 Enable Matching Rule 3 */ - } bits; -} GMAC_HASH_ENABLE_REG1_T; - -/* - * GMAC Matching Rule Control Register 0 - * GMAC0 offset 0x8078 - * GMAC1 offset 0xC078 - */ -typedef union { - unsigned int bits32; - struct bit_8078 { - unsigned int sprx : 8; /* bit 7:0 Support Protocol Register 7:0 */ - unsigned int reserved2 : 4; /* bit 11:8 */ - unsigned int tos_traffic : 1; /* bit 12 IPV4 TOS or IPV6 Traffice Class */ - unsigned int flow_lable : 1; /* bit 13 IPV6 Flow label */ - unsigned int ip_hdr_len : 1; /* bit 14 IPV4 Header length */ - unsigned int ip_version : 1; /* bit 15 0: IPV4, 1: IPV6 */ - unsigned int reserved1 : 3; /* bit 18:16 */ - unsigned int pppoe : 1; /* bit 19 PPPoE Session ID enable */ - unsigned int vlan : 1; /* bit 20 VLAN ID enable */ - unsigned int ether_type : 1; /* bit 21 Ethernet type enable */ - unsigned int sa : 1; /* bit 22 MAC SA enable */ - unsigned int da : 1; /* bit 23 MAC DA enable */ - unsigned int priority : 3; /* bit 26:24 priority if multi-rules matched */ - unsigned int port : 1; /* bit 27 PORT ID matching enable */ - unsigned int l7 : 1; /* bit 28 L7 matching enable */ - unsigned int l4 : 1; /* bit 29 L4 matching enable */ - unsigned int l3 : 1; /* bit 30 L3 matching enable */ - unsigned int l2 : 1; /* bit 31 L2 matching enable */ - } bits; -} GMAC_MRxCR0_T; - -#define MR_L2_BIT BIT(31) -#define MR_L3_BIT BIT(30) -#define MR_L4_BIT BIT(29) -#define MR_L7_BIT BIT(28) -#define MR_PORT_BIT BIT(27) -#define MR_PRIORITY_BIT BIT(26) -#define MR_DA_BIT BIT(23) -#define MR_SA_BIT BIT(22) -#define MR_ETHER_TYPE_BIT BIT(21) -#define MR_VLAN_BIT BIT(20) -#define MR_PPPOE_BIT BIT(19) -#define MR_IP_VER_BIT BIT(15) -#define MR_IP_HDR_LEN_BIT BIT(14) -#define MR_FLOW_LABLE_BIT BIT(13) -#define MR_TOS_TRAFFIC_BIT BIT(12) -#define MR_SPR_BIT(x) BIT(x) -#define MR_SPR_BITS 0xff - -/* - * GMAC Matching Rule Control Register 1 - * GMAC0 offset 0x807C - * GMAC1 offset 0xC07C - */ -typedef union { - unsigned int bits32; - struct bit_807C { - unsigned int l4_byte0_15 : 16; /* bit 15: 0 */ - unsigned int dip_netmask : 7; /* bit 22:16 Dest IP net mask, number of mask bits */ - unsigned int dip : 1; /* bit 23 Dest IP */ - unsigned int sip_netmask : 7; /* bit 30:24 Srce IP net mask, number of mask bits */ - unsigned int sip : 1; /* bit 31 Srce IP */ - } bits; -} GMAC_MRxCR1_T; - -/* - * GMAC Matching Rule Control Register 2 - * GMAC0 offset 0x8080 - * GMAC1 offset 0xC080 - */ -typedef union { - unsigned int bits32; - struct bit_8080 { - unsigned int l7_byte0_23 : 24; /* bit 23:0 */ - unsigned int l4_byte16_24 : 8; /* bit 31: 24 */ - } bits; -} GMAC_MRxCR2_T; - -/* - * GMAC Support registers - * GMAC0 offset 0x80A8 - * GMAC1 offset 0xC0A8 - */ -typedef union { - unsigned int bits32; - struct bit_80A8 { - unsigned int protocol : 8; /* bit 7:0 Supported protocol */ - unsigned int swap : 3; /* bit 10:8 Swap */ - unsigned int reserved : 21; /* bit 31:11 */ - } bits; -} GMAC_SPR_T; - -/* - * GMAC_AHB_WEIGHT registers - * GMAC0 offset 0x80C8 - * GMAC1 offset 0xC0C8 - */ -typedef union { - unsigned int bits32; - struct bit_80C8 { - unsigned int hash_weight : 5; /* 4:0 */ - unsigned int rx_weight : 5; /* 9:5 */ - unsigned int tx_weight : 5; /* 14:10 */ - unsigned int pre_req : 5; /* 19:15 Rx Data Pre Request FIFO Threshold */ - unsigned int tqDV_threshold : 5; /* 24:20 DMA TqCtrl to Start tqDV FIFO Threshold */ - unsigned int reserved : 7; /* 31:25 */ - } bits; -} GMAC_AHB_WEIGHT_T; - -/* - * the register structure of GMAC - */ - -/* - * GMAC RX FLTR - * GMAC0 Offset 0xA00C - * GMAC1 Offset 0xE00C - */ -typedef union { - unsigned int bits32; - struct bit1_000c { - unsigned int unicast : 1; /* enable receive of unicast frames that are sent to STA address */ - unsigned int multicast : 1; /* enable receive of multicast frames that pass multicast filter */ - unsigned int broadcast : 1; /* enable receive of broadcast frames */ - unsigned int promiscuous : 1; /* enable receive of all frames */ - unsigned int error : 1; /* enable receive of all error frames */ - unsigned int : 27; - } bits; -} GMAC_RX_FLTR_T; - -/* - * GMAC Configuration 0 - * GMAC0 Offset 0xA018 - * GMAC1 Offset 0xE018 - */ -typedef union { - unsigned int bits32; - struct bit1_0018 { - unsigned int dis_tx : 1; /* 0: disable transmit */ - unsigned int dis_rx : 1; /* 1: disable receive */ - unsigned int loop_back : 1; /* 2: transmit data loopback enable */ - unsigned int flow_ctrl : 1; /* 3: flow control also trigged by Rx queues */ - unsigned int adj_ifg : 4; /* 4-7: adjust IFG from 96+/-56 */ - unsigned int max_len : 3; /* 8-10 maximum receive frame length allowed */ - unsigned int dis_bkoff : 1; /* 11: disable back-off function */ - unsigned int dis_col : 1; /* 12: disable 16 collisions abort function */ - unsigned int sim_test : 1; /* 13: speed up timers in simulation */ - unsigned int rx_fc_en : 1; /* 14: RX flow control enable */ - unsigned int tx_fc_en : 1; /* 15: TX flow control enable */ - unsigned int rgmii_en : 1; /* 16: RGMII in-band status enable */ - unsigned int ipv4_rx_chksum : 1; /* 17: IPv4 RX Checksum enable */ - unsigned int ipv6_rx_chksum : 1; /* 18: IPv6 RX Checksum enable */ - unsigned int rx_tag_remove : 1; /* 19: Remove Rx VLAN tag */ - unsigned int rgmm_edge : 1; /* 20 */ - unsigned int rxc_inv : 1; /* 21 */ - unsigned int ipv6_exthdr_order : 1; /* 22 */ - unsigned int rx_err_detect : 1; /* 23 */ - unsigned int port0_chk_hwq : 1; /* 24 */ - unsigned int port1_chk_hwq : 1; /* 25 */ - unsigned int port0_chk_toeq : 1; /* 26 */ - unsigned int port1_chk_toeq : 1; /* 27 */ - unsigned int port0_chk_classq : 1; /* 28 */ - unsigned int port1_chk_classq : 1; /* 29 */ - unsigned int reserved : 2; /* 31 */ - } bits; -} GMAC_CONFIG0_T; - -#define CONFIG0_TX_RX_DISABLE (BIT(1)|BIT(0)) -#define CONFIG0_RX_CHKSUM (BIT(18)|BIT(17)) -#define CONFIG0_FLOW_RX (BIT(14)) -#define CONFIG0_FLOW_TX (BIT(15)) -#define CONFIG0_FLOW_TX_RX (BIT(14)|BIT(15)) -#define CONFIG0_FLOW_CTL (BIT(14)|BIT(15)) - -#define CONFIG0_MAXLEN_SHIFT 8 -#define CONFIG0_MAXLEN_MASK (7 << CONFIG0_MAXLEN_SHIFT) -#define CONFIG0_MAXLEN_1536 0 -#define CONFIG0_MAXLEN_1518 1 -#define CONFIG0_MAXLEN_1522 2 -#define CONFIG0_MAXLEN_1542 3 -#define CONFIG0_MAXLEN_9k 4 /* 9212 */ -#define CONFIG0_MAXLEN_10k 5 /* 10236 */ -#define CONFIG0_MAXLEN_1518__6 6 -#define CONFIG0_MAXLEN_1518__7 7 - -/* - * GMAC Configuration 1 - * GMAC0 Offset 0xA01C - * GMAC1 Offset 0xE01C - */ -typedef union { - unsigned int bits32; - struct bit1_001c { - unsigned int set_threshold : 8; /* flow control set threshold */ - unsigned int rel_threshold : 8; /* flow control release threshold */ - unsigned int reserved : 16; - } bits; -} GMAC_CONFIG1_T; - -#define GMAC_FLOWCTRL_SET_MAX 32 -#define GMAC_FLOWCTRL_SET_MIN 0 -#define GMAC_FLOWCTRL_RELEASE_MAX 32 -#define GMAC_FLOWCTRL_RELEASE_MIN 0 - -/* - * GMAC Configuration 2 - * GMAC0 Offset 0xA020 - * GMAC1 Offset 0xE020 - */ -typedef union { - unsigned int bits32; - struct bit1_0020 { - unsigned int set_threshold : 16; /* flow control set threshold */ - unsigned int rel_threshold : 16; /* flow control release threshold */ - } bits; -} GMAC_CONFIG2_T; - -/* - * GMAC Configuration 3 - * GMAC0 Offset 0xA024 - * GMAC1 Offset 0xE024 - */ -typedef union { - unsigned int bits32; - struct bit1_0024 { - unsigned int set_threshold : 16; /* flow control set threshold */ - unsigned int rel_threshold : 16; /* flow control release threshold */ - } bits; -} GMAC_CONFIG3_T; - - -/* - * GMAC STATUS - * GMAC0 Offset 0xA02C - * GMAC1 Offset 0xE02C - */ -typedef union { - unsigned int bits32; - struct bit1_002c { - unsigned int link : 1; /* link status */ - unsigned int speed : 2; /* link speed(00->2.5M 01->25M 10->125M) */ - unsigned int duplex : 1; /* duplex mode */ - unsigned int reserved : 1; - unsigned int mii_rmii : 2; /* PHY interface type */ - unsigned int : 25; - } bits; -} GMAC_STATUS_T; - -#define GMAC_SPEED_10 0 -#define GMAC_SPEED_100 1 -#define GMAC_SPEED_1000 2 - -#define GMAC_PHY_MII 0 -#define GMAC_PHY_GMII 1 -#define GMAC_PHY_RGMII_100_10 2 -#define GMAC_PHY_RGMII_1000 3 - -/* - * Queue Header - * (1) TOE Queue Header - * (2) Non-TOE Queue Header - * (3) Interrupt Queue Header - * - * memory Layout - * TOE Queue Header - * 0x60003000 +---------------------------+ 0x0000 - * | TOE Queue 0 Header | - * | 8 * 4 Bytes | - * +---------------------------+ 0x0020 - * | TOE Queue 1 Header | - * | 8 * 4 Bytes | - * +---------------------------+ 0x0040 - * | ...... | - * | | - * +---------------------------+ - * - * Non TOE Queue Header - * 0x60002000 +---------------------------+ 0x0000 - * | Default Queue 0 Header | - * | 2 * 4 Bytes | - * +---------------------------+ 0x0008 - * | Default Queue 1 Header | - * | 2 * 4 Bytes | - * +---------------------------+ 0x0010 - * | Classification Queue 0 | - * | 2 * 4 Bytes | - * +---------------------------+ - * | Classification Queue 1 | - * | 2 * 4 Bytes | - * +---------------------------+ (n * 8 + 0x10) - * | ... | - * | 2 * 4 Bytes | - * +---------------------------+ (13 * 8 + 0x10) - * | Classification Queue 13 | - * | 2 * 4 Bytes | - * +---------------------------+ 0x80 - * | Interrupt Queue 0 | - * | 2 * 4 Bytes | - * +---------------------------+ - * | Interrupt Queue 1 | - * | 2 * 4 Bytes | - * +---------------------------+ - * | Interrupt Queue 2 | - * | 2 * 4 Bytes | - * +---------------------------+ - * | Interrupt Queue 3 | - * | 2 * 4 Bytes | - * +---------------------------+ - * - */ -#define TOE_QUEUE_HDR_ADDR(n) (TOE_TOE_QUE_HDR_BASE + n * 32) -#define TOE_Q_HDR_AREA_END (TOE_QUEUE_HDR_ADDR(TOE_TOE_QUEUE_MAX + 1)) -#define TOE_DEFAULT_Q_HDR_BASE(x) (TOE_NONTOE_QUE_HDR_BASE + 0x08 * (x)) -#define TOE_CLASS_Q_HDR_BASE (TOE_NONTOE_QUE_HDR_BASE + 0x10) -#define TOE_INTR_Q_HDR_BASE (TOE_NONTOE_QUE_HDR_BASE + 0x80) -#define INTERRUPT_QUEUE_HDR_ADDR(n) (TOE_INTR_Q_HDR_BASE + n * 8) -#define NONTOE_Q_HDR_AREA_END (INTERRUPT_QUEUE_HDR_ADDR(TOE_INTR_QUEUE_MAX + 1)) -/* - * TOE Queue Header Word 0 - */ -typedef union { - unsigned int bits32; - unsigned int base_size; -} TOE_QHDR0_T; - -#define TOE_QHDR0_BASE_MASK (~0x0f) - -/* - * TOE Queue Header Word 1 - */ -typedef union { - unsigned int bits32; - struct bit_qhdr1 { - unsigned int rptr : 16; /* bit 15:0 */ - unsigned int wptr : 16; /* bit 31:16 */ - } bits; -} TOE_QHDR1_T; - -/* - * TOE Queue Header Word 2 - */ -typedef union { - unsigned int bits32; - struct bit_qhdr2 { - unsigned int TotalPktSize : 17; /* bit 16: 0 Total packet size */ - unsigned int reserved : 7; /* bit 23:17 */ - unsigned int dack : 1; /* bit 24 1: Duplicated ACK */ - unsigned int abn : 1; /* bit 25 1: Abnormal case Found */ - unsigned int tcp_opt : 1; /* bit 26 1: Have TCP option */ - unsigned int ip_opt : 1; /* bit 27 1: have IPV4 option or IPV6 Extension header */ - unsigned int sat : 1; /* bit 28 1: SeqCnt > SeqThreshold, or AckCnt > AckThreshold */ - unsigned int osq : 1; /* bit 29 1: out of sequence */ - unsigned int ctl : 1; /* bit 30 1: have control flag bits (except ack) */ - unsigned int usd : 1; /* bit 31 0: if no data assembled yet */ - } bits; -} TOE_QHDR2_T; - -/* - * TOE Queue Header Word 3 - */ -typedef union { - unsigned int bits32; - unsigned int seq_num; -} TOE_QHDR3_T; - -/* - * TOE Queue Header Word 4 - */ -typedef union { - unsigned int bits32; - unsigned int ack_num; -} TOE_QHDR4_T; - -/* - * TOE Queue Header Word 5 - */ -typedef union { - unsigned int bits32; - struct bit_qhdr5 { - unsigned int AckCnt : 16; /* bit 15:0 */ - unsigned int SeqCnt : 16; /* bit 31:16 */ - } bits; -} TOE_QHDR5_T; - -/* - * TOE Queue Header Word 6 - */ -typedef union { - unsigned int bits32; - struct bit_qhdr6 { - unsigned int WinSize : 16; /* bit 15:0 */ - unsigned int iq_num : 2; /* bit 17:16 */ - unsigned int MaxPktSize : 14; /* bit 31:18 */ - } bits; -} TOE_QHDR6_T; - -/* - * TOE Queue Header Word 7 - */ -typedef union { - unsigned int bits32; - struct bit_qhdr7 { - unsigned int AckThreshold : 16; /* bit 15:0 */ - unsigned int SeqThreshold : 16; /* bit 31:16 */ - } bits; -} TOE_QHDR7_T; - -/* - * TOE Queue Header - */ -typedef struct { - TOE_QHDR0_T word0; - TOE_QHDR1_T word1; - TOE_QHDR2_T word2; - TOE_QHDR3_T word3; - TOE_QHDR4_T word4; - TOE_QHDR5_T word5; - TOE_QHDR6_T word6; - TOE_QHDR7_T word7; -} TOE_QHDR_T; - -/* - * NONTOE Queue Header Word 0 - */ -typedef union { - unsigned int bits32; - unsigned int base_size; -} NONTOE_QHDR0_T; - -#define NONTOE_QHDR0_BASE_MASK (~0x0f) - -/* - * NONTOE Queue Header Word 1 - */ -typedef union { - unsigned int bits32; - struct bit_nonqhdr1 { - unsigned int rptr : 16; /* bit 15:0 */ - unsigned int wptr : 16; /* bit 31:16 */ - } bits; -} NONTOE_QHDR1_T; - -/* - * Non-TOE Queue Header - */ -typedef struct { - NONTOE_QHDR0_T word0; - NONTOE_QHDR1_T word1; -} NONTOE_QHDR_T; - -/* - * Interrupt Queue Header Word 0 - */ -typedef union { - unsigned int bits32; - struct bit_intrqhdr0 { - unsigned int win_size : 16; /* bit 15:0 Descriptor Ring Size */ - unsigned int wptr : 16; /* bit 31:16 Write Pointer where hw stopped */ - } bits; -} INTR_QHDR0_T; - -/* - * Interrupt Queue Header Word 1 - */ -typedef union { - unsigned int bits32; - struct bit_intrqhdr1 { - unsigned int TotalPktSize : 17; /* bit 16: 0 Total packet size */ - unsigned int tcp_qid : 8; /* bit 24:17 TCP Queue ID */ - unsigned int dack : 1; /* bit 25 1: Duplicated ACK */ - unsigned int abn : 1; /* bit 26 1: Abnormal case Found */ - unsigned int tcp_opt : 1; /* bit 27 1: Have TCP option */ - unsigned int ip_opt : 1; /* bit 28 1: have IPV4 option or IPV6 Extension header */ - unsigned int sat : 1; /* bit 29 1: SeqCnt > SeqThreshold, or AckCnt > AckThreshold */ - unsigned int osq : 1; /* bit 30 1: out of sequence */ - unsigned int ctl : 1; /* bit 31 1: have control flag bits (except ack) */ - } bits; -} INTR_QHDR1_T; - -/* - * Interrupt Queue Header Word 2 - */ -typedef union { - unsigned int bits32; - unsigned int seq_num; -} INTR_QHDR2_T; - -/* - * Interrupt Queue Header Word 3 - */ -typedef union { - unsigned int bits32; - unsigned int ack_num; -} INTR_QHDR3_T; - -/* - * Interrupt Queue Header Word 4 - */ -typedef union { - unsigned int bits32; - struct bit_intrqhdr4 { - unsigned int AckCnt : 16; /* bit 15:0 Ack# change since last ack# intr. */ - unsigned int SeqCnt : 16; /* bit 31:16 Seq# change since last seq# intr. */ - } bits; -} INTR_QHDR4_T; - -/* - * Interrupt Queue Header - */ -typedef struct { - INTR_QHDR0_T word0; - INTR_QHDR1_T word1; - INTR_QHDR2_T word2; - INTR_QHDR3_T word3; - INTR_QHDR4_T word4; - unsigned int word5; - unsigned int word6; - unsigned int word7; -} INTR_QHDR_T; - -#endif /* _GMAC_SL351x_H */ diff --git a/target/linux/gemini/files/drivers/usb/host/ehci-fotg2.c b/target/linux/gemini/files/drivers/usb/host/ehci-fotg2.c deleted file mode 100644 index 0717abce9..000000000 --- a/target/linux/gemini/files/drivers/usb/host/ehci-fotg2.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Gemini EHCI Host Controller driver - * - * Copyright (C) 2014 Roman Yeryomin - * Copyright (C) 2012 Tobias Waldvogel - * based on GPLd code from Sony Computer Entertainment Inc. - * - * 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; version 2 of the License. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ehci.h" - -#define DRV_NAME "ehci-fotg2" - -#define HCD_MISC 0x40 - -#define OTGC_SCR 0x80 -#define OTGC_INT_STS 0x84 -#define OTGC_INT_EN 0x88 - -#define GLOBAL_ISR 0xC0 -#define GLOBAL_ICR 0xC4 - -#define GLOBAL_INT_POLARITY (1 << 3) -#define GLOBAL_INT_MASK_HC (1 << 2) -#define GLOBAL_INT_MASK_OTG (1 << 1) -#define GLOBAL_INT_MASK_DEV (1 << 0) - -#define OTGC_SCR_ID (1 << 21) -#define OTGC_SCR_CROLE (1 << 20) -#define OTGC_SCR_VBUS_VLD (1 << 19) -#define OTGC_SCR_A_SRP_RESP_TYPE (1 << 8) -#define OTGC_SCR_A_SRP_DET_EN (1 << 7) -#define OTGC_SCR_A_SET_B_HNP_EN (1 << 6) -#define OTGC_SCR_A_BUS_DROP (1 << 5) -#define OTGC_SCR_A_BUS_REQ (1 << 4) - -#define OTGC_INT_APLGRMV (1 << 12) -#define OTGC_INT_BPLGRMV (1 << 11) -#define OTGC_INT_OVC (1 << 10) -#define OTGC_INT_IDCHG (1 << 9) -#define OTGC_INT_RLCHG (1 << 8) -#define OTGC_INT_AVBUSERR (1 << 5) -#define OTGC_INT_ASRPDET (1 << 4) -#define OTGC_INT_BSRPDN (1 << 0) - -#define OTGC_INT_A_TYPE ( \ - OTGC_INT_ASRPDET | \ - OTGC_INT_AVBUSERR | \ - OTGC_INT_OVC | \ - OTGC_INT_RLCHG | \ - OTGC_INT_IDCHG | \ - OTGC_INT_APLGRMV \ - ) -#define OTGC_INT_B_TYPE ( \ - OTGC_INT_AVBUSERR | \ - OTGC_INT_OVC | \ - OTGC_INT_RLCHG | \ - OTGC_INT_IDCHG \ - ) - - -static void fotg2_otg_init(struct usb_hcd *hcd) -{ - u32 val; - - writel(GLOBAL_INT_POLARITY | GLOBAL_INT_MASK_HC | - GLOBAL_INT_MASK_OTG | GLOBAL_INT_MASK_DEV, - hcd->regs + GLOBAL_ICR); - - val = readl(hcd->regs + OTGC_SCR); - val &= ~(OTGC_SCR_A_SRP_RESP_TYPE | OTGC_SCR_A_SRP_DET_EN | - OTGC_SCR_A_BUS_DROP | OTGC_SCR_A_SET_B_HNP_EN); - val |= OTGC_SCR_A_BUS_REQ; - writel(val, hcd->regs + OTGC_SCR); - - writel(OTGC_INT_A_TYPE, hcd->regs + OTGC_INT_EN); - - /* setup MISC register, fixes timing problems */ - val = readl(hcd->regs + HCD_MISC); - val |= 0xD; - writel(val, hcd->regs + HCD_MISC); - - writel(~0, hcd->regs + GLOBAL_ISR); - writel(~0, hcd->regs + OTGC_INT_STS); -} - -static int fotg2_ehci_reset(struct usb_hcd *hcd) -{ - int retval; - - retval = ehci_setup(hcd); - if (retval) - return retval; - - writel(GLOBAL_INT_POLARITY, hcd->regs + GLOBAL_ICR); - return 0; -} - -static const struct hc_driver fotg2_ehci_hc_driver = { - .description = hcd_name, - .product_desc = "FOTG2 EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - .reset = fotg2_ehci_reset, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - .get_frame_number = ehci_get_frame, - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, -#if defined(CONFIG_PM) - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -#endif - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static irqreturn_t fotg2_ehci_irq(int irq, void *data) -{ - struct usb_hcd *hcd = data; - u32 icr, sts; - irqreturn_t retval; - - icr = readl(hcd->regs + GLOBAL_ICR); - writel(GLOBAL_INT_POLARITY | GLOBAL_INT_MASK_HC | - GLOBAL_INT_MASK_OTG | GLOBAL_INT_MASK_DEV, - hcd->regs + GLOBAL_ICR); - - retval = IRQ_NONE; - - sts = ~icr; - sts &= GLOBAL_INT_MASK_HC | GLOBAL_INT_MASK_OTG | GLOBAL_INT_MASK_DEV; - sts &= readl(hcd->regs + GLOBAL_ISR); - writel(sts, hcd->regs + GLOBAL_ISR); - - if (unlikely(sts & GLOBAL_INT_MASK_DEV)) { - ehci_warn(hcd_to_ehci(hcd), - "Received unexpected irq for device role\n"); - retval = IRQ_HANDLED; - } - - if (unlikely(sts & GLOBAL_INT_MASK_OTG)) { - u32 otg_sts; - - otg_sts = readl(hcd->regs + OTGC_INT_STS); - writel(otg_sts, hcd->regs + OTGC_INT_STS); - - ehci_warn(hcd_to_ehci(hcd), - "Received unexpected irq for OTG management\n"); - retval = IRQ_HANDLED; - } - - if (sts & GLOBAL_INT_MASK_HC) { - retval = IRQ_NONE; - } - - writel(icr, hcd->regs + GLOBAL_ICR); - return retval; -} - -static int fotg2_ehci_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct resource *res; - int irq , err; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - pr_err("no irq provided"); - return irq; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - pr_err("no memory resource provided"); - return -ENXIO; - } - - hcd = usb_create_hcd(&fotg2_ehci_hc_driver, &pdev->dev, - dev_name(&pdev->dev)); - if (!hcd) - return -ENOMEM; - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - hcd->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(hcd->regs)) { - err = -ENOMEM; - goto err_put_hcd; - } - - hcd->has_tt = 1; - hcd_to_ehci(hcd)->caps = hcd->regs; - - fotg2_otg_init(hcd); - - err = request_irq(irq, &fotg2_ehci_irq, IRQF_SHARED, "fotg2", hcd); - if (err) - goto err_put_hcd; - - err = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (err) - goto err_put_hcd; - - platform_set_drvdata(pdev, hcd); - return 0; - -err_put_hcd: - usb_put_hcd(hcd); - return err; -} - -static int fotg2_ehci_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - writel(GLOBAL_INT_POLARITY | GLOBAL_INT_MASK_HC | - GLOBAL_INT_MASK_OTG | GLOBAL_INT_MASK_DEV, - hcd->regs + GLOBAL_ICR); - - free_irq(hcd->irq, hcd); - usb_remove_hcd(hcd); - usb_put_hcd(hcd); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -MODULE_ALIAS("platform:" DRV_NAME); - -static struct platform_driver ehci_fotg2_driver = { - .probe = fotg2_ehci_probe, - .remove = fotg2_ehci_remove, - .driver.name = DRV_NAME, -}; diff --git a/target/linux/gemini/files/drivers/watchdog/gemini_wdt.c b/target/linux/gemini/files/drivers/watchdog/gemini_wdt.c deleted file mode 100644 index 20d30b64e..000000000 --- a/target/linux/gemini/files/drivers/watchdog/gemini_wdt.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Watchdog driver for Cortina Systems Gemini SoC - * - * Copyright (C) 2009 Paulius Zaleckas - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GEMINI_WDCOUNTER 0x0 -#define GEMINI_WDLOAD 0x4 -#define GEMINI_WDRESTART 0x8 - -#define WDRESTART_MAGIC 0x5AB9 - -#define GEMINI_WDCR 0xC - -#define WDCR_CLOCK_5MHZ (1 << 4) -#define WDCR_SYS_RST (1 << 1) -#define WDCR_ENABLE (1 << 0) - -#define WDT_CLOCK 5000000 /* 5 MHz */ -#define WDT_DEFAULT_TIMEOUT 13 -#define WDT_MAX_TIMEOUT (0xFFFFFFFF / WDT_CLOCK) - -/* status bits */ -#define WDT_ACTIVE 0 -#define WDT_OK_TO_CLOSE 1 - -static unsigned int timeout = WDT_DEFAULT_TIMEOUT; -static int nowayout = WATCHDOG_NOWAYOUT; - -static DEFINE_SPINLOCK(gemini_wdt_lock); - -static struct platform_device *gemini_wdt_dev; - -struct gemini_wdt_struct { - struct resource *res; - struct device *dev; - void __iomem *base; - unsigned long status; -}; - -static struct watchdog_info gemini_wdt_info = { - .identity = "Gemini watchdog", - .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | - WDIOF_SETTIMEOUT, -}; - -/* Disable the watchdog. */ -static void gemini_wdt_stop(struct gemini_wdt_struct *gemini_wdt) -{ - spin_lock(&gemini_wdt_lock); - - __raw_writel(0, gemini_wdt->base + GEMINI_WDCR); - - clear_bit(WDT_ACTIVE, &gemini_wdt->status); - - spin_unlock(&gemini_wdt_lock); -} - -/* Service the watchdog */ -static void gemini_wdt_service(struct gemini_wdt_struct *gemini_wdt) -{ - __raw_writel(WDRESTART_MAGIC, gemini_wdt->base + GEMINI_WDRESTART); -} - -/* Enable and reset the watchdog. */ -static void gemini_wdt_start(struct gemini_wdt_struct *gemini_wdt) -{ - spin_lock(&gemini_wdt_lock); - - __raw_writel(timeout * WDT_CLOCK, gemini_wdt->base + GEMINI_WDLOAD); - - gemini_wdt_service(gemini_wdt); - - /* set clock before enabling */ - __raw_writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST, - gemini_wdt->base + GEMINI_WDCR); - - __raw_writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE, - gemini_wdt->base + GEMINI_WDCR); - - set_bit(WDT_ACTIVE, &gemini_wdt->status); - - spin_unlock(&gemini_wdt_lock); -} - -/* Watchdog device is opened, and watchdog starts running. */ -static int gemini_wdt_open(struct inode *inode, struct file *file) -{ - struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(gemini_wdt_dev); - - if (test_bit(WDT_ACTIVE, &gemini_wdt->status)) - return -EBUSY; - - file->private_data = gemini_wdt; - - gemini_wdt_start(gemini_wdt); - - return nonseekable_open(inode, file); -} - -/* Close the watchdog device. */ -static int gemini_wdt_close(struct inode *inode, struct file *file) -{ - struct gemini_wdt_struct *gemini_wdt = file->private_data; - - /* Disable the watchdog if possible */ - if (test_bit(WDT_OK_TO_CLOSE, &gemini_wdt->status)) - gemini_wdt_stop(gemini_wdt); - else - dev_warn(gemini_wdt->dev, "Device closed unexpectedly - timer will not stop\n"); - - return 0; -} - -/* Handle commands from user-space. */ -static long gemini_wdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct gemini_wdt_struct *gemini_wdt = file->private_data; - - int value; - - switch (cmd) { - case WDIOC_KEEPALIVE: - gemini_wdt_service(gemini_wdt); - return 0; - - case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *)arg, &gemini_wdt_info, - sizeof(gemini_wdt_info)) ? -EFAULT : 0; - - case WDIOC_SETTIMEOUT: - if (get_user(value, (int *)arg)) - return -EFAULT; - - if ((value < 1) || (value > WDT_MAX_TIMEOUT)) - return -EINVAL; - - timeout = value; - - /* restart wdt to use new timeout */ - gemini_wdt_stop(gemini_wdt); - gemini_wdt_start(gemini_wdt); - - /* Fall through */ - case WDIOC_GETTIMEOUT: - return put_user(timeout, (int *)arg); - - case WDIOC_GETTIMELEFT: - value = __raw_readl(gemini_wdt->base + GEMINI_WDCOUNTER); - return put_user(value / WDT_CLOCK, (int *)arg); - - default: - return -ENOTTY; - } -} - -/* Refresh the watchdog whenever device is written to. */ -static ssize_t gemini_wdt_write(struct file *file, const char *data, - size_t len, loff_t *ppos) -{ - struct gemini_wdt_struct *gemini_wdt = file->private_data; - - if (len) { - if (!nowayout) { - size_t i; - - clear_bit(WDT_OK_TO_CLOSE, &gemini_wdt->status); - for (i = 0; i != len; i++) { - char c; - - if (get_user(c, data + i)) - return -EFAULT; - if (c == 'V') - set_bit(WDT_OK_TO_CLOSE, - &gemini_wdt->status); - } - } - gemini_wdt_service(gemini_wdt); - } - - return len; -} - -static const struct file_operations gemini_wdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .unlocked_ioctl = gemini_wdt_ioctl, - .open = gemini_wdt_open, - .release = gemini_wdt_close, - .write = gemini_wdt_write, -}; - -static struct miscdevice gemini_wdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &gemini_wdt_fops, -}; - -static void gemini_wdt_shutdown(struct platform_device *pdev) -{ - struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(pdev); - - gemini_wdt_stop(gemini_wdt); -} - -static int gemini_wdt_probe(struct platform_device *pdev) -{ - int ret; - int res_size; - struct resource *res; - void __iomem *base; - struct gemini_wdt_struct *gemini_wdt; - unsigned int reg; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "can't get device resources\n"); - return -ENODEV; - } - - res_size = resource_size(res); - if (!request_mem_region(res->start, res_size, res->name)) { - dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n", - res_size, res->start); - return -ENOMEM; - } - - base = ioremap(res->start, res_size); - if (!base) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -EIO; - goto fail0; - } - - gemini_wdt = kzalloc(sizeof(struct gemini_wdt_struct), GFP_KERNEL); - if (!gemini_wdt) { - dev_err(&pdev->dev, "can't allocate interface\n"); - ret = -ENOMEM; - goto fail1; - } - - /* Setup gemini_wdt driver structure */ - gemini_wdt->base = base; - gemini_wdt->res = res; - - /* Set up platform driver data */ - platform_set_drvdata(pdev, gemini_wdt); - gemini_wdt_dev = pdev; - - if (gemini_wdt_miscdev.parent) { - ret = -EBUSY; - goto fail2; - } - - gemini_wdt_miscdev.parent = &pdev->dev; - - reg = __raw_readw(gemini_wdt->base + GEMINI_WDCR); - if (reg & WDCR_ENABLE) { - /* Watchdog was enabled by the bootloader, disable it. */ - reg &= ~(WDCR_ENABLE); - __raw_writel(reg, gemini_wdt->base + GEMINI_WDCR); - } - - ret = misc_register(&gemini_wdt_miscdev); - if (ret) - goto fail2; - - return 0; - -fail2: - platform_set_drvdata(pdev, NULL); - kfree(gemini_wdt); -fail1: - iounmap(base); -fail0: - release_mem_region(res->start, res_size); - - return ret; -} - -static int gemini_wdt_remove(struct platform_device *pdev) -{ - struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - misc_deregister(&gemini_wdt_miscdev); - gemini_wdt_dev = NULL; - iounmap(gemini_wdt->base); - release_mem_region(gemini_wdt->res->start, resource_size(gemini_wdt->res)); - - kfree(gemini_wdt); - - return 0; -} - -#ifdef CONFIG_PM -static int gemini_wdt_suspend(struct platform_device *pdev, pm_message_t message) -{ - struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(pdev); - unsigned int reg; - - reg = __raw_readw(gemini_wdt->base + GEMINI_WDCR); - reg &= ~(WDCR_WDENABLE); - __raw_writel(reg, gemini_wdt->base + GEMINI_WDCR); - - return 0; -} - -static int gemini_wdt_resume(struct platform_device *pdev) -{ - struct gemini_wdt_struct *gemini_wdt = platform_get_drvdata(pdev); - unsigned int reg; - - if (gemini_wdt->status) { - reg = __raw_readw(gemini_wdt->base + GEMINI_WDCR); - reg |= WDCR_WDENABLE; - __raw_writel(reg, gemini_wdt->base + GEMINI_WDCR); - } - - return 0; -} -#else -#define gemini_wdt_suspend NULL -#define gemini_wdt_resume NULL -#endif - -static struct platform_driver gemini_wdt_driver = { - .probe = gemini_wdt_probe, - .remove = gemini_wdt_remove, - .shutdown = gemini_wdt_shutdown, - .suspend = gemini_wdt_suspend, - .resume = gemini_wdt_resume, - .driver = { - .name = "gemini-wdt", - .owner = THIS_MODULE, - }, -}; - -static int __init gemini_wdt_init(void) -{ - return platform_driver_probe(&gemini_wdt_driver, gemini_wdt_probe); -} - -static void __exit gemini_wdt_exit(void) -{ - platform_driver_unregister(&gemini_wdt_driver); -} - -module_init(gemini_wdt_init); -module_exit(gemini_wdt_exit); - -module_param(timeout, uint, 0); -MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds"); - -module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); - -MODULE_AUTHOR("Paulius Zaleckas"); -MODULE_DESCRIPTION("Watchdog driver for Gemini"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -MODULE_ALIAS("platform:gemini-wdt"); diff --git a/target/linux/gemini/image/Makefile b/target/linux/gemini/image/Makefile index 2cea85777..3e122fc45 100644 --- a/target/linux/gemini/image/Makefile +++ b/target/linux/gemini/image/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009-2014 OpenWrt.org +# Copyright (C) 2009-2018 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,81 +7,124 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/image.mk -ifeq ($(SUBTARGET),wiligear) -define Image/Prepare -# WBD111: mach id 1690 (0x69a) - echo -en "\x06\x1c\xa0\xe3\x9a\x10\x81\xe3" > $(KDIR)/wbd111-zImage - cat $(KDIR)/zImage >> $(KDIR)/wbd111-zImage -# WBD222: mach id 2753 (0xAC1) - echo -en "\x0a\x1c\xa0\xe3\xc1\x10\x81\xe3" > $(KDIR)/wbd222-zImage - cat $(KDIR)/zImage >> $(KDIR)/wbd222-zImage -endef -endif - -ifeq ($(SUBTARGET),raidsonic) -define Image/Prepare -# NAS4220: mach id 2038 (0x7F6) - echo -en "\x07\x1c\xa0\xe3\xf6\x10\x81\xe3" > $(KDIR)/nas4220-zImage - cat $(KDIR)/zImage >> $(KDIR)/nas4220-zImage -endef -endif - -ifeq ($(SUBTARGET),wiligear) -define Image/BuildKernel -# workaround the bootloader's bug with extra nops - echo -en "\x00\x00\xa0\xe1\x00\x00\xa0\xe1\x00\x00\xa0\xe1\x00\x00\xa0\xe1" > $(BIN_DIR)/$(IMG_PREFIX)-wbd111-zImage - cat $(KDIR)/wbd111-zImage >> $(BIN_DIR)/$(IMG_PREFIX)-wbd111-zImage - echo -en "\x00\x00\xa0\xe1\x00\x00\xa0\xe1\x00\x00\xa0\xe1\x00\x00\xa0\xe1" > $(BIN_DIR)/$(IMG_PREFIX)-wbd222-zImage - cat $(KDIR)/wbd222-zImage >> $(BIN_DIR)/$(IMG_PREFIX)-wbd222-zImage -endef -endif - -define Image/Build/jffs2-64k - dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-$(1).img bs=64k conv=sync +# Just copy the zImage for D-Link DIR-685 +define Build/dir685-images + cp $(IMAGE_KERNEL) $(BIN_DIR)/$(IMG_PREFIX)-dir685-zImage endef -define Image/Build/jffs2-128k - dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-$(1).img bs=128k conv=sync +# Build D-Link DNS-313 images using the special header tool. +# rootfs.tgz and rd.tgz contains nothing, we only need them +# to satisfy the boot loader on the device. The zImage is +# the only real content. +define Build/dns313-images + if [ -d $(BIN_DIR)/.boot ] ; then rm -rf $(BIN_DIR)/.boot ; fi + mkdir -p $(BIN_DIR)/.boot + echo "dummy" > $(BIN_DIR)/.boot/dummyfile + dns313-header $(BIN_DIR)/.boot/dummyfile \ + $(BIN_DIR)/.boot/rootfs.tgz + dns313-header $(BIN_DIR)/.boot/dummyfile \ + $(BIN_DIR)/.boot/rd.gz + dns313-header $(IMAGE_KERNEL) \ + $(BIN_DIR)/.boot/zImage + rm -f $(BIN_DIR)/.boot/dummyfile + (cd $(BIN_DIR); tar -czf $(IMG_PREFIX)-dns313-bootpart.tar.gz .boot) + if [ -d $(BIN_DIR)/.boot ] ; then rm -rf $(BIN_DIR)/.boot ; fi endef -define Image/Build/squashfs - $(call prepare_generic_squashfs,$(KDIR)/root.squashfs) - dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-$(1).img bs=128k conv=sync -endef - -ifeq ($(SUBTARGET),wiligear) -define Image/Build - $(call Image/Build/$(1),$(1)) - -$(STAGING_DIR_HOST)/bin/mkfwimage2 \ - -m GEOS -f 0x30000000 -z \ - -v WILI-S.WILIBOARD.v5.00.SL3512.OpenWrt.00000.000000.000000 \ - -o $(BIN_DIR)/$(IMG_PREFIX)-wbd111-$(1).bin \ - -p Kernel:0x020000:0x100000:0:0:$(BIN_DIR)/$(IMG_PREFIX)-wbd111-zImage \ - -p Ramdisk:0x120000:0x500000:0:0:$(BIN_DIR)/$(IMG_PREFIX)-$(1).img - - -$(STAGING_DIR_HOST)/bin/mkfwimage2 \ - -m GEOS -f 0x30000000 -z \ - -v WILI-S.WBD222.v5.00.SL3512.OpenWrt.00000.000000.000000 \ - -o $(BIN_DIR)/$(IMG_PREFIX)-wbd222-$(1).bin \ - -p Kernel:0x020000:0x100000:0:0:$(BIN_DIR)/$(IMG_PREFIX)-wbd222-zImage \ - -p Ramdisk:0x120000:0x500000:0:0:$(BIN_DIR)/$(IMG_PREFIX)-$(1).img -endef -endif - -ifeq ($(SUBTARGET),raidsonic) -define Image/Build - $(call Image/Build/$(1),$(1)) - dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(1).img of=$(BIN_DIR)/rd.gz bs=6144k count=1 -# dd if=/dev/zero of=$(BIN_DIR)/hddapp.tgz bs=6144k count=1 - dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(1).img of=$(BIN_DIR)/hddapp.tgz bs=6144k count=1 seek=1 - cp $(KDIR)/nas4220-zImage $(BIN_DIR)/$(IMG_PREFIX)-nas4220-zImage - cp $(BIN_DIR)/$(IMG_PREFIX)-nas4220-zImage $(BIN_DIR)/zImage +# Create the special NAS4220B image format with the squashfs +# split across two "partitions" named rd.gz and hddapp.tgz but +# essentially just being used by OpenWRT as one big partition +define Build/nas4220b-images + dd if=$(IMAGE_ROOTFS) of=$(BIN_DIR)/rd.gz bs=6144k conv=sync + dd if=$(IMAGE_ROOTFS) of=$(BIN_DIR)/hddapp.tgz bs=6144k count=1 seek=1 + cp $(IMAGE_KERNEL) $(BIN_DIR)/zImage cp ./ImageInfo-ib4220 $(BIN_DIR)/ImageInfo - (cd $(BIN_DIR); tar -czf $(IMG_PREFIX)-sysupgrade-ib4220.tar.gz ImageInfo zImage rd.gz hddapp.tgz) - mv $(BIN_DIR)/rd.gz $(BIN_DIR)/$(IMG_PREFIX)-nas4220-rd.gz - mv $(BIN_DIR)/hddapp.tgz $(BIN_DIR)/$(IMG_PREFIX)-nas4220-hddapp.tgz - rm -f $(BIN_DIR)/zImage $(BIN_DIR)/ImageInfo + (cd $(BIN_DIR); tar -czf $(IMG_PREFIX)-sysupgrade-ib4220b.tar.gz ImageInfo zImage rd.gz hddapp.tgz) + mv $(BIN_DIR)/rd.gz $(BIN_DIR)/$(IMG_PREFIX)-nas4220b-rd.gz + mv $(BIN_DIR)/hddapp.tgz $(BIN_DIR)/$(IMG_PREFIX)-nas4220b-hddapp.tgz + mv $(BIN_DIR)/zImage $(BIN_DIR)/$(IMG_PREFIX)-nas4220b-zImage + rm -f $(BIN_DIR)/ImageInfo endef -endif + +# WBD-111 and WBD-222: +# work around the bootloader's bug with extra nops +# FIXME: is this really needed now that we no longer append the code +# to change the machine ID number? Needs testing on Wiliboard. +define Build/wbd-nops + mv $@ $@.tmp + echo -en "\x00\x00\xa0\xe1\x00\x00\xa0\xe1\x00\x00\xa0\xe1\x00\x00\xa0\xe1" > $@ + cat $@.tmp >> $@ + rm -f $@.tmp +endef + +# All DTB files are prefixed with "gemini-" +define Device/Default + DEVICE_DTS := $(patsubst %.dtb,%,$(notdir $(wildcard $(if $(IB),$(KDIR),$(DTS_DIR))/*-$(1).dtb))) + KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts) + KERNEL_NAME := zImage + KERNEL := kernel-bin | append-dtb + FILESYSTEMS := squashfs + IMAGE_NAME := $$(IMAGE_PREFIX)-$$(1).$$(2) + BLOCKSIZE := 128k + PAGESIZE := 2048 +endef + +# A reasonable set of default packages handling the NAS type +# of devices out of the box (former NAS42x0 IcyBox defaults) +GEMINI_NAS_PACKAGES:=kmod-md-mod kmod-md-linear kmod-md-multipath \ + kmod-md-raid0 kmod-md-raid1 kmod-md-raid10 kmod-md-raid456 \ + kmod-fs-btrfs kmod-fs-cifs kmod-fs-nfs \ + kmod-fs-nfsd kmod-fs-ntfs kmod-fs-reiserfs kmod-fs-vfat \ + kmod-nls-utf8 kmod-usb-storage-extras \ + samba36-server mdadm cfdisk fdisk e2fsprogs badblocks + +define Device/dlink-dir-685 + DEVICE_TITLE := D-Link DIR-685 Xtreme N Storage Router + DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES) \ + kmod-switch-rtl8366rb swconfig + IMAGES += dir685-image + IMAGE/dir685-image := dir685-images +endef +TARGET_DEVICES += dlink-dir-685 + +define Device/dlink-dns-313 + DEVICE_TITLE := D-Link DNS-313 1-Bay Network Storage Enclosure + DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES) + IMAGES += dns313-image + IMAGE/dns313-image := dns313-images +endef +TARGET_DEVICES += dlink-dns-313 + +define Device/nas4220b + DEVICE_TITLE := Raidsonic NAS IB-4220-B + IMAGES += nas4220b-image + IMAGE/nas4220b-image := nas4220b-images + DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES) +endef +TARGET_DEVICES += nas4220b + +define Device/rut1xx + DEVICE_TITLE := Teltonika RUT1xx + DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES) +endef +TARGET_DEVICES += rut1xx + +define Device/sq201 + DEVICE_TITLE := ITian Square One SQ201 + DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES) rt61-pci-firmware +endef +TARGET_DEVICES += sq201 + +define Device/wbd111 + DEVICE_TITLE := Wiliboard WBD-111 + KERNEL := kernel-bin | append-dtb | wbd-nops +endef +TARGET_DEVICES += wbd111 + +define Device/wbd222 + DEVICE_TITLE := Wiliboard WBD-222 + KERNEL := kernel-bin | append-dtb | wbd-nops +endef +TARGET_DEVICES += wbd222 $(eval $(call BuildImage)) diff --git a/target/linux/gemini/patches-4.4/060-cache-fa.patch b/target/linux/gemini/patches-4.14/0001-cache-patch-from-OpenWRT.patch similarity index 79% rename from target/linux/gemini/patches-4.4/060-cache-fa.patch rename to target/linux/gemini/patches-4.14/0001-cache-patch-from-OpenWRT.patch index fc74c0af8..4430ffee9 100644 --- a/target/linux/gemini/patches-4.4/060-cache-fa.patch +++ b/target/linux/gemini/patches-4.14/0001-cache-patch-from-OpenWRT.patch @@ -1,3 +1,12 @@ +From 57615e112aba6ae4c831d50e769c2c102f013686 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Tue, 7 Jun 2016 22:53:24 +0200 +Subject: [PATCH 01/31] cache patch from OpenWRT + +--- + arch/arm/mm/cache-fa.S | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + --- a/arch/arm/mm/cache-fa.S +++ b/arch/arm/mm/cache-fa.S @@ -24,7 +24,8 @@ diff --git a/target/linux/gemini/patches-4.14/0002-pinctrl-gemini-Add-missing-functions.patch b/target/linux/gemini/patches-4.14/0002-pinctrl-gemini-Add-missing-functions.patch new file mode 100644 index 000000000..604fee469 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0002-pinctrl-gemini-Add-missing-functions.patch @@ -0,0 +1,33 @@ +From fd7823e6993f440930e9cb85e56375be5823485c Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sat, 14 Oct 2017 17:13:03 +0200 +Subject: [PATCH 02/31] pinctrl: gemini: Add missing functions + +Some two functions were missing from the Gemini pin control +driver. Noticed when trying to use ethernet. Fix it up by +adding them. + +Signed-off-by: Linus Walleij +--- + drivers/pinctrl/pinctrl-gemini.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -2074,6 +2074,16 @@ static const struct gemini_pmx_func gemi + .num_groups = ARRAY_SIZE(satagrps), + }, + { ++ .name = "usb", ++ .groups = usbgrps, ++ .num_groups = ARRAY_SIZE(usbgrps), ++ }, ++ { ++ .name = "gmii", ++ .groups = gmiigrps, ++ .num_groups = ARRAY_SIZE(gmiigrps), ++ }, ++ { + .name = "pci", + .groups = pcigrps, + .num_groups = ARRAY_SIZE(pcigrps), diff --git a/target/linux/gemini/patches-4.14/0003-ARM-dts-Add-TVE200-to-the-Gemini-SoC-DTSI.patch b/target/linux/gemini/patches-4.14/0003-ARM-dts-Add-TVE200-to-the-Gemini-SoC-DTSI.patch new file mode 100644 index 000000000..81d9788af --- /dev/null +++ b/target/linux/gemini/patches-4.14/0003-ARM-dts-Add-TVE200-to-the-Gemini-SoC-DTSI.patch @@ -0,0 +1,51 @@ +From 00e53d08bbe92051765c5bb94223b6f628cd3740 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Wed, 11 Oct 2017 19:45:19 +0200 +Subject: [PATCH 03/31] ARM: dts: Add TVE200 to the Gemini SoC DTSI + +The Faraday TVE200 is present in the Gemini SoC, sometimes +under the name "TVC". Add it to the SoC DTSI file along with +its resources. + +Signed-off-by: Linus Walleij +Signed-off-by: Arnd Bergmann +--- + arch/arm/boot/dts/gemini.dtsi | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/arch/arm/boot/dts/gemini.dtsi ++++ b/arch/arm/boot/dts/gemini.dtsi +@@ -142,6 +142,12 @@ + groups = "idegrp"; + }; + }; ++ tvc_default_pins: pinctrl-tvc { ++ mux { ++ function = "tvc"; ++ groups = "tvcgrp"; ++ }; ++ }; + }; + }; + +@@ -348,5 +354,20 @@ + memcpy-bus-width = <32>; + #dma-cells = <2>; + }; ++ ++ display-controller@6a000000 { ++ compatible = "cortina,gemini-tvc", "faraday,tve200"; ++ reg = <0x6a000000 0x1000>; ++ interrupts = <13 IRQ_TYPE_EDGE_RISING>; ++ resets = <&syscon GEMINI_RESET_TVC>; ++ clocks = <&syscon GEMINI_CLK_GATE_TVC>, ++ <&syscon GEMINI_CLK_TVC>; ++ clock-names = "PCLK", "TVE"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&tvc_default_pins>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; + }; + }; diff --git a/target/linux/gemini/patches-4.14/0004-pinctrl-Add-skew-delay-pin-config-and-bindings.patch b/target/linux/gemini/patches-4.14/0004-pinctrl-Add-skew-delay-pin-config-and-bindings.patch new file mode 100644 index 000000000..ac39a3282 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0004-pinctrl-Add-skew-delay-pin-config-and-bindings.patch @@ -0,0 +1,73 @@ +From eb3742c4250c6a79e7080bdb6286e5df50c7f26a Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sat, 28 Oct 2017 15:37:17 +0200 +Subject: [PATCH 04/31] pinctrl: Add skew-delay pin config and bindings + +Some pin controllers (such as the Gemini) can control the +expected clock skew and output delay on certain pins with a +sub-nanosecond granularity. This is typically done by shunting +in a number of double inverters in front of or behind the pin. +Make it possible to configure this with a generic binding. + +Cc: devicetree@vger.kernel.org +Acked-by: Rob Herring +Acked-by: Hans Ulli Kroll +Signed-off-by: Linus Walleij +--- + Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | 4 ++++ + drivers/pinctrl/pinconf-generic.c | 2 ++ + include/linux/pinctrl/pinconf-generic.h | 5 +++++ + 3 files changed, 11 insertions(+) + +--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt ++++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +@@ -271,6 +271,10 @@ output-high - set the pin to output mod + sleep-hardware-state - indicate this is sleep related state which will be programmed + into the registers for the sleep state. + slew-rate - set the slew rate ++skew-delay - this affects the expected clock skew on input pins ++ and the delay before latching a value to an output ++ pin. Typically indicates how many double-inverters are ++ used to delay the signal. + + For example: + +--- a/drivers/pinctrl/pinconf-generic.c ++++ b/drivers/pinctrl/pinconf-generic.c +@@ -49,6 +49,7 @@ static const struct pin_config_item conf + PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector", true), + PCONFDUMP(PIN_CONFIG_SLEEP_HARDWARE_STATE, "sleep hardware state", NULL, false), + PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL, true), ++ PCONFDUMP(PIN_CONFIG_SKEW_DELAY, "skew delay", NULL, true), + }; + + static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev, +@@ -181,6 +182,7 @@ static const struct pinconf_generic_para + { "power-source", PIN_CONFIG_POWER_SOURCE, 0 }, + { "sleep-hardware-state", PIN_CONFIG_SLEEP_HARDWARE_STATE, 0 }, + { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 }, ++ { "skew-delay", PIN_CONFIG_SKEW_DELAY, 0 }, + }; + + /** +--- a/include/linux/pinctrl/pinconf-generic.h ++++ b/include/linux/pinctrl/pinconf-generic.h +@@ -90,6 +90,10 @@ + * @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to + * this parameter (on a custom format) tells the driver which alternative + * slew rate to use. ++ * @PIN_CONFIG_SKEW_DELAY: if the pin has programmable skew rate (on inputs) ++ * or latch delay (on outputs) this parameter (in a custom format) ++ * specifies the clock skew or latch delay. It typically controls how ++ * many double inverters are put in front of the line. + * @PIN_CONFIG_END: this is the last enumerator for pin configurations, if + * you need to pass in custom configurations to the pin controller, use + * PIN_CONFIG_END+1 as the base offset. +@@ -117,6 +121,7 @@ enum pin_config_param { + PIN_CONFIG_POWER_SOURCE, + PIN_CONFIG_SLEEP_HARDWARE_STATE, + PIN_CONFIG_SLEW_RATE, ++ PIN_CONFIG_SKEW_DELAY, + PIN_CONFIG_END = 0x7F, + PIN_CONFIG_MAX = 0xFF, + }; diff --git a/target/linux/gemini/patches-4.14/0005-pinctrl-gemini-Use-generic-DT-parser.patch b/target/linux/gemini/patches-4.14/0005-pinctrl-gemini-Use-generic-DT-parser.patch new file mode 100644 index 000000000..5b0bba1cd --- /dev/null +++ b/target/linux/gemini/patches-4.14/0005-pinctrl-gemini-Use-generic-DT-parser.patch @@ -0,0 +1,112 @@ +From 09240ae27ffca65518f7b9d2360c020c1b1ddabe Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sat, 28 Oct 2017 15:37:18 +0200 +Subject: [PATCH 05/31] pinctrl: gemini: Use generic DT parser + +We can just use the generic Device Tree parser code +in this driver and save some code. + +Acked-by: Hans Ulli Kroll +Signed-off-by: Linus Walleij +--- + drivers/pinctrl/Kconfig | 1 + + drivers/pinctrl/pinctrl-gemini.c | 66 +++------------------------------------- + 2 files changed, 5 insertions(+), 62 deletions(-) + +--- a/drivers/pinctrl/Kconfig ++++ b/drivers/pinctrl/Kconfig +@@ -153,6 +153,7 @@ config PINCTRL_GEMINI + depends on ARCH_GEMINI + default ARCH_GEMINI + select PINMUX ++ select GENERIC_PINCONF + select MFD_SYSCON + + config PINCTRL_MCP23S08 +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -13,6 +13,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -1918,73 +1920,13 @@ static void gemini_pin_dbg_show(struct p + seq_printf(s, " " DRIVER_NAME); + } + +-static int gemini_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, +- struct device_node *np, +- struct pinctrl_map **map, +- unsigned int *reserved_maps, +- unsigned int *num_maps) +-{ +- int ret; +- const char *function = NULL; +- const char *group; +- struct property *prop; +- +- ret = of_property_read_string(np, "function", &function); +- if (ret < 0) +- return ret; +- +- ret = of_property_count_strings(np, "groups"); +- if (ret < 0) +- return ret; +- +- ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, +- num_maps, ret); +- if (ret < 0) +- return ret; +- +- of_property_for_each_string(np, "groups", prop, group) { +- ret = pinctrl_utils_add_map_mux(pctldev, map, reserved_maps, +- num_maps, group, function); +- if (ret < 0) +- return ret; +- pr_debug("ADDED FUNCTION %s <-> GROUP %s\n", +- function, group); +- } +- +- return 0; +-} +- +-static int gemini_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, +- struct device_node *np_config, +- struct pinctrl_map **map, +- unsigned int *num_maps) +-{ +- unsigned int reserved_maps = 0; +- struct device_node *np; +- int ret; +- +- *map = NULL; +- *num_maps = 0; +- +- for_each_child_of_node(np_config, np) { +- ret = gemini_pinctrl_dt_subnode_to_map(pctldev, np, map, +- &reserved_maps, num_maps); +- if (ret < 0) { +- pinctrl_utils_free_map(pctldev, *map, *num_maps); +- return ret; +- } +- } +- +- return 0; +-}; +- + static const struct pinctrl_ops gemini_pctrl_ops = { + .get_groups_count = gemini_get_groups_count, + .get_group_name = gemini_get_group_name, + .get_group_pins = gemini_get_group_pins, + .pin_dbg_show = gemini_pin_dbg_show, +- .dt_node_to_map = gemini_pinctrl_dt_node_to_map, +- .dt_free_map = pinctrl_utils_free_map, ++ .dt_node_to_map = pinconf_generic_dt_node_to_map_group, ++ .dt_free_map = pinconf_generic_dt_free_map, + }; + + /** diff --git a/target/linux/gemini/patches-4.14/0006-pinctrl-gemini-Implement-clock-skew-delay-config.patch b/target/linux/gemini/patches-4.14/0006-pinctrl-gemini-Implement-clock-skew-delay-config.patch new file mode 100644 index 000000000..4bff3bce9 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0006-pinctrl-gemini-Implement-clock-skew-delay-config.patch @@ -0,0 +1,280 @@ +From 43e8f011ddbb293e0a3394d0f39819ea2ead4a1b Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sat, 28 Oct 2017 15:37:19 +0200 +Subject: [PATCH 06/31] pinctrl: gemini: Implement clock skew/delay config + +This enabled pin config on the Gemini driver and implements +pin skew/delay so that the ethernet pins clocking can be +properly configured. + +Acked-by: Hans Ulli Kroll +Signed-off-by: Linus Walleij +--- + .../bindings/pinctrl/cortina,gemini-pinctrl.txt | 10 +- + drivers/pinctrl/pinctrl-gemini.c | 178 ++++++++++++++++++++- + 2 files changed, 182 insertions(+), 6 deletions(-) + +--- a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt ++++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt +@@ -9,8 +9,14 @@ The pin controller node must be a subnod + Required properties: + - compatible: "cortina,gemini-pinctrl" + +-Subnodes of the pin controller contain pin control multiplexing set-up. +-Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes. ++Subnodes of the pin controller contain pin control multiplexing set-up ++and pin configuration of individual pins. ++ ++Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes ++and generic pin config nodes. ++ ++Supported configurations: ++- skew-delay is supported on the Ethernet pins + + Example: + +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -24,6 +24,19 @@ + #define DRIVER_NAME "pinctrl-gemini" + + /** ++ * struct gemini_pin_conf - information about configuring a pin ++ * @pin: the pin number ++ * @reg: config register ++ * @mask: the bits affecting the configuration of the pin ++ */ ++struct gemini_pin_conf { ++ unsigned int pin; ++ u32 reg; ++ u32 mask; ++}; ++ ++/** ++ * struct gemini_pmx - state holder for the gemini pin controller + * @dev: a pointer back to containing device + * @virtbase: the offset to the controller in virtual memory + * @map: regmap to access registers +@@ -31,6 +44,8 @@ + * @is_3516: whether the SoC/package is the 3516 variant + * @flash_pin: whether the flash pin (extended pins for parallel + * flash) is set ++ * @confs: pin config information ++ * @nconfs: number of pin config information items + */ + struct gemini_pmx { + struct device *dev; +@@ -39,6 +54,8 @@ struct gemini_pmx { + bool is_3512; + bool is_3516; + bool flash_pin; ++ const struct gemini_pin_conf *confs; ++ unsigned int nconfs; + }; + + /** +@@ -59,6 +76,13 @@ struct gemini_pin_group { + u32 value; + }; + ++/* Some straight-forward control registers */ ++#define GLOBAL_WORD_ID 0x00 ++#define GLOBAL_STATUS 0x04 ++#define GLOBAL_STATUS_FLPIN BIT(20) ++#define GLOBAL_GMAC_CTRL_SKEW 0x1c ++#define GLOBAL_GMAC0_DATA_SKEW 0x20 ++#define GLOBAL_GMAC1_DATA_SKEW 0x24 + /* + * Global Miscellaneous Control Register + * This register controls all Gemini pad/pin multiplexing +@@ -71,9 +95,6 @@ struct gemini_pin_group { + * DISABLED again. So you select a flash configuration once, and then + * you are stuck with it. + */ +-#define GLOBAL_WORD_ID 0x00 +-#define GLOBAL_STATUS 0x04 +-#define GLOBAL_STATUS_FLPIN BIT(20) + #define GLOBAL_MISC_CTRL 0x30 + #define TVC_CLK_PAD_ENABLE BIT(20) + #define PCI_CLK_PAD_ENABLE BIT(17) +@@ -1925,7 +1946,7 @@ static const struct pinctrl_ops gemini_p + .get_group_name = gemini_get_group_name, + .get_group_pins = gemini_get_group_pins, + .pin_dbg_show = gemini_pin_dbg_show, +- .dt_node_to_map = pinconf_generic_dt_node_to_map_group, ++ .dt_node_to_map = pinconf_generic_dt_node_to_map_all, + .dt_free_map = pinconf_generic_dt_free_map, + }; + +@@ -2203,10 +2224,155 @@ static const struct pinmux_ops gemini_pm + .set_mux = gemini_pmx_set_mux, + }; + ++#define GEMINI_CFGPIN(_n, _r, _lb, _hb) { \ ++ .pin = _n, \ ++ .reg = _r, \ ++ .mask = GENMASK(_hb, _lb) \ ++} ++ ++static const struct gemini_pin_conf gemini_confs_3512[] = { ++ GEMINI_CFGPIN(259, GLOBAL_GMAC_CTRL_SKEW, 0, 3), /* GMAC0 RXDV */ ++ GEMINI_CFGPIN(277, GLOBAL_GMAC_CTRL_SKEW, 4, 7), /* GMAC0 RXC */ ++ GEMINI_CFGPIN(241, GLOBAL_GMAC_CTRL_SKEW, 8, 11), /* GMAC0 TXEN */ ++ GEMINI_CFGPIN(312, GLOBAL_GMAC_CTRL_SKEW, 12, 15), /* GMAC0 TXC */ ++ GEMINI_CFGPIN(298, GLOBAL_GMAC_CTRL_SKEW, 16, 19), /* GMAC1 RXDV */ ++ GEMINI_CFGPIN(280, GLOBAL_GMAC_CTRL_SKEW, 20, 23), /* GMAC1 RXC */ ++ GEMINI_CFGPIN(316, GLOBAL_GMAC_CTRL_SKEW, 24, 27), /* GMAC1 TXEN */ ++ GEMINI_CFGPIN(243, GLOBAL_GMAC_CTRL_SKEW, 28, 31), /* GMAC1 TXC */ ++ GEMINI_CFGPIN(295, GLOBAL_GMAC0_DATA_SKEW, 0, 3), /* GMAC0 RXD0 */ ++ GEMINI_CFGPIN(313, GLOBAL_GMAC0_DATA_SKEW, 4, 7), /* GMAC0 RXD1 */ ++ GEMINI_CFGPIN(242, GLOBAL_GMAC0_DATA_SKEW, 8, 11), /* GMAC0 RXD2 */ ++ GEMINI_CFGPIN(260, GLOBAL_GMAC0_DATA_SKEW, 12, 15), /* GMAC0 RXD3 */ ++ GEMINI_CFGPIN(294, GLOBAL_GMAC0_DATA_SKEW, 16, 19), /* GMAC0 TXD0 */ ++ GEMINI_CFGPIN(276, GLOBAL_GMAC0_DATA_SKEW, 20, 23), /* GMAC0 TXD1 */ ++ GEMINI_CFGPIN(258, GLOBAL_GMAC0_DATA_SKEW, 24, 27), /* GMAC0 TXD2 */ ++ GEMINI_CFGPIN(240, GLOBAL_GMAC0_DATA_SKEW, 28, 31), /* GMAC0 TXD3 */ ++ GEMINI_CFGPIN(262, GLOBAL_GMAC1_DATA_SKEW, 0, 3), /* GMAC1 RXD0 */ ++ GEMINI_CFGPIN(244, GLOBAL_GMAC1_DATA_SKEW, 4, 7), /* GMAC1 RXD1 */ ++ GEMINI_CFGPIN(317, GLOBAL_GMAC1_DATA_SKEW, 8, 11), /* GMAC1 RXD2 */ ++ GEMINI_CFGPIN(299, GLOBAL_GMAC1_DATA_SKEW, 12, 15), /* GMAC1 RXD3 */ ++ GEMINI_CFGPIN(261, GLOBAL_GMAC1_DATA_SKEW, 16, 19), /* GMAC1 TXD0 */ ++ GEMINI_CFGPIN(279, GLOBAL_GMAC1_DATA_SKEW, 20, 23), /* GMAC1 TXD1 */ ++ GEMINI_CFGPIN(297, GLOBAL_GMAC1_DATA_SKEW, 24, 27), /* GMAC1 TXD2 */ ++ GEMINI_CFGPIN(315, GLOBAL_GMAC1_DATA_SKEW, 28, 31), /* GMAC1 TXD3 */ ++}; ++ ++static const struct gemini_pin_conf gemini_confs_3516[] = { ++ GEMINI_CFGPIN(347, GLOBAL_GMAC_CTRL_SKEW, 0, 3), /* GMAC0 RXDV */ ++ GEMINI_CFGPIN(386, GLOBAL_GMAC_CTRL_SKEW, 4, 7), /* GMAC0 RXC */ ++ GEMINI_CFGPIN(307, GLOBAL_GMAC_CTRL_SKEW, 8, 11), /* GMAC0 TXEN */ ++ GEMINI_CFGPIN(327, GLOBAL_GMAC_CTRL_SKEW, 12, 15), /* GMAC0 TXC */ ++ GEMINI_CFGPIN(309, GLOBAL_GMAC_CTRL_SKEW, 16, 19), /* GMAC1 RXDV */ ++ GEMINI_CFGPIN(390, GLOBAL_GMAC_CTRL_SKEW, 20, 23), /* GMAC1 RXC */ ++ GEMINI_CFGPIN(370, GLOBAL_GMAC_CTRL_SKEW, 24, 27), /* GMAC1 TXEN */ ++ GEMINI_CFGPIN(350, GLOBAL_GMAC_CTRL_SKEW, 28, 31), /* GMAC1 TXC */ ++ GEMINI_CFGPIN(367, GLOBAL_GMAC0_DATA_SKEW, 0, 3), /* GMAC0 RXD0 */ ++ GEMINI_CFGPIN(348, GLOBAL_GMAC0_DATA_SKEW, 4, 7), /* GMAC0 RXD1 */ ++ GEMINI_CFGPIN(387, GLOBAL_GMAC0_DATA_SKEW, 8, 11), /* GMAC0 RXD2 */ ++ GEMINI_CFGPIN(328, GLOBAL_GMAC0_DATA_SKEW, 12, 15), /* GMAC0 RXD3 */ ++ GEMINI_CFGPIN(306, GLOBAL_GMAC0_DATA_SKEW, 16, 19), /* GMAC0 TXD0 */ ++ GEMINI_CFGPIN(325, GLOBAL_GMAC0_DATA_SKEW, 20, 23), /* GMAC0 TXD1 */ ++ GEMINI_CFGPIN(346, GLOBAL_GMAC0_DATA_SKEW, 24, 27), /* GMAC0 TXD2 */ ++ GEMINI_CFGPIN(326, GLOBAL_GMAC0_DATA_SKEW, 28, 31), /* GMAC0 TXD3 */ ++ GEMINI_CFGPIN(391, GLOBAL_GMAC1_DATA_SKEW, 0, 3), /* GMAC1 RXD0 */ ++ GEMINI_CFGPIN(351, GLOBAL_GMAC1_DATA_SKEW, 4, 7), /* GMAC1 RXD1 */ ++ GEMINI_CFGPIN(310, GLOBAL_GMAC1_DATA_SKEW, 8, 11), /* GMAC1 RXD2 */ ++ GEMINI_CFGPIN(371, GLOBAL_GMAC1_DATA_SKEW, 12, 15), /* GMAC1 RXD3 */ ++ GEMINI_CFGPIN(329, GLOBAL_GMAC1_DATA_SKEW, 16, 19), /* GMAC1 TXD0 */ ++ GEMINI_CFGPIN(389, GLOBAL_GMAC1_DATA_SKEW, 20, 23), /* GMAC1 TXD1 */ ++ GEMINI_CFGPIN(369, GLOBAL_GMAC1_DATA_SKEW, 24, 27), /* GMAC1 TXD2 */ ++ GEMINI_CFGPIN(308, GLOBAL_GMAC1_DATA_SKEW, 28, 31), /* GMAC1 TXD3 */ ++}; ++ ++static const struct gemini_pin_conf *gemini_get_pin_conf(struct gemini_pmx *pmx, ++ unsigned int pin) ++{ ++ const struct gemini_pin_conf *retconf; ++ int i; ++ ++ for (i = 0; i < pmx->nconfs; i++) { ++ retconf = &gemini_confs_3516[i]; ++ if (retconf->pin == pin) ++ return retconf; ++ } ++ return NULL; ++} ++ ++static int gemini_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, ++ unsigned long *config) ++{ ++ struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); ++ enum pin_config_param param = pinconf_to_config_param(*config); ++ const struct gemini_pin_conf *conf; ++ u32 val; ++ ++ switch (param) { ++ case PIN_CONFIG_SKEW_DELAY: ++ conf = gemini_get_pin_conf(pmx, pin); ++ if (!conf) ++ return -ENOTSUPP; ++ regmap_read(pmx->map, conf->reg, &val); ++ val &= conf->mask; ++ val >>= (ffs(conf->mask) - 1); ++ *config = pinconf_to_config_packed(PIN_CONFIG_SKEW_DELAY, val); ++ break; ++ default: ++ return -ENOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int gemini_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ++ unsigned long *configs, unsigned int num_configs) ++{ ++ struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); ++ const struct gemini_pin_conf *conf; ++ enum pin_config_param param; ++ u32 arg; ++ int ret = 0; ++ int i; ++ ++ for (i = 0; i < num_configs; i++) { ++ param = pinconf_to_config_param(configs[i]); ++ arg = pinconf_to_config_argument(configs[i]); ++ ++ switch (param) { ++ case PIN_CONFIG_SKEW_DELAY: ++ if (arg > 0xf) ++ return -EINVAL; ++ conf = gemini_get_pin_conf(pmx, pin); ++ if (!conf) { ++ dev_err(pmx->dev, ++ "invalid pin for skew delay %d\n", pin); ++ return -ENOTSUPP; ++ } ++ arg <<= (ffs(conf->mask) - 1); ++ dev_dbg(pmx->dev, ++ "set pin %d to skew delay mask %08x, val %08x\n", ++ pin, conf->mask, arg); ++ regmap_update_bits(pmx->map, conf->reg, conf->mask, arg); ++ break; ++ default: ++ dev_err(pmx->dev, "Invalid config param %04x\n", param); ++ return -ENOTSUPP; ++ } ++ } ++ ++ return ret; ++} ++ ++static const struct pinconf_ops gemini_pinconf_ops = { ++ .pin_config_get = gemini_pinconf_get, ++ .pin_config_set = gemini_pinconf_set, ++ .is_generic = true, ++}; ++ + static struct pinctrl_desc gemini_pmx_desc = { + .name = DRIVER_NAME, + .pctlops = &gemini_pctrl_ops, + .pmxops = &gemini_pmx_ops, ++ .confops = &gemini_pinconf_ops, + .owner = THIS_MODULE, + }; + +@@ -2249,11 +2415,15 @@ static int gemini_pmx_probe(struct platf + val &= 0xffff; + if (val == 0x3512) { + pmx->is_3512 = true; ++ pmx->confs = gemini_confs_3512; ++ pmx->nconfs = ARRAY_SIZE(gemini_confs_3512); + gemini_pmx_desc.pins = gemini_3512_pins; + gemini_pmx_desc.npins = ARRAY_SIZE(gemini_3512_pins); + dev_info(dev, "detected 3512 chip variant\n"); + } else if (val == 0x3516) { + pmx->is_3516 = true; ++ pmx->confs = gemini_confs_3516; ++ pmx->nconfs = ARRAY_SIZE(gemini_confs_3516); + gemini_pmx_desc.pins = gemini_3516_pins; + gemini_pmx_desc.npins = ARRAY_SIZE(gemini_3516_pins); + dev_info(dev, "detected 3516 chip variant\n"); diff --git a/target/linux/gemini/patches-4.14/0007-pinctrl-gemini-Fix-GMAC-groups.patch b/target/linux/gemini/patches-4.14/0007-pinctrl-gemini-Fix-GMAC-groups.patch new file mode 100644 index 000000000..902168ba6 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0007-pinctrl-gemini-Fix-GMAC-groups.patch @@ -0,0 +1,186 @@ +From e7759c44e0c20dd6b5a259300acdc7350ea6dd32 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Mon, 6 Nov 2017 21:27:34 +0100 +Subject: [PATCH 07/31] pinctrl: gemini: Fix GMAC groups + +The GMII groups need to be split across GMAC0 and GMAC1 since +GMAC0 is always available but GMAC1 masks GPIO2 lines 0-7 +so we might want just one interface out. + +Signed-off-by: Linus Walleij +--- + drivers/pinctrl/pinctrl-gemini.c | 79 +++++++++++++++++++++++++++------------- + 1 file changed, 54 insertions(+), 25 deletions(-) + +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -96,6 +96,13 @@ struct gemini_pin_group { + * you are stuck with it. + */ + #define GLOBAL_MISC_CTRL 0x30 ++#define GEMINI_GMAC_IOSEL_MASK GENMASK(28, 27) ++/* Not really used */ ++#define GEMINI_GMAC_IOSEL_GMAC0_GMII BIT(28) ++/* Activated with GMAC1 */ ++#define GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII BIT(27) ++/* This will be the default */ ++#define GEMINI_GMAC_IOSEL_GMAC0_RGMII_GMAC1_GPIO2 0 + #define TVC_CLK_PAD_ENABLE BIT(20) + #define PCI_CLK_PAD_ENABLE BIT(17) + #define LPC_CLK_PAD_ENABLE BIT(16) +@@ -109,8 +116,8 @@ struct gemini_pin_group { + #define NAND_PADS_DISABLE BIT(2) + #define PFLASH_PADS_DISABLE BIT(1) + #define SFLASH_PADS_DISABLE BIT(0) +-#define PADS_MASK (GENMASK(9, 0) | BIT(16) | BIT(17) | BIT(20)) +-#define PADS_MAXBIT 20 ++#define PADS_MASK (GENMASK(9, 0) | BIT(16) | BIT(17) | BIT(20) | BIT(27)) ++#define PADS_MAXBIT 27 + + /* Ordered by bit index */ + static const char * const gemini_padgroups[] = { +@@ -516,9 +523,12 @@ static const unsigned int usb_3512_pins[ + }; + + /* GMII, ethernet pins */ +-static const unsigned int gmii_3512_pins[] = { +- 311, 240, 258, 276, 294, 312, 241, 259, 277, 295, 313, 242, 260, 278, 296, +- 315, 297, 279, 261, 243, 316, 298, 280, 262, 244, 317, 299, 281 ++static const unsigned int gmii_gmac0_3512_pins[] = { ++ 240, 241, 242, 258, 259, 260, 276, 277, 278, 294, 295, 311, 312, 313 ++}; ++ ++static const unsigned int gmii_gmac1_3512_pins[] = { ++ 243, 244, 261, 262, 279, 280, 281, 296, 297, 298, 299, 315, 316, 317 + }; + + static const unsigned int pci_3512_pins[] = { +@@ -668,10 +678,10 @@ static const unsigned int gpio1c_3512_pi + /* The GPIO1D (28-31) pins overlap with LCD and TVC */ + static const unsigned int gpio1d_3512_pins[] = { 246, 319, 301, 283 }; + +-/* The GPIO2A (0-3) pins overlap with GMII and extended parallel flash */ ++/* The GPIO2A (0-3) pins overlap with GMII GMAC1 and extended parallel flash */ + static const unsigned int gpio2a_3512_pins[] = { 315, 297, 279, 261 }; + +-/* The GPIO2B (4-7) pins overlap with GMII, extended parallel flash and LCD */ ++/* The GPIO2B (4-7) pins overlap with GMII GMAC1, extended parallel flash and LCD */ + static const unsigned int gpio2b_3512_pins[] = { 262, 244, 317, 299 }; + + /* The GPIO2C (8-31) pins overlap with PCI */ +@@ -738,9 +748,16 @@ static const struct gemini_pin_group gem + .num_pins = ARRAY_SIZE(usb_3512_pins), + }, + { +- .name = "gmiigrp", +- .pins = gmii_3512_pins, +- .num_pins = ARRAY_SIZE(gmii_3512_pins), ++ .name = "gmii_gmac0_grp", ++ .pins = gmii_gmac0_3512_pins, ++ .num_pins = ARRAY_SIZE(gmii_gmac0_3512_pins), ++ }, ++ { ++ .name = "gmii_gmac1_grp", ++ .pins = gmii_gmac1_3512_pins, ++ .num_pins = ARRAY_SIZE(gmii_gmac1_3512_pins), ++ /* Bring out RGMII on the GMAC1 pins */ ++ .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, + }, + { + .name = "pcigrp", +@@ -954,14 +971,15 @@ static const struct gemini_pin_group gem + .name = "gpio2agrp", + .pins = gpio2a_3512_pins, + .num_pins = ARRAY_SIZE(gpio2a_3512_pins), +- /* Conflict with GMII and extended parallel flash */ ++ .mask = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, ++ /* Conflict with GMII GMAC1 and extended parallel flash */ + }, + { + .name = "gpio2bgrp", + .pins = gpio2b_3512_pins, + .num_pins = ARRAY_SIZE(gpio2b_3512_pins), +- /* Conflict with GMII, extended parallel flash and LCD */ +- .mask = LCD_PADS_ENABLE, ++ /* Conflict with GMII GMAC1, extended parallel flash and LCD */ ++ .mask = LCD_PADS_ENABLE | GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, + }, + { + .name = "gpio2cgrp", +@@ -1441,9 +1459,12 @@ static const unsigned int usb_3516_pins[ + }; + + /* GMII, ethernet pins */ +-static const unsigned int gmii_3516_pins[] = { +- 306, 307, 308, 309, 310, 325, 326, 327, 328, 329, 330, 345, 346, 347, +- 348, 349, 350, 351, 367, 368, 369, 370, 371, 386, 387, 389, 390, 391 ++static const unsigned int gmii_gmac0_3516_pins[] = { ++ 306, 307, 325, 326, 327, 328, 345, 346, 347, 348, 367, 368, 386, 387 ++}; ++ ++static const unsigned int gmii_gmac1_3516_pins[] = { ++ 308, 309, 310, 329, 330, 349, 350, 351, 369, 370, 371, 389, 390, 391 + }; + + static const unsigned int pci_3516_pins[] = { +@@ -1585,10 +1606,10 @@ static const unsigned int gpio1c_3516_pi + /* The GPIO1D (28-31) pins overlap with TVC */ + static const unsigned int gpio1d_3516_pins[] = { 353, 311, 394, 374 }; + +-/* The GPIO2A (0-3) pins overlap with GMII and extended parallel flash */ ++/* The GPIO2A (0-3) pins overlap with GMII GMAC1 and extended parallel flash */ + static const unsigned int gpio2a_3516_pins[] = { 308, 369, 389, 329 }; + +-/* The GPIO2B (4-7) pins overlap with GMII, extended parallel flash and LCD */ ++/* The GPIO2B (4-7) pins overlap with GMII GMAC1, extended parallel flash and LCD */ + static const unsigned int gpio2b_3516_pins[] = { 391, 351, 310, 371 }; + + /* The GPIO2C (8-31) pins overlap with PCI */ +@@ -1660,9 +1681,16 @@ static const struct gemini_pin_group gem + .num_pins = ARRAY_SIZE(usb_3516_pins), + }, + { +- .name = "gmiigrp", +- .pins = gmii_3516_pins, +- .num_pins = ARRAY_SIZE(gmii_3516_pins), ++ .name = "gmii_gmac0_grp", ++ .pins = gmii_gmac0_3516_pins, ++ .num_pins = ARRAY_SIZE(gmii_gmac0_3516_pins), ++ }, ++ { ++ .name = "gmii_gmac1_grp", ++ .pins = gmii_gmac1_3516_pins, ++ .num_pins = ARRAY_SIZE(gmii_gmac1_3516_pins), ++ /* Bring out RGMII on the GMAC1 pins */ ++ .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, + }, + { + .name = "pcigrp", +@@ -1861,14 +1889,15 @@ static const struct gemini_pin_group gem + .name = "gpio2agrp", + .pins = gpio2a_3516_pins, + .num_pins = ARRAY_SIZE(gpio2a_3516_pins), +- /* Conflict with GMII and extended parallel flash */ ++ .mask = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, ++ /* Conflict with GMII GMAC1 and extended parallel flash */ + }, + { + .name = "gpio2bgrp", + .pins = gpio2b_3516_pins, + .num_pins = ARRAY_SIZE(gpio2b_3516_pins), +- /* Conflict with GMII, extended parallel flash and LCD */ +- .mask = LCD_PADS_ENABLE, ++ /* Conflict with GMII GMAC1, extended parallel flash and LCD */ ++ .mask = LCD_PADS_ENABLE | GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, + }, + { + .name = "gpio2cgrp", +@@ -1971,7 +2000,7 @@ static const char * const icegrps[] = { + static const char * const idegrps[] = { "idegrp" }; + static const char * const satagrps[] = { "satagrp" }; + static const char * const usbgrps[] = { "usbgrp" }; +-static const char * const gmiigrps[] = { "gmiigrp" }; ++static const char * const gmiigrps[] = { "gmii_gmac0_grp", "gmii_gmac1_grp" }; + static const char * const pcigrps[] = { "pcigrp" }; + static const char * const lpcgrps[] = { "lpcgrp" }; + static const char * const lcdgrps[] = { "lcdgrp" }; diff --git a/target/linux/gemini/patches-4.14/0008-pinctrl-gemini-Fix-missing-pad-descriptions.patch b/target/linux/gemini/patches-4.14/0008-pinctrl-gemini-Fix-missing-pad-descriptions.patch new file mode 100644 index 000000000..2d7ed8304 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0008-pinctrl-gemini-Fix-missing-pad-descriptions.patch @@ -0,0 +1,27 @@ +From 3f2941cb12a6d6a0ef4e53e0ecb8d2431d352964 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Mon, 13 Nov 2017 22:36:12 +0100 +Subject: [PATCH 08/31] pinctrl: gemini: Fix missing pad descriptions + +A pretty clever static checker found a bug in my patch: I added more +bits to a bitmask but didn't extend the array indexed to the same +bitmask. + +Fixes: 756a024f3983 ("pinctrl: gemini: Fix GMAC groups") +Reported-by: Dan Carpenter +Signed-off-by: Linus Walleij +--- + drivers/pinctrl/pinctrl-gemini.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -136,6 +136,8 @@ static const char * const gemini_padgrou + "PCI CLK", + NULL, NULL, + "TVC CLK", ++ NULL, NULL, NULL, NULL, NULL, ++ "GMAC1", + }; + + static const struct pinctrl_pin_desc gemini_3512_pins[] = { diff --git a/target/linux/gemini/patches-4.14/0009-pinctrl-gemini-Add-two-missing-GPIO-groups.patch b/target/linux/gemini/patches-4.14/0009-pinctrl-gemini-Add-two-missing-GPIO-groups.patch new file mode 100644 index 000000000..46fc102c1 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0009-pinctrl-gemini-Add-two-missing-GPIO-groups.patch @@ -0,0 +1,25 @@ +From c25653d045ce86c5ae472258fdaa39a6baaf75eb Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sun, 19 Nov 2017 10:57:27 +0100 +Subject: [PATCH 09/31] pinctrl: gemini: Add two missing GPIO groups + +The 3512 has two more GPIO groups on GPIO area 0, so let's +make it possible to combine these with the function. + +Signed-off-by: Linus Walleij +--- + drivers/pinctrl/pinctrl-gemini.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -2015,7 +2015,8 @@ static const char * const sflashgrps[] = + static const char * const gpio0grps[] = { "gpio0agrp", "gpio0bgrp", "gpio0cgrp", + "gpio0dgrp", "gpio0egrp", "gpio0fgrp", + "gpio0ggrp", "gpio0hgrp", "gpio0igrp", +- "gpio0jgrp", "gpio0kgrp" }; ++ "gpio0jgrp", "gpio0kgrp", "gpio0lgrp", ++ "gpio0mgrp" }; + static const char * const gpio1grps[] = { "gpio1agrp", "gpio1bgrp", "gpio1cgrp", + "gpio1dgrp" }; + static const char * const gpio2grps[] = { "gpio2agrp", "gpio2bgrp", "gpio2cgrp" }; diff --git a/target/linux/gemini/patches-4.14/0010-pinctrl-gemini-Fix-usage-of-3512-groups.patch b/target/linux/gemini/patches-4.14/0010-pinctrl-gemini-Fix-usage-of-3512-groups.patch new file mode 100644 index 000000000..1cab269a6 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0010-pinctrl-gemini-Fix-usage-of-3512-groups.patch @@ -0,0 +1,25 @@ +From 88a5c6ad311588f178c5a88e4eeacc6d40b8ede3 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Wed, 22 Nov 2017 21:04:14 +0100 +Subject: [PATCH 10/31] pinctrl: gemini: Fix usage of 3512 groups + +The pin config lookup function was still hardcoding the +3516 pin set, which is obviously wrong. Use the pointer +in the state container. + +Signed-off-by: Linus Walleij +--- + drivers/pinctrl/pinctrl-gemini.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -2323,7 +2323,7 @@ static const struct gemini_pin_conf *gem + int i; + + for (i = 0; i < pmx->nconfs; i++) { +- retconf = &gemini_confs_3516[i]; ++ retconf = &pmx->confs[i]; + if (retconf->pin == pin) + return retconf; + } diff --git a/target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch b/target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch new file mode 100644 index 000000000..5fefece49 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch @@ -0,0 +1,198 @@ +From f147cf49ef39f5e87d5df9ef1fab52683bc75c63 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sat, 2 Dec 2017 12:23:09 +0100 +Subject: [PATCH 11/31] pinctrl: gemini: Support drive strength setting + +The Gemini pin controller can set drive strength for a few +select groups of pins (not individually). Implement this +for GMAC0 and 1 (ethernet ports), IDE and PCI. + +Cc: devicetree@vger.kernel.org +Reviewed-by: Rob Herring +Signed-off-by: Linus Walleij +--- + .../bindings/pinctrl/cortina,gemini-pinctrl.txt | 3 + + drivers/pinctrl/pinctrl-gemini.c | 81 ++++++++++++++++++++++ + 2 files changed, 84 insertions(+) + +--- a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt ++++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt +@@ -17,6 +17,9 @@ and generic pin config nodes. + + Supported configurations: + - skew-delay is supported on the Ethernet pins ++- drive-strength with 4, 8, 12 or 16 mA as argument is supported for ++ entire groups on the groups "idegrp", "gmii_gmac0_grp", "gmii_gmac1_grp" ++ and "pcigrp". + + Example: + +--- a/drivers/pinctrl/pinctrl-gemini.c ++++ b/drivers/pinctrl/pinctrl-gemini.c +@@ -67,6 +67,9 @@ struct gemini_pmx { + * elements in .pins so we can iterate over that array + * @mask: bits to clear to enable this when doing pin muxing + * @value: bits to set to enable this when doing pin muxing ++ * @driving_mask: bitmask for the IO Pad driving register for this ++ * group, if it supports altering the driving strength of ++ * its lines. + */ + struct gemini_pin_group { + const char *name; +@@ -74,12 +77,14 @@ struct gemini_pin_group { + const unsigned int num_pins; + u32 mask; + u32 value; ++ u32 driving_mask; + }; + + /* Some straight-forward control registers */ + #define GLOBAL_WORD_ID 0x00 + #define GLOBAL_STATUS 0x04 + #define GLOBAL_STATUS_FLPIN BIT(20) ++#define GLOBAL_IODRIVE 0x10 + #define GLOBAL_GMAC_CTRL_SKEW 0x1c + #define GLOBAL_GMAC0_DATA_SKEW 0x20 + #define GLOBAL_GMAC1_DATA_SKEW 0x24 +@@ -738,6 +743,7 @@ static const struct gemini_pin_group gem + /* Conflict with all flash usage */ + .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE | + PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE, ++ .driving_mask = GENMASK(21, 20), + }, + { + .name = "satagrp", +@@ -753,6 +759,7 @@ static const struct gemini_pin_group gem + .name = "gmii_gmac0_grp", + .pins = gmii_gmac0_3512_pins, + .num_pins = ARRAY_SIZE(gmii_gmac0_3512_pins), ++ .driving_mask = GENMASK(17, 16), + }, + { + .name = "gmii_gmac1_grp", +@@ -760,6 +767,7 @@ static const struct gemini_pin_group gem + .num_pins = ARRAY_SIZE(gmii_gmac1_3512_pins), + /* Bring out RGMII on the GMAC1 pins */ + .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, ++ .driving_mask = GENMASK(19, 18), + }, + { + .name = "pcigrp", +@@ -767,6 +775,7 @@ static const struct gemini_pin_group gem + .num_pins = ARRAY_SIZE(pci_3512_pins), + /* Conflict only with GPIO2 */ + .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE, ++ .driving_mask = GENMASK(23, 22), + }, + { + .name = "lpcgrp", +@@ -1671,6 +1680,7 @@ static const struct gemini_pin_group gem + /* Conflict with all flash usage */ + .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE | + PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE, ++ .driving_mask = GENMASK(21, 20), + }, + { + .name = "satagrp", +@@ -1686,6 +1696,7 @@ static const struct gemini_pin_group gem + .name = "gmii_gmac0_grp", + .pins = gmii_gmac0_3516_pins, + .num_pins = ARRAY_SIZE(gmii_gmac0_3516_pins), ++ .driving_mask = GENMASK(17, 16), + }, + { + .name = "gmii_gmac1_grp", +@@ -1693,6 +1704,7 @@ static const struct gemini_pin_group gem + .num_pins = ARRAY_SIZE(gmii_gmac1_3516_pins), + /* Bring out RGMII on the GMAC1 pins */ + .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, ++ .driving_mask = GENMASK(19, 18), + }, + { + .name = "pcigrp", +@@ -1700,6 +1712,7 @@ static const struct gemini_pin_group gem + .num_pins = ARRAY_SIZE(pci_3516_pins), + /* Conflict only with GPIO2 */ + .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE, ++ .driving_mask = GENMASK(23, 22), + }, + { + .name = "lpcgrp", +@@ -2394,9 +2407,77 @@ static int gemini_pinconf_set(struct pin + return ret; + } + ++static int gemini_pinconf_group_set(struct pinctrl_dev *pctldev, ++ unsigned selector, ++ unsigned long *configs, ++ unsigned num_configs) ++{ ++ struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); ++ const struct gemini_pin_group *grp = NULL; ++ enum pin_config_param param; ++ u32 arg; ++ u32 val; ++ int i; ++ ++ if (pmx->is_3512) ++ grp = &gemini_3512_pin_groups[selector]; ++ if (pmx->is_3516) ++ grp = &gemini_3516_pin_groups[selector]; ++ ++ /* First figure out if this group supports configs */ ++ if (!grp->driving_mask) { ++ dev_err(pmx->dev, "pin config group \"%s\" does " ++ "not support drive strength setting\n", ++ grp->name); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < num_configs; i++) { ++ param = pinconf_to_config_param(configs[i]); ++ arg = pinconf_to_config_argument(configs[i]); ++ ++ switch (param) { ++ case PIN_CONFIG_DRIVE_STRENGTH: ++ switch (arg) { ++ case 4: ++ val = 0; ++ break; ++ case 8: ++ val = 1; ++ break; ++ case 12: ++ val = 2; ++ break; ++ case 16: ++ val = 3; ++ break; ++ default: ++ dev_err(pmx->dev, ++ "invalid drive strength %d mA\n", ++ arg); ++ return -ENOTSUPP; ++ } ++ val <<= (ffs(grp->driving_mask) - 1); ++ 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); ++ break; ++ default: ++ dev_err(pmx->dev, "invalid config param %04x\n", param); ++ return -ENOTSUPP; ++ } ++ } ++ ++ return 0; ++} ++ + static const struct pinconf_ops gemini_pinconf_ops = { + .pin_config_get = gemini_pinconf_get, + .pin_config_set = gemini_pinconf_set, ++ .pin_config_group_set = gemini_pinconf_group_set, + .is_generic = true, + }; + diff --git a/target/linux/gemini/patches-4.14/0012-ARM-dts-Add-ethernet-PHYs-to-the-a-bunch-of-Geminis.patch b/target/linux/gemini/patches-4.14/0012-ARM-dts-Add-ethernet-PHYs-to-the-a-bunch-of-Geminis.patch new file mode 100644 index 000000000..db701e3e9 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0012-ARM-dts-Add-ethernet-PHYs-to-the-a-bunch-of-Geminis.patch @@ -0,0 +1,113 @@ +From f0674df220f3da81c173025636a904b395cf8f8b Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sun, 19 Nov 2017 10:46:16 +0100 +Subject: [PATCH 12/31] ARM: dts: Add ethernet PHYs to the a bunch of Geminis + +These Gemini boards have Ethernet PHY on GPIO bit-banged +MDIO, clearly defined in the corresponding OpenWRT +ethernet patches since ages. Add them in accordance with +the OpenWRT patch so we can use them when we add ethernet +support. + +Reviewed-by: Andrew Lunn +Signed-off-by: Linus Walleij +--- + arch/arm/boot/dts/gemini-nas4220b.dts | 13 +++++++++++++ + arch/arm/boot/dts/gemini-rut1xx.dts | 13 +++++++++++++ + arch/arm/boot/dts/gemini-wbd111.dts | 13 +++++++++++++ + arch/arm/boot/dts/gemini-wbd222.dts | 18 ++++++++++++++++++ + 4 files changed, 57 insertions(+) + +--- a/arch/arm/boot/dts/gemini-nas4220b.dts ++++ b/arch/arm/boot/dts/gemini-nas4220b.dts +@@ -64,6 +64,19 @@ + }; + }; + ++ mdio0: ethernet-phy { ++ compatible = "virtual,mdio-gpio"; ++ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ ++ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ device_type = "ethernet-phy"; ++ }; ++ }; ++ + soc { + flash@30000000 { + status = "okay"; +--- a/arch/arm/boot/dts/gemini-rut1xx.dts ++++ b/arch/arm/boot/dts/gemini-rut1xx.dts +@@ -58,6 +58,19 @@ + }; + }; + ++ mdio0: ethernet-phy { ++ compatible = "virtual,mdio-gpio"; ++ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ ++ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ device_type = "ethernet-phy"; ++ }; ++ }; ++ + soc { + flash@30000000 { + status = "okay"; +--- a/arch/arm/boot/dts/gemini-wbd111.dts ++++ b/arch/arm/boot/dts/gemini-wbd111.dts +@@ -69,6 +69,19 @@ + }; + }; + ++ mdio0: ethernet-phy { ++ compatible = "virtual,mdio-gpio"; ++ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ ++ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ device_type = "ethernet-phy"; ++ }; ++ }; ++ + soc { + flash@30000000 { + status = "okay"; +--- a/arch/arm/boot/dts/gemini-wbd222.dts ++++ b/arch/arm/boot/dts/gemini-wbd222.dts +@@ -69,6 +69,24 @@ + }; + }; + ++ mdio0: ethernet-phy { ++ compatible = "virtual,mdio-gpio"; ++ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ ++ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ device_type = "ethernet-phy"; ++ }; ++ ++ phy1: ethernet-phy@3 { ++ reg = <3>; ++ device_type = "ethernet-phy"; ++ }; ++ }; ++ + soc { + flash@30000000 { + status = "okay"; diff --git a/target/linux/gemini/patches-4.14/0013-ARM-dts-Add-basic-devicetree-for-D-Link-DNS-313.patch b/target/linux/gemini/patches-4.14/0013-ARM-dts-Add-basic-devicetree-for-D-Link-DNS-313.patch new file mode 100644 index 000000000..cdf25a925 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0013-ARM-dts-Add-basic-devicetree-for-D-Link-DNS-313.patch @@ -0,0 +1,272 @@ +From 2f08de94f207a4347053e1faa22c9a310c9c61b0 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Fri, 17 Nov 2017 16:36:32 +0100 +Subject: [PATCH 13/31] ARM: dts: Add basic devicetree for D-Link DNS-313 + +This adds a basic device tree for the D-Link DNS-313 +NAS enclosure. This device has a thermal sensor and a +fan so we add a thermal zone for the chassis in the +device tree based on information from the product. + +Reviewed-by: Andrew Lunn +Signed-off-by: Linus Walleij +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/gemini-dlink-dns-313.dts | 241 +++++++++++++++++++++++++++++ + 2 files changed, 242 insertions(+) + create mode 100644 arch/arm/boot/dts/gemini-dlink-dns-313.dts + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -185,6 +185,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \ + exynos5800-peach-pi.dtb + dtb-$(CONFIG_ARCH_GEMINI) += \ + gemini-dlink-dir-685.dtb \ ++ gemini-dlink-dns-313.dtb \ + gemini-nas4220b.dtb \ + gemini-rut1xx.dtb \ + gemini-sq201.dtb \ +--- /dev/null ++++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts +@@ -0,0 +1,241 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Device Tree file for D-Link DNS-313 1-Bay Network Storage Enclosure ++ */ ++ ++/dts-v1/; ++ ++#include "gemini.dtsi" ++#include ++#include ++ ++/ { ++ model = "D-Link DNS-313 1-Bay Network Storage Enclosure"; ++ compatible = "dlink,dir-313", "cortina,gemini"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ memory { ++ /* 64 MB SDRAM in a Nanya NT5DS32M16BS-6K package */ ++ device_type = "memory"; ++ reg = <0x00000000 0x4000000>; ++ }; ++ ++ aliases { ++ mdio-gpio0 = &mdio0; ++ }; ++ ++ chosen { ++ stdout-path = "uart0:19200n8"; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ button-esc { ++ debounce_interval = <50>; ++ wakeup-source; ++ linux,code = ; ++ label = "reset"; ++ gpios = <&gpio1 31 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ led-power { ++ label = "dns313:blue:power"; ++ gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ linux,default-trigger = "heartbeat"; ++ }; ++ led-disk-blue { ++ label = "dns313:blue:disk"; ++ gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ led-disk-green { ++ label = "dns313:green:disk"; ++ gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ linux,default-trigger = "ide-disk"; ++ /* Ideally should activate while reading */ ++ }; ++ led-disk-red { ++ label = "dns313:red:disk"; ++ gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ /* Ideally should activate while writing */ ++ }; ++ }; ++ ++ /* ++ * This is a ADDA AD0405GB-G73 fan @3000 and 6000 RPM. ++ */ ++ fan0: gpio-fan { ++ compatible = "gpio-fan"; ++ gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>, ++ <&gpio0 12 GPIO_ACTIVE_HIGH>; ++ gpio-fan,speed-map = <0 0>, <3000 1>, <6000 2>; ++ cooling-min-level = <0>; ++ cooling-max-level = <2>; ++ #cooling-cells = <2>; ++ }; ++ ++ ++ /* Global Mixed-Mode Technology G751 mounted on GPIO I2C */ ++ gpio-i2c { ++ compatible = "i2c-gpio"; ++ sda-gpios = <&gpio0 15 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; ++ scl-gpios = <&gpio0 16 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ g751: temperature-sensor@48 { ++ compatible = "gmt,g751"; ++ reg = <0x48>; ++ #thermal-sensor-cells = <0>; ++ }; ++ }; ++ ++ thermal-zones { ++ chassis-thermal { ++ /* Poll every 20 seconds */ ++ polling-delay = <20000>; ++ /* Poll every 2nd second when cooling */ ++ polling-delay-passive = <2000>; ++ ++ thermal-sensors = <&g751>; ++ ++ /* Tripping points from the fan.script in the rootfs */ ++ trips { ++ chassis_alert0: chassis-alert0 { ++ /* At 43 degrees turn on low speed */ ++ temperature = <43000>; ++ hysteresis = <3000>; ++ type = "active"; ++ }; ++ chassis_alert1: chassis-alert1 { ++ /* At 47 degrees turn on high speed */ ++ temperature = <47000>; ++ hysteresis = <3000>; ++ type = "active"; ++ }; ++ chassis_crit: chassis-crit { ++ /* Just shut down at 60 degrees */ ++ temperature = <60000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&chassis_alert0>; ++ cooling-device = <&fan0 1 1>; ++ }; ++ map1 { ++ trip = <&chassis_alert1>; ++ cooling-device = <&fan0 2 2>; ++ }; ++ }; ++ }; ++ }; ++ ++ mdio0: ethernet-phy { ++ compatible = "virtual,mdio-gpio"; ++ /* Uses MDC and MDIO */ ++ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ ++ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* This is a Realtek RTL8211B Gigabit ethernet transceiver */ ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ device_type = "ethernet-phy"; ++ }; ++ }; ++ ++ soc { ++ flash@30000000 { ++ status = "okay"; ++ /* 512KB of flash */ ++ reg = <0x30000000 0x00080000>; ++ ++ /* ++ * This "RedBoot" is the Storlink derivative. ++ */ ++ partition@0 { ++ label = "RedBoot"; ++ reg = <0x00000000 0x00040000>; ++ read-only; ++ }; ++ partition@40000 { ++ label = "MTD1"; ++ reg = <0x00040000 0x00020000>; ++ read-only; ++ }; ++ partition@60000 { ++ label = "MTD2"; ++ reg = <0x00060000 0x00020000>; ++ read-only; ++ }; ++ }; ++ ++ syscon: syscon@40000000 { ++ pinctrl { ++ /* ++ */ ++ gpio0_default_pins: pinctrl-gpio0 { ++ mux { ++ function = "gpio0"; ++ groups = ++ /* Used by LEDs conflicts ICE */ ++ "gpio0bgrp", ++ /* Used by ? conflicts ICE */ ++ "gpio0cgrp", ++ /* ++ * Used by fan & G751, conflicts LPC, ++ * UART modem lines, SSP ++ */ ++ "gpio0egrp", ++ /* Used by G751 */ ++ "gpio0fgrp", ++ /* Used by MDIO */ ++ "gpio0igrp"; ++ }; ++ }; ++ gpio1_default_pins: pinctrl-gpio1 { ++ mux { ++ function = "gpio1"; ++ /* Used by "reset" button */ ++ groups = "gpio1dgrp"; ++ }; ++ }; ++ }; ++ }; ++ ++ sata: sata@46000000 { ++ /* The ROM uses this muxmode */ ++ cortina,gemini-ata-muxmode = <3>; ++ cortina,gemini-enable-sata-bridge; ++ status = "okay"; ++ }; ++ ++ gpio0: gpio@4d000000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio0_default_pins>; ++ }; ++ ++ gpio1: gpio@4e000000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio1_default_pins>; ++ }; ++ ++ ata@63000000 { ++ status = "okay"; ++ }; ++ }; ++}; diff --git a/target/linux/gemini/patches-4.14/0014-ARM-dts-Flags-D-Link-DIR-685-I2C-bus-gpios.patch b/target/linux/gemini/patches-4.14/0014-ARM-dts-Flags-D-Link-DIR-685-I2C-bus-gpios.patch new file mode 100644 index 000000000..5cefd18aa --- /dev/null +++ b/target/linux/gemini/patches-4.14/0014-ARM-dts-Flags-D-Link-DIR-685-I2C-bus-gpios.patch @@ -0,0 +1,27 @@ +From eed839dc713fdb7b2579dbfea41d676386b8259b Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sun, 10 Sep 2017 20:02:33 +0200 +Subject: [PATCH 14/31] ARM: dts: Flags D-Link DIR-685 I2C bus gpios + +These GPIOs are used in open drain mode, so make sure to +flag them as such. Use the new separate scl/sda line +GPIO bindings. + +Signed-off-by: Linus Walleij +--- + arch/arm/boot/dts/gemini-dlink-dir-685.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -99,8 +99,8 @@ + gpio-i2c { + compatible = "i2c-gpio"; + /* Collides with ICE */ +- gpios = <&gpio0 5 0>, /* SDA */ +- <&gpio0 6 0>; /* SCL */ ++ sda-gpios = <&gpio0 5 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; ++ scl-gpios = <&gpio0 6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + #address-cells = <1>; + #size-cells = <0>; + diff --git a/target/linux/gemini/patches-4.14/0015-ARM-dts-Add-PCI-to-WBD111-and-WBD222.patch b/target/linux/gemini/patches-4.14/0015-ARM-dts-Add-PCI-to-WBD111-and-WBD222.patch new file mode 100644 index 000000000..429625ed2 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0015-ARM-dts-Add-PCI-to-WBD111-and-WBD222.patch @@ -0,0 +1,74 @@ +From dec551d2301f71a692ed1729a323c8259d36f849 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Wed, 11 Oct 2017 19:49:13 +0200 +Subject: [PATCH 15/31] ARM: dts: Add PCI to WBD111 and WBD222 + +These two boards have mini-PCI card slots, so enable PCI +on both of them. + +Signed-off-by: Linus Walleij +--- + arch/arm/boot/dts/gemini-wbd111.dts | 22 ++++++++++++++++++++++ + arch/arm/boot/dts/gemini-wbd222.dts | 22 ++++++++++++++++++++++ + 2 files changed, 44 insertions(+) + +--- a/arch/arm/boot/dts/gemini-wbd111.dts ++++ b/arch/arm/boot/dts/gemini-wbd111.dts +@@ -138,5 +138,27 @@ + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; ++ ++ pci@50000000 { ++ status = "okay"; ++ interrupt-map-mask = <0xf800 0 0 7>; ++ interrupt-map = ++ <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */ ++ <0x4800 0 0 2 &pci_intc 1>, ++ <0x4800 0 0 3 &pci_intc 2>, ++ <0x4800 0 0 4 &pci_intc 3>, ++ <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */ ++ <0x5000 0 0 2 &pci_intc 2>, ++ <0x5000 0 0 3 &pci_intc 3>, ++ <0x5000 0 0 4 &pci_intc 0>, ++ <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */ ++ <0x5800 0 0 2 &pci_intc 3>, ++ <0x5800 0 0 3 &pci_intc 0>, ++ <0x5800 0 0 4 &pci_intc 1>, ++ <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */ ++ <0x6000 0 0 2 &pci_intc 0>, ++ <0x6000 0 0 3 &pci_intc 1>, ++ <0x6000 0 0 4 &pci_intc 2>; ++ }; + }; + }; +--- a/arch/arm/boot/dts/gemini-wbd222.dts ++++ b/arch/arm/boot/dts/gemini-wbd222.dts +@@ -143,5 +143,27 @@ + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; ++ ++ pci@50000000 { ++ status = "okay"; ++ interrupt-map-mask = <0xf800 0 0 7>; ++ interrupt-map = ++ <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */ ++ <0x4800 0 0 2 &pci_intc 1>, ++ <0x4800 0 0 3 &pci_intc 2>, ++ <0x4800 0 0 4 &pci_intc 3>, ++ <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */ ++ <0x5000 0 0 2 &pci_intc 2>, ++ <0x5000 0 0 3 &pci_intc 3>, ++ <0x5000 0 0 4 &pci_intc 0>, ++ <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */ ++ <0x5800 0 0 2 &pci_intc 3>, ++ <0x5800 0 0 3 &pci_intc 0>, ++ <0x5800 0 0 4 &pci_intc 1>, ++ <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */ ++ <0x6000 0 0 2 &pci_intc 0>, ++ <0x6000 0 0 3 &pci_intc 1>, ++ <0x6000 0 0 4 &pci_intc 2>; ++ }; + }; + }; diff --git a/target/linux/gemini/patches-4.14/0016-ARM-dts-Add-TVE-TVC-and-ILI9322-panel-to-DIR-685.patch b/target/linux/gemini/patches-4.14/0016-ARM-dts-Add-TVE-TVC-and-ILI9322-panel-to-DIR-685.patch new file mode 100644 index 000000000..e0cf267cc --- /dev/null +++ b/target/linux/gemini/patches-4.14/0016-ARM-dts-Add-TVE-TVC-and-ILI9322-panel-to-DIR-685.patch @@ -0,0 +1,113 @@ +From 9d3b968d13ba1eecaf22d5824cf8fd270c061534 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sat, 15 Jul 2017 21:02:06 +0200 +Subject: [PATCH 16/31] ARM: dts: Add TVE/TVC and ILI9322 panel to DIR-685 + +This adds the TVE200/TVC TV-encoder and the Ilitek ILI9322 panel +to the DIR-685 device tree. + +This brings graphics to this funky router and it is possible to +even run a console on its tiny screen. + +Incidentally this requires us to disable the access to the +parallel (NOR) flash, as the communication pins to the panel +are shared with the flash memory. + +To access the flash, a separate kernel with the panel disabled +and the flash enabled should be booted. The pin control selecting +whether to use the lines cannot be altered at runtime due to +hardware constraints. + +Cc: David Lechner +Cc: Stefano Babic +Cc: Ben Dooks +Signed-off-by: Linus Walleij +--- + arch/arm/boot/dts/gemini-dlink-dir-685.dts | 63 +++++++++++++++++++++++++++++- + 1 file changed, 62 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -45,6 +45,47 @@ + }; + }; + ++ vdisp: regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "display-power"; ++ regulator-min-microvolt = <3600000>; ++ regulator-max-microvolt = <3600000>; ++ /* Collides with LCD E */ ++ gpio = <&gpio0 16 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ ++ spi { ++ compatible = "spi-gpio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* Collides with IDE pins, that's cool (we do not use them) */ ++ 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>; ++ ++ panel: display@0 { ++ compatible = "dlink,dir-685-panel", "ilitek,ili9322"; ++ reg = <0>; ++ /* 50 ns min period = 20 MHz */ ++ spi-max-frequency = <20000000>; ++ spi-cpol; /* Clock active low */ ++ vcc-supply = <&vdisp>; ++ iovcc-supply = <&vdisp>; ++ vci-supply = <&vdisp>; ++ ++ port { ++ panel_in: endpoint { ++ remote-endpoint = <&display_out>; ++ }; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + led-wps { +@@ -115,7 +156,16 @@ + + soc { + flash@30000000 { +- status = "okay"; ++ /* ++ * 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. ++ */ ++ /* status = "okay"; */ + /* 32MB of flash */ + reg = <0x30000000 0x02000000>; + +@@ -242,5 +292,16 @@ + ata@63000000 { + status = "okay"; + }; ++ ++ display-controller@6a000000 { ++ status = "okay"; ++ ++ port@0 { ++ reg = <0>; ++ display_out: endpoint { ++ remote-endpoint = <&panel_in>; ++ }; ++ }; ++ }; + }; + }; diff --git a/target/linux/gemini/patches-4.14/0017-watchdog-gemini-ftwdt010-rename-DT-bindings.patch b/target/linux/gemini/patches-4.14/0017-watchdog-gemini-ftwdt010-rename-DT-bindings.patch new file mode 100644 index 000000000..3fe0b8f8c --- /dev/null +++ b/target/linux/gemini/patches-4.14/0017-watchdog-gemini-ftwdt010-rename-DT-bindings.patch @@ -0,0 +1,88 @@ +From d73f6cc09bcbe258a72c06899215d1a3e8a7686d Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Mon, 16 Oct 2017 22:54:23 +0200 +Subject: [PATCH 17/31] watchdog: gemini/ftwdt010: rename DT bindings + +The device tree bindings are in two copies and also should be +consolidated into a single Faraday Technology FTWDT010 +binding since we uncovered that this IP part is a standard +IP from Faraday. + +Cc: devicetree@vger.kernel.org +Acked-by: Rob Herring +Signed-off-by: Linus Walleij +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +--- + .../bindings/watchdog/cortina,gemini-watchdog.txt | 17 ----------------- + ...{cortina,gemin-watchdog.txt => faraday,ftwdt010.txt} | 11 ++++++++--- + 2 files changed, 8 insertions(+), 20 deletions(-) + delete mode 100644 Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt + rename Documentation/devicetree/bindings/watchdog/{cortina,gemin-watchdog.txt => faraday,ftwdt010.txt} (55%) + +--- a/Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt ++++ /dev/null +@@ -1,17 +0,0 @@ +-Cortina Systems Gemini SoC Watchdog +- +-Required properties: +-- compatible : must be "cortina,gemini-watchdog" +-- reg : shall contain base register location and length +-- interrupts : shall contain the interrupt for the watchdog +- +-Optional properties: +-- timeout-sec : the default watchdog timeout in seconds. +- +-Example: +- +-watchdog@41000000 { +- compatible = "cortina,gemini-watchdog"; +- reg = <0x41000000 0x1000>; +- interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; +-}; +--- a/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt ++++ /dev/null +@@ -1,17 +0,0 @@ +-Cortina Systems Gemini SoC Watchdog +- +-Required properties: +-- compatible : must be "cortina,gemini-watchdog" +-- reg : shall contain base register location and length +-- interrupts : shall contain the interrupt for the watchdog +- +-Optional properties: +-- timeout-sec : the default watchdog timeout in seconds. +- +-Example: +- +-watchdog@41000000 { +- compatible = "cortina,gemini-watchdog"; +- reg = <0x41000000 0x1000>; +- interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; +-}; +--- /dev/null ++++ b/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.txt +@@ -0,0 +1,22 @@ ++Faraday Technology FTWDT010 watchdog ++ ++This is an IP part from Faraday Technology found in the Gemini ++SoCs and others. ++ ++Required properties: ++- compatible : must be one of ++ "faraday,ftwdt010" ++ "cortina,gemini-watchdog", "faraday,ftwdt010" ++- reg : shall contain base register location and length ++- interrupts : shall contain the interrupt for the watchdog ++ ++Optional properties: ++- timeout-sec : the default watchdog timeout in seconds. ++ ++Example: ++ ++watchdog@41000000 { ++ compatible = "faraday,ftwdt010"; ++ reg = <0x41000000 0x1000>; ++ interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; ++}; diff --git a/target/linux/gemini/patches-4.14/0018-watchdog-gemini-ftwdt010-rename-driver-and-symbols.patch b/target/linux/gemini/patches-4.14/0018-watchdog-gemini-ftwdt010-rename-driver-and-symbols.patch new file mode 100644 index 000000000..23c198935 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0018-watchdog-gemini-ftwdt010-rename-driver-and-symbols.patch @@ -0,0 +1,527 @@ +From c197a5a04d658da490de08636066a6bdbebf16c5 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Mon, 16 Oct 2017 22:54:24 +0200 +Subject: [PATCH 18/31] watchdog: gemini/ftwdt010: rename driver and symbols + +This renames all the driver files and symbols for the Gemini +watchdog to FTWDT010 as it has been revealed that this IP block +is a generic watchdog timer from Faraday Technology used in +several SoC designs. + +Select this driver by default for the Gemini, it is a sensible +driver to always have enabled. + +Signed-off-by: Linus Walleij +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +--- + drivers/watchdog/Kconfig | 14 +-- + drivers/watchdog/Makefile | 2 +- + drivers/watchdog/{gemini_wdt.c => ftwdt010_wdt.c} | 117 +++++++++++----------- + 3 files changed, 68 insertions(+), 65 deletions(-) + rename drivers/watchdog/{gemini_wdt.c => ftwdt010_wdt.c} (50%) + +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -321,16 +321,18 @@ config 977_WATCHDOG + + Not sure? It's safe to say N. + +-config GEMINI_WATCHDOG +- tristate "Gemini watchdog" +- depends on ARCH_GEMINI ++config FTWDT010_WATCHDOG ++ tristate "Faraday Technology FTWDT010 watchdog" ++ depends on ARM || COMPILE_TEST + select WATCHDOG_CORE ++ default ARCH_GEMINI + help +- Say Y here if to include support for the watchdog timer +- embedded in the Cortina Systems Gemini family of devices. ++ Say Y here if to include support for the Faraday Technology ++ FTWDT010 watchdog timer embedded in the Cortina Systems Gemini ++ family of devices. + + To compile this driver as a module, choose M here: the +- module will be called gemini_wdt. ++ module will be called ftwdt010_wdt. + + config IXP4XX_WATCHDOG + tristate "IXP4xx Watchdog" +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -46,7 +46,7 @@ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt. + obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o + obj-$(CONFIG_21285_WATCHDOG) += wdt285.o + obj-$(CONFIG_977_WATCHDOG) += wdt977.o +-obj-$(CONFIG_GEMINI_WATCHDOG) += gemini_wdt.o ++obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o + obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o + obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o + obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o +--- a/drivers/watchdog/gemini_wdt.c ++++ /dev/null +@@ -1,229 +0,0 @@ +-/* +- * Watchdog driver for Cortina Systems Gemini SoC +- * +- * Copyright (C) 2017 Linus Walleij +- * +- * Inspired by the out-of-tree drivers from OpenWRT: +- * Copyright (C) 2009 Paulius Zaleckas +- * +- * 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define GEMINI_WDCOUNTER 0x0 +-#define GEMINI_WDLOAD 0x4 +-#define GEMINI_WDRESTART 0x8 +-#define GEMINI_WDCR 0xC +- +-#define WDRESTART_MAGIC 0x5AB9 +- +-#define WDCR_CLOCK_5MHZ BIT(4) +-#define WDCR_SYS_RST BIT(1) +-#define WDCR_ENABLE BIT(0) +- +-#define WDT_CLOCK 5000000 /* 5 MHz */ +- +-struct gemini_wdt { +- struct watchdog_device wdd; +- struct device *dev; +- void __iomem *base; +-}; +- +-static inline +-struct gemini_wdt *to_gemini_wdt(struct watchdog_device *wdd) +-{ +- return container_of(wdd, struct gemini_wdt, wdd); +-} +- +-static int gemini_wdt_start(struct watchdog_device *wdd) +-{ +- struct gemini_wdt *gwdt = to_gemini_wdt(wdd); +- +- writel(wdd->timeout * WDT_CLOCK, gwdt->base + GEMINI_WDLOAD); +- writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART); +- /* set clock before enabling */ +- writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST, +- gwdt->base + GEMINI_WDCR); +- writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE, +- gwdt->base + GEMINI_WDCR); +- +- return 0; +-} +- +-static int gemini_wdt_stop(struct watchdog_device *wdd) +-{ +- struct gemini_wdt *gwdt = to_gemini_wdt(wdd); +- +- writel(0, gwdt->base + GEMINI_WDCR); +- +- return 0; +-} +- +-static int gemini_wdt_ping(struct watchdog_device *wdd) +-{ +- struct gemini_wdt *gwdt = to_gemini_wdt(wdd); +- +- writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART); +- +- return 0; +-} +- +-static int gemini_wdt_set_timeout(struct watchdog_device *wdd, +- unsigned int timeout) +-{ +- wdd->timeout = timeout; +- if (watchdog_active(wdd)) +- gemini_wdt_start(wdd); +- +- return 0; +-} +- +-static irqreturn_t gemini_wdt_interrupt(int irq, void *data) +-{ +- struct gemini_wdt *gwdt = data; +- +- watchdog_notify_pretimeout(&gwdt->wdd); +- +- return IRQ_HANDLED; +-} +- +-static const struct watchdog_ops gemini_wdt_ops = { +- .start = gemini_wdt_start, +- .stop = gemini_wdt_stop, +- .ping = gemini_wdt_ping, +- .set_timeout = gemini_wdt_set_timeout, +- .owner = THIS_MODULE, +-}; +- +-static const struct watchdog_info gemini_wdt_info = { +- .options = WDIOF_KEEPALIVEPING +- | WDIOF_MAGICCLOSE +- | WDIOF_SETTIMEOUT, +- .identity = KBUILD_MODNAME, +-}; +- +- +-static int gemini_wdt_probe(struct platform_device *pdev) +-{ +- struct device *dev = &pdev->dev; +- struct resource *res; +- struct gemini_wdt *gwdt; +- unsigned int reg; +- int irq; +- int ret; +- +- gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL); +- if (!gwdt) +- return -ENOMEM; +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- gwdt->base = devm_ioremap_resource(dev, res); +- if (IS_ERR(gwdt->base)) +- return PTR_ERR(gwdt->base); +- +- irq = platform_get_irq(pdev, 0); +- if (!irq) +- return -EINVAL; +- +- gwdt->dev = dev; +- gwdt->wdd.info = &gemini_wdt_info; +- gwdt->wdd.ops = &gemini_wdt_ops; +- gwdt->wdd.min_timeout = 1; +- gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK; +- gwdt->wdd.parent = dev; +- +- /* +- * If 'timeout-sec' unspecified in devicetree, assume a 13 second +- * default. +- */ +- gwdt->wdd.timeout = 13U; +- watchdog_init_timeout(&gwdt->wdd, 0, dev); +- +- reg = readw(gwdt->base + GEMINI_WDCR); +- if (reg & WDCR_ENABLE) { +- /* Watchdog was enabled by the bootloader, disable it. */ +- reg &= ~WDCR_ENABLE; +- writel(reg, gwdt->base + GEMINI_WDCR); +- } +- +- ret = devm_request_irq(dev, irq, gemini_wdt_interrupt, 0, +- "watchdog bark", gwdt); +- if (ret) +- return ret; +- +- ret = devm_watchdog_register_device(dev, &gwdt->wdd); +- if (ret) { +- dev_err(&pdev->dev, "failed to register watchdog\n"); +- return ret; +- } +- +- /* Set up platform driver data */ +- platform_set_drvdata(pdev, gwdt); +- dev_info(dev, "Gemini watchdog driver enabled\n"); +- +- return 0; +-} +- +-static int __maybe_unused gemini_wdt_suspend(struct device *dev) +-{ +- struct gemini_wdt *gwdt = dev_get_drvdata(dev); +- unsigned int reg; +- +- reg = readw(gwdt->base + GEMINI_WDCR); +- reg &= ~WDCR_ENABLE; +- writel(reg, gwdt->base + GEMINI_WDCR); +- +- return 0; +-} +- +-static int __maybe_unused gemini_wdt_resume(struct device *dev) +-{ +- struct gemini_wdt *gwdt = dev_get_drvdata(dev); +- unsigned int reg; +- +- if (watchdog_active(&gwdt->wdd)) { +- reg = readw(gwdt->base + GEMINI_WDCR); +- reg |= WDCR_ENABLE; +- writel(reg, gwdt->base + GEMINI_WDCR); +- } +- +- return 0; +-} +- +-static const struct dev_pm_ops gemini_wdt_dev_pm_ops = { +- SET_SYSTEM_SLEEP_PM_OPS(gemini_wdt_suspend, +- gemini_wdt_resume) +-}; +- +-#ifdef CONFIG_OF +-static const struct of_device_id gemini_wdt_match[] = { +- { .compatible = "cortina,gemini-watchdog" }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, gemini_wdt_match); +-#endif +- +-static struct platform_driver gemini_wdt_driver = { +- .probe = gemini_wdt_probe, +- .driver = { +- .name = "gemini-wdt", +- .of_match_table = of_match_ptr(gemini_wdt_match), +- .pm = &gemini_wdt_dev_pm_ops, +- }, +-}; +-module_platform_driver(gemini_wdt_driver); +-MODULE_AUTHOR("Linus Walleij"); +-MODULE_DESCRIPTION("Watchdog driver for Gemini"); +-MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/drivers/watchdog/ftwdt010_wdt.c +@@ -0,0 +1,230 @@ ++/* ++ * Watchdog driver for Faraday Technology FTWDT010 ++ * ++ * Copyright (C) 2017 Linus Walleij ++ * ++ * Inspired by the out-of-tree drivers from OpenWRT: ++ * Copyright (C) 2009 Paulius Zaleckas ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define FTWDT010_WDCOUNTER 0x0 ++#define FTWDT010_WDLOAD 0x4 ++#define FTWDT010_WDRESTART 0x8 ++#define FTWDT010_WDCR 0xC ++ ++#define WDRESTART_MAGIC 0x5AB9 ++ ++#define WDCR_CLOCK_5MHZ BIT(4) ++#define WDCR_SYS_RST BIT(1) ++#define WDCR_ENABLE BIT(0) ++ ++#define WDT_CLOCK 5000000 /* 5 MHz */ ++ ++struct ftwdt010_wdt { ++ struct watchdog_device wdd; ++ struct device *dev; ++ void __iomem *base; ++}; ++ ++static inline ++struct ftwdt010_wdt *to_ftwdt010_wdt(struct watchdog_device *wdd) ++{ ++ return container_of(wdd, struct ftwdt010_wdt, wdd); ++} ++ ++static int ftwdt010_wdt_start(struct watchdog_device *wdd) ++{ ++ struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd); ++ ++ writel(wdd->timeout * WDT_CLOCK, gwdt->base + FTWDT010_WDLOAD); ++ writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART); ++ /* set clock before enabling */ ++ writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST, ++ gwdt->base + FTWDT010_WDCR); ++ writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE, ++ gwdt->base + FTWDT010_WDCR); ++ ++ return 0; ++} ++ ++static int ftwdt010_wdt_stop(struct watchdog_device *wdd) ++{ ++ struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd); ++ ++ writel(0, gwdt->base + FTWDT010_WDCR); ++ ++ return 0; ++} ++ ++static int ftwdt010_wdt_ping(struct watchdog_device *wdd) ++{ ++ struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd); ++ ++ writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART); ++ ++ return 0; ++} ++ ++static int ftwdt010_wdt_set_timeout(struct watchdog_device *wdd, ++ unsigned int timeout) ++{ ++ wdd->timeout = timeout; ++ if (watchdog_active(wdd)) ++ ftwdt010_wdt_start(wdd); ++ ++ return 0; ++} ++ ++static irqreturn_t ftwdt010_wdt_interrupt(int irq, void *data) ++{ ++ struct ftwdt010_wdt *gwdt = data; ++ ++ watchdog_notify_pretimeout(&gwdt->wdd); ++ ++ return IRQ_HANDLED; ++} ++ ++static const struct watchdog_ops ftwdt010_wdt_ops = { ++ .start = ftwdt010_wdt_start, ++ .stop = ftwdt010_wdt_stop, ++ .ping = ftwdt010_wdt_ping, ++ .set_timeout = ftwdt010_wdt_set_timeout, ++ .owner = THIS_MODULE, ++}; ++ ++static const struct watchdog_info ftwdt010_wdt_info = { ++ .options = WDIOF_KEEPALIVEPING ++ | WDIOF_MAGICCLOSE ++ | WDIOF_SETTIMEOUT, ++ .identity = KBUILD_MODNAME, ++}; ++ ++ ++static int ftwdt010_wdt_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct resource *res; ++ struct ftwdt010_wdt *gwdt; ++ unsigned int reg; ++ int irq; ++ int ret; ++ ++ gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL); ++ if (!gwdt) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ gwdt->base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(gwdt->base)) ++ return PTR_ERR(gwdt->base); ++ ++ irq = platform_get_irq(pdev, 0); ++ if (!irq) ++ return -EINVAL; ++ ++ gwdt->dev = dev; ++ gwdt->wdd.info = &ftwdt010_wdt_info; ++ gwdt->wdd.ops = &ftwdt010_wdt_ops; ++ gwdt->wdd.min_timeout = 1; ++ gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK; ++ gwdt->wdd.parent = dev; ++ ++ /* ++ * If 'timeout-sec' unspecified in devicetree, assume a 13 second ++ * default. ++ */ ++ gwdt->wdd.timeout = 13U; ++ watchdog_init_timeout(&gwdt->wdd, 0, dev); ++ ++ reg = readw(gwdt->base + FTWDT010_WDCR); ++ if (reg & WDCR_ENABLE) { ++ /* Watchdog was enabled by the bootloader, disable it. */ ++ reg &= ~WDCR_ENABLE; ++ writel(reg, gwdt->base + FTWDT010_WDCR); ++ } ++ ++ ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0, ++ "watchdog bark", gwdt); ++ if (ret) ++ return ret; ++ ++ ret = devm_watchdog_register_device(dev, &gwdt->wdd); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to register watchdog\n"); ++ return ret; ++ } ++ ++ /* Set up platform driver data */ ++ platform_set_drvdata(pdev, gwdt); ++ dev_info(dev, "FTWDT010 watchdog driver enabled\n"); ++ ++ return 0; ++} ++ ++static int __maybe_unused ftwdt010_wdt_suspend(struct device *dev) ++{ ++ struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev); ++ unsigned int reg; ++ ++ reg = readw(gwdt->base + FTWDT010_WDCR); ++ reg &= ~WDCR_ENABLE; ++ writel(reg, gwdt->base + FTWDT010_WDCR); ++ ++ return 0; ++} ++ ++static int __maybe_unused ftwdt010_wdt_resume(struct device *dev) ++{ ++ struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev); ++ unsigned int reg; ++ ++ if (watchdog_active(&gwdt->wdd)) { ++ reg = readw(gwdt->base + FTWDT010_WDCR); ++ reg |= WDCR_ENABLE; ++ writel(reg, gwdt->base + FTWDT010_WDCR); ++ } ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops ftwdt010_wdt_dev_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(ftwdt010_wdt_suspend, ++ ftwdt010_wdt_resume) ++}; ++ ++#ifdef CONFIG_OF ++static const struct of_device_id ftwdt010_wdt_match[] = { ++ { .compatible = "faraday,ftwdt010" }, ++ { .compatible = "cortina,gemini-watchdog" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ftwdt010_wdt_match); ++#endif ++ ++static struct platform_driver ftwdt010_wdt_driver = { ++ .probe = ftwdt010_wdt_probe, ++ .driver = { ++ .name = "ftwdt010-wdt", ++ .of_match_table = of_match_ptr(ftwdt010_wdt_match), ++ .pm = &ftwdt010_wdt_dev_pm_ops, ++ }, ++}; ++module_platform_driver(ftwdt010_wdt_driver); ++MODULE_AUTHOR("Linus Walleij"); ++MODULE_DESCRIPTION("Watchdog driver for Faraday Technology FTWDT010"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/gemini/patches-4.14/0019-watchdog-ftwdt010-Make-interrupt-optional.patch b/target/linux/gemini/patches-4.14/0019-watchdog-ftwdt010-Make-interrupt-optional.patch new file mode 100644 index 000000000..23c4ab5c0 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0019-watchdog-ftwdt010-Make-interrupt-optional.patch @@ -0,0 +1,93 @@ +From 4347a0b0699989b889857c9d4ccfbce339859f13 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Mon, 16 Oct 2017 22:54:25 +0200 +Subject: [PATCH 19/31] watchdog: ftwdt010: Make interrupt optional + +The Moxart does not appear to be using the interrupt from the +watchdog timer, maybe it's not even routed, so as to support +more architectures with this driver, make the interrupt +optional. + +While we are at it: actually enable the use of the interrupt +if present by setting the right bit in the control register +and define the missing control register bits. + +Signed-off-by: Linus Walleij +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +--- + drivers/watchdog/ftwdt010_wdt.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +--- a/drivers/watchdog/ftwdt010_wdt.c ++++ b/drivers/watchdog/ftwdt010_wdt.c +@@ -30,6 +30,8 @@ + #define WDRESTART_MAGIC 0x5AB9 + + #define WDCR_CLOCK_5MHZ BIT(4) ++#define WDCR_WDEXT BIT(3) ++#define WDCR_WDINTR BIT(2) + #define WDCR_SYS_RST BIT(1) + #define WDCR_ENABLE BIT(0) + +@@ -39,6 +41,7 @@ struct ftwdt010_wdt { + struct watchdog_device wdd; + struct device *dev; + void __iomem *base; ++ bool has_irq; + }; + + static inline +@@ -50,14 +53,17 @@ struct ftwdt010_wdt *to_ftwdt010_wdt(str + static int ftwdt010_wdt_start(struct watchdog_device *wdd) + { + struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd); ++ u32 enable; + + writel(wdd->timeout * WDT_CLOCK, gwdt->base + FTWDT010_WDLOAD); + writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART); + /* set clock before enabling */ +- writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST, +- gwdt->base + FTWDT010_WDCR); +- writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE, +- gwdt->base + FTWDT010_WDCR); ++ enable = WDCR_CLOCK_5MHZ | WDCR_SYS_RST; ++ writel(enable, gwdt->base + FTWDT010_WDCR); ++ if (gwdt->has_irq) ++ enable |= WDCR_WDINTR; ++ enable |= WDCR_ENABLE; ++ writel(enable, gwdt->base + FTWDT010_WDCR); + + return 0; + } +@@ -133,10 +139,6 @@ static int ftwdt010_wdt_probe(struct pla + if (IS_ERR(gwdt->base)) + return PTR_ERR(gwdt->base); + +- irq = platform_get_irq(pdev, 0); +- if (!irq) +- return -EINVAL; +- + gwdt->dev = dev; + gwdt->wdd.info = &ftwdt010_wdt_info; + gwdt->wdd.ops = &ftwdt010_wdt_ops; +@@ -158,10 +160,14 @@ static int ftwdt010_wdt_probe(struct pla + writel(reg, gwdt->base + FTWDT010_WDCR); + } + +- ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0, +- "watchdog bark", gwdt); +- if (ret) +- return ret; ++ irq = platform_get_irq(pdev, 0); ++ if (irq) { ++ ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0, ++ "watchdog bark", gwdt); ++ if (ret) ++ return ret; ++ gwdt->has_irq = true; ++ } + + ret = devm_watchdog_register_device(dev, &gwdt->wdd); + if (ret) { diff --git a/target/linux/gemini/patches-4.14/0020-soc-Add-SoC-driver-for-Gemini.patch b/target/linux/gemini/patches-4.14/0020-soc-Add-SoC-driver-for-Gemini.patch new file mode 100644 index 000000000..f1bbe0a15 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0020-soc-Add-SoC-driver-for-Gemini.patch @@ -0,0 +1,113 @@ +From b0a88a861b036124ef2d6acfe6dd87cfde63e750 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Fri, 22 Dec 2017 00:19:08 +0100 +Subject: [PATCH 20/31] soc: Add SoC driver for Gemini + +This adds an SoC driver for the Gemini. Currently there +is only one thing not fitting into any other framework, +and that is the bus arbitration setting. + +All Gemini vendor trees seem to be setting this register to +exactly the same arbitration so we just add a small code +snippet to do this at subsys_init() time before any other +drivers kick in. + +Signed-off-by: Linus Walleij +Signed-off-by: Arnd Bergmann +--- + drivers/soc/Makefile | 1 + + drivers/soc/gemini/Makefile | 2 ++ + drivers/soc/gemini/soc-gemini.c | 71 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 74 insertions(+) + create mode 100644 drivers/soc/gemini/Makefile + create mode 100644 drivers/soc/gemini/soc-gemini.c + +--- a/drivers/soc/Makefile ++++ b/drivers/soc/Makefile +@@ -9,6 +9,7 @@ obj-y += bcm/ + obj-$(CONFIG_ARCH_DOVE) += dove/ + obj-$(CONFIG_MACH_DOVE) += dove/ + obj-y += fsl/ ++obj-$(CONFIG_ARCH_GEMINI) += gemini/ + obj-$(CONFIG_ARCH_MXC) += imx/ + obj-$(CONFIG_SOC_XWAY) += lantiq/ + obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ +--- /dev/null ++++ b/drivers/soc/gemini/Makefile +@@ -0,0 +1,2 @@ ++# SPDX-License-Identifier: GPL-2.0 ++obj-y += soc-gemini.o +--- /dev/null ++++ b/drivers/soc/gemini/soc-gemini.c +@@ -0,0 +1,71 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2017 Linaro Ltd. ++ * ++ * Author: Linus Walleij ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#define GLOBAL_WORD_ID 0x00 ++#define GEMINI_GLOBAL_ARB1_CTRL 0x2c ++#define GEMINI_ARB1_BURST_MASK GENMASK(21, 16) ++#define GEMINI_ARB1_BURST_SHIFT 16 ++/* These all define the priority on the BUS2 backplane */ ++#define GEMINI_ARB1_PRIO_MASK GENMASK(9, 0) ++#define GEMINI_ARB1_DMAC_HIGH_PRIO BIT(0) ++#define GEMINI_ARB1_IDE_HIGH_PRIO BIT(1) ++#define GEMINI_ARB1_RAID_HIGH_PRIO BIT(2) ++#define GEMINI_ARB1_SECURITY_HIGH_PRIO BIT(3) ++#define GEMINI_ARB1_GMAC0_HIGH_PRIO BIT(4) ++#define GEMINI_ARB1_GMAC1_HIGH_PRIO BIT(5) ++#define GEMINI_ARB1_USB0_HIGH_PRIO BIT(6) ++#define GEMINI_ARB1_USB1_HIGH_PRIO BIT(7) ++#define GEMINI_ARB1_PCI_HIGH_PRIO BIT(8) ++#define GEMINI_ARB1_TVE_HIGH_PRIO BIT(9) ++ ++#define GEMINI_DEFAULT_BURST_SIZE 0x20 ++#define GEMINI_DEFAULT_PRIO (GEMINI_ARB1_GMAC0_HIGH_PRIO | \ ++ GEMINI_ARB1_GMAC1_HIGH_PRIO) ++ ++static int __init gemini_soc_init(void) ++{ ++ struct regmap *map; ++ u32 rev; ++ u32 val; ++ int ret; ++ ++ /* Multiplatform guard, only proceed on Gemini */ ++ if (!of_machine_is_compatible("cortina,gemini")) ++ return 0; ++ ++ map = syscon_regmap_lookup_by_compatible("cortina,gemini-syscon"); ++ if (IS_ERR(map)) ++ return PTR_ERR(map); ++ ret = regmap_read(map, GLOBAL_WORD_ID, &rev); ++ if (ret) ++ return ret; ++ ++ val = (GEMINI_DEFAULT_BURST_SIZE << GEMINI_ARB1_BURST_SHIFT) | ++ GEMINI_DEFAULT_PRIO; ++ ++ /* Set up system arbitration */ ++ regmap_update_bits(map, ++ GEMINI_GLOBAL_ARB1_CTRL, ++ GEMINI_ARB1_BURST_MASK | GEMINI_ARB1_PRIO_MASK, ++ val); ++ ++ pr_info("Gemini SoC %04x revision %02x, set arbitration %08x\n", ++ rev >> 8, rev & 0xff, val); ++ ++ return 0; ++} ++subsys_initcall(gemini_soc_init); diff --git a/target/linux/gemini/patches-4.14/0021-net-ethernet-Add-DT-bindings-for-the-Gemini-ethernet.patch b/target/linux/gemini/patches-4.14/0021-net-ethernet-Add-DT-bindings-for-the-Gemini-ethernet.patch new file mode 100644 index 000000000..19653d5ad --- /dev/null +++ b/target/linux/gemini/patches-4.14/0021-net-ethernet-Add-DT-bindings-for-the-Gemini-ethernet.patch @@ -0,0 +1,119 @@ +From 49bc597009f52ec8970269f6201d3ed415a844ee Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Fri, 12 Jan 2018 22:34:23 +0100 +Subject: [PATCH 21/31] net: ethernet: Add DT bindings for the Gemini ethernet +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This adds the device tree bindings for the Gemini ethernet +controller. It is pretty straight-forward, using standard +bindings and modelling the two child ports as child devices +under the parent ethernet controller device. + +Cc: devicetree@vger.kernel.org +Cc: Tobias Waldvogel +Cc: MichaÅ‚ MirosÅ‚aw +Reviewed-by: Rob Herring +Signed-off-by: Linus Walleij +Signed-off-by: David S. Miller +--- + .../bindings/net/cortina,gemini-ethernet.txt | 92 ++++++++++++++++++++++ + 1 file changed, 92 insertions(+) + create mode 100644 Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt +@@ -0,0 +1,92 @@ ++Cortina Systems Gemini Ethernet Controller ++========================================== ++ ++This ethernet controller is found in the Gemini SoC family: ++StorLink SL3512 and SL3516, also known as Cortina Systems ++CS3512 and CS3516. ++ ++Required properties: ++- compatible: must be "cortina,gemini-ethernet" ++- reg: must contain the global registers and the V-bit and A-bit ++ memory areas, in total three register sets. ++- syscon: a phandle to the system controller ++- #address-cells: must be specified, must be <1> ++- #size-cells: must be specified, must be <1> ++- ranges: should be state like this giving a 1:1 address translation ++ for the subnodes ++ ++The subnodes represents the two ethernet ports in this device. ++They are not independent of each other since they share resources ++in the parent node, and are thus children. ++ ++Required subnodes: ++- port0: contains the resources for ethernet port 0 ++- port1: contains the resources for ethernet port 1 ++ ++Required subnode properties: ++- compatible: must be "cortina,gemini-ethernet-port" ++- reg: must contain two register areas: the DMA/TOE memory and ++ the GMAC memory area of the port ++- interrupts: should contain the interrupt line of the port. ++ this is nominally a level interrupt active high. ++- resets: this must provide an SoC-integrated reset line for ++ the port. ++- clocks: this should contain a handle to the PCLK clock for ++ clocking the silicon in this port ++- clock-names: must be "PCLK" ++ ++Optional subnode properties: ++- phy-mode: see ethernet.txt ++- phy-handle: see ethernet.txt ++ ++Example: ++ ++mdio-bus { ++ (...) ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ device_type = "ethernet-phy"; ++ }; ++ phy1: ethernet-phy@3 { ++ reg = <3>; ++ device_type = "ethernet-phy"; ++ }; ++}; ++ ++ ++ethernet@60000000 { ++ compatible = "cortina,gemini-ethernet"; ++ reg = <0x60000000 0x4000>, /* Global registers, queue */ ++ <0x60004000 0x2000>, /* V-bit */ ++ <0x60006000 0x2000>; /* A-bit */ ++ syscon = <&syscon>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ gmac0: ethernet-port@0 { ++ compatible = "cortina,gemini-ethernet-port"; ++ reg = <0x60008000 0x2000>, /* Port 0 DMA/TOE */ ++ <0x6000a000 0x2000>; /* Port 0 GMAC */ ++ interrupt-parent = <&intcon>; ++ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; ++ resets = <&syscon GEMINI_RESET_GMAC0>; ++ clocks = <&syscon GEMINI_CLK_GATE_GMAC0>; ++ clock-names = "PCLK"; ++ phy-mode = "rgmii"; ++ phy-handle = <&phy0>; ++ }; ++ ++ gmac1: ethernet-port@1 { ++ compatible = "cortina,gemini-ethernet-port"; ++ reg = <0x6000c000 0x2000>, /* Port 1 DMA/TOE */ ++ <0x6000e000 0x2000>; /* Port 1 GMAC */ ++ interrupt-parent = <&intcon>; ++ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; ++ resets = <&syscon GEMINI_RESET_GMAC1>; ++ clocks = <&syscon GEMINI_CLK_GATE_GMAC1>; ++ clock-names = "PCLK"; ++ phy-mode = "rgmii"; ++ phy-handle = <&phy1>; ++ }; ++}; diff --git a/target/linux/gemini/patches-4.14/0022-net-ethernet-Add-a-driver-for-Gemini-gigabit-etherne.patch b/target/linux/gemini/patches-4.14/0022-net-ethernet-Add-a-driver-for-Gemini-gigabit-etherne.patch new file mode 100644 index 000000000..bad9bfa34 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0022-net-ethernet-Add-a-driver-for-Gemini-gigabit-etherne.patch @@ -0,0 +1,3661 @@ +From 07826b86d4ce4d35fd1674d7f78e4b2060ab2910 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Fri, 12 Jan 2018 22:34:24 +0100 +Subject: [PATCH 22/31] net: ethernet: Add a driver for Gemini gigabit ethernet +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The Gemini ethernet has been around for years as an out-of-tree +patch used with the NAS boxen and routers built on StorLink +SL3512 and SL3516, later Storm Semiconductor, later Cortina +Systems. These ASICs are still being deployed and brand new +off-the-shelf systems using it can easily be acquired. + +The full name of the IP block is "Net Engine and Gigabit +Ethernet MAC" commonly just called "GMAC". + +The hardware block contains a common TCP Offload Enginer (TOE) +that can be used by both MACs. The current driver does not use +it. + +Cc: Tobias Waldvogel +Signed-off-by: MichaÅ‚ MirosÅ‚aw +Signed-off-by: Linus Walleij +Signed-off-by: David S. Miller +--- + MAINTAINERS | 2 + + drivers/net/ethernet/Kconfig | 1 + + drivers/net/ethernet/Makefile | 1 + + drivers/net/ethernet/cortina/Kconfig | 22 + + drivers/net/ethernet/cortina/Makefile | 4 + + drivers/net/ethernet/cortina/gemini.c | 2593 +++++++++++++++++++++++++++++++++ + drivers/net/ethernet/cortina/gemini.h | 958 ++++++++++++ + 7 files changed, 3581 insertions(+) + create mode 100644 drivers/net/ethernet/cortina/Kconfig + create mode 100644 drivers/net/ethernet/cortina/Makefile + create mode 100644 drivers/net/ethernet/cortina/gemini.c + create mode 100644 drivers/net/ethernet/cortina/gemini.h + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1327,8 +1327,10 @@ T: git git://github.com/ulli-kroll/linux + S: Maintained + F: Documentation/devicetree/bindings/arm/gemini.txt + F: Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt ++F: Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt + F: Documentation/devicetree/bindings/rtc/faraday,ftrtc010.txt + F: arch/arm/mach-gemini/ ++F: drivers/net/ethernet/cortina/gemini/* + F: drivers/pinctrl/pinctrl-gemini.c + F: drivers/rtc/rtc-ftrtc010.c + +--- a/drivers/net/ethernet/Kconfig ++++ b/drivers/net/ethernet/Kconfig +@@ -42,6 +42,7 @@ source "drivers/net/ethernet/cavium/Kcon + source "drivers/net/ethernet/chelsio/Kconfig" + source "drivers/net/ethernet/cirrus/Kconfig" + source "drivers/net/ethernet/cisco/Kconfig" ++source "drivers/net/ethernet/cortina/Kconfig" + + config CX_ECAT + tristate "Beckhoff CX5020 EtherCAT master support" +--- a/drivers/net/ethernet/Makefile ++++ b/drivers/net/ethernet/Makefile +@@ -29,6 +29,7 @@ obj-$(CONFIG_NET_VENDOR_CAVIUM) += caviu + obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/ + obj-$(CONFIG_NET_VENDOR_CIRRUS) += cirrus/ + obj-$(CONFIG_NET_VENDOR_CISCO) += cisco/ ++obj-$(CONFIG_NET_VENDOR_CORTINA) += cortina/ + obj-$(CONFIG_CX_ECAT) += ec_bhf.o + obj-$(CONFIG_DM9000) += davicom/ + obj-$(CONFIG_DNET) += dnet.o +--- /dev/null ++++ b/drivers/net/ethernet/cortina/Kconfig +@@ -0,0 +1,22 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# Cortina ethernet devices ++ ++config NET_VENDOR_CORTINA ++ bool "Cortina Gemini devices" ++ default y ++ ---help--- ++ If you have a network (Ethernet) card belonging to this class, say Y ++ and read the Ethernet-HOWTO, available from ++ . ++ ++if NET_VENDOR_CORTINA ++ ++config GEMINI_ETHERNET ++ tristate "Gemini Gigabit Ethernet support" ++ depends on OF ++ select PHYLIB ++ select CRC32 ++ ---help--- ++ This driver supports StorLink SL351x (Gemini) dual Gigabit Ethernet. ++ ++endif # NET_VENDOR_CORTINA +--- /dev/null ++++ b/drivers/net/ethernet/cortina/Makefile +@@ -0,0 +1,4 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# Makefile for the Cortina Gemini network device drivers. ++ ++obj-$(CONFIG_GEMINI_ETHERNET) += gemini.o +--- /dev/null ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -0,0 +1,2593 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Ethernet device driver for Cortina Systems Gemini SoC ++ * Also known as the StorLink SL3512 and SL3516 (SL351x) or Lepus ++ * Net Engine and Gigabit Ethernet MAC (GMAC) ++ * This hardware contains a TCP Offload Engine (TOE) but currently the ++ * driver does not make use of it. ++ * ++ * Authors: ++ * Linus Walleij ++ * Tobias Waldvogel (OpenWRT) ++ * MichaÅ‚ MirosÅ‚aw ++ * Paulius Zaleckas ++ * Giuseppe De Robertis ++ * Gary Chen & Ch Hsu Storlink Semiconductor ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "gemini.h" ++ ++#define DRV_NAME "gmac-gemini" ++#define DRV_VERSION "1.0" ++ ++#define HSIZE_8 0x00 ++#define HSIZE_16 0x01 ++#define HSIZE_32 0x02 ++ ++#define HBURST_SINGLE 0x00 ++#define HBURST_INCR 0x01 ++#define HBURST_INCR4 0x02 ++#define HBURST_INCR8 0x03 ++ ++#define HPROT_DATA_CACHE BIT(0) ++#define HPROT_PRIVILIGED BIT(1) ++#define HPROT_BUFFERABLE BIT(2) ++#define HPROT_CACHABLE BIT(3) ++ ++#define DEFAULT_RX_COALESCE_NSECS 0 ++#define DEFAULT_GMAC_RXQ_ORDER 9 ++#define DEFAULT_GMAC_TXQ_ORDER 8 ++#define DEFAULT_RX_BUF_ORDER 11 ++#define DEFAULT_NAPI_WEIGHT 64 ++#define TX_MAX_FRAGS 16 ++#define TX_QUEUE_NUM 1 /* max: 6 */ ++#define RX_MAX_ALLOC_ORDER 2 ++ ++#define GMAC0_IRQ0_2 (GMAC0_TXDERR_INT_BIT | GMAC0_TXPERR_INT_BIT | \ ++ GMAC0_RXDERR_INT_BIT | GMAC0_RXPERR_INT_BIT) ++#define GMAC0_IRQ0_TXQ0_INTS (GMAC0_SWTQ00_EOF_INT_BIT | \ ++ GMAC0_SWTQ00_FIN_INT_BIT) ++#define GMAC0_IRQ4_8 (GMAC0_MIB_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT) ++ ++#define GMAC_OFFLOAD_FEATURES (NETIF_F_SG | NETIF_F_IP_CSUM | \ ++ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | \ ++ NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6) ++ ++/** ++ * struct gmac_queue_page - page buffer per-page info ++ */ ++struct gmac_queue_page { ++ struct page *page; ++ dma_addr_t mapping; ++}; ++ ++struct gmac_txq { ++ struct gmac_txdesc *ring; ++ struct sk_buff **skb; ++ unsigned int cptr; ++ unsigned int noirq_packets; ++}; ++ ++struct gemini_ethernet; ++ ++struct gemini_ethernet_port { ++ u8 id; /* 0 or 1 */ ++ ++ struct gemini_ethernet *geth; ++ struct net_device *netdev; ++ struct device *dev; ++ void __iomem *dma_base; ++ void __iomem *gmac_base; ++ struct clk *pclk; ++ struct reset_control *reset; ++ int irq; ++ __le32 mac_addr[3]; ++ ++ void __iomem *rxq_rwptr; ++ struct gmac_rxdesc *rxq_ring; ++ unsigned int rxq_order; ++ ++ struct napi_struct napi; ++ struct hrtimer rx_coalesce_timer; ++ unsigned int rx_coalesce_nsecs; ++ unsigned int freeq_refill; ++ struct gmac_txq txq[TX_QUEUE_NUM]; ++ unsigned int txq_order; ++ unsigned int irq_every_tx_packets; ++ ++ dma_addr_t rxq_dma_base; ++ dma_addr_t txq_dma_base; ++ ++ unsigned int msg_enable; ++ spinlock_t config_lock; /* Locks config register */ ++ ++ struct u64_stats_sync tx_stats_syncp; ++ struct u64_stats_sync rx_stats_syncp; ++ struct u64_stats_sync ir_stats_syncp; ++ ++ struct rtnl_link_stats64 stats; ++ u64 hw_stats[RX_STATS_NUM]; ++ u64 rx_stats[RX_STATUS_NUM]; ++ u64 rx_csum_stats[RX_CHKSUM_NUM]; ++ u64 rx_napi_exits; ++ u64 tx_frag_stats[TX_MAX_FRAGS]; ++ u64 tx_frags_linearized; ++ u64 tx_hw_csummed; ++}; ++ ++struct gemini_ethernet { ++ struct device *dev; ++ void __iomem *base; ++ struct gemini_ethernet_port *port0; ++ struct gemini_ethernet_port *port1; ++ ++ spinlock_t irq_lock; /* Locks IRQ-related registers */ ++ unsigned int freeq_order; ++ unsigned int freeq_frag_order; ++ struct gmac_rxdesc *freeq_ring; ++ dma_addr_t freeq_dma_base; ++ struct gmac_queue_page *freeq_pages; ++ unsigned int num_freeq_pages; ++ spinlock_t freeq_lock; /* Locks queue from reentrance */ ++}; ++ ++#define GMAC_STATS_NUM ( \ ++ RX_STATS_NUM + RX_STATUS_NUM + RX_CHKSUM_NUM + 1 + \ ++ TX_MAX_FRAGS + 2) ++ ++static const char gmac_stats_strings[GMAC_STATS_NUM][ETH_GSTRING_LEN] = { ++ "GMAC_IN_DISCARDS", ++ "GMAC_IN_ERRORS", ++ "GMAC_IN_MCAST", ++ "GMAC_IN_BCAST", ++ "GMAC_IN_MAC1", ++ "GMAC_IN_MAC2", ++ "RX_STATUS_GOOD_FRAME", ++ "RX_STATUS_TOO_LONG_GOOD_CRC", ++ "RX_STATUS_RUNT_FRAME", ++ "RX_STATUS_SFD_NOT_FOUND", ++ "RX_STATUS_CRC_ERROR", ++ "RX_STATUS_TOO_LONG_BAD_CRC", ++ "RX_STATUS_ALIGNMENT_ERROR", ++ "RX_STATUS_TOO_LONG_BAD_ALIGN", ++ "RX_STATUS_RX_ERR", ++ "RX_STATUS_DA_FILTERED", ++ "RX_STATUS_BUFFER_FULL", ++ "RX_STATUS_11", ++ "RX_STATUS_12", ++ "RX_STATUS_13", ++ "RX_STATUS_14", ++ "RX_STATUS_15", ++ "RX_CHKSUM_IP_UDP_TCP_OK", ++ "RX_CHKSUM_IP_OK_ONLY", ++ "RX_CHKSUM_NONE", ++ "RX_CHKSUM_3", ++ "RX_CHKSUM_IP_ERR_UNKNOWN", ++ "RX_CHKSUM_IP_ERR", ++ "RX_CHKSUM_TCP_UDP_ERR", ++ "RX_CHKSUM_7", ++ "RX_NAPI_EXITS", ++ "TX_FRAGS[1]", ++ "TX_FRAGS[2]", ++ "TX_FRAGS[3]", ++ "TX_FRAGS[4]", ++ "TX_FRAGS[5]", ++ "TX_FRAGS[6]", ++ "TX_FRAGS[7]", ++ "TX_FRAGS[8]", ++ "TX_FRAGS[9]", ++ "TX_FRAGS[10]", ++ "TX_FRAGS[11]", ++ "TX_FRAGS[12]", ++ "TX_FRAGS[13]", ++ "TX_FRAGS[14]", ++ "TX_FRAGS[15]", ++ "TX_FRAGS[16+]", ++ "TX_FRAGS_LINEARIZED", ++ "TX_HW_CSUMMED", ++}; ++ ++static void gmac_dump_dma_state(struct net_device *netdev); ++ ++static void gmac_update_config0_reg(struct net_device *netdev, ++ u32 val, u32 vmask) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned long flags; ++ u32 reg; ++ ++ spin_lock_irqsave(&port->config_lock, flags); ++ ++ reg = readl(port->gmac_base + GMAC_CONFIG0); ++ reg = (reg & ~vmask) | val; ++ writel(reg, port->gmac_base + GMAC_CONFIG0); ++ ++ spin_unlock_irqrestore(&port->config_lock, flags); ++} ++ ++static void gmac_enable_tx_rx(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned long flags; ++ u32 reg; ++ ++ spin_lock_irqsave(&port->config_lock, flags); ++ ++ reg = readl(port->gmac_base + GMAC_CONFIG0); ++ reg &= ~CONFIG0_TX_RX_DISABLE; ++ writel(reg, port->gmac_base + GMAC_CONFIG0); ++ ++ spin_unlock_irqrestore(&port->config_lock, flags); ++} ++ ++static void gmac_disable_tx_rx(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned long flags; ++ u32 val; ++ ++ spin_lock_irqsave(&port->config_lock, flags); ++ ++ val = readl(port->gmac_base + GMAC_CONFIG0); ++ val |= CONFIG0_TX_RX_DISABLE; ++ writel(val, port->gmac_base + GMAC_CONFIG0); ++ ++ spin_unlock_irqrestore(&port->config_lock, flags); ++ ++ mdelay(10); /* let GMAC consume packet */ ++} ++ ++static void gmac_set_flow_control(struct net_device *netdev, bool tx, bool rx) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned long flags; ++ u32 val; ++ ++ spin_lock_irqsave(&port->config_lock, flags); ++ ++ val = readl(port->gmac_base + GMAC_CONFIG0); ++ val &= ~CONFIG0_FLOW_CTL; ++ if (tx) ++ val |= CONFIG0_FLOW_TX; ++ if (rx) ++ val |= CONFIG0_FLOW_RX; ++ writel(val, port->gmac_base + GMAC_CONFIG0); ++ ++ spin_unlock_irqrestore(&port->config_lock, flags); ++} ++ ++static void gmac_speed_set(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct phy_device *phydev = netdev->phydev; ++ union gmac_status status, old_status; ++ int pause_tx = 0; ++ int pause_rx = 0; ++ ++ status.bits32 = readl(port->gmac_base + GMAC_STATUS); ++ old_status.bits32 = status.bits32; ++ status.bits.link = phydev->link; ++ status.bits.duplex = phydev->duplex; ++ ++ switch (phydev->speed) { ++ case 1000: ++ status.bits.speed = GMAC_SPEED_1000; ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII) ++ status.bits.mii_rmii = GMAC_PHY_RGMII_1000; ++ netdev_info(netdev, "connect to RGMII @ 1Gbit\n"); ++ break; ++ case 100: ++ status.bits.speed = GMAC_SPEED_100; ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII) ++ status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; ++ netdev_info(netdev, "connect to RGMII @ 100 Mbit\n"); ++ break; ++ case 10: ++ status.bits.speed = GMAC_SPEED_10; ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII) ++ status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; ++ netdev_info(netdev, "connect to RGMII @ 10 Mbit\n"); ++ break; ++ default: ++ netdev_warn(netdev, "Not supported PHY speed (%d)\n", ++ phydev->speed); ++ } ++ ++ if (phydev->duplex == DUPLEX_FULL) { ++ u16 lcladv = phy_read(phydev, MII_ADVERTISE); ++ u16 rmtadv = phy_read(phydev, MII_LPA); ++ u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); ++ ++ if (cap & FLOW_CTRL_RX) ++ pause_rx = 1; ++ if (cap & FLOW_CTRL_TX) ++ pause_tx = 1; ++ } ++ ++ gmac_set_flow_control(netdev, pause_tx, pause_rx); ++ ++ if (old_status.bits32 == status.bits32) ++ return; ++ ++ if (netif_msg_link(port)) { ++ phy_print_status(phydev); ++ netdev_info(netdev, "link flow control: %s\n", ++ phydev->pause ++ ? (phydev->asym_pause ? "tx" : "both") ++ : (phydev->asym_pause ? "rx" : "none") ++ ); ++ } ++ ++ gmac_disable_tx_rx(netdev); ++ writel(status.bits32, port->gmac_base + GMAC_STATUS); ++ gmac_enable_tx_rx(netdev); ++} ++ ++static int gmac_setup_phy(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ union gmac_status status = { .bits32 = 0 }; ++ struct device *dev = port->dev; ++ struct phy_device *phy; ++ ++ phy = of_phy_get_and_connect(netdev, ++ dev->of_node, ++ gmac_speed_set); ++ if (!phy) ++ return -ENODEV; ++ netdev->phydev = phy; ++ ++ netdev_info(netdev, "connected to PHY \"%s\"\n", ++ phydev_name(phy)); ++ phy_attached_print(phy, "phy_id=0x%.8lx, phy_mode=%s\n", ++ (unsigned long)phy->phy_id, ++ phy_modes(phy->interface)); ++ ++ phy->supported &= PHY_GBIT_FEATURES; ++ phy->supported |= SUPPORTED_Asym_Pause | SUPPORTED_Pause; ++ phy->advertising = phy->supported; ++ ++ /* set PHY interface type */ ++ switch (phy->interface) { ++ case PHY_INTERFACE_MODE_MII: ++ netdev_info(netdev, "set GMAC0 to GMII mode, GMAC1 disabled\n"); ++ status.bits.mii_rmii = GMAC_PHY_MII; ++ netdev_info(netdev, "connect to MII\n"); ++ break; ++ case PHY_INTERFACE_MODE_GMII: ++ netdev_info(netdev, "set GMAC0 to GMII mode, GMAC1 disabled\n"); ++ status.bits.mii_rmii = GMAC_PHY_GMII; ++ netdev_info(netdev, "connect to GMII\n"); ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ dev_info(dev, "set GMAC0 and GMAC1 to MII/RGMII mode\n"); ++ status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; ++ netdev_info(netdev, "connect to RGMII\n"); ++ break; ++ default: ++ netdev_err(netdev, "Unsupported MII interface\n"); ++ phy_disconnect(phy); ++ netdev->phydev = NULL; ++ return -EINVAL; ++ } ++ writel(status.bits32, port->gmac_base + GMAC_STATUS); ++ ++ return 0; ++} ++ ++static int gmac_pick_rx_max_len(int max_l3_len) ++{ ++ /* index = CONFIG_MAXLEN_XXX values */ ++ static const int max_len[8] = { ++ 1536, 1518, 1522, 1542, ++ 9212, 10236, 1518, 1518 ++ }; ++ int i, n = 5; ++ ++ max_l3_len += ETH_HLEN + VLAN_HLEN; ++ ++ if (max_l3_len > max_len[n]) ++ return -1; ++ ++ for (i = 0; i < 5; i++) { ++ if (max_len[i] >= max_l3_len && max_len[i] < max_len[n]) ++ n = i; ++ } ++ ++ return n; ++} ++ ++static int gmac_init(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ union gmac_config0 config0 = { .bits = { ++ .dis_tx = 1, ++ .dis_rx = 1, ++ .ipv4_rx_chksum = 1, ++ .ipv6_rx_chksum = 1, ++ .rx_err_detect = 1, ++ .rgmm_edge = 1, ++ .port0_chk_hwq = 1, ++ .port1_chk_hwq = 1, ++ .port0_chk_toeq = 1, ++ .port1_chk_toeq = 1, ++ .port0_chk_classq = 1, ++ .port1_chk_classq = 1, ++ } }; ++ union gmac_ahb_weight ahb_weight = { .bits = { ++ .rx_weight = 1, ++ .tx_weight = 1, ++ .hash_weight = 1, ++ .pre_req = 0x1f, ++ .tq_dv_threshold = 0, ++ } }; ++ union gmac_tx_wcr0 hw_weigh = { .bits = { ++ .hw_tq3 = 1, ++ .hw_tq2 = 1, ++ .hw_tq1 = 1, ++ .hw_tq0 = 1, ++ } }; ++ union gmac_tx_wcr1 sw_weigh = { .bits = { ++ .sw_tq5 = 1, ++ .sw_tq4 = 1, ++ .sw_tq3 = 1, ++ .sw_tq2 = 1, ++ .sw_tq1 = 1, ++ .sw_tq0 = 1, ++ } }; ++ union gmac_config1 config1 = { .bits = { ++ .set_threshold = 16, ++ .rel_threshold = 24, ++ } }; ++ union gmac_config2 config2 = { .bits = { ++ .set_threshold = 16, ++ .rel_threshold = 32, ++ } }; ++ union gmac_config3 config3 = { .bits = { ++ .set_threshold = 0, ++ .rel_threshold = 0, ++ } }; ++ union gmac_config0 tmp; ++ u32 val; ++ ++ config0.bits.max_len = gmac_pick_rx_max_len(netdev->mtu); ++ tmp.bits32 = readl(port->gmac_base + GMAC_CONFIG0); ++ config0.bits.reserved = tmp.bits.reserved; ++ writel(config0.bits32, port->gmac_base + GMAC_CONFIG0); ++ writel(config1.bits32, port->gmac_base + GMAC_CONFIG1); ++ writel(config2.bits32, port->gmac_base + GMAC_CONFIG2); ++ writel(config3.bits32, port->gmac_base + GMAC_CONFIG3); ++ ++ val = readl(port->dma_base + GMAC_AHB_WEIGHT_REG); ++ writel(ahb_weight.bits32, port->dma_base + GMAC_AHB_WEIGHT_REG); ++ ++ writel(hw_weigh.bits32, ++ port->dma_base + GMAC_TX_WEIGHTING_CTRL_0_REG); ++ writel(sw_weigh.bits32, ++ port->dma_base + GMAC_TX_WEIGHTING_CTRL_1_REG); ++ ++ port->rxq_order = DEFAULT_GMAC_RXQ_ORDER; ++ port->txq_order = DEFAULT_GMAC_TXQ_ORDER; ++ port->rx_coalesce_nsecs = DEFAULT_RX_COALESCE_NSECS; ++ ++ /* Mark every quarter of the queue a packet for interrupt ++ * in order to be able to wake up the queue if it was stopped ++ */ ++ port->irq_every_tx_packets = 1 << (port->txq_order - 2); ++ ++ return 0; ++} ++ ++static void gmac_uninit(struct net_device *netdev) ++{ ++ if (netdev->phydev) ++ phy_disconnect(netdev->phydev); ++} ++ ++static int gmac_setup_txqs(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned int n_txq = netdev->num_tx_queues; ++ struct gemini_ethernet *geth = port->geth; ++ size_t entries = 1 << port->txq_order; ++ struct gmac_txq *txq = port->txq; ++ struct gmac_txdesc *desc_ring; ++ size_t len = n_txq * entries; ++ struct sk_buff **skb_tab; ++ void __iomem *rwptr_reg; ++ unsigned int r; ++ int i; ++ ++ rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; ++ ++ skb_tab = kcalloc(len, sizeof(*skb_tab), GFP_KERNEL); ++ if (!skb_tab) ++ return -ENOMEM; ++ ++ desc_ring = dma_alloc_coherent(geth->dev, len * sizeof(*desc_ring), ++ &port->txq_dma_base, GFP_KERNEL); ++ ++ if (!desc_ring) { ++ kfree(skb_tab); ++ return -ENOMEM; ++ } ++ ++ if (port->txq_dma_base & ~DMA_Q_BASE_MASK) { ++ dev_warn(geth->dev, "TX queue base it not aligned\n"); ++ return -ENOMEM; ++ } ++ ++ writel(port->txq_dma_base | port->txq_order, ++ port->dma_base + GMAC_SW_TX_QUEUE_BASE_REG); ++ ++ for (i = 0; i < n_txq; i++) { ++ txq->ring = desc_ring; ++ txq->skb = skb_tab; ++ txq->noirq_packets = 0; ++ ++ r = readw(rwptr_reg); ++ rwptr_reg += 2; ++ writew(r, rwptr_reg); ++ rwptr_reg += 2; ++ txq->cptr = r; ++ ++ txq++; ++ desc_ring += entries; ++ skb_tab += entries; ++ } ++ ++ return 0; ++} ++ ++static void gmac_clean_txq(struct net_device *netdev, struct gmac_txq *txq, ++ unsigned int r) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned int m = (1 << port->txq_order) - 1; ++ struct gemini_ethernet *geth = port->geth; ++ unsigned int c = txq->cptr; ++ union gmac_txdesc_0 word0; ++ union gmac_txdesc_1 word1; ++ unsigned int hwchksum = 0; ++ unsigned long bytes = 0; ++ struct gmac_txdesc *txd; ++ unsigned short nfrags; ++ unsigned int errs = 0; ++ unsigned int pkts = 0; ++ unsigned int word3; ++ dma_addr_t mapping; ++ ++ if (c == r) ++ return; ++ ++ while (c != r) { ++ txd = txq->ring + c; ++ word0 = txd->word0; ++ word1 = txd->word1; ++ mapping = txd->word2.buf_adr; ++ word3 = txd->word3.bits32; ++ ++ dma_unmap_single(geth->dev, mapping, ++ word0.bits.buffer_size, DMA_TO_DEVICE); ++ ++ if (word3 & EOF_BIT) ++ dev_kfree_skb(txq->skb[c]); ++ ++ c++; ++ c &= m; ++ ++ if (!(word3 & SOF_BIT)) ++ continue; ++ ++ if (!word0.bits.status_tx_ok) { ++ errs++; ++ continue; ++ } ++ ++ pkts++; ++ bytes += txd->word1.bits.byte_count; ++ ++ if (word1.bits32 & TSS_CHECKUM_ENABLE) ++ hwchksum++; ++ ++ nfrags = word0.bits.desc_count - 1; ++ if (nfrags) { ++ if (nfrags >= TX_MAX_FRAGS) ++ nfrags = TX_MAX_FRAGS - 1; ++ ++ u64_stats_update_begin(&port->tx_stats_syncp); ++ port->tx_frag_stats[nfrags]++; ++ u64_stats_update_end(&port->ir_stats_syncp); ++ } ++ } ++ ++ u64_stats_update_begin(&port->ir_stats_syncp); ++ port->stats.tx_errors += errs; ++ port->stats.tx_packets += pkts; ++ port->stats.tx_bytes += bytes; ++ port->tx_hw_csummed += hwchksum; ++ u64_stats_update_end(&port->ir_stats_syncp); ++ ++ txq->cptr = c; ++} ++ ++static void gmac_cleanup_txqs(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned int n_txq = netdev->num_tx_queues; ++ struct gemini_ethernet *geth = port->geth; ++ void __iomem *rwptr_reg; ++ unsigned int r, i; ++ ++ rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; ++ ++ for (i = 0; i < n_txq; i++) { ++ r = readw(rwptr_reg); ++ rwptr_reg += 2; ++ writew(r, rwptr_reg); ++ rwptr_reg += 2; ++ ++ gmac_clean_txq(netdev, port->txq + i, r); ++ } ++ writel(0, port->dma_base + GMAC_SW_TX_QUEUE_BASE_REG); ++ ++ kfree(port->txq->skb); ++ dma_free_coherent(geth->dev, ++ n_txq * sizeof(*port->txq->ring) << port->txq_order, ++ port->txq->ring, port->txq_dma_base); ++} ++ ++static int gmac_setup_rxq(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct gemini_ethernet *geth = port->geth; ++ struct nontoe_qhdr __iomem *qhdr; ++ ++ qhdr = geth->base + TOE_DEFAULT_Q_HDR_BASE(netdev->dev_id); ++ port->rxq_rwptr = &qhdr->word1; ++ ++ /* Remap a slew of memory to use for the RX queue */ ++ port->rxq_ring = dma_alloc_coherent(geth->dev, ++ sizeof(*port->rxq_ring) << port->rxq_order, ++ &port->rxq_dma_base, GFP_KERNEL); ++ if (!port->rxq_ring) ++ return -ENOMEM; ++ if (port->rxq_dma_base & ~NONTOE_QHDR0_BASE_MASK) { ++ dev_warn(geth->dev, "RX queue base it not aligned\n"); ++ return -ENOMEM; ++ } ++ ++ writel(port->rxq_dma_base | port->rxq_order, &qhdr->word0); ++ writel(0, port->rxq_rwptr); ++ return 0; ++} ++ ++static struct gmac_queue_page * ++gmac_get_queue_page(struct gemini_ethernet *geth, ++ struct gemini_ethernet_port *port, ++ dma_addr_t addr) ++{ ++ struct gmac_queue_page *gpage; ++ dma_addr_t mapping; ++ int i; ++ ++ /* Only look for even pages */ ++ mapping = addr & PAGE_MASK; ++ ++ if (!geth->freeq_pages) { ++ dev_err(geth->dev, "try to get page with no page list\n"); ++ return NULL; ++ } ++ ++ /* Look up a ring buffer page from virtual mapping */ ++ for (i = 0; i < geth->num_freeq_pages; i++) { ++ gpage = &geth->freeq_pages[i]; ++ if (gpage->mapping == mapping) ++ return gpage; ++ } ++ ++ return NULL; ++} ++ ++static void gmac_cleanup_rxq(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct gemini_ethernet *geth = port->geth; ++ struct gmac_rxdesc *rxd = port->rxq_ring; ++ static struct gmac_queue_page *gpage; ++ struct nontoe_qhdr __iomem *qhdr; ++ void __iomem *dma_reg; ++ void __iomem *ptr_reg; ++ dma_addr_t mapping; ++ union dma_rwptr rw; ++ unsigned int r, w; ++ ++ qhdr = geth->base + ++ TOE_DEFAULT_Q_HDR_BASE(netdev->dev_id); ++ dma_reg = &qhdr->word0; ++ ptr_reg = &qhdr->word1; ++ ++ rw.bits32 = readl(ptr_reg); ++ r = rw.bits.rptr; ++ w = rw.bits.wptr; ++ writew(r, ptr_reg + 2); ++ ++ writel(0, dma_reg); ++ ++ /* Loop from read pointer to write pointer of the RX queue ++ * and free up all pages by the queue. ++ */ ++ while (r != w) { ++ mapping = rxd[r].word2.buf_adr; ++ r++; ++ r &= ((1 << port->rxq_order) - 1); ++ ++ if (!mapping) ++ continue; ++ ++ /* Freeq pointers are one page off */ ++ gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE); ++ if (!gpage) { ++ dev_err(geth->dev, "could not find page\n"); ++ continue; ++ } ++ /* Release the RX queue reference to the page */ ++ put_page(gpage->page); ++ } ++ ++ dma_free_coherent(geth->dev, sizeof(*port->rxq_ring) << port->rxq_order, ++ port->rxq_ring, port->rxq_dma_base); ++} ++ ++static struct page *geth_freeq_alloc_map_page(struct gemini_ethernet *geth, ++ int pn) ++{ ++ struct gmac_rxdesc *freeq_entry; ++ struct gmac_queue_page *gpage; ++ unsigned int fpp_order; ++ unsigned int frag_len; ++ dma_addr_t mapping; ++ struct page *page; ++ int i; ++ ++ /* First allocate and DMA map a single page */ ++ page = alloc_page(GFP_ATOMIC); ++ if (!page) ++ return NULL; ++ ++ mapping = dma_map_single(geth->dev, page_address(page), ++ PAGE_SIZE, DMA_FROM_DEVICE); ++ if (dma_mapping_error(geth->dev, mapping)) { ++ put_page(page); ++ return NULL; ++ } ++ ++ /* The assign the page mapping (physical address) to the buffer address ++ * in the hardware queue. PAGE_SHIFT on ARM is 12 (1 page is 4096 bytes, ++ * 4k), and the default RX frag order is 11 (fragments are up 20 2048 ++ * bytes, 2k) so fpp_order (fragments per page order) is default 1. Thus ++ * each page normally needs two entries in the queue. ++ */ ++ frag_len = 1 << geth->freeq_frag_order; /* Usually 2048 */ ++ fpp_order = PAGE_SHIFT - geth->freeq_frag_order; ++ freeq_entry = geth->freeq_ring + (pn << fpp_order); ++ dev_dbg(geth->dev, "allocate page %d fragment length %d fragments per page %d, freeq entry %p\n", ++ pn, frag_len, (1 << fpp_order), freeq_entry); ++ for (i = (1 << fpp_order); i > 0; i--) { ++ freeq_entry->word2.buf_adr = mapping; ++ freeq_entry++; ++ mapping += frag_len; ++ } ++ ++ /* If the freeq entry already has a page mapped, then unmap it. */ ++ gpage = &geth->freeq_pages[pn]; ++ if (gpage->page) { ++ mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; ++ dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); ++ /* This should be the last reference to the page so it gets ++ * released ++ */ ++ put_page(gpage->page); ++ } ++ ++ /* Then put our new mapping into the page table */ ++ dev_dbg(geth->dev, "page %d, DMA addr: %08x, page %p\n", ++ pn, (unsigned int)mapping, page); ++ gpage->mapping = mapping; ++ gpage->page = page; ++ ++ return page; ++} ++ ++/** ++ * geth_fill_freeq() - Fill the freeq with empty fragments to use ++ * @geth: the ethernet adapter ++ * @refill: whether to reset the queue by filling in all freeq entries or ++ * just refill it, usually the interrupt to refill the queue happens when ++ * the queue is half empty. ++ */ ++static unsigned int geth_fill_freeq(struct gemini_ethernet *geth, bool refill) ++{ ++ unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; ++ unsigned int count = 0; ++ unsigned int pn, epn; ++ unsigned long flags; ++ union dma_rwptr rw; ++ unsigned int m_pn; ++ ++ /* Mask for page */ ++ m_pn = (1 << (geth->freeq_order - fpp_order)) - 1; ++ ++ spin_lock_irqsave(&geth->freeq_lock, flags); ++ ++ rw.bits32 = readl(geth->base + GLOBAL_SWFQ_RWPTR_REG); ++ pn = (refill ? rw.bits.wptr : rw.bits.rptr) >> fpp_order; ++ epn = (rw.bits.rptr >> fpp_order) - 1; ++ epn &= m_pn; ++ ++ /* Loop over the freeq ring buffer entries */ ++ while (pn != epn) { ++ struct gmac_queue_page *gpage; ++ struct page *page; ++ ++ gpage = &geth->freeq_pages[pn]; ++ page = gpage->page; ++ ++ dev_dbg(geth->dev, "fill entry %d page ref count %d add %d refs\n", ++ pn, page_ref_count(page), 1 << fpp_order); ++ ++ if (page_ref_count(page) > 1) { ++ unsigned int fl = (pn - epn) & m_pn; ++ ++ if (fl > 64 >> fpp_order) ++ break; ++ ++ page = geth_freeq_alloc_map_page(geth, pn); ++ if (!page) ++ break; ++ } ++ ++ /* Add one reference per fragment in the page */ ++ page_ref_add(page, 1 << fpp_order); ++ count += 1 << fpp_order; ++ pn++; ++ pn &= m_pn; ++ } ++ ++ writew(pn << fpp_order, geth->base + GLOBAL_SWFQ_RWPTR_REG + 2); ++ ++ spin_unlock_irqrestore(&geth->freeq_lock, flags); ++ ++ return count; ++} ++ ++static int geth_setup_freeq(struct gemini_ethernet *geth) ++{ ++ unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; ++ unsigned int frag_len = 1 << geth->freeq_frag_order; ++ unsigned int len = 1 << geth->freeq_order; ++ unsigned int pages = len >> fpp_order; ++ union queue_threshold qt; ++ union dma_skb_size skbsz; ++ unsigned int filled; ++ unsigned int pn; ++ ++ geth->freeq_ring = dma_alloc_coherent(geth->dev, ++ sizeof(*geth->freeq_ring) << geth->freeq_order, ++ &geth->freeq_dma_base, GFP_KERNEL); ++ if (!geth->freeq_ring) ++ return -ENOMEM; ++ if (geth->freeq_dma_base & ~DMA_Q_BASE_MASK) { ++ dev_warn(geth->dev, "queue ring base it not aligned\n"); ++ goto err_freeq; ++ } ++ ++ /* Allocate a mapping to page look-up index */ ++ geth->freeq_pages = kzalloc(pages * sizeof(*geth->freeq_pages), ++ GFP_KERNEL); ++ if (!geth->freeq_pages) ++ goto err_freeq; ++ geth->num_freeq_pages = pages; ++ ++ dev_info(geth->dev, "allocate %d pages for queue\n", pages); ++ for (pn = 0; pn < pages; pn++) ++ if (!geth_freeq_alloc_map_page(geth, pn)) ++ goto err_freeq_alloc; ++ ++ filled = geth_fill_freeq(geth, false); ++ if (!filled) ++ goto err_freeq_alloc; ++ ++ qt.bits32 = readl(geth->base + GLOBAL_QUEUE_THRESHOLD_REG); ++ qt.bits.swfq_empty = 32; ++ writel(qt.bits32, geth->base + GLOBAL_QUEUE_THRESHOLD_REG); ++ ++ skbsz.bits.sw_skb_size = 1 << geth->freeq_frag_order; ++ writel(skbsz.bits32, geth->base + GLOBAL_DMA_SKB_SIZE_REG); ++ writel(geth->freeq_dma_base | geth->freeq_order, ++ geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); ++ ++ return 0; ++ ++err_freeq_alloc: ++ while (pn > 0) { ++ struct gmac_queue_page *gpage; ++ dma_addr_t mapping; ++ ++ --pn; ++ mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; ++ dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); ++ gpage = &geth->freeq_pages[pn]; ++ put_page(gpage->page); ++ } ++ ++ kfree(geth->freeq_pages); ++err_freeq: ++ dma_free_coherent(geth->dev, ++ sizeof(*geth->freeq_ring) << geth->freeq_order, ++ geth->freeq_ring, geth->freeq_dma_base); ++ geth->freeq_ring = NULL; ++ return -ENOMEM; ++} ++ ++/** ++ * geth_cleanup_freeq() - cleanup the DMA mappings and free the queue ++ * @geth: the Gemini global ethernet state ++ */ ++static void geth_cleanup_freeq(struct gemini_ethernet *geth) ++{ ++ unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; ++ unsigned int frag_len = 1 << geth->freeq_frag_order; ++ unsigned int len = 1 << geth->freeq_order; ++ unsigned int pages = len >> fpp_order; ++ unsigned int pn; ++ ++ writew(readw(geth->base + GLOBAL_SWFQ_RWPTR_REG), ++ geth->base + GLOBAL_SWFQ_RWPTR_REG + 2); ++ writel(0, geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); ++ ++ for (pn = 0; pn < pages; pn++) { ++ struct gmac_queue_page *gpage; ++ dma_addr_t mapping; ++ ++ mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; ++ dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); ++ ++ gpage = &geth->freeq_pages[pn]; ++ while (page_ref_count(gpage->page) > 0) ++ put_page(gpage->page); ++ } ++ ++ kfree(geth->freeq_pages); ++ ++ dma_free_coherent(geth->dev, ++ sizeof(*geth->freeq_ring) << geth->freeq_order, ++ geth->freeq_ring, geth->freeq_dma_base); ++} ++ ++/** ++ * geth_resize_freeq() - resize the software queue depth ++ * @port: the port requesting the change ++ * ++ * This gets called at least once during probe() so the device queue gets ++ * "resized" from the hardware defaults. Since both ports/net devices share ++ * the same hardware queue, some synchronization between the ports is ++ * needed. ++ */ ++static int geth_resize_freeq(struct gemini_ethernet_port *port) ++{ ++ struct gemini_ethernet *geth = port->geth; ++ struct net_device *netdev = port->netdev; ++ struct gemini_ethernet_port *other_port; ++ struct net_device *other_netdev; ++ unsigned int new_size = 0; ++ unsigned int new_order; ++ unsigned long flags; ++ u32 en; ++ int ret; ++ ++ if (netdev->dev_id == 0) ++ other_netdev = geth->port1->netdev; ++ else ++ other_netdev = geth->port0->netdev; ++ ++ if (other_netdev && netif_running(other_netdev)) ++ return -EBUSY; ++ ++ new_size = 1 << (port->rxq_order + 1); ++ netdev_dbg(netdev, "port %d size: %d order %d\n", ++ netdev->dev_id, ++ new_size, ++ port->rxq_order); ++ if (other_netdev) { ++ other_port = netdev_priv(other_netdev); ++ new_size += 1 << (other_port->rxq_order + 1); ++ netdev_dbg(other_netdev, "port %d size: %d order %d\n", ++ other_netdev->dev_id, ++ (1 << (other_port->rxq_order + 1)), ++ other_port->rxq_order); ++ } ++ ++ new_order = min(15, ilog2(new_size - 1) + 1); ++ dev_dbg(geth->dev, "set shared queue to size %d order %d\n", ++ new_size, new_order); ++ if (geth->freeq_order == new_order) ++ return 0; ++ ++ spin_lock_irqsave(&geth->irq_lock, flags); ++ ++ /* Disable the software queue IRQs */ ++ en = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ en &= ~SWFQ_EMPTY_INT_BIT; ++ writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ spin_unlock_irqrestore(&geth->irq_lock, flags); ++ ++ /* Drop the old queue */ ++ if (geth->freeq_ring) ++ geth_cleanup_freeq(geth); ++ ++ /* Allocate a new queue with the desired order */ ++ geth->freeq_order = new_order; ++ ret = geth_setup_freeq(geth); ++ ++ /* Restart the interrupts - NOTE if this is the first resize ++ * after probe(), this is where the interrupts get turned on ++ * in the first place. ++ */ ++ spin_lock_irqsave(&geth->irq_lock, flags); ++ en |= SWFQ_EMPTY_INT_BIT; ++ writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ spin_unlock_irqrestore(&geth->irq_lock, flags); ++ ++ return ret; ++} ++ ++static void gmac_tx_irq_enable(struct net_device *netdev, ++ unsigned int txq, int en) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct gemini_ethernet *geth = port->geth; ++ u32 val, mask; ++ ++ netdev_dbg(netdev, "%s device %d\n", __func__, netdev->dev_id); ++ ++ mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq); ++ ++ if (en) ++ writel(mask, geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); ++ ++ val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); ++ val = en ? val | mask : val & ~mask; ++ writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); ++} ++ ++static void gmac_tx_irq(struct net_device *netdev, unsigned int txq_num) ++{ ++ struct netdev_queue *ntxq = netdev_get_tx_queue(netdev, txq_num); ++ ++ gmac_tx_irq_enable(netdev, txq_num, 0); ++ netif_tx_wake_queue(ntxq); ++} ++ ++static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, ++ struct gmac_txq *txq, unsigned short *desc) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct skb_shared_info *skb_si = skb_shinfo(skb); ++ unsigned short m = (1 << port->txq_order) - 1; ++ short frag, last_frag = skb_si->nr_frags - 1; ++ struct gemini_ethernet *geth = port->geth; ++ unsigned int word1, word3, buflen; ++ unsigned short w = *desc; ++ struct gmac_txdesc *txd; ++ skb_frag_t *skb_frag; ++ dma_addr_t mapping; ++ unsigned short mtu; ++ void *buffer; ++ ++ mtu = ETH_HLEN; ++ mtu += netdev->mtu; ++ if (skb->protocol == htons(ETH_P_8021Q)) ++ mtu += VLAN_HLEN; ++ ++ word1 = skb->len; ++ word3 = SOF_BIT; ++ ++ if (word1 > mtu) { ++ word1 |= TSS_MTU_ENABLE_BIT; ++ word3 |= mtu; ++ } ++ ++ if (skb->ip_summed != CHECKSUM_NONE) { ++ int tcp = 0; ++ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ word1 |= TSS_IP_CHKSUM_BIT; ++ tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; ++ } else { /* IPv6 */ ++ word1 |= TSS_IPV6_ENABLE_BIT; ++ tcp = ipv6_hdr(skb)->nexthdr == IPPROTO_TCP; ++ } ++ ++ word1 |= tcp ? TSS_TCP_CHKSUM_BIT : TSS_UDP_CHKSUM_BIT; ++ } ++ ++ frag = -1; ++ while (frag <= last_frag) { ++ if (frag == -1) { ++ buffer = skb->data; ++ buflen = skb_headlen(skb); ++ } else { ++ skb_frag = skb_si->frags + frag; ++ buffer = page_address(skb_frag_page(skb_frag)) + ++ skb_frag->page_offset; ++ buflen = skb_frag->size; ++ } ++ ++ if (frag == last_frag) { ++ word3 |= EOF_BIT; ++ txq->skb[w] = skb; ++ } ++ ++ mapping = dma_map_single(geth->dev, buffer, buflen, ++ DMA_TO_DEVICE); ++ if (dma_mapping_error(geth->dev, mapping)) ++ goto map_error; ++ ++ txd = txq->ring + w; ++ txd->word0.bits32 = buflen; ++ txd->word1.bits32 = word1; ++ txd->word2.buf_adr = mapping; ++ txd->word3.bits32 = word3; ++ ++ word3 &= MTU_SIZE_BIT_MASK; ++ w++; ++ w &= m; ++ frag++; ++ } ++ ++ *desc = w; ++ return 0; ++ ++map_error: ++ while (w != *desc) { ++ w--; ++ w &= m; ++ ++ dma_unmap_page(geth->dev, txq->ring[w].word2.buf_adr, ++ txq->ring[w].word0.bits.buffer_size, ++ DMA_TO_DEVICE); ++ } ++ return -ENOMEM; ++} ++ ++static int gmac_start_xmit(struct sk_buff *skb, struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned short m = (1 << port->txq_order) - 1; ++ struct netdev_queue *ntxq; ++ unsigned short r, w, d; ++ void __iomem *ptr_reg; ++ struct gmac_txq *txq; ++ int txq_num, nfrags; ++ union dma_rwptr rw; ++ ++ SKB_FRAG_ASSERT(skb); ++ ++ if (skb->len >= 0x10000) ++ goto out_drop_free; ++ ++ txq_num = skb_get_queue_mapping(skb); ++ ptr_reg = port->dma_base + GMAC_SW_TX_QUEUE_PTR_REG(txq_num); ++ txq = &port->txq[txq_num]; ++ ntxq = netdev_get_tx_queue(netdev, txq_num); ++ nfrags = skb_shinfo(skb)->nr_frags; ++ ++ rw.bits32 = readl(ptr_reg); ++ r = rw.bits.rptr; ++ w = rw.bits.wptr; ++ ++ d = txq->cptr - w - 1; ++ d &= m; ++ ++ if (d < nfrags + 2) { ++ gmac_clean_txq(netdev, txq, r); ++ d = txq->cptr - w - 1; ++ d &= m; ++ ++ if (d < nfrags + 2) { ++ netif_tx_stop_queue(ntxq); ++ ++ d = txq->cptr + nfrags + 16; ++ d &= m; ++ txq->ring[d].word3.bits.eofie = 1; ++ gmac_tx_irq_enable(netdev, txq_num, 1); ++ ++ u64_stats_update_begin(&port->tx_stats_syncp); ++ netdev->stats.tx_fifo_errors++; ++ u64_stats_update_end(&port->tx_stats_syncp); ++ return NETDEV_TX_BUSY; ++ } ++ } ++ ++ if (gmac_map_tx_bufs(netdev, skb, txq, &w)) { ++ if (skb_linearize(skb)) ++ goto out_drop; ++ ++ u64_stats_update_begin(&port->tx_stats_syncp); ++ port->tx_frags_linearized++; ++ u64_stats_update_end(&port->tx_stats_syncp); ++ ++ if (gmac_map_tx_bufs(netdev, skb, txq, &w)) ++ goto out_drop_free; ++ } ++ ++ writew(w, ptr_reg + 2); ++ ++ gmac_clean_txq(netdev, txq, r); ++ return NETDEV_TX_OK; ++ ++out_drop_free: ++ dev_kfree_skb(skb); ++out_drop: ++ u64_stats_update_begin(&port->tx_stats_syncp); ++ port->stats.tx_dropped++; ++ u64_stats_update_end(&port->tx_stats_syncp); ++ return NETDEV_TX_OK; ++} ++ ++static void gmac_tx_timeout(struct net_device *netdev) ++{ ++ netdev_err(netdev, "Tx timeout\n"); ++ gmac_dump_dma_state(netdev); ++} ++ ++static void gmac_enable_irq(struct net_device *netdev, int enable) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct gemini_ethernet *geth = port->geth; ++ unsigned long flags; ++ u32 val, mask; ++ ++ netdev_info(netdev, "%s device %d %s\n", __func__, ++ netdev->dev_id, enable ? "enable" : "disable"); ++ spin_lock_irqsave(&geth->irq_lock, flags); ++ ++ mask = GMAC0_IRQ0_2 << (netdev->dev_id * 2); ++ val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); ++ val = enable ? (val | mask) : (val & ~mask); ++ writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); ++ ++ mask = DEFAULT_Q0_INT_BIT << netdev->dev_id; ++ val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); ++ val = enable ? (val | mask) : (val & ~mask); ++ writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); ++ ++ mask = GMAC0_IRQ4_8 << (netdev->dev_id * 8); ++ val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ val = enable ? (val | mask) : (val & ~mask); ++ writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ ++ spin_unlock_irqrestore(&geth->irq_lock, flags); ++} ++ ++static void gmac_enable_rx_irq(struct net_device *netdev, int enable) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct gemini_ethernet *geth = port->geth; ++ unsigned long flags; ++ u32 val, mask; ++ ++ netdev_dbg(netdev, "%s device %d %s\n", __func__, netdev->dev_id, ++ enable ? "enable" : "disable"); ++ spin_lock_irqsave(&geth->irq_lock, flags); ++ mask = DEFAULT_Q0_INT_BIT << netdev->dev_id; ++ ++ val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); ++ val = enable ? (val | mask) : (val & ~mask); ++ writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); ++ ++ spin_unlock_irqrestore(&geth->irq_lock, flags); ++} ++ ++static struct sk_buff *gmac_skb_if_good_frame(struct gemini_ethernet_port *port, ++ union gmac_rxdesc_0 word0, ++ unsigned int frame_len) ++{ ++ unsigned int rx_csum = word0.bits.chksum_status; ++ unsigned int rx_status = word0.bits.status; ++ struct sk_buff *skb = NULL; ++ ++ port->rx_stats[rx_status]++; ++ port->rx_csum_stats[rx_csum]++; ++ ++ if (word0.bits.derr || word0.bits.perr || ++ rx_status || frame_len < ETH_ZLEN || ++ rx_csum >= RX_CHKSUM_IP_ERR_UNKNOWN) { ++ port->stats.rx_errors++; ++ ++ if (frame_len < ETH_ZLEN || RX_ERROR_LENGTH(rx_status)) ++ port->stats.rx_length_errors++; ++ if (RX_ERROR_OVER(rx_status)) ++ port->stats.rx_over_errors++; ++ if (RX_ERROR_CRC(rx_status)) ++ port->stats.rx_crc_errors++; ++ if (RX_ERROR_FRAME(rx_status)) ++ port->stats.rx_frame_errors++; ++ return NULL; ++ } ++ ++ skb = napi_get_frags(&port->napi); ++ if (!skb) ++ goto update_exit; ++ ++ if (rx_csum == RX_CHKSUM_IP_UDP_TCP_OK) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ ++update_exit: ++ port->stats.rx_bytes += frame_len; ++ port->stats.rx_packets++; ++ return skb; ++} ++ ++static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned short m = (1 << port->rxq_order) - 1; ++ struct gemini_ethernet *geth = port->geth; ++ void __iomem *ptr_reg = port->rxq_rwptr; ++ unsigned int frame_len, frag_len; ++ struct gmac_rxdesc *rx = NULL; ++ struct gmac_queue_page *gpage; ++ static struct sk_buff *skb; ++ union gmac_rxdesc_0 word0; ++ union gmac_rxdesc_1 word1; ++ union gmac_rxdesc_3 word3; ++ struct page *page = NULL; ++ unsigned int page_offs; ++ unsigned short r, w; ++ union dma_rwptr rw; ++ dma_addr_t mapping; ++ int frag_nr = 0; ++ ++ rw.bits32 = readl(ptr_reg); ++ /* Reset interrupt as all packages until here are taken into account */ ++ writel(DEFAULT_Q0_INT_BIT << netdev->dev_id, ++ geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); ++ r = rw.bits.rptr; ++ w = rw.bits.wptr; ++ ++ while (budget && w != r) { ++ rx = port->rxq_ring + r; ++ word0 = rx->word0; ++ word1 = rx->word1; ++ mapping = rx->word2.buf_adr; ++ word3 = rx->word3; ++ ++ r++; ++ r &= m; ++ ++ frag_len = word0.bits.buffer_size; ++ frame_len = word1.bits.byte_count; ++ page_offs = mapping & ~PAGE_MASK; ++ ++ if (!mapping) { ++ netdev_err(netdev, ++ "rxq[%u]: HW BUG: zero DMA desc\n", r); ++ goto err_drop; ++ } ++ ++ /* Freeq pointers are one page off */ ++ gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE); ++ if (!gpage) { ++ dev_err(geth->dev, "could not find mapping\n"); ++ continue; ++ } ++ page = gpage->page; ++ ++ if (word3.bits32 & SOF_BIT) { ++ if (skb) { ++ napi_free_frags(&port->napi); ++ port->stats.rx_dropped++; ++ } ++ ++ skb = gmac_skb_if_good_frame(port, word0, frame_len); ++ if (!skb) ++ goto err_drop; ++ ++ page_offs += NET_IP_ALIGN; ++ frag_len -= NET_IP_ALIGN; ++ frag_nr = 0; ++ ++ } else if (!skb) { ++ put_page(page); ++ continue; ++ } ++ ++ if (word3.bits32 & EOF_BIT) ++ frag_len = frame_len - skb->len; ++ ++ /* append page frag to skb */ ++ if (frag_nr == MAX_SKB_FRAGS) ++ goto err_drop; ++ ++ if (frag_len == 0) ++ netdev_err(netdev, "Received fragment with len = 0\n"); ++ ++ skb_fill_page_desc(skb, frag_nr, page, page_offs, frag_len); ++ skb->len += frag_len; ++ skb->data_len += frag_len; ++ skb->truesize += frag_len; ++ frag_nr++; ++ ++ if (word3.bits32 & EOF_BIT) { ++ napi_gro_frags(&port->napi); ++ skb = NULL; ++ --budget; ++ } ++ continue; ++ ++err_drop: ++ if (skb) { ++ napi_free_frags(&port->napi); ++ skb = NULL; ++ } ++ ++ if (mapping) ++ put_page(page); ++ ++ port->stats.rx_dropped++; ++ } ++ ++ writew(r, ptr_reg); ++ return budget; ++} ++ ++static int gmac_napi_poll(struct napi_struct *napi, int budget) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(napi->dev); ++ struct gemini_ethernet *geth = port->geth; ++ unsigned int freeq_threshold; ++ unsigned int received; ++ ++ freeq_threshold = 1 << (geth->freeq_order - 1); ++ u64_stats_update_begin(&port->rx_stats_syncp); ++ ++ received = gmac_rx(napi->dev, budget); ++ if (received < budget) { ++ napi_gro_flush(napi, false); ++ napi_complete_done(napi, received); ++ gmac_enable_rx_irq(napi->dev, 1); ++ ++port->rx_napi_exits; ++ } ++ ++ port->freeq_refill += (budget - received); ++ if (port->freeq_refill > freeq_threshold) { ++ port->freeq_refill -= freeq_threshold; ++ geth_fill_freeq(geth, true); ++ } ++ ++ u64_stats_update_end(&port->rx_stats_syncp); ++ return received; ++} ++ ++static void gmac_dump_dma_state(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct gemini_ethernet *geth = port->geth; ++ void __iomem *ptr_reg; ++ u32 reg[5]; ++ ++ /* Interrupt status */ ++ reg[0] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); ++ reg[1] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); ++ reg[2] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_2_REG); ++ reg[3] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_3_REG); ++ reg[4] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); ++ netdev_err(netdev, "IRQ status: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", ++ reg[0], reg[1], reg[2], reg[3], reg[4]); ++ ++ /* Interrupt enable */ ++ reg[0] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); ++ reg[1] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); ++ reg[2] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_2_REG); ++ reg[3] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_3_REG); ++ reg[4] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ netdev_err(netdev, "IRQ enable: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", ++ reg[0], reg[1], reg[2], reg[3], reg[4]); ++ ++ /* RX DMA status */ ++ reg[0] = readl(port->dma_base + GMAC_DMA_RX_FIRST_DESC_REG); ++ reg[1] = readl(port->dma_base + GMAC_DMA_RX_CURR_DESC_REG); ++ reg[2] = GET_RPTR(port->rxq_rwptr); ++ reg[3] = GET_WPTR(port->rxq_rwptr); ++ netdev_err(netdev, "RX DMA regs: 0x%08x 0x%08x, ptr: %u %u\n", ++ reg[0], reg[1], reg[2], reg[3]); ++ ++ reg[0] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD0_REG); ++ reg[1] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD1_REG); ++ reg[2] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD2_REG); ++ reg[3] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD3_REG); ++ netdev_err(netdev, "RX DMA descriptor: 0x%08x 0x%08x 0x%08x 0x%08x\n", ++ reg[0], reg[1], reg[2], reg[3]); ++ ++ /* TX DMA status */ ++ ptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; ++ ++ reg[0] = readl(port->dma_base + GMAC_DMA_TX_FIRST_DESC_REG); ++ reg[1] = readl(port->dma_base + GMAC_DMA_TX_CURR_DESC_REG); ++ reg[2] = GET_RPTR(ptr_reg); ++ reg[3] = GET_WPTR(ptr_reg); ++ netdev_err(netdev, "TX DMA regs: 0x%08x 0x%08x, ptr: %u %u\n", ++ reg[0], reg[1], reg[2], reg[3]); ++ ++ reg[0] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD0_REG); ++ reg[1] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD1_REG); ++ reg[2] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD2_REG); ++ reg[3] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD3_REG); ++ netdev_err(netdev, "TX DMA descriptor: 0x%08x 0x%08x 0x%08x 0x%08x\n", ++ reg[0], reg[1], reg[2], reg[3]); ++ ++ /* FREE queues status */ ++ ptr_reg = geth->base + GLOBAL_SWFQ_RWPTR_REG; ++ ++ reg[0] = GET_RPTR(ptr_reg); ++ reg[1] = GET_WPTR(ptr_reg); ++ ++ ptr_reg = geth->base + GLOBAL_HWFQ_RWPTR_REG; ++ ++ reg[2] = GET_RPTR(ptr_reg); ++ reg[3] = GET_WPTR(ptr_reg); ++ netdev_err(netdev, "FQ SW ptr: %u %u, HW ptr: %u %u\n", ++ reg[0], reg[1], reg[2], reg[3]); ++} ++ ++static void gmac_update_hw_stats(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned int rx_discards, rx_mcast, rx_bcast; ++ struct gemini_ethernet *geth = port->geth; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&geth->irq_lock, flags); ++ u64_stats_update_begin(&port->ir_stats_syncp); ++ ++ rx_discards = readl(port->gmac_base + GMAC_IN_DISCARDS); ++ port->hw_stats[0] += rx_discards; ++ port->hw_stats[1] += readl(port->gmac_base + GMAC_IN_ERRORS); ++ rx_mcast = readl(port->gmac_base + GMAC_IN_MCAST); ++ port->hw_stats[2] += rx_mcast; ++ rx_bcast = readl(port->gmac_base + GMAC_IN_BCAST); ++ port->hw_stats[3] += rx_bcast; ++ port->hw_stats[4] += readl(port->gmac_base + GMAC_IN_MAC1); ++ port->hw_stats[5] += readl(port->gmac_base + GMAC_IN_MAC2); ++ ++ port->stats.rx_missed_errors += rx_discards; ++ port->stats.multicast += rx_mcast; ++ port->stats.multicast += rx_bcast; ++ ++ writel(GMAC0_MIB_INT_BIT << (netdev->dev_id * 8), ++ geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); ++ ++ u64_stats_update_end(&port->ir_stats_syncp); ++ spin_unlock_irqrestore(&geth->irq_lock, flags); ++} ++ ++/** ++ * gmac_get_intr_flags() - get interrupt status flags for a port from ++ * @netdev: the net device for the port to get flags from ++ * @i: the interrupt status register 0..4 ++ */ ++static u32 gmac_get_intr_flags(struct net_device *netdev, int i) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ struct gemini_ethernet *geth = port->geth; ++ void __iomem *irqif_reg, *irqen_reg; ++ unsigned int offs, val; ++ ++ /* Calculate the offset using the stride of the status registers */ ++ offs = i * (GLOBAL_INTERRUPT_STATUS_1_REG - ++ GLOBAL_INTERRUPT_STATUS_0_REG); ++ ++ irqif_reg = geth->base + GLOBAL_INTERRUPT_STATUS_0_REG + offs; ++ irqen_reg = geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG + offs; ++ ++ val = readl(irqif_reg) & readl(irqen_reg); ++ return val; ++} ++ ++static enum hrtimer_restart gmac_coalesce_delay_expired(struct hrtimer *timer) ++{ ++ struct gemini_ethernet_port *port = ++ container_of(timer, struct gemini_ethernet_port, ++ rx_coalesce_timer); ++ ++ napi_schedule(&port->napi); ++ return HRTIMER_NORESTART; ++} ++ ++static irqreturn_t gmac_irq(int irq, void *data) ++{ ++ struct gemini_ethernet_port *port; ++ struct net_device *netdev = data; ++ struct gemini_ethernet *geth; ++ u32 val, orr = 0; ++ ++ port = netdev_priv(netdev); ++ geth = port->geth; ++ ++ val = gmac_get_intr_flags(netdev, 0); ++ orr |= val; ++ ++ if (val & (GMAC0_IRQ0_2 << (netdev->dev_id * 2))) { ++ /* Oh, crap */ ++ netdev_err(netdev, "hw failure/sw bug\n"); ++ gmac_dump_dma_state(netdev); ++ ++ /* don't know how to recover, just reduce losses */ ++ gmac_enable_irq(netdev, 0); ++ return IRQ_HANDLED; ++ } ++ ++ if (val & (GMAC0_IRQ0_TXQ0_INTS << (netdev->dev_id * 6))) ++ gmac_tx_irq(netdev, 0); ++ ++ val = gmac_get_intr_flags(netdev, 1); ++ orr |= val; ++ ++ if (val & (DEFAULT_Q0_INT_BIT << netdev->dev_id)) { ++ gmac_enable_rx_irq(netdev, 0); ++ ++ if (!port->rx_coalesce_nsecs) { ++ napi_schedule(&port->napi); ++ } else { ++ ktime_t ktime; ++ ++ ktime = ktime_set(0, port->rx_coalesce_nsecs); ++ hrtimer_start(&port->rx_coalesce_timer, ktime, ++ HRTIMER_MODE_REL); ++ } ++ } ++ ++ val = gmac_get_intr_flags(netdev, 4); ++ orr |= val; ++ ++ if (val & (GMAC0_MIB_INT_BIT << (netdev->dev_id * 8))) ++ gmac_update_hw_stats(netdev); ++ ++ if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) { ++ writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8), ++ geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); ++ ++ spin_lock(&geth->irq_lock); ++ u64_stats_update_begin(&port->ir_stats_syncp); ++ ++port->stats.rx_fifo_errors; ++ u64_stats_update_end(&port->ir_stats_syncp); ++ spin_unlock(&geth->irq_lock); ++ } ++ ++ return orr ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++static void gmac_start_dma(struct gemini_ethernet_port *port) ++{ ++ void __iomem *dma_ctrl_reg = port->dma_base + GMAC_DMA_CTRL_REG; ++ union gmac_dma_ctrl dma_ctrl; ++ ++ dma_ctrl.bits32 = readl(dma_ctrl_reg); ++ dma_ctrl.bits.rd_enable = 1; ++ dma_ctrl.bits.td_enable = 1; ++ dma_ctrl.bits.loopback = 0; ++ dma_ctrl.bits.drop_small_ack = 0; ++ dma_ctrl.bits.rd_insert_bytes = NET_IP_ALIGN; ++ dma_ctrl.bits.rd_prot = HPROT_DATA_CACHE | HPROT_PRIVILIGED; ++ dma_ctrl.bits.rd_burst_size = HBURST_INCR8; ++ dma_ctrl.bits.rd_bus = HSIZE_8; ++ dma_ctrl.bits.td_prot = HPROT_DATA_CACHE; ++ dma_ctrl.bits.td_burst_size = HBURST_INCR8; ++ dma_ctrl.bits.td_bus = HSIZE_8; ++ ++ writel(dma_ctrl.bits32, dma_ctrl_reg); ++} ++ ++static void gmac_stop_dma(struct gemini_ethernet_port *port) ++{ ++ void __iomem *dma_ctrl_reg = port->dma_base + GMAC_DMA_CTRL_REG; ++ union gmac_dma_ctrl dma_ctrl; ++ ++ dma_ctrl.bits32 = readl(dma_ctrl_reg); ++ dma_ctrl.bits.rd_enable = 0; ++ dma_ctrl.bits.td_enable = 0; ++ writel(dma_ctrl.bits32, dma_ctrl_reg); ++} ++ ++static int gmac_open(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ int err; ++ ++ if (!netdev->phydev) { ++ err = gmac_setup_phy(netdev); ++ if (err) { ++ netif_err(port, ifup, netdev, ++ "PHY init failed: %d\n", err); ++ return err; ++ } ++ } ++ ++ err = request_irq(netdev->irq, gmac_irq, ++ IRQF_SHARED, netdev->name, netdev); ++ if (err) { ++ netdev_err(netdev, "no IRQ\n"); ++ return err; ++ } ++ ++ netif_carrier_off(netdev); ++ phy_start(netdev->phydev); ++ ++ err = geth_resize_freeq(port); ++ if (err) { ++ netdev_err(netdev, "could not resize freeq\n"); ++ goto err_stop_phy; ++ } ++ ++ err = gmac_setup_rxq(netdev); ++ if (err) { ++ netdev_err(netdev, "could not setup RXQ\n"); ++ goto err_stop_phy; ++ } ++ ++ err = gmac_setup_txqs(netdev); ++ if (err) { ++ netdev_err(netdev, "could not setup TXQs\n"); ++ gmac_cleanup_rxq(netdev); ++ goto err_stop_phy; ++ } ++ ++ napi_enable(&port->napi); ++ ++ gmac_start_dma(port); ++ gmac_enable_irq(netdev, 1); ++ gmac_enable_tx_rx(netdev); ++ netif_tx_start_all_queues(netdev); ++ ++ hrtimer_init(&port->rx_coalesce_timer, CLOCK_MONOTONIC, ++ HRTIMER_MODE_REL); ++ port->rx_coalesce_timer.function = &gmac_coalesce_delay_expired; ++ ++ netdev_info(netdev, "opened\n"); ++ ++ return 0; ++ ++err_stop_phy: ++ phy_stop(netdev->phydev); ++ free_irq(netdev->irq, netdev); ++ return err; ++} ++ ++static int gmac_stop(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ ++ hrtimer_cancel(&port->rx_coalesce_timer); ++ netif_tx_stop_all_queues(netdev); ++ gmac_disable_tx_rx(netdev); ++ gmac_stop_dma(port); ++ napi_disable(&port->napi); ++ ++ gmac_enable_irq(netdev, 0); ++ gmac_cleanup_rxq(netdev); ++ gmac_cleanup_txqs(netdev); ++ ++ phy_stop(netdev->phydev); ++ free_irq(netdev->irq, netdev); ++ ++ gmac_update_hw_stats(netdev); ++ return 0; ++} ++ ++static void gmac_set_rx_mode(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ union gmac_rx_fltr filter = { .bits = { ++ .broadcast = 1, ++ .multicast = 1, ++ .unicast = 1, ++ } }; ++ struct netdev_hw_addr *ha; ++ unsigned int bit_nr; ++ u32 mc_filter[2]; ++ ++ mc_filter[1] = 0; ++ mc_filter[0] = 0; ++ ++ if (netdev->flags & IFF_PROMISC) { ++ filter.bits.error = 1; ++ filter.bits.promiscuous = 1; ++ mc_filter[1] = ~0; ++ mc_filter[0] = ~0; ++ } else if (netdev->flags & IFF_ALLMULTI) { ++ mc_filter[1] = ~0; ++ mc_filter[0] = ~0; ++ } else { ++ netdev_for_each_mc_addr(ha, netdev) { ++ bit_nr = ~crc32_le(~0, ha->addr, ETH_ALEN) & 0x3f; ++ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 0x1f); ++ } ++ } ++ ++ writel(mc_filter[0], port->gmac_base + GMAC_MCAST_FIL0); ++ writel(mc_filter[1], port->gmac_base + GMAC_MCAST_FIL1); ++ writel(filter.bits32, port->gmac_base + GMAC_RX_FLTR); ++} ++ ++static void gmac_write_mac_address(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ __le32 addr[3]; ++ ++ memset(addr, 0, sizeof(addr)); ++ memcpy(addr, netdev->dev_addr, ETH_ALEN); ++ ++ writel(le32_to_cpu(addr[0]), port->gmac_base + GMAC_STA_ADD0); ++ writel(le32_to_cpu(addr[1]), port->gmac_base + GMAC_STA_ADD1); ++ writel(le32_to_cpu(addr[2]), port->gmac_base + GMAC_STA_ADD2); ++} ++ ++static int gmac_set_mac_address(struct net_device *netdev, void *addr) ++{ ++ struct sockaddr *sa = addr; ++ ++ memcpy(netdev->dev_addr, sa->sa_data, ETH_ALEN); ++ gmac_write_mac_address(netdev); ++ ++ return 0; ++} ++ ++static void gmac_clear_hw_stats(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ ++ readl(port->gmac_base + GMAC_IN_DISCARDS); ++ readl(port->gmac_base + GMAC_IN_ERRORS); ++ readl(port->gmac_base + GMAC_IN_MCAST); ++ readl(port->gmac_base + GMAC_IN_BCAST); ++ readl(port->gmac_base + GMAC_IN_MAC1); ++ readl(port->gmac_base + GMAC_IN_MAC2); ++} ++ ++static void gmac_get_stats64(struct net_device *netdev, ++ struct rtnl_link_stats64 *stats) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned int start; ++ ++ gmac_update_hw_stats(netdev); ++ ++ /* Racing with RX NAPI */ ++ do { ++ start = u64_stats_fetch_begin(&port->rx_stats_syncp); ++ ++ stats->rx_packets = port->stats.rx_packets; ++ stats->rx_bytes = port->stats.rx_bytes; ++ stats->rx_errors = port->stats.rx_errors; ++ stats->rx_dropped = port->stats.rx_dropped; ++ ++ stats->rx_length_errors = port->stats.rx_length_errors; ++ stats->rx_over_errors = port->stats.rx_over_errors; ++ stats->rx_crc_errors = port->stats.rx_crc_errors; ++ stats->rx_frame_errors = port->stats.rx_frame_errors; ++ ++ } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); ++ ++ /* Racing with MIB and TX completion interrupts */ ++ do { ++ start = u64_stats_fetch_begin(&port->ir_stats_syncp); ++ ++ stats->tx_errors = port->stats.tx_errors; ++ stats->tx_packets = port->stats.tx_packets; ++ stats->tx_bytes = port->stats.tx_bytes; ++ ++ stats->multicast = port->stats.multicast; ++ stats->rx_missed_errors = port->stats.rx_missed_errors; ++ stats->rx_fifo_errors = port->stats.rx_fifo_errors; ++ ++ } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); ++ ++ /* Racing with hard_start_xmit */ ++ do { ++ start = u64_stats_fetch_begin(&port->tx_stats_syncp); ++ ++ stats->tx_dropped = port->stats.tx_dropped; ++ ++ } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); ++ ++ stats->rx_dropped += stats->rx_missed_errors; ++} ++ ++static int gmac_change_mtu(struct net_device *netdev, int new_mtu) ++{ ++ int max_len = gmac_pick_rx_max_len(new_mtu); ++ ++ if (max_len < 0) ++ return -EINVAL; ++ ++ gmac_disable_tx_rx(netdev); ++ ++ netdev->mtu = new_mtu; ++ gmac_update_config0_reg(netdev, max_len << CONFIG0_MAXLEN_SHIFT, ++ CONFIG0_MAXLEN_MASK); ++ ++ netdev_update_features(netdev); ++ ++ gmac_enable_tx_rx(netdev); ++ ++ return 0; ++} ++ ++static netdev_features_t gmac_fix_features(struct net_device *netdev, ++ netdev_features_t features) ++{ ++ if (netdev->mtu + ETH_HLEN + VLAN_HLEN > MTU_SIZE_BIT_MASK) ++ features &= ~GMAC_OFFLOAD_FEATURES; ++ ++ return features; ++} ++ ++static int gmac_set_features(struct net_device *netdev, ++ netdev_features_t features) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ int enable = features & NETIF_F_RXCSUM; ++ unsigned long flags; ++ u32 reg; ++ ++ spin_lock_irqsave(&port->config_lock, flags); ++ ++ reg = readl(port->gmac_base + GMAC_CONFIG0); ++ reg = enable ? reg | CONFIG0_RX_CHKSUM : reg & ~CONFIG0_RX_CHKSUM; ++ writel(reg, port->gmac_base + GMAC_CONFIG0); ++ ++ spin_unlock_irqrestore(&port->config_lock, flags); ++ return 0; ++} ++ ++static int gmac_get_sset_count(struct net_device *netdev, int sset) ++{ ++ return sset == ETH_SS_STATS ? GMAC_STATS_NUM : 0; ++} ++ ++static void gmac_get_strings(struct net_device *netdev, u32 stringset, u8 *data) ++{ ++ if (stringset != ETH_SS_STATS) ++ return; ++ ++ memcpy(data, gmac_stats_strings, sizeof(gmac_stats_strings)); ++} ++ ++static void gmac_get_ethtool_stats(struct net_device *netdev, ++ struct ethtool_stats *estats, u64 *values) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ unsigned int start; ++ u64 *p; ++ int i; ++ ++ gmac_update_hw_stats(netdev); ++ ++ /* Racing with MIB interrupt */ ++ do { ++ p = values; ++ start = u64_stats_fetch_begin(&port->ir_stats_syncp); ++ ++ for (i = 0; i < RX_STATS_NUM; i++) ++ *p++ = port->hw_stats[i]; ++ ++ } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); ++ values = p; ++ ++ /* Racing with RX NAPI */ ++ do { ++ p = values; ++ start = u64_stats_fetch_begin(&port->rx_stats_syncp); ++ ++ for (i = 0; i < RX_STATUS_NUM; i++) ++ *p++ = port->rx_stats[i]; ++ for (i = 0; i < RX_CHKSUM_NUM; i++) ++ *p++ = port->rx_csum_stats[i]; ++ *p++ = port->rx_napi_exits; ++ ++ } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); ++ values = p; ++ ++ /* Racing with TX start_xmit */ ++ do { ++ p = values; ++ start = u64_stats_fetch_begin(&port->tx_stats_syncp); ++ ++ for (i = 0; i < TX_MAX_FRAGS; i++) { ++ *values++ = port->tx_frag_stats[i]; ++ port->tx_frag_stats[i] = 0; ++ } ++ *values++ = port->tx_frags_linearized; ++ *values++ = port->tx_hw_csummed; ++ ++ } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); ++} ++ ++static int gmac_get_ksettings(struct net_device *netdev, ++ struct ethtool_link_ksettings *cmd) ++{ ++ if (!netdev->phydev) ++ return -ENXIO; ++ phy_ethtool_ksettings_get(netdev->phydev, cmd); ++ ++ return 0; ++} ++ ++static int gmac_set_ksettings(struct net_device *netdev, ++ const struct ethtool_link_ksettings *cmd) ++{ ++ if (!netdev->phydev) ++ return -ENXIO; ++ return phy_ethtool_ksettings_set(netdev->phydev, cmd); ++} ++ ++static int gmac_nway_reset(struct net_device *netdev) ++{ ++ if (!netdev->phydev) ++ return -ENXIO; ++ return phy_start_aneg(netdev->phydev); ++} ++ ++static void gmac_get_pauseparam(struct net_device *netdev, ++ struct ethtool_pauseparam *pparam) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ union gmac_config0 config0; ++ ++ config0.bits32 = readl(port->gmac_base + GMAC_CONFIG0); ++ ++ pparam->rx_pause = config0.bits.rx_fc_en; ++ pparam->tx_pause = config0.bits.tx_fc_en; ++ pparam->autoneg = true; ++} ++ ++static void gmac_get_ringparam(struct net_device *netdev, ++ struct ethtool_ringparam *rp) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ union gmac_config0 config0; ++ ++ config0.bits32 = readl(port->gmac_base + GMAC_CONFIG0); ++ ++ rp->rx_max_pending = 1 << 15; ++ rp->rx_mini_max_pending = 0; ++ rp->rx_jumbo_max_pending = 0; ++ rp->tx_max_pending = 1 << 15; ++ ++ rp->rx_pending = 1 << port->rxq_order; ++ rp->rx_mini_pending = 0; ++ rp->rx_jumbo_pending = 0; ++ rp->tx_pending = 1 << port->txq_order; ++} ++ ++static int gmac_set_ringparam(struct net_device *netdev, ++ struct ethtool_ringparam *rp) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ int err = 0; ++ ++ if (netif_running(netdev)) ++ return -EBUSY; ++ ++ if (rp->rx_pending) { ++ port->rxq_order = min(15, ilog2(rp->rx_pending - 1) + 1); ++ err = geth_resize_freeq(port); ++ } ++ if (rp->tx_pending) { ++ port->txq_order = min(15, ilog2(rp->tx_pending - 1) + 1); ++ port->irq_every_tx_packets = 1 << (port->txq_order - 2); ++ } ++ ++ return err; ++} ++ ++static int gmac_get_coalesce(struct net_device *netdev, ++ struct ethtool_coalesce *ecmd) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ ++ ecmd->rx_max_coalesced_frames = 1; ++ ecmd->tx_max_coalesced_frames = port->irq_every_tx_packets; ++ ecmd->rx_coalesce_usecs = port->rx_coalesce_nsecs / 1000; ++ ++ return 0; ++} ++ ++static int gmac_set_coalesce(struct net_device *netdev, ++ struct ethtool_coalesce *ecmd) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ ++ if (ecmd->tx_max_coalesced_frames < 1) ++ return -EINVAL; ++ if (ecmd->tx_max_coalesced_frames >= 1 << port->txq_order) ++ return -EINVAL; ++ ++ port->irq_every_tx_packets = ecmd->tx_max_coalesced_frames; ++ port->rx_coalesce_nsecs = ecmd->rx_coalesce_usecs * 1000; ++ ++ return 0; ++} ++ ++static u32 gmac_get_msglevel(struct net_device *netdev) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ ++ return port->msg_enable; ++} ++ ++static void gmac_set_msglevel(struct net_device *netdev, u32 level) ++{ ++ struct gemini_ethernet_port *port = netdev_priv(netdev); ++ ++ port->msg_enable = level; ++} ++ ++static void gmac_get_drvinfo(struct net_device *netdev, ++ struct ethtool_drvinfo *info) ++{ ++ strcpy(info->driver, DRV_NAME); ++ strcpy(info->version, DRV_VERSION); ++ strcpy(info->bus_info, netdev->dev_id ? "1" : "0"); ++} ++ ++static const struct net_device_ops gmac_351x_ops = { ++ .ndo_init = gmac_init, ++ .ndo_uninit = gmac_uninit, ++ .ndo_open = gmac_open, ++ .ndo_stop = gmac_stop, ++ .ndo_start_xmit = gmac_start_xmit, ++ .ndo_tx_timeout = gmac_tx_timeout, ++ .ndo_set_rx_mode = gmac_set_rx_mode, ++ .ndo_set_mac_address = gmac_set_mac_address, ++ .ndo_get_stats64 = gmac_get_stats64, ++ .ndo_change_mtu = gmac_change_mtu, ++ .ndo_fix_features = gmac_fix_features, ++ .ndo_set_features = gmac_set_features, ++}; ++ ++static const struct ethtool_ops gmac_351x_ethtool_ops = { ++ .get_sset_count = gmac_get_sset_count, ++ .get_strings = gmac_get_strings, ++ .get_ethtool_stats = gmac_get_ethtool_stats, ++ .get_link = ethtool_op_get_link, ++ .get_link_ksettings = gmac_get_ksettings, ++ .set_link_ksettings = gmac_set_ksettings, ++ .nway_reset = gmac_nway_reset, ++ .get_pauseparam = gmac_get_pauseparam, ++ .get_ringparam = gmac_get_ringparam, ++ .set_ringparam = gmac_set_ringparam, ++ .get_coalesce = gmac_get_coalesce, ++ .set_coalesce = gmac_set_coalesce, ++ .get_msglevel = gmac_get_msglevel, ++ .set_msglevel = gmac_set_msglevel, ++ .get_drvinfo = gmac_get_drvinfo, ++}; ++ ++static irqreturn_t gemini_port_irq_thread(int irq, void *data) ++{ ++ unsigned long irqmask = SWFQ_EMPTY_INT_BIT; ++ struct gemini_ethernet_port *port = data; ++ struct gemini_ethernet *geth; ++ unsigned long flags; ++ ++ geth = port->geth; ++ /* The queue is half empty so refill it */ ++ geth_fill_freeq(geth, true); ++ ++ spin_lock_irqsave(&geth->irq_lock, flags); ++ /* ACK queue interrupt */ ++ writel(irqmask, geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); ++ /* Enable queue interrupt again */ ++ irqmask |= readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ writel(irqmask, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ spin_unlock_irqrestore(&geth->irq_lock, flags); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t gemini_port_irq(int irq, void *data) ++{ ++ struct gemini_ethernet_port *port = data; ++ struct gemini_ethernet *geth; ++ irqreturn_t ret = IRQ_NONE; ++ u32 val, en; ++ ++ geth = port->geth; ++ spin_lock(&geth->irq_lock); ++ ++ val = readl(geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); ++ en = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ ++ if (val & en & SWFQ_EMPTY_INT_BIT) { ++ /* Disable the queue empty interrupt while we work on ++ * processing the queue. Also disable overrun interrupts ++ * as there is not much we can do about it here. ++ */ ++ en &= ~(SWFQ_EMPTY_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT ++ | GMAC1_RX_OVERRUN_INT_BIT); ++ writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ ret = IRQ_WAKE_THREAD; ++ } ++ ++ spin_unlock(&geth->irq_lock); ++ ++ return ret; ++} ++ ++static void gemini_port_remove(struct gemini_ethernet_port *port) ++{ ++ if (port->netdev) ++ unregister_netdev(port->netdev); ++ clk_disable_unprepare(port->pclk); ++ geth_cleanup_freeq(port->geth); ++} ++ ++static void gemini_ethernet_init(struct gemini_ethernet *geth) ++{ ++ writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); ++ writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); ++ writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_2_REG); ++ writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_3_REG); ++ writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); ++ ++ /* Interrupt config: ++ * ++ * GMAC0 intr bits ------> int0 ----> eth0 ++ * GMAC1 intr bits ------> int1 ----> eth1 ++ * TOE intr -------------> int1 ----> eth1 ++ * Classification Intr --> int0 ----> eth0 ++ * Default Q0 -----------> int0 ----> eth0 ++ * Default Q1 -----------> int1 ----> eth1 ++ * FreeQ intr -----------> int1 ----> eth1 ++ */ ++ writel(0xCCFC0FC0, geth->base + GLOBAL_INTERRUPT_SELECT_0_REG); ++ writel(0x00F00002, geth->base + GLOBAL_INTERRUPT_SELECT_1_REG); ++ writel(0xFFFFFFFF, geth->base + GLOBAL_INTERRUPT_SELECT_2_REG); ++ writel(0xFFFFFFFF, geth->base + GLOBAL_INTERRUPT_SELECT_3_REG); ++ writel(0xFF000003, geth->base + GLOBAL_INTERRUPT_SELECT_4_REG); ++ ++ /* edge-triggered interrupts packed to level-triggered one... */ ++ writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); ++ writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); ++ writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_2_REG); ++ writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_3_REG); ++ writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); ++ ++ /* Set up queue */ ++ writel(0, geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); ++ writel(0, geth->base + GLOBAL_HW_FREEQ_BASE_SIZE_REG); ++ writel(0, geth->base + GLOBAL_SWFQ_RWPTR_REG); ++ writel(0, geth->base + GLOBAL_HWFQ_RWPTR_REG); ++ ++ geth->freeq_frag_order = DEFAULT_RX_BUF_ORDER; ++ /* This makes the queue resize on probe() so that we ++ * set up and enable the queue IRQ. FIXME: fragile. ++ */ ++ geth->freeq_order = 1; ++} ++ ++static void gemini_port_save_mac_addr(struct gemini_ethernet_port *port) ++{ ++ port->mac_addr[0] = ++ cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD0)); ++ port->mac_addr[1] = ++ cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD1)); ++ port->mac_addr[2] = ++ cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD2)); ++} ++ ++static int gemini_ethernet_port_probe(struct platform_device *pdev) ++{ ++ char *port_names[2] = { "ethernet0", "ethernet1" }; ++ struct gemini_ethernet_port *port; ++ struct device *dev = &pdev->dev; ++ struct gemini_ethernet *geth; ++ struct net_device *netdev; ++ struct resource *gmacres; ++ struct resource *dmares; ++ struct device *parent; ++ unsigned int id; ++ int irq; ++ int ret; ++ ++ parent = dev->parent; ++ geth = dev_get_drvdata(parent); ++ ++ if (!strcmp(dev_name(dev), "60008000.ethernet-port")) ++ id = 0; ++ else if (!strcmp(dev_name(dev), "6000c000.ethernet-port")) ++ id = 1; ++ else ++ return -ENODEV; ++ ++ dev_info(dev, "probe %s ID %d\n", dev_name(dev), id); ++ ++ netdev = alloc_etherdev_mq(sizeof(*port), TX_QUEUE_NUM); ++ if (!netdev) { ++ dev_err(dev, "Can't allocate ethernet device #%d\n", id); ++ return -ENOMEM; ++ } ++ ++ port = netdev_priv(netdev); ++ SET_NETDEV_DEV(netdev, dev); ++ port->netdev = netdev; ++ port->id = id; ++ port->geth = geth; ++ port->dev = dev; ++ ++ /* DMA memory */ ++ dmares = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!dmares) { ++ dev_err(dev, "no DMA resource\n"); ++ return -ENODEV; ++ } ++ port->dma_base = devm_ioremap_resource(dev, dmares); ++ if (IS_ERR(port->dma_base)) ++ return PTR_ERR(port->dma_base); ++ ++ /* GMAC config memory */ ++ gmacres = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!gmacres) { ++ dev_err(dev, "no GMAC resource\n"); ++ return -ENODEV; ++ } ++ port->gmac_base = devm_ioremap_resource(dev, gmacres); ++ if (IS_ERR(port->gmac_base)) ++ return PTR_ERR(port->gmac_base); ++ ++ /* Interrupt */ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) { ++ dev_err(dev, "no IRQ\n"); ++ return irq ? irq : -ENODEV; ++ } ++ port->irq = irq; ++ ++ /* Clock the port */ ++ port->pclk = devm_clk_get(dev, "PCLK"); ++ if (IS_ERR(port->pclk)) { ++ dev_err(dev, "no PCLK\n"); ++ return PTR_ERR(port->pclk); ++ } ++ ret = clk_prepare_enable(port->pclk); ++ if (ret) ++ return ret; ++ ++ /* Maybe there is a nice ethernet address we should use */ ++ gemini_port_save_mac_addr(port); ++ ++ /* Reset the port */ ++ port->reset = devm_reset_control_get_exclusive(dev, NULL); ++ if (IS_ERR(port->reset)) { ++ dev_err(dev, "no reset\n"); ++ return PTR_ERR(port->reset); ++ } ++ reset_control_reset(port->reset); ++ usleep_range(100, 500); ++ ++ /* Assign pointer in the main state container */ ++ if (!id) ++ geth->port0 = port; ++ else ++ geth->port1 = port; ++ platform_set_drvdata(pdev, port); ++ ++ /* Set up and register the netdev */ ++ netdev->dev_id = port->id; ++ netdev->irq = irq; ++ netdev->netdev_ops = &gmac_351x_ops; ++ netdev->ethtool_ops = &gmac_351x_ethtool_ops; ++ ++ spin_lock_init(&port->config_lock); ++ gmac_clear_hw_stats(netdev); ++ ++ netdev->hw_features = GMAC_OFFLOAD_FEATURES; ++ netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; ++ ++ port->freeq_refill = 0; ++ netif_napi_add(netdev, &port->napi, gmac_napi_poll, ++ DEFAULT_NAPI_WEIGHT); ++ ++ if (is_valid_ether_addr((void *)port->mac_addr)) { ++ memcpy(netdev->dev_addr, port->mac_addr, ETH_ALEN); ++ } else { ++ dev_dbg(dev, "ethernet address 0x%08x%08x%08x invalid\n", ++ port->mac_addr[0], port->mac_addr[1], ++ port->mac_addr[2]); ++ dev_info(dev, "using a random ethernet address\n"); ++ random_ether_addr(netdev->dev_addr); ++ } ++ gmac_write_mac_address(netdev); ++ ++ ret = devm_request_threaded_irq(port->dev, ++ port->irq, ++ gemini_port_irq, ++ gemini_port_irq_thread, ++ IRQF_SHARED, ++ port_names[port->id], ++ port); ++ if (ret) ++ return ret; ++ ++ ret = register_netdev(netdev); ++ if (!ret) { ++ netdev_info(netdev, ++ "irq %d, DMA @ 0x%pap, GMAC @ 0x%pap\n", ++ port->irq, &dmares->start, ++ &gmacres->start); ++ ret = gmac_setup_phy(netdev); ++ if (ret) ++ netdev_info(netdev, ++ "PHY init failed, deferring to ifup time\n"); ++ return 0; ++ } ++ ++ port->netdev = NULL; ++ free_netdev(netdev); ++ return ret; ++} ++ ++static int gemini_ethernet_port_remove(struct platform_device *pdev) ++{ ++ struct gemini_ethernet_port *port = platform_get_drvdata(pdev); ++ ++ gemini_port_remove(port); ++ return 0; ++} ++ ++static const struct of_device_id gemini_ethernet_port_of_match[] = { ++ { ++ .compatible = "cortina,gemini-ethernet-port", ++ }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, gemini_ethernet_port_of_match); ++ ++static struct platform_driver gemini_ethernet_port_driver = { ++ .driver = { ++ .name = "gemini-ethernet-port", ++ .of_match_table = of_match_ptr(gemini_ethernet_port_of_match), ++ }, ++ .probe = gemini_ethernet_port_probe, ++ .remove = gemini_ethernet_port_remove, ++}; ++ ++static int gemini_ethernet_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct gemini_ethernet *geth; ++ unsigned int retry = 5; ++ struct resource *res; ++ u32 val; ++ ++ /* Global registers */ ++ geth = devm_kzalloc(dev, sizeof(*geth), GFP_KERNEL); ++ if (!geth) ++ return -ENOMEM; ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -ENODEV; ++ geth->base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(geth->base)) ++ return PTR_ERR(geth->base); ++ geth->dev = dev; ++ ++ /* Wait for ports to stabilize */ ++ do { ++ udelay(2); ++ val = readl(geth->base + GLOBAL_TOE_VERSION_REG); ++ barrier(); ++ } while (!val && --retry); ++ if (!retry) { ++ dev_err(dev, "failed to reset ethernet\n"); ++ return -EIO; ++ } ++ dev_info(dev, "Ethernet device ID: 0x%03x, revision 0x%01x\n", ++ (val >> 4) & 0xFFFU, val & 0xFU); ++ ++ spin_lock_init(&geth->irq_lock); ++ spin_lock_init(&geth->freeq_lock); ++ gemini_ethernet_init(geth); ++ ++ /* The children will use this */ ++ platform_set_drvdata(pdev, geth); ++ ++ /* Spawn child devices for the two ports */ ++ return devm_of_platform_populate(dev); ++} ++ ++static int gemini_ethernet_remove(struct platform_device *pdev) ++{ ++ struct gemini_ethernet *geth = platform_get_drvdata(pdev); ++ ++ gemini_ethernet_init(geth); ++ geth_cleanup_freeq(geth); ++ ++ return 0; ++} ++ ++static const struct of_device_id gemini_ethernet_of_match[] = { ++ { ++ .compatible = "cortina,gemini-ethernet", ++ }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, gemini_ethernet_of_match); ++ ++static struct platform_driver gemini_ethernet_driver = { ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = of_match_ptr(gemini_ethernet_of_match), ++ }, ++ .probe = gemini_ethernet_probe, ++ .remove = gemini_ethernet_remove, ++}; ++ ++static int __init gemini_ethernet_module_init(void) ++{ ++ int ret; ++ ++ ret = platform_driver_register(&gemini_ethernet_port_driver); ++ if (ret) ++ return ret; ++ ++ ret = platform_driver_register(&gemini_ethernet_driver); ++ if (ret) { ++ platform_driver_unregister(&gemini_ethernet_port_driver); ++ return ret; ++ } ++ ++ return 0; ++} ++module_init(gemini_ethernet_module_init); ++ ++static void __exit gemini_ethernet_module_exit(void) ++{ ++ platform_driver_unregister(&gemini_ethernet_driver); ++ platform_driver_unregister(&gemini_ethernet_port_driver); ++} ++module_exit(gemini_ethernet_module_exit); ++ ++MODULE_AUTHOR("Linus Walleij "); ++MODULE_DESCRIPTION("StorLink SL351x (Gemini) ethernet driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:" DRV_NAME); +--- /dev/null ++++ b/drivers/net/ethernet/cortina/gemini.h +@@ -0,0 +1,958 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Register definitions for Gemini GMAC Ethernet device driver ++ * ++ * Copyright (C) 2006 Storlink, Corp. ++ * Copyright (C) 2008-2009 Paulius Zaleckas ++ * Copyright (C) 2010 MichaÅ‚ MirosÅ‚aw ++ * Copytight (C) 2017 Linus Walleij ++ */ ++#ifndef _GEMINI_ETHERNET_H ++#define _GEMINI_ETHERNET_H ++ ++#include ++ ++/* Base Registers */ ++#define TOE_NONTOE_QUE_HDR_BASE 0x2000 ++#define TOE_TOE_QUE_HDR_BASE 0x3000 ++ ++/* Queue ID */ ++#define TOE_SW_FREE_QID 0x00 ++#define TOE_HW_FREE_QID 0x01 ++#define TOE_GMAC0_SW_TXQ0_QID 0x02 ++#define TOE_GMAC0_SW_TXQ1_QID 0x03 ++#define TOE_GMAC0_SW_TXQ2_QID 0x04 ++#define TOE_GMAC0_SW_TXQ3_QID 0x05 ++#define TOE_GMAC0_SW_TXQ4_QID 0x06 ++#define TOE_GMAC0_SW_TXQ5_QID 0x07 ++#define TOE_GMAC0_HW_TXQ0_QID 0x08 ++#define TOE_GMAC0_HW_TXQ1_QID 0x09 ++#define TOE_GMAC0_HW_TXQ2_QID 0x0A ++#define TOE_GMAC0_HW_TXQ3_QID 0x0B ++#define TOE_GMAC1_SW_TXQ0_QID 0x12 ++#define TOE_GMAC1_SW_TXQ1_QID 0x13 ++#define TOE_GMAC1_SW_TXQ2_QID 0x14 ++#define TOE_GMAC1_SW_TXQ3_QID 0x15 ++#define TOE_GMAC1_SW_TXQ4_QID 0x16 ++#define TOE_GMAC1_SW_TXQ5_QID 0x17 ++#define TOE_GMAC1_HW_TXQ0_QID 0x18 ++#define TOE_GMAC1_HW_TXQ1_QID 0x19 ++#define TOE_GMAC1_HW_TXQ2_QID 0x1A ++#define TOE_GMAC1_HW_TXQ3_QID 0x1B ++#define TOE_GMAC0_DEFAULT_QID 0x20 ++#define TOE_GMAC1_DEFAULT_QID 0x21 ++#define TOE_CLASSIFICATION_QID(x) (0x22 + x) /* 0x22 ~ 0x2F */ ++#define TOE_TOE_QID(x) (0x40 + x) /* 0x40 ~ 0x7F */ ++ ++/* TOE DMA Queue Size should be 2^n, n = 6...12 ++ * TOE DMA Queues are the following queue types: ++ * SW Free Queue, HW Free Queue, ++ * GMAC 0/1 SW TX Q0-5, and GMAC 0/1 HW TX Q0-5 ++ * The base address and descriptor number are configured at ++ * DMA Queues Descriptor Ring Base Address/Size Register (offset 0x0004) ++ */ ++#define GET_WPTR(addr) readw((addr) + 2) ++#define GET_RPTR(addr) readw((addr)) ++#define SET_WPTR(addr, data) writew((data), (addr) + 2) ++#define SET_RPTR(addr, data) writew((data), (addr)) ++#define __RWPTR_NEXT(x, mask) (((unsigned int)(x) + 1) & (mask)) ++#define __RWPTR_PREV(x, mask) (((unsigned int)(x) - 1) & (mask)) ++#define __RWPTR_DISTANCE(r, w, mask) (((unsigned int)(w) - (r)) & (mask)) ++#define __RWPTR_MASK(order) ((1 << (order)) - 1) ++#define RWPTR_NEXT(x, order) __RWPTR_NEXT((x), __RWPTR_MASK((order))) ++#define RWPTR_PREV(x, order) __RWPTR_PREV((x), __RWPTR_MASK((order))) ++#define RWPTR_DISTANCE(r, w, order) __RWPTR_DISTANCE((r), (w), \ ++ __RWPTR_MASK((order))) ++ ++/* Global registers */ ++#define GLOBAL_TOE_VERSION_REG 0x0000 ++#define GLOBAL_SW_FREEQ_BASE_SIZE_REG 0x0004 ++#define GLOBAL_HW_FREEQ_BASE_SIZE_REG 0x0008 ++#define GLOBAL_DMA_SKB_SIZE_REG 0x0010 ++#define GLOBAL_SWFQ_RWPTR_REG 0x0014 ++#define GLOBAL_HWFQ_RWPTR_REG 0x0018 ++#define GLOBAL_INTERRUPT_STATUS_0_REG 0x0020 ++#define GLOBAL_INTERRUPT_ENABLE_0_REG 0x0024 ++#define GLOBAL_INTERRUPT_SELECT_0_REG 0x0028 ++#define GLOBAL_INTERRUPT_STATUS_1_REG 0x0030 ++#define GLOBAL_INTERRUPT_ENABLE_1_REG 0x0034 ++#define GLOBAL_INTERRUPT_SELECT_1_REG 0x0038 ++#define GLOBAL_INTERRUPT_STATUS_2_REG 0x0040 ++#define GLOBAL_INTERRUPT_ENABLE_2_REG 0x0044 ++#define GLOBAL_INTERRUPT_SELECT_2_REG 0x0048 ++#define GLOBAL_INTERRUPT_STATUS_3_REG 0x0050 ++#define GLOBAL_INTERRUPT_ENABLE_3_REG 0x0054 ++#define GLOBAL_INTERRUPT_SELECT_3_REG 0x0058 ++#define GLOBAL_INTERRUPT_STATUS_4_REG 0x0060 ++#define GLOBAL_INTERRUPT_ENABLE_4_REG 0x0064 ++#define GLOBAL_INTERRUPT_SELECT_4_REG 0x0068 ++#define GLOBAL_HASH_TABLE_BASE_REG 0x006C ++#define GLOBAL_QUEUE_THRESHOLD_REG 0x0070 ++ ++/* GMAC 0/1 DMA/TOE register */ ++#define GMAC_DMA_CTRL_REG 0x0000 ++#define GMAC_TX_WEIGHTING_CTRL_0_REG 0x0004 ++#define GMAC_TX_WEIGHTING_CTRL_1_REG 0x0008 ++#define GMAC_SW_TX_QUEUE0_PTR_REG 0x000C ++#define GMAC_SW_TX_QUEUE1_PTR_REG 0x0010 ++#define GMAC_SW_TX_QUEUE2_PTR_REG 0x0014 ++#define GMAC_SW_TX_QUEUE3_PTR_REG 0x0018 ++#define GMAC_SW_TX_QUEUE4_PTR_REG 0x001C ++#define GMAC_SW_TX_QUEUE5_PTR_REG 0x0020 ++#define GMAC_SW_TX_QUEUE_PTR_REG(i) (GMAC_SW_TX_QUEUE0_PTR_REG + 4 * (i)) ++#define GMAC_HW_TX_QUEUE0_PTR_REG 0x0024 ++#define GMAC_HW_TX_QUEUE1_PTR_REG 0x0028 ++#define GMAC_HW_TX_QUEUE2_PTR_REG 0x002C ++#define GMAC_HW_TX_QUEUE3_PTR_REG 0x0030 ++#define GMAC_HW_TX_QUEUE_PTR_REG(i) (GMAC_HW_TX_QUEUE0_PTR_REG + 4 * (i)) ++#define GMAC_DMA_TX_FIRST_DESC_REG 0x0038 ++#define GMAC_DMA_TX_CURR_DESC_REG 0x003C ++#define GMAC_DMA_TX_DESC_WORD0_REG 0x0040 ++#define GMAC_DMA_TX_DESC_WORD1_REG 0x0044 ++#define GMAC_DMA_TX_DESC_WORD2_REG 0x0048 ++#define GMAC_DMA_TX_DESC_WORD3_REG 0x004C ++#define GMAC_SW_TX_QUEUE_BASE_REG 0x0050 ++#define GMAC_HW_TX_QUEUE_BASE_REG 0x0054 ++#define GMAC_DMA_RX_FIRST_DESC_REG 0x0058 ++#define GMAC_DMA_RX_CURR_DESC_REG 0x005C ++#define GMAC_DMA_RX_DESC_WORD0_REG 0x0060 ++#define GMAC_DMA_RX_DESC_WORD1_REG 0x0064 ++#define GMAC_DMA_RX_DESC_WORD2_REG 0x0068 ++#define GMAC_DMA_RX_DESC_WORD3_REG 0x006C ++#define GMAC_HASH_ENGINE_REG0 0x0070 ++#define GMAC_HASH_ENGINE_REG1 0x0074 ++/* matching rule 0 Control register 0 */ ++#define GMAC_MR0CR0 0x0078 ++#define GMAC_MR0CR1 0x007C ++#define GMAC_MR0CR2 0x0080 ++#define GMAC_MR1CR0 0x0084 ++#define GMAC_MR1CR1 0x0088 ++#define GMAC_MR1CR2 0x008C ++#define GMAC_MR2CR0 0x0090 ++#define GMAC_MR2CR1 0x0094 ++#define GMAC_MR2CR2 0x0098 ++#define GMAC_MR3CR0 0x009C ++#define GMAC_MR3CR1 0x00A0 ++#define GMAC_MR3CR2 0x00A4 ++/* Support Protocol Register 0 */ ++#define GMAC_SPR0 0x00A8 ++#define GMAC_SPR1 0x00AC ++#define GMAC_SPR2 0x00B0 ++#define GMAC_SPR3 0x00B4 ++#define GMAC_SPR4 0x00B8 ++#define GMAC_SPR5 0x00BC ++#define GMAC_SPR6 0x00C0 ++#define GMAC_SPR7 0x00C4 ++/* GMAC Hash/Rx/Tx AHB Weighting register */ ++#define GMAC_AHB_WEIGHT_REG 0x00C8 ++ ++/* TOE GMAC 0/1 register */ ++#define GMAC_STA_ADD0 0x0000 ++#define GMAC_STA_ADD1 0x0004 ++#define GMAC_STA_ADD2 0x0008 ++#define GMAC_RX_FLTR 0x000c ++#define GMAC_MCAST_FIL0 0x0010 ++#define GMAC_MCAST_FIL1 0x0014 ++#define GMAC_CONFIG0 0x0018 ++#define GMAC_CONFIG1 0x001c ++#define GMAC_CONFIG2 0x0020 ++#define GMAC_CONFIG3 0x0024 ++#define GMAC_RESERVED 0x0028 ++#define GMAC_STATUS 0x002c ++#define GMAC_IN_DISCARDS 0x0030 ++#define GMAC_IN_ERRORS 0x0034 ++#define GMAC_IN_MCAST 0x0038 ++#define GMAC_IN_BCAST 0x003c ++#define GMAC_IN_MAC1 0x0040 /* for STA 1 MAC Address */ ++#define GMAC_IN_MAC2 0x0044 /* for STA 2 MAC Address */ ++ ++#define RX_STATS_NUM 6 ++ ++/* DMA Queues description Ring Base Address/Size Register (offset 0x0004) */ ++union dma_q_base_size { ++ unsigned int bits32; ++ unsigned int base_size; ++}; ++ ++#define DMA_Q_BASE_MASK (~0x0f) ++ ++/* DMA SKB Buffer register (offset 0x0008) */ ++union dma_skb_size { ++ unsigned int bits32; ++ struct bit_0008 { ++ unsigned int sw_skb_size : 16; /* SW Free poll SKB Size */ ++ unsigned int hw_skb_size : 16; /* HW Free poll SKB Size */ ++ } bits; ++}; ++ ++/* DMA SW Free Queue Read/Write Pointer Register (offset 0x000c) */ ++union dma_rwptr { ++ unsigned int bits32; ++ struct bit_000c { ++ unsigned int rptr : 16; /* Read Ptr, RO */ ++ unsigned int wptr : 16; /* Write Ptr, RW */ ++ } bits; ++}; ++ ++/* Interrupt Status Register 0 (offset 0x0020) ++ * Interrupt Mask Register 0 (offset 0x0024) ++ * Interrupt Select Register 0 (offset 0x0028) ++ */ ++#define GMAC1_TXDERR_INT_BIT BIT(31) ++#define GMAC1_TXPERR_INT_BIT BIT(30) ++#define GMAC0_TXDERR_INT_BIT BIT(29) ++#define GMAC0_TXPERR_INT_BIT BIT(28) ++#define GMAC1_RXDERR_INT_BIT BIT(27) ++#define GMAC1_RXPERR_INT_BIT BIT(26) ++#define GMAC0_RXDERR_INT_BIT BIT(25) ++#define GMAC0_RXPERR_INT_BIT BIT(24) ++#define GMAC1_SWTQ15_FIN_INT_BIT BIT(23) ++#define GMAC1_SWTQ14_FIN_INT_BIT BIT(22) ++#define GMAC1_SWTQ13_FIN_INT_BIT BIT(21) ++#define GMAC1_SWTQ12_FIN_INT_BIT BIT(20) ++#define GMAC1_SWTQ11_FIN_INT_BIT BIT(19) ++#define GMAC1_SWTQ10_FIN_INT_BIT BIT(18) ++#define GMAC0_SWTQ05_FIN_INT_BIT BIT(17) ++#define GMAC0_SWTQ04_FIN_INT_BIT BIT(16) ++#define GMAC0_SWTQ03_FIN_INT_BIT BIT(15) ++#define GMAC0_SWTQ02_FIN_INT_BIT BIT(14) ++#define GMAC0_SWTQ01_FIN_INT_BIT BIT(13) ++#define GMAC0_SWTQ00_FIN_INT_BIT BIT(12) ++#define GMAC1_SWTQ15_EOF_INT_BIT BIT(11) ++#define GMAC1_SWTQ14_EOF_INT_BIT BIT(10) ++#define GMAC1_SWTQ13_EOF_INT_BIT BIT(9) ++#define GMAC1_SWTQ12_EOF_INT_BIT BIT(8) ++#define GMAC1_SWTQ11_EOF_INT_BIT BIT(7) ++#define GMAC1_SWTQ10_EOF_INT_BIT BIT(6) ++#define GMAC0_SWTQ05_EOF_INT_BIT BIT(5) ++#define GMAC0_SWTQ04_EOF_INT_BIT BIT(4) ++#define GMAC0_SWTQ03_EOF_INT_BIT BIT(3) ++#define GMAC0_SWTQ02_EOF_INT_BIT BIT(2) ++#define GMAC0_SWTQ01_EOF_INT_BIT BIT(1) ++#define GMAC0_SWTQ00_EOF_INT_BIT BIT(0) ++ ++/* Interrupt Status Register 1 (offset 0x0030) ++ * Interrupt Mask Register 1 (offset 0x0034) ++ * Interrupt Select Register 1 (offset 0x0038) ++ */ ++#define TOE_IQ3_FULL_INT_BIT BIT(31) ++#define TOE_IQ2_FULL_INT_BIT BIT(30) ++#define TOE_IQ1_FULL_INT_BIT BIT(29) ++#define TOE_IQ0_FULL_INT_BIT BIT(28) ++#define TOE_IQ3_INT_BIT BIT(27) ++#define TOE_IQ2_INT_BIT BIT(26) ++#define TOE_IQ1_INT_BIT BIT(25) ++#define TOE_IQ0_INT_BIT BIT(24) ++#define GMAC1_HWTQ13_EOF_INT_BIT BIT(23) ++#define GMAC1_HWTQ12_EOF_INT_BIT BIT(22) ++#define GMAC1_HWTQ11_EOF_INT_BIT BIT(21) ++#define GMAC1_HWTQ10_EOF_INT_BIT BIT(20) ++#define GMAC0_HWTQ03_EOF_INT_BIT BIT(19) ++#define GMAC0_HWTQ02_EOF_INT_BIT BIT(18) ++#define GMAC0_HWTQ01_EOF_INT_BIT BIT(17) ++#define GMAC0_HWTQ00_EOF_INT_BIT BIT(16) ++#define CLASS_RX_INT_BIT(x) BIT((x + 2)) ++#define DEFAULT_Q1_INT_BIT BIT(1) ++#define DEFAULT_Q0_INT_BIT BIT(0) ++ ++#define TOE_IQ_INT_BITS (TOE_IQ0_INT_BIT | TOE_IQ1_INT_BIT | \ ++ TOE_IQ2_INT_BIT | TOE_IQ3_INT_BIT) ++#define TOE_IQ_FULL_BITS (TOE_IQ0_FULL_INT_BIT | TOE_IQ1_FULL_INT_BIT | \ ++ TOE_IQ2_FULL_INT_BIT | TOE_IQ3_FULL_INT_BIT) ++#define TOE_IQ_ALL_BITS (TOE_IQ_INT_BITS | TOE_IQ_FULL_BITS) ++#define TOE_CLASS_RX_INT_BITS 0xfffc ++ ++/* Interrupt Status Register 2 (offset 0x0040) ++ * Interrupt Mask Register 2 (offset 0x0044) ++ * Interrupt Select Register 2 (offset 0x0048) ++ */ ++#define TOE_QL_FULL_INT_BIT(x) BIT(x) ++ ++/* Interrupt Status Register 3 (offset 0x0050) ++ * Interrupt Mask Register 3 (offset 0x0054) ++ * Interrupt Select Register 3 (offset 0x0058) ++ */ ++#define TOE_QH_FULL_INT_BIT(x) BIT(x - 32) ++ ++/* Interrupt Status Register 4 (offset 0x0060) ++ * Interrupt Mask Register 4 (offset 0x0064) ++ * Interrupt Select Register 4 (offset 0x0068) ++ */ ++#define GMAC1_RESERVED_INT_BIT BIT(31) ++#define GMAC1_MIB_INT_BIT BIT(30) ++#define GMAC1_RX_PAUSE_ON_INT_BIT BIT(29) ++#define GMAC1_TX_PAUSE_ON_INT_BIT BIT(28) ++#define GMAC1_RX_PAUSE_OFF_INT_BIT BIT(27) ++#define GMAC1_TX_PAUSE_OFF_INT_BIT BIT(26) ++#define GMAC1_RX_OVERRUN_INT_BIT BIT(25) ++#define GMAC1_STATUS_CHANGE_INT_BIT BIT(24) ++#define GMAC0_RESERVED_INT_BIT BIT(23) ++#define GMAC0_MIB_INT_BIT BIT(22) ++#define GMAC0_RX_PAUSE_ON_INT_BIT BIT(21) ++#define GMAC0_TX_PAUSE_ON_INT_BIT BIT(20) ++#define GMAC0_RX_PAUSE_OFF_INT_BIT BIT(19) ++#define GMAC0_TX_PAUSE_OFF_INT_BIT BIT(18) ++#define GMAC0_RX_OVERRUN_INT_BIT BIT(17) ++#define GMAC0_STATUS_CHANGE_INT_BIT BIT(16) ++#define CLASS_RX_FULL_INT_BIT(x) BIT(x + 2) ++#define HWFQ_EMPTY_INT_BIT BIT(1) ++#define SWFQ_EMPTY_INT_BIT BIT(0) ++ ++#define GMAC0_INT_BITS (GMAC0_RESERVED_INT_BIT | GMAC0_MIB_INT_BIT | \ ++ GMAC0_RX_PAUSE_ON_INT_BIT | \ ++ GMAC0_TX_PAUSE_ON_INT_BIT | \ ++ GMAC0_RX_PAUSE_OFF_INT_BIT | \ ++ GMAC0_TX_PAUSE_OFF_INT_BIT | \ ++ GMAC0_RX_OVERRUN_INT_BIT | \ ++ GMAC0_STATUS_CHANGE_INT_BIT) ++#define GMAC1_INT_BITS (GMAC1_RESERVED_INT_BIT | GMAC1_MIB_INT_BIT | \ ++ GMAC1_RX_PAUSE_ON_INT_BIT | \ ++ GMAC1_TX_PAUSE_ON_INT_BIT | \ ++ GMAC1_RX_PAUSE_OFF_INT_BIT | \ ++ GMAC1_TX_PAUSE_OFF_INT_BIT | \ ++ GMAC1_RX_OVERRUN_INT_BIT | \ ++ GMAC1_STATUS_CHANGE_INT_BIT) ++ ++#define CLASS_RX_FULL_INT_BITS 0xfffc ++ ++/* GLOBAL_QUEUE_THRESHOLD_REG (offset 0x0070) */ ++union queue_threshold { ++ unsigned int bits32; ++ struct bit_0070_2 { ++ /* 7:0 Software Free Queue Empty Threshold */ ++ unsigned int swfq_empty:8; ++ /* 15:8 Hardware Free Queue Empty Threshold */ ++ unsigned int hwfq_empty:8; ++ /* 23:16 */ ++ unsigned int intrq:8; ++ /* 31:24 */ ++ unsigned int toe_class:8; ++ } bits; ++}; ++ ++/* GMAC DMA Control Register ++ * GMAC0 offset 0x8000 ++ * GMAC1 offset 0xC000 ++ */ ++union gmac_dma_ctrl { ++ unsigned int bits32; ++ struct bit_8000 { ++ /* bit 1:0 Peripheral Bus Width */ ++ unsigned int td_bus:2; ++ /* bit 3:2 TxDMA max burst size for every AHB request */ ++ unsigned int td_burst_size:2; ++ /* bit 7:4 TxDMA protection control */ ++ unsigned int td_prot:4; ++ /* bit 9:8 Peripheral Bus Width */ ++ unsigned int rd_bus:2; ++ /* bit 11:10 DMA max burst size for every AHB request */ ++ unsigned int rd_burst_size:2; ++ /* bit 15:12 DMA Protection Control */ ++ unsigned int rd_prot:4; ++ /* bit 17:16 */ ++ unsigned int rd_insert_bytes:2; ++ /* bit 27:18 */ ++ unsigned int reserved:10; ++ /* bit 28 1: Drop, 0: Accept */ ++ unsigned int drop_small_ack:1; ++ /* bit 29 Loopback TxDMA to RxDMA */ ++ unsigned int loopback:1; ++ /* bit 30 Tx DMA Enable */ ++ unsigned int td_enable:1; ++ /* bit 31 Rx DMA Enable */ ++ unsigned int rd_enable:1; ++ } bits; ++}; ++ ++/* GMAC Tx Weighting Control Register 0 ++ * GMAC0 offset 0x8004 ++ * GMAC1 offset 0xC004 ++ */ ++union gmac_tx_wcr0 { ++ unsigned int bits32; ++ struct bit_8004 { ++ /* bit 5:0 HW TX Queue 3 */ ++ unsigned int hw_tq0:6; ++ /* bit 11:6 HW TX Queue 2 */ ++ unsigned int hw_tq1:6; ++ /* bit 17:12 HW TX Queue 1 */ ++ unsigned int hw_tq2:6; ++ /* bit 23:18 HW TX Queue 0 */ ++ unsigned int hw_tq3:6; ++ /* bit 31:24 */ ++ unsigned int reserved:8; ++ } bits; ++}; ++ ++/* GMAC Tx Weighting Control Register 1 ++ * GMAC0 offset 0x8008 ++ * GMAC1 offset 0xC008 ++ */ ++union gmac_tx_wcr1 { ++ unsigned int bits32; ++ struct bit_8008 { ++ /* bit 4:0 SW TX Queue 0 */ ++ unsigned int sw_tq0:5; ++ /* bit 9:5 SW TX Queue 1 */ ++ unsigned int sw_tq1:5; ++ /* bit 14:10 SW TX Queue 2 */ ++ unsigned int sw_tq2:5; ++ /* bit 19:15 SW TX Queue 3 */ ++ unsigned int sw_tq3:5; ++ /* bit 24:20 SW TX Queue 4 */ ++ unsigned int sw_tq4:5; ++ /* bit 29:25 SW TX Queue 5 */ ++ unsigned int sw_tq5:5; ++ /* bit 31:30 */ ++ unsigned int reserved:2; ++ } bits; ++}; ++ ++/* GMAC DMA Tx Description Word 0 Register ++ * GMAC0 offset 0x8040 ++ * GMAC1 offset 0xC040 ++ */ ++union gmac_txdesc_0 { ++ unsigned int bits32; ++ struct bit_8040 { ++ /* bit 15:0 Transfer size */ ++ unsigned int buffer_size:16; ++ /* bit 21:16 number of descriptors used for the current frame */ ++ unsigned int desc_count:6; ++ /* bit 22 Tx Status, 1: Successful 0: Failed */ ++ unsigned int status_tx_ok:1; ++ /* bit 28:23 Tx Status, Reserved bits */ ++ unsigned int status_rvd:6; ++ /* bit 29 protocol error during processing this descriptor */ ++ unsigned int perr:1; ++ /* bit 30 data error during processing this descriptor */ ++ unsigned int derr:1; ++ /* bit 31 */ ++ unsigned int reserved:1; ++ } bits; ++}; ++ ++/* GMAC DMA Tx Description Word 1 Register ++ * GMAC0 offset 0x8044 ++ * GMAC1 offset 0xC044 ++ */ ++union gmac_txdesc_1 { ++ unsigned int bits32; ++ struct txdesc_word1 { ++ /* bit 15: 0 Tx Frame Byte Count */ ++ unsigned int byte_count:16; ++ /* bit 16 TSS segmentation use MTU setting */ ++ unsigned int mtu_enable:1; ++ /* bit 17 IPV4 Header Checksum Enable */ ++ unsigned int ip_chksum:1; ++ /* bit 18 IPV6 Tx Enable */ ++ unsigned int ipv6_enable:1; ++ /* bit 19 TCP Checksum Enable */ ++ unsigned int tcp_chksum:1; ++ /* bit 20 UDP Checksum Enable */ ++ unsigned int udp_chksum:1; ++ /* bit 21 Bypass HW offload engine */ ++ unsigned int bypass_tss:1; ++ /* bit 22 Don't update IP length field */ ++ unsigned int ip_fixed_len:1; ++ /* bit 31:23 Tx Flag, Reserved */ ++ unsigned int reserved:9; ++ } bits; ++}; ++ ++#define TSS_IP_FIXED_LEN_BIT BIT(22) ++#define TSS_BYPASS_BIT BIT(21) ++#define TSS_UDP_CHKSUM_BIT BIT(20) ++#define TSS_TCP_CHKSUM_BIT BIT(19) ++#define TSS_IPV6_ENABLE_BIT BIT(18) ++#define TSS_IP_CHKSUM_BIT BIT(17) ++#define TSS_MTU_ENABLE_BIT BIT(16) ++ ++#define TSS_CHECKUM_ENABLE \ ++ (TSS_IP_CHKSUM_BIT | TSS_IPV6_ENABLE_BIT | \ ++ TSS_TCP_CHKSUM_BIT | TSS_UDP_CHKSUM_BIT) ++ ++/* GMAC DMA Tx Description Word 2 Register ++ * GMAC0 offset 0x8048 ++ * GMAC1 offset 0xC048 ++ */ ++union gmac_txdesc_2 { ++ unsigned int bits32; ++ unsigned int buf_adr; ++}; ++ ++/* GMAC DMA Tx Description Word 3 Register ++ * GMAC0 offset 0x804C ++ * GMAC1 offset 0xC04C ++ */ ++union gmac_txdesc_3 { ++ unsigned int bits32; ++ struct txdesc_word3 { ++ /* bit 12: 0 Tx Frame Byte Count */ ++ unsigned int mtu_size:13; ++ /* bit 28:13 */ ++ unsigned int reserved:16; ++ /* bit 29 End of frame interrupt enable */ ++ unsigned int eofie:1; ++ /* bit 31:30 11: only one, 10: first, 01: last, 00: linking */ ++ unsigned int sof_eof:2; ++ } bits; ++}; ++ ++#define SOF_EOF_BIT_MASK 0x3fffffff ++#define SOF_BIT 0x80000000 ++#define EOF_BIT 0x40000000 ++#define EOFIE_BIT BIT(29) ++#define MTU_SIZE_BIT_MASK 0x1fff ++ ++/* GMAC Tx Descriptor */ ++struct gmac_txdesc { ++ union gmac_txdesc_0 word0; ++ union gmac_txdesc_1 word1; ++ union gmac_txdesc_2 word2; ++ union gmac_txdesc_3 word3; ++}; ++ ++/* GMAC DMA Rx Description Word 0 Register ++ * GMAC0 offset 0x8060 ++ * GMAC1 offset 0xC060 ++ */ ++union gmac_rxdesc_0 { ++ unsigned int bits32; ++ struct bit_8060 { ++ /* bit 15:0 number of descriptors used for the current frame */ ++ unsigned int buffer_size:16; ++ /* bit 21:16 number of descriptors used for the current frame */ ++ unsigned int desc_count:6; ++ /* bit 24:22 Status of rx frame */ ++ unsigned int status:4; ++ /* bit 28:26 Check Sum Status */ ++ unsigned int chksum_status:3; ++ /* bit 29 protocol error during processing this descriptor */ ++ unsigned int perr:1; ++ /* bit 30 data error during processing this descriptor */ ++ unsigned int derr:1; ++ /* bit 31 TOE/CIS Queue Full dropped packet to default queue */ ++ unsigned int drop:1; ++ } bits; ++}; ++ ++#define GMAC_RXDESC_0_T_derr BIT(30) ++#define GMAC_RXDESC_0_T_perr BIT(29) ++#define GMAC_RXDESC_0_T_chksum_status(x) BIT(x + 26) ++#define GMAC_RXDESC_0_T_status(x) BIT(x + 22) ++#define GMAC_RXDESC_0_T_desc_count(x) BIT(x + 16) ++ ++#define RX_CHKSUM_IP_UDP_TCP_OK 0 ++#define RX_CHKSUM_IP_OK_ONLY 1 ++#define RX_CHKSUM_NONE 2 ++#define RX_CHKSUM_IP_ERR_UNKNOWN 4 ++#define RX_CHKSUM_IP_ERR 5 ++#define RX_CHKSUM_TCP_UDP_ERR 6 ++#define RX_CHKSUM_NUM 8 ++ ++#define RX_STATUS_GOOD_FRAME 0 ++#define RX_STATUS_TOO_LONG_GOOD_CRC 1 ++#define RX_STATUS_RUNT_FRAME 2 ++#define RX_STATUS_SFD_NOT_FOUND 3 ++#define RX_STATUS_CRC_ERROR 4 ++#define RX_STATUS_TOO_LONG_BAD_CRC 5 ++#define RX_STATUS_ALIGNMENT_ERROR 6 ++#define RX_STATUS_TOO_LONG_BAD_ALIGN 7 ++#define RX_STATUS_RX_ERR 8 ++#define RX_STATUS_DA_FILTERED 9 ++#define RX_STATUS_BUFFER_FULL 10 ++#define RX_STATUS_NUM 16 ++ ++#define RX_ERROR_LENGTH(s) \ ++ ((s) == RX_STATUS_TOO_LONG_GOOD_CRC || \ ++ (s) == RX_STATUS_TOO_LONG_BAD_CRC || \ ++ (s) == RX_STATUS_TOO_LONG_BAD_ALIGN) ++#define RX_ERROR_OVER(s) \ ++ ((s) == RX_STATUS_BUFFER_FULL) ++#define RX_ERROR_CRC(s) \ ++ ((s) == RX_STATUS_CRC_ERROR || \ ++ (s) == RX_STATUS_TOO_LONG_BAD_CRC) ++#define RX_ERROR_FRAME(s) \ ++ ((s) == RX_STATUS_ALIGNMENT_ERROR || \ ++ (s) == RX_STATUS_TOO_LONG_BAD_ALIGN) ++#define RX_ERROR_FIFO(s) \ ++ (0) ++ ++/* GMAC DMA Rx Description Word 1 Register ++ * GMAC0 offset 0x8064 ++ * GMAC1 offset 0xC064 ++ */ ++union gmac_rxdesc_1 { ++ unsigned int bits32; ++ struct rxdesc_word1 { ++ /* bit 15: 0 Rx Frame Byte Count */ ++ unsigned int byte_count:16; ++ /* bit 31:16 Software ID */ ++ unsigned int sw_id:16; ++ } bits; ++}; ++ ++/* GMAC DMA Rx Description Word 2 Register ++ * GMAC0 offset 0x8068 ++ * GMAC1 offset 0xC068 ++ */ ++union gmac_rxdesc_2 { ++ unsigned int bits32; ++ unsigned int buf_adr; ++}; ++ ++#define RX_INSERT_NONE 0 ++#define RX_INSERT_1_BYTE 1 ++#define RX_INSERT_2_BYTE 2 ++#define RX_INSERT_3_BYTE 3 ++ ++/* GMAC DMA Rx Description Word 3 Register ++ * GMAC0 offset 0x806C ++ * GMAC1 offset 0xC06C ++ */ ++union gmac_rxdesc_3 { ++ unsigned int bits32; ++ struct rxdesc_word3 { ++ /* bit 7: 0 L3 data offset */ ++ unsigned int l3_offset:8; ++ /* bit 15: 8 L4 data offset */ ++ unsigned int l4_offset:8; ++ /* bit 23: 16 L7 data offset */ ++ unsigned int l7_offset:8; ++ /* bit 24 Duplicated ACK detected */ ++ unsigned int dup_ack:1; ++ /* bit 25 abnormal case found */ ++ unsigned int abnormal:1; ++ /* bit 26 IPV4 option or IPV6 extension header */ ++ unsigned int option:1; ++ /* bit 27 Out of Sequence packet */ ++ unsigned int out_of_seq:1; ++ /* bit 28 Control Flag is present */ ++ unsigned int ctrl_flag:1; ++ /* bit 29 End of frame interrupt enable */ ++ unsigned int eofie:1; ++ /* bit 31:30 11: only one, 10: first, 01: last, 00: linking */ ++ unsigned int sof_eof:2; ++ } bits; ++}; ++ ++/* GMAC Rx Descriptor, this is simply fitted over the queue registers */ ++struct gmac_rxdesc { ++ union gmac_rxdesc_0 word0; ++ union gmac_rxdesc_1 word1; ++ union gmac_rxdesc_2 word2; ++ union gmac_rxdesc_3 word3; ++}; ++ ++/* GMAC Matching Rule Control Register 0 ++ * GMAC0 offset 0x8078 ++ * GMAC1 offset 0xC078 ++ */ ++#define MR_L2_BIT BIT(31) ++#define MR_L3_BIT BIT(30) ++#define MR_L4_BIT BIT(29) ++#define MR_L7_BIT BIT(28) ++#define MR_PORT_BIT BIT(27) ++#define MR_PRIORITY_BIT BIT(26) ++#define MR_DA_BIT BIT(23) ++#define MR_SA_BIT BIT(22) ++#define MR_ETHER_TYPE_BIT BIT(21) ++#define MR_VLAN_BIT BIT(20) ++#define MR_PPPOE_BIT BIT(19) ++#define MR_IP_VER_BIT BIT(15) ++#define MR_IP_HDR_LEN_BIT BIT(14) ++#define MR_FLOW_LABLE_BIT BIT(13) ++#define MR_TOS_TRAFFIC_BIT BIT(12) ++#define MR_SPR_BIT(x) BIT(x) ++#define MR_SPR_BITS 0xff ++ ++/* GMAC_AHB_WEIGHT registers ++ * GMAC0 offset 0x80C8 ++ * GMAC1 offset 0xC0C8 ++ */ ++union gmac_ahb_weight { ++ unsigned int bits32; ++ struct bit_80C8 { ++ /* 4:0 */ ++ unsigned int hash_weight:5; ++ /* 9:5 */ ++ unsigned int rx_weight:5; ++ /* 14:10 */ ++ unsigned int tx_weight:5; ++ /* 19:15 Rx Data Pre Request FIFO Threshold */ ++ unsigned int pre_req:5; ++ /* 24:20 DMA TqCtrl to Start tqDV FIFO Threshold */ ++ unsigned int tq_dv_threshold:5; ++ /* 31:25 */ ++ unsigned int reserved:7; ++ } bits; ++}; ++ ++/* GMAC RX FLTR ++ * GMAC0 Offset 0xA00C ++ * GMAC1 Offset 0xE00C ++ */ ++union gmac_rx_fltr { ++ unsigned int bits32; ++ struct bit1_000c { ++ /* Enable receive of unicast frames that are sent to STA ++ * address ++ */ ++ unsigned int unicast:1; ++ /* Enable receive of multicast frames that pass multicast ++ * filter ++ */ ++ unsigned int multicast:1; ++ /* Enable receive of broadcast frames */ ++ unsigned int broadcast:1; ++ /* Enable receive of all frames */ ++ unsigned int promiscuous:1; ++ /* Enable receive of all error frames */ ++ unsigned int error:1; ++ unsigned int reserved:27; ++ } bits; ++}; ++ ++/* GMAC Configuration 0 ++ * GMAC0 Offset 0xA018 ++ * GMAC1 Offset 0xE018 ++ */ ++union gmac_config0 { ++ unsigned int bits32; ++ struct bit1_0018 { ++ /* 0: disable transmit */ ++ unsigned int dis_tx:1; ++ /* 1: disable receive */ ++ unsigned int dis_rx:1; ++ /* 2: transmit data loopback enable */ ++ unsigned int loop_back:1; ++ /* 3: flow control also trigged by Rx queues */ ++ unsigned int flow_ctrl:1; ++ /* 4-7: adjust IFG from 96+/-56 */ ++ unsigned int adj_ifg:4; ++ /* 8-10 maximum receive frame length allowed */ ++ unsigned int max_len:3; ++ /* 11: disable back-off function */ ++ unsigned int dis_bkoff:1; ++ /* 12: disable 16 collisions abort function */ ++ unsigned int dis_col:1; ++ /* 13: speed up timers in simulation */ ++ unsigned int sim_test:1; ++ /* 14: RX flow control enable */ ++ unsigned int rx_fc_en:1; ++ /* 15: TX flow control enable */ ++ unsigned int tx_fc_en:1; ++ /* 16: RGMII in-band status enable */ ++ unsigned int rgmii_en:1; ++ /* 17: IPv4 RX Checksum enable */ ++ unsigned int ipv4_rx_chksum:1; ++ /* 18: IPv6 RX Checksum enable */ ++ unsigned int ipv6_rx_chksum:1; ++ /* 19: Remove Rx VLAN tag */ ++ unsigned int rx_tag_remove:1; ++ /* 20 */ ++ unsigned int rgmm_edge:1; ++ /* 21 */ ++ unsigned int rxc_inv:1; ++ /* 22 */ ++ unsigned int ipv6_exthdr_order:1; ++ /* 23 */ ++ unsigned int rx_err_detect:1; ++ /* 24 */ ++ unsigned int port0_chk_hwq:1; ++ /* 25 */ ++ unsigned int port1_chk_hwq:1; ++ /* 26 */ ++ unsigned int port0_chk_toeq:1; ++ /* 27 */ ++ unsigned int port1_chk_toeq:1; ++ /* 28 */ ++ unsigned int port0_chk_classq:1; ++ /* 29 */ ++ unsigned int port1_chk_classq:1; ++ /* 30, 31 */ ++ unsigned int reserved:2; ++ } bits; ++}; ++ ++#define CONFIG0_TX_RX_DISABLE (BIT(1) | BIT(0)) ++#define CONFIG0_RX_CHKSUM (BIT(18) | BIT(17)) ++#define CONFIG0_FLOW_RX BIT(14) ++#define CONFIG0_FLOW_TX BIT(15) ++#define CONFIG0_FLOW_TX_RX (BIT(14) | BIT(15)) ++#define CONFIG0_FLOW_CTL (BIT(14) | BIT(15)) ++ ++#define CONFIG0_MAXLEN_SHIFT 8 ++#define CONFIG0_MAXLEN_MASK (7 << CONFIG0_MAXLEN_SHIFT) ++#define CONFIG0_MAXLEN_1536 0 ++#define CONFIG0_MAXLEN_1518 1 ++#define CONFIG0_MAXLEN_1522 2 ++#define CONFIG0_MAXLEN_1542 3 ++#define CONFIG0_MAXLEN_9k 4 /* 9212 */ ++#define CONFIG0_MAXLEN_10k 5 /* 10236 */ ++#define CONFIG0_MAXLEN_1518__6 6 ++#define CONFIG0_MAXLEN_1518__7 7 ++ ++/* GMAC Configuration 1 ++ * GMAC0 Offset 0xA01C ++ * GMAC1 Offset 0xE01C ++ */ ++union gmac_config1 { ++ unsigned int bits32; ++ struct bit1_001c { ++ /* Flow control set threshold */ ++ unsigned int set_threshold:8; ++ /* Flow control release threshold */ ++ unsigned int rel_threshold:8; ++ unsigned int reserved:16; ++ } bits; ++}; ++ ++#define GMAC_FLOWCTRL_SET_MAX 32 ++#define GMAC_FLOWCTRL_SET_MIN 0 ++#define GMAC_FLOWCTRL_RELEASE_MAX 32 ++#define GMAC_FLOWCTRL_RELEASE_MIN 0 ++ ++/* GMAC Configuration 2 ++ * GMAC0 Offset 0xA020 ++ * GMAC1 Offset 0xE020 ++ */ ++union gmac_config2 { ++ unsigned int bits32; ++ struct bit1_0020 { ++ /* Flow control set threshold */ ++ unsigned int set_threshold:16; ++ /* Flow control release threshold */ ++ unsigned int rel_threshold:16; ++ } bits; ++}; ++ ++/* GMAC Configuration 3 ++ * GMAC0 Offset 0xA024 ++ * GMAC1 Offset 0xE024 ++ */ ++union gmac_config3 { ++ unsigned int bits32; ++ struct bit1_0024 { ++ /* Flow control set threshold */ ++ unsigned int set_threshold:16; ++ /* Flow control release threshold */ ++ unsigned int rel_threshold:16; ++ } bits; ++}; ++ ++/* GMAC STATUS ++ * GMAC0 Offset 0xA02C ++ * GMAC1 Offset 0xE02C ++ */ ++union gmac_status { ++ unsigned int bits32; ++ struct bit1_002c { ++ /* Link status */ ++ unsigned int link:1; ++ /* Link speed(00->2.5M 01->25M 10->125M) */ ++ unsigned int speed:2; ++ /* Duplex mode */ ++ unsigned int duplex:1; ++ unsigned int reserved_1:1; ++ /* PHY interface type */ ++ unsigned int mii_rmii:2; ++ unsigned int reserved_2:25; ++ } bits; ++}; ++ ++#define GMAC_SPEED_10 0 ++#define GMAC_SPEED_100 1 ++#define GMAC_SPEED_1000 2 ++ ++#define GMAC_PHY_MII 0 ++#define GMAC_PHY_GMII 1 ++#define GMAC_PHY_RGMII_100_10 2 ++#define GMAC_PHY_RGMII_1000 3 ++ ++/* Queue Header ++ * (1) TOE Queue Header ++ * (2) Non-TOE Queue Header ++ * (3) Interrupt Queue Header ++ * ++ * memory Layout ++ * TOE Queue Header ++ * 0x60003000 +---------------------------+ 0x0000 ++ * | TOE Queue 0 Header | ++ * | 8 * 4 Bytes | ++ * +---------------------------+ 0x0020 ++ * | TOE Queue 1 Header | ++ * | 8 * 4 Bytes | ++ * +---------------------------+ 0x0040 ++ * | ...... | ++ * | | ++ * +---------------------------+ ++ * ++ * Non TOE Queue Header ++ * 0x60002000 +---------------------------+ 0x0000 ++ * | Default Queue 0 Header | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ 0x0008 ++ * | Default Queue 1 Header | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ 0x0010 ++ * | Classification Queue 0 | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ ++ * | Classification Queue 1 | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ (n * 8 + 0x10) ++ * | ... | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ (13 * 8 + 0x10) ++ * | Classification Queue 13 | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ 0x80 ++ * | Interrupt Queue 0 | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ ++ * | Interrupt Queue 1 | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ ++ * | Interrupt Queue 2 | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ ++ * | Interrupt Queue 3 | ++ * | 2 * 4 Bytes | ++ * +---------------------------+ ++ * ++ */ ++#define TOE_QUEUE_HDR_ADDR(n) (TOE_TOE_QUE_HDR_BASE + n * 32) ++#define TOE_Q_HDR_AREA_END (TOE_QUEUE_HDR_ADDR(TOE_TOE_QUEUE_MAX + 1)) ++#define TOE_DEFAULT_Q_HDR_BASE(x) (TOE_NONTOE_QUE_HDR_BASE + 0x08 * (x)) ++#define TOE_CLASS_Q_HDR_BASE (TOE_NONTOE_QUE_HDR_BASE + 0x10) ++#define TOE_INTR_Q_HDR_BASE (TOE_NONTOE_QUE_HDR_BASE + 0x80) ++#define INTERRUPT_QUEUE_HDR_ADDR(n) (TOE_INTR_Q_HDR_BASE + n * 8) ++#define NONTOE_Q_HDR_AREA_END (INTERRUPT_QUEUE_HDR_ADDR(TOE_INTR_QUEUE_MAX + 1)) ++ ++/* NONTOE Queue Header Word 0 */ ++union nontoe_qhdr0 { ++ unsigned int bits32; ++ unsigned int base_size; ++}; ++ ++#define NONTOE_QHDR0_BASE_MASK (~0x0f) ++ ++/* NONTOE Queue Header Word 1 */ ++union nontoe_qhdr1 { ++ unsigned int bits32; ++ struct bit_nonqhdr1 { ++ /* bit 15:0 */ ++ unsigned int rptr:16; ++ /* bit 31:16 */ ++ unsigned int wptr:16; ++ } bits; ++}; ++ ++/* Non-TOE Queue Header */ ++struct nontoe_qhdr { ++ union nontoe_qhdr0 word0; ++ union nontoe_qhdr1 word1; ++}; ++ ++#endif /* _GEMINI_ETHERNET_H */ diff --git a/target/linux/gemini/patches-4.14/0023-ARM-dts-Add-ethernet-to-the-Gemini-SoC.patch b/target/linux/gemini/patches-4.14/0023-ARM-dts-Add-ethernet-to-the-Gemini-SoC.patch new file mode 100644 index 000000000..0960f6bfd --- /dev/null +++ b/target/linux/gemini/patches-4.14/0023-ARM-dts-Add-ethernet-to-the-Gemini-SoC.patch @@ -0,0 +1,74 @@ +From 860005c1a2f16aaa33458a7d80c9728b710ae292 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Mon, 6 Nov 2017 00:05:28 +0100 +Subject: [PATCH 23/31] ARM: dts: Add ethernet to the Gemini SoC + +This adds the Gemini ethernet node to the Gemini SoC. + +Signed-off-by: Linus Walleij +--- + arch/arm/boot/dts/gemini.dtsi | 44 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 43 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/gemini.dtsi ++++ b/arch/arm/boot/dts/gemini.dtsi +@@ -114,9 +114,16 @@ + }; + }; + gmii_default_pins: pinctrl-gmii { ++ /* ++ * Only activate GMAC0 by default since ++ * GMAC1 will overlap with 8 GPIO lines ++ * gpio2a, gpio2b. Overlay groups with ++ * "gmii_gmac0_grp", "gmii_gmac1_grp" for ++ * both ethernet interfaces. ++ */ + mux { + function = "gmii"; +- groups = "gmiigrp"; ++ groups = "gmii_gmac0_grp"; + }; + }; + pci_default_pins: pinctrl-pci { +@@ -316,6 +323,41 @@ + }; + }; + ++ ethernet@60000000 { ++ compatible = "cortina,gemini-ethernet"; ++ reg = <0x60000000 0x4000>, /* Global registers, queue */ ++ <0x60004000 0x2000>, /* V-bit */ ++ <0x60006000 0x2000>; /* A-bit */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmii_default_pins>; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ gmac0: ethernet-port@0 { ++ compatible = "cortina,gemini-ethernet-port"; ++ reg = <0x60008000 0x2000>, /* Port 0 DMA/TOE */ ++ <0x6000a000 0x2000>; /* Port 0 GMAC */ ++ interrupt-parent = <&intcon>; ++ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; ++ resets = <&syscon GEMINI_RESET_GMAC0>; ++ clocks = <&syscon GEMINI_CLK_GATE_GMAC0>; ++ clock-names = "PCLK"; ++ }; ++ ++ gmac1: ethernet-port@1 { ++ compatible = "cortina,gemini-ethernet-port"; ++ reg = <0x6000c000 0x2000>, /* Port 1 DMA/TOE */ ++ <0x6000e000 0x2000>; /* Port 1 GMAC */ ++ interrupt-parent = <&intcon>; ++ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; ++ resets = <&syscon GEMINI_RESET_GMAC1>; ++ clocks = <&syscon GEMINI_CLK_GATE_GMAC1>; ++ clock-names = "PCLK"; ++ }; ++ }; ++ + ata@63000000 { + compatible = "cortina,gemini-pata", "faraday,ftide010"; + reg = <0x63000000 0x1000>; diff --git a/target/linux/gemini/patches-4.14/0024-net-gemini-Depend-on-HAS_IOMEM.patch b/target/linux/gemini/patches-4.14/0024-net-gemini-Depend-on-HAS_IOMEM.patch new file mode 100644 index 000000000..2b95a9287 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0024-net-gemini-Depend-on-HAS_IOMEM.patch @@ -0,0 +1,30 @@ +From e0a7c7762e3a81e908bcca4176139ea9755d0985 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sun, 21 Jan 2018 14:15:41 +0100 +Subject: [PATCH 24/31] net: gemini: Depend on HAS_IOMEM + +The zeroday builder notices that since Usermode Linux does not +have IO memory, the build fails for them when selecting everything +it can enable. + +As the driver is clearly using memory-mapped registers to access +the network adapter, we add depends on HAS_IOMEM to solve this +problem. + +Reported-by: kbuild test robot +Signed-off-by: Linus Walleij +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/cortina/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/cortina/Kconfig ++++ b/drivers/net/ethernet/cortina/Kconfig +@@ -14,6 +14,7 @@ if NET_VENDOR_CORTINA + config GEMINI_ETHERNET + tristate "Gemini Gigabit Ethernet support" + depends on OF ++ depends on HAS_IOMEM + select PHYLIB + select CRC32 + ---help--- diff --git a/target/linux/gemini/patches-4.14/0025-ARM-dts-Set-D-Link-DNS-313-SATA-to-muxmode-0.patch b/target/linux/gemini/patches-4.14/0025-ARM-dts-Set-D-Link-DNS-313-SATA-to-muxmode-0.patch new file mode 100644 index 000000000..06609a7ed --- /dev/null +++ b/target/linux/gemini/patches-4.14/0025-ARM-dts-Set-D-Link-DNS-313-SATA-to-muxmode-0.patch @@ -0,0 +1,36 @@ +From f30cc6acdeb834be1a6ae54d47c84b2f8012b83d Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Thu, 18 Jan 2018 14:36:21 +0100 +Subject: [PATCH 25/31] ARM: dts: Set D-Link DNS-313 SATA to muxmode 0 + +This stops the driver from trying to probe the ATA slave +interface. The vendor code enables the slave interface +but the driver in the vendor tree does not make use of +it. + +Setting it to muxmode 0 disables the slave interface: +the hardware only has the master interface connected +to the one harddrive slot anyways. + +Without this change booting takes excessive time, so it +is very annoying to end users. + +Fixes: dd5c0561db75 ("ARM: dts: Add basic devicetree for D-Link DNS-313") +Signed-off-by: Linus Walleij +--- +ARM SoC folks: please apply this for fixes for v4.16. +--- + arch/arm/boot/dts/gemini-dlink-dns-313.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts +@@ -219,7 +219,7 @@ + + sata: sata@46000000 { + /* The ROM uses this muxmode */ +- cortina,gemini-ata-muxmode = <3>; ++ cortina,gemini-ata-muxmode = <0>; + cortina,gemini-enable-sata-bridge; + status = "okay"; + }; diff --git a/target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch b/target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch new file mode 100644 index 000000000..e97aeaca4 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch @@ -0,0 +1,80 @@ +From da443bc125265cae24a0e5f7d1c7bba196a9319f Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Thu, 22 Feb 2018 08:34:35 +0100 +Subject: [PATCH 26/31] power: gemini-poweroff: Avoid spurious poweroff + +On the D-Link DIR-685 we get spurious poweroff from +infrared. Since that block (CIR) doesn't even have a +driver this can be safely ignored, we can revisit this +code once we have a device supporting CIR. + +On the D-Link DNS-313 we get spurious poweroff from +the power button. This appears to be an initialization +issue: we need to enable the block (start the state +machine) before we clear any dangling IRQ. + +This patch fixes both issues. + +Fixes: f7a388d6cd1c ("power: reset: Add a driver for the Gemini poweroff") +Signed-off-by: Linus Walleij +--- +ChangeLog v1->v2: +- Fix both issues and rename the patch. +- Proper commit message with specifics. +--- + drivers/power/reset/gemini-poweroff.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +--- a/drivers/power/reset/gemini-poweroff.c ++++ b/drivers/power/reset/gemini-poweroff.c +@@ -47,8 +47,12 @@ static irqreturn_t gemini_powerbutton_in + val &= 0x70U; + switch (val) { + case GEMINI_STAT_CIR: +- dev_info(gpw->dev, "infrared poweroff\n"); +- orderly_poweroff(true); ++ /* ++ * We do not yet have a driver for the infrared ++ * controller so it can cause spurious poweroff ++ * events. Ignore those for now. ++ */ ++ dev_info(gpw->dev, "infrared poweroff - ignored\n"); + break; + case GEMINI_STAT_RTC: + dev_info(gpw->dev, "RTC poweroff\n"); +@@ -116,7 +120,17 @@ static int gemini_poweroff_probe(struct + return -ENODEV; + } + +- /* Clear the power management IRQ */ ++ /* ++ * Enable the power controller. This is crucial on Gemini ++ * systems: if this is not done, pressing the power button ++ * will result in unconditional poweroff without any warning. ++ * This makes the kernel handle the poweroff. ++ */ ++ val = readl(gpw->base + GEMINI_PWC_CTRLREG); ++ val |= GEMINI_CTRL_ENABLE; ++ writel(val, gpw->base + GEMINI_PWC_CTRLREG); ++ ++ /* Now that the state machine is active, clear the IRQ */ + val = readl(gpw->base + GEMINI_PWC_CTRLREG); + val |= GEMINI_CTRL_IRQ_CLR; + writel(val, gpw->base + GEMINI_PWC_CTRLREG); +@@ -129,16 +143,6 @@ static int gemini_poweroff_probe(struct + pm_power_off = gemini_poweroff; + gpw_poweroff = gpw; + +- /* +- * Enable the power controller. This is crucial on Gemini +- * systems: if this is not done, pressing the power button +- * will result in unconditional poweroff without any warning. +- * This makes the kernel handle the poweroff. +- */ +- val = readl(gpw->base + GEMINI_PWC_CTRLREG); +- val |= GEMINI_CTRL_ENABLE; +- writel(val, gpw->base + GEMINI_PWC_CTRLREG); +- + dev_info(dev, "Gemini poweroff driver registered\n"); + + return 0; diff --git a/target/linux/gemini/patches-4.14/0027-usb-host-add-DT-bindings-for-faraday-fotg2.patch b/target/linux/gemini/patches-4.14/0027-usb-host-add-DT-bindings-for-faraday-fotg2.patch new file mode 100644 index 000000000..e677c3843 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0027-usb-host-add-DT-bindings-for-faraday-fotg2.patch @@ -0,0 +1,65 @@ +From 3699f119ff8da021fe7a1759e98e38ca88fa6766 Mon Sep 17 00:00:00 2001 +From: Hans Ulli Kroll +Date: Wed, 8 Feb 2017 21:00:09 +0100 +Subject: [PATCH 27/31] 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 +Signed-off-by: Linus Walleij +--- +ChangeLog v1->v3: +- Change compatible to "faraday,fotg210" as the name of the + hardware block. +- Add an elaborate SoC-specific compatible string for the + Cortina Systems Gemini so that SoC-specific features can + be enabled. +- Add cortina,gemini-mini-b to indicate a Gemini PHY with + a Mini-B adapter connected. +- Indicated that the Gemini version can handle "wakeup-source". +- Add optional IP block clock. +--- + .../devicetree/bindings/usb/faraday,fotg210.txt | 35 ++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + create mode 100644 Documentation/devicetree/bindings/usb/faraday,fotg210.txt + +--- /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 ++ OTH 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; ++}; diff --git a/target/linux/gemini/patches-4.14/0028-usb-host-fotg2-add-device-tree-probing.patch b/target/linux/gemini/patches-4.14/0028-usb-host-fotg2-add-device-tree-probing.patch new file mode 100644 index 000000000..862cb6490 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0028-usb-host-fotg2-add-device-tree-probing.patch @@ -0,0 +1,61 @@ +From 5662c553e89ac4179ec2a7a94a342ba3e5d78cf7 Mon Sep 17 00:00:00 2001 +From: Hans Ulli Kroll +Date: Thu, 9 Feb 2017 15:20:49 +0100 +Subject: [PATCH 28/31] usb: host: fotg2: add device tree probing + +Add device tree probing to the fotg2 driver. + +Signed-off-by: Hans Ulli Kroll +Signed-off-by: Linus Walleij +--- +ChangeLog v2->v3: +- Change compatible to "faraday,fotg210" simply. +--- + drivers/usb/host/fotg210-hcd.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -23,6 +23,7 @@ + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include ++#include + #include + #include + #include +@@ -5600,6 +5601,15 @@ static int fotg210_hcd_probe(struct plat + if (usb_disabled()) + return -ENODEV; + ++ /* Right now device-tree probed devices don't get dma_mask set. ++ * Since shared usb code relies on it, set it here for now. ++ * Once we have dma capability bindings this can go away. ++ */ ++ ++ retval = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); ++ if (retval) ++ goto fail_create_hcd; ++ + pdev->dev.power.power_state = PMSG_ON; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); +@@ -5676,9 +5686,18 @@ static int fotg210_hcd_remove(struct pla + 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, diff --git a/target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch b/target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch new file mode 100644 index 000000000..4a1faf938 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0029-usb-host-fotg2-add-silicon-clock-handling.patch @@ -0,0 +1,99 @@ +From acd19633751f14607ccd76f9dfde5bde7935766c Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Fri, 21 Apr 2017 20:46:12 +0200 +Subject: [PATCH 29/31] usb: host: fotg2: add silicon clock handling + +When used in a system with software-controller 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. + +Signed-off-by: Linus Walleij +--- + drivers/usb/host/fotg210-hcd.c | 26 ++++++++++++++++++++++---- + drivers/usb/host/fotg210.h | 3 +++ + 2 files changed, 25 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -5635,7 +5636,7 @@ static int fotg210_hcd_probe(struct plat + 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; +@@ -5645,22 +5646,35 @@ static int fotg210_hcd_probe(struct plat + + 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_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); +@@ -5676,6 +5690,10 @@ static int fotg210_hcd_remove(struct pla + { + 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; +--- a/drivers/usb/host/fotg210.h ++++ b/drivers/usb/host/fotg210.h +@@ -182,6 +182,9 @@ struct fotg210_hcd { /* one per contro + # define COUNT(x) + #endif + ++ /* silicon clock */ ++ struct clk *pclk; ++ + /* debug files */ + struct dentry *debug_dir; + }; diff --git a/target/linux/gemini/patches-4.14/0030-usb-host-fotg2-add-Gemini-specific-handling.patch b/target/linux/gemini/patches-4.14/0030-usb-host-fotg2-add-Gemini-specific-handling.patch new file mode 100644 index 000000000..2e781e403 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0030-usb-host-fotg2-add-Gemini-specific-handling.patch @@ -0,0 +1,131 @@ +From e8ede0f62b39a3d3b06ae3dc04a74680a1f0a64b Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Fri, 21 Apr 2017 22:19:00 +0200 +Subject: [PATCH 30/31] 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 +--- + drivers/usb/host/Kconfig | 1 + + drivers/usb/host/fotg210-hcd.c | 76 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 77 insertions(+) + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -375,6 +375,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 +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -46,6 +46,10 @@ + #include + #include + #include ++#include ++/* For Cortina Gemini */ ++#include ++#include + + #include + #include +@@ -5583,6 +5587,72 @@ static void fotg210_init(struct 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 + * +@@ -5662,6 +5732,12 @@ static int fotg210_hcd_probe(struct plat + + 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); diff --git a/target/linux/gemini/patches-4.14/0031-ARM-dts-Add-the-FOTG210-USB-host-to-Gemini.patch b/target/linux/gemini/patches-4.14/0031-ARM-dts-Add-the-FOTG210-USB-host-to-Gemini.patch new file mode 100644 index 000000000..cb6fdb875 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0031-ARM-dts-Add-the-FOTG210-USB-host-to-Gemini.patch @@ -0,0 +1,178 @@ +From dd62aee5d2d24199e71e745544e49a1a8b3c6f7a Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Fri, 21 Apr 2017 20:50:22 +0200 +Subject: [PATCH 31/31] ARM: dts: Add the FOTG210 USB host to Gemini + +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 (these per-platform enablements are done on the out-of-tree +OpenWrt patch set). It is not enabled on the Itian SquareOne +NAS/router since this instead has a VIA host controller +soldered on the PCI port, and can gate off these USB host +controllers. + +Signed-off-by: Linus Walleij +--- +USB maintainers: I will merge this through the ARM SoC tree, +the patch is only included in the series for context. +--- + 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-wbd111.dts | 20 ++++++++++++++++++++ + arch/arm/boot/dts/gemini-wbd222.dts | 21 +++++++++++++++++++++ + arch/arm/boot/dts/gemini.dtsi | 26 ++++++++++++++++++++++++++ + 6 files changed, 103 insertions(+) + +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -303,5 +303,13 @@ + }; + }; + }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +--- a/arch/arm/boot/dts/gemini-nas4220b.dts ++++ b/arch/arm/boot/dts/gemini-nas4220b.dts +@@ -146,5 +146,13 @@ + ata@63000000 { + status = "okay"; + }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +--- a/arch/arm/boot/dts/gemini-rut1xx.dts ++++ b/arch/arm/boot/dts/gemini-rut1xx.dts +@@ -114,5 +114,25 @@ + pinctrl-names = "default"; + pinctrl-0 = <&gpio1_default_pins>; + }; ++ ++ 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"; ++ }; + }; + }; +--- a/arch/arm/boot/dts/gemini-wbd111.dts ++++ b/arch/arm/boot/dts/gemini-wbd111.dts +@@ -160,5 +160,25 @@ + <0x6000 0 0 3 &pci_intc 1>, + <0x6000 0 0 4 &pci_intc 2>; + }; ++ ++ 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"; ++ }; + }; + }; +--- a/arch/arm/boot/dts/gemini-wbd222.dts ++++ b/arch/arm/boot/dts/gemini-wbd222.dts +@@ -165,5 +165,26 @@ + <0x6000 0 0 3 &pci_intc 1>, + <0x6000 0 0 4 &pci_intc 2>; + }; ++ ++ ethernet@60000000 { ++ status = "okay"; ++ ++ ethernet-port@0 { ++ phy-mode = "rgmii"; ++ phy-handle = <&phy0>; ++ }; ++ ethernet-port@1 { ++ phy-mode = "rgmii"; ++ phy-handle = <&phy1>; ++ }; ++ }; ++ ++ usb@68000000 { ++ status = "okay"; ++ }; ++ ++ usb@69000000 { ++ status = "okay"; ++ }; + }; + }; +--- a/arch/arm/boot/dts/gemini.dtsi ++++ b/arch/arm/boot/dts/gemini.dtsi +@@ -411,5 +411,31 @@ + #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"; ++ 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"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb_default_pins>; ++ syscon = <&syscon>; ++ status = "disabled"; ++ }; + }; + }; diff --git a/target/linux/gemini/patches-4.14/0032-usb-host-fotg2-restart-hcd-after-port-reset.patch b/target/linux/gemini/patches-4.14/0032-usb-host-fotg2-restart-hcd-after-port-reset.patch new file mode 100644 index 000000000..80b2fc410 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0032-usb-host-fotg2-restart-hcd-after-port-reset.patch @@ -0,0 +1,26 @@ +From 731a2896e11b4e6a8d252e6c14edb1b09dbfcd46 Mon Sep 17 00:00:00 2001 +From: Hans Ulli Kroll +Date: Sat, 14 Apr 2018 18:49:57 +0200 +Subject: [PATCH 1/2] 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 +--- + drivers/usb/host/fotg210-hcd.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -1658,6 +1658,10 @@ static int fotg210_hub_control(struct us + /* 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))) { diff --git a/target/linux/gemini/patches-4.14/0033-ARM-dts-Fix-bootargs-for-Gemini-D-Link-devices.patch b/target/linux/gemini/patches-4.14/0033-ARM-dts-Fix-bootargs-for-Gemini-D-Link-devices.patch new file mode 100644 index 000000000..d8fd853b3 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0033-ARM-dts-Fix-bootargs-for-Gemini-D-Link-devices.patch @@ -0,0 +1,38 @@ +From 5813b729eb9fe91fcf895a5c2f30bf34fbd46379 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Wed, 2 May 2018 09:17:25 +0200 +Subject: [PATCH] ARM: dts: Fix bootargs for Gemini D-Link devices + +These machines need to be booted from very specific harddisk +partitions (as the D-Link DNS-313 boots specifically from +partition 4). Add the proper bootargs so that everything works +smoothly. + +Signed-off-by: Linus Walleij +--- + arch/arm/boot/dts/gemini-dlink-dir-685.dts | 3 ++- + arch/arm/boot/dts/gemini-dlink-dns-313.dts | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -20,7 +20,8 @@ + }; + + chosen { +- stdout-path = "uart0:115200n8"; ++ bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait"; ++ stdout-path = "uart0:19200n8"; + }; + + gpio_keys { +--- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts +@@ -26,6 +26,7 @@ + }; + + chosen { ++ bootargs = "console=ttyS0,19200n8 root=/dev/sda4 rw rootwait"; + stdout-path = "uart0:19200n8"; + }; + diff --git a/target/linux/gemini/patches-4.14/0034-ARM-dts-Add-ethernet-to-a-bunch-of-platforms.patch b/target/linux/gemini/patches-4.14/0034-ARM-dts-Add-ethernet-to-a-bunch-of-platforms.patch new file mode 100644 index 000000000..3e588223b --- /dev/null +++ b/target/linux/gemini/patches-4.14/0034-ARM-dts-Add-ethernet-to-a-bunch-of-platforms.patch @@ -0,0 +1,116 @@ +From 6d5af7093aea4f18e040e73db2ad99aaa0c0f77e Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sun, 19 Nov 2017 11:04:23 +0100 +Subject: [PATCH] ARM: dts: Add ethernet to a bunch of platforms + +These platforms have the PHY defined already so we just +need to add a single device node to each of them to activate +the ethernet device. + +The PHY skew/delay settings for pin control is known from a +few vendor trees and old OpenWRT patch sets. + +This is a modified version of upstream commit +95220046a62c00b5afb1aa7c1971989d427db977, +just dropping the NAS4220B changes. + +Signed-off-by: Linus Walleij +--- + arch/arm/boot/dts/gemini-dlink-dns-313.dts | 62 ++++++++++++++++++++++++++++++ + arch/arm/boot/dts/gemini-wbd222.dts | 7 ++++ + 2 files changed, 69 insertions(+) + +--- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts +@@ -215,6 +215,56 @@ + groups = "gpio1dgrp"; + }; + }; ++ pinctrl-gmii { ++ mux { ++ function = "gmii"; ++ groups = "gmii_gmac0_grp"; ++ }; ++ /* ++ * In the vendor Linux tree, these values are set for the C3 ++ * version of the SL3512 ASIC with the comment "benson suggest" ++ */ ++ conf0 { ++ pins = "R8 GMAC0 RXDV", "U11 GMAC1 RXDV"; ++ skew-delay = <0>; ++ }; ++ conf1 { ++ pins = "T8 GMAC0 RXC"; ++ skew-delay = <10>; ++ }; ++ conf2 { ++ pins = "T11 GMAC1 RXC"; ++ skew-delay = <15>; ++ }; ++ conf3 { ++ pins = "P8 GMAC0 TXEN", "V11 GMAC1 TXEN"; ++ skew-delay = <7>; ++ }; ++ conf4 { ++ pins = "V7 GMAC0 TXC", "P10 GMAC1 TXC"; ++ skew-delay = <10>; ++ }; ++ conf5 { ++ /* The data lines all have default skew */ ++ pins = "U8 GMAC0 RXD0", "V8 GMAC0 RXD1", ++ "P9 GMAC0 RXD2", "R9 GMAC0 RXD3", ++ "R11 GMAC1 RXD0", "P11 GMAC1 RXD1", ++ "V12 GMAC1 RXD2", "U12 GMAC1 RXD3", ++ "R10 GMAC1 TXD0", "T10 GMAC1 TXD1", ++ "U10 GMAC1 TXD2", "V10 GMAC1 TXD3"; ++ skew-delay = <7>; ++ }; ++ conf6 { ++ pins = "U7 GMAC0 TXD0", "T7 GMAC0 TXD1", ++ "R7 GMAC0 TXD2", "P7 GMAC0 TXD3"; ++ skew-delay = <5>; ++ }; ++ /* Set up drive strength on GMAC0 to 16 mA */ ++ conf7 { ++ groups = "gmii_gmac0_grp"; ++ drive-strength = <16>; ++ }; ++ }; + }; + }; + +@@ -235,6 +285,18 @@ + pinctrl-0 = <&gpio1_default_pins>; + }; + ++ ethernet@60000000 { ++ status = "okay"; ++ ++ ethernet-port@0 { ++ phy-mode = "rgmii"; ++ phy-handle = <&phy0>; ++ }; ++ ethernet-port@1 { ++ /* Not used in this platform */ ++ }; ++ }; ++ + ata@63000000 { + status = "okay"; + }; +--- a/arch/arm/boot/dts/gemini-wbd222.dts ++++ b/arch/arm/boot/dts/gemini-wbd222.dts +@@ -136,6 +136,13 @@ + "gpio0bgrp"; + }; + }; ++ pinctrl-gmii { ++ /* This platform use both the ethernet ports */ ++ mux { ++ function = "gmii"; ++ groups = "gmii_gmac0_grp", "gmii_gmac1_grp"; ++ }; ++ }; + }; + }; + diff --git a/target/linux/gemini/patches-4.14/0900-arm-dts-gemini-add-openwrt-partitions-for-nas4220b.patch b/target/linux/gemini/patches-4.14/0900-arm-dts-gemini-add-openwrt-partitions-for-nas4220b.patch new file mode 100644 index 000000000..0fae0af0e --- /dev/null +++ b/target/linux/gemini/patches-4.14/0900-arm-dts-gemini-add-openwrt-partitions-for-nas4220b.patch @@ -0,0 +1,17 @@ +--- a/arch/arm/boot/dts/gemini-nas4220b.dts ++++ b/arch/arm/boot/dts/gemini-nas4220b.dts +@@ -115,6 +115,14 @@ + reg = <0x00fe0000 0x00020000>; + read-only; + }; ++ firmware@20000 { ++ label = "firmware"; ++ reg = <0x00020000 0x00f00000>; ++ }; ++ rootfs@320000 { ++ label = "rootfs"; ++ reg = <0x00320000 0x00c00000>; ++ }; + }; + + syscon: syscon@40000000 { diff --git a/target/linux/gemini/patches-4.14/0901-arm-dts-gemini-fix-ethernet-for-nas4220b.patch b/target/linux/gemini/patches-4.14/0901-arm-dts-gemini-fix-ethernet-for-nas4220b.patch new file mode 100644 index 000000000..90e95a70c --- /dev/null +++ b/target/linux/gemini/patches-4.14/0901-arm-dts-gemini-fix-ethernet-for-nas4220b.patch @@ -0,0 +1,69 @@ +--- a/arch/arm/boot/dts/gemini-nas4220b.dts ++++ b/arch/arm/boot/dts/gemini-nas4220b.dts +@@ -137,6 +137,47 @@ + groups = "gpio1dgrp"; + }; + }; ++ pinctrl-gmii { ++ mux { ++ function = "gmii"; ++ groups = "gmii_gmac0_grp"; ++ }; ++ conf0 { ++ pins = "V8 GMAC0 RXDV", "T10 GMAC1 RXDV"; ++ skew-delay = <0>; ++ }; ++ conf1 { ++ pins = "Y7 GMAC0 RXC", "Y11 GMAC1 RXC"; ++ skew-delay = <15>; ++ }; ++ conf2 { ++ pins = "T8 GMAC0 TXEN", "W11 GMAC1 TXEN"; ++ skew-delay = <7>; ++ }; ++ conf3 { ++ pins = "U8 GMAC0 TXC"; ++ skew-delay = <11>; ++ }; ++ conf4 { ++ pins = "V11 GMAC1 TXC"; ++ skew-delay = <10>; ++ }; ++ conf5 { ++ pins = "W8 GMAC0 RXD0", "V9 GMAC0 RXD1", ++ "Y8 GMAC0 RXD2", "U9 GMAC0 RXD3", ++ "T7 GMAC0 TXD0", "U6 GMAC0 TXD1", ++ "V7 GMAC0 TXD2", "U7 GMAC0 TXD3", ++ "Y12 GMAC1 RXD0", "V12 GMAC1 RXD1", ++ "T11 GMAC1 RXD2", "W12 GMAC1 RXD3", ++ "U10 GMAC1 TXD0", "Y10 GMAC1 TXD1", ++ "W10 GMAC1 TXD2", "T9 GMAC1 TXD3"; ++ skew-delay = <7>; ++ }; ++ conf6 { ++ groups = "gmii_gmac0_grp"; ++ drive-strength = <16>; ++ }; ++ }; + }; + }; + +@@ -151,6 +192,18 @@ + pinctrl-0 = <&gpio1_default_pins>; + }; + ++ ethernet@60000000 { ++ status = "okay"; ++ ++ gmac0: ethernet-port@0 { ++ phy-mode = "rgmii"; ++ phy-handle = <&phy0>; ++ }; ++ gmac1: ethernet-port@1 { ++ status = "disabled"; ++ }; ++ }; ++ + ata@63000000 { + status = "okay"; + }; diff --git a/target/linux/gemini/patches-4.14/0902-arm-dts-gemini-add-second-ata-for-nas4220b.patch b/target/linux/gemini/patches-4.14/0902-arm-dts-gemini-add-second-ata-for-nas4220b.patch new file mode 100644 index 000000000..ef9817236 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0902-arm-dts-gemini-add-second-ata-for-nas4220b.patch @@ -0,0 +1,13 @@ +--- a/arch/arm/boot/dts/gemini-nas4220b.dts ++++ b/arch/arm/boot/dts/gemini-nas4220b.dts +@@ -208,6 +208,10 @@ + status = "okay"; + }; + ++ ata@63400000 { ++ status = "okay"; ++ }; ++ + usb@68000000 { + status = "okay"; + }; diff --git a/target/linux/gemini/patches-4.14/0903-arm-dts-gemini-disable-usb-port-1-until-fixed.patch b/target/linux/gemini/patches-4.14/0903-arm-dts-gemini-disable-usb-port-1-until-fixed.patch new file mode 100644 index 000000000..6962d563a --- /dev/null +++ b/target/linux/gemini/patches-4.14/0903-arm-dts-gemini-disable-usb-port-1-until-fixed.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/boot/dts/gemini-nas4220b.dts ++++ b/arch/arm/boot/dts/gemini-nas4220b.dts +@@ -217,7 +217,7 @@ + }; + + usb@69000000 { +- status = "okay"; ++ status = "disabled"; + }; + }; + }; diff --git a/target/linux/gemini/patches-4.14/0904-net-cortina-fix-uninitialized-struct-member-usage.patch b/target/linux/gemini/patches-4.14/0904-net-cortina-fix-uninitialized-struct-member-usage.patch new file mode 100644 index 000000000..15a2d6cd8 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0904-net-cortina-fix-uninitialized-struct-member-usage.patch @@ -0,0 +1,23 @@ +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -1013,9 +1013,9 @@ static int geth_resize_freeq(struct gemi + int ret; + + if (netdev->dev_id == 0) +- other_netdev = geth->port1->netdev; ++ other_netdev = (geth->port1)? geth->port1->netdev : NULL; + else +- other_netdev = geth->port0->netdev; ++ other_netdev = (geth->port0)? geth->port0->netdev : NULL; + + if (other_netdev && netif_running(other_netdev)) + return -EBUSY; +@@ -2510,6 +2510,8 @@ static int gemini_ethernet_probe(struct + if (IS_ERR(geth->base)) + return PTR_ERR(geth->base); + geth->dev = dev; ++ geth->port0 = NULL; ++ geth->port1 = NULL; + + /* Wait for ports to stabilize */ + do { diff --git a/target/linux/gemini/patches-4.14/0905-arm-dts-gemini-dlink-dir-685-add-rtl8366rb.patch b/target/linux/gemini/patches-4.14/0905-arm-dts-gemini-dlink-dir-685-add-rtl8366rb.patch new file mode 100644 index 000000000..288b0d878 --- /dev/null +++ b/target/linux/gemini/patches-4.14/0905-arm-dts-gemini-dlink-dir-685-add-rtl8366rb.patch @@ -0,0 +1,82 @@ +--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts ++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts +@@ -87,6 +87,12 @@ + }; + }; + ++ rtl8366rb { ++ compatible = "realtek,rtl8366rb"; ++ gpio-sda = <&gpio0 22 GPIO_ACTIVE_HIGH>; ++ gpio-sck = <&gpio0 21 GPIO_ACTIVE_HIGH>; ++ }; ++ + leds { + compatible = "gpio-leds"; + led-wps { +@@ -249,6 +255,47 @@ + groups = "gpio1bgrp"; + }; + }; ++ pinctrl-gmii { ++ mux { ++ function = "gmii"; ++ groups = "gmii_gmac0_grp"; ++ }; ++ conf0 { ++ pins = "V8 GMAC0 RXDV", "T10 GMAC1 RXDV"; ++ skew-delay = <0>; ++ }; ++ conf1 { ++ pins = "Y7 GMAC0 RXC", "Y11 GMAC1 RXC"; ++ skew-delay = <15>; ++ }; ++ conf2 { ++ pins = "T8 GMAC0 TXEN", "W11 GMAC1 TXEN"; ++ skew-delay = <7>; ++ }; ++ conf3 { ++ pins = "U8 GMAC0 TXC"; ++ skew-delay = <11>; ++ }; ++ conf4 { ++ pins = "V11 GMAC1 TXC"; ++ skew-delay = <10>; ++ }; ++ conf5 { ++ pins = "W8 GMAC0 RXD0", "V9 GMAC0 RXD1", ++ "Y8 GMAC0 RXD2", "U9 GMAC0 RXD3", ++ "T7 GMAC0 TXD0", "U6 GMAC0 TXD1", ++ "V7 GMAC0 TXD2", "U7 GMAC0 TXD3", ++ "Y12 GMAC1 RXD0", "V12 GMAC1 RXD1", ++ "T11 GMAC1 RXD2", "W12 GMAC1 RXD3", ++ "U10 GMAC1 TXD0", "Y10 GMAC1 TXD1", ++ "W10 GMAC1 TXD2", "T9 GMAC1 TXD3"; ++ skew-delay = <7>; ++ }; ++ conf6 { ++ groups = "gmii_gmac0_grp"; ++ drive-strength = <16>; ++ }; ++ }; + }; + }; + +@@ -290,6 +337,18 @@ + <0x6000 0 0 4 &pci_intc 2>; + }; + ++ ethernet@60000000 { ++ status = "okay"; ++ ++ ethernet-port@0 { ++ phy-mode = "rgmii"; ++ // phy-handle = <&phy0>; ++ }; ++ ethernet-port@1 { ++ /* Not used in this platform */ ++ }; ++ }; ++ + ata@63000000 { + status = "okay"; + }; diff --git a/target/linux/gemini/patches-4.4/050-gpio-to-irq.patch b/target/linux/gemini/patches-4.4/050-gpio-to-irq.patch deleted file mode 100644 index 757284986..000000000 --- a/target/linux/gemini/patches-4.4/050-gpio-to-irq.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/arch/arm/mach-gemini/gpio.c -+++ b/arch/arm/mach-gemini/gpio.c -@@ -196,12 +196,18 @@ static int gemini_gpio_direction_output( - return 0; - } - -+static int gemini_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) -+{ -+ return gpio + GPIO_IRQ_BASE; -+} -+ - static struct gpio_chip gemini_gpio_chip = { - .label = "Gemini", - .direction_input = gemini_gpio_direction_input, - .get = gemini_gpio_get, - .direction_output = gemini_gpio_direction_output, - .set = gemini_gpio_set, -+ .to_irq = gemini_gpio_to_irq, - .base = 0, - .ngpio = GPIO_PORT_NUM * 32, - }; diff --git a/target/linux/gemini/patches-4.4/110-watchdog-add-gemini_wdt-driver.patch b/target/linux/gemini/patches-4.4/110-watchdog-add-gemini_wdt-driver.patch deleted file mode 100644 index bb66ae4dd..000000000 --- a/target/linux/gemini/patches-4.4/110-watchdog-add-gemini_wdt-driver.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -229,6 +229,16 @@ config 977_WATCHDOG - - Not sure? It's safe to say N. - -+config GEMINI_WATCHDOG -+ tristate "Gemini watchdog" -+ depends on ARCH_GEMINI -+ help -+ Say Y here if to include support for the watchdog timer -+ embedded in the Cortina Systems Gemini family of devices. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called gemini_wdt. -+ - config IXP4XX_WATCHDOG - tristate "IXP4xx Watchdog" - depends on ARCH_IXP4XX ---- a/drivers/watchdog/Makefile -+++ b/drivers/watchdog/Makefile -@@ -37,6 +37,7 @@ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt. - obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o - obj-$(CONFIG_21285_WATCHDOG) += wdt285.o - obj-$(CONFIG_977_WATCHDOG) += wdt977.o -+obj-$(CONFIG_GEMINI_WATCHDOG) += gemini_wdt.o - obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o - obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o - obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o diff --git a/target/linux/gemini/patches-4.4/111-arm-gemini-add-watchdog-device.patch b/target/linux/gemini/patches-4.4/111-arm-gemini-add-watchdog-device.patch deleted file mode 100644 index ab32e9e84..000000000 --- a/target/linux/gemini/patches-4.4/111-arm-gemini-add-watchdog-device.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/arch/arm/mach-gemini/devices.c -+++ b/arch/arm/mach-gemini/devices.c -@@ -116,3 +116,20 @@ int __init platform_register_rtc(void) - return platform_device_register(&gemini_rtc_device); - } - -+static struct resource wdt_resource = { -+ .start = GEMINI_WAQTCHDOG_BASE, -+ .end = GEMINI_WAQTCHDOG_BASE + 0x18, -+ .flags = IORESOURCE_MEM, -+}; -+ -+static struct platform_device wdt_device = { -+ .name = "gemini-wdt", -+ .id = 0, -+ .resource = &wdt_resource, -+ .num_resources = 1, -+}; -+ -+int __init platform_register_watchdog(void) -+{ -+ return platform_device_register(&wdt_device); -+} ---- a/arch/arm/mach-gemini/common.h -+++ b/arch/arm/mach-gemini/common.h -@@ -27,6 +27,7 @@ extern int platform_register_uart(void); - extern int platform_register_pflash(unsigned int size, - struct mtd_partition *parts, - unsigned int nr_parts); -+extern int platform_register_watchdog(void); - - extern void gemini_restart(enum reboot_mode mode, const char *cmd); - diff --git a/target/linux/gemini/patches-4.4/112-arm-gemini-register-watchdog-devices.patch b/target/linux/gemini/patches-4.4/112-arm-gemini-register-watchdog-devices.patch deleted file mode 100644 index d7660be4e..000000000 --- a/target/linux/gemini/patches-4.4/112-arm-gemini-register-watchdog-devices.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/arch/arm/mach-gemini/board-nas4220b.c -+++ b/arch/arm/mach-gemini/board-nas4220b.c -@@ -94,6 +94,7 @@ static void __init ib4220b_init(void) - platform_device_register(&ib4220b_led_device); - platform_device_register(&ib4220b_key_device); - platform_register_rtc(); -+ platform_register_watchdog(); - } - - MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") ---- a/arch/arm/mach-gemini/board-wbd111.c -+++ b/arch/arm/mach-gemini/board-wbd111.c -@@ -121,6 +121,7 @@ static void __init wbd111_init(void) - platform_device_register(&wbd111_leds_device); - platform_device_register(&wbd111_keys_device); - platform_register_rtc(); -+ platform_register_watchdog(); - } - - MACHINE_START(WBD111, "Wiliboard WBD-111") ---- a/arch/arm/mach-gemini/board-wbd222.c -+++ b/arch/arm/mach-gemini/board-wbd222.c -@@ -121,6 +121,7 @@ static void __init wbd222_init(void) - platform_device_register(&wbd222_leds_device); - platform_device_register(&wbd222_keys_device); - platform_register_rtc(); -+ platform_register_watchdog(); - } - - MACHINE_START(WBD222, "Wiliboard WBD-222") ---- a/arch/arm/mach-gemini/board-rut1xx.c -+++ b/arch/arm/mach-gemini/board-rut1xx.c -@@ -80,6 +80,7 @@ static void __init rut1xx_init(void) - platform_device_register(&rut1xx_leds); - platform_device_register(&rut1xx_keys_device); - platform_register_rtc(); -+ platform_register_watchdog(); - } - - MACHINE_START(RUT100, "Teltonika RUT100") diff --git a/target/linux/gemini/patches-4.4/120-net-add-gemini-gmac-driver.patch b/target/linux/gemini/patches-4.4/120-net-add-gemini-gmac-driver.patch deleted file mode 100644 index be11ae242..000000000 --- a/target/linux/gemini/patches-4.4/120-net-add-gemini-gmac-driver.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/drivers/net/ethernet/Kconfig -+++ b/drivers/net/ethernet/Kconfig -@@ -73,6 +73,7 @@ source "drivers/net/ethernet/neterion/Kc - source "drivers/net/ethernet/faraday/Kconfig" - source "drivers/net/ethernet/freescale/Kconfig" - source "drivers/net/ethernet/fujitsu/Kconfig" -+source "drivers/net/ethernet/gemini/Kconfig" - source "drivers/net/ethernet/hisilicon/Kconfig" - source "drivers/net/ethernet/hp/Kconfig" - source "drivers/net/ethernet/ibm/Kconfig" ---- a/drivers/net/ethernet/Makefile -+++ b/drivers/net/ethernet/Makefile -@@ -36,6 +36,7 @@ obj-$(CONFIG_NET_VENDOR_EXAR) += neterio - obj-$(CONFIG_NET_VENDOR_FARADAY) += faraday/ - obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/ - obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/ -+obj-$(CONFIG_NET_VENDOR_GEMINI) += gemini/ - obj-$(CONFIG_NET_VENDOR_HISILICON) += hisilicon/ - obj-$(CONFIG_NET_VENDOR_HP) += hp/ - obj-$(CONFIG_NET_VENDOR_IBM) += ibm/ diff --git a/target/linux/gemini/patches-4.4/121-arm-gemini-add-gmac-device.patch b/target/linux/gemini/patches-4.4/121-arm-gemini-add-gmac-device.patch deleted file mode 100644 index 6e7722490..000000000 --- a/target/linux/gemini/patches-4.4/121-arm-gemini-add-gmac-device.patch +++ /dev/null @@ -1,85 +0,0 @@ ---- a/arch/arm/mach-gemini/common.h -+++ b/arch/arm/mach-gemini/common.h -@@ -15,6 +15,7 @@ - #include - - struct mtd_partition; -+struct gemini_gmac_platform_data; - - extern void gemini_map_io(void); - extern void gemini_init_irq(void); -@@ -28,6 +29,7 @@ extern int platform_register_pflash(unsi - struct mtd_partition *parts, - unsigned int nr_parts); - extern int platform_register_watchdog(void); -+extern int platform_register_ethernet(struct gemini_gmac_platform_data *pdata); - - extern void gemini_restart(enum reboot_mode mode, const char *cmd); - ---- a/arch/arm/mach-gemini/devices.c -+++ b/arch/arm/mach-gemini/devices.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - static struct plat_serial8250_port serial_platform_data[] = { - { -@@ -133,3 +134,56 @@ int __init platform_register_watchdog(vo - { - return platform_device_register(&wdt_device); - } -+ -+static struct resource gmac_resources[] = { -+ { -+ .start = GEMINI_TOE_BASE, -+ .end = GEMINI_TOE_BASE + 0xffff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = IRQ_GMAC0, -+ .end = IRQ_GMAC0, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .start = IRQ_GMAC1, -+ .end = IRQ_GMAC1, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 gmac_dmamask = 0xffffffffUL; -+ -+static struct platform_device ethernet_device = { -+ .name = "gmac-gemini", -+ .id = 0, -+ .dev = { -+ .dma_mask = &gmac_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(gmac_resources), -+ .resource = gmac_resources, -+}; -+ -+int platform_register_ethernet(struct gemini_gmac_platform_data *pdata) -+{ -+ unsigned int reg; -+ -+ reg = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_MISC_CTRL)); -+ -+ reg &= ~(GMAC_GMII | GMAC_1_ENABLE); -+ -+ if (pdata->bus_id[1]) -+ reg |= GMAC_1_ENABLE; -+ else if (pdata->interface[0] == PHY_INTERFACE_MODE_GMII) -+ reg |= GMAC_GMII; -+ -+ writel(reg, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_MISC_CTRL)); -+ -+ ethernet_device.dev.platform_data = pdata; -+ -+ return platform_device_register(ðernet_device); -+} diff --git a/target/linux/gemini/patches-4.4/122-arm-gemini-register-ethernet.patch b/target/linux/gemini/patches-4.4/122-arm-gemini-register-ethernet.patch deleted file mode 100644 index 1cd9efc20..000000000 --- a/target/linux/gemini/patches-4.4/122-arm-gemini-register-ethernet.patch +++ /dev/null @@ -1,227 +0,0 @@ ---- a/arch/arm/mach-gemini/board-nas4220b.c -+++ b/arch/arm/mach-gemini/board-nas4220b.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -27,9 +28,27 @@ - - #include - #include -+#include - - #include "common.h" - -+static struct mdio_gpio_platform_data ib4220b_mdio = { -+ .mdc = 22, -+ .mdio = 21, -+ .phy_mask = ~(1 << 1), -+}; -+ -+static struct platform_device ib4220b_phy_device = { -+ .name = "mdio-gpio", -+ .id = 0, -+ .dev = { .platform_data = &ib4220b_mdio, }, -+}; -+ -+static struct gemini_gmac_platform_data ib4220b_gmac_data = { -+ .bus_id[0] = "gpio-0:01", -+ .interface[0] = PHY_INTERFACE_MODE_RGMII, -+}; -+ - static struct gpio_led ib4220b_leds[] = { - { - .name = "nas4220b:orange:hdd", -@@ -86,15 +105,47 @@ static struct platform_device ib4220b_ke - }, - }; - -+static void __init ib4220b_gmac_init(void) -+{ -+ unsigned int val; -+ -+ val = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_IO_DRIVING_CTRL)); -+ val |= (0x3 << GMAC0_PADS_SHIFT) | (0x3 << GMAC1_PADS_SHIFT); -+ writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_IO_DRIVING_CTRL)); -+ -+ val = (0x0 << GMAC0_RXDV_SKEW_SHIFT) | (0xf << GMAC0_RXC_SKEW_SHIFT) | -+ (0x7 << GMAC0_TXEN_SKEW_SHIFT) | (0xb << GMAC0_TXC_SKEW_SHIFT) | -+ (0x0 << GMAC1_RXDV_SKEW_SHIFT) | (0xf << GMAC1_RXC_SKEW_SHIFT) | -+ (0x7 << GMAC1_TXEN_SKEW_SHIFT) | (0xa << GMAC1_TXC_SKEW_SHIFT); -+ writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_GMAC_CTRL_SKEW_CTRL)); -+ -+ writel(0x77777777, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_GMAC0_DATA_SKEW_CTRL)); -+ writel(0x77777777, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_GMAC1_DATA_SKEW_CTRL)); -+ -+ val = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_ARBITRATION1_CTRL)) & ~BURST_LENGTH_MASK; -+ val |= (0x20 << BURST_LENGTH_SHIFT) | GMAC0_HIGH_PRIO | GMAC1_HIGH_PRIO; -+ writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_ARBITRATION1_CTRL)); -+} -+ - static void __init ib4220b_init(void) - { - gemini_gpio_init(); -+ ib4220b_gmac_init(); - platform_register_uart(); - platform_register_pflash(SZ_16M, NULL, 0); - platform_device_register(&ib4220b_led_device); - platform_device_register(&ib4220b_key_device); - platform_register_rtc(); - platform_register_watchdog(); -+ platform_device_register(&ib4220b_phy_device); -+ platform_register_ethernet(&ib4220b_gmac_data); - } - - MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") ---- a/arch/arm/mach-gemini/board-wbd111.c -+++ b/arch/arm/mach-gemini/board-wbd111.c -@@ -17,13 +17,34 @@ - #include - #include - #include -+#include - #include - #include - #include - -+#include - - #include "common.h" - -+static struct mdio_gpio_platform_data wbd111_mdio = { -+ .mdc = 22, -+ .mdio = 21, -+ .phy_mask = ~(1 << 1), -+}; -+ -+static struct platform_device wbd111_phy_device = { -+ .name = "mdio-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &wbd111_mdio, -+ }, -+}; -+ -+static struct gemini_gmac_platform_data gmac_data = { -+ .bus_id[0] = "gpio-0:01", -+ .interface[0] = PHY_INTERFACE_MODE_MII, -+}; -+ - static struct gpio_keys_button wbd111_keys[] = { - { - .code = KEY_SETUP, -@@ -122,6 +143,8 @@ static void __init wbd111_init(void) - platform_device_register(&wbd111_keys_device); - platform_register_rtc(); - platform_register_watchdog(); -+ platform_device_register(&wbd111_phy_device); -+ platform_register_ethernet(&gmac_data); - } - - MACHINE_START(WBD111, "Wiliboard WBD-111") ---- a/arch/arm/mach-gemini/board-wbd222.c -+++ b/arch/arm/mach-gemini/board-wbd222.c -@@ -17,13 +17,36 @@ - #include - #include - #include -+#include - #include - #include - #include - -+#include - - #include "common.h" - -+static struct mdio_gpio_platform_data wbd222_mdio = { -+ .mdc = 22, -+ .mdio = 21, -+ .phy_mask = ~((1 << 1) | (1 << 3)), -+}; -+ -+static struct platform_device wbd222_phy_device = { -+ .name = "mdio-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &wbd222_mdio, -+ }, -+}; -+ -+static struct gemini_gmac_platform_data gmac_data = { -+ .bus_id[0] = "gpio-0:01", -+ .interface[0] = PHY_INTERFACE_MODE_MII, -+ .bus_id[1] = "gpio-0:03", -+ .interface[1] = PHY_INTERFACE_MODE_MII, -+}; -+ - static struct gpio_keys_button wbd222_keys[] = { - { - .code = KEY_SETUP, -@@ -122,6 +145,8 @@ static void __init wbd222_init(void) - platform_device_register(&wbd222_keys_device); - platform_register_rtc(); - platform_register_watchdog(); -+ platform_device_register(&wbd222_phy_device); -+ platform_register_ethernet(&gmac_data); - } - - MACHINE_START(WBD222, "Wiliboard WBD-222") ---- a/arch/arm/mach-gemini/board-rut1xx.c -+++ b/arch/arm/mach-gemini/board-rut1xx.c -@@ -15,13 +15,35 @@ - #include - #include - #include -+#include - - #include - #include - #include - -+#include -+ - #include "common.h" - -+static struct mdio_gpio_platform_data rut1xx_mdio = { -+ .mdc = 22, -+ .mdio = 21, -+ .phy_mask = ~(1 << 1), -+}; -+ -+static struct platform_device rut1xx_phy_device = { -+ .name = "mdio-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &rut1xx_mdio, -+ }, -+}; -+ -+static struct gemini_gmac_platform_data gmac_data = { -+ .bus_id[0] = "gpio-0:01", -+ .interface[0] = PHY_INTERFACE_MODE_MII, -+}; -+ - static struct gpio_keys_button rut1xx_keys[] = { - { - .code = KEY_SETUP, -@@ -81,6 +103,8 @@ static void __init rut1xx_init(void) - platform_device_register(&rut1xx_keys_device); - platform_register_rtc(); - platform_register_watchdog(); -+ platform_device_register(&rut1xx_phy_device); -+ platform_register_ethernet(&gmac_data); - } - - MACHINE_START(RUT100, "Teltonika RUT100") diff --git a/target/linux/gemini/patches-4.4/130-usb-ehci-add-fot2g-driver.patch b/target/linux/gemini/patches-4.4/130-usb-ehci-add-fot2g-driver.patch deleted file mode 100644 index 2192ad69b..000000000 --- a/target/linux/gemini/patches-4.4/130-usb-ehci-add-fot2g-driver.patch +++ /dev/null @@ -1,133 +0,0 @@ ---- a/drivers/usb/host/ehci-hcd.c -+++ b/drivers/usb/host/ehci-hcd.c -@@ -352,11 +352,13 @@ static void ehci_silence_controller(stru - ehci->rh_state = EHCI_RH_HALTED; - ehci_turn_off_all_ports(ehci); - -+#ifndef CONFIG_ARCH_GEMINI - /* make BIOS/etc use companion controller during reboot */ - ehci_writel(ehci, 0, &ehci->regs->configured_flag); - - /* unblock posted writes */ - ehci_readl(ehci, &ehci->regs->configured_flag); -+#endif - spin_unlock_irq(&ehci->lock); - } - -@@ -608,7 +610,9 @@ static int ehci_run (struct usb_hcd *hcd - // Philips, Intel, and maybe others need CMD_RUN before the - // root hub will detect new devices (why?); NEC doesn't - ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); -+#ifndef CONFIG_ARCH_GEMINI - ehci->command |= CMD_RUN; -+#endif - ehci_writel(ehci, ehci->command, &ehci->regs->command); - dbg_cmd (ehci, "init", ehci->command); - -@@ -628,9 +632,11 @@ static int ehci_run (struct usb_hcd *hcd - */ - down_write(&ehci_cf_port_reset_rwsem); - ehci->rh_state = EHCI_RH_RUNNING; -+#ifndef CONFIG_ARCH_GEMINI - ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); - ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ - msleep(5); -+#endif - up_write(&ehci_cf_port_reset_rwsem); - ehci->last_periodic_enable = ktime_get_real(); - -@@ -768,9 +774,10 @@ static irqreturn_t ehci_irq (struct usb_ - pcd_status = status; - - /* resume root hub? */ -+#ifndef CONFIG_ARCH_GEMINI - if (ehci->rh_state == EHCI_RH_SUSPENDED) - usb_hcd_resume_root_hub(hcd); -- -+#endif - /* get per-port change detect bits */ - if (ehci->has_ppcd) - ppcd = status >> 16; -@@ -1296,6 +1303,11 @@ MODULE_LICENSE ("GPL"); - #define PLATFORM_DRIVER ehci_hcd_sead3_driver - #endif - -+#ifdef CONFIG_ARCH_GEMINI -+#include "ehci-fotg2.c" -+#define PLATFORM_DRIVER ehci_fotg2_driver -+#endif -+ - static int __init ehci_hcd_init(void) - { - int retval = 0; ---- a/drivers/usb/host/ehci-timer.c -+++ b/drivers/usb/host/ehci-timer.c -@@ -208,7 +208,9 @@ static void ehci_handle_controller_death - - /* Clean up the mess */ - ehci->rh_state = EHCI_RH_HALTED; -+#ifndef CONFIG_ARCH_GEMINI - ehci_writel(ehci, 0, &ehci->regs->configured_flag); -+#endif - ehci_writel(ehci, 0, &ehci->regs->intr_enable); - ehci_work(ehci); - end_unlink_async(ehci); ---- a/drivers/usb/host/ehci.h -+++ b/drivers/usb/host/ehci.h -@@ -657,7 +657,12 @@ static inline unsigned int - ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) - { - if (ehci_is_TDI(ehci)) { -- switch ((portsc >> (ehci->has_hostpc ? 25 : 26)) & 3) { -+#ifdef CONFIG_ARCH_GEMINI -+ portsc = readl(ehci_to_hcd(ehci)->regs + 0x80); -+ switch ((portsc>>22)&3) { -+#else -+ switch ((portsc>>26)&3) { -+#endif - case 0: - return 0; - case 1: ---- a/drivers/usb/host/ehci-hub.c -+++ b/drivers/usb/host/ehci-hub.c -@@ -1076,6 +1076,11 @@ int ehci_hub_control( - /* see what we found out */ - temp = check_reset_complete (ehci, wIndex, status_reg, - ehci_readl(ehci, status_reg)); -+#ifdef CONFIG_ARCH_GEMINI -+ /* restart schedule */ -+ ehci->command |= CMD_RUN; -+ ehci_writel(ehci, ehci->command, &ehci->regs->command); -+#endif - } - - /* transfer dedicated ports to the companion hc */ ---- a/include/linux/usb/ehci_def.h -+++ b/include/linux/usb/ehci_def.h -@@ -112,8 +112,13 @@ struct ehci_regs { - u32 frame_list; /* points to periodic list */ - /* ASYNCLISTADDR: offset 0x18 */ - u32 async_next; /* address of next async queue head */ -- -+#ifndef CONFIG_ARCH_GEMINI - u32 reserved1[2]; -+#else -+ u32 reserved1; -+ /* PORTSC: offset 0x20 for Faraday OTG */ -+ u32 port_status[1]; -+#endif - - /* TXFILLTUNING: offset 0x24 */ - u32 txfill_tuning; /* TX FIFO Tuning register */ -@@ -125,8 +130,11 @@ struct ehci_regs { - u32 configured_flag; - #define FLAG_CF (1<<0) /* true: we'll support "high speed" */ - -+#ifndef CONFIG_ARCH_GEMINI - /* PORTSC: offset 0x44 */ - u32 port_status[0]; /* up to N_PORTS */ -+#endif -+ - /* EHCI 1.1 addendum */ - #define PORTSC_SUSPEND_STS_ACK 0 - #define PORTSC_SUSPEND_STS_NYET 1 diff --git a/target/linux/gemini/patches-4.4/131-arm-gemini-add-usb-device.patch b/target/linux/gemini/patches-4.4/131-arm-gemini-add-usb-device.patch deleted file mode 100644 index a75a5c1c6..000000000 --- a/target/linux/gemini/patches-4.4/131-arm-gemini-add-usb-device.patch +++ /dev/null @@ -1,77 +0,0 @@ ---- a/arch/arm/mach-gemini/devices.c -+++ b/arch/arm/mach-gemini/devices.c -@@ -187,3 +187,64 @@ int platform_register_ethernet(struct ge - - return platform_device_register(ðernet_device); - } -+ -+static struct resource usb0_resources[] = { -+ { -+ .start = GEMINI_USB0_BASE, -+ .end = GEMINI_USB0_BASE + 0xfff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = IRQ_USB0, -+ .end = IRQ_USB0, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct resource usb1_resources[] = { -+ { -+ .start = GEMINI_USB1_BASE, -+ .end = GEMINI_USB1_BASE + 0xfff, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = IRQ_USB1, -+ .end = IRQ_USB1, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 usb0_dmamask = 0xffffffffUL; -+static u64 usb1_dmamask = 0xffffffffUL; -+ -+static struct platform_device usb_device[] = { -+ { -+ .name = "ehci-fotg2", -+ .id = 0, -+ .dev = { -+ .dma_mask = &usb0_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(usb0_resources), -+ .resource = usb0_resources, -+ }, -+ { -+ .name = "ehci-fotg2", -+ .id = 1, -+ .dev = { -+ .dma_mask = &usb1_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(usb1_resources), -+ .resource = usb1_resources, -+ }, -+}; -+ -+int __init platform_register_usb(unsigned int id) -+{ -+ if (id > 1) -+ return -EINVAL; -+ -+ return platform_device_register(&usb_device[id]); -+} -+ ---- a/arch/arm/mach-gemini/common.h -+++ b/arch/arm/mach-gemini/common.h -@@ -30,6 +30,7 @@ extern int platform_register_pflash(unsi - unsigned int nr_parts); - extern int platform_register_watchdog(void); - extern int platform_register_ethernet(struct gemini_gmac_platform_data *pdata); -+extern int platform_register_usb(unsigned int id); - - extern void gemini_restart(enum reboot_mode mode, const char *cmd); - diff --git a/target/linux/gemini/patches-4.4/132-arm-gemini-register-usb.patch b/target/linux/gemini/patches-4.4/132-arm-gemini-register-usb.patch deleted file mode 100644 index 2a61d828e..000000000 --- a/target/linux/gemini/patches-4.4/132-arm-gemini-register-usb.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- a/arch/arm/mach-gemini/board-wbd111.c -+++ b/arch/arm/mach-gemini/board-wbd111.c -@@ -145,6 +145,7 @@ static void __init wbd111_init(void) - platform_register_watchdog(); - platform_device_register(&wbd111_phy_device); - platform_register_ethernet(&gmac_data); -+ platform_register_usb(0); - } - - MACHINE_START(WBD111, "Wiliboard WBD-111") ---- a/arch/arm/mach-gemini/board-wbd222.c -+++ b/arch/arm/mach-gemini/board-wbd222.c -@@ -147,6 +147,7 @@ static void __init wbd222_init(void) - platform_register_watchdog(); - platform_device_register(&wbd222_phy_device); - platform_register_ethernet(&gmac_data); -+ platform_register_usb(0); - } - - MACHINE_START(WBD222, "Wiliboard WBD-222") ---- a/arch/arm/mach-gemini/board-rut1xx.c -+++ b/arch/arm/mach-gemini/board-rut1xx.c -@@ -105,6 +105,7 @@ static void __init rut1xx_init(void) - platform_register_watchdog(); - platform_device_register(&rut1xx_phy_device); - platform_register_ethernet(&gmac_data); -+ platform_register_usb(0); - } - - MACHINE_START(RUT100, "Teltonika RUT100") ---- a/arch/arm/mach-gemini/board-nas4220b.c -+++ b/arch/arm/mach-gemini/board-nas4220b.c -@@ -134,10 +134,23 @@ static void __init ib4220b_gmac_init(voi - GLOBAL_ARBITRATION1_CTRL)); - } - -+static void __init usb_ib4220b_init(void) -+{ -+ unsigned int val; -+ -+ val = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_MISC_CTRL)); -+ val &= ~(USB0_PLUG_MINIB | USB1_PLUG_MINIB); -+ val |= USB0_VBUS_ON | USB1_VBUS_ON; -+ writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_MISC_CTRL)); -+} -+ - static void __init ib4220b_init(void) - { - gemini_gpio_init(); - ib4220b_gmac_init(); -+ usb_ib4220b_init(); - platform_register_uart(); - platform_register_pflash(SZ_16M, NULL, 0); - platform_device_register(&ib4220b_led_device); -@@ -146,6 +159,8 @@ static void __init ib4220b_init(void) - platform_register_watchdog(); - platform_device_register(&ib4220b_phy_device); - platform_register_ethernet(&ib4220b_gmac_data); -+ platform_register_usb(0); -+ platform_register_usb(1); - } - - MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") diff --git a/target/linux/gemini/patches-4.4/140-arm-gemini-add-pci-support.patch b/target/linux/gemini/patches-4.4/140-arm-gemini-add-pci-support.patch deleted file mode 100644 index d17b1a1f8..000000000 --- a/target/linux/gemini/patches-4.4/140-arm-gemini-add-pci-support.patch +++ /dev/null @@ -1,66 +0,0 @@ ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -399,6 +399,7 @@ config ARCH_GEMINI - select CLKSRC_MMIO - select CPU_FA526 - select GENERIC_CLOCKEVENTS -+ select MIGHT_HAVE_PCI - help - Support for the Cortina Systems Gemini family SoCs - ---- a/arch/arm/mach-gemini/include/mach/hardware.h -+++ b/arch/arm/mach-gemini/include/mach/hardware.h -@@ -68,4 +68,9 @@ - */ - #define IO_ADDRESS(x) IOMEM((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000) - -+/* -+ * PCI subsystem macros -+ */ -+#define pcibios_assign_all_busses() 1 -+ - #endif ---- a/arch/arm/mach-gemini/include/mach/irqs.h -+++ b/arch/arm/mach-gemini/include/mach/irqs.h -@@ -43,11 +43,14 @@ - - #define NORMAL_IRQ_NUM 32 - --#define GPIO_IRQ_BASE NORMAL_IRQ_NUM -+#define PCI_IRQ_BASE NORMAL_IRQ_NUM -+#define PCI_IRQ_NUM 4 -+ -+#define GPIO_IRQ_BASE (NORMAL_IRQ_NUM + PCI_IRQ_NUM) - #define GPIO_IRQ_NUM (3 * 32) - - #define ARCH_TIMER_IRQ IRQ_TIMER2 - --#define NR_IRQS (NORMAL_IRQ_NUM + GPIO_IRQ_NUM) -+#define NR_IRQS (NORMAL_IRQ_NUM + PCI_IRQ_NUM + GPIO_IRQ_NUM) - - #endif /* __MACH_IRQS_H__ */ ---- a/arch/arm/mach-gemini/Makefile -+++ b/arch/arm/mach-gemini/Makefile -@@ -6,6 +6,8 @@ - - obj-y := irq.o mm.o time.o devices.o gpio.o idle.o reset.o - -+obj-$(CONFIG_PCI) += pci.o -+ - # Board-specific support - obj-$(CONFIG_MACH_NAS4220B) += board-nas4220b.o - obj-$(CONFIG_MACH_RUT100) += board-rut1xx.o ---- a/arch/arm/mach-gemini/mm.c -+++ b/arch/arm/mach-gemini/mm.c -@@ -59,6 +59,11 @@ static struct map_desc gemini_io_desc[] - .length = SZ_512K, - .type = MT_DEVICE, - }, { -+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_PCI_IO_BASE), -+ .pfn = __phys_to_pfn(GEMINI_PCI_IO_BASE), -+ .length = SZ_512K, -+ .type = MT_DEVICE, -+ }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_FLASH_CTRL_BASE), - .pfn = __phys_to_pfn(GEMINI_FLASH_CTRL_BASE), - .length = SZ_512K, diff --git a/target/linux/gemini/patches-4.4/150-gemini-pata.patch b/target/linux/gemini/patches-4.4/150-gemini-pata.patch deleted file mode 100644 index 1054be08b..000000000 --- a/target/linux/gemini/patches-4.4/150-gemini-pata.patch +++ /dev/null @@ -1,192 +0,0 @@ ---- a/arch/arm/mach-gemini/include/mach/global_reg.h -+++ b/arch/arm/mach-gemini/include/mach/global_reg.h -@@ -227,7 +227,13 @@ - #define USB0_PLUG_MINIB (1 << 29) - #define GMAC_GMII (1 << 28) - #define GMAC_1_ENABLE (1 << 27) --/* TODO: define ATA/SATA bits */ -+/* 011 - ata0 <-> sata0, sata1; bring out ata1 -+ * 010 - ata1 <-> sata1, sata0; bring out ata0 -+ * 001 - ata0 <-> sata0, ata1 <-> sata1; bring out ata1 -+ * 000 - ata0 <-> sata0, ata1 <-> sata1; bring out ata0 */ -+#define IDE_IOMUX_MASK (7 << 24) -+#define IDE_IOMUX_SATA1_SATA0 (2 << 24) -+#define IDE_IOMUX_SATA0_SATA1 (3 << 24) - #define USB1_VBUS_ON (1 << 23) - #define USB0_VBUS_ON (1 << 22) - #define APB_CLKOUT_ENABLE (1 << 21) ---- a/arch/arm/mach-gemini/irq.c -+++ b/arch/arm/mach-gemini/irq.c -@@ -89,6 +89,9 @@ void __init gemini_init_irq(void) - irq_set_handler(i, handle_edge_irq); - mode |= 1 << i; - level |= 1 << i; -+ } else if (i >= IRQ_IDE0 && i <= IRQ_IDE1) { -+ irq_set_handler(i, handle_edge_irq); -+ mode |= 1 << i; - } else { - irq_set_handler(i, handle_level_irq); - } ---- a/arch/arm/mach-gemini/common.h -+++ b/arch/arm/mach-gemini/common.h -@@ -31,6 +31,7 @@ extern int platform_register_pflash(unsi - extern int platform_register_watchdog(void); - extern int platform_register_ethernet(struct gemini_gmac_platform_data *pdata); - extern int platform_register_usb(unsigned int id); -+extern int platform_register_pata(unsigned int id); - - extern void gemini_restart(enum reboot_mode mode, const char *cmd); - ---- a/arch/arm/mach-gemini/devices.c -+++ b/arch/arm/mach-gemini/devices.c -@@ -248,3 +248,67 @@ int __init platform_register_usb(unsigne - return platform_device_register(&usb_device[id]); - } - -+static u64 pata_gemini_dmamask0 = 0xffffffffUL; -+static u64 pata_gemini_dmamask1 = 0xffffffffUL; -+ -+static struct resource pata_gemini_resources0[] = -+{ -+ [0] = { -+ .start = GEMINI_IDE0_BASE, -+ .end = GEMINI_IDE0_BASE + 0x40, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_IDE0, -+ .end = IRQ_IDE0, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct resource pata_gemini_resources1[] = -+{ -+ [0] = { -+ .start = GEMINI_IDE1_BASE, -+ .end = GEMINI_IDE1_BASE + 0x40, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_IDE1, -+ .end = IRQ_IDE1, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct platform_device pata_gemini_devices[] = -+{ -+ { -+ .name = "pata-gemini", -+ .id = 0, -+ .dev = -+ { -+ .dma_mask = &pata_gemini_dmamask0, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(pata_gemini_resources0), -+ .resource = pata_gemini_resources0, -+ }, -+ { -+ .name = "pata-gemini", -+ .id = 1, -+ .dev = -+ { -+ .dma_mask = &pata_gemini_dmamask1, -+ .coherent_dma_mask = 0xffffffff, -+ }, -+ .num_resources = ARRAY_SIZE(pata_gemini_resources1), -+ .resource = pata_gemini_resources1, -+ }, -+}; -+ -+int __init platform_register_pata(unsigned int id) -+{ -+ if (id > 1) -+ return -EINVAL; -+ -+ return platform_device_register(&pata_gemini_devices[id]); -+} ---- a/arch/arm/mach-gemini/mm.c -+++ b/arch/arm/mach-gemini/mm.c -@@ -24,6 +24,11 @@ static struct map_desc gemini_io_desc[] - .length = SZ_512K, - .type = MT_DEVICE, - }, { -+ .virtual = (unsigned long)IO_ADDRESS(GEMINI_SATA_BASE), -+ .pfn = __phys_to_pfn(GEMINI_SATA_BASE), -+ .length = SZ_512K, -+ .type = MT_DEVICE, -+ }, { - .virtual = (unsigned long)IO_ADDRESS(GEMINI_UART_BASE), - .pfn = __phys_to_pfn(GEMINI_UART_BASE), - .length = SZ_512K, ---- a/drivers/ata/Kconfig -+++ b/drivers/ata/Kconfig -@@ -567,6 +567,16 @@ config PATA_EP93XX - - If unsure, say N. - -+config PATA_GEMINI -+ tristate "Gemini PATA support (Experimental)" -+ depends on ARCH_GEMINI -+ help -+ This option enables support for the Gemini PATA-Controller. -+ Note that the Gemini SoC has no native SATA-Controller but an -+ onboard PATA-SATA bridge. -+ -+ If unsure, say N. -+ - config PATA_HPT366 - tristate "HPT 366/368 PATA support" - depends on PCI ---- a/drivers/ata/Makefile -+++ b/drivers/ata/Makefile -@@ -56,6 +56,7 @@ obj-$(CONFIG_PATA_CS5536) += pata_cs5536 - obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o - obj-$(CONFIG_PATA_EFAR) += pata_efar.o - obj-$(CONFIG_PATA_EP93XX) += pata_ep93xx.o -+obj-$(CONFIG_PATA_GEMINI) += pata_gemini.o - obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o - obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o - obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o ---- a/arch/arm/mach-gemini/board-nas4220b.c -+++ b/arch/arm/mach-gemini/board-nas4220b.c -@@ -146,11 +146,28 @@ static void __init usb_ib4220b_init(void - GLOBAL_MISC_CTRL)); - } - -+static void __init sata_ib4220b_init(void) -+{ -+ unsigned val; -+ -+ val = readl((void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_MISC_CTRL)); -+ val &= ~(IDE_IOMUX_MASK | PFLASH_PADS_DISABLE); -+ val |= IDE_PADS_ENABLE; -+ writel(val, (void __iomem*)(IO_ADDRESS(GEMINI_GLOBAL_BASE) + -+ GLOBAL_MISC_CTRL)); -+ -+ /* enabling ports for presence detection, master only */ -+ writel(0x00000001, (void __iomem*)(IO_ADDRESS(GEMINI_SATA_BASE) + 0x18)); -+ writel(0x00000001, (void __iomem*)(IO_ADDRESS(GEMINI_SATA_BASE) + 0x1c)); -+} -+ - static void __init ib4220b_init(void) - { - gemini_gpio_init(); - ib4220b_gmac_init(); - usb_ib4220b_init(); -+ sata_ib4220b_init(); - platform_register_uart(); - platform_register_pflash(SZ_16M, NULL, 0); - platform_device_register(&ib4220b_led_device); -@@ -161,6 +178,8 @@ static void __init ib4220b_init(void) - platform_register_ethernet(&ib4220b_gmac_data); - platform_register_usb(0); - platform_register_usb(1); -+ platform_register_pata(0); -+ platform_register_pata(1); - } - - MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") diff --git a/target/linux/gemini/raidsonic/config-default b/target/linux/gemini/raidsonic/config-default deleted file mode 100644 index 91605238b..000000000 --- a/target/linux/gemini/raidsonic/config-default +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_CMDLINE="rootfstype=squashfs,jffs2 noinitrd console=ttyS0,19200 mem=128M mtdparts=physmap-flash.0:128k(BOOT),3072k(Kern),6144k(Ramdisk),6144k(Application),128k(VCTL),640k(CurConf),128k(FIS-directory),12288k@0x320000(rootfs),15360k@0x20000(firmware) root=/dev/mtdblock7" -CONFIG_MACH_NAS4220B=y -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_SPLIT_FIRMWARE=y diff --git a/target/linux/gemini/raidsonic/target.mk b/target/linux/gemini/raidsonic/target.mk deleted file mode 100644 index d158090d4..000000000 --- a/target/linux/gemini/raidsonic/target.mk +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (C) 2014 OpenWrt.org -# - -SUBTARGET:=raidsonic -BOARDNAME:=Raidsonic NAS42x0 -FEATURES+=usb -DEFAULT_PACKAGES+=kmod-usb2 kmod-md-mod kmod-md-linear kmod-md-multipath \ - kmod-md-raid0 kmod-md-raid1 kmod-md-raid10 kmod-md-raid456 \ - kmod-fs-btrfs kmod-fs-cifs kmod-fs-ext4 kmod-fs-nfs \ - kmod-fs-nfsd kmod-fs-ntfs kmod-fs-reiserfs kmod-fs-vfat \ - kmod-nls-utf8 kmod-usb-storage-extras \ - samba36-server mdadm cfdisk fdisk e2fsprogs badblocks - -define Target/Description - Build firmware images for Raidsonic NAS4220. -endef diff --git a/target/linux/gemini/wiligear/target.mk b/target/linux/gemini/wiligear/target.mk deleted file mode 100644 index 97cab1859..000000000 --- a/target/linux/gemini/wiligear/target.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2014 OpenWrt.org -# - -SUBTARGET:=wiligear -BOARDNAME:=Wiligear WBD-222/111 - -define Target/Description - Build firmware images for Wiligear WBD-222 and WBD-111 boards. -endef diff --git a/target/linux/generic/backport-4.14/030-USB-serial-option-fix-dwm-158-3g-modem-interface.patch b/target/linux/generic/backport-4.14/030-USB-serial-option-fix-dwm-158-3g-modem-interface.patch new file mode 100644 index 000000000..30aa03a69 --- /dev/null +++ b/target/linux/generic/backport-4.14/030-USB-serial-option-fix-dwm-158-3g-modem-interface.patch @@ -0,0 +1,42 @@ +From 4d304a6fe93538ce356b4593dc43476b50c023e7 Mon Sep 17 00:00:00 2001 +From: Giuseppe Lippolis +Date: Mon, 23 Apr 2018 09:03:06 +0200 +Subject: USB: serial: option: blacklist unused dwm-158 interfaces + +The dwm-158 interface 4 and 5 doesn't answer to the AT commands +and doesn't appears a option interface. +Tested on openwrt distribution (kernel 4.14 using the old blacklist +definitions). + +Lars Melin also writes: + + Blacklisting interface 4 and 5 is correct because: + + MI_00 D-Link Mobile Broadband Device (cdc_ether) + MI_02 D-Link HSPA+DataCard Diagnostics Interface (also ppp modem) + MI_03 D-Link HSPA+DataCard NMEA Device + MI_04 D-Link HSPA+DataCard Speech Port + MI_05 D-Link HSPA+DataCard Debug Port + MI_06 USB Mass Storage Device + +Signed-off-by: Giuseppe Lippolis +[ johan: add Lars's comment on the interface layout and reword summary ] +Cc: Lars Melin +Cc: Dan Williams +Signed-off-by: Johan Hovold +--- + drivers/usb/serial/option.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1919,7 +1919,8 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d01, 0xff) }, /* D-Link DWM-156 (variant) */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d02, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d03, 0xff) }, +- { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ ++ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff), /* D-Link DWM-158 */ ++ .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ + .driver_info = RSVD(4) }, diff --git a/target/linux/generic/backport-4.14/030-v4.17-0001-usb-dwc2-add-support-for-host-mode-external-vbus-sup.patch b/target/linux/generic/backport-4.14/030-v4.17-0001-usb-dwc2-add-support-for-host-mode-external-vbus-sup.patch new file mode 100644 index 000000000..f490639f3 --- /dev/null +++ b/target/linux/generic/backport-4.14/030-v4.17-0001-usb-dwc2-add-support-for-host-mode-external-vbus-sup.patch @@ -0,0 +1,109 @@ +From 531ef5ebea96394ddb7f554d4d88e017dde30a59 Mon Sep 17 00:00:00 2001 +From: Amelie Delaunay +Date: Tue, 13 Feb 2018 09:28:12 +0100 +Subject: [PATCH] usb: dwc2: add support for host mode external vbus supply + +This patch adds a way to enable an external vbus supply in host mode, +when dwc2 drvvbus signal is not used. + +This patch is very similar to the one done in U-Boot dwc2 driver [1]. It +also adds dynamic vbus supply management depending on the role and state +of the core. + +[1] https://lists.denx.de/pipermail/u-boot/2017-March/283434.html + +Signed-off-by: Amelie Delaunay +Signed-off-by: Felipe Balbi +--- + drivers/usb/dwc2/core.h | 2 ++ + drivers/usb/dwc2/hcd.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 28 insertions(+) + +--- a/drivers/usb/dwc2/core.h ++++ b/drivers/usb/dwc2/core.h +@@ -777,6 +777,7 @@ struct dwc2_hregs_backup { + * @plat: The platform specific configuration data. This can be + * removed once all SoCs support usb transceiver. + * @supplies: Definition of USB power supplies ++ * @vbus_supply: Regulator supplying vbus. + * @phyif: PHY interface width + * @lock: Spinlock that protects all the driver data structures + * @priv: Stores a pointer to the struct usb_hcd +@@ -913,6 +914,7 @@ struct dwc2_hsotg { + struct usb_phy *uphy; + struct dwc2_hsotg_plat *plat; + struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES]; ++ struct regulator *vbus_supply; + u32 phyif; + + spinlock_t lock; +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -359,6 +359,23 @@ static void dwc2_gusbcfg_init(struct dwc + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); + } + ++static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg) ++{ ++ hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus"); ++ if (IS_ERR(hsotg->vbus_supply)) ++ return 0; ++ ++ return regulator_enable(hsotg->vbus_supply); ++} ++ ++static int dwc2_vbus_supply_exit(struct dwc2_hsotg *hsotg) ++{ ++ if (hsotg->vbus_supply) ++ return regulator_disable(hsotg->vbus_supply); ++ ++ return 0; ++} ++ + /** + * dwc2_enable_host_interrupts() - Enables the Host mode interrupts + * +@@ -3246,6 +3263,7 @@ static void dwc2_conn_id_status_change(s + + /* B-Device connector (Device Mode) */ + if (gotgctl & GOTGCTL_CONID_B) { ++ dwc2_vbus_supply_exit(hsotg); + /* Wait for switch to device mode */ + dev_dbg(hsotg->dev, "connId B\n"); + if (hsotg->bus_suspended) { +@@ -4352,6 +4370,9 @@ static int _dwc2_hcd_start(struct usb_hc + } + + spin_unlock_irqrestore(&hsotg->lock, flags); ++ ++ dwc2_vbus_supply_init(hsotg); ++ + return 0; + } + +@@ -4379,6 +4400,8 @@ static void _dwc2_hcd_stop(struct usb_hc + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + spin_unlock_irqrestore(&hsotg->lock, flags); + ++ dwc2_vbus_supply_exit(hsotg); ++ + usleep_range(1000, 3000); + } + +@@ -4415,6 +4438,7 @@ static int _dwc2_hcd_suspend(struct usb_ + hprt0 |= HPRT0_SUSP; + hprt0 &= ~HPRT0_PWR; + dwc2_writel(hprt0, hsotg->regs + HPRT0); ++ dwc2_vbus_supply_exit(hsotg); + } + + /* Enter hibernation */ +@@ -4495,6 +4519,8 @@ static int _dwc2_hcd_resume(struct usb_h + spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_port_resume(hsotg); + } else { ++ dwc2_vbus_supply_init(hsotg); ++ + /* Wait for controller to correctly update D+/D- level */ + usleep_range(3000, 5000); + diff --git a/target/linux/generic/backport-4.14/030-v4.17-0002-usb-dwc2-dwc2_vbus_supply_init-fix-error-check.patch b/target/linux/generic/backport-4.14/030-v4.17-0002-usb-dwc2-dwc2_vbus_supply_init-fix-error-check.patch new file mode 100644 index 000000000..f3f93af68 --- /dev/null +++ b/target/linux/generic/backport-4.14/030-v4.17-0002-usb-dwc2-dwc2_vbus_supply_init-fix-error-check.patch @@ -0,0 +1,55 @@ +From 438fea2a6325933868aebc20279e2669c9a21207 Mon Sep 17 00:00:00 2001 +From: Tomeu Vizoso +Date: Mon, 26 Mar 2018 11:00:01 +0200 +Subject: [PATCH] usb: dwc2: dwc2_vbus_supply_init: fix error check + +devm_regulator_get_optional returns -ENODEV if the regulator isn't +there, so if that's the case we have to make sure not to leave -ENODEV +in the regulator pointer. + +Also, make sure we return 0 in that case, but correctly propagate any +other errors. Also propagate the error from _dwc2_hcd_start. + +Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external vbus supply") +Cc: Amelie Delaunay +Reviewed-by: Amelie Delaunay +Reviewed-by: Heiko Stuebner +Reviewed-by: Grigor Tovmasyan +Tested-by: Heiko Stuebner +Acked-by: Minas Harutyunyan +Signed-off-by: Tomeu Vizoso +Signed-off-by: Felipe Balbi +--- + drivers/usb/dwc2/hcd.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -361,9 +361,14 @@ static void dwc2_gusbcfg_init(struct dwc + + static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg) + { ++ int ret; ++ + hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus"); +- if (IS_ERR(hsotg->vbus_supply)) +- return 0; ++ if (IS_ERR(hsotg->vbus_supply)) { ++ ret = PTR_ERR(hsotg->vbus_supply); ++ hsotg->vbus_supply = NULL; ++ return ret == -ENODEV ? 0 : ret; ++ } + + return regulator_enable(hsotg->vbus_supply); + } +@@ -4371,9 +4376,7 @@ static int _dwc2_hcd_start(struct usb_hc + + spin_unlock_irqrestore(&hsotg->lock, flags); + +- dwc2_vbus_supply_init(hsotg); +- +- return 0; ++ return dwc2_vbus_supply_init(hsotg); + } + + /* diff --git a/target/linux/generic/backport-4.14/042-v4.18-0001-mtd-move-code-adding-registering-partitions-to-the-p.patch b/target/linux/generic/backport-4.14/042-v4.18-0001-mtd-move-code-adding-registering-partitions-to-the-p.patch new file mode 100644 index 000000000..83077431b --- /dev/null +++ b/target/linux/generic/backport-4.14/042-v4.18-0001-mtd-move-code-adding-registering-partitions-to-the-p.patch @@ -0,0 +1,168 @@ +From 5ac67ce36cfe38b4c104a42ce52c5c8d526f1c95 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 27 Mar 2018 22:35:41 +0200 +Subject: [PATCH] mtd: move code adding (registering) partitions to the + parse_mtd_partitions() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This commit slightly simplifies the code. Every parse_mtd_partitions() +caller (out of two existing ones) had to add partitions & cleanup parser +on its own. This moves that responsibility into the function. + +That change also allows dropping struct mtd_partitions argument. + +There is one minor behavior change caused by this cleanup. If +parse_mtd_partitions() fails to add partitions (add_mtd_partitions() +return an error) then mtd_device_parse_register() will still try to +add (register) fallback partitions. It's a real corner case affecting +one of uncommon error paths and shouldn't cause any harm. + +Signed-off-by: RafaÅ‚ MiÅ‚ecki +Signed-off-by: Boris Brezillon +--- + drivers/mtd/mtdcore.c | 14 ++++---------- + drivers/mtd/mtdcore.h | 1 - + drivers/mtd/mtdpart.c | 44 ++++++++++++++++---------------------------- + 3 files changed, 20 insertions(+), 39 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -686,7 +686,6 @@ int mtd_device_parse_register(struct mtd + const struct mtd_partition *parts, + int nr_parts) + { +- struct mtd_partitions parsed = { }; + int ret; + + mtd_set_dev_defaults(mtd); +@@ -698,13 +697,10 @@ int mtd_device_parse_register(struct mtd + } + + /* Prefer parsed partitions over driver-provided fallback */ +- ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); +- if (!ret && parsed.nr_parts) { +- parts = parsed.parts; +- nr_parts = parsed.nr_parts; +- } +- +- if (nr_parts) ++ ret = parse_mtd_partitions(mtd, types, parser_data); ++ if (ret > 0) ++ ret = 0; ++ else if (nr_parts) + ret = add_mtd_partitions(mtd, parts, nr_parts); + else if (!device_is_registered(&mtd->dev)) + ret = add_mtd_device(mtd); +@@ -730,8 +726,6 @@ int mtd_device_parse_register(struct mtd + } + + out: +- /* Cleanup any parsed partitions */ +- mtd_part_parser_cleanup(&parsed); + if (ret && device_is_registered(&mtd->dev)) + del_mtd_device(mtd); + +--- a/drivers/mtd/mtdcore.h ++++ b/drivers/mtd/mtdcore.h +@@ -15,7 +15,6 @@ int del_mtd_partitions(struct mtd_info * + struct mtd_partitions; + + int parse_mtd_partitions(struct mtd_info *master, const char * const *types, +- struct mtd_partitions *pparts, + struct mtd_part_parser_data *data); + + void mtd_part_parser_cleanup(struct mtd_partitions *parts); +--- a/drivers/mtd/mtdpart.c ++++ b/drivers/mtd/mtdpart.c +@@ -383,20 +383,7 @@ static inline void free_partition(struct + */ + static int mtd_parse_part(struct mtd_part *slave, const char *const *types) + { +- struct mtd_partitions parsed; +- int err; +- +- err = parse_mtd_partitions(&slave->mtd, types, &parsed, NULL); +- if (err) +- return err; +- else if (!parsed.nr_parts) +- return -ENOENT; +- +- err = add_mtd_partitions(&slave->mtd, parsed.parts, parsed.nr_parts); +- +- mtd_part_parser_cleanup(&parsed); +- +- return err; ++ return parse_mtd_partitions(&slave->mtd, types, NULL); + } + + static struct mtd_part *allocate_partition(struct mtd_info *parent, +@@ -981,30 +968,27 @@ static int mtd_part_of_parse(struct mtd_ + } + + /** +- * parse_mtd_partitions - parse MTD partitions ++ * parse_mtd_partitions - parse and register MTD partitions ++ * + * @master: the master partition (describes whole MTD device) + * @types: names of partition parsers to try or %NULL +- * @pparts: info about partitions found is returned here + * @data: MTD partition parser-specific data + * +- * This function tries to find partition on MTD device @master. It uses MTD +- * partition parsers, specified in @types. However, if @types is %NULL, then +- * the default list of parsers is used. The default list contains only the ++ * This function tries to find & register partitions on MTD device @master. It ++ * uses MTD partition parsers, specified in @types. However, if @types is %NULL, ++ * then the default list of parsers is used. The default list contains only the + * "cmdlinepart" and "ofpart" parsers ATM. + * Note: If there are more then one parser in @types, the kernel only takes the + * partitions parsed out by the first parser. + * + * This function may return: + * o a negative error code in case of failure +- * o zero otherwise, and @pparts will describe the partitions, number of +- * partitions, and the parser which parsed them. Caller must release +- * resources with mtd_part_parser_cleanup() when finished with the returned +- * data. ++ * o number of found partitions otherwise + */ + int parse_mtd_partitions(struct mtd_info *master, const char *const *types, +- struct mtd_partitions *pparts, + struct mtd_part_parser_data *data) + { ++ struct mtd_partitions pparts = { }; + struct mtd_part_parser *parser; + int ret, err = 0; + +@@ -1018,7 +1002,7 @@ int parse_mtd_partitions(struct mtd_info + * handled in a separated function. + */ + if (!strcmp(*types, "ofpart")) { +- ret = mtd_part_of_parse(master, pparts); ++ ret = mtd_part_of_parse(master, &pparts); + } else { + pr_debug("%s: parsing partitions %s\n", master->name, + *types); +@@ -1029,13 +1013,17 @@ int parse_mtd_partitions(struct mtd_info + parser ? parser->name : NULL); + if (!parser) + continue; +- ret = mtd_part_do_parse(parser, master, pparts, data); ++ ret = mtd_part_do_parse(parser, master, &pparts, data); + if (ret <= 0) + mtd_part_parser_put(parser); + } + /* Found partitions! */ +- if (ret > 0) +- return 0; ++ if (ret > 0) { ++ err = add_mtd_partitions(master, pparts.parts, ++ pparts.nr_parts); ++ mtd_part_parser_cleanup(&pparts); ++ return err ? err : pparts.nr_parts; ++ } + /* + * Stash the first error we see; only report it if no parser + * succeeds diff --git a/target/linux/generic/pending-4.14/142-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch b/target/linux/generic/backport-4.14/043-v4.18-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch similarity index 88% rename from target/linux/generic/pending-4.14/142-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch rename to target/linux/generic/backport-4.14/043-v4.18-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch index 60c8ecbdc..e08f8dad3 100644 --- a/target/linux/generic/pending-4.14/142-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch +++ b/target/linux/generic/backport-4.14/043-v4.18-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch @@ -1,4 +1,6 @@ +From 237ea0d4762cc14d0fc80e80d61f0f08e1050c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 12 Apr 2018 07:24:52 +0200 Subject: [PATCH] mtd: bcm47xxpart: improve handling TRX partition size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -6,7 +8,7 @@ Content-Transfer-Encoding: 8bit When bcm47xxpart finds a TRX partition (container) it's supposed to jump to the end of it and keep looking for more partitions. TRX and its -subpartitions are handled be a separated parser. +subpartitions are handled by a separate parser. The problem with old code was relying on the length specified in a TRX header. That isn't reliable as TRX is commonly modified to have checksum @@ -22,7 +24,10 @@ This makes code more optimal & reliable thanks to skipping data that shouldn't be parsed. Signed-off-by: RafaÅ‚ MiÅ‚ecki +Signed-off-by: Boris Brezillon --- + drivers/mtd/bcm47xxpart.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c diff --git a/target/linux/generic/backport-4.14/300-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch b/target/linux/generic/backport-4.14/300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch similarity index 100% rename from target/linux/generic/backport-4.14/300-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch rename to target/linux/generic/backport-4.14/300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch diff --git a/target/linux/generic/backport-4.14/301-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch b/target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch similarity index 100% rename from target/linux/generic/backport-4.14/301-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch rename to target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch diff --git a/target/linux/generic/backport-4.14/302-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch b/target/linux/generic/backport-4.14/302-v4.16-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch similarity index 100% rename from target/linux/generic/backport-4.14/302-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch rename to target/linux/generic/backport-4.14/302-v4.16-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch diff --git a/target/linux/generic/backport-4.14/303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch b/target/linux/generic/backport-4.14/303-v4.16-netfilter-nf_tables-remove-multihook-chains-and-fami.patch similarity index 100% rename from target/linux/generic/backport-4.14/303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch rename to target/linux/generic/backport-4.14/303-v4.16-netfilter-nf_tables-remove-multihook-chains-and-fami.patch diff --git a/target/linux/generic/backport-4.14/304-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch b/target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch similarity index 100% rename from target/linux/generic/backport-4.14/304-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch rename to target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch diff --git a/target/linux/generic/backport-4.14/305-netfilter-move-checksum_partial-indirection-to-struc.patch b/target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch similarity index 100% rename from target/linux/generic/backport-4.14/305-netfilter-move-checksum_partial-indirection-to-struc.patch rename to target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch diff --git a/target/linux/generic/backport-4.14/306-netfilter-remove-saveroute-indirection-in-struct-nf_.patch b/target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch similarity index 100% rename from target/linux/generic/backport-4.14/306-netfilter-remove-saveroute-indirection-in-struct-nf_.patch rename to target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch diff --git a/target/linux/generic/backport-4.14/307-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch b/target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch similarity index 100% rename from target/linux/generic/backport-4.14/307-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch rename to target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch diff --git a/target/linux/generic/backport-4.14/308-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch b/target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch similarity index 100% rename from target/linux/generic/backport-4.14/308-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch rename to target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch diff --git a/target/linux/generic/backport-4.14/309-netfilter-remove-route_key_size-field-in-struct-nf_a.patch b/target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch similarity index 100% rename from target/linux/generic/backport-4.14/309-netfilter-remove-route_key_size-field-in-struct-nf_a.patch rename to target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch diff --git a/target/linux/generic/backport-4.14/310-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch b/target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch similarity index 100% rename from target/linux/generic/backport-4.14/310-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch rename to target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch diff --git a/target/linux/generic/backport-4.14/311-netfilter-nf_tables_arp-don-t-set-forward-chain.patch b/target/linux/generic/backport-4.14/311-v4.16-netfilter-nf_tables_arp-don-t-set-forward-chain.patch similarity index 100% rename from target/linux/generic/backport-4.14/311-netfilter-nf_tables_arp-don-t-set-forward-chain.patch rename to target/linux/generic/backport-4.14/311-v4.16-netfilter-nf_tables_arp-don-t-set-forward-chain.patch diff --git a/target/linux/generic/backport-4.14/312-netfilter-nf_tables-remove-hooks-from-family-definit.patch b/target/linux/generic/backport-4.14/312-v4.16-netfilter-nf_tables-remove-hooks-from-family-definit.patch similarity index 100% rename from target/linux/generic/backport-4.14/312-netfilter-nf_tables-remove-hooks-from-family-definit.patch rename to target/linux/generic/backport-4.14/312-v4.16-netfilter-nf_tables-remove-hooks-from-family-definit.patch diff --git a/target/linux/generic/backport-4.14/313-netfilter-remove-defensive-check-on-malformed-packet.patch b/target/linux/generic/backport-4.14/313-v4.16-netfilter-remove-defensive-check-on-malformed-packet.patch similarity index 100% rename from target/linux/generic/backport-4.14/313-netfilter-remove-defensive-check-on-malformed-packet.patch rename to target/linux/generic/backport-4.14/313-v4.16-netfilter-remove-defensive-check-on-malformed-packet.patch diff --git a/target/linux/generic/backport-4.14/314-netfilter-meta-secpath-support.patch b/target/linux/generic/backport-4.14/314-v4.16-netfilter-meta-secpath-support.patch similarity index 100% rename from target/linux/generic/backport-4.14/314-netfilter-meta-secpath-support.patch rename to target/linux/generic/backport-4.14/314-v4.16-netfilter-meta-secpath-support.patch diff --git a/target/linux/generic/backport-4.14/315-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch b/target/linux/generic/backport-4.14/315-v4.15-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch similarity index 100% rename from target/linux/generic/backport-4.14/315-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch rename to target/linux/generic/backport-4.14/315-v4.15-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch diff --git a/target/linux/generic/backport-4.14/320-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch b/target/linux/generic/backport-4.14/320-v4.16-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch similarity index 100% rename from target/linux/generic/backport-4.14/320-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch rename to target/linux/generic/backport-4.14/320-v4.16-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch diff --git a/target/linux/generic/backport-4.14/321-netfilter-nf_tables-add-flow-table-netlink-frontend.patch b/target/linux/generic/backport-4.14/321-v4.16-netfilter-nf_tables-add-flow-table-netlink-frontend.patch similarity index 100% rename from target/linux/generic/backport-4.14/321-netfilter-nf_tables-add-flow-table-netlink-frontend.patch rename to target/linux/generic/backport-4.14/321-v4.16-netfilter-nf_tables-add-flow-table-netlink-frontend.patch diff --git a/target/linux/generic/backport-4.14/322-netfilter-add-generic-flow-table-infrastructure.patch b/target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch similarity index 100% rename from target/linux/generic/backport-4.14/322-netfilter-add-generic-flow-table-infrastructure.patch rename to target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch diff --git a/target/linux/generic/backport-4.14/323-netfilter-flow-table-support-for-IPv4.patch b/target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch similarity index 100% rename from target/linux/generic/backport-4.14/323-netfilter-flow-table-support-for-IPv4.patch rename to target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch diff --git a/target/linux/generic/backport-4.14/324-netfilter-flow-table-support-for-IPv6.patch b/target/linux/generic/backport-4.14/324-v4.16-netfilter-flow-table-support-for-IPv6.patch similarity index 100% rename from target/linux/generic/backport-4.14/324-netfilter-flow-table-support-for-IPv6.patch rename to target/linux/generic/backport-4.14/324-v4.16-netfilter-flow-table-support-for-IPv6.patch diff --git a/target/linux/generic/backport-4.14/325-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch b/target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch similarity index 100% rename from target/linux/generic/backport-4.14/325-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch rename to target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch diff --git a/target/linux/generic/backport-4.14/326-netfilter-nf_tables-flow-offload-expression.patch b/target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch similarity index 100% rename from target/linux/generic/backport-4.14/326-netfilter-nf_tables-flow-offload-expression.patch rename to target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch diff --git a/target/linux/generic/backport-4.14/327-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch b/target/linux/generic/backport-4.14/327-v4.16-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch similarity index 100% rename from target/linux/generic/backport-4.14/327-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch rename to target/linux/generic/backport-4.14/327-v4.16-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch diff --git a/target/linux/generic/backport-4.14/328-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch b/target/linux/generic/backport-4.14/328-v4.16-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch similarity index 100% rename from target/linux/generic/backport-4.14/328-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch rename to target/linux/generic/backport-4.14/328-v4.16-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch diff --git a/target/linux/generic/backport-4.14/329-netfilter-improve-flow-table-Kconfig-dependencies.patch b/target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch similarity index 100% rename from target/linux/generic/backport-4.14/329-netfilter-improve-flow-table-Kconfig-dependencies.patch rename to target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch diff --git a/target/linux/generic/backport-4.14/330-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch b/target/linux/generic/backport-4.14/330-v4.16-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch similarity index 100% rename from target/linux/generic/backport-4.14/330-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch rename to target/linux/generic/backport-4.14/330-v4.16-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch diff --git a/target/linux/generic/backport-4.14/331-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch b/target/linux/generic/backport-4.14/331-v4.16-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch similarity index 100% rename from target/linux/generic/backport-4.14/331-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch rename to target/linux/generic/backport-4.14/331-v4.16-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch diff --git a/target/linux/generic/backport-4.14/332-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch b/target/linux/generic/backport-4.14/332-v4.16-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch similarity index 100% rename from target/linux/generic/backport-4.14/332-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch rename to target/linux/generic/backport-4.14/332-v4.16-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch diff --git a/target/linux/generic/backport-4.14/334-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch b/target/linux/generic/backport-4.14/334-v4.15-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch similarity index 100% rename from target/linux/generic/backport-4.14/334-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch rename to target/linux/generic/backport-4.14/334-v4.15-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch diff --git a/target/linux/generic/backport-4.14/335-netfilter-nf_tables-add-single-table-list-for-all-fa.patch b/target/linux/generic/backport-4.14/335-v4.16-netfilter-nf_tables-add-single-table-list-for-all-fa.patch similarity index 100% rename from target/linux/generic/backport-4.14/335-netfilter-nf_tables-add-single-table-list-for-all-fa.patch rename to target/linux/generic/backport-4.14/335-v4.16-netfilter-nf_tables-add-single-table-list-for-all-fa.patch diff --git a/target/linux/generic/backport-4.14/336-netfilter-exit_net-cleanup-check-added.patch b/target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch similarity index 100% rename from target/linux/generic/backport-4.14/336-netfilter-exit_net-cleanup-check-added.patch rename to target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch diff --git a/target/linux/generic/backport-4.14/337-netfilter-nf_tables-get-rid-of-pernet-families.patch b/target/linux/generic/backport-4.14/337-v4.16-netfilter-nf_tables-get-rid-of-pernet-families.patch similarity index 100% rename from target/linux/generic/backport-4.14/337-netfilter-nf_tables-get-rid-of-pernet-families.patch rename to target/linux/generic/backport-4.14/337-v4.16-netfilter-nf_tables-get-rid-of-pernet-families.patch diff --git a/target/linux/generic/backport-4.14/338-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch b/target/linux/generic/backport-4.14/338-v4.16-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch similarity index 100% rename from target/linux/generic/backport-4.14/338-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch rename to target/linux/generic/backport-4.14/338-v4.16-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch diff --git a/target/linux/generic/backport-4.14/339-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch b/target/linux/generic/backport-4.14/339-v4.16-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch similarity index 100% rename from target/linux/generic/backport-4.14/339-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch rename to target/linux/generic/backport-4.14/339-v4.16-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch diff --git a/target/linux/generic/backport-4.14/340-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch b/target/linux/generic/backport-4.14/340-v4.16-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch similarity index 100% rename from target/linux/generic/backport-4.14/340-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch rename to target/linux/generic/backport-4.14/340-v4.16-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch diff --git a/target/linux/generic/backport-4.14/341-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch b/target/linux/generic/backport-4.14/341-v4.16-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch similarity index 100% rename from target/linux/generic/backport-4.14/341-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch rename to target/linux/generic/backport-4.14/341-v4.16-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch diff --git a/target/linux/generic/backport-4.14/342-netfilter-nf_tables-fix-flowtable-free.patch b/target/linux/generic/backport-4.14/342-v4.16-netfilter-nf_tables-fix-flowtable-free.patch similarity index 100% rename from target/linux/generic/backport-4.14/342-netfilter-nf_tables-fix-flowtable-free.patch rename to target/linux/generic/backport-4.14/342-v4.16-netfilter-nf_tables-fix-flowtable-free.patch diff --git a/target/linux/generic/backport-4.14/344-netfilter-nf_tables-allocate-handle-and-delete-objec.patch b/target/linux/generic/backport-4.14/344-v4.16-netfilter-nf_tables-allocate-handle-and-delete-objec.patch similarity index 100% rename from target/linux/generic/backport-4.14/344-netfilter-nf_tables-allocate-handle-and-delete-objec.patch rename to target/linux/generic/backport-4.14/344-v4.16-netfilter-nf_tables-allocate-handle-and-delete-objec.patch diff --git a/target/linux/generic/backport-4.14/345-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch b/target/linux/generic/backport-4.14/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch similarity index 100% rename from target/linux/generic/backport-4.14/345-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch rename to target/linux/generic/backport-4.14/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch diff --git a/target/linux/generic/backport-4.14/346-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch b/target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch similarity index 100% rename from target/linux/generic/backport-4.14/346-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch rename to target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch diff --git a/target/linux/generic/backport-4.14/347-netfilter-remove-duplicated-include.patch b/target/linux/generic/backport-4.14/347-v4.16-netfilter-remove-duplicated-include.patch similarity index 100% rename from target/linux/generic/backport-4.14/347-netfilter-remove-duplicated-include.patch rename to target/linux/generic/backport-4.14/347-v4.16-netfilter-remove-duplicated-include.patch diff --git a/target/linux/generic/backport-4.14/348-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch b/target/linux/generic/backport-4.14/348-v4.18-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch similarity index 100% rename from target/linux/generic/backport-4.14/348-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch rename to target/linux/generic/backport-4.14/348-v4.18-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch diff --git a/target/linux/generic/backport-4.14/349-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch b/target/linux/generic/backport-4.14/349-v4.18-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch similarity index 100% rename from target/linux/generic/backport-4.14/349-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch rename to target/linux/generic/backport-4.14/349-v4.18-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch diff --git a/target/linux/generic/backport-4.14/350-ipv6-make-ip6_dst_mtu_forward-inline.patch b/target/linux/generic/backport-4.14/350-v4.18-ipv6-make-ip6_dst_mtu_forward-inline.patch similarity index 100% rename from target/linux/generic/backport-4.14/350-ipv6-make-ip6_dst_mtu_forward-inline.patch rename to target/linux/generic/backport-4.14/350-v4.18-ipv6-make-ip6_dst_mtu_forward-inline.patch diff --git a/target/linux/generic/backport-4.14/351-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch b/target/linux/generic/backport-4.14/351-v4.18-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch similarity index 100% rename from target/linux/generic/backport-4.14/351-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch rename to target/linux/generic/backport-4.14/351-v4.18-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch diff --git a/target/linux/generic/backport-4.14/352-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch b/target/linux/generic/backport-4.14/352-v4.18-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch similarity index 100% rename from target/linux/generic/backport-4.14/352-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch rename to target/linux/generic/backport-4.14/352-v4.18-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch diff --git a/target/linux/generic/backport-4.14/353-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch b/target/linux/generic/backport-4.14/353-v4.18-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch similarity index 100% rename from target/linux/generic/backport-4.14/353-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch rename to target/linux/generic/backport-4.14/353-v4.18-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch diff --git a/target/linux/generic/backport-4.14/354-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch b/target/linux/generic/backport-4.14/354-v4.18-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch similarity index 100% rename from target/linux/generic/backport-4.14/354-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch rename to target/linux/generic/backport-4.14/354-v4.18-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch diff --git a/target/linux/generic/backport-4.14/355-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch b/target/linux/generic/backport-4.14/355-v4.18-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch similarity index 100% rename from target/linux/generic/backport-4.14/355-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch rename to target/linux/generic/backport-4.14/355-v4.18-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch diff --git a/target/linux/generic/backport-4.14/356-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch b/target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch similarity index 100% rename from target/linux/generic/backport-4.14/356-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch rename to target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch diff --git a/target/linux/generic/backport-4.14/357-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch b/target/linux/generic/backport-4.14/357-v4.18-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch similarity index 100% rename from target/linux/generic/backport-4.14/357-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch rename to target/linux/generic/backport-4.14/357-v4.18-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch diff --git a/target/linux/generic/backport-4.14/358-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch b/target/linux/generic/backport-4.14/358-v4.18-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch similarity index 100% rename from target/linux/generic/backport-4.14/358-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch rename to target/linux/generic/backport-4.14/358-v4.18-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch diff --git a/target/linux/generic/backport-4.14/359-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch b/target/linux/generic/backport-4.14/359-v4.18-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch similarity index 100% rename from target/linux/generic/backport-4.14/359-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch rename to target/linux/generic/backport-4.14/359-v4.18-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch diff --git a/target/linux/generic/backport-4.14/360-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch b/target/linux/generic/backport-4.14/360-v4.18-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch similarity index 100% rename from target/linux/generic/backport-4.14/360-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch rename to target/linux/generic/backport-4.14/360-v4.18-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch diff --git a/target/linux/generic/backport-4.14/361-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch b/target/linux/generic/backport-4.14/361-v4.18-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch similarity index 100% rename from target/linux/generic/backport-4.14/361-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch rename to target/linux/generic/backport-4.14/361-v4.18-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch diff --git a/target/linux/generic/backport-4.14/362-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch b/target/linux/generic/backport-4.14/362-v4.18-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch similarity index 100% rename from target/linux/generic/backport-4.14/362-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch rename to target/linux/generic/backport-4.14/362-v4.18-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch diff --git a/target/linux/generic/backport-4.14/363-netfilter-nf_flow_table-add-support-for-sending-flow.patch b/target/linux/generic/backport-4.14/363-v4.18-netfilter-nf_flow_table-add-support-for-sending-flow.patch similarity index 100% rename from target/linux/generic/backport-4.14/363-netfilter-nf_flow_table-add-support-for-sending-flow.patch rename to target/linux/generic/backport-4.14/363-v4.18-netfilter-nf_flow_table-add-support-for-sending-flow.patch diff --git a/target/linux/generic/backport-4.14/364-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch b/target/linux/generic/backport-4.14/364-v4.18-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch similarity index 100% rename from target/linux/generic/backport-4.14/364-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch rename to target/linux/generic/backport-4.14/364-v4.18-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch diff --git a/target/linux/generic/backport-4.14/365-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch b/target/linux/generic/backport-4.14/365-v4.16-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch similarity index 100% rename from target/linux/generic/backport-4.14/365-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch rename to target/linux/generic/backport-4.14/365-v4.16-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch diff --git a/target/linux/generic/backport-4.14/367-netfilter-nf_flow_table-add-missing-condition-for-TC.patch b/target/linux/generic/backport-4.14/367-v4.18-netfilter-nf_flow_table-add-missing-condition-for-TC.patch similarity index 100% rename from target/linux/generic/backport-4.14/367-netfilter-nf_flow_table-add-missing-condition-for-TC.patch rename to target/linux/generic/backport-4.14/367-v4.18-netfilter-nf_flow_table-add-missing-condition-for-TC.patch diff --git a/target/linux/generic/backport-4.14/368-netfilter-nf_flow_table-fix-offloading-connections-w.patch b/target/linux/generic/backport-4.14/368-v4.18-netfilter-nf_flow_table-fix-offloading-connections-w.patch similarity index 100% rename from target/linux/generic/backport-4.14/368-netfilter-nf_flow_table-fix-offloading-connections-w.patch rename to target/linux/generic/backport-4.14/368-v4.18-netfilter-nf_flow_table-fix-offloading-connections-w.patch diff --git a/target/linux/generic/config-4.14 b/target/linux/generic/config-4.14 index 1ea2feb30..aa227ec6b 100644 --- a/target/linux/generic/config-4.14 +++ b/target/linux/generic/config-4.14 @@ -262,6 +262,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARCH_VT8500 is not set # CONFIG_ARCH_VULCAN is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_WANTS_THP_SWAP is not set # CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set # CONFIG_ARCH_WM8505 is not set # CONFIG_ARCH_WM8750 is not set @@ -1116,7 +1117,9 @@ CONFIG_DEVPORT=y # CONFIG_DMA_API_DEBUG is not set # CONFIG_DMA_ENGINE is not set # CONFIG_DMA_FENCE_TRACE is not set +# CONFIG_DMA_NOOP_OPS is not set # CONFIG_DMA_SHARED_BUFFER is not set +# CONFIG_DMA_VIRT_OPS is not set # CONFIG_DM_CACHE is not set # CONFIG_DM_DEBUG is not set # CONFIG_DM_DELAY is not set @@ -1167,6 +1170,7 @@ CONFIG_DQL=y # CONFIG_DRM_I2C_NXP_TDA998X is not set # CONFIG_DRM_I2C_SIL164 is not set # CONFIG_DRM_LEGACY is not set +# CONFIG_DRM_LIB_RANDOM is not set # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set # CONFIG_DRM_LVDS_ENCODER is not set # CONFIG_DRM_MALI_DISPLAY is not set @@ -1268,7 +1272,7 @@ CONFIG_ETHERNET=y # CONFIG_ETHOC is not set CONFIG_EVENTFD=y CONFIG_EXPERT=y -# CONFIG_EXPORTFS is not set +CONFIG_EXPORTFS=y # CONFIG_EXPORTFS_BLOCK_OPS is not set # CONFIG_EXT2_FS is not set # CONFIG_EXT2_FS_XATTR is not set @@ -1442,6 +1446,7 @@ CONFIG_FSNOTIFY=y # CONFIG_FUSION_SAS is not set # CONFIG_FUSION_SPI is not set CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y # CONFIG_FW_CFG_SYSFS is not set CONFIG_FW_LOADER=y CONFIG_FW_LOADER_USER_HELPER=y @@ -1535,7 +1540,6 @@ CONFIG_GENERIC_NET_UTILS=y # CONFIG_HAMRADIO is not set # CONFIG_HAPPYMEAL is not set # CONFIG_HARDENED_USERCOPY is not set -# CONFIG_HARDEN_BRANCH_PREDICTOR is not set # CONFIG_HARDLOCKUP_DETECTOR is not set # CONFIG_HAVE_AOUT is not set CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y @@ -4000,7 +4004,7 @@ CONFIG_SCSI_PROC_FS=y CONFIG_SECTION_MISMATCH_WARN_ONLY=y # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY_DMESG_RESTRICT=y CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ABITUGURU3 is not set @@ -4854,6 +4858,7 @@ CONFIG_TEXTSEARCH=y # CONFIG_THERMAL_HWMON is not set # CONFIG_THERMAL_WRITABLE_TRIPS is not set # CONFIG_THINKPAD_ACPI is not set +CONFIG_THIN_ARCHIVES=y # CONFIG_THRUSTMASTER_FF is not set # CONFIG_THUNDERBOLT is not set # CONFIG_THUNDER_NIC_BGX is not set @@ -5022,7 +5027,6 @@ CONFIG_UNIX=y CONFIG_UNIX98_PTYS=y # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_UNIX_DIAG is not set -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_UPROBES is not set # CONFIG_UPROBE_EVENT is not set diff --git a/target/linux/generic/pending-4.14/103-MIPS-c-r4k-fix-data-corruption-related-to-cache-coherence.patch b/target/linux/generic/pending-4.14/103-MIPS-c-r4k-fix-data-corruption-related-to-cache-coherence.patch new file mode 100644 index 000000000..69d926bd5 --- /dev/null +++ b/target/linux/generic/pending-4.14/103-MIPS-c-r4k-fix-data-corruption-related-to-cache-coherence.patch @@ -0,0 +1,90 @@ +From patchwork Thu Apr 26 23:28:34 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v2] MIPS: c-r4k: fix data corruption related to cache coherence. +X-Patchwork-Submitter: NeilBrown +X-Patchwork-Id: 19259 +Message-Id: <87vacdlf8d.fsf@notabene.neil.brown.name> +To: James Hogan +Cc: Ralf Baechle , + Paul Burton , linux-mips@linux-mips.org, + linux-kernel@vger.kernel.org +Date: Fri, 27 Apr 2018 09:28:34 +1000 +From: NeilBrown +List-Id: linux-mips + +When DMA will be performed to a MIPS32 1004K CPS, the +L1-cache for the range needs to be flushed and invalidated +first. +The code currently takes one of two approaches. +1/ If the range is less than the size of the dcache, then + HIT type requests flush/invalidate cache lines for the + particular addresses. HIT-type requests a globalised + by the CPS so this is safe on SMP. + +2/ If the range is larger than the size of dcache, then + INDEX type requests flush/invalidate the whole cache. + INDEX type requests affect the local cache only. CPS + does not propagate them in any way. So this invalidation + is not safe on SMP CPS systems. + +Data corruption due to '2' can quite easily be demonstrated by +repeatedly "echo 3 > /proc/sys/vm/drop_caches" and then sha1sum +a file that is several times the size of available memory. +Dropping caches means that large contiguous extents (large than +dcache) are more likely. + +This was not a problem before Linux-4.8 because option 2 was +never used if CONFIG_MIPS_CPS was defined. The commit +which removed that apparently didn't appreciate the full +consequence of the change. + +We could, in theory, globalize the INDEX based flush by sending an IPI +to other cores. These cache invalidation routines can be called with +interrupts disabled and synchronous IPI require interrupts to be +enabled. Asynchronous IPI may not trigger writeback soon enough. +So we cannot use IPI in practice. + +We can already test is IPI would be needed for an INDEX operation +with r4k_op_needs_ipi(R4K_INDEX). If this is True then we mustn't try +the INDEX approach as we cannot use IPI. If this is False (e.g. when +there is only one core and hence one L1 cache) then it is safe to +use the INDEX approach without IPI. + +This patch avoids options 2 if r4k_op_needs_ipi(R4K_INDEX), and so +eliminates the corruption. + +Fixes: c00ab4896ed5 ("MIPS: Remove cpu_has_safe_index_cacheops") +Cc: stable@vger.kernel.org # v4.8+ +Signed-off-by: NeilBrown +--- + arch/mips/mm/c-r4k.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/arch/mips/mm/c-r4k.c ++++ b/arch/mips/mm/c-r4k.c +@@ -851,9 +851,12 @@ static void r4k_dma_cache_wback_inv(unsi + /* + * Either no secondary cache or the available caches don't have the + * subset property so we have to flush the primary caches +- * explicitly ++ * explicitly. ++ * If we would need IPI to perform an INDEX-type operation, then ++ * we have to use the HIT-type alternative as IPI cannot be used ++ * here due to interrupts possibly being disabled. + */ +- if (size >= dcache_size) { ++ if (!r4k_op_needs_ipi(R4K_INDEX) && size >= dcache_size) { + r4k_blast_dcache(); + } else { + R4600_HIT_CACHEOP_WAR_IMPL; +@@ -890,7 +893,7 @@ static void r4k_dma_cache_inv(unsigned l + return; + } + +- if (size >= dcache_size) { ++ if (!r4k_op_needs_ipi(R4K_INDEX) && size >= dcache_size) { + r4k_blast_dcache(); + } else { + R4600_HIT_CACHEOP_WAR_IMPL; diff --git a/target/linux/generic/pending-4.14/161-mtd-part-add-generic-parsing-of-linux-part-probe.patch b/target/linux/generic/pending-4.14/161-mtd-part-add-generic-parsing-of-linux-part-probe.patch index 6379ff33f..0e858d93b 100644 --- a/target/linux/generic/pending-4.14/161-mtd-part-add-generic-parsing-of-linux-part-probe.patch +++ b/target/linux/generic/pending-4.14/161-mtd-part-add-generic-parsing-of-linux-part-probe.patch @@ -104,7 +104,7 @@ Signed-off-by: Hauke Mehrtens #include #include -@@ -864,6 +865,32 @@ void deregister_mtd_parser(struct mtd_pa +@@ -851,6 +852,32 @@ void deregister_mtd_parser(struct mtd_pa EXPORT_SYMBOL_GPL(deregister_mtd_parser); /* @@ -137,8 +137,8 @@ Signed-off-by: Hauke Mehrtens * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you * are changing this array! */ -@@ -1007,6 +1034,13 @@ int parse_mtd_partitions(struct mtd_info - { +@@ -991,6 +1018,13 @@ int parse_mtd_partitions(struct mtd_info + struct mtd_partitions pparts = { }; struct mtd_part_parser *parser; int ret, err = 0; + const char *const *types_of = NULL; @@ -151,7 +151,7 @@ Signed-off-by: Hauke Mehrtens if (!types) types = default_mtd_part_types; -@@ -1043,6 +1077,7 @@ int parse_mtd_partitions(struct mtd_info +@@ -1031,6 +1065,7 @@ int parse_mtd_partitions(struct mtd_info if (ret < 0 && !err) err = ret; } diff --git a/target/linux/generic/pending-4.14/400-mtd-add-rootfs-split-support.patch b/target/linux/generic/pending-4.14/400-mtd-add-rootfs-split-support.patch index e722d8ca9..bc2272d26 100644 --- a/target/linux/generic/pending-4.14/400-mtd-add-rootfs-split-support.patch +++ b/target/linux/generic/pending-4.14/400-mtd-add-rootfs-split-support.patch @@ -60,7 +60,7 @@ Signed-off-by: Felix Fietkau /* * Given a pointer to the MTD object in the mtd_part structure, we can retrieve * the pointer to that structure. -@@ -687,6 +691,7 @@ int mtd_add_partition(struct mtd_info *p +@@ -674,6 +678,7 @@ int mtd_add_partition(struct mtd_info *p mutex_unlock(&mtd_partitions_mutex); add_mtd_device(&new->mtd); @@ -68,7 +68,7 @@ Signed-off-by: Felix Fietkau mtd_add_partition_attrs(new); -@@ -765,6 +770,35 @@ int mtd_del_partition(struct mtd_info *m +@@ -752,6 +757,35 @@ int mtd_del_partition(struct mtd_info *m } EXPORT_SYMBOL_GPL(mtd_del_partition); @@ -104,7 +104,7 @@ Signed-off-by: Felix Fietkau /* * This function, given a master MTD object and a partition table, creates * and registers slave MTD objects which are bound to the master according to -@@ -796,6 +830,7 @@ int add_mtd_partitions(struct mtd_info * +@@ -783,6 +817,7 @@ int add_mtd_partitions(struct mtd_info * mutex_unlock(&mtd_partitions_mutex); add_mtd_device(&slave->mtd); diff --git a/target/linux/generic/pending-4.14/401-mtd-add-support-for-different-partition-parser-types.patch b/target/linux/generic/pending-4.14/401-mtd-add-support-for-different-partition-parser-types.patch index 182d8d474..7cb336bd1 100644 --- a/target/linux/generic/pending-4.14/401-mtd-add-support-for-different-partition-parser-types.patch +++ b/target/linux/generic/pending-4.14/401-mtd-add-support-for-different-partition-parser-types.patch @@ -9,7 +9,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c -@@ -1132,6 +1132,62 @@ void mtd_part_parser_cleanup(struct mtd_ +@@ -1120,6 +1120,62 @@ void mtd_part_parser_cleanup(struct mtd_ } } diff --git a/target/linux/generic/pending-4.14/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch b/target/linux/generic/pending-4.14/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch index 26a19b82f..cfd178e42 100644 --- a/target/linux/generic/pending-4.14/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch +++ b/target/linux/generic/pending-4.14/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c -@@ -770,6 +770,36 @@ int mtd_del_partition(struct mtd_info *m +@@ -757,6 +757,36 @@ int mtd_del_partition(struct mtd_info *m } EXPORT_SYMBOL_GPL(mtd_del_partition); @@ -47,7 +47,7 @@ Signed-off-by: Gabor Juhos #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME #else -@@ -778,6 +808,7 @@ EXPORT_SYMBOL_GPL(mtd_del_partition); +@@ -765,6 +795,7 @@ EXPORT_SYMBOL_GPL(mtd_del_partition); static void split_firmware(struct mtd_info *master, struct mtd_part *part) { @@ -55,7 +55,7 @@ Signed-off-by: Gabor Juhos } void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, -@@ -792,6 +823,12 @@ static void mtd_partition_split(struct m +@@ -779,6 +810,12 @@ static void mtd_partition_split(struct m if (rootfs_found) return; diff --git a/target/linux/generic/pending-4.14/404-mtd-add-more-helper-functions.patch b/target/linux/generic/pending-4.14/404-mtd-add-more-helper-functions.patch index 9b2fcac93..98732e4c8 100644 --- a/target/linux/generic/pending-4.14/404-mtd-add-more-helper-functions.patch +++ b/target/linux/generic/pending-4.14/404-mtd-add-more-helper-functions.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c -@@ -800,6 +800,17 @@ run_parsers_by_type(struct mtd_part *sla +@@ -787,6 +787,17 @@ run_parsers_by_type(struct mtd_part *sla return nr_parts; } @@ -29,7 +29,7 @@ Signed-off-by: Gabor Juhos #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME #else -@@ -1242,6 +1253,24 @@ int mtd_is_partition(const struct mtd_in +@@ -1230,6 +1241,24 @@ int mtd_is_partition(const struct mtd_in } EXPORT_SYMBOL_GPL(mtd_is_partition); diff --git a/target/linux/generic/pending-4.14/411-mtd-partial_eraseblock_write.patch b/target/linux/generic/pending-4.14/411-mtd-partial_eraseblock_write.patch index 9de5fd263..2fcaec52d 100644 --- a/target/linux/generic/pending-4.14/411-mtd-partial_eraseblock_write.patch +++ b/target/linux/generic/pending-4.14/411-mtd-partial_eraseblock_write.patch @@ -107,7 +107,7 @@ Signed-off-by: Felix Fietkau if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) instr->fail_addr -= part->offset; -@@ -599,19 +668,22 @@ static struct mtd_part *allocate_partiti +@@ -586,19 +655,22 @@ static struct mtd_part *allocate_partiti remainder = do_div(tmp, wr_alignment); if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { /* Doesn't start on a boundary of major erase size */ diff --git a/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh32.patch b/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh32.patch new file mode 100644 index 000000000..b8d510151 --- /dev/null +++ b/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh32.patch @@ -0,0 +1,10 @@ +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -955,6 +955,7 @@ static const struct flash_info spi_nor_i + { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, + { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, + { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) }, ++ { "en25qh32", INFO(0x1c7016, 0, 64 * 1024, 64, 0) }, + { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, + { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, + { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, diff --git a/target/linux/generic/pending-4.14/642-net-8021q-support-hardware-flow-table-offload.patch b/target/linux/generic/pending-4.14/642-net-8021q-support-hardware-flow-table-offload.patch index ca340fc8e..0d6eab16f 100644 --- a/target/linux/generic/pending-4.14/642-net-8021q-support-hardware-flow-table-offload.patch +++ b/target/linux/generic/pending-4.14/642-net-8021q-support-hardware-flow-table-offload.patch @@ -9,22 +9,22 @@ Signed-off-by: Felix Fietkau --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c -@@ -29,9 +29,11 @@ - #include - #include - #include -+#include +@@ -32,6 +32,10 @@ #include #include #include ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) ++#include +#include ++#endif #include "vlan.h" #include "vlanproc.h" -@@ -766,6 +768,25 @@ static int vlan_dev_get_iflink(const str +@@ -766,6 +770,27 @@ static int vlan_dev_get_iflink(const str return real_dev->ifindex; } ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +static int vlan_dev_flow_offload_check(struct flow_offload_hw_path *path) +{ + struct net_device *dev = path->dev; @@ -43,15 +43,18 @@ Signed-off-by: Felix Fietkau + + return 0; +} ++#endif /* CONFIG_NF_FLOW_TABLE */ + static const struct ethtool_ops vlan_ethtool_ops = { .get_link_ksettings = vlan_ethtool_get_link_ksettings, .get_drvinfo = vlan_ethtool_get_drvinfo, -@@ -803,6 +824,7 @@ static const struct net_device_ops vlan_ +@@ -803,6 +828,9 @@ static const struct net_device_ops vlan_ .ndo_fix_features = vlan_dev_fix_features, .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, .ndo_get_iflink = vlan_dev_get_iflink, ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) + .ndo_flow_offload_check = vlan_dev_flow_offload_check, ++#endif }; static void vlan_dev_free(struct net_device *dev) diff --git a/target/linux/generic/pending-4.14/643-net-bridge-support-hardware-flow-table-offload.patch b/target/linux/generic/pending-4.14/643-net-bridge-support-hardware-flow-table-offload.patch index 3158714f5..a070fe163 100644 --- a/target/linux/generic/pending-4.14/643-net-bridge-support-hardware-flow-table-offload.patch +++ b/target/linux/generic/pending-4.14/643-net-bridge-support-hardware-flow-table-offload.patch @@ -9,19 +9,22 @@ Signed-off-by: Felix Fietkau --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c -@@ -18,6 +18,8 @@ +@@ -18,6 +18,10 @@ #include #include #include ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +#include +#include ++#endif #include #include "br_private.h" -@@ -340,6 +342,26 @@ static const struct ethtool_ops br_ethto +@@ -340,6 +344,28 @@ static const struct ethtool_ops br_ethto .get_link = ethtool_op_get_link, }; ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +static int br_flow_offload_check(struct flow_offload_hw_path *path) +{ + struct net_device *dev = path->dev; @@ -41,15 +44,18 @@ Signed-off-by: Felix Fietkau + + return 0; +} ++#endif /* CONFIG_NF_FLOW_TABLE */ + static const struct net_device_ops br_netdev_ops = { .ndo_open = br_dev_open, .ndo_stop = br_dev_stop, -@@ -367,6 +389,7 @@ static const struct net_device_ops br_ne +@@ -367,6 +393,9 @@ static const struct net_device_ops br_ne .ndo_bridge_setlink = br_setlink, .ndo_bridge_dellink = br_dellink, .ndo_features_check = passthru_features_check, ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) + .ndo_flow_offload_check = br_flow_offload_check, ++#endif }; static struct device_type br_type = { diff --git a/target/linux/generic/pending-4.14/644-net-pppoe-support-hardware-flow-table-offload.patch b/target/linux/generic/pending-4.14/644-net-pppoe-support-hardware-flow-table-offload.patch index 9565412c0..935b79d1d 100644 --- a/target/linux/generic/pending-4.14/644-net-pppoe-support-hardware-flow-table-offload.patch +++ b/target/linux/generic/pending-4.14/644-net-pppoe-support-hardware-flow-table-offload.patch @@ -9,20 +9,23 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c -@@ -56,6 +56,9 @@ +@@ -56,6 +56,11 @@ #include #include ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +#include +#include ++#endif + #define PPP_VERSION "2.4.2" /* -@@ -1382,12 +1385,33 @@ static void ppp_dev_priv_destructor(stru +@@ -1382,12 +1387,37 @@ static void ppp_dev_priv_destructor(stru ppp_destroy_interface(ppp); } ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +static int ppp_flow_offload_check(struct flow_offload_hw_path *path) +{ + struct ppp *ppp = netdev_priv(path->dev); @@ -42,6 +45,7 @@ Signed-off-by: Felix Fietkau + + return chan->ops->flow_offload_check(chan, path); +} ++#endif /* CONFIG_NF_FLOW_TABLE */ + static const struct net_device_ops ppp_netdev_ops = { .ndo_init = ppp_dev_init, @@ -49,25 +53,31 @@ Signed-off-by: Felix Fietkau .ndo_start_xmit = ppp_start_xmit, .ndo_do_ioctl = ppp_net_ioctl, .ndo_get_stats64 = ppp_get_stats64, ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) + .ndo_flow_offload_check = ppp_flow_offload_check, ++#endif }; static struct device_type ppp_type = { --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c -@@ -77,6 +77,8 @@ - #include +@@ -78,6 +78,11 @@ #include #include + ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +#include +#include - ++#endif ++ #include #include -@@ -970,8 +972,32 @@ static int pppoe_xmit(struct ppp_channel + #include +@@ -974,8 +979,36 @@ static int pppoe_xmit(struct ppp_channel return __pppoe_xmit(sk, skb); } ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) +static int pppoe_flow_offload_check(struct ppp_channel *chan, + struct flow_offload_hw_path *path) +{ @@ -90,21 +100,26 @@ Signed-off-by: Felix Fietkau + + return 0; +} ++#endif /* CONFIG_NF_FLOW_TABLE */ + static const struct ppp_channel_ops pppoe_chan_ops = { .start_xmit = pppoe_xmit, ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) + .flow_offload_check = pppoe_flow_offload_check, ++#endif }; static int pppoe_recvmsg(struct socket *sock, struct msghdr *m, --- a/include/linux/ppp_channel.h +++ b/include/linux/ppp_channel.h -@@ -32,6 +32,8 @@ struct ppp_channel_ops { +@@ -32,6 +32,10 @@ struct ppp_channel_ops { int (*start_xmit)(struct ppp_channel *, struct sk_buff *); /* Handle an ioctl call that has come in via /dev/ppp. */ int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long); + ++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) + int (*flow_offload_check)(struct ppp_channel *, struct flow_offload_hw_path *); ++#endif }; struct ppp_channel { diff --git a/target/linux/generic/pending-4.14/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-4.14/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch index 1ac009b65..45f387f26 100644 --- a/target/linux/generic/pending-4.14/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +++ b/target/linux/generic/pending-4.14/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch @@ -171,7 +171,7 @@ Signed-off-by: Jonas Gorski /* * Allocate a dst for local (unicast / anycast) address. */ -@@ -3000,7 +3033,8 @@ static int rtm_to_fib6_config(struct sk_ +@@ -3002,7 +3035,8 @@ static int rtm_to_fib6_config(struct sk_ if (rtm->rtm_type == RTN_UNREACHABLE || rtm->rtm_type == RTN_BLACKHOLE || rtm->rtm_type == RTN_PROHIBIT || @@ -181,7 +181,7 @@ Signed-off-by: Jonas Gorski cfg->fc_flags |= RTF_REJECT; if (rtm->rtm_type == RTN_LOCAL) -@@ -3490,6 +3524,9 @@ static int rt6_fill_node(struct net *net +@@ -3492,6 +3526,9 @@ static int rt6_fill_node(struct net *net case -EACCES: rtm->rtm_type = RTN_PROHIBIT; break; @@ -191,7 +191,7 @@ Signed-off-by: Jonas Gorski case -EAGAIN: rtm->rtm_type = RTN_THROW; break; -@@ -3808,6 +3845,8 @@ static int ip6_route_dev_notify(struct n +@@ -3810,6 +3847,8 @@ static int ip6_route_dev_notify(struct n #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.ip6_prohibit_entry->dst.dev = dev; net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); @@ -200,7 +200,15 @@ Signed-off-by: Jonas Gorski net->ipv6.ip6_blk_hole_entry->dst.dev = dev; net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); #endif -@@ -4035,6 +4074,17 @@ static int __net_init ip6_route_net_init +@@ -3821,6 +3860,7 @@ static int ip6_route_dev_notify(struct n + in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); ++ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev); + in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); + #endif + } +@@ -4037,6 +4077,17 @@ static int __net_init ip6_route_net_init net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, ip6_template_metrics, true); @@ -218,7 +226,7 @@ Signed-off-by: Jonas Gorski #endif net->ipv6.sysctl.flush_delay = 0; -@@ -4053,6 +4103,8 @@ out: +@@ -4055,6 +4106,8 @@ out: return ret; #ifdef CONFIG_IPV6_MULTIPLE_TABLES @@ -227,7 +235,7 @@ Signed-off-by: Jonas Gorski out_ip6_prohibit_entry: kfree(net->ipv6.ip6_prohibit_entry); out_ip6_null_entry: -@@ -4070,6 +4122,7 @@ static void __net_exit ip6_route_net_exi +@@ -4072,6 +4125,7 @@ static void __net_exit ip6_route_net_exi #ifdef CONFIG_IPV6_MULTIPLE_TABLES kfree(net->ipv6.ip6_prohibit_entry); kfree(net->ipv6.ip6_blk_hole_entry); @@ -235,7 +243,7 @@ Signed-off-by: Jonas Gorski #endif dst_entries_destroy(&net->ipv6.ip6_dst_ops); } -@@ -4143,6 +4196,9 @@ void __init ip6_route_init_special_entri +@@ -4145,6 +4199,9 @@ void __init ip6_route_init_special_entri init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network index b7e5fb6ff..3fc5e55df 100755 --- a/target/linux/ramips/base-files/etc/board.d/02_network +++ b/target/linux/ramips/base-files/etc/board.d/02_network @@ -44,6 +44,7 @@ ramips_setup_interfaces() all0256n-8M|\ all5002|\ all5003|\ + bocco|\ broadway|\ dcs-930|\ dcs-930l-b1|\ @@ -113,7 +114,8 @@ ramips_setup_interfaces() vr500|\ wf-2881|\ whr-g300n|\ - witi|\ + mqmaker,witi-256m|\ + mqmaker,witi-512m|\ wl-wn575a3|\ wndr3700v5|\ youku-yk1|\ @@ -208,6 +210,7 @@ ramips_setup_interfaces() ubnt-erx|\ ubnt-erx-sfp|\ ur-326n4g|\ + ravpower,wd03|\ wrtnode|\ wrtnode2p | \ wrtnode2r | \ diff --git a/target/linux/ramips/base-files/etc/diag.sh b/target/linux/ramips/base-files/etc/diag.sh index d84bdff3a..6a5177872 100644 --- a/target/linux/ramips/base-files/etc/diag.sh +++ b/target/linux/ramips/base-files/etc/diag.sh @@ -279,7 +279,8 @@ get_status_led() { status_led="$boardname:green:status" ;; w306r-v20|\ - witi|\ + mqmaker,witi-256m|\ + mqmaker,witi-512m|\ zbt-wr8305rt) status_led="$boardname:green:sys" ;; diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh index 75474fbc6..edccfcd4a 100755 --- a/target/linux/ramips/base-files/lib/ramips.sh +++ b/target/linux/ramips/base-files/lib/ramips.sh @@ -76,6 +76,9 @@ ramips_board_detect() { *"BC2") name="bc2" ;; + *"BOCCO") + name="bocco" + ;; *"BR-6475nD") name="br-6475nd" ;; @@ -577,9 +580,6 @@ ramips_board_detect() { *"WHR-G300N") name="whr-g300n" ;; - *"WiTi") - name="witi" - ;; *"WIZARD 8800") name="wizard8800" ;; diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh index 0a43f2992..7aa14770c 100755 --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh @@ -31,6 +31,7 @@ platform_check_image() { awm002-evb-4M|\ awm002-evb-8M|\ bc2|\ + bocco|\ broadway|\ c108|\ carambola|\ @@ -165,6 +166,7 @@ platform_check_image() { w2914nsv2|\ w306r-v20|\ w502u|\ + ravpower,wd03|\ wf-2881|\ whr-1166d|\ whr-300hp2|\ @@ -172,7 +174,8 @@ platform_check_image() { whr-g300n|\ widora,neo-16m|\ widora,neo-32m|\ - witi|\ + mqmaker,witi-256m|\ + mqmaker,witi-512m|\ wizfi630a|\ wl-330n|\ wl-330n3g|\ diff --git a/target/linux/ramips/base-files/sbin/fixup-mac-address b/target/linux/ramips/base-files/sbin/fixup-mac-address index 98264c082..309db8ce4 100755 --- a/target/linux/ramips/base-files/sbin/fixup-mac-address +++ b/target/linux/ramips/base-files/sbin/fixup-mac-address @@ -9,7 +9,8 @@ YES= board=$(board_name) case $board in - witi) + mqmaker,witi-256m|\ + mqmaker,witi-512m) partname=factory offset=$((0xe000)) ;; diff --git a/target/linux/ramips/dts/BOCCO.dts b/target/linux/ramips/dts/BOCCO.dts new file mode 100644 index 000000000..96aab7bd0 --- /dev/null +++ b/target/linux/ramips/dts/BOCCO.dts @@ -0,0 +1,162 @@ +/dts-v1/; + +#include "mt7620a.dtsi" + +#include +#include + +/ { + compatible = "planex,cs-qr10", "ralink,mt7620a-soc"; + model = "YUKAI Engineering BOCCO"; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio_export { + compatible = "gpio-export"; + #size-cells = <0>; + + s1 { + gpio-export,name = "rec"; + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + }; + s2 { + gpio-export,name = "play"; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "Audio-I2S"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink0_master>; + simple-audio-card,frame-master = <&dailink0_master>; + simple-audio-card,widgets = + "Headphone", "Headphones"; + simple-audio-card,routing = + "Headphones", "HP_L", + "Headphones", "HP_R"; + simple-audio-card,mclk-fs = <256>; + + simple-audio-card,cpu { + sound-dai = <&i2s>; + }; + + dailink0_master: simple-audio-card,codec { + sound-dai = <&codec>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&i2c { + status = "okay"; + + codec: wm8960@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8960"; + reg = <0x1a>; + + wlf,shared-lrclk; + }; +}; + +&i2s { + #sound-dai-cells = <0>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pcm_i2s_pins>; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + label = "firmware"; + reg = <0x50000 0x7b0000>; + }; + }; +}; + +&pcm { + status = "okay"; +}; + +&gdma { + status = "okay"; +}; + +&pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "spi refclk", "rgmii1"; + ralink,function = "gpio"; + }; + }; +}; + +ðernet { + pinctrl-names = "default"; + pinctrl-0 = <&ephy_pins>; + mtd-mac-address = <&factory 0x4>; + mediatek,portmap = "llllw"; +}; + +&gsw { + ralink,port4 = "ephy"; +}; + +&wmac { + ralink,mtd-eeprom = <&factory 0>; +}; diff --git a/target/linux/ramips/dts/MT7628.dts b/target/linux/ramips/dts/MT7628.dts index dc86c7013..3bd172a05 100644 --- a/target/linux/ramips/dts/MT7628.dts +++ b/target/linux/ramips/dts/MT7628.dts @@ -15,7 +15,7 @@ &pinctrl { state_default: pinctrl0 { gpio { - ralink,group = "i2c", "jtag"; + ralink,group = "i2c"; ralink,function = "gpio"; }; }; diff --git a/target/linux/ramips/dts/WD03.dts b/target/linux/ramips/dts/WD03.dts new file mode 100644 index 000000000..454e757ce --- /dev/null +++ b/target/linux/ramips/dts/WD03.dts @@ -0,0 +1,112 @@ +/dts-v1/; + +#include "mt7620a.dtsi" + +#include +#include + +/ { + compatible = "ravpower,wd03", "ralink,mt7620a-soc"; + model = "Ravpower WD03"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + green-wifi { + label = "wd03:green:wifi"; + gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; + }; + + + blue-wifi { + label = "wd03:blue:wifi"; + gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + linux,code = ; + }; + }; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + label = "firmware"; + reg = <0x50000 0x7b0000>; + }; + }; +}; + +&ehci { + status = "okay"; +}; + +&ohci { + status = "okay"; +}; + +ðernet { + mtd-mac-address = <&factory 0x4000>; + ralink,port-map = "wllll"; +}; + +&wmac { + ralink,mtd-eeprom = <&factory 0>; +}; + +&pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "wled", "ephy"; + ralink,function = "gpio"; + }; + }; +}; diff --git a/target/linux/ramips/dts/WITI-256M.dts b/target/linux/ramips/dts/WITI-256M.dts new file mode 100644 index 000000000..4c12d8c3b --- /dev/null +++ b/target/linux/ramips/dts/WITI-256M.dts @@ -0,0 +1,13 @@ +/dts-v1/; + +#include "WITI.dtsi" + +/ { + compatible = "mqmaker,witi-256m", "mqmaker,witi", "mediatek,mt7621-soc"; + model = "MQmaker WiTi (256MB RAM)"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x10000000>; + }; +}; diff --git a/target/linux/ramips/dts/WITI-512M.dts b/target/linux/ramips/dts/WITI-512M.dts new file mode 100644 index 000000000..b24907553 --- /dev/null +++ b/target/linux/ramips/dts/WITI-512M.dts @@ -0,0 +1,13 @@ +/dts-v1/; + +#include "WITI.dtsi" + +/ { + compatible = "mqmaker,witi-512m", "mqmaker,witi", "mediatek,mt7621-soc"; + model = "MQmaker WiTi (512MB RAM)"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x1c000000>, <0x20000000 0x4000000>; + }; +}; diff --git a/target/linux/ramips/dts/WITI.dts b/target/linux/ramips/dts/WITI.dtsi similarity index 95% rename from target/linux/ramips/dts/WITI.dts rename to target/linux/ramips/dts/WITI.dtsi index 097c8163f..767ea03ff 100644 --- a/target/linux/ramips/dts/WITI.dts +++ b/target/linux/ramips/dts/WITI.dtsi @@ -7,12 +7,6 @@ / { compatible = "mqmaker,witi", "mediatek,mt7621-soc"; - model = "MQmaker WiTi"; - - memory@0 { - device_type = "memory"; - reg = <0x0 0x10000000>; - }; chosen { bootargs = "console=ttyS0,57600"; diff --git a/target/linux/ramips/dts/mt7620n.dtsi b/target/linux/ramips/dts/mt7620n.dtsi index 4eb1dde8a..91d124ca7 100644 --- a/target/linux/ramips/dts/mt7620n.dtsi +++ b/target/linux/ramips/dts/mt7620n.dtsi @@ -160,6 +160,22 @@ status = "disabled"; }; + i2c: i2c@900 { + compatible = "ralink,rt2880-i2c"; + reg = <0x900 0x100>; + + resets = <&rstctrl 16>; + reset-names = "i2c"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + pinctrl-names = "default"; + pinctrl-0 = <&i2c_pins>; + }; + spi0: spi@b00 { compatible = "ralink,mt7620a-spi", "ralink,rt2880-spi"; reg = <0xb00 0x40>; @@ -192,6 +208,13 @@ pinctrl-0 = <&spi_cs1>; }; + i2c_pins: i2c { + i2c { + ralink,group = "i2c"; + ralink,function = "i2c"; + }; + }; + uartlite: uartlite@c00 { compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a"; reg = <0xc00 0x100>; diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi index daca857f6..87399a113 100644 --- a/target/linux/ramips/dts/mt7621.dtsi +++ b/target/linux/ramips/dts/mt7621.dtsi @@ -440,10 +440,11 @@ 0x01000000 0 0x00000000 0x1e160000 0 0x00010000 /* io space */ >; - interrupt-parent = <&gic>; - interrupts = ; + #interrupt-cells = <1>; + interrupt-map-mask = <0xF0000 0 0 1>; + interrupt-map = <0x10000 0 0 1 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>, + <0x20000 0 0 1 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>, + <0x30000 0 0 1 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; diff --git a/target/linux/ramips/files-4.14/arch/mips/pci/pci-mt7621.c b/target/linux/ramips/files-4.14/arch/mips/pci/pci-mt7621.c new file mode 100644 index 000000000..edd95013f --- /dev/null +++ b/target/linux/ramips/files-4.14/arch/mips/pci/pci-mt7621.c @@ -0,0 +1,698 @@ +/************************************************************************** + * + * BRIEF MODULE DESCRIPTION + * PCI init for Ralink RT2880 solution + * + * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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. + * + * + ************************************************************************** + * May 2007 Bruce Chang + * Initial Release + * + * May 2009 Bruce Chang + * support RT2880/RT3883 PCIe + * + * May 2011 Bruce Chang + * support RT6855/MT7620 PCIe + * + ************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * These functions and structures provide the BIOS scan and mapping of the PCI + * devices. + */ + +#define RALINK_PCIE0_CLK_EN (1<<24) +#define RALINK_PCIE1_CLK_EN (1<<25) +#define RALINK_PCIE2_CLK_EN (1<<26) + +#define RALINK_PCI_CONFIG_ADDR 0x20 +#define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG 0x24 +#define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028) +#define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C) +#define RALINK_PCIE0_RST (1<<24) +#define RALINK_PCIE1_RST (1<<25) +#define RALINK_PCIE2_RST (1<<26) +#define RALINK_SYSCTL_BASE 0xBE000000 + +#define RALINK_PCI_PCICFG_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x0000) +#define RALINK_PCI_PCIMSK_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x000C) +#define RALINK_PCI_BASE 0xBE140000 + +#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) +#define RT6855_PCIE0_OFFSET 0x2000 +#define RT6855_PCIE1_OFFSET 0x3000 +#define RT6855_PCIE2_OFFSET 0x4000 + +#define RALINK_PCI0_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010) +#define RALINK_PCI0_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018) +#define RALINK_PCI0_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030) +#define RALINK_PCI0_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034) +#define RALINK_PCI0_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038) +#define RALINK_PCI0_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050) +#define RALINK_PCI0_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060) +#define RALINK_PCI0_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064) + +#define RALINK_PCI1_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010) +#define RALINK_PCI1_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018) +#define RALINK_PCI1_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030) +#define RALINK_PCI1_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034) +#define RALINK_PCI1_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038) +#define RALINK_PCI1_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050) +#define RALINK_PCI1_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060) +#define RALINK_PCI1_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064) + +#define RALINK_PCI2_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0010) +#define RALINK_PCI2_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0018) +#define RALINK_PCI2_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0030) +#define RALINK_PCI2_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0034) +#define RALINK_PCI2_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0038) +#define RALINK_PCI2_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0050) +#define RALINK_PCI2_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0060) +#define RALINK_PCI2_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0064) + +#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) +#define RALINK_PCIEPHY_P2_CTL_OFFSET (RALINK_PCI_BASE + 0xA000) + +#define MV_WRITE(ofs, data) \ + *(volatile u32 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le32(data) +#define MV_READ(ofs, data) \ + *(data) = le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs))) +#define MV_READ_DATA(ofs) \ + le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs))) + +#define MV_WRITE_16(ofs, data) \ + *(volatile u16 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le16(data) +#define MV_READ_16(ofs, data) \ + *(data) = le16_to_cpu(*(volatile u16 *)(RALINK_PCI_BASE+(ofs))) + +#define MV_WRITE_8(ofs, data) \ + *(volatile u8 *)(RALINK_PCI_BASE+(ofs)) = data +#define MV_READ_8(ofs, data) \ + *(data) = *(volatile u8 *)(RALINK_PCI_BASE+(ofs)) + +#define RALINK_PCI_MM_MAP_BASE 0x60000000 +#define RALINK_PCI_IO_MAP_BASE 0x1e160000 + +#define RALINK_SYSTEM_CONTROL_BASE 0xbe000000 + +#define ASSERT_SYSRST_PCIE(val) \ + do { \ + if (*(unsigned int *)(0xbe00000c) == 0x00030101) \ + RALINK_RSTCTRL |= val; \ + else \ + RALINK_RSTCTRL &= ~val; \ + } while(0) +#define DEASSERT_SYSRST_PCIE(val) \ + do { \ + if (*(unsigned int *)(0xbe00000c) == 0x00030101) \ + RALINK_RSTCTRL &= ~val; \ + else \ + RALINK_RSTCTRL |= val; \ + } while(0) +#define RALINK_SYSCFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x14) +#define RALINK_CLKCFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x30) +#define RALINK_RSTCTRL *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x34) +#define RALINK_GPIOMODE *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x60) +#define RALINK_PCIE_CLK_GEN *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x7c) +#define RALINK_PCIE_CLK_GEN1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x80) +#define PPLL_CFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x9c) +#define PPLL_DRV *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0xa0) +//RALINK_SYSCFG1 bit +#define RALINK_PCI_HOST_MODE_EN (1<<7) +#define RALINK_PCIE_RC_MODE_EN (1<<8) +//RALINK_RSTCTRL bit +#define RALINK_PCIE_RST (1<<23) +#define RALINK_PCI_RST (1<<24) +//RALINK_CLKCFG1 bit +#define RALINK_PCI_CLK_EN (1<<19) +#define RALINK_PCIE_CLK_EN (1<<21) +//RALINK_GPIOMODE bit +#define PCI_SLOTx2 (1<<11) +#define PCI_SLOTx1 (2<<11) +//MTK PCIE PLL bit +#define PDRV_SW_SET (1<<31) +#define LC_CKDRVPD_ (1<<19) + +#define MEMORY_BASE 0x0 +static int pcie_link_status = 0; + +#define PCI_ACCESS_READ_1 0 +#define PCI_ACCESS_READ_2 1 +#define PCI_ACCESS_READ_4 2 +#define PCI_ACCESS_WRITE_1 3 +#define PCI_ACCESS_WRITE_2 4 +#define PCI_ACCESS_WRITE_4 5 + +static int config_access(unsigned char access_type, struct pci_bus *bus, + unsigned int devfn, unsigned int where, u32 * data) +{ + unsigned int slot = PCI_SLOT(devfn); + u8 func = PCI_FUNC(devfn); + uint32_t address_reg, data_reg; + unsigned int address; + + address_reg = RALINK_PCI_CONFIG_ADDR; + data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG; + + address = (((where&0xF00)>>8)<<24) |(bus->number << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 0x80000000; + MV_WRITE(address_reg, address); + + switch(access_type) { + case PCI_ACCESS_WRITE_1: + MV_WRITE_8(data_reg+(where&0x3), *data); + break; + case PCI_ACCESS_WRITE_2: + MV_WRITE_16(data_reg+(where&0x3), *data); + break; + case PCI_ACCESS_WRITE_4: + MV_WRITE(data_reg, *data); + break; + case PCI_ACCESS_READ_1: + MV_READ_8( data_reg+(where&0x3), data); + break; + case PCI_ACCESS_READ_2: + MV_READ_16(data_reg+(where&0x3), data); + break; + case PCI_ACCESS_READ_4: + MV_READ(data_reg, data); + break; + default: + printk("no specify access type\n"); + break; + } + return 0; +} + +static int +read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val) +{ + return config_access(PCI_ACCESS_READ_1, bus, devfn, (unsigned int)where, (u32 *)val); +} + +static int +read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val) +{ + return config_access(PCI_ACCESS_READ_2, bus, devfn, (unsigned int)where, (u32 *)val); +} + +static int +read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val) +{ + return config_access(PCI_ACCESS_READ_4, bus, devfn, (unsigned int)where, (u32 *)val); +} + +static int +write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val) +{ + if (config_access(PCI_ACCESS_WRITE_1, bus, devfn, (unsigned int)where, (u32 *)&val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int +write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val) +{ + if (config_access(PCI_ACCESS_WRITE_2, bus, devfn, where, (u32 *)&val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int +write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val) +{ + if (config_access(PCI_ACCESS_WRITE_4, bus, devfn, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int +pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) +{ + switch (size) { + case 1: + return read_config_byte(bus, devfn, where, (u8 *) val); + case 2: + return read_config_word(bus, devfn, where, (u16 *) val); + default: + return read_config_dword(bus, devfn, where, val); + } +} + +static int +pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) +{ + switch (size) { + case 1: + return write_config_byte(bus, devfn, where, (u8) val); + case 2: + return write_config_word(bus, devfn, where, (u16) val); + default: + return write_config_dword(bus, devfn, where, val); + } +} + +struct pci_ops mt7621_pci_ops= { + .read = pci_config_read, + .write = pci_config_write, +}; + +static struct resource mt7621_res_pci_mem1; +static struct resource mt7621_res_pci_io1; +static struct pci_controller mt7621_controller = { + .pci_ops = &mt7621_pci_ops, + .mem_resource = &mt7621_res_pci_mem1, + .io_resource = &mt7621_res_pci_io1, +}; + +static void +read_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long *val) +{ + unsigned int address_reg, data_reg, address; + + address_reg = RALINK_PCI_CONFIG_ADDR; + data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG; + address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ; + MV_WRITE(address_reg, address); + MV_READ(data_reg, val); + return; +} + +static void +write_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long val) +{ + unsigned int address_reg, data_reg, address; + + address_reg = RALINK_PCI_CONFIG_ADDR; + data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG; + address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ; + MV_WRITE(address_reg, address); + MV_WRITE(data_reg, val); + return; +} + +int +pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + u16 cmd; + u32 val; + int irq; + + if (dev->bus->number == 0) { + write_config(0, slot, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); + read_config(0, slot, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val); + printk("BAR0 at slot %d = %x\n", slot, val); + } + + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14); //configure cache line size 0x14 + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xFF); //configure latency timer 0x10 + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + pci_write_config_word(dev, PCI_COMMAND, cmd); + + irq = of_irq_parse_and_map_pci(dev, slot, pin); + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); + return irq; +} + +void +set_pcie_phy(u32 *addr, int start_b, int bits, int val) +{ + *(unsigned int *)(addr) &= ~(((1<> 6) & 0x7; + /* Set PCIe Port0 & Port1 PHY to disable SSC */ + /* Debug Xtal Type */ + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 1 enable control + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x00); // rg_pe1_phy_en //Port 1 disable + if(reg <= 5 && reg >= 3) { // 40MHz Xtal + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) + printk("***** Xtal 40MHz *****\n"); + } else { // 25MHz | 20MHz Xtal + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) + if (reg >= 6) { + printk("***** Xtal 25MHz *****\n"); + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode) + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial + } else { + printk("***** Xtal 20MHz *****\n"); + } + } + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN + if(reg <= 5 && reg >= 3) { // 40MHz Xtal + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv + } + /* Enable PHY and disable force mode */ + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x01); // rg_pe1_phy_en //Port 1 enable + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 1 disable control + + /* Set PCIe Port2 PHY to disable SSC */ + /* Debug Xtal Type */ + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable + if(reg <= 5 && reg >= 3) { // 40MHz Xtal + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) + } else { // 25MHz | 20MHz Xtal + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) + if (reg >= 6) { // 25MHz Xtal + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode) + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial + } + } + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN + if(reg <= 5 && reg >= 3) { // 40MHz Xtal + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv + } + /* Enable PHY and disable force mode */ + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable + set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control +} + +void setup_cm_memory_region(struct resource *mem_resource) +{ + resource_size_t mask; + if (mips_cps_numiocu(0)) { + /* FIXME: hardware doesn't accept mask values with 1s after + * 0s (e.g. 0xffef), so it would be great to warn if that's + * about to happen */ + mask = ~(mem_resource->end - mem_resource->start); + + write_gcr_reg1_base(mem_resource->start); + write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); + printk("PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", + (unsigned long long)read_gcr_reg1_base(), + (unsigned long long)read_gcr_reg1_mask()); + } +} + +static int mt7621_pci_probe(struct platform_device *pdev) +{ + unsigned long val = 0; + + iomem_resource.start = 0; + iomem_resource.end= ~0; + ioport_resource.start= 0; + ioport_resource.end = ~0; + + val = RALINK_PCIE0_RST; + val |= RALINK_PCIE1_RST; + val |= RALINK_PCIE2_RST; + + ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST); + + *(unsigned int *)(0xbe000060) &= ~(0x3<<10 | 0x3<<3); + *(unsigned int *)(0xbe000060) |= 0x1<<10 | 0x1<<3; + mdelay(100); + *(unsigned int *)(0xbe000600) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // use GPIO19/GPIO8/GPIO7 (PERST_N/UART_RXD3/UART_TXD3) + mdelay(100); + *(unsigned int *)(0xbe000620) &= ~(0x1<<19 | 0x1<<8 | 0x1<<7); // clear DATA + + mdelay(100); + + val = RALINK_PCIE0_RST; + val |= RALINK_PCIE1_RST; + val |= RALINK_PCIE2_RST; + + DEASSERT_SYSRST_PCIE(val); + + if ((*(unsigned int *)(0xbe00000c)&0xFFFF) == 0x0101) // MT7621 E2 + bypass_pipe_rst(); + set_phy_for_ssc(); + + read_config(0, 0, 0, 0x70c, &val); + printk("Port 0 N_FTS = %x\n", (unsigned int)val); + + read_config(0, 1, 0, 0x70c, &val); + printk("Port 1 N_FTS = %x\n", (unsigned int)val); + + read_config(0, 2, 0, 0x70c, &val); + printk("Port 2 N_FTS = %x\n", (unsigned int)val); + + RALINK_RSTCTRL = (RALINK_RSTCTRL | RALINK_PCIE_RST); + RALINK_SYSCFG1 &= ~(0x30); + RALINK_SYSCFG1 |= (2<<4); + RALINK_PCIE_CLK_GEN &= 0x7fffffff; + RALINK_PCIE_CLK_GEN1 &= 0x80ffffff; + RALINK_PCIE_CLK_GEN1 |= 0xa << 24; + RALINK_PCIE_CLK_GEN |= 0x80000000; + mdelay(50); + RALINK_RSTCTRL = (RALINK_RSTCTRL & ~RALINK_PCIE_RST); + + /* Use GPIO control instead of PERST_N */ + *(unsigned int *)(0xbe000620) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // set DATA + mdelay(1000); + + if(( RALINK_PCI0_STATUS & 0x1) == 0) + { + printk("PCIE0 no card, disable it(RST&CLK)\n"); + ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST); + RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE0_CLK_EN); + pcie_link_status &= ~(1<<0); + } else { + pcie_link_status |= 1<<0; + RALINK_PCI_PCIMSK_ADDR |= (1<<20); // enable pcie1 interrupt + } + + if(( RALINK_PCI1_STATUS & 0x1) == 0) + { + printk("PCIE1 no card, disable it(RST&CLK)\n"); + ASSERT_SYSRST_PCIE(RALINK_PCIE1_RST); + RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE1_CLK_EN); + pcie_link_status &= ~(1<<1); + } else { + pcie_link_status |= 1<<1; + RALINK_PCI_PCIMSK_ADDR |= (1<<21); // enable pcie1 interrupt + } + + if (( RALINK_PCI2_STATUS & 0x1) == 0) { + printk("PCIE2 no card, disable it(RST&CLK)\n"); + ASSERT_SYSRST_PCIE(RALINK_PCIE2_RST); + RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE2_CLK_EN); + pcie_link_status &= ~(1<<2); + } else { + pcie_link_status |= 1<<2; + RALINK_PCI_PCIMSK_ADDR |= (1<<22); // enable pcie2 interrupt + } + + if (pcie_link_status == 0) + return 0; + +/* +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: + RALINK_PCI_PCICFG_ADDR &= ~0x00ff0000; + RALINK_PCI_PCICFG_ADDR |= 0x1 << 16; //port0 + RALINK_PCI_PCICFG_ADDR |= 0x0 << 20; //port1 + break; + case 4: + RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; + RALINK_PCI_PCICFG_ADDR |= 0x1 << 16; //port0 + RALINK_PCI_PCICFG_ADDR |= 0x2 << 20; //port1 + RALINK_PCI_PCICFG_ADDR |= 0x0 << 24; //port2 + break; + case 5: + RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; + RALINK_PCI_PCICFG_ADDR |= 0x0 << 16; //port0 + RALINK_PCI_PCICFG_ADDR |= 0x2 << 20; //port1 + RALINK_PCI_PCICFG_ADDR |= 0x1 << 24; //port2 + break; + case 6: + RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; + RALINK_PCI_PCICFG_ADDR |= 0x2 << 16; //port0 + RALINK_PCI_PCICFG_ADDR |= 0x0 << 20; //port1 + RALINK_PCI_PCICFG_ADDR |= 0x1 << 24; //port2 + break; + } + +/* + ioport_resource.start = mt7621_res_pci_io1.start; + ioport_resource.end = mt7621_res_pci_io1.end; +*/ + + RALINK_PCI_MEMBASE = 0xffffffff; //RALINK_PCI_MM_MAP_BASE; + RALINK_PCI_IOBASE = RALINK_PCI_IO_MAP_BASE; + + //PCIe0 + if((pcie_link_status & 0x1) != 0) { + RALINK_PCI0_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE + RALINK_PCI0_IMBASEBAR0_ADDR = MEMORY_BASE; + RALINK_PCI0_CLASS = 0x06040001; + printk("PCIE0 enabled\n"); + } + + //PCIe1 + if ((pcie_link_status & 0x2) != 0) { + RALINK_PCI1_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE + RALINK_PCI1_IMBASEBAR0_ADDR = MEMORY_BASE; + RALINK_PCI1_CLASS = 0x06040001; + printk("PCIE1 enabled\n"); + } + + //PCIe2 + if ((pcie_link_status & 0x4) != 0) { + RALINK_PCI2_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE + RALINK_PCI2_IMBASEBAR0_ADDR = MEMORY_BASE; + RALINK_PCI2_CLASS = 0x06040001; + printk("PCIE2 enabled\n"); + } + + switch(pcie_link_status) { + case 7: + read_config(0, 2, 0, 0x4, &val); + write_config(0, 2, 0, 0x4, val|0x4); + read_config(0, 2, 0, 0x70c, &val); + val &= ~(0xff)<<8; + val |= 0x50<<8; + write_config(0, 2, 0, 0x70c, val); + case 3: + case 5: + case 6: + read_config(0, 1, 0, 0x4, &val); + write_config(0, 1, 0, 0x4, val|0x4); + read_config(0, 1, 0, 0x70c, &val); + val &= ~(0xff)<<8; + val |= 0x50<<8; + write_config(0, 1, 0, 0x70c, val); + default: + read_config(0, 0, 0, 0x4, &val); + write_config(0, 0, 0, 0x4, val|0x4); //bus master enable + read_config(0, 0, 0, 0x70c, &val); + val &= ~(0xff)<<8; + val |= 0x50<<8; + write_config(0, 0, 0, 0x70c, val); + } + + pci_load_of_ranges(&mt7621_controller, pdev->dev.of_node); + setup_cm_memory_region(mt7621_controller.mem_resource); + register_pci_controller(&mt7621_controller); + return 0; + +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static const struct of_device_id mt7621_pci_ids[] = { + { .compatible = "mediatek,mt7621-pci" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt7621_pci_ids); + +static struct platform_driver mt7621_pci_driver = { + .probe = mt7621_pci_probe, + .driver = { + .name = "mt7621-pci", + .of_match_table = of_match_ptr(mt7621_pci_ids), + }, +}; + +static int __init mt7621_pci_init(void) +{ + return platform_driver_register(&mt7621_pci_driver); +} + +arch_initcall(mt7621_pci_init); diff --git a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/board.h b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/board.h index 33bfc7b95..a7d82f321 100644 --- a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/board.h +++ b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/board.h @@ -36,27 +36,10 @@ #ifndef __ARCH_ARM_MACH_BOARD_H #define __ARCH_ARM_MACH_BOARD_H -#include -#include -/* --- chhung */ -// #include -// #include -/* end of chhung */ - -typedef void (*sdio_irq_handler_t)(void*); /* external irq handler */ -typedef void (*pm_callback_t)(pm_message_t state, void *data); - #define MSDC_CD_PIN_EN (1 << 0) /* card detection pin is wired */ #define MSDC_WP_PIN_EN (1 << 1) /* write protection pin is wired */ #define MSDC_RST_PIN_EN (1 << 2) /* emmc reset pin is wired */ -#define MSDC_SDIO_IRQ (1 << 3) /* use internal sdio irq (bus) */ -#define MSDC_EXT_SDIO_IRQ (1 << 4) /* use external sdio irq */ #define MSDC_REMOVABLE (1 << 5) /* removable slot */ -#define MSDC_SYS_SUSPEND (1 << 6) /* suspended by system */ -#define MSDC_HIGHSPEED (1 << 7) /* high-speed mode support */ -#define MSDC_UHS1 (1 << 8) /* uhs-1 mode support */ -#define MSDC_DDR (1 << 9) /* ddr mode support */ - #define MSDC_SMPL_RISING (0) #define MSDC_SMPL_FALLING (1) @@ -67,71 +50,14 @@ typedef void (*pm_callback_t)(pm_message_t state, void *data); #define MSDC_WP_PIN (3) #define MSDC_RST_PIN (4) -enum { - MSDC_CLKSRC_48MHZ = 0, -// MSDC_CLKSRC_26MHZ = 0, -// MSDC_CLKSRC_197MHZ = 1, -// MSDC_CLKSRC_208MHZ = 2 -}; - struct msdc_hw { - unsigned char clk_src; /* host clock source */ - unsigned char cmd_edge; /* command latch edge */ - unsigned char data_edge; /* data latch edge */ - unsigned char clk_drv; /* clock pad driving */ - unsigned char cmd_drv; /* command pad driving */ - unsigned char dat_drv; /* data pad driving */ - unsigned long flags; /* hardware capability flags */ - unsigned long data_pins; /* data pins */ - unsigned long data_offset; /* data address offset */ + unsigned char clk_src; /* host clock source */ + unsigned long flags; /* hardware capability flags */ - /* config gpio pull mode */ - void (*config_gpio_pin)(int type, int pull); - - /* external power control for card */ - void (*ext_power_on)(void); - void (*ext_power_off)(void); - - /* external sdio irq operations */ - void (*request_sdio_eirq)(sdio_irq_handler_t sdio_irq_handler, void *data); - void (*enable_sdio_eirq)(void); - void (*disable_sdio_eirq)(void); - - /* external cd irq operations */ - void (*request_cd_eirq)(sdio_irq_handler_t cd_irq_handler, void *data); - void (*enable_cd_eirq)(void); - void (*disable_cd_eirq)(void); - int (*get_cd_status)(void); - - /* power management callback for external module */ - void (*register_pm)(pm_callback_t pm_cb, void *data); + /* config gpio pull mode */ + void (*config_gpio_pin)(int type, int pull); }; extern struct msdc_hw msdc0_hw; -extern struct msdc_hw msdc1_hw; -extern struct msdc_hw msdc2_hw; -extern struct msdc_hw msdc3_hw; - -/*GPS driver*/ -#define GPS_FLAG_FORCE_OFF 0x0001 -struct mt3326_gps_hardware { - int (*ext_power_on)(int); - int (*ext_power_off)(int); -}; -extern struct mt3326_gps_hardware mt3326_gps_hw; - -/* NAND driver */ -struct mt6575_nand_host_hw { - unsigned int nfi_bus_width; /* NFI_BUS_WIDTH */ - unsigned int nfi_access_timing; /* NFI_ACCESS_TIMING */ - unsigned int nfi_cs_num; /* NFI_CS_NUM */ - unsigned int nand_sec_size; /* NAND_SECTOR_SIZE */ - unsigned int nand_sec_shift; /* NAND_SECTOR_SHIFT */ - unsigned int nand_ecc_size; - unsigned int nand_ecc_bytes; - unsigned int nand_ecc_mode; -}; -extern struct mt6575_nand_host_hw mt6575_nand_hw; #endif /* __ARCH_ARM_MACH_BOARD_H */ - diff --git a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.c b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.c index ae4ef0fa5..d897b1216 100644 --- a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.c +++ b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.c @@ -32,7 +32,7 @@ * have been modified by MediaTek Inc. All revisions are subject to any receiver's * applicable license agreements with MediaTek Inc. */ - + #include #include #include @@ -48,276 +48,239 @@ #include "mt6575_sd.h" #include -/* mode select */ -u32 dma_size[4]={ - 512, - 512, - 512, - 512 -}; -msdc_mode drv_mode[4]={ - MODE_SIZE_DEP, /* using DMA or not depend on the size */ - MODE_SIZE_DEP, - MODE_SIZE_DEP, - MODE_SIZE_DEP -}; - -#if defined (MT6575_SD_DEBUG) static char cmd_buf[256]; /* for debug zone */ -static unsigned int sd_debug_zone[4]={ +unsigned int sd_debug_zone[4] = { 0, 0, 0, 0 }; - +#if defined(MT6575_SD_DEBUG) /* for driver profile */ #define TICKS_ONE_MS (13000) -u32 gpt_enable = 0; -u32 sdio_pro_enable = 0; /* make sure gpt is enabled */ -u32 sdio_pro_time = 0; /* no more than 30s */ -struct sdio_profile sdio_perfomance = {0}; +u32 gpt_enable; +u32 sdio_pro_enable; /* make sure gpt is enabled */ +u32 sdio_pro_time; /* no more than 30s */ +struct sdio_profile sdio_perfomance = {0}; #if 0 /* --- chhung */ void msdc_init_gpt(void) { - GPT_CONFIG config; - - config.num = GPT6; - config.mode = GPT_FREE_RUN; - config.clkSrc = GPT_CLK_SRC_SYS; - config.clkDiv = GPT_CLK_DIV_1; /* 13MHz GPT6 */ - - if (GPT_Config(config) == FALSE ) - return; - - GPT_Start(GPT6); + GPT_CONFIG config; + + config.num = GPT6; + config.mode = GPT_FREE_RUN; + config.clkSrc = GPT_CLK_SRC_SYS; + config.clkDiv = GPT_CLK_DIV_1; /* 13MHz GPT6 */ + + if (GPT_Config(config) == FALSE) + return; + + GPT_Start(GPT6); } #endif /* end of --- */ u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32) { - u32 ret = 0; - - if (new_H32 == old_H32) { - ret = new_L32 - old_L32; - } else if(new_H32 == (old_H32 + 1)) { - if (new_L32 > old_L32) { - printk("msdc old_L<0x%x> new_L<0x%x>\n", old_L32, new_L32); - } - ret = (0xffffffff - old_L32); - ret += new_L32; - } else { - printk("msdc old_H<0x%x> new_H<0x%x>\n", old_H32, new_H32); - } + u32 ret = 0; - return ret; + if (new_H32 == old_H32) { + ret = new_L32 - old_L32; + } else if (new_H32 == (old_H32 + 1)) { + if (new_L32 > old_L32) + printk("msdc old_L<0x%x> new_L<0x%x>\n", old_L32, new_L32); + ret = (0xffffffff - old_L32); + ret += new_L32; + } else { + printk("msdc old_H<0x%x> new_H<0x%x>\n", old_H32, new_H32); + } + + return ret; } -void msdc_sdio_profile(struct sdio_profile* result) +void msdc_sdio_profile(struct sdio_profile *result) { - struct cmd_profile* cmd; - u32 i; - - printk("sdio === performance dump ===\n"); - printk("sdio === total execute tick<%d> time<%dms> Tx<%dB> Rx<%dB>\n", - result->total_tc, result->total_tc / TICKS_ONE_MS, - result->total_tx_bytes, result->total_rx_bytes); + struct cmd_profile *cmd; + u32 i; - /* CMD52 Dump */ - cmd = &result->cmd52_rx; - printk("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, - cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count); - cmd = &result->cmd52_tx; - printk("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, - cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count); - - /* CMD53 Rx bytes + block mode */ - for (i=0; i<512; i++) { - cmd = &result->cmd53_rx_byte[i]; - if (cmd->count) { - printk("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, - cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count, - cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10)); - } - } - for (i=0; i<100; i++) { - cmd = &result->cmd53_rx_blk[i]; - if (cmd->count) { - printk("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, - cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count, - cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10)); - } - } + printk("sdio === performance dump ===\n"); + printk("sdio === total execute tick<%d> time<%dms> Tx<%dB> Rx<%dB>\n", + result->total_tc, result->total_tc / TICKS_ONE_MS, + result->total_tx_bytes, result->total_rx_bytes); - /* CMD53 Tx bytes + block mode */ - for (i=0; i<512; i++) { - cmd = &result->cmd53_tx_byte[i]; - if (cmd->count) { - printk("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, - cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count, - cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10)); - } - } - for (i=0; i<100; i++) { - cmd = &result->cmd53_tx_blk[i]; - if (cmd->count) { - printk("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, - cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count, - cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10)); - } - } - - printk("sdio === performance dump done ===\n"); + /* CMD52 Dump */ + cmd = &result->cmd52_rx; + printk("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, + cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count); + cmd = &result->cmd52_tx; + printk("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, + cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count); + + /* CMD53 Rx bytes + block mode */ + for (i = 0; i < 512; i++) { + cmd = &result->cmd53_rx_byte[i]; + if (cmd->count) { + printk("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, + cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, + cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); + } + } + for (i = 0; i < 100; i++) { + cmd = &result->cmd53_rx_blk[i]; + if (cmd->count) { + printk("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, + cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, + cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); + } + } + + /* CMD53 Tx bytes + block mode */ + for (i = 0; i < 512; i++) { + cmd = &result->cmd53_tx_byte[i]; + if (cmd->count) { + printk("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, + cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, + cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); + } + } + for (i = 0; i < 100; i++) { + cmd = &result->cmd53_tx_blk[i]; + if (cmd->count) { + printk("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, + cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count, + cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10)); + } + } + + printk("sdio === performance dump done ===\n"); } //========= sdio command table =========== void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks) { - struct sdio_profile* result = &sdio_perfomance; - struct cmd_profile* cmd; - u32 block; + struct sdio_profile *result = &sdio_perfomance; + struct cmd_profile *cmd; + u32 block; - if (sdio_pro_enable == 0) { - return; - } + if (sdio_pro_enable == 0) + return; - if (opcode == 52) { - cmd = bRx ? &result->cmd52_rx : &result->cmd52_tx; - } else if (opcode == 53) { - if (sizes < 512) { - cmd = bRx ? &result->cmd53_rx_byte[sizes] : &result->cmd53_tx_byte[sizes]; - } else { - block = sizes / 512; - if (block >= 99) { - printk("cmd53 error blocks\n"); - while(1); - } - cmd = bRx ? &result->cmd53_rx_blk[block] : &result->cmd53_tx_blk[block]; - } - } else { - return; - } - - /* update the members */ - if (ticks > cmd->max_tc){ - cmd->max_tc = ticks; - } - if (cmd->min_tc == 0 || ticks < cmd->min_tc) { - cmd->min_tc = ticks; - } - cmd->tot_tc += ticks; - cmd->tot_bytes += sizes; - cmd->count ++; - - if (bRx) { - result->total_rx_bytes += sizes; - } else { - result->total_tx_bytes += sizes; - } - result->total_tc += ticks; - - /* dump when total_tc > 30s */ - if (result->total_tc >= sdio_pro_time * TICKS_ONE_MS * 1000) { - msdc_sdio_profile(result); - memset(result, 0 , sizeof(struct sdio_profile)); - } + if (opcode == 52) { + cmd = bRx ? &result->cmd52_rx : &result->cmd52_tx; + } else if (opcode == 53) { + if (sizes < 512) { + cmd = bRx ? &result->cmd53_rx_byte[sizes] : &result->cmd53_tx_byte[sizes]; + } else { + block = sizes / 512; + if (block >= 99) { + printk("cmd53 error blocks\n"); + while (1) + ; + } + cmd = bRx ? &result->cmd53_rx_blk[block] : &result->cmd53_tx_blk[block]; + } + } else { + return; + } + + /* update the members */ + if (ticks > cmd->max_tc) + cmd->max_tc = ticks; + if (cmd->min_tc == 0 || ticks < cmd->min_tc) + cmd->min_tc = ticks; + cmd->tot_tc += ticks; + cmd->tot_bytes += sizes; + cmd->count++; + + if (bRx) + result->total_rx_bytes += sizes; + else + result->total_tx_bytes += sizes; + result->total_tc += ticks; + + /* dump when total_tc > 30s */ + if (result->total_tc >= sdio_pro_time * TICKS_ONE_MS * 1000) { + msdc_sdio_profile(result); + memset(result, 0, sizeof(struct sdio_profile)); + } } //========== driver proc interface =========== static int msdc_debug_proc_read(struct seq_file *s, void *p) { - seq_printf(s, "\n=========================================\n"); - seq_printf(s, "Index<0> + Id + Zone\n"); - seq_printf(s, "-> PWR<9> WRN<8> | FIO<7> OPS<6> FUN<5> CFG<4> | INT<3> RSP<2> CMD<1> DMA<0>\n"); - seq_printf(s, "-> echo 0 3 0x3ff >msdc_bebug -> host[3] debug zone set to 0x3ff\n"); + seq_puts(s, "\n=========================================\n"); + seq_puts(s, "Index<0> + Id + Zone\n"); + seq_puts(s, "-> PWR<9> WRN<8> | FIO<7> OPS<6> FUN<5> CFG<4> | INT<3> RSP<2> CMD<1> DMA<0>\n"); + seq_puts(s, "-> echo 0 3 0x3ff >msdc_bebug -> host[3] debug zone set to 0x3ff\n"); seq_printf(s, "-> MSDC[0] Zone: 0x%.8x\n", sd_debug_zone[0]); seq_printf(s, "-> MSDC[1] Zone: 0x%.8x\n", sd_debug_zone[1]); seq_printf(s, "-> MSDC[2] Zone: 0x%.8x\n", sd_debug_zone[2]); seq_printf(s, "-> MSDC[3] Zone: 0x%.8x\n", sd_debug_zone[3]); - seq_printf(s, "Index<1> + ID:4|Mode:4 + DMA_SIZE\n"); - seq_printf(s, "-> 0)PIO 1)DMA 2)SIZE\n"); - seq_printf(s, "-> echo 1 22 0x200 >msdc_bebug -> host[2] size mode, dma when >= 512\n"); - seq_printf(s, "-> MSDC[0] mode<%d> size<%d>\n", drv_mode[0], dma_size[0]); - seq_printf(s, "-> MSDC[1] mode<%d> size<%d>\n", drv_mode[1], dma_size[1]); - seq_printf(s, "-> MSDC[2] mode<%d> size<%d>\n", drv_mode[2], dma_size[2]); - seq_printf(s, "-> MSDC[3] mode<%d> size<%d>\n", drv_mode[3], dma_size[3]); - - seq_printf(s, "Index<3> + SDIO_PROFILE + TIME\n"); - seq_printf(s, "-> echo 3 1 0x1E >msdc_bebug -> enable sdio_profile, 30s\n"); + seq_puts(s, "Index<3> + SDIO_PROFILE + TIME\n"); + seq_puts(s, "-> echo 3 1 0x1E >msdc_bebug -> enable sdio_profile, 30s\n"); seq_printf(s, "-> SDIO_PROFILE<%d> TIME<%ds>\n", sdio_pro_enable, sdio_pro_time); - seq_printf(s, "=========================================\n\n"); + seq_puts(s, "=========================================\n\n"); return 0; } -static ssize_t msdc_debug_proc_write(struct file *file, - const char __user *buf, size_t count, loff_t *data) +static ssize_t msdc_debug_proc_write(struct file *file, + const char __user *buf, size_t count, loff_t *data) { int ret; - - int cmd, p1, p2; - int id, zone; - int mode, size; - - if (count == 0)return -1; - if(count > 255)count = 255; - ret = copy_from_user(cmd_buf, buf, count); - if (ret < 0)return -1; - + int cmd, p1, p2; + int id, zone; + int mode, size; + + if (count == 0) + return -1; + if (count > 255) + count = 255; + + if (copy_from_user(cmd_buf, buf, count)) + return -EFAULT; + cmd_buf[count] = '\0'; printk("msdc Write %s\n", cmd_buf); sscanf(cmd_buf, "%x %x %x", &cmd, &p1, &p2); - - if(cmd == SD_TOOL_ZONE) { - id = p1; zone = p2; zone &= 0x3ff; + + if (cmd == SD_TOOL_ZONE) { + id = p1; + zone = p2; + zone &= 0x3ff; printk("msdc host_id<%d> zone<0x%.8x>\n", id, zone); - if(id >=0 && id<=3){ + if (id >= 0 && id <= 3) { sd_debug_zone[id] = zone; - } - else if(id == 4){ + } else if (id == 4) { sd_debug_zone[0] = sd_debug_zone[1] = zone; sd_debug_zone[2] = sd_debug_zone[3] = zone; - } - else{ + } else { printk("msdc host_id error when set debug zone\n"); } - } else if (cmd == SD_TOOL_DMA_SIZE) { - id = p1>>4; mode = (p1&0xf); size = p2; - if(id >=0 && id<=3){ - drv_mode[id] = mode; - dma_size[id] = p2; - } - else if(id == 4){ - drv_mode[0] = drv_mode[1] = mode; - drv_mode[2] = drv_mode[3] = mode; - dma_size[0] = dma_size[1] = p2; - dma_size[2] = dma_size[3] = p2; - } - else{ - printk("msdc host_id error when select mode\n"); - } } else if (cmd == SD_TOOL_SDIO_PROFILE) { if (p1 == 1) { /* enable profile */ if (gpt_enable == 0) { // msdc_init_gpt(); /* --- by chhung */ gpt_enable = 1; - } + } sdio_pro_enable = 1; - if (p2 == 0) p2 = 1; if (p2 >= 30) p2 = 30; - sdio_pro_time = p2 ; - } else if (p1 == 0) { + if (p2 == 0) + p2 = 1; + if (p2 >= 30) + p2 = 30; + sdio_pro_time = p2; + } else if (p1 == 0) { /* todo */ sdio_pro_enable = 0; - } + } } - + return count; } @@ -327,22 +290,17 @@ static int msdc_debug_show(struct inode *inode, struct file *file) } static const struct file_operations msdc_debug_fops = { - .owner = THIS_MODULE, - .open = msdc_debug_show, - .read = seq_read, - .write = msdc_debug_proc_write, - .llseek = seq_lseek, - .release = single_release, + .owner = THIS_MODULE, + .open = msdc_debug_show, + .read = seq_read, + .write = msdc_debug_proc_write, + .llseek = seq_lseek, + .release = single_release, }; -int msdc_debug_proc_init(void) -{ - struct proc_dir_entry *de = proc_create("msdc_debug", 0667, NULL, &msdc_debug_fops); - - if (!de || IS_ERR(de)) - printk("!! Create MSDC debug PROC fail !!\n"); - - return 0 ; +void msdc_debug_proc_init(void) +{ + proc_create("msdc_debug", 0660, NULL, &msdc_debug_fops); } EXPORT_SYMBOL_GPL(msdc_debug_proc_init); #endif diff --git a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.h b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.h index e58c43129..5a25a69b0 100644 --- a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.h +++ b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.h @@ -39,47 +39,45 @@ extern u32 sdio_pro_enable; /* for a type command, e.g. CMD53, 2 blocks */ struct cmd_profile { - u32 max_tc; /* Max tick count */ - u32 min_tc; - u32 tot_tc; /* total tick count */ - u32 tot_bytes; - u32 count; /* the counts of the command */ + u32 max_tc; /* Max tick count */ + u32 min_tc; + u32 tot_tc; /* total tick count */ + u32 tot_bytes; + u32 count; /* the counts of the command */ }; /* dump when total_tc and total_bytes */ struct sdio_profile { - u32 total_tc; /* total tick count of CMD52 and CMD53 */ - u32 total_tx_bytes; /* total bytes of CMD53 Tx */ - u32 total_rx_bytes; /* total bytes of CMD53 Rx */ - - /*CMD52*/ - struct cmd_profile cmd52_tx; - struct cmd_profile cmd52_rx; + u32 total_tc; /* total tick count of CMD52 and CMD53 */ + u32 total_tx_bytes; /* total bytes of CMD53 Tx */ + u32 total_rx_bytes; /* total bytes of CMD53 Rx */ - /*CMD53 in byte unit */ - struct cmd_profile cmd53_tx_byte[512]; - struct cmd_profile cmd53_rx_byte[512]; - - /*CMD53 in block unit */ - struct cmd_profile cmd53_tx_blk[100]; - struct cmd_profile cmd53_rx_blk[100]; + /*CMD52*/ + struct cmd_profile cmd52_tx; + struct cmd_profile cmd52_rx; + + /*CMD53 in byte unit */ + struct cmd_profile cmd53_tx_byte[512]; + struct cmd_profile cmd53_rx_byte[512]; + + /*CMD53 in block unit */ + struct cmd_profile cmd53_tx_blk[100]; + struct cmd_profile cmd53_rx_blk[100]; }; //========================== -typedef enum { - SD_TOOL_ZONE = 0, - SD_TOOL_DMA_SIZE = 1, - SD_TOOL_PM_ENABLE = 2, - SD_TOOL_SDIO_PROFILE = 3, -} msdc_dbg; +enum msdc_dbg { + SD_TOOL_ZONE = 0, + SD_TOOL_DMA_SIZE = 1, + SD_TOOL_PM_ENABLE = 2, + SD_TOOL_SDIO_PROFILE = 3, +}; -typedef enum { - MODE_PIO = 0, - MODE_DMA = 1, - MODE_SIZE_DEP = 2, -} msdc_mode; -extern msdc_mode drv_mode[4]; -extern u32 dma_size[4]; +enum msdc_mode { + MODE_PIO = 0, + MODE_DMA = 1, + MODE_SIZE_DEP = 2, +}; /* Debug message event */ #define DBG_EVT_NONE (0) /* No event */ @@ -104,9 +102,10 @@ extern unsigned int sd_debug_zone[4]; do { \ if (x) { \ printk("[BUG] %s LINE:%d FILE:%s\n", #x, __LINE__, __FILE__); \ - while(1); \ + while (1) \ + ; \ } \ -}while(0) +} while (0) #endif /* end of +++ */ #define N_MSG(evt, fmt, args...) @@ -121,36 +120,36 @@ do { \ #define ERR_MSG(fmt, args...) \ do { \ - printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ - host->id, ##args , __FUNCTION__, __LINE__, current->comm, current->pid); \ -} while(0); + printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ + host->id, ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \ +} while (0); #if 1 -//defined CONFIG_MTK_MMC_CD_POLL +//defined CONFIG_MTK_MMC_CD_POLL #define INIT_MSG(fmt, args...) -#define IRQ_MSG(fmt, args...) +#define IRQ_MSG(fmt, args...) #else #define INIT_MSG(fmt, args...) \ do { \ - printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ - host->id, ##args , __FUNCTION__, __LINE__, current->comm, current->pid); \ -} while(0); + printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \ + host->id, ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \ +} while (0); /* PID in ISR in not corrent */ #define IRQ_MSG(fmt, args...) \ do { \ - printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n", \ - host->id, ##args , __FUNCTION__, __LINE__); \ -} while(0); + printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n", \ + host->id, ##args, __FUNCTION__, __LINE__); \ +} while (0); #endif -int msdc_debug_proc_init(void); +void msdc_debug_proc_init(void); #if 0 /* --- chhung */ void msdc_init_gpt(void); extern void GPT_GetCounter64(UINT32 *cntL32, UINT32 *cntH32); #endif /* end of --- */ u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32); -void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks); +void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks); #endif diff --git a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/mt6575_sd.h b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/mt6575_sd.h index bb1f60ee5..33fa59a01 100644 --- a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/mt6575_sd.h +++ b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/mt6575_sd.h @@ -37,7 +37,6 @@ #define MT6575_SD_H #include -#include #include // #include /* --- by chhung */ @@ -45,7 +44,7 @@ /*--------------------------------------------------------------------------*/ /* Common Macro */ /*--------------------------------------------------------------------------*/ -#define REG_ADDR(x) ((volatile u32*)(base + OFFSET_##x)) +#define REG_ADDR(x) (base + OFFSET_##x) /*--------------------------------------------------------------------------*/ /* Common Definition */ @@ -89,15 +88,15 @@ #define MSDC_EMMC_BOOTMODE1 (1) /* Reset CMD mode */ enum { - RESP_NONE = 0, - RESP_R1, - RESP_R2, - RESP_R3, - RESP_R4, - RESP_R5, - RESP_R6, - RESP_R7, - RESP_R1B + RESP_NONE = 0, + RESP_R1, + RESP_R2, + RESP_R3, + RESP_R4, + RESP_R5, + RESP_R6, + RESP_R7, + RESP_R1B }; /*--------------------------------------------------------------------------*/ @@ -254,7 +253,7 @@ enum { #define MSDC_PS_CDDEBOUNCE (0xf << 12) /* RW */ #define MSDC_PS_DAT (0xff << 16) /* R */ #define MSDC_PS_CMD (0x1 << 24) /* R */ -#define MSDC_PS_WP (0x1UL<< 31) /* R */ +#define MSDC_PS_WP (0x1UL << 31) /* R */ /* MSDC_INT mask */ #define MSDC_INT_MMCIRQ (0x1 << 0) /* W1C */ @@ -295,14 +294,14 @@ enum { /* MSDC_FIFOCS mask */ #define MSDC_FIFOCS_RXCNT (0xff << 0) /* R */ #define MSDC_FIFOCS_TXCNT (0xff << 16) /* R */ -#define MSDC_FIFOCS_CLR (0x1UL<< 31) /* RW */ +#define MSDC_FIFOCS_CLR (0x1UL << 31) /* RW */ /* SDC_CFG mask */ #define SDC_CFG_SDIOINTWKUP (0x1 << 0) /* RW */ #define SDC_CFG_INSWKUP (0x1 << 1) /* RW */ #define SDC_CFG_BUSWIDTH (0x3 << 16) /* RW */ #define SDC_CFG_SDIO (0x1 << 19) /* RW */ -#define SDC_CFG_SDIOIDE (0x1 << 20) /* RW */ +#define SDC_CFG_SDIOIDE (0x1 << 20) /* RW */ #define SDC_CFG_INTATGAP (0x1 << 21) /* RW */ #define SDC_CFG_DTOC (0xffUL << 24) /* RW */ @@ -315,7 +314,7 @@ enum { #define SDC_CMD_RW (0x1 << 13) /* RW */ #define SDC_CMD_STOP (0x1 << 14) /* RW */ #define SDC_CMD_GOIRQ (0x1 << 15) /* RW */ -#define SDC_CMD_BLKLEN (0xfff<< 16) /* RW */ +#define SDC_CMD_BLKLEN (0xfff << 16) /* RW */ #define SDC_CMD_AUTOCMD (0x3 << 28) /* RW */ #define SDC_CMD_VOLSWTH (0x1 << 30) /* RW */ @@ -397,7 +396,7 @@ enum { #define MSDC_PAD_CTL0_CLKSMT (0x1 << 18) /* RW */ #define MSDC_PAD_CTL0_CLKIES (0x1 << 19) /* RW */ #define MSDC_PAD_CTL0_CLKTDSEL (0xf << 20) /* RW */ -#define MSDC_PAD_CTL0_CLKRDSEL (0xffUL<< 24) /* RW */ +#define MSDC_PAD_CTL0_CLKRDSEL (0xffUL << 24) /* RW */ /* MSDC_PAD_CTL1 mask */ #define MSDC_PAD_CTL1_CMDDRVN (0x7 << 0) /* RW */ @@ -408,7 +407,7 @@ enum { #define MSDC_PAD_CTL1_CMDSMT (0x1 << 18) /* RW */ #define MSDC_PAD_CTL1_CMDIES (0x1 << 19) /* RW */ #define MSDC_PAD_CTL1_CMDTDSEL (0xf << 20) /* RW */ -#define MSDC_PAD_CTL1_CMDRDSEL (0xffUL<< 24) /* RW */ +#define MSDC_PAD_CTL1_CMDRDSEL (0xffUL << 24) /* RW */ /* MSDC_PAD_CTL2 mask */ #define MSDC_PAD_CTL2_DATDRVN (0x7 << 0) /* RW */ @@ -419,7 +418,7 @@ enum { #define MSDC_PAD_CTL2_DATIES (0x1 << 19) /* RW */ #define MSDC_PAD_CTL2_DATSMT (0x1 << 18) /* RW */ #define MSDC_PAD_CTL2_DATTDSEL (0xf << 20) /* RW */ -#define MSDC_PAD_CTL2_DATRDSEL (0xffUL<< 24) /* RW */ +#define MSDC_PAD_CTL2_DATRDSEL (0xffUL << 24) /* RW */ /* MSDC_PAD_TUNE mask */ #define MSDC_PAD_TUNE_DATWRDLY (0x1F << 0) /* RW */ @@ -439,564 +438,549 @@ enum { #define MSDC_DAT_RDDLY1_D6 (0x1F << 16) /* RW */ #define MSDC_DAT_RDDLY1_D7 (0x1F << 24) /* RW */ -#define MSDC_CKGEN_MSDC_DLY_SEL (0x1F<<10) -#define MSDC_INT_DAT_LATCH_CK_SEL (0x7<<7) -#define MSDC_CKGEN_MSDC_CK_SEL (0x1<<6) -#define CARD_READY_FOR_DATA (1<<8) -#define CARD_CURRENT_STATE(x) ((x&0x00001E00)>>9) +#define MSDC_CKGEN_MSDC_DLY_SEL (0x1F << 10) +#define MSDC_INT_DAT_LATCH_CK_SEL (0x7 << 7) +#define MSDC_CKGEN_MSDC_CK_SEL (0x1 << 6) +#define CARD_READY_FOR_DATA (1 << 8) +#define CARD_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /*--------------------------------------------------------------------------*/ /* Descriptor Structure */ /*--------------------------------------------------------------------------*/ -typedef struct { - u32 hwo:1; /* could be changed by hw */ - u32 bdp:1; - u32 rsv0:6; - u32 chksum:8; - u32 intr:1; - u32 rsv1:15; - void *next; - void *ptr; - u32 buflen:16; - u32 extlen:8; - u32 rsv2:8; - u32 arg; - u32 blknum; - u32 cmd; -} gpd_t; +struct gpd { + u32 hwo:1; /* could be changed by hw */ + u32 bdp:1; + u32 rsv0:6; + u32 chksum:8; + u32 intr:1; + u32 rsv1:15; + void *next; + void *ptr; + u32 buflen:16; + u32 extlen:8; + u32 rsv2:8; + u32 arg; + u32 blknum; + u32 cmd; +}; -typedef struct { - u32 eol:1; - u32 rsv0:7; - u32 chksum:8; - u32 rsv1:1; - u32 blkpad:1; - u32 dwpad:1; - u32 rsv2:13; - void *next; - void *ptr; - u32 buflen:16; - u32 rsv3:16; -} bd_t; +struct bd { + u32 eol:1; + u32 rsv0:7; + u32 chksum:8; + u32 rsv1:1; + u32 blkpad:1; + u32 dwpad:1; + u32 rsv2:13; + void *next; + void *ptr; + u32 buflen:16; + u32 rsv3:16; +}; /*--------------------------------------------------------------------------*/ /* Register Debugging Structure */ /*--------------------------------------------------------------------------*/ -typedef struct { - u32 msdc:1; - u32 ckpwn:1; - u32 rst:1; - u32 pio:1; - u32 ckdrven:1; - u32 start18v:1; - u32 pass18v:1; - u32 ckstb:1; - u32 ckdiv:8; - u32 ckmod:2; - u32 pad:14; -} msdc_cfg_reg; -typedef struct { - u32 sdr104cksel:1; - u32 rsmpl:1; - u32 dsmpl:1; - u32 ddlysel:1; - u32 ddr50ckd:1; - u32 dsplsel:1; - u32 pad1:10; - u32 d0spl:1; - u32 d1spl:1; - u32 d2spl:1; - u32 d3spl:1; - u32 d4spl:1; - u32 d5spl:1; - u32 d6spl:1; - u32 d7spl:1; - u32 riscsz:1; - u32 pad2:7; -} msdc_iocon_reg; -typedef struct { - u32 cden:1; - u32 cdsts:1; - u32 pad1:10; - u32 cddebounce:4; - u32 dat:8; - u32 cmd:1; - u32 pad2:6; - u32 wp:1; -} msdc_ps_reg; -typedef struct { - u32 mmcirq:1; - u32 cdsc:1; - u32 pad1:1; - u32 atocmdrdy:1; - u32 atocmdtmo:1; - u32 atocmdcrc:1; - u32 dmaqempty:1; - u32 sdioirq:1; - u32 cmdrdy:1; - u32 cmdtmo:1; - u32 rspcrc:1; - u32 csta:1; - u32 xfercomp:1; - u32 dxferdone:1; - u32 dattmo:1; - u32 datcrc:1; - u32 atocmd19done:1; - u32 pad2:15; -} msdc_int_reg; -typedef struct { - u32 mmcirq:1; - u32 cdsc:1; - u32 pad1:1; - u32 atocmdrdy:1; - u32 atocmdtmo:1; - u32 atocmdcrc:1; - u32 dmaqempty:1; - u32 sdioirq:1; - u32 cmdrdy:1; - u32 cmdtmo:1; - u32 rspcrc:1; - u32 csta:1; - u32 xfercomp:1; - u32 dxferdone:1; - u32 dattmo:1; - u32 datcrc:1; - u32 atocmd19done:1; - u32 pad2:15; -} msdc_inten_reg; -typedef struct { - u32 rxcnt:8; - u32 pad1:8; - u32 txcnt:8; - u32 pad2:7; - u32 clr:1; -} msdc_fifocs_reg; -typedef struct { - u32 val; -} msdc_txdat_reg; -typedef struct { - u32 val; -} msdc_rxdat_reg; -typedef struct { - u32 sdiowkup:1; - u32 inswkup:1; - u32 pad1:14; - u32 buswidth:2; - u32 pad2:1; - u32 sdio:1; - u32 sdioide:1; - u32 intblkgap:1; - u32 pad4:2; - u32 dtoc:8; -} sdc_cfg_reg; -typedef struct { - u32 cmd:6; - u32 brk:1; - u32 rsptyp:3; - u32 pad1:1; - u32 dtype:2; - u32 rw:1; - u32 stop:1; - u32 goirq:1; - u32 blklen:12; - u32 atocmd:2; - u32 volswth:1; - u32 pad2:1; -} sdc_cmd_reg; -typedef struct { - u32 arg; -} sdc_arg_reg; -typedef struct { - u32 sdcbusy:1; - u32 cmdbusy:1; - u32 pad:29; - u32 swrcmpl:1; -} sdc_sts_reg; -typedef struct { - u32 val; -} sdc_resp0_reg; -typedef struct { - u32 val; -} sdc_resp1_reg; -typedef struct { - u32 val; -} sdc_resp2_reg; -typedef struct { - u32 val; -} sdc_resp3_reg; -typedef struct { - u32 num; -} sdc_blknum_reg; -typedef struct { - u32 sts; -} sdc_csts_reg; -typedef struct { - u32 sts; -} sdc_cstsen_reg; -typedef struct { - u32 datcrcsts:8; - u32 ddrcrcsts:4; - u32 pad:20; -} sdc_datcrcsts_reg; -typedef struct { - u32 bootstart:1; - u32 bootstop:1; - u32 bootmode:1; - u32 pad1:9; - u32 bootwaidly:3; - u32 bootsupp:1; - u32 pad2:16; -} emmc_cfg0_reg; -typedef struct { - u32 bootcrctmc:16; - u32 pad:4; - u32 bootacktmc:12; -} emmc_cfg1_reg; -typedef struct { - u32 bootcrcerr:1; - u32 bootackerr:1; - u32 bootdattmo:1; - u32 bootacktmo:1; - u32 bootupstate:1; - u32 bootackrcv:1; - u32 bootdatrcv:1; - u32 pad:25; -} emmc_sts_reg; -typedef struct { - u32 bootrst:1; - u32 pad:31; -} emmc_iocon_reg; -typedef struct { - u32 val; -} msdc_acmd_resp_reg; -typedef struct { - u32 tunesel:4; - u32 pad:28; -} msdc_acmd19_trg_reg; -typedef struct { - u32 val; -} msdc_acmd19_sts_reg; -typedef struct { - u32 addr; -} msdc_dma_sa_reg; -typedef struct { - u32 addr; -} msdc_dma_ca_reg; -typedef struct { - u32 start:1; - u32 stop:1; - u32 resume:1; - u32 pad1:5; - u32 mode:1; - u32 pad2:1; - u32 lastbuf:1; - u32 pad3:1; - u32 brustsz:3; - u32 pad4:1; - u32 xfersz:16; -} msdc_dma_ctrl_reg; -typedef struct { - u32 status:1; - u32 decsen:1; - u32 pad1:2; - u32 bdcsen:1; - u32 gpdcsen:1; - u32 pad2:26; -} msdc_dma_cfg_reg; -typedef struct { - u32 sel:16; - u32 pad2:16; -} msdc_dbg_sel_reg; -typedef struct { - u32 val; -} msdc_dbg_out_reg; -typedef struct { - u32 clkdrvn:3; - u32 rsv0:1; - u32 clkdrvp:3; - u32 rsv1:1; - u32 clksr:1; - u32 rsv2:7; - u32 clkpd:1; - u32 clkpu:1; - u32 clksmt:1; - u32 clkies:1; - u32 clktdsel:4; - u32 clkrdsel:8; -} msdc_pad_ctl0_reg; -typedef struct { - u32 cmddrvn:3; - u32 rsv0:1; - u32 cmddrvp:3; - u32 rsv1:1; - u32 cmdsr:1; - u32 rsv2:7; - u32 cmdpd:1; - u32 cmdpu:1; - u32 cmdsmt:1; - u32 cmdies:1; - u32 cmdtdsel:4; - u32 cmdrdsel:8; -} msdc_pad_ctl1_reg; -typedef struct { - u32 datdrvn:3; - u32 rsv0:1; - u32 datdrvp:3; - u32 rsv1:1; - u32 datsr:1; - u32 rsv2:7; - u32 datpd:1; - u32 datpu:1; - u32 datsmt:1; - u32 daties:1; - u32 dattdsel:4; - u32 datrdsel:8; -} msdc_pad_ctl2_reg; -typedef struct { - u32 wrrxdly:3; - u32 pad1:5; - u32 rdrxdly:8; - u32 pad2:16; -} msdc_pad_tune_reg; -typedef struct { - u32 dat0:5; - u32 rsv0:3; - u32 dat1:5; - u32 rsv1:3; - u32 dat2:5; - u32 rsv2:3; - u32 dat3:5; - u32 rsv3:3; -} msdc_dat_rddly0; -typedef struct { - u32 dat4:5; - u32 rsv4:3; - u32 dat5:5; - u32 rsv5:3; - u32 dat6:5; - u32 rsv6:3; - u32 dat7:5; - u32 rsv7:3; -} msdc_dat_rddly1; -typedef struct { - u32 dbg0sel:8; - u32 dbg1sel:6; - u32 pad1:2; - u32 dbg2sel:6; - u32 pad2:2; - u32 dbg3sel:6; - u32 pad3:2; -} msdc_hw_dbg_reg; -typedef struct { - u32 val; -} msdc_version_reg; -typedef struct { - u32 val; -} msdc_eco_ver_reg; +struct msdc_cfg_reg { + u32 msdc:1; + u32 ckpwn:1; + u32 rst:1; + u32 pio:1; + u32 ckdrven:1; + u32 start18v:1; + u32 pass18v:1; + u32 ckstb:1; + u32 ckdiv:8; + u32 ckmod:2; + u32 pad:14; +}; + +struct msdc_iocon_reg { + u32 sdr104cksel:1; + u32 rsmpl:1; + u32 dsmpl:1; + u32 ddlysel:1; + u32 ddr50ckd:1; + u32 dsplsel:1; + u32 pad1:10; + u32 d0spl:1; + u32 d1spl:1; + u32 d2spl:1; + u32 d3spl:1; + u32 d4spl:1; + u32 d5spl:1; + u32 d6spl:1; + u32 d7spl:1; + u32 riscsz:1; + u32 pad2:7; +}; + +struct msdc_ps_reg { + u32 cden:1; + u32 cdsts:1; + u32 pad1:10; + u32 cddebounce:4; + u32 dat:8; + u32 cmd:1; + u32 pad2:6; + u32 wp:1; +}; + +struct msdc_int_reg { + u32 mmcirq:1; + u32 cdsc:1; + u32 pad1:1; + u32 atocmdrdy:1; + u32 atocmdtmo:1; + u32 atocmdcrc:1; + u32 dmaqempty:1; + u32 sdioirq:1; + u32 cmdrdy:1; + u32 cmdtmo:1; + u32 rspcrc:1; + u32 csta:1; + u32 xfercomp:1; + u32 dxferdone:1; + u32 dattmo:1; + u32 datcrc:1; + u32 atocmd19done:1; + u32 pad2:15; +}; + +struct msdc_inten_reg { + u32 mmcirq:1; + u32 cdsc:1; + u32 pad1:1; + u32 atocmdrdy:1; + u32 atocmdtmo:1; + u32 atocmdcrc:1; + u32 dmaqempty:1; + u32 sdioirq:1; + u32 cmdrdy:1; + u32 cmdtmo:1; + u32 rspcrc:1; + u32 csta:1; + u32 xfercomp:1; + u32 dxferdone:1; + u32 dattmo:1; + u32 datcrc:1; + u32 atocmd19done:1; + u32 pad2:15; +}; + +struct msdc_fifocs_reg { + u32 rxcnt:8; + u32 pad1:8; + u32 txcnt:8; + u32 pad2:7; + u32 clr:1; +}; + +struct msdc_txdat_reg { + u32 val; +}; + +struct msdc_rxdat_reg { + u32 val; +}; + +struct sdc_cfg_reg { + u32 sdiowkup:1; + u32 inswkup:1; + u32 pad1:14; + u32 buswidth:2; + u32 pad2:1; + u32 sdio:1; + u32 sdioide:1; + u32 intblkgap:1; + u32 pad4:2; + u32 dtoc:8; +}; + +struct sdc_cmd_reg { + u32 cmd:6; + u32 brk:1; + u32 rsptyp:3; + u32 pad1:1; + u32 dtype:2; + u32 rw:1; + u32 stop:1; + u32 goirq:1; + u32 blklen:12; + u32 atocmd:2; + u32 volswth:1; + u32 pad2:1; +}; + +struct sdc_arg_reg { + u32 arg; +}; + +struct sdc_sts_reg { + u32 sdcbusy:1; + u32 cmdbusy:1; + u32 pad:29; + u32 swrcmpl:1; +}; + +struct sdc_resp0_reg { + u32 val; +}; + +struct sdc_resp1_reg { + u32 val; +}; + +struct sdc_resp2_reg { + u32 val; +}; + +struct sdc_resp3_reg { + u32 val; +}; + +struct sdc_blknum_reg { + u32 num; +}; + +struct sdc_csts_reg { + u32 sts; +}; + +struct sdc_cstsen_reg { + u32 sts; +}; + +struct sdc_datcrcsts_reg { + u32 datcrcsts:8; + u32 ddrcrcsts:4; + u32 pad:20; +}; + +struct emmc_cfg0_reg { + u32 bootstart:1; + u32 bootstop:1; + u32 bootmode:1; + u32 pad1:9; + u32 bootwaidly:3; + u32 bootsupp:1; + u32 pad2:16; +}; + +struct emmc_cfg1_reg { + u32 bootcrctmc:16; + u32 pad:4; + u32 bootacktmc:12; +}; + +struct emmc_sts_reg { + u32 bootcrcerr:1; + u32 bootackerr:1; + u32 bootdattmo:1; + u32 bootacktmo:1; + u32 bootupstate:1; + u32 bootackrcv:1; + u32 bootdatrcv:1; + u32 pad:25; +}; + +struct emmc_iocon_reg { + u32 bootrst:1; + u32 pad:31; +}; + +struct msdc_acmd_resp_reg { + u32 val; +}; + +struct msdc_acmd19_trg_reg { + u32 tunesel:4; + u32 pad:28; +}; + +struct msdc_acmd19_sts_reg { + u32 val; +}; + +struct msdc_dma_sa_reg { + u32 addr; +}; + +struct msdc_dma_ca_reg { + u32 addr; +}; + +struct msdc_dma_ctrl_reg { + u32 start:1; + u32 stop:1; + u32 resume:1; + u32 pad1:5; + u32 mode:1; + u32 pad2:1; + u32 lastbuf:1; + u32 pad3:1; + u32 brustsz:3; + u32 pad4:1; + u32 xfersz:16; +}; + +struct msdc_dma_cfg_reg { + u32 status:1; + u32 decsen:1; + u32 pad1:2; + u32 bdcsen:1; + u32 gpdcsen:1; + u32 pad2:26; +}; + +struct msdc_dbg_sel_reg { + u32 sel:16; + u32 pad2:16; +}; + +struct msdc_dbg_out_reg { + u32 val; +}; + +struct msdc_pad_ctl0_reg { + u32 clkdrvn:3; + u32 rsv0:1; + u32 clkdrvp:3; + u32 rsv1:1; + u32 clksr:1; + u32 rsv2:7; + u32 clkpd:1; + u32 clkpu:1; + u32 clksmt:1; + u32 clkies:1; + u32 clktdsel:4; + u32 clkrdsel:8; +}; + +struct msdc_pad_ctl1_reg { + u32 cmddrvn:3; + u32 rsv0:1; + u32 cmddrvp:3; + u32 rsv1:1; + u32 cmdsr:1; + u32 rsv2:7; + u32 cmdpd:1; + u32 cmdpu:1; + u32 cmdsmt:1; + u32 cmdies:1; + u32 cmdtdsel:4; + u32 cmdrdsel:8; +}; + +struct msdc_pad_ctl2_reg { + u32 datdrvn:3; + u32 rsv0:1; + u32 datdrvp:3; + u32 rsv1:1; + u32 datsr:1; + u32 rsv2:7; + u32 datpd:1; + u32 datpu:1; + u32 datsmt:1; + u32 daties:1; + u32 dattdsel:4; + u32 datrdsel:8; +}; + +struct msdc_pad_tune_reg { + u32 wrrxdly:3; + u32 pad1:5; + u32 rdrxdly:8; + u32 pad2:16; +}; + +struct msdc_dat_rddly0 { + u32 dat0:5; + u32 rsv0:3; + u32 dat1:5; + u32 rsv1:3; + u32 dat2:5; + u32 rsv2:3; + u32 dat3:5; + u32 rsv3:3; +}; + +struct msdc_dat_rddly1 { + u32 dat4:5; + u32 rsv4:3; + u32 dat5:5; + u32 rsv5:3; + u32 dat6:5; + u32 rsv6:3; + u32 dat7:5; + u32 rsv7:3; +}; + +struct msdc_hw_dbg_reg { + u32 dbg0sel:8; + u32 dbg1sel:6; + u32 pad1:2; + u32 dbg2sel:6; + u32 pad2:2; + u32 dbg3sel:6; + u32 pad3:2; +}; + +struct msdc_version_reg { + u32 val; +}; + +struct msdc_eco_ver_reg { + u32 val; +}; struct msdc_regs { - msdc_cfg_reg msdc_cfg; /* base+0x00h */ - msdc_iocon_reg msdc_iocon; /* base+0x04h */ - msdc_ps_reg msdc_ps; /* base+0x08h */ - msdc_int_reg msdc_int; /* base+0x0ch */ - msdc_inten_reg msdc_inten; /* base+0x10h */ - msdc_fifocs_reg msdc_fifocs; /* base+0x14h */ - msdc_txdat_reg msdc_txdat; /* base+0x18h */ - msdc_rxdat_reg msdc_rxdat; /* base+0x1ch */ - u32 rsv1[4]; - sdc_cfg_reg sdc_cfg; /* base+0x30h */ - sdc_cmd_reg sdc_cmd; /* base+0x34h */ - sdc_arg_reg sdc_arg; /* base+0x38h */ - sdc_sts_reg sdc_sts; /* base+0x3ch */ - sdc_resp0_reg sdc_resp0; /* base+0x40h */ - sdc_resp1_reg sdc_resp1; /* base+0x44h */ - sdc_resp2_reg sdc_resp2; /* base+0x48h */ - sdc_resp3_reg sdc_resp3; /* base+0x4ch */ - sdc_blknum_reg sdc_blknum; /* base+0x50h */ - u32 rsv2[1]; - sdc_csts_reg sdc_csts; /* base+0x58h */ - sdc_cstsen_reg sdc_cstsen; /* base+0x5ch */ - sdc_datcrcsts_reg sdc_dcrcsta; /* base+0x60h */ - u32 rsv3[3]; - emmc_cfg0_reg emmc_cfg0; /* base+0x70h */ - emmc_cfg1_reg emmc_cfg1; /* base+0x74h */ - emmc_sts_reg emmc_sts; /* base+0x78h */ - emmc_iocon_reg emmc_iocon; /* base+0x7ch */ - msdc_acmd_resp_reg acmd_resp; /* base+0x80h */ - msdc_acmd19_trg_reg acmd19_trg; /* base+0x84h */ - msdc_acmd19_sts_reg acmd19_sts; /* base+0x88h */ - u32 rsv4[1]; - msdc_dma_sa_reg dma_sa; /* base+0x90h */ - msdc_dma_ca_reg dma_ca; /* base+0x94h */ - msdc_dma_ctrl_reg dma_ctrl; /* base+0x98h */ - msdc_dma_cfg_reg dma_cfg; /* base+0x9ch */ - msdc_dbg_sel_reg dbg_sel; /* base+0xa0h */ - msdc_dbg_out_reg dbg_out; /* base+0xa4h */ - u32 rsv5[2]; - u32 patch0; /* base+0xb0h */ - u32 patch1; /* base+0xb4h */ - u32 rsv6[10]; - msdc_pad_ctl0_reg pad_ctl0; /* base+0xe0h */ - msdc_pad_ctl1_reg pad_ctl1; /* base+0xe4h */ - msdc_pad_ctl2_reg pad_ctl2; /* base+0xe8h */ - msdc_pad_tune_reg pad_tune; /* base+0xech */ - msdc_dat_rddly0 dat_rddly0; /* base+0xf0h */ - msdc_dat_rddly1 dat_rddly1; /* base+0xf4h */ - msdc_hw_dbg_reg hw_dbg; /* base+0xf8h */ - u32 rsv7[1]; - msdc_version_reg version; /* base+0x100h */ - msdc_eco_ver_reg eco_ver; /* base+0x104h */ + struct msdc_cfg_reg msdc_cfg; /* base+0x00h */ + struct msdc_iocon_reg msdc_iocon; /* base+0x04h */ + struct msdc_ps_reg msdc_ps; /* base+0x08h */ + struct msdc_int_reg msdc_int; /* base+0x0ch */ + struct msdc_inten_reg msdc_inten; /* base+0x10h */ + struct msdc_fifocs_reg msdc_fifocs; /* base+0x14h */ + struct msdc_txdat_reg msdc_txdat; /* base+0x18h */ + struct msdc_rxdat_reg msdc_rxdat; /* base+0x1ch */ + u32 rsv1[4]; + struct sdc_cfg_reg sdc_cfg; /* base+0x30h */ + struct sdc_cmd_reg sdc_cmd; /* base+0x34h */ + struct sdc_arg_reg sdc_arg; /* base+0x38h */ + struct sdc_sts_reg sdc_sts; /* base+0x3ch */ + struct sdc_resp0_reg sdc_resp0; /* base+0x40h */ + struct sdc_resp1_reg sdc_resp1; /* base+0x44h */ + struct sdc_resp2_reg sdc_resp2; /* base+0x48h */ + struct sdc_resp3_reg sdc_resp3; /* base+0x4ch */ + struct sdc_blknum_reg sdc_blknum; /* base+0x50h */ + u32 rsv2[1]; + struct sdc_csts_reg sdc_csts; /* base+0x58h */ + struct sdc_cstsen_reg sdc_cstsen; /* base+0x5ch */ + struct sdc_datcrcsts_reg sdc_dcrcsta; /* base+0x60h */ + u32 rsv3[3]; + struct emmc_cfg0_reg emmc_cfg0; /* base+0x70h */ + struct emmc_cfg1_reg emmc_cfg1; /* base+0x74h */ + struct emmc_sts_reg emmc_sts; /* base+0x78h */ + struct emmc_iocon_reg emmc_iocon; /* base+0x7ch */ + struct msdc_acmd_resp_reg acmd_resp; /* base+0x80h */ + struct msdc_acmd19_trg_reg acmd19_trg; /* base+0x84h */ + struct msdc_acmd19_sts_reg acmd19_sts; /* base+0x88h */ + u32 rsv4[1]; + struct msdc_dma_sa_reg dma_sa; /* base+0x90h */ + struct msdc_dma_ca_reg dma_ca; /* base+0x94h */ + struct msdc_dma_ctrl_reg dma_ctrl; /* base+0x98h */ + struct msdc_dma_cfg_reg dma_cfg; /* base+0x9ch */ + struct msdc_dbg_sel_reg dbg_sel; /* base+0xa0h */ + struct msdc_dbg_out_reg dbg_out; /* base+0xa4h */ + u32 rsv5[2]; + u32 patch0; /* base+0xb0h */ + u32 patch1; /* base+0xb4h */ + u32 rsv6[10]; + struct msdc_pad_ctl0_reg pad_ctl0; /* base+0xe0h */ + struct msdc_pad_ctl1_reg pad_ctl1; /* base+0xe4h */ + struct msdc_pad_ctl2_reg pad_ctl2; /* base+0xe8h */ + struct msdc_pad_tune_reg pad_tune; /* base+0xech */ + struct msdc_dat_rddly0 dat_rddly0; /* base+0xf0h */ + struct msdc_dat_rddly1 dat_rddly1; /* base+0xf4h */ + struct msdc_hw_dbg_reg hw_dbg; /* base+0xf8h */ + u32 rsv7[1]; + struct msdc_version_reg version; /* base+0x100h */ + struct msdc_eco_ver_reg eco_ver; /* base+0x104h */ }; -struct scatterlist_ex { - u32 cmd; - u32 arg; - u32 sglen; - struct scatterlist *sg; -}; - -#define DMA_FLAG_NONE (0x00000000) -#define DMA_FLAG_EN_CHKSUM (0x00000001) -#define DMA_FLAG_PAD_BLOCK (0x00000002) -#define DMA_FLAG_PAD_DWORD (0x00000004) - struct msdc_dma { - u32 flags; /* flags */ - u32 xfersz; /* xfer size in bytes */ - u32 sglen; /* size of scatter list */ - u32 blklen; /* block size */ - struct scatterlist *sg; /* I/O scatter list */ - struct scatterlist_ex *esg; /* extended I/O scatter list */ - u8 mode; /* dma mode */ - u8 burstsz; /* burst size */ - u8 intr; /* dma done interrupt */ - u8 padding; /* padding */ - u32 cmd; /* enhanced mode command */ - u32 arg; /* enhanced mode arg */ - u32 rsp; /* enhanced mode command response */ - u32 autorsp; /* auto command response */ + u32 sglen; /* size of scatter list */ + struct scatterlist *sg; /* I/O scatter list */ + u8 mode; /* dma mode */ - gpd_t *gpd; /* pointer to gpd array */ - bd_t *bd; /* pointer to bd array */ - dma_addr_t gpd_addr; /* the physical address of gpd array */ - dma_addr_t bd_addr; /* the physical address of bd array */ - u32 used_gpd; /* the number of used gpd elements */ - u32 used_bd; /* the number of used bd elements */ + struct gpd *gpd; /* pointer to gpd array */ + struct bd *bd; /* pointer to bd array */ + dma_addr_t gpd_addr; /* the physical address of gpd array */ + dma_addr_t bd_addr; /* the physical address of bd array */ }; -struct msdc_host -{ - struct msdc_hw *hw; +struct msdc_host { + struct msdc_hw *hw; - struct mmc_host *mmc; /* mmc structure */ - struct mmc_command *cmd; - struct mmc_data *data; - struct mmc_request *mrq; - int cmd_rsp; - int cmd_rsp_done; - int cmd_r1b_done; + struct mmc_host *mmc; /* mmc structure */ + struct mmc_command *cmd; + struct mmc_data *data; + struct mmc_request *mrq; + int cmd_rsp; - int error; - spinlock_t lock; /* mutex */ - struct semaphore sem; + int error; + spinlock_t lock; /* mutex */ + struct semaphore sem; - u32 blksz; /* host block size */ - u32 base; /* host base address */ - int id; /* host id */ - int pwr_ref; /* core power reference count */ + u32 blksz; /* host block size */ + void __iomem *base; /* host base address */ + int id; /* host id */ + int pwr_ref; /* core power reference count */ - u32 xfer_size; /* total transferred size */ + u32 xfer_size; /* total transferred size */ - struct msdc_dma dma; /* dma channel */ - u32 dma_addr; /* dma transfer address */ - u32 dma_left_size; /* dma transfer left size */ - u32 dma_xfer_size; /* dma transfer size in bytes */ - int dma_xfer; /* dma transfer mode */ + struct msdc_dma dma; /* dma channel */ + u32 dma_xfer_size; /* dma transfer size in bytes */ - u32 timeout_ns; /* data timeout ns */ - u32 timeout_clks; /* data timeout clks */ + u32 timeout_ns; /* data timeout ns */ + u32 timeout_clks; /* data timeout clks */ - atomic_t abort; /* abort transfer */ + int irq; /* host interrupt */ - int irq; /* host interrupt */ + struct delayed_work card_delaywork; - struct tasklet_struct card_tasklet; -#if 0 - struct work_struct card_workqueue; -#else - struct delayed_work card_delaywork; -#endif + struct completion cmd_done; + struct completion xfer_done; + struct pm_message pm_state; - struct completion cmd_done; - struct completion xfer_done; - struct pm_message pm_state; - - u32 mclk; /* mmc subsystem clock */ - u32 hclk; /* host clock speed */ - u32 sclk; /* SD/MS clock speed */ - u8 core_clkon; /* Host core clock on ? */ - u8 card_clkon; /* Card clock on ? */ - u8 core_power; /* core power */ - u8 power_mode; /* host power mode */ - u8 card_inserted; /* card inserted ? */ - u8 suspend; /* host suspended ? */ - u8 reserved; - u8 app_cmd; /* for app command */ - u32 app_cmd_arg; - u64 starttime; + u32 mclk; /* mmc subsystem clock */ + u32 hclk; /* host clock speed */ + u32 sclk; /* SD/MS clock speed */ + u8 core_clkon; /* Host core clock on ? */ + u8 card_clkon; /* Card clock on ? */ + u8 core_power; /* core power */ + u8 power_mode; /* host power mode */ + u8 card_inserted; /* card inserted ? */ + u8 suspend; /* host suspended ? */ + u8 app_cmd; /* for app command */ + u32 app_cmd_arg; }; -static inline unsigned int uffs(unsigned int x) -{ - unsigned int r = 1; +#define sdr_read8(reg) readb(reg) +#define sdr_read32(reg) readl(reg) +#define sdr_write8(reg, val) writeb(val, reg) +#define sdr_write32(reg, val) writel(val, reg) - if (!x) - return 0; - if (!(x & 0xffff)) { - x >>= 16; - r += 16; - } - if (!(x & 0xff)) { - x >>= 8; - r += 8; - } - if (!(x & 0xf)) { - x >>= 4; - r += 4; - } - if (!(x & 3)) { - x >>= 2; - r += 2; - } - if (!(x & 1)) { - x >>= 1; - r += 1; - } - return r; +static inline void sdr_set_bits(void __iomem *reg, u32 bs) +{ + u32 val = readl(reg); + + val |= bs; + writel(val, reg); } -#define sdr_read8(reg) __raw_readb(reg) -#define sdr_read16(reg) __raw_readw(reg) -#define sdr_read32(reg) __raw_readl(reg) -#define sdr_write8(reg,val) __raw_writeb(val,reg) -#define sdr_write16(reg,val) __raw_writew(val,reg) -#define sdr_write32(reg,val) __raw_writel(val,reg) -#define sdr_set_bits(reg,bs) ((*(volatile u32*)(reg)) |= (u32)(bs)) -#define sdr_clr_bits(reg,bs) ((*(volatile u32*)(reg)) &= ~((u32)(bs))) +static inline void sdr_clr_bits(void __iomem *reg, u32 bs) +{ + u32 val = readl(reg); -#define sdr_set_field(reg,field,val) \ - do { \ - volatile unsigned int tv = sdr_read32(reg); \ - tv &= ~(field); \ - tv |= ((val) << (uffs((unsigned int)field) - 1)); \ - sdr_write32(reg,tv); \ - } while(0) -#define sdr_get_field(reg,field,val) \ - do { \ - volatile unsigned int tv = sdr_read32(reg); \ - val = ((tv & (field)) >> (uffs((unsigned int)field) - 1)); \ - } while(0) + val &= ~bs; + writel(val, reg); +} + +static inline void sdr_set_field(void __iomem *reg, u32 field, u32 val) +{ + unsigned int tv = readl(reg); + + tv &= ~field; + tv |= ((val) << (ffs((unsigned int)field) - 1)); + writel(tv, reg); +} + +static inline void sdr_get_field(void __iomem *reg, u32 field, u32 *val) +{ + unsigned int tv = readl(reg); + *val = ((tv & field) >> (ffs((unsigned int)field) - 1)); +} #endif - diff --git a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/sd.c b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/sd.c index 3a146f646..2a032fcba 100644 --- a/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/sd.c +++ b/target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/sd.c @@ -34,38 +34,22 @@ */ #include -#include -#include +#include +#include #include -#include -#include -#include #include #include -#include -#include -#include + #include -#include -#include #include #include #include -#include -/* +++ by chhung */ -#include -#include -#include -#include -#include +#include -#define MSDC_SMPL_FALLING (1) -#define MSDC_CD_PIN_EN (1 << 0) /* card detection pin is wired */ -#define MSDC_WP_PIN_EN (1 << 1) /* write protection pin is wired */ -#define MSDC_REMOVABLE (1 << 5) /* removable slot */ -#define MSDC_SYS_SUSPEND (1 << 6) /* suspended by system */ -#define MSDC_HIGHSPEED (1 << 7) +#include "board.h" +#include "dbg.h" +#include "mt6575_sd.h" //#define IRQ_SDC 14 //MT7620 /*FIXME*/ #ifdef CONFIG_SOC_MT7621 @@ -77,46 +61,11 @@ #endif #define IRQ_SDC 22 /*FIXME*/ -#include -/* end of +++ */ - - -#include - -#if 0 /* --- by chhung */ -#include -#include -#include -#include -#include -//#include -//#include -//#include -#include -// #include -#endif /* end of --- */ - -#include "mt6575_sd.h" -#include "dbg.h" - -/* +++ by chhung */ -#include "board.h" -/* end of +++ */ - -#if 0 /* --- by chhung */ -#define isb() __asm__ __volatile__ ("" : : : "memory") -#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ - : : "r" (0) : "memory") -#define dmb() __asm__ __volatile__ ("" : : : "memory") -#endif /* end of --- */ - #define DRV_NAME "mtk-sd" -#define HOST_MAX_NUM (1) /* +/- by chhung */ - -#if defined (CONFIG_SOC_MT7620) +#if defined(CONFIG_SOC_MT7620) #define HOST_MAX_MCLK (48000000) /* +/- by chhung */ -#elif defined (CONFIG_SOC_MT7621) +#elif defined(CONFIG_SOC_MT7621) #define HOST_MAX_MCLK (50000000) /* +/- by chhung */ #endif #define HOST_MIN_MCLK (260000) @@ -130,14 +79,14 @@ #if 0 /* --- by chhung */ #define MSDC_CLKSRC_REG (0xf100000C) -#define PDN_REG (0xF1000010) +#define PDN_REG (0xF1000010) #endif /* end of --- */ #define DEFAULT_DEBOUNCE (8) /* 8 cycles */ #define DEFAULT_DTOC (40) /* data timeout counter. 65536x40 sclk. */ -#define CMD_TIMEOUT (HZ/10) /* 100ms */ -#define DAT_TIMEOUT (HZ/2 * 5) /* 500ms x5 */ +#define CMD_TIMEOUT (HZ / 10) /* 100ms */ +#define DAT_TIMEOUT (HZ / 2 * 5) /* 500ms x5 */ #define MAX_DMA_CNT (64 * 1024 - 512) /* a single transaction for WIFI may be 50K*/ @@ -148,9 +97,7 @@ #define MAX_HW_SGMTS (MAX_BD_NUM) #define MAX_PHY_SGMTS (MAX_BD_NUM) #define MAX_SGMT_SZ (MAX_DMA_CNT) -#define MAX_REQ_SZ (MAX_SGMT_SZ * 8) - -static int mtk_sw_poll; +#define MAX_REQ_SZ (MAX_SGMT_SZ * 8) static int cd_active_low = 1; @@ -162,200 +109,147 @@ static int cd_active_low = 1; #if 0 /* --- by chhung */ /* gate means clock power down */ -static int g_clk_gate = 0; +static int g_clk_gate = 0; #define msdc_gate_clock(id) \ - do { \ - g_clk_gate &= ~(1 << ((id) + PERI_MSDC0_PDN)); \ - } while(0) + do { \ + g_clk_gate &= ~(1 << ((id) + PERI_MSDC0_PDN)); \ + } while (0) /* not like power down register. 1 means clock on. */ #define msdc_ungate_clock(id) \ - do { \ - g_clk_gate |= 1 << ((id) + PERI_MSDC0_PDN); \ - } while(0) + do { \ + g_clk_gate |= 1 << ((id) + PERI_MSDC0_PDN); \ + } while (0) -// do we need sync object or not -void msdc_clk_status(int * status) +// do we need sync object or not +void msdc_clk_status(int *status) { - *status = g_clk_gate; + *status = g_clk_gate; } #endif /* end of --- */ /* +++ by chhung */ struct msdc_hw msdc0_hw = { .clk_src = 0, - .cmd_edge = MSDC_SMPL_FALLING, - .data_edge = MSDC_SMPL_FALLING, - .clk_drv = 4, - .cmd_drv = 4, - .dat_drv = 4, - .data_pins = 4, - .data_offset = 0, - .flags = MSDC_SYS_SUSPEND | MSDC_CD_PIN_EN | MSDC_REMOVABLE | MSDC_HIGHSPEED, -// .flags = MSDC_SYS_SUSPEND | MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE, + .flags = MSDC_CD_PIN_EN | MSDC_REMOVABLE, +// .flags = MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE, }; -static struct resource mtk_sd_resources[] = { - [0] = { - .start = RALINK_MSDC_BASE, - .end = RALINK_MSDC_BASE+0x3fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_SDC, /*FIXME*/ - .end = IRQ_SDC, /*FIXME*/ - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device mtk_sd_device = { - .name = "mtk-sd", - .id = 0, - .num_resources = ARRAY_SIZE(mtk_sd_resources), - .resource = mtk_sd_resources, -}; /* end of +++ */ static int msdc_rsp[] = { - 0, /* RESP_NONE */ - 1, /* RESP_R1 */ - 2, /* RESP_R2 */ - 3, /* RESP_R3 */ - 4, /* RESP_R4 */ - 1, /* RESP_R5 */ - 1, /* RESP_R6 */ - 1, /* RESP_R7 */ - 7, /* RESP_R1b */ + 0, /* RESP_NONE */ + 1, /* RESP_R1 */ + 2, /* RESP_R2 */ + 3, /* RESP_R3 */ + 4, /* RESP_R4 */ + 1, /* RESP_R5 */ + 1, /* RESP_R6 */ + 1, /* RESP_R7 */ + 7, /* RESP_R1b */ }; -/* For Inhanced DMA */ -#define msdc_init_gpd_ex(gpd,extlen,cmd,arg,blknum) \ - do { \ - ((gpd_t*)gpd)->extlen = extlen; \ - ((gpd_t*)gpd)->cmd = cmd; \ - ((gpd_t*)gpd)->arg = arg; \ - ((gpd_t*)gpd)->blknum = blknum; \ - }while(0) - -#define msdc_init_bd(bd, blkpad, dwpad, dptr, dlen) \ - do { \ - BUG_ON(dlen > 0xFFFFUL); \ - ((bd_t*)bd)->blkpad = blkpad; \ - ((bd_t*)bd)->dwpad = dwpad; \ - ((bd_t*)bd)->ptr = (void*)dptr; \ - ((bd_t*)bd)->buflen = dlen; \ - }while(0) - #define msdc_txfifocnt() ((sdr_read32(MSDC_FIFOCS) & MSDC_FIFOCS_TXCNT) >> 16) #define msdc_rxfifocnt() ((sdr_read32(MSDC_FIFOCS) & MSDC_FIFOCS_RXCNT) >> 0) #define msdc_fifo_write32(v) sdr_write32(MSDC_TXDATA, (v)) #define msdc_fifo_write8(v) sdr_write8(MSDC_TXDATA, (v)) #define msdc_fifo_read32() sdr_read32(MSDC_RXDATA) -#define msdc_fifo_read8() sdr_read8(MSDC_RXDATA) - +#define msdc_fifo_read8() sdr_read8(MSDC_RXDATA) #define msdc_dma_on() sdr_clr_bits(MSDC_CFG, MSDC_CFG_PIO) -#define msdc_dma_off() sdr_set_bits(MSDC_CFG, MSDC_CFG_PIO) -#define msdc_retry(expr,retry,cnt) \ - do { \ - int backup = cnt; \ - while (retry) { \ - if (!(expr)) break; \ - if (cnt-- == 0) { \ - retry--; mdelay(1); cnt = backup; \ - } \ - } \ - WARN_ON(retry == 0); \ - } while(0) +#define msdc_retry(expr, retry, cnt) \ + do { \ + int backup = cnt; \ + while (retry) { \ + if (!(expr)) \ + break; \ + if (cnt-- == 0) { \ + retry--; mdelay(1); cnt = backup; \ + } \ + } \ + WARN_ON(retry == 0); \ + } while (0) -#if 0 /* --- by chhung */ -#define msdc_reset() \ - do { \ - int retry = 3, cnt = 1000; \ - sdr_set_bits(MSDC_CFG, MSDC_CFG_RST); \ - dsb(); \ - msdc_retry(sdr_read32(MSDC_CFG) & MSDC_CFG_RST, retry, cnt); \ - } while(0) -#else -#define msdc_reset() \ - do { \ - int retry = 3, cnt = 1000; \ - sdr_set_bits(MSDC_CFG, MSDC_CFG_RST); \ - msdc_retry(sdr_read32(MSDC_CFG) & MSDC_CFG_RST, retry, cnt); \ - } while(0) -#endif /* end of +/- */ +static void msdc_reset_hw(struct msdc_host *host) +{ + void __iomem *base = host->base; + + sdr_set_bits(MSDC_CFG, MSDC_CFG_RST); + while (sdr_read32(MSDC_CFG) & MSDC_CFG_RST) + cpu_relax(); +} #define msdc_clr_int() \ - do { \ - volatile u32 val = sdr_read32(MSDC_INT); \ - sdr_write32(MSDC_INT, val); \ - } while(0) + do { \ + volatile u32 val = sdr_read32(MSDC_INT); \ + sdr_write32(MSDC_INT, val); \ + } while (0) #define msdc_clr_fifo() \ - do { \ - int retry = 3, cnt = 1000; \ - sdr_set_bits(MSDC_FIFOCS, MSDC_FIFOCS_CLR); \ - msdc_retry(sdr_read32(MSDC_FIFOCS) & MSDC_FIFOCS_CLR, retry, cnt); \ - } while(0) + do { \ + int retry = 3, cnt = 1000; \ + sdr_set_bits(MSDC_FIFOCS, MSDC_FIFOCS_CLR); \ + msdc_retry(sdr_read32(MSDC_FIFOCS) & MSDC_FIFOCS_CLR, retry, cnt); \ + } while (0) #define msdc_irq_save(val) \ - do { \ - val = sdr_read32(MSDC_INTEN); \ - sdr_clr_bits(MSDC_INTEN, val); \ - } while(0) - + do { \ + val = sdr_read32(MSDC_INTEN); \ + sdr_clr_bits(MSDC_INTEN, val); \ + } while (0) + #define msdc_irq_restore(val) \ - do { \ - sdr_set_bits(MSDC_INTEN, val); \ - } while(0) + do { \ + sdr_set_bits(MSDC_INTEN, val); \ + } while (0) /* clock source for host: global */ -#if defined (CONFIG_SOC_MT7620) +#if defined(CONFIG_SOC_MT7620) static u32 hclks[] = {48000000}; /* +/- by chhung */ -#elif defined (CONFIG_SOC_MT7621) +#elif defined(CONFIG_SOC_MT7621) static u32 hclks[] = {50000000}; /* +/- by chhung */ #endif //============================================ // the power for msdc host controller: global -// always keep the VMC on. +// always keep the VMC on. //============================================ #define msdc_vcore_on(host) \ - do { \ - INIT_MSG("[+]VMC ref. count<%d>", ++host->pwr_ref); \ - (void)hwPowerOn(MT65XX_POWER_LDO_VMC, VOL_3300, "SD"); \ - } while (0) + do { \ + INIT_MSG("[+]VMC ref. count<%d>", ++host->pwr_ref); \ + (void)hwPowerOn(MT65XX_POWER_LDO_VMC, VOL_3300, "SD"); \ + } while (0) #define msdc_vcore_off(host) \ - do { \ - INIT_MSG("[-]VMC ref. count<%d>", --host->pwr_ref); \ - (void)hwPowerDown(MT65XX_POWER_LDO_VMC, "SD"); \ - } while (0) + do { \ + INIT_MSG("[-]VMC ref. count<%d>", --host->pwr_ref); \ + (void)hwPowerDown(MT65XX_POWER_LDO_VMC, "SD"); \ + } while (0) //==================================== -// the vdd output for card: global -// always keep the VMCH on. -//==================================== +// the vdd output for card: global +// always keep the VMCH on. +//==================================== #define msdc_vdd_on(host) \ - do { \ - (void)hwPowerOn(MT65XX_POWER_LDO_VMCH, VOL_3300, "SD"); \ - } while (0) + do { \ + (void)hwPowerOn(MT65XX_POWER_LDO_VMCH, VOL_3300, "SD"); \ + } while (0) #define msdc_vdd_off(host) \ - do { \ - (void)hwPowerDown(MT65XX_POWER_LDO_VMCH, "SD"); \ - } while (0) + do { \ + (void)hwPowerDown(MT65XX_POWER_LDO_VMCH, "SD"); \ + } while (0) #define sdc_is_busy() (sdr_read32(SDC_STS) & SDC_STS_SDCBUSY) #define sdc_is_cmd_busy() (sdr_read32(SDC_STS) & SDC_STS_CMDBUSY) -#define sdc_send_cmd(cmd,arg) \ - do { \ - sdr_write32(SDC_ARG, (arg)); \ - sdr_write32(SDC_CMD, (cmd)); \ - } while(0) +#define sdc_send_cmd(cmd, arg) \ + do { \ + sdr_write32(SDC_ARG, (arg)); \ + sdr_write32(SDC_CMD, (cmd)); \ + } while (0) // can modify to read h/w register. //#define is_card_present(h) ((sdr_read32(MSDC_PS) & MSDC_PS_CDSTS) ? 0 : 1); -#define is_card_present(h) (((struct msdc_host*)(h))->card_inserted) +#define is_card_present(h) (((struct msdc_host *)(h))->card_inserted) /* +++ by chhung */ #ifndef __ASSEMBLY__ @@ -364,2013 +258,1621 @@ static u32 hclks[] = {50000000}; /* +/- by chhung */ #define PHYSADDR(a) ((a) & 0x1fffffff) #endif /* end of +++ */ -static unsigned int msdc_do_command(struct msdc_host *host, - struct mmc_command *cmd, - int tune, - unsigned long timeout); - -static int msdc_tune_cmdrsp(struct msdc_host*host,struct mmc_command *cmd); +static unsigned int msdc_do_command(struct msdc_host *host, + struct mmc_command *cmd, + int tune, + unsigned long timeout); + +static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd); #ifdef MT6575_SD_DEBUG static void msdc_dump_card_status(struct msdc_host *host, u32 status) { - static char *state[] = { - "Idle", /* 0 */ - "Ready", /* 1 */ - "Ident", /* 2 */ - "Stby", /* 3 */ - "Tran", /* 4 */ - "Data", /* 5 */ - "Rcv", /* 6 */ - "Prg", /* 7 */ - "Dis", /* 8 */ - "Reserved", /* 9 */ - "Reserved", /* 10 */ - "Reserved", /* 11 */ - "Reserved", /* 12 */ - "Reserved", /* 13 */ - "Reserved", /* 14 */ - "I/O mode", /* 15 */ - }; - if (status & R1_OUT_OF_RANGE) - N_MSG(RSP, "[CARD_STATUS] Out of Range"); - if (status & R1_ADDRESS_ERROR) - N_MSG(RSP, "[CARD_STATUS] Address Error"); - if (status & R1_BLOCK_LEN_ERROR) - N_MSG(RSP, "[CARD_STATUS] Block Len Error"); - if (status & R1_ERASE_SEQ_ERROR) - N_MSG(RSP, "[CARD_STATUS] Erase Seq Error"); - if (status & R1_ERASE_PARAM) - N_MSG(RSP, "[CARD_STATUS] Erase Param"); - if (status & R1_WP_VIOLATION) - N_MSG(RSP, "[CARD_STATUS] WP Violation"); - if (status & R1_CARD_IS_LOCKED) - N_MSG(RSP, "[CARD_STATUS] Card is Locked"); - if (status & R1_LOCK_UNLOCK_FAILED) - N_MSG(RSP, "[CARD_STATUS] Lock/Unlock Failed"); - if (status & R1_COM_CRC_ERROR) - N_MSG(RSP, "[CARD_STATUS] Command CRC Error"); - if (status & R1_ILLEGAL_COMMAND) - N_MSG(RSP, "[CARD_STATUS] Illegal Command"); - if (status & R1_CARD_ECC_FAILED) - N_MSG(RSP, "[CARD_STATUS] Card ECC Failed"); - if (status & R1_CC_ERROR) - N_MSG(RSP, "[CARD_STATUS] CC Error"); - if (status & R1_ERROR) - N_MSG(RSP, "[CARD_STATUS] Error"); - if (status & R1_UNDERRUN) - N_MSG(RSP, "[CARD_STATUS] Underrun"); - if (status & R1_OVERRUN) - N_MSG(RSP, "[CARD_STATUS] Overrun"); - if (status & R1_CID_CSD_OVERWRITE) - N_MSG(RSP, "[CARD_STATUS] CID/CSD Overwrite"); - if (status & R1_WP_ERASE_SKIP) - N_MSG(RSP, "[CARD_STATUS] WP Eraser Skip"); - if (status & R1_CARD_ECC_DISABLED) - N_MSG(RSP, "[CARD_STATUS] Card ECC Disabled"); - if (status & R1_ERASE_RESET) - N_MSG(RSP, "[CARD_STATUS] Erase Reset"); - if (status & R1_READY_FOR_DATA) - N_MSG(RSP, "[CARD_STATUS] Ready for Data"); - if (status & R1_SWITCH_ERROR) - N_MSG(RSP, "[CARD_STATUS] Switch error"); - if (status & R1_APP_CMD) - N_MSG(RSP, "[CARD_STATUS] App Command"); - - N_MSG(RSP, "[CARD_STATUS] '%s' State", state[R1_CURRENT_STATE(status)]); +/* N_MSG is currently a no-op */ +#if 0 + static char *state[] = { + "Idle", /* 0 */ + "Ready", /* 1 */ + "Ident", /* 2 */ + "Stby", /* 3 */ + "Tran", /* 4 */ + "Data", /* 5 */ + "Rcv", /* 6 */ + "Prg", /* 7 */ + "Dis", /* 8 */ + "Reserved", /* 9 */ + "Reserved", /* 10 */ + "Reserved", /* 11 */ + "Reserved", /* 12 */ + "Reserved", /* 13 */ + "Reserved", /* 14 */ + "I/O mode", /* 15 */ + }; +#endif + if (status & R1_OUT_OF_RANGE) + N_MSG(RSP, "[CARD_STATUS] Out of Range"); + if (status & R1_ADDRESS_ERROR) + N_MSG(RSP, "[CARD_STATUS] Address Error"); + if (status & R1_BLOCK_LEN_ERROR) + N_MSG(RSP, "[CARD_STATUS] Block Len Error"); + if (status & R1_ERASE_SEQ_ERROR) + N_MSG(RSP, "[CARD_STATUS] Erase Seq Error"); + if (status & R1_ERASE_PARAM) + N_MSG(RSP, "[CARD_STATUS] Erase Param"); + if (status & R1_WP_VIOLATION) + N_MSG(RSP, "[CARD_STATUS] WP Violation"); + if (status & R1_CARD_IS_LOCKED) + N_MSG(RSP, "[CARD_STATUS] Card is Locked"); + if (status & R1_LOCK_UNLOCK_FAILED) + N_MSG(RSP, "[CARD_STATUS] Lock/Unlock Failed"); + if (status & R1_COM_CRC_ERROR) + N_MSG(RSP, "[CARD_STATUS] Command CRC Error"); + if (status & R1_ILLEGAL_COMMAND) + N_MSG(RSP, "[CARD_STATUS] Illegal Command"); + if (status & R1_CARD_ECC_FAILED) + N_MSG(RSP, "[CARD_STATUS] Card ECC Failed"); + if (status & R1_CC_ERROR) + N_MSG(RSP, "[CARD_STATUS] CC Error"); + if (status & R1_ERROR) + N_MSG(RSP, "[CARD_STATUS] Error"); + if (status & R1_UNDERRUN) + N_MSG(RSP, "[CARD_STATUS] Underrun"); + if (status & R1_OVERRUN) + N_MSG(RSP, "[CARD_STATUS] Overrun"); + if (status & R1_CID_CSD_OVERWRITE) + N_MSG(RSP, "[CARD_STATUS] CID/CSD Overwrite"); + if (status & R1_WP_ERASE_SKIP) + N_MSG(RSP, "[CARD_STATUS] WP Eraser Skip"); + if (status & R1_CARD_ECC_DISABLED) + N_MSG(RSP, "[CARD_STATUS] Card ECC Disabled"); + if (status & R1_ERASE_RESET) + N_MSG(RSP, "[CARD_STATUS] Erase Reset"); + if (status & R1_READY_FOR_DATA) + N_MSG(RSP, "[CARD_STATUS] Ready for Data"); + if (status & R1_SWITCH_ERROR) + N_MSG(RSP, "[CARD_STATUS] Switch error"); + if (status & R1_APP_CMD) + N_MSG(RSP, "[CARD_STATUS] App Command"); + + N_MSG(RSP, "[CARD_STATUS] '%s' State", state[R1_CURRENT_STATE(status)]); } static void msdc_dump_ocr_reg(struct msdc_host *host, u32 resp) { - if (resp & (1 << 7)) - N_MSG(RSP, "[OCR] Low Voltage Range"); - if (resp & (1 << 15)) - N_MSG(RSP, "[OCR] 2.7-2.8 volt"); - if (resp & (1 << 16)) - N_MSG(RSP, "[OCR] 2.8-2.9 volt"); - if (resp & (1 << 17)) - N_MSG(RSP, "[OCR] 2.9-3.0 volt"); - if (resp & (1 << 18)) - N_MSG(RSP, "[OCR] 3.0-3.1 volt"); - if (resp & (1 << 19)) - N_MSG(RSP, "[OCR] 3.1-3.2 volt"); - if (resp & (1 << 20)) - N_MSG(RSP, "[OCR] 3.2-3.3 volt"); - if (resp & (1 << 21)) - N_MSG(RSP, "[OCR] 3.3-3.4 volt"); - if (resp & (1 << 22)) - N_MSG(RSP, "[OCR] 3.4-3.5 volt"); - if (resp & (1 << 23)) - N_MSG(RSP, "[OCR] 3.5-3.6 volt"); - if (resp & (1 << 24)) - N_MSG(RSP, "[OCR] Switching to 1.8V Accepted (S18A)"); - if (resp & (1 << 30)) - N_MSG(RSP, "[OCR] Card Capacity Status (CCS)"); - if (resp & (1 << 31)) - N_MSG(RSP, "[OCR] Card Power Up Status (Idle)"); - else - N_MSG(RSP, "[OCR] Card Power Up Status (Busy)"); + if (resp & (1 << 7)) + N_MSG(RSP, "[OCR] Low Voltage Range"); + if (resp & (1 << 15)) + N_MSG(RSP, "[OCR] 2.7-2.8 volt"); + if (resp & (1 << 16)) + N_MSG(RSP, "[OCR] 2.8-2.9 volt"); + if (resp & (1 << 17)) + N_MSG(RSP, "[OCR] 2.9-3.0 volt"); + if (resp & (1 << 18)) + N_MSG(RSP, "[OCR] 3.0-3.1 volt"); + if (resp & (1 << 19)) + N_MSG(RSP, "[OCR] 3.1-3.2 volt"); + if (resp & (1 << 20)) + N_MSG(RSP, "[OCR] 3.2-3.3 volt"); + if (resp & (1 << 21)) + N_MSG(RSP, "[OCR] 3.3-3.4 volt"); + if (resp & (1 << 22)) + N_MSG(RSP, "[OCR] 3.4-3.5 volt"); + if (resp & (1 << 23)) + N_MSG(RSP, "[OCR] 3.5-3.6 volt"); + if (resp & (1 << 24)) + N_MSG(RSP, "[OCR] Switching to 1.8V Accepted (S18A)"); + if (resp & (1 << 30)) + N_MSG(RSP, "[OCR] Card Capacity Status (CCS)"); + if (resp & (1 << 31)) + N_MSG(RSP, "[OCR] Card Power Up Status (Idle)"); + else + N_MSG(RSP, "[OCR] Card Power Up Status (Busy)"); } static void msdc_dump_rca_resp(struct msdc_host *host, u32 resp) { - u32 status = (((resp >> 15) & 0x1) << 23) | - (((resp >> 14) & 0x1) << 22) | - (((resp >> 13) & 0x1) << 19) | - (resp & 0x1fff); - - N_MSG(RSP, "[RCA] 0x%.4x", resp >> 16); - msdc_dump_card_status(host, status); + u32 status = (((resp >> 15) & 0x1) << 23) | + (((resp >> 14) & 0x1) << 22) | + (((resp >> 13) & 0x1) << 19) | + (resp & 0x1fff); + + N_MSG(RSP, "[RCA] 0x%.4x", resp >> 16); + msdc_dump_card_status(host, status); } static void msdc_dump_io_resp(struct msdc_host *host, u32 resp) { - u32 flags = (resp >> 8) & 0xFF; - char *state[] = {"DIS", "CMD", "TRN", "RFU"}; - - if (flags & (1 << 7)) - N_MSG(RSP, "[IO] COM_CRC_ERR"); - if (flags & (1 << 6)) - N_MSG(RSP, "[IO] Illgal command"); - if (flags & (1 << 3)) - N_MSG(RSP, "[IO] Error"); - if (flags & (1 << 2)) - N_MSG(RSP, "[IO] RFU"); - if (flags & (1 << 1)) - N_MSG(RSP, "[IO] Function number error"); - if (flags & (1 << 0)) - N_MSG(RSP, "[IO] Out of range"); + u32 flags = (resp >> 8) & 0xFF; +#if 0 + char *state[] = {"DIS", "CMD", "TRN", "RFU"}; +#endif + if (flags & (1 << 7)) + N_MSG(RSP, "[IO] COM_CRC_ERR"); + if (flags & (1 << 6)) + N_MSG(RSP, "[IO] Illgal command"); + if (flags & (1 << 3)) + N_MSG(RSP, "[IO] Error"); + if (flags & (1 << 2)) + N_MSG(RSP, "[IO] RFU"); + if (flags & (1 << 1)) + N_MSG(RSP, "[IO] Function number error"); + if (flags & (1 << 0)) + N_MSG(RSP, "[IO] Out of range"); - N_MSG(RSP, "[IO] State: %s, Data:0x%x", state[(resp >> 12) & 0x3], resp & 0xFF); + N_MSG(RSP, "[IO] State: %s, Data:0x%x", state[(resp >> 12) & 0x3], resp & 0xFF); } #endif static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) { - u32 base = host->base; - u32 timeout, clk_ns; + void __iomem *base = host->base; + u32 timeout, clk_ns; - host->timeout_ns = ns; - host->timeout_clks = clks; + host->timeout_ns = ns; + host->timeout_clks = clks; - clk_ns = 1000000000UL / host->sclk; - timeout = ns / clk_ns + clks; - timeout = timeout >> 16; /* in 65536 sclk cycle unit */ - timeout = timeout > 1 ? timeout - 1 : 0; - timeout = timeout > 255 ? 255 : timeout; + clk_ns = 1000000000UL / host->sclk; + timeout = ns / clk_ns + clks; + timeout = timeout >> 16; /* in 65536 sclk cycle unit */ + timeout = timeout > 1 ? timeout - 1 : 0; + timeout = timeout > 255 ? 255 : timeout; - sdr_set_field(SDC_CFG, SDC_CFG_DTOC, timeout); + sdr_set_field(SDC_CFG, SDC_CFG_DTOC, timeout); - N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 65536 cycles", - ns, clks, timeout + 1); + N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 65536 cycles", + ns, clks, timeout + 1); } -/* msdc_eirq_sdio() will be called when EIRQ(for WIFI) */ -static void msdc_eirq_sdio(void *data) -{ - struct msdc_host *host = (struct msdc_host *)data; - - N_MSG(INT, "SDIO EINT"); - - mmc_signal_sdio_irq(host->mmc); -} - -/* msdc_eirq_cd will not be used! We not using EINT for card detection. */ -static void msdc_eirq_cd(void *data) -{ - struct msdc_host *host = (struct msdc_host *)data; - - N_MSG(INT, "CD EINT"); - -#if 0 - tasklet_hi_schedule(&host->card_tasklet); -#else - schedule_delayed_work(&host->card_delaywork, HZ); -#endif -} - -#if 0 -static void msdc_tasklet_card(unsigned long arg) -{ - struct msdc_host *host = (struct msdc_host *)arg; -#else static void msdc_tasklet_card(struct work_struct *work) { - struct msdc_host *host = (struct msdc_host *)container_of(work, - struct msdc_host, card_delaywork.work); -#endif - struct msdc_hw *hw = host->hw; - u32 base = host->base; - u32 inserted; - u32 status = 0; + struct msdc_host *host = (struct msdc_host *)container_of(work, + struct msdc_host, card_delaywork.work); + void __iomem *base = host->base; + u32 inserted; + u32 status = 0; //u32 change = 0; - spin_lock(&host->lock); + spin_lock(&host->lock); - if (hw->get_cd_status) { // NULL - inserted = hw->get_cd_status(); - } else { - status = sdr_read32(MSDC_PS); - if (cd_active_low) + status = sdr_read32(MSDC_PS); + if (cd_active_low) inserted = (status & MSDC_PS_CDSTS) ? 0 : 1; else - inserted = (status & MSDC_PS_CDSTS) ? 1 : 0; - } - if (host->mmc->caps & MMC_CAP_NEEDS_POLL) - inserted = 1; + inserted = (status & MSDC_PS_CDSTS) ? 1 : 0; #if 0 - change = host->card_inserted ^ inserted; - host->card_inserted = inserted; - - if (change && !host->suspend) { - if (inserted) { - host->mmc->f_max = HOST_MAX_MCLK; // work around - } - mmc_detect_change(host->mmc, msecs_to_jiffies(20)); - } + change = host->card_inserted ^ inserted; + host->card_inserted = inserted; + + if (change && !host->suspend) { + if (inserted) + host->mmc->f_max = HOST_MAX_MCLK; // work around + mmc_detect_change(host->mmc, msecs_to_jiffies(20)); + } #else /* Make sure: handle the last interrupt */ - host->card_inserted = inserted; - - if (!host->suspend) { - host->mmc->f_max = HOST_MAX_MCLK; - mmc_detect_change(host->mmc, msecs_to_jiffies(20)); - } - - IRQ_MSG("card found<%s>", inserted ? "inserted" : "removed"); + host->card_inserted = inserted; + + if (!host->suspend) { + host->mmc->f_max = HOST_MAX_MCLK; + mmc_detect_change(host->mmc, msecs_to_jiffies(20)); + } + + IRQ_MSG("card found<%s>", inserted ? "inserted" : "removed"); #endif - spin_unlock(&host->lock); + spin_unlock(&host->lock); } #if 0 /* --- by chhung */ /* For E2 only */ static u8 clk_src_bit[4] = { - 0, 3, 5, 7 + 0, 3, 5, 7 }; -static void msdc_select_clksrc(struct msdc_host* host, unsigned char clksrc) +static void msdc_select_clksrc(struct msdc_host *host, unsigned char clksrc) { - u32 val; - u32 base = host->base; - - BUG_ON(clksrc > 3); - INIT_MSG("set clock source to <%d>", clksrc); + u32 val; + void __iomem *base = host->base; - val = sdr_read32(MSDC_CLKSRC_REG); - if (sdr_read32(MSDC_ECO_VER) >= 4) { - val &= ~(0x3 << clk_src_bit[host->id]); - val |= clksrc << clk_src_bit[host->id]; - } else { - val &= ~0x3; val |= clksrc; - } - sdr_write32(MSDC_CLKSRC_REG, val); - - host->hclk = hclks[clksrc]; - host->hw->clk_src = clksrc; + BUG_ON(clksrc > 3); + INIT_MSG("set clock source to <%d>", clksrc); + + val = sdr_read32(MSDC_CLKSRC_REG); + if (sdr_read32(MSDC_ECO_VER) >= 4) { + val &= ~(0x3 << clk_src_bit[host->id]); + val |= clksrc << clk_src_bit[host->id]; + } else { + val &= ~0x3; val |= clksrc; + } + sdr_write32(MSDC_CLKSRC_REG, val); + + host->hclk = hclks[clksrc]; + host->hw->clk_src = clksrc; } #endif /* end of --- */ static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz) { - //struct msdc_hw *hw = host->hw; - u32 base = host->base; - u32 mode; - u32 flags; - u32 div; - u32 sclk; - u32 hclk = host->hclk; - //u8 clksrc = hw->clk_src; + //struct msdc_hw *hw = host->hw; + void __iomem *base = host->base; + u32 mode; + u32 flags; + u32 div; + u32 sclk; + u32 hclk = host->hclk; + //u8 clksrc = hw->clk_src; - if (!hz) { // set mmc system clock to 0 ? - //ERR_MSG("set mclk to 0!!!"); - msdc_reset(); - return; - } + if (!hz) { // set mmc system clock to 0 ? + //ERR_MSG("set mclk to 0!!!"); + msdc_reset_hw(host); + return; + } - msdc_irq_save(flags); - -#if defined (CONFIG_MT7621_FPGA) || defined (CONFIG_MT7628_FPGA) - mode = 0x0; /* use divisor */ - if (hz >= (hclk >> 1)) { - div = 0; /* mean div = 1/2 */ - sclk = hclk >> 1; /* sclk = clk / 2 */ - } else { - div = (hclk + ((hz << 2) - 1)) / (hz << 2); - sclk = (hclk >> 2) / div; - } -#else - if (ddr) { - mode = 0x2; /* ddr mode and use divisor */ - if (hz >= (hclk >> 2)) { - div = 1; /* mean div = 1/4 */ - sclk = hclk >> 2; /* sclk = clk / 4 */ - } else { - div = (hclk + ((hz << 2) - 1)) / (hz << 2); - sclk = (hclk >> 2) / div; - } - } else if (hz >= hclk) { /* bug fix */ - mode = 0x1; /* no divisor and divisor is ignored */ - div = 0; - sclk = hclk; - } else { - mode = 0x0; /* use divisor */ - if (hz >= (hclk >> 1)) { - div = 0; /* mean div = 1/2 */ - sclk = hclk >> 1; /* sclk = clk / 2 */ - } else { - div = (hclk + ((hz << 2) - 1)) / (hz << 2); - sclk = (hclk >> 2) / div; - } - } -#endif - /* set clock mode and divisor */ - sdr_set_field(MSDC_CFG, MSDC_CFG_CKMOD, mode); - sdr_set_field(MSDC_CFG, MSDC_CFG_CKDIV, div); - - /* wait clock stable */ - while (!(sdr_read32(MSDC_CFG) & MSDC_CFG_CKSTB)); + msdc_irq_save(flags); - host->sclk = sclk; - host->mclk = hz; - msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); // need? - - INIT_MSG("================"); - INIT_MSG("!!! Set<%dKHz> Source<%dKHz> -> sclk<%dKHz>", hz/1000, hclk/1000, sclk/1000); - INIT_MSG("================"); + if (ddr) { + mode = 0x2; /* ddr mode and use divisor */ + if (hz >= (hclk >> 2)) { + div = 1; /* mean div = 1/4 */ + sclk = hclk >> 2; /* sclk = clk / 4 */ + } else { + div = (hclk + ((hz << 2) - 1)) / (hz << 2); + sclk = (hclk >> 2) / div; + } + } else if (hz >= hclk) { /* bug fix */ + mode = 0x1; /* no divisor and divisor is ignored */ + div = 0; + sclk = hclk; + } else { + mode = 0x0; /* use divisor */ + if (hz >= (hclk >> 1)) { + div = 0; /* mean div = 1/2 */ + sclk = hclk >> 1; /* sclk = clk / 2 */ + } else { + div = (hclk + ((hz << 2) - 1)) / (hz << 2); + sclk = (hclk >> 2) / div; + } + } - msdc_irq_restore(flags); + /* set clock mode and divisor */ + sdr_set_field(MSDC_CFG, MSDC_CFG_CKMOD, mode); + sdr_set_field(MSDC_CFG, MSDC_CFG_CKDIV, div); + + /* wait clock stable */ + while (!(sdr_read32(MSDC_CFG) & MSDC_CFG_CKSTB)) + cpu_relax(); + + host->sclk = sclk; + host->mclk = hz; + msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); // need? + + INIT_MSG("================"); + INIT_MSG("!!! Set<%dKHz> Source<%dKHz> -> sclk<%dKHz>", hz / 1000, hclk / 1000, sclk / 1000); + INIT_MSG("================"); + + msdc_irq_restore(flags); } /* Fix me. when need to abort */ static void msdc_abort_data(struct msdc_host *host) { - u32 base = host->base; - struct mmc_command *stop = host->mrq->stop; + void __iomem *base = host->base; + struct mmc_command *stop = host->mrq->stop; - ERR_MSG("Need to Abort. dma<%d>", host->dma_xfer); - - msdc_reset(); - msdc_clr_fifo(); - msdc_clr_int(); + ERR_MSG("Need to Abort."); - // need to check FIFO count 0 ? - - if (stop) { /* try to stop, but may not success */ - ERR_MSG("stop when abort CMD<%d>", stop->opcode); - (void)msdc_do_command(host, stop, 0, CMD_TIMEOUT); - } - - //if (host->mclk >= 25000000) { - // msdc_set_mclk(host, 0, host->mclk >> 1); - //} + msdc_reset_hw(host); + msdc_clr_fifo(); + msdc_clr_int(); + + // need to check FIFO count 0 ? + + if (stop) { /* try to stop, but may not success */ + ERR_MSG("stop when abort CMD<%d>", stop->opcode); + (void)msdc_do_command(host, stop, 0, CMD_TIMEOUT); + } + + //if (host->mclk >= 25000000) { + // msdc_set_mclk(host, 0, host->mclk >> 1); + //} } #if 0 /* --- by chhung */ static void msdc_pin_config(struct msdc_host *host, int mode) { - struct msdc_hw *hw = host->hw; - u32 base = host->base; - int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN; + struct msdc_hw *hw = host->hw; + void __iomem *base = host->base; + int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN; - /* Config WP pin */ - if (hw->flags & MSDC_WP_PIN_EN) { - if (hw->config_gpio_pin) /* NULL */ - hw->config_gpio_pin(MSDC_WP_PIN, pull); - } + /* Config WP pin */ + if (hw->flags & MSDC_WP_PIN_EN) { + if (hw->config_gpio_pin) /* NULL */ + hw->config_gpio_pin(MSDC_WP_PIN, pull); + } - switch (mode) { - case MSDC_PIN_PULL_UP: - //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 1); /* Check & FIXME */ - //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */ - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 1); - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 1); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0); - break; - case MSDC_PIN_PULL_DOWN: - //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */ - //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 1); /* Check & FIXME */ - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0); - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 1); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 1); - break; - case MSDC_PIN_PULL_NONE: - default: - //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */ - //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */ - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0); - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0); - break; - } - - N_MSG(CFG, "Pins mode(%d), down(%d), up(%d)", - mode, MSDC_PIN_PULL_DOWN, MSDC_PIN_PULL_UP); + switch (mode) { + case MSDC_PIN_PULL_UP: + //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 1); /* Check & FIXME */ + //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */ + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 1); + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 1); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0); + break; + case MSDC_PIN_PULL_DOWN: + //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */ + //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 1); /* Check & FIXME */ + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0); + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 1); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 1); + break; + case MSDC_PIN_PULL_NONE: + default: + //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */ + //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */ + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0); + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0); + break; + } + + N_MSG(CFG, "Pins mode(%d), down(%d), up(%d)", + mode, MSDC_PIN_PULL_DOWN, MSDC_PIN_PULL_UP); } void msdc_pin_reset(struct msdc_host *host, int mode) { - struct msdc_hw *hw = (struct msdc_hw *)host->hw; - u32 base = host->base; - int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN; + struct msdc_hw *hw = (struct msdc_hw *)host->hw; + void __iomem *base = host->base; + int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN; - /* Config reset pin */ - if (hw->flags & MSDC_RST_PIN_EN) { - if (hw->config_gpio_pin) /* NULL */ - hw->config_gpio_pin(MSDC_RST_PIN, pull); + /* Config reset pin */ + if (hw->flags & MSDC_RST_PIN_EN) { + if (hw->config_gpio_pin) /* NULL */ + hw->config_gpio_pin(MSDC_RST_PIN, pull); - if (mode == MSDC_PIN_PULL_UP) { - sdr_clr_bits(EMMC_IOCON, EMMC_IOCON_BOOTRST); - } else { - sdr_set_bits(EMMC_IOCON, EMMC_IOCON_BOOTRST); - } - } + if (mode == MSDC_PIN_PULL_UP) + sdr_clr_bits(EMMC_IOCON, EMMC_IOCON_BOOTRST); + else + sdr_set_bits(EMMC_IOCON, EMMC_IOCON_BOOTRST); + } } static void msdc_core_power(struct msdc_host *host, int on) { - N_MSG(CFG, "Turn %s %s power (copower: %d -> %d)", - on ? "on" : "off", "core", host->core_power, on); + N_MSG(CFG, "Turn %s %s power (copower: %d -> %d)", + on ? "on" : "off", "core", host->core_power, on); - if (on && host->core_power == 0) { - msdc_vcore_on(host); - host->core_power = 1; - msleep(1); - } else if (!on && host->core_power == 1) { - msdc_vcore_off(host); - host->core_power = 0; - msleep(1); - } + if (on && host->core_power == 0) { + msdc_vcore_on(host); + host->core_power = 1; + msleep(1); + } else if (!on && host->core_power == 1) { + msdc_vcore_off(host); + host->core_power = 0; + msleep(1); + } } static void msdc_host_power(struct msdc_host *host, int on) { - N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "host"); + N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "host"); - if (on) { - //msdc_core_power(host, 1); // need do card detection. - msdc_pin_reset(host, MSDC_PIN_PULL_UP); - } else { - msdc_pin_reset(host, MSDC_PIN_PULL_DOWN); - //msdc_core_power(host, 0); - } + if (on) { + //msdc_core_power(host, 1); // need do card detection. + msdc_pin_reset(host, MSDC_PIN_PULL_UP); + } else { + msdc_pin_reset(host, MSDC_PIN_PULL_DOWN); + //msdc_core_power(host, 0); + } } static void msdc_card_power(struct msdc_host *host, int on) { - N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "card"); + N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "card"); - if (on) { - msdc_pin_config(host, MSDC_PIN_PULL_UP); - if (host->hw->ext_power_on) { - host->hw->ext_power_on(); - } else { - //msdc_vdd_on(host); // need todo card detection. - } - msleep(1); - } else { - if (host->hw->ext_power_off) { - host->hw->ext_power_off(); - } else { - //msdc_vdd_off(host); - } - msdc_pin_config(host, MSDC_PIN_PULL_DOWN); - msleep(1); - } + if (on) { + msdc_pin_config(host, MSDC_PIN_PULL_UP); + //msdc_vdd_on(host); // need todo card detection. + msleep(1); + } else { + //msdc_vdd_off(host); + msdc_pin_config(host, MSDC_PIN_PULL_DOWN); + msleep(1); + } } static void msdc_set_power_mode(struct msdc_host *host, u8 mode) { - N_MSG(CFG, "Set power mode(%d)", mode); + N_MSG(CFG, "Set power mode(%d)", mode); - if (host->power_mode == MMC_POWER_OFF && mode != MMC_POWER_OFF) { - msdc_host_power(host, 1); - msdc_card_power(host, 1); - } else if (host->power_mode != MMC_POWER_OFF && mode == MMC_POWER_OFF) { - msdc_card_power(host, 0); - msdc_host_power(host, 0); - } - host->power_mode = mode; + if (host->power_mode == MMC_POWER_OFF && mode != MMC_POWER_OFF) { + msdc_host_power(host, 1); + msdc_card_power(host, 1); + } else if (host->power_mode != MMC_POWER_OFF && mode == MMC_POWER_OFF) { + msdc_card_power(host, 0); + msdc_host_power(host, 0); + } + host->power_mode = mode; } #endif /* end of --- */ #ifdef CONFIG_PM /* - register as callback function of WIFI(combo_sdio_register_pm) . - can called by msdc_drv_suspend/resume too. + register as callback function of WIFI(combo_sdio_register_pm) . + can called by msdc_drv_suspend/resume too. */ static void msdc_pm(pm_message_t state, void *data) { - struct msdc_host *host = (struct msdc_host *)data; - int evt = state.event; + struct msdc_host *host = (struct msdc_host *)data; + int evt = state.event; - if (evt == PM_EVENT_USER_RESUME || evt == PM_EVENT_USER_SUSPEND) { - INIT_MSG("USR_%s: suspend<%d> power<%d>", - evt == PM_EVENT_USER_RESUME ? "EVENT_USER_RESUME" : "EVENT_USER_SUSPEND", - host->suspend, host->power_mode); - } + if (evt == PM_EVENT_USER_RESUME || evt == PM_EVENT_USER_SUSPEND) { + INIT_MSG("USR_%s: suspend<%d> power<%d>", + evt == PM_EVENT_USER_RESUME ? "EVENT_USER_RESUME" : "EVENT_USER_SUSPEND", + host->suspend, host->power_mode); + } - if (evt == PM_EVENT_SUSPEND || evt == PM_EVENT_USER_SUSPEND) { - if (host->suspend) /* already suspend */ /* default 0*/ - return; + if (evt == PM_EVENT_SUSPEND || evt == PM_EVENT_USER_SUSPEND) { + if (host->suspend) /* already suspend */ /* default 0*/ + return; - /* for memory card. already power off by mmc */ - if (evt == PM_EVENT_SUSPEND && host->power_mode == MMC_POWER_OFF) - return; + /* for memory card. already power off by mmc */ + if (evt == PM_EVENT_SUSPEND && host->power_mode == MMC_POWER_OFF) + return; - host->suspend = 1; - host->pm_state = state; /* default PMSG_RESUME */ - - INIT_MSG("%s Suspend", evt == PM_EVENT_SUSPEND ? "PM" : "USR"); - if(host->hw->flags & MSDC_SYS_SUSPEND) /* set for card */ - (void)mmc_suspend_host(host->mmc); - else { - // host->mmc->pm_flags |= MMC_PM_IGNORE_PM_NOTIFY; /* just for double confirm */ /* --- by chhung */ - mmc_remove_host(host->mmc); - } - } else if (evt == PM_EVENT_RESUME || evt == PM_EVENT_USER_RESUME) { - if (!host->suspend){ - //ERR_MSG("warning: already resume"); - return; - } + host->suspend = 1; + host->pm_state = state; /* default PMSG_RESUME */ - /* No PM resume when USR suspend */ - if (evt == PM_EVENT_RESUME && host->pm_state.event == PM_EVENT_USER_SUSPEND) { - ERR_MSG("PM Resume when in USR Suspend"); /* won't happen. */ - return; - } - - host->suspend = 0; - host->pm_state = state; - - INIT_MSG("%s Resume", evt == PM_EVENT_RESUME ? "PM" : "USR"); - if(host->hw->flags & MSDC_SYS_SUSPEND) { /* will not set for WIFI */ - (void)mmc_resume_host(host->mmc); - } - else { - // host->mmc->pm_flags |= MMC_PM_IGNORE_PM_NOTIFY; /* --- by chhung */ - mmc_add_host(host->mmc); - } - } + } else if (evt == PM_EVENT_RESUME || evt == PM_EVENT_USER_RESUME) { + if (!host->suspend) { + //ERR_MSG("warning: already resume"); + return; + } + + /* No PM resume when USR suspend */ + if (evt == PM_EVENT_RESUME && host->pm_state.event == PM_EVENT_USER_SUSPEND) { + ERR_MSG("PM Resume when in USR Suspend"); /* won't happen. */ + return; + } + + host->suspend = 0; + host->pm_state = state; + + } } #endif /*--------------------------------------------------------------------------*/ /* mmc_host_ops members */ /*--------------------------------------------------------------------------*/ -static unsigned int msdc_command_start(struct msdc_host *host, - struct mmc_command *cmd, - int tune, /* not used */ - unsigned long timeout) +static unsigned int msdc_command_start(struct msdc_host *host, + struct mmc_command *cmd, + int tune, /* not used */ + unsigned long timeout) { - u32 base = host->base; - u32 opcode = cmd->opcode; - u32 rawcmd; - u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | - MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | - MSDC_INT_ACMD19_DONE; - - u32 resp; - unsigned long tmo; + void __iomem *base = host->base; + u32 opcode = cmd->opcode; + u32 rawcmd; + u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | + MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | + MSDC_INT_ACMD19_DONE; - /* Protocol layer does not provide response type, but our hardware needs - * to know exact type, not just size! - */ - if (opcode == MMC_SEND_OP_COND || opcode == SD_APP_OP_COND) - resp = RESP_R3; - else if (opcode == MMC_SET_RELATIVE_ADDR || opcode == SD_SEND_RELATIVE_ADDR) - resp = (mmc_cmd_type(cmd) == MMC_CMD_BCR) ? RESP_R6 : RESP_R1; - else if (opcode == MMC_FAST_IO) - resp = RESP_R4; - else if (opcode == MMC_GO_IRQ_STATE) - resp = RESP_R5; - else if (opcode == MMC_SELECT_CARD) - resp = (cmd->arg != 0) ? RESP_R1B : RESP_NONE; - else if (opcode == SD_IO_RW_DIRECT || opcode == SD_IO_RW_EXTENDED) - resp = RESP_R1; /* SDIO workaround. */ - else if (opcode == SD_SEND_IF_COND && (mmc_cmd_type(cmd) == MMC_CMD_BCR)) - resp = RESP_R1; - else { - switch (mmc_resp_type(cmd)) { - case MMC_RSP_R1: - resp = RESP_R1; - break; - case MMC_RSP_R1B: - resp = RESP_R1B; - break; - case MMC_RSP_R2: - resp = RESP_R2; - break; - case MMC_RSP_R3: - resp = RESP_R3; - break; - case MMC_RSP_NONE: - default: - resp = RESP_NONE; - break; - } - } + u32 resp; + unsigned long tmo; - cmd->error = 0; - /* rawcmd : - * vol_swt << 30 | auto_cmd << 28 | blklen << 16 | go_irq << 15 | - * stop << 14 | rw << 13 | dtype << 11 | rsptyp << 7 | brk << 6 | opcode - */ - rawcmd = opcode | msdc_rsp[resp] << 7 | host->blksz << 16; - - if (opcode == MMC_READ_MULTIPLE_BLOCK) { - rawcmd |= (2 << 11); - } else if (opcode == MMC_READ_SINGLE_BLOCK) { - rawcmd |= (1 << 11); - } else if (opcode == MMC_WRITE_MULTIPLE_BLOCK) { - rawcmd |= ((2 << 11) | (1 << 13)); - } else if (opcode == MMC_WRITE_BLOCK) { - rawcmd |= ((1 << 11) | (1 << 13)); - } else if (opcode == SD_IO_RW_EXTENDED) { - if (cmd->data->flags & MMC_DATA_WRITE) - rawcmd |= (1 << 13); - if (cmd->data->blocks > 1) - rawcmd |= (2 << 11); - else - rawcmd |= (1 << 11); - } else if (opcode == SD_IO_RW_DIRECT && cmd->flags == (unsigned int)-1) { - rawcmd |= (1 << 14); - } else if ((opcode == SD_APP_SEND_SCR) || - (opcode == SD_APP_SEND_NUM_WR_BLKS) || - (opcode == SD_SWITCH && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) || - (opcode == SD_APP_SD_STATUS && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) || - (opcode == MMC_SEND_EXT_CSD && (mmc_cmd_type(cmd) == MMC_CMD_ADTC))) { - rawcmd |= (1 << 11); - } else if (opcode == MMC_STOP_TRANSMISSION) { - rawcmd |= (1 << 14); - rawcmd &= ~(0x0FFF << 16); - } + /* Protocol layer does not provide response type, but our hardware needs + * to know exact type, not just size! + */ + if (opcode == MMC_SEND_OP_COND || opcode == SD_APP_OP_COND) { + resp = RESP_R3; + } else if (opcode == MMC_SET_RELATIVE_ADDR) { + resp = (mmc_cmd_type(cmd) == MMC_CMD_BCR) ? RESP_R6 : RESP_R1; + } else if (opcode == MMC_FAST_IO) { + resp = RESP_R4; + } else if (opcode == MMC_GO_IRQ_STATE) { + resp = RESP_R5; + } else if (opcode == MMC_SELECT_CARD) { + resp = (cmd->arg != 0) ? RESP_R1B : RESP_NONE; + } else if (opcode == SD_IO_RW_DIRECT || opcode == SD_IO_RW_EXTENDED) { + resp = RESP_R1; /* SDIO workaround. */ + } else if (opcode == SD_SEND_IF_COND && (mmc_cmd_type(cmd) == MMC_CMD_BCR)) { + resp = RESP_R1; + } else { + switch (mmc_resp_type(cmd)) { + case MMC_RSP_R1: + resp = RESP_R1; + break; + case MMC_RSP_R1B: + resp = RESP_R1B; + break; + case MMC_RSP_R2: + resp = RESP_R2; + break; + case MMC_RSP_R3: + resp = RESP_R3; + break; + case MMC_RSP_NONE: + default: + resp = RESP_NONE; + break; + } + } - N_MSG(CMD, "CMD<%d><0x%.8x> Arg<0x%.8x>", opcode , rawcmd, cmd->arg); + cmd->error = 0; + /* rawcmd : + * vol_swt << 30 | auto_cmd << 28 | blklen << 16 | go_irq << 15 | + * stop << 14 | rw << 13 | dtype << 11 | rsptyp << 7 | brk << 6 | opcode + */ + rawcmd = opcode | msdc_rsp[resp] << 7 | host->blksz << 16; - tmo = jiffies + timeout; + if (opcode == MMC_READ_MULTIPLE_BLOCK) { + rawcmd |= (2 << 11); + } else if (opcode == MMC_READ_SINGLE_BLOCK) { + rawcmd |= (1 << 11); + } else if (opcode == MMC_WRITE_MULTIPLE_BLOCK) { + rawcmd |= ((2 << 11) | (1 << 13)); + } else if (opcode == MMC_WRITE_BLOCK) { + rawcmd |= ((1 << 11) | (1 << 13)); + } else if (opcode == SD_IO_RW_EXTENDED) { + if (cmd->data->flags & MMC_DATA_WRITE) + rawcmd |= (1 << 13); + if (cmd->data->blocks > 1) + rawcmd |= (2 << 11); + else + rawcmd |= (1 << 11); + } else if (opcode == SD_IO_RW_DIRECT && cmd->flags == (unsigned int)-1) { + rawcmd |= (1 << 14); + } else if ((opcode == SD_APP_SEND_SCR) || + (opcode == SD_APP_SEND_NUM_WR_BLKS) || + (opcode == SD_SWITCH && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) || + (opcode == SD_APP_SD_STATUS && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) || + (opcode == MMC_SEND_EXT_CSD && (mmc_cmd_type(cmd) == MMC_CMD_ADTC))) { + rawcmd |= (1 << 11); + } else if (opcode == MMC_STOP_TRANSMISSION) { + rawcmd |= (1 << 14); + rawcmd &= ~(0x0FFF << 16); + } - if (opcode == MMC_SEND_STATUS) { - for (;;) { - if (!sdc_is_cmd_busy()) - break; - - if (time_after(jiffies, tmo)) { - ERR_MSG("XXX cmd_busy timeout: before CMD<%d>", opcode); - cmd->error = (unsigned int)-ETIMEDOUT; - msdc_reset(); - goto end; - } - } - }else { - for (;;) { - if (!sdc_is_busy()) - break; - if (time_after(jiffies, tmo)) { - ERR_MSG("XXX sdc_busy timeout: before CMD<%d>", opcode); - cmd->error = (unsigned int)-ETIMEDOUT; - msdc_reset(); - goto end; - } - } - } - - //BUG_ON(in_interrupt()); - host->cmd = cmd; - host->cmd_rsp = resp; - - init_completion(&host->cmd_done); + N_MSG(CMD, "CMD<%d><0x%.8x> Arg<0x%.8x>", opcode, rawcmd, cmd->arg); - sdr_set_bits(MSDC_INTEN, wints); - sdc_send_cmd(rawcmd, cmd->arg); - -end: - return cmd->error; + tmo = jiffies + timeout; + + if (opcode == MMC_SEND_STATUS) { + for (;;) { + if (!sdc_is_cmd_busy()) + break; + + if (time_after(jiffies, tmo)) { + ERR_MSG("XXX cmd_busy timeout: before CMD<%d>", opcode); + cmd->error = -ETIMEDOUT; + msdc_reset_hw(host); + goto end; + } + } + } else { + for (;;) { + if (!sdc_is_busy()) + break; + if (time_after(jiffies, tmo)) { + ERR_MSG("XXX sdc_busy timeout: before CMD<%d>", opcode); + cmd->error = -ETIMEDOUT; + msdc_reset_hw(host); + goto end; + } + } + } + + //BUG_ON(in_interrupt()); + host->cmd = cmd; + host->cmd_rsp = resp; + + init_completion(&host->cmd_done); + + sdr_set_bits(MSDC_INTEN, wints); + sdc_send_cmd(rawcmd, cmd->arg); + +end: + return cmd->error; } -static unsigned int msdc_command_resp(struct msdc_host *host, - struct mmc_command *cmd, - int tune, - unsigned long timeout) +static unsigned int msdc_command_resp(struct msdc_host *host, + struct mmc_command *cmd, + int tune, + unsigned long timeout) + __must_hold(&host->lock) { - u32 base = host->base; - u32 opcode = cmd->opcode; - //u32 rawcmd; - u32 resp; - u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | - MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | - MSDC_INT_ACMD19_DONE; - - resp = host->cmd_rsp; + void __iomem *base = host->base; + u32 opcode = cmd->opcode; + //u32 rawcmd; + u32 resp; + u32 wints = MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | + MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | + MSDC_INT_ACMD19_DONE; - BUG_ON(in_interrupt()); - //init_completion(&host->cmd_done); - //sdr_set_bits(MSDC_INTEN, wints); - - spin_unlock(&host->lock); - if(!wait_for_completion_timeout(&host->cmd_done, 10*timeout)){ - ERR_MSG("XXX CMD<%d> wait_for_completion timeout ARG<0x%.8x>", opcode, cmd->arg); - cmd->error = (unsigned int)-ETIMEDOUT; - msdc_reset(); - } - spin_lock(&host->lock); + resp = host->cmd_rsp; - sdr_clr_bits(MSDC_INTEN, wints); - host->cmd = NULL; + BUG_ON(in_interrupt()); + //init_completion(&host->cmd_done); + //sdr_set_bits(MSDC_INTEN, wints); + + spin_unlock(&host->lock); + if (!wait_for_completion_timeout(&host->cmd_done, 10 * timeout)) { + ERR_MSG("XXX CMD<%d> wait_for_completion timeout ARG<0x%.8x>", opcode, cmd->arg); + cmd->error = -ETIMEDOUT; + msdc_reset_hw(host); + } + spin_lock(&host->lock); + + sdr_clr_bits(MSDC_INTEN, wints); + host->cmd = NULL; //end: #ifdef MT6575_SD_DEBUG - switch (resp) { - case RESP_NONE: - N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)", opcode, cmd->error, resp); - break; - case RESP_R2: - N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= %.8x %.8x %.8x %.8x", - opcode, cmd->error, resp, cmd->resp[0], cmd->resp[1], - cmd->resp[2], cmd->resp[3]); - break; - default: /* Response types 1, 3, 4, 5, 6, 7(1b) */ - N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= 0x%.8x", - opcode, cmd->error, resp, cmd->resp[0]); - if (cmd->error == 0) { - switch (resp) { - case RESP_R1: - case RESP_R1B: - msdc_dump_card_status(host, cmd->resp[0]); - break; - case RESP_R3: - msdc_dump_ocr_reg(host, cmd->resp[0]); - break; - case RESP_R5: - msdc_dump_io_resp(host, cmd->resp[0]); - break; - case RESP_R6: - msdc_dump_rca_resp(host, cmd->resp[0]); - break; - } - } - break; - } + switch (resp) { + case RESP_NONE: + N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)", opcode, cmd->error, resp); + break; + case RESP_R2: + N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= %.8x %.8x %.8x %.8x", + opcode, cmd->error, resp, cmd->resp[0], cmd->resp[1], + cmd->resp[2], cmd->resp[3]); + break; + default: /* Response types 1, 3, 4, 5, 6, 7(1b) */ + N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= 0x%.8x", + opcode, cmd->error, resp, cmd->resp[0]); + if (cmd->error == 0) { + switch (resp) { + case RESP_R1: + case RESP_R1B: + msdc_dump_card_status(host, cmd->resp[0]); + break; + case RESP_R3: + msdc_dump_ocr_reg(host, cmd->resp[0]); + break; + case RESP_R5: + msdc_dump_io_resp(host, cmd->resp[0]); + break; + case RESP_R6: + msdc_dump_rca_resp(host, cmd->resp[0]); + break; + } + } + break; + } #endif - /* do we need to save card's RCA when SD_SEND_RELATIVE_ADDR */ + /* do we need to save card's RCA when SD_SEND_RELATIVE_ADDR */ - if (!tune) { - return cmd->error; - } + if (!tune) + return cmd->error; - /* memory card CRC */ - if(host->hw->flags & MSDC_REMOVABLE && cmd->error == (unsigned int)(-EIO) ) { - if (sdr_read32(SDC_CMD) & 0x1800) { /* check if has data phase */ - msdc_abort_data(host); - } else { - /* do basic: reset*/ - msdc_reset(); - msdc_clr_fifo(); - msdc_clr_int(); - } - cmd->error = msdc_tune_cmdrsp(host,cmd); - } + /* memory card CRC */ + if (host->hw->flags & MSDC_REMOVABLE && cmd->error == -EIO) { + if (sdr_read32(SDC_CMD) & 0x1800) { /* check if has data phase */ + msdc_abort_data(host); + } else { + /* do basic: reset*/ + msdc_reset_hw(host); + msdc_clr_fifo(); + msdc_clr_int(); + } + cmd->error = msdc_tune_cmdrsp(host, cmd); + } - // check DAT0 - /* if (resp == RESP_R1B) { - while ((sdr_read32(MSDC_PS) & 0x10000) != 0x10000); - } */ - /* CMD12 Error Handle */ - - return cmd->error; -} + // check DAT0 + /* if (resp == RESP_R1B) { + while ((sdr_read32(MSDC_PS) & 0x10000) != 0x10000); + } */ + /* CMD12 Error Handle */ -static unsigned int msdc_do_command(struct msdc_host *host, - struct mmc_command *cmd, - int tune, - unsigned long timeout) -{ - if (msdc_command_start(host, cmd, tune, timeout)) - goto end; - - if (msdc_command_resp(host, cmd, tune, timeout)) - goto end; - -end: - - N_MSG(CMD, " return<%d> resp<0x%.8x>", cmd->error, cmd->resp[0]); - return cmd->error; -} - -/* The abort condition when PIO read/write - tmo: -*/ -static int msdc_pio_abort(struct msdc_host *host, struct mmc_data *data, unsigned long tmo) -{ - int ret = 0; - u32 base = host->base; - - if (atomic_read(&host->abort)) { - ret = 1; - } - - if (time_after(jiffies, tmo)) { - data->error = (unsigned int)-ETIMEDOUT; - ERR_MSG("XXX PIO Data Timeout: CMD<%d>", host->mrq->cmd->opcode); - ret = 1; - } - - if(ret) { - msdc_reset(); - msdc_clr_fifo(); - msdc_clr_int(); - ERR_MSG("msdc pio find abort"); - } - return ret; + return cmd->error; } -/* - Need to add a timeout, or WDT timeout, system reboot. -*/ -// pio mode data read/write -static int msdc_pio_read(struct msdc_host *host, struct mmc_data *data) +static unsigned int msdc_do_command(struct msdc_host *host, + struct mmc_command *cmd, + int tune, + unsigned long timeout) { - struct scatterlist *sg = data->sg; - u32 base = host->base; - u32 num = data->sg_len; - u32 *ptr; - u8 *u8ptr; - u32 left = 0; - u32 count, size = 0; - u32 wints = MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR ; - unsigned long tmo = jiffies + DAT_TIMEOUT; - - sdr_set_bits(MSDC_INTEN, wints); - while (num) { - left = sg_dma_len(sg); - ptr = sg_virt(sg); - while (left) { - if ((left >= MSDC_FIFO_THD) && (msdc_rxfifocnt() >= MSDC_FIFO_THD)) { - count = MSDC_FIFO_THD >> 2; - do { - *ptr++ = msdc_fifo_read32(); - } while (--count); - left -= MSDC_FIFO_THD; - } else if ((left < MSDC_FIFO_THD) && msdc_rxfifocnt() >= left) { - while (left > 3) { - *ptr++ = msdc_fifo_read32(); - left -= 4; - } - - u8ptr = (u8 *)ptr; - while(left) { - * u8ptr++ = msdc_fifo_read8(); - left--; - } - } - - if (msdc_pio_abort(host, data, tmo)) { - goto end; - } - } - size += sg_dma_len(sg); - sg = sg_next(sg); num--; - } + if (msdc_command_start(host, cmd, tune, timeout)) + goto end; + + if (msdc_command_resp(host, cmd, tune, timeout)) + goto end; + end: - data->bytes_xfered += size; - N_MSG(FIO, " PIO Read<%d>bytes", size); - - sdr_clr_bits(MSDC_INTEN, wints); - if(data->error) ERR_MSG("read pio data->error<%d> left<%d> size<%d>", data->error, left, size); - return data->error; -} -/* please make sure won't using PIO when size >= 512 - which means, memory card block read/write won't using pio - then don't need to handle the CMD12 when data error. -*/ -static int msdc_pio_write(struct msdc_host* host, struct mmc_data *data) -{ - u32 base = host->base; - struct scatterlist *sg = data->sg; - u32 num = data->sg_len; - u32 *ptr; - u8 *u8ptr; - u32 left; - u32 count, size = 0; - u32 wints = MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR ; - unsigned long tmo = jiffies + DAT_TIMEOUT; - - sdr_set_bits(MSDC_INTEN, wints); - while (num) { - left = sg_dma_len(sg); - ptr = sg_virt(sg); - - while (left) { - if (left >= MSDC_FIFO_SZ && msdc_txfifocnt() == 0) { - count = MSDC_FIFO_SZ >> 2; - do { - msdc_fifo_write32(*ptr); ptr++; - } while (--count); - left -= MSDC_FIFO_SZ; - } else if (left < MSDC_FIFO_SZ && msdc_txfifocnt() == 0) { - while (left > 3) { - msdc_fifo_write32(*ptr); ptr++; - left -= 4; - } - - u8ptr = (u8*)ptr; - while(left){ - msdc_fifo_write8(*u8ptr); u8ptr++; - left--; - } - } - - if (msdc_pio_abort(host, data, tmo)) { - goto end; - } - } - size += sg_dma_len(sg); - sg = sg_next(sg); num--; - } -end: - data->bytes_xfered += size; - N_MSG(FIO, " PIO Write<%d>bytes", size); - if(data->error) ERR_MSG("write pio data->error<%d>", data->error); - - sdr_clr_bits(MSDC_INTEN, wints); - return data->error; + N_MSG(CMD, " return<%d> resp<0x%.8x>", cmd->error, cmd->resp[0]); + return cmd->error; } #if 0 /* --- by chhung */ -// DMA resume / start / stop +// DMA resume / start / stop static void msdc_dma_resume(struct msdc_host *host) { - u32 base = host->base; + void __iomem *base = host->base; - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_RESUME, 1); + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_RESUME, 1); - N_MSG(DMA, "DMA resume"); + N_MSG(DMA, "DMA resume"); } #endif /* end of --- */ static void msdc_dma_start(struct msdc_host *host) { - u32 base = host->base; - u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR ; - - sdr_set_bits(MSDC_INTEN, wints); - //dsb(); /* --- by chhung */ - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1); + void __iomem *base = host->base; + u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR; - N_MSG(DMA, "DMA start"); + sdr_set_bits(MSDC_INTEN, wints); + //dsb(); /* --- by chhung */ + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1); + + N_MSG(DMA, "DMA start"); } static void msdc_dma_stop(struct msdc_host *host) { - u32 base = host->base; - //u32 retries=500; - u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR ; - - N_MSG(DMA, "DMA status: 0x%.8x",sdr_read32(MSDC_DMA_CFG)); - //while (sdr_read32(MSDC_DMA_CFG) & MSDC_DMA_CFG_STS); + void __iomem *base = host->base; + //u32 retries=500; + u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR; - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1); - while (sdr_read32(MSDC_DMA_CFG) & MSDC_DMA_CFG_STS); + N_MSG(DMA, "DMA status: 0x%.8x", sdr_read32(MSDC_DMA_CFG)); + //while (sdr_read32(MSDC_DMA_CFG) & MSDC_DMA_CFG_STS); - //dsb(); /* --- by chhung */ - sdr_clr_bits(MSDC_INTEN, wints); /* Not just xfer_comp */ + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1); + while (sdr_read32(MSDC_DMA_CFG) & MSDC_DMA_CFG_STS) + ; - N_MSG(DMA, "DMA stop"); + //dsb(); /* --- by chhung */ + sdr_clr_bits(MSDC_INTEN, wints); /* Not just xfer_comp */ + + N_MSG(DMA, "DMA stop"); } -#if 0 /* --- by chhung */ -/* dump a gpd list */ -static void msdc_dma_dump(struct msdc_host *host, struct msdc_dma *dma) -{ - gpd_t *gpd = dma->gpd; - bd_t *bd = dma->bd; - bd_t *ptr; - int i = 0; - int p_to_v; - - if (dma->mode != MSDC_MODE_DMA_DESC) { - return; - } - - ERR_MSG("try to dump gpd and bd"); - - /* dump gpd */ - ERR_MSG(".gpd<0x%.8x> gpd_phy<0x%.8x>", (int)gpd, (int)dma->gpd_addr); - ERR_MSG("...hwo <%d>", gpd->hwo ); - ERR_MSG("...bdp <%d>", gpd->bdp ); - ERR_MSG("...chksum<0x%.8x>", gpd->chksum ); - //ERR_MSG("...intr <0x%.8x>", gpd->intr ); - ERR_MSG("...next <0x%.8x>", (int)gpd->next ); - ERR_MSG("...ptr <0x%.8x>", (int)gpd->ptr ); - ERR_MSG("...buflen<0x%.8x>", gpd->buflen ); - //ERR_MSG("...extlen<0x%.8x>", gpd->extlen ); - //ERR_MSG("...arg <0x%.8x>", gpd->arg ); - //ERR_MSG("...blknum<0x%.8x>", gpd->blknum ); - //ERR_MSG("...cmd <0x%.8x>", gpd->cmd ); - - /* dump bd */ - ERR_MSG(".bd<0x%.8x> bd_phy<0x%.8x> gpd_ptr<0x%.8x>", (int)bd, (int)dma->bd_addr, (int)gpd->ptr); - ptr = bd; - p_to_v = ((u32)bd - (u32)dma->bd_addr); - while (1) { - ERR_MSG(".bd[%d]", i); i++; - ERR_MSG("...eol <%d>", ptr->eol ); - ERR_MSG("...chksum<0x%.8x>", ptr->chksum ); - //ERR_MSG("...blkpad<0x%.8x>", ptr->blkpad ); - //ERR_MSG("...dwpad <0x%.8x>", ptr->dwpad ); - ERR_MSG("...next <0x%.8x>", (int)ptr->next ); - ERR_MSG("...ptr <0x%.8x>", (int)ptr->ptr ); - ERR_MSG("...buflen<0x%.8x>", (int)ptr->buflen ); - - if (ptr->eol == 1) { - break; - } - - /* find the next bd, virtual address of ptr->next */ - /* don't need to enable when use malloc */ - //BUG_ON( (ptr->next + p_to_v)!=(ptr+1) ); - //ERR_MSG(".next bd<0x%.8x><0x%.8x>", (ptr->next + p_to_v), (ptr+1)); - ptr++; - } - - ERR_MSG("dump gpd and bd finished"); -} -#endif /* end of --- */ - /* calc checksum */ static u8 msdc_dma_calcs(u8 *buf, u32 len) { - u32 i, sum = 0; - for (i = 0; i < len; i++) { - sum += buf[i]; - } - return 0xFF - (u8)sum; + u32 i, sum = 0; + + for (i = 0; i < len; i++) + sum += buf[i]; + return 0xFF - (u8)sum; } /* gpd bd setup + dma registers */ -static int msdc_dma_config(struct msdc_host *host, struct msdc_dma *dma) +static void msdc_dma_config(struct msdc_host *host, struct msdc_dma *dma) { - u32 base = host->base; - u32 sglen = dma->sglen; - //u32 i, j, num, bdlen, arg, xfersz; - u32 j, num, bdlen; - u8 blkpad, dwpad, chksum; - struct scatterlist *sg = dma->sg; - gpd_t *gpd; - bd_t *bd; + void __iomem *base = host->base; + //u32 i, j, num, bdlen, arg, xfersz; + u32 j, num; + struct scatterlist *sg; + struct gpd *gpd; + struct bd *bd; - switch (dma->mode) { - case MSDC_MODE_DMA_BASIC: - BUG_ON(dma->xfersz > 65535); - BUG_ON(dma->sglen != 1); - sdr_write32(MSDC_DMA_SA, PHYSADDR(sg_dma_address(sg))); - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_LASTBUF, 1); + switch (dma->mode) { + case MSDC_MODE_DMA_BASIC: + BUG_ON(host->xfer_size > 65535); + BUG_ON(dma->sglen != 1); + sdr_write32(MSDC_DMA_SA, PHYSADDR(sg_dma_address(sg))); + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_LASTBUF, 1); //#if defined (CONFIG_RALINK_MT7620) - if (ralink_soc == MT762X_SOC_MT7620A) - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_XFERSZ, sg_dma_len(sg)); + if (ralink_soc == MT762X_SOC_MT7620A) + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_XFERSZ, sg_dma_len(sg)); //#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) - else - sdr_write32((volatile u32*)(RALINK_MSDC_BASE+0xa8), sg_dma_len(sg)); + else + sdr_write32((void __iomem *)(RALINK_MSDC_BASE + 0xa8), sg_dma_len(sg)); //#endif - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ, dma->burstsz); - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 0); - break; - case MSDC_MODE_DMA_DESC: - blkpad = (dma->flags & DMA_FLAG_PAD_BLOCK) ? 1 : 0; - dwpad = (dma->flags & DMA_FLAG_PAD_DWORD) ? 1 : 0; - chksum = (dma->flags & DMA_FLAG_EN_CHKSUM) ? 1 : 0; + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ, + MSDC_BRUST_64B); + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 0); + break; + case MSDC_MODE_DMA_DESC: - /* calculate the required number of gpd */ - num = (sglen + MAX_BD_PER_GPD - 1) / MAX_BD_PER_GPD; - BUG_ON(num !=1 ); - - gpd = dma->gpd; - bd = dma->bd; - bdlen = sglen; + /* calculate the required number of gpd */ + num = (dma->sglen + MAX_BD_PER_GPD - 1) / MAX_BD_PER_GPD; + BUG_ON(num != 1); - /* modify gpd*/ - //gpd->intr = 0; - gpd->hwo = 1; /* hw will clear it */ - gpd->bdp = 1; - gpd->chksum = 0; /* need to clear first. */ - gpd->chksum = (chksum ? msdc_dma_calcs((u8 *)gpd, 16) : 0); - - /* modify bd*/ - for (j = 0; j < bdlen; j++) { - msdc_init_bd(&bd[j], blkpad, dwpad, sg_dma_address(sg), sg_dma_len(sg)); - if(j == bdlen - 1) { - bd[j].eol = 1; /* the last bd */ - } else { - bd[j].eol = 0; - } - bd[j].chksum = 0; /* checksume need to clear first */ - bd[j].chksum = (chksum ? msdc_dma_calcs((u8 *)(&bd[j]), 16) : 0); - sg++; - } - - dma->used_gpd += 2; - dma->used_bd += bdlen; + gpd = dma->gpd; + bd = dma->bd; - sdr_set_field(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, chksum); - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ, dma->burstsz); - sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 1); + /* modify gpd*/ + //gpd->intr = 0; + gpd->hwo = 1; /* hw will clear it */ + gpd->bdp = 1; + gpd->chksum = 0; /* need to clear first. */ + gpd->chksum = msdc_dma_calcs((u8 *)gpd, 16); - sdr_write32(MSDC_DMA_SA, PHYSADDR((u32)dma->gpd_addr)); - break; + /* modify bd*/ + for_each_sg(dma->sg, sg, dma->sglen, j) { + bd[j].blkpad = 0; + bd[j].dwpad = 0; + bd[j].ptr = (void *)sg_dma_address(sg); + bd[j].buflen = sg_dma_len(sg); - default: - break; - } - - N_MSG(DMA, "DMA_CTRL = 0x%x", sdr_read32(MSDC_DMA_CTRL)); - N_MSG(DMA, "DMA_CFG = 0x%x", sdr_read32(MSDC_DMA_CFG)); - N_MSG(DMA, "DMA_SA = 0x%x", sdr_read32(MSDC_DMA_SA)); + if (j == dma->sglen - 1) + bd[j].eol = 1; /* the last bd */ + else + bd[j].eol = 0; - return 0; -} + bd[j].chksum = 0; /* checksume need to clear first */ + bd[j].chksum = msdc_dma_calcs((u8 *)(&bd[j]), 16); + } -static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, - struct scatterlist *sg, unsigned int sglen) -{ - BUG_ON(sglen > MAX_BD_NUM); /* not support currently */ + sdr_set_field(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1); + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ, + MSDC_BRUST_64B); + sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 1); - dma->sg = sg; - dma->flags = DMA_FLAG_EN_CHKSUM; - //dma->flags = DMA_FLAG_NONE; /* CHECKME */ - dma->sglen = sglen; - dma->xfersz = host->xfer_size; - dma->burstsz = MSDC_BRUST_64B; - - if (sglen == 1 && sg_dma_len(sg) <= MAX_DMA_CNT) - dma->mode = MSDC_MODE_DMA_BASIC; - else - dma->mode = MSDC_MODE_DMA_DESC; + sdr_write32(MSDC_DMA_SA, PHYSADDR((u32)dma->gpd_addr)); + break; - N_MSG(DMA, "DMA mode<%d> sglen<%d> xfersz<%d>", dma->mode, dma->sglen, dma->xfersz); + default: + break; + } + + N_MSG(DMA, "DMA_CTRL = 0x%x", sdr_read32(MSDC_DMA_CTRL)); + N_MSG(DMA, "DMA_CFG = 0x%x", sdr_read32(MSDC_DMA_CFG)); + N_MSG(DMA, "DMA_SA = 0x%x", sdr_read32(MSDC_DMA_SA)); - msdc_dma_config(host, dma); - - /*if (dma->mode == MSDC_MODE_DMA_DESC) { - //msdc_dma_dump(host, dma); - } */ } -/* set block number before send command */ -static void msdc_set_blknum(struct msdc_host *host, u32 blknum) +static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, + struct scatterlist *sg, unsigned int sglen) { - u32 base = host->base; + BUG_ON(sglen > MAX_BD_NUM); /* not support currently */ - sdr_write32(SDC_BLK_NUM, blknum); + dma->sg = sg; + dma->sglen = sglen; + + dma->mode = MSDC_MODE_DMA_DESC; + + N_MSG(DMA, "DMA mode<%d> sglen<%d> xfersz<%d>", dma->mode, dma->sglen, + host->xfer_size); + + msdc_dma_config(host, dma); } -static int msdc_do_request(struct mmc_host*mmc, struct mmc_request*mrq) +static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq) + __must_hold(&host->lock) { - struct msdc_host *host = mmc_priv(mmc); - struct mmc_command *cmd; - struct mmc_data *data; - u32 base = host->base; - //u32 intsts = 0; - unsigned int left=0; - int dma = 0, read = 1, dir = DMA_FROM_DEVICE, send_type=0; - - #define SND_DAT 0 - #define SND_CMD 1 + struct msdc_host *host = mmc_priv(mmc); + struct mmc_command *cmd; + struct mmc_data *data; + void __iomem *base = host->base; + //u32 intsts = 0; + int read = 1, send_type = 0; - BUG_ON(mmc == NULL); - BUG_ON(mrq == NULL); +#define SND_DAT 0 +#define SND_CMD 1 + + BUG_ON(mmc == NULL); + BUG_ON(mrq == NULL); + + host->error = 0; + + cmd = mrq->cmd; + data = mrq->cmd->data; - host->error = 0; - atomic_set(&host->abort, 0); - - cmd = mrq->cmd; - data = mrq->cmd->data; - #if 0 /* --- by chhung */ - //if(host->id ==1){ - N_MSG(OPS, "enable clock!"); - msdc_ungate_clock(host->id); - //} + //if(host->id ==1){ + N_MSG(OPS, "enable clock!"); + msdc_ungate_clock(host->id); + //} #endif /* end of --- */ - - if (!data) { - send_type=SND_CMD; - if (msdc_do_command(host, cmd, 1, CMD_TIMEOUT) != 0) { - goto done; - } - } else { - BUG_ON(data->blksz > HOST_MAX_BLKSZ); - send_type=SND_DAT; - data->error = 0; - read = data->flags & MMC_DATA_READ ? 1 : 0; - host->data = data; - host->xfer_size = data->blocks * data->blksz; - host->blksz = data->blksz; + if (!data) { + send_type = SND_CMD; + if (msdc_do_command(host, cmd, 1, CMD_TIMEOUT) != 0) + goto done; + } else { + BUG_ON(data->blksz > HOST_MAX_BLKSZ); + send_type = SND_DAT; - /* deside the transfer mode */ - if (drv_mode[host->id] == MODE_PIO) { - host->dma_xfer = dma = 0; - } else if (drv_mode[host->id] == MODE_DMA) { - host->dma_xfer = dma = 1; - } else if (drv_mode[host->id] == MODE_SIZE_DEP) { - host->dma_xfer = dma = ((host->xfer_size >= dma_size[host->id]) ? 1 : 0); - } + data->error = 0; + read = data->flags & MMC_DATA_READ ? 1 : 0; + host->data = data; + host->xfer_size = data->blocks * data->blksz; + host->blksz = data->blksz; - if (read) { - if ((host->timeout_ns != data->timeout_ns) || - (host->timeout_clks != data->timeout_clks)) { - msdc_set_timeout(host, data->timeout_ns, data->timeout_clks); - } - } - - msdc_set_blknum(host, data->blocks); - //msdc_clr_fifo(); /* no need */ + if (read) { + if ((host->timeout_ns != data->timeout_ns) || + (host->timeout_clks != data->timeout_clks)) { + msdc_set_timeout(host, data->timeout_ns, data->timeout_clks); + } + } - if (dma) { - msdc_dma_on(); /* enable DMA mode first!! */ - init_completion(&host->xfer_done); - - /* start the command first*/ - if (msdc_command_start(host, cmd, 1, CMD_TIMEOUT) != 0) - goto done; + sdr_write32(SDC_BLK_NUM, data->blocks); + //msdc_clr_fifo(); /* no need */ - dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - (void)dma_map_sg(mmc_dev(mmc), data->sg, data->sg_len, dir); - msdc_dma_setup(host, &host->dma, data->sg, data->sg_len); - - /* then wait command done */ - if (msdc_command_resp(host, cmd, 1, CMD_TIMEOUT) != 0) - goto done; + msdc_dma_on(); /* enable DMA mode first!! */ + init_completion(&host->xfer_done); - /* for read, the data coming too fast, then CRC error - start DMA no business with CRC. */ - //init_completion(&host->xfer_done); - msdc_dma_start(host); - - spin_unlock(&host->lock); - if(!wait_for_completion_timeout(&host->xfer_done, DAT_TIMEOUT)){ - ERR_MSG("XXX CMD<%d> wait xfer_done<%d> timeout!!", cmd->opcode, data->blocks * data->blksz); - ERR_MSG(" DMA_SA = 0x%x", sdr_read32(MSDC_DMA_SA)); - ERR_MSG(" DMA_CA = 0x%x", sdr_read32(MSDC_DMA_CA)); - ERR_MSG(" DMA_CTRL = 0x%x", sdr_read32(MSDC_DMA_CTRL)); - ERR_MSG(" DMA_CFG = 0x%x", sdr_read32(MSDC_DMA_CFG)); - data->error = (unsigned int)-ETIMEDOUT; - - msdc_reset(); - msdc_clr_fifo(); - msdc_clr_int(); - } - spin_lock(&host->lock); - msdc_dma_stop(host); - } else { - /* Firstly: send command */ - if (msdc_do_command(host, cmd, 1, CMD_TIMEOUT) != 0) { - goto done; - } - - /* Secondly: pio data phase */ - if (read) { - if (msdc_pio_read(host, data)){ - goto done; - } - } else { - if (msdc_pio_write(host, data)) { - goto done; - } - } + /* start the command first*/ + if (msdc_command_start(host, cmd, 1, CMD_TIMEOUT) != 0) + goto done; - /* For write case: make sure contents in fifo flushed to device */ - if (!read) { - while (1) { - left=msdc_txfifocnt(); - if (left == 0) { - break; - } - if (msdc_pio_abort(host, data, jiffies + DAT_TIMEOUT)) { - break; - /* Fix me: what about if data error, when stop ? how to? */ - } - } - } else { - /* Fix me: read case: need to check CRC error */ - } + data->sg_count = dma_map_sg(mmc_dev(mmc), data->sg, + data->sg_len, + mmc_get_dma_dir(data)); + msdc_dma_setup(host, &host->dma, data->sg, + data->sg_count); - /* For write case: SDCBUSY and Xfer_Comp will assert when DAT0 not busy. - For read case : SDCBUSY and Xfer_Comp will assert when last byte read out from FIFO. - */ - - /* try not to wait xfer_comp interrupt. - the next command will check SDC_BUSY. - SDC_BUSY means xfer_comp assert - */ - - } // PIO mode - - /* Last: stop transfer */ - if (data->stop){ - if (msdc_do_command(host, data->stop, 0, CMD_TIMEOUT) != 0) { - goto done; - } - } - } + /* then wait command done */ + if (msdc_command_resp(host, cmd, 1, CMD_TIMEOUT) != 0) + goto done; + + /* for read, the data coming too fast, then CRC error + start DMA no business with CRC. */ + //init_completion(&host->xfer_done); + msdc_dma_start(host); + + spin_unlock(&host->lock); + if (!wait_for_completion_timeout(&host->xfer_done, DAT_TIMEOUT)) { + ERR_MSG("XXX CMD<%d> wait xfer_done<%d> timeout!!", cmd->opcode, data->blocks * data->blksz); + ERR_MSG(" DMA_SA = 0x%x", sdr_read32(MSDC_DMA_SA)); + ERR_MSG(" DMA_CA = 0x%x", sdr_read32(MSDC_DMA_CA)); + ERR_MSG(" DMA_CTRL = 0x%x", sdr_read32(MSDC_DMA_CTRL)); + ERR_MSG(" DMA_CFG = 0x%x", sdr_read32(MSDC_DMA_CFG)); + data->error = -ETIMEDOUT; + + msdc_reset_hw(host); + msdc_clr_fifo(); + msdc_clr_int(); + } + spin_lock(&host->lock); + msdc_dma_stop(host); + + /* Last: stop transfer */ + if (data->stop) { + if (msdc_do_command(host, data->stop, 0, CMD_TIMEOUT) != 0) + goto done; + } + } done: - if (data != NULL) { - host->data = NULL; - host->dma_xfer = 0; - if (dma != 0) { - msdc_dma_off(); - host->dma.used_bd = 0; - host->dma.used_gpd = 0; - dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, dir); - } - host->blksz = 0; - -#if 0 // don't stop twice! - if(host->hw->flags & MSDC_REMOVABLE && data->error) { - msdc_abort_data(host); - /* reset in IRQ, stop command has issued. -> No need */ - } -#endif + if (data != NULL) { + host->data = NULL; + dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, + mmc_get_dma_dir(data)); + host->blksz = 0; - N_MSG(OPS, "CMD<%d> data<%s %s> blksz<%d> block<%d> error<%d>",cmd->opcode, (dma? "dma":"pio"), - (read ? "read ":"write") ,data->blksz, data->blocks, data->error); - } +#if 0 // don't stop twice! + if (host->hw->flags & MSDC_REMOVABLE && data->error) { + msdc_abort_data(host); + /* reset in IRQ, stop command has issued. -> No need */ + } +#endif + + N_MSG(OPS, "CMD<%d> data<%s %s> blksz<%d> block<%d> error<%d>", cmd->opcode, (dma ? "dma" : "pio"), + (read ? "read " : "write"), data->blksz, data->blocks, data->error); + } #if 0 /* --- by chhung */ -#if 1 - //if(host->id==1) { - if(send_type==SND_CMD) { - if(cmd->opcode == MMC_SEND_STATUS) { - if((cmd->resp[0] & CARD_READY_FOR_DATA) ||(CARD_CURRENT_STATE(cmd->resp[0]) != 7)){ - N_MSG(OPS,"disable clock, CMD13 IDLE"); - msdc_gate_clock(host->id); - } - } else { - N_MSG(OPS,"disable clock, CMD<%d>", cmd->opcode); - msdc_gate_clock(host->id); - } - } else { - if(read) { - N_MSG(OPS,"disable clock!!! Read CMD<%d>",cmd->opcode); - msdc_gate_clock(host->id); - } - } - //} +#if 1 + //if(host->id==1) { + if (send_type == SND_CMD) { + if (cmd->opcode == MMC_SEND_STATUS) { + if ((cmd->resp[0] & CARD_READY_FOR_DATA) || (CARD_CURRENT_STATE(cmd->resp[0]) != 7)) { + N_MSG(OPS, "disable clock, CMD13 IDLE"); + msdc_gate_clock(host->id); + } + } else { + N_MSG(OPS, "disable clock, CMD<%d>", cmd->opcode); + msdc_gate_clock(host->id); + } + } else { + if (read) { + N_MSG(OPS, "disable clock!!! Read CMD<%d>", cmd->opcode); + msdc_gate_clock(host->id); + } + } + //} #else - msdc_gate_clock(host->id); + msdc_gate_clock(host->id); #endif #endif /* end of --- */ - - if (mrq->cmd->error) host->error = 0x001; - if (mrq->data && mrq->data->error) host->error |= 0x010; - if (mrq->stop && mrq->stop->error) host->error |= 0x100; - //if (host->error) ERR_MSG("host->error<%d>", host->error); + if (mrq->cmd->error) + host->error = 0x001; + if (mrq->data && mrq->data->error) + host->error |= 0x010; + if (mrq->stop && mrq->stop->error) + host->error |= 0x100; - return host->error; + //if (host->error) ERR_MSG("host->error<%d>", host->error); + + return host->error; } static int msdc_app_cmd(struct mmc_host *mmc, struct msdc_host *host) { - struct mmc_command cmd; - struct mmc_request mrq; - u32 err; + struct mmc_command cmd; + struct mmc_request mrq; + u32 err; - memset(&cmd, 0, sizeof(struct mmc_command)); - cmd.opcode = MMC_APP_CMD; -#if 0 /* bug: we meet mmc->card is null when ACMD6 */ - cmd.arg = mmc->card->rca << 16; -#else - cmd.arg = host->app_cmd_arg; -#endif - cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_APP_CMD; +#if 0 /* bug: we meet mmc->card is null when ACMD6 */ + cmd.arg = mmc->card->rca << 16; +#else + cmd.arg = host->app_cmd_arg; +#endif + cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - memset(&mrq, 0, sizeof(struct mmc_request)); - mrq.cmd = &cmd; cmd.mrq = &mrq; - cmd.data = NULL; + memset(&mrq, 0, sizeof(struct mmc_request)); + mrq.cmd = &cmd; cmd.mrq = &mrq; + cmd.data = NULL; - err = msdc_do_command(host, &cmd, 0, CMD_TIMEOUT); - return err; + err = msdc_do_command(host, &cmd, 0, CMD_TIMEOUT); + return err; } -static int msdc_tune_cmdrsp(struct msdc_host*host, struct mmc_command *cmd) +static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd) { - int result = -1; - u32 base = host->base; - u32 rsmpl, cur_rsmpl, orig_rsmpl; - u32 rrdly, cur_rrdly = 0xffffffff, orig_rrdly; - u32 skip = 1; - - /* ==== don't support 3.0 now ==== - 1: R_SMPL[1] - 2: PAD_CMD_RESP_RXDLY[26:22] - ==========================*/ + int result = -1; + void __iomem *base = host->base; + u32 rsmpl, cur_rsmpl, orig_rsmpl; + u32 rrdly, cur_rrdly = 0xffffffff, orig_rrdly; + u32 skip = 1; - // save the previous tune result - sdr_get_field(MSDC_IOCON, MSDC_IOCON_RSPL, orig_rsmpl); - sdr_get_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, orig_rrdly); + /* ==== don't support 3.0 now ==== + 1: R_SMPL[1] + 2: PAD_CMD_RESP_RXDLY[26:22] + ==========================*/ - rrdly = 0; - do { - for (rsmpl = 0; rsmpl < 2; rsmpl++) { - /* Lv1: R_SMPL[1] */ - cur_rsmpl = (orig_rsmpl + rsmpl) % 2; - if (skip == 1) { - skip = 0; - continue; - } - sdr_set_field(MSDC_IOCON, MSDC_IOCON_RSPL, cur_rsmpl); + // save the previous tune result + sdr_get_field(MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl); + sdr_get_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, &orig_rrdly); - if (host->app_cmd) { - result = msdc_app_cmd(host->mmc, host); - if (result) { - ERR_MSG("TUNE_CMD app_cmd<%d> failed: RESP_RXDLY<%d>,R_SMPL<%d>", - host->mrq->cmd->opcode, cur_rrdly, cur_rsmpl); - continue; - } - } - result = msdc_do_command(host, cmd, 0, CMD_TIMEOUT); // not tune. - ERR_MSG("TUNE_CMD<%d> %s PAD_CMD_RESP_RXDLY[26:22]<%d> R_SMPL[1]<%d>", cmd->opcode, - (result == 0) ? "PASS" : "FAIL", cur_rrdly, cur_rsmpl); - - if (result == 0) { - return 0; - } - if (result != (unsigned int)(-EIO)) { - ERR_MSG("TUNE_CMD<%d> Error<%d> not -EIO", cmd->opcode, result); - return result; - } + rrdly = 0; + do { + for (rsmpl = 0; rsmpl < 2; rsmpl++) { + /* Lv1: R_SMPL[1] */ + cur_rsmpl = (orig_rsmpl + rsmpl) % 2; + if (skip == 1) { + skip = 0; + continue; + } + sdr_set_field(MSDC_IOCON, MSDC_IOCON_RSPL, cur_rsmpl); - /* should be EIO */ - if (sdr_read32(SDC_CMD) & 0x1800) { /* check if has data phase */ - msdc_abort_data(host); - } - } - - /* Lv2: PAD_CMD_RESP_RXDLY[26:22] */ - cur_rrdly = (orig_rrdly + rrdly + 1) % 32; - sdr_set_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, cur_rrdly); - }while (++rrdly < 32); - - return result; + if (host->app_cmd) { + result = msdc_app_cmd(host->mmc, host); + if (result) { + ERR_MSG("TUNE_CMD app_cmd<%d> failed: RESP_RXDLY<%d>,R_SMPL<%d>", + host->mrq->cmd->opcode, cur_rrdly, cur_rsmpl); + continue; + } + } + result = msdc_do_command(host, cmd, 0, CMD_TIMEOUT); // not tune. + ERR_MSG("TUNE_CMD<%d> %s PAD_CMD_RESP_RXDLY[26:22]<%d> R_SMPL[1]<%d>", cmd->opcode, + (result == 0) ? "PASS" : "FAIL", cur_rrdly, cur_rsmpl); + + if (result == 0) + return 0; + if (result != -EIO) { + ERR_MSG("TUNE_CMD<%d> Error<%d> not -EIO", cmd->opcode, result); + return result; + } + + /* should be EIO */ + if (sdr_read32(SDC_CMD) & 0x1800) { /* check if has data phase */ + msdc_abort_data(host); + } + } + + /* Lv2: PAD_CMD_RESP_RXDLY[26:22] */ + cur_rrdly = (orig_rrdly + rrdly + 1) % 32; + sdr_set_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, cur_rrdly); + } while (++rrdly < 32); + + return result; } /* Support SD2.0 Only */ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq) { - struct msdc_host *host = mmc_priv(mmc); - u32 base = host->base; - u32 ddr=0; - u32 dcrc=0; - u32 rxdly, cur_rxdly0, cur_rxdly1; - u32 dsmpl, cur_dsmpl, orig_dsmpl; - u32 cur_dat0, cur_dat1, cur_dat2, cur_dat3; - u32 cur_dat4, cur_dat5, cur_dat6, cur_dat7; - u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3; - u32 orig_dat4, orig_dat5, orig_dat6, orig_dat7; - int result = -1; - u32 skip = 1; + struct msdc_host *host = mmc_priv(mmc); + void __iomem *base = host->base; + u32 ddr = 0; + u32 dcrc = 0; + u32 rxdly, cur_rxdly0, cur_rxdly1; + u32 dsmpl, cur_dsmpl, orig_dsmpl; + u32 cur_dat0, cur_dat1, cur_dat2, cur_dat3; + u32 cur_dat4, cur_dat5, cur_dat6, cur_dat7; + u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3; + u32 orig_dat4, orig_dat5, orig_dat6, orig_dat7; + int result = -1; + u32 skip = 1; - sdr_get_field(MSDC_IOCON, MSDC_IOCON_DSPL, orig_dsmpl); - - /* Tune Method 2. */ - sdr_set_field(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); + sdr_get_field(MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl); - rxdly = 0; - do { - for (dsmpl = 0; dsmpl < 2; dsmpl++) { - cur_dsmpl = (orig_dsmpl + dsmpl) % 2; - if (skip == 1) { - skip = 0; - continue; - } - sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, cur_dsmpl); + /* Tune Method 2. */ + sdr_set_field(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); - if (host->app_cmd) { - result = msdc_app_cmd(host->mmc, host); - if (result) { - ERR_MSG("TUNE_BREAD app_cmd<%d> failed", host->mrq->cmd->opcode); - continue; - } - } - result = msdc_do_request(mmc,mrq); - - sdr_get_field(SDC_DCRC_STS, SDC_DCRC_STS_POS|SDC_DCRC_STS_NEG, dcrc); /* RO */ - if (!ddr) dcrc &= ~SDC_DCRC_STS_NEG; - ERR_MSG("TUNE_BREAD<%s> dcrc<0x%x> DATRDDLY0/1<0x%x><0x%x> dsmpl<0x%x>", - (result == 0 && dcrc == 0) ? "PASS" : "FAIL", dcrc, - sdr_read32(MSDC_DAT_RDDLY0), sdr_read32(MSDC_DAT_RDDLY1), cur_dsmpl); + rxdly = 0; + do { + for (dsmpl = 0; dsmpl < 2; dsmpl++) { + cur_dsmpl = (orig_dsmpl + dsmpl) % 2; + if (skip == 1) { + skip = 0; + continue; + } + sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, cur_dsmpl); - /* Fix me: result is 0, but dcrc is still exist */ - if (result == 0 && dcrc == 0) { - goto done; - } else { - /* there is a case: command timeout, and data phase not processed */ - if (mrq->data->error != 0 && mrq->data->error != (unsigned int)(-EIO)) { - ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>", - result, mrq->cmd->error, mrq->data->error); - goto done; - } - } - } + if (host->app_cmd) { + result = msdc_app_cmd(host->mmc, host); + if (result) { + ERR_MSG("TUNE_BREAD app_cmd<%d> failed", host->mrq->cmd->opcode); + continue; + } + } + result = msdc_do_request(mmc, mrq); - cur_rxdly0 = sdr_read32(MSDC_DAT_RDDLY0); - cur_rxdly1 = sdr_read32(MSDC_DAT_RDDLY1); + sdr_get_field(SDC_DCRC_STS, + SDC_DCRC_STS_POS | SDC_DCRC_STS_NEG, + &dcrc); /* RO */ + if (!ddr) + dcrc &= ~SDC_DCRC_STS_NEG; + ERR_MSG("TUNE_BREAD<%s> dcrc<0x%x> DATRDDLY0/1<0x%x><0x%x> dsmpl<0x%x>", + (result == 0 && dcrc == 0) ? "PASS" : "FAIL", dcrc, + sdr_read32(MSDC_DAT_RDDLY0), sdr_read32(MSDC_DAT_RDDLY1), cur_dsmpl); - /* E1 ECO. YD: Reverse */ - if (sdr_read32(MSDC_ECO_VER) >= 4) { - orig_dat0 = (cur_rxdly0 >> 24) & 0x1F; - orig_dat1 = (cur_rxdly0 >> 16) & 0x1F; - orig_dat2 = (cur_rxdly0 >> 8) & 0x1F; - orig_dat3 = (cur_rxdly0 >> 0) & 0x1F; - orig_dat4 = (cur_rxdly1 >> 24) & 0x1F; - orig_dat5 = (cur_rxdly1 >> 16) & 0x1F; - orig_dat6 = (cur_rxdly1 >> 8) & 0x1F; - orig_dat7 = (cur_rxdly1 >> 0) & 0x1F; - } else { - orig_dat0 = (cur_rxdly0 >> 0) & 0x1F; - orig_dat1 = (cur_rxdly0 >> 8) & 0x1F; - orig_dat2 = (cur_rxdly0 >> 16) & 0x1F; - orig_dat3 = (cur_rxdly0 >> 24) & 0x1F; - orig_dat4 = (cur_rxdly1 >> 0) & 0x1F; - orig_dat5 = (cur_rxdly1 >> 8) & 0x1F; - orig_dat6 = (cur_rxdly1 >> 16) & 0x1F; - orig_dat7 = (cur_rxdly1 >> 24) & 0x1F; - } - - if (ddr) { - cur_dat0 = (dcrc & (1 << 0) || dcrc & (1 << 8)) ? ((orig_dat0 + 1) % 32) : orig_dat0; - cur_dat1 = (dcrc & (1 << 1) || dcrc & (1 << 9)) ? ((orig_dat1 + 1) % 32) : orig_dat1; - cur_dat2 = (dcrc & (1 << 2) || dcrc & (1 << 10)) ? ((orig_dat2 + 1) % 32) : orig_dat2; - cur_dat3 = (dcrc & (1 << 3) || dcrc & (1 << 11)) ? ((orig_dat3 + 1) % 32) : orig_dat3; - } else { - cur_dat0 = (dcrc & (1 << 0)) ? ((orig_dat0 + 1) % 32) : orig_dat0; - cur_dat1 = (dcrc & (1 << 1)) ? ((orig_dat1 + 1) % 32) : orig_dat1; - cur_dat2 = (dcrc & (1 << 2)) ? ((orig_dat2 + 1) % 32) : orig_dat2; - cur_dat3 = (dcrc & (1 << 3)) ? ((orig_dat3 + 1) % 32) : orig_dat3; - } - cur_dat4 = (dcrc & (1 << 4)) ? ((orig_dat4 + 1) % 32) : orig_dat4; - cur_dat5 = (dcrc & (1 << 5)) ? ((orig_dat5 + 1) % 32) : orig_dat5; - cur_dat6 = (dcrc & (1 << 6)) ? ((orig_dat6 + 1) % 32) : orig_dat6; - cur_dat7 = (dcrc & (1 << 7)) ? ((orig_dat7 + 1) % 32) : orig_dat7; + /* Fix me: result is 0, but dcrc is still exist */ + if (result == 0 && dcrc == 0) { + goto done; + } else { + /* there is a case: command timeout, and data phase not processed */ + if (mrq->data->error != 0 && + mrq->data->error != -EIO) { + ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>", + result, mrq->cmd->error, mrq->data->error); + goto done; + } + } + } - cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0); - cur_rxdly1 = (cur_dat4 << 24) | (cur_dat5 << 16) | (cur_dat6 << 8) | (cur_dat7 << 0); + cur_rxdly0 = sdr_read32(MSDC_DAT_RDDLY0); + cur_rxdly1 = sdr_read32(MSDC_DAT_RDDLY1); - sdr_write32(MSDC_DAT_RDDLY0, cur_rxdly0); - sdr_write32(MSDC_DAT_RDDLY1, cur_rxdly1); + /* E1 ECO. YD: Reverse */ + if (sdr_read32(MSDC_ECO_VER) >= 4) { + orig_dat0 = (cur_rxdly0 >> 24) & 0x1F; + orig_dat1 = (cur_rxdly0 >> 16) & 0x1F; + orig_dat2 = (cur_rxdly0 >> 8) & 0x1F; + orig_dat3 = (cur_rxdly0 >> 0) & 0x1F; + orig_dat4 = (cur_rxdly1 >> 24) & 0x1F; + orig_dat5 = (cur_rxdly1 >> 16) & 0x1F; + orig_dat6 = (cur_rxdly1 >> 8) & 0x1F; + orig_dat7 = (cur_rxdly1 >> 0) & 0x1F; + } else { + orig_dat0 = (cur_rxdly0 >> 0) & 0x1F; + orig_dat1 = (cur_rxdly0 >> 8) & 0x1F; + orig_dat2 = (cur_rxdly0 >> 16) & 0x1F; + orig_dat3 = (cur_rxdly0 >> 24) & 0x1F; + orig_dat4 = (cur_rxdly1 >> 0) & 0x1F; + orig_dat5 = (cur_rxdly1 >> 8) & 0x1F; + orig_dat6 = (cur_rxdly1 >> 16) & 0x1F; + orig_dat7 = (cur_rxdly1 >> 24) & 0x1F; + } + + if (ddr) { + cur_dat0 = (dcrc & (1 << 0) || dcrc & (1 << 8)) ? ((orig_dat0 + 1) % 32) : orig_dat0; + cur_dat1 = (dcrc & (1 << 1) || dcrc & (1 << 9)) ? ((orig_dat1 + 1) % 32) : orig_dat1; + cur_dat2 = (dcrc & (1 << 2) || dcrc & (1 << 10)) ? ((orig_dat2 + 1) % 32) : orig_dat2; + cur_dat3 = (dcrc & (1 << 3) || dcrc & (1 << 11)) ? ((orig_dat3 + 1) % 32) : orig_dat3; + } else { + cur_dat0 = (dcrc & (1 << 0)) ? ((orig_dat0 + 1) % 32) : orig_dat0; + cur_dat1 = (dcrc & (1 << 1)) ? ((orig_dat1 + 1) % 32) : orig_dat1; + cur_dat2 = (dcrc & (1 << 2)) ? ((orig_dat2 + 1) % 32) : orig_dat2; + cur_dat3 = (dcrc & (1 << 3)) ? ((orig_dat3 + 1) % 32) : orig_dat3; + } + cur_dat4 = (dcrc & (1 << 4)) ? ((orig_dat4 + 1) % 32) : orig_dat4; + cur_dat5 = (dcrc & (1 << 5)) ? ((orig_dat5 + 1) % 32) : orig_dat5; + cur_dat6 = (dcrc & (1 << 6)) ? ((orig_dat6 + 1) % 32) : orig_dat6; + cur_dat7 = (dcrc & (1 << 7)) ? ((orig_dat7 + 1) % 32) : orig_dat7; + + cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0); + cur_rxdly1 = (cur_dat4 << 24) | (cur_dat5 << 16) | (cur_dat6 << 8) | (cur_dat7 << 0); + + sdr_write32(MSDC_DAT_RDDLY0, cur_rxdly0); + sdr_write32(MSDC_DAT_RDDLY1, cur_rxdly1); + + } while (++rxdly < 32); - } while (++rxdly < 32); - done: - return result; + return result; } -static int msdc_tune_bwrite(struct mmc_host *mmc,struct mmc_request *mrq) +static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq) { - struct msdc_host *host = mmc_priv(mmc); - u32 base = host->base; + struct msdc_host *host = mmc_priv(mmc); + void __iomem *base = host->base; - u32 wrrdly, cur_wrrdly = 0xffffffff, orig_wrrdly; - u32 dsmpl, cur_dsmpl, orig_dsmpl; - u32 rxdly, cur_rxdly0; - u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3; - u32 cur_dat0, cur_dat1, cur_dat2, cur_dat3; - int result = -1; - u32 skip = 1; + u32 wrrdly, cur_wrrdly = 0xffffffff, orig_wrrdly; + u32 dsmpl, cur_dsmpl, orig_dsmpl; + u32 rxdly, cur_rxdly0; + u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3; + u32 cur_dat0, cur_dat1, cur_dat2, cur_dat3; + int result = -1; + u32 skip = 1; - // MSDC_IOCON_DDR50CKD need to check. [Fix me] - - sdr_get_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, orig_wrrdly); - sdr_get_field(MSDC_IOCON, MSDC_IOCON_DSPL, orig_dsmpl ); + // MSDC_IOCON_DDR50CKD need to check. [Fix me] - /* Tune Method 2. just DAT0 */ - sdr_set_field(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); - cur_rxdly0 = sdr_read32(MSDC_DAT_RDDLY0); - - /* E1 ECO. YD: Reverse */ - if (sdr_read32(MSDC_ECO_VER) >= 4) { - orig_dat0 = (cur_rxdly0 >> 24) & 0x1F; - orig_dat1 = (cur_rxdly0 >> 16) & 0x1F; - orig_dat2 = (cur_rxdly0 >> 8) & 0x1F; - orig_dat3 = (cur_rxdly0 >> 0) & 0x1F; - } else { - orig_dat0 = (cur_rxdly0 >> 0) & 0x1F; - orig_dat1 = (cur_rxdly0 >> 8) & 0x1F; - orig_dat2 = (cur_rxdly0 >> 16) & 0x1F; - orig_dat3 = (cur_rxdly0 >> 24) & 0x1F; - } + sdr_get_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, &orig_wrrdly); + sdr_get_field(MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl); - rxdly = 0; - do { - wrrdly = 0; - do { - for (dsmpl = 0; dsmpl < 2; dsmpl++) { - cur_dsmpl = (orig_dsmpl + dsmpl) % 2; - if (skip == 1) { - skip = 0; - continue; - } - sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, cur_dsmpl); - - if (host->app_cmd) { - result = msdc_app_cmd(host->mmc, host); - if (result) { - ERR_MSG("TUNE_BWRITE app_cmd<%d> failed", host->mrq->cmd->opcode); - continue; - } - } - result = msdc_do_request(mmc,mrq); - - ERR_MSG("TUNE_BWRITE<%s> DSPL<%d> DATWRDLY<%d> MSDC_DAT_RDDLY0<0x%x>", - result == 0 ? "PASS" : "FAIL", - cur_dsmpl, cur_wrrdly, cur_rxdly0); - - if (result == 0) { - goto done; - } - else { - /* there is a case: command timeout, and data phase not processed */ - if (mrq->data->error != (unsigned int)(-EIO)) { - ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>", - result, mrq->cmd->error, mrq->data->error); - goto done; - } - } - } - cur_wrrdly = (orig_wrrdly + wrrdly + 1) % 32; - sdr_set_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, cur_wrrdly); - } while (++wrrdly < 32); - - cur_dat0 = (orig_dat0 + rxdly) % 32; /* only adjust bit-1 for crc */ - cur_dat1 = orig_dat1; - cur_dat2 = orig_dat2; - cur_dat3 = orig_dat3; - - cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0); - sdr_write32(MSDC_DAT_RDDLY0, cur_rxdly0); - } while (++rxdly < 32); + /* Tune Method 2. just DAT0 */ + sdr_set_field(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); + cur_rxdly0 = sdr_read32(MSDC_DAT_RDDLY0); + + /* E1 ECO. YD: Reverse */ + if (sdr_read32(MSDC_ECO_VER) >= 4) { + orig_dat0 = (cur_rxdly0 >> 24) & 0x1F; + orig_dat1 = (cur_rxdly0 >> 16) & 0x1F; + orig_dat2 = (cur_rxdly0 >> 8) & 0x1F; + orig_dat3 = (cur_rxdly0 >> 0) & 0x1F; + } else { + orig_dat0 = (cur_rxdly0 >> 0) & 0x1F; + orig_dat1 = (cur_rxdly0 >> 8) & 0x1F; + orig_dat2 = (cur_rxdly0 >> 16) & 0x1F; + orig_dat3 = (cur_rxdly0 >> 24) & 0x1F; + } + + rxdly = 0; + do { + wrrdly = 0; + do { + for (dsmpl = 0; dsmpl < 2; dsmpl++) { + cur_dsmpl = (orig_dsmpl + dsmpl) % 2; + if (skip == 1) { + skip = 0; + continue; + } + sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, cur_dsmpl); + + if (host->app_cmd) { + result = msdc_app_cmd(host->mmc, host); + if (result) { + ERR_MSG("TUNE_BWRITE app_cmd<%d> failed", host->mrq->cmd->opcode); + continue; + } + } + result = msdc_do_request(mmc, mrq); + + ERR_MSG("TUNE_BWRITE<%s> DSPL<%d> DATWRDLY<%d> MSDC_DAT_RDDLY0<0x%x>", + result == 0 ? "PASS" : "FAIL", + cur_dsmpl, cur_wrrdly, cur_rxdly0); + + if (result == 0) { + goto done; + } else { + /* there is a case: command timeout, and data phase not processed */ + if (mrq->data->error != -EIO) { + ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>", + result, mrq->cmd->error, mrq->data->error); + goto done; + } + } + } + cur_wrrdly = (orig_wrrdly + wrrdly + 1) % 32; + sdr_set_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, cur_wrrdly); + } while (++wrrdly < 32); + + cur_dat0 = (orig_dat0 + rxdly) % 32; /* only adjust bit-1 for crc */ + cur_dat1 = orig_dat1; + cur_dat2 = orig_dat2; + cur_dat3 = orig_dat3; + + cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0); + sdr_write32(MSDC_DAT_RDDLY0, cur_rxdly0); + } while (++rxdly < 32); done: - return result; + return result; } static int msdc_get_card_status(struct mmc_host *mmc, struct msdc_host *host, u32 *status) { - struct mmc_command cmd; - struct mmc_request mrq; - u32 err; + struct mmc_command cmd; + struct mmc_request mrq; + u32 err; - memset(&cmd, 0, sizeof(struct mmc_command)); - cmd.opcode = MMC_SEND_STATUS; - if (mmc->card) { - cmd.arg = mmc->card->rca << 16; - } else { - ERR_MSG("cmd13 mmc card is null"); - cmd.arg = host->app_cmd_arg; - } - cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_SEND_STATUS; + if (mmc->card) { + cmd.arg = mmc->card->rca << 16; + } else { + ERR_MSG("cmd13 mmc card is null"); + cmd.arg = host->app_cmd_arg; + } + cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; - memset(&mrq, 0, sizeof(struct mmc_request)); - mrq.cmd = &cmd; cmd.mrq = &mrq; - cmd.data = NULL; + memset(&mrq, 0, sizeof(struct mmc_request)); + mrq.cmd = &cmd; cmd.mrq = &mrq; + cmd.data = NULL; - err = msdc_do_command(host, &cmd, 1, CMD_TIMEOUT); - - if (status) { - *status = cmd.resp[0]; - } - - return err; + err = msdc_do_command(host, &cmd, 1, CMD_TIMEOUT); + + if (status) + *status = cmd.resp[0]; + + return err; } static int msdc_check_busy(struct mmc_host *mmc, struct msdc_host *host) { - u32 err = 0; - u32 status = 0; - - do { - err = msdc_get_card_status(mmc, host, &status); - if (err) return err; - /* need cmd12? */ - ERR_MSG("cmd<13> resp<0x%x>", status); - } while (R1_CURRENT_STATE(status) == 7); - - return err; + u32 err = 0; + u32 status = 0; + + do { + err = msdc_get_card_status(mmc, host, &status); + if (err) + return err; + /* need cmd12? */ + ERR_MSG("cmd<13> resp<0x%x>", status); + } while (R1_CURRENT_STATE(status) == 7); + + return err; } /* failed when msdc_do_request */ static int msdc_tune_request(struct mmc_host *mmc, struct mmc_request *mrq) { - struct msdc_host *host = mmc_priv(mmc); - struct mmc_command *cmd; - struct mmc_data *data; - //u32 base = host->base; - int ret=0, read; - - cmd = mrq->cmd; - data = mrq->cmd->data; - - read = data->flags & MMC_DATA_READ ? 1 : 0; + struct msdc_host *host = mmc_priv(mmc); + struct mmc_command *cmd; + struct mmc_data *data; + //u32 base = host->base; + int ret = 0, read; - if (read) { - if (data->error == (unsigned int)(-EIO)) { - ret = msdc_tune_bread(mmc,mrq); - } - } else { - ret = msdc_check_busy(mmc, host); - if (ret){ - ERR_MSG("XXX cmd13 wait program done failed"); - return ret; - } - /* CRC and TO */ - /* Fix me: don't care card status? */ - ret = msdc_tune_bwrite(mmc,mrq); - } + cmd = mrq->cmd; + data = mrq->cmd->data; - return ret; + read = data->flags & MMC_DATA_READ ? 1 : 0; + + if (read) { + if (data->error == -EIO) + ret = msdc_tune_bread(mmc, mrq); + } else { + ret = msdc_check_busy(mmc, host); + if (ret) { + ERR_MSG("XXX cmd13 wait program done failed"); + return ret; + } + /* CRC and TO */ + /* Fix me: don't care card status? */ + ret = msdc_tune_bwrite(mmc, mrq); + } + + return ret; } /* ops.request */ -static void msdc_ops_request(struct mmc_host *mmc,struct mmc_request *mrq) -{ - struct msdc_host *host = mmc_priv(mmc); +static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct msdc_host *host = mmc_priv(mmc); - //=== for sdio profile === + //=== for sdio profile === #if 0 /* --- by chhung */ - u32 old_H32, old_L32, new_H32, new_L32; - u32 ticks = 0, opcode = 0, sizes = 0, bRx = 0; + u32 old_H32, old_L32, new_H32, new_L32; + u32 ticks = 0, opcode = 0, sizes = 0, bRx = 0; #endif /* end of --- */ - - if(host->mrq){ - ERR_MSG("XXX host->mrq<0x%.8x>", (int)host->mrq); - BUG(); - } - - if (!is_card_present(host) || host->power_mode == MMC_POWER_OFF) { - ERR_MSG("cmd<%d> card<%d> power<%d>", mrq->cmd->opcode, is_card_present(host), host->power_mode); - mrq->cmd->error = (unsigned int)-ENOMEDIUM; - -#if 1 - mrq->done(mrq); // call done directly. -#else - mrq->cmd->retries = 0; // please don't retry. - mmc_request_done(mmc, mrq); -#endif - return; - } - - /* start to process */ - spin_lock(&host->lock); + WARN_ON(host->mrq); + + /* start to process */ + spin_lock(&host->lock); #if 0 /* --- by chhung */ - if (sdio_pro_enable) { //=== for sdio profile === - if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) { - GPT_GetCounter64(&old_L32, &old_H32); - } - } + if (sdio_pro_enable) { //=== for sdio profile === + if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) + GPT_GetCounter64(&old_L32, &old_H32); + } #endif /* end of --- */ - - host->mrq = mrq; - if (msdc_do_request(mmc,mrq)) { - if(host->hw->flags & MSDC_REMOVABLE && ralink_soc == MT762X_SOC_MT7621AT && mrq->data && mrq->data->error) { - msdc_tune_request(mmc,mrq); - } - } + host->mrq = mrq; - /* ==== when request done, check if app_cmd ==== */ - if (mrq->cmd->opcode == MMC_APP_CMD) { - host->app_cmd = 1; - host->app_cmd_arg = mrq->cmd->arg; /* save the RCA */ - } else { - host->app_cmd = 0; - //host->app_cmd_arg = 0; - } - - host->mrq = NULL; + if (msdc_do_request(mmc, mrq)) { + if (host->hw->flags & MSDC_REMOVABLE && ralink_soc == MT762X_SOC_MT7621AT && mrq->data && mrq->data->error) + msdc_tune_request(mmc, mrq); + } + + /* ==== when request done, check if app_cmd ==== */ + if (mrq->cmd->opcode == MMC_APP_CMD) { + host->app_cmd = 1; + host->app_cmd_arg = mrq->cmd->arg; /* save the RCA */ + } else { + host->app_cmd = 0; + //host->app_cmd_arg = 0; + } + + host->mrq = NULL; #if 0 /* --- by chhung */ - //=== for sdio profile === - if (sdio_pro_enable) { - if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) { - GPT_GetCounter64(&new_L32, &new_H32); - ticks = msdc_time_calc(old_L32, old_H32, new_L32, new_H32); - - opcode = mrq->cmd->opcode; - if (mrq->cmd->data) { - sizes = mrq->cmd->data->blocks * mrq->cmd->data->blksz; - bRx = mrq->cmd->data->flags & MMC_DATA_READ ? 1 : 0 ; - } else { - bRx = mrq->cmd->arg & 0x80000000 ? 1 : 0; - } - - if (!mrq->cmd->error) { - msdc_performance(opcode, sizes, bRx, ticks); - } - } - } + //=== for sdio profile === + if (sdio_pro_enable) { + if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) { + GPT_GetCounter64(&new_L32, &new_H32); + ticks = msdc_time_calc(old_L32, old_H32, new_L32, new_H32); + + opcode = mrq->cmd->opcode; + if (mrq->cmd->data) { + sizes = mrq->cmd->data->blocks * mrq->cmd->data->blksz; + bRx = mrq->cmd->data->flags & MMC_DATA_READ ? 1 : 0; + } else { + bRx = mrq->cmd->arg & 0x80000000 ? 1 : 0; + } + + if (!mrq->cmd->error) + msdc_performance(opcode, sizes, bRx, ticks); + } + } #endif /* end of --- */ - spin_unlock(&host->lock); - - mmc_request_done(mmc, mrq); - - return; + spin_unlock(&host->lock); + + mmc_request_done(mmc, mrq); + + return; } /* called by ops.set_ios */ static void msdc_set_buswidth(struct msdc_host *host, u32 width) { - u32 base = host->base; - u32 val = sdr_read32(SDC_CFG); - - val &= ~SDC_CFG_BUSWIDTH; - - switch (width) { - default: - case MMC_BUS_WIDTH_1: - width = 1; - val |= (MSDC_BUS_1BITS << 16); - break; - case MMC_BUS_WIDTH_4: - val |= (MSDC_BUS_4BITS << 16); - break; - case MMC_BUS_WIDTH_8: - val |= (MSDC_BUS_8BITS << 16); - break; - } - - sdr_write32(SDC_CFG, val); + void __iomem *base = host->base; + u32 val = sdr_read32(SDC_CFG); - N_MSG(CFG, "Bus Width = %d", width); + val &= ~SDC_CFG_BUSWIDTH; + + switch (width) { + default: + case MMC_BUS_WIDTH_1: + width = 1; + val |= (MSDC_BUS_1BITS << 16); + break; + case MMC_BUS_WIDTH_4: + val |= (MSDC_BUS_4BITS << 16); + break; + case MMC_BUS_WIDTH_8: + val |= (MSDC_BUS_8BITS << 16); + break; + } + + sdr_write32(SDC_CFG, val); + + N_MSG(CFG, "Bus Width = %d", width); } /* ops.set_ios */ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { - struct msdc_host *host = mmc_priv(mmc); - struct msdc_hw *hw=host->hw; - u32 base = host->base; - u32 ddr = 0; + struct msdc_host *host = mmc_priv(mmc); + void __iomem *base = host->base; + u32 ddr = 0; #ifdef MT6575_SD_DEBUG - static char *vdd[] = { - "1.50v", "1.55v", "1.60v", "1.65v", "1.70v", "1.80v", "1.90v", - "2.00v", "2.10v", "2.20v", "2.30v", "2.40v", "2.50v", "2.60v", - "2.70v", "2.80v", "2.90v", "3.00v", "3.10v", "3.20v", "3.30v", - "3.40v", "3.50v", "3.60v" - }; - static char *power_mode[] = { - "OFF", "UP", "ON" - }; - static char *bus_mode[] = { - "UNKNOWN", "OPENDRAIN", "PUSHPULL" - }; - static char *timing[] = { - "LEGACY", "MMC_HS", "SD_HS" - }; + static char *vdd[] = { + "1.50v", "1.55v", "1.60v", "1.65v", "1.70v", "1.80v", "1.90v", + "2.00v", "2.10v", "2.20v", "2.30v", "2.40v", "2.50v", "2.60v", + "2.70v", "2.80v", "2.90v", "3.00v", "3.10v", "3.20v", "3.30v", + "3.40v", "3.50v", "3.60v" + }; + static char *power_mode[] = { + "OFF", "UP", "ON" + }; + static char *bus_mode[] = { + "UNKNOWN", "OPENDRAIN", "PUSHPULL" + }; + static char *timing[] = { + "LEGACY", "MMC_HS", "SD_HS" + }; - printk("SET_IOS: CLK(%dkHz), BUS(%s), BW(%u), PWR(%s), VDD(%s), TIMING(%s)", - ios->clock / 1000, bus_mode[ios->bus_mode], - (ios->bus_width == MMC_BUS_WIDTH_4) ? 4 : 1, - power_mode[ios->power_mode], vdd[ios->vdd], timing[ios->timing]); + printk("SET_IOS: CLK(%dkHz), BUS(%s), BW(%u), PWR(%s), VDD(%s), TIMING(%s)", + ios->clock / 1000, bus_mode[ios->bus_mode], + (ios->bus_width == MMC_BUS_WIDTH_4) ? 4 : 1, + power_mode[ios->power_mode], vdd[ios->vdd], timing[ios->timing]); #endif - msdc_set_buswidth(host, ios->bus_width); - - /* Power control ??? */ - switch (ios->power_mode) { - case MMC_POWER_OFF: - case MMC_POWER_UP: - // msdc_set_power_mode(host, ios->power_mode); /* --- by chhung */ - break; - case MMC_POWER_ON: - host->power_mode = MMC_POWER_ON; - break; - default: - break; - } + msdc_set_buswidth(host, ios->bus_width); - /* Clock control */ - if (host->mclk != ios->clock) { - if(ios->clock > 25000000) { - //if (!(host->hw->flags & MSDC_REMOVABLE)) { - INIT_MSG("SD data latch edge<%d>", hw->data_edge); - sdr_set_field(MSDC_IOCON, MSDC_IOCON_RSPL, hw->cmd_edge); - sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, hw->data_edge); - //} /* for tuning debug */ - } else { /* default value */ - sdr_write32(MSDC_IOCON, 0x00000000); - // sdr_write32(MSDC_DAT_RDDLY0, 0x00000000); - sdr_write32(MSDC_DAT_RDDLY0, 0x10101010); // for MT7620 E2 and afterward - sdr_write32(MSDC_DAT_RDDLY1, 0x00000000); - // sdr_write32(MSDC_PAD_TUNE, 0x00000000); - sdr_write32(MSDC_PAD_TUNE, 0x84101010); // for MT7620 E2 and afterward - } - msdc_set_mclk(host, ddr, ios->clock); - } + /* Power control ??? */ + switch (ios->power_mode) { + case MMC_POWER_OFF: + case MMC_POWER_UP: + // msdc_set_power_mode(host, ios->power_mode); /* --- by chhung */ + break; + case MMC_POWER_ON: + host->power_mode = MMC_POWER_ON; + break; + default: + break; + } + + /* Clock control */ + if (host->mclk != ios->clock) { + if (ios->clock > 25000000) { + //if (!(host->hw->flags & MSDC_REMOVABLE)) { + INIT_MSG("SD data latch edge<%d>", MSDC_SMPL_FALLING); + sdr_set_field(MSDC_IOCON, MSDC_IOCON_RSPL, + MSDC_SMPL_FALLING); + sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, + MSDC_SMPL_FALLING); + //} /* for tuning debug */ + } else { /* default value */ + sdr_write32(MSDC_IOCON, 0x00000000); + // sdr_write32(MSDC_DAT_RDDLY0, 0x00000000); + sdr_write32(MSDC_DAT_RDDLY0, 0x10101010); // for MT7620 E2 and afterward + sdr_write32(MSDC_DAT_RDDLY1, 0x00000000); + // sdr_write32(MSDC_PAD_TUNE, 0x00000000); + sdr_write32(MSDC_PAD_TUNE, 0x84101010); // for MT7620 E2 and afterward + } + msdc_set_mclk(host, ddr, ios->clock); + } } /* ops.get_ro */ static int msdc_ops_get_ro(struct mmc_host *mmc) { - struct msdc_host *host = mmc_priv(mmc); - u32 base = host->base; - unsigned long flags; - int ro = 0; + struct msdc_host *host = mmc_priv(mmc); + void __iomem *base = host->base; + unsigned long flags; + int ro = 0; - if (host->hw->flags & MSDC_WP_PIN_EN) { /* set for card */ - spin_lock_irqsave(&host->lock, flags); - ro = (sdr_read32(MSDC_PS) >> 31); - spin_unlock_irqrestore(&host->lock, flags); - } - return ro; + if (host->hw->flags & MSDC_WP_PIN_EN) { /* set for card */ + spin_lock_irqsave(&host->lock, flags); + ro = (sdr_read32(MSDC_PS) >> 31); + spin_unlock_irqrestore(&host->lock, flags); + } + return ro; } /* ops.get_cd */ static int msdc_ops_get_cd(struct mmc_host *mmc) { - struct msdc_host *host = mmc_priv(mmc); - u32 base = host->base; - unsigned long flags; - int present = 1; + struct msdc_host *host = mmc_priv(mmc); + void __iomem *base = host->base; + unsigned long flags; + int present = 1; - /* for sdio, MSDC_REMOVABLE not set, always return 1 */ - if (!(host->hw->flags & MSDC_REMOVABLE)) { - /* For sdio, read H/W always get<1>, but may timeout some times */ + /* for sdio, MSDC_REMOVABLE not set, always return 1 */ + if (!(host->hw->flags & MSDC_REMOVABLE)) { + /* For sdio, read H/W always get<1>, but may timeout some times */ #if 1 - host->card_inserted = 1; - return 1; + host->card_inserted = 1; + return 1; #else - host->card_inserted = (host->pm_state.event == PM_EVENT_USER_RESUME) ? 1 : 0; - INIT_MSG("sdio ops_get_cd<%d>", host->card_inserted); - return host->card_inserted; + host->card_inserted = (host->pm_state.event == PM_EVENT_USER_RESUME) ? 1 : 0; + INIT_MSG("sdio ops_get_cd<%d>", host->card_inserted); + return host->card_inserted; #endif - } + } - /* MSDC_CD_PIN_EN set for card */ - if (host->hw->flags & MSDC_CD_PIN_EN) { - spin_lock_irqsave(&host->lock, flags); -#if 0 - present = host->card_inserted; /* why not read from H/W: Fix me*/ + /* MSDC_CD_PIN_EN set for card */ + if (host->hw->flags & MSDC_CD_PIN_EN) { + spin_lock_irqsave(&host->lock, flags); +#if 0 + present = host->card_inserted; /* why not read from H/W: Fix me*/ #else - // CD - if (cd_active_low) - present = (sdr_read32(MSDC_PS) & MSDC_PS_CDSTS) ? 0 : 1; - else - present = (sdr_read32(MSDC_PS) & MSDC_PS_CDSTS) ? 1 : 0; - if (host->mmc->caps & MMC_CAP_NEEDS_POLL) - present = 1; - host->card_inserted = present; -#endif - spin_unlock_irqrestore(&host->lock, flags); - } else { - present = 0; /* TODO? Check DAT3 pins for card detection */ - } + // CD + if (cd_active_low) + present = (sdr_read32(MSDC_PS) & MSDC_PS_CDSTS) ? 0 : 1; + else + present = (sdr_read32(MSDC_PS) & MSDC_PS_CDSTS) ? 1 : 0; + host->card_inserted = present; +#endif + spin_unlock_irqrestore(&host->lock, flags); + } else { + present = 0; /* TODO? Check DAT3 pins for card detection */ + } - INIT_MSG("ops_get_cd return<%d>", present); - return present; -} - -/* ops.enable_sdio_irq */ -static void msdc_ops_enable_sdio_irq(struct mmc_host *mmc, int enable) -{ - struct msdc_host *host = mmc_priv(mmc); - struct msdc_hw *hw = host->hw; - u32 base = host->base; - u32 tmp; - - if (hw->flags & MSDC_EXT_SDIO_IRQ) { /* yes for sdio */ - if (enable) { - hw->enable_sdio_eirq(); /* combo_sdio_enable_eirq */ - } else { - hw->disable_sdio_eirq(); /* combo_sdio_disable_eirq */ - } - } else { - ERR_MSG("XXX "); /* so never enter here */ - tmp = sdr_read32(SDC_CFG); - /* FIXME. Need to interrupt gap detection */ - if (enable) { - tmp |= (SDC_CFG_SDIOIDE | SDC_CFG_SDIOINTWKUP); - } else { - tmp &= ~(SDC_CFG_SDIOIDE | SDC_CFG_SDIOINTWKUP); - } - sdr_write32(SDC_CFG, tmp); - } + INIT_MSG("ops_get_cd return<%d>", present); + return present; } static struct mmc_host_ops mt_msdc_ops = { - .request = msdc_ops_request, - .set_ios = msdc_ops_set_ios, - .get_ro = msdc_ops_get_ro, - .get_cd = msdc_ops_get_cd, - .enable_sdio_irq = msdc_ops_enable_sdio_irq, + .request = msdc_ops_request, + .set_ios = msdc_ops_set_ios, + .get_ro = msdc_ops_get_ro, + .get_cd = msdc_ops_get_cd, }; /*--------------------------------------------------------------------------*/ @@ -2378,150 +1880,135 @@ static struct mmc_host_ops mt_msdc_ops = { /*--------------------------------------------------------------------------*/ static irqreturn_t msdc_irq(int irq, void *dev_id) { - struct msdc_host *host = (struct msdc_host *)dev_id; - struct mmc_data *data = host->data; - struct mmc_command *cmd = host->cmd; - u32 base = host->base; - - u32 cmdsts = MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | MSDC_INT_CMDRDY | - MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | MSDC_INT_ACMDRDY | - MSDC_INT_ACMD19_DONE; - u32 datsts = MSDC_INT_DATCRCERR |MSDC_INT_DATTMO; + struct msdc_host *host = (struct msdc_host *)dev_id; + struct mmc_data *data = host->data; + struct mmc_command *cmd = host->cmd; + void __iomem *base = host->base; - u32 intsts = sdr_read32(MSDC_INT); - u32 inten = sdr_read32(MSDC_INTEN); inten &= intsts; + u32 cmdsts = MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO | MSDC_INT_CMDRDY | + MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | MSDC_INT_ACMDRDY | + MSDC_INT_ACMD19_DONE; + u32 datsts = MSDC_INT_DATCRCERR | MSDC_INT_DATTMO; - sdr_write32(MSDC_INT, intsts); /* clear interrupts */ - /* MSG will cause fatal error */ - - /* card change interrupt */ - if (intsts & MSDC_INT_CDSC){ - if (mtk_sw_poll) - return IRQ_HANDLED; - IRQ_MSG("MSDC_INT_CDSC irq<0x%.8x>", intsts); -#if 0 /* ---/+++ by chhung: fix slot mechanical bounce issue */ - tasklet_hi_schedule(&host->card_tasklet); -#else - schedule_delayed_work(&host->card_delaywork, HZ); -#endif - /* tuning when plug card ? */ - } - - /* sdio interrupt */ - if (intsts & MSDC_INT_SDIOIRQ){ - IRQ_MSG("XXX MSDC_INT_SDIOIRQ"); /* seems not sdio irq */ - //mmc_signal_sdio_irq(host->mmc); - } + u32 intsts = sdr_read32(MSDC_INT); + u32 inten = sdr_read32(MSDC_INTEN); inten &= intsts; - /* transfer complete interrupt */ - if (data != NULL) { - if (inten & MSDC_INT_XFER_COMPL) { - data->bytes_xfered = host->dma.xfersz; - complete(&host->xfer_done); - } - - if (intsts & datsts) { - /* do basic reset, or stop command will sdc_busy */ - msdc_reset(); - msdc_clr_fifo(); - msdc_clr_int(); - atomic_set(&host->abort, 1); /* For PIO mode exit */ - - if (intsts & MSDC_INT_DATTMO){ - IRQ_MSG("XXX CMD<%d> MSDC_INT_DATTMO", host->mrq->cmd->opcode); - data->error = (unsigned int)-ETIMEDOUT; - } - else if (intsts & MSDC_INT_DATCRCERR){ - IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, sdr_read32(SDC_DCRC_STS)); - data->error = (unsigned int)-EIO; - } - - //if(sdr_read32(MSDC_INTEN) & MSDC_INT_XFER_COMPL) { - if (host->dma_xfer) { - complete(&host->xfer_done); /* Read CRC come fast, XFER_COMPL not enabled */ - } /* PIO mode can't do complete, because not init */ - } - } + sdr_write32(MSDC_INT, intsts); /* clear interrupts */ + /* MSG will cause fatal error */ - /* command interrupts */ - if ((cmd != NULL) && (intsts & cmdsts)) { - if ((intsts & MSDC_INT_CMDRDY) || (intsts & MSDC_INT_ACMDRDY) || - (intsts & MSDC_INT_ACMD19_DONE)) { - u32 *rsp = &cmd->resp[0]; - - switch (host->cmd_rsp) { - case RESP_NONE: - break; - case RESP_R2: - *rsp++ = sdr_read32(SDC_RESP3); *rsp++ = sdr_read32(SDC_RESP2); - *rsp++ = sdr_read32(SDC_RESP1); *rsp++ = sdr_read32(SDC_RESP0); - break; - default: /* Response types 1, 3, 4, 5, 6, 7(1b) */ - if ((intsts & MSDC_INT_ACMDRDY) || (intsts & MSDC_INT_ACMD19_DONE)) { - *rsp = sdr_read32(SDC_ACMD_RESP); - } else { - *rsp = sdr_read32(SDC_RESP0); - } - break; - } - } else if ((intsts & MSDC_INT_RSPCRCERR) || (intsts & MSDC_INT_ACMDCRCERR)) { - if(intsts & MSDC_INT_ACMDCRCERR){ - IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDCRCERR",cmd->opcode); - } - else { - IRQ_MSG("XXX CMD<%d> MSDC_INT_RSPCRCERR",cmd->opcode); - } - cmd->error = (unsigned int)-EIO; - } else if ((intsts & MSDC_INT_CMDTMO) || (intsts & MSDC_INT_ACMDTMO)) { - if(intsts & MSDC_INT_ACMDTMO){ - IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDTMO",cmd->opcode); - } - else { - IRQ_MSG("XXX CMD<%d> MSDC_INT_CMDTMO",cmd->opcode); - } - cmd->error = (unsigned int)-ETIMEDOUT; - msdc_reset(); - msdc_clr_fifo(); - msdc_clr_int(); - } - complete(&host->cmd_done); - } + /* card change interrupt */ + if (intsts & MSDC_INT_CDSC) { + if (host->mmc->caps & MMC_CAP_NEEDS_POLL) + return IRQ_HANDLED; + IRQ_MSG("MSDC_INT_CDSC irq<0x%.8x>", intsts); + schedule_delayed_work(&host->card_delaywork, HZ); + /* tuning when plug card ? */ + } + + /* sdio interrupt */ + if (intsts & MSDC_INT_SDIOIRQ) { + IRQ_MSG("XXX MSDC_INT_SDIOIRQ"); /* seems not sdio irq */ + //mmc_signal_sdio_irq(host->mmc); + } + + /* transfer complete interrupt */ + if (data != NULL) { + if (inten & MSDC_INT_XFER_COMPL) { + data->bytes_xfered = host->xfer_size; + complete(&host->xfer_done); + } + + if (intsts & datsts) { + /* do basic reset, or stop command will sdc_busy */ + msdc_reset_hw(host); + msdc_clr_fifo(); + msdc_clr_int(); + + if (intsts & MSDC_INT_DATTMO) { + IRQ_MSG("XXX CMD<%d> MSDC_INT_DATTMO", host->mrq->cmd->opcode); + data->error = -ETIMEDOUT; + } else if (intsts & MSDC_INT_DATCRCERR) { + IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, sdr_read32(SDC_DCRC_STS)); + data->error = -EIO; + } + + //if(sdr_read32(MSDC_INTEN) & MSDC_INT_XFER_COMPL) { + complete(&host->xfer_done); /* Read CRC come fast, XFER_COMPL not enabled */ + } + } + + /* command interrupts */ + if ((cmd != NULL) && (intsts & cmdsts)) { + if ((intsts & MSDC_INT_CMDRDY) || (intsts & MSDC_INT_ACMDRDY) || + (intsts & MSDC_INT_ACMD19_DONE)) { + u32 *rsp = &cmd->resp[0]; + + switch (host->cmd_rsp) { + case RESP_NONE: + break; + case RESP_R2: + *rsp++ = sdr_read32(SDC_RESP3); *rsp++ = sdr_read32(SDC_RESP2); + *rsp++ = sdr_read32(SDC_RESP1); *rsp++ = sdr_read32(SDC_RESP0); + break; + default: /* Response types 1, 3, 4, 5, 6, 7(1b) */ + if ((intsts & MSDC_INT_ACMDRDY) || (intsts & MSDC_INT_ACMD19_DONE)) + *rsp = sdr_read32(SDC_ACMD_RESP); + else + *rsp = sdr_read32(SDC_RESP0); + break; + } + } else if ((intsts & MSDC_INT_RSPCRCERR) || (intsts & MSDC_INT_ACMDCRCERR)) { + if (intsts & MSDC_INT_ACMDCRCERR) + IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDCRCERR", cmd->opcode); + else + IRQ_MSG("XXX CMD<%d> MSDC_INT_RSPCRCERR", cmd->opcode); + cmd->error = -EIO; + } else if ((intsts & MSDC_INT_CMDTMO) || (intsts & MSDC_INT_ACMDTMO)) { + if (intsts & MSDC_INT_ACMDTMO) + IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDTMO", cmd->opcode); + else + IRQ_MSG("XXX CMD<%d> MSDC_INT_CMDTMO", cmd->opcode); + cmd->error = -ETIMEDOUT; + msdc_reset_hw(host); + msdc_clr_fifo(); + msdc_clr_int(); + } + complete(&host->cmd_done); + } + + /* mmc irq interrupts */ + if (intsts & MSDC_INT_MMCIRQ) + printk(KERN_INFO "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n", host->id, sdr_read32(SDC_CSTS)); - /* mmc irq interrupts */ - if (intsts & MSDC_INT_MMCIRQ) { - printk(KERN_INFO "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n", host->id, sdr_read32(SDC_CSTS)); - } - #ifdef MT6575_SD_DEBUG - { - msdc_int_reg *int_reg = (msdc_int_reg*)&intsts; - N_MSG(INT, "IRQ_EVT(0x%x): MMCIRQ(%d) CDSC(%d), ACRDY(%d), ACTMO(%d), ACCRE(%d) AC19DN(%d)", - intsts, - int_reg->mmcirq, - int_reg->cdsc, - int_reg->atocmdrdy, - int_reg->atocmdtmo, - int_reg->atocmdcrc, - int_reg->atocmd19done); - N_MSG(INT, "IRQ_EVT(0x%x): SDIO(%d) CMDRDY(%d), CMDTMO(%d), RSPCRC(%d), CSTA(%d)", - intsts, - int_reg->sdioirq, - int_reg->cmdrdy, - int_reg->cmdtmo, - int_reg->rspcrc, - int_reg->csta); - N_MSG(INT, "IRQ_EVT(0x%x): XFCMP(%d) DXDONE(%d), DATTMO(%d), DATCRC(%d), DMAEMP(%d)", - intsts, - int_reg->xfercomp, - int_reg->dxferdone, - int_reg->dattmo, - int_reg->datcrc, - int_reg->dmaqempty); - - } + { +/* msdc_int_reg *int_reg = (msdc_int_reg*)&intsts;*/ + N_MSG(INT, "IRQ_EVT(0x%x): MMCIRQ(%d) CDSC(%d), ACRDY(%d), ACTMO(%d), ACCRE(%d) AC19DN(%d)", + intsts, + int_reg->mmcirq, + int_reg->cdsc, + int_reg->atocmdrdy, + int_reg->atocmdtmo, + int_reg->atocmdcrc, + int_reg->atocmd19done); + N_MSG(INT, "IRQ_EVT(0x%x): SDIO(%d) CMDRDY(%d), CMDTMO(%d), RSPCRC(%d), CSTA(%d)", + intsts, + int_reg->sdioirq, + int_reg->cmdrdy, + int_reg->cmdtmo, + int_reg->rspcrc, + int_reg->csta); + N_MSG(INT, "IRQ_EVT(0x%x): XFCMP(%d) DXDONE(%d), DATTMO(%d), DATCRC(%d), DMAEMP(%d)", + intsts, + int_reg->xfercomp, + int_reg->dxferdone, + int_reg->dattmo, + int_reg->datcrc, + int_reg->dmaqempty); + } #endif - - return IRQ_HANDLED; + + return IRQ_HANDLED; } /*--------------------------------------------------------------------------*/ @@ -2531,15 +2018,15 @@ static irqreturn_t msdc_irq(int irq, void *dev_id) static void msdc_enable_cd_irq(struct msdc_host *host, int enable) { struct msdc_hw *hw = host->hw; - u32 base = host->base; + void __iomem *base = host->base; /* for sdio, not set */ if ((hw->flags & MSDC_CD_PIN_EN) == 0) { /* Pull down card detection pin since it is not avaiable */ /* - if (hw->config_gpio_pin) - hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN); - */ + if (hw->config_gpio_pin) + hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN); + */ sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN); sdr_clr_bits(MSDC_INTEN, MSDC_INTEN_CDSC); sdr_clr_bits(SDC_CFG, SDC_CFG_INSWKUP); @@ -2549,424 +2036,374 @@ static void msdc_enable_cd_irq(struct msdc_host *host, int enable) N_MSG(CFG, "CD IRQ Eanable(%d)", enable); if (enable) { - if (hw->enable_cd_eirq) { /* not set, never enter */ - hw->enable_cd_eirq(); - } else { - /* card detection circuit relies on the core power so that the core power - * shouldn't be turned off. Here adds a reference count to keep - * the core power alive. - */ - //msdc_vcore_on(host); //did in msdc_init_hw() + /* card detection circuit relies on the core power so that the core power + * shouldn't be turned off. Here adds a reference count to keep + * the core power alive. + */ + //msdc_vcore_on(host); //did in msdc_init_hw() - if (hw->config_gpio_pin) /* NULL */ - hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_UP); + if (hw->config_gpio_pin) /* NULL */ + hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_UP); - sdr_set_field(MSDC_PS, MSDC_PS_CDDEBOUNCE, DEFAULT_DEBOUNCE); - sdr_set_bits(MSDC_PS, MSDC_PS_CDEN); - sdr_set_bits(MSDC_INTEN, MSDC_INTEN_CDSC); - sdr_set_bits(SDC_CFG, SDC_CFG_INSWKUP); /* not in document! Fix me */ - } - } else { - if (hw->disable_cd_eirq) { - hw->disable_cd_eirq(); - } else { - if (hw->config_gpio_pin) /* NULL */ - hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN); + sdr_set_field(MSDC_PS, MSDC_PS_CDDEBOUNCE, DEFAULT_DEBOUNCE); + sdr_set_bits(MSDC_PS, MSDC_PS_CDEN); + sdr_set_bits(MSDC_INTEN, MSDC_INTEN_CDSC); + sdr_set_bits(SDC_CFG, SDC_CFG_INSWKUP); /* not in document! Fix me */ + } else { + if (hw->config_gpio_pin) /* NULL */ + hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN); - sdr_clr_bits(SDC_CFG, SDC_CFG_INSWKUP); - sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN); - sdr_clr_bits(MSDC_INTEN, MSDC_INTEN_CDSC); + sdr_clr_bits(SDC_CFG, SDC_CFG_INSWKUP); + sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN); + sdr_clr_bits(MSDC_INTEN, MSDC_INTEN_CDSC); - /* Here decreases a reference count to core power since card - * detection circuit is shutdown. - */ - //msdc_vcore_off(host); - } - } + /* Here decreases a reference count to core power since card + * detection circuit is shutdown. + */ + //msdc_vcore_off(host); + } } /* called by msdc_drv_probe */ static void msdc_init_hw(struct msdc_host *host) { - u32 base = host->base; - struct msdc_hw *hw = host->hw; + void __iomem *base = host->base; - /* Power on */ + /* Power on */ #if 0 /* --- by chhung */ - msdc_vcore_on(host); - msdc_pin_reset(host, MSDC_PIN_PULL_UP); - msdc_select_clksrc(host, hw->clk_src); - enable_clock(PERI_MSDC0_PDN + host->id, "SD"); - msdc_vdd_on(host); + msdc_vcore_on(host); + msdc_pin_reset(host, MSDC_PIN_PULL_UP); + msdc_select_clksrc(host, hw->clk_src); + enable_clock(PERI_MSDC0_PDN + host->id, "SD"); + msdc_vdd_on(host); #endif /* end of --- */ - /* Configure to MMC/SD mode */ - sdr_set_field(MSDC_CFG, MSDC_CFG_MODE, MSDC_SDMMC); - - /* Reset */ - msdc_reset(); - msdc_clr_fifo(); + /* Configure to MMC/SD mode */ + sdr_set_field(MSDC_CFG, MSDC_CFG_MODE, MSDC_SDMMC); - /* Disable card detection */ - sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN); + /* Reset */ + msdc_reset_hw(host); + msdc_clr_fifo(); + + /* Disable card detection */ + sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN); + + /* Disable and clear all interrupts */ + sdr_clr_bits(MSDC_INTEN, sdr_read32(MSDC_INTEN)); + sdr_write32(MSDC_INT, sdr_read32(MSDC_INT)); - /* Disable and clear all interrupts */ - sdr_clr_bits(MSDC_INTEN, sdr_read32(MSDC_INTEN)); - sdr_write32(MSDC_INT, sdr_read32(MSDC_INT)); - #if 1 /* reset tuning parameter */ - sdr_write32(MSDC_PAD_CTL0, 0x00090000); - sdr_write32(MSDC_PAD_CTL1, 0x000A0000); - sdr_write32(MSDC_PAD_CTL2, 0x000A0000); - // sdr_write32(MSDC_PAD_TUNE, 0x00000000); - sdr_write32(MSDC_PAD_TUNE, 0x84101010); // for MT7620 E2 and afterward - // sdr_write32(MSDC_DAT_RDDLY0, 0x00000000); - sdr_write32(MSDC_DAT_RDDLY0, 0x10101010); // for MT7620 E2 and afterward - sdr_write32(MSDC_DAT_RDDLY1, 0x00000000); - sdr_write32(MSDC_IOCON, 0x00000000); + sdr_write32(MSDC_PAD_CTL0, 0x00090000); + sdr_write32(MSDC_PAD_CTL1, 0x000A0000); + sdr_write32(MSDC_PAD_CTL2, 0x000A0000); + // sdr_write32(MSDC_PAD_TUNE, 0x00000000); + sdr_write32(MSDC_PAD_TUNE, 0x84101010); // for MT7620 E2 and afterward + // sdr_write32(MSDC_DAT_RDDLY0, 0x00000000); + sdr_write32(MSDC_DAT_RDDLY0, 0x10101010); // for MT7620 E2 and afterward + sdr_write32(MSDC_DAT_RDDLY1, 0x00000000); + sdr_write32(MSDC_IOCON, 0x00000000); #if 0 // use MT7620 default value: 0x403c004f - sdr_write32(MSDC_PATCH_BIT0, 0x003C000F); /* bit0 modified: Rx Data Clock Source: 1 -> 2.0*/ + sdr_write32(MSDC_PATCH_BIT0, 0x003C000F); /* bit0 modified: Rx Data Clock Source: 1 -> 2.0*/ #endif - if (sdr_read32(MSDC_ECO_VER) >= 4) { - if (host->id == 1) { - sdr_set_field(MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_WRDAT_CRCS, 1); - sdr_set_field(MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_CMD_RSP, 1); - - /* internal clock: latch read data */ - sdr_set_bits(MSDC_PATCH_BIT0, MSDC_PATCH_BIT_CKGEN_CK); - } - } -#endif + if (sdr_read32(MSDC_ECO_VER) >= 4) { + if (host->id == 1) { + sdr_set_field(MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_WRDAT_CRCS, 1); + sdr_set_field(MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_CMD_RSP, 1); - /* for safety, should clear SDC_CFG.SDIO_INT_DET_EN & set SDC_CFG.SDIO in - pre-loader,uboot,kernel drivers. and SDC_CFG.SDIO_INT_DET_EN will be only - set when kernel driver wants to use SDIO bus interrupt */ - /* Configure to enable SDIO mode. it's must otherwise sdio cmd5 failed */ - sdr_set_bits(SDC_CFG, SDC_CFG_SDIO); + /* internal clock: latch read data */ + sdr_set_bits(MSDC_PATCH_BIT0, MSDC_PATCH_BIT_CKGEN_CK); + } + } +#endif - /* disable detect SDIO device interupt function */ - sdr_clr_bits(SDC_CFG, SDC_CFG_SDIOIDE); + /* for safety, should clear SDC_CFG.SDIO_INT_DET_EN & set SDC_CFG.SDIO in + pre-loader,uboot,kernel drivers. and SDC_CFG.SDIO_INT_DET_EN will be only + set when kernel driver wants to use SDIO bus interrupt */ + /* Configure to enable SDIO mode. it's must otherwise sdio cmd5 failed */ + sdr_set_bits(SDC_CFG, SDC_CFG_SDIO); - /* eneable SMT for glitch filter */ - sdr_set_bits(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT); - sdr_set_bits(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT); - sdr_set_bits(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT); + /* disable detect SDIO device interupt function */ + sdr_clr_bits(SDC_CFG, SDC_CFG_SDIOIDE); + + /* eneable SMT for glitch filter */ + sdr_set_bits(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT); + sdr_set_bits(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT); + sdr_set_bits(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT); #if 1 - /* set clk, cmd, dat pad driving */ - sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, hw->clk_drv); - sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, hw->clk_drv); - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, hw->cmd_drv); - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, hw->cmd_drv); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, hw->dat_drv); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, hw->dat_drv); -#else - sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 0); - sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 0); - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 0); - sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 0); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 0); - sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 0); + /* set clk, cmd, dat pad driving */ + sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 4); + sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 4); + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 4); + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 4); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 4); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 4); +#else + sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 0); + sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 0); + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 0); + sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 0); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 0); + sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 0); #endif - /* set sampling edge */ + /* set sampling edge */ - /* write crc timeout detection */ - sdr_set_field(MSDC_PATCH_BIT0, 1 << 30, 1); + /* write crc timeout detection */ + sdr_set_field(MSDC_PATCH_BIT0, 1 << 30, 1); - /* Configure to default data timeout */ - sdr_set_field(SDC_CFG, SDC_CFG_DTOC, DEFAULT_DTOC); + /* Configure to default data timeout */ + sdr_set_field(SDC_CFG, SDC_CFG_DTOC, DEFAULT_DTOC); - msdc_set_buswidth(host, MMC_BUS_WIDTH_1); + msdc_set_buswidth(host, MMC_BUS_WIDTH_1); - N_MSG(FUC, "init hardware done!"); + N_MSG(FUC, "init hardware done!"); } /* called by msdc_drv_remove */ static void msdc_deinit_hw(struct msdc_host *host) { - u32 base = host->base; + void __iomem *base = host->base; - /* Disable and clear all interrupts */ - sdr_clr_bits(MSDC_INTEN, sdr_read32(MSDC_INTEN)); - sdr_write32(MSDC_INT, sdr_read32(MSDC_INT)); + /* Disable and clear all interrupts */ + sdr_clr_bits(MSDC_INTEN, sdr_read32(MSDC_INTEN)); + sdr_write32(MSDC_INT, sdr_read32(MSDC_INT)); - /* Disable card detection */ - msdc_enable_cd_irq(host, 0); - // msdc_set_power_mode(host, MMC_POWER_OFF); /* make sure power down */ /* --- by chhung */ + /* Disable card detection */ + msdc_enable_cd_irq(host, 0); + // msdc_set_power_mode(host, MMC_POWER_OFF); /* make sure power down */ /* --- by chhung */ } /* init gpd and bd list in msdc_drv_probe */ static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma) { - gpd_t *gpd = dma->gpd; - bd_t *bd = dma->bd; - bd_t *ptr, *prev; - - /* we just support one gpd */ - int bdlen = MAX_BD_PER_GPD; + struct gpd *gpd = dma->gpd; + struct bd *bd = dma->bd; + int i; - /* init the 2 gpd */ - memset(gpd, 0, sizeof(gpd_t) * 2); - //gpd->next = (void *)virt_to_phys(gpd + 1); /* pointer to a null gpd, bug! kmalloc <-> virt_to_phys */ - //gpd->next = (dma->gpd_addr + 1); /* bug */ - gpd->next = (void *)((u32)dma->gpd_addr + sizeof(gpd_t)); + /* we just support one gpd, but gpd->next must be set for desc + * DMA. That's why we alloc 2 gpd structurs. + */ - //gpd->intr = 0; - gpd->bdp = 1; /* hwo, cs, bd pointer */ - //gpd->ptr = (void*)virt_to_phys(bd); - gpd->ptr = (void *)dma->bd_addr; /* physical address */ - - memset(bd, 0, sizeof(bd_t) * bdlen); - ptr = bd + bdlen - 1; - //ptr->eol = 1; /* 0 or 1 [Fix me]*/ - //ptr->next = 0; - - while (ptr != bd) { - prev = ptr - 1; - prev->next = (void *)(dma->bd_addr + sizeof(bd_t) *(ptr - bd)); - ptr = prev; - } + memset(gpd, 0, sizeof(struct gpd) * 2); + + gpd->bdp = 1; /* hwo, cs, bd pointer */ + gpd->ptr = (void *)dma->bd_addr; /* physical address */ + gpd->next = (void *)((u32)dma->gpd_addr + sizeof(struct gpd)); + + memset(bd, 0, sizeof(struct bd) * MAX_BD_NUM); + for (i = 0; i < (MAX_BD_NUM - 1); i++) + bd[i].next = (void *)(dma->bd_addr + sizeof(*bd) * (i + 1)); } static int msdc_drv_probe(struct platform_device *pdev) { - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - __iomem void *base; - struct mmc_host *mmc; - struct resource *mem; - struct msdc_host *host; - struct msdc_hw *hw; - int ret, irq; - - pdev->dev.platform_data = &msdc0_hw; - - if (of_property_read_bool(pdev->dev.of_node, "mtk,wp-en")) - msdc0_hw.flags |= MSDC_WP_PIN_EN; - - /* Allocate MMC host for this device */ - mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); - if (!mmc) return -ENOMEM; + struct resource *res; + __iomem void *base; + struct mmc_host *mmc; + struct msdc_host *host; + struct msdc_hw *hw; + int ret; + u32 reg; - hw = (struct msdc_hw*)pdev->dev.platform_data; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); + // Set the pins for sdxc to sdxc mode + //FIXME: this should be done by pinctl and not by the sd driver + reg = sdr_read32((void __iomem *)(RALINK_SYSCTL_BASE + 0x60)) & ~(0x3 << 18); + sdr_write32((void __iomem *)(RALINK_SYSCTL_BASE + 0x60), reg); - //BUG_ON((!hw) || (!mem) || (irq < 0)); /* --- by chhung */ - - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); + hw = &msdc0_hw; - /* Set host parameters to mmc */ - mmc->ops = &mt_msdc_ops; - mmc->f_min = HOST_MIN_MCLK; - mmc->f_max = HOST_MAX_MCLK; - mmc->ocr_avail = MSDC_OCR_AVAIL; - - /* For sd card: MSDC_SYS_SUSPEND | MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE | MSDC_HIGHSPEED, - For sdio : MSDC_EXT_SDIO_IRQ | MSDC_HIGHSPEED */ - if (hw->flags & MSDC_HIGHSPEED) { - mmc->caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; - } - if (hw->data_pins == 4) { /* current data_pins are all 4*/ - mmc->caps |= MMC_CAP_4_BIT_DATA; - } else if (hw->data_pins == 8) { - mmc->caps |= MMC_CAP_8_BIT_DATA; - } - if ((hw->flags & MSDC_SDIO_IRQ) || (hw->flags & MSDC_EXT_SDIO_IRQ)) - mmc->caps |= MMC_CAP_SDIO_IRQ; /* yes for sdio */ + if (of_property_read_bool(pdev->dev.of_node, "mtk,wp-en")) + msdc0_hw.flags |= MSDC_WP_PIN_EN; - cd_active_low = !of_property_read_bool(pdev->dev.of_node, "mediatek,cd-high"); - mtk_sw_poll = of_property_read_bool(pdev->dev.of_node, "mediatek,cd-poll"); + /* Allocate MMC host for this device */ + mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); + if (!mmc) + return -ENOMEM; - if (mtk_sw_poll) - mmc->caps |= MMC_CAP_NEEDS_POLL; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) { + ret = PTR_ERR(base); + goto host_free; + } - /* MMC core transfer sizes tunable parameters */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0) - mmc->max_segs = MAX_HW_SGMTS; -#else - mmc->max_hw_segs = MAX_HW_SGMTS; - mmc->max_phys_segs = MAX_PHY_SGMTS; -#endif - mmc->max_seg_size = MAX_SGMT_SZ; - mmc->max_blk_size = HOST_MAX_BLKSZ; - mmc->max_req_size = MAX_REQ_SZ; - mmc->max_blk_count = mmc->max_req_size; + /* Set host parameters to mmc */ + mmc->ops = &mt_msdc_ops; + mmc->f_min = HOST_MIN_MCLK; + mmc->f_max = HOST_MAX_MCLK; + mmc->ocr_avail = MSDC_OCR_AVAIL; - host = mmc_priv(mmc); - host->hw = hw; - host->mmc = mmc; - host->id = 0; - host->error = 0; - host->irq = irq; - host->base = (unsigned long) base; - host->mclk = 0; /* mclk: the request clock of mmc sub-system */ - host->hclk = hclks[hw->clk_src]; /* hclk: clock of clock source to msdc controller */ - host->sclk = 0; /* sclk: the really clock after divition */ - host->pm_state = PMSG_RESUME; - host->suspend = 0; - host->core_clkon = 0; - host->card_clkon = 0; - host->core_power = 0; - host->power_mode = MMC_POWER_OFF; + mmc->caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; + + //TODO: read this as bus-width from dt (via mmc_of_parse) + mmc->caps |= MMC_CAP_4_BIT_DATA; + + cd_active_low = !of_property_read_bool(pdev->dev.of_node, "mediatek,cd-high"); + + if (of_property_read_bool(pdev->dev.of_node, "mediatek,cd-poll")) + mmc->caps |= MMC_CAP_NEEDS_POLL; + + /* MMC core transfer sizes tunable parameters */ + mmc->max_segs = MAX_HW_SGMTS; + + mmc->max_seg_size = MAX_SGMT_SZ; + mmc->max_blk_size = HOST_MAX_BLKSZ; + mmc->max_req_size = MAX_REQ_SZ; + mmc->max_blk_count = mmc->max_req_size; + + host = mmc_priv(mmc); + host->hw = hw; + host->mmc = mmc; + host->id = pdev->id; + if (host->id < 0 || host->id >= 4) + host->id = 0; + host->error = 0; + + host->irq = platform_get_irq(pdev, 0); + if (host->irq < 0) { + ret = -EINVAL; + goto host_free; + } + + host->base = base; + host->mclk = 0; /* mclk: the request clock of mmc sub-system */ + host->hclk = hclks[hw->clk_src]; /* hclk: clock of clock source to msdc controller */ + host->sclk = 0; /* sclk: the really clock after divition */ + host->pm_state = PMSG_RESUME; + host->suspend = 0; + host->core_clkon = 0; + host->card_clkon = 0; + host->core_power = 0; + host->power_mode = MMC_POWER_OFF; // host->card_inserted = hw->flags & MSDC_REMOVABLE ? 0 : 1; - host->timeout_ns = 0; - host->timeout_clks = DEFAULT_DTOC * 65536; - - host->mrq = NULL; - //init_MUTEX(&host->sem); /* we don't need to support multiple threads access */ - - host->dma.used_gpd = 0; - host->dma.used_bd = 0; - mmc_dev(mmc)->dma_mask = NULL; + host->timeout_ns = 0; + host->timeout_clks = DEFAULT_DTOC * 65536; - /* using dma_alloc_coherent*/ /* todo: using 1, for all 4 slots */ - host->dma.gpd = dma_alloc_coherent(NULL, MAX_GPD_NUM * sizeof(gpd_t), &host->dma.gpd_addr, GFP_KERNEL); - host->dma.bd = dma_alloc_coherent(NULL, MAX_BD_NUM * sizeof(bd_t), &host->dma.bd_addr, GFP_KERNEL); - BUG_ON((!host->dma.gpd) || (!host->dma.bd)); - msdc_init_gpd_bd(host, &host->dma); - -#if 0 - tasklet_init(&host->card_tasklet, msdc_tasklet_card, (ulong)host); -#else - INIT_DELAYED_WORK(&host->card_delaywork, msdc_tasklet_card); -#endif - spin_lock_init(&host->lock); - msdc_init_hw(host); + host->mrq = NULL; + //init_MUTEX(&host->sem); /* we don't need to support multiple threads access */ - if (ralink_soc == MT762X_SOC_MT7621AT) - ret = request_irq((unsigned int)irq, msdc_irq, 0, dev_name(&pdev->dev), host); - else - ret = request_irq((unsigned int)irq, msdc_irq, IRQF_TRIGGER_LOW, dev_name(&pdev->dev), host); + mmc_dev(mmc)->dma_mask = NULL; - if (ret) goto release; - // mt65xx_irq_unmask(irq); /* --- by chhung */ - - if (hw->flags & MSDC_CD_PIN_EN) { /* not set for sdio */ - if (hw->request_cd_eirq) { /* not set for MT6575 */ - hw->request_cd_eirq(msdc_eirq_cd, (void*)host); /* msdc_eirq_cd will not be used! */ - } - } + /* using dma_alloc_coherent*/ /* todo: using 1, for all 4 slots */ + host->dma.gpd = dma_alloc_coherent(&pdev->dev, + MAX_GPD_NUM * sizeof(struct gpd), + &host->dma.gpd_addr, GFP_KERNEL); + host->dma.bd = dma_alloc_coherent(&pdev->dev, + MAX_BD_NUM * sizeof(struct bd), + &host->dma.bd_addr, GFP_KERNEL); + if (!host->dma.gpd || !host->dma.bd) { + ret = -ENOMEM; + goto release_mem; + } + msdc_init_gpd_bd(host, &host->dma); - if (hw->request_sdio_eirq) /* set to combo_sdio_request_eirq() for WIFI */ - hw->request_sdio_eirq(msdc_eirq_sdio, (void*)host); /* msdc_eirq_sdio() will be called when EIRQ */ + INIT_DELAYED_WORK(&host->card_delaywork, msdc_tasklet_card); + spin_lock_init(&host->lock); + msdc_init_hw(host); - if (hw->register_pm) {/* yes for sdio */ -#ifdef CONFIG_PM - hw->register_pm(msdc_pm, (void*)host); /* combo_sdio_register_pm() */ -#endif - if(hw->flags & MSDC_SYS_SUSPEND) { /* will not set for WIFI */ - ERR_MSG("MSDC_SYS_SUSPEND and register_pm both set"); - } - //mmc->pm_flags |= MMC_PM_IGNORE_PM_NOTIFY; /* pm not controlled by system but by client. */ /* --- by chhung */ - } - - platform_set_drvdata(pdev, mmc); + /* TODO check weather flags 0 is correct, the mtk-sd driver uses + * IRQF_TRIGGER_LOW | IRQF_ONESHOT for flags + * + * for flags 0 the trigger polarity is determined by the + * device tree, but not the oneshot flag, but maybe it is also + * not needed because the soc could be oneshot safe. + */ + ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq, 0, pdev->name, + host); + if (ret) + goto release; - ret = mmc_add_host(mmc); - if (ret) goto free_irq; + platform_set_drvdata(pdev, mmc); - /* Config card detection pin and enable interrupts */ - if (hw->flags & MSDC_CD_PIN_EN) { /* set for card */ - msdc_enable_cd_irq(host, 1); - } else { - msdc_enable_cd_irq(host, 0); - } + ret = mmc_add_host(mmc); + if (ret) + goto release; - return 0; + /* Config card detection pin and enable interrupts */ + if (hw->flags & MSDC_CD_PIN_EN) { /* set for card */ + msdc_enable_cd_irq(host, 1); + } else { + msdc_enable_cd_irq(host, 0); + } + + return 0; -free_irq: - free_irq(irq, host); release: - platform_set_drvdata(pdev, NULL); - msdc_deinit_hw(host); + platform_set_drvdata(pdev, NULL); + msdc_deinit_hw(host); + cancel_delayed_work_sync(&host->card_delaywork); -#if 0 - tasklet_kill(&host->card_tasklet); -#else - cancel_delayed_work_sync(&host->card_delaywork); -#endif +release_mem: + if (host->dma.gpd) + dma_free_coherent(&pdev->dev, MAX_GPD_NUM * sizeof(struct gpd), + host->dma.gpd, host->dma.gpd_addr); + if (host->dma.bd) + dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct bd), + host->dma.bd, host->dma.bd_addr); +host_free: + mmc_free_host(mmc); - if (mem) - release_mem_region(mem->start, mem->end - mem->start + 1); - - mmc_free_host(mmc); - - return ret; + return ret; } /* 4 device share one driver, using "drvdata" to show difference */ static int msdc_drv_remove(struct platform_device *pdev) { - struct mmc_host *mmc; - struct msdc_host *host; - struct resource *mem; + struct mmc_host *mmc; + struct msdc_host *host; - mmc = platform_get_drvdata(pdev); - BUG_ON(!mmc); - - host = mmc_priv(mmc); - BUG_ON(!host); + mmc = platform_get_drvdata(pdev); + BUG_ON(!mmc); - ERR_MSG("removed !!!"); + host = mmc_priv(mmc); + BUG_ON(!host); - platform_set_drvdata(pdev, NULL); - mmc_remove_host(host->mmc); - msdc_deinit_hw(host); + ERR_MSG("removed !!!"); -#if 0 - tasklet_kill(&host->card_tasklet); -#else - cancel_delayed_work_sync(&host->card_delaywork); -#endif - free_irq(host->irq, host); + platform_set_drvdata(pdev, NULL); + mmc_remove_host(host->mmc); + msdc_deinit_hw(host); - dma_free_coherent(NULL, MAX_GPD_NUM * sizeof(gpd_t), host->dma.gpd, host->dma.gpd_addr); - dma_free_coherent(NULL, MAX_BD_NUM * sizeof(bd_t), host->dma.bd, host->dma.bd_addr); + cancel_delayed_work_sync(&host->card_delaywork); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dma_free_coherent(&pdev->dev, MAX_GPD_NUM * sizeof(struct gpd), + host->dma.gpd, host->dma.gpd_addr); + dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct bd), + host->dma.bd, host->dma.bd_addr); - if (mem) - release_mem_region(mem->start, mem->end - mem->start + 1); + mmc_free_host(host->mmc); - mmc_free_host(host->mmc); - - return 0; + return 0; } /* Fix me: Power Flow */ #ifdef CONFIG_PM + +static void msdc_drv_pm(struct platform_device *pdev, pm_message_t state) +{ + struct mmc_host *mmc = platform_get_drvdata(pdev); + if (mmc) { + struct msdc_host *host = mmc_priv(mmc); + msdc_pm(state, (void *)host); + } +} + static int msdc_drv_suspend(struct platform_device *pdev, pm_message_t state) { - int ret = 0; - struct mmc_host *mmc = platform_get_drvdata(pdev); - struct msdc_host *host = mmc_priv(mmc); - - if (mmc && state.event == PM_EVENT_SUSPEND && (host->hw->flags & MSDC_SYS_SUSPEND)) { /* will set for card */ - msdc_pm(state, (void*)host); - } - - return ret; + if (state.event == PM_EVENT_SUSPEND) + msdc_drv_pm(pdev, state); + return 0; } static int msdc_drv_resume(struct platform_device *pdev) { - int ret = 0; - struct mmc_host *mmc = platform_get_drvdata(pdev); - struct msdc_host *host = mmc_priv(mmc); - struct pm_message state; + struct pm_message state; - state.event = PM_EVENT_RESUME; - if (mmc && (host->hw->flags & MSDC_SYS_SUSPEND)) {/* will set for card */ - msdc_pm(state, (void*)host); - } - - /* This mean WIFI not controller by PM */ - - return ret; + state.event = PM_EVENT_RESUME; + msdc_drv_pm(pdev, state); + return 0; } #endif @@ -2977,16 +2414,16 @@ static const struct of_device_id mt7620_sdhci_match[] = { MODULE_DEVICE_TABLE(of, mt7620_sdhci_match); static struct platform_driver mt_msdc_driver = { - .probe = msdc_drv_probe, - .remove = msdc_drv_remove, + .probe = msdc_drv_probe, + .remove = msdc_drv_remove, #ifdef CONFIG_PM - .suspend = msdc_drv_suspend, - .resume = msdc_drv_resume, + .suspend = msdc_drv_suspend, + .resume = msdc_drv_resume, #endif - .driver = { - .name = DRV_NAME, - .of_match_table = mt7620_sdhci_match, - }, + .driver = { + .name = DRV_NAME, + .of_match_table = mt7620_sdhci_match, + }, }; /*--------------------------------------------------------------------------*/ @@ -2994,63 +2431,27 @@ static struct platform_driver mt_msdc_driver = { /*--------------------------------------------------------------------------*/ static int __init mt_msdc_init(void) { - int ret; -/* +++ by chhung */ - u32 reg; + int ret; -#if defined (CONFIG_MTD_ANY_RALINK) - extern int ra_check_flash_type(void); - if(ra_check_flash_type() == 2) { /* NAND */ - printk("%s: !!!!! SDXC Module Initialize Fail !!!!!", __func__); - return 0; - } + ret = platform_driver_register(&mt_msdc_driver); + if (ret) { + printk(KERN_ERR DRV_NAME ": Can't register driver"); + return ret; + } + +#if defined(MT6575_SD_DEBUG) + msdc_debug_proc_init(); #endif - printk("MTK MSDC device init.\n"); - mtk_sd_device.dev.platform_data = &msdc0_hw; -if (ralink_soc == MT762X_SOC_MT7620A || ralink_soc == MT762X_SOC_MT7621AT) { -//#if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) - reg = sdr_read32((volatile u32*)(RALINK_SYSCTL_BASE + 0x60)) & ~(0x3<<18); -//#if defined (CONFIG_RALINK_MT7620) - if (ralink_soc == MT762X_SOC_MT7620A) - reg |= 0x1<<18; -//#endif -} else { -//#elif defined (CONFIG_RALINK_MT7628) - /* TODO: maybe omitted when RAether already toggle AGPIO_CFG */ - reg = sdr_read32((volatile u32*)(RALINK_SYSCTL_BASE + 0x3c)); - reg |= 0x1e << 16; - sdr_write32((volatile u32*)(RALINK_SYSCTL_BASE + 0x3c), reg); - - reg = sdr_read32((volatile u32*)(RALINK_SYSCTL_BASE + 0x60)) & ~(0x3<<10); -#if defined (CONFIG_MTK_MMC_EMMC_8BIT) - reg |= 0x3<<26 | 0x3<<28 | 0x3<<30; - msdc0_hw.data_pins = 8, -#endif -//#endif -} - sdr_write32((volatile u32*)(RALINK_SYSCTL_BASE + 0x60), reg); - //platform_device_register(&mtk_sd_device); -/* end of +++ */ - - ret = platform_driver_register(&mt_msdc_driver); - if (ret) { - printk(KERN_ERR DRV_NAME ": Can't register driver"); - return ret; - } - printk(KERN_INFO DRV_NAME ": MediaTek MT6575 MSDC Driver\n"); - -#if defined (MT6575_SD_DEBUG) - msdc_debug_proc_init(); -#endif - return 0; + return 0; } static void __exit mt_msdc_exit(void) { -// platform_device_unregister(&mtk_sd_device); - platform_driver_unregister(&mt_msdc_driver); + platform_driver_unregister(&mt_msdc_driver); } module_init(mt_msdc_init); module_exit(mt_msdc_exit); MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek MT6575 SD/MMC Card Driver"); +MODULE_AUTHOR("Infinity Chen "); diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/esw_rt3050.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/esw_rt3050.c index 6cad5856c..816c588dd 100644 --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/esw_rt3050.c +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/esw_rt3050.c @@ -1358,8 +1358,8 @@ static int esw_probe(struct platform_device *pdev) esw->dev = &pdev->dev; esw->irq = irq_of_parse_and_map(np, 0); esw->base = devm_ioremap_resource(&pdev->dev, res); - if (!esw->base) - return -EADDRNOTAVAIL; + if (IS_ERR(esw->base)) + return PTR_ERR(esw->base); port_map = of_get_property(np, "mediatek,portmap", NULL); if (port_map) diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7620.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7620.c index 4093f09d4..a4602c458 100644 --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7620.c +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7620.c @@ -215,8 +215,8 @@ static int mt7620_gsw_probe(struct platform_device *pdev) return -ENOMEM; gsw->base = devm_ioremap_resource(&pdev->dev, res); - if (!gsw->base) - return -EADDRNOTAVAIL; + if (IS_ERR(gsw->base)) + return PTR_ERR(gsw->base); gsw->dev = &pdev->dev; diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c index 9d5fe6efe..89be23900 100644 --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c @@ -245,8 +245,8 @@ static int mt7621_gsw_probe(struct platform_device *pdev) return -ENOMEM; gsw->base = devm_ioremap_resource(&pdev->dev, res); - if (!gsw->base) - return -EADDRNOTAVAIL; + if (IS_ERR(gsw->base)) + return PTR_ERR(gsw->base); gsw->dev = &pdev->dev; gsw->irq = platform_get_irq(pdev, 0); diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mdio.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mdio.c index b2a31589b..bdfdf7a43 100644 --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mdio.c +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mdio.c @@ -82,10 +82,10 @@ int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node) phydev = of_phy_connect(priv->netdev, phy_node, fe_phy_link_adjust, 0, phy_mode); - if (IS_ERR(phydev)) { + if (!phydev) { dev_err(priv->dev, "could not connect to PHY\n"); priv->phy->phy_node[port] = NULL; - return PTR_ERR(phydev); + return -ENODEV; } phydev->supported &= PHY_GBIT_FEATURES; diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c index d0d88b92c..c806e289b 100644 --- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c +++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c @@ -1513,7 +1513,7 @@ static int fe_probe(struct platform_device *pdev) soc->reg_table = fe_reg_table; fe_base = devm_ioremap_resource(&pdev->dev, res); - if (!fe_base) { + if (IS_ERR(fe_base)) { err = -EADDRNOTAVAIL; goto err_out; } diff --git a/target/linux/ramips/image/mt7620.mk b/target/linux/ramips/image/mt7620.mk index 102a846e0..8081d906f 100644 --- a/target/linux/ramips/image/mt7620.mk +++ b/target/linux/ramips/image/mt7620.mk @@ -83,6 +83,13 @@ define Device/ArcherMR200 endef TARGET_DEVICES += ArcherMR200 +define Device/bocco + DTS := BOCCO + DEVICE_TITLE := YUKAI Engineering BOCCO + DEVICE_PACKAGES := kmod-sound-core kmod-sound-mt7620 kmod-i2c-ralink +endef +TARGET_DEVICES += bocco + define Device/c108 DTS := C108 IMAGE_SIZE := 16777216 @@ -479,6 +486,14 @@ define Device/vonets_var11n-300 endef TARGET_DEVICES += vonets_var11n-300 +define Device/ravpower_wd03 + DTS := WD03 + IMAGE_SIZE := $(ralink_default_fw_size_8M) + DEVICE_TITLE := Ravpower WD03 + DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mt76 kmod-usb-ehci +endef +TARGET_DEVICES += ravpower_wd03 + define Device/whr-1166d DTS := WHR-1166D IMAGE_SIZE := 15040k diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index d78175cf7..b84b74a5b 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -310,15 +310,26 @@ define Device/wf-2881 endef TARGET_DEVICES += wf-2881 -define Device/witi - DTS := WITI +define Device/mqmaker_witi-256m + DTS := WITI-256M IMAGE_SIZE := $(ralink_default_fw_size_16M) - DEVICE_TITLE := MQmaker WiTi + DEVICE_TITLE := MQmaker WiTi (256MB RAM) + DEVICE_PACKAGES := \ + kmod-ata-core kmod-ata-ahci kmod-mt76x2 kmod-sdhci-mt7620 kmod-usb3 \ + kmod-usb-ledtrig-usbport wpad-mini + SUPPORTED_DEVICES += witi +endef +TARGET_DEVICES += mqmaker_witi-256m + +define Device/mqmaker_witi-512m + DTS := WITI-512M + IMAGE_SIZE := $(ralink_default_fw_size_16M) + DEVICE_TITLE := MQmaker WiTi (512MB RAM) DEVICE_PACKAGES := \ kmod-ata-core kmod-ata-ahci kmod-mt76x2 kmod-sdhci-mt7620 kmod-usb3 \ kmod-usb-ledtrig-usbport wpad-mini endef -TARGET_DEVICES += witi +TARGET_DEVICES += mqmaker_witi-512m define Device/wndr3700v5 DTS := WNDR3700V5 diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk index c0b243c3c..aeb6faf0e 100644 --- a/target/linux/ramips/image/mt76x8.mk +++ b/target/linux/ramips/image/mt76x8.mk @@ -88,6 +88,7 @@ define Device/mt7628 DEVICE_TITLE := MediaTek MT7628 EVB DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport endef +TARGET_DEVICES += mt7628 define Device/omega2 DTS := OMEGA2 diff --git a/target/linux/ramips/image/rt288x.mk b/target/linux/ramips/image/rt288x.mk index 280ce5617..c7f7d064f 100644 --- a/target/linux/ramips/image/rt288x.mk +++ b/target/linux/ramips/image/rt288x.mk @@ -47,13 +47,11 @@ endef TARGET_DEVICES += dlink_dap-1522-a1 define Device/f5d8235-v1 + DTS := F5D8235_V1 IMAGE_SIZE := 7744k DEVICE_TITLE := Belkin F5D8235 V1 DEVICE_PACKAGES := kmod-switch-rtl8366s kmod-usb-core kmod-usb-ohci \ kmod-usb-ohci-pci kmod-usb2 kmod-usb2-pci kmod-usb-ledtrig-usbport - DEVICE_DTS := F5D8235_V1 - KERNEL := kernel-bin | append-dtb | lzma | uImage lzma - KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | uImage lzma endef TARGET_DEVICES += f5d8235-v1 diff --git a/target/linux/ramips/mt7620/config-4.14 b/target/linux/ramips/mt7620/config-4.14 index 3e006e2ef..d60696b22 100644 --- a/target/linux/ramips/mt7620/config-4.14 +++ b/target/linux/ramips/mt7620/config-4.14 @@ -19,7 +19,6 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_ARCH_USE_QUEUED_RWLOCKS=y CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y CONFIG_AT803X_PHY=y CONFIG_BLK_MQ_PCI=y @@ -54,18 +53,13 @@ CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CSRC_R4K=y CONFIG_DEBUG_PINCTRL=y CONFIG_DMA_NONCOHERENT=y -# CONFIG_DMA_NOOP_OPS is not set -# CONFIG_DMA_VIRT_OPS is not set -# CONFIG_DRM_LIB_RANDOM is not set # CONFIG_DTB_MT7620A_EVAL is not set # CONFIG_DTB_OMEGA2P is not set CONFIG_DTB_RT_NONE=y # CONFIG_DTB_VOCORE2 is not set CONFIG_DTC=y CONFIG_EARLY_PRINTK=y -CONFIG_EXPORTFS=y CONFIG_FIXED_PHY=y -CONFIG_FUTEX_PI=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y @@ -233,7 +227,6 @@ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_SYS_SUPPORTS_ARBIT_HZ=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_THIN_ARCHIVES=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y diff --git a/target/linux/ramips/mt76x8/config-4.14 b/target/linux/ramips/mt76x8/config-4.14 index 0939aa4d4..614c366d1 100644 --- a/target/linux/ramips/mt76x8/config-4.14 +++ b/target/linux/ramips/mt76x8/config-4.14 @@ -19,7 +19,6 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_ARCH_USE_QUEUED_RWLOCKS=y CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y CONFIG_AT803X_PHY=y CONFIG_BLK_MQ_PCI=y @@ -54,18 +53,13 @@ CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CSRC_R4K=y CONFIG_DEBUG_PINCTRL=y CONFIG_DMA_NONCOHERENT=y -# CONFIG_DMA_NOOP_OPS is not set -# CONFIG_DMA_VIRT_OPS is not set -# CONFIG_DRM_LIB_RANDOM is not set # CONFIG_DTB_MT7620A_EVAL is not set # CONFIG_DTB_OMEGA2P is not set CONFIG_DTB_RT_NONE=y # CONFIG_DTB_VOCORE2 is not set CONFIG_DTC=y CONFIG_EARLY_PRINTK=y -CONFIG_EXPORTFS=y CONFIG_FIXED_PHY=y -CONFIG_FUTEX_PI=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y @@ -229,7 +223,6 @@ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_SYS_SUPPORTS_ARBIT_HZ=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_THIN_ARCHIVES=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y diff --git a/target/linux/ramips/patches-4.14/0004-MIPS-ralink-add-MT7621-pcie-driver.patch b/target/linux/ramips/patches-4.14/0004-MIPS-ralink-add-MT7621-pcie-driver.patch index b6f1ce93f..2d50510bb 100644 --- a/target/linux/ramips/patches-4.14/0004-MIPS-ralink-add-MT7621-pcie-driver.patch +++ b/target/linux/ramips/patches-4.14/0004-MIPS-ralink-add-MT7621-pcie-driver.patch @@ -6,9 +6,7 @@ Subject: [PATCH 04/53] MIPS: ralink: add MT7621 pcie driver Signed-off-by: John Crispin --- arch/mips/pci/Makefile | 1 + - arch/mips/pci/pci-mt7621.c | 813 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 814 insertions(+) - create mode 100644 arch/mips/pci/pci-mt7621.c + 1 file changed, 1 insertion(+) --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -20,842 +18,3 @@ Signed-off-by: John Crispin obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o ---- /dev/null -+++ b/arch/mips/pci/pci-mt7621.c -@@ -0,0 +1,836 @@ -+/************************************************************************** -+ * -+ * BRIEF MODULE DESCRIPTION -+ * PCI init for Ralink RT2880 solution -+ * -+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) -+ * -+ * 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. -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * 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. -+ * -+ * -+ ************************************************************************** -+ * May 2007 Bruce Chang -+ * Initial Release -+ * -+ * May 2009 Bruce Chang -+ * support RT2880/RT3883 PCIe -+ * -+ * May 2011 Bruce Chang -+ * support RT6855/MT7620 PCIe -+ * -+ ************************************************************************** -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+extern void pcie_phy_init(void); -+extern void chk_phy_pll(void); -+ -+/* -+ * These functions and structures provide the BIOS scan and mapping of the PCI -+ * devices. -+ */ -+ -+#define CONFIG_PCIE_PORT0 -+#define CONFIG_PCIE_PORT1 -+#define CONFIG_PCIE_PORT2 -+#define RALINK_PCIE0_CLK_EN (1<<24) -+#define RALINK_PCIE1_CLK_EN (1<<25) -+#define RALINK_PCIE2_CLK_EN (1<<26) -+ -+#define RALINK_PCI_CONFIG_ADDR 0x20 -+#define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG 0x24 -+#define RALINK_INT_PCIE0 pcie_irq[0] -+#define RALINK_INT_PCIE1 pcie_irq[1] -+#define RALINK_INT_PCIE2 pcie_irq[2] -+#define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028) -+#define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C) -+#define RALINK_PCIE0_RST (1<<24) -+#define RALINK_PCIE1_RST (1<<25) -+#define RALINK_PCIE2_RST (1<<26) -+#define RALINK_SYSCTL_BASE 0xBE000000 -+ -+#define RALINK_PCI_PCICFG_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x0000) -+#define RALINK_PCI_PCIMSK_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x000C) -+#define RALINK_PCI_BASE 0xBE140000 -+ -+#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) -+#define RT6855_PCIE0_OFFSET 0x2000 -+#define RT6855_PCIE1_OFFSET 0x3000 -+#define RT6855_PCIE2_OFFSET 0x4000 -+ -+#define RALINK_PCI0_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010) -+#define RALINK_PCI0_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018) -+#define RALINK_PCI0_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030) -+#define RALINK_PCI0_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034) -+#define RALINK_PCI0_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038) -+#define RALINK_PCI0_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050) -+#define RALINK_PCI0_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060) -+#define RALINK_PCI0_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064) -+ -+#define RALINK_PCI1_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010) -+#define RALINK_PCI1_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018) -+#define RALINK_PCI1_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030) -+#define RALINK_PCI1_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034) -+#define RALINK_PCI1_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038) -+#define RALINK_PCI1_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050) -+#define RALINK_PCI1_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060) -+#define RALINK_PCI1_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064) -+ -+#define RALINK_PCI2_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0010) -+#define RALINK_PCI2_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0018) -+#define RALINK_PCI2_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0030) -+#define RALINK_PCI2_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0034) -+#define RALINK_PCI2_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0038) -+#define RALINK_PCI2_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0050) -+#define RALINK_PCI2_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0060) -+#define RALINK_PCI2_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0064) -+ -+#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) -+#define RALINK_PCIEPHY_P2_CTL_OFFSET (RALINK_PCI_BASE + 0xA000) -+ -+ -+#define MV_WRITE(ofs, data) \ -+ *(volatile u32 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le32(data) -+#define MV_READ(ofs, data) \ -+ *(data) = le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs))) -+#define MV_READ_DATA(ofs) \ -+ le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs))) -+ -+#define MV_WRITE_16(ofs, data) \ -+ *(volatile u16 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le16(data) -+#define MV_READ_16(ofs, data) \ -+ *(data) = le16_to_cpu(*(volatile u16 *)(RALINK_PCI_BASE+(ofs))) -+ -+#define MV_WRITE_8(ofs, data) \ -+ *(volatile u8 *)(RALINK_PCI_BASE+(ofs)) = data -+#define MV_READ_8(ofs, data) \ -+ *(data) = *(volatile u8 *)(RALINK_PCI_BASE+(ofs)) -+ -+ -+ -+#define RALINK_PCI_MM_MAP_BASE 0x60000000 -+#define RALINK_PCI_IO_MAP_BASE 0x1e160000 -+ -+#define RALINK_SYSTEM_CONTROL_BASE 0xbe000000 -+#define GPIO_PERST -+#define ASSERT_SYSRST_PCIE(val) do { \ -+ if (*(unsigned int *)(0xbe00000c) == 0x00030101) \ -+ RALINK_RSTCTRL |= val; \ -+ else \ -+ RALINK_RSTCTRL &= ~val; \ -+ } while(0) -+#define DEASSERT_SYSRST_PCIE(val) do { \ -+ if (*(unsigned int *)(0xbe00000c) == 0x00030101) \ -+ RALINK_RSTCTRL &= ~val; \ -+ else \ -+ RALINK_RSTCTRL |= val; \ -+ } while(0) -+#define RALINK_SYSCFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x14) -+#define RALINK_CLKCFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x30) -+#define RALINK_RSTCTRL *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x34) -+#define RALINK_GPIOMODE *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x60) -+#define RALINK_PCIE_CLK_GEN *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x7c) -+#define RALINK_PCIE_CLK_GEN1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x80) -+#define PPLL_CFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x9c) -+#define PPLL_DRV *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0xa0) -+//RALINK_SYSCFG1 bit -+#define RALINK_PCI_HOST_MODE_EN (1<<7) -+#define RALINK_PCIE_RC_MODE_EN (1<<8) -+//RALINK_RSTCTRL bit -+#define RALINK_PCIE_RST (1<<23) -+#define RALINK_PCI_RST (1<<24) -+//RALINK_CLKCFG1 bit -+#define RALINK_PCI_CLK_EN (1<<19) -+#define RALINK_PCIE_CLK_EN (1<<21) -+//RALINK_GPIOMODE bit -+#define PCI_SLOTx2 (1<<11) -+#define PCI_SLOTx1 (2<<11) -+//MTK PCIE PLL bit -+#define PDRV_SW_SET (1<<31) -+#define LC_CKDRVPD_ (1<<19) -+ -+#define MEMORY_BASE 0x0 -+static int pcie_link_status = 0; -+ -+#define PCI_ACCESS_READ_1 0 -+#define PCI_ACCESS_READ_2 1 -+#define PCI_ACCESS_READ_4 2 -+#define PCI_ACCESS_WRITE_1 3 -+#define PCI_ACCESS_WRITE_2 4 -+#define PCI_ACCESS_WRITE_4 5 -+ -+static int pcie_irq[3]; -+ -+static int config_access(unsigned char access_type, struct pci_bus *bus, -+ unsigned int devfn, unsigned int where, u32 * data) -+{ -+ unsigned int slot = PCI_SLOT(devfn); -+ u8 func = PCI_FUNC(devfn); -+ uint32_t address_reg, data_reg; -+ unsigned int address; -+ -+ address_reg = RALINK_PCI_CONFIG_ADDR; -+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG; -+ -+ address = (((where&0xF00)>>8)<<24) |(bus->number << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 0x80000000; -+ MV_WRITE(address_reg, address); -+ -+ switch(access_type) { -+ case PCI_ACCESS_WRITE_1: -+ MV_WRITE_8(data_reg+(where&0x3), *data); -+ break; -+ case PCI_ACCESS_WRITE_2: -+ MV_WRITE_16(data_reg+(where&0x3), *data); -+ break; -+ case PCI_ACCESS_WRITE_4: -+ MV_WRITE(data_reg, *data); -+ break; -+ case PCI_ACCESS_READ_1: -+ MV_READ_8( data_reg+(where&0x3), data); -+ break; -+ case PCI_ACCESS_READ_2: -+ MV_READ_16(data_reg+(where&0x3), data); -+ break; -+ case PCI_ACCESS_READ_4: -+ MV_READ(data_reg, data); -+ break; -+ default: -+ printk("no specify access type\n"); -+ break; -+ } -+ return 0; -+} -+ -+static int -+read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val) -+{ -+ return config_access(PCI_ACCESS_READ_1, bus, devfn, (unsigned int)where, (u32 *)val); -+} -+ -+static int -+read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val) -+{ -+ return config_access(PCI_ACCESS_READ_2, bus, devfn, (unsigned int)where, (u32 *)val); -+} -+ -+static int -+read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val) -+{ -+ return config_access(PCI_ACCESS_READ_4, bus, devfn, (unsigned int)where, (u32 *)val); -+} -+ -+static int -+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val) -+{ -+ if (config_access(PCI_ACCESS_WRITE_1, bus, devfn, (unsigned int)where, (u32 *)&val)) -+ return -1; -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int -+write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val) -+{ -+ if (config_access(PCI_ACCESS_WRITE_2, bus, devfn, where, (u32 *)&val)) -+ return -1; -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int -+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val) -+{ -+ if (config_access(PCI_ACCESS_WRITE_4, bus, devfn, where, &val)) -+ return -1; -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+ -+static int -+pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) -+{ -+ switch (size) { -+ case 1: -+ return read_config_byte(bus, devfn, where, (u8 *) val); -+ case 2: -+ return read_config_word(bus, devfn, where, (u16 *) val); -+ default: -+ return read_config_dword(bus, devfn, where, val); -+ } -+} -+ -+static int -+pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) -+{ -+ switch (size) { -+ case 1: -+ return write_config_byte(bus, devfn, where, (u8) val); -+ case 2: -+ return write_config_word(bus, devfn, where, (u16) val); -+ default: -+ return write_config_dword(bus, devfn, where, val); -+ } -+} -+ -+struct pci_ops mt7621_pci_ops= { -+ .read = pci_config_read, -+ .write = pci_config_write, -+}; -+ -+static struct resource mt7621_res_pci_mem1 = { -+ .name = "PCI MEM1", -+ .start = RALINK_PCI_MM_MAP_BASE, -+ .end = (u32)((RALINK_PCI_MM_MAP_BASE + (unsigned char *)0x0fffffff)), -+ .flags = IORESOURCE_MEM, -+}; -+static struct resource mt7621_res_pci_io1 = { -+ .name = "PCI I/O1", -+ .start = RALINK_PCI_IO_MAP_BASE, -+ .end = (u32)((RALINK_PCI_IO_MAP_BASE + (unsigned char *)0x0ffff)), -+ .flags = IORESOURCE_IO, -+}; -+ -+static struct pci_controller mt7621_controller = { -+ .pci_ops = &mt7621_pci_ops, -+ .mem_resource = &mt7621_res_pci_mem1, -+ .io_resource = &mt7621_res_pci_io1, -+ .mem_offset = 0x00000000UL, -+ .io_offset = 0x00000000UL, -+ .io_map_base = 0xa0000000, -+}; -+ -+static void -+read_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long *val) -+{ -+ unsigned int address_reg, data_reg, address; -+ -+ address_reg = RALINK_PCI_CONFIG_ADDR; -+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG; -+ address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ; -+ MV_WRITE(address_reg, address); -+ MV_READ(data_reg, val); -+ return; -+} -+ -+static void -+write_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long val) -+{ -+ unsigned int address_reg, data_reg, address; -+ -+ address_reg = RALINK_PCI_CONFIG_ADDR; -+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG; -+ address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ; -+ MV_WRITE(address_reg, address); -+ MV_WRITE(data_reg, val); -+ return; -+} -+ -+ -+int -+pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ u16 cmd; -+ u32 val; -+ int irq = 0; -+ -+ if ((dev->bus->number == 0) && (slot == 0)) { -+ write_config(0, 0, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); -+ read_config(0, 0, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val); -+ printk("BAR0 at slot 0 = %x\n", val); -+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); -+ } else if((dev->bus->number == 0) && (slot == 0x1)) { -+ write_config(0, 1, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); -+ read_config(0, 1, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val); -+ printk("BAR0 at slot 1 = %x\n", val); -+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); -+ } else if((dev->bus->number == 0) && (slot == 0x2)) { -+ write_config(0, 2, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); -+ read_config(0, 2, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val); -+ printk("BAR0 at slot 2 = %x\n", val); -+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); -+ } else if ((dev->bus->number == 1) && (slot == 0x0)) { -+ switch (pcie_link_status) { -+ case 2: -+ case 6: -+ irq = RALINK_INT_PCIE1; -+ break; -+ case 4: -+ irq = RALINK_INT_PCIE2; -+ break; -+ default: -+ irq = RALINK_INT_PCIE0; -+ } -+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); -+ } else if ((dev->bus->number == 2) && (slot == 0x0)) { -+ switch (pcie_link_status) { -+ case 5: -+ case 6: -+ irq = RALINK_INT_PCIE2; -+ break; -+ default: -+ irq = RALINK_INT_PCIE1; -+ } -+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); -+ } else if ((dev->bus->number == 2) && (slot == 0x1)) { -+ switch (pcie_link_status) { -+ case 5: -+ case 6: -+ irq = RALINK_INT_PCIE2; -+ break; -+ default: -+ irq = RALINK_INT_PCIE1; -+ } -+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); -+ } else if ((dev->bus->number ==3) && (slot == 0x0)) { -+ irq = RALINK_INT_PCIE2; -+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); -+ } else if ((dev->bus->number ==3) && (slot == 0x1)) { -+ irq = RALINK_INT_PCIE2; -+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); -+ } else if ((dev->bus->number ==3) && (slot == 0x2)) { -+ irq = RALINK_INT_PCIE2; -+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq); -+ } else { -+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot); -+ return 0; -+ } -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14); //configure cache line size 0x14 -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xFF); //configure latency timer 0x10 -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -+ return irq; -+} -+ -+void -+set_pcie_phy(u32 *addr, int start_b, int bits, int val) -+{ -+// printk("0x%p:", addr); -+// printk(" %x", *addr); -+ *(unsigned int *)(addr) &= ~(((1< %x\n", *addr); -+} -+ -+void -+bypass_pipe_rst(void) -+{ -+#if defined (CONFIG_PCIE_PORT0) -+ /* PCIe Port 0 */ -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -+#endif -+#if defined (CONFIG_PCIE_PORT1) -+ /* PCIe Port 1 */ -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 12, 1, 0x01); // rg_pe1_pipe_rst_b -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -+#endif -+#if defined (CONFIG_PCIE_PORT2) -+ /* PCIe Port 2 */ -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] -+#endif -+} -+ -+void -+set_phy_for_ssc(void) -+{ -+ unsigned long reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10)); -+ -+ reg = (reg >> 6) & 0x7; -+#if defined (CONFIG_PCIE_PORT0) || defined (CONFIG_PCIE_PORT1) -+ /* Set PCIe Port0 & Port1 PHY to disable SSC */ -+ /* Debug Xtal Type */ -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 1 enable control -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x00); // rg_pe1_phy_en //Port 1 disable -+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) -+ printk("***** Xtal 40MHz *****\n"); -+ } else { // 25MHz | 20MHz Xtal -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) -+ if (reg >= 6) { -+ printk("***** Xtal 25MHz *****\n"); -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode) -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial -+ } else { -+ printk("***** Xtal 20MHz *****\n"); -+ } -+ } -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN -+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv -+ } -+ /* Enable PHY and disable force mode */ -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x01); // rg_pe1_phy_en //Port 1 enable -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 1 disable control -+#endif -+#if defined (CONFIG_PCIE_PORT2) -+ /* Set PCIe Port2 PHY to disable SSC */ -+ /* Debug Xtal Type */ -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable -+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) -+ } else { // 25MHz | 20MHz Xtal -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) -+ if (reg >= 6) { // 25MHz Xtal -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode) -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial -+ } -+ } -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN -+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv -+ } -+ /* Enable PHY and disable force mode */ -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable -+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control -+#endif -+} -+ -+void setup_cm_memory_region(struct resource *mem_resource) -+{ -+ resource_size_t mask; -+ if (mips_cps_numiocu(0)) { -+ /* FIXME: hardware doesn't accept mask values with 1s after -+ 0s (e.g. 0xffef), so it would be great to warn if that's -+ about to happen */ -+ mask = ~(mem_resource->end - mem_resource->start); -+ -+ write_gcr_reg1_base(mem_resource->start); -+ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); -+ printk("PCI coherence region base: 0x%08lx, mask/settings: 0x%08lx\n", -+ read_gcr_reg1_base(), -+ read_gcr_reg1_mask()); -+ } -+} -+ -+static int mt7621_pci_probe(struct platform_device *pdev) -+{ -+ unsigned long val = 0; -+ int i; -+ -+ for (i = 0; i < 3; i++) -+ pcie_irq[i] = irq_of_parse_and_map(pdev->dev.of_node, i); -+ -+ iomem_resource.start = 0; -+ iomem_resource.end= ~0; -+ ioport_resource.start= 0; -+ ioport_resource.end = ~0; -+ -+#if defined (CONFIG_PCIE_PORT0) -+ val = RALINK_PCIE0_RST; -+#endif -+#if defined (CONFIG_PCIE_PORT1) -+ val |= RALINK_PCIE1_RST; -+#endif -+#if defined (CONFIG_PCIE_PORT2) -+ val |= RALINK_PCIE2_RST; -+#endif -+ ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST); -+ printk("pull PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); -+#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/ -+ *(unsigned int *)(0xbe000060) &= ~(0x3<<10 | 0x3<<3); -+ *(unsigned int *)(0xbe000060) |= 0x1<<10 | 0x1<<3; -+ mdelay(100); -+ *(unsigned int *)(0xbe000600) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // use GPIO19/GPIO8/GPIO7 (PERST_N/UART_RXD3/UART_TXD3) -+ mdelay(100); -+ *(unsigned int *)(0xbe000620) &= ~(0x1<<19 | 0x1<<8 | 0x1<<7); // clear DATA -+ -+ mdelay(100); -+#else -+ *(unsigned int *)(0xbe000060) &= ~0x00000c00; -+#endif -+#if defined (CONFIG_PCIE_PORT0) -+ val = RALINK_PCIE0_RST; -+#endif -+#if defined (CONFIG_PCIE_PORT1) -+ val |= RALINK_PCIE1_RST; -+#endif -+#if defined (CONFIG_PCIE_PORT2) -+ val |= RALINK_PCIE2_RST; -+#endif -+ DEASSERT_SYSRST_PCIE(val); -+ printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); -+ -+ if ((*(unsigned int *)(0xbe00000c)&0xFFFF) == 0x0101) // MT7621 E2 -+ bypass_pipe_rst(); -+ set_phy_for_ssc(); -+ printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL); -+ -+#if defined (CONFIG_PCIE_PORT0) -+ read_config(0, 0, 0, 0x70c, &val); -+ printk("Port 0 N_FTS = %x\n", (unsigned int)val); -+#endif -+#if defined (CONFIG_PCIE_PORT1) -+ read_config(0, 1, 0, 0x70c, &val); -+ printk("Port 1 N_FTS = %x\n", (unsigned int)val); -+#endif -+#if defined (CONFIG_PCIE_PORT2) -+ read_config(0, 2, 0, 0x70c, &val); -+ printk("Port 2 N_FTS = %x\n", (unsigned int)val); -+#endif -+ -+ RALINK_RSTCTRL = (RALINK_RSTCTRL | RALINK_PCIE_RST); -+ RALINK_SYSCFG1 &= ~(0x30); -+ RALINK_SYSCFG1 |= (2<<4); -+ RALINK_PCIE_CLK_GEN &= 0x7fffffff; -+ RALINK_PCIE_CLK_GEN1 &= 0x80ffffff; -+ RALINK_PCIE_CLK_GEN1 |= 0xa << 24; -+ RALINK_PCIE_CLK_GEN |= 0x80000000; -+ mdelay(50); -+ RALINK_RSTCTRL = (RALINK_RSTCTRL & ~RALINK_PCIE_RST); -+ -+ -+#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/ -+ *(unsigned int *)(0xbe000620) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // set DATA -+ mdelay(100); -+#else -+ RALINK_PCI_PCICFG_ADDR &= ~(1<<1); //de-assert PERST -+#endif -+ mdelay(500); -+ -+ -+ mdelay(500); -+#if defined (CONFIG_PCIE_PORT0) -+ if(( RALINK_PCI0_STATUS & 0x1) == 0) -+ { -+ printk("PCIE0 no card, disable it(RST&CLK)\n"); -+ ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST); -+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE0_CLK_EN); -+ pcie_link_status &= ~(1<<0); -+ } else { -+ pcie_link_status |= 1<<0; -+ RALINK_PCI_PCIMSK_ADDR |= (1<<20); // enable pcie1 interrupt -+ } -+#endif -+#if defined (CONFIG_PCIE_PORT1) -+ if(( RALINK_PCI1_STATUS & 0x1) == 0) -+ { -+ printk("PCIE1 no card, disable it(RST&CLK)\n"); -+ ASSERT_SYSRST_PCIE(RALINK_PCIE1_RST); -+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE1_CLK_EN); -+ pcie_link_status &= ~(1<<1); -+ } else { -+ pcie_link_status |= 1<<1; -+ RALINK_PCI_PCIMSK_ADDR |= (1<<21); // enable pcie1 interrupt -+ } -+#endif -+#if defined (CONFIG_PCIE_PORT2) -+ if (( RALINK_PCI2_STATUS & 0x1) == 0) { -+ printk("PCIE2 no card, disable it(RST&CLK)\n"); -+ ASSERT_SYSRST_PCIE(RALINK_PCIE2_RST); -+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE2_CLK_EN); -+ pcie_link_status &= ~(1<<2); -+ } else { -+ pcie_link_status |= 1<<2; -+ RALINK_PCI_PCIMSK_ADDR |= (1<<22); // enable pcie2 interrupt -+ } -+#endif -+ if (pcie_link_status == 0) -+ return 0; -+ -+/* -+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: -+ RALINK_PCI_PCICFG_ADDR &= ~0x00ff0000; -+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 16; //port0 -+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 20; //port1 -+ break; -+ case 4: -+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; -+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 16; //port0 -+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 20; //port1 -+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 24; //port2 -+ break; -+ case 5: -+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; -+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 16; //port0 -+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 20; //port1 -+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 24; //port2 -+ break; -+ case 6: -+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; -+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 16; //port0 -+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 20; //port1 -+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 24; //port2 -+ break; -+ } -+ printk(" -> %x\n", RALINK_PCI_PCICFG_ADDR); -+ //printk(" RALINK_PCI_ARBCTL = %x\n", RALINK_PCI_ARBCTL); -+ -+/* -+ ioport_resource.start = mt7621_res_pci_io1.start; -+ ioport_resource.end = mt7621_res_pci_io1.end; -+*/ -+ -+ RALINK_PCI_MEMBASE = 0xffffffff; //RALINK_PCI_MM_MAP_BASE; -+ RALINK_PCI_IOBASE = RALINK_PCI_IO_MAP_BASE; -+ -+#if defined (CONFIG_PCIE_PORT0) -+ //PCIe0 -+ if((pcie_link_status & 0x1) != 0) { -+ RALINK_PCI0_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE -+ RALINK_PCI0_IMBASEBAR0_ADDR = MEMORY_BASE; -+ RALINK_PCI0_CLASS = 0x06040001; -+ printk("PCIE0 enabled\n"); -+ } -+#endif -+#if defined (CONFIG_PCIE_PORT1) -+ //PCIe1 -+ if ((pcie_link_status & 0x2) != 0) { -+ RALINK_PCI1_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE -+ RALINK_PCI1_IMBASEBAR0_ADDR = MEMORY_BASE; -+ RALINK_PCI1_CLASS = 0x06040001; -+ printk("PCIE1 enabled\n"); -+ } -+#endif -+#if defined (CONFIG_PCIE_PORT2) -+ //PCIe2 -+ if ((pcie_link_status & 0x4) != 0) { -+ RALINK_PCI2_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE -+ RALINK_PCI2_IMBASEBAR0_ADDR = MEMORY_BASE; -+ RALINK_PCI2_CLASS = 0x06040001; -+ printk("PCIE2 enabled\n"); -+ } -+#endif -+ -+ -+ switch(pcie_link_status) { -+ case 7: -+ read_config(0, 2, 0, 0x4, &val); -+ write_config(0, 2, 0, 0x4, val|0x4); -+ // write_config(0, 1, 0, 0x4, val|0x7); -+ read_config(0, 2, 0, 0x70c, &val); -+ val &= ~(0xff)<<8; -+ val |= 0x50<<8; -+ write_config(0, 2, 0, 0x70c, val); -+ case 3: -+ case 5: -+ case 6: -+ read_config(0, 1, 0, 0x4, &val); -+ write_config(0, 1, 0, 0x4, val|0x4); -+ // write_config(0, 1, 0, 0x4, val|0x7); -+ read_config(0, 1, 0, 0x70c, &val); -+ val &= ~(0xff)<<8; -+ val |= 0x50<<8; -+ write_config(0, 1, 0, 0x70c, val); -+ default: -+ read_config(0, 0, 0, 0x4, &val); -+ write_config(0, 0, 0, 0x4, val|0x4); //bus master enable -+ // write_config(0, 0, 0, 0x4, val|0x7); //bus master enable -+ read_config(0, 0, 0, 0x70c, &val); -+ val &= ~(0xff)<<8; -+ val |= 0x50<<8; -+ write_config(0, 0, 0, 0x70c, val); -+ } -+ -+ pci_load_of_ranges(&mt7621_controller, pdev->dev.of_node); -+ setup_cm_memory_region(mt7621_controller.mem_resource); -+ register_pci_controller(&mt7621_controller); -+ return 0; -+ -+} -+ -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ return 0; -+} -+ -+static const struct of_device_id mt7621_pci_ids[] = { -+ { .compatible = "mediatek,mt7621-pci" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mt7621_pci_ids); -+ -+static struct platform_driver mt7621_pci_driver = { -+ .probe = mt7621_pci_probe, -+ .driver = { -+ .name = "mt7621-pci", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(mt7621_pci_ids), -+ }, -+}; -+ -+static int __init mt7621_pci_init(void) -+{ -+ return platform_driver_register(&mt7621_pci_driver); -+} -+ -+arch_initcall(mt7621_pci_init); diff --git a/target/linux/ramips/patches-4.14/0032-USB-dwc2-add-device_reset.patch b/target/linux/ramips/patches-4.14/0032-USB-dwc2-add-device_reset.patch index 7d3352e92..0cfd5acdf 100644 --- a/target/linux/ramips/patches-4.14/0032-USB-dwc2-add-device_reset.patch +++ b/target/linux/ramips/patches-4.14/0032-USB-dwc2-add-device_reset.patch @@ -18,7 +18,7 @@ Signed-off-by: John Crispin #include #include -@@ -5075,6 +5076,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hso +@@ -5104,6 +5105,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hso retval = -ENOMEM; diff --git a/target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch b/target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch index 97e434466..f5cdfc9bc 100644 --- a/target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch +++ b/target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch @@ -1299,7 +1299,7 @@ Signed-off-by: John Crispin + --- /dev/null +++ b/drivers/mtd/nand/mtk_nand2.c -@@ -0,0 +1,2363 @@ +@@ -0,0 +1,2365 @@ +/****************************************************************************** +* mtk_nand2.c - MTK NAND Flash Device Driver + * @@ -2748,7 +2748,8 @@ Signed-off-by: John Crispin +{ + struct nand_chip *chip = (struct nand_chip *)mtd->priv; + -+ chip->erase(mtd, page); ++ chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); ++ chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); + + return chip->waitfunc(mtd, chip); +} @@ -3431,7 +3432,6 @@ Signed-off-by: John Crispin + nand_chip->write_page = mtk_nand_write_page; + nand_chip->ecc.write_oob = mtk_nand_write_oob; + nand_chip->block_markbad = mtk_nand_block_markbad; // need to add nand_get_device()/nand_release_device(). -+ nand_chip->erase_mtk = mtk_nand_erase; + nand_chip->read_page = mtk_nand_read_page; + nand_chip->ecc.read_oob = mtk_nand_read_oob; + nand_chip->block_bad = mtk_nand_block_bad; @@ -3562,6 +3562,8 @@ Signed-off-by: John Crispin + goto out; + } + ++ nand_chip->erase = mtk_nand_erase; ++ + g_page_size = mtd->writesize; + platform_set_drvdata(pdev, host); + if (hw->nfi_bus_width == 16) { @@ -4303,7 +4305,7 @@ Signed-off-by: John Crispin +#endif /* __NAND_DEF_H__ */ --- /dev/null +++ b/drivers/mtd/nand/nand_device_list.h -@@ -0,0 +1,56 @@ +@@ -0,0 +1,59 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are @@ -4350,6 +4352,9 @@ Signed-off-by: John Crispin + {0xADBC, 0x905554, 5, 16, 512, 128, 2048, 64, 0x10801011, "H9DA4GH4JJAMC", 0}, + {0x01F1, 0x801D01, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "S34ML01G100TF", 0}, + {0x92F1, 0x8095FF, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "F59L1G81A", 0}, ++ {0xC8D1, 0x809540, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "F59L1G81MA", 0}, ++ {0xC8DA, 0x909544, 5, 8, 256, 128, 2048, 64, 0x30C77fff, "F59L2G81A", 0}, ++ {0xC8DC, 0x909554, 5, 8, 512, 128, 2048, 64, 0x30C77fff, "F59L4G81A", 0}, + {0xECD3, 0x519558, 5, 8, 1024, 128, 2048, 64, 0x44333, "K9K8G8000", 0}, + {0xC2F1, 0x801DC2, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "MX30LF1G08AA", 0}, + {0x98D3, 0x902676, 5, 8, 1024, 256, 4096, 224, 0x00C25332, "TC58NVG3S0F", 0}, diff --git a/target/linux/ramips/patches-4.14/0040-nand-hack-restore-write_page.patch b/target/linux/ramips/patches-4.14/0040-nand-hack-restore-write_page.patch deleted file mode 100644 index ec2afeaf0..000000000 --- a/target/linux/ramips/patches-4.14/0040-nand-hack-restore-write_page.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/include/linux/mtd/rawnand.h -+++ b/include/linux/mtd/rawnand.h -@@ -885,6 +885,9 @@ struct nand_chip { - int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this); - int (*erase)(struct mtd_info *mtd, int page); - int (*scan_bbt)(struct mtd_info *mtd); -+ int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, -+ uint32_t offset, int data_len, const uint8_t *buf, -+ int oob_required, int page, int raw); - int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip, - int feature_addr, uint8_t *subfeature_para); - int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, ---- a/drivers/mtd/nand/nand_base.c -+++ b/drivers/mtd/nand/nand_base.c -@@ -2761,9 +2761,14 @@ static int nand_do_write_ops(struct mtd_ - memset(chip->oob_poi, 0xff, mtd->oobsize); - } - -- ret = nand_write_page(mtd, chip, column, bytes, wbuf, -- oob_required, page, -- (ops->mode == MTD_OPS_RAW)); -+// if (chip->write_page) -+ ret = chip->write_page(mtd, chip, column, bytes, wbuf, -+ oob_required, page, -+ (ops->mode == MTD_OPS_RAW)); -+// else -+// ret = nand_write_page(mtd, chip, column, bytes, wbuf, -+// oob_required, page, -+// (ops->mode == MTD_OPS_RAW)); - if (ret) - break; - -@@ -4719,6 +4724,9 @@ int nand_scan_tail(struct mtd_info *mtd) - } - } - -+// if (!chip->write_page) -+// chip->write_page = nand_write_page; -+ - /* - * Check ECC mode, default to software if 3byte/512byte hardware ECC is - * selected and we have 256 byte pagesize fallback to software ECC diff --git a/target/linux/ramips/patches-4.14/0040-nand-hack.patch b/target/linux/ramips/patches-4.14/0040-nand-hack.patch index ae6eed933..c906d7fa6 100644 --- a/target/linux/ramips/patches-4.14/0040-nand-hack.patch +++ b/target/linux/ramips/patches-4.14/0040-nand-hack.patch @@ -18,47 +18,42 @@ if (ret < 0) { if (use_bufpoi) /* Invalidate page cache */ -@@ -3084,8 +3088,11 @@ int nand_erase_nand(struct mtd_info *mtd - (page + pages_per_block)) - chip->pagebuf = -1; +@@ -2761,9 +2765,14 @@ static int nand_do_write_ops(struct mtd_ + memset(chip->oob_poi, 0xff, mtd->oobsize); + } + +- ret = nand_write_page(mtd, chip, column, bytes, wbuf, +- oob_required, page, +- (ops->mode == MTD_OPS_RAW)); ++ if (chip->write_page) ++ ret = chip->write_page(mtd, chip, column, bytes, wbuf, ++ oob_required, page, ++ (ops->mode == MTD_OPS_RAW)); ++ else ++ ret = nand_write_page(mtd, chip, column, bytes, wbuf, ++ oob_required, page, ++ (ops->mode == MTD_OPS_RAW)); + if (ret) + break; -+#ifdef CONFIG_MTK_MTD_NAND -+ status = chip->erase_mtk(mtd, page & chip->pagemask); -+#else - status = chip->erase(mtd, page & chip->pagemask); -- -+#endif - /* See if block erase succeeded */ - if (status & NAND_STATUS_FAIL) { - pr_debug("%s: failed erase, page 0x%08x\n", -@@ -4215,6 +4222,7 @@ int nand_scan_ident(struct mtd_info *mtd - * cmdfunc() both expect cmd_ctrl() to be populated, - * so we need to check that that's the case - */ -+ printk("%s:%s[%d]%p %p %p\n", __FILE__, __func__, __LINE__, chip->cmdfunc, chip->select_chip, chip->cmd_ctrl); - pr_err("chip.cmd_ctrl() callback is not provided"); - return -EINVAL; - } ---- a/drivers/mtd/nand/nand_device_list.h -+++ b/drivers/mtd/nand/nand_device_list.h -@@ -44,6 +44,8 @@ static const flashdev_info gen_FlashTabl - {0xADBC, 0x905554, 5, 16, 512, 128, 2048, 64, 0x10801011, "H9DA4GH4JJAMC", 0}, - {0x01F1, 0x801D01, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "S34ML01G100TF", 0}, - {0x92F1, 0x8095FF, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "F59L1G81A", 0}, -+ {0xC8DA, 0x909544, 5, 8, 256, 128, 2048, 64, 0x30C77fff, "F59L2G81A", 0}, -+ {0xC8DC, 0x909554, 5, 8, 512, 128, 2048, 64, 0x30C77fff, "F59L4G81A", 0}, - {0xECD3, 0x519558, 5, 8, 1024, 128, 2048, 64, 0x44333, "K9K8G8000", 0}, - {0xC2F1, 0x801DC2, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "MX30LF1G08AA", 0}, - {0x98D3, 0x902676, 5, 8, 1024, 256, 4096, 224, 0x00C25332, "TC58NVG3S0F", 0}, --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h -@@ -896,6 +896,10 @@ struct nand_chip { +@@ -885,6 +885,9 @@ struct nand_chip { + int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this); + int (*erase)(struct mtd_info *mtd, int page); + int (*scan_bbt)(struct mtd_info *mtd); ++ int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, ++ uint32_t offset, int data_len, const uint8_t *buf, ++ int oob_required, int page, int raw); + int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip, + int feature_addr, uint8_t *subfeature_para); + int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, +@@ -893,6 +896,9 @@ struct nand_chip { int (*setup_data_interface)(struct mtd_info *mtd, int chipnr, const struct nand_data_interface *conf); +#ifdef CONFIG_MTK_MTD_NAND + int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, u8 *buf, int page); -+ int (*erase_mtk)(struct mtd_info *mtd, int page); +#endif /* CONFIG_MTK_MTD_NAND */ int chip_delay; diff --git a/target/linux/ramips/patches-4.14/0043-spi-add-mt7621-support.patch b/target/linux/ramips/patches-4.14/0043-spi-add-mt7621-support.patch index c615601e5..d9bc48d69 100644 --- a/target/linux/ramips/patches-4.14/0043-spi-add-mt7621-support.patch +++ b/target/linux/ramips/patches-4.14/0043-spi-add-mt7621-support.patch @@ -38,7 +38,7 @@ Signed-off-by: John Crispin obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o --- /dev/null +++ b/drivers/spi/spi-mt7621.c -@@ -0,0 +1,488 @@ +@@ -0,0 +1,494 @@ +/* + * spi-mt7621.c -- MediaTek MT7621 SPI controller driver + * @@ -131,9 +131,11 @@ Signed-off-by: John Crispin + + master |= 7 << 29; + master |= 1 << 2; ++#ifdef CONFIG_SOC_MT7620 + if (duplex) + master |= 1 << 10; + else ++#endif + master &= ~(1 << 10); + + mt7621_spi_write(rs, MT7621_SPI_MASTER, master); @@ -308,6 +310,7 @@ Signed-off-by: John Crispin + return 0; +} + ++#ifdef CONFIG_SOC_MT7620 +static int mt7621_spi_transfer_full_duplex(struct spi_master *master, + struct spi_message *m) +{ @@ -392,15 +395,18 @@ Signed-off-by: John Crispin + + return 0; +} ++#endif + +static int mt7621_spi_transfer_one_message(struct spi_master *master, + struct spi_message *m) +{ + struct spi_device *spi = m->spi; ++#ifdef CONFIG_SOC_MT7620 + int cs = spi->chip_select; + + if (cs) + return mt7621_spi_transfer_full_duplex(master, m); ++#endif + return mt7621_spi_transfer_half_duplex(master, m); +} + diff --git a/target/linux/ramips/rt288x/config-4.14 b/target/linux/ramips/rt288x/config-4.14 index dba539766..a4b49790a 100644 --- a/target/linux/ramips/rt288x/config-4.14 +++ b/target/linux/ramips/rt288x/config-4.14 @@ -19,7 +19,6 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_ARCH_USE_QUEUED_RWLOCKS=y CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y CONFIG_BLK_MQ_PCI=y # CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set @@ -50,16 +49,11 @@ CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y -# CONFIG_DMA_NOOP_OPS is not set -# CONFIG_DMA_VIRT_OPS is not set -# CONFIG_DRM_LIB_RANDOM is not set # CONFIG_DTB_RT2880_EVAL is not set CONFIG_DTB_RT_NONE=y CONFIG_DTC=y CONFIG_EARLY_PRINTK=y -CONFIG_EXPORTFS=y CONFIG_FIXED_PHY=y -CONFIG_FUTEX_PI=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y @@ -217,7 +211,6 @@ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_SYS_SUPPORTS_ARBIT_HZ=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_THIN_ARCHIVES=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TINY_SRCU=y CONFIG_USB=m diff --git a/target/linux/ramips/rt3883/config-4.14 b/target/linux/ramips/rt3883/config-4.14 index 0c0a840c3..f663d4986 100644 --- a/target/linux/ramips/rt3883/config-4.14 +++ b/target/linux/ramips/rt3883/config-4.14 @@ -20,7 +20,6 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_ARCH_USE_QUEUED_RWLOCKS=y CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y CONFIG_BLK_MQ_PCI=y # CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set @@ -52,17 +51,12 @@ CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CSRC_R4K=y CONFIG_DEBUG_PINCTRL=y CONFIG_DMA_NONCOHERENT=y -# CONFIG_DMA_NOOP_OPS is not set -# CONFIG_DMA_VIRT_OPS is not set -# CONFIG_DRM_LIB_RANDOM is not set # CONFIG_DTB_RT3883_EVAL is not set CONFIG_DTB_RT_NONE=y CONFIG_DTC=y CONFIG_EARLY_PRINTK=y CONFIG_ETHERNET_PACKET_MANGLE=y -CONFIG_EXPORTFS=y CONFIG_FIXED_PHY=y -CONFIG_FUTEX_PI=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y @@ -226,7 +220,6 @@ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_SYS_SUPPORTS_ARBIT_HZ=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_THIN_ARCHIVES=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TINY_SRCU=y CONFIG_USB_SUPPORT=y