Compare commits

...

10 commits

23 changed files with 2343 additions and 85 deletions

View file

@ -18,6 +18,7 @@ properties:
enum:
- qcom,qca2066-bt
- qcom,qca6174-bt
- qcom,qca6490-bt
- qcom,qca9377-bt
- qcom,wcn3988-bt
- qcom,wcn3990-bt
@ -37,6 +38,15 @@ properties:
description: gpio specifier is used to find status
of clock supply to SoC
wlan-gpios:
maxItems: 1
description: gpio specifier used to enable the WLAN
chip, on QCA6490 only
power-domains:
maxItems: 1
description: power domain associated with the chip
clocks:
maxItems: 1
description: clock provided to the controller (SUSCLK_32KHZ)
@ -114,6 +124,17 @@ allOf:
- enable-gpios
- clocks
- if:
properties:
compatible:
contains:
enum:
- qcom,qca6490-bt
then:
required:
- enable-gpios
- wlan-gpios
- if:
properties:
compatible:

View file

@ -227,6 +227,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8350-oneplus-lemonade.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8350-oneplus-lemonadep.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8350-sony-xperia-sagami-pdx214.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8350-sony-xperia-sagami-pdx215.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8350-samsung-r9q2.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8450-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8450-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8450-sony-xperia-nagara-pdx223.dtb

View file

