diff mbox series

[net-next,06/20] net: ethernet: qualcomm: Add PPE TDM config

Message ID 20240110114033.32575-7-quic_luoj@quicinc.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net: ethernet: Add qcom PPE driver | expand

Checks

Context Check Description
netdev/series_format fail Series longer than 15 patches (and no cover letter)
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 26 this patch: 28
netdev/cc_maintainers success CCed 0 of 0 maintainers
netdev/build_clang fail Errors and warnings before: 20 this patch: 21
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 19 this patch: 19
netdev/checkpatch warning WARNING: line length of 81 exceeds 80 columns WARNING: line length of 82 exceeds 80 columns WARNING: line length of 83 exceeds 80 columns WARNING: line length of 84 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns WARNING: line length of 89 exceeds 80 columns WARNING: line length of 90 exceeds 80 columns WARNING: line length of 93 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jie Luo Jan. 10, 2024, 11:40 a.m. UTC
TDM(Time Division Multiplex) config controls the performance of the
PPE ports, which assigns the clock tickets for the PPE port to receive
and transmit packet.

Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
 drivers/net/ethernet/qualcomm/ppe/ppe.c      | 111 ++++++++++++++++++-
 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h |  30 +++++
 2 files changed, 140 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
index 122e325b407d..85d8b06a326b 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
@@ -625,6 +625,111 @@  static int of_parse_ppe_qm(struct ppe_device *ppe_dev,
 	return ret;
 }
 
