MSM8916Pkg: Implement Bam
Signed-off-by: Ivaylo Ivanov <ivo.ivanov@null.net>
This commit is contained in:
parent
c2681ce7d9
commit
7b49b7c6c1
30
MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
Normal file
30
MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
Normal file
@ -0,0 +1,30 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = BamDxe
|
||||
FILE_GUID = 6914BF99-1BAB-4042-A266-B206374E0239
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = BamDxeInitialize
|
||||
|
||||
[Sources.common]
|
||||
Driver.c
|
||||
bam.c
|
||||
|
||||
[BuildOptions.AARCH64]
|
||||
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
MSM8916Pkg/MSM8916Pkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Protocols]
|
||||
gQcomBamProtocolGuid
|
||||
|
||||
[Depex]
|
||||
TRUE
|
40
MSM8916Pkg/Drivers/BamDxe/Driver.c
Normal file
40
MSM8916Pkg/Drivers/BamDxe/Driver.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/LKEnvLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Protocol/QcomBam.h>
|
||||
|
||||
#include "bam_p.h"
|
||||
|
||||
STATIC QCOM_BAM_PROTOCOL mBam = {
|
||||
bam_init,
|
||||
bam_sys_pipe_init,
|
||||
bam_pipe_fifo_init,
|
||||
bam_add_cmd_element,
|
||||
bam_add_desc,
|
||||
bam_add_one_desc,
|
||||
bam_sys_gen_event,
|
||||
bam_wait_for_interrupt,
|
||||
bam_read_offset_update,
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BamDxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_HANDLE Handle = NULL;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces(
|
||||
&Handle,
|
||||
&gQcomBamProtocolGuid,
|
||||
&mBam,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
return Status;
|
||||
}
|
2
MSM8916Pkg/Drivers/BamDxe/Source.txt
Normal file
2
MSM8916Pkg/Drivers/BamDxe/Source.txt
Normal file
@ -0,0 +1,2 @@
|
||||
URL: https://source.codeaurora.org/quic/la/kernel/lk
|
||||
BRANCH: LA.AF.1.1-02810-8064.0
|
471
MSM8916Pkg/Drivers/BamDxe/bam.c
Normal file
471
MSM8916Pkg/Drivers/BamDxe/bam.c
Normal file
@ -0,0 +1,471 @@
|
||||
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <Library/LKEnvLib.h>
|
||||
#include <Library/Pow2Lib.h>
|
||||
#include <Protocol/QcomBam.h>
|
||||
|
||||
#include "bam_p.h"
|
||||
|
||||
#define HLOS_EE_INDEX 0
|
||||
|
||||
/* Reset BAM registers and pipes */
|
||||
static void bam_reset(struct bam_instance *bam)
|
||||
{
|
||||
/* Initiate SW reset */
|
||||
writel(BAM_SW_RST_BIT_MASK, BAM_CTRL_REG(bam->base));
|
||||
|
||||
/* No delay required */
|
||||
|
||||
/* Disable SW reset */
|
||||
writel(~BAM_SW_RST_BIT_MASK, BAM_CTRL_REG(bam->base));
|
||||
}
|
||||
|
||||
/* Resets pipe registers and state machines */
|
||||
static void bam_pipe_reset(struct bam_instance *bam,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
/* Start sw reset of the pipe to be allocated */
|
||||
writel(1, BAM_P_RSTn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
|
||||
/* No delay required */
|
||||
|
||||
/* Stop sw reset of the pipe to be allocated */
|
||||
writel(0, BAM_P_RSTn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
}
|
||||
|
||||
/* A blocking function that waits till an interrupt is signalled.
|
||||
* bam : BAM instance for the descriptors to be queued.
|
||||
* pipe_num : pipe number for the descriptors to be queued.
|
||||
* interrupt: interrupt to wait for.
|
||||
*/
|
||||
int bam_wait_for_interrupt(struct bam_instance *bam,
|
||||
uint8_t pipe_num,
|
||||
enum p_int_type interrupt)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Wait for a interrupt on the right pipe */
|
||||
do{
|
||||
/* Determine the pipe causing the interrupt */
|
||||
val = readl(BAM_IRQ_SRCS(bam->base));
|
||||
/* Flush out the right most global interrupt bit */
|
||||
} while (!((val & 0x7FFF) & (1 << bam->pipe[pipe_num].pipe_num)));
|
||||
|
||||
/* Check the reason for this BAM interrupt */
|
||||
if (readl(BAM_IRQ_STTS(bam->base)))
|
||||
goto bam_wait_int_error;
|
||||
|
||||
/* Check the interrupt type */
|
||||
/* Read interrupt status register */
|
||||
val = readl(BAM_P_IRQ_STTSn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
|
||||
/* Check for error */
|
||||
if (val & P_ERR_EN_MASK)
|
||||
goto bam_wait_int_error;
|
||||
|
||||
if (val & interrupt)
|
||||
{
|
||||
/* Correct interrupt was fired. */
|
||||
/* Clear the other interrupts */
|
||||
val = P_OUT_OF_DESC_EN_MASK | P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
|
||||
writel (val, BAM_P_IRQ_CLRn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
return BAM_RESULT_SUCCESS;
|
||||
}
|
||||
else if (val & P_TRNSFR_END_EN_MASK)
|
||||
{
|
||||
dprintf(CRITICAL,
|
||||
"Trasfer end signalled before the last descc was processed\n");
|
||||
goto bam_wait_int_error;
|
||||
}
|
||||
}
|
||||
|
||||
bam_wait_int_error:
|
||||
|
||||
dprintf(CRITICAL, "Unexpected interrupt\n");
|
||||
return BAM_RESULT_FAILURE;
|
||||
}
|
||||
|
||||
/* Enable BAM and pipe level interrupts */
|
||||
void bam_enable_interrupts(struct bam_instance *bam, uint8_t pipe_num)
|
||||
{
|
||||
|
||||
uint32_t int_mask = P_ERR_EN_MASK | P_OUT_OF_DESC_EN_MASK |
|
||||
P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
|
||||
uint32_t val;
|
||||
|
||||
/* Enable BAM error interrupts */
|
||||
writel(BAM_ERROR_EN_MASK, BAM_IRQ_EN_REG(bam->base));
|
||||
|
||||
/* Enable the interrupts for the pipe by enabling the relevant bits
|
||||
* in the BAM_PIPE_INTERRUPT_ENABLE register.
|
||||
*/
|
||||
writel(int_mask,
|
||||
BAM_P_IRQ_ENn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
|
||||
/* Enable pipe interrups */
|
||||
/* Do read-modify-write */
|
||||
val = readl(BAM_IRQ_SRCS_MSK(bam->base));
|
||||
writel((1 << bam->pipe[pipe_num].pipe_num) | val,
|
||||
BAM_IRQ_SRCS_MSK(bam->base));
|
||||
}
|
||||
|
||||
/* Reset and initialize the bam module */
|
||||
void bam_init(struct bam_instance *bam)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
bam_reset(bam);
|
||||
|
||||
/* Check for only one pipe's direction.
|
||||
* The other is assumed to be the opposite system
|
||||
* transaction.
|
||||
*/
|
||||
if (bam->pipe[0].trans_type == SYS2BAM ||
|
||||
bam->pipe[0].trans_type == BAM2SYS)
|
||||
{
|
||||
/* Program the threshold count */
|
||||
writel(bam->threshold, BAM_DESC_CNT_TRSHLD_REG(bam->base));
|
||||
}
|
||||
|
||||
/* Program config register for H/W bug fixes */
|
||||
val = 0xffffffff & ~(1 << 11);
|
||||
writel(val, BAM_CNFG_BITS(bam->base));
|
||||
|
||||
/* Write the EE index to control the mapping of interrupts to EE */
|
||||
val = HLOS_EE_INDEX & BAM_EE_MASK;
|
||||
writel(val, BAM_TRUST_REG(bam->base));
|
||||
|
||||
/* Enable the BAM */
|
||||
writel(BAM_ENABLE_BIT_MASK, BAM_CTRL_REG(bam->base));
|
||||
}
|
||||
|
||||
/* Funtion to setup a simple fifo structure.
|
||||
* Note: Addr should be 8 byte aligned.
|
||||
* bam : BAM instance for the descriptors to be queued.
|
||||
* pipe_num : pipe number for the descriptors to be queued.
|
||||
*/
|
||||
int bam_pipe_fifo_init(struct bam_instance *bam,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
if (bam->pipe[pipe_num].fifo.size > 0x7FFF)
|
||||
{
|
||||
dprintf(CRITICAL,
|
||||
"Size exceeds max size for a descriptor(0x7FFF)\n");
|
||||
return BAM_RESULT_FAILURE;
|
||||
}
|
||||
|
||||
/* Check if fifo start is 8-byte alligned */
|
||||
ASSERT(!((uint32_t)bam->pipe[pipe_num].fifo.head & 0x7));
|
||||
|
||||
/* Check if fifo size is a power of 2.
|
||||
* The circular fifo logic in lk expects this.
|
||||
*/
|
||||
ASSERT(ispow2(bam->pipe[pipe_num].fifo.size));
|
||||
|
||||
bam->pipe[pipe_num].fifo.current = bam->pipe[pipe_num].fifo.head;
|
||||
|
||||
/* Set the descriptor buffer size. Must be a multiple of 8 */
|
||||
writel(bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE,
|
||||
BAM_P_FIFO_SIZESn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
|
||||
/* Write descriptors FIFO base addr must be 8-byte aligned */
|
||||
/* Needs a physical address conversion as we are setting up
|
||||
* the base of the FIFO for the BAM state machine.
|
||||
*/
|
||||
writel((uint32_t)bam->pipe[pipe_num].fifo.head,
|
||||
BAM_P_DESC_FIFO_ADDRn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
|
||||
/* Initialize FIFO offset for the first read */
|
||||
bam->pipe[pipe_num].fifo.offset = BAM_DESC_SIZE;
|
||||
|
||||
/* Everything is set.
|
||||
* Flag pipe init done.
|
||||
*/
|
||||
bam->pipe[pipe_num].initialized = 1;
|
||||
|
||||
return BAM_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void bam_sys_pipe_init(struct bam_instance *bam,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
/* Reset the pipe to be allocated */
|
||||
bam_pipe_reset(bam, pipe_num);
|
||||
|
||||
/* Enable minimal interrupts */
|
||||
bam_enable_interrupts(bam, pipe_num);
|
||||
|
||||
/* Pipe event threshold register is not relevant in sys modes */
|
||||
|
||||
/* Enable pipe in system mode and set the direction */
|
||||
writel(P_SYS_MODE_MASK | P_ENABLE |
|
||||
(bam->pipe[pipe_num].trans_type << P_DIRECTION_SHIFT),
|
||||
BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
|
||||
/* Write the EE index to control the mapping of pipe interrupts to EE */
|
||||
val = HLOS_EE_INDEX & BAM_EE_MASK;
|
||||
writel(val, BAM_P_TRUST_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
|
||||
/* Mark the pipe FIFO as uninitialized. */
|
||||
bam->pipe[pipe_num].initialized = 0;
|
||||
}
|
||||
|
||||
/* Function to notify written descriptors to BAM.
|
||||
* bam : BAM instance for the descriptors to be queued.
|
||||
* pipe_num : pipe number for the descriptors to be queued.
|
||||
* num_desc : number of the descriptors.
|
||||
* fifo : Circular FIFO used for the descriptors.
|
||||
*/
|
||||
void bam_sys_gen_event(struct bam_instance *bam,
|
||||
uint8_t pipe_num,
|
||||
unsigned int num_desc)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
if (num_desc >= bam->pipe[pipe_num].fifo.size) {
|
||||
dprintf(CRITICAL,
|
||||
"Max allowed desc is one less than the fifo length\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update the fifo peer offset */
|
||||
val = (num_desc - 1) * BAM_DESC_SIZE;
|
||||
val += bam->pipe[pipe_num].fifo.offset;
|
||||
val &= (bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE - 1);
|
||||
|
||||
writel(val, BAM_P_EVNT_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
}
|
||||
|
||||
/* Function to read the updates for FIFO offsets.
|
||||
* bam : BAM that uses the FIFO.
|
||||
* pipe : BAM pipe that uses the FIFO.
|
||||
* return : FIFO offset where the next descriptor should be written.
|
||||
* Note : S/W maintains the circular properties of the FIFO and updates
|
||||
* the offsets accordingly.
|
||||
*/
|
||||
void bam_read_offset_update(struct bam_instance *bam, unsigned int pipe_num)
|
||||
{
|
||||
uint32_t offset;
|
||||
|
||||
offset = readl(BAM_P_SW_OFSTSn(bam->pipe[pipe_num].pipe_num, bam->base));
|
||||
offset &= 0xFFFF;
|
||||
|
||||
dprintf(INFO, "Offset value is %d \n", offset);
|
||||
|
||||
/* Save the next offset to be written to. */
|
||||
bam->pipe[pipe_num].fifo.current = (struct bam_desc*)
|
||||
((uint32_t)bam->pipe[pipe_num].fifo.head + offset);
|
||||
|
||||
bam->pipe[pipe_num].fifo.offset = offset + BAM_DESC_SIZE ;
|
||||
}
|
||||
|
||||
/* Function to get the next desc address.
|
||||
* Keeps track of circular properties of the FIFO
|
||||
* and returns the appropriate address.
|
||||
*/
|
||||
static struct bam_desc* fifo_getnext(struct bam_desc_fifo *fifo,
|
||||
struct bam_desc* desc)
|
||||
{
|
||||
uint16_t offset;
|
||||
|
||||
offset = desc - fifo->head;
|
||||
|
||||
if (offset == (fifo->size - 1))
|
||||
return fifo->head;
|
||||
else
|
||||
return desc + 1;
|
||||
}
|
||||
|
||||
/* Function to add BAM descriptors for a given fifo.
|
||||
* bam : BAM instance to be used.
|
||||
* data_ptr : Memory address for data transfer.
|
||||
* data_len : Length of the data_ptr.
|
||||
* flags : Flags to be set on the last desc added.
|
||||
*
|
||||
* Note: This function also notifies the BAM about the added descriptors.
|
||||
*/
|
||||
int bam_add_desc(struct bam_instance *bam,
|
||||
unsigned int pipe_num,
|
||||
unsigned char *data_ptr,
|
||||
unsigned int data_len,
|
||||
unsigned flags)
|
||||
{
|
||||
int bam_ret = BAM_RESULT_SUCCESS;
|
||||
unsigned int len = data_len;
|
||||
unsigned int desc_len;
|
||||
unsigned int n = 0;
|
||||
unsigned int desc_flags;
|
||||
|
||||
dprintf(INFO, "Data length for BAM transfer is %u\n", data_len);
|
||||
|
||||
if (data_ptr == NULL || len == 0)
|
||||
{
|
||||
dprintf(CRITICAL, "Wrong params for BAM transfer \n");
|
||||
bam_ret = BAM_RESULT_FAILURE;
|
||||
goto bam_add_desc_error;
|
||||
}
|
||||
|
||||
/* Check if we have enough space in FIFO */
|
||||
if (len > (unsigned)bam->pipe[pipe_num].fifo.size * BAM_MAX_DESC_DATA_LEN)
|
||||
{
|
||||
dprintf(CRITICAL, "Data transfer exceeds desc fifo length.\n");
|
||||
bam_ret = BAM_RESULT_FAILURE;
|
||||
goto bam_add_desc_error;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
|
||||
/* There are only 16 bits to write data length.
|
||||
* If more bits are needed, create more
|
||||
* descriptors.
|
||||
*/
|
||||
if (len > BAM_MAX_DESC_DATA_LEN)
|
||||
{
|
||||
desc_len = BAM_MAX_DESC_DATA_LEN;
|
||||
len -= BAM_MAX_DESC_DATA_LEN;
|
||||
desc_flags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc_len = len;
|
||||
len = 0;
|
||||
/* Set correct flags on the last desc. */
|
||||
desc_flags = flags;
|
||||
}
|
||||
|
||||
/* Write descriptor */
|
||||
bam_add_one_desc(bam, pipe_num, data_ptr, desc_len, desc_flags);
|
||||
|
||||
data_ptr += BAM_MAX_DESC_DATA_LEN;
|
||||
n++;
|
||||
}
|
||||
|
||||
|
||||
/* Create a read/write event to notify the periperal of the added desc. */
|
||||
bam_sys_gen_event(bam, pipe_num, n);
|
||||
|
||||
bam_add_desc_error:
|
||||
|
||||
return bam_ret;
|
||||
}
|
||||
|
||||
/* Function to add a BAM descriptor for a given fifo.
|
||||
* bam : BAM instance to be used.
|
||||
* data_ptr : Memory address for data transfer.
|
||||
* data_len : Length of the data_ptr.
|
||||
* flags : Flags to be set on the desc added.
|
||||
*
|
||||
* Note: This function does not notify the BAM about the added descriptor.
|
||||
*/
|
||||
int bam_add_one_desc(struct bam_instance *bam,
|
||||
unsigned int pipe_num,
|
||||
unsigned char* data_ptr,
|
||||
uint32_t len,
|
||||
uint8_t flags)
|
||||
{
|
||||
|
||||
struct bam_desc *desc = bam->pipe[pipe_num].fifo.current;
|
||||
int bam_ret = BAM_RESULT_SUCCESS;
|
||||
|
||||
if (data_ptr == NULL || len == 0)
|
||||
{
|
||||
dprintf(CRITICAL, "Wrong params for BAM transfer \n");
|
||||
bam_ret = BAM_RESULT_FAILURE;
|
||||
goto bam_add_one_desc_error;
|
||||
}
|
||||
|
||||
/* Check if the FIFO is allocated for the pipe */
|
||||
if (!bam->pipe[pipe_num].initialized)
|
||||
{
|
||||
dprintf(CRITICAL, "Please allocate the FIFO for the BAM pipe %d\n",
|
||||
bam->pipe[pipe_num].pipe_num);
|
||||
bam_ret = BAM_RESULT_FAILURE;
|
||||
goto bam_add_one_desc_error;
|
||||
}
|
||||
|
||||
if ((flags & BAM_DESC_LOCK_FLAG) && (flags & BAM_DESC_UNLOCK_FLAG))
|
||||
{
|
||||
dprintf(CRITICAL, "Can't lock and unlock in the same desc\n");
|
||||
bam_ret = BAM_RESULT_FAILURE;
|
||||
goto bam_add_one_desc_error;
|
||||
}
|
||||
|
||||
/* Setting EOT flag on a CMD desc is not valid */
|
||||
if ((flags & BAM_DESC_EOT_FLAG) && (flags & BAM_DESC_CMD_FLAG))
|
||||
{
|
||||
dprintf(CRITICAL, "EOT flag set on the CMD desc\n");
|
||||
bam_ret = BAM_RESULT_FAILURE;
|
||||
goto bam_add_one_desc_error;
|
||||
}
|
||||
|
||||
/* Check for the length of the desc. */
|
||||
if (len > BAM_MAX_DESC_DATA_LEN)
|
||||
{
|
||||
dprintf(CRITICAL, "len of the desc exceeds max length"
|
||||
" %d > %d\n", len, BAM_MAX_DESC_DATA_LEN);
|
||||
bam_ret = BAM_RESULT_FAILURE;
|
||||
goto bam_add_one_desc_error;
|
||||
}
|
||||
|
||||
desc->flags = flags;
|
||||
desc->addr = (uint32_t)data_ptr;
|
||||
desc->size = (uint16_t)len;
|
||||
desc->reserved = 0;
|
||||
|
||||
/* Update the FIFO to point to the head */
|
||||
bam->pipe[pipe_num].fifo.current = fifo_getnext(&bam->pipe[pipe_num].fifo, desc);
|
||||
|
||||
bam_add_one_desc_error:
|
||||
return bam_ret;
|
||||
}
|
||||
|
||||
struct cmd_element* bam_add_cmd_element(struct cmd_element *ptr,
|
||||
uint32_t reg_addr,
|
||||
uint32_t value,
|
||||
enum bam_ce_cmd_t cmd_type)
|
||||
{
|
||||
/* Write cmd type.
|
||||
* Also, write the register address.
|
||||
*/
|
||||
ptr->addr_n_cmd = (reg_addr & ~(0xFF000000)) | (cmd_type << 24);
|
||||
|
||||
/* Do not mask any of the addr bits by default */
|
||||
ptr->reg_mask = 0xFFFFFFFF;
|
||||
|
||||
/* Write the value to be written */
|
||||
ptr->reg_data = value;
|
||||
|
||||
/* Return the address to add the next element to */
|
||||
return ptr + 1;
|
||||
}
|
31
MSM8916Pkg/Drivers/BamDxe/bam_p.h
Normal file
31
MSM8916Pkg/Drivers/BamDxe/bam_p.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef _BAM_PRIVATE_H
|
||||
#define _BAM_PRIVATE_H
|
||||
|
||||
void bam_init(struct bam_instance *bam);
|
||||
void bam_sys_pipe_init(struct bam_instance *bam,
|
||||
uint8_t pipe_num);
|
||||
int bam_pipe_fifo_init(struct bam_instance *bam,
|
||||
uint8_t pipe_num);
|
||||
struct cmd_element* bam_add_cmd_element(struct cmd_element *ptr,
|
||||
uint32_t addr,
|
||||
uint32_t data,
|
||||
enum bam_ce_cmd_t cmd_type);
|
||||
int bam_add_desc(struct bam_instance *bam,
|
||||
unsigned int pipe_num,
|
||||
unsigned char *data_ptr,
|
||||
unsigned int data_len,
|
||||
unsigned flags);
|
||||
int bam_add_one_desc(struct bam_instance *bam,
|
||||
unsigned int pipe_num,
|
||||
unsigned char*,
|
||||
uint32_t len,
|
||||
uint8_t flags);
|
||||
void bam_sys_gen_event(struct bam_instance *bam,
|
||||
uint8_t pipe_num,
|
||||
unsigned int num_desc);
|
||||
int bam_wait_for_interrupt(struct bam_instance *bam,
|
||||
uint8_t pipe_num,
|
||||
enum p_int_type interrupt);
|
||||
void bam_read_offset_update(struct bam_instance *bam, unsigned int pipe_num);
|
||||
|
||||
#endif // _BAM_PRIVATE_H
|
222
MSM8916Pkg/Include/Chipset/bam.h
Normal file
222
MSM8916Pkg/Include/Chipset/bam.h
Normal file
@ -0,0 +1,222 @@
|
||||
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __PLATFORM_MSM_SHARED_BAM_H
|
||||
#define __PLATFORM_MSM_SHARED_BAM_H
|
||||
|
||||
#include <Library/LKEnvLib.h>
|
||||
|
||||
#define BAM_DESC_SIZE 8
|
||||
#define BAM_CE_SIZE 16
|
||||
#define BAM_MAX_DESC_DATA_LEN 0xFFFF
|
||||
#define BAM_DATA_READ 0
|
||||
#define BAM_DATA_WRITE 1
|
||||
|
||||
#define BAM_CTRL_REG(x) (0x0000 + (x))
|
||||
#define BAM_SW_RST_BIT_MASK 1
|
||||
#define BAM_ENABLE_BIT_MASK (1 << 1)
|
||||
|
||||
#define BAM_DESC_CNT_TRSHLD_REG(x) (0x0008 + (x))
|
||||
#define COUNT_TRESHOLD_MASK 0xFF
|
||||
#define BAM_IRQ_SRCS(x) (0x0000000C + (x))
|
||||
#define BAM_IRQ_SRCS_MSK(x) (0x00000010 + (x))
|
||||
#define BAM_IRQ_MASK (1 << 31)
|
||||
#define P_IRQ_MASK (1)
|
||||
|
||||
/* Pipe Interrupt masks */
|
||||
enum p_int_type
|
||||
{
|
||||
P_PRCSD_DESC_EN_MASK = 1,
|
||||
P_OUT_OF_DESC_EN_MASK = (1 << 3),
|
||||
P_ERR_EN_MASK = (1 << 4),
|
||||
P_TRNSFR_END_EN_MASK = (1 << 5)
|
||||
};
|
||||
|
||||
#define BAM_IRQ_STTS(x) (0x00000014 + (x))
|
||||
#define BAM_IRQ_SRCS_UNMASKED(x) (0x00000030 + (x))
|
||||
|
||||
#define BAM_IRQ_EN_REG(x) (0x001C + (x))
|
||||
#define BAM_TIMER_EN_MASK (1 << 4)
|
||||
/* Available only in BAM-Lite */
|
||||
#define BAM_EMPTY_EN_MASK (1 << 3)
|
||||
#define BAM_ERROR_EN_MASK (1 << 2)
|
||||
/* Available only in BAM */
|
||||
#define BAM_HRESP_ERR_EN_MASK (1 << 1)
|
||||
|
||||
#define BAM_TRUST_REG(x) (0x00000070 + (x))
|
||||
#define BAM_EE_MASK (7 << 0)
|
||||
#define BAM_RESET_BLK_MASK (1 << 7)
|
||||
#define BAM_LOCK_EE_CTRL_MASK (1 << 13)
|
||||
|
||||
#define BAM_CNFG_BITS(x) (0x0000007C + (x))
|
||||
|
||||
#define BAM_P_CTRLn(n, x) (0x00001000 + 0x1000 * (n) + (x))
|
||||
#define P_SYS_MODE_MASK (1 << 5)
|
||||
/* 1: Producer mode 0: Consumer mode */
|
||||
#define P_DIRECTION_SHIFT 3
|
||||
#define P_ENABLE (1 << 1)
|
||||
|
||||
#define BAM_P_RSTn(n, x) (0x00001000 + 0x4 + 0x1000 * (n) + (x))
|
||||
#define BAM_P_IRQ_STTSn(n, x) (0x00001000 + 0x10 + 0x1000 * (n) + (x))
|
||||
#define BAM_P_IRQ_CLRn(n, x) (0x00001000 + 0x14 + 0x1000 * (n) + (x))
|
||||
#define BAM_P_IRQ_ENn(n, x) (0x00001000 + 0x18 + 0x1000 * (n) + (x))
|
||||
#define BAM_P_TRUST_REGn(n, x) (0x00001000 + 0x30 + 0x1000 * (n) + (x))
|
||||
#define BAM_P_SW_OFSTSn(n, x) (0x00001800 + 0x1000 * (n) + (x))
|
||||
#define BAM_P_EVNT_REGn(n, x) (0x00001818 + 0x1000 * (n) + (x))
|
||||
#define P_DESC_FIFO_PEER_OFST_MASK 0xFF
|
||||
|
||||
#define BAM_P_DESC_FIFO_ADDRn(n, x) (0x0000181C + 0x1000 * (n) + (x))
|
||||
#define BAM_P_FIFO_SIZESn(n, x) (0x00001820 + 0x1000 * (n) + (x))
|
||||
|
||||
/* Flags for descriptors */
|
||||
#define BAM_DESC_INT_FLAG (1 << 7)
|
||||
#define BAM_DESC_EOT_FLAG (1 << 6)
|
||||
#define BAM_DESC_EOB_FLAG (1 << 5)
|
||||
#define BAM_DESC_NWD_FLAG (1 << 4)
|
||||
#define BAM_DESC_CMD_FLAG (1 << 3)
|
||||
#define BAM_DESC_LOCK_FLAG (1 << 2)
|
||||
#define BAM_DESC_UNLOCK_FLAG (1 << 1)
|
||||
|
||||
enum bam_ce_cmd_t{
|
||||
CE_WRITE_TYPE = 0,
|
||||
CE_READ_TYPE = 1
|
||||
};
|
||||
|
||||
/* result type */
|
||||
typedef enum {
|
||||
BAM_RESULT_SUCCESS = 0,
|
||||
BAM_RESULT_FAILURE = 1,
|
||||
BAM_RESULT_TIMEOUT = 2
|
||||
} bam_result_t;
|
||||
|
||||
|
||||
/* Enum to define the BAM type:
|
||||
* BAM2BAM:Producer BAM to Consumer BAM.
|
||||
* SYS2BAM:Producer System to Consumer BAM.
|
||||
* BAM2SYS:Producer BAM to Consumer System.
|
||||
*/
|
||||
enum bam_transaction_type {
|
||||
SYS2BAM,
|
||||
BAM2SYS,
|
||||
BAM2BAM,
|
||||
};
|
||||
|
||||
/* Enum to define BAM mode:
|
||||
* SPS:Use BAM pipes.
|
||||
* DIRECT:Pipes are disabled.
|
||||
* LEGACY:BAM is not used.
|
||||
*/
|
||||
enum bam_mode {
|
||||
SPS,
|
||||
DIRECT,
|
||||
LEGACY,
|
||||
};
|
||||
|
||||
/* Enum to define BAM pipe states:
|
||||
* ENABLED:Producer and Consumer pipes are enabled.
|
||||
* HALT:Consumer pipe is halted. (Preferred type)
|
||||
* FULL_HALT:Both Producer and Consumer pipes are halted.
|
||||
*/
|
||||
enum bam_pipe_state {
|
||||
ENABLED,
|
||||
HALT,
|
||||
FULL_HALT,
|
||||
};
|
||||
|
||||
enum bam_type {
|
||||
BAM_LITE,
|
||||
BAM,
|
||||
};
|
||||
|
||||
/* Structure to define BAM descriptors that describe the data
|
||||
* descriptors written to the data FIFO.
|
||||
* addr:Descriptor address.
|
||||
* size:Each descriptor is 8 bytes. Size of the descriptor fifo must
|
||||
* contain an integer number of Descriptors.
|
||||
*/
|
||||
struct bam_desc {
|
||||
uint32_t addr;
|
||||
uint16_t size;
|
||||
uint8_t reserved;
|
||||
uint8_t flags;
|
||||
} __PACKED;
|
||||
|
||||
struct bam_desc_fifo {
|
||||
struct bam_desc *head;
|
||||
struct bam_desc *current;
|
||||
uint16_t size;
|
||||
uint16_t offset;
|
||||
};
|
||||
|
||||
/* Structure to define BAM pipes
|
||||
* pipe_state: BAM pipe states.
|
||||
* trans_type: BAM tranaction type.
|
||||
* evt_gen_threshold: This register configures the threshold value for
|
||||
* Read/Write event generation by the BAM
|
||||
* towards another BAM.
|
||||
* fifo: Circular fifo associated with this pipe.
|
||||
* num_pipe: Number of pipes used in this bam.
|
||||
* pipe: Pipe number for this pipe.
|
||||
*/
|
||||
struct bam_pipe {
|
||||
enum bam_pipe_state state;
|
||||
enum bam_transaction_type trans_type;
|
||||
struct bam_desc_fifo fifo;
|
||||
uint16_t evt_gen_threshold;
|
||||
uint8_t pipe_num;
|
||||
uint8_t initialized;
|
||||
};
|
||||
|
||||
/* Structure to define a BAM instance being used
|
||||
* base:Base address for the BAM.
|
||||
* type:BAM type.
|
||||
* mode:BAM mode.
|
||||
* pipe_pair:The pipe pairs to be used to access the BAM.
|
||||
* threshold:This Register holds a threshold value for the
|
||||
* counter summing the Size of the Descriptors Provided.
|
||||
* init:Pipe initialization status for the BAM.
|
||||
*/
|
||||
struct bam_instance {
|
||||
uint32_t base;
|
||||
enum bam_type type;
|
||||
enum bam_mode mode;
|
||||
uint8_t num_of_pipes;
|
||||
struct bam_pipe pipe[3];
|
||||
uint16_t threshold;
|
||||
void (*callback)(int);
|
||||
};
|
||||
|
||||
/* Command element(CE) structure*/
|
||||
struct cmd_element {
|
||||
uint32_t addr_n_cmd;
|
||||
uint32_t reg_data;
|
||||
uint32_t reg_mask;
|
||||
uint32_t reserve;
|
||||
} __PACKED;
|
||||
|
||||
#endif
|
58
MSM8916Pkg/Include/Library/Pow2Lib.h
Normal file
58
MSM8916Pkg/Include/Library/Pow2Lib.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Travis Geiselbrecht
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __LIBRARY_POW2_H
|
||||
#define __LIBRARY_POW2_H
|
||||
|
||||
#include <Library/LKEnvLib.h>
|
||||
|
||||
/* routines for dealing with power of 2 values for efficiency */
|
||||
STATIC inline __ALWAYS_INLINE BOOLEAN ispow2(UINTN val)
|
||||
{
|
||||
return ((val - 1) & val) == 0;
|
||||
}
|
||||
|
||||
STATIC inline __ALWAYS_INLINE UINTN log2(UINTN val)
|
||||
{
|
||||
if (!ispow2(val))
|
||||
return 0; // undefined
|
||||
|
||||
return __builtin_ctz(val);
|
||||
}
|
||||
|
||||
STATIC inline __ALWAYS_INLINE UINTN valpow2(UINTN valp2)
|
||||
{
|
||||
return 1 << valp2;
|
||||
}
|
||||
|
||||
STATIC inline __ALWAYS_INLINE UINTN divpow2(UINTN val, UINTN divp2)
|
||||
{
|
||||
return val >> divp2;
|
||||
}
|
||||
|
||||
STATIC inline __ALWAYS_INLINE UINTN modpow2(UINTN val, UINTN modp2)
|
||||
{
|
||||
return val & ((1UL << modp2) - 1);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
35
MSM8916Pkg/Include/Protocol/QcomBam.h
Normal file
35
MSM8916Pkg/Include/Protocol/QcomBam.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __QCOM_PROTOCOL_BAM_H__
|
||||
#define __QCOM_PROTOCOL_BAM_H__
|
||||
|
||||
#include <Chipset/bam.h>
|
||||
|
||||
#define QCOM_BAM_PROTOCOL_GUID \
|
||||
{ 0xacdd545a, 0xf1f6, 0x4272, { 0x81, 0xc5, 0x04, 0x93, 0xe3, 0x58, 0x05, 0x32 } }
|
||||
|
||||
typedef struct _QCOM_BAM_PROTOCOL QCOM_BAM_PROTOCOL;
|
||||
|
||||
typedef void (EFIAPI *bam_init_t)(struct bam_instance *bam);
|
||||
typedef void (EFIAPI *bam_sys_pipe_init_t)(struct bam_instance *bam, uint8_t pipe_num);
|
||||
typedef int (EFIAPI *bam_pipe_fifo_init_t)(struct bam_instance *bam, uint8_t pipe_num);
|
||||
typedef struct cmd_element* (EFIAPI *bam_add_cmd_element_t)(struct cmd_element *ptr, uint32_t addr, uint32_t data, enum bam_ce_cmd_t cmd_type);
|
||||
typedef int (EFIAPI *bam_add_desc_t)(struct bam_instance *bam, unsigned int pipe_num, unsigned char *data_ptr, unsigned int data_len, unsigned flags);
|
||||
typedef int (EFIAPI *bam_add_one_desc_t)(struct bam_instance *bam, unsigned int pipe_num, unsigned char*, uint32_t len, uint8_t flags);
|
||||
typedef void (EFIAPI *bam_sys_gen_event_t)(struct bam_instance *bam, uint8_t pipe_num, unsigned int num_desc);
|
||||
typedef int (EFIAPI *bam_wait_for_interrupt_t)(struct bam_instance *bam, uint8_t pipe_num, enum p_int_type interrupt);
|
||||
typedef void (EFIAPI *bam_read_offset_update_t)(struct bam_instance *bam, unsigned int pipe_num);
|
||||
|
||||
struct _QCOM_BAM_PROTOCOL {
|
||||
bam_init_t bam_init;
|
||||
bam_sys_pipe_init_t bam_sys_pipe_init;
|
||||
bam_pipe_fifo_init_t bam_pipe_fifo_init;
|
||||
bam_add_cmd_element_t bam_add_cmd_element;
|
||||
bam_add_desc_t bam_add_desc;
|
||||
bam_add_one_desc_t bam_add_one_desc;
|
||||
bam_sys_gen_event_t bam_sys_gen_event;
|
||||
bam_wait_for_interrupt_t bam_wait_for_interrupt;
|
||||
bam_read_offset_update_t bam_read_offset_update;
|
||||
};
|
||||
|
||||
extern EFI_GUID gQcomBamProtocolGuid;
|
||||
|
||||
#endif
|
@ -34,6 +34,7 @@
|
||||
[Protocols]
|
||||
gEFIDroidKeypadDeviceProtocolGuid = { 0xb27625b5, 0x0b6c, 0x4614, { 0xaa, 0x3c, 0x33, 0x13, 0xb5, 0x1d, 0x36, 0x46 } }
|
||||
gQcomClockProtocolGuid = { 0x4fcc91c2, 0x9c4f, 0x4e3c, { 0xa6, 0x73, 0xc6, 0xdf, 0x62, 0xe0, 0x41, 0xd5 } }
|
||||
gQcomBamProtocolGuid = { 0xacdd545a, 0xf1f6, 0x4272, { 0x81, 0xc5, 0x04, 0x93, 0xe3, 0x58, 0x05, 0x32 } }
|
||||
|
||||
[PcdsFixedAtBuild.common]
|
||||
# Simple FrameBuffer
|
||||
|
@ -203,6 +203,7 @@
|
||||
#
|
||||
|
||||
MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
||||
MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
|
||||
|
||||
#
|
||||
# Virtual Keyboard
|
||||
|
@ -157,6 +157,7 @@ READ_LOCK_STATUS = TRUE
|
||||
# SoC Drivers
|
||||
#
|
||||
INF MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
||||
INF MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
|
||||
|
||||
#
|
||||
# USB Host Support
|
||||
|
Loading…
Reference in New Issue
Block a user