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

Commit 987bbebd authored by Karthikeyan Ramasubramanian's avatar Karthikeyan Ramasubramanian Committed by Rohit Vaswani
Browse files

soc: qcom: Add snapshot of G-Link driver



This snapshot is taken as of msm-3.18 commit e70ad0cd (Promotion of
kernel.lnx.3.18-151201.)

Signed-off-by: default avatarKarthikeyan Ramasubramanian <kramasub@codeaurora.org>
parent c064e79d
Loading
Loading
Loading
Loading
+1239 −0

File added.

Preview size limit exceeded, changes collapsed.

+46 −0
Original line number Diff line number Diff line
@@ -31,6 +31,45 @@ config MSM_SMD_DEBUG
	  what channels caused interrupt activity, and when internal state
	  change events occur.

config MSM_GLINK
	bool "Generic Link (G-Link)"
	help
	  G-Link is a generic link transport that replaces SMD.  It is used
	  within a System-on-Chip (SoC) for communication between both internal
	  processors and external peripherals.  The actual physical transport
	  is handled by transport plug-ins that can be individually enabled and
	  configured separately.

config MSM_GLINK_LOOPBACK_SERVER
	bool "Generic Link (G-Link) Loopback Server"
	help
	  G-Link Loopback Server that enable loopback test framework to test
	  and validate the G-Link protocol stack. It support both local and
	  remote clients to configure the loopback server and echo back the
	  data received from the clients.

config MSM_GLINK_SMD_XPRT
	depends on MSM_SMD
	depends on MSM_GLINK
	bool "Generic Link (G-Link) SMD Transport"
	help
	  G-Link SMD Transport is a G-Link Transport plug-in.  It allows G-Link
	  communication to remote entities through a SMD physical transport
	  channel.  The remote side is assumed to be pure SMD.  The nature of
	  SMD limits this G-Link transport to only connecting with entities
	  internal to the System-on-Chip.

config MSM_GLINK_SMEM_NATIVE_XPRT
	depends on MSM_SMEM
	depends on MSM_GLINK
	bool "Generic Link (G-Link) SMEM Native Transport"
	help
	  G-Link SMEM Native Transport is a G-Link Transport plug-in.  It allows
	  G-Link communication to remote entities through a shared memory
	  physical transport.  The nature of shared memory limits this G-Link
	  transport to only connecting with entities internal to the
	  System-on-Chip.

config QCOM_GSBI
        tristate "QCOM General Serial Bus Interface"
        depends on ARCH_QCOM
@@ -146,3 +185,10 @@ config QCOM_MEMORY_DUMP_V2
	  give a snapshot of the system at the time of the crash.

endif # ARCH_QCOM

config TRACER_PKT
	bool "Tracer Packet"
	help
	  Tracer Packet helps in profiling the performance of inter-
	  processor communication protocols. The profiling information
	  can be logged into the tracer packet itself.
+5 −0
Original line number Diff line number Diff line
obj-$(CONFIG_MSM_SMEM)	+=	msm_smem.o smem_debug.o
obj-$(CONFIG_MSM_SMD)	+= 	msm_smd.o smd_debug.o smd_private.o smd_init_dt.o smsm_debug.o
obj-$(CONFIG_MSM_GLINK)	+=	glink.o glink_debugfs.o glink_ssr.o
obj-$(CONFIG_MSM_GLINK_LOOPBACK_SERVER)	+=	glink_loopback_server.o
obj-$(CONFIG_MSM_GLINK_SMD_XPRT)	+=	glink_smd_xprt.o
obj-$(CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT)+=	glink_smem_native_xprt.o
obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
obj-$(CONFIG_QCOM_PM)	+=	spm.o
obj-$(CONFIG_QCOM_SMD) +=	smd.o
@@ -14,3 +18,4 @@ obj-$(CONFIG_QCOM_WATCHDOG_V2) += watchdog_v2.o
obj-$(CONFIG_QCOM_MEMORY_DUMP) += memory_dump.o
obj-$(CONFIG_QCOM_MEMORY_DUMP_V2) += memory_dump_v2.o
obj-$(CONFIG_QCOM_WATCHDOG_V2) += watchdog_v2.o
obj-$(CONFIG_TRACER_PKT)	+=	tracer_pkt.o
+5713 −0