+static int of_parse_ppe_tdm(struct ppe_device *ppe_dev,
+			    struct device_node *ppe_node)
+{
+	struct device_node *tdm_node;
+	u32 *cfg, reg_val;
+	int ret, cnt;
+
+	tdm_node = of_get_child_by_name(ppe_node, "tdm-config");
+	if (!tdm_node)
+		return dev_err_probe(ppe_dev->dev, -ENODEV,
+				     "tdm-config is not defined\n");
+
+	cnt = of_property_count_u32_elems(tdm_node, "qcom,tdm-bm-config");
+	if (cnt < 0)
+		return dev_err_probe(ppe_dev->dev, -EINVAL,
+				     "Fail to get qcom,tdm-bm-config\n");
+
+	cfg = kmalloc_array(cnt, sizeof(*cfg), GFP_KERNEL | __GFP_ZERO);
+	if (!cfg)
+		return -ENOMEM;
+
+	ret = of_property_read_u32_array(tdm_node, "qcom,tdm-bm-config", cfg, cnt);
+	if (ret) {
+		dev_err(ppe_dev->dev, "Fail to get qcom,tdm-bm-config\n");
+		goto parse_tdm_err;
+	}
+
+	/* Parse TDM BM configuration,
+	 * the dts property:
+	 * qcom,tdm-bm-config = <valid dir port second_valid second_port>;
+	 *
+	 * This config decides the number ticks available for physical port
+	 * to utilize buffer for receiving and transmiting packet.
+	 */
+	reg_val = FIELD_PREP(PPE_BM_TDM_CTRL_TDM_DEPTH, cnt / 5) |
+		  FIELD_PREP(PPE_BM_TDM_CTRL_TDM_OFFSET, 0) |
+		  FIELD_PREP(PPE_BM_TDM_CTRL_TDM_EN, 1);
+	ret = ppe_write(ppe_dev, PPE_BM_TDM_CTRL, reg_val);
+	if (ret)
+		return ret;
+
+	ret = 0;
+	while ((cnt - ret) / 5) {
+		reg_val = FIELD_PREP(PPE_BM_TDM_CFG_TBL_VALID, cfg[ret]) |
+			  FIELD_PREP(PPE_BM_TDM_CFG_TBL_DIR, cfg[ret + 1]) |
+			  FIELD_PREP(PPE_BM_TDM_CFG_TBL_PORT_NUM, cfg[ret + 2]) |
+			  FIELD_PREP(PPE_BM_TDM_CFG_TBL_SECOND_PORT_VALID, cfg[ret + 3]) |
+			  FIELD_PREP(PPE_BM_TDM_CFG_TBL_SECOND_PORT, cfg[ret + 4]);
+
+		ppe_write(ppe_dev,
+			  PPE_BM_TDM_CFG_TBL + (ret / 5) * PPE_BM_TDM_CFG_TBL_INC,
+			  reg_val);
+		ret += 5;
+	}
+
+	cnt = of_property_count_u32_elems(tdm_node, "qcom,tdm-port-scheduler-config");
+	if (cnt < 0) {
+		dev_err(ppe_dev->dev, "Fail to get qcom,tdm-port-scheduler-config\n");
+		goto parse_tdm_err;
+	}
+
+	cfg = krealloc_array(cfg, cnt, sizeof(*cfg), GFP_KERNEL | __GFP_ZERO);
+	if (!cfg) {
+		ret = -ENOMEM;
+		goto parse_tdm_err;
+	}
+
+	ret = of_property_read_u32_array(tdm_node, "qcom,tdm-port-scheduler-config",
+					 cfg, cnt);
+	if (ret) {
+		dev_err(ppe_dev->dev, "Fail to get qcom,tdm-port-scheduler-config\n");
+		goto parse_tdm_err;
+	}
+
+	/* Parse TDM scheduler configuration,
+	 * the dts property:
+	 * qcom,tdm-port-scheduler-config = <ensch_bmp ensch_port desch_port
+	 * desch_second_valid desch_second_port>;
+	 *
+	 * This config decides the ticks number available for packet enqueue
+	 * and dequeue on the physical port.
+	 */
+	reg_val = FIELD_PREP(PPE_PSCH_TDM_DEPTH_CFG_TDM_DEPTH, cnt / 5);
+	ppe_write(ppe_dev, PPE_PSCH_TDM_DEPTH_CFG, reg_val);
+
+	ret = 0;
+	while ((cnt - ret) / 5) {
+		reg_val = FIELD_PREP(PPE_PSCH_TDM_CFG_TBL_ENS_PORT_BITMAP, cfg[ret]) |
+			  FIELD_PREP(PPE_PSCH_TDM_CFG_TBL_ENS_PORT, cfg[ret + 1]) |
+			  FIELD_PREP(PPE_PSCH_TDM_CFG_TBL_DES_PORT, cfg[ret + 2]) |
+			  FIELD_PREP(PPE_PSCH_TDM_CFG_TBL_DES_SECOND_PORT_EN, cfg[ret + 3]) |
+			  FIELD_PREP(PPE_PSCH_TDM_CFG_TBL_DES_SECOND_PORT, cfg[ret + 4]);
+
+		ppe_write(ppe_dev,
+			  PPE_PSCH_TDM_CFG_TBL + (ret / 5) * PPE_PSCH_TDM_CFG_TBL_INC,
+			  reg_val);
+		ret += 5;
+	}
+
+	ret = 0;
+parse_tdm_err:
+	kfree(cfg);
+	return ret;
+};
+
 static int of_parse_ppe_config(struct ppe_device *ppe_dev,
 			       struct device_node *ppe_node)
 {
@@ -634,7 +739,11 @@  static int of_parse_ppe_config(struct ppe_device *ppe_dev,
 	if (ret)
 		return ret;
 
-	return of_parse_ppe_qm(ppe_dev, ppe_node);
+	ret = of_parse_ppe_qm(ppe_dev, ppe_node);
+	if (ret)
+		return ret;
+
+	return of_parse_ppe_tdm(ppe_dev, ppe_node);
 }
 
 static int qcom_ppe_probe(struct platform_device *pdev)
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
index 3e75b75fa48c..589f92a4f607 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
@@ -7,14 +7,44 @@ 
 #ifndef __PPE_REGS_H__
 #define __PPE_REGS_H__
 
+#define PPE_BM_TDM_CTRL						0xb000
+#define PPE_BM_TDM_CTRL_NUM					1
+#define PPE_BM_TDM_CTRL_INC					4
+#define PPE_BM_TDM_CTRL_TDM_DEPTH				GENMASK(7, 0)
+#define PPE_BM_TDM_CTRL_TDM_OFFSET				GENMASK(14, 8)
+#define PPE_BM_TDM_CTRL_TDM_EN					BIT(31)
+
+#define PPE_BM_TDM_CFG_TBL					0xc000
+#define PPE_BM_TDM_CFG_TBL_NUM					128
+#define PPE_BM_TDM_CFG_TBL_INC					0x10
+#define PPE_BM_TDM_CFG_TBL_PORT_NUM				GENMASK(3, 0)
+#define PPE_BM_TDM_CFG_TBL_DIR					BIT(4)
+#define PPE_BM_TDM_CFG_TBL_VALID				BIT(5)
+#define PPE_BM_TDM_CFG_TBL_SECOND_PORT_VALID			BIT(6)
+#define PPE_BM_TDM_CFG_TBL_SECOND_PORT				GENMASK(11, 8)
+
 #define PPE_EG_BRIDGE_CONFIG					0x20044
 #define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN			BIT(2)
 
+#define PPE_PSCH_TDM_DEPTH_CFG					0x400000
+#define PPE_PSCH_TDM_DEPTH_CFG_NUM				1
+#define PPE_PSCH_TDM_DEPTH_CFG_INC				4
+#define PPE_PSCH_TDM_DEPTH_CFG_TDM_DEPTH			GENMASK(7, 0)
+
 #define PPE_DEQ_OPR_TBL						0x430000
 #define PPE_DEQ_OPR_TBL_NUM					300
 #define PPE_DEQ_OPR_TBL_INC					0x10
 #define PPE_ENQ_OPR_TBL_DEQ_DISABLE				BIT(0)
 
+#define PPE_PSCH_TDM_CFG_TBL					0x47a000
+#define PPE_PSCH_TDM_CFG_TBL_NUM				128
+#define PPE_PSCH_TDM_CFG_TBL_INC				0x10
+#define PPE_PSCH_TDM_CFG_TBL_DES_PORT				GENMASK(3, 0)
+#define PPE_PSCH_TDM_CFG_TBL_ENS_PORT				GENMASK(7, 4)
+#define PPE_PSCH_TDM_CFG_TBL_ENS_PORT_BITMAP			GENMASK(15, 8)
+#define PPE_PSCH_TDM_CFG_TBL_DES_SECOND_PORT_EN			BIT(16)
+#define PPE_PSCH_TDM_CFG_TBL_DES_SECOND_PORT			GENMASK(20, 17)
+
 #define PPE_BM_PORT_FC_MODE					0x600100
 #define PPE_BM_PORT_FC_MODE_NUM					15
 #define PPE_BM_PORT_FC_MODE_INC					4