From 8e2ab05000ab91daea63022665d2b0c86f5cba3c Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 25 May 2020 13:39:52 +0200 Subject: usb: xhci: Use only 32-bit accesses in xhci_writeq/xhci_readq There might be hardware configurations where 64-bit data accesses to XHCI registers are not supported properly. This patch removes the readq/writeq so always two 32-bit accesses are used to read/write 64-bit XHCI registers, similarly as it is done in Linux kernel. This patch fixes operation of the XHCI controller on RPI4 Broadcom BCM2711 SoC based board, where the VL805 USB XHCI controller is connected to the PCIe Root Complex, which is attached to the system through the SCB bridge. Even though the architecture is 64-bit the PCIe BAR is 32-bit and likely the 64-bit wide register accesses initiated by the CPU are not properly translated to a sequence of 32-bit PCIe accesses. xhci_readq(), for example, always returns same value in upper and lower 32-bits, e.g. 0xabcd1234abcd1234 instead of 0x00000000abcd1234. Cc: Sergey Temerkhanov Signed-off-by: Sylwester Nawrocki Reviewed-by: Bin Meng Reviewed-by: Nicolas Saenz Julienne Signed-off-by: Matthias Brugger --- include/usb/xhci.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include') diff --git a/include/usb/xhci.h b/include/usb/xhci.h index 20e4a21066..1170c0ac69 100644 --- a/include/usb/xhci.h +++ b/include/usb/xhci.h @@ -1114,28 +1114,20 @@ static inline void xhci_writel(uint32_t volatile *regs, const unsigned int val) */ static inline u64 xhci_readq(__le64 volatile *regs) { -#if BITS_PER_LONG == 64 - return readq(regs); -#else __u32 *ptr = (__u32 *)regs; u64 val_lo = readl(ptr); u64 val_hi = readl(ptr + 1); return val_lo + (val_hi << 32); -#endif } static inline void xhci_writeq(__le64 volatile *regs, const u64 val) { -#if BITS_PER_LONG == 64 - writeq(val, regs); -#else __u32 *ptr = (__u32 *)regs; u32 val_lo = lower_32_bits(val); /* FIXME */ u32 val_hi = upper_32_bits(val); writel(val_lo, ptr); writel(val_hi, ptr + 1); -#endif } int xhci_hcd_init(int index, struct xhci_hccr **ret_hccr, -- cgit From b6687e19f9d3fdd33e76991df3dfcba60961ce35 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 25 May 2020 13:39:53 +0200 Subject: pci: Move some PCIe register offset definitions to a common header Some PCI Express register offsets are currently defined in multiple drivers, move them to a common header to avoid re-definitions and as a pre-requisite for adding new PCIe driver. While at it replace some spaces with tabs. Signed-off-by: Sylwester Nawrocki Reviewed-by: Bin Meng Reviewed-by: Nicolas Saenz Julienne Signed-off-by: Matthias Brugger --- include/pci.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/pci.h b/include/pci.h index 19c9244b94..9cd8564436 100644 --- a/include/pci.h +++ b/include/pci.h @@ -471,10 +471,19 @@ #define PCI_EA_FIELD_MASK 0xfffffffc /* For Base & Max Offset */ /* PCI Express capabilities */ +#define PCI_EXP_FLAGS 2 /* Capabilities register */ +#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */ +#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */ #define PCI_EXP_DEVCAP 4 /* Device capabilities */ -#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ +#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ #define PCI_EXP_DEVCTL 8 /* Device Control */ -#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ +#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ +#define PCI_EXP_LNKCAP 12 /* Link Capabilities */ +#define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */ +#define PCI_EXP_LNKSTA 18 /* Link Status */ +#define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ +#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ +#define PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */ /* Include the ID list */ -- cgit From c92921bb52a7e104e0a48740d518c41ec4c86097 Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Mon, 25 May 2020 13:39:56 +0200 Subject: linux/bitfield.h: Add primitives for manipulating bitfields both in host- and fixed-endian Imports Al Viro's original Linux commit 00b0c9b82663a, which contains an in depth explanation and two fixes from Johannes Berg: e7d4a95da86e0 "bitfield: fix *_encode_bits()", 37a3862e12382 "bitfield: add u8 helpers". Signed-off-by: Nicolas Saenz Julienne [s.nawrocki: added empty lines between functions and macros] Signed-off-by: Sylwester Nawrocki [mb: squash fix including byteorder.h] Signed-off-by: Matthias Brugger --- include/linux/bitfield.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'include') diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 8b9d6fff00..7ad02f8cbb 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h @@ -16,6 +16,7 @@ #define _LINUX_BITFIELD_H #include +#include /* * Bitfield access macros @@ -103,4 +104,56 @@ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ }) +extern void __compiletime_error("value doesn't fit into mask") +__field_overflow(void); +extern void __compiletime_error("bad bitfield mask") +__bad_mask(void); + +static __always_inline u64 field_multiplier(u64 field) +{ + if ((field | (field - 1)) & ((field | (field - 1)) + 1)) + __bad_mask(); + return field & -field; +} + +static __always_inline u64 field_mask(u64 field) +{ + return field / field_multiplier(field); +} + +#define ____MAKE_OP(type, base, to, from) \ +static __always_inline __##type type##_encode_bits(base v, base field) \ +{ \ + if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ + __field_overflow(); \ + return to((v & field_mask(field)) * field_multiplier(field)); \ +} \ +static __always_inline __##type type##_replace_bits(__##type old, \ + base val, base field) \ +{ \ + return (old & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static __always_inline void type##p_replace_bits(__##type * p, \ + base val, base field) \ +{ \ + *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static __always_inline base type##_get_bits(__##type v, base field) \ +{ \ + return (from(v) & field) / field_multiplier(field); \ +} + +#define __MAKE_OP(size) \ + ____MAKE_OP(le##size, u##size, cpu_to_le##size, le##size##_to_cpu) \ + ____MAKE_OP(be##size, u##size, cpu_to_be##size, be##size##_to_cpu) \ + ____MAKE_OP(u##size, u##size, ,) + +____MAKE_OP(u8, u8, ,) +__MAKE_OP(16) +__MAKE_OP(32) +__MAKE_OP(64) + +#undef __MAKE_OP +#undef ____MAKE_OP + #endif -- cgit From db75485f5c1e09e8571bdf15a6e15a8b62696d76 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 25 May 2020 13:39:57 +0200 Subject: pci: Add some PCI Express capability register offset definitions Add PCI Express capability definitions required by the Broadcom STB PCIe controller driver. Signed-off-by: Sylwester Nawrocki Reviewed-by: Bin Meng Reviewed-by: Nicolas Saenz Julienne Signed-off-by: Matthias Brugger --- include/pci.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/pci.h b/include/pci.h index 9cd8564436..281f353916 100644 --- a/include/pci.h +++ b/include/pci.h @@ -479,11 +479,20 @@ #define PCI_EXP_DEVCTL 8 /* Device Control */ #define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ +#define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ +#define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ #define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */ #define PCI_EXP_LNKSTA 18 /* Link Status */ +#define PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */ +#define PCI_EXP_LNKSTA_CLS_2_5GB 0x0001 /* Current Link Speed 2.5GT/s */ +#define PCI_EXP_LNKSTA_CLS_5_0GB 0x0002 /* Current Link Speed 5.0GT/s */ +#define PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 /* Current Link Speed 8.0GT/s */ +#define PCI_EXP_LNKSTA_NLW 0x03f0 /* Negotiated Link Width */ +#define PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */ #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ #define PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */ +#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ /* Include the ID list */ -- cgit From f676eb217bdff3bd734a42c8f9bbc58c9100055c Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Mon, 29 Jun 2020 18:37:23 +0200 Subject: reset: Add Raspberry Pi 4 firmware reset controller Raspberry Pi 4's co-processor controls some of the board's HW initialization process, but it's up to Linux to trigger it when relevant. Introduce a reset controller capable of interfacing with RPi4's co-processor that models these firmware initialization routines as reset lines. Signed-off-by: Nicolas Saenz Julienne Signed-off-by: Matthias Brugger --- include/dt-bindings/reset/raspberrypi,firmware-reset.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 include/dt-bindings/reset/raspberrypi,firmware-reset.h (limited to 'include') diff --git a/include/dt-bindings/reset/raspberrypi,firmware-reset.h b/include/dt-bindings/reset/raspberrypi,firmware-reset.h new file mode 100644 index 0000000000..1a4f4c7927 --- /dev/null +++ b/include/dt-bindings/reset/raspberrypi,firmware-reset.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Nicolas Saenz Julienne + * Author: Nicolas Saenz Julienne + */ + +#ifndef _DT_BINDINGS_RASPBERRYPI_FIRMWARE_RESET_H +#define _DT_BINDINGS_RASPBERRYPI_FIRMWARE_RESET_H + +#define RASPBERRYPI_FIRMWARE_RESET_ID_USB 0 +#define RASPBERRYPI_FIRMWARE_RESET_NUM_IDS 1 + +#endif -- cgit From 0b80371b350e6732a02d5e39bf900413ae1271ba Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Mon, 29 Jun 2020 18:37:25 +0200 Subject: usb: xhci: Add reset controller support Some atypical users of xhci might need to manually reset their xHCI controller before starting the HCD setup. Check if a reset controller device is available to the PCI bus and trigger a reset. Signed-off-by: Nicolas Saenz Julienne [mb: squash fix to only build xhci_reset_hw() if CONFIG_DM_BUS] Signed-off-by: Matthias Brugger --- include/usb/xhci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/usb/xhci.h b/include/usb/xhci.h index 1170c0ac69..7d34103fd5 100644 --- a/include/usb/xhci.h +++ b/include/usb/xhci.h @@ -16,6 +16,7 @@ #ifndef HOST_XHCI_H_ #define HOST_XHCI_H_ +#include #include #include #include @@ -1209,6 +1210,7 @@ struct xhci_ctrl { #if CONFIG_IS_ENABLED(DM_USB) struct udevice *dev; #endif + struct reset_ctl reset; struct xhci_hccr *hccr; /* R/O registers, not need for volatile */ struct xhci_hcor *hcor; struct xhci_doorbell_array *dba; -- cgit