File added.

Preview size limit exceeded, changes collapsed.

+213 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, 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 _SOC_QCOM_GLINK_CORE_IF_H_
#define _SOC_QCOM_GLINK_CORE_IF_H_

#include <linux/of.h>
#include <linux/types.h>
#include "glink_private.h"

/* Local Channel state */
enum local_channel_state_e {
	GLINK_CHANNEL_CLOSED = 0,
	GLINK_CHANNEL_OPENING,
	GLINK_CHANNEL_OPENED,
	GLINK_CHANNEL_CLOSING,
};

/* Transport Negotiation State */
enum transport_state_e {
	GLINK_XPRT_DOWN,
	GLINK_XPRT_NEGOTIATING,
	GLINK_XPRT_OPENED,
	GLINK_XPRT_FAILED,
};

struct channel_ctx;
struct glink_core_xprt_ctx;
struct glink_transport_if;
struct glink_core_version;

/**
 * struct glink_core_version - Individual version element
 *
 * version:	supported version
 * features:	all supported features for version
 */
struct glink_core_version {
	uint32_t version;
	uint32_t features;

	uint32_t (*negotiate_features)(struct glink_transport_if *if_ptr,
			const struct glink_core_version *version_ptr,
			uint32_t features);
};

/**
 * RX intent
 *
 * data:	pointer to the data (may be NULL for zero-copy)
 * id:		remote or local intent ID
 * pkt_size:	total size of packet
 * write_offset: next write offset (initially 0)
 * intent_size:	size of the original intent (do not modify)
 * tracer_pkt:	Flag to indicate if the data is a tracer packet
 * iovec:	Pointer to vector buffer if the transport passes a vector buffer
 * vprovider:	Virtual address-space buffer provider for a vector buffer
 * pprovider:	Physical address-space buffer provider for a vector buffer
 * pkt_priv:	G-Link core owned packet-private data
 * list:	G-Link core owned list node
 * bounce_buf:	Pointer to the temporary/internal bounce buffer
 */
struct glink_core_rx_intent {
	void *data;
	uint32_t id;
	size_t pkt_size;
	size_t write_offset;
	size_t intent_size;
	bool tracer_pkt;
	void *iovec;
	void * (*vprovider)(void *iovec, size_t offset, size_t *size);
	void * (*pprovider)(void *iovec, size_t offset, size_t *size);

	/* G-Link-Core-owned elements - please ignore */
	struct list_head list;
	const void *pkt_priv;
	void *bounce_buf;
};

/**
 * struct glink_core_flow_info - Flow specific Information
 * @mtu_tx_time_us:	Time to transmit an MTU in microseconds.
 * @power_state:	Power state associated with the traffic flow.
 */
struct glink_core_flow_info {
	unsigned long mtu_tx_time_us;
	uint32_t power_state;
};

/**
 * struct glink_core_transport_cfg - configuration of a new transport
 * @name:		Name of the transport.
 * @edge:		Subsystem the transport connects to.
 * @versions:		Array of transport versions supported.
 * @versions_entries:	Number of entries in @versions.
 * @max_cid:		Maximum number of channel identifiers supported.
 * @max_iid:		Maximum number of intent identifiers supported.
 * @mtu:		MTU supported by this transport.
 * @num_flows:		Number of traffic flows/priority buckets.
 * @flow_info:		Information about each flow/priority.
 * @token_count:	Number of tokens per assignment.
 */
struct glink_core_transport_cfg {
	const char *name;
	const char *edge;
	const struct glink_core_version *versions;
	size_t versions_entries;
	uint32_t max_cid;
	uint32_t max_iid;

	size_t mtu;
	uint32_t num_flows;
	struct glink_core_flow_info *flow_info;
	uint32_t token_count;
};

