/** * struct panthor_fw_cs_iface - Firmware command stream slot interface
*/ struct panthor_fw_cs_iface { /** * @lock: Lock protecting access to the panthor_fw_cs_input_iface::req * field. * * Needed so we can update the req field concurrently from the interrupt * handler and the scheduler logic. * * TODO: Ideally we'd want to use a cmpxchg() to update the req, but FW * interface sections are mapped uncached/write-combined right now, and * using cmpxchg() on such mappings leads to SError faults. Revisit when * we have 'SHARED' GPU mappings hooked up.
*/
spinlock_t lock;
/** * @control: Command stream slot control interface. * * Used to expose command stream slot properties. * * This interface is read-only.
*/ struct panthor_fw_cs_control_iface *control;
/** * @input: Command stream slot input interface. * * Used for host updates/events.
*/ struct panthor_fw_cs_input_iface *input;
/** * @output: Command stream slot output interface. * * Used for FW updates/events. * * This interface is read-only.
*/ conststruct panthor_fw_cs_output_iface *output;
};
/** * struct panthor_fw_csg_iface - Firmware command stream group slot interface
*/ struct panthor_fw_csg_iface { /** * @lock: Lock protecting access to the panthor_fw_csg_input_iface::req * field. * * Needed so we can update the req field concurrently from the interrupt * handler and the scheduler logic. * * TODO: Ideally we'd want to use a cmpxchg() to update the req, but FW * interface sections are mapped uncached/write-combined right now, and * using cmpxchg() on such mappings leads to SError faults. Revisit when * we have 'SHARED' GPU mappings hooked up.
*/
spinlock_t lock;
/** * @control: Command stream group slot control interface. * * Used to expose command stream group slot properties. * * This interface is read-only.
*/ conststruct panthor_fw_csg_control_iface *control;
/** * @input: Command stream slot input interface. * * Used for host updates/events.
*/ struct panthor_fw_csg_input_iface *input;
/** * @output: Command stream group slot output interface. * * Used for FW updates/events. * * This interface is read-only.
*/ conststruct panthor_fw_csg_output_iface *output;
};
/** * struct panthor_fw_global_iface - Firmware global interface
*/ struct panthor_fw_global_iface { /** * @lock: Lock protecting access to the panthor_fw_global_input_iface::req * field. * * Needed so we can update the req field concurrently from the interrupt * handler and the scheduler/FW management logic. * * TODO: Ideally we'd want to use a cmpxchg() to update the req, but FW * interface sections are mapped uncached/write-combined right now, and * using cmpxchg() on such mappings leads to SError faults. Revisit when * we have 'SHARED' GPU mappings hooked up.
*/
spinlock_t lock;
/** * @control: Command stream group slot control interface. * * Used to expose global FW properties. * * This interface is read-only.
*/ conststruct panthor_fw_global_control_iface *control;
/** * @input: Global input interface. * * Used for host updates/events.
*/ struct panthor_fw_global_input_iface *input;
/** * @output: Global output interface. * * Used for FW updates/events. * * This interface is read-only.
*/ conststruct panthor_fw_global_output_iface *output;
};
/** * panthor_fw_toggle_reqs() - Toggle acknowledge bits to send an event to the FW * @__iface: The interface to operate on. * @__in_reg: Name of the register to update in the input section of the interface. * @__out_reg: Name of the register to take as a reference in the output section of the * interface. * @__mask: Mask to apply to the update. * * The Host -> FW event/message passing was designed to be lockless, with each side of * the channel having its writeable section. Events are signaled as a difference between * the host and FW side in the req/ack registers (when a bit differs, there's an event * pending, when they are the same, nothing needs attention). * * This helper allows one to update the req register based on the current value of the * ack register managed by the FW. Toggling a specific bit will flag an event. In order * for events to be re-evaluated, the interface doorbell needs to be rung. * * Concurrent accesses to the same req register is covered. * * Anything requiring atomic updates to multiple registers requires a dedicated lock.
*/ #define panthor_fw_toggle_reqs(__iface, __in_reg, __out_reg, __mask) \ do { \
u32 __cur_val, __new_val, __out_val; \
spin_lock(&(__iface)->lock); \
__cur_val = READ_ONCE((__iface)->input->__in_reg); \
__out_val = READ_ONCE((__iface)->output->__out_reg); \
__new_val = ((__out_val ^ (__mask)) & (__mask)) | (__cur_val & ~(__mask)); \
WRITE_ONCE((__iface)->input->__in_reg, __new_val); \
spin_unlock(&(__iface)->lock); \
} while (0)
/** * panthor_fw_update_reqs() - Update bits to reflect a configuration change * @__iface: The interface to operate on. * @__in_reg: Name of the register to update in the input section of the interface. * @__val: Value to set. * @__mask: Mask to apply to the update. * * Some configuration get passed through req registers that are also used to * send events to the FW. Those req registers being updated from the interrupt * handler, they require special helpers to update the configuration part as well. * * Concurrent accesses to the same req register is covered. * * Anything requiring atomic updates to multiple registers requires a dedicated lock.
*/ #define panthor_fw_update_reqs(__iface, __in_reg, __val, __mask) \ do { \
u32 __cur_val, __new_val; \
spin_lock(&(__iface)->lock); \
__cur_val = READ_ONCE((__iface)->input->__in_reg); \
__new_val = (__cur_val & ~(__mask)) | ((__val) & (__mask)); \
WRITE_ONCE((__iface)->input->__in_reg, __new_val); \
spin_unlock(&(__iface)->lock); \
} while (0)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.