Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: hci_bcm4377: Add BCM4388 support

This new variant needs a different core2_window1 and always uses
beamforming.
The BAR2 also has an offset (RAM start, presumably), so add that.

Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Sven Peter <sven@svenpeter.dev>
[sven: rebased, updated some comments, mentioned 4388 in Kconfig]
Signed-off-by: Sven Peter <sven@svenpeter.dev>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Hector Martin and committed by
Luiz Augusto von Dentz
08c22b52 f25b7fd3

+50 -17
+3 -3
drivers/bluetooth/Kconfig
··· 287 287 288 288 289 289 config BT_HCIBCM4377 290 - tristate "HCI BCM4377/4378/4387 PCIe driver" 290 + tristate "HCI BCM4377/4378/4387/4388 PCIe driver" 291 291 depends on PCI 292 292 select FW_LOADER 293 293 help 294 - Support for Broadcom BCM4377/4378/4387 Bluetooth chipsets attached via 295 - PCIe. These are usually found in Apple machines. 294 + Support for Broadcom BCM4377/4378/4387/4388 Bluetooth chipsets 295 + attached via PCIe. These are usually found in Apple machines. 296 296 297 297 Say Y here to compile support for HCI BCM4377 family devices into the 298 298 kernel or say M to compile it as module (hci_bcm4377).
+47 -14
drivers/bluetooth/hci_bcm4377.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 2 /* 3 - * Bluetooth HCI driver for Broadcom 4377/4378/4387 devices attached via PCIe 3 + * Bluetooth HCI driver for Broadcom 4377/4378/4387/4388 devices attached via PCIe 4 4 * 5 5 * Copyright (C) The Asahi Linux Contributors 6 6 */ ··· 26 26 BCM4377 = 0, 27 27 BCM4378, 28 28 BCM4387, 29 + BCM4388, 29 30 }; 30 31 31 32 #define BCM4377_DEVICE_ID 0x5fa0 32 33 #define BCM4378_DEVICE_ID 0x5f69 33 34 #define BCM4387_DEVICE_ID 0x5f71 35 + #define BCM4388_DEVICE_ID 0x5f72 34 36 35 37 #define BCM4377_TIMEOUT msecs_to_jiffies(1000) 36 38 #define BCM4377_BOOT_TIMEOUT msecs_to_jiffies(5000) ··· 490 488 * second window in BAR0 491 489 * has_bar0_core2_window2: Set to true if this chip requires the second core's 492 490 * second window to be configured 491 + * bar2_offset: Offset to the start of the variables in BAR2 493 492 * clear_pciecfg_subsystem_ctrl_bit19: Set to true if bit 19 in the 494 493 * vendor-specific subsystem control 495 494 * register has to be cleared ··· 514 511 u32 bar0_window1; 515 512 u32 bar0_window2; 516 513 u32 bar0_core2_window2; 514 + u32 bar2_offset; 517 515 518 516 unsigned long has_bar0_core2_window2 : 1; 519 517 unsigned long clear_pciecfg_subsystem_ctrl_bit19 : 1; ··· 840 836 struct bcm4377_data *bcm4377 = data; 841 837 u32 bootstage, rti_status; 842 838 843 - bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE); 844 - rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS); 839 + bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE); 840 + rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS); 845 841 846 842 if (bootstage != bcm4377->bootstage || 847 843 rti_status != bcm4377->rti_status) { ··· 1199 1195 return __bcm4378_send_calibration(bcm4377, 1200 1196 bcm4377->taurus_cal_blob, 1201 1197 bcm4377->taurus_cal_size); 1198 + } 1199 + 1200 + static int bcm4388_send_calibration(struct bcm4377_data *bcm4377) 1201 + { 1202 + /* BCM4388 always uses beamforming */ 1203 + return __bcm4378_send_calibration( 1204 + bcm4377, bcm4377->taurus_beamforming_cal_blob, 1205 + bcm4377->taurus_beamforming_cal_size); 1202 1206 } 1203 1207 1204 1208 static const struct firmware *bcm4377_request_blob(struct bcm4377_data *bcm4377, ··· 1832 1820 int ret = 0; 1833 1821 u32 bootstage, rti_status; 1834 1822 1835 - bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE); 1836 - rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS); 1823 + bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE); 1824 + rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS); 1837 1825 1838 1826 if (bootstage != 0) { 1839 1827 dev_err(&bcm4377->pdev->dev, "bootstage is %d and not 0\n", ··· 1867 1855 iowrite32(BCM4377_DMA_MASK, 1868 1856 bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_SIZE); 1869 1857 1870 - iowrite32(lower_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_LO); 1871 - iowrite32(upper_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_HI); 1872 - iowrite32(fw->size, bcm4377->bar2 + BCM4377_BAR2_FW_SIZE); 1858 + iowrite32(lower_32_bits(fw_dma), 1859 + bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_LO); 1860 + iowrite32(upper_32_bits(fw_dma), 1861 + bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_HI); 1862 + iowrite32(fw->size, 1863 + bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_SIZE); 1873 1864 iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_FW_DOORBELL); 1874 1865 1875 1866 dev_dbg(&bcm4377->pdev->dev, "waiting for firmware to boot\n"); ··· 1929 1914 dev_dbg(&bcm4377->pdev->dev, "RTI is in state 1\n"); 1930 1915 1931 1916 /* allow access to the entire IOVA space again */ 1932 - iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_LO); 1933 - iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_HI); 1917 + iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_LO); 1918 + iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_HI); 1934 1919 iowrite32(BCM4377_DMA_MASK, 1935 - bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_SIZE); 1920 + bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_SIZE); 1936 1921 1937 1922 /* setup "Converged IPC" context */ 1938 1923 iowrite32(lower_32_bits(bcm4377->ctx_dma), 1939 - bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_LO); 1924 + bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_LO); 1940 1925 iowrite32(upper_32_bits(bcm4377->ctx_dma), 1941 - bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_HI); 1926 + bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_HI); 1942 1927 iowrite32(2, bcm4377->bar0 + BCM4377_BAR0_RTI_CONTROL); 1943 1928 1944 1929 ret = wait_for_completion_interruptible_timeout(&bcm4377->event, ··· 2504 2489 .send_calibration = bcm4387_send_calibration, 2505 2490 .send_ptb = bcm4378_send_ptb, 2506 2491 }, 2492 + 2493 + [BCM4388] = { 2494 + .id = 0x4388, 2495 + .otp_offset = 0x415c, 2496 + .bar2_offset = 0x200000, 2497 + .bar0_window1 = 0x18002000, 2498 + .bar0_window2 = 0x18109000, 2499 + .bar0_core2_window2 = 0x18106000, 2500 + .has_bar0_core2_window2 = true, 2501 + .broken_mws_transport_config = true, 2502 + .broken_le_coded = true, 2503 + .broken_le_ext_adv_report_phy = true, 2504 + .send_calibration = bcm4388_send_calibration, 2505 + .send_ptb = bcm4378_send_ptb, 2506 + }, 2507 2507 }; 2508 2508 2509 2509 #define BCM4377_DEVID_ENTRY(id) \ ··· 2532 2502 BCM4377_DEVID_ENTRY(4377), 2533 2503 BCM4377_DEVID_ENTRY(4378), 2534 2504 BCM4377_DEVID_ENTRY(4387), 2505 + BCM4377_DEVID_ENTRY(4388), 2535 2506 {}, 2536 2507 }; 2537 2508 MODULE_DEVICE_TABLE(pci, bcm4377_devid_table); ··· 2547 2516 module_pci_driver(bcm4377_pci_driver); 2548 2517 2549 2518 MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>"); 2550 - MODULE_DESCRIPTION("Bluetooth support for Broadcom 4377/4378/4387 devices"); 2519 + MODULE_DESCRIPTION("Bluetooth support for Broadcom 4377/4378/4387/4388 devices"); 2551 2520 MODULE_LICENSE("Dual MIT/GPL"); 2552 2521 MODULE_FIRMWARE("brcm/brcmbt4377*.bin"); 2553 2522 MODULE_FIRMWARE("brcm/brcmbt4377*.ptb"); ··· 2555 2524 MODULE_FIRMWARE("brcm/brcmbt4378*.ptb"); 2556 2525 MODULE_FIRMWARE("brcm/brcmbt4387*.bin"); 2557 2526 MODULE_FIRMWARE("brcm/brcmbt4387*.ptb"); 2527 + MODULE_FIRMWARE("brcm/brcmbt4388*.bin"); 2528 + MODULE_FIRMWARE("brcm/brcmbt4388*.ptb");