Compare commits

...

11 Commits

Author SHA1 Message Date
Phil Elwell
6a12ecfa52 configs: Add USB gadget support (for Zero 2 W)
Bring the Pi 3 kernel in line with the Pi Zero and Pi 4 by enabling
USB gadget support, which is useful on Zero 2 W.

See: https://github.com/raspberrypi/firmware/issues/1654

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
2021-12-01 14:53:56 +00:00
Phil Elwell
1e02427d49 brcmfmac: Protect against reprobing
It is important to reinitialise the firmware array pointers to protect
against the case that the brcmfmac driver is reprobed without first
being unloaded.

The potential hazard was noticed while investigating
https://github.com/raspberrypi/firmware/issues/1644 .

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
2021-12-01 14:53:56 +00:00
Phil Elwell
1646810b3c brcmfmac: Read alternative firmware names from DT
Add the ability to load the names of alternative firmwares from the
Device Tree node. This permits separate firmwares for 43436s and 43438
and allows downstream firmwares to coexist with upstream.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
2021-12-01 14:53:55 +00:00
Phil Elwell
82c23f9745 Revert "brcmfmac: BCM43436 needs dedicated firmware"
This reverts commit c52581ffa4.

Replace the hardcoded alternate firmware names with mappings provided
from Device Tree.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
2021-12-01 14:53:55 +00:00
Phil Elwell
a4fd51ecb7 ARM: dts: Provide WLAN firmware names for Zero 2 W
BCM43430/2 may be BCM43430B0 or BCM43436P, and BCM43430/1 can be either
BCM43430A1 or BCM43436S, the former being upstream names and the
latter downstream names for differently-sourced sister parts.

Make the choice of firmwares board-specific (without making the actual
firmwares board-specific) by placing the alternative firmware names for
each part in the DT node.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
2021-12-01 14:53:55 +00:00
Phil Elwell
4e66bf3cd6 ARM: dt: Add DT nodes for the WLAN interfaces
Mirror upstream changes into the downstream dts files.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
2021-12-01 14:53:55 +00:00
Phil Elwell
b40638d339 ARM: dts: Rename Zero 2 W DT files
Retain the old names for backwards compatibility for a while, while the
necessary firmware change rolls out.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
2021-12-01 14:53:55 +00:00
Phil Elwell
1a1dcc24e4 ARM: dts: Add Pi Zero 2 support
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
2021-12-01 14:53:55 +00:00
Dom Cobley
727ea5ce7d clk-bcm2835: Remove VEC clock support
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
2021-12-01 14:53:54 +00:00
Dom Cobley
1b5086ca6f dt: Move VEC clock to clk-raspberrypi
clk-2835 is deprecated and gets an innacurate clock for VEC (107MHz).
Switch to clk-raspberrypi which uses the right PLL to get an accurate 108MHz.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
2021-12-01 14:53:54 +00:00
Dom Cobley
7a3819e174 clk-raspberrypi: Support VEC clock
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
2021-12-01 14:53:54 +00:00
16 changed files with 336 additions and 23 deletions

View File

@@ -7,6 +7,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
bcm2708-rpi-cm.dtb \
bcm2708-rpi-zero.dtb \
bcm2708-rpi-zero-w.dtb \
bcm2710-rpi-zero-2.dtb \
bcm2710-rpi-zero-2-w.dtb \
bcm2709-rpi-2-b.dtb \
bcm2710-rpi-2-b.dtb \
bcm2710-rpi-3-b.dtb \

View File

