Skip to content

Commit 53adf46

Browse files
committed
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 <[email protected]>
1 parent a108c7b commit 53adf46

1 file changed

Lines changed: 41 additions & 12 deletions

File tree

drivers/bluetooth/hci_bcm4377.c

Lines changed: 41 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 1000
3638

@@ -506,6 +508,7 @@ struct bcm4377_hw {
506508
u32 bar0_window1;
507509
u32 bar0_window2;
508510
u32 bar0_core2_window2;
511+
u32 bar2_offset;
509512

510513
unsigned long has_bar0_core2_window2 : 1;
511514
unsigned long clear_pciecfg_subsystem_ctrl_bit19 : 1;
@@ -830,8 +833,8 @@ static irqreturn_t bcm4377_irq(int irq, void *data)
830833
struct bcm4377_data *bcm4377 = data;
831834
u32 bootstage, rti_status;
832835

833-
bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE);
834-
rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS);
836+
bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE);
837+
rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS);
835838

836839
if (bootstage != bcm4377->bootstage ||
837840
rti_status != bcm4377->rti_status) {
@@ -1191,6 +1194,14 @@ static int bcm4387_send_calibration(struct bcm4377_data *bcm4377)
11911194
bcm4377->taurus_cal_size);
11921195
}
11931196

1197+
static int bcm4388_send_calibration(struct bcm4377_data *bcm4377)
1198+
{
1199+
/* Guess that these always use beamforming */
1200+
return __bcm4378_send_calibration(
1201+
bcm4377, bcm4377->taurus_beamforming_cal_blob,
1202+
bcm4377->taurus_beamforming_cal_size);
1203+
}
1204+
11941205
static const struct firmware *bcm4377_request_blob(struct bcm4377_data *bcm4377,
11951206
const char *suffix)
11961207
{
@@ -1814,8 +1825,8 @@ static int bcm4377_boot(struct bcm4377_data *bcm4377)
18141825
int ret = 0;
18151826
u32 bootstage, rti_status;
18161827

1817-
bootstage = ioread32(bcm4377->bar2 + BCM4377_BAR2_BOOTSTAGE);
1818-
rti_status = ioread32(bcm4377->bar2 + BCM4377_BAR2_RTI_STATUS);
1828+
bootstage = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_BOOTSTAGE);
1829+
rti_status = ioread32(bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_STATUS);
18191830

18201831
if (bootstage != 0) {
18211832
dev_err(&bcm4377->pdev->dev, "bootstage is %d and not 0\n",
@@ -1849,9 +1860,12 @@ static int bcm4377_boot(struct bcm4377_data *bcm4377)
18491860
iowrite32(BCM4377_DMA_MASK,
18501861
bcm4377->bar0 + BCM4377_BAR0_HOST_WINDOW_SIZE);
18511862

1852-
iowrite32(lower_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_LO);
1853-
iowrite32(upper_32_bits(fw_dma), bcm4377->bar2 + BCM4377_BAR2_FW_HI);
1854-
iowrite32(fw->size, bcm4377->bar2 + BCM4377_BAR2_FW_SIZE);
1863+
iowrite32(lower_32_bits(fw_dma),
1864+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_LO);
1865+
iowrite32(upper_32_bits(fw_dma),
1866+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_HI);
1867+
iowrite32(fw->size,
1868+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_FW_SIZE);
18551869
iowrite32(0, bcm4377->bar0 + BCM4377_BAR0_FW_DOORBELL);
18561870

18571871
dev_dbg(&bcm4377->pdev->dev, "waiting for firmware to boot\n");
@@ -1908,16 +1922,16 @@ static int bcm4377_setup_rti(struct bcm4377_data *bcm4377)
19081922
dev_dbg(&bcm4377->pdev->dev, "RTI is in state 1\n");
19091923

19101924
/* allow access to the entire IOVA space again */
1911-
iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_LO);
1912-
iowrite32(0, bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_HI);
1925+
iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_LO);
1926+
iowrite32(0, bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_HI);
19131927
iowrite32(BCM4377_DMA_MASK,
1914-
bcm4377->bar2 + BCM4377_BAR2_RTI_WINDOW_SIZE);
1928+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_RTI_WINDOW_SIZE);
19151929

19161930
/* setup "Converged IPC" context */
19171931
iowrite32(lower_32_bits(bcm4377->ctx_dma),
1918-
bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_LO);
1932+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_LO);
19191933
iowrite32(upper_32_bits(bcm4377->ctx_dma),
1920-
bcm4377->bar2 + BCM4377_BAR2_CONTEXT_ADDR_HI);
1934+
bcm4377->bar2 + bcm4377->hw->bar2_offset + BCM4377_BAR2_CONTEXT_ADDR_HI);
19211935
iowrite32(2, bcm4377->bar0 + BCM4377_BAR0_RTI_CONTROL);
19221936

19231937
ret = wait_for_completion_interruptible_timeout(&bcm4377->event,
@@ -2482,6 +2496,20 @@ static const struct bcm4377_hw bcm4377_hw_variants[] = {
24822496
.send_calibration = bcm4387_send_calibration,
24832497
.send_ptb = bcm4378_send_ptb,
24842498
},
2499+
2500+
[BCM4388] = {
2501+
.id = 0x4388,
2502+
.otp_offset = 0x415c,
2503+
.bar2_offset = 0x200000,
2504+
.bar0_window1 = 0x18002000,
2505+
.bar0_window2 = 0x18109000,
2506+
.bar0_core2_window2 = 0x18106000,
2507+
.has_bar0_core2_window2 = true,
2508+
.broken_mws_transport_config = true,
2509+
.broken_le_coded = true,
2510+
.send_calibration = bcm4388_send_calibration,
2511+
.send_ptb = bcm4378_send_ptb,
2512+
},
24852513
};
24862514

24872515
#define BCM4377_DEVID_ENTRY(id) \
@@ -2495,6 +2523,7 @@ static const struct pci_device_id bcm4377_devid_table[] = {
24952523
BCM4377_DEVID_ENTRY(4377),
24962524
BCM4377_DEVID_ENTRY(4378),
24972525
BCM4377_DEVID_ENTRY(4387),
2526+
BCM4377_DEVID_ENTRY(4388),
24982527
{},
24992528
};
25002529
MODULE_DEVICE_TABLE(pci, bcm4377_devid_table);

0 commit comments

Comments
 (0)