Skip to content

Commit 50771d6

Browse files
marcanjannau
authored andcommitted
Bluetooth: hci_bcm4377: Add BCM4388 support
This needs a different core2_window1. Guessing these newer chips always use beamforming (?). The BAR2 also has an offset (RAM start, presumably), so add that. Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent b51bc97 commit 50771d6

1 file changed

Lines changed: 42 additions & 12 deletions

File tree

drivers/bluetooth/hci_bcm4377.c

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ enum bcm4377_chip {
2626
BCM4377 = 0,
2727
BCM4378,
2828
BCM4387,
29+
BCM4388,
2930
};
3031

3132
#define BCM4377_DEVICE_ID 0x5fa0
3233
#define BCM4378_DEVICE_ID 0x5f69
3334
#define BCM4387_DEVICE_ID 0x5f71
35+
#define BCM4388_DEVICE_ID 0x5f72
3436

3537
#define BCM4377_TIMEOUT msecs_to_jiffies(1000)
3638
#define BCM4377_BOOT_TIMEOUT msecs_to_jiffies(5000)
@@ -511,6 +513,7 @@ struct bcm4377_hw {
511513
u32 bar0_window1;
512514
u32 bar0_window2;
513515
u32 bar0_core2_window2;
516+
u32 bar2_offset;
514517

515518
unsigned long has_bar0_core2_window2 : 1;
516519
unsigned long clear_pciecfg_subsystem_ctrl_bit19 : 1;
@@ -836,8 +839,8 @@ static irqreturn_t bcm4377_irq(int irq, void *data)
836839
struct bcm4377_data *bcm4377 = data;
837840
u32 bootstage, rti_status;
838841

839-
bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE);
840-
rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS);
842+
bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE);
843+
rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS);
841844

842845
if (bootstage != bcm4377->bootstage ||
843846
rti_status != bcm4377->rti_status) {
@@ -1197,6 +1200,14 @@ static int bcm4387_send_calibration(struct bcm4377_data *bcm4377)
11971200
bcm4377->taurus_cal_size);
11981201
}
11991202

1203+
static int bcm4388_send_calibration(struct bcm4377_data *bcm4377)
1204+
{
1205+
/* Guess that these always use beamforming */
1206+
return __bcm4378_send_calibration(
1207+
bcm4377, bcm4377->taurus_beamforming_cal_blob,
1208+
bcm4377->taurus_beamforming_cal_size);
1209+
}
1210+
12001211
static const struct firmware *bcm4377_request_blob(struct bcm4377_data *bcm4377,
12011212
const char *suffix)
12021213
{
@@ -1820,8 +1831,8 @@ static int bcm4377_boot(struct bcm4377_data *bcm4377)
18201831
int ret = 0;
18211832
u32 bootstage, rti_status;
18221833

1823-
bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE);
1824-
rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS);
1834+
bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE);
1835+
rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS);
18251836

18261837
if (bootstage != 0) {
18271838
dev_err(&bcm4377->pdev->dev, "bootstage is %d and not 0\n",
@@ -1855,9 +1866,12 @@ static int bcm4377_boot(struct bcm4377_data *bcm4377)
18551866
iowrite32(BCM4377_DMA_MASK,
18561867
bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_SIZE);
18571868

1858-
iowrite32(lower_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_LO);
1859-
iowrite32(upper_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_HI);
1860-
iowrite32(fw->size, bcm4377->bar2 + BCM4377_BAR2_FW_SIZE);
1869+
iowrite32(lower_32_bits(fw_dma),
1870+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_LO);
1871+
iowrite32(upper_32_bits(fw_dma),
1872+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_HI);
1873+
iowrite32(fw->size,
1874+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_SIZE);
18611875
iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_FW_DOORBELL);
18621876

18631877
dev_dbg(&bcm4377->pdev->dev, "waiting for firmware to boot\n");
@@ -1914,16 +1928,16 @@ static int bcm4377_setup_rti(struct bcm4377_data *bcm4377)
19141928
dev_dbg(&bcm4377->pdev->dev, "RTI is in state 1\n");
19151929

19161930
/* allow access to the entire IOVA space again */
1917-
iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_LO);
1918-
iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_HI);
1931+
iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_LO);
1932+
iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_HI);
19191933
iowrite32(BCM4377_DMA_MASK,
1920-
bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_SIZE);
1934+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_SIZE);
19211935

19221936
/* setup "Converged IPC" context */
19231937
iowrite32(lower_32_bits(bcm4377->ctx_dma),
1924-
bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_LO);
1938+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_LO);
19251939
iowrite32(upper_32_bits(bcm4377->ctx_dma),
1926-
bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_HI);
1940+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_HI);
19271941
iowrite32(2, bcm4377->bar0 + BCM4377_BAR0_RTI_CONTROL);
19281942

19291943
ret = wait_for_completion_interruptible_timeout(&bcm4377->event,
@@ -2489,6 +2503,21 @@ static const struct bcm4377_hw bcm4377_hw_variants[] = {
24892503
.send_calibration = bcm4387_send_calibration,
24902504
.send_ptb = bcm4378_send_ptb,
24912505
},
2506+
2507+
[BCM4388] = {
2508+
.id = 0x4388,
2509+
.otp_offset = 0x415c,
2510+
.bar2_offset = 0x200000,
2511+
.bar0_window1 = 0x18002000,
2512+
.bar0_window2 = 0x18109000,
2513+
.bar0_core2_window2 = 0x18106000,
2514+
.has_bar0_core2_window2 = true,
2515+
.broken_mws_transport_config = true,
2516+
.broken_le_coded = true,
2517+
.broken_le_ext_adv_report_phy = true,
2518+
.send_calibration = bcm4388_send_calibration,
2519+
.send_ptb = bcm4378_send_ptb,
2520+
},
24922521
};
24932522

24942523
#define BCM4377_DEVID_ENTRY(id) \
@@ -2502,6 +2531,7 @@ static const struct pci_device_id bcm4377_devid_table[] = {
25022531
BCM4377_DEVID_ENTRY(4377),
25032532
BCM4377_DEVID_ENTRY(4378),
25042533
BCM4377_DEVID_ENTRY(4387),
2534+
BCM4377_DEVID_ENTRY(4388),
25052535
{},
25062536
};
25072537
MODULE_DEVICE_TABLE(pci, bcm4377_devid_table);

0 commit comments

Comments
 (0)