357 lines
9.8 KiB
C
357 lines
9.8 KiB
C
/**
|
|
* @file sdrv_g2dlite.c
|
|
* @brief SemiDrive G2DLite driver file.
|
|
*
|
|
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include <g2dlite/g2dlite.h>
|
|
#include <g2dlite/g2dlite_core.h>
|
|
#include <g2dlite/g2dlite_log.h>
|
|
#include <irq.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <udelay/udelay.h>
|
|
#if CONFIG_OS_FREERTOS
|
|
#include <FreeRTOS.h>
|
|
#include <queue.h>
|
|
#include <semphr.h>
|
|
#include <task.h>
|
|
SemaphoreHandle_t g2dlite_lock;
|
|
SemaphoreHandle_t done_sema;
|
|
#endif
|
|
|
|
unsigned int G2DLITE_CMD_ARRAY[G2DLITE_CMDFILE_MAX_MEM] = {0};
|
|
|
|
static void g2dlite_done(void)
|
|
{
|
|
#if CONFIG_OS_FREERTOS
|
|
BaseType_t xReturn = xSemaphoreTake(done_sema, pdMS_TO_TICKS(5000));
|
|
if (pdTRUE != xReturn) {
|
|
G2DLITE_LOG_ERR("timeout for 5s !");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv g2dlite_probe
|
|
*
|
|
* This funtion probe the g2dlite device.
|
|
*
|
|
* @param [in] dev g2dlite device struct.
|
|
* @param [in] g2dlite_cfg g2dlite dev config information.
|
|
* @return SDRV_G2DLITE_STATUS_OK g2dlite probe successfully.
|
|
*/
|
|
status_t sdrv_g2dlite_probe(struct g2dlite_device *dev,
|
|
const struct g2dlite_config *g2dlite_cfg)
|
|
{
|
|
|
|
if (dev->inited)
|
|
return SDRV_G2DLITE_STATUS_OK;
|
|
dev->reg_base = g2dlite_cfg->base;
|
|
dev->cmd_info[0].arg = G2DLITE_CMD_ARRAY;
|
|
|
|
G2DLITE_LOG_INFO("dev->cmd_info[0].arg = 0x%p", dev->cmd_info[0].arg);
|
|
|
|
for (int i = 1; i < G2DLITE_CMDFILE_MAX_NUM; i++) {
|
|
dev->cmd_info[i].arg =
|
|
dev->cmd_info[i - 1].arg + G2DLITE_CMDFILE_MAX_LEN * 2;
|
|
}
|
|
|
|
dev->write_mode = G2DLITE_CMD_WRITE;
|
|
dev->ops = &ops;
|
|
dev->irq = g2dlite_cfg->irq;
|
|
dev->irq_handler = ops.irq_handler;
|
|
|
|
#if CONFIG_OS_FREERTOS
|
|
done_sema = xSemaphoreCreateBinary();
|
|
g2dlite_lock = xSemaphoreCreateMutex();
|
|
#endif
|
|
if (dev->ops->init)
|
|
dev->ops->init(dev);
|
|
|
|
irq_attach(dev->irq, dev->irq_handler, dev);
|
|
irq_enable(dev->irq);
|
|
dev->inited = 1;
|
|
|
|
return SDRV_G2DLITE_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv g2dlite update.
|
|
*
|
|
* This function perform multiple transformations at a time according to
|
|
* customer input and output settings.
|
|
*
|
|
* @param [in] dev g2dlite device struct.
|
|
* @param [in] input g2dlite input information.
|
|
* @return SDRV_G2DLITE_STATUS_OK g2dlite update successfully,
|
|
* SDRV_G2DLITE_STATUS_FAIL g2dlite update fail,
|
|
* SDRV_G2DLITE_STATUS_TIMEOUT g2dlite update timeout,
|
|
* SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite update param invalid.
|
|
*
|
|
*/
|
|
status_t sdrv_g2dlite_update(struct g2dlite_device *dev,
|
|
struct g2dlite_input *input)
|
|
{
|
|
status_t ret = SDRV_G2DLITE_STATUS_OK;
|
|
|
|
if ((input->output.width <= 0) || ((input->output.height <= 0)))
|
|
return SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
|
|
#if CONFIG_OS_FREERTOS
|
|
xSemaphoreTake(g2dlite_lock, portMAX_DELAY);
|
|
#endif
|
|
if (dev->ops->update) {
|
|
if (dev->ops->update(dev, input)) {
|
|
G2DLITE_LOG_ERR("update failed");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
goto EXIT;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("update is null");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
if (dev->ops->reset)
|
|
dev->ops->reset(dev);
|
|
|
|
if (dev->ops->enable) {
|
|
if (dev->ops->enable(dev)) {
|
|
G2DLITE_LOG_ERR("enable failed");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
goto EXIT;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("enable is null");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
g2dlite_done();
|
|
|
|
EXIT:
|
|
#if CONFIG_OS_FREERTOS
|
|
xSemaphoreGive(g2dlite_lock);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv g2dlite rotation.
|
|
*
|
|
* This function implements rotation operation.
|
|
*
|
|
* @param [in] dev g2dlite device struct.
|
|
* @param [in] input g2dlite input information.
|
|
* @return SDRV_G2DLITE_STATUS_OK g2dlite rotaion successfully,
|
|
* SDRV_G2DLITE_STATUS_FAIL g2dlite rotaion fail,
|
|
* SDRV_G2DLITE_STATUS_TIMEOUT g2dlite rotaion timeout,
|
|
* SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite rotaion param invalid.
|
|
*/
|
|
status_t sdrv_g2dlite_rotaion(struct g2dlite_device *dev,
|
|
struct g2dlite_input *input)
|
|
{
|
|
status_t ret = SDRV_G2DLITE_STATUS_OK;
|
|
|
|
if ((input->output.width <= 0) || ((input->output.height <= 0)))
|
|
return SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
|
|
#if CONFIG_OS_FREERTOS
|
|
xSemaphoreTake(g2dlite_lock, portMAX_DELAY);
|
|
#endif
|
|
if (dev->ops->rotation) {
|
|
if (dev->ops->rotation(dev, input)) {
|
|
G2DLITE_LOG_ERR("rotation failed");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
goto EXIT;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("rotation is null");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
if (dev->ops->reset)
|
|
dev->ops->reset(dev);
|
|
|
|
if (dev->ops->enable) {
|
|
if (dev->ops->enable(dev)) {
|
|
G2DLITE_LOG_ERR("enable failed");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
goto EXIT;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("enable is null");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
g2dlite_done();
|
|
|
|
EXIT:
|
|
#if CONFIG_OS_FREERTOS
|
|
xSemaphoreGive(g2dlite_lock);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv g2dlite fill rect.
|
|
*
|
|
* This function enables 2D monochrome rendering, and can be used to generate
|
|
* rectangular images using global Alpha or as pixel alpha buffer data.
|
|
*
|
|
* @param [in] dev g2dlite device struct.
|
|
* @param [in] bgcfg g2dlite background config information.
|
|
* @param [in] output g2dlite output config information.
|
|
* @return SDRV_G2DLITE_STATUS_OK g2dlite fill rect successfully,
|
|
* SDRV_G2DLITE_STATUS_FAIL g2dlite fill rect fail,
|
|
* SDRV_G2DLITE_STATUS_TIMEOUT g2dlite fill rect timeout,
|
|
* SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite fill rect param invalid.
|
|
*/
|
|
status_t sdrv_g2dlite_fill_rect(struct g2dlite_device *dev,
|
|
struct g2dlite_bg_cfg *bgcfg,
|
|
struct g2dlite_output_cfg *output)
|
|
{
|
|
status_t ret = SDRV_G2DLITE_STATUS_OK;
|
|
|
|
if ((output->width <= 0) || ((output->height <= 0)))
|
|
return SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
|
|
#if CONFIG_OS_FREERTOS
|
|
xSemaphoreTake(g2dlite_lock, portMAX_DELAY);
|
|
#endif
|
|
|
|
if (dev->ops->fill_rect) {
|
|
if (dev->ops->fill_rect(dev, bgcfg, output)) {
|
|
G2DLITE_LOG_ERR("fill_rect failed");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
goto EXIT;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("fill_rect is null");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
if (dev->ops->reset)
|
|
dev->ops->reset(dev);
|
|
|
|
if (dev->ops->enable) {
|
|
if (dev->ops->enable(dev)) {
|
|
G2DLITE_LOG_ERR("enable failed");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
goto EXIT;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("enable is null");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
g2dlite_done();
|
|
|
|
EXIT:
|
|
#if CONFIG_OS_FREERTOS
|
|
xSemaphoreGive(g2dlite_lock);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv g2dlite fastcopy.
|
|
*
|
|
* This function implements fast memory copy.
|
|
*
|
|
* @param [in] dev g2dlite device struct.
|
|
* @param [in] in g2dlite fcopy input config information.
|
|
* @param [in] out g2dlite fcopy output config information.
|
|
* @return SDRV_G2DLITE_STATUS_OK g2dlite fastcopy rect successfully,
|
|
* SDRV_G2DLITE_STATUS_FAIL g2dlite fastcopy fail,
|
|
* SDRV_G2DLITE_STATUS_TIMEOUT g2dlite fastcopy timeout,
|
|
* SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite fastcopy param invalid.
|
|
*/
|
|
status_t sdrv_g2dlite_fastcopy(struct g2dlite_device *dev, struct fcopy_t *in,
|
|
struct fcopy_t *out)
|
|
{
|
|
status_t ret = SDRV_G2DLITE_STATUS_OK;
|
|
|
|
if ((out->width <= 0) || ((out->height <= 0)))
|
|
return SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
|
|
#if CONFIG_OS_FREERTOS
|
|
xSemaphoreTake(g2dlite_lock, portMAX_DELAY);
|
|
#endif
|
|
|
|
if (dev->ops->fastcopy) {
|
|
if (dev->ops->fastcopy(dev, in, out)) {
|
|
G2DLITE_LOG_ERR("fastcopy failed");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
goto EXIT;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("fastcopy is null");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
if (dev->ops->reset)
|
|
dev->ops->reset(dev);
|
|
|
|
if (dev->ops->enable) {
|
|
if (dev->ops->enable(dev)) {
|
|
G2DLITE_LOG_ERR("enable failed");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
goto EXIT;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("enable is null");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
g2dlite_done();
|
|
|
|
EXIT:
|
|
#if CONFIG_OS_FREERTOS
|
|
xSemaphoreGive(g2dlite_lock);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv g2dlite clut setting.
|
|
*
|
|
* This function implements CLUT settings.
|
|
*
|
|
* @param [in] dev g2dlite device struct.
|
|
* @param [in] clut_table g2dlite clut config information.
|
|
* @return SDRV_G2DLITE_STATUS_OK g2dlite clut set successfully,
|
|
* SDRV_G2DLITE_STATUS_FAIL g2dlite clut set fail,
|
|
* SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite clut param invalid.
|
|
*/
|
|
status_t sdrv_g2dlite_clut_setting(struct g2dlite_device *dev, char *clut_table)
|
|
{
|
|
status_t ret = SDRV_G2DLITE_STATUS_OK;
|
|
|
|
if (dev->ops->clut_index_set) {
|
|
if (dev->ops->clut_index_set(dev, clut_table)) {
|
|
G2DLITE_LOG_ERR("clut setting failed");
|
|
ret = SDRV_G2DLITE_STATUS_FAIL;
|
|
return ret;
|
|
}
|
|
} else {
|
|
G2DLITE_LOG_ERR("clut index set is null");
|
|
ret = SDRV_G2DLITE_STATUS_INVALID_PARAM;
|
|
return ret;
|
|
}
|
|
return ret;
|
|
}
|