@ -24,6 +24,12 @@
chassis-type = "handset";
interrupt-parent = <&intc>;
aliases {
bluetooth = &bluetooth;
serial0 = &uart2;
serial1 = &uart18;
};
bat: battery {
compatible = "simple-battery";
device-chemistry = "lithium-ion";
@ -54,6 +60,33 @@
};
};
cnss_supply: cnss-supply {
compatible = "regulator-fixed";
regulator-name = "wcnss_regulator";
regulator-min-microvolt = <1900000>;
regulator-max-microvolt = <1900000>;
enable-active-high;
pinctrl-0 = <&cnss_regulator_active>;
pinctrl-names = "default";
gpio = <&tlmm 201 GPIO_ACTIVE_HIGH>;
};
/*
gpio_i2c4: gpio-i2c {
compatible = "i2c-gpio";
sda-gpios = <&tlmm 20 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
scl-gpios = <&tlmm 21 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
//#address-cells = <1>;
//#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c4_default>, <&tp_enable_2v8>;
};
*/
gpio-keys {
compatible = "gpio-keys";
@ -106,6 +139,27 @@
};
};
qca6490_pd: qca6490 {
compatible = "qcom,qca6490";
#power-domain-cells = <0>;
vddaonbt-supply = <&pm8350_s11>;
vddaonwl-supply = <&pmr735a_s2>;
vddasd-supply = <&pmr735a_l7>;
vddrfa1-supply = <&pm8350c_s1>;
vddrfa2-supply = <&pm8350_s12>;
vddrfa3-supply = <&pm8350c_s1>;
vddpcie1-supply = <&cnss_supply>;
vddpcie2-supply = <&pm8350c_s1>;
vddio-supply = <&pm8350_s10>;
pinctrl-0 = <&cnss_wlan_sleep>;
pinctrl-1 = <&cnss_wlan_active>;
pinctrl-names = "default", "active";
status = "disabled";
};
display_panel_avdd: regulator-display {
compatible = "regulator-fixed";
regulator-name = "display_panel_avdd";
@ -403,9 +457,23 @@
};
};
/* pm8350b has one regulator here; unused for now */
regulators-2 {
compatible = "qcom,pm8350b-rpmh-regulators";
qcom,pmic-id = "d";
vdd-l1-supply = <&pm8350_s12>;
pm8350b_l1: ldo1 {
regulator-name = "pm8350b_l1";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
RPMH_REGULATOR_MODE_HPM>;
};
};
regulators-3 {
compatible = "qcom,pmr735a-rpmh-regulators";
qcom,pmic-id = "e";
@ -486,6 +554,24 @@
status = "okay";
};
&dispcc {
//status = "okay";
};
&gmu {
/* FIXME: check_dtbs complains */
//firmware-name = "qcom/sm8350/lemonade/a660_gmu.bin";
};
&gpu {
//status = "okay";
zap-shader {
memory-region = <&pil_gpu_mem>;
firmware-name = "qcom/sm8350/lemonade/a660_zap.mbn";
};
};
&i2c2 {
clock-frequency = <100000>;
status = "okay";
@ -497,6 +583,7 @@
};
};
&i2c4 {
clock-frequency = <400000>;
status = "okay";
@ -554,14 +641,74 @@
status = "okay";
};
&mdss {
//status = "okay";
};
&mdss_dp {
//status = "okay";
ports {
port@1 {
reg = <1>;
endpoint {
};
};
};
};
&mdss_dsi0 {
vdda-supply = <&pm8350_l6>;
//status = "okay";
/* Common properties for OnePlus 9 and 9 Pro */
display_panel: panel-1@0 {
reg = <0>;
pinctrl-0 = <&sde_dsi_active &sde_te_active>;
pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
pinctrl-names = "default", "sleep";
reset-gpios = <&tlmm 24 GPIO_ACTIVE_LOW>;
vdd-supply = <&pm8350c_l13>;
vddio-supply = <&pm8350c_l12>;
avdd-supply = <&display_panel_avdd>;
//clocks = <&rpmhcc RPMH_DIV_CLK1>;
//clock-names = "div_clk";
//clocks = <&mdss_dsi0_phy DISP_CC_MDSS_>
status = "disabled";
port {
panel_in: endpoint {
remote-endpoint = <&mdss_dsi0_out>;
};
};
};
};
&mdss_dsi0_out {
remote-endpoint = <&panel_in>;
data-lanes = <0 1 2 3>;
};
&mdss_dsi0_phy {
vdds-supply = <&pm8350_l5>;
//status = "okay";
};
&mpss {
firmware-name = "qcom/sm8350/OnePlus/lemonade/modem.mbn";
status = "okay";
};
&pcie0 {
pinctrl-0 = <&pcie0_default_state>;
pinctrl-names = "default";
pinctrl-0 = <&pcie0_default_state>;//, <&pcie0_sleep_state>;
pinctrl-names = "default";//, "sleep";
//power-domains = <&qca6490_pd>;
perst-gpios = <&tlmm 94 GPIO_ACTIVE_HIGH>;
wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
@ -573,6 +720,8 @@
vdda-phy-supply = <&pm8350_l5>;
vdda-pll-supply = <&pm8350_l6>;
power-domains = <&qca6490_pd>;
status = "okay";
};
@ -865,10 +1014,15 @@
};
&pon_resin {
linux,code = <KEY_VOLUMEUP>;
linux,code = <KEY_VOLUMEDOWN>;
status = "okay";
};
/*
&qup_i2c4_default {
function = "gpio";
bias-disable;
};
*/
&qupv3_id_0 {
status = "okay";
};
@ -919,6 +1073,74 @@
/* Fingerprint sensor and NFC-related pins shouldn't be touched by us */
gpio-reserved-ranges = <52 8>;
bt_active: bt-active-state {
pins = "gpio65";
function = "gpio";
drive-strength = <16>;
output-high;
bias-pull-up;
};
bt_sleep: bt-sleep-state {
pins = "gpio65";
function = "gpio";
drive-strength = <2>;
output-low;
bias-pull-down;
};
cnss_regulator_active: cnss-regulator-active-state {
pins = "gpio201";
function = "gpio";
drive-strength = <16>;
bias-pull-down;
output-low;
};
cnss_wlan_active: cnss-wlan-active-state {
pins = "gpio64";
function = "gpio";
drive-strength = <16>;
output-high;
bias-pull-up;
};
cnss_wlan_sleep: cnss-wlan-sleep-state {
pins = "gpio64";
function = "gpio";
drive-strength = <2>;
output-low;
bias-pull-down;
};
sde_dsi_active: sde-dsi-active-state {
pins = "gpio24";
function = "gpio";
drive-strength = <8>;
bias-disable;
};
sde_dsi_suspend: sde-dsi-sleep-state {
pins = "gpio24";
function = "gpio";
drive-strength = <2>;
bias-pull-down;
};
sde_te_active: sde-te-active-state {
pins = "gpio82";
function = "mdp_vsync";
drive-strength = <2>;
bias-pull-down;
};
sde_te_suspend: sde-te-sleep-state {
pins = "gpio82";
function = "mdp_vsync";
drive-strength = <2>;
bias-pull-down;
};
pcie0_default_state: pcie0-default-state {
perst-pins {
pins = "gpio94";
@ -940,13 +1162,13 @@
drive-strength = <2>;
bias-pull-up;
};
};
sleep-pins {
pins = "gpio95";
function = "gpio";
drive-strength = <2>;
bias-pull-up;
};
pcie0_sleep_state: pcie0-sleep-state {
pins = "gpio95";
function = "gpio";
drive-strength = <2>;
bias-pull-up;
};
pcie1_default_state: pcie1-default-state {
@ -969,10 +1191,17 @@
function = "gpio";
drive-strength = <2>;
bias-pull-up;
/* wil6210_refclk_en_pin lives here also */
};
};
/* XXX: Is this correct? */
pcie1_sleep_state: pcie1-sleep-state {
pins = "gpio98";
function = "gpio";
drive-strength = <2>;
bias-pull-up;
};
/* Modem-related pin common on both devices */
rf_cable_ant0_active: rf-cable-ant0-active-state {
pins = "gpio165";
@ -1005,6 +1234,43 @@
};
};
&uart2 {
status = "okay";
};
&uart18 {
pinctrl-0 = <&qup_uart18_4pin>;
status = "okay";
bluetooth: bluetooth {
compatible = "qcom,qca6490-bt";
pinctrl-0 = <&bt_active>;
pinctrl-1 = <&bt_sleep>;
pinctrl-names = "default", "sleep";
/* QCA6490 requires wlan and bluetooth be enabled simultaneously */
enable-gpios = <&tlmm 65 GPIO_ACTIVE_HIGH>;
wlan-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
swctrl-gpios = <&tlmm 153 GPIO_ACTIVE_HIGH>;
power-domains = <&qca6490_pd>;
//vddio-supply = <&pm8350_s10>;
//vddaon-supply = <&pm8350_s11>;
//vddasd-supply = <&pmr735a_l7>;
//vdddig-supply = <&pm8350_s11>;
//vddrfa1-supply = <&pm8350c_s1>;
//vddrfa2-supply = <&pm8350_s12>;
//vddpcie1-supply = <&pm8350_s12>;
//vddpcie2-supply = <&pm8350c_s1>;
max-speed = <3200000>;
//status = "disabled";
};
};
&ufs_mem_hc {
reset-gpios = <&tlmm 203 GPIO_ACTIVE_LOW>;

View file

@ -36,6 +36,16 @@
<&rf_cable_ant3_active>,
<&rf_cable_ant7_active>;
pinctrl-names = "default";
status = "okay";
};
&qca6490_pd {
rf-gpios = <&tlmm 165 0>,
<&tlmm 27 0>,
<&tlmm 92 0>,
<&tlmm 44 0>,
<&tlmm 155 0>;
status = "okay";
};
&tlmm {
@ -68,18 +78,18 @@
bias-pull-up;
};
tp_rst_suspend: tp-rst-suspend-state {
pins = "gpio22";
function = "gpio";
drive-strength = <2>;
bias-pull-down;
};
tp_enable_2v8: tp-enable-2v8-state {
tp_enable_2v8: tp-2v8-enable-state {
pins = "gpio74";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
output-high;
};
tp_rst_suspend: tp-rst-suspend-state {
pins = "gpio22";
function = "gpio";
drive-strength = <2>;
bias-pull-down;
};
};

