Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0e6ace9 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "interconnect: qcom: Add QoS config support"

parents d129a56a 91f43c8e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@

qnoc-qcs404-objs			:= qcs404.o
qnoc-sdm845-objs			:= sdm845.o
qnoc-lahaina-objs			:= lahaina.o icc-rpmh.o
qnoc-lahaina-objs			:= lahaina.o icc-rpmh.o qnoc-qos.o
icc-smd-rpm-objs			:= smd-rpm.o
icc-bcm-voter-objs			:= bcm-voter.o

+12 −1
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@
#ifndef __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
#define __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__

#include <linux/regmap.h>

#define to_qcom_provider(_provider) \
	container_of(_provider, struct qcom_icc_provider, provider)

@@ -24,6 +26,9 @@ struct qcom_icc_provider {
	size_t num_bcms;
	struct bcm_voter *voter;
	struct list_head probe_list;
	struct regmap *regmap;
	struct clk_bulk_data *clks;
	int num_clks;
};

/**
@@ -85,6 +90,9 @@ struct qcom_icc_node {
	u64 max_peak[QCOM_ICC_NUM_BUCKETS];
	struct qcom_icc_bcm *bcms[MAX_BCM_PER_NODE];
	size_t num_bcms;
	struct regmap *regmap;
	struct qcom_icc_qosbox *qosbox;
	const struct qcom_icc_noc_ops *noc_ops;
};

/**
@@ -125,6 +133,7 @@ struct qcom_icc_fabric {
};

struct qcom_icc_desc {
	const struct regmap_config *config;
	struct qcom_icc_node **nodes;
	size_t num_nodes;
	struct qcom_icc_bcm **bcms;
@@ -132,12 +141,14 @@ struct qcom_icc_desc {
};

#define DEFINE_QNODE(_name, _id, _channels, _buswidth,			\
			_numlinks, ...)					\
			_qosbox, _numlinks, ...)			\
		static struct qcom_icc_node _name = {			\
		.id = _id,						\
		.name = #_name,						\
		.channels = _channels,					\
		.buswidth = _buswidth,					\
		.qosbox = _qosbox,					\
		.noc_ops = &qcom_qnoc4_ops,				\
		.num_links = _numlinks,					\
		.links = { __VA_ARGS__ },				\
	}
+234 −148

File changed.

Preview size limit exceeded, changes collapsed.

+61 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 *
 */

#include <linux/interconnect.h>
#include <linux/interconnect-provider.h>

#include "icc-rpmh.h"
#include "qnoc-qos.h"

#define QOSGEN_MAINCTL_LO(p, qp)	((p)->offsets[qp] + \
					(p)->regs[QOSGEN_OFF_MAINCTL_LO])
# define QOS_SLV_URG_MSG_EN		BIT(3)
# define QOS_DFLT_PRIO_MASK		0x7
# define QOS_DFLT_PRIO_SHFT		4

const u8 icc_qnoc_qos_regs[][QOSGEN_OFF_MAX_REGS] = {
	[ICC_QNOC_QOSGEN_TYPE_RPMH] = {
		[QOSGEN_OFF_MAINCTL_LO] = 0x8,
		[QOSGEN_OFF_LIMITBW_LO] = 0x18,
		[QOSGEN_OFF_SHAPING_LO] = 0x20,
		[QOSGEN_OFF_SHAPING_HI] = 0x24,
		[QOSGEN_OFF_REGUL0CTL_LO] = 0x40,
		[QOSGEN_OFF_REGUL0BW_LO] = 0x48,
	},
};

/**
 * qcom_icc_set_qos - initialize static QoS configurations
 * @node: qcom icc node to operate on
 */
static void qcom_icc_set_qos(struct qcom_icc_node *node)
{
	struct qcom_icc_qosbox *qos = node->qosbox;
	int port;

	if (!node->regmap)
		return;

	if (!qos)
		return;

	for (port = 0; port < qos->num_ports; port++) {
		regmap_update_bits(node->regmap, QOSGEN_MAINCTL_LO(qos, port),
				   QOS_DFLT_PRIO_MASK << QOS_DFLT_PRIO_SHFT,
				   qos->config->prio << QOS_DFLT_PRIO_SHFT);

		if (qos->config->urg_fwd)
			regmap_update_bits(node->regmap,
					   QOSGEN_MAINCTL_LO(qos, port),
					   QOS_SLV_URG_MSG_EN,
					   QOS_SLV_URG_MSG_EN);
	}
}

const struct qcom_icc_noc_ops qcom_qnoc4_ops = {
	.set_qos = qcom_icc_set_qos,
};
EXPORT_SYMBOL(qcom_qnoc4_ops);
+58 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 *
 */

#ifndef __DRIVERS_INTERCONNECT_QCOM_QNOC_QOS_H__
#define __DRIVERS_INTERCONNECT_QCOM_QNOC_QOS_H__

#define QOSGEN_OFF_MAX_REGS 6
#define ICC_QNOC_QOS_MAX_TYPE 1

enum {
	ICC_QNOC_QOSGEN_TYPE_RPMH,
};

enum {
	QOSGEN_OFF_MAINCTL_LO,
	QOSGEN_OFF_LIMITBW_LO,
	QOSGEN_OFF_SHAPING_LO,
	QOSGEN_OFF_SHAPING_HI,
	QOSGEN_OFF_REGUL0CTL_LO,
	QOSGEN_OFF_REGUL0BW_LO,
};

extern const u8 icc_qnoc_qos_regs[ICC_QNOC_QOS_MAX_TYPE][QOSGEN_OFF_MAX_REGS];

struct qcom_icc_noc_ops {
	void		(*set_qos)(struct qcom_icc_node *node);
};

struct qos_config {
	u32 prio;
	u32 urg_fwd;
};

struct qcom_icc_qosbox {
	u32 num_ports;
	const u8 *regs;
	struct qos_config *config;
	u32 offsets[];
};

#define DEFINE_QNODE_QOS(_name, _prio, _urg_fwd, _num_ports, ...)	\
		static struct qos_config _name##_qos_cfg = {		\
		.prio = _prio,						\
		.urg_fwd = _urg_fwd,					\
	};								\
		static struct qcom_icc_qosbox _name##_qos = {		\
		.num_ports = _num_ports,				\
		.config = &_name##_qos_cfg,				\
		.regs = icc_qnoc_qos_regs[ICC_QNOC_QOSGEN_TYPE_RPMH],	\
		.offsets = {__VA_ARGS__},				\
	}								\

extern const struct qcom_icc_noc_ops qcom_qnoc4_ops;

#endif