From 1c57837d55bedeb5cf96618885dca75bc5d83fbe Mon Sep 17 00:00:00 2001 From: "Ycarus (Yannick Chabanois)" Date: Tue, 23 May 2023 07:55:16 +0200 Subject: [PATCH] Add partial 6.1 support for ips40xx --- .../patches/003-fix-kernel-6.1-compile.patch | 15 + .../patches/301-fix-kernel-6.1-compile.patch | 22 + .../patches/101-fix-kernel-6.1-compile.patch | 18 + .../patches/301-fix-kernel-6.1-compile.patch | 325 +++++++ 6.1/target/linux/ipq40xx/config-6.1 | 533 +++++++++++ .../ipq40xx/files/drivers/net/phy/qca807x.c | 859 ++++++++++++++++++ .../104-clk-fix-apss-cpu-overclocking.patch | 115 +++ .../300-clk-qcom-ipq4019-add-ess-reset.patch | 52 ++ ...-compressed-add-appended-DTB-section.patch | 48 + ...d-set-ipq40xx-watchdog-to-allow-boot.patch | 66 ++ ...msm-use-sdhci_set_clock-instead-of-s.patch | 24 + .../420-firmware-qcom-scm-disable-SDI.patch | 47 + ...-firmware-qcom-scm-cold-boot-address.patch | 121 +++ ...-add-support-for-Toshiba-TC58NVG0S3H.patch | 29 + ...pecific-data-to-struct-skb_shared_in.patch | 43 + ...019-add-shinfo-based-tagging-driver-.patch | 187 ++++ ...4019-add-ethernet-controller-DT-node.patch | 81 ++ ...phy-define-PSGMII-PHY-interface-mode.patch | 61 ++ .../706-arm-dts-ipq4019-add-switch-node.patch | 98 ++ .../707-dt-bindings-net-add-QCA807x-PHY.patch | 61 ++ ...8-net-phy-Add-Qualcom-QCA807x-driver.patch | 50 + ...9-arm-dts-ipq4019-QCA807x-properties.patch | 61 ++ .../850-soc-add-qualcomm-syscon.patch | 180 ++++ .../patches-6.1/998-lantiq-atm-hacks.patch | 43 + .../999-atm-mpoa-intel-dsl-phy-support.patch | 137 +++ 25 files changed, 3276 insertions(+) create mode 100644 6.1/package/kernel/lantiq/ltq-ifxos/patches/003-fix-kernel-6.1-compile.patch create mode 100644 6.1/package/kernel/lantiq/ltq-vdsl-vr11-mei/patches/301-fix-kernel-6.1-compile.patch create mode 100644 6.1/package/kernel/lantiq/vrx518_ep/patches/101-fix-kernel-6.1-compile.patch create mode 100644 6.1/package/kernel/lantiq/vrx518_tc/patches/301-fix-kernel-6.1-compile.patch create mode 100644 6.1/target/linux/ipq40xx/config-6.1 create mode 100644 6.1/target/linux/ipq40xx/files/drivers/net/phy/qca807x.c create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/104-clk-fix-apss-cpu-overclocking.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/300-clk-qcom-ipq4019-add-ess-reset.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/301-arm-compressed-add-appended-DTB-section.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/302-arm-compressed-set-ipq40xx-watchdog-to-allow-boot.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/400-mmc-sdhci-sdhci-msm-use-sdhci_set_clock-instead-of-s.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/420-firmware-qcom-scm-disable-SDI.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/421-firmware-qcom-scm-cold-boot-address.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/444-mtd-nand-rawnand-add-support-for-Toshiba-TC58NVG0S3H.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/700-skbuff-add-DSA-specific-data-to-struct-skb_shared_in.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/701-net-dsa-tag_ipq4019-add-shinfo-based-tagging-driver-.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/703-arm-dts-ipq4019-add-ethernet-controller-DT-node.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/704-net-phy-define-PSGMII-PHY-interface-mode.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/706-arm-dts-ipq4019-add-switch-node.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/707-dt-bindings-net-add-QCA807x-PHY.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/708-net-phy-Add-Qualcom-QCA807x-driver.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/709-arm-dts-ipq4019-QCA807x-properties.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/850-soc-add-qualcomm-syscon.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/998-lantiq-atm-hacks.patch create mode 100644 6.1/target/linux/ipq40xx/patches-6.1/999-atm-mpoa-intel-dsl-phy-support.patch diff --git a/6.1/package/kernel/lantiq/ltq-ifxos/patches/003-fix-kernel-6.1-compile.patch b/6.1/package/kernel/lantiq/ltq-ifxos/patches/003-fix-kernel-6.1-compile.patch new file mode 100644 index 00000000..af6dc6b9 --- /dev/null +++ b/6.1/package/kernel/lantiq/ltq-ifxos/patches/003-fix-kernel-6.1-compile.patch @@ -0,0 +1,15 @@ +--- a/src/linux/ifxos_linux_thread_drv.c 2023-05-22 08:50:14.087507831 +0200 ++++ b/src/linux/ifxos_linux_thread_drv.c 2023-05-22 08:51:32.702129369 +0200 +@@ -154,8 +154,11 @@ + retVal = pThrCntrl->pThrFct(&pThrCntrl->thrParams); + pThrCntrl->thrParams.bRunning = IFX_FALSE; + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0)) + complete_and_exit(&pThrCntrl->thrCompletion, (long)retVal); +- ++#else ++ kthread_complete_and_exit(&pThrCntrl->thrCompletion, (long)retVal); ++#endif + IFXOS_PRN_USR_DBG_NL( IFXOS, IFXOS_PRN_LEVEL_NORMAL, + ("EXIT - Kernel Thread Startup <%s>" IFXOS_CRLF, + pThrCntrl->thrParams.pName)); diff --git a/6.1/package/kernel/lantiq/ltq-vdsl-vr11-mei/patches/301-fix-kernel-6.1-compile.patch b/6.1/package/kernel/lantiq/ltq-vdsl-vr11-mei/patches/301-fix-kernel-6.1-compile.patch new file mode 100644 index 00000000..5bb10d38 --- /dev/null +++ b/6.1/package/kernel/lantiq/ltq-vdsl-vr11-mei/patches/301-fix-kernel-6.1-compile.patch @@ -0,0 +1,22 @@ +--- a/src/drv_mei_cpe_linux.c 2023-05-22 14:07:34.356721319 +0200 ++++ b/src/drv_mei_cpe_linux.c 2023-05-22 14:08:02.328250656 +0200 +@@ -2062,7 +2062,7 @@ + + static int mei_proc_single_open(struct inode *inode, struct file *file) + { +- return single_open(file, mei_seq_single_show, PDE_DATA(inode)); ++ return single_open(file, mei_seq_single_show, pde_data(inode)); + } + + static void mei_proc_entry_create(struct proc_dir_entry *parent_node, +--- a/src/drv_mei_cpe_linux_proc_config.c 2023-05-22 14:12:26.251818708 +0200 ++++ b/src/drv_mei_cpe_linux_proc_config.c 2023-05-22 14:12:51.219401891 +0200 +@@ -1274,7 +1274,7 @@ + + static int mei_proc_single_open(struct inode *inode, struct file *file) + { +- return single_open(file, mei_seq_single_show, PDE_DATA(inode)); ++ return single_open(file, mei_seq_single_show, pde_data(inode)); + } + + static struct proc_ops proc_ops = { diff --git a/6.1/package/kernel/lantiq/vrx518_ep/patches/101-fix-kernel-6.1-compile.patch b/6.1/package/kernel/lantiq/vrx518_ep/patches/101-fix-kernel-6.1-compile.patch new file mode 100644 index 00000000..7d0a1346 --- /dev/null +++ b/6.1/package/kernel/lantiq/vrx518_ep/patches/101-fix-kernel-6.1-compile.patch @@ -0,0 +1,18 @@ +--- a/ep.c 2023-05-22 10:23:11.790142567 +0200 ++++ b/ep.c 2023-05-22 10:27:23.029791914 +0200 +@@ -589,13 +589,13 @@ + /* Target structures have a limit of 32 bit DMA pointers. + * DMA pointers can be wider than 32 bits by default on some systems. + */ +- ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); ++ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "32-bit DMA not available: %d\n", ret); + goto err_region; + } + +- ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); ++ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "cannot enable 32-bit consistent DMA\n"); + goto err_region; diff --git a/6.1/package/kernel/lantiq/vrx518_tc/patches/301-fix-kernel-6.1-compile.patch b/6.1/package/kernel/lantiq/vrx518_tc/patches/301-fix-kernel-6.1-compile.patch new file mode 100644 index 00000000..60d106e2 --- /dev/null +++ b/6.1/package/kernel/lantiq/vrx518_tc/patches/301-fix-kernel-6.1-compile.patch @@ -0,0 +1,325 @@ +--- a/dcdp/ptm_tc.c 2023-05-22 11:06:09.177510131 +0200 ++++ b/dcdp/ptm_tc.c 2023-05-22 11:37:23.765131033 +0200 +@@ -659,7 +659,11 @@ + memcpy(ptm_tc->outq_map, def_outq_map, sizeof(def_outq_map)); + SET_NETDEV_DEV(ptm_tc->dev, tc_priv->ep_dev[id].dev); + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0) ++ netif_napi_add(ptm_tc->dev, &ptm_tc->napi_rx, tc_priv->tc_ops.napi_rx); ++#else + netif_napi_add(ptm_tc->dev, &ptm_tc->napi_rx, tc_priv->tc_ops.napi_rx, NAPI_POLL_WEIGHT); ++#endif + netif_tx_napi_add(ptm_tc->dev, &ptm_tc->napi_tx, tc_priv->tc_ops.napi_tx, NAPI_POLL_WEIGHT); + + err = register_netdev(ptm_tc->dev); +@@ -3125,7 +3129,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct ptm_ep_priv *)pde_data(file_inode(file)); + + len = count < sizeof(str) ? count : sizeof(str) - 1; + rlen = len - copy_from_user(str, buf, len); +@@ -3335,7 +3339,7 @@ + local_buf[len] = 0; + + num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list)); +- priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct ptm_ep_priv *)pde_data(file_inode(file)); + if (priv == NULL) { + pr_err("%s: Invalid private data\n", __func__); + return -EINVAL; +--- a/dcdp/inc/ptm_tc.h 2023-05-22 11:24:47.982177396 +0200 ++++ b/dcdp/inc/ptm_tc.h 2023-05-22 11:25:34.313376656 +0200 +@@ -76,6 +76,9 @@ + #define SFSM_DBACE 0x6000 + #define SFSM_CBACE 0x7100 + ++ ++#define netif_tx_napi_add netif_napi_add_tx_weight ++ + enum { + US_DMA_PRE_RXCH = 0, + US_DMA_PRE_TXCH, +--- a/dcdp/tc_proc.c 2023-05-22 11:58:32.715356238 +0200 ++++ b/dcdp/tc_proc.c 2023-05-22 11:59:13.454660657 +0200 +@@ -343,7 +343,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = ((struct tc_comm *)PDE_DATA(file_inode(file))); ++ priv = ((struct tc_comm *)pde_data(file_inode(file))); + if (priv == NULL) { + pr_err("%s: Invalid priv data\n", __func__); + return -EFAULT; +@@ -476,7 +476,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = ((struct tc_comm *)PDE_DATA(file_inode(file))); ++ priv = ((struct tc_comm *)pde_data(file_inode(file))); + if (priv == NULL) { + pr_err("%s: priv pointer is NULL!!!\n", __func__); + return -EINVAL; +@@ -746,7 +746,7 @@ + + static int proc_read_pp32_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_pp32, PDE_DATA(inode)); ++ return single_open(file, proc_read_pp32, pde_data(inode)); + } + + static const struct proc_ops pp32_proc_fops = { +@@ -822,7 +822,7 @@ + len = count < sizeof(str) ? count : sizeof(str) - 1; + rlen = len - copy_from_user(str, buf, len); + str[rlen] = 0; +- priv = (struct tc_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct tc_priv *)pde_data(file_inode(file)); + if (priv == NULL) + return count; + +@@ -862,7 +862,7 @@ + + static int proc_read_tc_cfg_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_tc_cfg, PDE_DATA(inode)); ++ return single_open(file, proc_read_tc_cfg, pde_data(inode)); + } + + static const struct proc_ops tc_cfg_proc_fops = { +@@ -888,7 +888,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = (struct tc_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct tc_priv *)pde_data(file_inode(file)); + if (priv == NULL) + return count; + +@@ -947,7 +947,7 @@ + + static int proc_read_dbg_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_dbg, PDE_DATA(inode)); ++ return single_open(file, proc_read_dbg, pde_data(inode)); + } + + static const struct proc_ops tc_dbg_proc_fops = { +@@ -970,7 +970,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = (struct tc_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct tc_priv *)pde_data(file_inode(file)); + + len = count < sizeof(str) ? count : sizeof(str) - 1; + rlen = len - copy_from_user(str, buf, len); +@@ -1033,7 +1033,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = (struct tc_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct tc_priv *)pde_data(file_inode(file)); + + len = count < sizeof(str) ? count : sizeof(str) - 1; + rlen = len - copy_from_user(str, buf, len); +@@ -1125,7 +1125,7 @@ + + static int proc_read_ver_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_ver, PDE_DATA(inode)); ++ return single_open(file, proc_read_ver, pde_data(inode)); + } + + static const struct proc_ops tc_ver_proc_fops = { +@@ -1159,7 +1159,7 @@ + + static int proc_read_soc_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_soc, PDE_DATA(inode)); ++ return single_open(file, proc_read_soc, pde_data(inode)); + } + + static const struct proc_ops tc_soc_proc_fops = { +@@ -1185,7 +1185,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = (struct tc_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct tc_priv *)pde_data(file_inode(file)); + if (priv == NULL) + return count; + +@@ -1264,7 +1264,7 @@ + + static int proc_read_desc_conf_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_desc_conf, PDE_DATA(inode)); ++ return single_open(file, proc_read_desc_conf, pde_data(inode)); + } + #endif + +@@ -1343,7 +1343,7 @@ + + static int proc_read_ptm_wanmib_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_ptm_wanmib, PDE_DATA(inode)); ++ return single_open(file, proc_read_ptm_wanmib, pde_data(inode)); + } + + static const struct proc_ops ptm_wanmib_proc_fops = { +@@ -1382,7 +1382,7 @@ + + static int proc_read_cfg_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_ptm_read_cfg, PDE_DATA(inode)); ++ return single_open(file, proc_ptm_read_cfg, pde_data(inode)); + } + + static ssize_t ptm_cfg_proc_write(struct file *file, +@@ -1398,7 +1398,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct ptm_ep_priv *)pde_data(file_inode(file)); + if (priv == NULL) { + pr_err("%s: Invalid private data\n", __func__); + return -EINVAL; +@@ -1478,7 +1478,7 @@ + p1 = local_buf; + + num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list)); +- priv = (struct ptm_ep_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct ptm_ep_priv *)pde_data(file_inode(file)); + + if (priv == NULL) { + pr_err("%s: Invalid private data\n", __func__); +@@ -1554,7 +1554,7 @@ + + static int proc_ptm_read_prio_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_ptm_read_prio, PDE_DATA(inode)); ++ return single_open(file, proc_ptm_read_prio, pde_data(inode)); + } + + static const struct proc_ops ptm_prio_proc_fops = { +@@ -1567,7 +1567,7 @@ + + static int proc_ptm_read_bond_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_ptm_read_bond, PDE_DATA(inode)); ++ return single_open(file, proc_ptm_read_bond, pde_data(inode)); + } + + static const struct proc_ops ptm_bond_proc_fops = { +@@ -1580,7 +1580,7 @@ + static int proc_ptm_read_bondmib_seq_open(struct inode *inode, + struct file *file) + { +- return single_open(file, proc_ptm_read_bondmib, PDE_DATA(inode)); ++ return single_open(file, proc_ptm_read_bondmib, pde_data(inode)); + } + + static const struct proc_ops ptm_bondmib_proc_fops = { +@@ -1983,7 +1983,7 @@ + + num = vrx_split_buffer(local_buf, param_list, + ARRAY_SIZE(param_list)); +- priv = (struct tc_comm *)PDE_DATA(file_inode(file)); ++ priv = (struct tc_comm *)pde_data(file_inode(file)); + if (priv == NULL) { + pr_err("<%s>: Invalid private data\n", __func__); + return count; +@@ -2158,7 +2158,7 @@ + + static int proc_read_atm_cfg_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_atm_cfg, PDE_DATA(inode)); ++ return single_open(file, proc_read_atm_cfg, pde_data(inode)); + } + + static ssize_t atm_cfg_proc_write(struct file *file, +@@ -2174,7 +2174,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = (struct atm_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct atm_priv *)pde_data(file_inode(file)); + + if (!access_ok(buf, count)) + return -EFAULT; +@@ -2238,7 +2238,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- priv = (struct atm_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct atm_priv *)pde_data(file_inode(file)); + if (priv == NULL) { + pr_err("%s: Invalid private data\n", __func__); + return -EINVAL; +@@ -2266,7 +2266,7 @@ + static int proc_read_atm_wanmib_seq_open(struct inode *inode, + struct file *file) + { +- return single_open(file, proc_read_atm_wanmib, PDE_DATA(inode)); ++ return single_open(file, proc_read_atm_wanmib, pde_data(inode)); + } + + +@@ -2281,7 +2281,7 @@ + + static int proc_read_htu_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_htu, PDE_DATA(inode)); ++ return single_open(file, proc_read_htu, pde_data(inode)); + } + + static const struct proc_ops htu_proc_fops = { +@@ -2293,7 +2293,7 @@ + + static int proc_read_queue_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_read_queue, PDE_DATA(inode)); ++ return single_open(file, proc_read_queue, pde_data(inode)); + } + + static const struct proc_ops queue_proc_fops = { +@@ -2350,7 +2350,7 @@ + p1 = local_buf; + + num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list)); +- priv = (struct atm_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct atm_priv *)pde_data(file_inode(file)); + if (vrx_strcmpi(param_list[0], "help") == 0) + goto proc_atm_prio_help; + else if (vrx_strcmpi(param_list[0], "pvc") == 0) { +@@ -2513,7 +2513,7 @@ + + static int proc_atm_read_prio_seq_open(struct inode *inode, struct file *file) + { +- return single_open(file, proc_atm_read_prio, PDE_DATA(inode)); ++ return single_open(file, proc_atm_read_prio, pde_data(inode)); + } + + static const struct seq_operations pvc_mib_seq_ops = { +@@ -2536,7 +2536,7 @@ + int ret = seq_open(file, &pvc_mib_seq_ops); + if (ret == 0) { + struct seq_file *m = file->private_data; +- m->private = PDE_DATA(inode); ++ m->private = pde_data(inode); + } + return ret; + } +@@ -2574,7 +2574,7 @@ + local_buf[len] = 0; + + num = vrx_split_buffer(local_buf, param_list, ARRAY_SIZE(param_list)); +- priv = (struct atm_priv *)PDE_DATA(file_inode(file)); ++ priv = (struct atm_priv *)pde_data(file_inode(file)); + if (priv == NULL) { + pr_err("<%s>: Invalid private data\n", __func__); + return count; diff --git a/6.1/target/linux/ipq40xx/config-6.1 b/6.1/target/linux/ipq40xx/config-6.1 new file mode 100644 index 00000000..c758aeed --- /dev/null +++ b/6.1/target/linux/ipq40xx/config-6.1 @@ -0,0 +1,533 @@ +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_APQ_GCC_8084 is not set +# CONFIG_APQ_MMCC_8084 is not set +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_FORCE_MAX_ORDER=11 +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_IPQ40XX=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +# CONFIG_ARCH_MDM9615 is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_ARCH_MSM8909 is not set +# CONFIG_ARCH_MSM8916 is not set +# CONFIG_ARCH_MSM8960 is not set +# CONFIG_ARCH_MSM8974 is not set +# CONFIG_ARCH_MSM8X60 is not set +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_ATAG_DTB_COMPAT is not set +CONFIG_ARM_CPUIDLE=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +CONFIG_ARM_CRYPTO=y +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_QCOM_CPUFREQ_HW is not set +# CONFIG_ARM_QCOM_CPUFREQ_NVMEM is not set +# CONFIG_ARM_QCOM_SPM_CPUIDLE is not set +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_AT803X_PHY=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BCH=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BOUNCE=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CLKSRC_QCOM=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE_PARTITION=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_QCOM=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +CONFIG_CPU_THERMAL=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CRC8=y +CONFIG_CRYPTO_AES_ARM=y +CONFIG_CRYPTO_AES_ARM_BS=y +CONFIG_CRYPTO_BLAKE2S_ARM=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_DEV_QCE=y +# CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set +# CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL is not set +# CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set +CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER=y +CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y +CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 +CONFIG_CRYPTO_DEV_QCOM_RNG=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_DES=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA256_ARM=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SIMD=y +CONFIG_CRYPTO_XTS=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +CONFIG_DEBUG_MISC=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DTC=y +CONFIG_DT_IDLE_STATES=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EEPROM_AT24=y +CONFIG_EXTCON=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FWNODE_MDIO=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_VDSO_32=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_74X164=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_WATCHDOG=y +CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_SMP=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_QCOM=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_OPTEE=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +# CONFIG_I2C_QCOM_CCI is not set +CONFIG_I2C_QUP=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IO_URING=y +# CONFIG_IPQ_APSS_PLL is not set +CONFIG_IPQ_GCC_4019=y +# CONFIG_IPQ_GCC_6018 is not set +# CONFIG_IPQ_GCC_806X is not set +# CONFIG_IPQ_GCC_8074 is not set +# CONFIG_IPQ_LCC_806X is not set +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_KMAP_LOCAL=y +CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y +# CONFIG_KPSS_XCC is not set +# CONFIG_KRAITCC is not set +CONFIG_LEDS_LP5523=y +CONFIG_LEDS_LP5562=y +CONFIG_LEDS_LP55XX_COMMON=y +CONFIG_LEDS_TLC591XX=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_GPIO=y +CONFIG_MDIO_IPQ4019=y +# CONFIG_MDM_GCC_9615 is not set +# CONFIG_MDM_LCC_9615 is not set +CONFIG_MEMFD_CREATE=y +# CONFIG_MFD_HI6421_SPMI is not set +# CONFIG_MFD_QCOM_RPM is not set +# CONFIG_MFD_SPMI_PMIC is not set +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +# CONFIG_MSM_GCC_8909 is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +CONFIG_MMC_SDHCI_MSM=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MSM_GCC_8660 is not set +# CONFIG_MSM_GCC_8916 is not set +# CONFIG_MSM_GCC_8939 is not set +# CONFIG_MSM_GCC_8960 is not set +# CONFIG_MSM_GCC_8974 is not set +# CONFIG_MSM_GCC_8976 is not set +# CONFIG_MSM_GCC_8994 is not set +# CONFIG_MSM_GCC_8996 is not set +# CONFIG_MSM_GCC_8998 is not set +# CONFIG_MSM_GPUCC_8998 is not set +# CONFIG_MSM_LCC_8960 is not set +# CONFIG_MSM_MMCC_8960 is not set +# CONFIG_MSM_MMCC_8974 is not set +# CONFIG_MSM_MMCC_8996 is not set +# CONFIG_MSM_MMCC_8998 is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_SW_BCH=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_NAND_QCOM=y +# CONFIG_MTD_QCOMSMEM_PARTS is not set +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_SPLIT_WRGG_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEON=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_QCA8K_IPQ4019=y +CONFIG_NET_DSA_TAG_IPQ4019=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NLS=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +CONFIG_NVMEM_QCOM_QFPROM=y +# CONFIG_NVMEM_SPMI_SDAM is not set +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OPTEE=y +CONFIG_OPTEE_SHM_NUM_PRIV_PAGES=1 +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +CONFIG_PCIE_QCOM=y +CONFIG_PCI_DISABLE_COMMON_QUIRKS=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +# CONFIG_PHY_QCOM_APQ8064_SATA is not set +CONFIG_PHY_QCOM_IPQ4019_USB=y +# CONFIG_PHY_QCOM_IPQ806X_SATA is not set +# CONFIG_PHY_QCOM_IPQ806X_USB is not set +# CONFIG_PHY_QCOM_PCIE2 is not set +# CONFIG_PHY_QCOM_QMP is not set +# CONFIG_PHY_QCOM_QUSB2 is not set +# CONFIG_PHY_QCOM_USB_HS_28NM is not set +# CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2 is not set +# CONFIG_PHY_QCOM_USB_SS is not set +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_APQ8064 is not set +# CONFIG_PINCTRL_APQ8084 is not set +CONFIG_PINCTRL_IPQ4019=y +# CONFIG_PINCTRL_IPQ6018 is not set +# CONFIG_PINCTRL_IPQ8064 is not set +# CONFIG_PINCTRL_IPQ8074 is not set +# CONFIG_PINCTRL_MDM9615 is not set +CONFIG_PINCTRL_MSM=y +# CONFIG_PINCTRL_MSM8226 is not set +# CONFIG_PINCTRL_MSM8660 is not set +# CONFIG_PINCTRL_MSM8909 is not set +# CONFIG_PINCTRL_MSM8916 is not set +# CONFIG_PINCTRL_MSM8960 is not set +# CONFIG_PINCTRL_MSM8976 is not set +# CONFIG_PINCTRL_MSM8994 is not set +# CONFIG_PINCTRL_MSM8996 is not set +# CONFIG_PINCTRL_MSM8998 is not set +# CONFIG_PINCTRL_QCOM_SPMI_PMIC is not set +# CONFIG_PINCTRL_QCOM_SSBI_PMIC is not set +# CONFIG_PINCTRL_QCS404 is not set +# CONFIG_PINCTRL_SC7180 is not set +# CONFIG_PINCTRL_SDM660 is not set +# CONFIG_PINCTRL_SDM845 is not set +# CONFIG_PINCTRL_SM8150 is not set +# CONFIG_PINCTRL_SM8250 is not set +# CONFIG_PINCTRL_SDX65 is not set +# CONFIG_PHY_QCOM_EDP is not set +CONFIG_PM_OPP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_MSM=y +CONFIG_POWER_SUPPLY=y +CONFIG_PPS=y +CONFIG_PRINTK_TIME=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_QCA807X_PHY=y +# CONFIG_QCM_GCC_2290 is not set +# CONFIG_QCM_DISPCC_2290 is not set +CONFIG_QCOM_A53PLL=y +# CONFIG_QCOM_ADM is not set +CONFIG_QCOM_BAM_DMA=y +# CONFIG_QCOM_COMMAND_DB is not set +# CONFIG_QCOM_CPR is not set +# CONFIG_QCOM_EBI2 is not set +# CONFIG_QCOM_GENI_SE is not set +# CONFIG_QCOM_GSBI is not set +# CONFIG_QCOM_HFPLL is not set +# CONFIG_QCOM_ICC_BWMON is not set +# CONFIG_QCOM_IOMMU is not set +CONFIG_QCOM_IPQ4019_ESS_EDMA=y +# CONFIG_QCOM_LLCC is not set +# CONFIG_QCOM_OCMEM is not set +# CONFIG_QCOM_PDC is not set +# CONFIG_QCOM_RMTFS_MEM is not set +# CONFIG_QCOM_RPMH is not set +CONFIG_QCOM_SCM=y +# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set +CONFIG_QCOM_SMEM=y +# CONFIG_QCOM_SMSM is not set +# CONFIG_QCOM_SOCINFO is not set +# CONFIG_QCOM_SPM is not set +# CONFIG_QCOM_STATS is not set +CONFIG_QCOM_TCSR=y +# CONFIG_QCOM_TSENS is not set +CONFIG_QCOM_WDT=y +# CONFIG_QCS_GCC_404 is not set +# CONFIG_QCS_Q6SSTOP_404 is not set +# CONFIG_QCS_TURING_404 is not set +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_QCOM_LABIBB is not set +# CONFIG_REGULATOR_QCOM_SPMI is not set +# CONFIG_REGULATOR_QCOM_USB_VBUS is not set +CONFIG_REGULATOR_VCTRL=y +CONFIG_REGULATOR_VQMMC_IPQ4019=y +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_QCOM_AOSS is not set +# CONFIG_RESET_QCOM_PDC is not set +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_OPTEE is not set +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_MC146818_LIB=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +# CONFIG_SC_CAMCC_7280 is not set +# CONFIG_SC_DISPCC_7180 is not set +# CONFIG_SC_GCC_7180 is not set +# CONFIG_SC_GCC_8280XP is not set +# CONFIG_SC_GPUCC_7180 is not set +# CONFIG_SC_LPASS_CORECC_7180 is not set +# CONFIG_SC_LPASSCC_7280 is not set +# CONFIG_SC_LPASS_CORECC_7280 is not set +# CONFIG_SC_MSS_7180 is not set +# CONFIG_SC_VIDEOCC_7180 is not set +# CONFIG_SDM_CAMCC_845 is not set +# CONFIG_SDM_DISPCC_845 is not set +# CONFIG_SDM_GCC_660 is not set +# CONFIG_SDM_GCC_845 is not set +# CONFIG_SDM_GPUCC_845 is not set +# CONFIG_SDM_LPASSCC_845 is not set +# CONFIG_SDM_VIDEOCC_845 is not set +# CONFIG_SDX_GCC_65 is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +# CONFIG_SM_CAMCC_8450 is not set +# CONFIG_SM_GCC_8150 is not set +# CONFIG_SM_GCC_8250 is not set +# CONFIG_SM_GCC_8450 is not set +# CONFIG_SM_GPUCC_6350 is not set +# CONFIG_SM_GPUCC_8150 is not set +# CONFIG_SM_GPUCC_8250 is not set +# CONFIG_SM_GPUCC_8350 is not set +# CONFIG_SM_VIDEOCC_8150 is not set +# CONFIG_SM_VIDEOCC_8250 is not set +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_GPIO=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_QUP=y +CONFIG_SPMI=y +# CONFIG_SPMI_HISI3670 is not set +CONFIG_SPMI_MSM_PMIC_ARB=y +# CONFIG_SPMI_PMIC_CLKDIV is not set +CONFIG_SRCU=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TEE=y +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +# CONFIG_TRUSTED_KEYS_TEE is not set +CONFIG_UBIFS_FS=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNWINDER_ARM=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +CONFIG_USB_SUPPORT=y +CONFIG_USE_OF=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/6.1/target/linux/ipq40xx/files/drivers/net/phy/qca807x.c b/6.1/target/linux/ipq40xx/files/drivers/net/phy/qca807x.c new file mode 100644 index 00000000..ea61b53d --- /dev/null +++ b/6.1/target/linux/ipq40xx/files/drivers/net/phy/qca807x.c @@ -0,0 +1,859 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 Sartura Ltd. + * + * Author: Robert Marko + * + * Qualcomm QCA8072 and QCA8075 PHY driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PHY_ID_QCA8072 0x004dd0b2 +#define PHY_ID_QCA8075 0x004dd0b1 +#define PHY_ID_QCA807X_PSGMII 0x06820805 + +/* Downshift */ +#define QCA807X_SMARTSPEED_EN BIT(5) +#define QCA807X_SMARTSPEED_RETRY_LIMIT_MASK GENMASK(4, 2) +#define QCA807X_SMARTSPEED_RETRY_LIMIT_DEFAULT 5 +#define QCA807X_SMARTSPEED_RETRY_LIMIT_MIN 2 +#define QCA807X_SMARTSPEED_RETRY_LIMIT_MAX 9 + +/* Cable diagnostic test (CDT) */ +#define QCA807X_CDT 0x16 +#define QCA807X_CDT_ENABLE BIT(15) +#define QCA807X_CDT_ENABLE_INTER_PAIR_SHORT BIT(13) +#define QCA807X_CDT_STATUS BIT(11) +#define QCA807X_CDT_MMD3_STATUS 0x8064 +#define QCA807X_CDT_MDI0_STATUS_MASK GENMASK(15, 12) +#define QCA807X_CDT_MDI1_STATUS_MASK GENMASK(11, 8) +#define QCA807X_CDT_MDI2_STATUS_MASK GENMASK(7, 4) +#define QCA807X_CDT_MDI3_STATUS_MASK GENMASK(3, 0) +#define QCA807X_CDT_RESULTS_INVALID 0x0 +#define QCA807X_CDT_RESULTS_OK 0x1 +#define QCA807X_CDT_RESULTS_OPEN 0x2 +#define QCA807X_CDT_RESULTS_SAME_SHORT 0x3 +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OK 0x4 +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OK 0x8 +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OK 0xc +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OPEN 0x6 +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OPEN 0xa +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OPEN 0xe +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_SHORT 0x7 +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_SHORT 0xb +#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_SHORT 0xf +#define QCA807X_CDT_RESULTS_BUSY 0x9 +#define QCA807X_CDT_MMD3_MDI0_LENGTH 0x8065 +#define QCA807X_CDT_MMD3_MDI1_LENGTH 0x8066 +#define QCA807X_CDT_MMD3_MDI2_LENGTH 0x8067 +#define QCA807X_CDT_MMD3_MDI3_LENGTH 0x8068 +#define QCA807X_CDT_SAME_SHORT_LENGTH_MASK GENMASK(15, 8) +#define QCA807X_CDT_CROSS_SHORT_LENGTH_MASK GENMASK(7, 0) + +#define QCA807X_CHIP_CONFIGURATION 0x1f +#define QCA807X_BT_BX_REG_SEL BIT(15) +#define QCA807X_BT_BX_REG_SEL_FIBER 0 +#define QCA807X_BT_BX_REG_SEL_COPPER 1 +#define QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK GENMASK(3, 0) +#define QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII 4 +#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER 3 +#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER 0 + +#define QCA807X_MEDIA_SELECT_STATUS 0x1a +#define QCA807X_MEDIA_DETECTED_COPPER BIT(5) +#define QCA807X_MEDIA_DETECTED_1000_BASE_X BIT(4) +#define QCA807X_MEDIA_DETECTED_100_BASE_FX BIT(3) + +#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION 0x807e +#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN BIT(0) + +#define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a +#define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0) + +#define QCA807X_MMD7_LED_100N_1 0x8074 +#define QCA807X_MMD7_LED_100N_2 0x8075 +#define QCA807X_MMD7_LED_1000N_1 0x8076 +#define QCA807X_MMD7_LED_1000N_2 0x8077 +#define QCA807X_LED_TXACT_BLK_EN_2 BIT(10) +#define QCA807X_LED_RXACT_BLK_EN_2 BIT(9) +#define QCA807X_LED_GT_ON_EN_2 BIT(6) +#define QCA807X_LED_HT_ON_EN_2 BIT(5) +#define QCA807X_LED_BT_ON_EN_2 BIT(4) +#define QCA807X_GPIO_FORCE_EN BIT(15) +#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) + +#define QCA807X_INTR_ENABLE 0x12 +#define QCA807X_INTR_STATUS 0x13 +#define QCA807X_INTR_ENABLE_AUTONEG_ERR BIT(15) +#define QCA807X_INTR_ENABLE_SPEED_CHANGED BIT(14) +#define QCA807X_INTR_ENABLE_DUPLEX_CHANGED BIT(13) +#define QCA807X_INTR_ENABLE_LINK_FAIL BIT(11) +#define QCA807X_INTR_ENABLE_LINK_SUCCESS BIT(10) + +#define QCA807X_FUNCTION_CONTROL 0x10 +#define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) +#define QCA807X_FC_MDI_CROSSOVER_AUTO 3 +#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX 1 +#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI 0 + +#define QCA807X_PHY_SPECIFIC_STATUS 0x11 +#define QCA807X_SS_SPEED_AND_DUPLEX_RESOLVED BIT(11) +#define QCA807X_SS_SPEED_MASK GENMASK(15, 14) +#define QCA807X_SS_SPEED_1000 2 +#define QCA807X_SS_SPEED_100 1 +#define QCA807X_SS_SPEED_10 0 +#define QCA807X_SS_DUPLEX BIT(13) +#define QCA807X_SS_MDIX BIT(6) + +/* PSGMII PHY specific */ +#define PSGMII_QSGMII_DRIVE_CONTROL_1 0xb +#define PSGMII_QSGMII_TX_DRIVER_MASK GENMASK(7, 4) +#define PSGMII_MODE_CTRL 0x6d +#define PSGMII_MODE_CTRL_AZ_WORKAROUND_MASK BIT(0) +#define PSGMII_MMD3_SERDES_CONTROL 0x805a + +struct qca807x_gpio_priv { + struct phy_device *phy; +}; + +static int qca807x_get_downshift(struct phy_device *phydev, u8 *data) +{ + int val, cnt, enable; + + val = phy_read(phydev, MII_NWAYTEST); + if (val < 0) + return val; + + enable = FIELD_GET(QCA807X_SMARTSPEED_EN, val); + cnt = FIELD_GET(QCA807X_SMARTSPEED_RETRY_LIMIT_MASK, val) + 2; + + *data = enable ? cnt : DOWNSHIFT_DEV_DISABLE; + + return 0; +} + +static int qca807x_set_downshift(struct phy_device *phydev, u8 cnt) +{ + int ret, val; + + if (cnt > QCA807X_SMARTSPEED_RETRY_LIMIT_MAX || + (cnt < QCA807X_SMARTSPEED_RETRY_LIMIT_MIN && cnt != DOWNSHIFT_DEV_DISABLE)) + return -EINVAL; + + if (!cnt) { + ret = phy_clear_bits(phydev, MII_NWAYTEST, QCA807X_SMARTSPEED_EN); + } else { + val = QCA807X_SMARTSPEED_EN; + val |= FIELD_PREP(QCA807X_SMARTSPEED_RETRY_LIMIT_MASK, cnt - 2); + + phy_modify(phydev, MII_NWAYTEST, + QCA807X_SMARTSPEED_EN | + QCA807X_SMARTSPEED_RETRY_LIMIT_MASK, + val); + } + + ret = genphy_soft_reset(phydev); + + return ret; +} + +static int qca807x_get_tunable(struct phy_device *phydev, + struct ethtool_tunable *tuna, void *data) +{ + switch (tuna->id) { + case ETHTOOL_PHY_DOWNSHIFT: + return qca807x_get_downshift(phydev, data); + default: + return -EOPNOTSUPP; + } +} + +static int qca807x_set_tunable(struct phy_device *phydev, + struct ethtool_tunable *tuna, const void *data) +{ + switch (tuna->id) { + case ETHTOOL_PHY_DOWNSHIFT: + return qca807x_set_downshift(phydev, *(const u8 *)data); + default: + return -EOPNOTSUPP; + } +} + +static bool qca807x_distance_valid(int result) +{ + switch (result) { + case QCA807X_CDT_RESULTS_OPEN: + case QCA807X_CDT_RESULTS_SAME_SHORT: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OK: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OK: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OK: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OPEN: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OPEN: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OPEN: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_SHORT: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_SHORT: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_SHORT: + return true; + } + return false; +} + +static int qca807x_report_length(struct phy_device *phydev, + int pair, int result) +{ + int length; + int ret; + + ret = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA807X_CDT_MMD3_MDI0_LENGTH + pair); + if (ret < 0) + return ret; + + switch (result) { + case ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT: + length = (FIELD_GET(QCA807X_CDT_SAME_SHORT_LENGTH_MASK, ret) * 800) / 10; + break; + case ETHTOOL_A_CABLE_RESULT_CODE_OPEN: + case ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT: + length = (FIELD_GET(QCA807X_CDT_CROSS_SHORT_LENGTH_MASK, ret) * 800) / 10; + break; + } + + ethnl_cable_test_fault_length(phydev, pair, length); + + return 0; +} + +static int qca807x_cable_test_report_trans(int result) +{ + switch (result) { + case QCA807X_CDT_RESULTS_OK: + return ETHTOOL_A_CABLE_RESULT_CODE_OK; + case QCA807X_CDT_RESULTS_OPEN: + return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; + case QCA807X_CDT_RESULTS_SAME_SHORT: + return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OK: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OK: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OK: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OPEN: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OPEN: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OPEN: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_SHORT: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_SHORT: + case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_SHORT: + return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; + default: + return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; + } +} + +static int qca807x_cable_test_report(struct phy_device *phydev) +{ + int pair0, pair1, pair2, pair3; + int ret; + + ret = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA807X_CDT_MMD3_STATUS); + if (ret < 0) + return ret; + + pair0 = FIELD_GET(QCA807X_CDT_MDI0_STATUS_MASK, ret); + pair1 = FIELD_GET(QCA807X_CDT_MDI1_STATUS_MASK, ret); + pair2 = FIELD_GET(QCA807X_CDT_MDI2_STATUS_MASK, ret); + pair3 = FIELD_GET(QCA807X_CDT_MDI3_STATUS_MASK, ret); + + ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A, + qca807x_cable_test_report_trans(pair0)); + ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B, + qca807x_cable_test_report_trans(pair1)); + ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C, + qca807x_cable_test_report_trans(pair2)); + ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D, + qca807x_cable_test_report_trans(pair3)); + + if (qca807x_distance_valid(pair0)) + qca807x_report_length(phydev, 0, qca807x_cable_test_report_trans(pair0)); + if (qca807x_distance_valid(pair1)) + qca807x_report_length(phydev, 1, qca807x_cable_test_report_trans(pair1)); + if (qca807x_distance_valid(pair2)) + qca807x_report_length(phydev, 2, qca807x_cable_test_report_trans(pair2)); + if (qca807x_distance_valid(pair3)) + qca807x_report_length(phydev, 3, qca807x_cable_test_report_trans(pair3)); + + return 0; +} + +static int qca807x_cable_test_get_status(struct phy_device *phydev, + bool *finished) +{ + int val; + + *finished = false; + + val = phy_read(phydev, QCA807X_CDT); + if (!((val & QCA807X_CDT_ENABLE) && (val & QCA807X_CDT_STATUS))) { + *finished = true; + + return qca807x_cable_test_report(phydev); + } + + return 0; +} + +static int qca807x_cable_test_start(struct phy_device *phydev) +{ + int val, ret; + + val = phy_read(phydev, QCA807X_CDT); + /* Enable inter-pair short check as well */ + val &= ~QCA807X_CDT_ENABLE_INTER_PAIR_SHORT; + val |= QCA807X_CDT_ENABLE; + ret = phy_write(phydev, QCA807X_CDT, val); + + return ret; +} + +#ifdef CONFIG_GPIOLIB +static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static int qca807x_gpio_get_reg(unsigned int offset) +{ + return QCA807X_MMD7_LED_100N_2 + (offset % 2) * 2; +} + +static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); + int val; + + val = phy_read_mmd(priv->phy, MDIO_MMD_AN, qca807x_gpio_get_reg(offset)); + + return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); +} + +static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) +{ + struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); + int val; + + val = phy_read_mmd(priv->phy, MDIO_MMD_AN, qca807x_gpio_get_reg(offset)); + val &= ~QCA807X_GPIO_FORCE_MODE_MASK; + val |= QCA807X_GPIO_FORCE_EN; + val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value); + + phy_write_mmd(priv->phy, MDIO_MMD_AN, qca807x_gpio_get_reg(offset), val); +} + +static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value) +{ + qca807x_gpio_set(gc, offset, value); + + return 0; +} + +static int qca807x_gpio(struct phy_device *phydev) +{ + struct device *dev = &phydev->mdio.dev; + struct qca807x_gpio_priv *priv; + struct gpio_chip *gc; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->phy = phydev; + + gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); + if (!gc) + return -ENOMEM; + + gc->label = dev_name(dev); + gc->base = -1; + gc->ngpio = 2; + gc->parent = dev; + gc->owner = THIS_MODULE; + gc->can_sleep = true; + gc->get_direction = qca807x_gpio_get_direction; + gc->direction_output = qca807x_gpio_dir_out; + gc->get = qca807x_gpio_get; + gc->set = qca807x_gpio_set; + + return devm_gpiochip_add_data(dev, gc, priv); +} +#endif + +static int qca807x_read_copper_status(struct phy_device *phydev) +{ + int ss, err, old_link = phydev->link; + + /* Update the link, but return if there was an error */ + err = genphy_update_link(phydev); + if (err) + return err; + + /* why bother the PHY if nothing can have changed */ + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) + return 0; + + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + phydev->pause = 0; + phydev->asym_pause = 0; + + err = genphy_read_lpa(phydev); + if (err < 0) + return err; + + /* Read the QCA807x PHY-Specific Status register copper page, + * which indicates the speed and duplex that the PHY is actually + * using, irrespective of whether we are in autoneg mode or not. + */ + ss = phy_read(phydev, QCA807X_PHY_SPECIFIC_STATUS); + if (ss < 0) + return ss; + + if (ss & QCA807X_SS_SPEED_AND_DUPLEX_RESOLVED) { + int sfc; + + sfc = phy_read(phydev, QCA807X_FUNCTION_CONTROL); + if (sfc < 0) + return sfc; + + switch (FIELD_GET(QCA807X_SS_SPEED_MASK, ss)) { + case QCA807X_SS_SPEED_10: + phydev->speed = SPEED_10; + break; + case QCA807X_SS_SPEED_100: + phydev->speed = SPEED_100; + break; + case QCA807X_SS_SPEED_1000: + phydev->speed = SPEED_1000; + break; + } + if (ss & QCA807X_SS_DUPLEX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + + if (ss & QCA807X_SS_MDIX) + phydev->mdix = ETH_TP_MDI_X; + else + phydev->mdix = ETH_TP_MDI; + + switch (FIELD_GET(QCA807X_FC_MDI_CROSSOVER_MODE_MASK, sfc)) { + case QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI: + phydev->mdix_ctrl = ETH_TP_MDI; + break; + case QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX: + phydev->mdix_ctrl = ETH_TP_MDI_X; + break; + case QCA807X_FC_MDI_CROSSOVER_AUTO: + phydev->mdix_ctrl = ETH_TP_MDI_AUTO; + break; + } + } + + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) + phy_resolve_aneg_pause(phydev); + + return 0; +} + +static int qca807x_read_fiber_status(struct phy_device *phydev) +{ + int ss, err, lpa, old_link = phydev->link; + + /* Update the link, but return if there was an error */ + err = genphy_update_link(phydev); + if (err) + return err; + + /* why bother the PHY if nothing can have changed */ + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) + return 0; + + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + phydev->pause = 0; + phydev->asym_pause = 0; + + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { + lpa = phy_read(phydev, MII_LPA); + if (lpa < 0) + return lpa; + + linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, + phydev->lp_advertising, lpa & LPA_LPACK); + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, + phydev->lp_advertising, lpa & LPA_1000XFULL); + linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, + phydev->lp_advertising, lpa & LPA_1000XPAUSE); + linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, + phydev->lp_advertising, + lpa & LPA_1000XPAUSE_ASYM); + + phy_resolve_aneg_linkmode(phydev); + } + + /* Read the QCA807x PHY-Specific Status register fiber page, + * which indicates the speed and duplex that the PHY is actually + * using, irrespective of whether we are in autoneg mode or not. + */ + ss = phy_read(phydev, QCA807X_PHY_SPECIFIC_STATUS); + if (ss < 0) + return ss; + + if (ss & QCA807X_SS_SPEED_AND_DUPLEX_RESOLVED) { + switch (FIELD_GET(QCA807X_SS_SPEED_MASK, ss)) { + case QCA807X_SS_SPEED_100: + phydev->speed = SPEED_100; + break; + case QCA807X_SS_SPEED_1000: + phydev->speed = SPEED_1000; + break; + } + + if (ss & QCA807X_SS_DUPLEX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + } + + return 0; +} + +static int qca807x_read_status(struct phy_device *phydev) +{ + if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) { + switch (phydev->port) { + case PORT_FIBRE: + return qca807x_read_fiber_status(phydev); + case PORT_TP: + return qca807x_read_copper_status(phydev); + default: + return -EINVAL; + } + } else + return qca807x_read_copper_status(phydev); +} + +static int qca807x_config_intr(struct phy_device *phydev) +{ + int ret, val; + + val = phy_read(phydev, QCA807X_INTR_ENABLE); + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { + /* Check for combo port as it has fewer interrupts */ + if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { + val |= QCA807X_INTR_ENABLE_SPEED_CHANGED; + val |= QCA807X_INTR_ENABLE_LINK_FAIL; + val |= QCA807X_INTR_ENABLE_LINK_SUCCESS; + } else { + val |= QCA807X_INTR_ENABLE_AUTONEG_ERR; + val |= QCA807X_INTR_ENABLE_SPEED_CHANGED; + val |= QCA807X_INTR_ENABLE_DUPLEX_CHANGED; + val |= QCA807X_INTR_ENABLE_LINK_FAIL; + val |= QCA807X_INTR_ENABLE_LINK_SUCCESS; + } + ret = phy_write(phydev, QCA807X_INTR_ENABLE, val); + } else { + ret = phy_write(phydev, QCA807X_INTR_ENABLE, 0); + } + + return ret; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0) +static int qca807x_ack_intr(struct phy_device *phydev) +{ + int ret; + + ret = phy_read(phydev, QCA807X_INTR_STATUS); + + return (ret < 0) ? ret : 0; +} +#else +static irqreturn_t qca807x_handle_interrupt(struct phy_device *phydev) +{ + int irq_status, int_enabled; + + irq_status = phy_read(phydev, QCA807X_INTR_STATUS); + if (irq_status < 0) { + phy_error(phydev); + return IRQ_NONE; + } + + /* Read the current enabled interrupts */ + int_enabled = phy_read(phydev, QCA807X_INTR_ENABLE); + if (int_enabled < 0) { + phy_error(phydev); + return IRQ_NONE; + } + + /* See if this was one of our enabled interrupts */ + if (!(irq_status & int_enabled)) + return IRQ_NONE; + + phy_trigger_machine(phydev); + + return IRQ_HANDLED; +} +#endif + +static int qca807x_led_config(struct phy_device *phydev) +{ + struct device_node *node = phydev->mdio.dev.of_node; + bool led_config = false; + int val; + + val = phy_read_mmd(phydev, MDIO_MMD_AN, QCA807X_MMD7_LED_1000N_1); + if (val < 0) + return val; + + if (of_property_read_bool(node, "qcom,single-led-1000")) { + val |= QCA807X_LED_TXACT_BLK_EN_2; + val |= QCA807X_LED_RXACT_BLK_EN_2; + val |= QCA807X_LED_GT_ON_EN_2; + + led_config = true; + } + + if (of_property_read_bool(node, "qcom,single-led-100")) { + val |= QCA807X_LED_HT_ON_EN_2; + + led_config = true; + } + + if (of_property_read_bool(node, "qcom,single-led-10")) { + val |= QCA807X_LED_BT_ON_EN_2; + + led_config = true; + } + + if (led_config) + return phy_write_mmd(phydev, MDIO_MMD_AN, QCA807X_MMD7_LED_1000N_1, val); + else + return 0; +} + +static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) +{ + struct phy_device *phydev = upstream; + __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; + DECLARE_PHY_INTERFACE_MASK(interfaces); + phy_interface_t iface; + int ret; + + sfp_parse_support(phydev->sfp_bus, id, support, interfaces); + iface = sfp_select_interface(phydev->sfp_bus, support); + + dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface)); + + switch (iface) { + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_100BASEX: + /* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */ + ret = phy_modify(phydev, + QCA807X_CHIP_CONFIGURATION, + QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK, + QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER); + /* Enable fiber mode autodection (1000Base-X or 100Base-FX) */ + ret = phy_set_bits_mmd(phydev, + MDIO_MMD_AN, + QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION, + QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN); + /* Select fiber page */ + ret = phy_clear_bits(phydev, + QCA807X_CHIP_CONFIGURATION, + QCA807X_BT_BX_REG_SEL); + + phydev->port = PORT_FIBRE; + break; + default: + dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n"); + return -EINVAL; + } + + return ret; +} + +static void qca807x_sfp_remove(void *upstream) +{ + struct phy_device *phydev = upstream; + + /* Select copper page */ + phy_set_bits(phydev, + QCA807X_CHIP_CONFIGURATION, + QCA807X_BT_BX_REG_SEL); + + phydev->port = PORT_TP; +} + +static const struct sfp_upstream_ops qca807x_sfp_ops = { + .attach = phy_sfp_attach, + .detach = phy_sfp_detach, + .module_insert = qca807x_sfp_insert, + .module_remove = qca807x_sfp_remove, +}; + +static int qca807x_config(struct phy_device *phydev) +{ + struct device_node *node = phydev->mdio.dev.of_node; + int control_dac, ret = 0; + u32 of_control_dac; + + /* Check for Combo port */ + if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { + int psgmii_serdes; + + /* Prevent PSGMII going into hibernation via PSGMII self test */ + psgmii_serdes = phy_read_mmd(phydev, MDIO_MMD_PCS, PSGMII_MMD3_SERDES_CONTROL); + psgmii_serdes &= ~BIT(1); + ret = phy_write_mmd(phydev, MDIO_MMD_PCS, + PSGMII_MMD3_SERDES_CONTROL, + psgmii_serdes); + } + + if (!of_property_read_u32(node, "qcom,control-dac", &of_control_dac)) { + control_dac = phy_read_mmd(phydev, MDIO_MMD_AN, + QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH); + control_dac &= ~QCA807X_CONTROL_DAC_MASK; + control_dac |= FIELD_PREP(QCA807X_CONTROL_DAC_MASK, of_control_dac); + ret = phy_write_mmd(phydev, MDIO_MMD_AN, + QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH, + control_dac); + } + + /* Optionally configure LED-s */ + if (IS_ENABLED(CONFIG_GPIOLIB)) { + /* Check whether PHY-s pins are used as GPIO-s */ + if (!of_property_read_bool(node, "gpio-controller")) + ret = qca807x_led_config(phydev); + } else { + ret = qca807x_led_config(phydev); + } + + return ret; +} + +static int qca807x_probe(struct phy_device *phydev) +{ + struct device_node *node = phydev->mdio.dev.of_node; + int ret = 0; + + if (IS_ENABLED(CONFIG_GPIOLIB)) { + /* Do not register a GPIO controller unless flagged for it */ + if (of_property_read_bool(node, "gpio-controller")) + ret = qca807x_gpio(phydev); + } + + /* Attach SFP bus on combo port*/ + if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { + ret = phy_sfp_probe(phydev, &qca807x_sfp_ops); + linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising); + } + + return ret; +} + +static int qca807x_psgmii_config(struct phy_device *phydev) +{ + struct device_node *node = phydev->mdio.dev.of_node; + int tx_amp, ret = 0; + u32 tx_driver_strength; + + /* Workaround to enable AZ transmitting ability */ + ret = phy_clear_bits_mmd(phydev, + MDIO_MMD_PMAPMD, + PSGMII_MODE_CTRL, + PSGMII_MODE_CTRL_AZ_WORKAROUND_MASK); + + /* PSGMII/QSGMII TX amp set to DT defined value instead of default 600mV */ + if (!of_property_read_u32(node, "qcom,tx-driver-strength", &tx_driver_strength)) { + tx_amp = phy_read(phydev, PSGMII_QSGMII_DRIVE_CONTROL_1); + tx_amp &= ~PSGMII_QSGMII_TX_DRIVER_MASK; + tx_amp |= FIELD_PREP(PSGMII_QSGMII_TX_DRIVER_MASK, tx_driver_strength); + ret = phy_write(phydev, PSGMII_QSGMII_DRIVE_CONTROL_1, tx_amp); + } + + return ret; +} + +static struct phy_driver qca807x_drivers[] = { + { + PHY_ID_MATCH_EXACT(PHY_ID_QCA8072), + .name = "Qualcomm QCA8072", + .flags = PHY_POLL_CABLE_TEST, + /* PHY_GBIT_FEATURES */ + .probe = qca807x_probe, + .config_init = qca807x_config, + .read_status = qca807x_read_status, + .config_intr = qca807x_config_intr, +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0) + .ack_interrupt = qca807x_ack_intr, +#else + .handle_interrupt = qca807x_handle_interrupt, +#endif + .soft_reset = genphy_soft_reset, + .get_tunable = qca807x_get_tunable, + .set_tunable = qca807x_set_tunable, + .resume = genphy_resume, + .suspend = genphy_suspend, + .cable_test_start = qca807x_cable_test_start, + .cable_test_get_status = qca807x_cable_test_get_status, + }, + { + PHY_ID_MATCH_EXACT(PHY_ID_QCA8075), + .name = "Qualcomm QCA8075", + .flags = PHY_POLL_CABLE_TEST, + /* PHY_GBIT_FEATURES */ + .probe = qca807x_probe, + .config_init = qca807x_config, + .read_status = qca807x_read_status, + .config_intr = qca807x_config_intr, +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0) + .ack_interrupt = qca807x_ack_intr, +#else + .handle_interrupt = qca807x_handle_interrupt, +#endif + .soft_reset = genphy_soft_reset, + .get_tunable = qca807x_get_tunable, + .set_tunable = qca807x_set_tunable, + .resume = genphy_resume, + .suspend = genphy_suspend, + .cable_test_start = qca807x_cable_test_start, + .cable_test_get_status = qca807x_cable_test_get_status, + }, + { + PHY_ID_MATCH_EXACT(PHY_ID_QCA807X_PSGMII), + .name = "Qualcomm QCA807x PSGMII", + .probe = qca807x_psgmii_config, + }, +}; +module_phy_driver(qca807x_drivers); + +static struct mdio_device_id __maybe_unused qca807x_tbl[] = { + { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) }, + { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) }, + { PHY_ID_MATCH_MODEL(PHY_ID_QCA807X_PSGMII) }, + { } +}; + +MODULE_AUTHOR("Robert Marko"); +MODULE_DESCRIPTION("Qualcomm QCA807x PHY driver"); +MODULE_DEVICE_TABLE(mdio, qca807x_tbl); +MODULE_LICENSE("GPL"); diff --git a/6.1/target/linux/ipq40xx/patches-6.1/104-clk-fix-apss-cpu-overclocking.patch b/6.1/target/linux/ipq40xx/patches-6.1/104-clk-fix-apss-cpu-overclocking.patch new file mode 100644 index 00000000..2de03f7a --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/104-clk-fix-apss-cpu-overclocking.patch @@ -0,0 +1,115 @@ +From f2b87dc1028b710ec8ce25808b9d21f92b376184 Mon Sep 17 00:00:00 2001 +From: Christian Lamparter +Date: Sun, 11 Mar 2018 14:41:31 +0100 +Subject: [PATCH 2/2] clk: fix apss cpu overclocking + +There's an interaction issue between the clk changes:" +clk: qcom: ipq4019: Add the apss cpu pll divider clock node +clk: qcom: ipq4019: remove fixed clocks and add pll clocks +" and the cpufreq-dt. + +cpufreq-dt is now spamming the kernel-log with the following: + +[ 1099.190658] cpu cpu0: dev_pm_opp_set_rate: failed to find current OPP +for freq 761142857 (-34) + +This only happens on certain devices like the Compex WPJ428 +and AVM FritzBox!4040. However, other devices like the Asus +RT-AC58U and Meraki MR33 work just fine. + +The issue stem from the fact that all higher CPU-Clocks +are achieved by switching the clock-parent to the P_DDRPLLAPSS +(ddrpllapss). Which is set by Qualcomm's proprietary bootcode +as part of the DDR calibration. + +For example, the FB4040 uses 256 MiB Nanya NT5CC128M16IP clocked +at round 533 MHz (ddrpllsdcc = 190285714 Hz). + +whereas the 128 MiB Nanya NT5CC64M16GP-DI in the ASUS RT-AC58U is +clocked at a slightly higher 537 MHz ( ddrpllsdcc = 192000000 Hz). + +This patch attempts to fix the issue by modifying +clk_cpu_div_round_rate(), clk_cpu_div_set_rate(), clk_cpu_div_recalc_rate() +to use a new qcom_find_freq_close() function, which returns the closest +matching frequency, instead of the next higher. This way, the SoC in +the FB4040 (with its max clock speed of 710.4 MHz) will no longer +try to overclock to 761 MHz. + +Fixes: d83dcacea18 ("clk: qcom: ipq4019: Add the apss cpu pll divider clock node") +Signed-off-by: Christian Lamparter +Signed-off-by: John Crispin +--- + drivers/clk/qcom/gcc-ipq4019.c | 34 +++++++++++++++++++++++++++++++--- + 1 file changed, 31 insertions(+), 3 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq4019.c ++++ b/drivers/clk/qcom/gcc-ipq4019.c +@@ -1243,6 +1243,29 @@ static const struct clk_fepll_vco gcc_fe + .reg = 0x2f020, + }; + ++ ++const struct freq_tbl *qcom_find_freq_close(const struct freq_tbl *f, ++ unsigned long rate) ++{ ++ const struct freq_tbl *last = NULL; ++ ++ for ( ; f->freq; f++) { ++ if (rate == f->freq) ++ return f; ++ ++ if (f->freq > rate) { ++ if (!last || ++ (f->freq - rate) < (rate - last->freq)) ++ return f; ++ else ++ return last; ++ } ++ last = f; ++ } ++ ++ return last; ++} ++ + /* + * Round rate function for APSS CPU PLL Clock divider. + * It looks up the frequency table and returns the next higher frequency +@@ -1255,7 +1278,7 @@ static long clk_cpu_div_round_rate(struc + struct clk_hw *p_hw; + const struct freq_tbl *f; + +- f = qcom_find_freq(pll->freq_tbl, rate); ++ f = qcom_find_freq_close(pll->freq_tbl, rate); + if (!f) + return -EINVAL; + +@@ -1277,7 +1300,7 @@ static int clk_cpu_div_set_rate(struct c + const struct freq_tbl *f; + u32 mask; + +- f = qcom_find_freq(pll->freq_tbl, rate); ++ f = qcom_find_freq_close(pll->freq_tbl, rate); + if (!f) + return -EINVAL; + +@@ -1304,6 +1327,7 @@ static unsigned long + clk_cpu_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) + { ++ const struct freq_tbl *f; + struct clk_fepll *pll = to_clk_fepll(hw); + u32 cdiv, pre_div; + u64 rate; +@@ -1324,7 +1348,11 @@ clk_cpu_div_recalc_rate(struct clk_hw *h + rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2; + do_div(rate, pre_div); + +- return rate; ++ f = qcom_find_freq_close(pll->freq_tbl, rate); ++ if (!f) ++ return rate; ++ ++ return f->freq; + }; + + static const struct clk_ops clk_regmap_cpu_div_ops = { diff --git a/6.1/target/linux/ipq40xx/patches-6.1/300-clk-qcom-ipq4019-add-ess-reset.patch b/6.1/target/linux/ipq40xx/patches-6.1/300-clk-qcom-ipq4019-add-ess-reset.patch new file mode 100644 index 00000000..eb015251 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/300-clk-qcom-ipq4019-add-ess-reset.patch @@ -0,0 +1,52 @@ +From 480c1f7648fc586db12d6003c717c23667a4fcf0 Mon Sep 17 00:00:00 2001 +From: Ram Chandra Jangir +Date: Tue, 28 Mar 2017 22:35:33 +0530 +Subject: [PATCH] clk: qcom: ipq4019: add ess reset + +Added the ESS reset in IPQ4019 GCC. + +Signed-off-by: Ram Chandra Jangir +--- + drivers/clk/qcom/gcc-ipq4019.c | 11 +++++++++++ + include/dt-bindings/clock/qcom,gcc-ipq4019.h | 11 +++++++++++ + 2 files changed, 22 insertions(+) + +--- a/drivers/clk/qcom/gcc-ipq4019.c ++++ b/drivers/clk/qcom/gcc-ipq4019.c +@@ -1735,6 +1735,17 @@ static const struct qcom_reset_map gcc_i + [GCC_TCSR_BCR] = {0x22000, 0}, + [GCC_MPM_BCR] = {0x24000, 0}, + [GCC_SPDM_BCR] = {0x25000, 0}, ++ [ESS_MAC1_ARES] = {0x1200C, 0}, ++ [ESS_MAC2_ARES] = {0x1200C, 1}, ++ [ESS_MAC3_ARES] = {0x1200C, 2}, ++ [ESS_MAC4_ARES] = {0x1200C, 3}, ++ [ESS_MAC5_ARES] = {0x1200C, 4}, ++ [ESS_PSGMII_ARES] = {0x1200C, 5}, ++ [ESS_MAC1_CLK_DIS] = {0x1200C, 8}, ++ [ESS_MAC2_CLK_DIS] = {0x1200C, 9}, ++ [ESS_MAC3_CLK_DIS] = {0x1200C, 10}, ++ [ESS_MAC4_CLK_DIS] = {0x1200C, 11}, ++ [ESS_MAC5_CLK_DIS] = {0x1200C, 12}, + }; + + static const struct regmap_config gcc_ipq4019_regmap_config = { +--- a/include/dt-bindings/clock/qcom,gcc-ipq4019.h ++++ b/include/dt-bindings/clock/qcom,gcc-ipq4019.h +@@ -165,5 +165,16 @@ + #define GCC_QDSS_BCR 69 + #define GCC_MPM_BCR 70 + #define GCC_SPDM_BCR 71 ++#define ESS_MAC1_ARES 72 ++#define ESS_MAC2_ARES 73 ++#define ESS_MAC3_ARES 74 ++#define ESS_MAC4_ARES 75 ++#define ESS_MAC5_ARES 76 ++#define ESS_PSGMII_ARES 77 ++#define ESS_MAC1_CLK_DIS 78 ++#define ESS_MAC2_CLK_DIS 79 ++#define ESS_MAC3_CLK_DIS 80 ++#define ESS_MAC4_CLK_DIS 81 ++#define ESS_MAC5_CLK_DIS 82 + + #endif diff --git a/6.1/target/linux/ipq40xx/patches-6.1/301-arm-compressed-add-appended-DTB-section.patch b/6.1/target/linux/ipq40xx/patches-6.1/301-arm-compressed-add-appended-DTB-section.patch new file mode 100644 index 00000000..0448574e --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/301-arm-compressed-add-appended-DTB-section.patch @@ -0,0 +1,48 @@ +From 0843a61d6913bdac8889eb048ed89f7903059787 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 30 Oct 2020 13:36:31 +0100 +Subject: [PATCH] arm: compressed: add appended DTB section + +This adds a appended_dtb section to the ARM decompressor +linker script. + +This allows using the existing ARM zImage appended DTB support for +appending a DTB to the raw ELF kernel. + +Its size is set to 1MB max to match the zImage appended DTB size limit. + +To use it to pass the DTB to the kernel, objcopy is used: + +objcopy --set-section-flags=.appended_dtb=alloc,contents \ + --update-section=.appended_dtb=.dtb vmlinux + +This is based off the following patch: +https://github.com/openwrt/openwrt/commit/c063e27e02a9dcac0e7f5877fb154e58fa3e1a69 + +Signed-off-by: Robert Marko +--- + arch/arm/boot/compressed/vmlinux.lds.S | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/compressed/vmlinux.lds.S ++++ b/arch/arm/boot/compressed/vmlinux.lds.S +@@ -103,6 +103,13 @@ SECTIONS + + _edata = .; + ++ .appended_dtb : { ++ /* leave space for appended DTB */ ++ . += 0x100000; ++ } ++ ++ _edata_dtb = .; ++ + /* + * The image_end section appears after any additional loadable sections + * that the linker may decide to insert in the binary image. Having +@@ -140,4 +147,4 @@ SECTIONS + + ARM_ASSERTS + } +-ASSERT(_edata_real == _edata, "error: zImage file size is incorrect"); ++ASSERT(_edata_real == _edata_dtb, "error: zImage file size is incorrect"); diff --git a/6.1/target/linux/ipq40xx/patches-6.1/302-arm-compressed-set-ipq40xx-watchdog-to-allow-boot.patch b/6.1/target/linux/ipq40xx/patches-6.1/302-arm-compressed-set-ipq40xx-watchdog-to-allow-boot.patch new file mode 100644 index 00000000..51891c1f --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/302-arm-compressed-set-ipq40xx-watchdog-to-allow-boot.patch @@ -0,0 +1,66 @@ +From 11d6a6128a5a07c429941afc202b6e62a19771be Mon Sep 17 00:00:00 2001 +From: John Thomson +Date: Fri, 23 Oct 2020 19:42:36 +1000 +Subject: [PATCH 2/2] arm: compressed: set ipq40xx watchdog to allow boot + +For IPQ40XX systems where the SoC watchdog is activated before linux, +the watchdog timer may be too small for linux to finish uncompress, +boot, and watchdog management start. +If the watchdog is enabled, set the timeout for it to 30 seconds. +The functionality and offsets were copied from: +drivers/watchdog/qcom-wdt.c qcom_wdt_set_timeout & qcom_wdt_start +The watchdog memory address was taken from: +arch/arm/boot/dts/qcom-ipq4019.dtsi + +This was required on Mikrotik IPQ40XX consumer hardware using Mikrotik's +RouterBoot bootloader. + +Signed-off-by: John Thomson +--- + arch/arm/boot/compressed/head.S | 35 +++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +--- a/arch/arm/boot/compressed/head.S ++++ b/arch/arm/boot/compressed/head.S +@@ -624,6 +624,41 @@ not_relocated: mov r0, #0 + bic r4, r4, #1 + blne cache_on + ++/* Set the Qualcom IPQ40xx watchdog timeout to 30 seconds ++ * if it is enabled, so that there is time for kernel ++ * to decompress, boot, and take over the watchdog. ++ * data and functionality from drivers/watchdog/qcom-wdt.c ++ * address from arch/arm/boot/dts/qcom-ipq4019.dtsi ++ */ ++#ifdef CONFIG_ARCH_IPQ40XX ++watchdog_set: ++ /* offsets: ++ * 0x04 reset (=1 resets countdown) ++ * 0x08 enable (=0 disables) ++ * 0x0c status (=1 when SoC was reset by watchdog) ++ * 0x10 bark (=timeout warning in ticks) ++ * 0x14 bite (=timeout reset in ticks) ++ * clock rate is 1<<15 hertz ++ */ ++ .equ watchdog, 0x0b017000 @Store watchdog base address ++ movw r0, #:lower16:watchdog ++ movt r0, #:upper16:watchdog ++ ldr r1, [r0, #0x08] @Get enabled? ++ cmp r1, #1 @If not enabled, do not change ++ bne watchdog_finished ++ mov r1, #0 ++ str r1, [r0, #0x08] @Disable the watchdog ++ mov r1, #1 ++ str r1, [r0, #0x04] @Pet the watchdog ++ mov r1, #30 @30 seconds timeout ++ lsl r1, r1, #15 @converted to ticks ++ str r1, [r0, #0x10] @Set the bark timeout ++ str r1, [r0, #0x14] @Set the bite timeout ++ mov r1, #1 ++ str r1, [r0, #0x08] @Enable the watchdog ++watchdog_finished: ++#endif /* CONFIG_ARCH_IPQ40XX */ ++ + /* + * The C runtime environment should now be setup sufficiently. + * Set up some pointers, and start decompressing. diff --git a/6.1/target/linux/ipq40xx/patches-6.1/400-mmc-sdhci-sdhci-msm-use-sdhci_set_clock-instead-of-s.patch b/6.1/target/linux/ipq40xx/patches-6.1/400-mmc-sdhci-sdhci-msm-use-sdhci_set_clock-instead-of-s.patch new file mode 100644 index 00000000..3a3be917 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/400-mmc-sdhci-sdhci-msm-use-sdhci_set_clock-instead-of-s.patch @@ -0,0 +1,24 @@ +From f63ea127643a605da97090ce585fdd7c2d17fa42 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Mon, 14 Dec 2020 13:35:35 +0100 +Subject: [PATCH] mmc: sdhci-msm: use sdhci_set_clock + +When using sdhci_msm_set_clock clock setting will fail, so lets +use the generic sdhci_set_clock. + +Signed-off-by: Robert Marko +--- + drivers/mmc/host/sdhci-msm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mmc/host/sdhci-msm.c ++++ b/drivers/mmc/host/sdhci-msm.c +@@ -2447,7 +2447,7 @@ MODULE_DEVICE_TABLE(of, sdhci_msm_dt_mat + + static const struct sdhci_ops sdhci_msm_ops = { + .reset = sdhci_msm_reset, +- .set_clock = sdhci_msm_set_clock, ++ .set_clock = sdhci_set_clock, + .get_min_clock = sdhci_msm_get_min_clock, + .get_max_clock = sdhci_msm_get_max_clock, + .set_bus_width = sdhci_set_bus_width, diff --git a/6.1/target/linux/ipq40xx/patches-6.1/420-firmware-qcom-scm-disable-SDI.patch b/6.1/target/linux/ipq40xx/patches-6.1/420-firmware-qcom-scm-disable-SDI.patch new file mode 100644 index 00000000..a0074103 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/420-firmware-qcom-scm-disable-SDI.patch @@ -0,0 +1,47 @@ +--- a/drivers/firmware/qcom_scm.c ++++ b/drivers/firmware/qcom_scm.c +@@ -404,6 +404,20 @@ static int __qcom_scm_set_dload_mode(str + return qcom_scm_call_atomic(__scm->dev, &desc, NULL); + } + ++static int __qcom_scm_disable_sdi(struct device *dev) ++{ ++ struct qcom_scm_desc desc = { ++ .svc = QCOM_SCM_SVC_BOOT, ++ .cmd = QCOM_SCM_BOOT_CONFIG_SDI, ++ .arginfo = QCOM_SCM_ARGS(2), ++ .args[0] = 1 /* 1: disable watchdog debug */, ++ .args[1] = 0 /* 0: disable SDI */, ++ .owner = ARM_SMCCC_OWNER_SIP, ++ }; ++ ++ return qcom_scm_call(__scm->dev, &desc, NULL); ++} ++ + static void qcom_scm_set_download_mode(bool enable) + { + bool avail; +@@ -1314,6 +1328,13 @@ static int qcom_scm_probe(struct platfor + if (download_mode) + qcom_scm_set_download_mode(true); + ++ /* ++ * Factory firmware leaves SDI (a debug interface), which prevents ++ * clean reboot. ++ */ ++ if (of_machine_is_compatible("google,wifi")) ++ __qcom_scm_disable_sdi(__scm->dev); ++ + return 0; + } + +--- a/drivers/firmware/qcom_scm.h ++++ b/drivers/firmware/qcom_scm.h +@@ -77,6 +77,7 @@ extern int scm_legacy_call(struct device + #define QCOM_SCM_SVC_BOOT 0x01 + #define QCOM_SCM_BOOT_SET_ADDR 0x01 + #define QCOM_SCM_BOOT_TERMINATE_PC 0x02 ++#define QCOM_SCM_BOOT_CONFIG_SDI 0x09 + #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 + #define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a + #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 diff --git a/6.1/target/linux/ipq40xx/patches-6.1/421-firmware-qcom-scm-cold-boot-address.patch b/6.1/target/linux/ipq40xx/patches-6.1/421-firmware-qcom-scm-cold-boot-address.patch new file mode 100644 index 00000000..13ebb5b0 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/421-firmware-qcom-scm-cold-boot-address.patch @@ -0,0 +1,121 @@ +--- a/drivers/firmware/qcom_scm-legacy.c ++++ b/drivers/firmware/qcom_scm-legacy.c +@@ -13,6 +13,9 @@ + #include + #include + ++#include ++#include ++ + #include "qcom_scm.h" + + static DEFINE_MUTEX(qcom_scm_lock); +@@ -117,6 +120,25 @@ static void __scm_legacy_do(const struct + } while (res->a0 == QCOM_SCM_INTERRUPTED); + } + ++static void qcom_scm_inv_range(unsigned long start, unsigned long end) ++{ ++ u32 cacheline_size, ctr; ++ ++ asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr)); ++ cacheline_size = 4 << ((ctr >> 16) & 0xf); ++ ++ start = round_down(start, cacheline_size); ++ end = round_up(end, cacheline_size); ++ outer_inv_range(start, end); ++ while (start < end) { ++ asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start) ++ : "memory"); ++ start += cacheline_size; ++ } ++ dsb(); ++ isb(); ++} ++ + /** + * scm_legacy_call() - Sends a command to the SCM and waits for the command to + * finish processing. +@@ -160,10 +182,16 @@ int scm_legacy_call(struct device *dev, + + rsp = scm_legacy_command_to_response(cmd); + +- cmd_phys = dma_map_single(dev, cmd, alloc_len, DMA_TO_DEVICE); +- if (dma_mapping_error(dev, cmd_phys)) { +- kfree(cmd); +- return -ENOMEM; ++ if (dev) { ++ cmd_phys = dma_map_single(dev, cmd, alloc_len, DMA_TO_DEVICE); ++ if (dma_mapping_error(dev, cmd_phys)) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ } else { ++ cmd_phys = virt_to_phys(cmd); ++ __cpuc_flush_dcache_area(cmd, alloc_len); ++ outer_flush_range(cmd_phys, cmd_phys + alloc_len); + } + + smc.args[0] = 1; +@@ -179,13 +207,26 @@ int scm_legacy_call(struct device *dev, + goto out; + + do { +- dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len, +- sizeof(*rsp), DMA_FROM_DEVICE); ++ if (dev) { ++ dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + ++ cmd_len, sizeof(*rsp), ++ DMA_FROM_DEVICE); ++ } else { ++ unsigned long start = (uintptr_t)cmd + sizeof(*cmd) + ++ cmd_len; ++ qcom_scm_inv_range(start, start + sizeof(*rsp)); ++ } + } while (!rsp->is_complete); + +- dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len + +- le32_to_cpu(rsp->buf_offset), +- resp_len, DMA_FROM_DEVICE); ++ if (dev) { ++ dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len + ++ le32_to_cpu(rsp->buf_offset), ++ resp_len, DMA_FROM_DEVICE); ++ } else { ++ unsigned long start = (uintptr_t)cmd + sizeof(*cmd) + cmd_len + ++ le32_to_cpu(rsp->buf_offset); ++ qcom_scm_inv_range(start, start + resp_len); ++ } + + if (res) { + res_buf = scm_legacy_get_response_buffer(rsp); +@@ -193,7 +234,8 @@ int scm_legacy_call(struct device *dev, + res->result[i] = le32_to_cpu(res_buf[i]); + } + out: +- dma_unmap_single(dev, cmd_phys, alloc_len, DMA_TO_DEVICE); ++ if (dev) ++ dma_unmap_single(dev, cmd_phys, alloc_len, DMA_TO_DEVICE); + kfree(cmd); + return ret; + } +--- a/drivers/firmware/qcom_scm.c ++++ b/drivers/firmware/qcom_scm.c +@@ -344,6 +344,17 @@ int qcom_scm_set_cold_boot_addr(void *en + desc.args[0] = flags; + desc.args[1] = virt_to_phys(entry); + ++ /* ++ * Factory firmware doesn't support the atomic variant. Non-atomic SCMs ++ * require ugly DMA invalidation support that was dropped upstream a ++ * while ago. For more info, see: ++ * ++ * [RFC] qcom_scm: IPQ4019 firmware does not support atomic API? ++ * https://lore.kernel.org/linux-arm-msm/20200913201608.GA3162100@bDebian/ ++ */ ++ if (of_machine_is_compatible("google,wifi")) ++ return qcom_scm_call(__scm ? __scm->dev : NULL, &desc, NULL); ++ + return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL); + } + EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); diff --git a/6.1/target/linux/ipq40xx/patches-6.1/444-mtd-nand-rawnand-add-support-for-Toshiba-TC58NVG0S3H.patch b/6.1/target/linux/ipq40xx/patches-6.1/444-mtd-nand-rawnand-add-support-for-Toshiba-TC58NVG0S3H.patch new file mode 100644 index 00000000..91919b28 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/444-mtd-nand-rawnand-add-support-for-Toshiba-TC58NVG0S3H.patch @@ -0,0 +1,29 @@ +From 35ca7e3e6ccd120d694a3425f37fc6374ad2e11e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andreas=20B=C3=B6hler?= +Date: Wed, 20 Apr 2022 12:08:38 +0200 +Subject: [PATCH] mtd: rawnand: add support for Toshiba TC58NVG0S3HTA00 + NAND flash +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The Toshiba TC58NVG0S3HTA00 is detected with 64 byte OOB while the flash +has 128 bytes OOB. This adds a static NAND ID entry to correct this. + +Tested on FRITZ!Box 7530 flashed with OpenWrt. + +Signed-off-by: Andreas Böhler +(changed id_len to 8, added comment about possible counterfeits) +--- +--- a/drivers/mtd/nand/raw/nand_ids.c ++++ b/drivers/mtd/nand/raw/nand_ids.c +@@ -29,6 +29,9 @@ struct nand_flash_dev nand_flash_ids[] = + {"TC58NVG0S3E 1G 3.3V 8-bit", + { .id = {0x98, 0xd1, 0x90, 0x15, 0x76, 0x14, 0x01, 0x00} }, + SZ_2K, SZ_128, SZ_128K, 0, 8, 64, NAND_ECC_INFO(1, SZ_512), }, ++ {"TC58NVG0S3HTA00 1G 3.3V 8-bit", /* possibly counterfeit chip - see commit */ ++ { .id = {0x98, 0xf1, 0x80, 0x15} }, /* should be more bytes */ ++ SZ_2K, SZ_128, SZ_128K, 0, 8, 128, NAND_ECC_INFO(8, SZ_512), }, + {"TC58NVG2S0F 4G 3.3V 8-bit", + { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, + SZ_4K, SZ_512, SZ_256K, 0, 8, 224, NAND_ECC_INFO(4, SZ_512) }, diff --git a/6.1/target/linux/ipq40xx/patches-6.1/700-skbuff-add-DSA-specific-data-to-struct-skb_shared_in.patch b/6.1/target/linux/ipq40xx/patches-6.1/700-skbuff-add-DSA-specific-data-to-struct-skb_shared_in.patch new file mode 100644 index 00000000..582b98cc --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/700-skbuff-add-DSA-specific-data-to-struct-skb_shared_in.patch @@ -0,0 +1,43 @@ +From da75807ac41175e9db8c95f7a172b4133763b744 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 11 Jan 2021 17:49:36 +0100 +Subject: [PATCH] skbuff: add DSA specific data to struct skb_shared_info + +All of the already existing DSA tagging protocol drivers +are storing the tagging data directly into the skb. In most +cases that is the only way to send the required information +to the underlying ethernet switch. + +However on certain platforms (like the Qualcomm IPQ40xx +SoCs) the built-in ethernet switch is connected directly +to an ethernet MAC, and the tagging information must be +sent out-of-band which is done directly via the hardware +TX descriptors of the ethernet MAC. + +In such cases, putting the information into the skb causes +unneccesary overhead, because the ethernet driver must +remove that before sending the ethernet frame towards to +the hardware. + +This change adds two new DSA specific fields to struct +skb_shared_info which makes it possible to send the +tagging information via skb->shinfo. With this approach, +the twofold modifications of the skb data can be avoided. + +Signed-off-by: Gabor Juhos +--- + include/linux/skbuff.h | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -563,6 +563,9 @@ struct skb_shared_info { + unsigned int gso_type; + u32 tskey; + ++ unsigned int dsa_tag_proto; ++ unsigned char dsa_tag_data[8]; ++ + /* + * Warning : all fields before dataref are cleared in __alloc_skb() + */ diff --git a/6.1/target/linux/ipq40xx/patches-6.1/701-net-dsa-tag_ipq4019-add-shinfo-based-tagging-driver-.patch b/6.1/target/linux/ipq40xx/patches-6.1/701-net-dsa-tag_ipq4019-add-shinfo-based-tagging-driver-.patch new file mode 100644 index 00000000..664496df --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/701-net-dsa-tag_ipq4019-add-shinfo-based-tagging-driver-.patch @@ -0,0 +1,187 @@ +From 29a0c2fae991cab142575c92276c0afdeb260ebe Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 28 Oct 2021 21:44:52 +0200 +Subject: [PATCH] net: dsa: tag_ipq4019: add shinfo based tagging driver for + IPQ40xx + +This change adds a tagging protocol driver for the built-in +ethernet switch of the Qualcomm Atheros IPQ4019 SoCs. + +In comparison to the existing tagging protocols this hardware +requires a slightly different approach because the switch does +not use in-band tags. + +On the receive path, the source port information is embedded +into the RX descriptors of the ethernet MAC hardware. Similarly, +the destination port mask must be sent via the TX descriptors +of the ethernet MAC when a packet is sent towards the switch. + +In order to support this special requirements, this patch +adds a new tagging protocol driver. + +The driver extracts the source port information directly +from the 'receive return descriptor' of the ethernet MAC. +It is possible because that descriptor is part of the skb +received from the ethernet driver. + +Unfortunatley, it is not possible to put the destination +port information directly to the TX descriptors, because +those are handled internally by the driver of the ethernet +hardware. + +To overcome this limitation, this tagging driver uses the +DSA specific fields in skb->shinfo to send the destination +port information to the ethernet driver. + +A similar tagging driver is exist but that uses skb +extensions which causes unnecessary overhead. + +Signed-off-by: Gabor Juhos +--- + include/linux/dsa/ipq4019.h | 11 ++++++ + include/net/dsa.h | 2 + + net/dsa/Kconfig | 6 +++ + net/dsa/Makefile | 1 + + net/dsa/tag_ipq4019.c | 79 +++++++++++++++++++++++++++++++++++++ + 5 files changed, 99 insertions(+) + create mode 100644 include/linux/dsa/ipq4019.h + create mode 100644 net/dsa/tag_ipq4019.c + +--- /dev/null ++++ b/include/linux/dsa/ipq4019.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef DSA_IPQ40XX_H ++#define DSA_IPQ40XX_H ++ ++struct ipq40xx_dsa_tag_data { ++ u8 from_cpu; ++ u8 dp; ++}; ++ ++#endif /* DSA_IPQ40XX_H */ +--- a/include/net/dsa.h ++++ b/include/net/dsa.h +@@ -51,6 +51,7 @@ struct phylink_link_state; + #define DSA_TAG_PROTO_RTL8_4T_VALUE 24 + #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE 25 + #define DSA_TAG_PROTO_LAN937X_VALUE 27 ++#define DSA_TAG_PROTO_IPQ4019_VALUE 28 + + enum dsa_tag_protocol { + DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, +@@ -77,6 +78,7 @@ enum dsa_tag_protocol { + DSA_TAG_PROTO_RTL8_4T = DSA_TAG_PROTO_RTL8_4T_VALUE, + DSA_TAG_PROTO_RZN1_A5PSW = DSA_TAG_PROTO_RZN1_A5PSW_VALUE, + DSA_TAG_PROTO_LAN937X = DSA_TAG_PROTO_LAN937X_VALUE, ++ DSA_TAG_PROTO_IPQ4019 = DSA_TAG_PROTO_IPQ4019_VALUE, + }; + + struct dsa_switch; +--- a/net/dsa/Kconfig ++++ b/net/dsa/Kconfig +@@ -57,6 +57,12 @@ config NET_DSA_TAG_HELLCREEK + Say Y or M if you want to enable support for tagging frames + for the Hirschmann Hellcreek TSN switches. + ++config NET_DSA_TAG_IPQ4019 ++ tristate "Tag driver for Qualcomm Atheros IPQ4019 SoC built-in switch" ++ help ++ Say Y or M if you want to enable support for tagging frames for ++ the built-in switch of the Qualcomm Atheros IPQ4019 SoC-s. ++ + config NET_DSA_TAG_GSWIP + tristate "Tag driver for Lantiq / Intel GSWIP switches" + help +--- a/net/dsa/Makefile ++++ b/net/dsa/Makefile +@@ -8,6 +8,7 @@ obj-$(CONFIG_NET_DSA_TAG_AR9331) += tag_ + obj-$(CONFIG_NET_DSA_TAG_BRCM_COMMON) += tag_brcm.o + obj-$(CONFIG_NET_DSA_TAG_DSA_COMMON) += tag_dsa.o + obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o ++obj-$(CONFIG_NET_DSA_TAG_IPQ4019) += tag_ipq4019.o + obj-$(CONFIG_NET_DSA_TAG_HELLCREEK) += tag_hellcreek.o + obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o + obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o +--- /dev/null ++++ b/net/dsa/tag_ipq4019.c +@@ -0,0 +1,78 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++ ++/* Copyright (c) 2021, Gabor Juhos */ ++ ++#include ++#include ++ ++#include "dsa_priv.h" ++ ++/* Receive Return Descriptor */ ++struct edma_rrd { ++ u16 rrd0; ++ u16 rrd1; ++ u16 rrd2; ++ u16 rrd3; ++ u16 rrd4; ++ u16 rrd5; ++ u16 rrd6; ++ u16 rrd7; ++} __packed; ++ ++#define EDMA_RRD_SIZE sizeof(struct edma_rrd) ++ ++#define EDMA_RRD1_PORT_ID_MASK GENMASK(14, 12) ++ ++static struct sk_buff *ipq4019_sh_tag_xmit(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct dsa_port *dp = dsa_slave_to_port(dev); ++ struct ipq40xx_dsa_tag_data *tag_data; ++ ++ BUILD_BUG_ON(sizeof_field(struct skb_shared_info, dsa_tag_data) < ++ sizeof(struct ipq40xx_dsa_tag_data)); ++ ++ skb_shinfo(skb)->dsa_tag_proto = DSA_TAG_PROTO_IPQ4019; ++ tag_data = (struct ipq40xx_dsa_tag_data *)skb_shinfo(skb)->dsa_tag_data; ++ ++ tag_data->from_cpu = 1; ++ /* set the destination port information */ ++ tag_data->dp = BIT(dp->index); ++ ++ return skb; ++} ++ ++static struct sk_buff *ipq4019_sh_tag_rcv(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct edma_rrd *rrd; ++ int offset; ++ int port; ++ ++ offset = EDMA_RRD_SIZE + ETH_HLEN; ++ if (unlikely(skb_headroom(skb) < offset)) ++ return NULL; ++ ++ rrd = (struct edma_rrd *)(skb->data - offset); ++ port = FIELD_GET(EDMA_RRD1_PORT_ID_MASK, rrd->rrd1); ++ ++ skb->dev = dsa_master_find_slave(dev, 0, port); ++ if (!skb->dev) ++ return NULL; ++ ++ return skb; ++} ++ ++const struct dsa_device_ops ipq4019_sh_tag_dsa_ops = { ++ .name = "ipq4019-sh", ++ .proto = DSA_TAG_PROTO_IPQ4019, ++ .xmit = ipq4019_sh_tag_xmit, ++ .rcv = ipq4019_sh_tag_rcv, ++}; ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("DSA tag driver for the IPQ4019 SoC built-in ethernet switch"); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_IPQ4019); ++ ++module_dsa_tag_driver(ipq4019_sh_tag_dsa_ops); diff --git a/6.1/target/linux/ipq40xx/patches-6.1/703-arm-dts-ipq4019-add-ethernet-controller-DT-node.patch b/6.1/target/linux/ipq40xx/patches-6.1/703-arm-dts-ipq4019-add-ethernet-controller-DT-node.patch new file mode 100644 index 00000000..68fb4eb4 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/703-arm-dts-ipq4019-add-ethernet-controller-DT-node.patch @@ -0,0 +1,81 @@ +From 44327d7098d4f32c24ec8c528e5aff6e030956bc Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 20 Oct 2021 13:21:45 +0200 +Subject: [PATCH] arm: dts: ipq4019: add ethernet controller DT node + +Since IPQ40xx SoC built-in ethernet controller now has a driver, +add its DT node so it can be used. + +Signed-off-by: Robert Marko +--- + arch/arm/boot/dts/qcom-ipq4019.dtsi | 48 +++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi +@@ -38,6 +38,7 @@ + spi1 = &blsp1_spi2; + i2c0 = &blsp1_i2c3; + i2c1 = &blsp1_i2c4; ++ ethernet0 = &gmac; + }; + + cpus { +@@ -589,6 +590,57 @@ + status = "disabled"; + }; + ++ gmac: ethernet@c080000 { ++ compatible = "qcom,ipq4019-ess-edma"; ++ reg = <0xc080000 0x8000>; ++ resets = <&gcc ESS_RESET>; ++ reset-names = "ess_rst"; ++ clocks = <&gcc GCC_ESS_CLK>; ++ clock-names = "ess_clk"; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ ++ status = "disabled"; ++ ++ phy-mode = "internal"; ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ asym-pause; ++ }; ++ }; ++ + mdio: mdio@90000 { + #address-cells = <1>; + #size-cells = <0>; diff --git a/6.1/target/linux/ipq40xx/patches-6.1/704-net-phy-define-PSGMII-PHY-interface-mode.patch b/6.1/target/linux/ipq40xx/patches-6.1/704-net-phy-define-PSGMII-PHY-interface-mode.patch new file mode 100644 index 00000000..36d3e273 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/704-net-phy-define-PSGMII-PHY-interface-mode.patch @@ -0,0 +1,61 @@ +From 3e1825e00dafb68eec25df389b63f3ab3d905b59 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Fri, 25 Dec 2020 08:02:47 +0100 +Subject: [PATCH] net: phy: define PSGMII PHY interface mode + +The PSGMII interface is similar to QSGMII. The main difference +is that the PSGMII interface combines five SGMII lines into a +single link while in QSGMII only four lines are combined. + +Similarly to the QSGMII, this interface mode might also needs +special handling within the MAC driver. + +Add definitions for the PHY layer to allow to express this type +of connection between the MAC and PHY. + +Signed-off-by: Gabor Juhos +--- + Documentation/devicetree/bindings/net/ethernet-controller.yaml | 1 + + drivers/net/phy/phylink.c | 1 + + include/linux/phy.h | 3 +++ + 3 files changed, 5 insertions(+) + +--- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml ++++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml +@@ -64,6 +64,7 @@ properties: + - mii + - gmii + - sgmii ++ - psgmii + - qsgmii + - tbi + - rev-mii +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -629,6 +629,7 @@ static int phylink_parse_mode(struct phy + + switch (pl->link_config.interface) { + case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_QSGMII: + phylink_set(pl->supported, 10baseT_Half); + phylink_set(pl->supported, 10baseT_Full); +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -138,6 +138,7 @@ typedef enum { + PHY_INTERFACE_MODE_XGMII, + PHY_INTERFACE_MODE_XLGMII, + PHY_INTERFACE_MODE_MOCA, ++ PHY_INTERFACE_MODE_PSGMII, + PHY_INTERFACE_MODE_QSGMII, + PHY_INTERFACE_MODE_TRGMII, + PHY_INTERFACE_MODE_100BASEX, +@@ -243,6 +244,8 @@ static inline const char *phy_modes(phy_ + return "xlgmii"; + case PHY_INTERFACE_MODE_MOCA: + return "moca"; ++ case PHY_INTERFACE_MODE_PSGMII: ++ return "psgmii"; + case PHY_INTERFACE_MODE_QSGMII: + return "qsgmii"; + case PHY_INTERFACE_MODE_TRGMII: diff --git a/6.1/target/linux/ipq40xx/patches-6.1/706-arm-dts-ipq4019-add-switch-node.patch b/6.1/target/linux/ipq40xx/patches-6.1/706-arm-dts-ipq4019-add-switch-node.patch new file mode 100644 index 00000000..a231c733 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/706-arm-dts-ipq4019-add-switch-node.patch @@ -0,0 +1,98 @@ +From ebb62523990a27b3a25e422fa575619f7f725a20 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Mon, 1 Nov 2021 18:15:04 +0100 +Subject: [PATCH] arm: dts: ipq4019: add switch node + +Since the built-in IPQ40xx switch now has a driver, add the required node +for it to work. + +Signed-off-by: Robert Marko +--- + arch/arm/boot/dts/qcom-ipq4019.dtsi | 78 +++++++++++++++++++++++++++++ + 1 file changed, 78 insertions(+) + +--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi +@@ -590,6 +590,82 @@ + status = "disabled"; + }; + ++ switch: switch@c000000 { ++ compatible = "qca,ipq4019-qca8337n"; ++ reg = <0xc000000 0x80000>, <0x98000 0x800>; ++ reg-names = "base", "psgmii_phy"; ++ resets = <&gcc ESS_PSGMII_ARES>; ++ reset-names = "psgmii_rst"; ++ mdio = <&mdio>; ++ psgmii-ethphy = <&psgmiiphy>; ++ ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { /* MAC0 */ ++ reg = <0>; ++ label = "cpu"; ++ ethernet = <&gmac>; ++ phy-mode = "internal"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ asym-pause; ++ }; ++ }; ++ ++ swport1: port@1 { /* MAC1 */ ++ reg = <1>; ++ label = "lan1"; ++ phy-handle = <ðphy0>; ++ phy-mode = "psgmii"; ++ ++ status = "disabled"; ++ }; ++ ++ swport2: port@2 { /* MAC2 */ ++ reg = <2>; ++ label = "lan2"; ++ phy-handle = <ðphy1>; ++ phy-mode = "psgmii"; ++ ++ status = "disabled"; ++ }; ++ ++ swport3: port@3 { /* MAC3 */ ++ reg = <3>; ++ label = "lan3"; ++ phy-handle = <ðphy2>; ++ phy-mode = "psgmii"; ++ ++ status = "disabled"; ++ }; ++ ++ swport4: port@4 { /* MAC4 */ ++ reg = <4>; ++ label = "lan4"; ++ phy-handle = <ðphy3>; ++ phy-mode = "psgmii"; ++ ++ status = "disabled"; ++ }; ++ ++ swport5: port@5 { /* MAC5 */ ++ reg = <5>; ++ label = "wan"; ++ phy-handle = <ðphy4>; ++ phy-mode = "psgmii"; ++ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ + gmac: ethernet@c080000 { + compatible = "qcom,ipq4019-ess-edma"; + reg = <0xc080000 0x8000>; diff --git a/6.1/target/linux/ipq40xx/patches-6.1/707-dt-bindings-net-add-QCA807x-PHY.patch b/6.1/target/linux/ipq40xx/patches-6.1/707-dt-bindings-net-add-QCA807x-PHY.patch new file mode 100644 index 00000000..dfb8d692 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/707-dt-bindings-net-add-QCA807x-PHY.patch @@ -0,0 +1,61 @@ +From c66863c1ba8995b61e6d727d78a241c734f5bb57 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Thu, 1 Oct 2020 15:05:35 +0200 +Subject: [PATCH] dt-bindings: net: add QCA807x PHY + +Add DT bindings for Qualcomm QCA807x PHY series. + +Signed-off-by: Robert Marko +--- + include/dt-bindings/net/qcom-qca807x.h | 45 ++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + create mode 100644 include/dt-bindings/net/qcom-qca807x.h + +--- /dev/null ++++ b/include/dt-bindings/net/qcom-qca807x.h +@@ -0,0 +1,45 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * Device Tree constants for the Qualcomm QCA807X PHYs ++ */ ++ ++#ifndef _DT_BINDINGS_QCOM_QCA807X_H ++#define _DT_BINDINGS_QCOM_QCA807X_H ++ ++#define PSGMII_QSGMII_TX_DRIVER_140MV 0 ++#define PSGMII_QSGMII_TX_DRIVER_160MV 1 ++#define PSGMII_QSGMII_TX_DRIVER_180MV 2 ++#define PSGMII_QSGMII_TX_DRIVER_200MV 3 ++#define PSGMII_QSGMII_TX_DRIVER_220MV 4 ++#define PSGMII_QSGMII_TX_DRIVER_240MV 5 ++#define PSGMII_QSGMII_TX_DRIVER_260MV 6 ++#define PSGMII_QSGMII_TX_DRIVER_280MV 7 ++#define PSGMII_QSGMII_TX_DRIVER_300MV 8 ++#define PSGMII_QSGMII_TX_DRIVER_320MV 9 ++#define PSGMII_QSGMII_TX_DRIVER_400MV 10 ++#define PSGMII_QSGMII_TX_DRIVER_500MV 11 ++/* Default value */ ++#define PSGMII_QSGMII_TX_DRIVER_600MV 12 ++ ++/* Full amplitude, full bias current */ ++#define QCA807X_CONTROL_DAC_FULL_VOLT_BIAS 0 ++/* Amplitude follow DSP (amplitude is adjusted based on cable length), half bias current */ ++#define QCA807X_CONTROL_DAC_DSP_VOLT_HALF_BIAS 1 ++/* Full amplitude, bias current follow DSP (bias current is adjusted based on cable length) */ ++#define QCA807X_CONTROL_DAC_FULL_VOLT_DSP_BIAS 2 ++/* Both amplitude and bias current follow DSP */ ++#define QCA807X_CONTROL_DAC_DSP_VOLT_BIAS 3 ++/* Full amplitude, half bias current */ ++#define QCA807X_CONTROL_DAC_FULL_VOLT_HALF_BIAS 4 ++/* Amplitude follow DSP setting; 1/4 bias current when cable<10m, ++ * otherwise half bias current ++ */ ++#define QCA807X_CONTROL_DAC_DSP_VOLT_QUARTER_BIAS 5 ++/* Full amplitude; same bias current setting with “010” and “011”, ++ * but half more bias is reduced when cable <10m ++ */ ++#define QCA807X_CONTROL_DAC_FULL_VOLT_HALF_BIAS_SHORT 6 ++/* Amplitude follow DSP; same bias current setting with “110”, default value */ ++#define QCA807X_CONTROL_DAC_DSP_VOLT_HALF_BIAS_SHORT 7 ++ ++#endif diff --git a/6.1/target/linux/ipq40xx/patches-6.1/708-net-phy-Add-Qualcom-QCA807x-driver.patch b/6.1/target/linux/ipq40xx/patches-6.1/708-net-phy-Add-Qualcom-QCA807x-driver.patch new file mode 100644 index 00000000..87be5980 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/708-net-phy-Add-Qualcom-QCA807x-driver.patch @@ -0,0 +1,50 @@ +From f825cdc8bfde7616a14e2163f16303a8973031d2 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 7 Oct 2020 17:38:48 +0200 +Subject: [PATCH] net: phy: Add Qualcom QCA807x driver + +This adds driver for the Qualcomm QCA8072 and QCA8075 PHY-s. + +They are 2 or 5 port IEEE 802.3 clause 22 compliant 10BASE-Te, 100BASE-TX and 1000BASE-T PHY-s. + +They feature 2 SerDes, one for PSGMII or QSGMII connection with MAC, while second one is SGMII for connection to MAC or fiber. + +Both models have a combo port that supports 1000BASE-X and 100BASE-FX fiber. + +Each PHY inside of QCA807x series has 4 digitally controlled output only pins that natively drive LED-s. +But some vendors used these to driver generic LED-s controlled by userspace, +so lets enable registering each PHY as GPIO controller and add driver for it. + +These are commonly used in Qualcomm IPQ40xx, IPQ60xx and IPQ807x boards. + +Signed-off-by: Robert Marko +--- + drivers/net/phy/Kconfig | 6 ++++++ + drivers/net/phy/Makefile | 1 + + 2 files changed, 7 insertions(+) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -346,6 +346,12 @@ config AT803X_PHY + Currently supports the AR8030, AR8031, AR8033, AR8035 and internal + QCA8337(Internal qca8k PHY) model + ++config QCA807X_PHY ++ tristate "Qualcomm QCA807X PHYs" ++ depends on OF_MDIO ++ help ++ Currently supports the QCA8072 and QCA8075 models. ++ + config QSEMI_PHY + tristate "Quality Semiconductor PHYs" + help +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -92,6 +92,7 @@ obj-$(CONFIG_NATIONAL_PHY) += national.o + obj-$(CONFIG_NXP_C45_TJA11XX_PHY) += nxp-c45-tja11xx.o + obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o + obj-$(CONFIG_QSEMI_PHY) += qsemi.o ++obj-$(CONFIG_QCA807X_PHY) += qca807x.o + obj-$(CONFIG_REALTEK_PHY) += realtek.o + obj-$(CONFIG_RENESAS_PHY) += uPD60620.o + obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o diff --git a/6.1/target/linux/ipq40xx/patches-6.1/709-arm-dts-ipq4019-QCA807x-properties.patch b/6.1/target/linux/ipq40xx/patches-6.1/709-arm-dts-ipq4019-QCA807x-properties.patch new file mode 100644 index 00000000..cc4b44b3 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/709-arm-dts-ipq4019-QCA807x-properties.patch @@ -0,0 +1,61 @@ +From e0fa88eaa3c176b71e563da68949ac2ab45aaa61 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 2 Oct 2020 10:43:26 +0200 +Subject: [PATCH] arm: dts: ipq4019: QCA807x properties + +This adds necessary DT properties for QCA807x PHY-s to IPQ4019 DTSI. + +Signed-off-by: Robert Marko +--- + arch/arm/boot/dts/qcom-ipq4019.dtsi | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + / { + #address-cells = <1>; +@@ -726,22 +727,38 @@ + + ethphy0: ethernet-phy@0 { + reg = <0>; ++ ++ qcom,control-dac = ; + }; + + ethphy1: ethernet-phy@1 { + reg = <1>; ++ ++ qcom,control-dac = ; + }; + + ethphy2: ethernet-phy@2 { + reg = <2>; ++ ++ qcom,control-dac = ; + }; + + ethphy3: ethernet-phy@3 { + reg = <3>; ++ ++ qcom,control-dac = ; + }; + + ethphy4: ethernet-phy@4 { + reg = <4>; ++ ++ qcom,control-dac = ; ++ }; ++ ++ psgmiiphy: psgmii-phy@5 { ++ reg = <5>; ++ ++ qcom,tx-driver-strength = ; + }; + }; + diff --git a/6.1/target/linux/ipq40xx/patches-6.1/850-soc-add-qualcomm-syscon.patch b/6.1/target/linux/ipq40xx/patches-6.1/850-soc-add-qualcomm-syscon.patch new file mode 100644 index 00000000..9b44a4c8 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/850-soc-add-qualcomm-syscon.patch @@ -0,0 +1,180 @@ +From: Christian Lamparter +Subject: SoC: add qualcomm syscon +--- a/drivers/soc/qcom/Makefile ++++ b/drivers/soc/qcom/Makefile +@@ -21,6 +21,7 @@ obj-$(CONFIG_QCOM_SMP2P) += smp2p.o + obj-$(CONFIG_QCOM_SMSM) += smsm.o + obj-$(CONFIG_QCOM_SOCINFO) += socinfo.o + obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o ++obj-$(CONFIG_QCOM_TCSR) += qcom_tcsr.o + obj-$(CONFIG_QCOM_APR) += apr.o + obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o + obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o +--- a/drivers/soc/qcom/Kconfig ++++ b/drivers/soc/qcom/Kconfig +@@ -192,6 +192,13 @@ config QCOM_SOCINFO + Say yes here to support the Qualcomm socinfo driver, providing + information about the SoC to user space. + ++config QCOM_TCSR ++ tristate "QCOM Top Control and Status Registers" ++ depends on ARCH_QCOM ++ help ++ Say y here to enable TCSR support. The TCSR provides control ++ functions for various peripherals. ++ + config QCOM_WCNSS_CTRL + tristate "Qualcomm WCNSS control driver" + depends on ARCH_QCOM || COMPILE_TEST +--- /dev/null ++++ b/drivers/soc/qcom/qcom_tcsr.c +@@ -0,0 +1,98 @@ ++/* ++ * Copyright (c) 2014, The Linux foundation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License rev 2 and ++ * only rev 2 as published by the free Software foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define TCSR_USB_PORT_SEL 0xb0 ++#define TCSR_USB_HSPHY_CONFIG 0xC ++ ++#define TCSR_ESS_INTERFACE_SEL_OFFSET 0x0 ++#define TCSR_ESS_INTERFACE_SEL_MASK 0xf ++ ++#define TCSR_WIFI0_GLB_CFG_OFFSET 0x0 ++#define TCSR_WIFI1_GLB_CFG_OFFSET 0x4 ++#define TCSR_PNOC_SNOC_MEMTYPE_M0_M2 0x4 ++ ++static int tcsr_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ const struct device_node *node = pdev->dev.of_node; ++ void __iomem *base; ++ u32 val; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ if (!of_property_read_u32(node, "qcom,usb-ctrl-select", &val)) { ++ dev_err(&pdev->dev, "setting usb port select = %d\n", val); ++ writel(val, base + TCSR_USB_PORT_SEL); ++ } ++ ++ if (!of_property_read_u32(node, "qcom,usb-hsphy-mode-select", &val)) { ++ dev_info(&pdev->dev, "setting usb hs phy mode select = %x\n", val); ++ writel(val, base + TCSR_USB_HSPHY_CONFIG); ++ } ++ ++ if (!of_property_read_u32(node, "qcom,ess-interface-select", &val)) { ++ u32 tmp = 0; ++ dev_info(&pdev->dev, "setting ess interface select = %x\n", val); ++ tmp = readl(base + TCSR_ESS_INTERFACE_SEL_OFFSET); ++ tmp = tmp & (~TCSR_ESS_INTERFACE_SEL_MASK); ++ tmp = tmp | (val&TCSR_ESS_INTERFACE_SEL_MASK); ++ writel(tmp, base + TCSR_ESS_INTERFACE_SEL_OFFSET); ++ } ++ ++ if (!of_property_read_u32(node, "qcom,wifi_glb_cfg", &val)) { ++ dev_info(&pdev->dev, "setting wifi_glb_cfg = %x\n", val); ++ writel(val, base + TCSR_WIFI0_GLB_CFG_OFFSET); ++ writel(val, base + TCSR_WIFI1_GLB_CFG_OFFSET); ++ } ++ ++ if (!of_property_read_u32(node, "qcom,wifi_noc_memtype_m0_m2", &val)) { ++ dev_info(&pdev->dev, ++ "setting wifi_noc_memtype_m0_m2 = %x\n", val); ++ writel(val, base + TCSR_PNOC_SNOC_MEMTYPE_M0_M2); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id tcsr_dt_match[] = { ++ { .compatible = "qcom,tcsr", }, ++ { }, ++}; ++ ++MODULE_DEVICE_TABLE(of, tcsr_dt_match); ++ ++static struct platform_driver tcsr_driver = { ++ .driver = { ++ .name = "tcsr", ++ .owner = THIS_MODULE, ++ .of_match_table = tcsr_dt_match, ++ }, ++ .probe = tcsr_probe, ++}; ++ ++module_platform_driver(tcsr_driver); ++ ++MODULE_AUTHOR("Andy Gross "); ++MODULE_DESCRIPTION("QCOM TCSR driver"); ++MODULE_LICENSE("GPL v2"); +--- /dev/null ++++ b/include/dt-bindings/soc/qcom,tcsr.h +@@ -0,0 +1,48 @@ ++/* Copyright (c) 2014, The Linux Foundation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#ifndef __DT_BINDINGS_QCOM_TCSR_H ++#define __DT_BINDINGS_QCOM_TCSR_H ++ ++#define TCSR_USB_SELECT_USB3_P0 0x1 ++#define TCSR_USB_SELECT_USB3_P1 0x2 ++#define TCSR_USB_SELECT_USB3_DUAL 0x3 ++ ++/* IPQ40xx HS PHY Mode Select */ ++#define TCSR_USB_HSPHY_HOST_MODE 0x00E700E7 ++#define TCSR_USB_HSPHY_DEVICE_MODE 0x00C700E7 ++ ++/* IPQ40xx ess interface mode select */ ++#define TCSR_ESS_PSGMII 0 ++#define TCSR_ESS_PSGMII_RGMII5 1 ++#define TCSR_ESS_PSGMII_RMII0 2 ++#define TCSR_ESS_PSGMII_RMII1 4 ++#define TCSR_ESS_PSGMII_RMII0_RMII1 6 ++#define TCSR_ESS_PSGMII_RGMII4 9 ++ ++/* ++ * IPQ40xx WiFi Global Config ++ * Bit 30:AXID_EN ++ * Enable AXI master bus Axid translating to confirm all txn submitted by order ++ * Bit 24: Use locally generated socslv_wxi_bvalid ++ * 1: use locally generate socslv_wxi_bvalid for performance. ++ * 0: use SNOC socslv_wxi_bvalid. ++ */ ++#define TCSR_WIFI_GLB_CFG 0x41000000 ++ ++/* IPQ40xx MEM_TYPE_SEL_M0_M2 Select Bit 26:24 - 2 NORMAL */ ++#define TCSR_WIFI_NOC_MEMTYPE_M0_M2 0x02222222 ++ ++/* TCSR A/B REG */ ++#define IPQ806X_TCSR_REG_A_ADM_CRCI_MUX_SEL 0 ++#define IPQ806X_TCSR_REG_B_ADM_CRCI_MUX_SEL 1 ++ ++#endif diff --git a/6.1/target/linux/ipq40xx/patches-6.1/998-lantiq-atm-hacks.patch b/6.1/target/linux/ipq40xx/patches-6.1/998-lantiq-atm-hacks.patch new file mode 100644 index 00000000..c15a4b3a --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/998-lantiq-atm-hacks.patch @@ -0,0 +1,43 @@ +From: John Crispin +Date: Fri, 3 Aug 2012 10:27:25 +0200 +Subject: [PATCH 04/36] MIPS: lantiq: add atm hack + +Signed-off-by: John Crispin +--- a/include/uapi/linux/atm.h ++++ b/include/uapi/linux/atm.h +@@ -131,8 +131,14 @@ + #define ATM_ABR 4 + #define ATM_ANYCLASS 5 /* compatible with everything */ + ++#define ATM_VBR_NRT ATM_VBR ++#define ATM_VBR_RT 6 ++#define ATM_UBR_PLUS 7 ++#define ATM_GFR 8 ++ + #define ATM_MAX_PCR -1 /* maximum available PCR */ + ++ + struct atm_trafprm { + unsigned char traffic_class; /* traffic class (ATM_UBR, ...) */ + int max_pcr; /* maximum PCR in cells per second */ +@@ -155,6 +161,9 @@ struct atm_trafprm { + unsigned int adtf :10; /* ACR Decrease Time Factor (10-bit) */ + unsigned int cdf :3; /* Cutoff Decrease Factor (3-bit) */ + unsigned int spare :9; /* spare bits */ ++ int scr; /* sustained rate in cells per second */ ++ int mbs; /* maximum burst size (MBS) in cells */ ++ int cdv; /* Cell delay variation */ + }; + + struct atm_qos { +--- a/net/atm/proc.c ++++ b/net/atm/proc.c +@@ -141,7 +141,7 @@ static void *vcc_seq_next(struct seq_fil + static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc) + { + static const char *const class_name[] = { +- "off", "UBR", "CBR", "VBR", "ABR"}; ++ "off","UBR","CBR","NTR-VBR","ABR","ANY","RT-VBR","UBR+","GFR"}; + static const char *const aal_name[] = { + "---", "1", "2", "3/4", /* 0- 3 */ + "???", "5", "???", "???", /* 4- 7 */ diff --git a/6.1/target/linux/ipq40xx/patches-6.1/999-atm-mpoa-intel-dsl-phy-support.patch b/6.1/target/linux/ipq40xx/patches-6.1/999-atm-mpoa-intel-dsl-phy-support.patch new file mode 100644 index 00000000..b774fc39 --- /dev/null +++ b/6.1/target/linux/ipq40xx/patches-6.1/999-atm-mpoa-intel-dsl-phy-support.patch @@ -0,0 +1,137 @@ +From: Subhra Banerjee +Date: Fri, 31 Aug 2018 12:01:19 +0530 +Subject: [PATCH] UGW_SW-29163: ATM oam support + +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -2952,6 +2952,22 @@ char *ppp_dev_name(struct ppp_channel *c + return name; + } + ++/* ++ * Return the PPP device interface pointer ++ */ ++struct net_device *ppp_device(struct ppp_channel *chan) ++{ ++ struct channel *pch = chan->ppp; ++ struct net_device *dev = NULL; ++ ++ if (pch) { ++ read_lock_bh(&pch->upl); ++ if (pch->ppp && pch->ppp->dev) ++ dev = pch->ppp->dev; ++ read_unlock_bh(&pch->upl); ++ } ++ return dev; ++} + + /* + * Disconnect a channel from the generic layer. +@@ -3598,6 +3614,7 @@ EXPORT_SYMBOL(ppp_unregister_channel); + EXPORT_SYMBOL(ppp_channel_index); + EXPORT_SYMBOL(ppp_unit_number); + EXPORT_SYMBOL(ppp_dev_name); ++EXPORT_SYMBOL(ppp_device); + EXPORT_SYMBOL(ppp_input); + EXPORT_SYMBOL(ppp_input_error); + EXPORT_SYMBOL(ppp_output_wakeup); +--- a/include/linux/ppp_channel.h ++++ b/include/linux/ppp_channel.h +@@ -74,6 +74,9 @@ extern int ppp_unit_number(struct ppp_ch + /* Get the device name associated with a channel, or NULL if none */ + extern char *ppp_dev_name(struct ppp_channel *); + ++/* Get the device pointer associated with a channel, or NULL if none */ ++extern struct net_device *ppp_device(struct ppp_channel *); ++ + /* + * SMP locking notes: + * The channel code must ensure that when it calls ppp_unregister_channel, +--- a/net/atm/Kconfig ++++ b/net/atm/Kconfig +@@ -56,6 +56,12 @@ config ATM_MPOA + subnetwork boundaries. These shortcut connections bypass routers + enhancing overall network performance. + ++config ATM_MPOA_INTEL_DSL_PHY_SUPPORT ++ bool "Intel DSL Phy MPOA support" ++ depends on ATM && INET && ATM_MPOA!=n ++ help ++ Add support for Intel DSL Phy ATM MPOA ++ + config ATM_BR2684 + tristate "RFC1483/2684 Bridged protocols" + depends on ATM && INET +--- a/net/atm/br2684.c ++++ b/net/atm/br2684.c +@@ -596,6 +596,11 @@ static int br2684_regvcc(struct atm_vcc + atmvcc->push = br2684_push; + atmvcc->pop = br2684_pop; + atmvcc->release_cb = br2684_release_cb; ++#if IS_ENABLED(CONFIG_ATM_MPOA_INTEL_DSL_PHY_SUPPORT) ++ if (atm_hook_mpoa_setup) /* IPoA or EoA w/o FCS */ ++ atm_hook_mpoa_setup(atmvcc, brdev->payload == p_routed ? 3 : 0, ++ brvcc->encaps == BR2684_ENCAPS_LLC ? 1 : 0, net_dev); ++#endif + atmvcc->owner = THIS_MODULE; + + /* initialize netdev carrier state */ +--- a/net/atm/common.c ++++ b/net/atm/common.c +@@ -137,6 +137,11 @@ static struct proto vcc_proto = { + .release_cb = vcc_release_cb, + }; + ++#if IS_ENABLED(CONFIG_ATM_MPOA_INTEL_DSL_PHY_SUPPORT) ++void (*atm_hook_mpoa_setup)(struct atm_vcc *, int, int, struct net_device *) = NULL; ++EXPORT_SYMBOL(atm_hook_mpoa_setup); ++#endif ++ + int vcc_create(struct net *net, struct socket *sock, int protocol, int family, int kern) + { + struct sock *sk; +--- a/net/atm/common.h ++++ b/net/atm/common.h +@@ -53,4 +53,6 @@ int svc_change_qos(struct atm_vcc *vcc,s + + void atm_dev_release_vccs(struct atm_dev *dev); + ++extern void (*atm_hook_mpoa_setup)(struct atm_vcc *, int, int, struct net_device *); ++ + #endif +--- a/net/atm/mpc.c ++++ b/net/atm/mpc.c +@@ -31,6 +31,7 @@ + /* Modular too */ + #include + ++#include "common.h" + #include "lec.h" + #include "mpc.h" + #include "resources.h" +@@ -645,6 +646,10 @@ static int atm_mpoa_vcc_attach(struct at + vcc->proto_data = mpc->dev; + vcc->push = mpc_push; + ++#if IS_ENABLED(CONFIG_ATM_MPOA_INTEL_DSL_PHY_SUPPORT) ++ if (atm_hook_mpoa_setup) /* IPoA, LLC */ ++ atm_hook_mpoa_setup(vcc, 3, 1, mpc->dev); ++#endif + return 0; + } + +--- a/net/atm/pppoatm.c ++++ b/net/atm/pppoatm.c +@@ -422,6 +422,12 @@ static int pppoatm_assign_vcc(struct atm + atmvcc->user_back = pvcc; + atmvcc->push = pppoatm_push; + atmvcc->pop = pppoatm_pop; ++#if IS_ENABLED(CONFIG_ATM_MPOA_INTEL_DSL_PHY_SUPPORT) ++ if (atm_hook_mpoa_setup) /* PPPoA */ ++ atm_hook_mpoa_setup(atmvcc, 2, ++ pvcc->encaps == e_llc ? 1 : 0, ++ ppp_device(&pvcc->chan)); ++#endif + atmvcc->release_cb = pppoatm_release_cb; + __module_get(THIS_MODULE); + atmvcc->owner = THIS_MODULE;