View file

@ -14,7 +14,35 @@
model = "OnePlus 9 Pro";
};
&display_panel {
compatible = "samsung,amb670yf01";
status = "fail";
};
&mpss {
pinctrl-0 = <&rf_cable_ant0_active>;
pinctrl-names = "default";
status = "okay";
};
&qca6490_pd {
rf-gpios = <&tlmm 165 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&tlmm {
tp_enable_2v8: tp-2v8-enable-state {
pins = "gpio31", "gpio197";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
output-high;
};
tp_rst_suspend: tp-rst-suspend-state {
pins = "gpio22";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};

File diff suppressed because it is too large Load diff

View file

@ -2971,6 +2971,38 @@
bias-disable;
};
qup_uart18_4pin: qup-uart18-4pin-state {
cts-pins {
pins = "gpio68";
function = "qup18";
drive-strength = <2>;
bias-bus-hold;
};
rts-pins {
pins = "gpio69";
function = "qup18";
drive-strength = <2>;
bias-disable;
};
tx-pins {
pins = "gpio70";
function = "qup18";
drive-strength = <2>;
bias-disable;
output-enable;
};
rx-pins {
pins = "gpio71";
function = "qup18";
drive-strength = <2>;
bias-disable;
output-disable;
};
};
qup_i2c0_default: qup-i2c0-default-state {
pins = "gpio4", "gpio5";
function = "qup0";

View file

@ -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:

View file

@ -150,6 +150,7 @@ enum qca_btsoc_type {
QCA_WCN3991,
QCA_QCA2066,
QCA_QCA6390,
QCA_QCA6490,
QCA_WCN6750,
QCA_WCN6855,
QCA_WCN7850,

View file

@ -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;
@ -1692,6 +1694,12 @@ static int qca_regulator_init(struct hci_uart *hu)
* off the voltage regulator.
*/
qcadev = serdev_device_get_drvdata(hu->serdev);
if (!qcadev || !qcadev->bt_power) {
bt_dev_err(hu->hdev, "qcadev or bt_power is NULL");
return -ENODEV;
}
if (!qcadev->bt_power->vregs_on) {
serdev_device_close(hu->serdev);
ret = qca_regulator_enable(qcadev);
@ -1725,8 +1733,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 +1801,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 +1878,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 +1904,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 +1935,7 @@ retry:
case QCA_WCN6750:
case QCA_WCN6855:
case QCA_WCN7850:
case QCA_QCA6490: // XXX: TEMPORARY
break;
default:
@ -1965,7 +1985,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 +2066,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 +2334,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 +2454,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 +2615,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 +2636,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);

View file

@ -220,6 +220,15 @@ config SYSFB_SIMPLEFB
If unsure, say Y.
config SYNA_TCM_FW
tristate "Synaptics TCM Firmware Loader"
depends on RMI4_I2C
help
Say yes here to add support for loading firmware images on Synaptics
TCM on-cell touch controllers.
If unsure, say N.
config TI_SCI_PROTOCOL
tristate "TI System Control Interface (TISCI) Message Protocol"
depends on TI_MESSAGE_MANAGER

View file

@ -15,6 +15,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
obj-$(CONFIG_MTK_ADSP_IPC) += mtk-adsp-ipc.o
obj-$(CONFIG_SYNA_TCM_FW) += syna_tcm_loader.o
obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
obj-$(CONFIG_SYSFB) += sysfb.o

View file

@ -0,0 +1,80 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/rmi.h>
#include <linux/delay.h>
struct fw_block {
unsigned char *data;
unsigned int size;
unsigned int addr;
};
struct tcm_firmware {
struct fw_block boot_cfg;
struct fw_block app_fw;
struct fw_block app_cfg;
struct fw_block disp_cfg;
};
enum tcm_mode {
MODE_BL,
MODE_APP,
};
static int rmi_is_tcm(struct rmi_device *rmi) {
/* TODO */
return 0;
}
static int syna_tcm_switch_mode(struct rmi_device *rmi, enum tcm_mode mode)
{
unsigned char *response;
unsigned int
int ret;
mutex_lock(rmi->dev->mutex);
/* TODO */
mutex_unlock(rmi->dev->mutex);
}
static int syna_tcm_fw_load(struct rmi_device *rmi,
const struct tcm_firmware *fw)
{
int ret;
ret = syna_tcm_switch_mode(struct rmi_device *rmi, MODE_BL);
if (!ret) {
dev_err(dev, "Failed to switch into bootloader mode: %d\n", ret);
return ret;
}
/* XXX: Write the 4 fw imgs */
}
static int syna_tcm_fw_init(struct rmi_device *rmi)
{
struct tcm_firmware *fw;
struct device *dev = rmi->dev;
int ret;
ret = rmi_is_tcm(rmi);
if (ret) {
dev_err(dev, "RMI device is not TCM; aborting fw load: %d\n", ret);
return -ENODEV;
}
fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
if (!fw)
return -ENOMEM;
ret = syna_tcm_fw_load(rmi, const struct tcm_firmware *fw)
}
static const struct of_device_id syna_tcm_fw_match {
/* XXX: See if this is actually generic before upstreaming */
{
.compatible = "syna,tcm-fw-loader",
},
{},
};

View file

@ -551,6 +551,14 @@ config DRM_PANEL_SAMSUNG_AMB670YF01
Say Y here if you want to enable support for the Samsung AMB670YF01 DPI
1440x3216 panel found in OnePlus 9 Pro smartphones.
config DRM_PANEL_SAMSUNG_AMB641ZR01
tristate "Samsung AMB641ZR01 DSI command mode panel"
depends on OF && DRM_MIPI_DSI && BACKLIGHT_CLASS_DEVICE
select VIDEOMODE_HELPERS
help
Say Y here if you want to enable support for the Samsung AMB641ZR01 DPI
1080x2340 panel found in Samsung Galaxy S21 FE smartphones.
config DRM_PANEL_SAMSUNG_ATNA33XC20
tristate "Samsung ATNA33XC20 eDP panel"
depends on OF

View file

@ -53,6 +53,7 @@ obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o
obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o
obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMB670YF01) += panel-samsung-amb670yf01.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMB641ZR01) += panel-samsung-amb641zr01.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o

View file

@ -0,0 +1,478 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Panel driver for the Samsung AMB641ZR01.
* Found in the Samsung Galaxy S21 FE phone.
*
* Copyright (c) 2026 <>
*/
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/backlight.h>
#include <linux/regulator/consumer.h>
#include <video/mipi_display.h>
#include <drm/drm_panel.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_modes.h>
#include <drm/display/drm_dsc.h>
#include <drm/display/drm_dsc_helper.h>
#define L2_ACCESS_ENABLE (const u8[]){ 0xf0, 0x5a, 0x5a }
#define L2_ACCESS_DISABLE (const u8[]){ 0xf0, 0xa5, 0xa5 }
#define UPDATE_REFRESH_RATE (const u8[]){ 0xf7, 0x0f }
struct amb641zr01_panel {
struct drm_panel panel;
struct mipi_dsi_device *dsi;
struct drm_dsc_config *dsc;
struct regulator *supply_vdd;
struct regulator *supply_vddio;
struct regulator *supply_vddr;
struct regulator *supply_vddi;
struct regulator *supply_avdd;
struct gpio_desc *reset_gpio;
const struct drm_display_mode *mode;
bool prepared;
};
static const struct drm_display_mode amb641zr01_120hz_fhd_mode = {
.clock = (1080 + 92 + 92 + 92) * (2340 + 16 + 8 + 12) * 120 / 1000,
.hdisplay = 1080,
.hsync_start = 1080 + 92,
.hsync_end = 1080 + 92 + 92,
.htotal = 1080 + 92 + 92 + 92,
.vdisplay = 2340,
.vsync_start = 2340 + 16,
.vsync_end = 2340 + 16 + 8,
.vtotal = 2340 + 16 + 8 + 12,
.width_mm = 67,
.height_mm = 150,
.type = DRM_MODE_TYPE_DRIVER,
};
static inline
struct amb641zr01_panel *to_amb641zr01_panel(struct drm_panel *panel)
{
return container_of(panel, struct amb641zr01_panel, panel);
}
static void amb641zr01_panel_reset(struct amb641zr01_panel *ctx)
{
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
usleep_range(10000, 11000);
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
usleep_range(1000, 2000);
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
usleep_range(10000, 11000);
}
static int amb641zr01_panel_on(struct amb641zr01_panel *ctx)
{
struct mipi_dsi_device *dsi = ctx->dsi;
struct device *dev = &dsi->dev;
int ret;
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x14);
mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x01);
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
if (ret < 0) {
dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
return ret;
}
msleep(121);
mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
if (ret < 0) {
dev_err(dev, "Failed to set tear on: %d\n", ret);
return ret;
}
ret = mipi_dsi_dcs_set_column_address(dsi, 0x0000, 0x0437);
if (ret < 0) {
dev_err(dev, "Failed to set column address: %d\n", ret);
return ret;
}
ret = mipi_dsi_dcs_set_page_address(dsi, 0x0000, 0x095f);
if (ret < 0) {
dev_err(dev, "Failed to set page address: %d\n", ret);
return ret;
}
mipi_dsi_dcs_write_buffer(dsi, L2_ACCESS_ENABLE, 3);
msleep(50);
mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x27, 0xf2);
mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x00);
mipi_dsi_dcs_write_buffer(dsi, L2_ACCESS_DISABLE, 3);
mipi_dsi_dcs_write_buffer(dsi, L2_ACCESS_ENABLE, 3);
mipi_dsi_dcs_write_seq(dsi, 0x60, 0x00, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x0f);
mipi_dsi_dcs_write_seq(dsi, 0x35, 0x00);
mipi_dsi_dcs_write_buffer(dsi, UPDATE_REFRESH_RATE, 2);
mipi_dsi_dcs_write_buffer(dsi, L2_ACCESS_DISABLE, 3);
mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
ret = mipi_dsi_dcs_set_display_on(dsi);
if (ret < 0) {
dev_err(dev, "Failed to set display on: %d\n", ret);
return ret;
}
return 0;
}
static int amb641zr01_panel_off(struct amb641zr01_panel *ctx)
{
struct mipi_dsi_device *dsi = ctx->dsi;
struct device *dev = &dsi->dev;
int ret;
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
mipi_dsi_dcs_write_buffer(dsi, L2_ACCESS_ENABLE, 3);
msleep(50);
mipi_dsi_dcs_write_seq(dsi, 0x91, 0x02);
mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
mipi_dsi_dcs_write_buffer(dsi, L2_ACCESS_DISABLE, 3);
ret = mipi_dsi_dcs_set_display_off(dsi);
if (ret < 0) {
dev_err(dev, "Failed to set display off: %d\n", ret);
return ret;
}
msleep(21);
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
if (ret < 0) {
dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
return ret;
}
msleep(101);
return 0;
}
static int amb641zr01_panel_prepare(struct drm_panel *panel)
{
struct amb641zr01_panel *ctx = to_amb641zr01_panel(panel);
struct device *dev = &ctx->dsi->dev;
struct drm_dsc_picture_parameter_set pps;
int ret;
if (ctx->prepared)
return 0;
ctx->dsc->pic_width = ctx->mode->hdisplay;
ctx->dsc->pic_height = ctx->mode->vdisplay;
drm_dsc_compute_rc_parameters(ctx->dsc);
ret = regulator_enable(ctx->supply_vdd);
if (ret < 0) {
dev_err(dev, "Failed to enable regulator: %d\n", ret);
return ret;
}
ret = regulator_enable(ctx->supply_vddio);
if (ret < 0) {
dev_err(dev, "Failed to enable regulator: %d\n", ret);
return ret;
}
ret = regulator_enable(ctx->supply_vddr);
if (ret < 0) {
dev_err(dev, "Failed to enable regulator: %d\n", ret);
return ret;
}
ret = regulator_enable(ctx->supply_vddi);
if (ret < 0) {
dev_err(dev, "Failed to enable regulator: %d\n", ret);
return ret;
}
ret = regulator_enable(ctx->supply_avdd);
if (ret < 0) {
dev_err(dev, "Failed to enable regulator: %d\n", ret);
return ret;
}
amb641zr01_panel_reset(ctx);
ret = amb641zr01_panel_on(ctx);
if (ret < 0) {
dev_err(dev, "Failed to initialize panel: %d\n", ret);
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
return ret;
}
drm_dsc_pps_payload_pack(&pps, ctx->dsc);
ret = mipi_dsi_picture_parameter_set(ctx->dsi, &pps);
if (ret < 0) {
dev_err(panel->dev, "failed to transmit PPS: %d\n", ret);
return ret;
}
ret = mipi_dsi_compression_mode(ctx->dsi, true);
if (ret < 0) {
dev_err(dev, "failed to enable compression mode: %d\n", ret);
return ret;
}
msleep(28);
ctx->prepared = true;
return 0;
}
static int amb641zr01_panel_unprepare(struct drm_panel *panel)
{
struct amb641zr01_panel *ctx = to_amb641zr01_panel(panel);
if (!ctx->prepared)
return 0;
regulator_disable(ctx->supply_vdd);
regulator_disable(ctx->supply_vddio);
regulator_disable(ctx->supply_vddi);
regulator_disable(ctx->supply_vddr);
regulator_disable(ctx->supply_avdd);
ctx->prepared = false;
return 0;
}
static int amb641zr01_panel_disable(struct drm_panel *panel) {
struct amb641zr01_panel *ctx = to_amb641zr01_panel(panel);
struct device *dev = &ctx->dsi->dev;
int ret;
ret = amb641zr01_panel_off(ctx);
if (ret < 0) {
dev_err(dev, "Failed to disable panel: %d\n", ret);
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
return ret;
}
return ret;
}
static int amb641zr01_panel_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
struct drm_display_mode *mode;
struct amb641zr01_panel *ctx = to_amb641zr01_panel(panel);
mode = drm_mode_duplicate(connector->dev, ctx->mode);
if (!mode)
return -ENOMEM;
drm_mode_set_name(mode);
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
connector->display_info.width_mm = mode->width_mm;
connector->display_info.height_mm = mode->height_mm;
drm_mode_probed_add(connector, mode);
return 1;
}
static const struct drm_panel_funcs amb641zr01_panel_funcs = {
.prepare = amb641zr01_panel_prepare,
.unprepare = amb641zr01_panel_unprepare,
.disable = amb641zr01_panel_disable,
.get_modes = amb641zr01_panel_get_modes,
};
static int amb641zr01_panel_bl_update_status(struct backlight_device *bl)
{
struct mipi_dsi_device *dsi = bl_get_data(bl);
u16 brightness = backlight_get_brightness(bl);
int ret;
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
if (ret < 0)
return ret;
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
return 0;
}
static int amb641zr01_panel_bl_get_brightness(struct backlight_device *bl)
{
struct mipi_dsi_device *dsi = bl_get_data(bl);
u16 brightness;
int ret;
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness);
if (ret < 0)
return ret;
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
return brightness;
}
static const struct backlight_ops amb641zr01_panel_bl_ops = {
.update_status = amb641zr01_panel_bl_update_status,
.get_brightness = amb641zr01_panel_bl_get_brightness,
};
static struct backlight_device *amb641zr01_create_backlight(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
const struct backlight_properties props = {
.type = BACKLIGHT_RAW,
.brightness = 255,
/* Panel can go higher in high brightness mode */
.max_brightness = 486,
};
return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
&amb641zr01_panel_bl_ops, &props);
}
static int amb641zr01_panel_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
struct amb641zr01_panel *ctx;
int ret;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
ctx->mode = of_device_get_match_data(dev);
if (!ctx->mode) {
dev_err(dev, "Missing device mode\n");
return -ENODEV;
}
ctx->supply_vdd = devm_regulator_get(dev, "vdd");
if (IS_ERR(ctx->supply_vdd))
return dev_err_probe(dev, PTR_ERR(ctx->supply_vdd),
"Failed to get vdd regulator\n");
ctx->supply_vddio = devm_regulator_get(dev, "vddio");
if (IS_ERR(ctx->supply_vddio))
return dev_err_probe(dev, PTR_ERR(ctx->supply_vddio),
"Failed to get vddio regulator\n");
ctx->supply_avdd = devm_regulator_get(dev, "avdd");
if (IS_ERR(ctx->supply_avdd))
return dev_err_probe(dev, PTR_ERR(ctx->supply_avdd),
"Failed to get avdd regulator\n");
ctx->supply_vddr = devm_regulator_get(dev, "vddr");
if (IS_ERR(ctx->supply_vddr))
return dev_err_probe(dev, PTR_ERR(ctx->supply_vddr),
"Failed to get vddr regulator\n");
ctx->supply_vddi = devm_regulator_get(dev, "vddi");
if (IS_ERR(ctx->supply_vddi))
return dev_err_probe(dev, PTR_ERR(ctx->supply_vddi),
"Failed to get vddi regulator\n");
ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(ctx->reset_gpio))
return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
"Failed to get reset-gpios\n");
ctx->dsi = dsi;
mipi_dsi_set_drvdata(dsi, ctx);
dsi->lanes = 4;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_LPM;
drm_panel_init(&ctx->panel, dev, &amb641zr01_panel_funcs,
DRM_MODE_CONNECTOR_DSI);
ctx->panel.prepare_prev_first = true;
ctx->panel.backlight = amb641zr01_create_backlight(dsi);
if (IS_ERR(ctx->panel.backlight))
return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
"Failed to create backlight\n");
drm_panel_add(&ctx->panel);
ctx->dsc = devm_kzalloc(dev, sizeof(*ctx->dsc), GFP_KERNEL);
if (!ctx->dsc)
return -ENOMEM;
/* This panel only supports DSC */
ctx->dsc->dsc_version_major = 1;
ctx->dsc->dsc_version_minor = 1;
dsi->slice_per_pkt = 1;
ctx->dsc->slice_height = 30;
ctx->dsc->slice_width = 540;
WARN_ON(1080 % ctx->dsc->slice_width);
ctx->dsc->slice_count = 1080 / ctx->dsc->slice_width;
ctx->dsc->bits_per_component = 8;
ctx->dsc->bits_per_pixel = 8 << 4; /* 4 fractional bits */
ctx->dsc->block_pred_enable = true;
dsi->dsc = ctx->dsc;
ret = mipi_dsi_attach(dsi);
if (ret < 0) {
dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
drm_panel_remove(&ctx->panel);
return ret;
}
return 0;
}
static const struct of_device_id amb641zr01_panel_of_match[] = {
{
.compatible = "samsung,amb641zr01",
.data = &amb641zr01_120hz_fhd_mode,
},
{ /* sentinel */ }
};
static void amb641zr01_panel_remove(struct mipi_dsi_device *dsi)
{
struct amb641zr01_panel *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
drm_panel_remove(&ctx->panel);
}
MODULE_DEVICE_TABLE(of, amb641zr01_panel_of_match);
static struct mipi_dsi_driver amb641zr01_panel_driver = {
.probe = amb641zr01_panel_probe,
.remove = amb641zr01_panel_remove,
.driver = {
.name = "panel-samsung-amb641zr01",
.of_match_table = amb641zr01_panel_of_match,
},
};
module_mipi_dsi_driver(amb641zr01_panel_driver);

View file

@ -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",

View file

@ -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,

View file

@ -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;

View file

@ -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:

View file

@ -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,

View file

@ -1013,6 +1013,11 @@ static const struct rpmh_vreg_init_data pm8350_vreg_data[] = {
{}
};
static const struct rpmh_vreg_init_data pm8350b_vreg_data[] = {
RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"),
{}
};
static const struct rpmh_vreg_init_data pm8350c_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps515, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"),
@ -1474,6 +1479,10 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
.compatible = "qcom,pm8350-rpmh-regulators",
.data = pm8350_vreg_data,
},
{
.compatible = "qcom,pm8350b-rpmh-regulators",
.data = pm8350b_vreg_data,
},
{
.compatible = "qcom,pm8350c-rpmh-regulators",
.data = pm8350c_vreg_data,

View file

@ -1200,7 +1200,7 @@ void gether_disconnect(struct gether *link)
DBG(dev, "%s\n", __func__);
netif_device_detach(dev->net);
netif_stop_queue(dev->net);
netif_carrier_off(dev->net);
/* disable endpoints, forcing (synchronous) completion