@@ -83,6 +83,13 @@
pinctrl-0 = <&sdio_pins>;
bus-width = <4>;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
brcmf: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
};
};
&uart0 {

View File

@@ -84,6 +84,13 @@
pinctrl-0 = <&sdio_pins>;
bus-width = <4>;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
brcmf: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
};
};
&firmware {

View File

@@ -84,6 +84,13 @@
pinctrl-0 = <&sdio_pins>;
bus-width = <4>;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
brcmf: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
};
};
&soc {

View File

@@ -0,0 +1,197 @@
/dts-v1/;
#include "bcm2710.dtsi"
#include "bcm2709-rpi.dtsi"
#include "bcm283x-rpi-csi1-2lane.dtsi"
#include "bcm283x-rpi-i2c0mux_0_44.dtsi"
#include "bcm2708-rpi-bt.dtsi"
#include "bcm283x-rpi-cam1-regulator.dtsi"
/ {
compatible = "raspberrypi,model-zero-2-w", "brcm,bcm2837";
model = "Raspberry Pi Zero 2 W";
chosen {
bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1";
};
aliases {
serial0 = &uart1;
serial1 = &uart0;
mmc1 = &mmcnr;
};
};
&gpio {
spi0_pins: spi0_pins {
brcm,pins = <9 10 11>;
brcm,function = <4>; /* alt0 */
};
spi0_cs_pins: spi0_cs_pins {
brcm,pins = <8 7>;
brcm,function = <1>; /* output */
};
i2c0_pins: i2c0 {
brcm,pins = <0 1>;
brcm,function = <4>;
};
i2c1_pins: i2c1 {
brcm,pins = <2 3>;
brcm,function = <4>;
};
i2s_pins: i2s {
brcm,pins = <18 19 20 21>;
brcm,function = <4>; /* alt0 */
};
sdio_pins: sdio_pins {
brcm,pins = <34 35 36 37 38 39>;
brcm,function = <7>; // alt3 = SD1
brcm,pull = <0 2 2 2 2 2>;
};
bt_pins: bt_pins {
brcm,pins = <43>;
brcm,function = <4>; /* alt0:GPCLK2 */
brcm,pull = <0>;
};
uart0_pins: uart0_pins {
brcm,pins = <30 31 32 33>;
brcm,function = <7>; /* alt3=UART0 */
brcm,pull = <2 0 0 2>; /* up none none up */
};
uart1_pins: uart1_pins {
brcm,pins;
brcm,function;
brcm,pull;
};
audio_pins: audio_pins {
brcm,pins = <>;
brcm,function = <>;
};
};
&mmcnr {
pinctrl-names = "default";
pinctrl-0 = <&sdio_pins>;
bus-width = <4>;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
brcmf: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
firmwares {
fw_43436p {
chipid = <43430>;
revmask = <4>;
fw_base = "brcm/brcmfmac43436-sdio";
};
fw_43436s {
chipid = <43430>;
revmask = <2>;
fw_base = "brcm/brcmfmac43436s-sdio";
};
};
};
};
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins &bt_pins>;
status = "okay";
};
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins>;
status = "okay";
};
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
spidev0: spidev@0{
compatible = "spidev";
reg = <0>; /* CE0 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <125000000>;
};
spidev1: spidev@1{
compatible = "spidev";
reg = <1>; /* CE1 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <125000000>;
};
};
&i2c0if {
clock-frequency = <100000>;
};
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
clock-frequency = <100000>;
};
&i2c2 {
clock-frequency = <100000>;
};
&i2s {
pinctrl-names = "default";
pinctrl-0 = <&i2s_pins>;
};
&leds {
act_led: led-act {
label = "led0";
linux,default-trigger = "actpwr";
gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
};
};
&hdmi {
hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
&audio {
pinctrl-names = "default";
pinctrl-0 = <&audio_pins>;
brcm,disable-headphones = <1>;
};
&bt {
shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
};
&minibt {
shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
};
&cam1_reg {
gpio = <&gpio 40 GPIO_ACTIVE_HIGH>;
};
/ {
__overrides__ {
act_led_gpio = <&act_led>,"gpios:4";
act_led_activelow = <&act_led>,"gpios:8";
act_led_trigger = <&act_led>,"linux,default-trigger";
};
};

View File

@@ -0,0 +1 @@
#include "bcm2710-rpi-zero-2-w.dts"

View File

@@ -303,7 +303,7 @@
vec: vec@7ec13000 {
compatible = "brcm,bcm2711-vec";
reg = <0x7ec13000 0x1000>;
clocks = <&clocks BCM2835_CLOCK_VEC>;
clocks = <&firmware_clocks 15>;
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};

View File

@@ -109,7 +109,7 @@
vec: vec@7e806000 {
compatible = "brcm,bcm2835-vec";
reg = <0x7e806000 0x1000>;
clocks = <&clocks BCM2835_CLOCK_VEC>;
clocks = <&firmware_clocks 15>;
interrupts = <2 27>;
status = "disabled";
};

View File

@@ -1197,6 +1197,24 @@ CONFIG_USB_CXACRU=m
CONFIG_USB_UEAGLEATM=m
CONFIG_USB_XUSBATM=m
CONFIG_USB_GADGET=m
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
CONFIG_USB_CONFIGFS_ECM_SUBSET=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_LB_SS=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_UAC1=y
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_UVC=y
CONFIG_USB_CONFIGFS_F_PRINTER=y
CONFIG_USB_ZERO=m
CONFIG_USB_AUDIO=m
CONFIG_USB_ETH=m

View File

@@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-a-plus.dtb \
bcm2837-rpi-3-b.dtb \
bcm2837-rpi-3-b-plus.dtb \
bcm2837-rpi-cm3-io3.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-zero-2.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-2-b.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb

View File

@@ -0,0 +1 @@
#include "../../../../arm/boot/dts/bcm2710-rpi-zero-2.dts"

View File

@@ -2214,21 +2214,6 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.frac_bits = 12,
.tcnt_mux = 28),
/* TV encoder clock. Only operating frequency is 108Mhz. */
[BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
SOC_ALL,
.name = "vec",
.ctl_reg = CM_VECCTL,
.div_reg = CM_VECDIV,
.int_bits = 4,
.frac_bits = 0,
/*
* Allow rate change propagation only on PLLH_AUX which is
* assigned index 7 in the parent array.
*/
.set_rate_parent = BIT(7),
.tcnt_mux = 29),
/* dsi clocks */
[BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
SOC_ALL,

View File

@@ -33,6 +33,7 @@ enum rpi_firmware_clk_id {
RPI_FIRMWARE_EMMC2_CLK_ID,
RPI_FIRMWARE_M2MC_CLK_ID,
RPI_FIRMWARE_PIXEL_BVB_CLK_ID,
RPI_FIRMWARE_VEC_CLK_ID,
RPI_FIRMWARE_NUM_CLK_ID,
};
@@ -51,6 +52,7 @@ static char *rpi_firmware_clk_names[] = {
[RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2",
[RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc",
[RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb",
[RPI_FIRMWARE_VEC_CLK_ID] = "vec",
};
#define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
@@ -273,6 +275,7 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
case RPI_FIRMWARE_V3D_CLK_ID:
case RPI_FIRMWARE_HEVC_CLK_ID:
case RPI_FIRMWARE_PIXEL_BVB_CLK_ID:
case RPI_FIRMWARE_VEC_CLK_ID:
hw = raspberrypi_clk_register(rpi, clks->parent,
clks->id);
if (IS_ERR(hw))

View File

@@ -10,6 +10,7 @@
#include "debug.h"
#include "core.h"
#include "common.h"
#include "firmware.h"
#include "of.h"
void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
@@ -65,3 +66,38 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
sdio->oob_irq_nr = irq;
sdio->oob_irq_flags = irqf;
}
struct brcmf_firmware_mapping *
brcmf_of_fwnames(struct device *dev, u32 *fwname_count)
{
struct device_node *np = dev->of_node;
struct brcmf_firmware_mapping *fwnames;
struct device_node *map_np, *fw_np;
int of_count;
int count = 0;
map_np = of_get_child_by_name(np, "firmwares");
of_count = of_get_child_count(map_np);
if (!of_count)
return NULL;
fwnames = devm_kcalloc(dev, of_count,
sizeof(struct brcmf_firmware_mapping),
GFP_KERNEL);
for_each_child_of_node(map_np, fw_np)
{
struct brcmf_firmware_mapping *cur = &fwnames[count];
if (of_property_read_u32(fw_np, "chipid", &cur->chipid) ||
of_property_read_u32(fw_np, "revmask", &cur->revmask))
continue;
cur->fw_base = of_get_property(fw_np, "fw_base", NULL);
if (cur->fw_base)
count++;
}
*fwname_count = count;
return count ? fwnames : NULL;
}

View File

@@ -5,9 +5,16 @@
#ifdef CONFIG_OF
void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
struct brcmf_mp_device *settings);
struct brcmf_firmware_mapping *
brcmf_of_fwnames(struct device *dev, u32 *map_count);
#else
static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
struct brcmf_mp_device *settings)
{
}
static struct brcmf_firmware_mapping *
brcmf_of_fwnames(struct device *dev, u32 *map_count)
{
return NULL;
}
#endif /* CONFIG_OF */

View File

@@ -35,6 +35,7 @@
#include "core.h"
#include "common.h"
#include "bcdc.h"
#include "of.h"
#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
@@ -618,7 +619,6 @@ BRCMF_FW_DEF(4339, "brcmfmac4339-sdio");
BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
/* Note the names are not postfixed with a1 for backward compatibility */
BRCMF_FW_DEF(43430A1, "brcmfmac43430-sdio");
BRCMF_FW_DEF(43436, "brcmfmac43436-sdio");
BRCMF_FW_DEF(43455, "brcmfmac43455-sdio");
BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
BRCMF_FW_DEF(4354, "brcmfmac4354-sdio");
@@ -627,7 +627,7 @@ BRCMF_FW_DEF(4359, "brcmfmac4359-sdio");
BRCMF_FW_DEF(4373, "brcmfmac4373-sdio");
BRCMF_FW_DEF(43012, "brcmfmac43012-sdio");
static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
static const struct brcmf_firmware_mapping sdio_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0),
BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4),
@@ -641,8 +641,7 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0),
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFA, 43430A1),
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000004, 43436),
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1),
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456),
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455),
BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
@@ -652,6 +651,9 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
};
static const struct brcmf_firmware_mapping *brcmf_sdio_fwnames;
static u32 brcmf_sdio_fwnames_count;
#define TXCTL_CREDITS 2
static void pkt_align(struct sk_buff *p, int len, int align)
@@ -4137,7 +4139,7 @@ int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name,
}
fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
brcmf_sdio_fwnames,
ARRAY_SIZE(brcmf_sdio_fwnames),
brcmf_sdio_fwnames_count,
fwnames, ARRAY_SIZE(fwnames));
if (!fwreq)
return -ENOMEM;
@@ -4193,6 +4195,9 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
#define BRCMF_SDIO_FW_CODE 0
#define BRCMF_SDIO_FW_NVRAM 1
static struct brcmf_fw_request *
brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus);
static void brcmf_sdio_firmware_callback(struct device *dev, int err,
struct brcmf_fw_request *fwreq)
{
@@ -4208,6 +4213,22 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
if (err && brcmf_sdio_fwnames != sdio_fwnames) {
/* Try again with the standard firmware names */
brcmf_sdio_fwnames = sdio_fwnames;
brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames);
kfree(fwreq);
fwreq = brcmf_sdio_prepare_fw_request(bus);
if (!fwreq) {
err = -ENOMEM;
goto fail;
}
err = brcmf_fw_get_firmwares(dev, fwreq,
brcmf_sdio_firmware_callback);
if (!err)
return;
}
if (err)
goto fail;
@@ -4415,7 +4436,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev,
brcmf_sdio_fwnames,
ARRAY_SIZE(brcmf_sdio_fwnames),
brcmf_sdio_fwnames_count,
fwnames, ARRAY_SIZE(fwnames));
if (!fwreq)
return NULL;
@@ -4433,6 +4454,9 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
struct brcmf_sdio *bus;
struct workqueue_struct *wq;
struct brcmf_fw_request *fwreq;
struct brcmf_firmware_mapping *of_fwnames, *fwnames = NULL;
const int fwname_size = sizeof(struct brcmf_firmware_mapping);
u32 of_fw_count;
brcmf_dbg(TRACE, "Enter\n");
@@ -4515,6 +4539,23 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
brcmf_dbg(INFO, "completed!!\n");
brcmf_sdio_fwnames = sdio_fwnames;
brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames);
of_fwnames = brcmf_of_fwnames(sdiodev->dev, &of_fw_count);
if (of_fwnames)
fwnames = devm_kcalloc(sdiodev->dev,
of_fw_count + brcmf_sdio_fwnames_count,
fwname_size, GFP_KERNEL);
if (fwnames) {
/* The array is scanned in order, so overrides come first */
memcpy(fwnames, of_fwnames, of_fw_count * fwname_size);
memcpy(fwnames + of_fw_count, sdio_fwnames,
brcmf_sdio_fwnames_count * fwname_size);
brcmf_sdio_fwnames = fwnames;
brcmf_sdio_fwnames_count += of_fw_count;
}
fwreq = brcmf_sdio_prepare_fw_request(bus);
if (!fwreq) {
ret = -ENOMEM;