From ff19be52ff0b8d348069fee132e9180e6ffb4fdc Mon Sep 17 00:00:00 2001 From: Nia Espera Date: Wed, 6 Sep 2023 08:36:48 +0200 Subject: [PATCH] UNFINISHED: bluetooth: Add support for qca6490 --- drivers/bluetooth/btqca.c | 3 + drivers/bluetooth/btqca.h | 1 + drivers/bluetooth/hci_qca.c | 50 ++++++- drivers/net/wireless/ath/ath11k/core.c | 197 ++++++++++++++++++------- drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/mhi.c | 1 + drivers/net/wireless/ath/ath11k/pci.c | 6 + drivers/net/wireless/ath/ath11k/pcic.c | 11 ++ 8 files changed, 208 insertions(+), 62 deletions(-) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index fdb0fae88d1c..b89060a315f0 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -687,6 +687,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, snprintf(config.fwname, sizeof(config.fwname), "qca/msbtfw%02x.mbn", rom_ver); break; + case QCA_QCA6490: case QCA_WCN6855: snprintf(config.fwname, sizeof(config.fwname), "qca/hpbtfw%02x.tlv", rom_ver); @@ -746,6 +747,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, snprintf(config.fwname, sizeof(config.fwname), "qca/msnv%02x.bin", rom_ver); break; + case QCA_QCA6490: case QCA_WCN6855: snprintf(config.fwname, sizeof(config.fwname), "qca/hpnv%02x.bin", rom_ver); @@ -771,6 +773,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, case QCA_WCN3991: case QCA_QCA2066: case QCA_QCA6390: + case QCA_QCA6490: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index dc31984f71dc..107fe8785316 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -150,6 +150,7 @@ enum qca_btsoc_type { QCA_WCN3991, QCA_QCA2066, QCA_QCA6390, + QCA_QCA6490, QCA_WCN6750, QCA_WCN6855, QCA_WCN7850, diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 067e248e3599..11df067f0f25 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -219,6 +219,7 @@ struct qca_power { struct qca_serdev { struct hci_uart serdev_hu; struct gpio_desc *bt_en; + struct gpio_desc *wl_en; struct gpio_desc *sw_ctrl; struct clk *susclk; enum qca_btsoc_type btsoc_type; @@ -1112,13 +1113,14 @@ static void qca_controller_memdump(struct work_struct *work) * the controller. In such cases let us store the dummy * packets in the buffer. */ - /* For QCA6390, controller does not lost packets but + /* For QCA6(3,4)90, controller does not lost packets but * sequence number field of packet sometimes has error * bits, so skip this checking for missing packet. */ while ((seq_no > qca_memdump->current_seq_no + 1) && - (soc_type != QCA_QCA6390) && - seq_no != QCA_LAST_SEQUENCE_NUM) { + (soc_type != QCA_QCA6390) && + (soc_type != QCA_QCA6490) && + seq_no != QCA_LAST_SEQUENCE_NUM) { bt_dev_err(hu->hdev, "QCA controller missed packet:%d", qca_memdump->current_seq_no); rx_size = qca_memdump->received_dump; @@ -1725,8 +1727,13 @@ static int qca_regulator_init(struct hci_uart *hu) if (qcadev->bt_en) { gpiod_set_value_cansleep(qcadev->bt_en, 0); msleep(50); + /* For qca6490 also need to enable wlan gpio */ + if (qcadev->wl_en) + gpiod_set_value_cansleep(qcadev->wl_en, 0); gpiod_set_value_cansleep(qcadev->bt_en, 1); msleep(50); + if (qcadev->wl_en) + gpiod_set_value_cansleep(qcadev->wl_en, 1); if (qcadev->sw_ctrl) { sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl); bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state); @@ -1788,6 +1795,7 @@ static int qca_power_on(struct hci_dev *hdev) case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCA6490: ret = qca_regulator_init(hu); break; @@ -1864,6 +1872,10 @@ static int qca_setup(struct hci_uart *hu) soc_name = "wcn7850"; break; + case QCA_QCA6490: + soc_name = "qca6490"; + break; + default: soc_name = "ROME/QCA6390"; } @@ -1886,6 +1898,7 @@ retry: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCA6490: // XXX: Is this needed? set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); hci_set_aosp_capable(hdev); @@ -1916,6 +1929,7 @@ retry: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCA6490: // XXX: TEMPORARY break; default: @@ -1965,7 +1979,7 @@ out: } /* Setup bdaddr */ - if (soc_type == QCA_ROME) + if (soc_type == QCA_ROME) // XXX: Test here? hu->hdev->set_bdaddr = qca_set_bdaddr_rome; else hu->hdev->set_bdaddr = qca_set_bdaddr; @@ -2046,6 +2060,20 @@ static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = { .num_vregs = 0, }; +static const struct qca_device_data qca_soc_data_qca6490 __maybe_unused = { + .soc_type = QCA_QCA6490, // QCA_WCN6855 + /*.vregs = (struct qca_vreg []) { + { "vddio", 1800000 }, + { "vddaon", 950000 }, + { "vdddig", 950000 }, + { "vddrfa1", 1880000 }, + { "vddrfa2", 1350000 }, + { "vddasd", 2800000 }, + },*/ + .num_vregs = 0, + //.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, +}; + static const struct qca_device_data qca_soc_data_wcn6750 __maybe_unused = { .soc_type = QCA_WCN6750, .vregs = (struct qca_vreg []) { @@ -2300,6 +2328,15 @@ static int qca_serdev_probe(struct serdev_device *serdev) power_ctrl_enabled = false; } + /* QCA6490 needs wlan and bluetooth enabled together */ + qcadev->wl_en = devm_gpiod_get_optional(&serdev->dev, "wlan", + GPIOD_OUT_LOW); + if (IS_ERR_OR_NULL(qcadev->wl_en) && + data->soc_type == QCA_QCA6490) { + dev_err(&serdev->dev, "failed to acquire WL_EN gpio\n"); + power_ctrl_enabled = false; + } + qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", GPIOD_IN); if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && @@ -2411,7 +2448,8 @@ static void qca_serdev_shutdown(struct device *dev) const u8 ibs_wake_cmd[] = { 0xFD }; const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 }; - if (qcadev->btsoc_type == QCA_QCA6390) { + if ((qcadev->btsoc_type == QCA_QCA6390) || + (qcadev->btsoc_type == QCA_QCA6490)) { if (test_bit(QCA_BT_OFF, &qca->flags) || !test_bit(HCI_RUNNING, &hdev->flags)) return; @@ -2571,6 +2609,7 @@ static const struct of_device_id qca_bluetooth_of_match[] = { { .compatible = "qcom,qca2066-bt", .data = &qca_soc_data_qca2066}, { .compatible = "qcom,qca6174-bt" }, { .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390}, + { .compatible = "qcom,qca6490-bt", .data = &qca_soc_data_qca6490}, { .compatible = "qcom,qca9377-bt" }, { .compatible = "qcom,wcn3988-bt", .data = &qca_soc_data_wcn3988}, { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, @@ -2591,6 +2630,7 @@ static const struct acpi_device_id qca_bluetooth_acpi_match[] = { { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, { "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { "QCOM6490", (kernel_ulong_t)&qca_soc_data_qca6490 }, { }, }; MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match); diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 0c6ecbb9a066..664af4984bc3 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -292,86 +292,169 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .support_fw_mac_sequence = true, }, { - .name = "qcn9074 hw1.0", - .hw_rev = ATH11K_HW_QCN9074_HW10, - .fw = { - .dir = "QCN9074/hw1.0", - .board_size = 256 * 1024, - .cal_offset = 128 * 1024, - }, - .max_radios = 1, - .single_pdev_only = false, - .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074, - .hw_ops = &qcn9074_ops, - .ring_mask = &ath11k_hw_ring_mask_qcn9074, - .internal_sleep_clock = false, - .regs = &qcn9074_regs, - .host_ce_config = ath11k_host_ce_config_qcn9074, - .ce_count = 6, - .target_ce_config = ath11k_target_ce_config_wlan_qcn9074, + .name = "qca6490 hw1.0", + .hw_rev = ATH11K_HW_QCA6490_HW10, + .max_radios = 3, + .bdf_addr = 0x4B0C0000, + .hw_ops = &qca6390_ops, + .ring_mask = &ath11k_hw_ring_mask_qca6390, + .internal_sleep_clock = true, + .regs = &qca6390_regs, + .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, + .host_ce_config = ath11k_host_ce_config_qca6390, + .ce_count = 9, + .target_ce_config = ath11k_target_ce_config_wlan_qca6390, .target_ce_count = 9, - .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074, - .svc_to_ce_map_len = 18, + .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, + .svc_to_ce_map_len = 14, .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, - .rxdma1_enable = true, - .num_rxmda_per_pdev = 1, - .rx_mac_buf_ring = false, - .vdev_start_delay = false, - .htt_peer_map_v2 = true, + .single_pdev_only = true, + .rxdma1_enable = false, + .num_rxmda_per_pdev = 2, + .rx_mac_buf_ring = true, + .vdev_start_delay = true, + .htt_peer_map_v2 = false, .spectral = { - .fft_sz = 2, + .fft_sz = 0, .fft_pad_sz = 0, - .summary_pad_sz = 16, - .fft_hdr_len = 24, - .max_fft_bins = 1024, + .summary_pad_sz = 0, + .fft_hdr_len = 0, + .max_fft_bins = 0, .fragment_160mhz = false, }, .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_MESH_POINT), - .supports_monitor = true, - .full_monitor_mode = true, - .supports_shadow_regs = false, - .idle_ps = false, - .supports_sta_ps = false, + BIT(NL80211_IFTYPE_AP), + .supports_monitor = false, + .full_monitor_mode = false, + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, .coldboot_cal_mm = false, - .coldboot_cal_ftm = true, - .cbcal_restart_fw = true, - .fw_mem_mode = 2, - .num_vdevs = 8, - .num_peers = 128, - .supports_suspend = false, - .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), + .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = true, + .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .supports_regdb = false, .fix_l1ss = true, - .credit_flow = false, - .max_tx_ring = DP_TCL_NUM_RING_MAX, - .hal_params = &ath11k_hw_hal_params_ipq8074, - .supports_dynamic_smps_6ghz = true, - .alloc_cacheable_memory = true, - .supports_rssi_stats = false, - .fw_wmi_diag_event = false, - .current_cc_support = false, - .dbr_debug_support = true, - .global_reset = false, + .credit_flow = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, + .hal_params = &ath11k_hw_hal_params_qca6390, + .supports_dynamic_smps_6ghz = false, + .alloc_cacheable_memory = false, + .supports_rssi_stats = true, + .fw_wmi_diag_event = true, + .current_cc_support = true, + .dbr_debug_support = false, + .global_reset = true, .bios_sar_capa = NULL, .m3_fw_support = true, .fixed_bdf_addr = false, .fixed_mem_region = false, - .static_window_map = true, + .static_window_map = false, .hybrid_bus_type = false, .fixed_fw_mem = false, - .support_off_channel_tx = false, - .supports_multi_bssid = false, + .support_off_channel_tx = true, + .supports_multi_bssid = true, - .sram_dump = {}, + .sram_dump = { + .start = 0x01400000, + .end = 0x0171ffff, + }, .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, - .support_fw_mac_sequence = false, + .support_fw_mac_sequence = true, + }, + { + .name = "qcn9074 hw1.0", + .hw_rev = ATH11K_HW_QCN9074_HW10, + .fw = { + .dir = "WCN6855/hw2.0", + .board_size = 256 * 1024, + .cal_offset = 128 * 1024, + }, + .max_radios = 3, + .bdf_addr = 0x4B0C0000, + .hw_ops = &wcn6855_ops, + .ring_mask = &ath11k_hw_ring_mask_qca6390, + .internal_sleep_clock = true, + .regs = &wcn6855_regs, + .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, + .host_ce_config = ath11k_host_ce_config_qca6390, + .ce_count = 9, + .target_ce_config = ath11k_target_ce_config_wlan_qca6390, + .target_ce_count = 9, + .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, + .svc_to_ce_map_len = 14, + .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, + .single_pdev_only = true, + .rxdma1_enable = false, + .num_rxmda_per_pdev = 2, + .rx_mac_buf_ring = true, + .vdev_start_delay = true, + .htt_peer_map_v2 = false, + + .spectral = { + .fft_sz = 0, + .fft_pad_sz = 0, + .summary_pad_sz = 0, + .fft_hdr_len = 0, + .max_fft_bins = 0, + .fragment_160mhz = false, + }, + + .interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP), + .supports_monitor = false, + .full_monitor_mode = false, + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, + .cbcal_restart_fw = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, + .num_peers = 512, + .supports_suspend = true, + .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), + .supports_regdb = true, + .fix_l1ss = false, + .credit_flow = true, + .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, + .hal_params = &ath11k_hw_hal_params_qca6390, + .supports_dynamic_smps_6ghz = false, + .alloc_cacheable_memory = false, + .supports_rssi_stats = true, + .fw_wmi_diag_event = true, + .current_cc_support = true, + .dbr_debug_support = false, + .global_reset = true, + .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, + .m3_fw_support = true, + .fixed_bdf_addr = false, + .fixed_mem_region = false, + .static_window_map = false, + .hybrid_bus_type = false, + .fixed_fw_mem = false, + .support_off_channel_tx = true, + .supports_multi_bssid = true, + + .sram_dump = { + .start = 0x01400000, + .end = 0x0177ffff, + }, + + .tcl_ring_retry = true, + .tx_ring_size = DP_TCL_DATA_RING_SIZE, + .smp2p_wow_exit = false, + .support_fw_mac_sequence = true, }, { .name = "wcn6855 hw2.0", diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index f12b606e2d2e..462c592677fb 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -141,6 +141,7 @@ struct ath11k_skb_rxcb { enum ath11k_hw_rev { ATH11K_HW_IPQ8074, ATH11K_HW_QCA6390_HW20, + ATH11K_HW_QCA6490_HW10, ATH11K_HW_IPQ6018_HW10, ATH11K_HW_QCN9074_HW10, ATH11K_HW_WCN6855_HW20, diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index afeabd6ecc67..da48546b6c4f 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -441,6 +441,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) ath11k_mhi_config = &ath11k_mhi_config_qcn9074; break; case ATH11K_HW_QCA6390_HW20: + case ATH11K_HW_QCA6490_HW10: case ATH11K_HW_WCN6855_HW20: case ATH11K_HW_WCN6855_HW21: ath11k_mhi_config = &ath11k_mhi_config_qca6390; diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 09e65c5e55c4..817340177373 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -801,6 +801,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ath11k_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); switch (soc_hw_version_major) { + case 1: + switch (soc_hw_version_minor) { + case 0x10: + ab->hw_rev = ATH11K_HW_QCA6490_HW10; + } + break; case 2: switch (soc_hw_version_minor) { case 0x00: diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index 16d1e332193f..b6d3d5420b37 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -74,6 +74,17 @@ static const struct ath11k_msi_config ath11k_msi_config[] = { }, .hw_rev = ATH11K_HW_QCA6390_HW20, }, + /*{ + .total_vectors = 32, + .total_users = 4, + .users = (struct ath11k_msi_user[]) { + { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, + { .name = "CE", .num_vectors = 10, .base_vector = 3 }, + { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, + { .name = "DP", .num_vectors = 18, .base_vector = 14 }, + }, + .hw_rev = ATH11K_HW_QCA6490_HW10, + },*/ { .total_vectors = 16, .total_users = 3,