struct glink_core_if {
	/* Negotiation */
	void (*link_up)(struct glink_transport_if *if_ptr);
	void (*link_down)(struct glink_transport_if *if_ptr);
	void (*rx_cmd_version)(struct glink_transport_if *if_ptr,
			uint32_t version,
			uint32_t features);
	void (*rx_cmd_version_ack)(struct glink_transport_if *if_ptr,
			uint32_t version,
			uint32_t features);

	/* channel management */
	void (*rx_cmd_ch_remote_open)(struct glink_transport_if *if_ptr,
			uint32_t rcid, const char *name, uint16_t req_xprt);
	void (*rx_cmd_ch_open_ack)(struct glink_transport_if *if_ptr,
			uint32_t lcid, uint16_t xprt_resp);
	void (*rx_cmd_ch_remote_close)(struct glink_transport_if *if_ptr,
			uint32_t rcid);
	void (*rx_cmd_ch_close_ack)(struct glink_transport_if *if_ptr,
			uint32_t lcid);

	/* channel data */
	struct glink_core_rx_intent * (*rx_get_pkt_ctx)(
			struct glink_transport_if *if_ptr,
			uint32_t rcid, uint32_t liid);
	void (*rx_put_pkt_ctx)(struct glink_transport_if *if_ptr, uint32_t rcid,
			struct glink_core_rx_intent *intent_ptr, bool complete);
	void (*rx_cmd_remote_rx_intent_put)(struct glink_transport_if *if_ptr,
			uint32_t rcid, uint32_t riid, size_t size);
	void (*rx_cmd_tx_done)(struct glink_transport_if *if_ptr, uint32_t rcid,
			uint32_t riid, bool reuse);
	void (*rx_cmd_remote_rx_intent_req)(struct glink_transport_if *if_ptr,
			uint32_t rcid, size_t size);
	void (*rx_cmd_rx_intent_req_ack)(struct glink_transport_if *if_ptr,
			uint32_t rcid, bool granted);
	void (*rx_cmd_remote_sigs)(struct glink_transport_if *if_ptr,
			uint32_t rcid, uint32_t sigs);

	/* channel scheduling */
	void (*tx_resume)(struct glink_transport_if *if_ptr);
};

int glink_core_register_transport(struct glink_transport_if *if_ptr,
		struct glink_core_transport_cfg *cfg);

void glink_core_unregister_transport(struct glink_transport_if *if_ptr);

/**
 * of_get_glink_core_qos_cfg() - Parse the qos related dt entries
 * @phandle:	The handle to the qos related node in DT.
 * @cfg:	The transport configuration to be filled.
 *
 * Return: 0 on Success, standard Linux error otherwise.
 */
int of_get_glink_core_qos_cfg(struct device_node *phandle,
				struct glink_core_transport_cfg *cfg);

/**
 * rx_linear_vbuf_provider() - Virtual Buffer Provider for linear buffers
 * iovec:	Pointer to the beginning of the linear buffer.
 * offset:	Offset into the buffer whose address is needed.
 * size:	Pointer to hold the length of the contiguous buffer space.
 *
 * This function is used when a linear buffer is received while the client has
 * registered to receive vector buffers.
 *
 * Return: Address of the buffer which is at offset "offset" from the beginning
 *         of the buffer.
 */
static inline void *rx_linear_vbuf_provider(void *iovec, size_t offset,
					    size_t *size)
{
	struct glink_core_rx_intent *rx_info =
		(struct glink_core_rx_intent *)iovec;

	if (unlikely(!iovec || !size))
		return NULL;

	if (unlikely(offset >= rx_info->pkt_size))
		return NULL;

	if (unlikely(OVERFLOW_ADD_UNSIGNED(void *, rx_info->data, offset)))
		return NULL;

	*size = rx_info->pkt_size - offset;
	return rx_info->data + offset;
}

#endif /* _SOC_QCOM_GLINK_CORE_IF_H_ */
Loading