第一次提交
This commit is contained in:
546
drivers/source/asw/sdrv_asw.c
Normal file
546
drivers/source/asw/sdrv_asw.c
Normal file
@@ -0,0 +1,546 @@
|
||||
/**
|
||||
* @file sdrv_asw.c
|
||||
* @brief sdrv asw driver source.
|
||||
*
|
||||
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <armv7-r/cache.h>
|
||||
#include <asw/asw.h>
|
||||
#include <asw/asw_log.h>
|
||||
#include <dispss/disp_data_type.h>
|
||||
#include <g2dlite/g2dlite.h>
|
||||
#include <irq.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <udelay/udelay.h>
|
||||
|
||||
extern struct asw_operations sdrv_asw_ops;
|
||||
|
||||
#define TRI_SRC_W 1024
|
||||
#define TRI_SRC_H 2
|
||||
int tri_src[TRI_SRC_W * TRI_SRC_H * 4] = {0};
|
||||
|
||||
#define FILL_SRC_W 16
|
||||
#define FILL_SRC_H 16
|
||||
int fill_src[FILL_SRC_W * FILL_SRC_H * 4] = {0};
|
||||
|
||||
#define FILL_EX_W 35
|
||||
#define FILL_EX_H 35
|
||||
int blut_ext[FILL_EX_W * FILL_EX_H * 4 * 6] = {0};
|
||||
|
||||
static void asw_done(struct asw_dev *dev)
|
||||
{
|
||||
#if CONFIG_OS_FREERTOS
|
||||
BaseType_t xReturn = xSemaphoreTake(dev->wdone_sema, pdMS_TO_TICKS(2000));
|
||||
if (pdTRUE != xReturn) {
|
||||
ASW_LOG_ERR("timeout for 2s !");
|
||||
}
|
||||
#else
|
||||
int cnt = 0;
|
||||
while (!dev->asw_done) {
|
||||
udelay(10);
|
||||
if (++cnt == 200000) {
|
||||
ASW_LOG_ERR("timeout for 2s !");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int is_need_twice(double angle)
|
||||
{
|
||||
if ((angle > 45 && angle < 135) || (angle > 225 && angle < 315))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_fmt_bpp(int fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case FMT_MONOTONIC_8BIT:
|
||||
return 1;
|
||||
case FMT_RGB565:
|
||||
case FMT_ARGB1555:
|
||||
case FMT_RGBA5551:
|
||||
return 2;
|
||||
case FMT_RGB_YUV888:
|
||||
return 3;
|
||||
case FMT_RGBA8888:
|
||||
case FMT_ARGB8888:
|
||||
return 4;
|
||||
default:
|
||||
ASW_LOG_ERR("can't support this fmt");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
static int color_to_bgcolor(int color)
|
||||
{
|
||||
int b, g, r, a;
|
||||
b = (color >> 24) & 0xFF;
|
||||
g = (color >> 16) & 0xFF;
|
||||
r = (color >> 8) & 0xFF;
|
||||
a = color & 0xFF;
|
||||
return ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
}
|
||||
|
||||
void sdrv_asw_build_input(
|
||||
struct asw_dev *dev, struct asw_input *input, int work_mode, int lut_mode,
|
||||
int dst_fmt, int dst_hsize, int dst_vsize, int dst_ba, int dst_stride,
|
||||
int dst_bg_color, int dst_flip, int src_fmt, int src_hsize, int src_vsize,
|
||||
int src_ry_ba, int src_gu_ba, int src_bv_ba, int src_ry_stride,
|
||||
int src_gu_stride, int src_bv_stride, int src_flip, int asw_lut_hsize,
|
||||
int asw_lut_vsize, int cache_entry_type, int cache_way_n)
|
||||
{
|
||||
input->work_mode = work_mode;
|
||||
input->lut_mode = lut_mode;
|
||||
|
||||
input->dst.dst_fmt = dst_fmt;
|
||||
input->dst.dst_hsize = dst_hsize;
|
||||
input->dst.dst_vsize = dst_vsize;
|
||||
input->dst.dst_ba = dst_ba;
|
||||
input->dst.dst_stride = dst_stride;
|
||||
input->dst.dst_bg_color = dst_bg_color;
|
||||
input->dst.dst_flip = dst_flip;
|
||||
|
||||
input->src.src_fmt = src_fmt;
|
||||
input->src.src_hsize = src_hsize;
|
||||
input->src.src_vsize = src_vsize;
|
||||
input->src.src_ry_ba = src_ry_ba;
|
||||
input->src.src_gu_ba = src_gu_ba;
|
||||
input->src.src_bv_ba = src_bv_ba;
|
||||
input->src.src_ry_stride = src_ry_stride;
|
||||
input->src.src_gu_stride = src_gu_stride;
|
||||
input->src.src_bv_stride = src_bv_stride;
|
||||
input->src.src_flip = src_flip;
|
||||
|
||||
input->lut.asw_lut_hsize = asw_lut_hsize;
|
||||
input->lut.asw_lut_vsize = asw_lut_vsize;
|
||||
input->cache_entry_type = cache_entry_type;
|
||||
input->cache_way_n = cache_way_n;
|
||||
|
||||
dev->input = input;
|
||||
}
|
||||
|
||||
void sdrv_asw_bilinear_ftob32(const float *faddr, int *b32, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
int tmp = (int)(faddr[i] * 256);
|
||||
tmp = (tmp > 524287) ? 524287 : (tmp < -524288) ? -524288 : tmp;
|
||||
b32[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void sdrv_asw_bilinear_ftob16(const float *faddr, short *b16, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
int tmp16 = (int)(faddr[i] * 16);
|
||||
tmp16 = (tmp16 > 32767) ? 32767 : (tmp16 < -32768) ? -32768 : tmp16;
|
||||
b16[i] = (short)tmp16;
|
||||
}
|
||||
}
|
||||
|
||||
void sdrv_asw_probe(struct asw_dev *dev, const struct asw_config *asw_cfg)
|
||||
{
|
||||
dev->base = asw_cfg->base;
|
||||
dev->irq = asw_cfg->irq;
|
||||
dev->ops = &sdrv_asw_ops;
|
||||
dev->app.id = 0;
|
||||
irq_attach(dev->irq, (irq_handler)dev->ops->irq_handler, dev);
|
||||
irq_enable(dev->irq);
|
||||
#if CONFIG_OS_FREERTOS
|
||||
dev->wdone_sema = xSemaphoreCreateBinary();
|
||||
#endif
|
||||
}
|
||||
|
||||
void sdrv_asw_cubic(struct asw_input *input)
|
||||
{
|
||||
struct asw_dev *dev = &aswdev;
|
||||
|
||||
dev->ops->soft_reset(dev);
|
||||
dev->input = input;
|
||||
dev->ops->cubic_cfg(dev);
|
||||
asw_done(dev);
|
||||
}
|
||||
|
||||
void sdrv_asw_cubic_with_hvkt(struct asw_input *input, struct hvkt_param *hvkt)
|
||||
{
|
||||
struct asw_dev *dev = &aswdev;
|
||||
|
||||
dev->ops->soft_reset(dev);
|
||||
dev->input = input;
|
||||
dev->ops->cubic_cfg_with_hvkt(dev, hvkt);
|
||||
asw_done(dev);
|
||||
}
|
||||
|
||||
void sdrv_asw_bilinear(struct asw_input *input)
|
||||
{
|
||||
struct asw_dev *dev = &aswdev;
|
||||
|
||||
dev->ops->soft_reset(dev);
|
||||
dev->input = input;
|
||||
dev->ops->bilinear_cfg(dev);
|
||||
asw_done(dev);
|
||||
}
|
||||
|
||||
void sdrv_asw_bilinear_noblock(struct asw_input *input)
|
||||
{
|
||||
struct asw_dev *dev = &aswdev;
|
||||
|
||||
dev->ops->soft_reset(dev);
|
||||
dev->input = input;
|
||||
dev->ops->bilinear_cfg(dev);
|
||||
}
|
||||
|
||||
void sdrv_asw_bilinear_with_hvkt(struct asw_input *input,
|
||||
struct hvkt_param *hvkt)
|
||||
{
|
||||
struct asw_dev *dev = &aswdev;
|
||||
|
||||
dev->ops->soft_reset(dev);
|
||||
dev->input = input;
|
||||
dev->ops->bilinear_cfg_with_hvkt(dev, hvkt);
|
||||
asw_done(dev);
|
||||
}
|
||||
|
||||
void sdrv_asw_bilinear_rotation(struct asw_rot *rot)
|
||||
{
|
||||
struct asw_dev *dev = &aswdev;
|
||||
struct asw_input input = {0};
|
||||
struct hvkt_param hvkt = {0};
|
||||
int twice;
|
||||
double rot1, rot2;
|
||||
int offstep;
|
||||
static void *ext_addr;
|
||||
static bool inited = false;
|
||||
|
||||
rot->angle = (int)rot->angle % 360 + (rot->angle - (int)rot->angle);
|
||||
rot1 = rot->angle;
|
||||
|
||||
input.work_mode = WORK_MODE_M_TO_M;
|
||||
input.hdsk_mode = BUF_SIZE_16LINES;
|
||||
input.lut_mode = LUT_MODE_BILINEAR;
|
||||
input.ext_lut_fmt = EXT_LUT_FORMAT_32BIT;
|
||||
input.dst.dst_fmt = rot->dst_fmt;
|
||||
input.dst.dst_hsize = rot->hsize;
|
||||
input.dst.dst_vsize = rot->vsize;
|
||||
|
||||
twice = is_need_twice(rot->angle);
|
||||
if (twice) {
|
||||
if (!rot->t_buf) {
|
||||
ASW_LOG_ERR("t_buf is null when twice operation!");
|
||||
return;
|
||||
}
|
||||
|
||||
input.dst.dst_ba = rot->t_buf;
|
||||
input.dst.dst_stride = rot->t_stride;
|
||||
|
||||
if ((rot->angle > 45) && (rot->angle <= 90)) rot1 = 45;
|
||||
else if ((rot->angle > 90) && (rot->angle <=135)) rot1 = 135;
|
||||
else if ((rot->angle > 225) && (rot->angle <=270)) rot1 = 225;
|
||||
else rot1 = 315;
|
||||
|
||||
rot2 = rot->angle - rot1;
|
||||
} else {
|
||||
input.dst.dst_ba = rot->dst_ba;
|
||||
input.dst.dst_stride = rot->dst_stride;
|
||||
}
|
||||
|
||||
input.dst.dst_bg_color = rot->bg_color;
|
||||
|
||||
input.src.src_fmt = rot->src_fmt;
|
||||
input.src.src_hsize = rot->hsize;
|
||||
input.src.src_vsize = rot->vsize;
|
||||
input.src.src_ry_ba = rot->src_ba[0];
|
||||
input.src.src_gu_ba = rot->src_ba[1];
|
||||
input.src.src_bv_ba = rot->src_ba[2];
|
||||
input.src.src_ry_stride = rot->src_stride[0];
|
||||
input.src.src_gu_stride = rot->src_stride[1];
|
||||
input.src.src_bv_stride = rot->src_stride[2];
|
||||
|
||||
input.lut.asw_lut_hsize = 35;
|
||||
input.lut.asw_lut_vsize = 35;
|
||||
|
||||
offstep = 35 * 35 * 4;
|
||||
if (!inited) {
|
||||
ext_addr = (void *)blut_ext;
|
||||
inited = true;
|
||||
}
|
||||
|
||||
input.ext.ext_mlut_rx_ba = (int)ext_addr;
|
||||
input.ext.ext_mlut_ry_ba = (int)ext_addr + offstep;
|
||||
input.ext.ext_mlut_gx_ba = (int)ext_addr + offstep * 2;
|
||||
input.ext.ext_mlut_gy_ba = (int)ext_addr + offstep * 3;
|
||||
input.ext.ext_mlut_bx_ba = (int)ext_addr + offstep * 4;
|
||||
input.ext.ext_mlut_by_ba = (int)ext_addr + offstep * 5;
|
||||
input.ext.ext_mlut_rx_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_ry_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_gx_stride = input.lut.asw_lut_hsize * 4,
|
||||
input.ext.ext_mlut_gy_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_bx_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_by_stride = input.lut.asw_lut_hsize * 4;
|
||||
|
||||
input.cache_entry_type = C_ENTRY_TYPE_16X4;
|
||||
input.cache_way_n = 10;
|
||||
|
||||
/*hvkt*/
|
||||
hvkt.chn = 1;
|
||||
hvkt.is_external_lut = true;
|
||||
hvkt.fw_map = false;
|
||||
hvkt.external_lut_format = input.ext_lut_fmt; /* 32bits*/
|
||||
|
||||
hvkt.hsize = input.dst.dst_hsize;
|
||||
hvkt.vsize = input.dst.dst_vsize;
|
||||
|
||||
hvkt.hsize_in = input.src.src_hsize;
|
||||
hvkt.vsize_in = input.src.src_vsize;
|
||||
|
||||
hvkt.lut_h_size = input.lut.asw_lut_hsize;
|
||||
hvkt.lut_v_size = input.lut.asw_lut_vsize;
|
||||
|
||||
hvkt.extend = 1;
|
||||
|
||||
dev->ops->soft_reset(dev);
|
||||
dev->input = &input;
|
||||
dev->ops->bilinear_rotation(dev, rot1, &hvkt);
|
||||
asw_done(dev);
|
||||
|
||||
if (twice) {
|
||||
input.src.src_fmt = rot->dst_fmt;
|
||||
input.src.src_ry_ba = input.dst.dst_ba;
|
||||
input.src.src_ry_stride = input.dst.dst_stride;
|
||||
input.dst.dst_ba = rot->dst_ba;
|
||||
input.dst.dst_stride = rot->dst_stride;
|
||||
dev->ops->bilinear_rotation(dev, rot2, &hvkt);
|
||||
asw_done(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void sdrv_asw_ra_triangle(struct asw_ratria *info)
|
||||
{
|
||||
struct asw_input input = {0};
|
||||
float lutx[4], luty[4];
|
||||
int s_w, s_h, size;
|
||||
int *src = NULL;
|
||||
char *src8 = NULL;
|
||||
int offstep;
|
||||
int exaddr = 0;
|
||||
int bpp;
|
||||
|
||||
s_w = TRI_SRC_W;
|
||||
s_h = TRI_SRC_H;
|
||||
size = s_w * s_h;
|
||||
src = tri_src;
|
||||
src8 = (char *)src;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (info->fmt == FMT_MONOTONIC_8BIT)
|
||||
src8[i] = info->color & 0xFF;
|
||||
else
|
||||
src[i] = info->color;
|
||||
}
|
||||
arch_clean_cache_range((addr_t)src, size * 4);
|
||||
|
||||
bpp = get_fmt_bpp(info->fmt);
|
||||
input.work_mode = WORK_MODE_M_TO_M;
|
||||
input.hdsk_mode = BUF_SIZE_16LINES;
|
||||
input.lut_mode = LUT_MODE_BILINEAR;
|
||||
input.ext_lut_fmt = EXT_LUT_FORMAT_32BIT;
|
||||
input.dst.dst_fmt = info->fmt;
|
||||
input.dst.dst_hsize = info->hsize;
|
||||
input.dst.dst_vsize = info->vsize;
|
||||
input.dst.dst_ba =
|
||||
info->addr + info->pos_y * info->stride + info->pos_x * bpp;
|
||||
input.dst.dst_stride = info->stride;
|
||||
input.dst.dst_bg_color = 0x0;
|
||||
|
||||
if (info->fmt == FMT_MONOTONIC_8BIT) {
|
||||
input.src.src_fmt = FMT_MONOTONIC_8BIT;
|
||||
input.src.src_ry_stride = s_w;
|
||||
} else {
|
||||
input.src.src_fmt = FMT_ARGB8888;
|
||||
input.src.src_ry_stride = s_w * 4;
|
||||
}
|
||||
input.src.src_hsize = s_w;
|
||||
input.src.src_vsize = s_h;
|
||||
input.src.src_ry_ba = (int)src;
|
||||
input.src.src_gu_ba = 0;
|
||||
input.src.src_bv_ba = 0;
|
||||
input.src.src_gu_stride = 0;
|
||||
input.src.src_bv_stride = 0;
|
||||
|
||||
input.lut.asw_lut_hsize = 2;
|
||||
input.lut.asw_lut_vsize = 2;
|
||||
|
||||
offstep = input.lut.asw_lut_hsize * input.lut.asw_lut_vsize * 4;
|
||||
|
||||
exaddr = (int)blut_ext;
|
||||
|
||||
input.ext.ext_mlut_rx_ba = exaddr;
|
||||
input.ext.ext_mlut_ry_ba = exaddr + offstep;
|
||||
input.ext.ext_mlut_gx_ba = exaddr + offstep * 2;
|
||||
input.ext.ext_mlut_gy_ba = exaddr + offstep * 3;
|
||||
input.ext.ext_mlut_bx_ba = exaddr + offstep * 4;
|
||||
input.ext.ext_mlut_by_ba = exaddr + offstep * 5;
|
||||
input.ext.ext_mlut_rx_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_ry_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_gx_stride = input.lut.asw_lut_hsize * 4,
|
||||
input.ext.ext_mlut_gy_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_bx_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_by_stride = input.lut.asw_lut_hsize * 4;
|
||||
|
||||
input.cache_entry_type = C_ENTRY_TYPE_16X4;
|
||||
input.cache_way_n = 6;
|
||||
|
||||
switch (info->type) {
|
||||
case TRIAG_LEFT_TOP:
|
||||
lutx[0] = 0;
|
||||
lutx[1] = s_w - 1;
|
||||
lutx[2] = s_w - 1;
|
||||
lutx[3] = 2 * s_w - 1;
|
||||
|
||||
luty[0] = 0;
|
||||
luty[1] = 0;
|
||||
luty[2] = 1;
|
||||
luty[3] = 1;
|
||||
break;
|
||||
case TRIAG_LEFT_BOTTOM:
|
||||
lutx[0] = s_w - 1;
|
||||
lutx[1] = 2 * s_w - 1;
|
||||
lutx[2] = 0;
|
||||
lutx[3] = s_w - 1;
|
||||
|
||||
luty[0] = 0;
|
||||
luty[1] = 0;
|
||||
luty[2] = 1;
|
||||
luty[3] = 1;
|
||||
break;
|
||||
case TRIAG_TYPE_RIGHT_TOP:
|
||||
lutx[0] = 0;
|
||||
lutx[1] = s_w - 1;
|
||||
lutx[2] = 1 - s_w;
|
||||
lutx[3] = 0;
|
||||
|
||||
luty[0] = 0;
|
||||
luty[1] = 0;
|
||||
luty[2] = 1;
|
||||
luty[3] = 1;
|
||||
break;
|
||||
case TRIAG_TYPE_RIGHT_BOTTOM:
|
||||
lutx[0] = 1 - s_w;
|
||||
lutx[1] = 0;
|
||||
lutx[2] = 0;
|
||||
lutx[3] = s_w - 1;
|
||||
|
||||
luty[0] = 0;
|
||||
luty[1] = 0;
|
||||
luty[2] = 1;
|
||||
luty[3] = 1;
|
||||
break;
|
||||
default:
|
||||
ASW_LOG_ERR("Not Support This TYPE(%d)", info->type);
|
||||
return;
|
||||
}
|
||||
|
||||
sdrv_asw_bilinear_ftob32(lutx, (int *)input.ext.ext_mlut_rx_ba, 4);
|
||||
sdrv_asw_bilinear_ftob32(luty, (int *)input.ext.ext_mlut_ry_ba, 4);
|
||||
arch_clean_cache_range((addr_t)input.ext.ext_mlut_rx_ba, offstep * 6);
|
||||
sdrv_asw_bilinear(&input);
|
||||
}
|
||||
|
||||
void sdrv_asw_fill_rect(int fmt, int color, int hsize, int vsize, int pos_x,
|
||||
int pos_y, int addr, int stride)
|
||||
{
|
||||
struct asw_input input = {0};
|
||||
float lutx[4], luty[4];
|
||||
int s_w, s_h, size;
|
||||
int *src = NULL;
|
||||
char *src8 = NULL;
|
||||
int offstep;
|
||||
int exaddr = 0;
|
||||
int bpp;
|
||||
|
||||
s_w = FILL_SRC_W;
|
||||
s_h = FILL_SRC_H;
|
||||
size = s_w * s_h;
|
||||
src = fill_src;
|
||||
src8 = (char *)src;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (fmt == FMT_MONOTONIC_8BIT)
|
||||
src8[i] = color & 0xFF;
|
||||
else
|
||||
src[i] = color;
|
||||
}
|
||||
arch_clean_cache_range((addr_t)src, size * 4);
|
||||
|
||||
bpp = get_fmt_bpp(fmt);
|
||||
input.work_mode = WORK_MODE_M_TO_M;
|
||||
input.hdsk_mode = BUF_SIZE_16LINES;
|
||||
input.lut_mode = LUT_MODE_BILINEAR;
|
||||
input.ext_lut_fmt = EXT_LUT_FORMAT_32BIT;
|
||||
input.dst.dst_fmt = fmt;
|
||||
input.dst.dst_hsize = hsize;
|
||||
input.dst.dst_vsize = vsize;
|
||||
input.dst.dst_ba = addr + pos_y * stride + pos_x * bpp;
|
||||
input.dst.dst_stride = stride;
|
||||
input.dst.dst_bg_color = color_to_bgcolor(color);
|
||||
|
||||
if (fmt == FMT_MONOTONIC_8BIT) {
|
||||
input.src.src_fmt = FMT_MONOTONIC_8BIT;
|
||||
input.src.src_ry_stride = s_w;
|
||||
} else {
|
||||
input.src.src_fmt = FMT_ARGB8888;
|
||||
input.src.src_ry_stride = s_w * 4;
|
||||
}
|
||||
input.src.src_hsize = s_w;
|
||||
input.src.src_vsize = s_h;
|
||||
input.src.src_ry_ba = (int)src;
|
||||
input.src.src_gu_ba = 0;
|
||||
input.src.src_bv_ba = 0;
|
||||
input.src.src_gu_stride = 0;
|
||||
input.src.src_bv_stride = 0;
|
||||
|
||||
input.lut.asw_lut_hsize = 2;
|
||||
input.lut.asw_lut_vsize = 2;
|
||||
|
||||
offstep = input.lut.asw_lut_hsize * input.lut.asw_lut_vsize * 4;
|
||||
|
||||
exaddr = (int)blut_ext;
|
||||
|
||||
input.ext.ext_mlut_rx_ba = exaddr;
|
||||
input.ext.ext_mlut_ry_ba = exaddr + offstep;
|
||||
input.ext.ext_mlut_gx_ba = exaddr + offstep * 2;
|
||||
input.ext.ext_mlut_gy_ba = exaddr + offstep * 3;
|
||||
input.ext.ext_mlut_bx_ba = exaddr + offstep * 4;
|
||||
input.ext.ext_mlut_by_ba = exaddr + offstep * 5;
|
||||
input.ext.ext_mlut_rx_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_ry_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_gx_stride = input.lut.asw_lut_hsize * 4,
|
||||
input.ext.ext_mlut_gy_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_bx_stride = input.lut.asw_lut_hsize * 4;
|
||||
input.ext.ext_mlut_by_stride = input.lut.asw_lut_hsize * 4;
|
||||
|
||||
input.cache_entry_type = C_ENTRY_TYPE_16X4;
|
||||
input.cache_way_n = 6;
|
||||
|
||||
/* top-left*/
|
||||
lutx[0] = 0;
|
||||
luty[0] = 0;
|
||||
|
||||
/* top-right*/
|
||||
lutx[1] = s_w - 1;
|
||||
luty[1] = 0;
|
||||
|
||||
/* bottom-left*/
|
||||
lutx[2] = 0;
|
||||
luty[2] = s_h - 1;
|
||||
|
||||
/* bottom-right*/
|
||||
lutx[3] = s_w - 1;
|
||||
luty[3] = s_h - 1;
|
||||
|
||||
sdrv_asw_bilinear_ftob32(lutx, (int *)input.ext.ext_mlut_rx_ba, 4);
|
||||
sdrv_asw_bilinear_ftob32(luty, (int *)input.ext.ext_mlut_ry_ba, 4);
|
||||
arch_clean_cache_range((addr_t)input.ext.ext_mlut_rx_ba, offstep * 6);
|
||||
sdrv_asw_bilinear(&input);
|
||||
}
|
||||
859
drivers/source/asw/sdrv_asw_drv.c
Normal file
859
drivers/source/asw/sdrv_asw_drv.c
Normal file
@@ -0,0 +1,859 @@
|
||||
/**
|
||||
* @file sdrv_asw_drv.c
|
||||
* @brief sdrv asw driver source.
|
||||
*
|
||||
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <asw/asw.h>
|
||||
#include <asw/asw_log.h>
|
||||
#include <asw/gama_regs.h>
|
||||
#include <board.h>
|
||||
#include <debug.h>
|
||||
#include <dispss/disp.h>
|
||||
#include <param.h>
|
||||
#include <reg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <udelay/udelay.h>
|
||||
|
||||
#define LUT_HSIZE_MAX 35
|
||||
#define LUT_VSIZE_MAX 35
|
||||
int tblut_ext[LUT_HSIZE_MAX * LUT_VSIZE_MAX * 4 * 6] = {0};
|
||||
|
||||
static int sharp_addr[2] = {0x30400, 0x305FF};
|
||||
static int soft_addr[2] = {0x30600, 0x307FF};
|
||||
|
||||
static int sharp_coef[33][5] = {
|
||||
{0, 0, 32, 0, 0}, {0, 0, 32, 0, 0}, {0, -1, 32, 1, 0},
|
||||
{0, -1, 32, 1, 0}, {0, -1, 32, 1, 0}, {0, -1, 31, 2, 0},
|
||||
{0, -2, 32, 2, 0}, {0, -2, 31, 3, 0}, {0, -2, 31, 3, 0},
|
||||
{0, -2, 30, 4, 0}, {0, -2, 30, 4, 0}, {0, -2, 29, 5, 0},
|
||||
{0, -2, 29, 5, 0}, {0, -3, 29, 6, 0}, {0, -3, 29, 6, 0},
|
||||
{0, -3, 29, 7, -1}, {0, -3, 28, 8, -1}, {0, -3, 28, 8, -1},
|
||||
{0, -3, 27, 9, -1}, {0, -3, 27, 9, -1}, {0, -3, 26, 10, -1},
|
||||
{-1, -3, 26, 11, -1}, {-1, -3, 26, 11, -1}, {-1, -3, 25, 12, -1},
|
||||
{-1, -3, 24, 13, -1}, {-1, -3, 24, 13, -1}, {-1, -3, 23, 14, -1},
|
||||
{-1, -2, 22, 15, -2}, {-1, -2, 21, 16, -2}, {-1, -2, 21, 16, -2},
|
||||
{-1, -2, 20, 17, -2}, {-1, -2, 19, 18, -2}, {-1, -2, 19, 18, -2}};
|
||||
|
||||
static int soft_coef[33][5] = {
|
||||
{2, 2, 24, 2, 2}, {2, 2, 23, 3, 2}, {2, 2, 23, 3, 2}, {2, 2, 23, 3, 2},
|
||||
{2, 2, 23, 3, 2}, {2, 2, 22, 4, 2}, {2, 2, 22, 4, 2}, {2, 1, 23, 4, 2},
|
||||
{2, 1, 23, 4, 2}, {2, 1, 22, 5, 2}, {2, 1, 22, 5, 2}, {2, 1, 22, 5, 2},
|
||||
{2, 1, 21, 6, 2}, {2, 1, 21, 6, 2}, {2, 1, 21, 6, 2}, {2, 1, 20, 7, 2},
|
||||
{2, 1, 20, 7, 2}, {2, 1, 20, 7, 2}, {2, 1, 19, 8, 2}, {2, 1, 19, 8, 2},
|
||||
{2, 1, 18, 9, 2}, {2, 1, 18, 9, 2}, {2, 1, 18, 9, 2}, {2, 1, 17, 10, 2},
|
||||
{2, 1, 17, 10, 2}, {2, 1, 16, 11, 2}, {2, 1, 16, 11, 2}, {2, 1, 15, 12, 2},
|
||||
{2, 1, 16, 12, 1}, {2, 1, 16, 12, 1}, {2, 1, 15, 13, 1}, {2, 1, 15, 13, 1},
|
||||
{2, 1, 14, 14, 1}};
|
||||
|
||||
static inline unsigned int reg_value(unsigned int val, unsigned int src,
|
||||
unsigned int shift, unsigned int mask)
|
||||
{
|
||||
return (src & ~mask) | ((val << shift) & mask);
|
||||
}
|
||||
|
||||
static inline unsigned int gama_read(unsigned long base, unsigned int reg)
|
||||
{
|
||||
return readl(base + reg);
|
||||
}
|
||||
|
||||
static inline void lb_write(unsigned long base, unsigned int reg,
|
||||
unsigned int value)
|
||||
{
|
||||
writel(value, base + reg);
|
||||
}
|
||||
static inline void gama_write(unsigned long base, unsigned int reg,
|
||||
unsigned int value)
|
||||
{
|
||||
writel(value, base + reg);
|
||||
}
|
||||
|
||||
static int get_color_chn(int fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case FMT_MONOTONIC_8BIT:
|
||||
case FMT_RGB565:
|
||||
case FMT_RGBA5551:
|
||||
case FMT_ARGB1555:
|
||||
case FMT_RGB_YUV888:
|
||||
case FMT_RGBA8888:
|
||||
case FMT_ARGB8888:
|
||||
return 1;
|
||||
case FMT_YUV422_SEMI_U0V0:
|
||||
case FMT_YUV422_SEMI_V0U0:
|
||||
return 2;
|
||||
case FMT_RGB_YUV888_PLANAR:
|
||||
case FMT_YUV422_PLANAR:
|
||||
case FMT_YUV420_PLANAR:
|
||||
return 3;
|
||||
default:
|
||||
ASW_LOG_ERR("fmt [%d] is error", fmt);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_dst_color_chn(int fmt)
|
||||
{
|
||||
/* FMT_MONOTONIC_8BIT */
|
||||
/* FMT_RGB565 */
|
||||
/* FMT_RGBA5551 */
|
||||
/* FMT_ARGB1555 */
|
||||
/* FMT_RGB_YUV888 */
|
||||
/* FMT_YUV422_UYVY */
|
||||
/* FMT_YUV422_VYUY */
|
||||
/* FMT_RGBA8888 */
|
||||
/* FMT_ARGB8888 */
|
||||
/* FMT_YUV422_YUYV */
|
||||
/* FMT_YUV422_YVYU */
|
||||
|
||||
switch (fmt) {
|
||||
case FMT_MONOTONIC_8BIT:
|
||||
return 1;
|
||||
case FMT_RGB565:
|
||||
case FMT_RGB_YUV888:
|
||||
case FMT_YUV422_UYVY:
|
||||
case FMT_YUV422_VYUY:
|
||||
case FMT_YUV422_YUYV:
|
||||
case FMT_YUV422_YVYU:
|
||||
return 3;
|
||||
case FMT_RGBA5551:
|
||||
case FMT_ARGB1555:
|
||||
case FMT_RGBA8888:
|
||||
case FMT_ARGB8888:
|
||||
return 4;
|
||||
default:
|
||||
ASW_LOG_ERR("fmt [%d] is error", fmt);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_src_color_chn(int fmt)
|
||||
{
|
||||
/*SRC FMT support: */
|
||||
/* FMT_MONOTONIC_8BIT */
|
||||
/* FMT_RGB_YUV888_PLANAR*/
|
||||
/* FMT_YUV422_PLANAR */
|
||||
/* FMT_YUV420_PLANAR */
|
||||
/* FMT_RGB565 */
|
||||
/* FMT_RGBA5551 */
|
||||
/* FMT_ARGB1555 */
|
||||
/* FMT_RGB_YUV888 */
|
||||
/* FMT_YUV422_SEMI_U0V0 */
|
||||
/* FMT_YUV422_SEMI_V0U0 */
|
||||
/* FMT_RGBA8888 */
|
||||
/* FMT_ARGB8888 */
|
||||
|
||||
switch (fmt) {
|
||||
case FMT_MONOTONIC_8BIT:
|
||||
return 1;
|
||||
case FMT_RGB565:
|
||||
case FMT_YUV420_PLANAR:
|
||||
case FMT_YUV422_PLANAR:
|
||||
case FMT_RGB_YUV888:
|
||||
case FMT_RGB_YUV888_PLANAR:
|
||||
case FMT_YUV422_SEMI_U0V0:
|
||||
case FMT_YUV422_SEMI_V0U0:
|
||||
return 3;
|
||||
case FMT_RGBA5551:
|
||||
case FMT_ARGB1555:
|
||||
case FMT_RGBA8888:
|
||||
case FMT_ARGB8888:
|
||||
return 4;
|
||||
default:
|
||||
ASW_LOG_ERR("fmt [%d] is error", fmt);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_cache_entry_vsize(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case C_ENTRY_TYPE_8X4:
|
||||
case C_ENTRY_TYPE_16X4:
|
||||
case C_ENTRY_TYPE_32X4:
|
||||
return 4;
|
||||
case C_ENTRY_TYPE_8X8:
|
||||
case C_ENTRY_TYPE_16X8:
|
||||
return 8;
|
||||
default:
|
||||
ASW_LOG_ERR("type [%d] is error", type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_cache_entry_hsize(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case C_ENTRY_TYPE_8X4:
|
||||
case C_ENTRY_TYPE_8X8:
|
||||
return 8;
|
||||
case C_ENTRY_TYPE_16X4:
|
||||
case C_ENTRY_TYPE_16X8:
|
||||
return 16;
|
||||
case C_ENTRY_TYPE_32X4:
|
||||
return 32;
|
||||
default:
|
||||
ASW_LOG_ERR("type [%d] is error", type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_fmt_h_half(int fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case FMT_YUV422_PLANAR:
|
||||
case FMT_YUV420_PLANAR:
|
||||
case FMT_YUV422_SEMI_U0V0:
|
||||
case FMT_YUV422_SEMI_V0U0:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_cache_chn_size(struct asw_dev *dev, int index)
|
||||
{
|
||||
int hsize, ce_vsize;
|
||||
|
||||
switch (index) {
|
||||
default:
|
||||
case 0:
|
||||
hsize = ((dev->input->src.src_hsize + 111) / 128) * 128 + 16;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if (get_fmt_h_half(dev->input->src.src_fmt))
|
||||
hsize = ((dev->input->src.src_hsize / 2 + 111) / 128) * 128 + 16;
|
||||
else
|
||||
hsize = ((dev->input->src.src_hsize + 111) / 128) * 128 + 16;
|
||||
break;
|
||||
}
|
||||
|
||||
ce_vsize = get_cache_entry_vsize(dev->input->cache_entry_type);
|
||||
|
||||
return hsize * ce_vsize * dev->input->cache_way_n;
|
||||
}
|
||||
|
||||
/*burst_len = tile_hsize * byte_per_pixel / 8*/
|
||||
/*Using this func can get the byte_per_pixel*/
|
||||
int get_rdma_bpp_by_fmt(int fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case FMT_MONOTONIC_8BIT:
|
||||
case FMT_YUV422_PLANAR:
|
||||
case FMT_YUV420_PLANAR:
|
||||
case FMT_RGB_YUV888_PLANAR:
|
||||
return 1;
|
||||
case FMT_RGB565:
|
||||
case FMT_RGBA5551:
|
||||
case FMT_ARGB1555:
|
||||
case FMT_YUV422_SEMI_U0V0:
|
||||
case FMT_YUV422_SEMI_V0U0:
|
||||
return 2;
|
||||
case FMT_RGB_YUV888:
|
||||
return 3;
|
||||
case FMT_RGBA8888:
|
||||
case FMT_ARGB8888:
|
||||
return 4;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void lb_component_ba_calc(struct asw_dev *dev)
|
||||
{
|
||||
int chn, dchn, lut_shape_size, frb_size, cache_chn_size;
|
||||
struct asw_ba_info *bas = &dev->bas;
|
||||
struct asw_input *input = dev->input;
|
||||
|
||||
if (dev->input->lut_mode == LUT_MODE_CUBIC_SPLINE) {
|
||||
/*LUT*/
|
||||
bas->asw_pos_lut_ba = GAMA_LB_JUMP;
|
||||
chn = get_color_chn(input->src.src_fmt);
|
||||
lut_shape_size = 35 * 35 * 2 * chn * 4;
|
||||
bas->asw_m_v_ba = bas->asw_pos_lut_ba + lut_shape_size;
|
||||
|
||||
/*pfile*/
|
||||
bas->asw_pos_calc_pfile_ba = bas->asw_pos_lut_ba + lut_shape_size * 2;
|
||||
|
||||
/*alpha[]*/
|
||||
bas->asw_alpha_ba = bas->asw_pos_calc_pfile_ba + 16 * 4;
|
||||
|
||||
/*y/step_y*/
|
||||
bas->asw_y_stepy_ba = bas->asw_alpha_ba + 35 * 4;
|
||||
|
||||
/*LUT_H[]*/
|
||||
bas->asw_lut_h_ba = bas->asw_y_stepy_ba + 60 * 4;
|
||||
|
||||
/*M_H[]*/
|
||||
bas->asw_m_h_ba = bas->asw_lut_h_ba + 35 * 4;
|
||||
|
||||
/*Filter Result Buffer*/
|
||||
bas->asw_frb_ba = ALIGN(bas->asw_m_h_ba + 35 * 4, 16);
|
||||
} else { /*LUT_MODE_BILINEAR*/
|
||||
bas->asw_frb_ba = GAMA_LB_JUMP;
|
||||
}
|
||||
|
||||
/*CACHE*/
|
||||
dchn = get_src_color_chn(input->src.src_fmt);
|
||||
frb_size = (ALIGN(dev->input->dst.dst_hsize, 16) / 4) * 2 * dchn * 4; /*argb*/
|
||||
bas->asw_cache_ry_ba = ALIGN(bas->asw_frb_ba + frb_size, 128);
|
||||
cache_chn_size = get_cache_chn_size(dev, 0);
|
||||
if ((input->src.src_fmt == FMT_YUV422_SEMI_U0V0) ||
|
||||
((input->src.src_fmt == FMT_YUV422_SEMI_V0U0))) {
|
||||
bas->asw_cache_gu_ba =
|
||||
bas->asw_cache_ry_ba + ALIGN(cache_chn_size, 128);
|
||||
cache_chn_size = get_cache_chn_size(dev, 1);
|
||||
bas->asw_cache_bv_ba =
|
||||
bas->asw_cache_gu_ba + ALIGN(cache_chn_size, 128) + 64;
|
||||
} else {
|
||||
bas->asw_cache_gu_ba =
|
||||
bas->asw_cache_ry_ba + ALIGN(cache_chn_size, 128) + 32;
|
||||
cache_chn_size = get_cache_chn_size(dev, 1);
|
||||
bas->asw_cache_bv_ba =
|
||||
bas->asw_cache_gu_ba + ALIGN(cache_chn_size, 128) + 32;
|
||||
}
|
||||
|
||||
cache_chn_size = get_cache_chn_size(dev, 2);
|
||||
bas->asw_cache_a_ba =
|
||||
bas->asw_cache_bv_ba + ALIGN(cache_chn_size, 128) + 32;
|
||||
|
||||
ASW_LOG_DEBUG("asw_pos_calc_pfile_ba = 0x%08x", bas->asw_pos_calc_pfile_ba);
|
||||
ASW_LOG_DEBUG("asw_pos_lut_ba = 0x%08x", bas->asw_pos_lut_ba);
|
||||
ASW_LOG_DEBUG("asw_m_v_ba = 0x%08x", bas->asw_m_v_ba);
|
||||
ASW_LOG_DEBUG("asw_alpha_ba = 0x%08x", bas->asw_alpha_ba);
|
||||
ASW_LOG_DEBUG("asw_y_stepy_ba = 0x%08x", bas->asw_y_stepy_ba);
|
||||
ASW_LOG_DEBUG("asw_lut_h_ba = 0x%08x", bas->asw_lut_h_ba);
|
||||
ASW_LOG_DEBUG("asw_m_h_ba = 0x%08x", bas->asw_m_h_ba);
|
||||
ASW_LOG_DEBUG("asw_frb_ba = 0x%08x", bas->asw_frb_ba);
|
||||
ASW_LOG_DEBUG("asw_cache_ry_ba = 0x%08x", bas->asw_cache_ry_ba);
|
||||
ASW_LOG_DEBUG("asw_cache_gu_ba = 0x%08x", bas->asw_cache_gu_ba);
|
||||
ASW_LOG_DEBUG("asw_cache_bv_ba = 0x%08x", bas->asw_cache_bv_ba);
|
||||
ASW_LOG_DEBUG("asw_cache_a_ba = 0x%08x", bas->asw_cache_a_ba);
|
||||
}
|
||||
|
||||
static void load_lut(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
int addr;
|
||||
|
||||
addr = dev->bas.asw_pos_lut_ba;
|
||||
|
||||
for (int i = 0; addr < dev->bas.asw_pos_calc_pfile_ba; i++) {
|
||||
lb_write(base, addr,
|
||||
*(unsigned int *)(dev->input->cubic.lut_src_ba + i * 4));
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void load_cfg_parameter(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
int addr;
|
||||
|
||||
addr = dev->bas.asw_pos_calc_pfile_ba;
|
||||
|
||||
ASW_LOG_INFO("addr = 0x%x", addr);
|
||||
|
||||
/*params[0] = (float)1/2*/
|
||||
lb_write(base, addr, 0x3f000000);
|
||||
addr += 4;
|
||||
|
||||
/*params[1] = (float)1/3*/
|
||||
lb_write(base, addr, 0x3eaaaa9f);
|
||||
addr += 4;
|
||||
|
||||
/*params[2] = (float)1/6*/
|
||||
lb_write(base, addr, 0x3e2aaac1);
|
||||
addr += 4;
|
||||
|
||||
/*params[3] = (float)2*/
|
||||
lb_write(base, addr, 0x40000000);
|
||||
addr += 4;
|
||||
|
||||
/*params[4] = (float)6*/
|
||||
lb_write(base, addr, 0x40c00000);
|
||||
addr += 4;
|
||||
|
||||
/*params[5] = (float)(-(2^24-1)*256)*/
|
||||
lb_write(base, addr, 0xcf7fffff);
|
||||
addr += 4;
|
||||
|
||||
/*params[6] = (float)(+(2^24-1)*256)*/
|
||||
lb_write(base, addr, 0x4f7fffff);
|
||||
addr += 4;
|
||||
|
||||
/*params[7] = (float)256*/
|
||||
lb_write(base, addr, 0x43800000);
|
||||
addr += 4;
|
||||
|
||||
/*params[8]*/
|
||||
lb_write(base, addr, dev->bas.asw_alpha_ba - GAMA_LB_JUMP);
|
||||
addr += 4;
|
||||
|
||||
/*params[9]*/
|
||||
addr += 4;
|
||||
|
||||
/*params[10]*/
|
||||
lb_write(base, addr, dev->bas.asw_y_stepy_ba - GAMA_LB_JUMP);
|
||||
addr += 4;
|
||||
|
||||
/*params[11][12]*/
|
||||
addr += 8;
|
||||
|
||||
/*params[13]*/
|
||||
lb_write(base, addr, dev->bas.asw_lut_h_ba - GAMA_LB_JUMP);
|
||||
addr += 4;
|
||||
|
||||
/*params[14]*/
|
||||
lb_write(base, addr, dev->bas.asw_m_h_ba - GAMA_LB_JUMP);
|
||||
addr += 4;
|
||||
}
|
||||
|
||||
static void load_alpha(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
int addr;
|
||||
|
||||
addr = dev->bas.asw_alpha_ba;
|
||||
|
||||
for (int i = 0; addr < dev->bas.asw_y_stepy_ba; i++) {
|
||||
lb_write(base, addr,
|
||||
*(unsigned int *)(dev->input->cubic.alpha_src_ba + i * 4));
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void load_y_stepy(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
int step, addr;
|
||||
|
||||
step = (dev->input->dst.dst_vsize + 31) / 32;
|
||||
addr = dev->bas.asw_y_stepy_ba;
|
||||
|
||||
for (int i = 0; i < step; i++) {
|
||||
float val = (float)i / (float)step;
|
||||
int *pos = (int *)(&val);
|
||||
int value = *pos;
|
||||
lb_write(base, addr, value);
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void gama_rwdma_init(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
unsigned int val;
|
||||
|
||||
/*set dma circular buffer mode*/
|
||||
|
||||
gama_write(base, ASW_RD01C(0), dev->input->cbuf.low_limit_addr);
|
||||
gama_write(base, ASW_RD020(0), dev->input->cbuf.high_limit_addr);
|
||||
val = reg_value(dev->input->cbuf.range, 0, ASW_SHIFT01_RD024,
|
||||
ASW_MASK01_RD024);
|
||||
val = reg_value(dev->input->cbuf.enable, val, ASW_SHIFT00_RD024,
|
||||
ASW_MASK00_RD024);
|
||||
gama_write(base, ASW_RD024(0), val);
|
||||
|
||||
gama_write(base, 0x20000, 0x200000);
|
||||
gama_write(base, 0x2000c, 0x200000);
|
||||
}
|
||||
|
||||
static void gama_asw_set_hwmode(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
unsigned int val;
|
||||
|
||||
gama_rwdma_init(dev);
|
||||
|
||||
/*mode configs*/
|
||||
val = gama_read(base, ASW_RB010);
|
||||
val = reg_value(1, val, ASW_SHIFT02_RB010, ASW_MASK02_RB010);
|
||||
val =
|
||||
reg_value(LB_LAYOUT_B, val, ASW_SHIFT01_RB010, ASW_MASK01_RB010);
|
||||
val = reg_value(1, val, ASW_SHIFT00_RB010, ASW_MASK00_RB010);
|
||||
gama_write(base, ASW_RB010, val);
|
||||
}
|
||||
|
||||
static void gama_asw_cfg(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
unsigned int c_chn;
|
||||
unsigned int val;
|
||||
int asw_lut_hstep, asw_lut_vstep;
|
||||
|
||||
c_chn = get_color_chn(dev->input->src.src_fmt);
|
||||
|
||||
/*LUT parameters*/
|
||||
val = reg_value(dev->input->lut.asw_lut_hsize - 1, 0, ASW_SHIFT00_RA020,
|
||||
ASW_MASK00_RA020);
|
||||
val = reg_value(dev->input->lut.asw_lut_vsize - 1, val,
|
||||
ASW_SHIFT16_RA020, ASW_MASK16_RA020);
|
||||
gama_write(base, ASW_RA020, val);
|
||||
|
||||
if (dev->input->lut_mode == LUT_MODE_CUBIC_SPLINE) {
|
||||
asw_lut_hstep = (dev->input->dst.dst_hsize + 31) / 32;
|
||||
asw_lut_vstep = (dev->input->dst.dst_vsize + 31) / 32;
|
||||
} else { /*LUT_MODE_BILINEAR*/
|
||||
asw_lut_hstep =
|
||||
(dev->input->dst.dst_hsize + dev->input->lut.asw_lut_hsize - 2) /
|
||||
(dev->input->lut.asw_lut_hsize - 1);
|
||||
asw_lut_vstep =
|
||||
(dev->input->dst.dst_vsize + dev->input->lut.asw_lut_vsize - 2) /
|
||||
(dev->input->lut.asw_lut_vsize - 1);
|
||||
}
|
||||
val = reg_value(asw_lut_hstep - 1, 0, ASW_SHIFT00_RA024,
|
||||
ASW_MASK00_RA024);
|
||||
val = reg_value(asw_lut_vstep - 1, val, ASW_SHIFT16_RA024,
|
||||
ASW_MASK16_RA024);
|
||||
gama_write(base, ASW_RA024, val);
|
||||
|
||||
val = 0x100000 / asw_lut_hstep; /*(int)((1/lut_step_h)*2^20)*/
|
||||
gama_write(base, ASW_RA028, val);
|
||||
|
||||
val = 0x100000 / asw_lut_vstep; /*(int)((1/lut_step_v)*2^20)*/
|
||||
gama_write(base, ASW_RA02C, val);
|
||||
|
||||
if (dev->input->lut_mode == LUT_MODE_CUBIC_SPLINE) {
|
||||
gama_write(base, ASW_RA030,
|
||||
dev->bas.asw_pos_calc_pfile_ba - GAMA_LB_JUMP);
|
||||
int jump =
|
||||
dev->input->lut.asw_lut_hsize * 2 * c_chn * 4; /*jump one line*/
|
||||
gama_write(base, ASW_RA034,
|
||||
dev->bas.asw_pos_lut_ba + jump - GAMA_LB_JUMP);
|
||||
gama_write(base, ASW_RA038,
|
||||
dev->bas.asw_m_v_ba + jump - GAMA_LB_JUMP);
|
||||
} else { /*LUT_MODE_BILINEAR*/
|
||||
gama_write(base, ASW_RA090, dev->input->ext.ext_mlut_rx_ba);
|
||||
gama_write(base, ASW_RA0A8,
|
||||
dev->input->ext.ext_mlut_rx_stride - 1);
|
||||
gama_write(base, ASW_RA094, dev->input->ext.ext_mlut_ry_ba);
|
||||
gama_write(base, ASW_RA0AC,
|
||||
dev->input->ext.ext_mlut_ry_stride - 1);
|
||||
|
||||
if (c_chn > 1) {
|
||||
gama_write(base, ASW_RA098,
|
||||
dev->input->ext.ext_mlut_gx_ba);
|
||||
gama_write(base, ASW_RA0B0,
|
||||
dev->input->ext.ext_mlut_gx_stride - 1);
|
||||
gama_write(base, ASW_RA09C,
|
||||
dev->input->ext.ext_mlut_gy_ba);
|
||||
gama_write(base, ASW_RA0B4,
|
||||
dev->input->ext.ext_mlut_gy_stride - 1);
|
||||
}
|
||||
|
||||
if (c_chn > 2) {
|
||||
gama_write(base, ASW_RA0A0,
|
||||
dev->input->ext.ext_mlut_bx_ba);
|
||||
gama_write(base, ASW_RA0B8,
|
||||
dev->input->ext.ext_mlut_bx_stride - 1);
|
||||
gama_write(base, ASW_RA0A4,
|
||||
dev->input->ext.ext_mlut_by_ba);
|
||||
gama_write(base, ASW_RA0BC,
|
||||
dev->input->ext.ext_mlut_by_stride - 1);
|
||||
}
|
||||
}
|
||||
/*ASW Cache parameters*/
|
||||
gama_write(base, ASW_RA040, dev->bas.asw_cache_ry_ba - GAMA_LB_JUMP);
|
||||
gama_write(base, ASW_RA044, dev->bas.asw_cache_gu_ba - GAMA_LB_JUMP);
|
||||
gama_write(base, ASW_RA048, dev->bas.asw_cache_bv_ba - GAMA_LB_JUMP);
|
||||
gama_write(base, ASW_RA04C, dev->bas.asw_cache_a_ba - GAMA_LB_JUMP);
|
||||
|
||||
gama_write(base, ASW_RA050, dev->bas.asw_frb_ba - GAMA_LB_JUMP);
|
||||
gama_write(base, ASW_RA058,
|
||||
ALIGN(dev->input->dst.dst_hsize, 16) - 1);
|
||||
|
||||
/*src/des image formats*/
|
||||
val = reg_value(dev->input->src.src_vsize - 1, 0, ASW_SHIFT16_RA010,
|
||||
ASW_MASK16_RA010);
|
||||
val = reg_value(dev->input->src.src_hsize - 1, val, ASW_SHIFT00_RA010,
|
||||
ASW_MASK00_RA010);
|
||||
gama_write(base, ASW_RA010, val);
|
||||
|
||||
val = reg_value(dev->input->dst.dst_vsize - 1, 0, ASW_SHIFT16_RA014,
|
||||
ASW_MASK16_RA014);
|
||||
val = reg_value(dev->input->dst.dst_hsize - 1, val, ASW_SHIFT00_RA014,
|
||||
ASW_MASK00_RA014);
|
||||
gama_write(base, ASW_RA014, val);
|
||||
|
||||
val = gama_read(base, ASW_RA018);
|
||||
val = reg_value((dev->input->dst.dst_flip & FLIP_TYPE_HFLIP) ? 1 : 0, val,
|
||||
ASW_SHIFT24_RA018, ASW_MASK24_RA018);
|
||||
val = reg_value((dev->input->dst.dst_flip & FLIP_TYPE_VFLIP) ? 1 : 0, val,
|
||||
ASW_SHIFT25_RA018, ASW_MASK25_RA018);
|
||||
val = reg_value(dev->input->dst.dst_fmt, val, ASW_SHIFT16_RA018, ASW_MASK16_RA018);
|
||||
val = reg_value((dev->input->src.src_flip & FLIP_TYPE_HFLIP) ? 1 : 0, val,
|
||||
ASW_SHIFT08_RA018, ASW_MASK08_RA018);
|
||||
val = reg_value((dev->input->src.src_flip & FLIP_TYPE_VFLIP) ? 1 : 0, val,
|
||||
ASW_SHIFT09_RA018, ASW_MASK09_RA018);
|
||||
val = reg_value(dev->input->src.src_fmt, val, ASW_SHIFT00_RA018, ASW_MASK00_RA018);
|
||||
gama_write(base, ASW_RA018, val);
|
||||
|
||||
gama_write(base, ASW_RA060, dev->input->src.src_ry_ba);
|
||||
gama_write(base, ASW_RA06C, dev->input->src.src_ry_stride - 1);
|
||||
if (c_chn > 1) {
|
||||
gama_write(base, ASW_RA064, dev->input->src.src_gu_ba);
|
||||
gama_write(base, ASW_RA070, dev->input->src.src_gu_stride - 1);
|
||||
}
|
||||
if (c_chn > 2) {
|
||||
gama_write(base, ASW_RA068, dev->input->src.src_bv_ba);
|
||||
gama_write(base, ASW_RA074, dev->input->src.src_bv_stride - 1);
|
||||
}
|
||||
|
||||
gama_write(base, ASW_RA080, dev->input->dst.dst_ba);
|
||||
gama_write(base, ASW_RA084, dev->input->dst.dst_stride - 1);
|
||||
|
||||
/*ohter parameters*/
|
||||
val = gama_read(base, ASW_RA00C);
|
||||
if (dev->input->adb.dirty) {
|
||||
val = reg_value(dev->input->adb.offset, val, ASW_SHIFT04_RA00C,
|
||||
ASW_MASK04_RA00C);
|
||||
val = reg_value(dev->input->adb.slope, val, ASW_SHIFT00_RA00C,
|
||||
ASW_MASK00_RA00C);
|
||||
} else {
|
||||
val = reg_value(0x18, val, ASW_SHIFT04_RA00C, ASW_MASK04_RA00C);
|
||||
val = reg_value(0x7, val, ASW_SHIFT00_RA00C, ASW_MASK00_RA00C);
|
||||
}
|
||||
gama_write(base, ASW_RA00C, val);
|
||||
|
||||
gama_write(base, ASW_RA088, dev->input->dst.dst_bg_color);
|
||||
|
||||
val = gama_read(base, ASW_RA008);
|
||||
val = reg_value(dev->input->lut_mode, val, ASW_SHIFT00_RA008,
|
||||
ASW_MASK00_RA008);
|
||||
if (dev->input->lut_mode == LUT_MODE_BILINEAR) {
|
||||
val = reg_value(dev->input->ext_lut_fmt, val, ASW_SHIFT11_RA008,
|
||||
ASW_MASK11_RA008);
|
||||
}
|
||||
if (dev->input->lut_mode == LUT_MODE_CUBIC_SPLINE) {
|
||||
val = reg_value(CUBIC_MODE_INT_ASM, val, ASW_SHIFT10_RA008,
|
||||
ASW_MASK10_RA008);
|
||||
}
|
||||
val =
|
||||
reg_value(dev->input->work_mode, val, ASW_SHIFT08_RA008, ASW_MASK08_RA008);
|
||||
val = reg_value(dev->input->cache_entry_type, val, ASW_SHIFT01_RA008,
|
||||
ASW_MASK01_RA008);
|
||||
val = reg_value(dev->input->cache_way_n, val, ASW_SHIFT04_RA008,
|
||||
ASW_MASK04_RA008);
|
||||
gama_write(base, ASW_RA008, val);
|
||||
|
||||
gama_write(base, ASW_RC028, 0xFFE);
|
||||
|
||||
dev->asw_done = 0;
|
||||
switch (dev->input->work_mode) {
|
||||
case WORK_MODE_M_TO_M:
|
||||
default:
|
||||
gama_write(base, ASW_RA01C, 0x3); /*using prepare shadow load.*/
|
||||
ASW_LOG_DEBUG("m2m cfg fctrl");
|
||||
gama_write(base, ASW_RA000, 0x1); /*ASW frame start(when m_to_m mode)*/
|
||||
break;
|
||||
case WORK_MODE_CSI_HS:
|
||||
val = gama_read(base, ASW_RA008);
|
||||
val = reg_value(dev->input->csi_start_ln, val, ASW_SHIFT20_RA008,
|
||||
ASW_MASK20_RA008);
|
||||
val = reg_value(dev->input->hdsk_mode, val, ASW_SHIFT12_RA008,
|
||||
ASW_MASK12_RA008);
|
||||
gama_write(base, ASW_RA008, val);
|
||||
gama_write(base, ASW_RA01C, 0x3);
|
||||
break;
|
||||
case WORK_MODE_DC_HS:
|
||||
val = gama_read(base, ASW_RA008);
|
||||
val = reg_value(dev->input->hdsk_mode, val, ASW_SHIFT12_RA008,
|
||||
ASW_MASK12_RA008);
|
||||
gama_write(base, ASW_RA008, val);
|
||||
gama_write(base, ASW_RA01C, 0x3);
|
||||
break;
|
||||
case WORK_MODE_CSI_DC_HS:
|
||||
val = gama_read(base, ASW_RA008);
|
||||
val = reg_value(dev->input->csi_start_ln, val, ASW_SHIFT20_RA008,
|
||||
ASW_MASK20_RA008);
|
||||
val = reg_value(dev->input->hdsk_mode, val, ASW_SHIFT12_RA008,
|
||||
ASW_MASK12_RA008);
|
||||
gama_write(base, ASW_RA008, val);
|
||||
gama_write(base, ASW_RA01C, 0x3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gama_fliter_set(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
unsigned int head, tail;
|
||||
for (int i = 0; i < 33; i++) {
|
||||
head = (sharp_coef[i][0] & 0xff) | ((sharp_coef[i][1] & 0xff) << 8) |
|
||||
((sharp_coef[i][2] & 0xff) << 16);
|
||||
tail = ((sharp_coef[i][3] & 0xff)) | ((sharp_coef[i][4] & 0xff) << 8);
|
||||
|
||||
gama_write(base, sharp_addr[0] + (i * 2) * 4, head);
|
||||
gama_write(base, sharp_addr[0] + (i * 2 + 1) * 4, tail);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 33; i++) {
|
||||
head = (soft_coef[i][0] & 0xff) | ((soft_coef[i][1] & 0xff) << 8) |
|
||||
((soft_coef[i][2] & 0xff) << 16);
|
||||
tail = ((soft_coef[i][3] & 0xff)) | ((soft_coef[i][4] & 0xff) << 8);
|
||||
|
||||
gama_write(base, soft_addr[0] + (i * 2) * 4, head);
|
||||
gama_write(base, soft_addr[0] + (i * 2 + 1) * 4, tail);
|
||||
}
|
||||
}
|
||||
|
||||
static void asw_soft_reset(struct asw_dev *dev)
|
||||
{
|
||||
unsigned long base = dev->base;
|
||||
|
||||
gama_write(base, ASW_RA004, 1);
|
||||
udelay(10);
|
||||
gama_write(base, ASW_RA004, 0);
|
||||
}
|
||||
|
||||
/*cubic spline*/
|
||||
static void asw_cubic(struct asw_dev *dev)
|
||||
{
|
||||
lb_component_ba_calc(dev);
|
||||
gama_asw_set_hwmode(dev);
|
||||
|
||||
load_lut(dev);
|
||||
load_cfg_parameter(dev);
|
||||
load_alpha(dev);
|
||||
load_y_stepy(dev);
|
||||
gama_fliter_set(dev);
|
||||
gama_asw_cfg(dev);
|
||||
}
|
||||
|
||||
static void asw_cubic_with_hvkt(struct asw_dev *dev, struct hvkt_param *hvkt)
|
||||
{
|
||||
lb_component_ba_calc(dev);
|
||||
gama_asw_set_hwmode(dev);
|
||||
|
||||
hvkt->lut_addr = dev->base + dev->bas.asw_pos_lut_ba;
|
||||
hvkt->m_v_addr = dev->base + dev->bas.asw_m_v_ba;
|
||||
hvkt->alpha_addr = dev->base + dev->bas.asw_alpha_ba;
|
||||
hvkt->lut_h_step =
|
||||
(dev->input->dst.dst_hsize + (dev->input->lut.asw_lut_hsize - 2)) /
|
||||
(dev->input->lut.asw_lut_hsize - 1);
|
||||
hvkt->lut_v_step =
|
||||
(dev->input->dst.dst_vsize + (dev->input->lut.asw_lut_vsize - 2)) /
|
||||
(dev->input->lut.asw_lut_vsize - 1);
|
||||
|
||||
lut_hvk_ops.lut_table_gen(hvkt);
|
||||
lut_hvk_ops.lut_m_v_gen(hvkt);
|
||||
|
||||
load_cfg_parameter(dev);
|
||||
load_y_stepy(dev);
|
||||
gama_fliter_set(dev);
|
||||
gama_asw_cfg(dev);
|
||||
}
|
||||
|
||||
/*bilinear*/
|
||||
static void asw_bilinear(struct asw_dev *dev)
|
||||
{
|
||||
lb_component_ba_calc(dev);
|
||||
gama_asw_set_hwmode(dev);
|
||||
|
||||
gama_fliter_set(dev);
|
||||
gama_asw_cfg(dev);
|
||||
}
|
||||
|
||||
static void asw_bilinear_with_hvkt(struct asw_dev *dev, struct hvkt_param *hvkt)
|
||||
{
|
||||
lb_component_ba_calc(dev);
|
||||
gama_asw_set_hwmode(dev);
|
||||
|
||||
hvkt->lut_addr = (int)tblut_ext;
|
||||
hvkt->lut_real_addr[0] = dev->input->ext.ext_mlut_rx_ba;
|
||||
hvkt->lut_real_addr[1] = dev->input->ext.ext_mlut_ry_ba;
|
||||
hvkt->lut_real_addr[2] = dev->input->ext.ext_mlut_gx_ba;
|
||||
hvkt->lut_real_addr[3] = dev->input->ext.ext_mlut_gy_ba;
|
||||
hvkt->lut_real_addr[4] = dev->input->ext.ext_mlut_bx_ba;
|
||||
hvkt->lut_real_addr[5] = dev->input->ext.ext_mlut_by_ba;
|
||||
hvkt->lut_h_step =
|
||||
(dev->input->dst.dst_hsize + (dev->input->lut.asw_lut_hsize - 2)) /
|
||||
(dev->input->lut.asw_lut_hsize - 1);
|
||||
hvkt->lut_v_step =
|
||||
(dev->input->dst.dst_vsize + (dev->input->lut.asw_lut_vsize - 2)) /
|
||||
(dev->input->lut.asw_lut_vsize - 1);
|
||||
lut_hvk_ops.lut_table_gen(hvkt);
|
||||
|
||||
gama_fliter_set(dev);
|
||||
gama_asw_cfg(dev);
|
||||
}
|
||||
|
||||
static int asw_irq_handler(unsigned int irq, void *data)
|
||||
{
|
||||
struct asw_dev *dev = (struct asw_dev *)data;
|
||||
unsigned int val;
|
||||
|
||||
val = gama_read(dev->base, ASW_RC024);
|
||||
gama_write(dev->base, ASW_RC030, val);
|
||||
|
||||
if (val & WRITE_OUT_FRM_DONE_MASK) {
|
||||
dev->asw_done = 1;
|
||||
#if CONFIG_OS_FREERTOS
|
||||
xSemaphoreGiveFromISR(dev->wdone_sema, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void asw_cubic_rotation(struct asw_dev *dev, double rotate_angle,
|
||||
struct hvkt_param *hvkt)
|
||||
{
|
||||
lb_component_ba_calc(dev);
|
||||
gama_asw_set_hwmode(dev);
|
||||
|
||||
hvkt->lut_addr = dev->base + dev->bas.asw_pos_lut_ba;
|
||||
hvkt->m_v_addr = dev->base + dev->bas.asw_m_v_ba;
|
||||
hvkt->alpha_addr = dev->base + dev->bas.asw_alpha_ba;
|
||||
|
||||
lut_hvk_ops.lut_rotate_table_gen(rotate_angle, hvkt);
|
||||
lut_hvk_ops.lut_m_v_gen(hvkt);
|
||||
|
||||
dev->input->dst.dst_flip = hvkt->flip_type;
|
||||
load_cfg_parameter(dev);
|
||||
load_y_stepy(dev);
|
||||
gama_fliter_set(dev);
|
||||
gama_asw_cfg(dev);
|
||||
}
|
||||
|
||||
static void asw_bilinear_rotation(struct asw_dev *dev, double rotate_angle,
|
||||
struct hvkt_param *hvkt)
|
||||
{
|
||||
lb_component_ba_calc(dev);
|
||||
gama_asw_set_hwmode(dev);
|
||||
|
||||
hvkt->lut_addr = (int)tblut_ext;
|
||||
hvkt->lut_real_addr[0] = dev->input->ext.ext_mlut_rx_ba;
|
||||
hvkt->lut_real_addr[1] = dev->input->ext.ext_mlut_ry_ba;
|
||||
hvkt->lut_real_addr[2] = dev->input->ext.ext_mlut_gx_ba;
|
||||
hvkt->lut_real_addr[3] = dev->input->ext.ext_mlut_gy_ba;
|
||||
hvkt->lut_real_addr[4] = dev->input->ext.ext_mlut_bx_ba;
|
||||
hvkt->lut_real_addr[5] = dev->input->ext.ext_mlut_by_ba;
|
||||
hvkt->lut_h_step =
|
||||
(dev->input->dst.dst_hsize + (dev->input->lut.asw_lut_hsize - 2)) /
|
||||
(dev->input->lut.asw_lut_hsize - 1);
|
||||
hvkt->lut_v_step =
|
||||
(dev->input->dst.dst_vsize + (dev->input->lut.asw_lut_vsize - 2)) /
|
||||
(dev->input->lut.asw_lut_vsize - 1);
|
||||
lut_hvk_ops.lut_rotate_table_gen(rotate_angle, hvkt);
|
||||
|
||||
dev->input->dst.dst_flip = hvkt->flip_type;
|
||||
gama_fliter_set(dev);
|
||||
gama_asw_cfg(dev);
|
||||
}
|
||||
|
||||
struct asw_operations sdrv_asw_ops = {
|
||||
.soft_reset = asw_soft_reset,
|
||||
.cubic_cfg = asw_cubic,
|
||||
.cubic_cfg_with_hvkt = asw_cubic_with_hvkt,
|
||||
.cubic_rotation = asw_cubic_rotation,
|
||||
.bilinear_cfg = asw_bilinear,
|
||||
.bilinear_cfg_with_hvkt = asw_bilinear_with_hvkt,
|
||||
.bilinear_rotation = asw_bilinear_rotation,
|
||||
.irq_handler = asw_irq_handler,
|
||||
};
|
||||
426
drivers/source/asw/sdrv_asw_lut_hvk.c
Normal file
426
drivers/source/asw/sdrv_asw_lut_hvk.c
Normal file
@@ -0,0 +1,426 @@
|
||||
/**
|
||||
* @file sdrv_asw_lut_hvk.c
|
||||
* @brief sdrv asw driver source.
|
||||
*
|
||||
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <armv7-r/cache.h>
|
||||
#include <asw/asw_log.h>
|
||||
#include <asw/asw_lut_hvk.h>
|
||||
#include <debug.h>
|
||||
#include <math.h>
|
||||
#include <reg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LUT_SIZE_MAX 1024
|
||||
float TEMPAA[LUT_SIZE_MAX] = {0};
|
||||
float TEMPAB[LUT_SIZE_MAX] = {0};
|
||||
|
||||
static int m_parameter_calc_alpha(int lut_size, float *alpha)
|
||||
{
|
||||
for (int i = 0; i < lut_size; i++) {
|
||||
if ((i < 2) || (i >= (lut_size - 2)))
|
||||
alpha[i] = 1.0;
|
||||
else if (i == 2)
|
||||
alpha[i] = 0.25;
|
||||
else
|
||||
alpha[i] = 1.0 / (4.0 - alpha[i - 1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m_parameter_calc_1d(float *lut_ld, float *m_param_ld, float *alpha,
|
||||
int lut_size, bool is_rt1)
|
||||
{
|
||||
float *delta = TEMPAA;
|
||||
float *beta = TEMPAB;
|
||||
float c_one_third = 1.0 / 3.0;
|
||||
float c_one_sixth = 1.0 / 6.0;
|
||||
|
||||
for (int i = 0; i < lut_size; i++) {
|
||||
if ((i == 0) || (i == (lut_size - 1))) {
|
||||
delta[i] = 0.0;
|
||||
} else {
|
||||
if (!is_rt1) {
|
||||
delta[i] =
|
||||
6.0 * (lut_ld[i + 1] + lut_ld[i - 1] - 2.0 * lut_ld[i]);
|
||||
} else {
|
||||
delta[i] = lut_ld[i + 1] + lut_ld[i - 1];
|
||||
delta[i] = fma(-2.0, lut_ld[i], delta[i]);
|
||||
delta[i] = 6.0 * delta[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < lut_size; i++) {
|
||||
if (i == 0) {
|
||||
beta[i] = delta[1] * c_one_third;
|
||||
} else if (i == 1) {
|
||||
beta[i] = delta[1] * c_one_sixth;
|
||||
} else if (i == (lut_size - 2)) {
|
||||
beta[i] = delta[lut_size - 2] * c_one_sixth;
|
||||
} else if (i == (lut_size - 1)) {
|
||||
beta[i] = delta[lut_size - 2] * c_one_third;
|
||||
} else {
|
||||
if (!is_rt1) {
|
||||
beta[i] = (delta[i] - beta[i - 1]) * alpha[i];
|
||||
} else {
|
||||
beta[i] = delta[i] * alpha[i];
|
||||
beta[i] = fma(-beta[i - 1], alpha[i], beta[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = lut_size - 2; i >= 0; i--) {
|
||||
if (i == 0) {
|
||||
m_param_ld[i] = beta[i] - m_param_ld[i + 2];
|
||||
} else if (i == 1) {
|
||||
m_param_ld[i] = beta[i];
|
||||
} else if (i == (lut_size - 2)) {
|
||||
m_param_ld[i] = beta[i];
|
||||
} else {
|
||||
if (!is_rt1) {
|
||||
m_param_ld[i] = beta[i] - m_param_ld[i + 1] * alpha[i];
|
||||
} else {
|
||||
m_param_ld[i] = fma(-m_param_ld[i + 1], alpha[i], beta[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_param_ld[lut_size - 1] = beta[lut_size - 1] - m_param_ld[lut_size - 3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static float hvk_pos_calc(float x, float y, struct hvkt_param *hvkt,
|
||||
bool calc_x, int c_sel)
|
||||
{
|
||||
float pa, pb, pc, pd, pe, pf;
|
||||
float x_mag, y_mag;
|
||||
|
||||
struct hvkt_fabc *fabc = hvkt->fabc;
|
||||
|
||||
pa = fabc->fc0[c_sel] * x - fabc->fa0[c_sel];
|
||||
pb = fabc->fc1[c_sel] * x - fabc->fa1[c_sel];
|
||||
pc = fabc->fa2[c_sel] - fabc->fc2[c_sel] * x;
|
||||
|
||||
pd = fabc->fc0[c_sel] * y - fabc->fb0[c_sel];
|
||||
pe = fabc->fc1[c_sel] * y - fabc->fb1[c_sel];
|
||||
pf = fabc->fb2[c_sel] - fabc->fc2[c_sel] * y;
|
||||
|
||||
if (calc_x) {
|
||||
if (hvkt->fw_map)
|
||||
x_mag = (fabc->fa0[c_sel] * x + fabc->fa1[c_sel] * y +
|
||||
fabc->fa2[c_sel]) /
|
||||
(fabc->fc0[c_sel] * x + fabc->fc1[c_sel] * y +
|
||||
fabc->fc2[c_sel]);
|
||||
else
|
||||
x_mag = (pc * pe - pb * pf) / (pa * pe - pb * pd);
|
||||
|
||||
return x_mag * (float)(hvkt->hsize_in - 1) / (float)(hvkt->hsize - 1);
|
||||
} else {
|
||||
if (hvkt->fw_map)
|
||||
y_mag = (fabc->fb0[c_sel] * x + fabc->fb1[c_sel] * y +
|
||||
fabc->fb2[c_sel]) /
|
||||
(fabc->fc0[c_sel] * x + fabc->fc1[c_sel] * y +
|
||||
fabc->fc2[c_sel]);
|
||||
else
|
||||
y_mag = (pa * pf - pc * pd) / (pa * pe - pb * pd);
|
||||
|
||||
return y_mag * (float)(hvkt->vsize_in - 1) / (float)(hvkt->vsize - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int hvk_table_gen(struct hvkt_param *hvkt)
|
||||
{
|
||||
float delta_x0, delta_y0;
|
||||
float delta_x1, delta_y1;
|
||||
float sum_x, sum_y;
|
||||
float poly0, poly1;
|
||||
|
||||
float a0, a1, a2;
|
||||
float b0, b1, b2;
|
||||
float c0, c1, c2;
|
||||
|
||||
int lut_hsize, lut_vsize;
|
||||
float n, m;
|
||||
int extend;
|
||||
int chn;
|
||||
float *lut;
|
||||
int *lut_32[6];
|
||||
short *lut_16[6];
|
||||
|
||||
struct hvkt_fabc fabc = {0};
|
||||
|
||||
hvkt->fabc = &fabc;
|
||||
lut_hsize = hvkt->lut_h_size;
|
||||
lut_vsize = hvkt->lut_v_size;
|
||||
|
||||
lut = (float *)hvkt->lut_addr;
|
||||
|
||||
chn = hvkt->chn;
|
||||
for (int i = 0; i < chn; i++) {
|
||||
delta_x0 = hvkt->top_right_x[i] - hvkt->bottom_right_x[i];
|
||||
delta_y0 = hvkt->top_right_y[i] - hvkt->bottom_right_y[i];
|
||||
delta_x1 = hvkt->bottom_left_x[i] - hvkt->bottom_right_x[i];
|
||||
delta_y1 = hvkt->bottom_left_y[i] - hvkt->bottom_right_y[i];
|
||||
|
||||
sum_x = hvkt->top_left_x[i] - hvkt->top_right_x[i] +
|
||||
hvkt->bottom_right_x[i] - hvkt->bottom_left_x[i];
|
||||
sum_y = hvkt->top_left_y[i] - hvkt->top_right_y[i] +
|
||||
hvkt->bottom_right_y[i] - hvkt->bottom_left_y[i];
|
||||
|
||||
poly0 = (sum_x * delta_y1 - sum_y * delta_x1);
|
||||
poly0 = poly0 / (delta_x0 * delta_y1 - delta_x1 * delta_y0);
|
||||
poly1 = (sum_y * delta_x0 - sum_x * delta_y0) /
|
||||
(delta_x0 * delta_y1 - delta_x1 * delta_y0);
|
||||
|
||||
a0 = ((hvkt->top_right_x[i] - hvkt->top_left_x[i]) +
|
||||
poly0 * hvkt->top_right_x[i]) /
|
||||
(hvkt->hsize - 1);
|
||||
a1 = ((hvkt->bottom_left_x[i] - hvkt->top_left_x[i]) +
|
||||
poly1 * hvkt->bottom_left_x[i]) /
|
||||
(hvkt->vsize - 1);
|
||||
a2 = hvkt->top_left_x[i];
|
||||
|
||||
b0 = ((hvkt->top_right_y[i] - hvkt->top_left_y[i]) +
|
||||
poly0 * hvkt->top_right_y[i]) /
|
||||
(hvkt->hsize - 1);
|
||||
b1 = ((hvkt->bottom_left_y[i] - hvkt->top_left_y[i]) +
|
||||
poly1 * hvkt->bottom_left_y[i]) /
|
||||
(hvkt->vsize - 1);
|
||||
b2 = hvkt->top_left_y[i];
|
||||
|
||||
c0 = poly0 / (hvkt->hsize - 1);
|
||||
c1 = poly1 / (hvkt->vsize - 1);
|
||||
c2 = 1;
|
||||
|
||||
fabc.fa0[i] = a0;
|
||||
fabc.fa1[i] = a1;
|
||||
fabc.fa2[i] = a2;
|
||||
|
||||
fabc.fb0[i] = b0;
|
||||
fabc.fb1[i] = b1;
|
||||
fabc.fb2[i] = b2;
|
||||
|
||||
fabc.fc0[i] = c0;
|
||||
fabc.fc1[i] = c1;
|
||||
fabc.fc2[i] = c2;
|
||||
}
|
||||
|
||||
m = (float)hvkt->lut_h_step;
|
||||
n = (float)hvkt->lut_v_step;
|
||||
|
||||
if (!hvkt->is_external_lut) {
|
||||
extend = hvkt->extend;
|
||||
for (int v = -extend; v < lut_vsize - extend; v++) {
|
||||
for (int i = 0; i < chn; i++) {
|
||||
for (int h = -extend; h < lut_hsize - extend; h++) {
|
||||
float x = h * m;
|
||||
float y = v * n;
|
||||
int c_sel = i;
|
||||
|
||||
/*lut[v][i][0][h]*/
|
||||
int pos_x = (v + extend) * (lut_hsize * chn * 2) +
|
||||
i * (lut_hsize * 2) + (h + extend);
|
||||
/*lut[v][i][1][h]*/
|
||||
int pos_y = (v + extend) * (lut_hsize * chn * 2) +
|
||||
i * (lut_hsize * 2) + lut_hsize + (h + extend);
|
||||
// printf("pos_x=%d, pos_y=%d\n", pos_x, pos_y);
|
||||
lut[pos_x] = hvk_pos_calc(x, y, hvkt, true, c_sel); /*x*/
|
||||
lut[pos_y] = hvk_pos_calc(x, y, hvkt, false, c_sel); /*y*/
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /*bilinear*/
|
||||
for (int i = 0; i < 6; i++) {
|
||||
lut_32[i] = (int *)hvkt->lut_real_addr[i];
|
||||
lut_16[i] = (short *)hvkt->lut_real_addr[i];
|
||||
}
|
||||
for (int i = 0; i < chn; i++) {
|
||||
for (int v = 0; v < lut_vsize; v++) {
|
||||
for (int h = 0; h < lut_hsize; h++) {
|
||||
float x = h * m;
|
||||
float y = v * n;
|
||||
int c_sel = i;
|
||||
|
||||
lut[h] = hvk_pos_calc(x, y, hvkt, true, c_sel); /*x*/
|
||||
lut[lut_hsize + h] =
|
||||
hvk_pos_calc(x, y, hvkt, false, c_sel); /*y*/
|
||||
|
||||
if (hvkt->external_lut_format == 1) { /*32bits*/
|
||||
int tmp = (int)(lut[h] * 256);
|
||||
tmp = (tmp > 524287) ? 524287
|
||||
: (tmp < -524288) ? -524288 : tmp;
|
||||
lut_32[i * 2][v * lut_hsize + h] = tmp;
|
||||
|
||||
tmp = (int)(lut[lut_hsize + h] * 256);
|
||||
tmp = (tmp > 524287) ? 524287
|
||||
: (tmp < -524288) ? -524288 : tmp;
|
||||
lut_32[i * 2 + 1][v * lut_hsize + h] = tmp;
|
||||
} else {
|
||||
int tmp16 = (int)(lut[h] * 16);
|
||||
tmp16 = (tmp16 > 32767)
|
||||
? 32767
|
||||
: (tmp16 < -32768) ? -32768 : tmp16;
|
||||
lut_16[i * 2][v * lut_hsize + h] = (short)tmp16;
|
||||
|
||||
tmp16 = (int)(lut[lut_hsize + h] * 16);
|
||||
tmp16 = (tmp16 > 32767)
|
||||
? 32767
|
||||
: (tmp16 < -32768) ? -32768 : tmp16;
|
||||
lut_16[i * 2 + 1][v * lut_hsize + h] = (short)tmp16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (hvkt->external_lut_format == 1) /*32bits*/
|
||||
arch_clean_cache_range((int)lut_32[i],
|
||||
lut_hsize * lut_vsize * 4);
|
||||
else
|
||||
arch_clean_cache_range((int)lut_16[i],
|
||||
lut_hsize * lut_vsize * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m_v_parameter_calc(struct hvkt_param *hvkt)
|
||||
{
|
||||
int lut_hsize, lut_vsize;
|
||||
float *lut_ld = TEMPAA;
|
||||
float *m_param_ld = TEMPAB;
|
||||
float *lut = (float *)hvkt->lut_addr;
|
||||
float *m_v = (float *)hvkt->m_v_addr;
|
||||
float *alpha_addr = (float *)hvkt->alpha_addr;
|
||||
int chn = hvkt->chn;
|
||||
|
||||
lut_hsize = hvkt->lut_h_size;
|
||||
lut_vsize = hvkt->lut_v_size;
|
||||
|
||||
m_parameter_calc_alpha(lut_vsize, alpha_addr);
|
||||
|
||||
for (int h = 0; h < lut_hsize; h++) {
|
||||
for (int i = 0; i < chn; i++) {
|
||||
/*x*/
|
||||
for (int v = 0; v < lut_vsize; v++) {
|
||||
lut_ld[v] = lut[v * lut_hsize * chn * 2 + i * lut_hsize * 2 +
|
||||
h]; /*lut[v][i][0][h]*/
|
||||
}
|
||||
m_parameter_calc_1d(lut_ld, m_param_ld, alpha_addr, lut_vsize,
|
||||
false);
|
||||
|
||||
for (int v = 0; v < lut_vsize; v++) {
|
||||
/*m_v[i][v][0][h]*/
|
||||
m_v[v * lut_hsize * chn * 2 + i * lut_hsize * 2 + h] =
|
||||
m_param_ld[i];
|
||||
}
|
||||
|
||||
/*y*/
|
||||
for (int v = 0; v < lut_vsize; v++) {
|
||||
lut_ld[v] = lut[v * lut_hsize * chn * 2 + i * lut_hsize * 2 +
|
||||
lut_hsize + h]; /*lut[v][i][1][h]*/
|
||||
}
|
||||
m_parameter_calc_1d(lut_ld, m_param_ld, alpha_addr, lut_vsize,
|
||||
false);
|
||||
|
||||
for (int v = 0; v < lut_vsize; v++) {
|
||||
/*m_v[i][v][1][h]*/
|
||||
m_v[v * lut_hsize * chn * 2 + i * lut_hsize * 2 + lut_hsize +
|
||||
h] = m_param_ld[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double sinc(double phase)
|
||||
{
|
||||
if (fabs(phase) < 0.0001)
|
||||
return 1.0;
|
||||
else
|
||||
return sin(phase) / phase;
|
||||
}
|
||||
|
||||
static int rotation(double angle, struct hvkt_param *hvkt)
|
||||
{
|
||||
double r, theta, rot;
|
||||
double x, y;
|
||||
int transpose_en;
|
||||
double rotate_angle;
|
||||
|
||||
double PI = acos(-1);
|
||||
|
||||
rotate_angle = (angle * PI) / 180.0;
|
||||
x = (hvkt->hsize_in - 1.0) / 2.0;
|
||||
y = (hvkt->vsize_in - 1.0) / 2.0;
|
||||
theta = atan(y / x);
|
||||
r = sqrt(x * x + y * y);
|
||||
|
||||
if ((rotate_angle >= 0.0 && rotate_angle <= (PI / 4.0)) ||
|
||||
(rotate_angle > (PI * 7.0 / 4.0) && rotate_angle < (PI * 8.0 / 4.0))) {
|
||||
rot = rotate_angle;
|
||||
hvkt->flip_type = 0;
|
||||
transpose_en = 0;
|
||||
} else if (rotate_angle >= (3.0 * PI / 4.0) &&
|
||||
rotate_angle <= (5.0 * PI / 4.0)) {
|
||||
rot = rotate_angle - PI;
|
||||
hvkt->flip_type = 3;
|
||||
transpose_en = 0;
|
||||
} else if (rotate_angle > (PI / 4.0) && rotate_angle < (PI * 3.0 / 4.0)) {
|
||||
rot = PI / 2.0 - rotate_angle;
|
||||
hvkt->flip_type = 1;
|
||||
transpose_en = 1;
|
||||
} else if (rotate_angle > (PI * 5.0 / 4.0) &&
|
||||
rotate_angle < (PI * 7.0 / 4.0)) {
|
||||
rot = 6.0 * PI / 4.0 - rotate_angle;
|
||||
hvkt->flip_type = 2;
|
||||
transpose_en = 1;
|
||||
} else { /*illigal*/
|
||||
rot = rotate_angle;
|
||||
hvkt->flip_type = 0;
|
||||
transpose_en = 0;
|
||||
}
|
||||
|
||||
rot = -rot;
|
||||
|
||||
hvkt->top_left_x[0] = cos(1.0 * PI + theta - rot) * r + x;
|
||||
hvkt->top_left_y[0] = sin(1.0 * PI + theta - rot) * r + y;
|
||||
|
||||
hvkt->top_right_x[0] = cos(-theta - rot) * r + x;
|
||||
hvkt->top_right_y[0] = sin(-theta - rot) * r + y;
|
||||
|
||||
hvkt->bottom_left_x[0] = cos(PI - theta - rot) * r + x;
|
||||
hvkt->bottom_left_y[0] = sin(PI - theta - rot) * r + y;
|
||||
|
||||
hvkt->bottom_right_x[0] = cos(theta - rot) * r + x;
|
||||
hvkt->bottom_right_y[0] = sin(theta - rot) * r + y;
|
||||
ASW_LOG_DEBUG("top-left(%f, %f), top-right(%f, %f), bottom-left(%f, %f), "
|
||||
"bottom-right(%f, %f)",
|
||||
hvkt->top_left_x[0], hvkt->top_left_y[0],
|
||||
hvkt->top_right_x[0], hvkt->top_right_y[0],
|
||||
hvkt->bottom_left_x[0], hvkt->bottom_left_y[0],
|
||||
hvkt->bottom_right_x[0], hvkt->bottom_right_y[0]);
|
||||
|
||||
return transpose_en;
|
||||
}
|
||||
|
||||
static int rotate_lut_table_gen(double angle, struct hvkt_param *hvkt)
|
||||
{
|
||||
rotation(angle, hvkt);
|
||||
hvk_table_gen(hvkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sdrv_lut_hvk_ops lut_hvk_ops = {
|
||||
.lut_table_gen = hvk_table_gen,
|
||||
.lut_m_v_gen = m_v_parameter_calc,
|
||||
.lut_rotate_table_gen = rotate_lut_table_gen,
|
||||
};
|
||||
Reference in New Issue
Block a user