// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2017-2018, Intel Corporation
*/
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/genalloc.h>
#include <linux/io.h>
#include <linux/kfifo.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/firmware/intel/stratix10-smc.h>
#include <linux/firmware/intel/stratix10-svc-client.h>
#include <linux/types.h>
/**
* SVC_NUM_DATA_IN_FIFO - number of struct stratix10_svc_data in the FIFO
*
* SVC_NUM_CHANNEL - number of channel supported by service layer driver
*
* FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS - claim back the submitted buffer(s)
* from the secure world for FPGA manager to reuse, or to free the buffer(s)
* when all bit-stream data had be send.
*
* FPGA_CONFIG_STATUS_TIMEOUT_SEC - poll the FPGA configuration status,
* service layer will return error to FPGA manager when timeout occurs,
* timeout is set to 30 seconds (30 * 1000) at Intel Stratix10 SoC.
*/
#define SVC_NUM_DATA_IN_FIFO 32
#define SVC_NUM_CHANNEL 3
#define FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS 200
#define FPGA_CONFIG_STATUS_TIMEOUT_SEC 30
#define BYTE_TO_WORD_SIZE 4
/* stratix10 service layer clients */
#define STRATIX10_RSU "stratix10-rsu"
#define INTEL_FCS "intel-fcs"
typedef void (svc_invoke_fn)(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long,
struct arm_smccc_res *);
struct stratix10_svc_chan;
/**
* struct stratix10_svc - svc private data
* @stratix10_svc_rsu: pointer to stratix10 RSU device
*/
struct stratix10_svc {
struct platform_device *stratix10_svc_rsu;
struct platform_device *intel_svc_fcs;
};
/**
* struct stratix10_svc_sh_memory - service shared memory structure
* @sync_complete: state for a completion
* @addr: physical address of shared memory block
* @size: size of shared memory block
* @invoke_fn: function to issue secure monitor or hypervisor call
*
* This struct is used to save physical address and size of shared memory
* block. The shared memory blocked is allocated by secure monitor software
* at secure world.
*
* Service layer driver uses the physical address and size to create a memory
* pool, then allocates data buffer from that memory pool for service client.
*/
struct stratix10_svc_sh_memory {
struct completion sync_complete;
unsigned long addr;
unsigned long size;
svc_invoke_fn *invoke_fn;
};
/**
* struct stratix10_svc_data_mem - service memory structure
* @vaddr: virtual address
* @paddr: physical address
* @size: size of memory
* @node: link list head node
*
* This struct is used in a list that keeps track of buffers which have
* been allocated or freed from the memory pool. Service layer driver also
* uses this struct to transfer physical address to virtual address.
*/
struct stratix10_svc_data_mem {
void *vaddr;
phys_addr_t paddr;
size_t size;
struct list_head node;
};
/**
* struct stratix10_svc_data - service data structure
* @chan: service channel
* @paddr: physical address of to be processed payload
* @size: to be processed playload size
* @paddr_output: physical address of processed payload
* @size_output: processed payload size
* @command: service command requested by client
* @flag: configuration type (full or partial)
* @arg: args to be passed via registers and not physically mapped buffers
*
* This struct is used in service FIFO for inter-process communication.
*/
struct stratix10_svc_data {
struct stratix10_svc_chan *chan;
phys_addr_t paddr;
size_t size;
phys_addr_t paddr_output;
size_t size_output;
u32 command;
u32 flag;
u64 arg[3];
};
/**
* struct stratix10_svc_controller - service controller
* @dev: device
* @chans: array of service channels
* @num_chans: number of channels in 'chans' array
* @num_active_client: number of active service client
* @node: list management
* @genpool: memory pool pointing to the memory region
* @task: pointer to the thread task which handles SMC or HVC call
* @svc_fifo: a queue for storing service message data
* @complete_status: state for completion
* @svc_fifo_lock: protect access to service message data queue
* @invoke_fn: function to issue secure monitor call or hypervisor call
*
* This struct is used to create communication channels for service clients, to
* handle secure monitor or hypervisor call.
*/
struct stratix10_svc_controller {
struct device *dev;
struct stratix10_svc_chan *chans