mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
gdc: add endian support [1/1]
PD#SWPL-116164 Problem: add endian support Solution: add this support Verify: t7 Change-Id: Id6934ccd7bbfb98dc95f157704f7763808f7373a Signed-off-by: Jian Cao <jian.cao@amlogic.com>
This commit is contained in:
committed by
gerrit autosubmit
parent
29655631ae
commit
2796ae1550
@@ -27,6 +27,8 @@
|
||||
#include <linux/kasan.h>
|
||||
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#include <api/gdc_api.h>
|
||||
#include "system_log.h"
|
||||
|
||||
@@ -45,6 +47,12 @@
|
||||
//#define DEBUG
|
||||
|
||||
int gdc_log_level;
|
||||
int gdc_debug_enable;
|
||||
int gdc_in_swap_endian;
|
||||
int gdc_out_swap_endian;
|
||||
int gdc_in_swap_64bit;
|
||||
int gdc_out_swap_64bit;
|
||||
|
||||
struct gdc_manager_s gdc_manager;
|
||||
static int kthread_created;
|
||||
static struct gdc_irq_handle_wq irq_handle_wq[CORE_NUM];
|
||||
@@ -1453,10 +1461,12 @@ int gdc_process_phys(struct gdc_context_s *context,
|
||||
}
|
||||
}
|
||||
|
||||
gdc_log(LOG_DEBUG, "input, format:%d, width:%d, height:%d y_stride:%d c_stride:%d\n",
|
||||
format, i_width, i_height, i_y_stride, i_c_stride);
|
||||
gdc_log(LOG_DEBUG, "output, format:%d, width:%d, height:%d y_stride:%d c_stride:%d\n",
|
||||
format, o_width, o_height, o_y_stride, o_c_stride);
|
||||
gdc_log(LOG_DEBUG,
|
||||
"input, format:%d, width:%d, height:%d y_stride:%d c_stride:%d endian:0x%x\n",
|
||||
format, i_width, i_height, i_y_stride, i_c_stride, gs->in_endian);
|
||||
gdc_log(LOG_DEBUG,
|
||||
"output, format:%d, width:%d, height:%d y_stride:%d c_stride:%d endian:0x%x\n",
|
||||
format, o_width, o_height, o_y_stride, o_c_stride, gs->out_endian);
|
||||
|
||||
gdc_cmd->gdc_config.format = format;
|
||||
gdc_cmd->gdc_config.input_width = i_width;
|
||||
@@ -1471,6 +1481,8 @@ int gdc_process_phys(struct gdc_context_s *context,
|
||||
gdc_cmd->gdc_config.config_size = gs->config_size;
|
||||
gdc_cmd->outplane = gs->out_plane_num;
|
||||
gdc_cmd->use_sec_mem = gs->use_sec_mem;
|
||||
gdc_cmd->in_endian = gs->in_endian;
|
||||
gdc_cmd->out_endian = gs->out_endian;
|
||||
|
||||
/* set config_paddr MSB val */
|
||||
context->dma_cfg.config_cfg.paddr_8g_msb = (u64)gs->config_paddr >> 32;
|
||||
@@ -1924,6 +1936,45 @@ static const struct file_operations meson_gdc_fops = {
|
||||
.mmap = meson_gdc_mmap,
|
||||
};
|
||||
|
||||
static int parse_para(const char *para, int para_num, int *result)
|
||||
{
|
||||
char *token = NULL;
|
||||
char *params, *params_base;
|
||||
int *out = result;
|
||||
int len = 0, count = 0;
|
||||
int res = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!para)
|
||||
return 0;
|
||||
|
||||
params = kstrdup(para, GFP_KERNEL);
|
||||
params_base = params;
|
||||
token = params;
|
||||
if (!token)
|
||||
return 0;
|
||||
len = strlen(token);
|
||||
do {
|
||||
token = strsep(¶ms, " ");
|
||||
while (token && (isspace(*token) ||
|
||||
!isgraph(*token)) && len) {
|
||||
token++;
|
||||
len--;
|
||||
}
|
||||
if (len == 0 || !token)
|
||||
break;
|
||||
ret = kstrtoint(token, 0, &res);
|
||||
if (ret < 0)
|
||||
break;
|
||||
len = strlen(token);
|
||||
*out++ = res;
|
||||
count++;
|
||||
} while ((token) && (count < para_num) && (len > 0));
|
||||
|
||||
kfree(params_base);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t dump_reg_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@@ -2065,6 +2116,39 @@ static ssize_t config_out_path_store(struct device *dev,
|
||||
|
||||
static DEVICE_ATTR_RW(config_out_path);
|
||||
|
||||
static ssize_t debug_endian_show(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return snprintf(buf, 80, "%d %d %d %d %d\n",
|
||||
gdc_debug_enable,
|
||||
gdc_in_swap_endian,
|
||||
gdc_out_swap_endian,
|
||||
gdc_in_swap_64bit,
|
||||
gdc_out_swap_64bit);
|
||||
}
|
||||
|
||||
static ssize_t debug_endian_store(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int parsed[5];
|
||||
|
||||
if (likely(parse_para(buf, 5, parsed) == 5)) {
|
||||
gdc_debug_enable = parsed[0];
|
||||
gdc_in_swap_endian = parsed[1];
|
||||
gdc_out_swap_endian = parsed[2];
|
||||
gdc_in_swap_64bit = parsed[3];
|
||||
gdc_out_swap_64bit = parsed[4];
|
||||
} else {
|
||||
pr_err("wrong params\n");
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(debug_endian);
|
||||
|
||||
void irq_handle_func(struct work_struct *work)
|
||||
{
|
||||
struct gdc_irq_handle_wq *irq_handle_wq =
|
||||
@@ -2309,6 +2393,8 @@ static int gdc_platform_probe(struct platform_device *pdev)
|
||||
&dev_attr_trace_mode);
|
||||
device_create_file(gdc_dev->misc_dev.this_device,
|
||||
&dev_attr_config_out_path);
|
||||
device_create_file(gdc_dev->misc_dev.this_device,
|
||||
&dev_attr_debug_endian);
|
||||
|
||||
platform_set_drvdata(pdev, gdc_dev);
|
||||
dev_set_drvdata(gdc_dev->misc_dev.this_device, gdc_dev);
|
||||
|
||||
@@ -111,6 +111,12 @@ struct gdc_irq_data_s {
|
||||
|
||||
extern struct gdc_manager_s gdc_manager;
|
||||
|
||||
extern int gdc_debug_enable;
|
||||
extern int gdc_in_swap_endian;
|
||||
extern int gdc_out_swap_endian;
|
||||
extern int gdc_in_swap_64bit;
|
||||
extern int gdc_out_swap_64bit;
|
||||
|
||||
#define GDC_DEVICE(dev_type) ((dev_type) == ARM_GDC ? \
|
||||
&gdc_manager.gdc_dev->pdev->dev : \
|
||||
&gdc_manager.aml_gdc_dev->pdev->dev)
|
||||
@@ -142,6 +148,10 @@ extern struct gdc_manager_s gdc_manager;
|
||||
#define ISP_DWAP_TOP_DST_V_CTRL0 ((0x17 << 2) | ISP_DWAP_REG_MARK)
|
||||
#define ISP_DWAP_TOP_DST_V_CTRL1 ((0x18 << 2) | ISP_DWAP_REG_MARK)
|
||||
|
||||
#define ISP_DWAP_CMD_SWAP ((0x2b << 2) | ISP_DWAP_REG_MARK)
|
||||
#define ISP_DWAP_WMIF_CTRL1 ((0x40 << 2) | ISP_DWAP_REG_MARK)
|
||||
#define ISP_DWAP_RMIF_CTRL1 ((0x50 << 2) | ISP_DWAP_REG_MARK)
|
||||
|
||||
#define ISP_DWAP_GAMMA_CTRL ((0x60 << 2) | ISP_DWAP_REG_MARK)
|
||||
#define ISP_DWAP_GAMMA_OFST ((0x61 << 2) | ISP_DWAP_REG_MARK)
|
||||
#define ISP_DWAP_GAMMA_NUM ((0x62 << 2) | ISP_DWAP_REG_MARK)
|
||||
@@ -383,6 +393,54 @@ static inline u32 gdc_config_size_read(void)
|
||||
return system_gdc_read_32(0x14L, 0);
|
||||
}
|
||||
|
||||
// args: enable (1-swap endian 0-do not swap)
|
||||
static inline void gdc_datain_swap_endian_write(u32 enable, u32 core_id)
|
||||
{
|
||||
u32 curr = system_gdc_read_32(ISP_DWAP_CMD_SWAP, core_id);
|
||||
|
||||
curr &= ~(1 << 6);
|
||||
curr |= (enable << 6);
|
||||
system_gdc_write_32(ISP_DWAP_CMD_SWAP, curr, core_id);
|
||||
}
|
||||
|
||||
static inline void gdc_dataout_swap_endian_write(u32 enable, u32 core_id)
|
||||
{
|
||||
u32 curr = system_gdc_read_32(ISP_DWAP_WMIF_CTRL1, core_id);
|
||||
|
||||
curr &= ~(1 << 6);
|
||||
curr |= ((enable ? 0 : 1) << 6);
|
||||
system_gdc_write_32(ISP_DWAP_WMIF_CTRL1, curr, core_id);
|
||||
|
||||
curr = system_gdc_read_32(ISP_DWAP_CMD_SWAP, core_id);
|
||||
|
||||
curr &= ~(1 << 8);
|
||||
curr |= (enable << 8);
|
||||
system_gdc_write_32(ISP_DWAP_CMD_SWAP, curr, core_id);
|
||||
}
|
||||
|
||||
// args: enable (1-swap 64bit of 128bit 0-do not swap)
|
||||
static inline void gdc_datain_swap_64bit_write(u32 enable, u32 core_id)
|
||||
{
|
||||
u32 curr = system_gdc_read_32(ISP_DWAP_RMIF_CTRL1, core_id);
|
||||
|
||||
curr &= ~(1 << 7);
|
||||
curr |= (enable << 7);
|
||||
|
||||
/* for coef and mesh, in case of swap_64bit */
|
||||
curr &= ~(1 << 6);
|
||||
curr |= ((enable ? 0 : 1) << 6);
|
||||
system_gdc_write_32(ISP_DWAP_RMIF_CTRL1, curr, core_id);
|
||||
}
|
||||
|
||||
static inline void gdc_dataout_swap_64bit_write(u32 enable, u32 core_id)
|
||||
{
|
||||
u32 curr = system_gdc_read_32(ISP_DWAP_WMIF_CTRL1, core_id);
|
||||
|
||||
curr &= ~(1 << 7);
|
||||
curr |= (enable << 7);
|
||||
system_gdc_write_32(ISP_DWAP_WMIF_CTRL1, curr, core_id);
|
||||
}
|
||||
|
||||
// ----------------------------------- //
|
||||
// Register: datain width
|
||||
// ----------------------------------- //
|
||||
|
||||
@@ -96,6 +96,106 @@ void gdc_stop(struct gdc_cmd_s *gdc_cmd, u32 core_id)
|
||||
* @param gdc_cmd - overall gdc settings and state
|
||||
*
|
||||
*/
|
||||
|
||||
static void gdc_endian_config(struct gdc_cmd_s *gdc_cmd, u32 core_id)
|
||||
{
|
||||
u32 dev_type = gdc_cmd->dev_type;
|
||||
|
||||
if (dev_type == ARM_GDC)
|
||||
return;
|
||||
|
||||
if (gdc_debug_enable) {
|
||||
gdc_datain_swap_64bit_write(gdc_in_swap_64bit, core_id);
|
||||
gdc_dataout_swap_64bit_write(gdc_out_swap_64bit, core_id);
|
||||
|
||||
gdc_datain_swap_endian_write(gdc_in_swap_endian, core_id);
|
||||
gdc_dataout_swap_endian_write(gdc_out_swap_endian, core_id);
|
||||
} else {
|
||||
u32 in_swap_64bit = 0, out_swap_64bit = 0;
|
||||
u32 in_swap_endian = 0, out_swap_endian = 0;
|
||||
u32 in_endian = gdc_cmd->in_endian;
|
||||
u32 out_endian = gdc_cmd->out_endian;
|
||||
|
||||
if (in_endian == GDC_ENDIAN_LITTLE) {
|
||||
switch (out_endian) {
|
||||
case GDC_ENDIAN_LITTLE:
|
||||
in_swap_64bit = 0;
|
||||
out_swap_64bit = 0;
|
||||
in_swap_endian = 0;
|
||||
out_swap_endian = 0;
|
||||
break;
|
||||
case GDC_ENDIAN_BIG_8BYTES:
|
||||
in_swap_64bit = 0;
|
||||
out_swap_64bit = 1;
|
||||
in_swap_endian = 0;
|
||||
out_swap_endian = 1;
|
||||
break;
|
||||
case GDC_ENDIAN_BIG_16BYTES:
|
||||
in_swap_64bit = 0;
|
||||
out_swap_64bit = 0;
|
||||
in_swap_endian = 0;
|
||||
out_swap_endian = 1;
|
||||
break;
|
||||
}
|
||||
} else if (in_endian == GDC_ENDIAN_BIG_8BYTES) {
|
||||
switch (out_endian) {
|
||||
case GDC_ENDIAN_LITTLE:
|
||||
in_swap_64bit = 1;
|
||||
out_swap_64bit = 0;
|
||||
in_swap_endian = 1;
|
||||
out_swap_endian = 0;
|
||||
break;
|
||||
case GDC_ENDIAN_BIG_8BYTES:
|
||||
in_swap_64bit = 1;
|
||||
out_swap_64bit = 1;
|
||||
in_swap_endian = 1;
|
||||
out_swap_endian = 1;
|
||||
break;
|
||||
case GDC_ENDIAN_BIG_16BYTES:
|
||||
in_swap_64bit = 1;
|
||||
out_swap_64bit = 0;
|
||||
in_swap_endian = 1;
|
||||
out_swap_endian = 1;
|
||||
break;
|
||||
}
|
||||
} else if (in_endian == GDC_ENDIAN_BIG_16BYTES) {
|
||||
switch (out_endian) {
|
||||
case GDC_ENDIAN_LITTLE:
|
||||
in_swap_64bit = 0;
|
||||
out_swap_64bit = 0;
|
||||
in_swap_endian = 1;
|
||||
out_swap_endian = 0;
|
||||
break;
|
||||
case GDC_ENDIAN_BIG_8BYTES:
|
||||
in_swap_64bit = 0;
|
||||
out_swap_64bit = 1;
|
||||
in_swap_endian = 1;
|
||||
out_swap_endian = 1;
|
||||
break;
|
||||
case GDC_ENDIAN_BIG_16BYTES:
|
||||
in_swap_64bit = 0;
|
||||
out_swap_64bit = 0;
|
||||
in_swap_endian = 1;
|
||||
out_swap_endian = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gdc_datain_swap_64bit_write(in_swap_64bit, core_id);
|
||||
gdc_dataout_swap_64bit_write(out_swap_64bit, core_id);
|
||||
gdc_datain_swap_endian_write(in_swap_endian, core_id);
|
||||
gdc_dataout_swap_endian_write(out_swap_endian, core_id);
|
||||
|
||||
gdc_log(LOG_DEBUG, "in_endian:%d, out_endian:%d",
|
||||
in_endian, out_endian);
|
||||
|
||||
gdc_log(LOG_DEBUG,
|
||||
"in_swap_64bit:%d out_swap_64_bit:%d in_swap_endian:%d, out_swap_endian:%d",
|
||||
in_swap_64bit, out_swap_64bit,
|
||||
in_swap_endian, out_swap_endian);
|
||||
}
|
||||
}
|
||||
|
||||
void gdc_start(struct gdc_cmd_s *gdc_cmd, u32 core_id)
|
||||
{
|
||||
/* do a stop for sync */
|
||||
@@ -213,6 +313,7 @@ int gdc_process(struct gdc_cmd_s *gdc_cmd,
|
||||
if (GDC_DEV_T(dev_type)->ext_msb_8g)
|
||||
set_ext_8g_msb(dma_cfg, 2);
|
||||
|
||||
gdc_endian_config(gdc_cmd, core_id);
|
||||
gdc_start(gdc_cmd, core_id);
|
||||
|
||||
return 0;
|
||||
@@ -308,6 +409,7 @@ int gdc_process_yuv420p(struct gdc_cmd_s *gdc_cmd,
|
||||
if (GDC_DEV_T(dev_type)->ext_msb_8g)
|
||||
set_ext_8g_msb(dma_cfg, 3);
|
||||
|
||||
gdc_endian_config(gdc_cmd, core_id);
|
||||
gdc_start(gdc_cmd, core_id);
|
||||
|
||||
return 0;
|
||||
@@ -365,6 +467,7 @@ int gdc_process_y_grey(struct gdc_cmd_s *gdc_cmd,
|
||||
if (GDC_DEV_T(dev_type)->ext_msb_8g)
|
||||
set_ext_8g_msb(dma_cfg, 1);
|
||||
|
||||
gdc_endian_config(gdc_cmd, core_id);
|
||||
gdc_start(gdc_cmd, core_id);
|
||||
|
||||
return 0;
|
||||
@@ -454,6 +557,7 @@ int gdc_process_yuv444p(struct gdc_cmd_s *gdc_cmd,
|
||||
if (GDC_DEV_T(dev_type)->ext_msb_8g)
|
||||
set_ext_8g_msb(dma_cfg, 3);
|
||||
|
||||
gdc_endian_config(gdc_cmd, core_id);
|
||||
gdc_start(gdc_cmd, core_id);
|
||||
|
||||
return 0;
|
||||
@@ -545,6 +649,7 @@ int gdc_process_rgb444p(struct gdc_cmd_s *gdc_cmd,
|
||||
if (GDC_DEV_T(dev_type)->ext_msb_8g)
|
||||
set_ext_8g_msb(dma_cfg, 3);
|
||||
|
||||
gdc_endian_config(gdc_cmd, core_id);
|
||||
gdc_start(gdc_cmd, core_id);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -30,6 +30,13 @@ enum {
|
||||
GDC_MAX_FW
|
||||
};
|
||||
|
||||
enum {
|
||||
GDC_ENDAIN_DEFAULT = 0, /* no endian operation */
|
||||
GDC_ENDIAN_LITTLE = BIT(0),
|
||||
GDC_ENDIAN_BIG_8BYTES = BIT(1),
|
||||
GDC_ENDIAN_BIG_16BYTES = BIT(2)
|
||||
};
|
||||
|
||||
struct aml_dma_cfg {
|
||||
int fd;
|
||||
void *dev;
|
||||
@@ -112,6 +119,9 @@ struct gdc_cmd_s {
|
||||
u32 dev_type;
|
||||
/* secure mem access */
|
||||
u32 use_sec_mem;
|
||||
/* endian setting */
|
||||
u32 in_endian;
|
||||
u32 out_endian;
|
||||
};
|
||||
|
||||
struct gdc_context_s {
|
||||
@@ -186,6 +196,8 @@ struct gdc_phy_setting {
|
||||
ulong config_paddr;
|
||||
u32 config_size; /* in 32bit */
|
||||
u32 use_sec_mem; /* secure mem access */
|
||||
u32 in_endian;
|
||||
u32 out_endian;
|
||||
};
|
||||
|
||||
struct firmware_load_s {
|
||||
|
||||
Reference in New Issue
Block a user