Files
base/drivers/source/g2dlite/sdrv_g2dlite.c
2025-11-07 09:57:14 +08:00

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;
}