Merge Official Source
Closes: #332 Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
0ee01d71cd
@ -27,6 +27,10 @@ define Build/append-kernel
|
||||
dd if=$(IMAGE_KERNEL) >> $@
|
||||
endef
|
||||
|
||||
define Build/append-image
|
||||
dd if=$(BIN_DIR)/$(DEVICE_IMG_PREFIX)-$(1) >> $@
|
||||
endef
|
||||
|
||||
compat_version=$(if $(DEVICE_COMPAT_VERSION),$(DEVICE_COMPAT_VERSION),1.0)
|
||||
json_quote=$(subst ','\'',$(subst ",\",$(1)))
|
||||
#")')
|
||||
|
||||
@ -419,7 +419,7 @@ DEFAULT_DEVICE_VARS := \
|
||||
CMDLINE UBOOTENV_IN_UBI KERNEL_IN_UBI BLOCKSIZE PAGESIZE SUBPAGESIZE \
|
||||
VID_HDR_OFFSET UBINIZE_OPTS UBINIZE_PARTS MKUBIFS_OPTS DEVICE_DTS \
|
||||
DEVICE_DTS_CONFIG DEVICE_DTS_DIR DEVICE_DTS_OVERLAY DEVICE_FDT_NUM \
|
||||
SOC BOARD_NAME UIMAGE_MAGIC UIMAGE_NAME \
|
||||
DEVICE_IMG_PREFIX SOC BOARD_NAME UIMAGE_MAGIC UIMAGE_NAME \
|
||||
SUPPORTED_DEVICES IMAGE_METADATA KERNEL_ENTRY KERNEL_LOADADDR \
|
||||
UBOOT_PATH IMAGE_SIZE \
|
||||
DEVICE_COMPAT_VERSION DEVICE_COMPAT_MESSAGE \
|
||||
@ -478,6 +478,7 @@ define Device/Build/initramfs
|
||||
$$(if $$(CONFIG_JSON_OVERVIEW_IMAGE_INFO), $(BUILD_DIR)/json_info_files/$$(KERNEL_INITRAMFS_IMAGE).json,))
|
||||
|
||||
$(KDIR)/$$(KERNEL_INITRAMFS_NAME):: image_prepare
|
||||
$(1)-images: $(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE)
|
||||
$(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE): $(KDIR)/tmp/$$(KERNEL_INITRAMFS_IMAGE)
|
||||
cp $$^ $$@
|
||||
|
||||
@ -570,6 +571,7 @@ define Device/Build/image
|
||||
$(BUILD_DIR)/json_info_files/$(call DEVICE_IMG_NAME,$(1),$(2)).json, \
|
||||
$(BIN_DIR)/$(call DEVICE_IMG_NAME,$(1),$(2))$$(GZ_SUFFIX))
|
||||
$(eval $(call Device/Export,$(KDIR)/tmp/$(call DEVICE_IMG_NAME,$(1),$(2)),$(1)))
|
||||
$(3)-images: $(BIN_DIR)/$(call DEVICE_IMG_NAME,$(1),$(2))$$(GZ_SUFFIX)
|
||||
|
||||
ROOTFS/$(1)/$(3) := \
|
||||
$(KDIR)/root.$(1)$$(strip \
|
||||
@ -628,7 +630,7 @@ endef
|
||||
define Device/Build/artifact
|
||||
$$(_TARGET): $(BIN_DIR)/$(DEVICE_IMG_PREFIX)-$(1)
|
||||
$(eval $(call Device/Export,$(KDIR)/tmp/$(DEVICE_IMG_PREFIX)-$(1)))
|
||||
$(KDIR)/tmp/$(DEVICE_IMG_PREFIX)-$(1): $$(KDIR_KERNEL_IMAGE)
|
||||
$(KDIR)/tmp/$(DEVICE_IMG_PREFIX)-$(1): $$(KDIR_KERNEL_IMAGE) $(2)-images
|
||||
@rm -f $$@
|
||||
$$(call concat_cmd,$(ARTIFACT/$(1)))
|
||||
|
||||
@ -651,7 +653,7 @@ define Device/Build
|
||||
$$(call Device/Build/image,$$(fs),$$(image),$(1)))))
|
||||
|
||||
$$(eval $$(foreach artifact,$$(ARTIFACTS), \
|
||||
$$(call Device/Build/artifact,$$(artifact))))
|
||||
$$(call Device/Build/artifact,$$(artifact),$(1))))
|
||||
|
||||
endef
|
||||
|
||||
|
||||
@ -7,10 +7,10 @@ ifdef CONFIG_TESTING_KERNEL
|
||||
endif
|
||||
|
||||
LINUX_VERSION-5.4 = .106
|
||||
LINUX_VERSION-5.10 = .23
|
||||
LINUX_VERSION-5.10 = .26
|
||||
|
||||
LINUX_KERNEL_HASH-5.4.106 = cc873b2c39c1823d4bc4f6cde527943c8cfd28ae94cb517804b0f9679359c8db
|
||||
LINUX_KERNEL_HASH-5.10.23 = f6e21c03ec6ff85b26d77c59fdab81e64707792a57593643307df192749edb6a
|
||||
LINUX_KERNEL_HASH-5.10.26 = fc532833f1ac167f363f1b9de85db39d2d635ab516f66dc381bdd70804601482
|
||||
|
||||
remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1))))
|
||||
sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1)))))))
|
||||
|
||||
@ -136,6 +136,10 @@ $(eval $(call SetupHostCommand,bzip2,Please install 'bzip2', \
|
||||
$(eval $(call SetupHostCommand,wget,Please install GNU 'wget', \
|
||||
wget --version | grep GNU))
|
||||
|
||||
$(eval $(call SetupHostCommand,install,Please install GNU 'install', \
|
||||
install --version | grep GNU, \
|
||||
ginstall --version | grep GNU))
|
||||
|
||||
$(eval $(call SetupHostCommand,perl,Please install Perl 5.x, \
|
||||
perl --version | grep "perl.*v5"))
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ PKG_MIRROR_HASH:=0eda0e774a87e58e611d6436350e1cf2be3de50fddde334909a07a15b0c9862
|
||||
|
||||
PKG_MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=elfutils
|
||||
PKG_VERSION:=0.180
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:=https://sourceware.org/$(PKG_NAME)/ftp/$(PKG_VERSION)
|
||||
@ -21,7 +21,7 @@ PKG_CPE_ID:=cpe:/a:elfutils_project:elfutils
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
PKG_INSTALL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
PKG_USE_MIPS16:=1
|
||||
PKG_BUILD_DEPENDS:=!USE_GLIBC:argp-standalone
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@ -14,7 +14,7 @@ PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=https://github.com/jow-/ucode.git
|
||||
PKG_SOURCE_DATE:=2021-03-19
|
||||
PKG_SOURCE_VERSION:=4a5b9010ccc56fdf288fe758023af445feb93fad
|
||||
PKG_MIRROR_HASH:=145a2ce69e14cae9b448de85b94c7a817ba3aea04b1611399186ad36fb88958e
|
||||
PKG_MIRROR_HASH:=2d15fe2f51ebdeae532a2e8130689400cf2364876e737cfbb1bf9c045719acf1
|
||||
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
||||
PKG_LICENSE:=ISC
|
||||
|
||||
|
||||
6
rules.mk
6
rules.mk
@ -75,12 +75,12 @@ IS_PACKAGE_BUILD := $(if $(filter package/%,$(BUILD_SUBDIR)),1)
|
||||
OPTIMIZE_FOR_CPU=$(subst i386,i486,$(ARCH))
|
||||
|
||||
ifneq (,$(findstring $(ARCH) , aarch64 aarch64_be powerpc ))
|
||||
FPIC:=-fPIC
|
||||
FPIC:=-DPIC -fPIC
|
||||
else
|
||||
FPIC:=-fpic
|
||||
FPIC:=-DPIC -fpic
|
||||
endif
|
||||
|
||||
HOST_FPIC:=-fPIC
|
||||
HOST_FPIC:=-DPIC -fPIC
|
||||
|
||||
ARCH_SUFFIX:=$(call qstrip,$(CONFIG_CPU_TYPE))
|
||||
GCC_ARCH:=
|
||||
|
||||
@ -38,10 +38,9 @@ if output:
|
||||
"make",
|
||||
"--no-print-directory",
|
||||
"-C",
|
||||
"target/linux/{}".format(output["target"].split("/")[0]),
|
||||
"target/linux/",
|
||||
"val.DEFAULT_PACKAGES",
|
||||
"val.ARCH_PACKAGES",
|
||||
"DUMP=1",
|
||||
],
|
||||
stdout=PIPE,
|
||||
stderr=PIPE,
|
||||
@ -50,7 +49,8 @@ if output:
|
||||
universal_newlines=True,
|
||||
).stdout.splitlines()
|
||||
|
||||
output["default_packages"] = default_packages.split()
|
||||
output["default_packages"] = sorted(default_packages.split())
|
||||
|
||||
output_path.write_text(json.dumps(output, sort_keys=True, separators=(",", ":")))
|
||||
else:
|
||||
print("JSON info file script could not find any JSON files for target")
|
||||
|
||||
@ -13,7 +13,7 @@ produce a noisy warning.
|
||||
|
||||
--- a/drivers/usb/host/xhci-pci.c
|
||||
+++ b/drivers/usb/host/xhci-pci.c
|
||||
@@ -260,6 +260,7 @@ static void xhci_pci_quirks(struct devic
|
||||
@@ -261,6 +261,7 @@ static void xhci_pci_quirks(struct devic
|
||||
pdev->device == 0x0015) {
|
||||
xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||||
xhci->quirks |= XHCI_ZERO_64B_REGS;
|
||||
@ -43,7 +43,7 @@ produce a noisy warning.
|
||||
hcd->msi_enabled = 1;
|
||||
--- a/drivers/usb/host/xhci.h
|
||||
+++ b/drivers/usb/host/xhci.h
|
||||
@@ -1886,6 +1886,7 @@ struct xhci_hcd {
|
||||
@@ -1887,6 +1887,7 @@ struct xhci_hcd {
|
||||
struct xhci_hub usb2_rhub;
|
||||
struct xhci_hub usb3_rhub;
|
||||
/* support xHCI 1.0 spec USB2 hardware LPM */
|
||||
|
||||
@ -141,7 +141,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
{
|
||||
--- a/include/linux/gpio/consumer.h
|
||||
+++ b/include/linux/gpio/consumer.h
|
||||
@@ -713,6 +713,7 @@ static inline void devm_acpi_dev_remove_
|
||||
@@ -715,6 +715,7 @@ static inline void devm_acpi_dev_remove_
|
||||
|
||||
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
|
||||
|
||||
@ -149,7 +149,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||
int gpiod_export_link(struct device *dev, const char *name,
|
||||
struct gpio_desc *desc);
|
||||
@@ -720,6 +721,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||
@@ -722,6 +723,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||
|
||||
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
|
||||
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
From f1f811410af297c848e9ec17eaa280d190fdce10 Mon Sep 17 00:00:00 2001
|
||||
From: Mauri Sandberg <sandberg@mailfence.com>
|
||||
Date: Tue, 23 Feb 2021 18:09:31 +0200
|
||||
Subject: [PATCH] mtd: cfi_cmdset_0002: AMD chip 0x2201 - write words
|
||||
|
||||
Buffer writes do not work with AMD chip 0x2201. The chip in question
|
||||
is a AMD/Spansion/Cypress Semiconductor S29GL256N and datasheet [1]
|
||||
talks about writing buffers being possible. While waiting for a neater
|
||||
solution resort to writing word-sized chunks only.
|
||||
|
||||
Without the patch kernel logs will be flooded with entries like below:
|
||||
|
||||
jffs2_scan_eraseblock(): End of filesystem marker found at 0x0
|
||||
jffs2_build_filesystem(): unlocking the mtd device...
|
||||
done.
|
||||
jffs2_build_filesystem(): erasing all blocks after the end marker...
|
||||
MTD do_write_buffer_wait(): software timeout, address:0x01ec000a.
|
||||
jffs2: Write clean marker to block at 0x01920000 failed: -5
|
||||
MTD do_write_buffer_wait(): software timeout, address:0x01e2000a.
|
||||
jffs2: Write clean marker to block at 0x01880000 failed: -5
|
||||
MTD do_write_buffer_wait(): software timeout, address:0x01e0000a.
|
||||
jffs2: Write clean marker to block at 0x01860000 failed: -5
|
||||
MTD do_write_buffer_wait(): software timeout, address:0x01dc000a.
|
||||
jffs2: Write clean marker to block at 0x01820000 failed: -5
|
||||
MTD do_write_buffer_wait(): software timeout, address:0x01da000a.
|
||||
jffs2: Write clean marker to block at 0x01800000 failed: -5
|
||||
...
|
||||
|
||||
Tested on a Buffalo wzr-hp-g300nh running kernel 5.10.16.
|
||||
|
||||
[1] https://www.cypress.com/file/219941/download
|
||||
or https://datasheetspdf.com/pdf-file/565708/SPANSION/S29GL256N/1
|
||||
|
||||
Signed-off-by: Mauri Sandberg <sandberg@mailfence.com>
|
||||
---
|
||||
drivers/mtd/chips/cfi_cmdset_0002.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
@@ -272,6 +272,10 @@ static void fixup_use_write_buffers(stru
|
||||
{
|
||||
struct map_info *map = mtd->priv;
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
+
|
||||
+ if ((cfi->mfr == CFI_MFR_AMD) && (cfi->id == 0x2201))
|
||||
+ return;
|
||||
+
|
||||
if (cfi->cfiq->BufWriteTimeoutTyp) {
|
||||
pr_debug("Using buffer write method\n");
|
||||
mtd->_write = cfi_amdstd_write_buffers;
|
||||
@ -4,7 +4,7 @@ Date: Mon, 28 Jan 2013 20:06:30 +0100
|
||||
Subject: [PATCH 12/12] MIPS: BCM63XX: EHCI controller does not support
|
||||
overcurrent
|
||||
|
||||
This patch sets the ignore_oc flag for the BCM63XX EHCI controller as it
|
||||
This patch sets the spurious_oc flag for the BCM63XX EHCI controller as it
|
||||
does not support proper overcurrent reporting.
|
||||
|
||||
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
static struct usb_ehci_pdata bcm63xx_ehci_pdata = {
|
||||
.big_endian_desc = 1,
|
||||
.big_endian_mmio = 1,
|
||||
+ .ignore_oc = 1,
|
||||
+ .spurious_oc = 1,
|
||||
.power_on = bcm63xx_ehci_power_on,
|
||||
.power_off = bcm63xx_ehci_power_off,
|
||||
.power_suspend = bcm63xx_ehci_power_off,
|
||||
|
||||
@ -116,7 +116,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
|
||||
}
|
||||
--- a/drivers/gpio/gpiolib.c
|
||||
+++ b/drivers/gpio/gpiolib.c
|
||||
@@ -1886,7 +1886,8 @@ int gpiochip_add_pingroup_range(struct g
|
||||
@@ -1897,7 +1897,8 @@ int gpiochip_add_pingroup_range(struct g
|
||||
|
||||
list_add_tail(&pin_range->node, &gdev->pin_ranges);
|
||||
|
||||
@ -126,7 +126,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range);
|
||||
|
||||
@@ -1943,7 +1944,7 @@ int gpiochip_add_pin_range(struct gpio_c
|
||||
@@ -1954,7 +1955,7 @@ int gpiochip_add_pin_range(struct gpio_c
|
||||
|
||||
list_add_tail(&pin_range->node, &gdev->pin_ranges);
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ Date: Mon, 28 Jan 2013 20:06:30 +0100
|
||||
Subject: [PATCH 12/12] MIPS: BCM63XX: EHCI controller does not support
|
||||
overcurrent
|
||||
|
||||
This patch sets the ignore_oc flag for the BCM63XX EHCI controller as it
|
||||
This patch sets the spurious_oc flag for the BCM63XX EHCI controller as it
|
||||
does not support proper overcurrent reporting.
|
||||
|
||||
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
static struct usb_ehci_pdata bcm63xx_ehci_pdata = {
|
||||
.big_endian_desc = 1,
|
||||
.big_endian_mmio = 1,
|
||||
+ .ignore_oc = 1,
|
||||
+ .spurious_oc = 1,
|
||||
.power_on = bcm63xx_ehci_power_on,
|
||||
.power_off = bcm63xx_ehci_power_off,
|
||||
.power_suspend = bcm63xx_ehci_power_off,
|
||||
|
||||
@ -16,6 +16,17 @@ CONFIG_BCM63XX_POWER=y
|
||||
CONFIG_BCM7038_L1_IRQ=y
|
||||
CONFIG_BCM7038_WDT=y
|
||||
CONFIG_BCM7120_L2_IRQ=y
|
||||
CONFIG_BCMA=y
|
||||
CONFIG_BCMA_BLOCKIO=y
|
||||
# CONFIG_BCMA_DEBUG is not set
|
||||
# CONFIG_BCMA_DRIVER_GMAC_CMN is not set
|
||||
# CONFIG_BCMA_DRIVER_MIPS is not set
|
||||
CONFIG_BCMA_DRIVER_PCI=y
|
||||
# CONFIG_BCMA_DRIVER_PCI_HOSTMODE is not set
|
||||
CONFIG_BCMA_HOST_PCI=y
|
||||
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
|
||||
# CONFIG_BCMA_HOST_SOC is not set
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_BLK_PM=y
|
||||
CONFIG_BMIPS_GENERIC=y
|
||||
CONFIG_BOARD_SCACHE=y
|
||||
@ -139,6 +150,7 @@ CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_BUS_MUX=y
|
||||
CONFIG_MDIO_BUS_MUX_BCM6368=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIGRATION=y
|
||||
@ -194,6 +206,13 @@ CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_PADATA=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCIE_BCM6318=y
|
||||
CONFIG_PCIE_BCM6328=y
|
||||
CONFIG_PCIE_PME=y
|
||||
CONFIG_PCI_BCM6348=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DRIVERS_LEGACY=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
@ -244,6 +263,15 @@ CONFIG_SPI_BCM63XX_HSSPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_MEM=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_SSB=y
|
||||
CONFIG_SSB_B43_PCI_BRIDGE=y
|
||||
CONFIG_SSB_BLOCKIO=y
|
||||
# CONFIG_SSB_DRIVER_MIPS is not set
|
||||
CONFIG_SSB_DRIVER_PCICORE=y
|
||||
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
|
||||
CONFIG_SSB_PCIHOST=y
|
||||
CONFIG_SSB_PCIHOST_POSSIBLE=y
|
||||
CONFIG_SSB_SPROM=y
|
||||
CONFIG_SWAP_IO_SPACE=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYNC_R4K=y
|
||||
|
||||
@ -31,6 +31,28 @@
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
bcm43217-sprom {
|
||||
compatible = "brcm,bcm43217-sprom";
|
||||
|
||||
pci-bus = <1>;
|
||||
pci-dev = <0>;
|
||||
|
||||
mtd-mac-address = <&cfe 0x6a0>;
|
||||
mtd-mac-address-increment = <1>;
|
||||
|
||||
brcm,sprom-fixups = <6 0x1c00>,
|
||||
<65 0x1255>,
|
||||
<97 0xfe55>,
|
||||
<98 0x171d>,
|
||||
<99 0xfa42>,
|
||||
<113 0xfeb7>,
|
||||
<114 0x18cd>,
|
||||
<115 0xfa4f>,
|
||||
<162 0x6444>,
|
||||
<170 0x6444>,
|
||||
<172 0x6444>;
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
@ -164,6 +186,10 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pinctrl_leds: leds {
|
||||
function = "led";
|
||||
|
||||
@ -304,7 +304,7 @@
|
||||
compatible = "brcm,bcm6318-ehci", "generic-ehci";
|
||||
reg = <0x10005000 0x100>;
|
||||
big-endian;
|
||||
ignore-oc;
|
||||
spurious-oc;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6318_IRQ_EHCI>;
|
||||
@ -347,6 +347,41 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pcie: pcie@10010000 {
|
||||
compatible = "brcm,bcm6318-pcie";
|
||||
reg = <0x10010000 0x10000>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
device_type = "pci";
|
||||
bus-range = <0x00 0x01>;
|
||||
ranges = <0x2000000 0 0x10200000 0x10200000 0 0x100000>;
|
||||
linux,pci-probe-only = <1>;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6318_IRQ_PCIE_RC>;
|
||||
|
||||
clocks = <&periph_clk BCM6318_CLK_PCIE>,
|
||||
<&periph_clk BCM6318_CLK_PCIE25>,
|
||||
<&ubus_clk BCM6318_UCLK_PCIE>;
|
||||
clock-names = "pcie",
|
||||
"pcie25",
|
||||
"pcie-ubus";
|
||||
|
||||
resets = <&periph_rst BCM6318_RST_PCIE>,
|
||||
<&periph_rst BCM6318_RST_PCIE_EXT>,
|
||||
<&periph_rst BCM6318_RST_PCIE_CORE>,
|
||||
<&periph_rst BCM6318_RST_PCIE_HARD>;
|
||||
reset-names = "pcie",
|
||||
"pcie-ext",
|
||||
"pcie-core",
|
||||
"pcie-hard";
|
||||
|
||||
power-domains = <&periph_pwr BCM6318_POWER_DOMAIN_PCIE>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
switch0: switch@10080000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
@ -371,6 +371,12 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
serdes_cntl: syscon@10001804 {
|
||||
compatible = "syscon";
|
||||
reg = <0x10001804 0x4>;
|
||||
native-endian;
|
||||
};
|
||||
|
||||
periph_pwr: power-controller@1000184c {
|
||||
compatible = "brcm,bcm63268-power-controller";
|
||||
reg = <0x1000184c 0x4>;
|
||||
@ -390,7 +396,7 @@
|
||||
compatible = "brcm,bcm63268-ehci", "generic-ehci";
|
||||
reg = <0x10002500 0x100>;
|
||||
big-endian;
|
||||
ignore-oc;
|
||||
spurious-oc;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM63268_IRQ_EHCI>;
|
||||
@ -468,6 +474,39 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pcie: pcie@106e0000 {
|
||||
compatible = "brcm,bcm6328-pcie";
|
||||
reg = <0x106e0000 0x10000>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
device_type = "pci";
|
||||
bus-range = <0x00 0x01>;
|
||||
ranges = <0x2000000 0 0x11000000 0x11000000 0 0xf00000>;
|
||||
linux,pci-probe-only = <1>;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM63268_IRQ_PCIE_RC>;
|
||||
|
||||
clocks = <&periph_clk BCM63268_CLK_PCIE>;
|
||||
clock-names = "pcie";
|
||||
|
||||
resets = <&periph_rst BCM63268_RST_PCIE>,
|
||||
<&periph_rst BCM63268_RST_PCIE_EXT>,
|
||||
<&periph_rst BCM63268_RST_PCIE_CORE>,
|
||||
<&periph_rst BCM63268_RST_PCIE_HARD>;
|
||||
reset-names = "pcie",
|
||||
"pcie-ext",
|
||||
"pcie-core",
|
||||
"pcie-hard";
|
||||
|
||||
power-domains = <&periph_pwr BCM63268_POWER_DOMAIN_PCIE>;
|
||||
|
||||
brcm,serdes = <&serdes_cntl>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
switch0: switch@10700000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
@ -24,6 +24,41 @@
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
bcm43225-sprom {
|
||||
compatible = "brcm,bcm43225-sprom";
|
||||
|
||||
pci-bus = <1>;
|
||||
pci-dev = <0>;
|
||||
|
||||
mtd-mac-address = <&cfe 0x6a0>;
|
||||
mtd-mac-address-increment = <1>;
|
||||
|
||||
brcm,sprom-fixups = <2 0x05bb>,
|
||||
<65 0x1204>,
|
||||
<78 0x0303>,
|
||||
<79 0x0202>,
|
||||
<80 0xff02>,
|
||||
<87 0x0315>,
|
||||
<88 0x0315>,
|
||||
<96 0x2048>,
|
||||
<97 0xff11>,
|
||||
<98 0x1567>,
|
||||
<99 0xfb24>,
|
||||
<100 0x3e3c>,
|
||||
<101 0x4038>,
|
||||
<102 0xfe7f>,
|
||||
<103 0x1279>,
|
||||
<112 0x2048>,
|
||||
<113 0xff03>,
|
||||
<114 0x154c>,
|
||||
<115 0xfb27>,
|
||||
<116 0x3e3c>,
|
||||
<117 0x4038>,
|
||||
<118 0xfe87>,
|
||||
<119 0x1233>,
|
||||
<203 0x2226>;
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
@ -111,6 +146,10 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pinctrl_leds: leds {
|
||||
function = "led";
|
||||
|
||||
@ -317,6 +317,12 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
serdes_cntl: syscon@10001800 {
|
||||
compatible = "syscon";
|
||||
reg = <0x10001800 0x4>;
|
||||
native-endian;
|
||||
};
|
||||
|
||||
periph_pwr: power-controller@10001848 {
|
||||
compatible = "brcm,bcm6328-power-controller";
|
||||
reg = <0x10001848 0x4>;
|
||||
@ -328,7 +334,7 @@
|
||||
compatible = "brcm,bcm6328-ehci", "generic-ehci";
|
||||
reg = <0x10002500 0x100>;
|
||||
big-endian;
|
||||
ignore-oc;
|
||||
spurious-oc;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6328_IRQ_EHCI>;
|
||||
@ -462,5 +468,38 @@
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
pcie: pcie@10e40000 {
|
||||
compatible = "brcm,bcm6328-pcie";
|
||||
reg = <0x10e40000 0x10000>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
device_type = "pci";
|
||||
bus-range = <0x00 0x01>;
|
||||
ranges = <0x2000000 0 0x10f00000 0x10f00000 0 0x100000>;
|
||||
linux,pci-probe-only = <1>;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6328_IRQ_PCIE_RC>;
|
||||
|
||||
clocks = <&periph_clk BCM6328_CLK_PCIE>;
|
||||
clock-names = "pcie";
|
||||
|
||||
resets = <&periph_rst BCM6328_RST_PCIE>,
|
||||
<&periph_rst BCM6328_RST_PCIE_EXT>,
|
||||
<&periph_rst BCM6328_RST_PCIE_CORE>,
|
||||
<&periph_rst BCM6328_RST_PCIE_HARD>;
|
||||
reset-names = "pcie",
|
||||
"pcie-ext",
|
||||
"pcie-core",
|
||||
"pcie-hard";
|
||||
|
||||
power-domains = <&periph_pwr BCM6328_POWER_DOMAIN_PCIE>;
|
||||
|
||||
brcm,serdes = <&serdes_cntl>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -119,6 +119,21 @@
|
||||
gpios = <&pinctrl 28 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
ath9k-fixup {
|
||||
compatible = "brcm,ath9k-fixup";
|
||||
reg = <0x30000000 0x8000000>;
|
||||
|
||||
pci-dev = <1>;
|
||||
|
||||
mtd-mac-address = <&cfe 0x6a0>;
|
||||
mtd-mac-address-increment = <1>;
|
||||
|
||||
ath,eeprom = <&cal_data 0x1e000>;
|
||||
ath,endian-check;
|
||||
ath,led-pin = <2>;
|
||||
ath,led-active-high;
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
@ -129,6 +144,10 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pflash {
|
||||
status = "okay";
|
||||
|
||||
|
||||
@ -280,11 +280,36 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pci: pci@fffe1000 {
|
||||
compatible = "brcm,bcm6348-pci";
|
||||
reg = <0xfffe1000 0x200>,
|
||||
<0x08000000 0x10000>;
|
||||
reg-names = "pci",
|
||||
"pci-io";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
device_type = "pci";
|
||||
bus-range = <0x00 0x01>;
|
||||
ranges = <0x2000000 0 0x30000000 0x30000000 0 0x8000000>;
|
||||
linux,pci-probe-only = <1>;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6358_IRQ_MPI>;
|
||||
|
||||
resets = <&periph_rst BCM6358_RST_MPI>;
|
||||
reset-names = "pci";
|
||||
|
||||
brcm,remap;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ehci: usb@fffe1300 {
|
||||
compatible = "brcm,bcm6358-ehci", "generic-ehci";
|
||||
reg = <0xfffe1300 0x100>;
|
||||
big-endian;
|
||||
ignore-oc;
|
||||
spurious-oc;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6358_IRQ_EHCI>;
|
||||
|
||||
@ -209,6 +209,10 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pinctrl_leds: leds {
|
||||
function = "led";
|
||||
|
||||
@ -406,6 +406,12 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
serdes_cntl: syscon@10001804 {
|
||||
compatible = "syscon";
|
||||
reg = <0x10001804 0x4>;
|
||||
native-endian;
|
||||
};
|
||||
|
||||
periph_pwr: power-controller@10001848 {
|
||||
compatible = "brcm,bcm6362-power-controller";
|
||||
reg = <0x10001848 0x4>;
|
||||
@ -425,7 +431,7 @@
|
||||
compatible = "brcm,bcm6362-ehci", "generic-ehci";
|
||||
reg = <0x10002500 0x100>;
|
||||
big-endian;
|
||||
ignore-oc;
|
||||
spurious-oc;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6362_IRQ_EHCI>;
|
||||
@ -559,5 +565,36 @@
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
pcie: pcie@10e40000 {
|
||||
compatible = "brcm,bcm6328-pcie";
|
||||
reg = <0x10e40000 0x10000>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
device_type = "pci";
|
||||
bus-range = <0x00 0x01>;
|
||||
ranges = <0x2000000 0 0x10f00000 0x10f00000 0 0x100000>;
|
||||
linux,pci-probe-only = <1>;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6362_IRQ_PCIE_RC>;
|
||||
|
||||
clocks = <&periph_clk BCM6362_CLK_PCIE>;
|
||||
clock-names = "pcie";
|
||||
|
||||
resets = <&periph_rst BCM6362_RST_PCIE>,
|
||||
<&periph_rst BCM6362_RST_PCIE_EXT>,
|
||||
<&periph_rst BCM6362_RST_PCIE_CORE>;
|
||||
reset-names = "pcie",
|
||||
"pcie-ext",
|
||||
"pcie-core";
|
||||
|
||||
power-domains = <&periph_pwr BCM6362_POWER_DOMAIN_PCIE>;
|
||||
|
||||
brcm,serdes = <&serdes_cntl>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -53,6 +53,23 @@
|
||||
gpios = <&pinctrl 31 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
bcm43222-sprom {
|
||||
compatible = "brcm,bcm43222-sprom";
|
||||
|
||||
pci-bus = <0>;
|
||||
pci-dev = <1>;
|
||||
|
||||
mtd-mac-address = <&cfe 0x6a0>;
|
||||
mtd-mac-address-increment = <1>;
|
||||
|
||||
brcm,sprom-fixups = <97 0xfeb3>,
|
||||
<98 0x1618>,
|
||||
<99 0xfab0>,
|
||||
<113 0xfed1>,
|
||||
<114 0x1609>,
|
||||
<115 0xfad9>;
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
@ -69,6 +86,10 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pflash {
|
||||
status = "okay";
|
||||
|
||||
@ -98,7 +119,7 @@
|
||||
|
||||
&pinctrl {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pci &pinctrl_ephy0_led &pinctrl_ephy1_led
|
||||
pinctrl-0 = <&pinctrl_ephy0_led &pinctrl_ephy1_led
|
||||
&pinctrl_ephy2_led &pinctrl_ephy3_led>;
|
||||
};
|
||||
|
||||
|
||||
@ -414,11 +414,39 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pci: pci@10001000 {
|
||||
compatible = "brcm,bcm6348-pci";
|
||||
reg = <0x10001000 0x200>,
|
||||
<0x08000000 0x10000>;
|
||||
reg-names = "pci",
|
||||
"pci-io";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
|
||||
device_type = "pci";
|
||||
bus-range = <0x00 0x01>;
|
||||
ranges = <0x2000000 0 0x30000000 0x30000000 0 0x8000000>;
|
||||
linux,pci-probe-only = <1>;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6368_IRQ_MPI>;
|
||||
|
||||
resets = <&periph_rst BCM6368_RST_MPI>;
|
||||
reset-names = "pci";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pci>;
|
||||
|
||||
brcm,remap;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ehci: usb@10001500 {
|
||||
compatible = "brcm,bcm6368-ehci", "generic-ehci";
|
||||
reg = <0x10001500 0x100>;
|
||||
big-endian;
|
||||
ignore-oc;
|
||||
spurious-oc;
|
||||
|
||||
interrupt-parent = <&periph_intc>;
|
||||
interrupts = <BCM6368_IRQ_EHCI>;
|
||||
|
||||
240
target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c
Normal file
240
target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c
Normal file
@ -0,0 +1,240 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* ATH9K Fixup Driver
|
||||
*
|
||||
* Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
* Copyright (C) 2014 Jonas Gorski <jonas.gorski@gmail.com>
|
||||
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
|
||||
* Copyright (C) 2008 Florian Fainelli <f.fainelli@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ath9k_platform.h>
|
||||
|
||||
#define ATH9K_MAX_FIXUPS 2
|
||||
|
||||
#define ATH9K_DEF_LED_PIN -1
|
||||
#define ATH9K_DEF_PCI_DEV 255
|
||||
|
||||
struct ath9k_fixup {
|
||||
struct device *dev;
|
||||
struct resource *mem_res;
|
||||
u32 pci_dev;
|
||||
u8 mac[ETH_ALEN];
|
||||
struct ath9k_platform_data pdata;
|
||||
};
|
||||
|
||||
static int ath9k_num_fixups;
|
||||
static struct ath9k_fixup *ath9k_fixups[ATH9K_MAX_FIXUPS];
|
||||
|
||||
static void ath9k_pci_fixup(struct pci_dev *dev)
|
||||
{
|
||||
void __iomem *mem;
|
||||
struct ath9k_fixup *priv = NULL;
|
||||
struct ath9k_platform_data *pdata = NULL;
|
||||
struct pci_dev *bridge = pci_upstream_bridge(dev);
|
||||
u16 *cal_data = NULL;
|
||||
u16 cmd;
|
||||
u32 bar0;
|
||||
u32 val;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ath9k_num_fixups; i++) {
|
||||
if (ath9k_fixups[i]->pci_dev != PCI_SLOT(dev->devfn))
|
||||
continue;
|
||||
|
||||
priv = ath9k_fixups[i];
|
||||
cal_data = priv->pdata.eeprom_data;
|
||||
pdata = &priv->pdata;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cal_data == NULL)
|
||||
return;
|
||||
|
||||
if (*cal_data != 0xa55a) {
|
||||
pr_err("pci %s: invalid calibration data\n", pci_name(dev));
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("pci %s: fixup device configuration\n", pci_name(dev));
|
||||
|
||||
val = priv->mem_res->start;
|
||||
mem = ioremap(priv->mem_res->start, resource_size(priv->mem_res));
|
||||
if (!mem) {
|
||||
pr_err("pci %s: ioremap error\n", pci_name(dev));
|
||||
return;
|
||||
}
|
||||
|
||||
if (bridge)
|
||||
pci_enable_device(bridge);
|
||||
|
||||
pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
|
||||
pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
|
||||
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, val);
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
|
||||
/* set offset to first reg address */
|
||||
cal_data += 3;
|
||||
while(*cal_data != 0xffff) {
|
||||
u32 reg;
|
||||
|
||||
reg = *cal_data++;
|
||||
val = *cal_data++;
|
||||
val |= (*cal_data++) << 16;
|
||||
|
||||
writel(val, mem + reg);
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
|
||||
dev->vendor = val & 0xffff;
|
||||
dev->device = (val >> 16) & 0xffff;
|
||||
|
||||
pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
|
||||
dev->revision = val & 0xff;
|
||||
dev->class = val >> 8; /* upper 3 bytes */
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
|
||||
pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
|
||||
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
|
||||
|
||||
if (bridge)
|
||||
pci_disable_device(bridge);
|
||||
|
||||
iounmap(mem);
|
||||
|
||||
dev->dev.platform_data = pdata;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup);
|
||||
|
||||
static int ath9k_mtd_eeprom(struct ath9k_fixup *priv)
|
||||
{
|
||||
struct device *dev = priv->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct device_node *mtd_np = NULL;
|
||||
struct mtd_info *the_mtd;
|
||||
phandle phandle;
|
||||
size_t eeprom_readlen;
|
||||
const char *part;
|
||||
const __be32 *list;
|
||||
int ret, i;
|
||||
|
||||
list = of_get_property(node, "ath,eeprom", &i);
|
||||
if (!list || (i != (2 * sizeof(*list))))
|
||||
return -ENODEV;
|
||||
|
||||
phandle = be32_to_cpup(list++);
|
||||
if (phandle)
|
||||
mtd_np = of_find_node_by_phandle(phandle);
|
||||
if (!mtd_np)
|
||||
return -ENODEV;
|
||||
|
||||
part = of_get_property(mtd_np, "label", NULL);
|
||||
if (!part)
|
||||
part = mtd_np->name;
|
||||
|
||||
the_mtd = get_mtd_device_nm(part);
|
||||
if (IS_ERR(the_mtd))
|
||||
return -ENODEV;
|
||||
|
||||
ret = mtd_read(the_mtd, be32_to_cpup(list),
|
||||
ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16),
|
||||
&eeprom_readlen, (void *) priv->pdata.eeprom_data);
|
||||
put_mtd_device(the_mtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath9k_fixup_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct ath9k_fixup *priv;
|
||||
struct resource *res;
|
||||
const void *mac;
|
||||
int ret;
|
||||
|
||||
if (ath9k_num_fixups >= ATH9K_MAX_FIXUPS)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->dev = dev;
|
||||
priv->mem_res = res;
|
||||
|
||||
ret = of_property_read_u32(node, "pci-dev", &priv->pci_dev);
|
||||
if (ret)
|
||||
priv->pci_dev = ATH9K_DEF_PCI_DEV;
|
||||
|
||||
ret = ath9k_mtd_eeprom(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->pdata.endian_check = of_property_read_bool(node,
|
||||
"ath,endian-check");
|
||||
ret = of_property_read_s32(node, "ath,led-pin", &priv->pdata.led_pin);
|
||||
if (ret)
|
||||
priv->pdata.led_pin = ATH9K_DEF_LED_PIN;
|
||||
priv->pdata.led_active_high = of_property_read_bool(node,
|
||||
"ath,led-active-high");
|
||||
|
||||
mac = of_get_mac_address(node);
|
||||
if (!IS_ERR_OR_NULL(mac)) {
|
||||
memcpy(priv->mac, mac, ETH_ALEN);
|
||||
dev_info(dev, "mtd mac %pM\n", priv->mac);
|
||||
} else {
|
||||
random_ether_addr(priv->mac);
|
||||
dev_info(dev, "random mac %pM\n", priv->mac);
|
||||
}
|
||||
|
||||
priv->pdata.macaddr = priv->mac;
|
||||
|
||||
ath9k_fixups[ath9k_num_fixups] = priv;
|
||||
ath9k_num_fixups++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id ath9k_fixup_of_match[] = {
|
||||
{ .compatible = "brcm,ath9k-fixup" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver ath9k_fixup_driver = {
|
||||
.probe = ath9k_fixup_probe,
|
||||
.driver = {
|
||||
.name = "ath9k-fixup",
|
||||
.of_match_table = ath9k_fixup_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
int __init ath9k_fixup_init(void)
|
||||
{
|
||||
int ret = platform_driver_register(&ath9k_fixup_driver);
|
||||
if (ret)
|
||||
pr_err("ath9k_fixup: Error registering platform driver!\n");
|
||||
return ret;
|
||||
}
|
||||
late_initcall(ath9k_fixup_init);
|
||||
1195
target/linux/bmips/files/arch/mips/bmips/b43-sprom.c
Normal file
1195
target/linux/bmips/files/arch/mips/bmips/b43-sprom.c
Normal file
File diff suppressed because it is too large
Load Diff
18
target/linux/bmips/files/arch/mips/pci/fixup-bmips.c
Normal file
18
target/linux/bmips/files/arch/mips/pci/fixup-bmips.c
Normal file
@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
int bmips_pci_irq = -1;
|
||||
|
||||
int pcibios_plat_dev_init(struct pci_dev *pci_dev)
|
||||
{
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int pcibios_map_irq(const struct pci_dev *pci_dev, u8 slot, u8 pin)
|
||||
{
|
||||
return bmips_pci_irq;
|
||||
}
|
||||
825
target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c
Normal file
825
target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c
Normal file
@ -0,0 +1,825 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* BCM6348 PCI Controller Driver
|
||||
*
|
||||
* Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
* Copyright (C) 2015 Jonas Gorski <jonas.gorski@gmail.com>
|
||||
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "../pci.h"
|
||||
|
||||
#define CARDBUS_DUMMY_ID 0x6348
|
||||
#define CARDBUS_PCI_IDSEL 0x8
|
||||
#define FAKE_CB_BRIDGE_SLOT 0x1e
|
||||
|
||||
#define BCMPCI_REG_TIMERS 0x40
|
||||
#define REG_TIMER_TRDY_SHIFT 0
|
||||
#define REG_TIMER_TRDY_MASK (0xff << REG_TIMER_TRDY_SHIFT)
|
||||
#define REG_TIMER_RETRY_SHIFT 8
|
||||
#define REG_TIMER_RETRY_MASK (0xff << REG_TIMER_RETRY_SHIFT)
|
||||
|
||||
#define MPI_SP0_RANGE_REG 0x100
|
||||
#define MPI_SP0_REMAP_REG 0x104
|
||||
#define MPI_SP0_REMAP_ENABLE_MASK (1 << 0)
|
||||
#define MPI_SP1_RANGE_REG 0x10C
|
||||
#define MPI_SP1_REMAP_REG 0x110
|
||||
#define MPI_SP1_REMAP_ENABLE_MASK (1 << 0)
|
||||
|
||||
#define MPI_L2PCFG_REG 0x11c
|
||||
#define MPI_L2PCFG_CFG_TYPE_SHIFT 0
|
||||
#define MPI_L2PCFG_CFG_TYPE_MASK (0x3 << MPI_L2PCFG_CFG_TYPE_SHIFT)
|
||||
#define MPI_L2PCFG_REG_SHIFT 2
|
||||
#define MPI_L2PCFG_REG_MASK (0x3f << MPI_L2PCFG_REG_SHIFT)
|
||||
#define MPI_L2PCFG_FUNC_SHIFT 8
|
||||
#define MPI_L2PCFG_FUNC_MASK (0x7 << MPI_L2PCFG_FUNC_SHIFT)
|
||||
#define MPI_L2PCFG_DEVNUM_SHIFT 11
|
||||
#define MPI_L2PCFG_DEVNUM_MASK (0x1f << MPI_L2PCFG_DEVNUM_SHIFT)
|
||||
#define MPI_L2PCFG_CFG_USEREG_MASK (1 << 30)
|
||||
#define MPI_L2PCFG_CFG_SEL_MASK (1 << 31)
|
||||
|
||||
#define MPI_L2PMEMRANGE1_REG 0x120
|
||||
#define MPI_L2PMEMBASE1_REG 0x124
|
||||
#define MPI_L2PMEMREMAP1_REG 0x128
|
||||
#define MPI_L2PMEMRANGE2_REG 0x12C
|
||||
#define MPI_L2PMEMBASE2_REG 0x130
|
||||
#define MPI_L2PMEMREMAP2_REG 0x134
|
||||
#define MPI_L2PIORANGE_REG 0x138
|
||||
#define MPI_L2PIOBASE_REG 0x13C
|
||||
#define MPI_L2PIOREMAP_REG 0x140
|
||||
#define MPI_L2P_BASE_MASK (0xffff8000)
|
||||
#define MPI_L2PREMAP_ENABLED_MASK (1 << 0)
|
||||
#define MPI_L2PREMAP_IS_CARDBUS_MASK (1 << 2)
|
||||
|
||||
#define MPI_PCIMODESEL_REG 0x144
|
||||
#define MPI_PCIMODESEL_BAR1_NOSWAP_MASK (1 << 0)
|
||||
#define MPI_PCIMODESEL_BAR2_NOSWAP_MASK (1 << 1)
|
||||
#define MPI_PCIMODESEL_EXT_ARB_MASK (1 << 2)
|
||||
#define MPI_PCIMODESEL_PREFETCH_SHIFT 4
|
||||
#define MPI_PCIMODESEL_PREFETCH_MASK (0xf << MPI_PCIMODESEL_PREFETCH_SHIFT)
|
||||
|
||||
#define MPI_LOCBUSCTL_REG 0x14c
|
||||
#define MPI_LOCBUSCTL_EN_PCI_GPIO_MASK (1 << 0)
|
||||
#define MPI_LOCBUSCTL_U2P_NOSWAP_MASK (1 << 1)
|
||||
|
||||
#define MPI_LOCINT_REG 0x150
|
||||
#define MPI_LOCINT_MASK(x) (1 << (x + 16))
|
||||
#define MPI_LOCINT_STAT(x) (1 << (x))
|
||||
#define MPI_LOCINT_DIR_FAILED 6
|
||||
#define MPI_LOCINT_EXT_PCI_INT 7
|
||||
#define MPI_LOCINT_SERR 8
|
||||
#define MPI_LOCINT_CSERR 9
|
||||
|
||||
#define MPI_PCICFGCTL_REG 0x178
|
||||
#define MPI_PCICFGCTL_CFGADDR_SHIFT 2
|
||||
#define MPI_PCICFGCTL_CFGADDR_MASK (0x1f << MPI_PCICFGCTL_CFGADDR_SHIFT)
|
||||
#define MPI_PCICFGCTL_WRITEEN_MASK (1 << 7)
|
||||
|
||||
#define MPI_PCICFGDATA_REG 0x17c
|
||||
|
||||
#define PCMCIA_OFFSET 0x54
|
||||
|
||||
#define PCMCIA_C1_REG 0x0
|
||||
#define PCMCIA_C1_CD1_MASK (1 << 0)
|
||||
#define PCMCIA_C1_CD2_MASK (1 << 1)
|
||||
#define PCMCIA_C1_VS1_MASK (1 << 2)
|
||||
#define PCMCIA_C1_VS2_MASK (1 << 3)
|
||||
#define PCMCIA_C1_VS1OE_MASK (1 << 6)
|
||||
#define PCMCIA_C1_VS2OE_MASK (1 << 7)
|
||||
#define PCMCIA_C1_CBIDSEL_SHIFT (8)
|
||||
#define PCMCIA_C1_CBIDSEL_MASK (0x1f << PCMCIA_C1_CBIDSEL_SHIFT)
|
||||
#define PCMCIA_C1_EN_PCMCIA_GPIO_MASK (1 << 13)
|
||||
#define PCMCIA_C1_EN_PCMCIA_MASK (1 << 14)
|
||||
#define PCMCIA_C1_EN_CARDBUS_MASK (1 << 15)
|
||||
#define PCMCIA_C1_RESET_MASK (1 << 18)
|
||||
|
||||
#ifdef CONFIG_CARDBUS
|
||||
struct bcm6348_cb {
|
||||
u16 pci_command;
|
||||
u8 cb_latency;
|
||||
u8 subordinate_busn;
|
||||
u8 cardbus_busn;
|
||||
u8 pci_busn;
|
||||
int bus_assigned;
|
||||
u16 bridge_control;
|
||||
|
||||
u32 mem_base0;
|
||||
u32 mem_limit0;
|
||||
u32 mem_base1;
|
||||
u32 mem_limit1;
|
||||
|
||||
u32 io_base0;
|
||||
u32 io_limit0;
|
||||
u32 io_base1;
|
||||
u32 io_limit1;
|
||||
};
|
||||
#endif /* CONFIG_CARDBUS */
|
||||
|
||||
struct bcm6348_pci {
|
||||
void __iomem *pci;
|
||||
void __iomem *pcmcia;
|
||||
void __iomem *io;
|
||||
int irq;
|
||||
struct reset_control *reset;
|
||||
bool remap;
|
||||
#ifdef CONFIG_CARDBUS
|
||||
struct bcm6348_cb cb;
|
||||
int cb_bus;
|
||||
#endif /* CONFIG_CARDBUS */
|
||||
};
|
||||
|
||||
static struct bcm6348_pci bcm6348_pci;
|
||||
|
||||
extern int bmips_pci_irq;
|
||||
|
||||
static u32 bcm6348_int_cfg_readl(u32 reg)
|
||||
{
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
u32 tmp;
|
||||
|
||||
tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK;
|
||||
tmp |= MPI_PCICFGCTL_WRITEEN_MASK;
|
||||
__raw_writel(tmp, priv->pci + MPI_PCICFGCTL_REG);
|
||||
iob();
|
||||
return __raw_readl(priv->pci + MPI_PCICFGDATA_REG);
|
||||
}
|
||||
|
||||
static void bcm6348_int_cfg_writel(u32 val, u32 reg)
|
||||
{
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
u32 tmp;
|
||||
|
||||
tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK;
|
||||
tmp |= MPI_PCICFGCTL_WRITEEN_MASK;
|
||||
__raw_writel(tmp, priv->pci + MPI_PCICFGCTL_REG);
|
||||
__raw_writel(val, priv->pci + MPI_PCICFGDATA_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* swizzle 32bits data to return only the needed part
|
||||
*/
|
||||
static int postprocess_read(u32 data, int where, unsigned int size)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = (data >> ((where & 3) << 3)) & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
ret = (data >> ((where & 3) << 3)) & 0xffff;
|
||||
break;
|
||||
case 4:
|
||||
ret = data;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int preprocess_write(u32 orig_data, u32 val, int where,
|
||||
unsigned int size)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
|
||||
(val << ((where & 3) << 3));
|
||||
break;
|
||||
case 2:
|
||||
ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
|
||||
(val << ((where & 3) << 3));
|
||||
break;
|
||||
case 4:
|
||||
ret = val;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bcm6348_setup_cfg_access(int type, unsigned int busn,
|
||||
unsigned int devfn, int where)
|
||||
{
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
unsigned int slot, func, reg;
|
||||
u32 val;
|
||||
|
||||
slot = PCI_SLOT(devfn);
|
||||
func = PCI_FUNC(devfn);
|
||||
reg = where >> 2;
|
||||
|
||||
/* sanity check */
|
||||
if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT))
|
||||
return 1;
|
||||
|
||||
if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT))
|
||||
return 1;
|
||||
|
||||
if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT))
|
||||
return 1;
|
||||
|
||||
/* ok, setup config access */
|
||||
val = (reg << MPI_L2PCFG_REG_SHIFT);
|
||||
val |= (func << MPI_L2PCFG_FUNC_SHIFT);
|
||||
val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT);
|
||||
val |= MPI_L2PCFG_CFG_USEREG_MASK;
|
||||
val |= MPI_L2PCFG_CFG_SEL_MASK;
|
||||
/* type 0 cycle for local bus, type 1 cycle for anything else */
|
||||
if (type != 0) {
|
||||
/* FIXME: how to specify bus ??? */
|
||||
val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT);
|
||||
}
|
||||
__raw_writel(val, priv->pci + MPI_L2PCFG_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int bcm6348_do_cfg_read(int type, unsigned int busn,
|
||||
unsigned int devfn, int where, int size,
|
||||
u32 *val)
|
||||
{
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
u32 data;
|
||||
|
||||
/* two phase cycle, first we write address, then read data at
|
||||
* another location, caller already has a spinlock so no need
|
||||
* to add one here */
|
||||
if (bcm6348_setup_cfg_access(type, busn, devfn, where))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
iob();
|
||||
data = le32_to_cpu(__raw_readl(priv->io));
|
||||
/* restore IO space normal behaviour */
|
||||
__raw_writel(0, priv->pci + MPI_L2PCFG_REG);
|
||||
|
||||
*val = postprocess_read(data, where, size);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int bcm6348_do_cfg_write(int type, unsigned int busn,
|
||||
unsigned int devfn, int where, int size,
|
||||
u32 val)
|
||||
{
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
u32 data;
|
||||
|
||||
/* two phase cycle, first we write address, then write data to
|
||||
* another location, caller already has a spinlock so no need
|
||||
* to add one here */
|
||||
if (bcm6348_setup_cfg_access(type, busn, devfn, where))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
iob();
|
||||
|
||||
data = le32_to_cpu(__raw_readl(priv->io));
|
||||
data = preprocess_write(data, val, where, size);
|
||||
|
||||
__raw_writel(cpu_to_le32(data), priv->io);
|
||||
wmb();
|
||||
/* no way to know the access is done, we have to wait */
|
||||
udelay(500);
|
||||
/* restore IO space normal behaviour */
|
||||
__raw_writel(0, priv->pci + MPI_L2PCFG_REG);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int bcm6348_pci_read(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
int type;
|
||||
|
||||
type = bus->parent ? 1 : 0;
|
||||
|
||||
if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
return bcm6348_do_cfg_read(type, bus->number, devfn,
|
||||
where, size, val);
|
||||
}
|
||||
|
||||
static int bcm6348_pci_write(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
int type;
|
||||
|
||||
type = bus->parent ? 1 : 0;
|
||||
|
||||
if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
return bcm6348_do_cfg_write(type, bus->number, devfn,
|
||||
where, size, val);
|
||||
}
|
||||
|
||||
static struct pci_ops bcm6348_pci_ops = {
|
||||
.read = bcm6348_pci_read,
|
||||
.write = bcm6348_pci_write,
|
||||
};
|
||||
|
||||
static struct resource bcm6348_pci_io_resource = {
|
||||
.name = "BCM6348 PCI IO space",
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
static struct resource bcm6348_pci_mem_resource;
|
||||
static struct resource bcm6348_pci_busn_resource;
|
||||
|
||||
static struct pci_controller bcm6348_pci_controller = {
|
||||
.pci_ops = &bcm6348_pci_ops,
|
||||
.io_resource = &bcm6348_pci_io_resource,
|
||||
.mem_resource = &bcm6348_pci_mem_resource,
|
||||
.busn_resource = &bcm6348_pci_busn_resource,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CARDBUS
|
||||
static int bcm6348_cb_bridge_read(int where, int size, u32 *val)
|
||||
{
|
||||
struct bcm6348_cb *cb = &bcm6348_pci.cb;
|
||||
unsigned int reg;
|
||||
u32 data;
|
||||
|
||||
data = 0;
|
||||
reg = where >> 2;
|
||||
switch (reg) {
|
||||
case (PCI_VENDOR_ID >> 2):
|
||||
case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2):
|
||||
/* create dummy vendor/device id from our cpu id */
|
||||
data = (CARDBUS_DUMMY_ID << 16) | PCI_VENDOR_ID_BROADCOM;
|
||||
break;
|
||||
|
||||
case (PCI_COMMAND >> 2):
|
||||
data = (PCI_STATUS_DEVSEL_SLOW << 16);
|
||||
data |= cb->pci_command;
|
||||
break;
|
||||
|
||||
case (PCI_CLASS_REVISION >> 2):
|
||||
data = (PCI_CLASS_BRIDGE_CARDBUS << 16);
|
||||
break;
|
||||
|
||||
case (PCI_CACHE_LINE_SIZE >> 2):
|
||||
data = (PCI_HEADER_TYPE_CARDBUS << 16);
|
||||
break;
|
||||
|
||||
case (PCI_INTERRUPT_LINE >> 2):
|
||||
/* bridge control */
|
||||
data = (cb->bridge_control << 16);
|
||||
/* pin:intA line:0xff */
|
||||
data |= (0x1 << 8) | 0xff;
|
||||
break;
|
||||
|
||||
case (PCI_CB_PRIMARY_BUS >> 2):
|
||||
data = (cb->cb_latency << 24);
|
||||
data |= (cb->subordinate_busn << 16);
|
||||
data |= (cb->cardbus_busn << 8);
|
||||
data |= cb->pci_busn;
|
||||
break;
|
||||
|
||||
case (PCI_CB_MEMORY_BASE_0 >> 2):
|
||||
data = cb->mem_base0;
|
||||
break;
|
||||
|
||||
case (PCI_CB_MEMORY_LIMIT_0 >> 2):
|
||||
data = cb->mem_limit0;
|
||||
break;
|
||||
|
||||
case (PCI_CB_MEMORY_BASE_1 >> 2):
|
||||
data = cb->mem_base1;
|
||||
break;
|
||||
|
||||
case (PCI_CB_MEMORY_LIMIT_1 >> 2):
|
||||
data = cb->mem_limit1;
|
||||
break;
|
||||
|
||||
case (PCI_CB_IO_BASE_0 >> 2):
|
||||
/* | 1 for 32bits io support */
|
||||
data = cb->io_base0 | 0x1;
|
||||
break;
|
||||
|
||||
case (PCI_CB_IO_LIMIT_0 >> 2):
|
||||
data = cb->io_limit0;
|
||||
break;
|
||||
|
||||
case (PCI_CB_IO_BASE_1 >> 2):
|
||||
/* | 1 for 32bits io support */
|
||||
data = cb->io_base1 | 0x1;
|
||||
break;
|
||||
|
||||
case (PCI_CB_IO_LIMIT_1 >> 2):
|
||||
data = cb->io_limit1;
|
||||
break;
|
||||
}
|
||||
|
||||
*val = postprocess_read(data, where, size);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* emulate configuration write access on a cardbus bridge
|
||||
*/
|
||||
static int bcm6348_cb_bridge_write(int where, int size, u32 val)
|
||||
{
|
||||
struct bcm6348_cb *cb = &bcm6348_pci.cb;
|
||||
unsigned int reg;
|
||||
u32 data, tmp;
|
||||
int ret;
|
||||
|
||||
ret = bcm6348_cb_bridge_read((where & ~0x3), 4, &data);
|
||||
if (ret != PCIBIOS_SUCCESSFUL)
|
||||
return ret;
|
||||
|
||||
data = preprocess_write(data, val, where, size);
|
||||
|
||||
reg = where >> 2;
|
||||
switch (reg) {
|
||||
case (PCI_COMMAND >> 2):
|
||||
cb->pci_command = (data & 0xffff);
|
||||
break;
|
||||
|
||||
case (PCI_CB_PRIMARY_BUS >> 2):
|
||||
cb->cb_latency = (data >> 24) & 0xff;
|
||||
cb->subordinate_busn = (data >> 16) & 0xff;
|
||||
cb->cardbus_busn = (data >> 8) & 0xff;
|
||||
cb->pci_busn = data & 0xff;
|
||||
if (cb->cardbus_busn)
|
||||
cb->bus_assigned = 1;
|
||||
break;
|
||||
|
||||
case (PCI_INTERRUPT_LINE >> 2):
|
||||
tmp = (data >> 16) & 0xffff;
|
||||
/* Disable memory prefetch support */
|
||||
tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
|
||||
tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1;
|
||||
cb->bridge_control = tmp;
|
||||
break;
|
||||
|
||||
case (PCI_CB_MEMORY_BASE_0 >> 2):
|
||||
cb->mem_base0 = data;
|
||||
break;
|
||||
|
||||
case (PCI_CB_MEMORY_LIMIT_0 >> 2):
|
||||
cb->mem_limit0 = data;
|
||||
break;
|
||||
|
||||
case (PCI_CB_MEMORY_BASE_1 >> 2):
|
||||
cb->mem_base1 = data;
|
||||
break;
|
||||
|
||||
case (PCI_CB_MEMORY_LIMIT_1 >> 2):
|
||||
cb->mem_limit1 = data;
|
||||
break;
|
||||
|
||||
case (PCI_CB_IO_BASE_0 >> 2):
|
||||
cb->io_base0 = data;
|
||||
break;
|
||||
|
||||
case (PCI_CB_IO_LIMIT_0 >> 2):
|
||||
cb->io_limit0 = data;
|
||||
break;
|
||||
|
||||
case (PCI_CB_IO_BASE_1 >> 2):
|
||||
cb->io_base1 = data;
|
||||
break;
|
||||
|
||||
case (PCI_CB_IO_LIMIT_1 >> 2):
|
||||
cb->io_limit1 = data;
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int bcm6348_cb_read(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
struct bcm6348_cb *cb = &priv->cb;
|
||||
|
||||
/* Snoop access to slot 0x1e on root bus, we fake a cardbus
|
||||
* bridge at this location */
|
||||
if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
|
||||
priv->cb_bus = bus->number;
|
||||
return bcm6348_cb_bridge_read(where, size, val);
|
||||
}
|
||||
|
||||
/* A configuration cycle for the device behind the cardbus
|
||||
* bridge is actually done as a type 0 cycle on the primary
|
||||
* bus. This means that only one device can be on the cardbus
|
||||
* bus */
|
||||
if (cb->bus_assigned &&
|
||||
bus->number == cb->cardbus_busn &&
|
||||
PCI_SLOT(devfn) == 0)
|
||||
return bcm6348_do_cfg_read(0, 0,
|
||||
PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
|
||||
where, size, val);
|
||||
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int bcm6348_cb_write(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
struct bcm6348_cb *cb = &priv->cb;
|
||||
|
||||
if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
|
||||
priv->cb_bus = bus->number;
|
||||
return bcm6348_cb_bridge_write(where, size, val);
|
||||
}
|
||||
|
||||
if (cb->bus_assigned &&
|
||||
bus->number == cb->cardbus_busn &&
|
||||
PCI_SLOT(devfn) == 0)
|
||||
return bcm6348_do_cfg_write(0, 0,
|
||||
PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
|
||||
where, size, val);
|
||||
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
static struct pci_ops bcm6348_cb_ops = {
|
||||
.read = bcm6348_cb_read,
|
||||
.write = bcm6348_cb_write,
|
||||
};
|
||||
|
||||
/*
|
||||
* only one IO window, so it cannot be shared by PCI and cardbus, use
|
||||
* fixup to choose and detect unhandled configuration
|
||||
*/
|
||||
static void bcm6348_pci_fixup(struct pci_dev *dev)
|
||||
{
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
struct bcm6348_cb *cb = &priv->cb;
|
||||
static int io_window = -1;
|
||||
int i, found, new_io_window;
|
||||
u32 val;
|
||||
|
||||
/* look for any io resource */
|
||||
found = 0;
|
||||
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return;
|
||||
|
||||
/* skip our fake bus with only cardbus bridge on it */
|
||||
if (dev->bus->number == priv->cb_bus)
|
||||
return;
|
||||
|
||||
/* find on which bus the device is */
|
||||
if (cb->bus_assigned &&
|
||||
dev->bus->number == cb->cardbus_busn &&
|
||||
PCI_SLOT(dev->devfn) == 0)
|
||||
new_io_window = 1;
|
||||
else
|
||||
new_io_window = 0;
|
||||
|
||||
if (new_io_window == io_window)
|
||||
return;
|
||||
|
||||
if (io_window != -1) {
|
||||
pr_err("bcm63xx: both PCI and cardbus devices "
|
||||
"need IO, which hardware cannot do\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("bcm63xx: PCI IO window assigned to %s\n",
|
||||
(new_io_window == 0) ? "PCI" : "cardbus");
|
||||
|
||||
val = __raw_readl(priv->pci + MPI_L2PIOREMAP_REG);
|
||||
if (io_window)
|
||||
val |= MPI_L2PREMAP_IS_CARDBUS_MASK;
|
||||
else
|
||||
val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK;
|
||||
__raw_writel(val, priv->pci + MPI_L2PIOREMAP_REG);
|
||||
|
||||
io_window = new_io_window;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm6348_pci_fixup);
|
||||
|
||||
static struct resource bcm6348_cb_io_resource = {
|
||||
.name = "bcm6348 CB IO space",
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
static struct resource bcm6348_cb_mem_resource;
|
||||
|
||||
static struct pci_controller bcm6348_cb_controller = {
|
||||
.pci_ops = &bcm6348_cb_ops,
|
||||
.io_resource = &bcm6348_cb_io_resource,
|
||||
.mem_resource = &bcm6348_cb_mem_resource,
|
||||
};
|
||||
#endif /* CONFIG_CARDBUS */
|
||||
|
||||
static void bcm6348_pci_setup(struct bcm6348_pci *priv)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Setup local bus to PCI access (PCI memory) */
|
||||
val = bcm6348_pci_mem_resource.start & MPI_L2P_BASE_MASK;
|
||||
__raw_writel(val, priv->pci + MPI_L2PMEMBASE1_REG);
|
||||
__raw_writel(~(resource_size(&bcm6348_pci_mem_resource) - 1),
|
||||
priv->pci + MPI_L2PMEMRANGE1_REG);
|
||||
__raw_writel(val | MPI_L2PREMAP_ENABLED_MASK,
|
||||
priv->pci + MPI_L2PMEMREMAP1_REG);
|
||||
|
||||
/* Set Cardbus IDSEL (type 0 cfg access on primary bus for
|
||||
* this IDSEL will be done on Cardbus instead) */
|
||||
val = __raw_readl(priv->pcmcia + PCMCIA_C1_REG);
|
||||
val &= ~PCMCIA_C1_CBIDSEL_MASK;
|
||||
val |= (CARDBUS_PCI_IDSEL << PCMCIA_C1_CBIDSEL_SHIFT);
|
||||
__raw_writel(val, priv->pcmcia + PCMCIA_C1_REG);
|
||||
|
||||
#ifdef CONFIG_CARDBUS
|
||||
/* setup local bus to PCI access (Cardbus memory) */
|
||||
val = bcm6348_cb_mem_resource.start & MPI_L2P_BASE_MASK;
|
||||
__raw_writel(val, priv->pci + MPI_L2PMEMBASE2_REG);
|
||||
__raw_writel(~(resource_size(&bcm6348_cb_mem_resource) - 1),
|
||||
priv->pci + MPI_L2PMEMRANGE2_REG);
|
||||
val |= MPI_L2PREMAP_ENABLED_MASK | MPI_L2PREMAP_IS_CARDBUS_MASK;
|
||||
__raw_writel(val, priv->pci + MPI_L2PMEMREMAP2_REG);
|
||||
#else
|
||||
/* disable second access windows */
|
||||
__raw_writel(0, priv->pci + MPI_L2PMEMREMAP2_REG);
|
||||
#endif
|
||||
|
||||
/* setup local bus to PCI access (IO memory), we have only 1
|
||||
* IO window for both PCI and cardbus, but it cannot handle
|
||||
* both at the same time, assume standard PCI for now, if
|
||||
* cardbus card has IO zone, PCI fixup will change window to
|
||||
* cardbus */
|
||||
val = bcm6348_pci_io_resource.start & MPI_L2P_BASE_MASK;
|
||||
__raw_writel(val, priv->pci + MPI_L2PIOBASE_REG);
|
||||
__raw_writel(~(resource_size(&bcm6348_pci_io_resource) - 1),
|
||||
priv->pci + MPI_L2PIORANGE_REG);
|
||||
__raw_writel(val | MPI_L2PREMAP_ENABLED_MASK,
|
||||
priv->pci + MPI_L2PIOREMAP_REG);
|
||||
|
||||
/* Enable PCI related GPIO pins */
|
||||
__raw_writel(MPI_LOCBUSCTL_EN_PCI_GPIO_MASK,
|
||||
priv->pci + MPI_LOCBUSCTL_REG);
|
||||
|
||||
/* Setup PCI to local bus access, used by PCI device to target
|
||||
* local RAM while bus mastering */
|
||||
bcm6348_int_cfg_writel(0, PCI_BASE_ADDRESS_3);
|
||||
if (priv->remap)
|
||||
val = MPI_SP0_REMAP_ENABLE_MASK;
|
||||
else
|
||||
val = 0;
|
||||
__raw_writel(val, priv->pci + MPI_SP0_REMAP_REG);
|
||||
|
||||
bcm6348_int_cfg_writel(0, PCI_BASE_ADDRESS_4);
|
||||
__raw_writel(0, priv->pci + MPI_SP1_REMAP_REG);
|
||||
|
||||
/* Setup sp0 range to local RAM size */
|
||||
__raw_writel(~(memblock_phys_mem_size() - 1),
|
||||
priv->pci + MPI_SP0_RANGE_REG);
|
||||
__raw_writel(0, priv->pci + MPI_SP1_RANGE_REG);
|
||||
|
||||
/* Change host bridge retry counter to infinite number of
|
||||
* retries, needed for some broadcom wifi cards with Silicon
|
||||
* Backplane bus where access to srom seems very slow */
|
||||
val = bcm6348_int_cfg_readl(BCMPCI_REG_TIMERS);
|
||||
val &= ~REG_TIMER_RETRY_MASK;
|
||||
bcm6348_int_cfg_writel(val, BCMPCI_REG_TIMERS);
|
||||
|
||||
/* EEnable memory decoder and bus mastering */
|
||||
val = bcm6348_int_cfg_readl(PCI_COMMAND);
|
||||
val |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
||||
bcm6348_int_cfg_writel(val, PCI_COMMAND);
|
||||
|
||||
/* Enable read prefetching & disable byte swapping for bus
|
||||
* mastering transfers */
|
||||
val = __raw_readl(priv->pci + MPI_PCIMODESEL_REG);
|
||||
val &= ~MPI_PCIMODESEL_BAR1_NOSWAP_MASK;
|
||||
val &= ~MPI_PCIMODESEL_BAR2_NOSWAP_MASK;
|
||||
val &= ~MPI_PCIMODESEL_PREFETCH_MASK;
|
||||
val |= (8 << MPI_PCIMODESEL_PREFETCH_SHIFT);
|
||||
__raw_writel(val, priv->pci + MPI_PCIMODESEL_REG);
|
||||
|
||||
/* Enable pci interrupt */
|
||||
val = __raw_readl(priv->pci + MPI_LOCINT_REG);
|
||||
val |= MPI_LOCINT_MASK(MPI_LOCINT_EXT_PCI_INT);
|
||||
__raw_writel(val, priv->pci + MPI_LOCINT_REG);
|
||||
}
|
||||
|
||||
static int bcm6348_pci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct bcm6348_pci *priv = &bcm6348_pci;
|
||||
struct resource *res;
|
||||
|
||||
of_pci_check_probe_only();
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pci");
|
||||
priv->pci = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(priv->pci))
|
||||
return PTR_ERR(priv->pci);
|
||||
|
||||
priv->pcmcia = priv->pci + PCMCIA_OFFSET;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pci-io");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
#ifdef CONFIG_CARDBUS
|
||||
bcm6348_pci_io_resource.start = res->start;
|
||||
bcm6348_pci_io_resource.end = res->end - (resource_size(res) >> 1);
|
||||
bcm6348_cb_io_resource.start = res->start + (resource_size(res) >> 1);
|
||||
bcm6348_cb_io_resource.end = res->end;
|
||||
#else
|
||||
bcm6348_pci_io_resource.start = res->start;
|
||||
bcm6348_pci_io_resource.end = res->end;
|
||||
#endif
|
||||
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (!priv->irq)
|
||||
return -ENODEV;
|
||||
|
||||
bmips_pci_irq = priv->irq;
|
||||
|
||||
priv->reset = devm_reset_control_get(dev, "pci");
|
||||
if (IS_ERR(priv->reset))
|
||||
return PTR_ERR(priv->reset);
|
||||
|
||||
priv->remap = of_property_read_bool(np, "brcm,remap");
|
||||
|
||||
reset_control_reset(priv->reset);
|
||||
|
||||
pci_load_of_ranges(&bcm6348_pci_controller, np);
|
||||
if (!bcm6348_pci_mem_resource.start)
|
||||
return -EINVAL;
|
||||
|
||||
of_pci_parse_bus_range(np, &bcm6348_pci_busn_resource);
|
||||
|
||||
/*
|
||||
* Configuration accesses are done through IO space, remap 4
|
||||
* first bytes to access it from CPU.
|
||||
*
|
||||
* This means that no IO access from CPU should happen while
|
||||
* we do a configuration cycle, but there's no way we can add
|
||||
* a spinlock for each io access, so this is currently kind of
|
||||
* broken on SMP.
|
||||
*/
|
||||
priv->io = ioremap(bcm6348_pci_io_resource.start, sizeof(u32));
|
||||
if (!priv->io)
|
||||
return -ENOMEM;
|
||||
|
||||
bcm6348_pci_setup(priv);
|
||||
|
||||
register_pci_controller(&bcm6348_pci_controller);
|
||||
|
||||
#ifdef CONFIG_CARDBUS
|
||||
priv->cb_bus = -1;
|
||||
register_pci_controller(&bcm6348_cb_controller);
|
||||
#endif /* CONFIG_CARDBUS */
|
||||
|
||||
/* Mark memory space used for IO mapping as reserved */
|
||||
request_mem_region(bcm6348_pci_io_resource.start,
|
||||
resource_size(&bcm6348_pci_io_resource),
|
||||
"BCM6348 PCI IO space");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm6348_pci_of_match[] = {
|
||||
{ .compatible = "brcm,bcm6348-pci", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver bcm6348_pci_driver = {
|
||||
.probe = bcm6348_pci_probe,
|
||||
.driver = {
|
||||
.name = "bcm6348-pci",
|
||||
.of_match_table = bcm6348_pci_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
int __init bcm6348_pci_init(void)
|
||||
{
|
||||
int ret = platform_driver_register(&bcm6348_pci_driver);
|
||||
if (ret)
|
||||
pr_err("pci-bcm6348: Error registering platform driver!\n");
|
||||
return ret;
|
||||
}
|
||||
late_initcall_sync(bcm6348_pci_init);
|
||||
402
target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c
Normal file
402
target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c
Normal file
@ -0,0 +1,402 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* BCM6318 PCIe Controller Driver
|
||||
*
|
||||
* Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
* Copyright (C) 2015 Jonas Gorski <jonas.gorski@gmail.com>
|
||||
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "../pci.h"
|
||||
|
||||
#define PCIE_BUS_BRIDGE 0
|
||||
#define PCIE_BUS_DEVICE 1
|
||||
|
||||
#define PCIE_SPECIFIC_REG 0x188
|
||||
#define SPECIFIC_ENDIAN_MODE_BAR1_SHIFT 0
|
||||
#define SPECIFIC_ENDIAN_MODE_BAR1_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
|
||||
#define SPECIFIC_ENDIAN_MODE_BAR2_SHIFT 2
|
||||
#define SPECIFIC_ENDIAN_MODE_BAR2_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
|
||||
#define SPECIFIC_ENDIAN_MODE_BAR3_SHIFT 4
|
||||
#define SPECIFIC_ENDIAN_MODE_BAR3_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
|
||||
#define SPECIFIC_ENDIAN_MODE_WORD_ALIGN 0
|
||||
#define SPECIFIC_ENDIAN_MODE_HALFWORD_ALIGN 1
|
||||
#define SPECIFIC_ENDIAN_MODE_BYTE_ALIGN 2
|
||||
|
||||
#define PCIE_CONFIG2_REG 0x408
|
||||
#define CONFIG2_BAR1_SIZE_EN 1
|
||||
#define CONFIG2_BAR1_SIZE_MASK 0xf
|
||||
|
||||
#define PCIE_IDVAL3_REG 0x43c
|
||||
#define IDVAL3_CLASS_CODE_MASK 0xffffff
|
||||
#define IDVAL3_SUBCLASS_SHIFT 8
|
||||
#define IDVAL3_CLASS_SHIFT 16
|
||||
|
||||
#define PCIE_DLSTATUS_REG 0x1048
|
||||
#define DLSTATUS_PHYLINKUP (1 << 13)
|
||||
|
||||
#define PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG 0x400c
|
||||
#define C2P_MEM_WIN_ENDIAN_MODE_MASK 0x3
|
||||
#define C2P_MEM_WIN_ENDIAN_NO_SWAP 0
|
||||
#define C2P_MEM_WIN_ENDIAN_HALF_WORD_SWAP 1
|
||||
#define C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP 2
|
||||
#define C2P_MEM_WIN_BASE_ADDR_SHIFT 20
|
||||
#define C2P_MEM_WIN_BASE_ADDR_MASK (0xfff << C2P_MEM_WIN_BASE_ADDR_SHIFT)
|
||||
|
||||
#define PCIE_RC_BAR1_CONFIG_LO_REG 0x402c
|
||||
#define RC_BAR_CFG_LO_SIZE_256MB 0xd
|
||||
#define RC_BAR_CFG_LO_MATCH_ADDR_SHIFT 20
|
||||
#define RC_BAR_CFG_LO_MATCH_ADDR_MASK (0xfff << RC_BAR_CFG_LO_MATCH_ADDR_SHIFT)
|
||||
|
||||
#define PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG 0x4070
|
||||
#define C2P_BASELIMIT_LIMIT_SHIFT 20
|
||||
#define C2P_BASELIMIT_LIMIT_MASK (0xfff << C2P_BASELIMIT_LIMIT_SHIFT)
|
||||
#define C2P_BASELIMIT_BASE_SHIFT 4
|
||||
#define C2P_BASELIMIT_BASE_MASK (0xfff << C2P_BASELIMIT_BASE_SHIFT)
|
||||
|
||||
#define PCIE_UBUS_BAR1_CFG_REMAP_REG 0x4088
|
||||
#define BAR1_CFG_REMAP_OFFSET_SHIFT 20
|
||||
#define BAR1_CFG_REMAP_OFFSET_MASK (0xfff << BAR1_CFG_REMAP_OFFSET_SHIFT)
|
||||
#define BAR1_CFG_REMAP_ACCESS_EN 1
|
||||
|
||||
#define PCIE_HARD_DEBUG_REG 0x4204
|
||||
#define HARD_DEBUG_SERDES_IDDQ (1 << 23)
|
||||
|
||||
#define PCIE_CPU_INT1_MASK_CLEAR_REG 0x830c
|
||||
#define CPU_INT_PCIE_ERR_ATTN_CPU (1 << 0)
|
||||
#define CPU_INT_PCIE_INTA (1 << 1)
|
||||
#define CPU_INT_PCIE_INTB (1 << 2)
|
||||
#define CPU_INT_PCIE_INTC (1 << 3)
|
||||
#define CPU_INT_PCIE_INTD (1 << 4)
|
||||
#define CPU_INT_PCIE_INTR (1 << 5)
|
||||
#define CPU_INT_PCIE_NMI (1 << 6)
|
||||
#define CPU_INT_PCIE_UBUS (1 << 7)
|
||||
#define CPU_INT_IPI (1 << 8)
|
||||
|
||||
#define PCIE_EXT_CFG_INDEX_REG 0x8400
|
||||
#define EXT_CFG_FUNC_NUM_SHIFT 12
|
||||
#define EXT_CFG_FUNC_NUM_MASK (0x7 << EXT_CFG_FUNC_NUM_SHIFT)
|
||||
#define EXT_CFG_DEV_NUM_SHIFT 15
|
||||
#define EXT_CFG_DEV_NUM_MASK (0xf << EXT_CFG_DEV_NUM_SHIFT)
|
||||
#define EXT_CFG_BUS_NUM_SHIFT 20
|
||||
#define EXT_CFG_BUS_NUM_MASK (0xff << EXT_CFG_BUS_NUM_SHIFT)
|
||||
|
||||
#define PCIE_DEVICE_OFFSET 0x9000
|
||||
|
||||
struct bcm6318_pcie {
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
struct clk *clk;
|
||||
struct clk *clk25;
|
||||
struct clk *clk_ubus;
|
||||
struct reset_control *reset;
|
||||
struct reset_control *reset_ext;
|
||||
struct reset_control *reset_core;
|
||||
struct reset_control *reset_hard;
|
||||
};
|
||||
|
||||
static struct bcm6318_pcie bcm6318_pcie;
|
||||
|
||||
extern int bmips_pci_irq;
|
||||
|
||||
/*
|
||||
* swizzle 32bits data to return only the needed part
|
||||
*/
|
||||
static int postprocess_read(u32 data, int where, unsigned int size)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = (data >> ((where & 3) << 3)) & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
ret = (data >> ((where & 3) << 3)) & 0xffff;
|
||||
break;
|
||||
case 4:
|
||||
ret = data;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int preprocess_write(u32 orig_data, u32 val, int where,
|
||||
unsigned int size)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
|
||||
(val << ((where & 3) << 3));
|
||||
break;
|
||||
case 2:
|
||||
ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
|
||||
(val << ((where & 3) << 3));
|
||||
break;
|
||||
case 4:
|
||||
ret = val;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bcm6318_pcie_can_access(struct pci_bus *bus, int devfn)
|
||||
{
|
||||
struct bcm6318_pcie *priv = &bcm6318_pcie;
|
||||
|
||||
switch (bus->number) {
|
||||
case PCIE_BUS_BRIDGE:
|
||||
return PCI_SLOT(devfn) == 0;
|
||||
case PCIE_BUS_DEVICE:
|
||||
if (PCI_SLOT(devfn) == 0)
|
||||
return __raw_readl(priv->base + PCIE_DLSTATUS_REG)
|
||||
& DLSTATUS_PHYLINKUP;
|
||||
/* else, fall through */
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int bcm6318_pcie_read(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
struct bcm6318_pcie *priv = &bcm6318_pcie;
|
||||
u32 data;
|
||||
u32 reg = where & ~3;
|
||||
|
||||
if (!bcm6318_pcie_can_access(bus, devfn))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (bus->number == PCIE_BUS_DEVICE)
|
||||
reg += PCIE_DEVICE_OFFSET;
|
||||
|
||||
data = __raw_readl(priv->base + reg);
|
||||
*val = postprocess_read(data, where, size);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int bcm6318_pcie_write(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
struct bcm6318_pcie *priv = &bcm6318_pcie;
|
||||
u32 data;
|
||||
u32 reg = where & ~3;
|
||||
|
||||
if (!bcm6318_pcie_can_access(bus, devfn))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (bus->number == PCIE_BUS_DEVICE)
|
||||
reg += PCIE_DEVICE_OFFSET;
|
||||
|
||||
data = __raw_readl(priv->base + reg);
|
||||
data = preprocess_write(data, val, where, size);
|
||||
__raw_writel(data, priv->base + reg);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops bcm6318_pcie_ops = {
|
||||
.read = bcm6318_pcie_read,
|
||||
.write = bcm6318_pcie_write,
|
||||
};
|
||||
|
||||
static struct resource bcm6318_pcie_io_resource;
|
||||
static struct resource bcm6318_pcie_mem_resource;
|
||||
static struct resource bcm6318_pcie_busn_resource;
|
||||
|
||||
static struct pci_controller bcm6318_pcie_controller = {
|
||||
.pci_ops = &bcm6318_pcie_ops,
|
||||
.io_resource = &bcm6318_pcie_io_resource,
|
||||
.mem_resource = &bcm6318_pcie_mem_resource,
|
||||
.busn_resource = &bcm6318_pcie_busn_resource,
|
||||
};
|
||||
|
||||
static void bcm6318_pcie_reset(struct bcm6318_pcie *priv)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
reset_control_deassert(priv->reset_hard);
|
||||
|
||||
reset_control_assert(priv->reset);
|
||||
reset_control_assert(priv->reset_core);
|
||||
reset_control_assert(priv->reset_ext);
|
||||
mdelay(10);
|
||||
|
||||
reset_control_deassert(priv->reset_ext);
|
||||
mdelay(10);
|
||||
|
||||
reset_control_deassert(priv->reset);
|
||||
mdelay(10);
|
||||
|
||||
val = __raw_readl(priv->base + PCIE_HARD_DEBUG_REG);
|
||||
val &= ~HARD_DEBUG_SERDES_IDDQ;
|
||||
__raw_writel(val, priv->base + PCIE_HARD_DEBUG_REG);
|
||||
mdelay(10);
|
||||
|
||||
reset_control_deassert(priv->reset_core);
|
||||
mdelay(200);
|
||||
}
|
||||
|
||||
static void bcm6318_pcie_setup(struct bcm6318_pcie *priv)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
__raw_writel(CPU_INT_PCIE_INTA | CPU_INT_PCIE_INTB |
|
||||
CPU_INT_PCIE_INTC | CPU_INT_PCIE_INTD,
|
||||
priv->base + PCIE_CPU_INT1_MASK_CLEAR_REG);
|
||||
|
||||
val = bcm6318_pcie_mem_resource.end & C2P_BASELIMIT_LIMIT_MASK;
|
||||
val |= (bcm6318_pcie_mem_resource.start >> C2P_BASELIMIT_LIMIT_SHIFT)
|
||||
<< C2P_BASELIMIT_BASE_SHIFT;
|
||||
__raw_writel(val, priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG);
|
||||
|
||||
/* setup class code as bridge */
|
||||
val = __raw_readl(priv->base + PCIE_IDVAL3_REG);
|
||||
val &= ~IDVAL3_CLASS_CODE_MASK;
|
||||
val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT);
|
||||
__raw_writel(val, priv->base + PCIE_IDVAL3_REG);
|
||||
|
||||
/* disable bar1 size */
|
||||
val = __raw_readl(priv->base + PCIE_CONFIG2_REG);
|
||||
val &= ~CONFIG2_BAR1_SIZE_MASK;
|
||||
__raw_writel(val, priv->base + PCIE_CONFIG2_REG);
|
||||
|
||||
/* set bar0 to little endian */
|
||||
val = __raw_readl(priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
|
||||
val |= bcm6318_pcie_mem_resource.start & C2P_MEM_WIN_BASE_ADDR_MASK;
|
||||
val |= C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP;
|
||||
__raw_writel(val, priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
|
||||
|
||||
__raw_writel(SPECIFIC_ENDIAN_MODE_BYTE_ALIGN,
|
||||
priv->base + PCIE_SPECIFIC_REG);
|
||||
|
||||
__raw_writel(RC_BAR_CFG_LO_SIZE_256MB,
|
||||
priv->base + PCIE_RC_BAR1_CONFIG_LO_REG);
|
||||
|
||||
__raw_writel(BAR1_CFG_REMAP_ACCESS_EN,
|
||||
priv->base + PCIE_UBUS_BAR1_CFG_REMAP_REG);
|
||||
|
||||
__raw_writel(PCIE_BUS_DEVICE << EXT_CFG_BUS_NUM_SHIFT,
|
||||
priv->base + PCIE_EXT_CFG_INDEX_REG);
|
||||
}
|
||||
|
||||
static int bcm6318_pcie_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct bcm6318_pcie *priv = &bcm6318_pcie;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
of_pci_check_probe_only();
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (!priv->irq)
|
||||
return -ENODEV;
|
||||
|
||||
bmips_pci_irq = priv->irq;
|
||||
|
||||
priv->reset = devm_reset_control_get(dev, "pcie");
|
||||
if (IS_ERR(priv->reset))
|
||||
return PTR_ERR(priv->reset);
|
||||
|
||||
priv->reset_ext = devm_reset_control_get(dev, "pcie-ext");
|
||||
if (IS_ERR(priv->reset_ext))
|
||||
return PTR_ERR(priv->reset_ext);
|
||||
|
||||
priv->reset_core = devm_reset_control_get(dev, "pcie-core");
|
||||
if (IS_ERR(priv->reset_core))
|
||||
return PTR_ERR(priv->reset_core);
|
||||
|
||||
priv->reset_hard = devm_reset_control_get(dev, "pcie-hard");
|
||||
if (IS_ERR(priv->reset_hard))
|
||||
return PTR_ERR(priv->reset_hard);
|
||||
|
||||
priv->clk = devm_clk_get(dev, "pcie");
|
||||
if (IS_ERR(priv->clk))
|
||||
return PTR_ERR(priv->clk);
|
||||
|
||||
priv->clk25 = devm_clk_get(dev, "pcie25");
|
||||
if (IS_ERR(priv->clk25))
|
||||
return PTR_ERR(priv->clk25);
|
||||
|
||||
priv->clk_ubus = devm_clk_get(dev, "pcie-ubus");
|
||||
if (IS_ERR(priv->clk_ubus))
|
||||
return PTR_ERR(priv->clk_ubus);
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(priv->clk25);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(priv->clk_ubus);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pci_load_of_ranges(&bcm6318_pcie_controller, np);
|
||||
if (!bcm6318_pcie_mem_resource.start)
|
||||
return -EINVAL;
|
||||
|
||||
of_pci_parse_bus_range(np, &bcm6318_pcie_busn_resource);
|
||||
|
||||
bcm6318_pcie_reset(priv);
|
||||
bcm6318_pcie_setup(priv);
|
||||
|
||||
register_pci_controller(&bcm6318_pcie_controller);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm6318_pcie_of_match[] = {
|
||||
{ .compatible = "brcm,bcm6318-pcie", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver bcm6318_pcie_driver = {
|
||||
.probe = bcm6318_pcie_probe,
|
||||
.driver = {
|
||||
.name = "bcm6318-pcie",
|
||||
.of_match_table = bcm6318_pcie_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
int __init bcm6318_pcie_init(void)
|
||||
{
|
||||
int ret = platform_driver_register(&bcm6318_pcie_driver);
|
||||
if (ret)
|
||||
pr_err("pci-bcm6318: Error registering platform driver!\n");
|
||||
return ret;
|
||||
}
|
||||
late_initcall_sync(bcm6318_pcie_init);
|
||||
412
target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c
Normal file
412
target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c
Normal file
@ -0,0 +1,412 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* BCM6328 PCIe Controller Driver
|
||||
*
|
||||
* Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
* Copyright (C) 2015 Jonas Gorski <jonas.gorski@gmail.com>
|
||||
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "../pci.h"
|
||||
|
||||
#define SERDES_PCIE_EXD_EN BIT(15)
|
||||
#define SERDES_PCIE_EN BIT(0)
|
||||
|
||||
#define PCIE_BUS_BRIDGE 0
|
||||
#define PCIE_BUS_DEVICE 1
|
||||
|
||||
#define PCIE_CONFIG2_REG 0x408
|
||||
#define CONFIG2_BAR1_SIZE_EN 1
|
||||
#define CONFIG2_BAR1_SIZE_MASK 0xf
|
||||
|
||||
#define PCIE_IDVAL3_REG 0x43c
|
||||
#define IDVAL3_CLASS_CODE_MASK 0xffffff
|
||||
#define IDVAL3_SUBCLASS_SHIFT 8
|
||||
#define IDVAL3_CLASS_SHIFT 16
|
||||
|
||||
#define PCIE_DLSTATUS_REG 0x1048
|
||||
#define DLSTATUS_PHYLINKUP (1 << 13)
|
||||
|
||||
#define PCIE_BRIDGE_OPT1_REG 0x2820
|
||||
#define OPT1_RD_BE_OPT_EN (1 << 7)
|
||||
#define OPT1_RD_REPLY_BE_FIX_EN (1 << 9)
|
||||
#define OPT1_PCIE_BRIDGE_HOLE_DET_EN (1 << 11)
|
||||
#define OPT1_L1_INT_STATUS_MASK_POL (1 << 12)
|
||||
|
||||
#define PCIE_BRIDGE_OPT2_REG 0x2824
|
||||
#define OPT2_UBUS_UR_DECODE_DIS (1 << 2)
|
||||
#define OPT2_TX_CREDIT_CHK_EN (1 << 4)
|
||||
#define OPT2_CFG_TYPE1_BD_SEL (1 << 7)
|
||||
#define OPT2_CFG_TYPE1_BUS_NO_SHIFT 16
|
||||
#define OPT2_CFG_TYPE1_BUS_NO_MASK (0xff << OPT2_CFG_TYPE1_BUS_NO_SHIFT)
|
||||
|
||||
#define PCIE_BRIDGE_BAR0_BASEMASK_REG 0x2828
|
||||
#define BASEMASK_REMAP_EN (1 << 0)
|
||||
#define BASEMASK_SWAP_EN (1 << 1)
|
||||
#define BASEMASK_MASK_SHIFT 4
|
||||
#define BASEMASK_MASK_MASK (0xfff << BASEMASK_MASK_SHIFT)
|
||||
#define BASEMASK_BASE_SHIFT 20
|
||||
#define BASEMASK_BASE_MASK (0xfff << BASEMASK_BASE_SHIFT)
|
||||
|
||||
#define PCIE_BRIDGE_BAR0_REBASE_ADDR_REG 0x282c
|
||||
#define REBASE_ADDR_BASE_SHIFT 20
|
||||
#define REBASE_ADDR_BASE_MASK (0xfff << REBASE_ADDR_BASE_SHIFT)
|
||||
|
||||
#define PCIE_BRIDGE_RC_INT_MASK_REG 0x2854
|
||||
#define PCIE_RC_INT_A (1 << 0)
|
||||
#define PCIE_RC_INT_B (1 << 1)
|
||||
#define PCIE_RC_INT_C (1 << 2)
|
||||
#define PCIE_RC_INT_D (1 << 3)
|
||||
|
||||
#define PCIE_DEVICE_OFFSET 0x8000
|
||||
|
||||
struct bcm6328_pcie {
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
struct regmap *serdes;
|
||||
struct device **pm;
|
||||
struct device_link **link_pm;
|
||||
unsigned int num_pms;
|
||||
struct clk *clk;
|
||||
struct reset_control *reset;
|
||||
struct reset_control *reset_ext;
|
||||
struct reset_control *reset_core;
|
||||
struct reset_control *reset_hard;
|
||||
};
|
||||
|
||||
static struct bcm6328_pcie bcm6328_pcie;
|
||||
|
||||
extern int bmips_pci_irq;
|
||||
|
||||
/*
|
||||
* swizzle 32bits data to return only the needed part
|
||||
*/
|
||||
static int postprocess_read(u32 data, int where, unsigned int size)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = (data >> ((where & 3) << 3)) & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
ret = (data >> ((where & 3) << 3)) & 0xffff;
|
||||
break;
|
||||
case 4:
|
||||
ret = data;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int preprocess_write(u32 orig_data, u32 val, int where,
|
||||
unsigned int size)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
|
||||
(val << ((where & 3) << 3));
|
||||
break;
|
||||
case 2:
|
||||
ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
|
||||
(val << ((where & 3) << 3));
|
||||
break;
|
||||
case 4:
|
||||
ret = val;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bcm6328_pcie_can_access(struct pci_bus *bus, int devfn)
|
||||
{
|
||||
struct bcm6328_pcie *priv = &bcm6328_pcie;
|
||||
|
||||
switch (bus->number) {
|
||||
case PCIE_BUS_BRIDGE:
|
||||
return PCI_SLOT(devfn) == 0;
|
||||
case PCIE_BUS_DEVICE:
|
||||
if (PCI_SLOT(devfn) == 0)
|
||||
return __raw_readl(priv->base + PCIE_DLSTATUS_REG)
|
||||
& DLSTATUS_PHYLINKUP;
|
||||
/* else, fall through */
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int bcm6328_pcie_read(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
struct bcm6328_pcie *priv = &bcm6328_pcie;
|
||||
u32 data;
|
||||
u32 reg = where & ~3;
|
||||
|
||||
if (!bcm6328_pcie_can_access(bus, devfn))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (bus->number == PCIE_BUS_DEVICE)
|
||||
reg += PCIE_DEVICE_OFFSET;
|
||||
|
||||
data = __raw_readl(priv->base + reg);
|
||||
*val = postprocess_read(data, where, size);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int bcm6328_pcie_write(struct pci_bus *bus, unsigned int devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
struct bcm6328_pcie *priv = &bcm6328_pcie;
|
||||
u32 data;
|
||||
u32 reg = where & ~3;
|
||||
|
||||
if (!bcm6328_pcie_can_access(bus, devfn))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (bus->number == PCIE_BUS_DEVICE)
|
||||
reg += PCIE_DEVICE_OFFSET;
|
||||
|
||||
data = __raw_readl(priv->base + reg);
|
||||
data = preprocess_write(data, val, where, size);
|
||||
__raw_writel(data, priv->base + reg);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops bcm6328_pcie_ops = {
|
||||
.read = bcm6328_pcie_read,
|
||||
.write = bcm6328_pcie_write,
|
||||
};
|
||||
|
||||
static struct resource bcm6328_pcie_io_resource;
|
||||
static struct resource bcm6328_pcie_mem_resource;
|
||||
static struct resource bcm6328_pcie_busn_resource;
|
||||
|
||||
static struct pci_controller bcm6328_pcie_controller = {
|
||||
.pci_ops = &bcm6328_pcie_ops,
|
||||
.io_resource = &bcm6328_pcie_io_resource,
|
||||
.mem_resource = &bcm6328_pcie_mem_resource,
|
||||
.busn_resource = &bcm6328_pcie_busn_resource,
|
||||
};
|
||||
|
||||
static void bcm6328_pcie_reset(struct bcm6328_pcie *priv)
|
||||
{
|
||||
regmap_write_bits(priv->serdes, 0,
|
||||
SERDES_PCIE_EXD_EN | SERDES_PCIE_EN,
|
||||
SERDES_PCIE_EXD_EN | SERDES_PCIE_EN);
|
||||
|
||||
reset_control_assert(priv->reset);
|
||||
reset_control_assert(priv->reset_core);
|
||||
reset_control_assert(priv->reset_ext);
|
||||
if (priv->reset_hard) {
|
||||
reset_control_assert(priv->reset_hard);
|
||||
mdelay(10);
|
||||
reset_control_deassert(priv->reset_hard);
|
||||
}
|
||||
mdelay(10);
|
||||
|
||||
reset_control_deassert(priv->reset_core);
|
||||
reset_control_deassert(priv->reset);
|
||||
mdelay(10);
|
||||
|
||||
reset_control_deassert(priv->reset_ext);
|
||||
mdelay(200);
|
||||
}
|
||||
|
||||
static void bcm6328_pcie_setup(struct bcm6328_pcie *priv)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = __raw_readl(priv->base + PCIE_BRIDGE_OPT1_REG);
|
||||
val |= OPT1_RD_BE_OPT_EN;
|
||||
val |= OPT1_RD_REPLY_BE_FIX_EN;
|
||||
val |= OPT1_PCIE_BRIDGE_HOLE_DET_EN;
|
||||
val |= OPT1_L1_INT_STATUS_MASK_POL;
|
||||
__raw_writel(val, priv->base + PCIE_BRIDGE_OPT1_REG);
|
||||
|
||||
val = __raw_readl(priv->base + PCIE_BRIDGE_RC_INT_MASK_REG);
|
||||
val |= PCIE_RC_INT_A;
|
||||
val |= PCIE_RC_INT_B;
|
||||
val |= PCIE_RC_INT_C;
|
||||
val |= PCIE_RC_INT_D;
|
||||
__raw_writel(val, priv->base + PCIE_BRIDGE_RC_INT_MASK_REG);
|
||||
|
||||
val = __raw_readl(priv->base + PCIE_BRIDGE_OPT2_REG);
|
||||
/* enable credit checking and error checking */
|
||||
val |= OPT2_TX_CREDIT_CHK_EN;
|
||||
val |= OPT2_UBUS_UR_DECODE_DIS;
|
||||
/* set device bus/func for the pcie device */
|
||||
val |= (PCIE_BUS_DEVICE << OPT2_CFG_TYPE1_BUS_NO_SHIFT);
|
||||
val |= OPT2_CFG_TYPE1_BD_SEL;
|
||||
__raw_writel(val, priv->base + PCIE_BRIDGE_OPT2_REG);
|
||||
|
||||
/* setup class code as bridge */
|
||||
val = __raw_readl(priv->base + PCIE_IDVAL3_REG);
|
||||
val &= ~IDVAL3_CLASS_CODE_MASK;
|
||||
val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT);
|
||||
__raw_writel(val, priv->base + PCIE_IDVAL3_REG);
|
||||
|
||||
/* disable bar1 size */
|
||||
val = __raw_readl(priv->base + PCIE_CONFIG2_REG);
|
||||
val &= ~CONFIG2_BAR1_SIZE_MASK;
|
||||
__raw_writel(val, priv->base + PCIE_CONFIG2_REG);
|
||||
|
||||
/* set bar0 to little endian */
|
||||
val = (bcm6328_pcie_mem_resource.start >> 20)
|
||||
<< BASEMASK_BASE_SHIFT;
|
||||
val |= (bcm6328_pcie_mem_resource.end >> 20) << BASEMASK_MASK_SHIFT;
|
||||
val |= BASEMASK_REMAP_EN;
|
||||
__raw_writel(val, priv->base + PCIE_BRIDGE_BAR0_BASEMASK_REG);
|
||||
|
||||
val = (bcm6328_pcie_mem_resource.start >> 20)
|
||||
<< REBASE_ADDR_BASE_SHIFT;
|
||||
__raw_writel(val, priv->base + PCIE_BRIDGE_BAR0_REBASE_ADDR_REG);
|
||||
}
|
||||
|
||||
static int bcm6328_pcie_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct bcm6328_pcie *priv = &bcm6328_pcie;
|
||||
struct resource *res;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_no_callbacks(dev);
|
||||
|
||||
priv->num_pms = of_count_phandle_with_args(np, "power-domains",
|
||||
"#power-domain-cells");
|
||||
if (priv->num_pms > 1) {
|
||||
priv->pm = devm_kcalloc(dev, priv->num_pms,
|
||||
sizeof(struct device *), GFP_KERNEL);
|
||||
if (!priv->pm)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->link_pm = devm_kcalloc(dev, priv->num_pms,
|
||||
sizeof(struct device_link *),
|
||||
GFP_KERNEL);
|
||||
if (!priv->link_pm)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < priv->num_pms; i++) {
|
||||
priv->pm[i] = genpd_dev_pm_attach_by_id(dev, i);
|
||||
if (IS_ERR(priv->pm[i])) {
|
||||
dev_err(dev, "error getting pm %d\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->link_pm[i] = device_link_add(dev, priv->pm[i],
|
||||
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
|
||||
DL_FLAG_RPM_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_disable(dev);
|
||||
dev_info(dev, "PM prober defer: ret=%d\n", ret);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
of_pci_check_probe_only();
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (!priv->irq)
|
||||
return -ENODEV;
|
||||
|
||||
bmips_pci_irq = priv->irq;
|
||||
|
||||
priv->serdes = syscon_regmap_lookup_by_phandle(np, "brcm,serdes");
|
||||
if (IS_ERR(priv->serdes))
|
||||
return PTR_ERR(priv->serdes);
|
||||
|
||||
priv->reset = devm_reset_control_get(dev, "pcie");
|
||||
if (IS_ERR(priv->reset))
|
||||
return PTR_ERR(priv->reset);
|
||||
|
||||
priv->reset_ext = devm_reset_control_get(dev, "pcie-ext");
|
||||
if (IS_ERR(priv->reset_ext))
|
||||
return PTR_ERR(priv->reset_ext);
|
||||
|
||||
priv->reset_core = devm_reset_control_get(dev, "pcie-core");
|
||||
if (IS_ERR(priv->reset_core))
|
||||
return PTR_ERR(priv->reset_core);
|
||||
|
||||
priv->reset_hard = devm_reset_control_get_optional(dev, "pcie-hard");
|
||||
if (IS_ERR(priv->reset_hard))
|
||||
return PTR_ERR(priv->reset_hard);
|
||||
|
||||
priv->clk = devm_clk_get(dev, "pcie");
|
||||
if (IS_ERR(priv->clk))
|
||||
return PTR_ERR(priv->clk);
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pci_load_of_ranges(&bcm6328_pcie_controller, np);
|
||||
if (!bcm6328_pcie_mem_resource.start)
|
||||
return -EINVAL;
|
||||
|
||||
of_pci_parse_bus_range(np, &bcm6328_pcie_busn_resource);
|
||||
|
||||
bcm6328_pcie_reset(priv);
|
||||
bcm6328_pcie_setup(priv);
|
||||
|
||||
register_pci_controller(&bcm6328_pcie_controller);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm6328_pcie_of_match[] = {
|
||||
{ .compatible = "brcm,bcm6328-pcie", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver bcm6328_pcie_driver = {
|
||||
.probe = bcm6328_pcie_probe,
|
||||
.driver = {
|
||||
.name = "bcm6328-pcie",
|
||||
.of_match_table = bcm6328_pcie_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
int __init bcm6328_pcie_init(void)
|
||||
{
|
||||
int ret = platform_driver_register(&bcm6328_pcie_driver);
|
||||
if (ret)
|
||||
pr_err("pci-bcm6328: Error registering platform driver!\n");
|
||||
return ret;
|
||||
}
|
||||
late_initcall_sync(bcm6328_pcie_init);
|
||||
@ -249,6 +249,8 @@ define Device/Default
|
||||
DEVICE_LOADADDR :=
|
||||
endef
|
||||
|
||||
ATH9K_PACKAGES := kmod-ath9k wpad-basic-wolfssl
|
||||
B43_PACKAGES := kmod-b43 wpad-basic-wolfssl
|
||||
USB1_PACKAGES := kmod-usb-ohci kmod-ledtrig-usbdev
|
||||
USB2_PACKAGES := $(USB1_PACKAGES) kmod-usb2
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ define Device/comtrend_ar-5315u
|
||||
CHIP_ID := 6318
|
||||
CFE_BOARD_ID := 96318A-1441N1
|
||||
FLASH_MB := 16
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES)
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES) $(B43_PACKAGES)
|
||||
endef
|
||||
TARGET_DEVICES += comtrend_ar-5315u
|
||||
|
||||
@ -44,7 +44,7 @@ define Device/comtrend_ar-5387un
|
||||
CHIP_ID := 6328
|
||||
CFE_BOARD_ID := 96328A-1441N1
|
||||
FLASH_MB := 16
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES)
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES) $(B43_PACKAGES)
|
||||
endef
|
||||
TARGET_DEVICES += comtrend_ar-5387un
|
||||
|
||||
@ -56,7 +56,7 @@ define Device/comtrend_vr-3025u
|
||||
CFE_BOARD_ID := 96368M-1541N
|
||||
BLOCKSIZE := 0x20000
|
||||
FLASH_MB := 32
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES)
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES) $(B43_PACKAGES)
|
||||
endef
|
||||
TARGET_DEVICES += comtrend_vr-3025u
|
||||
|
||||
@ -69,6 +69,6 @@ define Device/huawei_hg556a-b
|
||||
CFE_BOARD_ID := HW556
|
||||
CFE_EXTRAS += --rsa-signature "EchoLife_HG556a" --tag-version 8
|
||||
BLOCKSIZE := 0x20000
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES)
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES) $(ATH9K_PACKAGES)
|
||||
endef
|
||||
TARGET_DEVICES += huawei_hg556a-b
|
||||
|
||||
@ -74,7 +74,7 @@ define Device/netgear_dgnd3700-v2
|
||||
CFE_RAM_JFFS2_PAD := 496k
|
||||
BLOCKSIZE := 16k
|
||||
PAGESIZE := 512
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES)
|
||||
DEVICE_PACKAGES += $(USB2_PACKAGES) $(B43_PACKAGES)
|
||||
CFE_WFI_FLASH_TYPE := 2
|
||||
CFE_WFI_VERSION := 0x5731
|
||||
endef
|
||||
|
||||
@ -1,104 +0,0 @@
|
||||
From a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Sun, 1 Nov 2020 21:16:09 +0200
|
||||
Subject: [PATCH] net: dsa: implement a central TX reallocation procedure
|
||||
|
||||
At the moment, taggers are left with the task of ensuring that the skb
|
||||
headers are writable (which they aren't, if the frames were cloned for
|
||||
TX timestamping, for flooding by the bridge, etc), and that there is
|
||||
enough space in the skb data area for the DSA tag to be pushed.
|
||||
|
||||
Moreover, the life of tail taggers is even harder, because they need to
|
||||
ensure that short frames have enough padding, a problem that normal
|
||||
taggers don't have.
|
||||
|
||||
The principle of the DSA framework is that everything except for the
|
||||
most intimate hardware specifics (like in this case, the actual packing
|
||||
of the DSA tag bits) should be done inside the core, to avoid having
|
||||
code paths that are very rarely tested.
|
||||
|
||||
So provide a TX reallocation procedure that should cover the known needs
|
||||
of DSA today.
|
||||
|
||||
Note that this patch also gives the network stack a good hint about the
|
||||
headroom/tailroom it's going to need. Up till now it wasn't doing that.
|
||||
So the reallocation procedure should really be there only for the
|
||||
exceptional cases, and for cloned packets which need to be unshared.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Tested-by: Christian Eggers <ceggers@arri.de> # For tail taggers only
|
||||
Tested-by: Kurt Kanzenbach <kurt@linutronix.de>
|
||||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
net/dsa/slave.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 45 insertions(+)
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -548,6 +548,30 @@ netdev_tx_t dsa_enqueue_skb(struct sk_bu
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dsa_enqueue_skb);
|
||||
|
||||
+static int dsa_realloc_skb(struct sk_buff *skb, struct net_device *dev)
|
||||
+{
|
||||
+ int needed_headroom = dev->needed_headroom;
|
||||
+ int needed_tailroom = dev->needed_tailroom;
|
||||
+
|
||||
+ /* For tail taggers, we need to pad short frames ourselves, to ensure
|
||||
+ * that the tail tag does not fail at its role of being at the end of
|
||||
+ * the packet, once the master interface pads the frame. Account for
|
||||
+ * that pad length here, and pad later.
|
||||
+ */
|
||||
+ if (unlikely(needed_tailroom && skb->len < ETH_ZLEN))
|
||||
+ needed_tailroom += ETH_ZLEN - skb->len;
|
||||
+ /* skb_headroom() returns unsigned int... */
|
||||
+ needed_headroom = max_t(int, needed_headroom - skb_headroom(skb), 0);
|
||||
+ needed_tailroom = max_t(int, needed_tailroom - skb_tailroom(skb), 0);
|
||||
+
|
||||
+ if (likely(!needed_headroom && !needed_tailroom && !skb_cloned(skb)))
|
||||
+ /* No reallocation needed, yay! */
|
||||
+ return 0;
|
||||
+
|
||||
+ return pskb_expand_head(skb, needed_headroom, needed_tailroom,
|
||||
+ GFP_ATOMIC);
|
||||
+}
|
||||
+
|
||||
static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct dsa_slave_priv *p = netdev_priv(dev);
|
||||
@@ -567,6 +591,17 @@ static netdev_tx_t dsa_slave_xmit(struct
|
||||
*/
|
||||
dsa_skb_tx_timestamp(p, skb);
|
||||
|
||||
+ if (dsa_realloc_skb(skb, dev)) {
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return NETDEV_TX_OK;
|
||||
+ }
|
||||
+
|
||||
+ /* needed_tailroom should still be 'warm' in the cache line from
|
||||
+ * dsa_realloc_skb(), which has also ensured that padding is safe.
|
||||
+ */
|
||||
+ if (dev->needed_tailroom)
|
||||
+ eth_skb_pad(skb);
|
||||
+
|
||||
/* Transmit function may have to reallocate the original SKB,
|
||||
* in which case it must have freed it. Only free it here on error.
|
||||
*/
|
||||
@@ -1825,6 +1860,16 @@ int dsa_slave_create(struct dsa_port *po
|
||||
slave_dev->netdev_ops = &dsa_slave_netdev_ops;
|
||||
if (ds->ops->port_max_mtu)
|
||||
slave_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index);
|
||||
+ if (cpu_dp->tag_ops->tail_tag)
|
||||
+ slave_dev->needed_tailroom = cpu_dp->tag_ops->overhead;
|
||||
+ else
|
||||
+ slave_dev->needed_headroom = cpu_dp->tag_ops->overhead;
|
||||
+ /* Try to save one extra realloc later in the TX path (in the master)
|
||||
+ * by also inheriting the master's needed headroom and tailroom.
|
||||
+ * The 8021q driver also does this.
|
||||
+ */
|
||||
+ slave_dev->needed_headroom += master->needed_headroom;
|
||||
+ slave_dev->needed_tailroom += master->needed_tailroom;
|
||||
SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
|
||||
|
||||
netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one,
|
||||
@ -80,7 +80,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
#define BRCM_TAG_LEN 4
|
||||
|
||||
/* Tag is constructed and desconstructed using byte by byte access
|
||||
@@ -197,6 +214,87 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
|
||||
@@ -194,6 +211,87 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
|
||||
MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM);
|
||||
#endif
|
||||
|
||||
@ -168,7 +168,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
|
||||
static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
@@ -229,6 +327,9 @@ static struct dsa_tag_driver *dsa_tag_dr
|
||||
@@ -226,6 +324,9 @@ static struct dsa_tag_driver *dsa_tag_dr
|
||||
#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
|
||||
&DSA_TAG_DRIVER_NAME(brcm_netdev_ops),
|
||||
#endif
|
||||
|
||||
@ -28,7 +28,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
This driver adds support for Broadcom managed switch chips. It supports
|
||||
--- a/drivers/net/dsa/b53/b53_common.c
|
||||
+++ b/drivers/net/dsa/b53/b53_common.c
|
||||
@@ -2010,15 +2010,17 @@ enum dsa_tag_protocol b53_get_tag_protoc
|
||||
@@ -2028,15 +2028,17 @@ enum dsa_tag_protocol b53_get_tag_protoc
|
||||
{
|
||||
struct b53_device *dev = ds->priv;
|
||||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
--- a/drivers/usb/host/ehci-platform.c
|
||||
+++ b/drivers/usb/host/ehci-platform.c
|
||||
@@ -286,6 +286,9 @@ static int ehci_platform_probe(struct pl
|
||||
if (of_property_read_bool(dev->dev.of_node, "big-endian"))
|
||||
ehci->big_endian_mmio = ehci->big_endian_desc = 1;
|
||||
|
||||
+ if (of_property_read_bool(dev->dev.of_node, "ignore-oc"))
|
||||
+ ehci->ignore_oc = 1;
|
||||
+
|
||||
if (of_property_read_bool(dev->dev.of_node,
|
||||
"needs-reset-on-resume"))
|
||||
priv->reset_on_resume = true;
|
||||
@ -13,7 +13,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
|
||||
--- a/drivers/net/dsa/b53/b53_common.c
|
||||
+++ b/drivers/net/dsa/b53/b53_common.c
|
||||
@@ -1140,6 +1140,36 @@ static void b53_force_port_config(struct
|
||||
@@ -1155,6 +1155,36 @@ static void b53_force_port_config(struct
|
||||
b53_write8(dev, B53_CTRL_PAGE, off, reg);
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
static void b53_adjust_link(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phydev)
|
||||
{
|
||||
@@ -1166,6 +1196,9 @@ static void b53_adjust_link(struct dsa_s
|
||||
@@ -1181,6 +1211,9 @@ static void b53_adjust_link(struct dsa_s
|
||||
tx_pause, rx_pause);
|
||||
b53_force_link(dev, port, phydev->link);
|
||||
|
||||
@ -60,7 +60,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
if (is531x5(dev) && phy_interface_is_rgmii(phydev)) {
|
||||
if (port == 8)
|
||||
off = B53_RGMII_CTRL_IMP;
|
||||
@@ -1358,6 +1391,9 @@ void b53_phylink_mac_link_up(struct dsa_
|
||||
@@ -1373,6 +1406,9 @@ void b53_phylink_mac_link_up(struct dsa_
|
||||
{
|
||||
struct b53_device *dev = ds->priv;
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -262,6 +262,7 @@ config BMIPS_GENERIC
|
||||
select BCM7038_L1_IRQ
|
||||
select BCM7120_L2_IRQ
|
||||
select BRCMSTB_L2_IRQ
|
||||
+ select HAVE_PCI
|
||||
select IRQ_MIPS_CPU
|
||||
select DMA_NONCOHERENT
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
--- a/arch/mips/pci/Makefile
|
||||
+++ b/arch/mips/pci/Makefile
|
||||
@@ -28,6 +28,7 @@ obj-$(CONFIG_PCI_XTALK_BRIDGE) += pci-xt
|
||||
# These are still pretty much in the old state, watch, go blind.
|
||||
#
|
||||
obj-$(CONFIG_ATH79) += fixup-ath79.o
|
||||
+obj-$(CONFIG_BMIPS_GENERIC) += fixup-bmips.o
|
||||
obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
|
||||
obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o
|
||||
obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o
|
||||
@ -0,0 +1,22 @@
|
||||
--- a/drivers/pci/controller/Kconfig
|
||||
+++ b/drivers/pci/controller/Kconfig
|
||||
@@ -3,6 +3,11 @@
|
||||
menu "PCI controller drivers"
|
||||
depends on PCI
|
||||
|
||||
+config PCIE_BCM6328
|
||||
+ bool "BCM6328 PCIe controller"
|
||||
+ depends on BMIPS_GENERIC || COMPILE_TEST
|
||||
+ depends on OF
|
||||
+
|
||||
config PCI_MVEBU
|
||||
bool "Marvell EBU PCIe controller"
|
||||
depends on ARCH_MVEBU || ARCH_DOVE || COMPILE_TEST
|
||||
--- a/drivers/pci/controller/Makefile
|
||||
+++ b/drivers/pci/controller/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o
|
||||
obj-$(CONFIG_PCIE_CADENCE) += cadence/
|
||||
obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o
|
||||
obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
|
||||
@ -0,0 +1,22 @@
|
||||
--- a/drivers/pci/controller/Kconfig
|
||||
+++ b/drivers/pci/controller/Kconfig
|
||||
@@ -3,6 +3,11 @@
|
||||
menu "PCI controller drivers"
|
||||
depends on PCI
|
||||
|
||||
+config PCIE_BCM6318
|
||||
+ bool "BCM6318 PCIe controller"
|
||||
+ depends on BMIPS_GENERIC || COMPILE_TEST
|
||||
+ depends on OF
|
||||
+
|
||||
config PCIE_BCM6328
|
||||
bool "BCM6328 PCIe controller"
|
||||
depends on BMIPS_GENERIC || COMPILE_TEST
|
||||
--- a/drivers/pci/controller/Makefile
|
||||
+++ b/drivers/pci/controller/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_PCIE_BCM6318) += pcie-bcm6318.o
|
||||
obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o
|
||||
obj-$(CONFIG_PCIE_CADENCE) += cadence/
|
||||
obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o
|
||||
@ -0,0 +1,22 @@
|
||||
--- a/drivers/pci/controller/Kconfig
|
||||
+++ b/drivers/pci/controller/Kconfig
|
||||
@@ -3,6 +3,11 @@
|
||||
menu "PCI controller drivers"
|
||||
depends on PCI
|
||||
|
||||
+config PCI_BCM6348
|
||||
+ bool "BCM6348 PCI controller"
|
||||
+ depends on BMIPS_GENERIC || COMPILE_TEST
|
||||
+ depends on OF
|
||||
+
|
||||
config PCIE_BCM6318
|
||||
bool "BCM6318 PCIe controller"
|
||||
depends on BMIPS_GENERIC || COMPILE_TEST
|
||||
--- a/drivers/pci/controller/Makefile
|
||||
+++ b/drivers/pci/controller/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_PCI_BCM6348) += pci-bcm6348.o
|
||||
obj-$(CONFIG_PCIE_BCM6318) += pcie-bcm6318.o
|
||||
obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o
|
||||
obj-$(CONFIG_PCIE_CADENCE) += cadence/
|
||||
@ -0,0 +1,6 @@
|
||||
--- a/arch/mips/bmips/Makefile
|
||||
+++ b/arch/mips/bmips/Makefile
|
||||
@@ -1,2 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-y += setup.o irq.o dma.o
|
||||
+obj-y += ath9k-fixup.o b43-sprom.o
|
||||
@ -25,7 +25,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2030,7 +2030,9 @@ static void dsa_slave_switchdev_event_wo
|
||||
@@ -2075,7 +2075,9 @@ static void dsa_slave_switchdev_event_wo
|
||||
|
||||
err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid);
|
||||
if (err) {
|
||||
@ -36,7 +36,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
break;
|
||||
}
|
||||
fdb_info->offloaded = true;
|
||||
@@ -2045,9 +2047,11 @@ static void dsa_slave_switchdev_event_wo
|
||||
@@ -2090,9 +2092,11 @@ static void dsa_slave_switchdev_event_wo
|
||||
|
||||
err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid);
|
||||
if (err) {
|
||||
|
||||
@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
struct sk_buff * (*xmit)(struct sk_buff *skb,
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2005,76 +2005,66 @@ static int dsa_slave_netdevice_event(str
|
||||
@@ -2050,76 +2050,66 @@ static int dsa_slave_netdevice_event(str
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
}
|
||||
|
||||
/* Called under rcu_read_lock() */
|
||||
@@ -2082,7 +2072,9 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2127,7 +2117,9 @@ static int dsa_slave_switchdev_event(str
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
|
||||
@ -177,7 +177,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
int err;
|
||||
|
||||
if (event == SWITCHDEV_PORT_ATTR_SET) {
|
||||
@@ -2095,20 +2087,32 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2140,20 +2132,32 @@ static int dsa_slave_switchdev_event(str
|
||||
if (!dsa_slave_dev_check(dev))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
@ -213,7 +213,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
dev_hold(dev);
|
||||
break;
|
||||
default:
|
||||
@@ -2118,10 +2122,6 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2163,10 +2167,6 @@ static int dsa_slave_switchdev_event(str
|
||||
|
||||
dsa_schedule_work(&switchdev_work->work);
|
||||
return NOTIFY_OK;
|
||||
|
||||
@ -20,7 +20,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2077,31 +2077,29 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2122,31 +2122,29 @@ static int dsa_slave_switchdev_event(str
|
||||
struct dsa_port *dp;
|
||||
int err;
|
||||
|
||||
@ -68,7 +68,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
fdb_info = ptr;
|
||||
|
||||
if (!fdb_info->added_by_user) {
|
||||
@@ -2114,13 +2112,12 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2159,13 +2157,12 @@ static int dsa_slave_switchdev_event(str
|
||||
switchdev_work->vid = fdb_info->vid;
|
||||
|
||||
dev_hold(dev);
|
||||
|
||||
@ -30,7 +30,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2090,6 +2090,9 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2135,6 +2135,9 @@ static int dsa_slave_switchdev_event(str
|
||||
|
||||
dp = dsa_slave_to_port(dev);
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
*/
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2067,6 +2067,28 @@ static void dsa_slave_switchdev_event_wo
|
||||
@@ -2112,6 +2112,28 @@ static void dsa_slave_switchdev_event_wo
|
||||
dev_put(dp->slave);
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
/* Called under rcu_read_lock() */
|
||||
static int dsa_slave_switchdev_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr)
|
||||
@@ -2085,10 +2107,37 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2130,10 +2152,37 @@ static int dsa_slave_switchdev_event(str
|
||||
return notifier_from_errno(err);
|
||||
case SWITCHDEV_FDB_ADD_TO_DEVICE:
|
||||
case SWITCHDEV_FDB_DEL_TO_DEVICE:
|
||||
@ -240,7 +240,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del)
|
||||
return NOTIFY_DONE;
|
||||
@@ -2103,18 +2152,13 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2148,18 +2197,13 @@ static int dsa_slave_switchdev_event(str
|
||||
switchdev_work->port = dp->index;
|
||||
switchdev_work->event = event;
|
||||
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
From 2d5ba37461013253d2ff0a3641b727fd32ea97a9 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Fainelli <florian@openwrt.org>
|
||||
Subject: USB: EHCI: add ignore_oc flag to disable overcurrent checking
|
||||
Date: Tue, 23 Feb 2021 18:44:53 +0100
|
||||
Subject: [PATCH 1/3] usb: ehci: add spurious flag to disable overcurrent
|
||||
checking
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch adds an ignore_oc flag which can be set by EHCI controller
|
||||
not supporting or wanting to disable overcurrent checking. The EHCI
|
||||
@ -7,13 +13,16 @@ platform data in include/linux/usb/ehci_pdriver.h is also augmented to
|
||||
take advantage of this new flag.
|
||||
|
||||
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20210223174455.1378-2-noltari@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ehci-hcd.c | 2 +-
|
||||
drivers/usb/host/ehci-hub.c | 4 ++--
|
||||
drivers/usb/host/ehci-platform.c | 1 +
|
||||
drivers/usb/host/ehci.h | 1 +
|
||||
include/linux/usb/ehci_pdriver.h | 1 +
|
||||
5 files changed, 6 insertions(+), 3 deletions(-)
|
||||
drivers/usb/host/ehci-hcd.c | 2 +-
|
||||
drivers/usb/host/ehci-hub.c | 4 ++--
|
||||
drivers/usb/host/ehci-platform.c | 2 ++
|
||||
drivers/usb/host/ehci.h | 1 +
|
||||
include/linux/usb/ehci_pdriver.h | 1 +
|
||||
5 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/ehci-hcd.c
|
||||
+++ b/drivers/usb/host/ehci-hcd.c
|
||||
@ -22,7 +31,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
|
||||
temp >> 8, temp & 0xff,
|
||||
- ignore_oc ? ", overcurrent ignored" : "");
|
||||
+ (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : "");
|
||||
+ (ignore_oc || ehci->spurious_oc) ? ", overcurrent ignored" : "");
|
||||
|
||||
ehci_writel(ehci, INTR_MASK,
|
||||
&ehci->regs->intr_enable); /* Turn On Interrupts */
|
||||
@ -33,7 +42,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
* PORT_POWER; that's surprising, but maybe within-spec.
|
||||
*/
|
||||
- if (!ignore_oc)
|
||||
+ if (!ignore_oc && !ehci->ignore_oc)
|
||||
+ if (!ignore_oc && !ehci->spurious_oc)
|
||||
mask = PORT_CSC | PORT_PEC | PORT_OCC;
|
||||
else
|
||||
mask = PORT_CSC | PORT_PEC;
|
||||
@ -42,7 +51,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
status |= USB_PORT_STAT_C_ENABLE << 16;
|
||||
|
||||
- if ((temp & PORT_OCC) && !ignore_oc){
|
||||
+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){
|
||||
+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){
|
||||
status |= USB_PORT_STAT_C_OVERCURRENT << 16;
|
||||
|
||||
/*
|
||||
@ -52,8 +61,8 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
hcd->has_tt = 1;
|
||||
if (pdata->reset_on_resume)
|
||||
priv->reset_on_resume = true;
|
||||
+ if (pdata->ignore_oc)
|
||||
+ ehci->ignore_oc = 1;
|
||||
+ if (pdata->spurious_oc)
|
||||
+ ehci->spurious_oc = 1;
|
||||
|
||||
#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
|
||||
if (ehci->big_endian_mmio) {
|
||||
@ -63,7 +72,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
|
||||
unsigned need_oc_pp_cycle:1; /* MPC834X port power */
|
||||
unsigned imx28_write_fix:1; /* For Freescale i.MX28 */
|
||||
+ unsigned ignore_oc:1;
|
||||
+ unsigned spurious_oc:1;
|
||||
|
||||
/* required for usb32 quirk */
|
||||
#define OHCI_CTRL_HCFS (3 << 6)
|
||||
@ -73,7 +82,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
unsigned no_io_watchdog:1;
|
||||
unsigned reset_on_resume:1;
|
||||
unsigned dma_mask_64:1;
|
||||
+ unsigned ignore_oc:1;
|
||||
+ unsigned spurious_oc:1;
|
||||
|
||||
/* Turn on all power and clocks */
|
||||
int (*power_on)(struct platform_device *pdev);
|
||||
@ -0,0 +1,31 @@
|
||||
From 4da57dbbffdfa7fe4e2b70b047fc5ff95ff25a3d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
|
||||
Date: Tue, 23 Feb 2021 18:44:55 +0100
|
||||
Subject: [PATCH 3/3] usb: host: ehci-platform: add spurious_oc DT support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Over-current reporting isn't supported on some platforms such as bcm63xx.
|
||||
These devices will incorrectly report over-current if this flag isn't properly
|
||||
activated.
|
||||
|
||||
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20210223174455.1378-4-noltari@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ehci-platform.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/ehci-platform.c
|
||||
+++ b/drivers/usb/host/ehci-platform.c
|
||||
@@ -286,6 +286,9 @@ static int ehci_platform_probe(struct pl
|
||||
if (of_property_read_bool(dev->dev.of_node, "big-endian"))
|
||||
ehci->big_endian_mmio = ehci->big_endian_desc = 1;
|
||||
|
||||
+ if (of_property_read_bool(dev->dev.of_node, "spurious-oc"))
|
||||
+ ehci->spurious_oc = 1;
|
||||
+
|
||||
if (of_property_read_bool(dev->dev.of_node,
|
||||
"needs-reset-on-resume"))
|
||||
priv->reset_on_resume = true;
|
||||
@ -1,5 +1,11 @@
|
||||
From 2d5ba37461013253d2ff0a3641b727fd32ea97a9 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Fainelli <florian@openwrt.org>
|
||||
Subject: USB: EHCI: add ignore_oc flag to disable overcurrent checking
|
||||
Date: Tue, 23 Feb 2021 18:44:53 +0100
|
||||
Subject: [PATCH 1/3] usb: ehci: add spurious flag to disable overcurrent
|
||||
checking
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch adds an ignore_oc flag which can be set by EHCI controller
|
||||
not supporting or wanting to disable overcurrent checking. The EHCI
|
||||
@ -7,13 +13,16 @@ platform data in include/linux/usb/ehci_pdriver.h is also augmented to
|
||||
take advantage of this new flag.
|
||||
|
||||
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20210223174455.1378-2-noltari@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ehci-hcd.c | 2 +-
|
||||
drivers/usb/host/ehci-hub.c | 4 ++--
|
||||
drivers/usb/host/ehci-platform.c | 1 +
|
||||
drivers/usb/host/ehci.h | 1 +
|
||||
include/linux/usb/ehci_pdriver.h | 1 +
|
||||
5 files changed, 6 insertions(+), 3 deletions(-)
|
||||
drivers/usb/host/ehci-hcd.c | 2 +-
|
||||
drivers/usb/host/ehci-hub.c | 4 ++--
|
||||
drivers/usb/host/ehci-platform.c | 2 ++
|
||||
drivers/usb/host/ehci.h | 1 +
|
||||
include/linux/usb/ehci_pdriver.h | 1 +
|
||||
5 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/ehci-hcd.c
|
||||
+++ b/drivers/usb/host/ehci-hcd.c
|
||||
@ -22,7 +31,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
|
||||
temp >> 8, temp & 0xff,
|
||||
- ignore_oc ? ", overcurrent ignored" : "");
|
||||
+ (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : "");
|
||||
+ (ignore_oc || ehci->spurious_oc) ? ", overcurrent ignored" : "");
|
||||
|
||||
ehci_writel(ehci, INTR_MASK,
|
||||
&ehci->regs->intr_enable); /* Turn On Interrupts */
|
||||
@ -33,7 +42,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
* PORT_POWER; that's surprising, but maybe within-spec.
|
||||
*/
|
||||
- if (!ignore_oc)
|
||||
+ if (!ignore_oc && !ehci->ignore_oc)
|
||||
+ if (!ignore_oc && !ehci->spurious_oc)
|
||||
mask = PORT_CSC | PORT_PEC | PORT_OCC;
|
||||
else
|
||||
mask = PORT_CSC | PORT_PEC;
|
||||
@ -42,7 +51,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
status |= USB_PORT_STAT_C_ENABLE << 16;
|
||||
|
||||
- if ((temp & PORT_OCC) && !ignore_oc){
|
||||
+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){
|
||||
+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){
|
||||
status |= USB_PORT_STAT_C_OVERCURRENT << 16;
|
||||
|
||||
/*
|
||||
@ -52,8 +61,8 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
hcd->has_tt = 1;
|
||||
if (pdata->reset_on_resume)
|
||||
priv->reset_on_resume = true;
|
||||
+ if (pdata->ignore_oc)
|
||||
+ ehci->ignore_oc = 1;
|
||||
+ if (pdata->spurious_oc)
|
||||
+ ehci->spurious_oc = 1;
|
||||
|
||||
#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
|
||||
if (ehci->big_endian_mmio) {
|
||||
@ -63,7 +72,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
|
||||
unsigned need_oc_pp_cycle:1; /* MPC834X port power */
|
||||
unsigned imx28_write_fix:1; /* For Freescale i.MX28 */
|
||||
+ unsigned ignore_oc:1;
|
||||
+ unsigned spurious_oc:1;
|
||||
|
||||
/* required for usb32 quirk */
|
||||
#define OHCI_CTRL_HCFS (3 << 6)
|
||||
@ -73,7 +82,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
unsigned no_io_watchdog:1;
|
||||
unsigned reset_on_resume:1;
|
||||
unsigned dma_mask_64:1;
|
||||
+ unsigned ignore_oc:1;
|
||||
+ unsigned spurious_oc:1;
|
||||
|
||||
/* Turn on all power and clocks */
|
||||
int (*power_on)(struct platform_device *pdev);
|
||||
@ -0,0 +1,31 @@
|
||||
From 4da57dbbffdfa7fe4e2b70b047fc5ff95ff25a3d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
|
||||
Date: Tue, 23 Feb 2021 18:44:55 +0100
|
||||
Subject: [PATCH 3/3] usb: host: ehci-platform: add spurious_oc DT support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Over-current reporting isn't supported on some platforms such as bcm63xx.
|
||||
These devices will incorrectly report over-current if this flag isn't properly
|
||||
activated.
|
||||
|
||||
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20210223174455.1378-4-noltari@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ehci-platform.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/ehci-platform.c
|
||||
+++ b/drivers/usb/host/ehci-platform.c
|
||||
@@ -278,6 +278,9 @@ static int ehci_platform_probe(struct pl
|
||||
if (of_property_read_bool(dev->dev.of_node, "big-endian"))
|
||||
ehci->big_endian_mmio = ehci->big_endian_desc = 1;
|
||||
|
||||
+ if (of_property_read_bool(dev->dev.of_node, "spurious-oc"))
|
||||
+ ehci->spurious_oc = 1;
|
||||
+
|
||||
if (of_property_read_bool(dev->dev.of_node,
|
||||
"needs-reset-on-resume"))
|
||||
priv->reset_on_resume = true;
|
||||
@ -17,7 +17,7 @@
|
||||
#define je16_to_cpu(x) ((x).v16)
|
||||
#define je32_to_cpu(x) ((x).v32)
|
||||
|
||||
#define NR_PARTS 1
|
||||
#define NR_PARTS 2
|
||||
|
||||
static int mtdsplit_cfe_bootfs_parse(struct mtd_info *mtd,
|
||||
const struct mtd_partition **pparts,
|
||||
@ -58,12 +58,16 @@ static int mtdsplit_cfe_bootfs_parse(struct mtd_info *mtd,
|
||||
if (!parts)
|
||||
return -ENOMEM;
|
||||
|
||||
parts[0].name = "bootfs";
|
||||
parts[0].offset = 0;
|
||||
parts[0].size = rootfs_offset;
|
||||
|
||||
if (type == MTDSPLIT_PART_TYPE_UBI)
|
||||
parts[0].name = UBI_PART_NAME;
|
||||
parts[1].name = UBI_PART_NAME;
|
||||
else
|
||||
parts[0].name = ROOTFS_PART_NAME;
|
||||
parts[0].offset = rootfs_offset;
|
||||
parts[0].size = mtd->size - rootfs_offset;
|
||||
parts[1].name = ROOTFS_PART_NAME;
|
||||
parts[1].offset = rootfs_offset;
|
||||
parts[1].size = mtd->size - rootfs_offset;
|
||||
|
||||
*pparts = parts;
|
||||
|
||||
|
||||
@ -104,7 +104,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
config MODULES_TREE_LOOKUP
|
||||
--- a/kernel/module.c
|
||||
+++ b/kernel/module.c
|
||||
@@ -3161,9 +3161,11 @@ static int setup_load_info(struct load_i
|
||||
@@ -3243,9 +3243,11 @@ static int setup_load_info(struct load_i
|
||||
|
||||
static int check_modinfo(struct module *mod, struct load_info *info, int flags)
|
||||
{
|
||||
@ -117,7 +117,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (flags & MODULE_INIT_IGNORE_VERMAGIC)
|
||||
modmagic = NULL;
|
||||
|
||||
@@ -3184,6 +3186,7 @@ static int check_modinfo(struct module *
|
||||
@@ -3266,6 +3268,7 @@ static int check_modinfo(struct module *
|
||||
mod->name);
|
||||
add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/fs/locks.c
|
||||
+++ b/fs/locks.c
|
||||
@@ -2996,6 +2996,8 @@ static const struct seq_operations locks
|
||||
@@ -2993,6 +2993,8 @@ static const struct seq_operations locks
|
||||
|
||||
static int __init proc_locks_init(void)
|
||||
{
|
||||
|
||||
@ -71,7 +71,7 @@ Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
|
||||
|
||||
--- a/mm/page_alloc.c
|
||||
+++ b/mm/page_alloc.c
|
||||
@@ -6951,7 +6951,7 @@ static void __ref alloc_node_mem_map(str
|
||||
@@ -7026,7 +7026,7 @@ static void __ref alloc_node_mem_map(str
|
||||
if (pgdat == NODE_DATA(0)) {
|
||||
mem_map = NODE_DATA(0)->node_mem_map;
|
||||
if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
|
||||
|
||||
@ -28,7 +28,7 @@ Add .ndo_fill_forward_path for dsa slave port devices
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -1582,6 +1582,21 @@ static struct devlink_port *dsa_slave_ge
|
||||
@@ -1617,6 +1617,21 @@ static struct devlink_port *dsa_slave_ge
|
||||
return dp->ds->devlink ? &dp->devlink_port : NULL;
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ Add .ndo_fill_forward_path for dsa slave port devices
|
||||
static const struct net_device_ops dsa_slave_netdev_ops = {
|
||||
.ndo_open = dsa_slave_open,
|
||||
.ndo_stop = dsa_slave_close,
|
||||
@@ -1607,6 +1622,7 @@ static const struct net_device_ops dsa_s
|
||||
@@ -1642,6 +1657,7 @@ static const struct net_device_ops dsa_s
|
||||
.ndo_vlan_rx_kill_vid = dsa_slave_vlan_rx_kill_vid,
|
||||
.ndo_get_devlink_port = dsa_slave_get_devlink_port,
|
||||
.ndo_change_mtu = dsa_slave_change_mtu,
|
||||
|
||||
@ -17,7 +17,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -1202,14 +1202,32 @@ static int dsa_slave_setup_tc_block(stru
|
||||
@@ -1237,14 +1237,32 @@ static int dsa_slave_setup_tc_block(stru
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
|
||||
--- a/drivers/net/phy/phy_device.c
|
||||
+++ b/drivers/net/phy/phy_device.c
|
||||
@@ -1644,6 +1644,9 @@ void phy_detach(struct phy_device *phyde
|
||||
@@ -1642,6 +1642,9 @@ void phy_detach(struct phy_device *phyde
|
||||
struct module *ndev_owner = NULL;
|
||||
struct mii_bus *bus;
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2144,10 +2144,12 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2189,10 +2189,12 @@ static int dsa_slave_switchdev_event(str
|
||||
fdb_info = ptr;
|
||||
|
||||
if (dsa_slave_dev_check(dev)) {
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2158,7 +2158,11 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2203,7 +2203,11 @@ static int dsa_slave_switchdev_event(str
|
||||
struct net_device *br_dev;
|
||||
struct dsa_slave_priv *p;
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2151,9 +2151,12 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2196,9 +2196,12 @@ static int dsa_slave_switchdev_event(str
|
||||
else if (!fdb_info->added_by_user)
|
||||
return NOTIFY_OK;
|
||||
} else {
|
||||
@ -44,7 +44,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||
*/
|
||||
struct net_device *br_dev;
|
||||
struct dsa_slave_priv *p;
|
||||
@@ -2175,7 +2178,8 @@ static int dsa_slave_switchdev_event(str
|
||||
@@ -2220,7 +2223,8 @@ static int dsa_slave_switchdev_event(str
|
||||
|
||||
dp = p->dp->cpu_dp;
|
||||
|
||||
|
||||
@ -75,12 +75,17 @@ define Device/bananapi_bpi-r64
|
||||
DEVICE_DTS := mt7622-bananapi-bpi-r64
|
||||
DEVICE_DTS_OVERLAY := mt7622-bananapi-bpi-r64-pcie1 mt7622-bananapi-bpi-r64-sata
|
||||
DEVICE_PACKAGES := kmod-ata-ahci-mtk kmod-btmtkuart kmod-usb3 e2fsprogs mkf2fs f2fsck
|
||||
ARTIFACTS := sdcard.img
|
||||
ARTIFACTS := sdcard.img.gz
|
||||
IMAGES := sysupgrade.itb
|
||||
KERNEL_INITRAMFS_SUFFIX := -recovery.itb
|
||||
ARTIFACT/sdcard.img := mt7622-gpt sdmmc | pad-to 128k | mt7622-gpt emmc | pad-to 256k |\
|
||||
bl2 emmc-2ddr | pad-to 512k | bl2 sdmmc-2ddr | pad-to 1024k | bl31-uboot bananapi_bpi-r64-emmc | pad-to 2048k |\
|
||||
bl31-uboot bananapi_bpi-r64-sdmmc | pad-to 6144k
|
||||
ARTIFACT/sdcard.img.gz := mt7622-gpt sdmmc |\
|
||||
pad-to 128k | mt7622-gpt emmc |\
|
||||
pad-to 256k | bl2 emmc-2ddr |\
|
||||
pad-to 512k | bl2 sdmmc-2ddr |\
|
||||
pad-to 1024k | bl31-uboot bananapi_bpi-r64-emmc |\
|
||||
pad-to 2048k | bl31-uboot bananapi_bpi-r64-sdmmc |\
|
||||
pad-to 6144k | append-image initramfs-recovery.itb |\
|
||||
pad-to 40960k | append-image squashfs-sysupgrade.itb | gzip
|
||||
KERNEL := kernel-bin | gzip
|
||||
KERNEL_INITRAMFS := kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb with-initrd | pad-to 128k
|
||||
IMAGE/sysupgrade.itb := append-kernel | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb external-static-with-rootfs | append-metadata
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <25000000>;
|
||||
spi-max-frequency = <80000000>;
|
||||
m25p,fast-read;
|
||||
|
||||
partitions {
|
||||
|
||||
@ -33,7 +33,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
phy_led_trigger_change_speed(phydev);
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ int phy_start_cable_test(struct phy_devi
|
||||
@@ -618,7 +618,7 @@ int phy_start_cable_test(struct phy_devi
|
||||
goto out;
|
||||
|
||||
/* Mark the carrier down until the test is complete */
|
||||
@ -42,7 +42,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
|
||||
netif_testing_on(dev);
|
||||
err = phydev->drv->cable_test_start(phydev);
|
||||
@@ -687,7 +687,7 @@ int phy_start_cable_test_tdr(struct phy_
|
||||
@@ -689,7 +689,7 @@ int phy_start_cable_test_tdr(struct phy_
|
||||
goto out;
|
||||
|
||||
/* Mark the carrier down until the test is complete */
|
||||
@ -51,7 +51,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
|
||||
netif_testing_on(dev);
|
||||
err = phydev->drv->cable_test_tdr_start(phydev, config);
|
||||
@@ -758,7 +758,7 @@ static int phy_check_link_status(struct
|
||||
@@ -760,7 +760,7 @@ static int phy_check_link_status(struct
|
||||
phy_link_up(phydev);
|
||||
} else if (!phydev->link && phydev->state != PHY_NOLINK) {
|
||||
phydev->state = PHY_NOLINK;
|
||||
@ -60,7 +60,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1162,7 +1162,7 @@ void phy_state_machine(struct work_struc
|
||||
@@ -1164,7 +1164,7 @@ void phy_state_machine(struct work_struc
|
||||
case PHY_HALTED:
|
||||
if (phydev->link) {
|
||||
phydev->link = 0;
|
||||
@ -71,7 +71,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
break;
|
||||
--- a/drivers/net/phy/phy_device.c
|
||||
+++ b/drivers/net/phy/phy_device.c
|
||||
@@ -937,14 +937,16 @@ struct phy_device *phy_find_first(struct
|
||||
@@ -935,14 +935,16 @@ struct phy_device *phy_find_first(struct
|
||||
}
|
||||
EXPORT_SYMBOL(phy_find_first);
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
|
||||
--- a/drivers/net/phy/phy.c
|
||||
+++ b/drivers/net/phy/phy.c
|
||||
@@ -758,7 +758,10 @@ static int phy_check_link_status(struct
|
||||
@@ -760,7 +760,10 @@ static int phy_check_link_status(struct
|
||||
phy_link_up(phydev);
|
||||
} else if (!phydev->link && phydev->state != PHY_NOLINK) {
|
||||
phydev->state = PHY_NOLINK;
|
||||
@ -23,7 +23,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1162,7 +1165,10 @@ void phy_state_machine(struct work_struc
|
||||
@@ -1164,7 +1167,10 @@ void phy_state_machine(struct work_struc
|
||||
case PHY_HALTED:
|
||||
if (phydev->link) {
|
||||
phydev->link = 0;
|
||||
|
||||
@ -141,7 +141,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
{
|
||||
--- a/include/linux/gpio/consumer.h
|
||||
+++ b/include/linux/gpio/consumer.h
|
||||
@@ -713,6 +713,7 @@ static inline void devm_acpi_dev_remove_
|
||||
@@ -715,6 +715,7 @@ static inline void devm_acpi_dev_remove_
|
||||
|
||||
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
|
||||
|
||||
@ -149,7 +149,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||
int gpiod_export_link(struct device *dev, const char *name,
|
||||
struct gpio_desc *desc);
|
||||
@@ -720,6 +721,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||
@@ -722,6 +723,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||
|
||||
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@ include $(INCLUDE_DIR)/image.mk
|
||||
KERNEL_LOADADDR = 0x80000000
|
||||
KERNEL_ENTRY = 0x80000400
|
||||
|
||||
DEVICE_VARS += ZYXEL_VERS
|
||||
|
||||
define Build/zyxel-vers
|
||||
( echo VERS;\
|
||||
for hw in $(1); do\
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
--- a/arch/x86/kernel/reboot.c
|
||||
+++ b/arch/x86/kernel/reboot.c
|
||||
@@ -477,6 +477,16 @@ static const struct dmi_system_id reboot
|
||||
},
|
||||
},
|
||||
|
||||
+ /* PC Engines */
|
||||
+ { /* Handle problems with rebooting on PC Engines apu2 */
|
||||
+ .callback = set_pci_reboot,
|
||||
+ .ident = "PC Engines apu2",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BOARD_VENDOR, "PC Engines"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "apu2"),
|
||||
+ },
|
||||
+ },
|
||||
+
|
||||
/* Sony */
|
||||
{ /* Handle problems with rebooting on Sony VGN-Z540N */
|
||||
.callback = set_bios_reboot,
|
||||
@ -1,19 +0,0 @@
|
||||
--- a/arch/x86/kernel/reboot.c
|
||||
+++ b/arch/x86/kernel/reboot.c
|
||||
@@ -486,6 +486,16 @@ static const struct dmi_system_id reboot
|
||||
},
|
||||
},
|
||||
|
||||
+ /* PC Engines */
|
||||
+ { /* Handle problems with rebooting on PC Engines apu2 */
|
||||
+ .callback = set_pci_reboot,
|
||||
+ .ident = "PC Engines apu2",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BOARD_VENDOR, "PC Engines"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "apu2"),
|
||||
+ },
|
||||
+ },
|
||||
+
|
||||
/* Sony */
|
||||
{ /* Handle problems with rebooting on Sony VGN-Z540N */
|
||||
.callback = set_bios_reboot,
|
||||
@ -27,12 +27,26 @@
|
||||
#error "Unsupported endianness"
|
||||
#endif
|
||||
|
||||
#define WFI_VERSION 0x00005732
|
||||
#define WFI_VERSION_NAND_1MB_DATA 0x00005731
|
||||
|
||||
#define WFI_NOR_FLASH 1
|
||||
#define WFI_NAND16_FLASH 2
|
||||
#define WFI_NAND128_FLASH 3
|
||||
#define WFI_NAND256_FLASH 4
|
||||
#define WFI_NAND512_FLASH 5
|
||||
#define WFI_NAND1024_FLASH 6
|
||||
#define WFI_NAND2048_FLASH 7
|
||||
|
||||
#define WFI_FLAG_HAS_PMC 0x1
|
||||
#define WFI_FLAG_SUPPORTS_BTRM 0x2
|
||||
|
||||
struct bcm4908img_tail {
|
||||
uint32_t crc32;
|
||||
uint32_t unk1;
|
||||
uint32_t family;
|
||||
uint32_t unk2;
|
||||
uint32_t unk3;
|
||||
uint32_t version;
|
||||
uint32_t chip_id;
|
||||
uint32_t flash_type;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
char *pathname;
|
||||
@ -272,10 +286,10 @@ static ssize_t bcm4908img_create_align(FILE *trx, size_t cur_offset, size_t alig
|
||||
|
||||
static int bcm4908img_create(int argc, char **argv) {
|
||||
struct bcm4908img_tail tail = {
|
||||
.unk1 = cpu_to_le32(0x5732),
|
||||
.family = cpu_to_le32(0x4908),
|
||||
.unk2 = cpu_to_le32(0x03),
|
||||
.unk3 = cpu_to_le32(0x02),
|
||||
.version = cpu_to_le32(WFI_VERSION),
|
||||
.chip_id = cpu_to_le32(0x4908),
|
||||
.flash_type = cpu_to_le32(WFI_NAND128_FLASH),
|
||||
.flags = cpu_to_le32(WFI_FLAG_SUPPORTS_BTRM),
|
||||
};
|
||||
uint32_t crc32 = 0xffffffff;
|
||||
size_t cur_offset = 0;
|
||||
|
||||
@ -27,11 +27,11 @@
|
||||
#endif
|
||||
|
||||
struct bcm4908kernel_header {
|
||||
uint32_t unk1;
|
||||
uint32_t unk2;
|
||||
uint32_t length;
|
||||
uint32_t boot_load_addr; /* AKA la_address */
|
||||
uint32_t boot_addr; /* AKA la_entrypt */
|
||||
uint32_t data_len;
|
||||
uint8_t magic[4];
|
||||
uint32_t unused;
|
||||
uint32_t uncomplen; /* Empty for LZMA, used for LZ4 */
|
||||
};
|
||||
|
||||
static void usage() {
|
||||
@ -103,14 +103,14 @@ int main(int argc, char **argv) {
|
||||
length += bytes;
|
||||
}
|
||||
|
||||
header.unk1 = cpu_to_le32(0x00080000);
|
||||
header.unk2 = cpu_to_le32(0x00080000);
|
||||
header.length = cpu_to_le32(length);
|
||||
header.boot_load_addr = cpu_to_le32(0x00080000);
|
||||
header.boot_addr = cpu_to_le32(0x00080000);
|
||||
header.data_len = cpu_to_le32(length);
|
||||
header.magic[0] = 'B';
|
||||
header.magic[1] = 'R';
|
||||
header.magic[2] = 'C';
|
||||
header.magic[3] = 'M';
|
||||
header.unused = 0;
|
||||
header.uncomplen = 0;
|
||||
|
||||
fseek(out, 0, SEEK_SET);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user