Commit 114eeeba authored by Federico Vaga's avatar Federico Vaga

sw:*: change mqueue header

With this effort we tried to improve the MQ header file
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent f7febb32
......@@ -43,37 +43,37 @@ struct rt_buffer svec_buffers[] = {
struct rt_variable svec_variables[] = {
[SVEC_VAR_LEMO_STA] = {
.addr = TRTL_DP_ADDR(GPIO_PSR),
.addr = TRTL_ADDR_DP(GPIO_PSR),
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[SVEC_VAR_LEMO_DIR] = {
.addr = TRTL_DP_ADDR(GPIO_DDR),
.addr = TRTL_ADDR_DP(GPIO_DDR),
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[SVEC_VAR_LEMO_SET] = {
.addr = TRTL_DP_ADDR(GPIO_SODR),
.addr = TRTL_ADDR_DP(GPIO_SODR),
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[SVEC_VAR_LEMO_CLR] = {
.addr = TRTL_DP_ADDR(GPIO_CODR),
.addr = TRTL_ADDR_DP(GPIO_CODR),
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[SVEC_VAR_LED_STA] = {
.addr = TRTL_DP_ADDR(GPIO_PSR),
.addr = TRTL_ADDR_DP(GPIO_PSR),
.mask = PIN_LED_MASK,
.offset = PIN_LED_OFFSET,
},
[SVEC_VAR_LED_SET] = {
.addr = TRTL_DP_ADDR(GPIO_SODR),
.addr = TRTL_ADDR_DP(GPIO_SODR),
.mask = PIN_LED_MASK,
.offset = PIN_LED_OFFSET,
},
[SVEC_VAR_LED_CLR] = {
.addr = TRTL_DP_ADDR(GPIO_CODR),
.addr = TRTL_ADDR_DP(GPIO_CODR),
.mask = PIN_LED_MASK,
.offset = PIN_LED_OFFSET,
},
......
......@@ -16,116 +16,109 @@
#ifndef __MQUEUE_H
#define __MQUEUE_H
// Nax number of supported incoming/outgoing slots
#define MAX_MQUEUE_SLOTS 16
// HMQ base address (wrs to the base addr of the WR Node Core)
#define BASE_HMQ 0x00000
// Global Control Registers base address, relative to BASE_HMQ (SLOT_COUNT, SLOT_STATUS, interrupt control, etc).
// Common for all incoming/outgoing slots in the queue
#define MQUEUE_BASE_GCR (0x0)
#define TRTL_MQ_BASE_GCR (0x0)
// Incoming slot base address, relative to BASE_HMQ
#define MQUEUE_BASE_IN(slot) (0x4000 + (slot) * 0x400)
#define TRTL_MQ_BASE_IN(slot) (0x4000 + (slot) * 0x400)
// Outgoung slot base address, relative to BASE_HMQ
#define MQUEUE_BASE_OUT(slot) (0x8000 + (slot) * 0x400)
#define TRTL_MQ_BASE_OUT(slot) (0x8000 + (slot) * 0x400)
// MQ slot registers, relative to the base address of each slot: MQUEUE_BASE_IN(slot_no) or MQUEUE_BASE_OUT(slot_no)
#define MQUEUE_SLOT_COMMAND 0
// MQ slot registers, relative to the base address of each slot: TRTL_MQ_BASE_IN(slot_no) or TRTL_MQ_BASE_OUT(slot_no)
#define TRTL_MQ_SLOT_COMMAND 0
// Status register
#define MQUEUE_SLOT_STATUS 4
#define TRTL_MQ_SLOT_STATUS 4
// Start of header block
#define MQUEUE_SLOT_HEADER_START 0x1000
#define TRTL_MQ_SLOT_HEADER_START 0x1000
// Start of data block
#define MQUEUE_SLOT_DATA_START 0x2000
#define TRTL_MQ_SLOT_DATA_START 0x2000
// Layout of MQUEUE_SLOT_COMMAND register:
// Layout of TRTL_MQ_SLOT_COMMAND register:
// Claim: prepares a slot to send a message (w/o)
#define MQUEUE_CMD_CLAIM (1<<24)
#define TRTL_MQ_CMD_CLAIM (1<<24)
// Purge: erases all messages from a slot (w/o)
#define MQUEUE_CMD_PURGE (1<<25)
#define TRTL_MQ_CMD_PURGE (1<<25)
// Ready: pushes the message to the queue. (w/o)
#define MQUEUE_CMD_READY (1<<26)
#define TRTL_MQ_CMD_READY (1<<26)
// Discard: removes last message from the queue, advancing to the next one (w/o)
#define MQUEUE_CMD_DISCARD (1<<27)
#define TRTL_MQ_CMD_DISCARD (1<<27)
// Size of the message to be sent, in words (w/o). Must be written together with the
// READY command, e.g.:
// writel (MQUEUE_CMD_READY | 10, MQUEUE_SLOT_COMMAND);
#define MQUEUE_CMD_MSG_SIZE_MASK 0xff
#define MQUEUE_CMD_MSG_SIZE_SHIFT 0
// writel (TRTL_MQ_CMD_READY | 10, TRTL_MQ_SLOT_COMMAND);
#define TRTL_MQ_CMD_MSG_SIZE_MASK 0xff
#define TRTL_MQ_CMD_MSG_SIZE_SHIFT 0
// Layout of MQUEUE_SLOT_STATUS register:
// Layout of TRTL_MQ_SLOT_STATUS register:
// [0] Slot is full
#define MQUEUE_SLOT_STATUS_FULL (1<<0)
#define TRTL_MQ_SLOT_STATUS_FULL (1<<0)
// [1] Slot is empty
#define MQUEUE_SLOT_STATUS_EMPTY (1<<1)
#define TRTL_MQ_SLOT_STATUS_EMPTY (1<<1)
// [15:8] Number of occupied entries
#define MQUEUE_SLOT_STATUS_OCCUPIED_SHIFT 8
#define MQUEUE_SLOT_STATUS_OCCUPIED_MASK 0xff00
#define TRTL_MQ_SLOT_STATUS_OCCUPIED_SHIFT 8
#define TRTL_MQ_SLOT_STATUS_OCCUPIED_MASK 0xff00
// [23:16] Number of transferred words in the message currently on top of the slot
#define MQUEUE_SLOT_STATUS_MSG_SIZE_SHIFT 16
#define MQUEUE_SLOT_STATUS_MSG_SIZE_MASK 0xff0000
#define TRTL_MQ_SLOT_STATUS_MSG_SIZE_SHIFT 16
#define TRTL_MQ_SLOT_STATUS_MSG_SIZE_MASK 0xff0000
// [31:28] log2(number of words in the slot).
#define MQUEUE_SLOT_STATUS_LOG2_WIDTH_SHIFT 28
#define MQUEUE_SLOT_STATUS_LOG2_WIDTH_MASK 0xf0000000
#define TRTL_MQ_SLOT_STATUS_LOG2_WIDTH_SHIFT 28
#define TRTL_MQ_SLOT_STATUS_LOG2_WIDTH_MASK 0xf0000000
// [7:2] log2(number of entries in the slot).
#define MQUEUE_SLOT_STATUS_LOG2_ENTRIES_SHIFT 2
#define MQUEUE_SLOT_STATUS_LOG2_ENTRIES_MASK 0xfc
#define TRTL_MQ_SLOT_STATUS_LOG2_ENTRIES_SHIFT 2
#define TRTL_MQ_SLOT_STATUS_LOG2_ENTRIES_MASK 0xfc
//
// MQ Global Control Registers.Adresses relative to MQUEUE_BASE_GCR:
// MQ Global Control Registers.Adresses relative to TRTL_MQ_BASE_GCR:
//
#define MQUEUE_GCR_INCOMING_STATUS_MASK (0x0000ffff)
#define TRTL_MQ_GCR_INCOMING_STATUS_MASK (0x0000ffff)
// Number of slots in this implementation of HMQ
#define MQUEUE_GCR_SLOT_COUNT 0
#define TRTL_MQ_GCR_SLOT_COUNT 0
// EMPTY bits of all slots in a single register (for polling/IRQ status)
#define MQUEUE_GCR_SLOT_STATUS 4
#define TRTL_MQ_GCR_SLOT_STATUS 4
// Interrupt mask (Outgoing: EMPTY, Incoming: not EMPTY)
#define MQUEUE_GCR_IRQ_MASK 8
#define TRTL_MQ_GCR_IRQ_MASK 8
// IRQ Coalescing register (reserved for future use)
#define MQUEUE_GCR_IRQ_COALESCE 12
#define TRTL_MQ_GCR_IRQ_COALESCE 12
// Layout of SLOT_COUNT register
// [7:0] Number of Incoming slots
#define MQUEUE_GCR_SLOT_COUNT_N_IN_SHIFT 0
#define MQUEUE_GCR_SLOT_COUNT_N_IN_MASK 0xff
#define TRTL_MQ_GCR_SLOT_COUNT_N_IN_SHIFT 0
#define TRTL_MQ_GCR_SLOT_COUNT_N_IN_MASK 0xff
// [15:8] Number of Outgoing slots
#define MQUEUE_GCR_SLOT_COUNT_N_OUT_SHIFT 8
#define MQUEUE_GCR_SLOT_COUNT_N_OUT_MASK 0xff00
#define TRTL_MQ_GCR_SLOT_COUNT_N_OUT_SHIFT 8
#define TRTL_MQ_GCR_SLOT_COUNT_N_OUT_MASK 0xff00
// Layout of SLOT_STATUS register
// [15:0] Outgoing slots status. Each bit indicates a NOT EMPTY status of the corresponding outgoing slot
#define MQUEUE_GCR_SLOT_STATUS_OUT_SHIFT 0
#define MQUEUE_GCR_SLOT_STATUS_OUT_MASK 0xffff
#define TRTL_MQ_GCR_SLOT_STATUS_OUT_SHIFT 0
#define TRTL_MQ_GCR_SLOT_STATUS_OUT_MASK 0xffff
// [31:16] Incoming slots status. Each bit indicates an EMPTY status of the corresponding incoming slot
#define MQUEUE_GCR_SLOT_STATUS_IN_SHIFT 16
#define MQUEUE_GCR_SLOT_STATUS_IN_MASK 0xffff0000
#define TRTL_MQ_GCR_SLOT_STATUS_IN_SHIFT 16
#define TRTL_MQ_GCR_SLOT_STATUS_IN_MASK 0xffff0000
// Layout of IRQ_MASK register
// [15:0] Outgoing slots status interrupt mask. Each bit enables generation of interrupt on NOT EMPTY status of the corresponding outgoing slot.
#define MQUEUE_GCR_IRQ_MASK_OUT_SHIFT 0
#define MQUEUE_GCR_IRQ_MASK_OUT_MASK 0xffff
#define TRTL_MQ_GCR_IRQ_MASK_OUT_SHIFT 0
#define TRTL_MQ_GCR_IRQ_MASK_OUT_MASK 0xffff
// [31:16] Incoming slots status interrupt mask. Each bit enables generation of interrupt on EMPTY status of the corresponding incoming slot.
#define MQUEUE_GCR_IRQ_MASK_IN_SHIFT 16
#define MQUEUE_GCR_IRQ_MASK_IN_MASK 0xffff0000
#define TRTL_MQ_GCR_IRQ_MASK_IN_SHIFT 16
#define TRTL_MQ_GCR_IRQ_MASK_IN_MASK 0xffff0000
// Layout of IRQ_COALSESCE register
// The register is left for future IRQ coalescing support (if ever needed)
......
......@@ -435,8 +435,9 @@ static void trtl_hmq_release(struct device *dev)
}
#define TRTL_SLOT_CFG(_name, _val) \
(1 << ((_val & MQUEUE_SLOT_STATUS_LOG2_##_name##_MASK) \
>> MQUEUE_SLOT_STATUS_LOG2_##_name##_SHIFT))
(1 << ((_val & TRTL_MQ_SLOT_STATUS_LOG2_##_name##_MASK) \
>> TRTL_MQ_SLOT_STATUS_LOG2_##_name##_SHIFT))
/**
* It initializes and registers a HMQ device
*/
......@@ -490,13 +491,13 @@ static int trtl_probe_hmq(struct trtl_dev *trtl, unsigned int slot,
if (is_input) { /* CPU input */
hmq->flags |= TRTL_FLAG_HMQ_DIR;
hmq->base_sr = trtl->base_hmq + MQUEUE_BASE_IN(slot);
hmq->base_sr = trtl->base_hmq + TRTL_MQ_BASE_IN(slot);
} else { /* CPU output */
hmq->base_sr = trtl->base_hmq + MQUEUE_BASE_OUT(slot);
hmq->base_sr = trtl->base_hmq + TRTL_MQ_BASE_OUT(slot);
}
/* Get HMQ dimensions */
val = trtl_ioread(trtl, hmq->base_sr + MQUEUE_SLOT_STATUS);
val = trtl_ioread(trtl, hmq->base_sr + TRTL_MQ_SLOT_STATUS);
hmq->max_width = TRTL_SLOT_CFG(WIDTH, val);
hmq->max_depth = TRTL_SLOT_CFG(ENTRIES, val);
hmq->buf.max_msg_size = hmq->max_width * 4;
......@@ -505,8 +506,8 @@ static int trtl_probe_hmq(struct trtl_dev *trtl, unsigned int slot,
val, hmq->max_width, hmq->max_depth);
spin_lock_init(&hmq->lock);
/* Flush the content of the slot */
trtl_iowrite(trtl, MQUEUE_CMD_PURGE,
hmq->base_sr + MQUEUE_SLOT_COMMAND);
trtl_iowrite(trtl, TRTL_MQ_CMD_PURGE,
hmq->base_sr + TRTL_MQ_SLOT_COMMAND);
return 0;
}
......@@ -628,7 +629,7 @@ int trtl_probe(struct platform_device *pdev)
trtl->base_smem = trtl->base_core + TRTL_ADDR_OFFSET_SHM;
trtl->base_hmq = trtl->base_core + TRTL_ADDR_OFFSET_HMQ;
trtl->base_cfg = trtl->base_core + TRTL_ADDR_OFFSET_CONFIG_ROM;
trtl->base_gcr = trtl->base_hmq + MQUEUE_BASE_GCR;
trtl->base_gcr = trtl->base_hmq + TRTL_MQ_BASE_GCR;
/* Register the device */
err = dev_set_name(&trtl->dev, "trtl-%04x", pdev->id);
......@@ -697,10 +698,10 @@ int trtl_probe(struct platform_device *pdev)
}
/* Get and check the number of HMQ slots */
tmp = trtl_ioread(trtl, trtl->base_gcr + MQUEUE_GCR_SLOT_COUNT);
trtl->n_hmq_in = tmp & MQUEUE_GCR_SLOT_COUNT_N_IN_MASK;
trtl->n_hmq_out = (tmp & MQUEUE_GCR_SLOT_COUNT_N_OUT_MASK) >>
MQUEUE_GCR_SLOT_COUNT_N_OUT_SHIFT;
tmp = trtl_ioread(trtl, trtl->base_gcr + TRTL_MQ_GCR_SLOT_COUNT);
trtl->n_hmq_in = tmp & TRTL_MQ_GCR_SLOT_COUNT_N_IN_MASK;
trtl->n_hmq_out = (tmp & TRTL_MQ_GCR_SLOT_COUNT_N_OUT_MASK) >>
TRTL_MQ_GCR_SLOT_COUNT_N_OUT_SHIFT;
if (trtl->n_hmq_in + trtl->n_hmq_out >= TRTL_MAX_HMQ_SLOT) {
dev_err(&pdev->dev, "trtl: invalid number of HMQ slots (in %d out %d)\n",
trtl->n_hmq_in, trtl->n_hmq_out);
......@@ -739,10 +740,10 @@ int trtl_probe(struct platform_device *pdev)
trtl->irq_mask = 0;
if (trtl->n_hmq_out)
trtl->irq_mask |= (((1 << trtl->n_hmq_out) - 1)
<< MQUEUE_GCR_IRQ_MASK_OUT_SHIFT);
<< TRTL_MQ_GCR_IRQ_MASK_OUT_SHIFT);
trtl_iowrite(trtl, trtl->irq_mask, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK);
tmp = trtl_ioread(trtl, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK);
trtl_iowrite(trtl, trtl->irq_mask, trtl->base_gcr + TRTL_MQ_GCR_IRQ_MASK);
tmp = trtl_ioread(trtl, trtl->base_gcr + TRTL_MQ_GCR_IRQ_MASK);
err = trtl_tty_probe(trtl);
if (err)
......@@ -791,7 +792,7 @@ int trtl_remove(struct platform_device *pdev)
trtl_tty_remove(trtl);
trtl_iowrite(trtl, 0x0, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK);
trtl_iowrite(trtl, 0x0, trtl->base_gcr + TRTL_MQ_GCR_IRQ_MASK);
free_irq(platform_get_irq(pdev, TRTL_IRQ_HMQ), trtl);
debugfs_remove_recursive(trtl->dbg_dir);
......
......@@ -31,6 +31,7 @@
#include "hw/mockturtle_config.h"
#include "mockturtle.h"
#define MAX_MQUEUE_SLOTS (TRTL_MAX_HMQ_SLOT / 2)
#define TRTL_MAX_CPU_MINORS (TRTL_MAX_CPU * TRTL_MAX_CARRIER)
#define TRTL_MAX_HMQ_MINORS (TRTL_MAX_HMQ_SLOT * TRTL_MAX_CARRIER)
#define TRTL_MAX_MINORS (TRTL_MAX_CARRIER + TRTL_MAX_CPU_MINORS + TRTL_MAX_HMQ_MINORS)
......
......@@ -117,7 +117,7 @@ static ssize_t trtl_show_full(struct device *dev,
struct trtl_dev *trtl = to_trtl_dev(dev->parent);
uint32_t status;
status = trtl_ioread(trtl, hmq->base_sr + MQUEUE_SLOT_STATUS);
status = trtl_ioread(trtl, hmq->base_sr + TRTL_MQ_SLOT_STATUS);
return sprintf(buf, "%d\n", !!(status & 0x1));
}
......@@ -134,7 +134,7 @@ static ssize_t trtl_show_empty(struct device *dev,
struct trtl_dev *trtl = to_trtl_dev(dev->parent);
uint32_t status;
status = trtl_ioread(trtl, hmq->base_sr + MQUEUE_SLOT_STATUS);
status = trtl_ioread(trtl, hmq->base_sr + TRTL_MQ_SLOT_STATUS);
return sprintf(buf, "%d\n", !!(status & 0x2));
}
......@@ -151,7 +151,7 @@ static ssize_t trtl_show_count(struct device *dev,
struct trtl_dev *trtl = to_trtl_dev(dev->parent);
uint32_t status;
status = trtl_ioread(trtl, hmq->base_sr + MQUEUE_SLOT_STATUS);
status = trtl_ioread(trtl, hmq->base_sr + TRTL_MQ_SLOT_STATUS);
return sprintf(buf, "%d\n", ((status >> 2) & 0xFF));
}
......@@ -500,9 +500,9 @@ static ssize_t trtl_hmq_write(struct file *f, const char __user *buf,
/* Enable interrupts for CPU input SLOT */
if (hmq_in_irq) {
mask = trtl_ioread(trtl, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK);
mask |= (1 << (hmq->index + MQUEUE_GCR_IRQ_MASK_IN_SHIFT));
trtl_iowrite(trtl, mask, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK);
mask = trtl_ioread(trtl, trtl->base_gcr + TRTL_MQ_GCR_IRQ_MASK);
mask |= (1 << (hmq->index + TRTL_MQ_GCR_IRQ_MASK_IN_SHIFT));
trtl_iowrite(trtl, mask, trtl->base_gcr + TRTL_MQ_GCR_IRQ_MASK);
}
/* Update counter */
......@@ -542,28 +542,30 @@ static int trtl_message_push(struct trtl_hmq *hmq, void *buf,
size, hmq->buf.max_msg_size);
return -EINVAL;
}
freeslot = trtl_ioread(trtl, hmq->base_sr + MQUEUE_SLOT_STATUS)
& MQUEUE_SLOT_STATUS_OCCUPIED_MASK
>> MQUEUE_SLOT_STATUS_OCCUPIED_SHIFT;
freeslot = trtl_ioread(trtl, hmq->base_sr + TRTL_MQ_SLOT_STATUS)
& TRTL_MQ_SLOT_STATUS_OCCUPIED_MASK
>> TRTL_MQ_SLOT_STATUS_OCCUPIED_SHIFT;
if (!freeslot)
return -EAGAIN;
/* Get the slot in order to write into it */
trtl_iowrite(trtl, MQUEUE_CMD_CLAIM, hmq->base_sr + MQUEUE_SLOT_COMMAND);
trtl_iowrite(trtl, TRTL_MQ_CMD_CLAIM, hmq->base_sr + TRTL_MQ_SLOT_COMMAND);
*seq = ++trtl->message_sequence;
/* Assign a sequence number to the message */
data[1] = *seq;
/* Write data into the slot */
for (i = 0; i < size / 4; ++i) {
trtl_iowrite(trtl, data[i],
hmq->base_sr + MQUEUE_SLOT_DATA_START + i * 4);
hmq->base_sr + TRTL_MQ_SLOT_DATA_START + i * 4);
dev_vdbg(&hmq->dev, "From HOST to MT data[%i] = 0x%08x\n",
i, data[i]);
}
/* The slot is ready to be sent to the CPU */
trtl_iowrite(trtl, MQUEUE_CMD_READY | ((size / 4) & 0xFF),
hmq->base_sr + MQUEUE_SLOT_COMMAND);
trtl_iowrite(trtl, TRTL_MQ_CMD_READY | ((size / 4) & 0xFF),
hmq->base_sr + TRTL_MQ_SLOT_COMMAND);
hmq->stats.count++;
......@@ -899,9 +901,9 @@ static void trtl_irq_handler_input(struct trtl_hmq *hmq)
* interrupts
*/
spin_lock_irqsave(&hmq->lock, flags);
mask = trtl_ioread(trtl, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK);
mask &= ~(1 << (hmq->index + MQUEUE_GCR_IRQ_MASK_IN_SHIFT));
trtl_iowrite(trtl, mask, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK);
mask = trtl_ioread(trtl, trtl->base_gcr + TRTL_MQ_GCR_IRQ_MASK);
mask &= ~(1 << (hmq->index + TRTL_MQ_GCR_IRQ_MASK_IN_SHIFT));
trtl_iowrite(trtl, mask, trtl->base_gcr + TRTL_MQ_GCR_IRQ_MASK);
spin_unlock_irqrestore(&hmq->lock, flags);
/* Wake up processes waiting for this */
......@@ -938,18 +940,17 @@ static void trtl_irq_handler_output(struct trtl_hmq *hmq)
spin_lock_irqsave(&hmq->lock, flags);
/* Get the message */
/* Get information about the incoming slot */
status = trtl_ioread(trtl, hmq->base_sr + MQUEUE_SLOT_STATUS);
size = (status & MQUEUE_SLOT_STATUS_MSG_SIZE_MASK);
size >>= MQUEUE_SLOT_STATUS_MSG_SIZE_SHIFT;
status = trtl_ioread(trtl, hmq->base_sr + TRTL_MQ_SLOT_STATUS);
size = (status & TRTL_MQ_SLOT_STATUS_MSG_SIZE_MASK);
size >>= TRTL_MQ_SLOT_STATUS_MSG_SIZE_SHIFT;
/* Read data from the slot */
for (i = 0; i < size; ++i) {
for (i = 0; i < size; ++i)
buffer[i] = trtl_ioread(trtl,
hmq->base_sr + MQUEUE_SLOT_DATA_START + i * 4);
/*dev_vdbg(&hmq->dev, "From MT to HOST data[%i] = 0x%08x\n",
i, buffer[i]);*/
}
hmq->base_sr + TRTL_MQ_SLOT_DATA_START + i * 4);
/* Discard the slot content */
trtl_iowrite(trtl, MQUEUE_CMD_DISCARD, hmq->base_sr + MQUEUE_SLOT_COMMAND);
trtl_iowrite(trtl, TRTL_MQ_CMD_DISCARD, hmq->base_sr + TRTL_MQ_SLOT_COMMAND);
spin_unlock_irqrestore(&hmq->lock, flags);
hmq->stats.count++;
......@@ -993,6 +994,7 @@ static void trtl_irq_handler_output(struct trtl_hmq *hmq)
wake_up_interruptible(&hmq->q_msg);
}
/**
* It handles HMQ interrupts. It checks if any of the slot has a pending
* interrupt. If the interrupt is pending it will handle it, otherwise it
......@@ -1007,7 +1009,7 @@ irqreturn_t trtl_irq_handler(int irq_core_base, void *arg)
int i, j, n_disp = 0;
/* Get the source of interrupt */
status = trtl_ioread(trtl, trtl->base_gcr + MQUEUE_GCR_SLOT_STATUS);
status = trtl_ioread(trtl, trtl->base_gcr + TRTL_MQ_GCR_SLOT_STATUS);
if (!status)
return IRQ_NONE;
status &= trtl->irq_mask;
......@@ -1033,7 +1035,7 @@ irqreturn_t trtl_irq_handler(int irq_core_base, void *arg)
/*
* check if other interrupts occurs in the meanwhile
*/
status = trtl_ioread(trtl, trtl->base_gcr + MQUEUE_GCR_SLOT_STATUS);
status = trtl_ioread(trtl, trtl->base_gcr + TRTL_MQ_GCR_SLOT_STATUS);
status &= trtl->irq_mask;
if (status && n_disp < hmq_max_irq_loop)
goto dispatch_irq;
......
......@@ -56,15 +56,15 @@ static inline int trtl_rt_init_mq(void)
for (i = 0; i < _app->n_mq; ++i) {
if (_app->mq[i].flags & TRTL_RT_MQ_FLAGS_OUTPUT) {
_app->mq[i].buf = MQ_BUFFER_OUT(_app->mq[i].type,
_app->mq[i].index);
_app->mq[i].buf = mq_map_out_buffer(_app->mq[i].type,
_app->mq[i].index);
mq_purge(_app->mq[i].type, _app->mq[i].index);
if (_app->mq[i].flags & TRTL_RT_MQ_FLAGS_CLAIM) {
mq_claim(_app->mq[i].type, _app->mq[i].index);
}
} else {
_app->mq[i].buf = MQ_BUFFER_IN(_app->mq[i].type,
_app->mq[i].index);
_app->mq[i].buf = mq_map_in_buffer(_app->mq[i].type,
_app->mq[i].index);
}
}
......
......@@ -17,7 +17,163 @@
#ifndef __TRTL_RT_MQUEUE_H
#define __TRTL_RT_MQUEUE_H
#error "Use mockturtle_queue.h and rt-mqueue.h instead"
#include <hw/mockturtle_addresses.h>
#include <hw/mockturtle_queue.h>
#include <hw/mockturtle_cpu_lr.h>
/**
* It computes the input MQ address for a given slot.
*/
#define MQ_IN(slot) (0x4000 + (slot) * 0x400)
/**
* It computes the output MQ address for a given slot.
*/
#define MQ_OUT(slot) (0x8000 + (slot) * 0x400)
/**
* List of Message Queue types
*/
enum trtl_mq_type {
TRTL_HMQ = 0, /**< Host Message Queue - Host-Firmware communication */
TRTL_RMQ, /**< Remote Message Queue - Network-Firmware communication */
};
/**
* It gets the Message Queue base address
* @param[in] type MQ type
*/
static inline void *trtl_mq_base_address(enum trtl_mq_type type)
{
return (void *)(type == TRTL_HMQ ? TRTL_ADDR_HMQ_BASE : TRTL_ADDR_RMQ_BASE);
}
/**
* It writes on a Message Queue register
* @param[in] type MQ type to use
* @param[val] value to write
* @param[reg] reg register offset
*/
static inline void mq_writel(enum trtl_mq_type type, uint32_t val, uint32_t reg)
{
*(volatile uint32_t *)(trtl_mq_base_address(type) + reg) = val;
}
/**
* @copydoc TRTL_MQ_CMD_CLAIM
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static inline void mq_claim(enum trtl_mq_type type, int slot)
{
mq_writel(type, TRTL_MQ_CMD_CLAIM, MQ_OUT(slot) + TRTL_MQ_SLOT_COMMAND);
}
/**
* @copydoc TRTL_MQ_CMD_PURGE
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static inline void mq_purge(enum trtl_mq_type type, int slot)
{
mq_writel(type, TRTL_MQ_CMD_PURGE, MQ_OUT(slot) + TRTL_MQ_SLOT_COMMAND);
}
/**
* @copydoc TRTL_MQ_CMD_READY
* @param[in] type MQ type to use
* @param[in] slot slot number
* @param[in] count number of 32bit words to send
*/
static inline void mq_send(enum trtl_mq_type type, int slot, int count)
{
mq_writel(type, TRTL_MQ_CMD_READY | count, MQ_OUT(slot) + TRTL_MQ_SLOT_COMMAND);
}
/**
* @copydoc TRTL_MQ_CMD_DISCARD
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static inline void mq_discard(enum trtl_mq_type type, int slot)
{
mq_writel(type, TRTL_MQ_CMD_DISCARD, MQ_IN(slot));
}
/**
* It gets the output slot data field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static inline void *mq_map_out_buffer(enum trtl_mq_type type, int slot)
{
return (void *) (trtl_mq_base_address(type) +
MQ_OUT (slot) +
TRTL_MQ_SLOT_DATA_START);
}
/**
* It gets the input slot data field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static inline void *mq_map_in_buffer(enum trtl_mq_type type, int slot)
{
return (void *) (trtl_mq_base_address(type) +
MQ_IN (slot) +
TRTL_MQ_SLOT_DATA_START);
}
/**
* It gets the output slot header field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static inline void *mq_map_out_header(enum trtl_mq_type type, int slot)
{
return (void *) (trtl_mq_base_address(type) +
MQ_OUT (slot) +
TRTL_MQ_SLOT_HEADER_START);
}
/**
* It gets the input slot header field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static inline void *mq_map_in_header(enum trtl_mq_type type, int slot)
{
return (void *) (trtl_mq_base_address(type) +
MQ_IN (slot) +
TRTL_MQ_SLOT_HEADER_START);
}
/**
* It gets the current status of the Message Queues (both Host and Remote)
*/
static inline uint32_t mq_poll(void)
{
return *(volatile uint32_t *) (TRTL_ADDR_LR_BASE + MT_CPU_LR_REG_POLL);
}
/**
* It gets the current status of the Remote Message Queues
*/
static inline uint32_t rmq_poll(int slot)
{
return (mq_poll() & ( 1<< (16 + slot )));
}
#endif
/**@}*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment