GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1 @@
|
||||
source "product/driver/Kconfig"
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
obj-y += main/
|
||||
obj-y += update/
|
||||
obj-y += driver/
|
||||
@@ -0,0 +1,19 @@
|
||||
menu "Product driver set"
|
||||
|
||||
config CMD_VO_DRIVER
|
||||
bool "Support VO driver"
|
||||
default n
|
||||
|
||||
config MIPI_LCD_SUPPORT
|
||||
bool "Support MIPI screen parameter set"
|
||||
depends on CMD_VO_DRIVER
|
||||
default n
|
||||
|
||||
config MCU_LCD_SUPPORT
|
||||
bool "Support MCU screen parameter set"
|
||||
depends on CMD_VO_DRIVER
|
||||
default n
|
||||
|
||||
endmenu
|
||||
|
||||
source "product/driver/ssp/Kconfig"
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
obj-y += cipher/
|
||||
obj-$(CONFIG_CMD_VO_DRIVER) += vo/
|
||||
obj-y += ssp/
|
||||
@@ -0,0 +1,6 @@
|
||||
ccflags-y += -I$(srctree)/product/driver/include
|
||||
|
||||
obj-y += xmedia_cipher.o
|
||||
obj-y += xmedia_rsa.o
|
||||
obj-y += xmedia_cipher_drv.o
|
||||
obj-y += xmedia_cipher_klad.o
|
||||
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "xmedia_cipher_osal.h"
|
||||
#define SHA256_H0 0x6a09e667
|
||||
#define SHA256_H1 0xbb67ae85
|
||||
#define SHA256_H2 0x3c6ef372
|
||||
#define SHA256_H3 0xa54ff53a
|
||||
#define SHA256_H4 0x510e527f
|
||||
#define SHA256_H5 0x9b05688c
|
||||
#define SHA256_H6 0x1f83d9ab
|
||||
#define SHA256_H7 0x5be0cd19
|
||||
|
||||
typedef struct {
|
||||
xmedia_u8 block_size;
|
||||
xmedia_u8 sha_len;
|
||||
xmedia_u8 last_block_size;
|
||||
xmedia_u8 reserve;
|
||||
xmedia_u32 total_data_len;
|
||||
xmedia_u32 sha_val[SHA256_RESULT_IN_WORD];
|
||||
xmedia_u8 last_block[SHA256_PADDING_MAX_SIZE];
|
||||
} hash_info_s;
|
||||
|
||||
static hash_info_s* g_cipher_hash_data = XMEDIA_NULL;
|
||||
static xmedia_s32 g_cipher_init_flag = 0;
|
||||
|
||||
static xmedia_u32 hash_msg_padding(xmedia_u8 *msg, xmedia_u32 byte_len, xmedia_u32 total_len, xmedia_u32 block_size)
|
||||
{
|
||||
xmedia_u32 tmp;
|
||||
xmedia_u32 padding_len;
|
||||
|
||||
if (block_size == 0) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
tmp = total_len % block_size;
|
||||
|
||||
padding_len = (tmp < 56) ? (56 - tmp) : (120 - tmp); /* 56, 120 */
|
||||
padding_len += 8; /* 8 padding len */
|
||||
|
||||
/* Format(binary): {data|1000...00| fix_data_len(bits)} */
|
||||
msg[byte_len++] = 0x80;
|
||||
crypto_memset(&msg[byte_len], SHA256_PADDING_MAX_SIZE, 0, padding_len - 1 - 8); /* 2, 8 */
|
||||
byte_len += padding_len - 1 - 8; /* 8 */
|
||||
|
||||
/* write 8 bytes fix data length */
|
||||
msg[byte_len++] = 0x00;
|
||||
msg[byte_len++] = 0x00;
|
||||
msg[byte_len++] = 0x00;
|
||||
msg[byte_len++] = (xmedia_u8)((total_len >> 29) & 0x07); /* 29 right shift */
|
||||
msg[byte_len++] = (xmedia_u8)((total_len >> 21) & 0xff); /* 21 right shift */
|
||||
msg[byte_len++] = (xmedia_u8)((total_len >> 13) & 0xff); /* 13 right shift */
|
||||
msg[byte_len++] = (xmedia_u8)((total_len >> 5) & 0xff); /* 5 right shift */
|
||||
msg[byte_len++] = (xmedia_u8)((total_len << 3) & 0xff); /* 3 right shift */
|
||||
|
||||
return byte_len;
|
||||
}
|
||||
|
||||
static xmedia_s32 cipher_hash_update_block(hash_info_s *hash_info, xmedia_u8 *input_data, xmedia_u32 input_data_len)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
cipher_hash_data_s hash_data;
|
||||
|
||||
crypto_memset(&hash_data, sizeof(cipher_hash_data_s), 0, sizeof(cipher_hash_data_s));
|
||||
hash_data.hard_chn = SPACC_CHN_SHA256;
|
||||
crypto_memcpy(hash_data.sha_val, sizeof(hash_data.sha_val), hash_info->sha_val, sizeof(hash_info->sha_val));
|
||||
|
||||
hash_data.data_len = input_data_len;
|
||||
hash_data.data_phy = get_ulong_low(input_data);
|
||||
hash_data.data_phy_high = get_ulong_high(input_data);
|
||||
ret = drv_cipher_sha256_update(&hash_data);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
crypto_memcpy(hash_info->sha_val, sizeof(hash_info->sha_val), hash_data.sha_val, sizeof(hash_data.sha_val));
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 cipher_hash_updata_tail(hash_info_s *hash_info,
|
||||
xmedia_u8 *data_phy, xmedia_u8 *input_data, xmedia_u32 input_data_len)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
|
||||
/* process the tail of last update */
|
||||
if (hash_info->last_block_size > 0) {
|
||||
crypto_memcpy(hash_info->last_block + hash_info->last_block_size,
|
||||
SHA256_PADDING_MAX_SIZE - hash_info->last_block_size,
|
||||
input_data,
|
||||
hash_info->block_size - hash_info->last_block_size);
|
||||
crypto_memcpy(data_phy, SHA256_BLOCK_SIZE, hash_info->last_block, hash_info->block_size);
|
||||
ret = cipher_hash_update_block(hash_info, data_phy, hash_info->block_size);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
input_data_len -= hash_info->block_size - hash_info->last_block_size;
|
||||
input_data += hash_info->block_size - hash_info->last_block_size;
|
||||
}
|
||||
|
||||
if (input_data_len >= hash_info->block_size) {
|
||||
xmedia_u32 size;
|
||||
size = input_data_len - (input_data_len % hash_info->block_size);
|
||||
ret = cipher_hash_update_block(hash_info, input_data, size);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
input_data_len -= size;
|
||||
input_data += size;
|
||||
}
|
||||
|
||||
/* save tail data */
|
||||
crypto_memset(hash_info->last_block, SHA256_PADDING_MAX_SIZE, 0, SHA256_PADDING_MAX_SIZE);
|
||||
hash_info->last_block_size = input_data_len;
|
||||
crypto_memcpy(hash_info->last_block, SHA256_PADDING_MAX_SIZE, input_data, input_data_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_deinit()
|
||||
{
|
||||
if (g_cipher_hash_data != XMEDIA_NULL) {
|
||||
cipher_free(g_cipher_hash_data);
|
||||
g_cipher_hash_data = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_cipher_init_flag == 0) {
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
if (drv_cipher_deinit() != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
} else {
|
||||
g_cipher_init_flag = 0;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_aes256(cipher_ctrl *ctrl, xmedia_bool is_encrypt, xmedia_size_t src_phy_addr,
|
||||
xmedia_size_t dest_phy_addr, xmedia_u32 byte_len)
|
||||
{
|
||||
cipher_data_s ci_data;
|
||||
xmedia_s32 ret;
|
||||
|
||||
if (g_cipher_init_flag == 0) {
|
||||
if (drv_cipher_init() != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_INIT);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
g_cipher_init_flag = 1;
|
||||
}
|
||||
|
||||
ret = drv_cipher_config_aes_chn(ctrl, is_encrypt);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_CONFIG_CHAN);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ci_data.src_phy_addr = get_ulong_low(src_phy_addr);
|
||||
ci_data.src_phy_addr_high = get_ulong_high(src_phy_addr);
|
||||
ci_data.dest_phy_addr = get_ulong_low(dest_phy_addr);
|
||||
ci_data.dest_phy_addr_high = get_ulong_high(dest_phy_addr);
|
||||
ci_data.data_length = byte_len;
|
||||
|
||||
ret = drv_cipher_aes(&ci_data);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_DECRYPT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_aes256_encrypt(cipher_ctrl *ctrl, xmedia_size_t src_phy_addr, xmedia_size_t dest_phy_addr, xmedia_u32 byte_len)
|
||||
{
|
||||
return xmedia_cipher_aes256(ctrl, XMEDIA_TRUE, src_phy_addr, dest_phy_addr, byte_len);
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_aes256_decrypt(cipher_ctrl *ctrl, xmedia_size_t src_phy_addr, xmedia_size_t dest_phy_addr, xmedia_u32 byte_len)
|
||||
{
|
||||
return xmedia_cipher_aes256(ctrl, XMEDIA_FALSE, src_phy_addr, dest_phy_addr, byte_len);
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_sha256_init()
|
||||
{
|
||||
if (g_cipher_init_flag == 0) {
|
||||
if (drv_cipher_init() != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_INIT);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
g_cipher_init_flag = 1;
|
||||
}
|
||||
|
||||
if (g_cipher_hash_data == XMEDIA_NULL) {
|
||||
/*sizeof(hash_info_s) = 0xA8*/
|
||||
g_cipher_hash_data = cipher_malloc(sizeof(hash_info_s));
|
||||
if (g_cipher_hash_data == XMEDIA_NULL) {
|
||||
cipher_debug_log(CIPHER_ERR_SHA256_MALLOC);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
crypto_memset(g_cipher_hash_data, sizeof(hash_info_s), 0, sizeof(hash_info_s));
|
||||
g_cipher_hash_data->block_size = SHA256_BLOCK_SIZE; /* 64 sha256 block size */
|
||||
g_cipher_hash_data->sha_len = SHA256_RESULT_SIZE;
|
||||
g_cipher_hash_data->sha_val[0] = cipher_cpu_to_be32(SHA256_H0); /* 0 sha256 index */
|
||||
g_cipher_hash_data->sha_val[1] = cipher_cpu_to_be32(SHA256_H1); /* 1 sha256 index */
|
||||
g_cipher_hash_data->sha_val[2] = cipher_cpu_to_be32(SHA256_H2); /* 2 sha256 index */
|
||||
g_cipher_hash_data->sha_val[3] = cipher_cpu_to_be32(SHA256_H3); /* 3 sha256 index */
|
||||
g_cipher_hash_data->sha_val[4] = cipher_cpu_to_be32(SHA256_H4); /* 4 sha256 index */
|
||||
g_cipher_hash_data->sha_val[5] = cipher_cpu_to_be32(SHA256_H5); /* 5 sha256 index */
|
||||
g_cipher_hash_data->sha_val[6] = cipher_cpu_to_be32(SHA256_H6); /* 6 sha256 index */
|
||||
g_cipher_hash_data->sha_val[7] = cipher_cpu_to_be32(SHA256_H7); /* 7 sha256 index */
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_sha256_update(xmedia_u8 *input_data, xmedia_u32 input_data_len)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
xmedia_u8 *data_phy = XMEDIA_NULL;
|
||||
hash_info_s *hash_info = g_cipher_hash_data;
|
||||
xmedia_u32 size;
|
||||
|
||||
if (input_data_len == 0)
|
||||
return XMEDIA_SUCCESS;
|
||||
|
||||
if (hash_info == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
data_phy = (xmedia_u8 *)cipher_malloc(SHA256_BLOCK_SIZE);
|
||||
if (data_phy == XMEDIA_NULL) {
|
||||
cipher_debug_log(CIPHER_ERR_SHA256_MALLOC);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
crypto_memset(data_phy, SHA256_BLOCK_SIZE, 0, SHA256_BLOCK_SIZE);
|
||||
|
||||
hash_info->total_data_len += input_data_len;
|
||||
size = hash_info->last_block_size + input_data_len;
|
||||
if (size < hash_info->block_size) {
|
||||
crypto_memcpy(hash_info->last_block + hash_info->last_block_size,
|
||||
(SHA256_PADDING_MAX_SIZE - hash_info->last_block_size), input_data, input_data_len);
|
||||
hash_info->last_block_size += input_data_len;
|
||||
goto free_data_phy;
|
||||
}
|
||||
|
||||
ret = cipher_hash_updata_tail(hash_info, data_phy, input_data, input_data_len);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_SHA256_UPDATE);
|
||||
}
|
||||
|
||||
free_data_phy:
|
||||
cipher_free(data_phy);
|
||||
data_phy = XMEDIA_NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_sha256_final(xmedia_u8 *output_hash)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
hash_info_s *hash_info = g_cipher_hash_data;
|
||||
cipher_hash_data_s hash_data;
|
||||
xmedia_u32 tmp;
|
||||
xmedia_u8 *data_phy = XMEDIA_NULL;
|
||||
|
||||
if (hash_info == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
data_phy = (xmedia_u8 *)cipher_malloc(SHA256_PADDING_MAX_SIZE);
|
||||
if (data_phy == XMEDIA_NULL) {
|
||||
cipher_debug_log(CIPHER_ERR_SHA256_MALLOC);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
crypto_memset(data_phy, SHA256_PADDING_MAX_SIZE, 0, SHA256_PADDING_MAX_SIZE);
|
||||
crypto_memset(&hash_data, sizeof(cipher_hash_data_s), 0, sizeof(cipher_hash_data_s));
|
||||
|
||||
tmp = hash_msg_padding(hash_info->last_block, hash_info->last_block_size, hash_info->total_data_len, hash_info->block_size);
|
||||
|
||||
crypto_memcpy(data_phy, SHA256_PADDING_MAX_SIZE, hash_info->last_block, tmp);
|
||||
|
||||
hash_data.data_len = tmp;
|
||||
hash_data.data_phy = get_ulong_low(data_phy);
|
||||
hash_data.data_phy_high = get_ulong_high(data_phy);
|
||||
crypto_memcpy(hash_data.sha_val, sizeof(hash_data.sha_val), hash_info->sha_val, sizeof(hash_info->sha_val));
|
||||
hash_data.hard_chn = SPACC_CHN_SHA256;
|
||||
|
||||
ret = drv_cipher_sha256_final(&hash_data);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_SHA256_FINAL);
|
||||
}
|
||||
crypto_memcpy(output_hash, SHA256_RESULT_SIZE, hash_data.sha_val, hash_info->sha_len);
|
||||
|
||||
cipher_free(data_phy);
|
||||
data_phy = XMEDIA_NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __XMDEDIA_CIPHER_CONFIG_H_
|
||||
#define __XMDEDIA_CIPHER_CONFIG_H_
|
||||
|
||||
#define CIPHER_CIPHER_REG_BASE_ADDR_PHY (0x10050000)
|
||||
#define CIPHER_RSA_REG_BASE_ADDR_PHY (0x10070000)
|
||||
|
||||
#define CIPHER_RSA_CRG_ADDR_PHY (0x120101A0)
|
||||
#define RSA_CRG_CLOCK_BIT (0x01 << 5)
|
||||
#define RSA_CRG_RESET_BIT (0x01 << 4)
|
||||
#define CIPHER_SPACC_CRG_ADDR_PHY (0x120101A0)
|
||||
#define SPACC_CRG_CLOCK_BIT (0x01 << 9)
|
||||
#define SPACC_CRG_RESET_BIT (0x01 << 8)
|
||||
|
||||
#define CIPHER_KLAD_REG_BASE_ADDR_PHY (0x10060000)
|
||||
#define CIPHER_OTP_REG_BASE_ADDR_PHY (0x100A0000)
|
||||
#define CIPHER_KLAD_CRG_ADDR_PHY (0x120101A0)
|
||||
|
||||
#define KLAD_CRG_CLOCK_BIT (0x01 << 1)
|
||||
#define KLAD_CRG_RESET_BIT (0x01 << 0)
|
||||
|
||||
|
||||
#define CIPHER_ERR_CIPHER_INIT 0x1
|
||||
#define CIPHER_ERR_CIPHER_CONFIG_CHAN 0x2
|
||||
#define CIPHER_ERR_CIPHER_DECRYPT 0x3
|
||||
#define CIPHER_ERR_CIPHER_ERRCODE_1 0x4
|
||||
#define CIPHER_ERR_CIPHER_ERRCODE_2 0x5
|
||||
#define CIPHER_ERR_CIPHER_ERRCODE_4 0x6
|
||||
#define CIPHER_ERR_CIPHER_CFG_OUTNODE 0x7
|
||||
#define CIPHER_ERR_CIPHER_WAIT_TIMEOUT 0x8
|
||||
#define CIPHER_ERR_CIPHER_MALLOC 0x9
|
||||
#define CIPHER_ERR_CIPHER_LOAD_KEY 0xA
|
||||
|
||||
#define CIPHER_ERR_SHA256_MALLOC 0x10
|
||||
#define CIPHER_ERR_SHA256_UPDATE 0x11
|
||||
#define CIPHER_ERR_SHA256_FINAL 0x12
|
||||
#define CIPHER_ERR_SHA256_START 0x13
|
||||
#define CIPHER_ERR_SHA256_WAIT_TIMEOUT 0x14
|
||||
|
||||
#define CIPHER_ERR_RSA_MALLOC 0x20
|
||||
#define CIPHER_ERR_RSA_KEY_LEN 0x21
|
||||
#define CIPHER_ERR_RSA_DEC 0x22
|
||||
#define CIPHER_ERR_RSA_CHECK_PADDING 0x23
|
||||
#define CIPHER_ERR_RSA_BUSY_TIMEOUT 0x24
|
||||
#define CIPHER_ERR_RSA_ERRORCODE 0x25
|
||||
#define CIPHER_ERR_RSA_M_ZERO 0x26
|
||||
#define CIPHER_ERR_RSA_M_LARGER_N 0x27
|
||||
#define CIPHER_ERR_RSA_E_EQUAL_1 0x28
|
||||
#define CIPHER_ERR_RSA_E_EQUAL_0 0x29
|
||||
#define CIPHER_ERR_RSA_SHA256 0x2A
|
||||
#define CIPHER_ERR_RSA_MGF1 0x2B
|
||||
#define CIPHER_ERR_RSA_VERIFY_HASH_CMP 0x2C
|
||||
#define CIPHER_ERR_RSA_VERIFY_M_LEN 0x2D
|
||||
#define CIPHER_ERR_RSA_VERIFY_EM0 0x2E
|
||||
#define CIPHER_ERR_RSA_VERIFY_BC 0x2F
|
||||
#define CIPHER_ERR_RSA_VERIFY_DB_1 0x30
|
||||
#define CIPHER_ERR_RSA_VERIFY_MASKEDDB_LEN 0x31
|
||||
#define CIPHER_ERR_RSA_VERIFY_EM_FIRSTBYTE 0x32
|
||||
#define CIPHER_ERR_RSA_VERIFY_EM_SECONDBYTE 0x33
|
||||
#define CIPHER_ERR_RSA_VERIFY_EM_PS 0x34
|
||||
#define CIPHER_ERR_RSA_VERIFY_EM_T_LEN 0x35
|
||||
#define CIPHER_ERR_RSA_VERIFY_ASN1_SHA256 0x36
|
||||
#define CIPHER_ERR_RSA_VERIFY_SHA256_DATA 0x37
|
||||
#define CIPHER_ERR_RSA_VERIFY_SHA256_DATA_LEN 0x38
|
||||
|
||||
#define CIPHER_ERR_OTP_WAIT_TIMEOUT 0x40
|
||||
#define CIPHER_ERR_KLAD_WAIT_TIMEOUT 0x41
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,846 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "xmedia_cipher_osal.h"
|
||||
#include "xmedia_cipher_reg.h"
|
||||
//#include "safety.h"
|
||||
|
||||
/* spacc symc int entry struct which is defined by hardware, you can't change it */
|
||||
struct spacc_symc_in_entry_t {
|
||||
unsigned int spacc_cmd: 2;
|
||||
unsigned int rev1: 6;
|
||||
unsigned int sym_ctrl: 7;
|
||||
unsigned int rev2: 1;
|
||||
unsigned int gcm_iv_len: 4;
|
||||
unsigned int rev3: 12;
|
||||
unsigned int sym_start_addr_high;
|
||||
unsigned int sym_start_addr;
|
||||
unsigned int sym_alg_length;
|
||||
unsigned int symc_iv[4]; /* 4 iv len */
|
||||
};
|
||||
|
||||
/* spacc digest in entry struct which is defined by hardware, you can't change it */
|
||||
struct spacc_digest_in_entry_t {
|
||||
unsigned int spacc_cmd: 2;
|
||||
unsigned int rev1: 6;
|
||||
unsigned int hash_ctrl: 6;
|
||||
unsigned int rev2: 18;
|
||||
unsigned int hash_start_addr;
|
||||
unsigned int hash_alg_length;
|
||||
unsigned int hash_start_addr_high;
|
||||
};
|
||||
|
||||
/* spacc symc out entry struct which is defined by hardware, you can't change it */
|
||||
struct spacc_symc_out_entry_t {
|
||||
unsigned int rev1: 8;
|
||||
unsigned int aes_ctrl: 4;
|
||||
unsigned int rev2: 20;
|
||||
unsigned int sym_start_addr;
|
||||
unsigned int sym_alg_length;
|
||||
unsigned int hash_rslt_start_addr;
|
||||
unsigned int tag[4]; /* 4 tag len */
|
||||
};
|
||||
|
||||
struct spacc_digest_context {
|
||||
digest_alg_en digest_alg;
|
||||
digest_mode_en digest_mode;
|
||||
unsigned int digest_len;
|
||||
unsigned int digest_blen;
|
||||
|
||||
struct spacc_digest_in_entry_t* entry_digest_in;
|
||||
unsigned int entry_digest_in_depth;
|
||||
unsigned int digest_cur_in_nodes;
|
||||
};
|
||||
|
||||
struct spacc_symc_context {
|
||||
symc_alg_en symc_alg;
|
||||
symc_mode_en symc_mode;
|
||||
unsigned int symc_iv[4]; /* 4 iv len */
|
||||
unsigned int symc_ivlen;
|
||||
|
||||
struct spacc_symc_in_entry_t* entry_symc_in;
|
||||
struct spacc_symc_out_entry_t* entry_symc_out;
|
||||
|
||||
unsigned int entry_symc_in_depth;
|
||||
unsigned int entry_symc_out_depth;
|
||||
unsigned int symc_cur_in_nodes;
|
||||
unsigned int symc_cur_out_nodes;
|
||||
};
|
||||
|
||||
#define SAPCC_SYMC_IN_ENTRY_TOTAL_SIZE (sizeof(struct spacc_symc_in_entry_t) * SPACC_MAX_DEPTH)
|
||||
#define SAPCC_SYMC_OUT_ENTRY_TOTAL_SIZE (sizeof(struct spacc_symc_out_entry_t) * SPACC_MAX_DEPTH)
|
||||
#define SAPCC_DIGEST_IN_ENTRY_TOTAL_SIZE (sizeof(struct spacc_digest_in_entry_t) * SPACC_MAX_DEPTH)
|
||||
|
||||
void *g_spacc_reg_base = 0;
|
||||
static struct spacc_digest_context *g_digest_context = XMEDIA_NULL;
|
||||
static struct spacc_symc_context *g_symc_context = XMEDIA_NULL;
|
||||
|
||||
static xmedia_void* g_cipher_reg_base = XMEDIA_NULL;
|
||||
static xmedia_void* cipher_entry_addr = XMEDIA_NULL;
|
||||
|
||||
void cipher_debug_log(unsigned short errflag)
|
||||
{
|
||||
char errStr[12];
|
||||
|
||||
errStr[0] = 'c';
|
||||
errStr[1] = 'i';
|
||||
errStr[2] = 'p';
|
||||
errStr[3] = 'h';
|
||||
errStr[4] = 'e';
|
||||
errStr[5] = 'r';
|
||||
errStr[6] = '#';
|
||||
errStr[7] = 'E';
|
||||
errStr[8] = (char)(errflag/10) + '0';
|
||||
errStr[9] = (char)(errflag%10) + '0';
|
||||
errStr[10] = '\n';
|
||||
errStr[11] = 0;
|
||||
xmedia_err_cipher(errStr);
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_digest_configure - configure the hash ctrl register.
|
||||
*/
|
||||
int spacc_sha256_config(unsigned int chn_num,
|
||||
digest_alg_en digest_alg,
|
||||
digest_mode_en digest_mode,
|
||||
unsigned char hard_key)
|
||||
{
|
||||
struct spacc_digest_context *info = g_digest_context;
|
||||
u_chann_hash_ctrl hash_ctrl;
|
||||
|
||||
info->digest_alg = digest_alg;
|
||||
info->digest_mode = digest_mode;
|
||||
info->digest_len = SHA256_RESULT_SIZE; /* 32 sha1 digest len */
|
||||
info->digest_blen = SHA256_BLOCK_SIZE; /* 64 sha1 digest blen */
|
||||
|
||||
hash_ctrl.u32 = spacc_read(chn_n_hash_ctrl(chn_num));
|
||||
hash_ctrl.bits.hash_chn_mode = digest_mode;
|
||||
hash_ctrl.bits.hash_chn_agl_sel = digest_alg;
|
||||
spacc_write(chn_n_hash_ctrl(chn_num), hash_ctrl.u32);
|
||||
|
||||
info->entry_digest_in_depth = 0;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* spacc_digest_addbuf - filling the buf addr and length of
|
||||
* data into nodes list.
|
||||
*
|
||||
*/
|
||||
int spacc_sha256_addbuf(unsigned int chn_num,
|
||||
unsigned long buf_phy,
|
||||
unsigned int buf_size,
|
||||
unsigned int ctrl)
|
||||
{
|
||||
struct spacc_digest_context *info = g_digest_context;
|
||||
unsigned int id, size;
|
||||
void *addr = XMEDIA_NULL;
|
||||
|
||||
id = info->digest_cur_in_nodes++;
|
||||
addr = &info->entry_digest_in[id];
|
||||
size = sizeof(struct spacc_digest_in_entry_t);
|
||||
crypto_memset(addr, sizeof(info->entry_digest_in[id]), 0, size);
|
||||
info->entry_digest_in[id].spacc_cmd = 0x00;
|
||||
info->entry_digest_in[id].hash_start_addr = get_ulong_low(buf_phy);
|
||||
info->entry_digest_in[id].hash_alg_length = buf_size;
|
||||
info->entry_digest_in[id].hash_ctrl = ctrl;
|
||||
info->entry_digest_in[id].hash_start_addr_high = get_ulong_high(buf_phy);
|
||||
info->entry_digest_in_depth++;
|
||||
info->digest_cur_in_nodes %= SPACC_MAX_DEPTH;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* spacc_digest_get - get hash result.
|
||||
*
|
||||
*/
|
||||
int spacc_sha256_get(unsigned int chn_num, unsigned int *digest)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < SHA256_RESULT_IN_WORD; i++) {
|
||||
spacc_write(chn_n_hash_state_val_addr(chn_num), i);
|
||||
digest[i] = spacc_read(chn_n_hash_state_val(chn_num));
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_digest_start - action the hash start to processing the node list.
|
||||
*/
|
||||
int spacc_sha256_start(unsigned int chn_num, spacc_ctrl_en spacc_ctrl, unsigned int *state)
|
||||
{
|
||||
unsigned int i;
|
||||
u_chann_hash_in_node_cfg in_node_cfg;
|
||||
struct spacc_digest_context *info = g_digest_context;
|
||||
unsigned int ptr;
|
||||
|
||||
/* Write last state */
|
||||
for (i = 0; i < SHA256_RESULT_IN_WORD; i++) {
|
||||
spacc_write(chn_n_hash_state_val_addr(chn_num), i);
|
||||
spacc_write(chn_n_hash_state_val(chn_num), state[i]);
|
||||
}
|
||||
|
||||
if (info->entry_digest_in_depth == 0)
|
||||
return XMEDIA_SUCCESS;
|
||||
|
||||
/* configure in-node */
|
||||
in_node_cfg.u32 = spacc_read(chn_n_hash_in_node_cfg(chn_num));
|
||||
if (in_node_cfg.bits.hash_in_node_wptr != in_node_cfg.bits.hash_in_node_rptr) {
|
||||
cipher_debug_log(CIPHER_ERR_SHA256_START);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
ptr = in_node_cfg.bits.hash_in_node_wptr + info->entry_digest_in_depth;
|
||||
in_node_cfg.bits.hash_in_node_wptr = ptr % SPACC_MAX_DEPTH;
|
||||
in_node_cfg.bits.hash_in_node_mpackage_int_level = 1;
|
||||
|
||||
/* Start */
|
||||
spacc_write(chn_n_hash_in_node_cfg(chn_num), in_node_cfg.u32);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_digest_done_try - test the int status of hash channel.
|
||||
*/
|
||||
unsigned int spacc_sha256_done_try(unsigned int chn_num)
|
||||
{
|
||||
u_hash_int_raw int_raw;
|
||||
unsigned int chn_mask;
|
||||
|
||||
int_raw.u32 = spacc_read(HASH_INT_RAW);
|
||||
int_raw.bits.hash_chn_oram_raw &= 0x01 << chn_num;
|
||||
chn_mask = int_raw.bits.hash_chn_oram_raw;
|
||||
|
||||
/* Clean raw int */
|
||||
spacc_write(HASH_INT_RAW, int_raw.u32);
|
||||
|
||||
return chn_mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_digest_get_err_code - get the error code of hash.
|
||||
*/
|
||||
unsigned int spacc_sha256_get_err_code(unsigned int chn_num, unsigned int *src_addr)
|
||||
{
|
||||
*src_addr = spacc_read(chn_n_hash_in_buf_rptr(chn_num));
|
||||
|
||||
return spacc_read(CALC_ERR);
|
||||
}
|
||||
|
||||
static xmedia_void spacc_config_start_addr(unsigned long entry_phy_addr, xmedia_void *entry_via_addr)
|
||||
{
|
||||
xmedia_size_t page_phy;
|
||||
xmedia_void *page_via = XMEDIA_NULL;
|
||||
u_chann_cipher_in_node_cfg cipher_in_cfg;
|
||||
u_chann_cipher_out_node_cfg cipher_out_cfg;
|
||||
u_chann_hash_in_node_cfg hash_in_cfg;
|
||||
|
||||
page_phy = entry_phy_addr;
|
||||
page_via = entry_via_addr;
|
||||
|
||||
/* set total num and start addr for cipher in node */
|
||||
cipher_in_cfg.u32 = spacc_read(chn_n_cipher_in_node_cfg(SPACC_CHN_AES));
|
||||
cipher_in_cfg.bits.cipher_in_node_total_num = SPACC_MAX_DEPTH;
|
||||
spacc_write(chn_n_cipher_in_node_cfg(SPACC_CHN_AES), cipher_in_cfg.u32);
|
||||
spacc_write(chn_n_cipher_in_node_start_addr(SPACC_CHN_AES), get_ulong_low(page_phy));
|
||||
spacc_write(chn_n_cipher_in_node_start_addr_high(SPACC_CHN_AES), get_ulong_high(page_phy));
|
||||
g_symc_context->entry_symc_in = (struct spacc_symc_in_entry_t*)page_via;
|
||||
g_symc_context->symc_cur_in_nodes = cipher_in_cfg.bits.cipher_in_node_wptr;
|
||||
g_symc_context->entry_symc_in_depth = 0;
|
||||
page_via += SAPCC_SYMC_IN_ENTRY_TOTAL_SIZE;
|
||||
page_phy += SAPCC_SYMC_IN_ENTRY_TOTAL_SIZE;
|
||||
|
||||
/* set total num and start addr for cipher out node */
|
||||
cipher_out_cfg.u32 = spacc_read(chn_n_cipher_out_node_cfg(SPACC_CHN_AES));
|
||||
cipher_out_cfg.bits.cipher_out_node_total_num = SPACC_MAX_DEPTH;
|
||||
spacc_write(chn_n_cipher_out_node_cfg(SPACC_CHN_AES), cipher_out_cfg.u32);
|
||||
spacc_write(chn_n_cipher_out_node_start_addr(SPACC_CHN_AES), get_ulong_low(page_phy));
|
||||
spacc_write(chn_n_cipher_out_node_start_addr_high(SPACC_CHN_AES), get_ulong_high(page_phy));
|
||||
g_symc_context->entry_symc_out = (struct spacc_symc_out_entry_t*)page_via;
|
||||
g_symc_context->symc_cur_out_nodes = cipher_out_cfg.bits.cipher_out_node_wptr;
|
||||
g_symc_context->entry_symc_out_depth = 0;
|
||||
page_via += SAPCC_SYMC_OUT_ENTRY_TOTAL_SIZE;
|
||||
page_phy += SAPCC_SYMC_OUT_ENTRY_TOTAL_SIZE;
|
||||
|
||||
/* set total num and start addr for hash in node */
|
||||
hash_in_cfg.u32 = spacc_read(chn_n_hash_in_node_cfg(SPACC_CHN_SHA256));
|
||||
hash_in_cfg.bits.hash_in_node_total_num = SPACC_MAX_DEPTH;
|
||||
spacc_write(chn_n_hash_in_node_cfg(SPACC_CHN_SHA256), hash_in_cfg.u32);
|
||||
spacc_write(chn_n_hash_in_node_start_addr(SPACC_CHN_SHA256), get_ulong_low(page_phy));
|
||||
spacc_write(chn_n_hash_in_node_start_addr_high(SPACC_CHN_SHA256), get_ulong_high(page_phy));
|
||||
g_digest_context->entry_digest_in = (struct spacc_digest_in_entry_t*)page_via;
|
||||
g_digest_context->digest_cur_in_nodes = hash_in_cfg.bits.hash_in_node_wptr;
|
||||
g_digest_context->entry_digest_in_depth = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* spacc_get_node_list_size - return the total size of nodes lists memory required by the drive.
|
||||
*/
|
||||
unsigned int spacc_get_node_list_size(void)
|
||||
{
|
||||
/*********************************************************************
|
||||
0x40 + 0x40 + 0x20
|
||||
*********************************************************************/
|
||||
return (SAPCC_SYMC_IN_ENTRY_TOTAL_SIZE + SAPCC_SYMC_OUT_ENTRY_TOTAL_SIZE + SAPCC_DIGEST_IN_ENTRY_TOTAL_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* spacc_init - spacc hardware initialization.
|
||||
* @reg_base: virtual address of spacc module which be accessed by CPU
|
||||
* @mmu_table_addr: mmu base table physical addr, if disable mmu, set it to 0
|
||||
* @entry_phy_addr: a consecutive physical memory, used for nodes
|
||||
* list of symc-in, symc-out and hash-in, the size
|
||||
* must large than spacc_get_node_list_size().
|
||||
* @entry_via_addr: virtual address of entry_phy_addr.
|
||||
*
|
||||
* Description:
|
||||
* spacc hardware initialization as follows:
|
||||
* - reset global var.
|
||||
* - enable interrupt
|
||||
* - set nodes list addr
|
||||
* - set mmu table addr
|
||||
* - configureure hardware register
|
||||
*
|
||||
* Context:
|
||||
* this function must be called one time in the beginning.
|
||||
*/
|
||||
int spacc_init(xmedia_void *reg_base, unsigned long entry_phy_addr, xmedia_void *entry_via_addr)
|
||||
{
|
||||
crypto_memset(g_symc_context, sizeof(struct spacc_symc_context), 0, sizeof(struct spacc_symc_context));
|
||||
crypto_memset(g_digest_context, sizeof(struct spacc_digest_context), 0, sizeof(struct spacc_digest_context));
|
||||
|
||||
g_spacc_reg_base = reg_base;
|
||||
|
||||
//not enable smmu
|
||||
//not enable int
|
||||
|
||||
/* configure start addr for in-node and out-node */
|
||||
spacc_config_start_addr(entry_phy_addr, entry_via_addr);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* spacc_deinit - spacc hardware deinit.
|
||||
*/
|
||||
int spacc_deinit(void)
|
||||
{
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_symc_configure - configure logic register, such as alg, mode, key len and so on.
|
||||
*/
|
||||
int spacc_symc_config(unsigned int chn_num, spacc_symc_config_s *symc_cfg)
|
||||
{
|
||||
struct spacc_symc_context *info = g_symc_context;
|
||||
u_chann_cipher_ctrl cipher_ctrl;
|
||||
|
||||
cipher_ctrl.u32 = spacc_read(chn_n_cipher_ctrl(chn_num));
|
||||
cipher_ctrl.bits.sym_chn_key_sel = (symc_cfg->key_type == SYMC_KEY_SRC_USER) ? 0 : 1; // bit[14], 0:cpu config key; 1: klad config key
|
||||
cipher_ctrl.bits.sym_chn_key_length = 2; // bit[11:10], 2:256bit
|
||||
cipher_ctrl.bits.sym_chn_dat_width = 0; // bit[9:8], 0:128bit
|
||||
cipher_ctrl.bits.sym_chn_decrypt = (symc_cfg->is_encrypt == XMEDIA_TRUE) ? 0 : 1; // bit[7], 0:encrypt; 1:decrypt
|
||||
cipher_ctrl.bits.sym_chn_alg_sel = symc_cfg->symc_alg;
|
||||
cipher_ctrl.bits.sym_chn_alg_mode = symc_cfg->symc_mode;
|
||||
spacc_write(chn_n_cipher_ctrl(chn_num), cipher_ctrl.u32);
|
||||
|
||||
info->symc_alg = symc_cfg->symc_alg;
|
||||
info->symc_mode = symc_cfg->symc_mode;
|
||||
info->entry_symc_in_depth = 0;
|
||||
info->entry_symc_out_depth = 0;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
/**
|
||||
* spacc_symc_setiv - set iv for symc.
|
||||
* @chn_num: the logic channel number, must 1~7.
|
||||
* @iv: the initialization vector
|
||||
* @ivlen: length of iv.
|
||||
*
|
||||
* Description:
|
||||
* here store the iv to global structure of channel, don't set to logic,
|
||||
* because the IV must be set in the nodes list.
|
||||
*
|
||||
*/
|
||||
int spacc_symc_setiv(unsigned int chn_num, unsigned char *iv, unsigned int ivlen)
|
||||
{
|
||||
struct spacc_symc_context *info = g_symc_context;
|
||||
|
||||
crypto_memset(info->symc_iv, sizeof(info->symc_iv), 0, sizeof(info->symc_iv));
|
||||
crypto_memcpy(info->symc_iv, sizeof(info->symc_iv), iv, ivlen);
|
||||
info->symc_ivlen = ivlen;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
void spacc_symc_setkey(xmedia_u32 chn_num, xmedia_u32 key[SYMC_KEY_MAX_SIZE_IN_WORD], xmedia_u32 odd)
|
||||
{
|
||||
xmedia_u32 i = 0;
|
||||
|
||||
/* Set key, odd key only valid for aes ecb/cbc/ofb/cfb/ctr */
|
||||
spacc_write(ODD_EVEN_KEY_SEL, odd);
|
||||
for (i = 0; i < SYMC_KEY_MAX_SIZE_IN_WORD; i++) {
|
||||
spacc_write(cipher_key(chn_num) + i * 4, key[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int drv_cipher_setkey(cipher_ctrl *config)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (config->key_type != XMEDIA_CIPHER_KEY_SRC_USER) {
|
||||
ret = drv_cipher_klad_load_key(SPACC_CHN_AES, config->key, 32, config->key_type); /* 16 key len */
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_LOAD_KEY);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
spacc_symc_setkey(SPACC_CHN_AES, config->key, XMEDIA_FALSE);
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_symc_addbuf - filling the buf addr and length of
|
||||
* encrypt/decrypt data into nodes list.
|
||||
*/
|
||||
int spacc_symc_addbuf(unsigned int chn_num, unsigned long buf_phy,
|
||||
unsigned int buf_size, spacc_buf_type_en type, unsigned int ctrl)
|
||||
{
|
||||
struct spacc_symc_context *info = g_symc_context;
|
||||
unsigned int id, size;
|
||||
void *addr = XMEDIA_NULL;
|
||||
|
||||
switch (type) {
|
||||
case SPACC_BUF_TYPE_SYMC_IN:
|
||||
id = info->symc_cur_in_nodes++;
|
||||
addr = &info->entry_symc_in[id];
|
||||
size = sizeof(struct spacc_symc_in_entry_t);
|
||||
crypto_memset(addr, sizeof(info->entry_symc_in[id]), 0, size);
|
||||
info->entry_symc_in[id].spacc_cmd = 0x00;
|
||||
info->entry_symc_in[id].sym_start_addr = get_ulong_low(buf_phy);
|
||||
info->entry_symc_in[id].sym_start_addr_high = get_ulong_high(buf_phy);
|
||||
info->entry_symc_in[id].sym_alg_length = buf_size;
|
||||
info->entry_symc_in[id].sym_ctrl = ctrl;
|
||||
info->entry_symc_in_depth++;
|
||||
info->symc_cur_in_nodes %= SPACC_MAX_DEPTH;
|
||||
break;
|
||||
case SPACC_BUF_TYPE_SYMC_OUT:
|
||||
id = info->symc_cur_out_nodes++;
|
||||
addr = &info->entry_symc_out[id];
|
||||
size = sizeof(struct spacc_symc_out_entry_t);
|
||||
crypto_memset(addr, sizeof(info->entry_symc_out[id]), 0, size);
|
||||
info->entry_symc_out[id].sym_start_addr = get_ulong_low(buf_phy);
|
||||
info->entry_symc_out[id].tag[0] = get_ulong_high(buf_phy);
|
||||
info->entry_symc_out[id].sym_alg_length = buf_size;
|
||||
info->entry_symc_out[id].aes_ctrl = ctrl;
|
||||
info->entry_symc_out_depth++;
|
||||
info->symc_cur_out_nodes %= SPACC_MAX_DEPTH;
|
||||
break;
|
||||
default:
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static int spacc_config_out_node(unsigned int chn_num, struct spacc_symc_context *info)
|
||||
{
|
||||
u_chann_cipher_out_node_cfg out_node_cfg;
|
||||
unsigned int ptr;
|
||||
|
||||
out_node_cfg.u32 = spacc_read(chn_n_cipher_out_node_cfg(chn_num));
|
||||
if (out_node_cfg.bits.cipher_out_node_wptr != out_node_cfg.bits.cipher_out_node_rptr) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_CFG_OUTNODE);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
ptr = out_node_cfg.bits.cipher_out_node_wptr + info->entry_symc_out_depth;
|
||||
out_node_cfg.bits.cipher_out_node_wptr = ptr % SPACC_MAX_DEPTH;
|
||||
out_node_cfg.bits.cipher_out_node_mpackage_int_level = info->entry_symc_out_depth;
|
||||
spacc_write(chn_n_cipher_out_node_cfg(chn_num), out_node_cfg.u32);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static void spacc_config_in_node(unsigned int chn_num, struct spacc_symc_context *info)
|
||||
{
|
||||
u_chann_cipher_in_node_cfg in_node_cfg;
|
||||
unsigned int ptr;
|
||||
|
||||
in_node_cfg.u32 = spacc_read(chn_n_cipher_in_node_cfg(chn_num));
|
||||
ptr = in_node_cfg.bits.cipher_in_node_wptr + info->entry_symc_in_depth;
|
||||
in_node_cfg.bits.cipher_in_node_wptr = ptr % SPACC_MAX_DEPTH;
|
||||
in_node_cfg.bits.cipher_in_node_mpackage_int_level = info->entry_symc_in_depth;
|
||||
|
||||
/* move forward the in-node ptr to action the symc working */
|
||||
spacc_write(chn_n_cipher_in_node_cfg(chn_num), in_node_cfg.u32);
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_symc_done_try - test the int status of symc channel.
|
||||
*/
|
||||
unsigned int spacc_symc_done_try(unsigned int chn_num)
|
||||
{
|
||||
u_cipher_int_raw int_raw;
|
||||
unsigned int chn_mask;
|
||||
|
||||
int_raw.u32 = spacc_read(CIPHER_INT_RAW);
|
||||
int_raw.bits.cipher_chn_obuf_raw &= 0x01 << chn_num;
|
||||
chn_mask = int_raw.bits.cipher_chn_obuf_raw;
|
||||
|
||||
/* Clean raw int */
|
||||
int_raw.u32 = 0x00;
|
||||
int_raw.bits.cipher_chn_obuf_raw = chn_mask;
|
||||
spacc_write(CIPHER_INT_RAW, int_raw.u32);
|
||||
|
||||
return chn_mask ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_symc_get_err_code - get the error code of symc.
|
||||
*/
|
||||
unsigned int spacc_symc_get_err_code(unsigned int chn_num,
|
||||
unsigned int *src_addr,
|
||||
unsigned int *dst_addr)
|
||||
{
|
||||
*src_addr = spacc_read(chn_n_cipher_in_buf_rptr(chn_num));
|
||||
*dst_addr = spacc_read(chn_n_cipher_out_buf_rptr(chn_num));
|
||||
|
||||
return spacc_read(CALC_ERR);
|
||||
}
|
||||
|
||||
/* check error code
|
||||
* bit0: klad_key_use_err
|
||||
* bit1: alg_len_err
|
||||
* bit2: smmu_page_unvlid
|
||||
*/
|
||||
static xmedia_s32 spacc_cipher_check_error_code(xmedia_u32 hard_num, xmedia_u32 wait, xmedia_u32 src_addr)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
|
||||
if (wait & 0x01) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_ERRCODE_1);
|
||||
ret = XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (wait & 0x02) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_ERRCODE_2);
|
||||
ret = XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (wait & 0x04) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_ERRCODE_4);
|
||||
ret = XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* spacc_symc_start - action the symc start to processing the node list.
|
||||
*/
|
||||
int spacc_symc_start(unsigned int chn_num)
|
||||
{
|
||||
unsigned int cur, i, j, node;
|
||||
u_chann_cipher_in_node_cfg in_node_cfg;
|
||||
struct spacc_symc_context *info = g_symc_context;
|
||||
|
||||
in_node_cfg.u32 = spacc_read(chn_n_cipher_in_node_cfg(chn_num));
|
||||
cur = in_node_cfg.bits.cipher_in_node_rptr;
|
||||
|
||||
for (j = 0; j < info->entry_symc_in_depth; j++) {
|
||||
if (info->symc_ivlen > 0) {
|
||||
/* Write iv to all nodes */
|
||||
node = (cur + j) % SPACC_MAX_DEPTH;
|
||||
for (i = 0; i < 4; i++) { /* 4 iv len */
|
||||
info->entry_symc_in[node].symc_iv[i] = info->symc_iv[i];
|
||||
}
|
||||
|
||||
info->entry_symc_in[node].gcm_iv_len = 0;
|
||||
info->entry_symc_in[node].sym_ctrl |= SPACC_CTRL_SYMC_IN_FIRST;
|
||||
}
|
||||
}
|
||||
|
||||
if (spacc_config_out_node(chn_num, info) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
/* spacc_config_in_node must be placed after flush_cache, otherwwise it may be crypt timeout */
|
||||
spacc_config_in_node(chn_num, info);
|
||||
|
||||
/* all the nodes are processing, reset the depth to 0 */
|
||||
info->entry_symc_in_depth = 0;
|
||||
info->entry_symc_out_depth = 0;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_cipher_sha256_config(cipher_hash_data_s *cipher_hash_data, spacc_ctrl_en *spacc_ctrl)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
digest_alg_en digest_alg;
|
||||
digest_mode_en digest_mode;
|
||||
|
||||
*spacc_ctrl = SPACC_CTRL_NONE;
|
||||
digest_alg = DIGEST_ALG_SHA256;
|
||||
digest_mode = DIGEST_MODE_HASH;
|
||||
|
||||
ret = spacc_sha256_config(cipher_hash_data->hard_chn, digest_alg, digest_mode, XMEDIA_FALSE);
|
||||
|
||||
*spacc_ctrl = ((xmedia_u32)*spacc_ctrl) | SPACC_CTRL_HASH_IN_FIRST;
|
||||
*spacc_ctrl = ((xmedia_u32)*spacc_ctrl) | SPACC_CTRL_HASH_IN_LAST;
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
static xmedia_s32 drv_cipher_sha256_wait_done(unsigned int channel)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
xmedia_u32 wait;
|
||||
xmedia_u32 time_out = SPACC_TIME_OUT;
|
||||
xmedia_u32 src_addr;
|
||||
|
||||
time_out = 0;
|
||||
while (time_out++ < SPACC_TIME_OUT) {
|
||||
if (spacc_sha256_done_try(channel))
|
||||
break;
|
||||
cipher_usleep(10);
|
||||
}
|
||||
if (time_out >= SPACC_TIME_OUT) {
|
||||
cipher_debug_log(CIPHER_ERR_SHA256_WAIT_TIMEOUT);
|
||||
ret = XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
/* check error code
|
||||
* bit0: klad_key_use_err
|
||||
* bit1: alg_len_err
|
||||
* bit2: smmu_page_unvlid
|
||||
*/
|
||||
wait = spacc_sha256_get_err_code(channel, &src_addr);
|
||||
if (spacc_cipher_check_error_code(channel, wait, src_addr) != XMEDIA_SUCCESS) {
|
||||
ret = XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_cipher_sha256_update(cipher_hash_data_s *cipher_hash_data)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
spacc_ctrl_en spacc_ctrl;
|
||||
|
||||
/* configure hash register */
|
||||
ret = drv_cipher_sha256_config(cipher_hash_data, &spacc_ctrl);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add the phy of data to nodes list */
|
||||
ret = spacc_sha256_addbuf(cipher_hash_data->hard_chn, make_ulong(cipher_hash_data->data_phy, cipher_hash_data->data_phy_high),
|
||||
cipher_hash_data->data_len, spacc_ctrl);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start working */
|
||||
ret = spacc_sha256_start(cipher_hash_data->hard_chn, spacc_ctrl, cipher_hash_data->sha_val);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Waiting hardware computing finished */
|
||||
ret = drv_cipher_sha256_wait_done(cipher_hash_data->hard_chn);
|
||||
if (ret == XMEDIA_SUCCESS) /* Read hash result */
|
||||
spacc_sha256_get(cipher_hash_data->hard_chn, cipher_hash_data->sha_val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_cipher_sha256_final(cipher_hash_data_s *cipher_hash_data)
|
||||
{
|
||||
return drv_cipher_sha256_update(cipher_hash_data);
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_cipher_reset(xmedia_void)
|
||||
{
|
||||
xmedia_u32 *pvirt = XMEDIA_NULL;
|
||||
xmedia_u32 spacc_stat = 0;
|
||||
|
||||
pvirt = cipher_ioremap_nocache(CIPHER_SPACC_CRG_ADDR_PHY, 16); /* 16 */
|
||||
|
||||
/* open clock, reset */
|
||||
spacc_stat = hal_cipher_read_reg(pvirt);
|
||||
spacc_stat |= SPACC_CRG_CLOCK_BIT;
|
||||
spacc_stat |= SPACC_CRG_RESET_BIT;
|
||||
hal_cipher_write_reg(pvirt, spacc_stat);
|
||||
cipher_usleep(10); /* 10us */
|
||||
|
||||
/* cancel reset */
|
||||
spacc_stat &= ~SPACC_CRG_RESET_BIT;
|
||||
hal_cipher_write_reg(pvirt, spacc_stat);
|
||||
|
||||
//enable_spacc_safety();
|
||||
|
||||
cipher_iounmap(pvirt);
|
||||
pvirt = XMEDIA_NULL;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_cipher_symc_wait_done(xmedia_u32 hw_chan, xmedia_u32 time_out)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
xmedia_u32 wait;
|
||||
xmedia_u32 src_addr, dst_addr;
|
||||
|
||||
time_out = 0;
|
||||
while (time_out++ < SPACC_TIME_OUT) {
|
||||
if (spacc_symc_done_try(hw_chan))
|
||||
break;
|
||||
cipher_usleep(10);
|
||||
}
|
||||
if (time_out >= SPACC_TIME_OUT) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_WAIT_TIMEOUT);
|
||||
ret = XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
wait = spacc_symc_get_err_code(hw_chan, &src_addr, &dst_addr);
|
||||
if (spacc_cipher_check_error_code(hw_chan, wait, src_addr) != XMEDIA_SUCCESS) {
|
||||
ret = XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_cipher_init(xmedia_void)
|
||||
{
|
||||
xmedia_u32 malloc_size;
|
||||
|
||||
dcache_disable();
|
||||
|
||||
g_cipher_reg_base = cipher_ioremap_nocache(CIPHER_CIPHER_REG_BASE_ADDR_PHY, 0x2000);
|
||||
|
||||
if (drv_cipher_reset() != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
malloc_size = spacc_get_node_list_size();
|
||||
cipher_entry_addr = cipher_malloc(malloc_size);
|
||||
if (cipher_entry_addr == XMEDIA_NULL) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_MALLOC);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
/*sizeof(struct spacc_digest_context) == 0x1C*/
|
||||
g_digest_context = cipher_malloc(sizeof(struct spacc_digest_context));
|
||||
if (g_digest_context == XMEDIA_NULL) {
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_MALLOC);
|
||||
cipher_free(cipher_entry_addr);
|
||||
cipher_entry_addr = XMEDIA_NULL;
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
/*sizeof(struct spacc_digest_context) == 0x34*/
|
||||
g_symc_context = cipher_malloc(sizeof(struct spacc_symc_context));
|
||||
if (g_symc_context == XMEDIA_NULL) {
|
||||
cipher_free(cipher_entry_addr);
|
||||
cipher_entry_addr = XMEDIA_NULL;
|
||||
cipher_free(g_digest_context);
|
||||
g_digest_context = XMEDIA_NULL;
|
||||
cipher_debug_log(CIPHER_ERR_CIPHER_MALLOC);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
crypto_memset(cipher_entry_addr, malloc_size, 0, malloc_size);
|
||||
spacc_init(g_cipher_reg_base, (unsigned long)cipher_entry_addr, cipher_entry_addr);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_cipher_deinit(xmedia_void)
|
||||
{
|
||||
spacc_deinit();
|
||||
|
||||
cipher_free(cipher_entry_addr);
|
||||
cipher_entry_addr = XMEDIA_NULL;
|
||||
|
||||
cipher_iounmap(g_cipher_reg_base);
|
||||
|
||||
cipher_free(g_digest_context);
|
||||
g_digest_context = XMEDIA_NULL;
|
||||
cipher_free(g_symc_context);
|
||||
g_symc_context = XMEDIA_NULL;
|
||||
|
||||
dcache_enable();
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_cipher_config_aes_chn(cipher_ctrl *config, xmedia_bool is_encrypt)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
spacc_symc_config_s symc_cfg;
|
||||
|
||||
symc_cfg.symc_alg = SYMC_ALG_AES;
|
||||
symc_cfg.symc_mode = config->work_mode;
|
||||
symc_cfg.symc_width = SYMC_DAT_WIDTH_128;
|
||||
symc_cfg.key_len = 32;
|
||||
symc_cfg.is_encrypt = is_encrypt;
|
||||
symc_cfg.key_type = config->key_type;
|
||||
|
||||
ret = spacc_symc_config(SPACC_CHN_AES, &symc_cfg);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drv_cipher_setkey(config);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = spacc_symc_setiv(SPACC_CHN_AES, (xmedia_u8*)config->iv, sizeof(config->iv));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_cipher_aes(cipher_data_s *ci_data)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
xmedia_size_t src_phy_addr, dest_phy_addr;
|
||||
|
||||
src_phy_addr = make_ulong(ci_data->src_phy_addr, ci_data->src_phy_addr_high);
|
||||
dest_phy_addr = make_ulong(ci_data->dest_phy_addr, ci_data->dest_phy_addr_high);
|
||||
|
||||
/* Add in buffer */
|
||||
ret = spacc_symc_addbuf(SPACC_CHN_AES, src_phy_addr, ci_data->data_length,
|
||||
SPACC_BUF_TYPE_SYMC_IN, SPACC_CTRL_SYMC_IN_LAST);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add out buffer */
|
||||
ret = spacc_symc_addbuf(SPACC_CHN_AES, dest_phy_addr, ci_data->data_length,
|
||||
SPACC_BUF_TYPE_SYMC_OUT, SPACC_CTRL_SYMC_OUT_LAST);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start working */
|
||||
spacc_symc_start(SPACC_CHN_AES);
|
||||
|
||||
/* Waiting hardware computing finished */
|
||||
ret = drv_cipher_symc_wait_done(SPACC_CHN_AES, SPACC_TIME_OUT);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPACC_BODY_H_
|
||||
#define _SPACC_BODY_H_
|
||||
|
||||
#define SHA256_RESULT_SIZE 32
|
||||
#define SHA256_RESULT_IN_WORD 8
|
||||
#define SHA256_BLOCK_SIZE 64
|
||||
#define SHA256_PADDING_MAX_SIZE 128
|
||||
|
||||
#define SPACC_CHN_MASK 0xFE
|
||||
#define SPACC_CHN_AES 0x1
|
||||
#define SPACC_CHN_SHA256 0x1
|
||||
|
||||
#define SPACC_MAX_DEPTH 2
|
||||
|
||||
#define SYMC_KEY_MAX_SIZE_IN_WORD 8
|
||||
|
||||
#define get_ulong_low(dw) (unsigned int)(dw)
|
||||
#define get_ulong_high(dw) 0
|
||||
#define make_ulong(low, high) (low)
|
||||
#define make_size(low) (((unsigned long)(low##High) << 32) | (low))
|
||||
|
||||
#define SPACC_TIME_OUT 300000
|
||||
#define RSA_TIMEOUT_CNT 300000
|
||||
|
||||
typedef enum {
|
||||
DIGEST_MODE_HASH,
|
||||
DIGEST_MODE_HMAC,
|
||||
DIGEST_MODE_COUNT,
|
||||
} digest_mode_en;
|
||||
|
||||
typedef enum {
|
||||
DIGEST_ALG_SHA1,
|
||||
DIGEST_ALG_SHA224,
|
||||
DIGEST_ALG_SHA256,
|
||||
DIGEST_ALG_SHA384,
|
||||
DIGEST_ALG_SHA512,
|
||||
DIGEST_ALG_SM3,
|
||||
DIGEST_ALG_COUNT,
|
||||
} digest_alg_en;
|
||||
|
||||
typedef enum {
|
||||
SYMC_ALG_DES = 0,
|
||||
SYMC_ALG_3DES,
|
||||
SYMC_ALG_AES,
|
||||
SYMC_ALG_SM4,
|
||||
SYMC_ALG_SM1,
|
||||
SYMC_ALG_NULL_CIPHER,
|
||||
SYMC_ALG_COUNT,
|
||||
} symc_alg_en;
|
||||
|
||||
typedef enum {
|
||||
SYMC_DAT_WIDTH_128 = 0,
|
||||
SYMC_DAT_WIDTH_64 = 0,
|
||||
SYMC_DAT_WIDTH_8,
|
||||
SYMC_DAT_WIDTH_1,
|
||||
SYMC_DAT_WIDTH_COUNT,
|
||||
} symc_dat_width_en;
|
||||
|
||||
typedef enum {
|
||||
SYMC_MODE_ECB = 0,
|
||||
SYMC_MODE_CBC,
|
||||
SYMC_MODE_CFB,
|
||||
SYMC_MODE_OFB,
|
||||
SYMC_MODE_CTR,
|
||||
SYMC_MODE_COUNT,
|
||||
} symc_mode_en;
|
||||
|
||||
typedef enum {
|
||||
SPACC_BUF_TYPE_SYMC_IN,
|
||||
SPACC_BUF_TYPE_SYMC_OUT,
|
||||
SPACC_BUF_TYPE_DIGEST_IN,
|
||||
SPACC_BUF_TYPE_COUNT,
|
||||
} spacc_buf_type_en;
|
||||
|
||||
typedef enum {
|
||||
SPACC_CTRL_NONE = 0x00,
|
||||
SPACC_CTRL_SYMC_IN_GCM_A = 0x00,
|
||||
SPACC_CTRL_SYMC_IN_GCM_P = 0x08,
|
||||
SPACC_CTRL_SYMC_IN_GCM_LEN = 0x10,
|
||||
SPACC_CTRL_SYMC_IN_CCM_N = 0x00,
|
||||
SPACC_CTRL_SYMC_IN_CCM_A = 0x08,
|
||||
SPACC_CTRL_SYMC_IN_CCM_P = 0x10,
|
||||
SPACC_CTRL_SYMC_IN_CBC_OUTPUT_DISABLE = 0x04,
|
||||
SPACC_CTRL_SYMC_IN_FIRST = 0x01,
|
||||
SPACC_CTRL_SYMC_IN_LAST = 0x02,
|
||||
SPACC_CTRL_HASH_IN_PAD = 0x04,
|
||||
SPACC_CTRL_HASH_IN_FIRST = 0x01,
|
||||
SPACC_CTRL_HASH_IN_LAST = 0x02,
|
||||
SPACC_CTRL_HASH_IN_AUTO_PADDING = 0x04,
|
||||
SPACC_CTRL_HASH_IN_HMAC_END = 0x08,
|
||||
SPACC_CTRL_SYMC_OUT_LAST = 0x02,
|
||||
SPACC_CTRL_SYMC_CCM_LAST = 0x20,
|
||||
SPACC_CTRL_SYMC_ODD_KEY = 0x40,
|
||||
SPACC_CTRL_SYMC_EVEN_KEY = 0x00,
|
||||
SPACC_CTRL_COUNT,
|
||||
} spacc_ctrl_en;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 hard_chn;
|
||||
xmedia_u32 sha_val[SHA256_RESULT_IN_WORD]; /* 16 size */
|
||||
xmedia_u32 data_phy;
|
||||
xmedia_u32 data_phy_high;
|
||||
xmedia_u32 data_len;
|
||||
} cipher_hash_data_s;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 src_phy_addr;
|
||||
xmedia_u32 src_phy_addr_high;
|
||||
xmedia_u32 dest_phy_addr;
|
||||
xmedia_u32 dest_phy_addr_high;
|
||||
xmedia_u32 data_length;
|
||||
} cipher_data_s;
|
||||
|
||||
typedef enum {
|
||||
SYMC_KEY_SRC_USER = 0x0,
|
||||
SYMC_KEY_SRC_KLAD_0,
|
||||
SYMC_KEY_SRC_KLAD_1,
|
||||
SYMC_KEY_SRC_KLAD_2,
|
||||
SYMC_KEY_SRC_KLAD_3,
|
||||
SYMC_KEY_SRC_BUTT,
|
||||
} symc_key_type;
|
||||
|
||||
typedef struct {
|
||||
symc_alg_en symc_alg;
|
||||
symc_mode_en symc_mode;
|
||||
symc_dat_width_en symc_width;
|
||||
xmedia_u32 key_len;
|
||||
xmedia_bool is_encrypt;
|
||||
symc_key_type key_type;
|
||||
} spacc_symc_config_s;
|
||||
|
||||
xmedia_s32 drv_cipher_sha256_update(cipher_hash_data_s *cipher_hash_data);
|
||||
xmedia_s32 drv_cipher_sha256_final(cipher_hash_data_s *cipher_hash_data);
|
||||
xmedia_s32 drv_cipher_init(xmedia_void);
|
||||
xmedia_s32 drv_cipher_deinit(xmedia_void);
|
||||
xmedia_s32 drv_cipher_config_aes_chn(cipher_ctrl *config, xmedia_bool is_encrypt);
|
||||
xmedia_s32 drv_cipher_aes(cipher_data_s *ci_data);
|
||||
xmedia_s32 drv_cipher_klad_load_key(xmedia_u32 chn_id, xmedia_u32* data_in, xmedia_u32 key_len, xmedia_cipher_key_type key_type);
|
||||
void cipher_debug_log(unsigned short errflag);
|
||||
#endif
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "xmedia_cipher_osal.h"
|
||||
|
||||
/*KLAD*/
|
||||
#define KLAD_REG_BASE_ADDR g_klad_base
|
||||
#define KLAD_REG_KLAD_CTRL (KLAD_REG_BASE_ADDR + 0x0420)
|
||||
#define KLAD_REG_DAT_IN (KLAD_REG_BASE_ADDR + 0x0400)
|
||||
|
||||
#define KLAD_KEY_LEN 4
|
||||
#define CIPHER_WAIT_IDEL_TIMES 300000
|
||||
|
||||
/*OTP USER*/
|
||||
#define OTP_USER_IF_BASE g_efuse_otp_reg_base
|
||||
#define OTP_USER_WORK_MODE (OTP_USER_IF_BASE + 0x0000)
|
||||
#define OTP_USER_OP_START (OTP_USER_IF_BASE + 0x0004)
|
||||
#define OTP_USER_KEY_INDEX (OTP_USER_IF_BASE + 0x0008)
|
||||
#define OTP_USER_CTRL_STA (OTP_USER_IF_BASE + 0x003C)
|
||||
|
||||
#define REG_SYS_OTP_CLK_ADDR_PHY 0x120101BC
|
||||
#define OTP_CRG_CLOCK_BIT (0x01 << 1)
|
||||
|
||||
typedef enum {
|
||||
OTP_USER_KEY0,
|
||||
OTP_USER_KEY1,
|
||||
OTP_USER_KEY2,
|
||||
OTP_USER_KEY3,
|
||||
OTP_USER_KEY_ROOTKEY,
|
||||
OTP_USER_KEY_HMACKEY,
|
||||
OTP_USER_KEY_UNKNOWN,
|
||||
} otp_user_key_index_e;
|
||||
|
||||
typedef enum {
|
||||
OTP_IDEL_WORK_MODE,
|
||||
OTP_READ_LOCK_STA_MODE,
|
||||
OTP_LOAD_CIPHER_KEY_MODE,
|
||||
OTP_WRITE_KEY_ID_OR_PASSWD_MODE,
|
||||
OTP_KEY_ID_OR_PASSWD_CRC_MODE,
|
||||
OTP_SET_FLAG_ENABLE_MODE,
|
||||
OTP_WRITE_USER_ROOM_MODE,
|
||||
OTP_READ_USER_ROOM_MODE,
|
||||
OTP_UNKOOWN_MODE,
|
||||
} otp_user_work_mode_e;
|
||||
typedef enum {
|
||||
OTP_KEY_LENGTH_64BIT,
|
||||
OTP_KEY_LENGTH_128BIT,
|
||||
OTP_KEY_LENGTH_256BIT,
|
||||
OTP_KEY_LENGTH_UNSUPPORT,
|
||||
} otp_user_key_length_e;
|
||||
|
||||
static xmedia_void *g_klad_base = XMEDIA_NULL;
|
||||
static xmedia_void *g_efuse_otp_reg_base = XMEDIA_NULL;
|
||||
static xmedia_u32 g_klad_init_flag = 0;
|
||||
/* OTP init */
|
||||
static xmedia_s32 hal_efuse_otp_init(xmedia_void)
|
||||
{
|
||||
xmedia_u32 crg_value = 0;
|
||||
xmedia_u32 *sys_addr = XMEDIA_NULL;
|
||||
|
||||
sys_addr = cipher_ioremap_nocache(REG_SYS_OTP_CLK_ADDR_PHY, 0x100);
|
||||
|
||||
crg_value = hal_cipher_read_reg(sys_addr);
|
||||
crg_value |= OTP_CRG_CLOCK_BIT; /* set the bit 0, clock opened */
|
||||
hal_cipher_write_reg(sys_addr, crg_value);
|
||||
|
||||
cipher_iounmap(sys_addr);
|
||||
sys_addr = XMEDIA_NULL;
|
||||
|
||||
g_efuse_otp_reg_base = cipher_ioremap_nocache(CIPHER_OTP_REG_BASE_ADDR_PHY, 0x100);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void hal_klad_init(xmedia_void)
|
||||
{
|
||||
xmedia_u32 crg_value;
|
||||
xmedia_u32 *sys_addr;
|
||||
|
||||
sys_addr = cipher_ioremap_nocache(CIPHER_KLAD_CRG_ADDR_PHY, 0x100);
|
||||
|
||||
crg_value = hal_cipher_read_reg(sys_addr);
|
||||
crg_value |= KLAD_CRG_RESET_BIT; /* reset */
|
||||
crg_value |= KLAD_CRG_CLOCK_BIT; /* set the bit 0, clock opened */
|
||||
hal_cipher_write_reg(sys_addr, crg_value);
|
||||
|
||||
cipher_usleep(10);
|
||||
|
||||
/* clock select and cancel reset 0x30100 */
|
||||
crg_value &= (~KLAD_CRG_RESET_BIT); /* cancel reset */
|
||||
crg_value |= KLAD_CRG_CLOCK_BIT; /* set the bit 0, clock opened */
|
||||
hal_cipher_write_reg(sys_addr, crg_value);
|
||||
|
||||
cipher_iounmap(sys_addr);
|
||||
}
|
||||
|
||||
xmedia_void xmedia_cipher_klad_deinit(xmedia_void)
|
||||
{
|
||||
if (g_klad_base != XMEDIA_NULL) {
|
||||
cipher_iounmap(g_klad_base);
|
||||
g_klad_base = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_efuse_otp_reg_base != XMEDIA_NULL) {
|
||||
cipher_iounmap(g_efuse_otp_reg_base);
|
||||
g_efuse_otp_reg_base = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
g_klad_init_flag = 0;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
static xmedia_s32 hal_otp_wait_free(xmedia_void)
|
||||
{
|
||||
xmedia_u32 timeout_cnt = 0;
|
||||
xmedia_u32 reg_value = 0;
|
||||
|
||||
while (1) {
|
||||
reg_value = hal_cipher_read_reg(OTP_USER_CTRL_STA);
|
||||
if ((reg_value & 0x1) == 0) /* bit0:otp_op_busy 0:idle, 1:busy */
|
||||
return XMEDIA_SUCCESS;
|
||||
|
||||
timeout_cnt++;
|
||||
if (timeout_cnt >= CIPHER_WAIT_IDEL_TIMES) {
|
||||
cipher_debug_log(CIPHER_ERR_OTP_WAIT_TIMEOUT); /*OTP_WaitFree TimeOut!*/
|
||||
break;
|
||||
}
|
||||
|
||||
cipher_usleep(10);
|
||||
}
|
||||
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
static xmedia_s32 hal_otp_wait_op_done(xmedia_void)
|
||||
{
|
||||
xmedia_u32 timeout_cnt = 0;
|
||||
xmedia_u32 reg_value = 0;
|
||||
|
||||
while (1) {
|
||||
reg_value = hal_cipher_read_reg(OTP_USER_CTRL_STA);
|
||||
if (reg_value & 0x2) { /* bit[1] otp_user_cmd_finish */
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
timeout_cnt++;
|
||||
if (timeout_cnt >= CIPHER_WAIT_IDEL_TIMES) {
|
||||
cipher_debug_log(CIPHER_ERR_OTP_WAIT_TIMEOUT); /*OTP_Wait_OP_done TimeOut!*/
|
||||
break;
|
||||
}
|
||||
|
||||
cipher_usleep(10);
|
||||
}
|
||||
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
static xmedia_s32 hal_cipher_wait_klad_done(void)
|
||||
{
|
||||
xmedia_u32 timeout_cnt = 0;
|
||||
xmedia_u32 reg_value;
|
||||
|
||||
|
||||
while (1) {
|
||||
reg_value = hal_cipher_read_reg(KLAD_REG_KLAD_CTRL);
|
||||
if ((reg_value & 0x2) == 0x00) /* bit[1] start: 1 busy; 0 free */
|
||||
return XMEDIA_SUCCESS;
|
||||
|
||||
timeout_cnt++;
|
||||
if (timeout_cnt >= CIPHER_WAIT_IDEL_TIMES) {
|
||||
cipher_debug_log(CIPHER_ERR_KLAD_WAIT_TIMEOUT); /*Klad time out!*/
|
||||
break;
|
||||
}
|
||||
|
||||
cipher_usleep(10);
|
||||
}
|
||||
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_cipher_klad_load_key(xmedia_u32 chn_id, xmedia_u32* data_in, xmedia_u32 key_len, xmedia_cipher_key_type key_type)
|
||||
{
|
||||
xmedia_u32 i = 0, j = 0, ctrl = 0, gh = 0;
|
||||
|
||||
if (g_klad_init_flag == 0) {
|
||||
g_klad_base = cipher_ioremap_nocache(CIPHER_KLAD_REG_BASE_ADDR_PHY, 0x100);
|
||||
|
||||
if (hal_efuse_otp_init() != XMEDIA_SUCCESS) {
|
||||
cipher_iounmap(g_klad_base);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
hal_klad_init();
|
||||
g_klad_init_flag = 1;
|
||||
}
|
||||
|
||||
/*1: set otp key to klad*/
|
||||
/*wait otp idle*/
|
||||
if (XMEDIA_SUCCESS != hal_otp_wait_free())
|
||||
return XMEDIA_FAILURE;
|
||||
|
||||
/*select key 0*/
|
||||
hal_cipher_write_reg(OTP_USER_KEY_INDEX, (xmedia_u32)(key_type - 1));
|
||||
|
||||
/*mode*/
|
||||
hal_cipher_write_reg(OTP_USER_WORK_MODE, (xmedia_u32)OTP_LOAD_CIPHER_KEY_MODE);
|
||||
|
||||
/*op start*/
|
||||
hal_cipher_write_reg(OTP_USER_OP_START, (xmedia_u32)0x1acce551);
|
||||
|
||||
if (XMEDIA_SUCCESS != hal_otp_wait_op_done())
|
||||
return XMEDIA_FAILURE;
|
||||
|
||||
/*
|
||||
*klad config
|
||||
*bit[18:16]: Klad2ci addr
|
||||
*bit[4:3]: klad type, 00:cipher's klad, 01:rsa's klad
|
||||
*bit[2]: high/low 128bit flag. 0:low 128bit 1:high 128bit
|
||||
*bit[1]: 1:start
|
||||
*bit[0]: 1:decrypt
|
||||
*/
|
||||
ctrl = chn_id << 16;
|
||||
ctrl |= (xmedia_u32)XMEDIA_CIPHER_KLAD_TARGET_AES << 3;
|
||||
ctrl |= (xmedia_u32)1;
|
||||
hal_cipher_write_reg(KLAD_REG_KLAD_CTRL, ctrl);
|
||||
|
||||
for (i = 0; i < key_len / 16; i++) {
|
||||
gh = (i == 1 ? 1 : 0);
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
hal_cipher_write_reg(KLAD_REG_DAT_IN + j * KLAD_KEY_LEN, data_in[i * 4 + j]);
|
||||
}
|
||||
|
||||
/* start */
|
||||
ctrl = hal_cipher_read_reg(KLAD_REG_KLAD_CTRL);
|
||||
ctrl &= ~(0x01 << 2);
|
||||
ctrl |= gh << 2;
|
||||
ctrl |= 0x2;
|
||||
hal_cipher_write_reg(KLAD_REG_KLAD_CTRL, ctrl);
|
||||
|
||||
//wait lock done
|
||||
if (XMEDIA_SUCCESS != hal_cipher_wait_klad_done())
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __XMDEDIA_CIPHER_OSAL_H_
|
||||
#define __XMDEDIA_CIPHER_OSAL_H_
|
||||
|
||||
#include "linux/lotus/securec.h"
|
||||
#include "linux/delay.h"
|
||||
#include "common.h"
|
||||
#include "xmedia_type.h"
|
||||
#include "xmedia_cipher.h"
|
||||
#include "xmedia_cipher_drv.h"
|
||||
#include "xmedia_cipher_config.h"
|
||||
|
||||
/**************************** M A C R O ****************************/
|
||||
#define cipher_min(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define get_ulong_low(dw) (unsigned int)(dw)
|
||||
#define get_ulong_high(dw) 0
|
||||
#define make_ulong(low, high) (low)
|
||||
|
||||
#define u32_to_point(addr) ((xmedia_void*)((xmedia_size_t)(addr)))
|
||||
#define point_to_u32(addr) ((xmedia_u32)((xmedia_size_t)(addr)))
|
||||
|
||||
|
||||
#define hal_cipher_read_reg(addr) (*(volatile unsigned int *)(addr))
|
||||
#define hal_cipher_write_reg(addr, result) (*(volatile unsigned int *)(addr) = (result))
|
||||
//#define hal_cipher_read_reg(addr) reg_get(addr)
|
||||
//#define hal_cipher_write_reg(addr, result) reg_set(addr, result)
|
||||
|
||||
|
||||
#define hal_set_bit(src, bit) ((src) |= (1 << (bit)))
|
||||
#define hal_clear_bit(src, bit) ((src) &= ~(1 << (bit)))
|
||||
#define cipher_cpu_to_be16(v) (((v) << 8) | ((v) >> 8))
|
||||
//#define cipher_cpu_to_be32(v) (((v) >> 24) | (((v) >> 8) & 0xff00) | (((v) << 8) & 0xff0000) | ((v) << 24))
|
||||
#define cipher_cpu_to_be32(v) (((v) >> 24) | (((v) >> 8) & 0xff00) | (((v)&0x0000ff00)<<8) | (((v)&0x000000ff)<<24))
|
||||
#define cipher_cpu_to_be64(x) ((xmedia_u64)( \
|
||||
(((x) & 0x00000000000000ffULL) << 56) | (((x) & 0x000000000000ff00ULL) << 40) | \
|
||||
(((x) & 0x0000000000ff0000ULL) << 24) | (((x) & 0x00000000ff000000ULL) << 8) | \
|
||||
(((x) & 0x000000ff00000000ULL) >> 8) | (((x) & 0x0000ff0000000000ULL) >> 24) | \
|
||||
(((x) & 0x00ff000000000000ULL) >> 40) | (((x) & 0xff00000000000000ULL) >> 56)))
|
||||
/**************************** S T D L I B ****************************/
|
||||
#define cipher_ioremap_nocache(addr, size) (xmedia_void*)(addr)
|
||||
#define cipher_iounmap(x)
|
||||
|
||||
#define CIPHER_MUTEX xmedia_void *
|
||||
#define cipher_mutex_init(x)
|
||||
#define cipher_mutex_lock(x)
|
||||
#define cipher_mutex_unlock(x)
|
||||
#define cipher_mutex_destroy(x)
|
||||
|
||||
#define CIPHER_QUEUE_HEAD xmedia_void *
|
||||
#define cipher_queue_init(x)
|
||||
#define cipher_queue_wait_up(x)
|
||||
#define cipher_queue_wait_timeout(head, con, time)
|
||||
|
||||
#define cipher_malloc(x) malloc(x)
|
||||
#define cipher_free(x) free(x)
|
||||
|
||||
#define crypto_memset(d,dmax,c,l) memset_s(d,dmax,c,l)
|
||||
#define crypto_memcmp(a,b,c) ((0 == memcmp(a,b,c))?(XMEDIA_SUCCESS):(XMEDIA_FAILURE))
|
||||
#define crypto_memcpy(d,dmax,s,l) memcpy_s(d,dmax,s,l)
|
||||
|
||||
#define cipher_msleep(msec) udelay((msec)*1000)
|
||||
#define cipher_usleep(usec) udelay(usec)
|
||||
|
||||
#define xmedia_err_cipher(a) printf("%s", a)
|
||||
#endif
|
||||
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _XMDEDIA_CIPHER_REG_H_
|
||||
#define _XMDEDIA_CIPHER_REG_H_
|
||||
|
||||
#define cipher_key(id) (g_spacc_reg_base + 0x0500 + (id) * 0x20)
|
||||
#define ODD_EVEN_KEY_SEL (g_spacc_reg_base + 0x0690)
|
||||
#define CALC_ERR (g_spacc_reg_base + 0x0720)
|
||||
#define CIPHER_INT_RAW (g_spacc_reg_base + 0x0808)
|
||||
#define chn_n_cipher_ctrl(id) (g_spacc_reg_base + 0x0800 + (id) * 0x80)
|
||||
#define chn_n_cipher_in_node_cfg(id) (g_spacc_reg_base + 0x0804 + (id) * 0x80)
|
||||
#define chn_n_cipher_in_node_start_addr(id) (g_spacc_reg_base + 0x0808 + (id) * 0x80)
|
||||
#define chn_n_cipher_in_buf_rptr(id) (g_spacc_reg_base + 0x080C + (id) * 0x80)
|
||||
#define chn_n_cipher_out_node_cfg(id) (g_spacc_reg_base + 0x0830 + (id) * 0x80)
|
||||
#define chn_n_cipher_out_node_start_addr(id) (g_spacc_reg_base + 0x0834 + (id) * 0x80)
|
||||
#define chn_n_cipher_out_buf_rptr(id) (g_spacc_reg_base + 0x0838 + (id) * 0x80)
|
||||
#define chn_n_cipher_in_node_start_addr_high(id) (g_spacc_reg_base + 0x0860 + (id) * 0x80)
|
||||
#define chn_n_cipher_out_node_start_addr_high(id) (g_spacc_reg_base + 0x0870 + (id) * 0x80)
|
||||
|
||||
#define HASH_INT_RAW (g_spacc_reg_base + 0x0C0C)
|
||||
#define chn_n_hash_ctrl(id) (g_spacc_reg_base + 0x0C00 + (id) * 0x80)
|
||||
#define chn_n_hash_in_node_cfg(id) (g_spacc_reg_base + 0x0C04 + (id) * 0x80)
|
||||
#define chn_n_hash_in_node_start_addr(id) (g_spacc_reg_base + 0x0C08 + (id) * 0x80)
|
||||
#define chn_n_hash_in_buf_rptr(id) (g_spacc_reg_base + 0x0C0C + (id) * 0x80)
|
||||
#define chn_n_hash_state_val(id) (g_spacc_reg_base + 0x0740 + (id) * 0x08)
|
||||
#define chn_n_hash_state_val_addr(id) (g_spacc_reg_base + 0x0744 + (id) * 0x08)
|
||||
#define chn_n_hash_in_node_start_addr_high(id) (g_spacc_reg_base + 0x0C20 + (id) * 0x80)
|
||||
|
||||
#define spacc_read(addr) *(volatile unsigned int *)(addr)
|
||||
#define spacc_write(addr, val) *(volatile unsigned int *)(addr) = (val)
|
||||
|
||||
/* Define the union u_hdcp_mode_ctrl */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int hdcp_mode_en : 1 ; /* [0] */
|
||||
unsigned int hdcp_rootkey_sel : 2 ; /* [2..1] */
|
||||
unsigned int reserved_0 : 1 ; /* [3] */
|
||||
unsigned int hdmi_tx_hdcp14_wr_en : 1 ; /* [4] */
|
||||
unsigned int hdmi_rx_hdcp14_wr_en : 1 ; /* [5] */
|
||||
unsigned int hdmi_rx_hdcp22_wr_en : 1 ; /* [6] */
|
||||
unsigned int reserved_1 : 1 ; /* [7] */
|
||||
unsigned int hdcp_wr_sel : 2 ; /* [9..8] */
|
||||
unsigned int reserved_2 : 22 ; /* [31..10] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_hdcp_mode_ctrl;
|
||||
|
||||
/* Define the union u_sec_chn_cfg */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int cipher_sec_chn_cfg : 8 ; /* [7..0] */
|
||||
unsigned int cipher_sec_chn_cfg_lock : 1 ; /* [8] */
|
||||
unsigned int reserved_0 : 7 ; /* [15..9] */
|
||||
unsigned int hash_sec_chn_cfg : 8 ; /* [23..16] */
|
||||
unsigned int hash_sec_chn_cfg_lock : 1 ; /* [24] */
|
||||
unsigned int reserved_1 : 7 ; /* [31..25] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_sec_chn_cfg;
|
||||
|
||||
/* Define the union u_mem_ema_cfg */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int rfs_ema : 3 ; /* [2..0] */
|
||||
unsigned int reserved_0 : 1 ; /* [3] */
|
||||
unsigned int rfs_emaw : 2 ; /* [5..4] */
|
||||
unsigned int reserved_1 : 2 ; /* [7..6] */
|
||||
unsigned int rft_emaa : 3 ; /* [10..8] */
|
||||
unsigned int rft_emab : 3 ; /* [13..11] */
|
||||
unsigned int rft_emasa : 1 ; /* [14] */
|
||||
unsigned int rft_colldisn : 1 ; /* [15] */
|
||||
unsigned int reserved_2 : 16 ; /* [31..16] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_mem_ema_cfg;
|
||||
|
||||
/* Define the union u_key_st */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int key_req_cur_st : 2 ; /* [1..0] */
|
||||
unsigned int reserved_0 : 30 ; /* [31..2] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_key_st;
|
||||
|
||||
/* Define the union u_calc_st0 */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int cipher_calc_cur_st : 4 ; /* [3..0] */
|
||||
unsigned int reserved_0 : 4 ; /* [7..4] */
|
||||
unsigned int hash_calc_cur_st : 4 ; /* [11..8] */
|
||||
unsigned int hdcp_key_ksv_crc4 : 4 ; /* [15..12] */
|
||||
unsigned int reserved_1 : 16 ; /* [31..16] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_calc_st0;
|
||||
|
||||
/* Define the union u_calc_err */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int klad_key_use_err : 1 ; /* [0] */
|
||||
unsigned int alg_len_err : 1 ; /* [1] */
|
||||
unsigned int smmu_page_unvlid : 1 ; /* [2] */
|
||||
unsigned int reserved_0 : 29 ; /* [31..3] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_calc_err;
|
||||
|
||||
/* Define the union u_chann_hash_state_val_addr */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int hash_state_val_addr : 4 ; /* [3..0] */
|
||||
unsigned int reserved_0 : 28 ; /* [31..4] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chann_hash_state_val_addr;
|
||||
|
||||
/* Define the union u_chan0_cipher_ctrl */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int sym_ch0_start : 1 ; /* [0] */
|
||||
unsigned int sym_ch0_alg_mode : 3 ; /* [3..1] */
|
||||
unsigned int sym_ch0_alg_sel : 3 ; /* [6..4] */
|
||||
unsigned int sym_ch0_decrypt : 1 ; /* [7] */
|
||||
unsigned int sym_ch0_dat_width : 2 ; /* [9..8] */
|
||||
unsigned int sym_ch0_key_length : 2 ; /* [11..10] */
|
||||
unsigned int sym_ch0_ccm_gcm_input_flag : 2 ; /* [13..12] */
|
||||
unsigned int sym_ch0_key_sel : 1 ; /* [14] */
|
||||
unsigned int sym_ch0_ivin_sel : 1 ; /* [15] */
|
||||
unsigned int reserved_0 : 2 ; /* [17..16] */
|
||||
unsigned int sym_ch0_sm1_round_num : 2 ; /* [19..18] */
|
||||
unsigned int sym_ch0_gcm_iv_len : 4 ; /* [23..20] */
|
||||
unsigned int sym_ch0_ccm_gcm_pc_last : 1 ; /* [24] */
|
||||
unsigned int sym_ccm_gcm_last_block : 4 ; /* [28..25] */
|
||||
unsigned int reserved_1 : 3 ; /* [31..28] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chan0_cipher_ctrl;
|
||||
|
||||
/* Define the union u_cipher_int_status */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int reserved_0 : 1 ; /* [0] */
|
||||
unsigned int cipher_chn_ibuf_int : 7 ; /* [7..1] */
|
||||
unsigned int cipher_chn_obuf_int : 8 ; /* [15..8] */
|
||||
unsigned int reserved_1 : 16 ; /* [31..16] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_cipher_int_status;
|
||||
|
||||
/* Define the union u_cipher_int_en */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int reserved_0 : 1 ; /* [0] */
|
||||
unsigned int cipher_chn_ibuf_en : 7 ; /* [7..1] */
|
||||
unsigned int cipher_chn_obuf_en : 8 ; /* [15..8] */
|
||||
unsigned int reserved_1 : 14 ; /* [29..16] */
|
||||
unsigned int cipher_sec_int_en : 1 ; /* [30] */
|
||||
unsigned int cipher_nsec_int_en : 1 ; /* [31] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_cipher_int_en;
|
||||
|
||||
/* Define the union u_cipher_int_raw */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int reserved_0 : 1 ; /* [0] */
|
||||
unsigned int cipher_chn_ibuf_raw : 7 ; /* [7..1] */
|
||||
unsigned int cipher_chn_obuf_raw : 8 ; /* [15..8] */
|
||||
unsigned int reserved_1 : 16 ; /* [31..16] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_cipher_int_raw;
|
||||
|
||||
/* Define the union u_cipher_in_smmu_en */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int cipher_in_chan_rd_dat_smmu_en : 7 ; /* [6..0] */
|
||||
unsigned int reserved_0 : 9 ; /* [15..7] */
|
||||
unsigned int cipher_in_chan_rd_node_smmu_en : 7 ; /* [22..16] */
|
||||
unsigned int reserved_1 : 9 ; /* [31..23] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_cipher_in_smmu_en;
|
||||
|
||||
/* Define the union u_out_smmu_en */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int out_chan_wr_dat_smmu_en : 7 ; /* [6..0] */
|
||||
unsigned int reserved_0 : 9 ; /* [15..7] */
|
||||
unsigned int out_chan_rd_node_smmu_en : 7 ; /* [22..16] */
|
||||
unsigned int reserved_1 : 9 ; /* [31..23] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_out_smmu_en;
|
||||
|
||||
/* Define the union u_in_st */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int hash_in_ctrl_cur_st : 5 ; /* [4..0] */
|
||||
unsigned int sym_in_ctrl_cur_st : 3 ; /* [7..5] */
|
||||
unsigned int sym_hash_req_cur_st : 4 ; /* [11..8] */
|
||||
unsigned int reserved_0 : 20 ; /* [31..12] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_in_st;
|
||||
|
||||
/* Define the union u_out_st */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int out_cur_st : 5 ; /* [4..0] */
|
||||
unsigned int reserved_0 : 27 ; /* [31..5] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_out_st;
|
||||
|
||||
/* Define the union u_chann_cipher_ctrl */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int reserved_0 : 1 ; /* [0] */
|
||||
unsigned int sym_chn_alg_mode : 3 ; /* [3..1] */
|
||||
unsigned int sym_chn_alg_sel : 3 ; /* [6..4] */
|
||||
unsigned int sym_chn_decrypt : 1 ; /* [7] */
|
||||
unsigned int sym_chn_dat_width : 2 ; /* [9..8] */
|
||||
unsigned int sym_chn_key_length : 2 ; /* [11..10] */
|
||||
unsigned int reserved_1 : 2 ; /* [13..12] */
|
||||
unsigned int sym_chn_key_sel : 1 ; /* [14] */
|
||||
unsigned int reserved_2 : 1 ; /* [15] */
|
||||
unsigned int sym_chn_dout_byte_swap_en : 1 ; /* [16] */
|
||||
unsigned int sym_chn_din_byte_swap_en : 1 ; /* [17] */
|
||||
unsigned int sym_chn_sm1_round_num : 2 ; /* [19..18] */
|
||||
unsigned int reserved_3 : 2 ; /* [21..20] */
|
||||
unsigned int weight : 10 ; /* [31..22] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chann_cipher_ctrl;
|
||||
|
||||
/* Define the union u_chann_cipher_in_node_cfg */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int cipher_in_node_mpackage_int_level : 7 ; /* [6..0] */
|
||||
unsigned int reserved_0 : 1 ; /* [7] */
|
||||
unsigned int cipher_in_node_rptr : 7 ; /* [14..8] */
|
||||
unsigned int reserved_1 : 1 ; /* [15] */
|
||||
unsigned int cipher_in_node_wptr : 7 ; /* [22..16] */
|
||||
unsigned int reserved_2 : 1 ; /* [23] */
|
||||
unsigned int cipher_in_node_total_num : 7 ; /* [30..24] */
|
||||
unsigned int reserved_3 : 1 ; /* [31] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chann_cipher_in_node_cfg;
|
||||
|
||||
/* Define the union u_chann_cipher_in_left_byte */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int in_left_byte0 : 24 ; /* [23..0] */
|
||||
unsigned int in_byte_cnt : 2 ; /* [25..24] */
|
||||
unsigned int in_word_cnt : 2 ; /* [27..26] */
|
||||
unsigned int reserved_0 : 4 ; /* [31..28] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chann_cipher_in_left_byte;
|
||||
|
||||
/* Define the union u_chann_cipher_out_node_cfg */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int cipher_out_node_mpackage_int_level : 7 ; /* [6..0] */
|
||||
unsigned int reserved_0 : 1 ; /* [7] */
|
||||
unsigned int cipher_out_node_rptr : 7 ; /* [14..8] */
|
||||
unsigned int reserved_1 : 1 ; /* [15] */
|
||||
unsigned int cipher_out_node_wptr : 7 ; /* [22..16] */
|
||||
unsigned int reserved_2 : 1 ; /* [23] */
|
||||
unsigned int cipher_out_node_total_num : 7 ; /* [30..24] */
|
||||
unsigned int reserved_3 : 1 ; /* [31] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chann_cipher_out_node_cfg;
|
||||
|
||||
/* Define the union u_chann_cipher_out_left_byte */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int out_left_byte0 : 24 ; /* [23..0] */
|
||||
unsigned int out_byte_cnt : 2 ; /* [25..24] */
|
||||
unsigned int out_word_cnt : 2 ; /* [27..26] */
|
||||
unsigned int reserved_0 : 4 ; /* [31..28] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chann_cipher_out_left_byte;
|
||||
|
||||
/* Define the union u_chan0_hash_ctrl */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int hash_ch0_start : 1 ; /* [0] */
|
||||
unsigned int hash_ch0_agl_sel : 3 ; /* [3..1] */
|
||||
unsigned int hash_ch0_hmac_calc_step : 1 ; /* [4] */
|
||||
unsigned int hash_ch0_mode : 1 ; /* [5] */
|
||||
unsigned int hash_ch0_key_sel : 1 ; /* [6] */
|
||||
unsigned int reserved_0 : 2 ; /* [8..7] */
|
||||
unsigned int hash_ch0_auto_padding_en : 1 ; /* [9] */
|
||||
unsigned int hash_ch0_hmac_key_addr : 3 ; /* [12..10] */
|
||||
unsigned int hash_ch0_used : 1 ; /* [13] */
|
||||
unsigned int hash_ch0_sec_alarm : 1 ; /* [13] */
|
||||
unsigned int reserved_1 : 17 ; /* [31..15] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chan0_hash_ctrl;
|
||||
|
||||
/* Define the union u_hash_int_status */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int reserved_0 : 18 ; /* [17..0] */
|
||||
unsigned int hash_ch0_oram_int : 1 ; /* [18] */
|
||||
unsigned int hash_ch1_oram_int : 1 ; /* [19] */
|
||||
unsigned int hash_ch2_oram_int : 1 ; /* [20] */
|
||||
unsigned int hash_ch3_oram_int : 1 ; /* [21] */
|
||||
unsigned int hash_ch4_oram_int : 1 ; /* [22] */
|
||||
unsigned int hash_ch5_oram_int : 1 ; /* [23] */
|
||||
unsigned int hash_ch6_oram_int : 1 ; /* [24] */
|
||||
unsigned int hash_ch7_oram_int : 1 ; /* [25] */
|
||||
unsigned int reserved_1 : 6 ; /* [31..26] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_hash_int_status;
|
||||
|
||||
/* Define the union u_hash_int_en */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int reserved_0 : 18 ; /* [17..0] */
|
||||
unsigned int hash_chn_oram_en : 8 ; /* [25..18] */
|
||||
unsigned int reserved_1 : 4 ; /* [29..26] */
|
||||
unsigned int hash_sec_int_en : 1 ; /* [30] */
|
||||
unsigned int hash_int_en : 1 ; /* [31] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_hash_int_en;
|
||||
|
||||
/* Define the union u_hash_int_raw */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int reserved_0 : 18 ; /* [17..0] */
|
||||
unsigned int hash_chn_oram_raw : 8 ; /* [25..18] */
|
||||
unsigned int reserved_1 : 6 ; /* [31..26] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_hash_int_raw;
|
||||
|
||||
/* Define the union u_hash_in_smmu_en */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int hash_in_chan_rd_dat_smmu_en : 7 ; /* [6..0] */
|
||||
unsigned int reserved_0 : 9 ; /* [15..7] */
|
||||
unsigned int hash_in_chan_rd_node_smmu_en : 7 ; /* [22..16] */
|
||||
unsigned int reserved_1 : 9 ; /* [31..23] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_hash_in_smmu_en;
|
||||
|
||||
/* Define the union u_chann_hash_ctrl */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int reserved_0 : 1 ; /* [0] */
|
||||
unsigned int hash_chn_agl_sel : 3 ; /* [3..1] */
|
||||
unsigned int reserved_1 : 1 ; /* [4] */
|
||||
unsigned int hash_chn_mode : 1 ; /* [5] */
|
||||
unsigned int hash_chn_key_sel : 1 ; /* [6] */
|
||||
unsigned int hash_chn_dat_in_byte_swap_en : 1 ; /* [7] */
|
||||
unsigned int hash_chn_dat_in_bit_swap_en : 1 ; /* [8] */
|
||||
unsigned int hash_chn_auto_padding_en : 1 ; /* [9] */
|
||||
unsigned int hash_chn_hmac_key_addr : 3 ; /* [12..10] */
|
||||
unsigned int reserved_2 : 19 ; /* [31..13] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chann_hash_ctrl;
|
||||
|
||||
/* Define the union u_chann_hash_in_node_cfg */
|
||||
typedef union {
|
||||
/* Define the struct bits */
|
||||
struct {
|
||||
unsigned int hash_in_node_mpackage_int_level : 8 ; /* [7..0] */
|
||||
unsigned int hash_in_node_rptr : 8 ; /* [15..8] */
|
||||
unsigned int hash_in_node_wptr : 8 ; /* [23..16] */
|
||||
unsigned int hash_in_node_total_num : 8 ; /* [31..24] */
|
||||
} bits;
|
||||
|
||||
/* Define an unsigned member */
|
||||
unsigned int u32;
|
||||
} u_chann_hash_in_node_cfg;
|
||||
#endif
|
||||
@@ -0,0 +1,754 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "xmedia_cipher_osal.h"
|
||||
//#include "safety.h"
|
||||
|
||||
/************************************************************/
|
||||
static xmedia_void *g_rsa_reg_base = XMEDIA_NULL;
|
||||
static xmedia_void *g_rsa_reg_crg = XMEDIA_NULL;
|
||||
static xmedia_u32 rsa_init_flag = 0;
|
||||
|
||||
/************************************************************/
|
||||
#define RSA_REG_BASE_RSA g_rsa_reg_base
|
||||
#define SEC_RSA_BUSY_REG (RSA_REG_BASE_RSA + 0x010C)
|
||||
#define SEC_RSA_MOD_REG (RSA_REG_BASE_RSA + 0x0110)
|
||||
#define SEC_RSA_WSEC_REG (RSA_REG_BASE_RSA + 0x0104)
|
||||
#define SEC_RSA_WDAT_REG (RSA_REG_BASE_RSA + 0x0108)
|
||||
#define SEC_RSA_RRSLT_REG (RSA_REG_BASE_RSA + 0x0120)
|
||||
#define SEC_RSA_START_REG (RSA_REG_BASE_RSA + 0x0114)
|
||||
#define SEC_RSA_ERROR_REG (RSA_REG_BASE_RSA + 0x0124)
|
||||
|
||||
#define RSA_DATA_CLR_KEY (1 << 2)
|
||||
#define RSA_DATA_CLR_INPUT (2 << 2)
|
||||
#define RSA_DATA_CLR_OUTPUT (4 << 2)
|
||||
#define RSA_MOD_SEL (3 << 0)
|
||||
#define RSA_MOD_SEL_OPT (0 << 0)
|
||||
#define RSA_MOD_SEL_RAM_CLAER (2 << 0)
|
||||
#define RSA_BUSY (1 << 0)
|
||||
#define RSA_START (1 << 0)
|
||||
|
||||
#define RSA_MAX_KEY_LEN 512
|
||||
#define CRC16_POLYNOMIAL 0x1021
|
||||
|
||||
#define RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE 0x44
|
||||
#define RSA_PKCS1_PSS_PADDING_CHECK_MALLOC_SIZE 0x48
|
||||
|
||||
#define ASN1_HASH_SHA256 "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"
|
||||
#define SHA256_DATA_BYTE_LEN 32
|
||||
|
||||
typedef enum {
|
||||
RSA_DATA_TYPE_CONTEXT,
|
||||
RSA_DATA_TYPE_MODULE,
|
||||
RSA_DATA_TYPE_KEY,
|
||||
} rsa_data_type_e;
|
||||
|
||||
typedef enum {
|
||||
RSA_KEY_WIDTH_1K = 0x00,
|
||||
RSA_KEY_WIDTH_2K = 0x01,
|
||||
RSA_KEY_WIDTH_4K = 0x02,
|
||||
RSA_KEY_WIDTH_3K = 0x03,
|
||||
RSA_KEY_WIDTH_BUTT = 0xff,
|
||||
} rsa_key_width_e;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 hlen;
|
||||
xmedia_u32 klen;
|
||||
xmedia_u32 em_bit;
|
||||
xmedia_u8 *in_data;
|
||||
xmedia_u32 in_len;
|
||||
} rsa_padding_s;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u8 *masked_db;
|
||||
xmedia_u8 *masked_seed;
|
||||
xmedia_u8 salt[RSA_MAX_KEY_LEN];
|
||||
xmedia_u32 msb_bits;
|
||||
xmedia_u32 slen;
|
||||
xmedia_u32 key_len;
|
||||
} rsa_pkcs1_pss_s;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u8 *input_data;
|
||||
xmedia_u8 *output_data;
|
||||
xmedia_u32 data_len;
|
||||
xmedia_u8 *rsa_n;
|
||||
xmedia_u8 *rsa_k;
|
||||
xmedia_u16 rsa_n_len;
|
||||
xmedia_u16 rsa_k_len;
|
||||
} rsa_data_s;
|
||||
|
||||
static xmedia_void hal_rsa_start(xmedia_void)
|
||||
{
|
||||
hal_cipher_write_reg(SEC_RSA_START_REG, 0x01);
|
||||
}
|
||||
|
||||
static xmedia_s32 hal_rsa_wait_free(xmedia_void)
|
||||
{
|
||||
xmedia_u32 value;
|
||||
xmedia_u32 try_count = 0;
|
||||
|
||||
do {
|
||||
value = hal_cipher_read_reg(SEC_RSA_BUSY_REG);
|
||||
if ((value & RSA_BUSY) == 0)
|
||||
return XMEDIA_SUCCESS;
|
||||
try_count++;
|
||||
cipher_usleep(10);
|
||||
} while (try_count < RSA_TIMEOUT_CNT);
|
||||
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
static xmedia_void hal_rsa_clear_ram(xmedia_void)
|
||||
{
|
||||
xmedia_u32 value;
|
||||
|
||||
value = hal_cipher_read_reg(SEC_RSA_MOD_REG);
|
||||
value &= 0x60;
|
||||
value |= RSA_DATA_CLR_INPUT | RSA_DATA_CLR_OUTPUT | RSA_DATA_CLR_KEY | RSA_MOD_SEL_RAM_CLAER;
|
||||
hal_cipher_write_reg(SEC_RSA_MOD_REG, value);
|
||||
}
|
||||
|
||||
static xmedia_void hal_rsa_config_mode(rsa_key_width_e ken_width)
|
||||
{
|
||||
xmedia_u32 value;
|
||||
|
||||
value = ((xmedia_u32)ken_width << 5) | RSA_MOD_SEL_OPT; /* 5 left shift */
|
||||
hal_cipher_write_reg(SEC_RSA_MOD_REG, value);
|
||||
}
|
||||
|
||||
static xmedia_void hal_rsa_write_data(rsa_data_type_e data_type,
|
||||
xmedia_u8 *data,
|
||||
xmedia_u32 data_len,
|
||||
xmedia_u32 length,
|
||||
xmedia_u32 random[2]) /* 2 random size */
|
||||
{
|
||||
xmedia_u32 *reg = XMEDIA_NULL;
|
||||
xmedia_u8 *pos = XMEDIA_NULL;
|
||||
xmedia_u32 i, value;
|
||||
xmedia_bool id = 0;
|
||||
|
||||
if (data_type == RSA_DATA_TYPE_CONTEXT)
|
||||
reg = SEC_RSA_WDAT_REG;
|
||||
else
|
||||
reg = SEC_RSA_WSEC_REG;
|
||||
|
||||
pos = data;
|
||||
for (i = 0; i < length; i += 4) { /* 4 groups */
|
||||
value = (xmedia_u32)pos[0];
|
||||
value |= ((xmedia_u32)pos[1]) << 8; /* 1 index, 8 left shift */
|
||||
value |= ((xmedia_u32)pos[2]) << 16; /* 2 index, 16 left shift */
|
||||
value |= ((xmedia_u32)pos[3]) << 24; /* 3 index, 24 left shift */
|
||||
if (data_type != RSA_DATA_TYPE_CONTEXT)
|
||||
value ^= random[id];
|
||||
|
||||
hal_cipher_write_reg(reg, value);
|
||||
pos += 4; /* 4 groups */
|
||||
id = (xmedia_u32)id ^ 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
static xmedia_void hal_rsa_read_data(xmedia_u8 *data, xmedia_u32 data_len, xmedia_u32 klen)
|
||||
{
|
||||
xmedia_u32 value;
|
||||
xmedia_u8 *pos = XMEDIA_NULL;
|
||||
xmedia_u32 i;
|
||||
|
||||
pos = data;
|
||||
for (i = 0; i < klen; i += 4) { /* 4 groups */
|
||||
value = hal_cipher_read_reg(SEC_RSA_RRSLT_REG);
|
||||
pos[0] = (xmedia_u8)(value & 0xFF);
|
||||
pos[1] = (xmedia_u8)((value >> 8) & 0xFF); /* 1 index, 8 right shift */
|
||||
pos[2] = (xmedia_u8)((value >> 16) & 0xFF); /* 2 index, 16 right shift */
|
||||
pos[3] = (xmedia_u8)((value >> 24) & 0xFF); /* 3 index, 24 right shift */
|
||||
pos += 4; /* 4 groups */
|
||||
}
|
||||
}
|
||||
|
||||
static xmedia_u32 hal_rsa_get_error_code(xmedia_void)
|
||||
{
|
||||
xmedia_u32 value;
|
||||
|
||||
value = hal_cipher_read_reg(SEC_RSA_ERROR_REG);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static xmedia_void hal_rsa_enable(xmedia_void)
|
||||
{
|
||||
xmedia_u32 value;
|
||||
|
||||
value = hal_cipher_read_reg(g_rsa_reg_crg);
|
||||
hal_set_bit(value, 5); /* 5bit clock opened */
|
||||
hal_cipher_write_reg(g_rsa_reg_crg, value);
|
||||
cipher_usleep(10);
|
||||
|
||||
hal_clear_bit(value, 4); /* 4bit cancel reset */
|
||||
hal_cipher_write_reg(g_rsa_reg_crg, value);
|
||||
cipher_usleep(10);
|
||||
|
||||
//enable_rsa_safety();
|
||||
}
|
||||
|
||||
static xmedia_void hal_rsa_disable(xmedia_void)
|
||||
{
|
||||
xmedia_u32 value;
|
||||
|
||||
value = hal_cipher_read_reg(g_rsa_reg_crg);
|
||||
|
||||
hal_set_bit(value, 4); /* 4bit reset */
|
||||
hal_cipher_write_reg(g_rsa_reg_crg, value);
|
||||
cipher_usleep(10);
|
||||
|
||||
hal_clear_bit(value, 5); /* 5bit clock closed */
|
||||
hal_cipher_write_reg(g_rsa_reg_crg, value);
|
||||
cipher_usleep(10);
|
||||
}
|
||||
|
||||
static xmedia_u32 rsa_get_bit_num(xmedia_u8 *big_num, xmedia_u32 num_len)
|
||||
{
|
||||
static const xmedia_s8 bits[16] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; /* 16 bits size */
|
||||
xmedia_u32 i;
|
||||
|
||||
for (i = 0; i < num_len; i++) {
|
||||
xmedia_u32 num;
|
||||
num = bits[(big_num[i] & 0xF0) >> 4]; /* 4 right shift */
|
||||
|
||||
if (num > 0)
|
||||
return (num_len - i - 1) * 8 + num + 4; /* 8, 4 */
|
||||
|
||||
num = bits[big_num[i] & 0xF];
|
||||
if (num > 0)
|
||||
return (num_len - i - 1) * 8 + num; /* 8 */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static xmedia_s32 rsa_pkcs1_mgf1(xmedia_u8 *seed, xmedia_u32 seed_len, xmedia_u8 *mask, xmedia_u32 mask_len)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_FAILURE;
|
||||
xmedia_u32 i, out_len;
|
||||
xmedia_u8 *ptr_cnt = XMEDIA_NULL;
|
||||
xmedia_u8 *ptr_md = XMEDIA_NULL;
|
||||
xmedia_u8 *ptr_seed = XMEDIA_NULL;
|
||||
xmedia_u8 *ptr_malloc = XMEDIA_NULL;
|
||||
|
||||
ptr_malloc = (xmedia_u8 *)cipher_malloc(RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE);
|
||||
if (ptr_malloc == XMEDIA_NULL) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_MALLOC);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
crypto_memset(ptr_malloc, RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE, 0, RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE);
|
||||
|
||||
ptr_cnt = ptr_malloc;
|
||||
ptr_md = ptr_malloc + 4;
|
||||
ptr_seed = (ptr_malloc + 4 + SHA256_RESULT_SIZE);
|
||||
|
||||
crypto_memcpy(ptr_seed, (RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE - SHA256_RESULT_SIZE - 4), seed, seed_len);
|
||||
|
||||
/* PKCS#1 V2.1*/
|
||||
for (i = 0, out_len = 0; out_len < mask_len; i++) {
|
||||
xmedia_u32 j, md_len;
|
||||
|
||||
//sha256 fixed
|
||||
md_len = 32;
|
||||
|
||||
ptr_cnt[0] = (xmedia_u8)((i >> 24) & 0xFF); /* 0 ptr_cnt index, 24 right shift */
|
||||
ptr_cnt[1] = (xmedia_u8)((i >> 16) & 0xFF); /* 1 ptr_cnt index, 16 right shift */
|
||||
ptr_cnt[2] = (xmedia_u8)((i >> 8) & 0xFF); /* 2 ptr_cnt index, 8 right shift */
|
||||
ptr_cnt[3] = (xmedia_u8)(i & 0xFF); /* 3 ptr_cnt index */
|
||||
|
||||
ret = xmedia_cipher_sha256_init();
|
||||
ret |= xmedia_cipher_sha256_update(ptr_seed, seed_len);
|
||||
ret |= xmedia_cipher_sha256_update(ptr_cnt, 4); /* 4 ptr_cnt size */
|
||||
ret |= xmedia_cipher_sha256_final(ptr_md);
|
||||
if(ret != XMEDIA_SUCCESS)
|
||||
{
|
||||
cipher_debug_log(CIPHER_ERR_RSA_SHA256); /*sha256 failed*/
|
||||
goto free_ptr;
|
||||
}
|
||||
|
||||
for (j = 0; (j < md_len) && (out_len < mask_len); j++)
|
||||
mask[out_len++] ^= ptr_md[j];
|
||||
}
|
||||
|
||||
free_ptr:
|
||||
cipher_free(ptr_malloc);
|
||||
ptr_malloc = XMEDIA_NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static xmedia_s32 rsa_padding_check_pkcs1_pss_hash(rsa_padding_s *pad, xmedia_u8 *mhash, rsa_pkcs1_pss_s *pss)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
xmedia_u32 mlen;
|
||||
xmedia_u8 *ptr_m = XMEDIA_NULL;
|
||||
xmedia_u8 arr_h[SHA256_RESULT_SIZE];
|
||||
|
||||
/*8+32+32*/
|
||||
mlen = pss->slen + pad->hlen + 8; /* 8 */
|
||||
ptr_m = (xmedia_u8 *)cipher_malloc(RSA_PKCS1_PSS_PADDING_CHECK_MALLOC_SIZE);
|
||||
if(ptr_m == XMEDIA_NULL)
|
||||
{
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
crypto_memset(arr_h, SHA256_RESULT_SIZE, 0, SHA256_RESULT_SIZE);
|
||||
crypto_memset(ptr_m, RSA_PKCS1_PSS_PADDING_CHECK_MALLOC_SIZE, 0, mlen);
|
||||
|
||||
/* M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
|
||||
crypto_memset(ptr_m, mlen, 0x00, 8); /* 8, 0 counts */
|
||||
crypto_memcpy(&ptr_m[8], mlen - 8, mhash, pad->hlen); /* 8, 0 counts */
|
||||
crypto_memcpy(&ptr_m[8 + pad->hlen], mlen - 8 - pad->hlen, pss->salt, pss->slen); /* 8, 0 counts */
|
||||
|
||||
ret = xmedia_cipher_sha256_init();
|
||||
ret |= xmedia_cipher_sha256_update(ptr_m, mlen);
|
||||
ret |= xmedia_cipher_sha256_final(arr_h);
|
||||
|
||||
cipher_free(ptr_m); /* Must free ptr_m befort return */
|
||||
ptr_m = XMEDIA_NULL;
|
||||
if(ret != XMEDIA_SUCCESS)
|
||||
{
|
||||
cipher_debug_log(CIPHER_ERR_RSA_SHA256); /*sha256 failed*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if(crypto_memcmp(arr_h, pss->masked_seed, pad->hlen) != XMEDIA_SUCCESS)
|
||||
{
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_HASH_CMP); /*masked_seed cmp failed*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 rsa_padding_check_pkcs1_pss(rsa_padding_s *pad, xmedia_u8 *mhash)
|
||||
{
|
||||
xmedia_u32 ret;
|
||||
xmedia_u32 index, tmp_len;
|
||||
rsa_pkcs1_pss_s pss;
|
||||
|
||||
crypto_memset(&pss, sizeof(rsa_pkcs1_pss_s), 0, sizeof(rsa_pkcs1_pss_s));
|
||||
pss.slen = pad->hlen;
|
||||
pss.key_len = (pad->em_bit + 7) / 8; /* 7, 8 */
|
||||
pss.msb_bits = (pad->em_bit - 1) & 0x07;
|
||||
|
||||
if (pss.key_len < (pad->hlen + pss.slen + 2)) { /* 2 */
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_M_LEN); /*message too long*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (pad->in_data[0] & (0xFF << pss.msb_bits)) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM0); /*inconsistent, EM[0] invalid*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (pss.msb_bits == 0) {
|
||||
pad->in_data++;
|
||||
pss.key_len--;
|
||||
}
|
||||
|
||||
pss.masked_db = pad->in_data;
|
||||
pss.masked_seed = pad->in_data + pss.key_len - pad->hlen - 1;
|
||||
|
||||
if (pad->in_data[pss.key_len - 1] != 0xBC) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_BC); /*inconsistent, EM[key_len - 1] != 0xBC*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
/* formula: maskedDB = DB xor dbMask, DB = PS || 0x01 || salt */
|
||||
ret = rsa_pkcs1_mgf1(pss.masked_seed, pad->hlen, pss.masked_db, pss.key_len - pad->hlen - 1);
|
||||
if(ret != XMEDIA_SUCCESS)
|
||||
{
|
||||
cipher_debug_log(CIPHER_ERR_RSA_MGF1); /*rsa_pkcs1_mgf1 failed*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (pss.msb_bits)
|
||||
pss.masked_db[0] &= 0xFF >> (8 - pss.msb_bits); /* 8 */
|
||||
|
||||
tmp_len = pss.key_len - pss.slen - pad->hlen - 2; /* 2 */
|
||||
if (tmp_len >= RSA_MAX_KEY_LEN - 1) { /* -1 is for index++, avoid masked_db overflow */
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_MASKEDDB_LEN); /*operate masked_db maybe overflow*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
for (index = 0; index < tmp_len; index++) {
|
||||
if (pss.masked_db[index] != 0x00) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pss.slen = pss.key_len - pad->hlen - index - 2;
|
||||
|
||||
if(pss.masked_db[index] != 0x1)
|
||||
{
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_DB_1); /*check masked_db failed*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
index++;
|
||||
crypto_memcpy(pss.salt, sizeof(pss.salt), &pss.masked_db[index], pss.slen);
|
||||
|
||||
return rsa_padding_check_pkcs1_pss_hash(pad, mhash, &pss);
|
||||
}
|
||||
|
||||
static xmedia_s32 rsa_padding_check_pkcs1_v15(xmedia_u8 *mhash, xmedia_u32 hash_len, xmedia_u8 *em, xmedia_u32 key_len)
|
||||
{
|
||||
xmedia_u8 *data_hash[32];
|
||||
xmedia_u8 *p;
|
||||
xmedia_u32 t_len;
|
||||
|
||||
if (hash_len != SHA256_DATA_BYTE_LEN) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_SHA256_DATA_LEN); /* only support sha256 */
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
/* EM = 0x00 || 0x01 || PS || 0x00 || T */
|
||||
p = em;
|
||||
|
||||
if (*p++ != 0x0) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM_FIRSTBYTE); /* EM's first byte must be 0 */
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (*p++ != 0x1) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM_SECONDBYTE); /* EM's second byte must be 1 */
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
while (*p != 0) {
|
||||
if ((p >= em + key_len - 1) || (*p != 0xFF)) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM_PS); /* PS's every byte is 0xff */
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
p++; // skip 0x0 before T
|
||||
|
||||
t_len = key_len- (xmedia_u32)(p - em);
|
||||
if (t_len != (19 + hash_len)) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM_T_LEN); /* T length must be 51 (19 + 32), just for sha256 */
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (memcmp(p, ASN1_HASH_SHA256, 19)) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_ASN1_SHA256); /* just for sha256 */
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (memcmp(p + 19, mhash, hash_len)) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_VERIFY_SHA256_DATA); /* sha256 data invalid */
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_cipher_calc_rsa(rsa_data_s *rsa_data);
|
||||
static xmedia_s32 rsa_public(const cipher_rsa_pub_key *pub_key, const xmedia_u8 *input, xmedia_u8 *output)
|
||||
{
|
||||
rsa_data_s rsa_data;
|
||||
|
||||
rsa_data.rsa_n = pub_key->n;
|
||||
rsa_data.rsa_k = pub_key->e;
|
||||
rsa_data.rsa_n_len = pub_key->n_len;
|
||||
rsa_data.rsa_k_len = pub_key->e_len;
|
||||
rsa_data.input_data = (xmedia_u8 *)input;
|
||||
rsa_data.output_data = output;
|
||||
rsa_data.data_len = pub_key->n_len;
|
||||
|
||||
return drv_cipher_calc_rsa(&rsa_data);
|
||||
}
|
||||
|
||||
static xmedia_s32 rsa_verify_pad_init(rsa_padding_s *pad, const cipher_rsa_verify *rsa_verify,
|
||||
cipher_verify_data *verify_data, xmedia_u8 *arr_em)
|
||||
{
|
||||
/*fix here: only support sha256*/
|
||||
pad->hlen = SHA256_RESULT_SIZE; /* 32 pad hlen */
|
||||
pad->klen = rsa_verify->pub_key.n_len;
|
||||
pad->in_data = arr_em;
|
||||
pad->in_len = verify_data->sign_len;
|
||||
if(verify_data->sign_len != pad->klen)
|
||||
{
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return rsa_public(&rsa_verify->pub_key, verify_data->sign, pad->in_data);
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_rsa_init(xmedia_void)
|
||||
{
|
||||
g_rsa_reg_crg = cipher_ioremap_nocache(CIPHER_RSA_CRG_ADDR_PHY, 16); /* 16 */
|
||||
g_rsa_reg_base = cipher_ioremap_nocache(CIPHER_RSA_REG_BASE_ADDR_PHY, 0x1000);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void drv_rsa_deinit(xmedia_void)
|
||||
{
|
||||
if (g_rsa_reg_base != XMEDIA_NULL) {
|
||||
cipher_iounmap(g_rsa_reg_base);
|
||||
g_rsa_reg_base = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_rsa_reg_crg != XMEDIA_NULL) {
|
||||
cipher_iounmap(g_rsa_reg_crg);
|
||||
g_rsa_reg_crg = XMEDIA_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_rsa_wait_done(xmedia_void)
|
||||
{
|
||||
return hal_rsa_wait_free();
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_cipher_check_rsa_data(xmedia_u8 *rsa_n, xmedia_u8 *rsa_e, xmedia_u8 *rsa_mc, xmedia_u32 length)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
|
||||
/* formula: rsa_mc > 0 */
|
||||
for (i = 0; i < length; i++) {
|
||||
if (rsa_mc[i] > 0)
|
||||
break;
|
||||
}
|
||||
if (i >= length) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_M_ZERO); /*RSA M/C is zero, error*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
/* formula: rsa_mc < rsa_n */
|
||||
for (i = 0; i < length; i++) {
|
||||
if(rsa_mc[i] < rsa_n[i])
|
||||
break;
|
||||
|
||||
if(rsa_mc[i] == rsa_n[i])
|
||||
continue;
|
||||
|
||||
if (rsa_mc[i] > rsa_n[i])
|
||||
{
|
||||
cipher_debug_log(CIPHER_ERR_RSA_M_LARGER_N); /*RSA M/C is larger than rsa_n, error!*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
if (i >= length) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_M_LARGER_N); /*RSA M/C is larger than rsa_n, error!*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
/* formula: rsa_e > 1 */
|
||||
for (i = 0; i < length; i++) {
|
||||
if (rsa_e[i] > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((i == length -1) && (rsa_e[i] == 1)) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_E_EQUAL_1); /*RSA D/rsa_e is 1, error!*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (i >= length) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_E_EQUAL_0); /*RSA D/rsa_e is zero, error!*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_cipher_clear_rsa_ram(xmedia_void)
|
||||
{
|
||||
if (hal_rsa_wait_free() != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_BUSY_TIMEOUT); /*RSA is busy and timeout,error!*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
hal_rsa_clear_ram();
|
||||
hal_rsa_start();
|
||||
|
||||
if (drv_rsa_wait_done() != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_BUSY_TIMEOUT); /*RSA is busy and timeout,error!*/
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void drv_rsa_rand_mask(rsa_data_s *rsa_data,
|
||||
xmedia_u32 key_len,
|
||||
xmedia_u32 *random)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void drv_rsa_cipher_klad(rsa_data_s *rsa_data, xmedia_u32 key_len, xmedia_u32 *random)
|
||||
{
|
||||
hal_rsa_write_data(RSA_DATA_TYPE_KEY, rsa_data->rsa_k,
|
||||
rsa_data->rsa_n_len, key_len, random);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_rsa_key_info(rsa_data_s *rsa_data,
|
||||
xmedia_u32 *key_len,
|
||||
rsa_key_width_e *key_width)
|
||||
{
|
||||
/* Only support the key width of 1024, 2048 and 4096 */
|
||||
if (rsa_data->rsa_n_len <= 128) { /* key n size 128 */
|
||||
*key_len = 128; /* key n size 128 */
|
||||
*key_width = RSA_KEY_WIDTH_1K;
|
||||
} else if (rsa_data->rsa_n_len <= 256) { /* key n size 256 */
|
||||
*key_len = 256; /* key n size 256 */
|
||||
*key_width = RSA_KEY_WIDTH_2K;
|
||||
} else if (rsa_data->rsa_n_len <= 384) { /* key n size 384 */
|
||||
*key_len = 384; /* key n size 384 */
|
||||
*key_width = RSA_KEY_WIDTH_3K;
|
||||
} else if (rsa_data->rsa_n_len <= 512) { /* key n size 512 */
|
||||
*key_len = 512; /* key n size 512 */
|
||||
*key_width = RSA_KEY_WIDTH_4K;
|
||||
} else {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_KEY_LEN);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_cipher_calc_rsa_ex(rsa_data_s *rsa_data,
|
||||
xmedia_u32 key_len,
|
||||
rsa_key_width_e key_width)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_FAILURE;
|
||||
xmedia_u32 err_code = 0;
|
||||
xmedia_u64 random = 0;
|
||||
|
||||
ret = drv_cipher_check_rsa_data(rsa_data->rsa_n, rsa_data->rsa_k, rsa_data->input_data, key_len);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
hal_rsa_enable();
|
||||
|
||||
ret = hal_rsa_wait_free();
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_BUSY_TIMEOUT); /*RSA is busy!*/
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Config Mode */
|
||||
hal_rsa_config_mode(key_width);
|
||||
|
||||
//V500 not support,reserved!
|
||||
drv_rsa_rand_mask(rsa_data, key_len, (xmedia_u32 *)&random);
|
||||
|
||||
/* Write rsa_n, rsa_e, rsa_m */
|
||||
hal_rsa_write_data(RSA_DATA_TYPE_MODULE,
|
||||
rsa_data->rsa_n, rsa_data->rsa_n_len, key_len, (xmedia_u32 *)&random);
|
||||
|
||||
/* V500 not support rand mask,random reserved! */
|
||||
drv_rsa_cipher_klad(rsa_data, key_len, (xmedia_u32 *)&random);
|
||||
|
||||
hal_rsa_write_data(RSA_DATA_TYPE_CONTEXT,
|
||||
rsa_data->input_data, rsa_data->rsa_n_len, key_len, (xmedia_u32 *)&random);
|
||||
|
||||
/* Sart */
|
||||
hal_rsa_start();
|
||||
|
||||
ret = drv_rsa_wait_done();
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_BUSY_TIMEOUT); /*RSA is busy and timeout,error!*/
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Get result */
|
||||
hal_rsa_read_data(rsa_data->output_data, rsa_data->rsa_n_len, key_len);
|
||||
|
||||
err_code = hal_rsa_get_error_code();
|
||||
if (err_code == 0) {
|
||||
ret = XMEDIA_SUCCESS;
|
||||
} else {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_ERRORCODE); /*RSA is err!*/
|
||||
ret = XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
exit:
|
||||
(void)drv_cipher_clear_rsa_ram();
|
||||
hal_rsa_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static xmedia_s32 drv_cipher_calc_rsa(rsa_data_s *rsa_data)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
xmedia_u32 key_len = 0;
|
||||
rsa_data_s cipher_rsa_data;
|
||||
rsa_key_width_e key_width = RSA_KEY_WIDTH_BUTT;
|
||||
|
||||
ret = drv_rsa_key_info(rsa_data, &key_len, &key_width);
|
||||
if (ret != XMEDIA_SUCCESS)
|
||||
return ret;
|
||||
|
||||
crypto_memset(&cipher_rsa_data, sizeof(rsa_data_s), 0, sizeof(rsa_data_s));
|
||||
cipher_rsa_data.rsa_n = rsa_data->rsa_n;
|
||||
cipher_rsa_data.rsa_k = rsa_data->rsa_k;
|
||||
cipher_rsa_data.rsa_n_len = key_len;
|
||||
cipher_rsa_data.rsa_k_len = key_len;
|
||||
cipher_rsa_data.input_data = rsa_data->input_data;
|
||||
cipher_rsa_data.data_len = key_len;
|
||||
cipher_rsa_data.output_data = rsa_data->output_data;
|
||||
|
||||
ret = drv_cipher_calc_rsa_ex(&cipher_rsa_data, key_len, key_width);
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_rsa_deinit(xmedia_void)
|
||||
{
|
||||
if (rsa_init_flag == 1) {
|
||||
drv_rsa_deinit();
|
||||
rsa_init_flag = 0;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_cipher_rsa_verify(const cipher_rsa_verify *rsa_verify, cipher_verify_data *verify_data)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
rsa_padding_s pad;
|
||||
xmedia_u8 arr_em[RSA_MAX_KEY_LEN];
|
||||
|
||||
if (rsa_init_flag == 0) {
|
||||
if (drv_rsa_init() != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
rsa_init_flag = 1;
|
||||
}
|
||||
|
||||
crypto_memset(arr_em, sizeof(arr_em), 0, sizeof(arr_em));
|
||||
crypto_memset(&pad, sizeof(rsa_padding_s), 0, sizeof(rsa_padding_s));
|
||||
ret = rsa_verify_pad_init(&pad, rsa_verify, verify_data, arr_em);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_DEC);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (rsa_verify->scheme == XMEDIA_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256) {
|
||||
ret = rsa_padding_check_pkcs1_v15(verify_data->hash_data, SHA256_DATA_BYTE_LEN, arr_em, rsa_verify->pub_key.n_len);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_CHECK_PADDING);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
} else {
|
||||
pad.em_bit = rsa_get_bit_num(rsa_verify->pub_key.n, pad.klen);
|
||||
ret = rsa_padding_check_pkcs1_pss(&pad, verify_data->hash_data);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
cipher_debug_log(CIPHER_ERR_RSA_CHECK_PADDING);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __XMEDIA_CIPHER_H__
|
||||
#define __XMEDIA_CIPHER_H__
|
||||
|
||||
#include "xmedia_type.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Klad target. */
|
||||
typedef enum {
|
||||
XMEDIA_CIPHER_KLAD_TARGET_AES = 0x0, /* Klad for AES. */
|
||||
XMEDIA_CIPHER_KLAD_TARGET_RSA, /* Klad for RSA. */
|
||||
XMEDIA_CIPHER_KLAD_TARGET_BUTT,
|
||||
} cipher_klad_target;
|
||||
|
||||
/* Hash algrithm type. */
|
||||
typedef enum {
|
||||
XMEDIA_CIPHER_HASH_TYPE_SHA1,
|
||||
XMEDIA_CIPHER_HASH_TYPE_SHA224,
|
||||
XMEDIA_CIPHER_HASH_TYPE_SHA256,
|
||||
XMEDIA_CIPHER_HASH_TYPE_SHA384,
|
||||
XMEDIA_CIPHER_HASH_TYPE_SHA512,
|
||||
XMEDIA_CIPHER_HASH_TYPE_HMAC_SHA1,
|
||||
XMEDIA_CIPHER_HASH_TYPE_HMAC_SHA224,
|
||||
XMEDIA_CIPHER_HASH_TYPE_HMAC_SHA256,
|
||||
XMEDIA_CIPHER_HASH_TYPE_HMAC_SHA384,
|
||||
XMEDIA_CIPHER_HASH_TYPE_HMAC_SHA512,
|
||||
XMEDIA_CIPHER_HASH_TYPE_SM3,
|
||||
XMEDIA_CIPHER_HASH_TYPE_BUTT,
|
||||
XMEDIA_CIPHER_HASH_TYPE_INVALID = 0xffffffff,
|
||||
} cipher_hash_type;
|
||||
|
||||
/* Cipher algorithm. */
|
||||
typedef enum {
|
||||
XMEDIA_CIPHER_ALG_AES = 0x0, /* Advanced encryption standard (AES) algorithm */
|
||||
XMEDIA_CIPHER_ALG_SM1 = 0x1, /* SM1 algorithm. */
|
||||
XMEDIA_CIPHER_ALG_SM4 = 0x2, /* SM4 algorithm. */
|
||||
XMEDIA_CIPHER_ALG_DMA = 0x3, /* DMA copy. */
|
||||
XMEDIA_CIPHER_ALG_BUTT = 0x4,
|
||||
XMEDIA_CIPHER_ALG_INVALID = 0xffffffff,
|
||||
} cipher_alg;
|
||||
|
||||
/* Cipher bit width. */
|
||||
typedef enum {
|
||||
XMEDIA_CIPHER_BIT_WIDTH_128BIT = 0x0, /* 128-bit width */
|
||||
XMEDIA_CIPHER_BIT_WIDTH_64BIT = 0x1, /* 64-bit width */
|
||||
XMEDIA_CIPHER_BIT_WIDTH_8BIT = 0x2, /* 8-bit width */
|
||||
XMEDIA_CIPHER_BIT_WIDTH_1BIT = 0x3, /* 1-bit width */
|
||||
XMEDIA_CIPHER_BIT_WIDTH_BUTT = 0x4,
|
||||
XMEDIA_CIPHER_BIT_WIDTH_INVALID = 0xffffffff,
|
||||
} cipher_bit_width;
|
||||
|
||||
/* enum typedef */
|
||||
/* Cipher work mode. */
|
||||
typedef enum {
|
||||
XMEDIA_CIPHER_WORK_MODE_ECB = 0x0, /* Electronic codebook (ECB) mode, ECB has been considered insecure and it is
|
||||
recommended not to use it. */
|
||||
XMEDIA_CIPHER_WORK_MODE_CBC, /* Cipher block chaining (CBC) mode. */
|
||||
XMEDIA_CIPHER_WORK_MODE_CFB, /* Cipher feedback (CFB) mode. */
|
||||
XMEDIA_CIPHER_WORK_MODE_OFB, /* Output feedback (OFB) mode. */
|
||||
XMEDIA_CIPHER_WORK_MODE_CTR, /* Counter (CTR) mode. */
|
||||
XMEDIA_CIPHER_WORK_MODE_BUTT,
|
||||
XMEDIA_CIPHER_WORK_MODE_INVALID = 0xffffffff,
|
||||
} cipher_work_mode;
|
||||
|
||||
/* Key length. */
|
||||
typedef enum {
|
||||
XMEDIA_CIPHER_KEY_DEFAULT = 0x0, /* Default key length, AES-16, SM1-48, SM4-16 */
|
||||
XMEDIA_CIPHER_KEY_AES_128BIT = 0x0, /* 128-bit key for the AES algorithm */
|
||||
XMEDIA_CIPHER_KEY_AES_192BIT = 0x1, /* 192-bit key for the AES algorithm */
|
||||
XMEDIA_CIPHER_KEY_AES_256BIT = 0x2, /* 256-bit key for the AES algorithm */
|
||||
XMEDIA_CIPHER_KEY_LEN_BUTT = 0x3,
|
||||
XMEDIA_CIPHER_KEY_INVALID = 0xffffffff,
|
||||
} cipher_key_len;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_CIPHER_KEY_SRC_USER = 0x0, /* plain key */
|
||||
XMEDIA_CIPHER_KEY_SRC_KLAD_0, /* aes key0 */
|
||||
XMEDIA_CIPHER_KEY_SRC_KLAD_1, /* aes key1 */
|
||||
XMEDIA_CIPHER_KEY_SRC_KLAD_2, /* aes key2 */
|
||||
XMEDIA_CIPHER_KEY_SRC_KLAD_3, /* aes key3 */
|
||||
XMEDIA_CIPHER_KEY_SRC_BUTT,
|
||||
} xmedia_cipher_key_type;
|
||||
|
||||
/* Structure of the cipher control information */
|
||||
typedef struct {
|
||||
xmedia_u32 key[8]; /* Key input */
|
||||
xmedia_u32 iv[4]; /* Initialization vector (IV) */
|
||||
xmedia_cipher_key_type key_type;
|
||||
cipher_work_mode work_mode;
|
||||
} cipher_ctrl;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256 = 0x0, /* PKCS#1 RSASSA_PKCS1_V15_SHA256 */
|
||||
XMEDIA_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA256, /* PKCS#1 RSASSA_PKCS1_PSS_SHA256 */
|
||||
XMEDIA_CIPHER_RSA_SIGN_SCHEME_BUTT,
|
||||
} xmedia_cipher_rsa_sign_scheme;
|
||||
|
||||
/* RSA public key struct */
|
||||
typedef struct {
|
||||
xmedia_u8 *n; /* Point to public modulus N */
|
||||
xmedia_u8 *e; /* Point to public exponent E */
|
||||
xmedia_u16 n_len; /* Length of public modulus N, max value is 512Byte */
|
||||
xmedia_u16 e_len; /* Length of public exponent E, max value is 512Byte */
|
||||
} cipher_rsa_pub_key;
|
||||
|
||||
/* RSA signature verify struct input */
|
||||
typedef struct {
|
||||
xmedia_cipher_rsa_sign_scheme scheme;
|
||||
cipher_rsa_pub_key pub_key; /* RSA public key struct */
|
||||
} cipher_rsa_verify;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u8 *hash_data; /* Hash of data. */
|
||||
xmedia_u32 hash_data_len; /* Length of hash data. */
|
||||
xmedia_u8 *sign; /* Input sign data. */
|
||||
xmedia_u32 sign_len; /* Length of input sign data. */
|
||||
} cipher_verify_data;
|
||||
|
||||
xmedia_s32 xmedia_cipher_deinit(xmedia_void);
|
||||
/*
|
||||
* 函数说明:AES256加密接口
|
||||
*
|
||||
* 1、支持aes加密算法,支持ECB、CBC、CFB、OFB、CTR模式,key长度只支持256bits
|
||||
* 2、支持明文key与密文key,使用明文key时,ctrl->key_type需配置为XMEDIA_CIPHER_KEY_SRC_USER,AES逻辑实际使用的key
|
||||
* 与配置的明文key相同;使用密文key时,ctrl->key_type需配置为XMEDIA_CIPHER_KEY_SRC_KLAD_X(X为[0,3],依次对应OTP中的AES KEY0~3),
|
||||
* cipher模块首先调用KLAD模块使用OTP中的AES KEY对输入的密文key进行AES256 ECB解密,然后AES逻辑使用解密后的明文key对输入数据进行加密
|
||||
*/
|
||||
xmedia_s32 xmedia_cipher_aes256_encrypt(cipher_ctrl *ctrl, xmedia_size_t src_phy_addr, xmedia_size_t dest_phy_addr, xmedia_u32 byte_len);
|
||||
|
||||
/*
|
||||
* 函数说明:AES256解密接口
|
||||
*
|
||||
* 1、支持aes解密算法,支持ECB、CBC、CFB、OFB、CTR模式,key长度只支持256bits
|
||||
* 2、支持明文key与密文key,使用明文key时,ctrl->key_type需配置为XMEDIA_CIPHER_KEY_SRC_USER,AES逻辑实际使用的key
|
||||
* 与配置的明文key相同;使用密文key时,ctrl->key_type需配置为XMEDIA_CIPHER_KEY_SRC_KLAD_X(X为[0,3],依次对应OTP中的AES KEY0~3),
|
||||
* cipher模块首先调用KLAD模块使用OTP中的AES KEY对输入的密文key进行AES256 ECB解密,然后AES逻辑使用解密后的明文key对输入数据进行解密
|
||||
*/
|
||||
xmedia_s32 xmedia_cipher_aes256_decrypt(cipher_ctrl *ctrl, xmedia_size_t src_phy_addr, xmedia_size_t dest_phy_addr, xmedia_u32 byte_len);
|
||||
|
||||
xmedia_s32 xmedia_cipher_sha256_init(xmedia_void);
|
||||
xmedia_s32 xmedia_cipher_sha256_update(xmedia_u8 *input_data, xmedia_u32 input_data_len);
|
||||
xmedia_s32 xmedia_cipher_sha256_final(xmedia_u8 *output_hash);
|
||||
xmedia_s32 xmedia_cipher_rsa_deinit(xmedia_void);
|
||||
/*
|
||||
* 函数说明:RSA验签接口
|
||||
*
|
||||
* 1、RSA验签运算支持两种key长度,分别是2048bits、4096bits,通过输入参数中的公钥参数rsa_verify->pub_key进行指定
|
||||
* 2、支持两种验签标准,分别是PKCS#1 RSASSA_PKCS1_PSS_SHA256与PKCS#1 RSASSA_PKCS1_V15_SHA256,通过输入参数rsa_verify->schme进行指定
|
||||
*
|
||||
* 注:根据支持的验签标准,传入的数据hash值必须采用SHA256算法,可调用xmedia_cipher_sha256_xxx系列接口进行hash运算
|
||||
*/
|
||||
xmedia_s32 xmedia_cipher_rsa_verify(const cipher_rsa_verify *rsa_verify, cipher_verify_data *verify_data);
|
||||
xmedia_void xmedia_cipher_klad_deinit(xmedia_void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __XMEDIA_CIPHER_H__ */
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __XMEDIA_TYPE_H__
|
||||
#define __XMEDIA_TYPE_H__
|
||||
|
||||
typedef unsigned char xmedia_uchar;
|
||||
typedef unsigned char xmedia_u8;
|
||||
typedef unsigned short xmedia_u16;
|
||||
typedef unsigned int xmedia_u32;
|
||||
typedef unsigned long long xmedia_u64;
|
||||
typedef unsigned long xmedia_ulong;
|
||||
|
||||
typedef char xmedia_char;
|
||||
typedef signed char xmedia_s8;
|
||||
typedef short xmedia_s16;
|
||||
typedef int xmedia_s32;
|
||||
typedef long long xmedia_s64;
|
||||
typedef long xmedia_slong;
|
||||
|
||||
typedef float xmedia_float;
|
||||
typedef double xmedia_double;
|
||||
|
||||
typedef void xmedia_void;
|
||||
|
||||
typedef xmedia_u32 xmedia_handle;
|
||||
|
||||
typedef xmedia_ulong xmedia_uintptr_t;
|
||||
typedef xmedia_slong xmedia_intptr_t;
|
||||
|
||||
typedef unsigned long xmedia_size_t;
|
||||
typedef unsigned long xmedia_length_t;
|
||||
|
||||
/* DMA addresses are 32-bits wide */
|
||||
typedef unsigned long phys_addr_t;
|
||||
typedef unsigned long phys_size_t;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_FALSE = 0,
|
||||
XMEDIA_TRUE = 1,
|
||||
} xmedia_bool;
|
||||
|
||||
#define XMEDIA_NULL 0L
|
||||
|
||||
#define XMEDIA_SUCCESS 0
|
||||
#define XMEDIA_FAILURE (-1)
|
||||
|
||||
#define XMEDIA_INVALID_HANDLE (0xffffffff)
|
||||
|
||||
#define XMEDIA_UNUSED(x) ((x) = (x))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
menu "Support ssp lcd set"
|
||||
|
||||
config CMD_LCD_ST7789
|
||||
bool "Support lcd st7789 init cmd"
|
||||
depends on SPI
|
||||
default n
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1 @@
|
||||
obj-$(CONFIG_CMD_LCD_ST7789) += lcd_st7789.o
|
||||
@@ -0,0 +1,150 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
|
||||
*/
|
||||
/*
|
||||
* SPI Read/Write Utilities
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <errno.h>
|
||||
#include <spi.h>
|
||||
#include <asm/io.h>
|
||||
/*-----------------------------------------------------------------------
|
||||
* Definitions
|
||||
*/
|
||||
void spi_write_a9byte(struct spi_slave *slave, unsigned char cmd_dat,unsigned char dat)
|
||||
{
|
||||
unsigned short spi_data = 0;
|
||||
if (cmd_dat)
|
||||
spi_data = 1 << 8;
|
||||
else
|
||||
spi_data = 0 << 8;
|
||||
spi_data = spi_data | dat;
|
||||
spi_xfer(slave, 9, &spi_data, NULL, 0);
|
||||
return;
|
||||
}
|
||||
void ssp_write_dat(struct spi_slave *slave, unsigned char dat)
|
||||
{
|
||||
spi_write_a9byte(slave, 1, dat);
|
||||
}
|
||||
void ssp_write_cmd(struct spi_slave *slave,unsigned char dat)
|
||||
{
|
||||
spi_write_a9byte(slave, 0, dat);
|
||||
}
|
||||
int do_lcd_st7789_init (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
struct spi_slave *slave;
|
||||
int ret = 0;
|
||||
/*
|
||||
* We use the last specified parameters, unless new ones are
|
||||
* entered.
|
||||
*/
|
||||
if ((flag & CMD_FLAG_REPEAT) == 0) {
|
||||
slave = spi_setup_slave(0, 0, 1000000, SPI_MODE_3);
|
||||
if (!slave) {
|
||||
printf("Invalid device \n");
|
||||
return -EINVAL;
|
||||
}
|
||||
spi_set_wordlen(slave, 9);
|
||||
ret = spi_claim_bus(slave);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
/* st7789v turn on sleep mode */
|
||||
ssp_write_cmd(slave,0x10);
|
||||
/* st7789v software reset */
|
||||
ssp_write_cmd(slave,0x01);
|
||||
udelay(120000);
|
||||
/* st7789v turn off sleep mode */
|
||||
ssp_write_cmd(slave,0x11);
|
||||
udelay(120000);
|
||||
/* Display Setting */
|
||||
ssp_write_cmd(slave,0x53);
|
||||
ssp_write_dat(slave,0x04);
|
||||
ssp_write_cmd(slave,0x36);
|
||||
ssp_write_dat(slave,0x00);
|
||||
ssp_write_cmd(slave,0x3a);
|
||||
ssp_write_dat(slave,0x60);
|
||||
ssp_write_cmd(slave,0x21);
|
||||
/* st7789v frame rate setting */
|
||||
ssp_write_cmd(slave,0xb0);
|
||||
ssp_write_dat(slave,0x11);
|
||||
ssp_write_dat(slave,0x04);
|
||||
ssp_write_cmd(slave,0xb2);
|
||||
ssp_write_dat(slave,0x05);
|
||||
ssp_write_dat(slave,0x05);
|
||||
ssp_write_dat(slave,0x00);
|
||||
ssp_write_dat(slave,0x33);
|
||||
ssp_write_dat(slave,0x33);
|
||||
ssp_write_cmd(slave,0xb7);
|
||||
ssp_write_dat(slave,0x35);
|
||||
/* st7789v power setting */
|
||||
ssp_write_cmd(slave,0xb8);
|
||||
ssp_write_dat(slave,0x2f);
|
||||
ssp_write_dat(slave,0x2b);
|
||||
ssp_write_dat(slave,0x2f);
|
||||
ssp_write_cmd(slave,0xbb);
|
||||
ssp_write_dat(slave,0x20);
|
||||
ssp_write_cmd(slave,0xc0);
|
||||
ssp_write_dat(slave,0x2c);
|
||||
ssp_write_cmd(slave,0xc2);
|
||||
ssp_write_dat(slave,0x01);
|
||||
ssp_write_cmd(slave,0xc3);
|
||||
ssp_write_dat(slave,0x0b);
|
||||
ssp_write_cmd(slave,0xc4);
|
||||
ssp_write_dat(slave,0x20);
|
||||
ssp_write_cmd(slave,0xc6);
|
||||
ssp_write_dat(slave,0x11);
|
||||
ssp_write_cmd(slave,0xd0);
|
||||
ssp_write_dat(slave,0xa4);
|
||||
ssp_write_dat(slave,0xa1);
|
||||
ssp_write_cmd(slave,0xe8);
|
||||
ssp_write_dat(slave,0x03);
|
||||
ssp_write_cmd(slave,0xe9);
|
||||
ssp_write_dat(slave,0x0d);
|
||||
ssp_write_dat(slave,0x12);
|
||||
ssp_write_dat(slave,0x00);
|
||||
/* st7789v gamma setting */
|
||||
ssp_write_cmd(slave,0xe0);
|
||||
ssp_write_dat(slave,0xd0);
|
||||
ssp_write_dat(slave,0x06);
|
||||
ssp_write_dat(slave,0x0b);
|
||||
ssp_write_dat(slave,0x0a);
|
||||
ssp_write_dat(slave,0x09);
|
||||
ssp_write_dat(slave,0x05);
|
||||
ssp_write_dat(slave,0x2e);
|
||||
ssp_write_dat(slave,0x43);
|
||||
ssp_write_dat(slave,0x44);
|
||||
ssp_write_dat(slave,0x09);
|
||||
ssp_write_dat(slave,0x16);
|
||||
ssp_write_dat(slave,0x15);
|
||||
ssp_write_dat(slave,0x23);
|
||||
ssp_write_dat(slave,0x27);
|
||||
ssp_write_cmd(slave,0xe1);
|
||||
ssp_write_dat(slave,0xd0);
|
||||
ssp_write_dat(slave,0x06);
|
||||
ssp_write_dat(slave,0x0b);
|
||||
ssp_write_dat(slave,0x09);
|
||||
ssp_write_dat(slave,0x08);
|
||||
ssp_write_dat(slave,0x06);
|
||||
ssp_write_dat(slave,0x2e);
|
||||
ssp_write_dat(slave,0x44);
|
||||
ssp_write_dat(slave,0x44);
|
||||
ssp_write_dat(slave,0x3a);
|
||||
ssp_write_dat(slave,0x15);
|
||||
ssp_write_dat(slave,0x15);
|
||||
ssp_write_dat(slave,0x23);
|
||||
ssp_write_dat(slave,0x26);
|
||||
ssp_write_cmd(slave,0x29);
|
||||
spi_release_bus(slave);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/***************************************************/
|
||||
U_BOOT_CMD(
|
||||
lcd_st7789_init, 1, 0, do_lcd_st7789_init,
|
||||
"do lcd st7789 init",
|
||||
""
|
||||
);
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
ccflags-y += -I$(srctree)/product/driver/include
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/hal
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/hal/$(CHIPARCH)
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/hal/$(CHIPARCH)/disp
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/hal/$(CHIPARCH)/gamma
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/hal/$(CHIPARCH)/csc
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/hal/$(CHIPARCH)/clock
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/hal/$(CHIPARCH)/intf
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/hal/include
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/include
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/common
|
||||
ccflags-y += -I$(srctree)/product/driver/vo/common/xmfalcon
|
||||
|
||||
obj-y += cmd_vo.o
|
||||
obj-y += common/$(CHIPARCH)/sys_hal.o
|
||||
obj-y += common/$(CHIPARCH)/sys_drv.o
|
||||
obj-y += common/drv_sys.o
|
||||
|
||||
obj-y += hal/$(CHIPARCH)/clock/hal_vo_clock.o
|
||||
obj-y += hal/$(CHIPARCH)/csc/hal_vo_csc.o
|
||||
obj-y += hal/$(CHIPARCH)/disp/hal_vo_disp.o
|
||||
obj-y += hal/$(CHIPARCH)/gamma/hal_vo_gamma.o
|
||||
obj-y += hal/$(CHIPARCH)/hal_vo.o
|
||||
obj-y += hal/$(CHIPARCH)/hal_vo_chip_cfg.o
|
||||
obj-y += hal/$(CHIPARCH)/hal_vo_reg.o
|
||||
obj-y += hal/$(CHIPARCH)/intf/hal_vo_intf.o
|
||||
obj-y += drv_vo.o
|
||||
|
||||
EXTRA_CFLAGS += -DVO_BOOT
|
||||
EXTRA_CFLAGS += -D$(CHIPARCH)
|
||||
|
||||
Executable
+249
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include "drv_vo.h"
|
||||
#include "xmedia_vo.h"
|
||||
#ifndef CFG_MAXARGS
|
||||
#define CFG_MAXARGS 10
|
||||
#endif
|
||||
|
||||
#define CFG_MAXARGS_SETVOBG 3
|
||||
#define CFG_MAXARGS_STARTVO 4
|
||||
#define CFG_MAXARGS_STOPVO 2
|
||||
#define CFG_MAXARGS_STARTVL 8
|
||||
#define CFG_MAXARGS_STOPVL 2
|
||||
#define CFG_MAXARGS_STARTGX 9
|
||||
#define CFG_MAXARGS_STOPGX 2
|
||||
#define CMD_VO_ARGS_BASE10 10
|
||||
#define CMD_VO_ARGS_BASE16 16
|
||||
#define CMD_VO_ARGS_BASE_ALL 0
|
||||
|
||||
extern int init_vo(xmedia_void);
|
||||
extern int deinit_vo(xmedia_void);
|
||||
extern int set_vobg(unsigned int dev, unsigned int rgb);
|
||||
extern int start_vo(unsigned int dev, xmedia_s32 screen_type);
|
||||
extern int stop_vo(unsigned int dev);
|
||||
extern int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, xmedia_video_rect layer_rect);
|
||||
extern int stop_videolayer(unsigned int layer);
|
||||
extern int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, xmedia_video_rect gx_rect);
|
||||
extern int stop_gx(unsigned int layer);
|
||||
extern int check_vo_support(unsigned int dev, xmedia_s32 screen_type);
|
||||
|
||||
static int do_initvo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
init_vo();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_deinitvo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
deinit_vo();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_startvo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
xmedia_vo_dev dev = 0;
|
||||
xmedia_s32 screen_type;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("insufficient parameter!\n");
|
||||
printf("usage:\n%s\n", cmdtp->usage);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
|
||||
screen_type = (unsigned int)simple_strtoul(argv[2], NULL, CMD_VO_ARGS_BASE10);
|
||||
|
||||
if (check_vo_support(dev, screen_type)) {
|
||||
printf("unsupported parameter!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
start_vo(dev, screen_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_stopvo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
xmedia_vo_dev dev = 0;
|
||||
if (argc < 2) {
|
||||
printf("insufficient parameter!\n");
|
||||
printf("usage:\n%s\n", cmdtp->usage);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev = (unsigned int)simple_strtoul(argv[1], NULL, CMD_VO_ARGS_BASE10);
|
||||
|
||||
stop_vo(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int start_layer_parse(char *const argv[], unsigned int *layer,
|
||||
unsigned long *addr, unsigned int *strd, xmedia_video_rect *layer_rect)
|
||||
{
|
||||
int ret;
|
||||
unsigned long layer_tmp, addr_tmp, strd_tmp, x_tmp, y_tmp, width_tmp, height_tmp;
|
||||
ret = strict_strtoul(argv[1], CMD_VO_ARGS_BASE10, &layer_tmp); /* 1st arg */
|
||||
if (ret != 0) {
|
||||
printf("parse layer failed.\n");
|
||||
return -1;
|
||||
}
|
||||
ret = strict_strtoul(argv[2], CMD_VO_ARGS_BASE16, &addr_tmp); /* 2nd arg */
|
||||
if (ret != 0) {
|
||||
printf("parse addr failed.\n");
|
||||
return -1;
|
||||
}
|
||||
ret = strict_strtoul(argv[3], CMD_VO_ARGS_BASE10, &strd_tmp); /* 3rd arg */
|
||||
if (ret != 0) {
|
||||
printf("parse strd failed.\n");
|
||||
return -1;
|
||||
}
|
||||
ret = strict_strtoul(argv[4], CMD_VO_ARGS_BASE10, &x_tmp); /* 4th arg */
|
||||
if (ret != 0) {
|
||||
printf("parse x failed.\n");
|
||||
return -1;
|
||||
}
|
||||
ret = strict_strtoul(argv[5], CMD_VO_ARGS_BASE10, &y_tmp); /* 5th arg */
|
||||
if (ret != 0) {
|
||||
printf("parse y failed.\n");
|
||||
return -1;
|
||||
}
|
||||
ret = strict_strtoul(argv[6], CMD_VO_ARGS_BASE10, &width_tmp); /* 6th arg */
|
||||
if (ret != 0) {
|
||||
printf("parse width failed.\n");
|
||||
return -1;
|
||||
}
|
||||
ret = strict_strtoul(argv[7], CMD_VO_ARGS_BASE10, &height_tmp); /* 7th arg */
|
||||
if (ret != 0) {
|
||||
printf("parse height failed.\n");
|
||||
return -1;
|
||||
}
|
||||
*layer = (unsigned int)layer_tmp;
|
||||
*addr = addr_tmp;
|
||||
*strd = (unsigned int)strd_tmp;
|
||||
layer_rect->x = (unsigned int)x_tmp;
|
||||
layer_rect->y = (unsigned int)y_tmp;
|
||||
layer_rect->width = (unsigned int)width_tmp;
|
||||
layer_rect->height = (unsigned int)height_tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_startvl(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
int ret;
|
||||
unsigned int layer, strd;
|
||||
unsigned long addr;
|
||||
xmedia_video_rect layer_rect;
|
||||
|
||||
if (argc < 8) { /* max 8 args */
|
||||
printf("insufficient parameter!\n");
|
||||
printf("usage:\n%s\n", cmdtp->usage);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = start_layer_parse(argv, &layer, &addr, &strd, &layer_rect);
|
||||
if (ret != 0) {
|
||||
printf("insufficient parameter!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = start_videolayer(layer, addr, strd, layer_rect);
|
||||
if (ret != 0) {
|
||||
printf("start_videolayer error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("video layer %u opened!\n", layer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_stopvl(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
int ret;
|
||||
unsigned long layer_tmp;
|
||||
if (argc < 2) { /* max 8 args */
|
||||
printf("insufficient parameter!\n");
|
||||
printf("usage:\n%s\n", cmdtp->usage);
|
||||
return -1;
|
||||
}
|
||||
ret = strict_strtoul(argv[1], CMD_VO_ARGS_BASE10, &layer_tmp); /* 1st arg */
|
||||
if (ret != 0) {
|
||||
printf("strict_strtoul error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
stop_videolayer(layer_tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_startgx(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
//todo
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_stopgx(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
//todo
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(initvo, CFG_MAXARGS, 1, do_initvo,
|
||||
"initvo", "initvo");
|
||||
|
||||
U_BOOT_CMD(deinitvo, CFG_MAXARGS, 1, do_deinitvo,
|
||||
"deinitvo", "deinitvo");
|
||||
|
||||
|
||||
U_BOOT_CMD(startvo, CFG_MAXARGS, 1, do_startvo,
|
||||
"startvo - open vo device with a certain output interface.\n"
|
||||
"\t- startvo [dev screen_type]",
|
||||
"\nargs: [dev screen_type]\n"
|
||||
"\t-<dev> : 0: DHD0, 1: DHD1\n"
|
||||
"\t-<screen_type>: 0:MICROTECH_MTF050_LCD_800X480\n"
|
||||
"\t-<screen_type>: 1:SATOZ_SAT935_MIPI_800X1280_RGB8888_24BIT\n"
|
||||
"\t-<screen_type>: 2:SIL9024_BT1120_1920X1080P60\n"
|
||||
"\t-<screen_type>: 3:MICROTECH_MTF101_FT01_LVDS_800X1280_RGB666_18BIT\n"
|
||||
"\t-<screen_type>: 4:MICROTECH_MTF101_FS16_LVDS_1280X800_RGB888_24BIT\n"
|
||||
"\t- ....");
|
||||
|
||||
U_BOOT_CMD(stopvo, CFG_MAXARGS, 1, do_stopvo,
|
||||
"stopvo - close interface of vo device.\n"
|
||||
"\t- stopvo [dev]",
|
||||
"\nargs: [dev]\n"
|
||||
"\t-<dev> : 0(HD0), 1: DHD1\n");
|
||||
|
||||
U_BOOT_CMD(startvl, CFG_MAXARGS, 1, do_startvl,
|
||||
"startvl - open video layer.\n"
|
||||
"\t- startvl [layer addr stride x y w h]\n",
|
||||
"\nargs: [layer, addr, stride, x, y, w, h]\n"
|
||||
"\t-<layer> : 0(V0)\n"
|
||||
"\t-<addr> : picture address\n"
|
||||
"\t-<stride> : picture stride\n"
|
||||
"\t-<x,y,w,h> : display area\n");
|
||||
|
||||
U_BOOT_CMD(stopvl, CFG_MAXARGS, 1, do_stopvl,
|
||||
"stopvl - close video layer.\n"
|
||||
"\t- stopvl [layer]",
|
||||
"\nargs: [layer]\n"
|
||||
"\t-<layer> : 0(V0) 1(V1)\n");
|
||||
|
||||
U_BOOT_CMD(startgx, CFG_MAXARGS, 1, do_startgx,
|
||||
"startgx - open graphics layer.\n"
|
||||
"\t- startgx [layer addr stride x y w h]\n",
|
||||
"\nargs: [layer, addr, stride, x, y, w, h]\n"
|
||||
"\t-<layer> : 0(G0)\n"
|
||||
"\t-<addr> : picture address\n"
|
||||
"\t-<stride> : picture stride\n"
|
||||
"\t-<x,y,w,h> : display area\n");
|
||||
|
||||
U_BOOT_CMD(stopgx, CFG_MAXARGS, 1, do_stopgx,
|
||||
"stopgx - close graphics layer.\n"
|
||||
"\t- stopgx [layer]",
|
||||
"\nargs: [layer]\n"
|
||||
"\t-<layer> : 0(G0)\n");
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "drv_sys.h"
|
||||
#include "sys_drv.h"
|
||||
#include "sys_hal.h"
|
||||
|
||||
xmedia_s32 drv_sys_mod_ctrl(xmedia_chn_info *chn_info, sys_func_id func_id, xmedia_void *io_args)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_FAILURE;
|
||||
|
||||
ret = sys_mod_ctrl(chn_info, func_id, io_args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef DRV_SYS_H
|
||||
#define DRV_SYS_H
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
typedef enum {
|
||||
SYS_VO_VOU_HD_CKSEL,
|
||||
SYS_VO_VOU_PPC_CKSEL,
|
||||
SYS_VO_LVDS_POR_SRST,
|
||||
SYS_VO_MIPITX_PLL_REF_CKSEL,
|
||||
SYS_VO_LVDS_CKSEL,
|
||||
SYS_VO_LCD_DIV_CFG,
|
||||
SYS_VO_PLL_DIV_CFG,
|
||||
SYS_VO_VOU_HD_CKEN,
|
||||
SYS_VO_VOU_SRST_REQ,
|
||||
SYS_VO_VOU_SRST_GET,
|
||||
SYS_VO_LCD_DIV_CKEN,
|
||||
SYS_VO_PLL_DIV_CKEN,
|
||||
SYS_VO_BT_HD_CKSEL,
|
||||
SYS_VO_LCD_HD_CKSEL,
|
||||
SYS_VO_MIPITX_HD_CKSEL,
|
||||
SYS_VO_LVDSTX_HD_CKSEL,
|
||||
SYS_VO_BT_PCTRL,
|
||||
SYS_VO_LCD_PCTRL,
|
||||
SYS_VO_MIPITX_PCTRL,
|
||||
SYS_VO_LVDSTX_PCTRL,
|
||||
SYS_VO_BT_CKEN,
|
||||
SYS_VO_LCD_CKEN,
|
||||
SYS_VO_MIPITX_CKEN,
|
||||
SYS_VO_LVDSTX_CKEN,
|
||||
SYS_MAX
|
||||
} sys_func_id;
|
||||
|
||||
#ifndef xmedia_chn_info
|
||||
typedef struct {
|
||||
xmedia_mod_id mod_id;
|
||||
xmedia_s32 dev_id;
|
||||
xmedia_s32 chn_id;
|
||||
} xmedia_chn_info;
|
||||
#endif
|
||||
|
||||
xmedia_s32 drv_sys_mod_init(xmedia_void);
|
||||
xmedia_void drv_sys_mod_exit(xmedia_void);
|
||||
|
||||
xmedia_s32 drv_sys_mod_ctrl(xmedia_chn_info *chn_info, sys_func_id func_id, xmedia_void *io_args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
#endif /* DRV_SYS_H */
|
||||
|
||||
+434
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifndef __DRV_VO_SYS_H__
|
||||
#define __DRV_VO_SYS_H__
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned char xmedia_uchar;
|
||||
typedef unsigned char xmedia_u8;
|
||||
typedef unsigned short xmedia_u16;
|
||||
typedef unsigned int xmedia_u32;
|
||||
typedef unsigned long long xmedia_u64;
|
||||
typedef unsigned long xmedia_ulong;
|
||||
|
||||
typedef char xmedia_char;
|
||||
typedef signed char xmedia_s8;
|
||||
typedef short xmedia_s16;
|
||||
typedef int xmedia_s32;
|
||||
typedef long long xmedia_s64;
|
||||
typedef long xmedia_slong;
|
||||
|
||||
typedef float xmedia_float;
|
||||
typedef double xmedia_double;
|
||||
|
||||
typedef void xmedia_void;
|
||||
|
||||
typedef xmedia_u32 xmedia_handle;
|
||||
|
||||
typedef xmedia_ulong xmedia_uintptr_t;
|
||||
typedef xmedia_slong xmedia_intptr_t;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_FALSE = 0,
|
||||
XMEDIA_TRUE = 1,
|
||||
} xmedia_bool;
|
||||
|
||||
#define XMEDIA_NULL 0L
|
||||
|
||||
#define XMEDIA_SUCCESS 0
|
||||
#define XMEDIA_FAILURE (-1)
|
||||
|
||||
#define XMEDIA_INVALID_HANDLE (0xffffffff)
|
||||
|
||||
#define XMEDIA_UNUSED(x) ((x) = (x))
|
||||
|
||||
#define XMEDIA_ERRCODE_INVALID_PARAM (xmedia_s32)(0x80010001)
|
||||
#define XMEDIA_ERRCODE_NULL_PTR (xmedia_s32)(0x80010002)
|
||||
#define XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY (xmedia_s32)(0x80010003) // memory allocation fails
|
||||
#define XMEDIA_ERRCODE_NOT_INIT (xmedia_s32)(0x80010004)
|
||||
#define XMEDIA_ERRCODE_NOT_SUPPORT (xmedia_s32)(0x80010005)
|
||||
#define XMEDIA_ERRCODE_TIMEOUT (xmedia_s32)(0x80010006)
|
||||
#define XMEDIA_ERRCODE_BAD_ADDRESS (xmedia_s32)(0x80010007)
|
||||
#define XMEDIA_ERRCODE_OPEN_FAILED (xmedia_s32)(0x80010008)
|
||||
#define XMEDIA_ERRCODE_CLOSE_FAILED (xmedia_s32)(0x80010009)
|
||||
#define XMEDIA_ERRCODE_CREATE_FAILED (xmedia_s32)(0x8001000A)
|
||||
#define XMEDIA_ERRCODE_DESTROY_FAILED (xmedia_s32)(0x8001000B)
|
||||
#define XMEDIA_ERRCODE_BUFFER_EMPTY (xmedia_s32)(0x8001000C)
|
||||
#define XMEDIA_ERRCODE_BUFFER_FULL (xmedia_s32)(0x8001000D)
|
||||
#define XMEDIA_ERRCODE_NO_BUFFER_FREE (xmedia_s32)(0x8001000E)
|
||||
#define XMEDIA_ERRCODE_NOT_PERMITTED (xmedia_s32)(0x8001000F) // Operation not permitted
|
||||
#define XMEDIA_ERRCODE_EXIST (xmedia_s32)(0x80010010) // Target exists
|
||||
#define XMEDIA_ERRCODE_NOT_EXIST (xmedia_s32)(0x80010011) // Target does not exist
|
||||
#define XMEDIA_ERRCODE_NOT_READY (xmedia_s32)(0x80010012) // Target not ready
|
||||
#define XMEDIA_ERRCODE_BUSY (xmedia_s32)(0x80010013) // Device or resource busy
|
||||
#define XMEDIA_ERRCODE_COPY_DATA_ERROR (xmedia_s32)(0x80010014)
|
||||
#define XMEDIA_ERRCODE_TYPE_ERROR (xmedia_s32)(0x80010015)
|
||||
#define XMEDIA_ERRCODE_CHN_FULL (xmedia_s32)(0x80010016)
|
||||
#define XMEDIA_ERRCODE_INVALID_CHN_ID (xmedia_s32)(0x80010017)
|
||||
#define XMEDIA_ERRCODE_INVALID_DEV_ID (xmedia_s32)(0x80010018)
|
||||
#define XMEDIA_ERRCODE_INVALID_PIPE_ID (xmedia_s32)(0x80010019)
|
||||
#define XMEDIA_ERRCODE_INVALID_GRP_ID (xmedia_s32)(0x8001001A)
|
||||
#define XMEDIA_ERRCODE_NOT_CONFIG (xmedia_s32)(0x8001001B)
|
||||
#define XMEDIA_ERRCODE_NOT_ENABLE (xmedia_s32)(0x8001001C)
|
||||
#define XMEDIA_ERRCODE_NOT_DISABLE (xmedia_s32)(0x8001001D)
|
||||
#define XMEDIA_ERRCODE_NOT_BIND (xmedia_s32)(0x8001001E)
|
||||
#define XMEDIA_ERRCODE_BINDED (xmedia_s32)(0x8001001F)
|
||||
|
||||
#define MODULE_DBG_EMERG 0
|
||||
#define MODULE_DBG_ALERT 1
|
||||
#define MODULE_DBG_CRIT 2
|
||||
#define MODULE_DBG_ERR 3
|
||||
#define MODULE_DBG_WARN 4
|
||||
#define MODULE_DBG_NOTICE 5
|
||||
#define MODULE_DBG_INFO 6
|
||||
#define MODULE_DBG_DEBUG 7
|
||||
#define ALIGN_NUM 4
|
||||
|
||||
#define MODULE_USR_DEFAULT_DBG MODULE_DBG_ERR // 用户态日志管理初始化失败时各模块的打印等级
|
||||
#define ATTRIBUTE __attribute__((aligned (ALIGN_NUM)))
|
||||
|
||||
typedef enum {
|
||||
MOD_ID_VB = 0,
|
||||
MOD_ID_SYS = 1,
|
||||
MOD_ID_LOG = 2,
|
||||
|
||||
MOD_ID_RGN = 3,
|
||||
MOD_ID_CHNL = 4,
|
||||
MOD_ID_VI = 5,
|
||||
MOD_ID_VO = 6,
|
||||
MOD_ID_DIS = 7,
|
||||
MOD_ID_AVS = 8,
|
||||
MOD_ID_VPSS = 9,
|
||||
MOD_ID_ISP = 10,
|
||||
MOD_ID_FB = 11,
|
||||
MOD_ID_GDC = 12,
|
||||
MOD_ID_TDE = 13,
|
||||
MOD_ID_VGS = 14,
|
||||
MOD_ID_MCF = 15,
|
||||
MOD_ID_HDMI = 16,
|
||||
|
||||
MOD_ID_VDEC = 17,
|
||||
MOD_ID_VENC = 18,
|
||||
MOD_ID_VPU = 19,
|
||||
MOD_ID_VALG = 20,
|
||||
MOD_ID_RC = 21,
|
||||
MOD_ID_JPEGE = 22,
|
||||
MOD_ID_JPEGD = 23,
|
||||
MOD_ID_H264E = 24,
|
||||
MOD_ID_H264D = 25,
|
||||
MOD_ID_H265E = 26,
|
||||
|
||||
MOD_ID_AIO = 29,
|
||||
MOD_ID_AI = 30,
|
||||
MOD_ID_AO = 31,
|
||||
MOD_ID_AENC = 32,
|
||||
MOD_ID_ADEC = 33,
|
||||
MOD_ID_ACOMM = 34,
|
||||
|
||||
MOD_ID_NPU = 35,
|
||||
MOD_ID_IVE = 36,
|
||||
MOD_ID_USER = 37,
|
||||
MOD_ID_PM = 38,
|
||||
MOD_ID_GYRODIS = 39,
|
||||
MOD_ID_IR = 40,
|
||||
MOD_ID_NPU_SVP = 41,
|
||||
MOD_ID_DDR_OST_QOS = 42,
|
||||
MOD_ID_CIPHER = 43,
|
||||
|
||||
MOD_ID_MAX,
|
||||
} xmedia_mod_id;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 width;
|
||||
xmedia_u32 height;
|
||||
} xmedia_video_size;
|
||||
|
||||
typedef struct {
|
||||
xmedia_s32 x;
|
||||
xmedia_s32 y;
|
||||
xmedia_u32 width;
|
||||
xmedia_u32 height;
|
||||
} xmedia_video_rect;
|
||||
|
||||
typedef enum {
|
||||
/* Semi-Planner */
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420 = 0,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_444,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_444,
|
||||
|
||||
/* Package */
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YUYV_PACKAGE_422 = 0x40,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YVYU_PACKAGE_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_UYVY_PACKAGE_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_VYUY_PACKAGE_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YYUV_PACKAGE_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YYVU_PACKAGE_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_UVYY_PACKAGE_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_VUYY_PACKAGE_422,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_VY1UY0_PACKAGE_422,
|
||||
|
||||
/*yuv 400 */
|
||||
XMEDIA_VIDEO_PIXEL_FMT_YUV_400 = 0x90,
|
||||
|
||||
/*RGB*/
|
||||
XMEDIA_VIDEO_PIXEL_FMT_ARGB_1555 = 0xC0,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_ARGB_4444,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_ARGB_8888,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_ABGR_1555,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_ABGR_4444,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_ABGR_8888,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_RGBA_1555,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_RGBA_4444,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_RGBA_8888,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_BGRA_1555,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_BGRA_4444,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_BGRA_8888,
|
||||
|
||||
XMEDIA_VIDEO_PIXEL_FMT_RGB_565,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_RGB_888,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_BGR_565,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_BGR_888,
|
||||
|
||||
/*CLUT*/
|
||||
XMEDIA_VIDEO_PIXEL_FMT_CLUT2 = 0x100,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_CLUT4,
|
||||
XMEDIA_VIDEO_PIXEL_FMT_CLUT8,
|
||||
|
||||
/*RAW*/
|
||||
XMEDIA_VIDEO_PIXEL_FMT_RAW = 0x110,
|
||||
|
||||
XMEDIA_VIDEO_PIXEL_FMT_MAX = 0x120
|
||||
} xmedia_video_pixel_format;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VIDEO_FMT_LINEAR = 0x0,
|
||||
XMEDIA_VIDEO_FMT_TILE_16x4,
|
||||
XMEDIA_VIDEO_FMT_TILE_32x4,
|
||||
XMEDIA_VIDEO_FMT_TILE_64x4,
|
||||
XMEDIA_VIDEO_FMT_TILE_64x64,
|
||||
XMEDIA_VIDEO_FMT_MAX
|
||||
} xmedia_video_format;
|
||||
|
||||
/*维度:
|
||||
*yuv、RGB、RAW
|
||||
*有损/无损,
|
||||
*行、帧、段紧凑、段非紧凑
|
||||
*/
|
||||
typedef enum {
|
||||
XMEDIA_VIDEO_COMPRESS_MODE_NONE = 0x0,
|
||||
XMEDIA_VIDEO_COMPRESS_MODE_LINE, // 3DNR 使用行压缩
|
||||
XMEDIA_VIDEO_COMPRESS_MODE_FRAME,
|
||||
XMEDIA_VIDEO_COMPRESS_MODE_SEG,
|
||||
XMEDIA_VIDEO_COMPRESS_MODE_TILE,
|
||||
XMEDIA_VIDEO_COMPRESS_MODE_SLICE,
|
||||
|
||||
XMEDIA_VIDEO_COMPRESS_MODE_MAX
|
||||
} xmedia_video_compress_mode;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VIDEO_COLOR_SPACE_YUV = 0x0,
|
||||
XMEDIA_VIDEO_COLOR_SPACE_RGB,
|
||||
XMEDIA_VIDEO_COLOR_SPACE_MAX
|
||||
} xmedia_video_color_space;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VIDEO_COLOR_GAMUT_BT601 = 0x0,
|
||||
XMEDIA_VIDEO_COLOR_GAMUT_BT709,
|
||||
XMEDIA_VIDEO_COLOR_GAMUT_BT2020,
|
||||
XMEDIA_VIDEO_COLOR_GAMUT_USER,
|
||||
XMEDIA_VIDEO_COLOR_GAMUT_MAX
|
||||
} xmedia_video_color_gamut;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VIDEO_COLOR_LIMITED_RANGE = 0x0,
|
||||
XMEDIA_VIDEO_COLOR_FULL_RANGE,
|
||||
XMEDIA_VIDEO_COLOR_RANGE_MAX
|
||||
} xmedia_video_color_quantify_range;
|
||||
|
||||
typedef struct {
|
||||
xmedia_video_color_space color_space;
|
||||
xmedia_video_color_gamut color_gamut;
|
||||
xmedia_video_color_quantify_range quantify_range;
|
||||
} xmedia_video_color_descript;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VIDEO_DYNAMIC_RANGE_SDR = 0x0,
|
||||
XMEDIA_VIDEO_DYNAMIC_RANGE_HDR10,
|
||||
XMEDIA_VIDEO_DYNAMIC_RANGE_HLG,
|
||||
XMEDIA_VIDEO_DYNAMIC_RANGE_MAX
|
||||
} xmedia_video_dynamic_range;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VIDEO_DATA_WIDTH_8 = 0x0,
|
||||
XMEDIA_VIDEO_DATA_WIDTH_10,
|
||||
XMEDIA_VIDEO_DATA_WIDTH_12,
|
||||
XMEDIA_VIDEO_DATA_WIDTH_14,
|
||||
XMEDIA_VIDEO_DATA_WIDTH_16,
|
||||
XMEDIA_VIDEO_DATA_WIDTH_MAX
|
||||
} xmedia_video_data_width;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u64 isp_info_phy_addr;
|
||||
xmedia_u64 lowdelay_info_phy_addr;
|
||||
xmedia_u64 vdec_info_phy_addr;
|
||||
|
||||
xmedia_void *ATTRIBUTE isp_info_vir_addr;
|
||||
xmedia_void *ATTRIBUTE lowdelay_info_vir_addr;
|
||||
xmedia_void *ATTRIBUTE vdec_info_vir_addr;
|
||||
} xmedia_video_private_info;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u64 y_head_phy_addr;
|
||||
xmedia_u64 c_head_phy_addr;
|
||||
xmedia_u64 y_phy_addr;
|
||||
xmedia_u64 c_phy_addr;
|
||||
// xmedia_u64 y_buf_phy_addr; // luma buffer start phy addr
|
||||
// xmedia_u64 c_buf_phy_addr; // chroma buffer start phy addr
|
||||
// xmedia_u32 y_size; // luma buffer size
|
||||
// xmedia_u32 c_size; // chroma buffer size
|
||||
} xmedia_video_frame_address;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 y_head_stride;
|
||||
xmedia_u32 c_head_stride;
|
||||
xmedia_u32 y_stride;
|
||||
xmedia_u32 c_stride;
|
||||
} xmedia_video_frame_stride;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 index;
|
||||
|
||||
xmedia_u32 width;
|
||||
xmedia_u32 height;
|
||||
xmedia_video_frame_address addr;
|
||||
xmedia_video_frame_stride stride;
|
||||
|
||||
xmedia_video_data_width bit_width;
|
||||
xmedia_video_pixel_format pixel_fmt;
|
||||
xmedia_video_compress_mode compress_mode;
|
||||
xmedia_video_format video_fmt;
|
||||
|
||||
xmedia_video_dynamic_range dynamic_range;
|
||||
xmedia_video_color_descript color_info;
|
||||
|
||||
xmedia_u64 pts;
|
||||
xmedia_u32 time_ref;
|
||||
xmedia_u32 frame_flag;
|
||||
xmedia_video_private_info priv_info;
|
||||
} xmedia_video_frame;
|
||||
|
||||
typedef struct {
|
||||
xmedia_video_frame frame;
|
||||
xmedia_u32 pool_id;
|
||||
xmedia_mod_id mod_id;
|
||||
} xmedia_video_frame_info;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_8BIT = 0,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_10BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_12BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_14BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_16BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_20BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_24BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_YUV420_8BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_YUV420_LEGACY_8BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_YUV422_8BIT,
|
||||
XMEDIA_INTF_MIPI_CSI_DATA_TYPE_MAX
|
||||
} xmedia_intf_mipi_csi_data_type;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_MIPI_DSI_DATA_TYPE_YUV422_16BIT = 0,
|
||||
XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB666_18BIT,
|
||||
XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB888_24BIT,
|
||||
XMEDIA_INTF_MIPI_DSI_DATA_TYPE_MAX
|
||||
} xmedia_intf_mipi_dsi_data_type;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_BT_DATA_TYPE_YUV422_8BIT = 0,
|
||||
XMEDIA_INTF_BT_DATA_TYPE_YUV422_10BIT,
|
||||
XMEDIA_INTF_BT_DATA_TYPE_MAX
|
||||
} xmedia_intf_bt_data_type;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_LCD_DATA_TYPE_RGB565_16BIT = 0,
|
||||
XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT,
|
||||
XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT,
|
||||
XMEDIA_INTF_LCD_DATA_TYPE_MAX
|
||||
} xmedia_intf_lcd_data_type;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_LVDS_DATA_TYPE_RGB666_18BIT = 0,
|
||||
XMEDIA_INTF_LVDS_DATA_TYPE_RGB666_36BIT,
|
||||
XMEDIA_INTF_LVDS_DATA_TYPE_RGB888_24BIT,
|
||||
XMEDIA_INTF_LVDS_DATA_TYPE_RGB888_48BIT,
|
||||
XMEDIA_INTF_LVDS_DATA_TYPE_MAX
|
||||
} xmedia_intf_lvds_data_type;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_DC_DATA_TYPE_RAW_8BIT = 0,
|
||||
XMEDIA_INTF_DC_DATA_TYPE_RAW_10BIT,
|
||||
XMEDIA_INTF_DC_DATA_TYPE_RAW_12BIT,
|
||||
XMEDIA_INTF_DC_DATA_TYPE_RAW_14BIT,
|
||||
XMEDIA_INTF_DC_DATA_TYPE_RAW_16BIT,
|
||||
XMEDIA_INTF_DC_DATA_TYPE_MAX
|
||||
} xmedia_intf_dc_data_type;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_TYPE_BT601 = 0,
|
||||
XMEDIA_INTF_TYPE_BT656,
|
||||
XMEDIA_INTF_TYPE_BT1120,
|
||||
XMEDIA_INTF_TYPE_MIPI_CSI,
|
||||
XMEDIA_INTF_TYPE_MIPI_DSI,
|
||||
XMEDIA_INTF_TYPE_LCD,
|
||||
XMEDIA_INTF_TYPE_LVDS,
|
||||
XMEDIA_INTF_TYPE_DC,
|
||||
XMEDIA_INTF_TYPE_MCU,
|
||||
XMEDIA_INTF_TYPE_MAX
|
||||
} xmedia_intf_type;
|
||||
|
||||
/* bt601&bt656 */
|
||||
typedef enum {
|
||||
XMEDIA_INTF_BT601_BT656_DATA_SEQ_UYVY = 0,
|
||||
XMEDIA_INTF_BT601_BT656_DATA_SEQ_VYUY,
|
||||
XMEDIA_INTF_BT601_BT656_DATA_SEQ_YUYV,
|
||||
XMEDIA_INTF_BT601_BT656_DATA_SEQ_YVYU,
|
||||
XMEDIA_INTF_BT601_BT656_DATA_SEQ_MAX
|
||||
} xmedia_intf_bt601_bt656_data_seq;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_BT1120_DATA_SEQ_VUVU = 0,
|
||||
XMEDIA_INTF_BT1120_DATA_SEQ_UVUV,
|
||||
XMEDIA_INTF_BT1120_DATA_SEQ_MAX,
|
||||
} xmedia_intf_bt1120_data_seq;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_LCD_DATA_SEQ_RGB = 0,
|
||||
XMEDIA_INTF_LCD_DATA_SEQ_RBG,
|
||||
XMEDIA_INTF_LCD_DATA_SEQ_GRB,
|
||||
XMEDIA_INTF_LCD_DATA_SEQ_GBR,
|
||||
XMEDIA_INTF_LCD_DATA_SEQ_BRG,
|
||||
XMEDIA_INTF_LCD_DATA_SEQ_BGR,
|
||||
XMEDIA_INTF_LCD_DATA_SEQ_MAX,
|
||||
} xmedia_intf_lcd_data_seq;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_INTF_LVDS_FORMAT_VESA = 0,
|
||||
XMEDIA_INTF_LVDS_FORMAT_JEIDA,
|
||||
XMEDIA_INTF_LVDS_FORMAT_MAX
|
||||
} xmedia_intf_lvds_format;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifndef __DRV_VO_COMMON_H__
|
||||
#define __DRV_VO_COMMON_H__
|
||||
#include <net.h>
|
||||
#include <exports.h>
|
||||
#include <serial.h>
|
||||
#include <xyzModem.h>
|
||||
#include "xmedia_vo.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define VO_MIN_CHN_WIDTH 32
|
||||
#define VO_MIN_CHN_HEIGHT 32
|
||||
#define VO_MAX_ZOOM_RATIO 1000
|
||||
#define VO_MAX_DEV_NUM 4
|
||||
#define VO_MAX_LAYER_NUM 4
|
||||
#define VO_MAX_CHN_NUM 4
|
||||
#define VO_MIN_TOLERATE 1
|
||||
#define VO_MAX_TOLERATE 100000
|
||||
|
||||
#define VO_INVALID_CHN_ID VO_MAX_CHN_NUM
|
||||
#define VO_INVALID_NODE_INDEX 0
|
||||
|
||||
#ifdef xmorca
|
||||
#define XMEDIA_VO_REAL_DEV_NUM XMEDIA_VO_DEV_1
|
||||
#define XMEDIA_VO_REAL_LAYER_NUM XMEDIA_VO_LAYER_V1
|
||||
#define XMEDIA_VO_VIRT_DEV_NUM 1
|
||||
#define XMEDIA_VO_VIRT_LAYER_NUM 1
|
||||
#endif
|
||||
|
||||
#ifdef xmfalcon
|
||||
#define XMEDIA_VO_REAL_DEV_NUM XMEDIA_VO_DEV_VIRT_0
|
||||
#define XMEDIA_VO_REAL_LAYER_NUM XMEDIA_VO_LAYER_VIRT_V0
|
||||
#define XMEDIA_VO_VIRT_DEV_NUM 2
|
||||
#define XMEDIA_VO_VIRT_LAYER_NUM 2
|
||||
#endif
|
||||
#define VO_CHECK_VAILD_DEV(dev) ((((dev) >= (XMEDIA_VO_DEV_0)) && ((dev) < (XMEDIA_VO_REAL_DEV_NUM))) || \
|
||||
(((dev) >= (XMEDIA_VO_DEV_VIRT_0)) && ((dev) < ((XMEDIA_VO_DEV_VIRT_0) + (XMEDIA_VO_VIRT_DEV_NUM)))))
|
||||
|
||||
#define VO_CHECK_REAL_DEV(dev) (((dev) >= (XMEDIA_VO_DEV_0)) && ((dev) < (XMEDIA_VO_REAL_DEV_NUM)))
|
||||
|
||||
#define VO_CHECK_VIRT_DEV(dev) (((dev) >= XMEDIA_VO_DEV_VIRT_0) && \
|
||||
((dev) < ((XMEDIA_VO_DEV_VIRT_0) + (XMEDIA_VO_VIRT_DEV_NUM))))
|
||||
|
||||
#define VO_CHECK_VAILD_LAYER(layer) ((((layer) >= (XMEDIA_VO_LAYER_V0)) && ((layer) < (XMEDIA_VO_REAL_LAYER_NUM))) || \
|
||||
(((layer) >= (XMEDIA_VO_LAYER_VIRT_V0)) && ((layer) < ((XMEDIA_VO_LAYER_VIRT_V0) + (XMEDIA_VO_VIRT_LAYER_NUM)))))
|
||||
|
||||
|
||||
#define VO_TRACE(level, fmt, ...) \
|
||||
do { \
|
||||
if (level <= MODULE_DBG_ERR) { \
|
||||
printf("[Func]:%s [Line]:%d [Info]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_VO_PTR_RETURN(pointer) \
|
||||
do { \
|
||||
if ((pointer) == XMEDIA_NULL) { \
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo para is null ptr.\n"); \
|
||||
return XMEDIA_ERRCODE_NULL_PTR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_VO_DEV_ID_RETURN(dev) \
|
||||
do { \
|
||||
if (dev >= XMEDIA_VO_DEV_MAX) { \
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo dev %d is invalid.\n",dev); \
|
||||
return XMEDIA_ERRCODE_INVALID_DEV_ID; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_VO_DEV_ID(dev) \
|
||||
do { \
|
||||
if (dev >= XMEDIA_VO_DEV_MAX) { \
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo dev %d is invalid.\n",dev); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define CHECK_VO_LAYER_ID_RETURN(layer) \
|
||||
do { \
|
||||
if (layer >= XMEDIA_VO_LAYER_MAX){ \
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo layer %d is invalid.\n",layer); \
|
||||
return XMEDIA_ERRCODE_INVALID_GRP_ID; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_VO_CHN_ID_RETURN(chn) \
|
||||
do { \
|
||||
if ((chn < 0) || (chn >= VO_MAX_CHN_NUM)) { \
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo chn %d is invalid.\n",chn); \
|
||||
return XMEDIA_ERRCODE_INVALID_CHN_ID; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_VO_ZERO_RETURN(value) \
|
||||
do { \
|
||||
if (value == 0) { \
|
||||
VO_TRACE(MODULE_DBG_ERR,"a denominator of 0 is illegal\n"); \
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define IS_ALIGN(x, bitw) (((x % bitw) == 0) ? XMEDIA_TRUE : XMEDIA_FALSE)
|
||||
|
||||
#define osal_memset(ptr, value, len) memset(ptr, value, len)
|
||||
#define osal_mdelay(msecs) mdelay(msecs)
|
||||
#define osal_memcpy(dst, src, size) memcpy(dst, src, size)
|
||||
#define osal_udelay(usecs) udelay(usecs)
|
||||
#define osal_vmalloc(size) malloc(size)
|
||||
#define osal_vfree(addr) free(addr)
|
||||
|
||||
typedef enum {
|
||||
VO_ISR_INTERRUPT_TYPE = 0,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD0_VTT0 = 0x1,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD0_VTT1 = 0x2,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD0_VTT2 = 0x4,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD0_VTT3 = 0x8,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD0_UFINT = 0x10000, //low band width
|
||||
|
||||
VO_ISR_INTERRUPT_TYPE_DHD1_VTT0 = 0x10,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD1_VTT1 = 0x20,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD1_VTT2 = 0x40,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD1_VTT3 = 0x80,
|
||||
VO_ISR_INTERRUPT_TYPE_DHD1_UFINT = 0x20000,
|
||||
|
||||
VO_ISR_INTERRUPT_TYPE_LOW_DELAY_CERR = 0x100000,
|
||||
VO_ISR_INTERRUPT_TYPE_LOW_DELAY_YERR = 0x200000,
|
||||
|
||||
VO_ISR_INTERRUPT_TYPE_BUSR_ERR = 0x1000000,
|
||||
VO_ISR_INTERRUPT_TYPE_BUSW_ERR = 0x2000000,
|
||||
|
||||
VO_ISR_INTERRUPT_TYPE_ALL = 0xffffffff,
|
||||
} vo_isr_interrupt_type;
|
||||
|
||||
typedef enum {
|
||||
VO_ISR_FIELD_FLAG_FRAME = 0,
|
||||
VO_ISR_FIELD_FLAG_TOP,
|
||||
VO_ISR_FIELD_FLAG_BOTTOM,
|
||||
VO_ISR_FIELD_FLAG_TOP_BOTTOM,
|
||||
VO_ISR_FIELD_FLAG_MAX
|
||||
} vo_isr_field_flag;
|
||||
|
||||
#ifdef xmorca
|
||||
typedef enum {
|
||||
VO_CSC_YUV2RGB_601_LIMIT2FULL = 0,
|
||||
VO_CSC_YUV2RGB_709_LIMIT2FULL,
|
||||
VO_CSC_YUV2RGB_601_FULL2LIMIT,
|
||||
VO_CSC_YUV2RGB_709_FULL2LIMIT,
|
||||
VO_CSC_YUV2RGB_601_FULL2FULL,
|
||||
VO_CSC_YUV2RGB_709_FULL2FULL,
|
||||
VO_CSC_YUV2RGB_601_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2RGB_709_LIMIT2LIMIT,
|
||||
|
||||
VO_CSC_YUV2YUV_601_601_LIMIT2LIMIT = 8,
|
||||
VO_CSC_YUV2YUV_601_709_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_601_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_709_LIMIT2LIMIT,
|
||||
|
||||
VO_CSC_YUV2YUV_601_601_FULL2FULL = 12,
|
||||
VO_CSC_YUV2YUV_601_709_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_709_601_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_709_709_FULL2FULL,
|
||||
|
||||
VO_CSC_YUV2YUV_601_601_LIMIT2FULL = 16,
|
||||
VO_CSC_YUV2YUV_601_709_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_709_601_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_709_709_LIMIT2FULL,
|
||||
|
||||
VO_CSC_YUV2YUV_601_601_FULL2LIMIT = 20,
|
||||
VO_CSC_YUV2YUV_601_709_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_601_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_709_FULL2LIMIT,
|
||||
VO_CSC_MAX
|
||||
} vo_csc_type;
|
||||
#endif
|
||||
|
||||
#ifdef xmfalcon
|
||||
typedef enum {
|
||||
VO_CSC_YUV2RGB_601_LIMIT2FULL = 0,
|
||||
VO_CSC_YUV2RGB_709_LIMIT2FULL,
|
||||
VO_CSC_YUV2RGB_2020_LIMIT2FULL,
|
||||
VO_CSC_YUV2RGB_601_FULL2LIMIT,
|
||||
VO_CSC_YUV2RGB_709_FULL2LIMIT,
|
||||
VO_CSC_YUV2RGB_2020_FULL2LIMIT,
|
||||
VO_CSC_YUV2RGB_601_FULL2FULL,
|
||||
VO_CSC_YUV2RGB_709_FULL2FULL,
|
||||
VO_CSC_YUV2RGB_2020_FULL2FULL,
|
||||
VO_CSC_YUV2RGB_601_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2RGB_709_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2RGB_2020_LIMIT2LIMIT,
|
||||
|
||||
VO_CSC_RGB2YUV_601_LIMIT2FULL = 12,
|
||||
VO_CSC_RGB2YUV_709_LIMIT2FULL,
|
||||
VO_CSC_RGB2YUV_2020_LIMIT2FULL,
|
||||
VO_CSC_RGB2YUV_601_FULL2LIMIT,
|
||||
VO_CSC_RGB2YUV_709_FULL2LIMIT,
|
||||
VO_CSC_RGB2YUV_2020_FULL2LIMIT,
|
||||
VO_CSC_RGB2YUV_601_FULL2FULL,
|
||||
VO_CSC_RGB2YUV_709_FULL2FULL,
|
||||
VO_CSC_RGB2YUV_2020_FULL2FULL,
|
||||
VO_CSC_RGB2YUV_601_LIMIT2LIMIT,
|
||||
VO_CSC_RGB2YUV_709_LIMIT2LIMIT,
|
||||
VO_CSC_RGB2YUV_2020_LIMIT2LIMIT,
|
||||
|
||||
VO_CSC_YUV2YUV_601_601_LIMIT2LIMIT = 24,
|
||||
VO_CSC_YUV2YUV_601_709_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_601_2020_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_601_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_709_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_2020_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_2020_601_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_2020_709_LIMIT2LIMIT,
|
||||
VO_CSC_YUV2YUV_2020_2020_LIMIT2LIMIT,
|
||||
|
||||
VO_CSC_YUV2YUV_601_601_FULL2FULL = 33,
|
||||
VO_CSC_YUV2YUV_601_709_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_601_2020_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_709_601_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_709_709_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_709_2020_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_2020_601_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_2020_709_FULL2FULL,
|
||||
VO_CSC_YUV2YUV_2020_2020_FULL2FULL,
|
||||
|
||||
VO_CSC_YUV2YUV_601_601_LIMIT2FULL = 42,
|
||||
VO_CSC_YUV2YUV_601_709_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_601_2020_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_709_601_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_709_709_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_709_2020_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_2020_601_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_2020_709_LIMIT2FULL,
|
||||
VO_CSC_YUV2YUV_2020_2020_LIMIT2FULL,
|
||||
|
||||
VO_CSC_YUV2YUV_601_601_FULL2LIMIT = 51,
|
||||
VO_CSC_YUV2YUV_601_709_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_601_2020_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_601_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_709_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_709_2020_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_2020_601_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_2020_709_FULL2LIMIT,
|
||||
VO_CSC_YUV2YUV_2020_2020_FULL2LIMIT,
|
||||
|
||||
VO_CSC_RGB2RGB_LIMIT2LIMIT = 60,
|
||||
VO_CSC_RGB2RGB_FULL2FULL,
|
||||
VO_CSC_RGB2RGB_FULL2LIMIT,
|
||||
VO_CSC_RGB2RGB_LIMIT2FULL,
|
||||
|
||||
VO_CSC_MAX
|
||||
} vo_csc_type;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
vo_csc_type csc_type;
|
||||
xmedia_u32 luma;
|
||||
xmedia_u32 contrast;
|
||||
xmedia_u32 hue;
|
||||
xmedia_u32 saturation;
|
||||
} vo_pic_info;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u64 lum_addr;
|
||||
xmedia_u64 chm_addr;
|
||||
xmedia_u32 lum_stride;
|
||||
xmedia_u32 chm_stride;
|
||||
} vo_addr;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool config;
|
||||
xmedia_bool enable;
|
||||
xmedia_u32 chn; //硬件region区域 所对应的软件chn号
|
||||
xmedia_video_rect src_rect;
|
||||
xmedia_video_rect dst_rect;
|
||||
xmedia_video_rect lba_rect;
|
||||
xmedia_u32 lba_color;
|
||||
vo_addr region_addr;
|
||||
} vo_region_info;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool mute_en;
|
||||
xmedia_video_rect frame_rect; //真实内容 相对于显示窗口的rect
|
||||
xmedia_video_rect video_rect; //层 相对于显示窗口的rect
|
||||
xmedia_video_rect lba_rect;
|
||||
xmedia_u32 lba_color;
|
||||
vo_addr frame_addr;
|
||||
} vo_layer_single_cfg;
|
||||
|
||||
typedef struct {
|
||||
xmedia_video_rect reso_rect;
|
||||
xmedia_video_rect disp_rect;
|
||||
xmedia_u32 region_id;
|
||||
xmedia_bool region_overlap;
|
||||
xmedia_u32 overlap_id;
|
||||
xmedia_u32 region_sort;
|
||||
vo_region_info region[VO_MAX_CHN_NUM]; //硬件region区域配置
|
||||
} vo_layer_multi_cfg;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool bt656_intf_en;
|
||||
xmedia_bool bt1120_intf_en;
|
||||
xmedia_bool lcd_intf_en;
|
||||
xmedia_bool mipi_intf_en;
|
||||
xmedia_bool lvds_intf_en;
|
||||
xmedia_vo_dev dev;
|
||||
} vo_dev_intf_type_mux;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef DRV_REG_CRG_H
|
||||
#define DRV_REG_CRG_H
|
||||
|
||||
#define CRG_REGS_ADDR 0x12010000
|
||||
#define CRG_REGS_SIZE 0X10000
|
||||
|
||||
#define CRG_PERCTL0_ADDR (CRG_REGS_ADDR + 0x0)
|
||||
#define CRG_PERCTL1_ADDR (CRG_REGS_ADDR + 0x4)
|
||||
#define CRG_PERCTL2_ADDR (CRG_REGS_ADDR + 0x8)
|
||||
|
||||
#define CRG_PERCTL50_ADDR (CRG_REGS_ADDR + 0xc8)
|
||||
#define CRG_PERCTL65_ADDR (CRG_REGS_ADDR + 0x104)
|
||||
#define CRG_PERCTL66_ADDR (CRG_REGS_ADDR + 0x108)
|
||||
#define CRG_PERCTL67_ADDR (CRG_REGS_ADDR + 0x10c)
|
||||
#define CRG_PERCTL121_ADDR (CRG_REGS_ADDR + 0x1e4)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef DRV_REG_SYS_H
|
||||
#define DRV_REG_SYS_H
|
||||
|
||||
#define SYS_REGS_ADDR 0x12020000
|
||||
#define SYS_REGS_SIZE 0x8000
|
||||
|
||||
#define MISC_REGS_ADDR 0x12028000
|
||||
#define MISC_REGS_SIZE 0x8000
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "sys_drv.h"
|
||||
#include "sys_hal.h"
|
||||
#include "drv_sys.h"
|
||||
#include "xmedia_vo.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
#define PHASE 32
|
||||
#define SYS_MULTI_V 1048576
|
||||
#define SYS_MULTI_H 1048576
|
||||
|
||||
|
||||
|
||||
xmedia_s32 sys_mod_init(xmedia_void)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
ret = sys_hal_init();
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 sys_mod_exit(xmedia_void)
|
||||
{
|
||||
sys_hal_exit();
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
xmedia_s32 sys_mod_ctrl(xmedia_chn_info *chn_info, sys_func_id func_id, xmedia_void *io_args)
|
||||
{
|
||||
xmedia_s32 dev;
|
||||
|
||||
dev = chn_info->dev_id;
|
||||
switch (func_id) {
|
||||
case SYS_VO_VOU_HD_CKSEL:{
|
||||
xmedia_u32 *vou_hd_sel = XMEDIA_NULL;
|
||||
vou_hd_sel = (xmedia_u32 *)io_args;
|
||||
sys_hal_vo_vou_hd_sel(dev, *vou_hd_sel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_VOU_PPC_CKSEL: {
|
||||
xmedia_u32 *vou_ppc_cksel = XMEDIA_NULL;
|
||||
vou_ppc_cksel = (xmedia_u32 *)io_args;
|
||||
sys_hal_vo_vou_ppc_cksel(*vou_ppc_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDS_POR_SRST: {
|
||||
xmedia_bool *lvd_por_srst = XMEDIA_NULL;
|
||||
lvd_por_srst = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvds_por_srst(*lvd_por_srst);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_MIPITX_PLL_REF_CKSEL: {
|
||||
xmedia_bool *mipitx_pll_ref_cksel = XMEDIA_NULL;
|
||||
mipitx_pll_ref_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_mipitx_pll_ref_cksel(*mipitx_pll_ref_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDS_CKSEL:{
|
||||
xmedia_bool *lvds_cksel = XMEDIA_NULL;
|
||||
lvds_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvds_cksel(dev, *lvds_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_DIV_CFG:{
|
||||
xmedia_u32 *lcd_div_cfg = XMEDIA_NULL;
|
||||
lcd_div_cfg = (xmedia_u32 *)io_args;
|
||||
sys_hal_vo_lcd_div_cfg(*lcd_div_cfg);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_PLL_DIV_CFG:{
|
||||
xmedia_u32 *pll_div_cfg = XMEDIA_NULL;
|
||||
pll_div_cfg = (xmedia_u32 *)io_args;
|
||||
if(sys_hal_vo_pll_div_cfg(*pll_div_cfg) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_VOU_HD_CKEN:{
|
||||
xmedia_bool *vou_hd_cken = XMEDIA_NULL;
|
||||
vou_hd_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_vou_hd_cken(dev, *vou_hd_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_VOU_SRST_REQ:{
|
||||
xmedia_bool *vou_srst_req = XMEDIA_NULL;
|
||||
vou_srst_req = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_vou_srst_req(*vou_srst_req);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_VOU_SRST_GET:{
|
||||
xmedia_bool *vou_srst = XMEDIA_NULL;
|
||||
vou_srst = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_vou_srst_get(vou_srst);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_DIV_CKEN:{
|
||||
xmedia_bool *lcd_div_cken = XMEDIA_NULL;
|
||||
lcd_div_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lcd_div_cken(*lcd_div_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_PLL_DIV_CKEN:{
|
||||
xmedia_bool *pll_div_cken = XMEDIA_NULL;
|
||||
pll_div_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_pll_div_cken(*pll_div_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_BT_HD_CKSEL:{
|
||||
xmedia_bool *bt_hd_cksel = XMEDIA_NULL;
|
||||
bt_hd_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_bt_hd_cksel(*bt_hd_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_HD_CKSEL:{
|
||||
xmedia_bool *lcd_hd_cksel = XMEDIA_NULL;
|
||||
lcd_hd_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lcd_hd_cksel(*lcd_hd_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_MIPITX_HD_CKSEL:{
|
||||
xmedia_bool *mipitx_hd_cksel = XMEDIA_NULL;
|
||||
mipitx_hd_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_mipitx_hd_cksel(*mipitx_hd_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDSTX_HD_CKSEL:{
|
||||
xmedia_bool *lvdstx_hd_cksel = XMEDIA_NULL;
|
||||
lvdstx_hd_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvdstx_hd_cksel(*lvdstx_hd_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_BT_PCTRL:{
|
||||
xmedia_bool *bt_pctrl = XMEDIA_NULL;
|
||||
bt_pctrl = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_bt_pctrl(*bt_pctrl);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_PCTRL:{
|
||||
xmedia_bool *lcd_pctrl = XMEDIA_NULL;
|
||||
lcd_pctrl = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lcd_pctrl(*lcd_pctrl);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_MIPITX_PCTRL:{
|
||||
xmedia_bool *mipitx_pctrl = XMEDIA_NULL;
|
||||
mipitx_pctrl = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_mipitx_pctrl(*mipitx_pctrl);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDSTX_PCTRL:{
|
||||
xmedia_bool *lvdstx_pctrl = XMEDIA_NULL;
|
||||
lvdstx_pctrl = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvdstx_pctrl(*lvdstx_pctrl);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_BT_CKEN:{
|
||||
xmedia_bool *bt_cken = XMEDIA_NULL;
|
||||
bt_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_bt_cken(*bt_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_CKEN:{
|
||||
xmedia_bool *lcd_cken = XMEDIA_NULL;
|
||||
lcd_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lcd_cken(*lcd_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_MIPITX_CKEN:{
|
||||
xmedia_bool *mipitx_cken = XMEDIA_NULL;
|
||||
mipitx_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_mipitx_cken(*mipitx_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDSTX_CKEN:{
|
||||
xmedia_bool *lvdstx_cken = XMEDIA_NULL;
|
||||
lvdstx_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvdstx_cken(*lvdstx_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default: {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef SYS_DRV_H
|
||||
#define SYS_DRV_H
|
||||
|
||||
#include "drv_sys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
/*
|
||||
* End : Segment compress parameter data definition.
|
||||
*/
|
||||
xmedia_s32 sys_mod_init(xmedia_void);
|
||||
xmedia_s32 sys_mod_exit(xmedia_void);
|
||||
|
||||
xmedia_s32 sys_mod_ctrl(xmedia_chn_info *chn_info, sys_func_id func_id, xmedia_void *io_args);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
#endif /* End of #ifndef SYS_DRV_H */
|
||||
|
||||
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "drv_reg_crg.h"
|
||||
#include "drv_reg_sys.h"
|
||||
#include "sys_hal.h"
|
||||
#include "xmedia_vo.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
|
||||
#define DDRC0_REG_ADDR 0x120d0000 /* base addr of DDRCB */
|
||||
#define DDRC_REGS_SIZE 0x10000
|
||||
|
||||
#define SCT_REGS_ADDR 0x12050000 /* base addr of syscnt */
|
||||
#define SCT_REGS_SIZE 0x100
|
||||
|
||||
#define OTP_REGS_ADDR 0x100A0000
|
||||
#define OTP_REGS_SIZE 0X10000
|
||||
|
||||
#define APLL_VO_VCO_MAX 3700
|
||||
#define APLL_VO_VCO_MIN 1000
|
||||
|
||||
void *g_reg_crg_base_va = (void *)CRG_REGS_ADDR;
|
||||
void *g_reg_sys_base_va = (void *)SYS_REGS_ADDR;
|
||||
void *g_reg_ddr0_base_va = (void *)DDRC0_REG_ADDR;
|
||||
void *g_reg_misc_base_va = (void *)MISC_REGS_ADDR;
|
||||
void *g_reg_otp_base_va = (void *)OTP_REGS_ADDR;
|
||||
void *g_sct_addr = (void *)SCT_REGS_ADDR;
|
||||
|
||||
xmedia_u32 g_sys_efuse_addr = 0;
|
||||
xmedia_u32 g_sys_chip_addr = 0;
|
||||
|
||||
#define IO_CRG_ADDRESS(x) ((uintptr_t)g_reg_crg_base_va + ((x) - (CRG_REGS_ADDR)))
|
||||
#define IO_SYS_ADDRESS(x) ((uintptr_t)g_reg_sys_base_va + ((x) - (SYS_REGS_ADDR)))
|
||||
#define IO_DDR0_ADDRESS(x) ((uintptr_t)g_reg_ddr0_base_va + ((x) - (DDRC0_REG_ADDR)))
|
||||
#define IO_MISC_ADDRESS(x) ((uintptr_t)g_reg_misc_base_va + ((x) - (MISC_REGS_ADDR)))
|
||||
|
||||
static xmedia_u32 hal_vo_sys_reg_read(volatile xmedia_uintptr_t addr)
|
||||
{
|
||||
return *(volatile xmedia_u32 *)(addr);
|
||||
}
|
||||
|
||||
static xmedia_void hal_vo_sys_reg_write(volatile xmedia_uintptr_t addr, xmedia_u32 val)
|
||||
{
|
||||
*(volatile xmedia_u32 *)(addr) = val;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void sys_reg_set_bit(unsigned long value, unsigned long offset, unsigned long addr)
|
||||
{
|
||||
unsigned long t, mask;
|
||||
|
||||
mask = 1 << offset;
|
||||
t = hal_vo_sys_reg_read((xmedia_uintptr_t)addr);
|
||||
t &= ~mask;
|
||||
t |= (value << offset) & mask;
|
||||
hal_vo_sys_reg_write ( (xmedia_uintptr_t)addr, t);
|
||||
}
|
||||
|
||||
static inline void sys_reg_write_32(unsigned long value, unsigned long mask, unsigned long addr)
|
||||
{
|
||||
unsigned long t;
|
||||
|
||||
t = hal_vo_sys_reg_read((xmedia_uintptr_t)addr);
|
||||
t &= ~mask;
|
||||
t |= value & mask;
|
||||
hal_vo_sys_reg_write((xmedia_uintptr_t)addr, t);
|
||||
}
|
||||
|
||||
static inline void sys_reg_read(unsigned int *pvalue, unsigned long addr)
|
||||
{
|
||||
*pvalue = hal_vo_sys_reg_read((uintptr_t)addr);
|
||||
}
|
||||
|
||||
xmedia_s32 sys_hal_usrdef_slv_enable(xmedia_bool enable)
|
||||
{
|
||||
if (enable == XMEDIA_TRUE) {
|
||||
sys_reg_set_bit(1, 1, IO_CRG_ADDRESS(CRG_PERCTL50_ADDR)); // 打开时钟
|
||||
sys_reg_set_bit(0, 0, IO_CRG_ADDRESS(CRG_PERCTL50_ADDR)); // 撤消复位
|
||||
} else if (enable == XMEDIA_FALSE) {
|
||||
sys_reg_set_bit(0, 1, IO_CRG_ADDRESS(CRG_PERCTL50_ADDR)); // 关闭时钟
|
||||
} else {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
xmedia_void sys_hal_vo_vou_hd_sel(xmedia_s32 vo_dev, xmedia_u32 vou_hd_sel)
|
||||
{
|
||||
if(vo_dev == 0) {
|
||||
sys_reg_write_32(vou_hd_sel << 1 , 0xf << 1, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else if (vo_dev == 1) {
|
||||
sys_reg_write_32(vou_hd_sel << 13 , 0xf << 13, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_vou_ppc_cksel(xmedia_u32 vou_ppc_cksel)
|
||||
{
|
||||
sys_reg_write_32(vou_ppc_cksel << 24 , 0x3 << 24, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_lvds_por_srst(xmedia_bool lvd_por_srst)
|
||||
{
|
||||
xmedia_u32 tmp = (lvd_por_srst == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 21, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
|
||||
}
|
||||
xmedia_void sys_hal_vo_mipitx_pll_ref_cksel(xmedia_bool mipitx_pll_ref_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (mipitx_pll_ref_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 20, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
|
||||
static inline xmedia_u64 vo_div64_u64(xmedia_u64 dividend, xmedia_u64 divisor)
|
||||
{
|
||||
return dividend / divisor;
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_lcd_div_cfg(xmedia_u32 lcd_div_cfg)
|
||||
{
|
||||
xmedia_u32 lcd_clk_div = (xmedia_u32)vo_div64_u64(vo_div64_u64((xmedia_u64)lcd_div_cfg , 1375) * (1 << 27),
|
||||
1000*1000);
|
||||
sys_reg_set_bit(0, 28, IO_CRG_ADDRESS(CRG_PERCTL65_ADDR));
|
||||
|
||||
sys_reg_write_32(lcd_clk_div, 0x7ffffff, IO_CRG_ADDRESS(CRG_PERCTL65_ADDR));
|
||||
}
|
||||
|
||||
static xmedia_s32 hal_vo_find_fout_div(xmedia_u32 *fout0_div, xmedia_u32 *fout1_div, xmedia_u32 pll_div,
|
||||
xmedia_u32 *pll_vco){
|
||||
xmedia_u32 fout0;
|
||||
xmedia_u32 fout1;
|
||||
xmedia_u32 vco;
|
||||
|
||||
//fout0 fout1 取值范围都是0 - 15
|
||||
for(fout0 = 0;fout0 < 16;fout0++) {
|
||||
for(fout1 = 0;fout1 < 16;fout1++) {
|
||||
vco = pll_div * (fout0 + 1) * (fout1 + 1);
|
||||
//vco的取值范围是950 - 3800,但ic要求不要取临近值,所以这里使用1000 - 3700
|
||||
if((vco > (APLL_VO_VCO_MIN * 1000)) && (vco < (APLL_VO_VCO_MAX * 1000))) {
|
||||
*fout0_div = fout0;
|
||||
*fout1_div = fout1;
|
||||
*pll_vco = vco;
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
xmedia_s32 sys_hal_vo_pll_div_cfg(xmedia_u32 pll_div_cfg)
|
||||
{
|
||||
xmedia_u32 apll_frac;
|
||||
xmedia_u32 apll_fbdiv;
|
||||
xmedia_u32 fout0_div;
|
||||
xmedia_u32 fout1_div;
|
||||
xmedia_u32 vco;
|
||||
xmedia_u32 pll_div;
|
||||
|
||||
//为避免超出u32范围 对1000取整计算
|
||||
pll_div = pll_div_cfg / 1000;
|
||||
|
||||
//理论不会存在获取不到分频因子的情况
|
||||
if(hal_vo_find_fout_div(&fout0_div, &fout1_div, pll_div, &vco) != XMEDIA_SUCCESS){
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
//apll倍频整数部分
|
||||
apll_fbdiv = (vco / 24) / 1000;
|
||||
//apll倍频小数部分
|
||||
apll_frac = (vco / 24) % 1000;
|
||||
apll_frac = (apll_frac * ((1 << 24) / 1000));
|
||||
|
||||
sys_reg_write_32(apll_frac, 0xffffff, IO_CRG_ADDRESS(CRG_PERCTL0_ADDR));
|
||||
|
||||
// apll 小数/整数分频控制 默认为0 小数分频
|
||||
sys_reg_set_bit(0, 23, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
|
||||
//除了fout1 fout0 其他都bypass
|
||||
sys_reg_write_32(0xc << 18, 0xf << 18, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
|
||||
//参考时钟分频系数默认设置为1 apll参考时钟则为24mhz
|
||||
sys_reg_write_32(0x1 << 12, 0x3f << 12, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
|
||||
sys_reg_write_32(apll_fbdiv, 0xfff, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
|
||||
//APLL 配置fout0 fout1 分频因子
|
||||
sys_reg_write_32(fout0_div | (fout1_div << 4), 0xffff, IO_CRG_ADDRESS(CRG_PERCTL2_ADDR));
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_lvds_cksel(xmedia_s32 vo_dev, xmedia_bool lvds_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (lvds_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
if(vo_dev == 0) {
|
||||
sys_reg_set_bit(tmp, 22, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else if (vo_dev == 1){
|
||||
sys_reg_set_bit(tmp, 23, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_vou_hd_cken(xmedia_s32 vo_dev, xmedia_bool vou_hd_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (vou_hd_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
if(vo_dev == 0) {
|
||||
sys_reg_set_bit(tmp, 0, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else if (vo_dev == 1){
|
||||
sys_reg_set_bit(tmp, 12, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
xmedia_void sys_hal_vo_vou_srst_req(xmedia_bool vou_srst_req)
|
||||
{
|
||||
xmedia_u32 tmp = (vou_srst_req == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 28, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
}
|
||||
|
||||
xmedia_s32 sys_hal_vo_vou_srst_get(xmedia_bool* vou_srst)
|
||||
{
|
||||
xmedia_u32 reg;
|
||||
|
||||
if (vou_srst == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
sys_reg_read(®, IO_CRG_ADDRESS(CRG_PERCTL121_ADDR));
|
||||
*vou_srst = (reg & 0x1); // bit[0]: vou reset state
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_lcd_div_cken(xmedia_bool lcd_div_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (lcd_div_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 27, IO_CRG_ADDRESS(CRG_PERCTL65_ADDR));
|
||||
|
||||
}
|
||||
xmedia_void sys_hal_vo_pll_div_cken(xmedia_bool pll_div_cken)
|
||||
{
|
||||
//0表示输出时钟,只使能或去使能fout1 fout0
|
||||
xmedia_u32 apll_foutpostdivpd = ((!pll_div_cken) << 1) | ((!pll_div_cken) << 0);
|
||||
sys_reg_write_32(apll_foutpostdivpd << 24, 0xf << 24, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
//APLL Power Down控制
|
||||
sys_reg_set_bit(!pll_div_cken, 29, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
//APLL VCO输出Power Down控制
|
||||
sys_reg_set_bit(!pll_div_cken, 28, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
//APLL 测试信号控制
|
||||
sys_reg_set_bit(!pll_div_cken, 22, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_bt_hd_cksel(xmedia_bool bt_hd_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (bt_hd_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 17, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lcd_hd_cksel(xmedia_bool lcd_hd_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (lcd_hd_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 16, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_mipitx_hd_cksel(xmedia_bool mipitx_hd_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (mipitx_hd_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 19, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lvdstx_hd_cksel(xmedia_bool lvdstx_hd_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (lvdstx_hd_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 18, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_bt_pctrl(xmedia_bool bt_pctrl)
|
||||
{
|
||||
xmedia_u32 tmp = (bt_pctrl == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 9, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lcd_pctrl(xmedia_bool lcd_pctrl)
|
||||
{
|
||||
xmedia_u32 tmp = (lcd_pctrl == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 8, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_mipitx_pctrl(xmedia_bool mipitx_pctrl)
|
||||
{
|
||||
xmedia_u32 tmp = (mipitx_pctrl == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 11, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lvdstx_pctrl(xmedia_bool lvdstx_pctrl)
|
||||
{
|
||||
xmedia_u32 tmp = (lvdstx_pctrl == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 10, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_bt_cken(xmedia_bool bt_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (bt_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 1, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lcd_cken(xmedia_bool lcd_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (lcd_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 0, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_mipitx_cken(xmedia_bool mipitx_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (mipitx_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 3, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lvdstx_cken(xmedia_bool lvdstx_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (lvdstx_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 2, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
|
||||
|
||||
xmedia_s32 sys_hal_init(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (osal_spin_lock_init(&g_crg_spin_lock) < 0) {
|
||||
osal_printk("spinlock init fail, line: %d. \n", __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (g_reg_crg_base_va == XMEDIA_NULL) {
|
||||
g_reg_crg_base_va = (void *)osal_ioremap(CRG_REGS_ADDR, (xmedia_u32)CRG_REGS_SIZE);
|
||||
if (g_reg_crg_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap crg reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_reg_sys_base_va == XMEDIA_NULL) {
|
||||
g_reg_sys_base_va = (void *)osal_ioremap(SYS_REGS_ADDR, (xmedia_u32)SYS_REGS_SIZE);
|
||||
if (g_reg_sys_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap sys reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_reg_ddr0_base_va == XMEDIA_NULL) {
|
||||
g_reg_ddr0_base_va = (void *)osal_ioremap(DDRC0_REG_ADDR, (xmedia_u32)DDRC_REGS_SIZE);
|
||||
if (g_reg_ddr0_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap ddr0 reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_reg_misc_base_va == XMEDIA_NULL) {
|
||||
g_reg_misc_base_va = (void *)osal_ioremap(MISC_REGS_ADDR, (xmedia_u32)MISC_REGS_SIZE);
|
||||
if (g_reg_misc_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap MISC reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* version_id与性能限制相关,为了避免通过修改osal_ioremap来更改version_id,使用特殊的iomap函数 */
|
||||
if (g_reg_otp_base_va == XMEDIA_NULL) {
|
||||
#ifdef VO_KERNEL
|
||||
g_reg_otp_base_va = (void *)osal_ioremap(OTP_REGS_ADDR, (xmedia_u32)OTP_REGS_SIZE);
|
||||
#else
|
||||
g_reg_otp_base_va = sys_hal_zonediv(OTP_REGS_ADDR, (xmedia_u32)OTP_REGS_SIZE);
|
||||
#endif
|
||||
if (g_reg_otp_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap OTP reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_sct_addr == XMEDIA_NULL) {
|
||||
g_sct_addr = (void *)osal_ioremap(SCT_REGS_ADDR, (xmedia_u32)SCT_REGS_SIZE);
|
||||
if(g_sct_addr == XMEDIA_NULL) {
|
||||
osal_printk("remap SCT reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
sys_hal_exit();
|
||||
return -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_exit(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_reg_crg_base_va != XMEDIA_NULL) {
|
||||
osal_iounmap(g_reg_crg_base_va);
|
||||
g_reg_crg_base_va = XMEDIA_NULL;
|
||||
}
|
||||
if (g_reg_sys_base_va != XMEDIA_NULL) {
|
||||
osal_iounmap(g_reg_sys_base_va);
|
||||
g_reg_sys_base_va = XMEDIA_NULL;
|
||||
}
|
||||
if (g_reg_ddr0_base_va != XMEDIA_NULL) {
|
||||
osal_iounmap(g_reg_ddr0_base_va);
|
||||
g_reg_ddr0_base_va = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_reg_misc_base_va != XMEDIA_NULL) {
|
||||
osal_iounmap(g_reg_misc_base_va);
|
||||
g_reg_misc_base_va = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_reg_otp_base_va != XMEDIA_NULL) {
|
||||
#ifdef VO_KERNEL
|
||||
osal_iounmap(g_reg_otp_base_va);
|
||||
#else
|
||||
sys_hal_atmos(g_reg_otp_base_va);
|
||||
#endif
|
||||
g_reg_otp_base_va = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_sct_addr != XMEDIA_NULL) {
|
||||
osal_iounmap(g_sct_addr);
|
||||
g_sct_addr = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
osal_spin_lock_destroy(&g_crg_spin_lock);
|
||||
|
||||
return;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifndef SYS_HAL_H
|
||||
#define SYS_HAL_H
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
xmedia_s32 sys_hal_init(xmedia_void);
|
||||
xmedia_void sys_hal_exit(xmedia_void);
|
||||
|
||||
xmedia_void sys_hal_vo_vou_hd_sel(xmedia_s32 vo_dev, xmedia_u32 vou_hd_sel);
|
||||
xmedia_void sys_hal_vo_vou_ppc_cksel(xmedia_u32 vou_ppc_cksel);
|
||||
xmedia_void sys_hal_vo_lvds_por_srst(xmedia_bool lvd_por_srst);
|
||||
xmedia_void sys_hal_vo_mipitx_pll_ref_cksel(xmedia_bool mipitx_pll_ref_cksel);
|
||||
xmedia_void sys_hal_vo_lvds_cksel(xmedia_s32 vo_dev, xmedia_bool lvds_cksel);
|
||||
xmedia_void sys_hal_vo_lcd_div_cfg(xmedia_u32 lcd_div_cfg);
|
||||
xmedia_s32 sys_hal_vo_pll_div_cfg(xmedia_u32 pll_div_cfg);
|
||||
xmedia_void sys_hal_vo_vou_hd_cken(xmedia_s32 vo_dev, xmedia_bool vou_hd_cken);
|
||||
xmedia_void sys_hal_vo_vou_srst_req(xmedia_bool vou_srst_req);
|
||||
xmedia_s32 sys_hal_vo_vou_srst_get(xmedia_bool* vou_srst_req);
|
||||
xmedia_void sys_hal_vo_lcd_div_cken(xmedia_bool lcd_div_cken);
|
||||
xmedia_void sys_hal_vo_pll_div_cken(xmedia_bool pll_div_cken);
|
||||
xmedia_void sys_hal_vo_bt_hd_cksel(xmedia_bool bt_hd_cksel);
|
||||
xmedia_void sys_hal_vo_lcd_hd_cksel(xmedia_bool lcd_hd_cksel);
|
||||
xmedia_void sys_hal_vo_mipitx_hd_cksel(xmedia_bool mipitx_hd_cksel);
|
||||
xmedia_void sys_hal_vo_lvdstx_hd_cksel(xmedia_bool lvdstx_hd_cksel);
|
||||
xmedia_void sys_hal_vo_bt_pctrl(xmedia_bool bt_pctrl);
|
||||
xmedia_void sys_hal_vo_lcd_pctrl(xmedia_bool lcd_pctrl);
|
||||
xmedia_void sys_hal_vo_mipitx_pctrl(xmedia_bool mipitx_pctrl);
|
||||
xmedia_void sys_hal_vo_lvdstx_pctrl(xmedia_bool lvdstx_pctrl);
|
||||
xmedia_void sys_hal_vo_bt_cken(xmedia_bool bt_cken);
|
||||
xmedia_void sys_hal_vo_lcd_cken(xmedia_bool lcd_cken);
|
||||
xmedia_void sys_hal_vo_mipitx_cken(xmedia_bool mipitx_cken);
|
||||
xmedia_void sys_hal_vo_lvdstx_cken(xmedia_bool lvdstx_cken);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
#endif /* End of #ifndef SYS_HAL_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef DRV_REG_CRG_H
|
||||
#define DRV_REG_CRG_H
|
||||
|
||||
#define CRG_REGS_ADDR 0x12010000
|
||||
#define CRG_REGS_SIZE 0X10000
|
||||
|
||||
#define CRG_PERCTL0_ADDR (CRG_REGS_ADDR + 0x0)
|
||||
#define CRG_PERCTL1_ADDR (CRG_REGS_ADDR + 0x4)
|
||||
#define CRG_PERCTL2_ADDR (CRG_REGS_ADDR + 0x8)
|
||||
|
||||
#define CRG_PERCTL50_ADDR (CRG_REGS_ADDR + 0xc8)
|
||||
#define CRG_PERCTL65_ADDR (CRG_REGS_ADDR + 0x104)
|
||||
#define CRG_PERCTL66_ADDR (CRG_REGS_ADDR + 0x108)
|
||||
#define CRG_PERCTL67_ADDR (CRG_REGS_ADDR + 0x10c)
|
||||
#define CRG_PERCTL121_ADDR (CRG_REGS_ADDR + 0x1e4)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef DRV_REG_SYS_H
|
||||
#define DRV_REG_SYS_H
|
||||
|
||||
#define SYS_REGS_ADDR 0x12020000
|
||||
#define SYS_REGS_SIZE 0x8000
|
||||
|
||||
#define MISC_REGS_ADDR 0x12028000
|
||||
#define MISC_REGS_SIZE 0x8000
|
||||
|
||||
#endif
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "sys_drv.h"
|
||||
#include "sys_hal.h"
|
||||
#include "drv_sys.h"
|
||||
#include "xmedia_vo.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
#define PHASE 32
|
||||
#define SYS_MULTI_V 1048576
|
||||
#define SYS_MULTI_H 1048576
|
||||
|
||||
|
||||
|
||||
xmedia_s32 sys_mod_init(xmedia_void)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
ret = sys_hal_init();
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 sys_mod_exit(xmedia_void)
|
||||
{
|
||||
sys_hal_exit();
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
xmedia_s32 sys_mod_ctrl(xmedia_chn_info *chn_info, sys_func_id func_id, xmedia_void *io_args)
|
||||
{
|
||||
xmedia_s32 dev;
|
||||
|
||||
dev = chn_info->dev_id;
|
||||
switch (func_id) {
|
||||
case SYS_VO_VOU_HD_CKSEL:{
|
||||
xmedia_u32 *vou_hd_sel = XMEDIA_NULL;
|
||||
vou_hd_sel = (xmedia_u32 *)io_args;
|
||||
sys_hal_vo_vou_hd_sel(dev, *vou_hd_sel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_VOU_PPC_CKSEL: {
|
||||
xmedia_u32 *vou_ppc_cksel = XMEDIA_NULL;
|
||||
vou_ppc_cksel = (xmedia_u32 *)io_args;
|
||||
sys_hal_vo_vou_ppc_cksel(*vou_ppc_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDS_POR_SRST: {
|
||||
xmedia_bool *lvd_por_srst = XMEDIA_NULL;
|
||||
lvd_por_srst = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvds_por_srst(*lvd_por_srst);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_MIPITX_PLL_REF_CKSEL: {
|
||||
xmedia_bool *mipitx_pll_ref_cksel = XMEDIA_NULL;
|
||||
mipitx_pll_ref_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_mipitx_pll_ref_cksel(*mipitx_pll_ref_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDS_CKSEL:{
|
||||
xmedia_bool *lvds_cksel = XMEDIA_NULL;
|
||||
lvds_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvds_cksel(dev, *lvds_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_DIV_CFG:{
|
||||
xmedia_u32 *lcd_div_cfg = XMEDIA_NULL;
|
||||
lcd_div_cfg = (xmedia_u32 *)io_args;
|
||||
sys_hal_vo_lcd_div_cfg(*lcd_div_cfg);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_PLL_DIV_CFG:{
|
||||
xmedia_u32 *pll_div_cfg = XMEDIA_NULL;
|
||||
pll_div_cfg = (xmedia_u32 *)io_args;
|
||||
if(sys_hal_vo_pll_div_cfg(*pll_div_cfg) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_VOU_HD_CKEN:{
|
||||
xmedia_bool *vou_hd_cken = XMEDIA_NULL;
|
||||
vou_hd_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_vou_hd_cken(dev, *vou_hd_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_VOU_SRST_REQ:{
|
||||
xmedia_bool *vou_srst_req = XMEDIA_NULL;
|
||||
vou_srst_req = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_vou_srst_req(*vou_srst_req);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_VOU_SRST_GET:{
|
||||
xmedia_bool *vou_srst = XMEDIA_NULL;
|
||||
vou_srst = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_vou_srst_get(vou_srst);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_DIV_CKEN:{
|
||||
xmedia_bool *lcd_div_cken = XMEDIA_NULL;
|
||||
lcd_div_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lcd_div_cken(*lcd_div_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_PLL_DIV_CKEN:{
|
||||
xmedia_bool *pll_div_cken = XMEDIA_NULL;
|
||||
pll_div_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_pll_div_cken(*pll_div_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_BT_HD_CKSEL:{
|
||||
xmedia_bool *bt_hd_cksel = XMEDIA_NULL;
|
||||
bt_hd_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_bt_hd_cksel(*bt_hd_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_HD_CKSEL:{
|
||||
xmedia_bool *lcd_hd_cksel = XMEDIA_NULL;
|
||||
lcd_hd_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lcd_hd_cksel(*lcd_hd_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_MIPITX_HD_CKSEL:{
|
||||
xmedia_bool *mipitx_hd_cksel = XMEDIA_NULL;
|
||||
mipitx_hd_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_mipitx_hd_cksel(*mipitx_hd_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDSTX_HD_CKSEL:{
|
||||
xmedia_bool *lvdstx_hd_cksel = XMEDIA_NULL;
|
||||
lvdstx_hd_cksel = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvdstx_hd_cksel(*lvdstx_hd_cksel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_BT_PCTRL:{
|
||||
xmedia_bool *bt_pctrl = XMEDIA_NULL;
|
||||
bt_pctrl = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_bt_pctrl(*bt_pctrl);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_PCTRL:{
|
||||
xmedia_bool *lcd_pctrl = XMEDIA_NULL;
|
||||
lcd_pctrl = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lcd_pctrl(*lcd_pctrl);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_MIPITX_PCTRL:{
|
||||
xmedia_bool *mipitx_pctrl = XMEDIA_NULL;
|
||||
mipitx_pctrl = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_mipitx_pctrl(*mipitx_pctrl);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDSTX_PCTRL:{
|
||||
xmedia_bool *lvdstx_pctrl = XMEDIA_NULL;
|
||||
lvdstx_pctrl = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvdstx_pctrl(*lvdstx_pctrl);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_BT_CKEN:{
|
||||
xmedia_bool *bt_cken = XMEDIA_NULL;
|
||||
bt_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_bt_cken(*bt_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LCD_CKEN:{
|
||||
xmedia_bool *lcd_cken = XMEDIA_NULL;
|
||||
lcd_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lcd_cken(*lcd_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_MIPITX_CKEN:{
|
||||
xmedia_bool *mipitx_cken = XMEDIA_NULL;
|
||||
mipitx_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_mipitx_cken(*mipitx_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYS_VO_LVDSTX_CKEN:{
|
||||
xmedia_bool *lvdstx_cken = XMEDIA_NULL;
|
||||
lvdstx_cken = (xmedia_bool *)io_args;
|
||||
sys_hal_vo_lvdstx_cken(*lvdstx_cken);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default: {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef SYS_DRV_H
|
||||
#define SYS_DRV_H
|
||||
|
||||
#include "drv_sys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
/*
|
||||
* End : Segment compress parameter data definition.
|
||||
*/
|
||||
xmedia_s32 sys_mod_init(xmedia_void);
|
||||
xmedia_s32 sys_mod_exit(xmedia_void);
|
||||
|
||||
xmedia_s32 sys_mod_ctrl(xmedia_chn_info *chn_info, sys_func_id func_id, xmedia_void *io_args);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
#endif /* End of #ifndef SYS_DRV_H */
|
||||
|
||||
+453
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "drv_reg_crg.h"
|
||||
#include "drv_reg_sys.h"
|
||||
#include "sys_hal.h"
|
||||
#include "xmedia_vo.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
|
||||
#define DDRC0_REG_ADDR 0x120d0000 /* base addr of DDRCB */
|
||||
#define DDRC_REGS_SIZE 0x10000
|
||||
|
||||
#define SCT_REGS_ADDR 0x12050000 /* base addr of syscnt */
|
||||
#define SCT_REGS_SIZE 0x100
|
||||
|
||||
#define OTP_REGS_ADDR 0x100A0000
|
||||
#define OTP_REGS_SIZE 0X10000
|
||||
|
||||
#define APLL_VO_VCO_MAX 3700
|
||||
#define APLL_VO_VCO_MIN 1000
|
||||
#define VO_LCD_DIV_SRC 1188
|
||||
|
||||
void *g_reg_crg_base_va = (void *)CRG_REGS_ADDR;
|
||||
void *g_reg_sys_base_va = (void *)SYS_REGS_ADDR;
|
||||
void *g_reg_ddr0_base_va = (void *)DDRC0_REG_ADDR;
|
||||
void *g_reg_misc_base_va = (void *)MISC_REGS_ADDR;
|
||||
void *g_reg_otp_base_va = (void *)OTP_REGS_ADDR;
|
||||
void *g_sct_addr = (void *)SCT_REGS_ADDR;
|
||||
|
||||
xmedia_u32 g_sys_efuse_addr = 0;
|
||||
xmedia_u32 g_sys_chip_addr = 0;
|
||||
|
||||
#define IO_CRG_ADDRESS(x) ((uintptr_t)g_reg_crg_base_va + ((x) - (CRG_REGS_ADDR)))
|
||||
#define IO_SYS_ADDRESS(x) ((uintptr_t)g_reg_sys_base_va + ((x) - (SYS_REGS_ADDR)))
|
||||
#define IO_DDR0_ADDRESS(x) ((uintptr_t)g_reg_ddr0_base_va + ((x) - (DDRC0_REG_ADDR)))
|
||||
#define IO_MISC_ADDRESS(x) ((uintptr_t)g_reg_misc_base_va + ((x) - (MISC_REGS_ADDR)))
|
||||
|
||||
static xmedia_u32 hal_vo_sys_reg_read(volatile xmedia_uintptr_t addr)
|
||||
{
|
||||
return *(volatile xmedia_u32 *)(addr);
|
||||
}
|
||||
|
||||
static xmedia_void hal_vo_sys_reg_write(volatile xmedia_uintptr_t addr, xmedia_u32 val)
|
||||
{
|
||||
*(volatile xmedia_u32 *)(addr) = val;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void sys_reg_set_bit(unsigned long value, unsigned long offset, unsigned long addr)
|
||||
{
|
||||
unsigned long t, mask;
|
||||
|
||||
mask = 1 << offset;
|
||||
t = hal_vo_sys_reg_read((xmedia_uintptr_t)addr);
|
||||
t &= ~mask;
|
||||
t |= (value << offset) & mask;
|
||||
hal_vo_sys_reg_write ( (xmedia_uintptr_t)addr, t);
|
||||
}
|
||||
|
||||
static inline void sys_reg_write_32(unsigned long value, unsigned long mask, unsigned long addr)
|
||||
{
|
||||
unsigned long t;
|
||||
|
||||
t = hal_vo_sys_reg_read((xmedia_uintptr_t)addr);
|
||||
t &= ~mask;
|
||||
t |= value & mask;
|
||||
hal_vo_sys_reg_write((xmedia_uintptr_t)addr, t);
|
||||
}
|
||||
|
||||
static inline void sys_reg_read(unsigned int *pvalue, unsigned long addr)
|
||||
{
|
||||
*pvalue = hal_vo_sys_reg_read((uintptr_t)addr);
|
||||
}
|
||||
|
||||
xmedia_s32 sys_hal_usrdef_slv_enable(xmedia_bool enable)
|
||||
{
|
||||
if (enable == XMEDIA_TRUE) {
|
||||
sys_reg_set_bit(1, 1, IO_CRG_ADDRESS(CRG_PERCTL50_ADDR)); // 打开时钟
|
||||
sys_reg_set_bit(0, 0, IO_CRG_ADDRESS(CRG_PERCTL50_ADDR)); // 撤消复位
|
||||
} else if (enable == XMEDIA_FALSE) {
|
||||
sys_reg_set_bit(0, 1, IO_CRG_ADDRESS(CRG_PERCTL50_ADDR)); // 关闭时钟
|
||||
} else {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
xmedia_void sys_hal_vo_vou_hd_sel(xmedia_s32 vo_dev, xmedia_u32 vou_hd_sel)
|
||||
{
|
||||
if(vo_dev == 0) {
|
||||
sys_reg_write_32(vou_hd_sel << 1 , 0xf << 1, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else if (vo_dev == 1) {
|
||||
sys_reg_write_32(vou_hd_sel << 13 , 0xf << 13, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_vou_ppc_cksel(xmedia_u32 vou_ppc_cksel)
|
||||
{
|
||||
sys_reg_write_32(vou_ppc_cksel << 24 , 0x3 << 24, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_lvds_por_srst(xmedia_bool lvd_por_srst)
|
||||
{
|
||||
xmedia_u32 tmp = (lvd_por_srst == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 21, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
|
||||
}
|
||||
xmedia_void sys_hal_vo_mipitx_pll_ref_cksel(xmedia_bool mipitx_pll_ref_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (mipitx_pll_ref_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 20, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
|
||||
static inline xmedia_u64 vo_div64_u64(xmedia_u64 dividend, xmedia_u64 divisor)
|
||||
{
|
||||
return dividend / divisor;
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_lcd_div_cfg(xmedia_u32 lcd_div_cfg)
|
||||
{
|
||||
xmedia_u32 lcd_clk_div = (xmedia_u32)vo_div64_u64(vo_div64_u64((xmedia_u64)lcd_div_cfg , VO_LCD_DIV_SRC) * (1 << 27),
|
||||
1000*1000);
|
||||
sys_reg_set_bit(0, 28, IO_CRG_ADDRESS(CRG_PERCTL65_ADDR));
|
||||
|
||||
sys_reg_write_32(lcd_clk_div, 0x7ffffff, IO_CRG_ADDRESS(CRG_PERCTL65_ADDR));
|
||||
}
|
||||
|
||||
static xmedia_s32 hal_vo_find_fout_div(xmedia_u32 *fout0_div, xmedia_u32 *fout1_div, xmedia_u32 pll_div,
|
||||
xmedia_u32 *pll_vco){
|
||||
xmedia_u32 fout0;
|
||||
xmedia_u32 fout1;
|
||||
xmedia_u32 vco;
|
||||
|
||||
//fout0 fout1 取值范围都是0 - 15
|
||||
for(fout0 = 0;fout0 < 16;fout0++) {
|
||||
for(fout1 = 0;fout1 < 16;fout1++) {
|
||||
vco = pll_div * (fout0 + 1) * (fout1 + 1);
|
||||
//vco的取值范围是950 - 3800,但ic要求不要取临近值,所以这里使用1000 - 3700
|
||||
if((vco > (APLL_VO_VCO_MIN * 1000)) && (vco < (APLL_VO_VCO_MAX * 1000))) {
|
||||
*fout0_div = fout0;
|
||||
*fout1_div = fout1;
|
||||
*pll_vco = vco;
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
xmedia_s32 sys_hal_vo_pll_div_cfg(xmedia_u32 pll_div_cfg)
|
||||
{
|
||||
xmedia_u32 apll_frac;
|
||||
xmedia_u32 apll_fbdiv;
|
||||
xmedia_u32 fout0_div;
|
||||
xmedia_u32 fout1_div;
|
||||
xmedia_u32 vco;
|
||||
xmedia_u32 pll_div;
|
||||
|
||||
//为避免超出u32范围 对1000取整计算
|
||||
pll_div = pll_div_cfg / 1000;
|
||||
|
||||
//理论不会存在获取不到分频因子的情况
|
||||
if(hal_vo_find_fout_div(&fout0_div, &fout1_div, pll_div, &vco) != XMEDIA_SUCCESS){
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
//apll倍频整数部分
|
||||
apll_fbdiv = (vco / 24) / 1000;
|
||||
//apll倍频小数部分
|
||||
apll_frac = (vco / 24) % 1000;
|
||||
apll_frac = (apll_frac * ((1 << 24) / 1000));
|
||||
|
||||
sys_reg_write_32(apll_frac, 0xffffff, IO_CRG_ADDRESS(CRG_PERCTL0_ADDR));
|
||||
|
||||
// apll 小数/整数分频控制 默认为0 小数分频
|
||||
sys_reg_set_bit(0, 23, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
|
||||
//除了fout1 fout0 其他都bypass
|
||||
sys_reg_write_32(0xc << 18, 0xf << 18, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
|
||||
//参考时钟分频系数默认设置为1 apll参考时钟则为24mhz
|
||||
sys_reg_write_32(0x1 << 12, 0x3f << 12, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
|
||||
sys_reg_write_32(apll_fbdiv, 0xfff, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
|
||||
//APLL 配置fout0 fout1 分频因子
|
||||
sys_reg_write_32(fout0_div | (fout1_div << 4), 0xffff, IO_CRG_ADDRESS(CRG_PERCTL2_ADDR));
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_lvds_cksel(xmedia_s32 vo_dev, xmedia_bool lvds_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (lvds_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
if(vo_dev == 0) {
|
||||
sys_reg_set_bit(tmp, 22, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else if (vo_dev == 1){
|
||||
sys_reg_set_bit(tmp, 23, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_vou_hd_cken(xmedia_s32 vo_dev, xmedia_bool vou_hd_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (vou_hd_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
if(vo_dev == 0) {
|
||||
sys_reg_set_bit(tmp, 0, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else if (vo_dev == 1){
|
||||
sys_reg_set_bit(tmp, 12, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
xmedia_void sys_hal_vo_vou_srst_req(xmedia_bool vou_srst_req)
|
||||
{
|
||||
xmedia_u32 tmp = (vou_srst_req == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 28, IO_CRG_ADDRESS(CRG_PERCTL67_ADDR));
|
||||
}
|
||||
|
||||
xmedia_s32 sys_hal_vo_vou_srst_get(xmedia_bool* vou_srst)
|
||||
{
|
||||
xmedia_u32 reg;
|
||||
|
||||
if (vou_srst == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
sys_reg_read(®, IO_CRG_ADDRESS(CRG_PERCTL121_ADDR));
|
||||
*vou_srst = (reg & 0x1); // bit[0]: vou reset state
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_vo_lcd_div_cken(xmedia_bool lcd_div_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (lcd_div_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 27, IO_CRG_ADDRESS(CRG_PERCTL65_ADDR));
|
||||
|
||||
}
|
||||
xmedia_void sys_hal_vo_pll_div_cken(xmedia_bool pll_div_cken)
|
||||
{
|
||||
//0表示输出时钟,只使能或去使能fout1 fout0
|
||||
xmedia_u32 apll_foutpostdivpd = ((!pll_div_cken) << 1) | ((!pll_div_cken) << 0);
|
||||
sys_reg_write_32(apll_foutpostdivpd << 24, 0xf << 24, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
//APLL Power Down控制
|
||||
sys_reg_set_bit(!pll_div_cken, 29, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
//APLL VCO输出Power Down控制
|
||||
sys_reg_set_bit(!pll_div_cken, 28, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
//APLL 测试信号控制
|
||||
sys_reg_set_bit(!pll_div_cken, 22, IO_CRG_ADDRESS(CRG_PERCTL1_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_bt_hd_cksel(xmedia_bool bt_hd_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (bt_hd_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 17, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lcd_hd_cksel(xmedia_bool lcd_hd_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (lcd_hd_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 16, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_mipitx_hd_cksel(xmedia_bool mipitx_hd_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (mipitx_hd_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 19, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lvdstx_hd_cksel(xmedia_bool lvdstx_hd_cksel)
|
||||
{
|
||||
xmedia_u32 tmp = (lvdstx_hd_cksel == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 18, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_bt_pctrl(xmedia_bool bt_pctrl)
|
||||
{
|
||||
xmedia_u32 tmp = (bt_pctrl == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 9, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lcd_pctrl(xmedia_bool lcd_pctrl)
|
||||
{
|
||||
xmedia_u32 tmp = (lcd_pctrl == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 8, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_mipitx_pctrl(xmedia_bool mipitx_pctrl)
|
||||
{
|
||||
xmedia_u32 tmp = (mipitx_pctrl == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 11, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lvdstx_pctrl(xmedia_bool lvdstx_pctrl)
|
||||
{
|
||||
xmedia_u32 tmp = (lvdstx_pctrl == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 10, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_bt_cken(xmedia_bool bt_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (bt_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 1, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lcd_cken(xmedia_bool lcd_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (lcd_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 0, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_mipitx_cken(xmedia_bool mipitx_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (mipitx_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 3, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
xmedia_void sys_hal_vo_lvdstx_cken(xmedia_bool lvdstx_cken)
|
||||
{
|
||||
xmedia_u32 tmp = (lvdstx_cken == XMEDIA_TRUE) ? 1 : 0;
|
||||
|
||||
sys_reg_set_bit(tmp, 2, IO_CRG_ADDRESS(CRG_PERCTL66_ADDR));
|
||||
}
|
||||
|
||||
|
||||
xmedia_s32 sys_hal_init(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (osal_spin_lock_init(&g_crg_spin_lock) < 0) {
|
||||
osal_printk("spinlock init fail, line: %d. \n", __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (g_reg_crg_base_va == XMEDIA_NULL) {
|
||||
g_reg_crg_base_va = (void *)osal_ioremap(CRG_REGS_ADDR, (xmedia_u32)CRG_REGS_SIZE);
|
||||
if (g_reg_crg_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap crg reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_reg_sys_base_va == XMEDIA_NULL) {
|
||||
g_reg_sys_base_va = (void *)osal_ioremap(SYS_REGS_ADDR, (xmedia_u32)SYS_REGS_SIZE);
|
||||
if (g_reg_sys_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap sys reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_reg_ddr0_base_va == XMEDIA_NULL) {
|
||||
g_reg_ddr0_base_va = (void *)osal_ioremap(DDRC0_REG_ADDR, (xmedia_u32)DDRC_REGS_SIZE);
|
||||
if (g_reg_ddr0_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap ddr0 reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_reg_misc_base_va == XMEDIA_NULL) {
|
||||
g_reg_misc_base_va = (void *)osal_ioremap(MISC_REGS_ADDR, (xmedia_u32)MISC_REGS_SIZE);
|
||||
if (g_reg_misc_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap MISC reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* version_id与性能限制相关,为了避免通过修改osal_ioremap来更改version_id,使用特殊的iomap函数 */
|
||||
if (g_reg_otp_base_va == XMEDIA_NULL) {
|
||||
#ifdef VO_KERNEL
|
||||
g_reg_otp_base_va = (void *)osal_ioremap(OTP_REGS_ADDR, (xmedia_u32)OTP_REGS_SIZE);
|
||||
#else
|
||||
g_reg_otp_base_va = sys_hal_zonediv(OTP_REGS_ADDR, (xmedia_u32)OTP_REGS_SIZE);
|
||||
#endif
|
||||
if (g_reg_otp_base_va == XMEDIA_NULL) {
|
||||
osal_printk("remap OTP reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_sct_addr == XMEDIA_NULL) {
|
||||
g_sct_addr = (void *)osal_ioremap(SCT_REGS_ADDR, (xmedia_u32)SCT_REGS_SIZE);
|
||||
if(g_sct_addr == XMEDIA_NULL) {
|
||||
osal_printk("remap SCT reg fail, line: %d. \n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
sys_hal_exit();
|
||||
return -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmedia_void sys_hal_exit(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_reg_crg_base_va != XMEDIA_NULL) {
|
||||
osal_iounmap(g_reg_crg_base_va);
|
||||
g_reg_crg_base_va = XMEDIA_NULL;
|
||||
}
|
||||
if (g_reg_sys_base_va != XMEDIA_NULL) {
|
||||
osal_iounmap(g_reg_sys_base_va);
|
||||
g_reg_sys_base_va = XMEDIA_NULL;
|
||||
}
|
||||
if (g_reg_ddr0_base_va != XMEDIA_NULL) {
|
||||
osal_iounmap(g_reg_ddr0_base_va);
|
||||
g_reg_ddr0_base_va = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_reg_misc_base_va != XMEDIA_NULL) {
|
||||
osal_iounmap(g_reg_misc_base_va);
|
||||
g_reg_misc_base_va = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_reg_otp_base_va != XMEDIA_NULL) {
|
||||
#ifdef VO_KERNEL
|
||||
osal_iounmap(g_reg_otp_base_va);
|
||||
#else
|
||||
sys_hal_atmos(g_reg_otp_base_va);
|
||||
#endif
|
||||
g_reg_otp_base_va = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_sct_addr != XMEDIA_NULL) {
|
||||
osal_iounmap(g_sct_addr);
|
||||
g_sct_addr = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
osal_spin_lock_destroy(&g_crg_spin_lock);
|
||||
|
||||
return;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifndef SYS_HAL_H
|
||||
#define SYS_HAL_H
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
xmedia_s32 sys_hal_init(xmedia_void);
|
||||
xmedia_void sys_hal_exit(xmedia_void);
|
||||
|
||||
xmedia_void sys_hal_vo_vou_hd_sel(xmedia_s32 vo_dev, xmedia_u32 vou_hd_sel);
|
||||
xmedia_void sys_hal_vo_vou_ppc_cksel(xmedia_u32 vou_ppc_cksel);
|
||||
xmedia_void sys_hal_vo_lvds_por_srst(xmedia_bool lvd_por_srst);
|
||||
xmedia_void sys_hal_vo_mipitx_pll_ref_cksel(xmedia_bool mipitx_pll_ref_cksel);
|
||||
xmedia_void sys_hal_vo_lvds_cksel(xmedia_s32 vo_dev, xmedia_bool lvds_cksel);
|
||||
xmedia_void sys_hal_vo_lcd_div_cfg(xmedia_u32 lcd_div_cfg);
|
||||
xmedia_s32 sys_hal_vo_pll_div_cfg(xmedia_u32 pll_div_cfg);
|
||||
xmedia_void sys_hal_vo_vou_hd_cken(xmedia_s32 vo_dev, xmedia_bool vou_hd_cken);
|
||||
xmedia_void sys_hal_vo_vou_srst_req(xmedia_bool vou_srst_req);
|
||||
xmedia_s32 sys_hal_vo_vou_srst_get(xmedia_bool* vou_srst_req);
|
||||
xmedia_void sys_hal_vo_lcd_div_cken(xmedia_bool lcd_div_cken);
|
||||
xmedia_void sys_hal_vo_pll_div_cken(xmedia_bool pll_div_cken);
|
||||
xmedia_void sys_hal_vo_bt_hd_cksel(xmedia_bool bt_hd_cksel);
|
||||
xmedia_void sys_hal_vo_lcd_hd_cksel(xmedia_bool lcd_hd_cksel);
|
||||
xmedia_void sys_hal_vo_mipitx_hd_cksel(xmedia_bool mipitx_hd_cksel);
|
||||
xmedia_void sys_hal_vo_lvdstx_hd_cksel(xmedia_bool lvdstx_hd_cksel);
|
||||
xmedia_void sys_hal_vo_bt_pctrl(xmedia_bool bt_pctrl);
|
||||
xmedia_void sys_hal_vo_lcd_pctrl(xmedia_bool lcd_pctrl);
|
||||
xmedia_void sys_hal_vo_mipitx_pctrl(xmedia_bool mipitx_pctrl);
|
||||
xmedia_void sys_hal_vo_lvdstx_pctrl(xmedia_bool lvdstx_pctrl);
|
||||
xmedia_void sys_hal_vo_bt_cken(xmedia_bool bt_cken);
|
||||
xmedia_void sys_hal_vo_lcd_cken(xmedia_bool lcd_cken);
|
||||
xmedia_void sys_hal_vo_mipitx_cken(xmedia_bool mipitx_cken);
|
||||
xmedia_void sys_hal_vo_lvdstx_cken(xmedia_bool lvdstx_cken);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
#endif /* End of #ifndef SYS_HAL_H */
|
||||
File diff suppressed because it is too large
Load Diff
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#ifndef __DRV_VO_H__
|
||||
#define __DRV_VO_H__
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
int init_vo(xmedia_void);
|
||||
int deinit_vo(xmedia_void);
|
||||
int start_vo(unsigned int dev, xmedia_s32 screen_type);
|
||||
int stop_vo(unsigned int dev);
|
||||
int start_videolayer(unsigned int layer, unsigned long addr, unsigned int strd, xmedia_video_rect layer_rect);
|
||||
int stop_videolayer(unsigned int layer);
|
||||
int start_gx(unsigned int layer, unsigned long addr, unsigned int strd, xmedia_video_rect gx_rect);
|
||||
int stop_gx(unsigned int layer);
|
||||
#endif
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
/* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_H__
|
||||
#define __HAL_VO_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
#include "hal_vo_chip_cfg.h"
|
||||
#include "hal_vo_disp.h"
|
||||
#include "hal_vo_intf.h"
|
||||
#include "hal_vo_clock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VO_INT_STATE_TYPE_MASK = 0,
|
||||
VO_INT_STATE_TYPE_UNMASK,
|
||||
VO_INT_STATE_TYPE_MAX,
|
||||
} vo_int_state_type;
|
||||
|
||||
typedef enum {
|
||||
VO_FIELD_FRAME = 0,
|
||||
VO_FIELD_TOP,
|
||||
VO_FIELD_BOTTOM,
|
||||
VO_FIELD_TOP_BOTTOM,
|
||||
VO_FIELD_MAX
|
||||
} vo_field_mode;
|
||||
|
||||
typedef enum {
|
||||
VO_PATTERN_MODE_FULLCOLOR = 0,
|
||||
VO_PATTERN_MODE_CHECKER,
|
||||
VO_PATTERN_MODE_COLORBAR,
|
||||
VO_PATTERN_MODE_BLACKBOARD,
|
||||
VO_PATTERN_MODE_MAX
|
||||
} vo_pattern_mode;
|
||||
|
||||
typedef enum {
|
||||
VO_PATTERN_DATA_MODE_DYNAMAIC = 0,
|
||||
VO_PATTERN_DATA_MODE_VIDEO,
|
||||
VO_PATTERN_DATA_MODE_MAX
|
||||
} vo_pattern_data_mode;
|
||||
|
||||
typedef enum {
|
||||
VO_PATTERN_POSTION_VIDEO = 0,
|
||||
VO_PATTERN_POSTION_INTF,
|
||||
VO_PATTERN_POSTION_MAX
|
||||
} vo_pattern_postion;
|
||||
|
||||
typedef struct {
|
||||
xmedia_vo_intf_sync intf_sync;
|
||||
xmedia_vo_user_sync_timing sync_timing;
|
||||
xmedia_bool clk_reverse_en;
|
||||
} vo_intf_timing;
|
||||
|
||||
//定义固定分频相关属性
|
||||
typedef struct {
|
||||
vo_intf_special_timing special_timing[XMEDIA_VO_DEV_MAX];//固定频点 和 实际需求频点 纠正得到的特殊时序
|
||||
#ifdef xmfalcon
|
||||
mipi_phy_config mipi_phy_cfg;
|
||||
#endif
|
||||
vo_clock_config clock_config; //hal层vo时钟配置
|
||||
} vo_hal_context;
|
||||
|
||||
typedef struct {
|
||||
vo_pattern_postion pos;
|
||||
vo_pattern_mode pattern_mode;
|
||||
vo_pattern_data_mode data_mode;
|
||||
xmedia_bool pattern_en;
|
||||
xmedia_bool rgb;
|
||||
xmedia_u32 color;
|
||||
xmedia_u32 width;
|
||||
xmedia_u32 height;
|
||||
} vo_pattern_info;
|
||||
|
||||
//初始化和去初始化
|
||||
xmedia_s32 hal_vo_init(xmedia_void);
|
||||
xmedia_void hal_vo_deinit(xmedia_void);
|
||||
vo_base_cap* hal_vo_get_capacity(xmedia_void);
|
||||
vo_layer_cap* hal_get_layer_capacity(xmedia_u32 layer);
|
||||
vo_dev_cap* hal_get_dev_capacity(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_mipi_htotal_adjust_value(xmedia_s32 htotal_adjust_value);
|
||||
xmedia_void hal_vo_set_mipi_vsync_adjust_value(xmedia_s32 vsync_adjust_value);
|
||||
|
||||
//时钟和寄存器生效
|
||||
xmedia_void hal_vo_set_clock_gate_enable(xmedia_bool clk_en);
|
||||
xmedia_void hal_vo_set_top_regup_enable(xmedia_bool enable);
|
||||
xmedia_bool hal_vo_get_top_regup_enable(xmedia_void);
|
||||
xmedia_void hal_vo_set_dev_intf_regup_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_bool hal_vo_get_dev_intf_regup_state(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_layer_regup_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_bool hal_vo_get_layer_regup_enable(xmedia_vo_layer layer);
|
||||
|
||||
// 中断相关:state表示中断的状态,比如vtt1,vvt2
|
||||
xmedia_void hal_vo_get_interrupt_state(vo_int_state_type type, xmedia_u32 *state);
|
||||
xmedia_void hal_vo_clean_interrupt_state(vo_int_state_type type, xmedia_u32 state);
|
||||
xmedia_void hal_vo_set_interrupt_enable(vo_isr_interrupt_type int_type, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_int_mode(xmedia_vo_dev dev, xmedia_u32 vtt_id, vo_isr_field_flag int_mode);
|
||||
xmedia_void hal_vo_set_dev_thd(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_u32 thd);
|
||||
xmedia_void hal_vo_get_dev_state(xmedia_vo_dev dev, xmedia_bool *btm, xmedia_u16 *vcnt, xmedia_u8 *vstate);
|
||||
|
||||
xmedia_void hal_vo_set_dev_mixer_prio(xmedia_vo_dev dev, vo_mix_prio prio_id);
|
||||
xmedia_void hal_vo_set_dev_bgcolor(xmedia_vo_dev dev, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_get_dev_bgcolor(xmedia_vo_dev dev, xmedia_u32 *bgcolor);
|
||||
xmedia_void hal_vo_set_dev_csc_en(xmedia_vo_dev dev, xmedia_bool csc_en);
|
||||
xmedia_void hal_vo_get_dev_csc_en(xmedia_vo_dev dev, xmedia_bool *csc_en);
|
||||
xmedia_s32 hal_vo_set_dev_csc_coef(xmedia_vo_dev dev, vo_pic_info* pic_info);
|
||||
|
||||
//设备接口时序包含相关时钟配置
|
||||
xmedia_void hal_vo_set_crg_clock_reset(xmedia_bool reset_en);
|
||||
xmedia_bool hal_vo_get_crg_clock_reset_state(xmedia_void);
|
||||
xmedia_s32 hal_vo_set_crg_clock(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_bool clk_reverse_en,
|
||||
xmedia_intf_type intf_type);
|
||||
xmedia_void hal_vo_set_crg_clock_enable(xmedia_vo_dev dev, xmedia_intf_type intf_type, xmedia_bool clk_en);
|
||||
xmedia_void hal_vo_set_crg_intf_detach_dev(xmedia_vo_dev dev, xmedia_intf_type intf_type);
|
||||
xmedia_void hal_vo_set_dev_intf_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing);
|
||||
xmedia_void hal_vo_set_clock_sel_priority(xmedia_vo_dev dev, vo_clock_priority_sel vo_lcd_divider_priority);
|
||||
vo_hal_context* hal_vo_get_hal_context(xmedia_void);
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_dev_intf_enable(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_s32 hal_vo_enable_dev_phy_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_u32 frame_rate,
|
||||
xmedia_vo_user_sync_timing *sync_timing, xmedia_intf_type intf_type);
|
||||
xmedia_void hal_vo_disable_dev_phy_cfg(xmedia_intf_type intf_type);
|
||||
xmedia_s32 vo_calc_dev_phy_clk_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_vo_intf_config *intf_config);
|
||||
|
||||
//视频层相关配置
|
||||
xmedia_void hal_vo_set_layer_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_layer_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_layer_bg_color(xmedia_vo_layer layer, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_layer_mute_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_layer_mute_color(xmedia_vo_layer layer, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_layer_csc_en(xmedia_vo_layer layer, xmedia_bool csc_en);
|
||||
xmedia_s32 hal_vo_set_layer_csc_coef(xmedia_vo_layer layer, vo_pic_info* pic_info);
|
||||
|
||||
//设置输出的宽和高
|
||||
xmedia_void hal_vo_set_layer_disp_rect(xmedia_vo_layer layer, xmedia_video_rect *disp_rect);
|
||||
xmedia_void hal_vo_get_layer_disp_rect(xmedia_vo_layer layer, xmedia_video_rect *disp_rect);
|
||||
xmedia_void hal_vo_set_layer_reso_rect(xmedia_vo_layer layer, xmedia_video_rect *reso_rect);
|
||||
xmedia_void hal_vo_get_layer_reso_rect(xmedia_vo_layer layer, xmedia_video_rect *reso_rect);
|
||||
xmedia_void hal_vo_set_layer_pixel_format(xmedia_vo_layer layer, xmedia_video_pixel_format pix_format);
|
||||
|
||||
//单区域和多区域控制
|
||||
xmedia_void hal_vo_set_layer_multi_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_layer_multi_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_layer_region_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_layer_region_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_layer_region_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id,
|
||||
xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_layer_region_mute_color(xmedia_vo_layer layer, xmedia_u32 region_id,
|
||||
xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_layer_single_region_cfg(xmedia_vo_layer layer, vo_layer_single_cfg *single_cfg);
|
||||
xmedia_void hal_vo_set_layer_multi_region_cfg(xmedia_vo_layer layer, vo_layer_multi_cfg *multi_cfg);
|
||||
|
||||
xmedia_void hal_vo_set_dev_debug_pattern(xmedia_vo_dev dev, vo_pattern_info *pattern_info);
|
||||
xmedia_void hal_vo_set_layer_debug_pattern(xmedia_vo_layer layer, vo_pattern_info *pattern_info);
|
||||
xmedia_void hal_vo_set_debug_ink(xmedia_vo_dev dev, vo_csc_ink_info *ink_info);
|
||||
xmedia_void hal_vo_set_debug_mask(xmedia_vo_dev dev, vo_mix_prio mix_pro);
|
||||
xmedia_void hal_vo_get_debug_checksum(xmedia_vo_dev dev, xmedia_u32 *y, xmedia_u32 *u, xmedia_u32 *v);
|
||||
|
||||
xmedia_void hal_vo_set_gamma_addr(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_gamma_table(xmedia_vo_dev dev, xmedia_vo_gamma_table *gamma_table);
|
||||
xmedia_void hal_vo_get_gamma_table(xmedia_vo_dev dev, xmedia_vo_gamma_table *gamma_table);
|
||||
xmedia_s32 hal_vo_gamma_init(xmedia_vo_dev dev);
|
||||
xmedia_s32 hal_vo_gamma_deinit(xmedia_vo_dev dev);
|
||||
|
||||
xmedia_s32 hal_vo_reg_record(xmedia_void);
|
||||
xmedia_s32 hal_vo_reg_restore(xmedia_void);
|
||||
xmedia_u32 hal_vo_get_cyc_pre_pixel(xmedia_vo_intf_config *intf_config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_H__ */
|
||||
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "hal_vo.h"
|
||||
#include "hal_vo_disp.h"
|
||||
#include "hal_vo_reg.h"
|
||||
#include "sys_drv.h"
|
||||
#include "hal_vo_clock.h"
|
||||
#include "xmedia_vo.h"
|
||||
|
||||
extern s_vout_regs_type *g_p_vout_reg;
|
||||
xmedia_u64 g_vo_mipi_lcd_clk;
|
||||
|
||||
xmedia_void hal_vo_clock_init(vo_clock_config * vo_clock)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
memset(vo_clock, 0, sizeof(vo_clock_config));
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
vo_clock->dev_clock_info[i].clock_sel = VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
for(i = VO_CRG_CLOCK_TYPE_MIPI;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
vo_clock->intf_clock_info[i].intf_sel_dev = XMEDIA_VO_DEV_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_clock_deinit(xmedia_void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//vo top 门控使能
|
||||
xmedia_void hal_vo_set_clock_gate(vo_clock_config * vo_clock, xmedia_bool enable)
|
||||
{
|
||||
hal_vout_set_cfg_ck_dyn_gt_en_dma(g_p_vout_reg, enable);
|
||||
hal_vout_set_cfg_ck_dyn_gt_en(g_p_vout_reg, enable);
|
||||
vo_clock->vo_top_clock_gate = enable;
|
||||
return;
|
||||
}
|
||||
|
||||
static vo_clock_src_sel vo_fix_clk_sel(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz)
|
||||
{
|
||||
if ((0 < clk_hz) && (clk_hz <= VO_CLOCK_SRC_13_5MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_13_5MHZ;
|
||||
return VO_CLOCK_SRC_SEL_13_5MHZ;
|
||||
} else if ((VO_CLOCK_SRC_13_5MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_27MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_27MHZ;
|
||||
return VO_CLOCK_SRC_SEL_27MHZ;
|
||||
} else if ((VO_CLOCK_SRC_27MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_37_125MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_37_125MHZ;
|
||||
return VO_CLOCK_SRC_SEL_37_125MHZ;
|
||||
} else if ((VO_CLOCK_SRC_37_125MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_74_25MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_74_25MHZ;
|
||||
return VO_CLOCK_SRC_SEL_74_25MHZ;
|
||||
} else if ((VO_CLOCK_SRC_74_25MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_148_5MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_148_5MHZ;
|
||||
return VO_CLOCK_SRC_SEL_148_5MHZ;
|
||||
} else if ((VO_CLOCK_SRC_148_5MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_297MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_297MHZ;
|
||||
return VO_CLOCK_SRC_SEL_297MHZ;
|
||||
} else if ((VO_CLOCK_SRC_297MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_343_75MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_343_75MHZ;
|
||||
return VO_CLOCK_SRC_SEL_297MHZ;
|
||||
} else {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "not match normal Hz! Use LCD or PLL Hz!\n");
|
||||
return VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static vo_clock_ppc_sel vo_get_ppc_clock(vo_clock_config *vo_clock, xmedia_u32 clk_hz)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
clk_hz = (clk_hz > vo_clock->dev_clock_info[i].clock_hz) ? clk_hz : vo_clock->dev_clock_info[i].clock_hz;
|
||||
}
|
||||
|
||||
if (clk_hz <= 74250000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_74_25MHZ;
|
||||
} else if (clk_hz <= 148500000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_148_5MHZ;
|
||||
} else if (clk_hz <= 297000000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_297MHZ;
|
||||
} else if (clk_hz <= 343000000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_343MHZ;
|
||||
} else {
|
||||
return VO_CLOCK_SRC_PPC_SEL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static vo_clock_src_sel vo_div_clk_sel(vo_clock_config *vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_u32 clk_hz)
|
||||
{
|
||||
xmedia_bool lcd_use_flag = XMEDIA_TRUE;
|
||||
xmedia_u32 i;
|
||||
|
||||
//判断lcd分频能否使用
|
||||
if (clk_hz <= LCD_FREQUENCY_DIVIDER_MAX) {
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
//lcd分频已使能&&不是本dev使用&&分频频率不同 则无法使用lcd分频
|
||||
if ((vo_clock->dev_clock_info[i].clock_sel == VO_CLOCK_SRC_SEL_LCD) &&
|
||||
(i != dev) && (vo_clock->dev_clock_info[i].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_hz != clk_hz)) {
|
||||
lcd_use_flag = XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
//配置lcd分频
|
||||
if (lcd_use_flag == XMEDIA_TRUE) {
|
||||
return VO_CLOCK_SRC_SEL_LCD;
|
||||
}
|
||||
}
|
||||
return VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
|
||||
static vo_div_clock_type vo_clk_sel_to_div_type(vo_clock_src_sel clk_sel)
|
||||
{
|
||||
switch (clk_sel) {
|
||||
case VO_CLOCK_SRC_SEL_LCD:
|
||||
return VO_DIV_CLOCK_TYPE_LCD;
|
||||
default :
|
||||
return VO_DIV_CLOCK_TYPE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
//crg 分频时钟配置
|
||||
xmedia_s32 hal_vo_set_dev_div_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz,
|
||||
xmedia_bool *vo_special_timing_sel, xmedia_bool vo_lcd_divider_priority)
|
||||
{
|
||||
vo_clock_src_sel clk_sel;
|
||||
vo_clock_ppc_sel vo_ppc_sel;
|
||||
vo_div_clock_type div_type;
|
||||
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
//debug状态位检测,优先使用lcd分频器 or 优先使用固定频点
|
||||
if (vo_lcd_divider_priority == XMEDIA_TRUE) {
|
||||
clk_sel = vo_div_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
//分频器无法使用,尝试使用固定频点
|
||||
clk_sel = vo_fix_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
} else {
|
||||
div_type = vo_clk_sel_to_div_type(clk_sel);
|
||||
if (div_type == VO_DIV_CLOCK_TYPE_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//使用lcd分频器
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = 0;
|
||||
vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz = clk_hz;
|
||||
if (g_vo_mipi_lcd_clk != 0) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CFG, &g_vo_mipi_lcd_clk);
|
||||
} else {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CFG, &clk_hz);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clk_sel = vo_fix_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel != VO_CLOCK_SRC_SEL_MAX) {
|
||||
//使用固定频点
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
} else {
|
||||
clk_sel = vo_div_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
div_type = vo_clk_sel_to_div_type(clk_sel);
|
||||
if (div_type == VO_DIV_CLOCK_TYPE_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//使用lcd分频
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = 0;
|
||||
vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz = clk_hz;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CFG, &clk_hz);
|
||||
}
|
||||
}
|
||||
|
||||
//都使用校正后的特殊时序,不同的是依照 分频器时钟值/固定频点值 计算出不同的矫正时序
|
||||
*vo_special_timing_sel = XMEDIA_TRUE;
|
||||
|
||||
//时钟源选择配置
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_HD_CKSEL, &vo_clock->dev_clock_info[dev].clock_sel);
|
||||
|
||||
vo_clock->dev_clock_info[dev].clock_hz = clk_hz;
|
||||
|
||||
//ppc 时钟配置
|
||||
vo_ppc_sel = vo_get_ppc_clock(vo_clock, clk_hz);
|
||||
if (vo_ppc_sel != VO_CLOCK_SRC_PPC_SEL_MAX) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_PPC_CKSEL, &vo_ppc_sel);
|
||||
}else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
//crg时钟 分频器使能
|
||||
xmedia_void hal_vo_set_dev_div_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_en)
|
||||
{
|
||||
xmedia_bool lcd_div_freq_en = XMEDIA_FALSE;
|
||||
xmedia_u32 i;
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel == VO_CLOCK_SRC_SEL_LCD) {
|
||||
vo_clock->dev_clock_info[dev].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_en = clk_en;
|
||||
}
|
||||
//有可能两个dev用同一个分屏器的频点,判断是否是所有dev分频器的使能状态
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
lcd_div_freq_en |= vo_clock->dev_clock_info[i].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_en;
|
||||
}
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CKEN, &lcd_div_freq_en);
|
||||
return;
|
||||
}
|
||||
|
||||
//crg时钟 vou软复位请求
|
||||
xmedia_void hal_vo_set_clock_reset_enable(vo_clock_config * vo_clock, xmedia_bool reset_en)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_SRST_REQ, &reset_en);
|
||||
//软复位 暂定状态将会改变 其他配置呢 div配置及门控使能 intf门控使能等????
|
||||
vo_clock->dev_clock_info[XMEDIA_VO_DEV_0].dev_clock_gate = XMEDIA_FALSE;
|
||||
vo_clock->dev_clock_info[XMEDIA_VO_DEV_1].dev_clock_gate = XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_clock_reset_sta(xmedia_void)
|
||||
{
|
||||
xmedia_bool state;
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_SRST_GET, &state);
|
||||
return state;
|
||||
}
|
||||
|
||||
//crg时钟 vou dev0/dev1门控使能
|
||||
xmedia_void hal_vo_set_dev_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_en)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_HD_CKEN, &clk_en);
|
||||
vo_clock->dev_clock_info[dev].dev_clock_gate = clk_en;
|
||||
|
||||
return;
|
||||
}
|
||||
xmedia_bool vo_check_intf_sel_dev(vo_clock_config * vo_clock,
|
||||
vo_crg_intf_type crg_int_type, xmedia_vo_dev dev)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
for(i = VO_CRG_CLOCK_TYPE_MIPI;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
//dev是否已经被其他intf选定了
|
||||
if ((vo_clock->intf_clock_info[i].intf_sel_dev == dev) && (crg_int_type != i)) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static vo_crg_intf_type hal_vo_swap_intf_type(xmedia_intf_type intf_type)
|
||||
{
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
return VO_CRG_CLOCK_TYPE_BT;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
return VO_CRG_CLOCK_TYPE_LCD;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
return VO_CRG_CLOCK_TYPE_MIPI;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
return VO_CRG_CLOCK_TYPE_LVDS;
|
||||
default:
|
||||
return VO_CRG_CLOCK_TYPE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_detach_dev(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
|
||||
for(i = VO_CRG_CLOCK_TYPE_MIPI;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
if ((vo_clock->intf_clock_info[i].intf_sel_dev == dev) && (hal_vo_swap_intf_type(intf_type) == i)) {
|
||||
vo_clock->intf_clock_info[i].intf_sel_dev = XMEDIA_VO_DEV_MAX;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//crg intf 时钟 通道选择
|
||||
xmedia_s32 hal_vo_set_intf_clock(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_reverse_en, xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
xmedia_bool vo_lvds_por_srst = XMEDIA_TRUE;
|
||||
xmedia_bool vo_mipitx_pll_ref_cksel = VO_MIPI_PLL_FREF;
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
if (intf_type == XMEDIA_INTF_TYPE_LVDS) {
|
||||
//lvds 使用LVDS TXPHY PLL_CLKOUT 不需要配置分频
|
||||
vo_clock->dev_clock_info[dev].vo_lvds_sel = XMEDIA_TRUE;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDS_POR_SRST, &vo_lvds_por_srst);//lvds por 软复位
|
||||
vo_lvds_por_srst = XMEDIA_FALSE;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDS_POR_SRST, &vo_lvds_por_srst);
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDS_CKSEL, &vo_clock->dev_clock_info[dev].vo_lvds_sel);
|
||||
} else {
|
||||
vo_clock->dev_clock_info[dev].vo_lvds_sel = XMEDIA_FALSE;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDS_CKSEL, &vo_clock->dev_clock_info[dev].vo_lvds_sel);
|
||||
}
|
||||
//mipitx_pll_ref_cksel 配置为0 表示使用24Mh 时钟源
|
||||
if (intf_type == XMEDIA_INTF_TYPE_MIPI_DSI) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_MIPITX_PLL_REF_CKSEL, &vo_mipitx_pll_ref_cksel);
|
||||
}
|
||||
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_BT, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_HD_CKSEL, &dev); //bt接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_PCTRL, &clk_reverse_en); //bt接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_BT].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_BT].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_LCD, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_HD_CKSEL, &dev); //lcd接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_PCTRL, &clk_reverse_en); //lcd接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LCD].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LCD].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_MIPI, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_MIPITX_HD_CKSEL, &dev); //mipi接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_MIPITX_PCTRL, &clk_reverse_en); //mipi接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_MIPI].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_MIPI].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_LVDS, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDSTX_HD_CKSEL, &dev); //lvds接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDSTX_PCTRL, &clk_reverse_en); //lvds接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LVDS].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LVDS].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
default:
|
||||
VO_TRACE(MODULE_DBG_ERR, "intf type error!\n");
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
//crg intf 接口时钟门控使能
|
||||
xmedia_void hal_vo_set_intf_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_intf_type intf_type, xmedia_bool clock_enable)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_CKEN, &clock_enable); //bt时钟使能
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_CKEN, &clock_enable); //lcd时钟使能
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_MIPITX_CKEN, &clock_enable); //mipi时钟使能
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LVDSTX_CKEN, &clock_enable); //lvds时钟使能
|
||||
break;
|
||||
default:
|
||||
VO_TRACE(MODULE_DBG_ERR, "intf type error!\n");
|
||||
return;
|
||||
}
|
||||
vo_clock->intf_clock_info[hal_vo_swap_intf_type(intf_type)].intf_clock_gate = clock_enable;
|
||||
return;
|
||||
}
|
||||
|
||||
//获取接口实际配置时钟
|
||||
xmedia_s32 hal_vo_get_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 *clock_hz)
|
||||
{
|
||||
vo_div_clock_type div_type;
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "clock_sel error!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel != VO_CLOCK_SRC_SEL_LCD) {
|
||||
*clock_hz = vo_clock->dev_clock_info[dev].fixed_clock_hz;
|
||||
} else {
|
||||
div_type = vo_clk_sel_to_div_type(vo_clock->dev_clock_info[dev].clock_sel);
|
||||
*clock_hz = vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CLOCK_H__
|
||||
#define __HAL_VO_CLOCK_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef enum {
|
||||
VO_MIPITX_PLL_REF_CKSEL_24M = 0,
|
||||
VO_MIPITX_PLL_REF_CKSEL_36M,
|
||||
VO_MIPITX_PLL_REF_CKSEL_MAX
|
||||
} vo_mipitx_pll_ref_cksel;
|
||||
|
||||
#define LCD_FREQUENCY_DIVIDER_MAX (148.5 * 1000 * 1000)
|
||||
#define PLL_FREQUENCY_DIVIDER_MAX (297 * 1000 * 1000)
|
||||
|
||||
#define LCD_DIV_2_POWER_27 (1 << 27) //2的27次方
|
||||
#define LCD_DIV_2_POWER_24 (1 << 24) //2的24次方
|
||||
#define LCD_DIV_SORCE_FRE (1375*1000*1000) //lcd源频率
|
||||
|
||||
#define VO_CLOCK_SRC_13_5MHZ 13500000
|
||||
#define VO_CLOCK_SRC_27MHZ 27000000
|
||||
#define VO_CLOCK_SRC_37_125MHZ 37125000
|
||||
#define VO_CLOCK_SRC_74_25MHZ 74250000
|
||||
#define VO_CLOCK_SRC_148_5MHZ 148500000
|
||||
#define VO_CLOCK_SRC_297MHZ 297000000
|
||||
#define VO_CLOCK_SRC_343_75MHZ 343750000
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_SRC_SEL_297MHZ,
|
||||
VO_CLOCK_SRC_SEL_148_5MHZ,
|
||||
VO_CLOCK_SRC_SEL_74_25MHZ,
|
||||
VO_CLOCK_SRC_SEL_37_125MHZ,
|
||||
VO_CLOCK_SRC_SEL_27MHZ,
|
||||
VO_CLOCK_SRC_SEL_13_5MHZ,
|
||||
VO_CLOCK_SRC_SEL_LCD,
|
||||
VO_CLOCK_SRC_SEL_APLL_FOUT1,
|
||||
VO_CLOCK_SRC_SEL_343_75MHZ,
|
||||
VO_CLOCK_SRC_SEL_MAX,
|
||||
}vo_clock_src_sel;
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_SRC_PPC_SEL_343MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_297MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_148_5MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_74_25MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_MAX,
|
||||
}vo_clock_ppc_sel;
|
||||
|
||||
typedef enum {
|
||||
VO_DIV_CLOCK_TYPE_LCD,
|
||||
VO_DIV_CLOCK_TYPE_MAX,
|
||||
} vo_div_clock_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CRG_CLOCK_TYPE_MIPI,
|
||||
VO_CRG_CLOCK_TYPE_LVDS,
|
||||
VO_CRG_CLOCK_TYPE_BT,
|
||||
VO_CRG_CLOCK_TYPE_LCD,
|
||||
VO_CRG_CLOCK_TYPE_MAX,
|
||||
} vo_crg_intf_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_PRIORITY_SEL_NORMAL,
|
||||
VO_CLOCK_PRIORITY_SEL_LCD,
|
||||
VO_CLOCK_PRIORITY_SEL_FIX,
|
||||
VO_CLOCK_PRIORITY_SEL_MAX,
|
||||
} vo_clock_priority_sel;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool div_clock_en; //分频器使能状态 dev0 dev1 共用同一分频器时 需判断两个dev的使能状态来使能分频器
|
||||
xmedia_u32 div_clock_hz; //分频器频率
|
||||
} vo_div_clock_info;
|
||||
|
||||
typedef struct {
|
||||
vo_clock_src_sel clock_sel; //dev 时钟源选择
|
||||
xmedia_bool vo_lvds_sel; //lvds时需要配1 选择LVDS TXPHY PLL_CLKOUT,否则配0 选择SOC时钟
|
||||
xmedia_u32 clock_hz;
|
||||
xmedia_u32 fixed_clock_hz; //固定频点时钟
|
||||
vo_div_clock_info freq_clock[VO_DIV_CLOCK_TYPE_MAX];//dev 分频器信息
|
||||
xmedia_bool dev_clock_gate; //dev时钟门控
|
||||
} vo_dev_clock_info;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool intf_clock_gate; //intf时钟门控
|
||||
xmedia_vo_dev intf_sel_dev; //接口时钟通道选择
|
||||
xmedia_bool intf_reverse_en;
|
||||
} vo_intf_clock_info;
|
||||
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool vo_top_clock_gate; //vo top层动态时钟门控
|
||||
vo_dev_clock_info dev_clock_info[XMEDIA_VO_DEV_MAX]; //dev时钟信息
|
||||
vo_intf_clock_info intf_clock_info[VO_CRG_CLOCK_TYPE_MAX]; //intf时钟信息
|
||||
} vo_clock_config;
|
||||
|
||||
#define VO_MIPI_PLL_FREF VO_MIPITX_PLL_REF_CKSEL_24M //24MHz pll原始频率
|
||||
|
||||
xmedia_void hal_vo_clock_init(vo_clock_config * vo_clock);
|
||||
xmedia_void hal_vo_clock_deinit(xmedia_void);
|
||||
xmedia_void hal_vo_set_clock_gate(vo_clock_config * vo_clock, xmedia_bool enable);
|
||||
xmedia_s32 hal_vo_set_dev_div_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz,
|
||||
xmedia_bool *vo_special_timing_sel, xmedia_bool vo_lcd_divider_priority);
|
||||
|
||||
xmedia_void hal_vo_set_dev_div_clock_enable(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_bool clk_en);
|
||||
xmedia_void hal_vo_set_clock_reset_enable(vo_clock_config * vo_clock, xmedia_bool reset_en);
|
||||
xmedia_bool hal_vo_get_clock_reset_sta(xmedia_void);
|
||||
xmedia_void hal_vo_set_dev_clock_enable(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_bool clk_en);
|
||||
xmedia_s32 hal_vo_set_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_bool clk_reverse_en,
|
||||
xmedia_intf_type intf_type);
|
||||
xmedia_void hal_vo_set_intf_clock_enable(vo_clock_config * vo_clock, xmedia_intf_type intf_type,
|
||||
xmedia_bool clock_enable);
|
||||
xmedia_void hal_vo_set_intf_detach_dev(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_intf_type intf_type);
|
||||
xmedia_s32 hal_vo_get_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 *clock_hz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
|
||||
#define VO_CSC_TABLE_MAX 61
|
||||
|
||||
typedef struct{
|
||||
vo_csc_type type;
|
||||
const vo_csc_coef *matrix;
|
||||
} vo_csc_type_matrix;
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv601limit = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv601limit = {
|
||||
880, 0, 0, 0, 899, 0, 0, 0, 899,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv601limit = {
|
||||
1024, 102, 196, 0, 1014, -113, 0, -74, 1007,
|
||||
-16, -128, -128,
|
||||
-16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv601limit = {
|
||||
880, 90, 173, 0, 891, -99, 0, -65, 864,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv709limit = {
|
||||
1024, -118, -213, 0, 1043, 117, 0, 77, 1050,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv709limit = {
|
||||
880, -103, -187, 0, 916, 102, 0, 67, 922,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv709limit = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv709limit = {
|
||||
880, 0, 0, 0, 899, 0, 0, 0, 899,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv601full = {
|
||||
1192, 0, 0, 0, 1165, 0, 0, 0, 1165,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv601full = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv601full = {
|
||||
1192, 117, 222, 0, 1154, -128, 0, -84, 1146,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv601full = {
|
||||
1024, 102, 196, 0, 1014, -113, 0, -74, 1007,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv709full = {
|
||||
1192, -137, -248, 0, 1188, 133, 0, 87, 1194,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv709full = {
|
||||
1024, -118, -213, 0, 1043, 117, 0, 77, 1050,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv709full = {
|
||||
1192, 0, 0, 0, 1165, 0, 0, 0, 1165,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv709full = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_rgbfull = {
|
||||
1192, 0, 1634, 1192, -400, -833, 1192, 2066, 0,
|
||||
-16, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_rgbfull = {
|
||||
1024, 0, 1040, 1024, -344, -706, 1024, 1774, 0,
|
||||
0, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_rgbfull = {
|
||||
1192, 0, 1836, 1192, -218, -547, 1192, 2166, 0,
|
||||
-16, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_rgbfull = {
|
||||
1024, 0, 1577, 1024, -187, -470, 1024, 1860, 0,
|
||||
0, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_rgblimit = {
|
||||
1024, 0, 1404, 1024, -344, -716, 1024, 1775, 0,
|
||||
-16, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_rgblimit = {
|
||||
880, 0, 1233, 880, -302, -629, 880, 1559, 0,
|
||||
0, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_rgblimit = {
|
||||
1024, 0, 1578, 1024, -187, -470, 1024, 1861, 0,
|
||||
-16, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_rgblimit = {
|
||||
880, 0, 1385, 880, -164, -413, 880, 1634, 0,
|
||||
0, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const int g_sin_table[VO_CSC_TABLE_MAX] = {
|
||||
-500, -485, -469, -454, -438, -422, -407, -391, -374, -358,
|
||||
-342, -325, -309, -292, -276, -259, -242, -225, -208, -191,
|
||||
-174, -156, -139, -122, -104, -87, -70, -52, -35, -17,
|
||||
0, 17, 35, 52, 70, 87, 104, 122, 139, 156,
|
||||
174, 191, 208, 225, 242, 259, 276, 292, 309, 325,
|
||||
342, 358, 374, 391, 407, 422, 438, 454, 469, 485,
|
||||
500
|
||||
};
|
||||
|
||||
const int g_cos_table[VO_CSC_TABLE_MAX] = {
|
||||
866, 875, 883, 891, 899, 906, 914, 921, 927, 934,
|
||||
940, 946, 951, 956, 961, 966, 970, 974, 978, 982,
|
||||
985, 988, 990, 993, 995, 996, 998, 999, 999, 1000,
|
||||
1000, 1000, 999, 999, 998, 996, 995, 993, 990, 988,
|
||||
985, 982, 978, 974, 970, 966, 961, 956, 951, 946,
|
||||
940, 934, 927, 921, 914, 906, 899, 891, 883, 875,
|
||||
866
|
||||
};
|
||||
|
||||
//后面需要根据算法提供的参数进行更新
|
||||
static vo_csc_type_matrix g_type_to_matrix[VO_CSC_MAX] = {
|
||||
{ VO_CSC_YUV2RGB_601_LIMIT2FULL, &g_csc_yuv601limit_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_709_LIMIT2FULL, &g_csc_yuv709limit_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_601_FULL2LIMIT, &g_csc_yuv601full_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_709_FULL2LIMIT, &g_csc_yuv709full_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_601_FULL2FULL, &g_csc_yuv601full_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_709_FULL2FULL, &g_csc_yuv709full_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_601_LIMIT2LIMIT, &g_csc_yuv601limit_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_709_LIMIT2LIMIT, &g_csc_yuv709limit_to_rgblimit },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_LIMIT2LIMIT, &g_csc_yuv601limit_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_601_709_LIMIT2LIMIT, &g_csc_yuv601limit_to_yuv709limit },
|
||||
{ VO_CSC_YUV2YUV_709_601_LIMIT2LIMIT, &g_csc_yuv709limit_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_709_709_LIMIT2LIMIT, &g_csc_yuv709limit_to_yuv709limit },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_FULL2FULL, &g_csc_yuv601full_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_601_709_FULL2FULL, &g_csc_yuv601full_to_yuv709full },
|
||||
{ VO_CSC_YUV2YUV_709_601_FULL2FULL, &g_csc_yuv709full_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_709_709_FULL2FULL, &g_csc_yuv709full_to_yuv709full },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_LIMIT2FULL, &g_csc_yuv601limit_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_601_709_LIMIT2FULL, &g_csc_yuv601limit_to_yuv709full },
|
||||
{ VO_CSC_YUV2YUV_709_601_LIMIT2FULL, &g_csc_yuv709limit_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_709_709_LIMIT2FULL, &g_csc_yuv709limit_to_yuv709full },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_FULL2LIMIT, &g_csc_yuv601full_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_601_709_FULL2LIMIT, &g_csc_yuv601full_to_yuv709limit },
|
||||
{ VO_CSC_YUV2YUV_709_601_FULL2LIMIT, &g_csc_yuv709full_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_709_709_FULL2LIMIT, &g_csc_yuv709full_to_yuv709limit },
|
||||
};
|
||||
|
||||
static xmedia_s32 vo_get_base_matrix_by_type(vo_csc_type csc_type, const vo_csc_coef **csc_tmp)
|
||||
{
|
||||
xmedia_u32 loop;
|
||||
xmedia_u32 len;
|
||||
|
||||
len = sizeof(g_type_to_matrix) / sizeof(vo_csc_type_matrix);
|
||||
for (loop = 0; loop < len; loop++) {
|
||||
if (g_type_to_matrix[loop].type == csc_type) {
|
||||
if (g_type_to_matrix[loop].matrix != XMEDIA_NULL) {
|
||||
*csc_tmp = g_type_to_matrix[loop].matrix;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
}
|
||||
return XMEDIA_FAILURE;
|
||||
};
|
||||
|
||||
static xmedia_bool vo_check_csc_type(vo_csc_type type)
|
||||
{
|
||||
if ((type >= VO_CSC_YUV2RGB_601_LIMIT2FULL) && (type <= VO_CSC_YUV2RGB_709_LIMIT2LIMIT)) {
|
||||
return XMEDIA_TRUE;
|
||||
}
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_csc_coef_convert(vo_pic_info *src_pic_info, vo_csc_coef *pst_csc_matrix)
|
||||
{
|
||||
xmedia_s32 luma = 0;
|
||||
xmedia_s32 contrast = 0;
|
||||
xmedia_s32 hue = 0;
|
||||
xmedia_s32 satu = 0;
|
||||
const vo_csc_coef *base_csc_matrix = XMEDIA_NULL;
|
||||
|
||||
luma = (xmedia_s32)src_pic_info->luma * 64 / 100 - 32;
|
||||
contrast = ((xmedia_s32)src_pic_info->contrast - 50) * 2 + 100;
|
||||
hue = (xmedia_s32)src_pic_info->hue * 60 / 100;
|
||||
satu = ((xmedia_s32)src_pic_info->saturation - 50) * 2 + 100;
|
||||
if (hue >= VO_CSC_TABLE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hue %d error!\n", hue);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (vo_get_base_matrix_by_type(src_pic_info->csc_type, &base_csc_matrix) != XMEDIA_SUCCESS) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo_get_base_matrix_by_type error!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
pst_csc_matrix->csc_offset_in0 = base_csc_matrix->csc_offset_in0;
|
||||
pst_csc_matrix->csc_offset_in1 = base_csc_matrix->csc_offset_in1;
|
||||
pst_csc_matrix->csc_offset_in2 = base_csc_matrix->csc_offset_in2;
|
||||
pst_csc_matrix->csc_offset_out0 = base_csc_matrix->csc_offset_out0;
|
||||
pst_csc_matrix->csc_offset_out1 = base_csc_matrix->csc_offset_out1;
|
||||
pst_csc_matrix->csc_offset_out2 = base_csc_matrix->csc_offset_out2;
|
||||
|
||||
/* C_ratio的调节范围一般是0~1.99, C_ratio=s32Contrast/100
|
||||
* S的调节范围一般为0~1.99,S=s32Satu/100
|
||||
* 色调调节参数的范围一般为-30°~30°,通过查表法求得COS和SIN值并/1000
|
||||
*/
|
||||
if (vo_check_csc_type(src_pic_info->csc_type) == XMEDIA_TRUE) {
|
||||
/* 此公式仅用于YUV->RGB转换,RGB->YUV转换不可用此公式 */
|
||||
pst_csc_matrix->csc_coef0 = (contrast * base_csc_matrix->csc_coef0) / 100;
|
||||
pst_csc_matrix->csc_coef1 = (contrast * satu * ((base_csc_matrix->csc_coef1 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef2 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef2 = (contrast * satu * ((base_csc_matrix->csc_coef1 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef2 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef3 = (contrast * base_csc_matrix->csc_coef3) / 100;
|
||||
pst_csc_matrix->csc_coef4 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef5 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef5 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef5 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef6 = (contrast * base_csc_matrix->csc_coef6) / 100;
|
||||
pst_csc_matrix->csc_coef7 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef8 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef8 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef8 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_offset_in0 += (contrast != 0) ? (luma * 100 / contrast) : luma * 100;
|
||||
} else {
|
||||
/* 此公式仅用于RGB->YUV转换,YUV->RGB转换不可用此公式,
|
||||
* YUV->YUV仅调节图像效果可用此公式,因为常量矩阵为单位矩阵 */
|
||||
pst_csc_matrix->csc_coef0 = (contrast * base_csc_matrix->csc_coef0) / 100;
|
||||
pst_csc_matrix->csc_coef1 = (contrast * base_csc_matrix->csc_coef1) / 100;
|
||||
pst_csc_matrix->csc_coef2 = (contrast * base_csc_matrix->csc_coef2) / 100;
|
||||
pst_csc_matrix->csc_coef3 = (contrast * satu * ((base_csc_matrix->csc_coef3 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef3 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef4 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef4 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef5 = (contrast * satu * ((base_csc_matrix->csc_coef5 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef5 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef6 = (contrast * satu * ((base_csc_matrix->csc_coef6 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef6 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef7 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef7 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef8 = (contrast * satu * ((base_csc_matrix->csc_coef8 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef8 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_offset_out0 += luma;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CSC_H__
|
||||
#define __HAL_VO_CSC_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
xmedia_s32 csc_coef0;
|
||||
xmedia_s32 csc_coef1;
|
||||
xmedia_s32 csc_coef2;
|
||||
|
||||
xmedia_s32 csc_coef3;
|
||||
xmedia_s32 csc_coef4;
|
||||
xmedia_s32 csc_coef5;
|
||||
|
||||
xmedia_s32 csc_coef6;
|
||||
xmedia_s32 csc_coef7;
|
||||
xmedia_s32 csc_coef8;
|
||||
|
||||
xmedia_s32 csc_offset_in0;
|
||||
xmedia_s32 csc_offset_in1;
|
||||
xmedia_s32 csc_offset_in2;
|
||||
xmedia_s32 csc_offset_out0;
|
||||
xmedia_s32 csc_offset_out1;
|
||||
xmedia_s32 csc_offset_out2;
|
||||
} vo_csc_coef;
|
||||
|
||||
xmedia_s32 hal_vo_csc_coef_convert(vo_pic_info *src_pic_info, vo_csc_coef *pst_csc_matrix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_DISP_H__
|
||||
#define __HAL_VO_DISP_H__
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VO_MRG_MIX_PRIO_RDMA0 = 0,
|
||||
VO_MRG_MIX_PRIO_RDMA1,
|
||||
VO_MRG_MIX_PRIO_MAX,
|
||||
} vo_mrg_mix_prio;
|
||||
|
||||
typedef enum {
|
||||
VO_MIX_PRIO_VIDEO = 0,
|
||||
VO_MIX_PRIO_GFX,
|
||||
VO_MIX_PRIO_MAX,
|
||||
} vo_mix_prio;
|
||||
|
||||
typedef enum {
|
||||
VO_PIXEL_FMT_YUV_400 = 0,
|
||||
VO_PIXEL_FMT_YUV_420,
|
||||
VO_PIXEL_FMT_YUV_422,
|
||||
VO_PIXEL_FMT_YUV_MAX
|
||||
} vo_pixel_format;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool vcus_mode;
|
||||
xmedia_bool hcus_mode;
|
||||
xmedia_u8 hcus_coef0;
|
||||
xmedia_u8 hcus_coef1;
|
||||
xmedia_u8 hcus_coef2;
|
||||
xmedia_u8 hcus_coef3;
|
||||
xmedia_u8 vcus_coef0;
|
||||
xmedia_u8 vcus_coef1;
|
||||
xmedia_u8 vcus_coef2;
|
||||
xmedia_u8 vcus_coef3;
|
||||
} vo_video_cus;
|
||||
|
||||
xmedia_void hal_vo_set_top_regup(xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_top_regup(xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_video_regup(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_intf_regup(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_version0(xmedia_u32 *version);
|
||||
xmedia_void hal_vo_get_version1(xmedia_u32 *version);
|
||||
xmedia_void hal_vo_set_mem_ctrl(xmedia_u32 speed);
|
||||
xmedia_u32 hal_vo_get_mask_interrupt_state(xmedia_void);
|
||||
xmedia_void hal_vo_clear_mask_interrupt_state(vo_isr_interrupt_type int_mask);
|
||||
xmedia_void hal_vo_set_mask_interrupt_enable(vo_isr_interrupt_type int_mask,xmedia_bool enable);
|
||||
xmedia_u32 hal_vo_get_unmask_interrupt_state(xmedia_void);
|
||||
xmedia_void hal_vo_clear_lowband_state(xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_cbm_mixer_prio(xmedia_vo_dev dev, vo_mix_prio prio_id);
|
||||
xmedia_void hal_vo_set_cbm_bgcolor(xmedia_vo_dev dev, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_get_cbm_bgcolor(xmedia_vo_dev dev, xmedia_u32 *bgcolor);
|
||||
xmedia_void hal_vo_set_dma_standing(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_u8 hal_vo_get_dma_standing(xmedia_void);
|
||||
xmedia_void hal_vo_set_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
//两个及时寄存器
|
||||
xmedia_void hal_vo_set_regup_mode(xmedia_vo_layer layer, xmedia_bool filed_en);
|
||||
xmedia_void hal_vo_set_regup_field(xmedia_vo_layer layer, xmedia_bool bottom_en);
|
||||
xmedia_void hal_vo_set_alpha(xmedia_vo_layer layer, xmedia_u8 alpha);
|
||||
xmedia_void hal_vo_set_alpha_enable(xmedia_vo_layer layer, xmedia_bool alpha_en);
|
||||
xmedia_void hal_vo_set_alpha_blend_mode(xmedia_vo_layer layer, xmedia_bool alpha_blend_en);
|
||||
xmedia_void hal_vo_set_src_pixel_format(xmedia_vo_layer layer, vo_pixel_format format, xmedia_bool uv_order);
|
||||
xmedia_void hal_vo_set_multi_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_multi_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_bgcolor(xmedia_vo_layer layer, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_get_bgcolor(xmedia_vo_layer layer, xmedia_u32 *bgcolor);
|
||||
xmedia_void hal_vo_set_mute_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_mute_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_video_regup_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mute_color(xmedia_vo_layer layer, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_mute_pattern_mode(xmedia_vo_layer layer, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_mute_data_mode(xmedia_vo_layer layer, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_checkbar_size(xmedia_vo_layer layer, xmedia_u8 width, xmedia_u8 height);
|
||||
xmedia_void hal_vo_set_disp_rect (xmedia_vo_layer layer, xmedia_video_rect *disp_rect);
|
||||
xmedia_void hal_vo_get_disp_rect (xmedia_vo_layer layer, xmedia_video_rect *disp_rect);
|
||||
xmedia_void hal_vo_set_src_rect (xmedia_vo_layer layer, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_get_src_rect (xmedia_vo_layer layer, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_set_dst_rect (xmedia_vo_layer layer, xmedia_video_rect *dst_rect);
|
||||
xmedia_void hal_vo_set_addr (xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_mixer_prio(xmedia_vo_layer layer, vo_mrg_mix_prio prio_id);
|
||||
xmedia_void hal_vo_set_mrg_rdma1_link(xmedia_vo_layer layer, xmedia_u8 rgion_id);
|
||||
xmedia_void hal_vo_set_mrg_rdma1_en(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mrg_mute_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_mrg_sort(xmedia_vo_layer layer, xmedia_u16 sort);
|
||||
xmedia_void hal_vo_set_mrg_src_rect (xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_set_mrg_dst_rect (xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *dst_rect);
|
||||
xmedia_void hal_vo_set_mrg0_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg1_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg2_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg3_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_addr(xmedia_vo_layer layer, xmedia_u32 region_id,vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_mute_color(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_cus(xmedia_vo_layer layer, vo_video_cus *cus);
|
||||
xmedia_void hal_vo_set_csc_en(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg0_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg1_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg2_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg3_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg_csc(xmedia_vo_layer layer, xmedia_u32 region_id, vo_csc_coef *csc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_reg.h"
|
||||
#include "hal_vo_gamma.h"
|
||||
|
||||
extern s_vout_regs_type *g_p_vout_reg;
|
||||
|
||||
xmedia_void hal_vo_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_vout_set_cfg_gamma_en(g_p_vout_reg, enable);
|
||||
} else if (dev == XMEDIA_VO_DEV_1) {
|
||||
hal_vout_set_voutintf1_cfg_gamma_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_get_table_size(xmedia_void)
|
||||
{
|
||||
return VO_GAMMA_MAP_SIZE * sizeof(xmedia_u8);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_set_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
xmedia_s32 i;
|
||||
for (i = 0;i < VO_GAMMA_MAP_SIZE; i++) {
|
||||
((xmedia_u8 *)gamma_virtual_addr)[i] = gamma_table->gamma_table[i];
|
||||
}
|
||||
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_vout_set_cfg_para_2_update(g_p_vout_reg, XMEDIA_TRUE);
|
||||
} else if (dev == XMEDIA_VO_DEV_1) {
|
||||
hal_vout_set_cfg_para_3_update(g_p_vout_reg, XMEDIA_TRUE);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_get_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
xmedia_s32 i;
|
||||
|
||||
for (i = 0;i < VO_GAMMA_MAP_SIZE; i++) {
|
||||
gamma_table->gamma_table[i] = ((xmedia_u8 *)gamma_virtual_addr)[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_set_addr(xmedia_vo_dev dev, xmedia_u64 addr)
|
||||
{
|
||||
xmedia_u32 addr_l = addr & 0xFFFFFFFF;
|
||||
xmedia_u32 addr_h = (addr & 0xFFFFFFFF00000000) >> 32;
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_vout_set_cfg_para_2_addr_h(g_p_vout_reg, addr_h);
|
||||
hal_vout_set_cfg_para_2_addr_l(g_p_vout_reg, addr_l);
|
||||
} else if (dev == XMEDIA_VO_DEV_1) {
|
||||
hal_vout_set_cfg_para_3_addr_h(g_p_vout_reg, addr_h);
|
||||
hal_vout_set_cfg_para_3_addr_l(g_p_vout_reg, addr_l);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_GAMMA_H__
|
||||
#define __HAL_VO_GAMMA_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
#include "xmedia_vo.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
xmedia_void hal_vo_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_s32 hal_vo_gamma_get_table_size(xmedia_void);
|
||||
xmedia_void hal_vo_gamma_set_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table);
|
||||
xmedia_void hal_vo_gamma_get_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table);
|
||||
xmedia_void hal_vo_gamma_set_addr(xmedia_vo_dev dev, xmedia_u64 addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
|
||||
+954
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "hal_vo.h"
|
||||
#include "hal_vo_chip_cfg.h"
|
||||
#include "hal_vo_reg.h"
|
||||
#include "hal_vo_disp.h"
|
||||
#include "hal_vo_intf.h"
|
||||
#include "hal_vo_clock.h"
|
||||
#include "hal_vo_gamma.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
static xmedia_s32 vo_mipi_htotal_adjust_value = 0;
|
||||
static xmedia_s32 vo_mipi_vsync_adjust_value = 0;
|
||||
|
||||
xmedia_void hal_vo_set_mipi_htotal_adjust_value(xmedia_s32 htotal_adjust_value)
|
||||
{
|
||||
vo_mipi_htotal_adjust_value = htotal_adjust_value;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mipi_vsync_adjust_value(xmedia_s32 vsync_adjust_value)
|
||||
{
|
||||
vo_mipi_vsync_adjust_value = vsync_adjust_value;
|
||||
}
|
||||
|
||||
vo_hal_context vo_hal_ctx;
|
||||
vo_hal_context *hal_vo_get_hal_context(xmedia_void)
|
||||
{
|
||||
return &vo_hal_ctx;
|
||||
}
|
||||
|
||||
#define vo_reg_addr_offset(REG) ((xmedia_ulong) & (((s_vout_regs_type *)0)->REG))
|
||||
#define OFFSET_ELE_NUM 2
|
||||
#ifdef VO_KERNEL
|
||||
static xmedia_ulong g_vo_reg_offset[][OFFSET_ELE_NUM] = {
|
||||
{ vo_reg_addr_offset(vout_top_ctrl), 0x320 },
|
||||
{ vo_reg_addr_offset(vout_lvds_phy_update), 0x50 },
|
||||
{ vo_reg_addr_offset(vout_v0_ctrl), 0x300 },
|
||||
{ vo_reg_addr_offset(vout_intf_ctrl), 0x230 },
|
||||
{ vo_reg_addr_offset(vout_intf_csc_offset_in), 0x70 },
|
||||
{ vo_reg_addr_offset(vout_v1_ctrl), 0x300 },
|
||||
{ vo_reg_addr_offset(vout_intf1_ctrl), 0x230 },
|
||||
{ vo_reg_addr_offset(vout_intf1_csc_offset_in), 0x70 },
|
||||
};
|
||||
#endif
|
||||
#ifdef VO_KERNEL
|
||||
static xmedia_u8 *g_vo_reg_record = XMEDIA_NULL;
|
||||
#endif
|
||||
typedef struct {
|
||||
xmedia_u64 gamma_phy_addr;
|
||||
xmedia_void *gamma_virtual_addr;
|
||||
xmedia_u32 gamma_mem_len;
|
||||
} vo_dev_gamma_buf;
|
||||
|
||||
#define VO_BASE_ADDR 0x11280000
|
||||
#define VO_MIPI_TX_CTRL_BASE 0x11960000
|
||||
#define VO_MIPI_TX_PHY_BASE 0x11970000
|
||||
|
||||
s_vout_regs_type *g_p_vout_reg = (s_vout_regs_type *)VO_BASE_ADDR;
|
||||
void *g_p_vout_mipi_tx_ctrl = (void *)VO_MIPI_TX_CTRL_BASE;
|
||||
void *g_p_vout_mipi_tx_phy = (void *)VO_MIPI_TX_PHY_BASE;
|
||||
|
||||
#define VO_MIPI_TX_PHY_SIZE 0x1000
|
||||
#define VO_FIFO_DEPTH 1919
|
||||
#define VO_MMZ_NAME_SIZE 128
|
||||
|
||||
#ifdef VO_KERNEL
|
||||
static vo_dev_gamma_buf g_vo_gamma_buf[XMEDIA_VO_DEV_MAX];
|
||||
#endif
|
||||
static xmedia_s32 vo_reg_map(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_p_vout_reg == XMEDIA_NULL) {
|
||||
g_p_vout_reg = (s_vout_regs_type *)osal_ioremap_nocache(VO_BASE_ADDR, sizeof(s_vout_regs_type));
|
||||
if (g_p_vout_reg == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_p_vout_mipi_tx_phy == XMEDIA_NULL) {
|
||||
g_p_vout_mipi_tx_phy = osal_ioremap_nocache(VO_MIPI_TX_PHY_BASE, VO_MIPI_TX_PHY_SIZE);
|
||||
if (g_p_vout_mipi_tx_phy == XMEDIA_NULL) {
|
||||
osal_iounmap((xmedia_void *)g_p_vout_reg);
|
||||
g_p_vout_reg = XMEDIA_NULL;
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_p_vout_mipi_tx_phy_2 == XMEDIA_NULL) {
|
||||
g_p_vout_mipi_tx_phy_2 = osal_ioremap_nocache(VO_MIPI_TX_PHY_BASE_2, VO_MIPI_TX_PHY_SIZE);
|
||||
if (g_p_vout_mipi_tx_phy_2 == XMEDIA_NULL) {
|
||||
osal_iounmap((xmedia_void *)g_p_vout_reg);
|
||||
osal_iounmap((xmedia_void *)g_p_vout_mipi_tx_phy);
|
||||
g_p_vout_reg = XMEDIA_NULL;
|
||||
g_p_vout_mipi_tx_phy = XMEDIA_NULL;
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void vo_reg_unmap(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_p_vout_reg != XMEDIA_NULL) {
|
||||
osal_iounmap((xmedia_void *)g_p_vout_reg);
|
||||
g_p_vout_reg = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_p_vout_mipi_tx_phy != XMEDIA_NULL) {
|
||||
osal_iounmap(g_p_vout_mipi_tx_phy);
|
||||
g_p_vout_mipi_tx_phy = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_p_vout_mipi_tx_phy_2 != XMEDIA_NULL) {
|
||||
osal_iounmap(g_p_vout_mipi_tx_phy_2);
|
||||
g_p_vout_mipi_tx_phy_2 = XMEDIA_NULL;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_init(xmedia_vo_dev dev)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
xmedia_char mmz_user_name[VO_MMZ_NAME_SIZE];
|
||||
xmedia_vo_gamma_table gamma_table;
|
||||
|
||||
g_vo_gamma_buf[dev].gamma_mem_len = hal_vo_gamma_get_table_size();
|
||||
osal_snprintf(mmz_user_name, sizeof(mmz_user_name), "vo_gamma_dev%u", dev);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = drv_vo_mmz_alloc(mmz_user_name,
|
||||
g_vo_gamma_buf[dev].gamma_mem_len, XMEDIA_NULL);
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr == XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"drv_vo_mmz_alloc error!\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = drv_vo_mmz_map(g_vo_gamma_buf[dev].gamma_phy_addr,
|
||||
g_vo_gamma_buf[dev].gamma_mem_len);
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr == XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
VO_TRACE(MODULE_DBG_ERR,"drv_vo_mmz_map return NULL!\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
gamma_table.gamma_table[dev] = dev;
|
||||
hal_vo_set_gamma_table(dev, &gamma_table);
|
||||
return XMEDIA_SUCCESS;
|
||||
err_out:
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_unmap(g_vo_gamma_buf[dev].gamma_virtual_addr);
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
}
|
||||
#endif
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_deinit(xmedia_vo_dev dev)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_unmap(g_vo_gamma_buf[dev].gamma_virtual_addr);
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
}
|
||||
#endif
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_init(xmedia_void)
|
||||
{
|
||||
xmedia_u32 ret;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
memset(hal_ctx, 0, sizeof(vo_hal_context));
|
||||
|
||||
hal_vo_init_chip_capaciblity();
|
||||
ret = vo_reg_map();
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
hal_vo_clock_init(&hal_ctx->clock_config);
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_deinit(xmedia_void)
|
||||
{
|
||||
//关闭所有的时钟todo
|
||||
hal_vo_clock_deinit();
|
||||
vo_reg_unmap();
|
||||
return;
|
||||
}
|
||||
|
||||
vo_base_cap* hal_vo_get_capacity(xmedia_void)
|
||||
{
|
||||
return hal_vo_get_chip_capacity();
|
||||
}
|
||||
|
||||
vo_layer_cap* hal_get_layer_capacity(xmedia_u32 layer)
|
||||
{
|
||||
return hal_get_layer_chip_capacity(layer);
|
||||
}
|
||||
|
||||
vo_dev_cap* hal_get_dev_capacity(xmedia_vo_dev dev)
|
||||
{
|
||||
return hal_get_dev_chip_capacity(dev);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_clock_gate_enable(xmedia_bool clk_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_clock_gate(&hal_ctx->clock_config, clk_en);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_clock_reset(xmedia_bool reset_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_clock_reset_enable(&hal_ctx->clock_config, reset_en);
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_crg_clock_reset_state(xmedia_void)
|
||||
{
|
||||
return hal_vo_get_clock_reset_sta();
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_clock_sel_priority(xmedia_vo_dev dev, vo_clock_priority_sel vo_clock_priority_sel)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_ctx->special_timing[dev].vo_clock_priority_sel = vo_clock_priority_sel;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_crg_clock(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_bool clk_reverse_en,
|
||||
xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_bool vo_lcd_divider_priority = XMEDIA_FALSE;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
//根据时钟判断是否需要使用特殊时序配置
|
||||
if (hal_ctx->special_timing[dev].vo_clock_priority_sel == VO_CLOCK_PRIORITY_SEL_LCD) {
|
||||
vo_lcd_divider_priority = XMEDIA_TRUE;
|
||||
} else if (hal_ctx->special_timing[dev].vo_clock_priority_sel == VO_CLOCK_PRIORITY_SEL_FIX) {
|
||||
vo_lcd_divider_priority = XMEDIA_FALSE;
|
||||
} else {
|
||||
//debug没有设置lcd分频器时,对接口类型做二次判断,lcd/lvds优先使用LCD分频器
|
||||
if (intf_type == XMEDIA_INTF_TYPE_LCD || intf_type == XMEDIA_INTF_TYPE_LVDS) {
|
||||
vo_lcd_divider_priority = XMEDIA_TRUE;
|
||||
}
|
||||
}
|
||||
ret = hal_vo_set_dev_div_clock(&hal_ctx->clock_config, dev, clk_hz,
|
||||
&hal_ctx->special_timing[dev].vo_special_timing_sel, vo_lcd_divider_priority);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = hal_vo_set_intf_clock(&hal_ctx->clock_config, dev, clk_reverse_en, intf_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_clock_enable(xmedia_vo_dev dev, xmedia_intf_type intf_type, xmedia_bool clk_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_dev_div_clock_enable(&hal_ctx->clock_config, dev, clk_en);
|
||||
hal_vo_set_dev_clock_enable(&hal_ctx->clock_config, dev, clk_en);
|
||||
hal_vo_set_intf_clock_enable(&hal_ctx->clock_config, intf_type, clk_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_intf_detach_dev(xmedia_vo_dev dev, xmedia_intf_type intf_type)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_intf_detach_dev(&hal_ctx->clock_config, dev, intf_type);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_top_regup_enable(xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_top_regup(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_top_regup_enable(xmedia_void)
|
||||
{
|
||||
xmedia_bool enable = XMEDIA_FALSE;
|
||||
hal_vo_get_top_regup(&enable);
|
||||
return enable;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_regup_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_intf_regup(dev, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_dev_intf_regup_state(xmedia_vo_dev dev)
|
||||
{
|
||||
xmedia_bool state = XMEDIA_FALSE;
|
||||
hal_vo_get_intf_regup(dev, &state);
|
||||
return state;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_regup_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_video_regup_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_layer_regup_enable(xmedia_vo_layer layer)
|
||||
{
|
||||
xmedia_bool enable = XMEDIA_FALSE;
|
||||
hal_vo_get_video_regup(layer, &enable);
|
||||
return enable;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_interrupt_state(vo_int_state_type type, xmedia_u32 *state)
|
||||
{
|
||||
if (type == VO_INT_STATE_TYPE_MASK) {
|
||||
*state = hal_vo_get_mask_interrupt_state();
|
||||
} else if (type == VO_INT_STATE_TYPE_UNMASK) {
|
||||
*state = hal_vo_get_unmask_interrupt_state();
|
||||
} else {
|
||||
*state = hal_vo_get_mask_interrupt_state();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_clean_interrupt_state(vo_int_state_type type, vo_isr_interrupt_type state)
|
||||
{
|
||||
if (type == VO_INT_STATE_TYPE_UNMASK) {
|
||||
hal_vo_clear_lowband_state(XMEDIA_TRUE);
|
||||
} else {
|
||||
hal_vo_clear_mask_interrupt_state(state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_interrupt_enable(vo_isr_interrupt_type int_type, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mask_interrupt_enable(int_type, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_int_mode(xmedia_vo_dev dev, xmedia_u32 vtt_id, vo_isr_field_flag int_mode)
|
||||
{
|
||||
xmedia_bool frame_mode;
|
||||
|
||||
if ((int_mode == VO_ISR_FIELD_FLAG_TOP) || (int_mode == VO_ISR_FIELD_FLAG_BOTTOM) ||
|
||||
(int_mode == VO_ISR_FIELD_FLAG_TOP_BOTTOM)) {
|
||||
frame_mode = XMEDIA_TRUE;
|
||||
} else {
|
||||
frame_mode = XMEDIA_FALSE;
|
||||
}
|
||||
hal_vo_set_intf_vtt_mode(dev, vtt_id, frame_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_thd(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_u32 thd)
|
||||
{
|
||||
//设置中断有效区计数
|
||||
hal_vo_set_intf_vtt_sel(dev, vtt_id, 1);
|
||||
hal_vo_set_intf_vtt_thd(dev, vtt_id, thd);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_state(xmedia_vo_dev dev, xmedia_bool *btm, xmedia_u16 *vcnt, xmedia_u8 *vstate)
|
||||
{
|
||||
hal_vo_get_intf_state(dev, btm, vcnt, vstate);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_mixer_prio(xmedia_vo_dev dev, vo_mix_prio prio_id)
|
||||
{
|
||||
hal_vo_set_cbm_mixer_prio(dev, prio_id);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_bgcolor(xmedia_vo_dev dev, xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_cbm_bgcolor(dev, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_bgcolor(xmedia_vo_dev dev, xmedia_u32 *bgcolor)
|
||||
{
|
||||
xmedia_u32 color;
|
||||
hal_vo_get_cbm_bgcolor(dev, &color);
|
||||
*bgcolor = color;
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_csc_en(xmedia_vo_dev dev, xmedia_bool csc_en)
|
||||
{
|
||||
hal_vo_set_intf_csc_en(dev, csc_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_csc_en(xmedia_vo_dev dev, xmedia_bool *csc_en)
|
||||
{
|
||||
hal_vo_get_intf_csc_en(dev, csc_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_dev_csc_coef(xmedia_vo_dev dev, vo_pic_info* pic_info)
|
||||
{
|
||||
vo_csc_coef csc_matrix;
|
||||
|
||||
if (hal_vo_csc_coef_convert(pic_info, &csc_matrix) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
hal_vo_set_intf_csc(dev, &csc_matrix);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/*以下关于特殊时序计算均参考 “VOUT_MIPI 时序配置说明.excel”,
|
||||
*以下计算得到的值都是非-1 计算,而excel中的寄存器值都是-1运算
|
||||
*/
|
||||
static xmedia_void hal_vo_calc_special_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing, mipi_phy_config *mipi_phy_cfg)
|
||||
{
|
||||
xmedia_s32 cycle_n = 0;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
vo_intf_special_timing * special_timing = &hal_ctx->special_timing[dev];
|
||||
xmedia_u32 fixed_clock_hz;
|
||||
xmedia_s32 htotal_adjust_value;
|
||||
xmedia_s32 vsync_adjust_value;
|
||||
|
||||
switch(intf_config->intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
//cycle_n表示单个像素时钟倍数,lcd串行配置为3,并行为1,bt656并行yuv为2
|
||||
if ((intf_config->intf_type == XMEDIA_INTF_TYPE_LCD) &&
|
||||
(intf_config->lcd_attr.data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL)) {
|
||||
cycle_n = 3;
|
||||
} else if (intf_config->intf_type == XMEDIA_INTF_TYPE_BT656) {
|
||||
cycle_n = 2;
|
||||
} else {
|
||||
cycle_n = 1;
|
||||
}
|
||||
if (hal_vo_get_intf_clock(&hal_ctx->clock_config, dev, &fixed_clock_hz) != XMEDIA_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
/* =INT(1/I4/(I9+I10+I11+I12)/(1/(I26/I23)/10^6))
|
||||
* (1/(frame_rate * (vbb + vfb + vact))) / (1/((fixed_clock_Mz/cycle_n) * 10^6))
|
||||
* ((fixed_clock_Mz/cycle_n) * 10^6) / (frame_rate * (vbb + vfb + vact))
|
||||
* (fixed_clock_hz/cycle_n) / (frame_rate * (vbb + vfb + vact))
|
||||
*/
|
||||
special_timing->fixed_clk_htotal = (fixed_clock_hz / cycle_n) / (frame_rate * (sync_timing->vbb +
|
||||
sync_timing->vfb + sync_timing->vact));
|
||||
/* (I27-I31-1)/2-1
|
||||
* (special_timing->fixed_clk_htotal - sync_timing->hact) / 2
|
||||
* 表格运算会出现小数,和逻辑沟通,向下取整忽略小数部分
|
||||
*/
|
||||
special_timing->fixed_clk_hbb = (special_timing->fixed_clk_htotal - sync_timing->hact) / 2;
|
||||
/* I27-(I31+1)-(I29+1)-1
|
||||
* fixed_clk_hfb - hact - hbb
|
||||
*/
|
||||
special_timing->fixed_clk_hfb = special_timing->fixed_clk_htotal - sync_timing->hact -
|
||||
special_timing->fixed_clk_hbb;
|
||||
|
||||
special_timing->vs_st_v_filed = sync_timing->vfb;
|
||||
special_timing->vs_end_v_filed = special_timing->vs_st_v_filed + sync_timing->vpw;
|
||||
VO_TRACE(MODULE_DBG_DEBUG,
|
||||
"fixed_clk_htotal %d fixed_clock_hz %d fixed_clk_hbb %d fixed_clk_hfb %d\n",
|
||||
special_timing->fixed_clk_htotal, fixed_clock_hz,
|
||||
special_timing->fixed_clk_hbb, special_timing->fixed_clk_hfb);
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "vs_st_v_filed %d vs_end_v_filed %d\n",
|
||||
special_timing->vs_st_v_filed, special_timing->vs_end_v_filed);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
if (hal_vo_get_intf_clock(&hal_ctx->clock_config, dev, &fixed_clock_hz) != XMEDIA_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
htotal_adjust_value = (vo_mipi_htotal_adjust_value != 0) ? vo_mipi_htotal_adjust_value :
|
||||
mipi_phy_cfg->phy_htotal_adjust;
|
||||
vsync_adjust_value = (vo_mipi_vsync_adjust_value != 0) ? vo_mipi_vsync_adjust_value :
|
||||
mipi_phy_cfg->phy_vsync_adjust;
|
||||
/*
|
||||
* INT(D20/D15*D26) + FIXCLOCK_HTOTAL_AJUST_VALUE
|
||||
* hal_ctx->mipi_phy_cfg.phy_vid_hline_time * fixed_clock_Mhz / phy_lanebyte_clock_hzMhz + AJUST
|
||||
* hal_ctx->mipi_phy_cfg.phy_vid_hline_time * fixed_clock_hz / phy_lanebyte_clock_hzhz + AJUST
|
||||
* hal_ctx->mipi_phy_cfg.phy_vid_hline_time * (fixed_clock_hz/1000) / (phy_lanebyte_clock_hzhz/1000) + AJUST
|
||||
*/
|
||||
special_timing->fixed_clk_htotal = (hal_ctx->mipi_phy_cfg.phy_vid_hline_time * (fixed_clock_hz/1000)) /
|
||||
(hal_ctx->mipi_phy_cfg.phy_lanebyte_clock_hz/1000) + htotal_adjust_value;
|
||||
|
||||
// = D7 => hbp => hbb - hpw
|
||||
special_timing->fixed_clk_hbb = sync_timing->hbb - sync_timing->hpw;
|
||||
|
||||
// D29-(D33+1)-(D31+1) => fixed_clk_htotal - vact - fixed_clk_hbb
|
||||
special_timing->fixed_clk_hfb = special_timing->fixed_clk_htotal - sync_timing->hact -
|
||||
special_timing->fixed_clk_hbb;
|
||||
|
||||
// D34 + 1 + D28 => vfb + 1 + FIXCLOCK_VSYNC_AJUST_VALUE
|
||||
special_timing->vs_st_v_filed = sync_timing->vfb + 1 + vsync_adjust_value - 1;
|
||||
|
||||
// D39 + D21 => vs_st_v_filed + vpw
|
||||
special_timing->vs_end_v_filed = special_timing->vs_st_v_filed + sync_timing->vpw;
|
||||
|
||||
VO_TRACE(MODULE_DBG_DEBUG,
|
||||
"fixed_clk_htotal %d phy_vid_hline_time %d fixed_clock_hz %d phy_lanebyte_clock_hz %d! fixed_clk_hbb %d fixed_clk_hfb %d\n",
|
||||
special_timing->fixed_clk_htotal, hal_ctx->mipi_phy_cfg.phy_vid_hline_time, fixed_clock_hz,
|
||||
hal_ctx->mipi_phy_cfg.phy_lanebyte_clock_hz, special_timing->fixed_clk_hbb, special_timing->fixed_clk_hfb);
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "vs_st_v_filed %d vs_end_v_filed %d\n",
|
||||
special_timing->vs_st_v_filed, special_timing->vs_end_v_filed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing)
|
||||
{
|
||||
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
#ifdef VO_KERNEL
|
||||
ddr_ost_info ost_value;
|
||||
#endif
|
||||
hal_vo_set_intf_cnt_pos(dev);
|
||||
|
||||
if (hal_ctx->special_timing[dev].vo_special_timing_sel) {
|
||||
hal_vo_calc_special_timing(dev, frame_rate, intf_config, sync_timing, &hal_ctx->mipi_phy_cfg);
|
||||
}
|
||||
hal_vo_set_intf_timing(dev, frame_rate, intf_config, sync_timing, &hal_ctx->special_timing[dev]);
|
||||
hal_vo_set_intf_fifo(dev, VO_FIFO_DEPTH);
|
||||
#ifdef VO_KERNEL
|
||||
drv_ddr_get_ost(XMEDIA_MOD_ID_VO, &ost_value);
|
||||
#endif
|
||||
|
||||
hal_vo_set_dma_standing(dev, 8);
|
||||
|
||||
switch(intf_config->intf_type){
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
hal_vo_set_bt656_intf_cfg(dev, &(intf_config->bt656_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
hal_vo_set_bt1120_intf_cfg(dev, &(intf_config->bt1120_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
hal_vo_set_lcd_intf_cfg(dev, &(intf_config->lcd_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
hal_vo_set_mipi_intf_cfg(dev, &(intf_config->mipi_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
hal_vo_set_lvds_intf_cfg(dev, &(intf_config->lvds_attr));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//intf 时钟相关绑定及门控 在前级set crg中做了
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
xmedia_bool intf_en[XMEDIA_VO_DEV_MAX];
|
||||
xmedia_vo_dev i;
|
||||
|
||||
hal_vo_set_intf_enable(dev, enable);
|
||||
|
||||
for (i = 0; i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
hal_vo_get_intf_enable(i, &intf_en[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_intf_enable(xmedia_vo_dev dev, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_intf_enable(dev, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_enable(layer,enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_bg_color(xmedia_vo_layer layer, xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_bgcolor(layer, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_mute_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mute_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_mute_color(xmedia_vo_layer layer, xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_mute_enable(layer, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_csc_en(xmedia_vo_layer layer, xmedia_bool csc_en)
|
||||
{
|
||||
hal_vo_set_csc_en(layer, csc_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_layer_csc_coef(xmedia_vo_layer layer, vo_pic_info* pic_info)
|
||||
{
|
||||
vo_csc_coef csc_matrix;
|
||||
xmedia_bool multi_en;
|
||||
|
||||
hal_vo_set_alpha(layer, 0xFF);
|
||||
|
||||
if (hal_vo_csc_coef_convert(pic_info, &csc_matrix) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
hal_vo_get_multi_enable(layer, &multi_en);
|
||||
if (multi_en == XMEDIA_TRUE) {
|
||||
hal_vo_set_mrg0_csc(layer, &csc_matrix);
|
||||
hal_vo_set_mrg1_csc(layer, &csc_matrix);
|
||||
hal_vo_set_mrg2_csc(layer, &csc_matrix);
|
||||
hal_vo_set_mrg3_csc(layer, &csc_matrix);
|
||||
} else {
|
||||
//单区域的csc复用多区域0的csc
|
||||
hal_vo_set_csc(layer, &csc_matrix);
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_disp_rect(xmedia_vo_layer layer, xmedia_video_rect *disp_rect)
|
||||
{
|
||||
hal_vo_set_disp_rect(layer, disp_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_disp_rect(xmedia_vo_layer layer, xmedia_video_rect *disp_rect)
|
||||
{
|
||||
hal_vo_get_disp_rect(layer, disp_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
//单区域模式 设定真实内容相对于层的rect
|
||||
xmedia_void hal_vo_set_layer_reso_rect(xmedia_vo_layer layer, xmedia_video_rect *reso_rect)
|
||||
{
|
||||
hal_vo_set_src_rect(layer, reso_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_reso_rect(xmedia_vo_layer layer, xmedia_video_rect *reso_rect)
|
||||
{
|
||||
hal_vo_get_src_rect(layer, reso_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_pixel_format(xmedia_vo_layer layer, xmedia_video_pixel_format pix_format)
|
||||
{
|
||||
vo_pixel_format format = VO_PIXEL_FMT_YUV_420;
|
||||
xmedia_bool uv_order = 0;
|
||||
|
||||
//注意下逻辑的排序与应用理解的UV是方向的
|
||||
if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 1;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 0;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) {
|
||||
format = VO_PIXEL_FMT_YUV_422;
|
||||
uv_order = 1;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) {
|
||||
format = VO_PIXEL_FMT_YUV_422;
|
||||
uv_order = 0;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
|
||||
format = VO_PIXEL_FMT_YUV_400;
|
||||
uv_order = 0;
|
||||
} else {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 1;
|
||||
}
|
||||
hal_vo_set_src_pixel_format(layer, format, uv_order);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//单区域和多区域控制
|
||||
xmedia_void hal_vo_set_layer_multi_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_multi_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_multi_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_multi_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_region_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id,
|
||||
xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_mute_color(xmedia_vo_layer layer, xmedia_u32 region_id,
|
||||
xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_mrg_mute_color(layer, region_id, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_single_region_cfg(xmedia_vo_layer layer, vo_layer_single_cfg *single_cfg)
|
||||
{
|
||||
//真实内容 相对于显示窗口的rect
|
||||
hal_vo_set_src_rect(layer, &(single_cfg->frame_rect));
|
||||
//层 相对于显示窗口的rect
|
||||
hal_vo_set_dst_rect(layer, &(single_cfg->video_rect));
|
||||
hal_vo_set_addr(layer, &(single_cfg->frame_addr));
|
||||
hal_vo_set_mute_enable(layer, single_cfg->mute_en);
|
||||
hal_vo_set_mrg_rdma1_en(layer, XMEDIA_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_multi_region_cfg(xmedia_vo_layer layer, vo_layer_multi_cfg *multi_cfg)
|
||||
{
|
||||
xmedia_u32 id;
|
||||
|
||||
id = multi_cfg->region_id;
|
||||
hal_vo_set_mrg_enable(layer, id, multi_cfg->region[id].enable);
|
||||
hal_vo_set_mrg_src_rect(layer,id, &(multi_cfg->region[id].src_rect));
|
||||
hal_vo_set_mrg_dst_rect(layer,id, &(multi_cfg->region[id].dst_rect));
|
||||
hal_vo_set_mrg_addr(layer,id, &(multi_cfg->region[id].region_addr));
|
||||
|
||||
if (multi_cfg->region_overlap) {
|
||||
hal_vo_set_mrg_rdma1_en(layer, XMEDIA_TRUE);
|
||||
//rdma0+rdma1 rdma1绑定优先级最高的
|
||||
hal_vo_set_mrg_mixer_prio(layer, VO_MRG_MIX_PRIO_RDMA0);
|
||||
hal_vo_set_mrg_rdma1_link(layer, multi_cfg->overlap_id);
|
||||
} else {
|
||||
hal_vo_set_mrg_rdma1_en(layer, XMEDIA_FALSE);
|
||||
hal_vo_set_mrg_mixer_prio(layer, VO_MRG_MIX_PRIO_RDMA0);
|
||||
}
|
||||
//sort的配置会影响画面的输出
|
||||
hal_vo_set_mrg_sort(layer, multi_cfg->region_sort);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_debug_pattern(xmedia_vo_dev dev, vo_pattern_info *pattern_info)
|
||||
{
|
||||
hal_vo_set_intf_mute_enable(dev, pattern_info->pattern_en);
|
||||
hal_vo_set_intf_mute_pattern_mode(dev, pattern_info->pattern_mode);
|
||||
hal_vo_set_intf_mute_data_mode(dev, pattern_info->data_mode);
|
||||
hal_vo_set_intf_mute_color(dev, pattern_info->color, pattern_info->color);
|
||||
hal_vo_set_intf_cbar_sel(dev, pattern_info->rgb);
|
||||
if (pattern_info->pattern_mode == VO_PATTERN_MODE_CHECKER) {
|
||||
hal_vo_set_intf_checkbar_size(dev, pattern_info->width, pattern_info->height);
|
||||
hal_vo_set_intf_mute_color(dev, pattern_info->color, !(pattern_info->color));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_debug_pattern(xmedia_vo_layer layer, vo_pattern_info *pattern_info)
|
||||
{
|
||||
vo_pattern_mode mode = VO_PATTERN_MODE_FULLCOLOR;
|
||||
|
||||
mode = pattern_info->pattern_mode;
|
||||
if ((mode != VO_PATTERN_MODE_FULLCOLOR) && (mode != VO_PATTERN_MODE_CHECKER)) {
|
||||
mode = VO_PATTERN_MODE_FULLCOLOR;
|
||||
}
|
||||
hal_vo_set_mute_enable(layer, pattern_info->pattern_en);
|
||||
hal_vo_set_mute_pattern_mode(layer, pattern_info->pattern_mode);
|
||||
hal_vo_set_mute_data_mode(layer, pattern_info->data_mode);
|
||||
hal_vo_set_mute_color(layer, pattern_info->color);
|
||||
if (mode == VO_PATTERN_MODE_CHECKER) {
|
||||
hal_vo_set_checkbar_size(layer, pattern_info->width, pattern_info->height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_debug_ink(xmedia_vo_dev dev, vo_csc_ink_info *ink_info)
|
||||
{
|
||||
hal_vo_set_intf_ink(dev, ink_info);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_debug_checksum(xmedia_vo_dev dev, xmedia_u32 *y, xmedia_u32 *u, xmedia_u32 *v)
|
||||
{
|
||||
hal_vo_get_intf_checksum_value(dev, y, u,v);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_enable_dev_phy_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_u32 frame_rate,
|
||||
xmedia_vo_user_sync_timing *sync_timing,
|
||||
xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
vo_hal_context * hal_ctx = hal_vo_get_hal_context();
|
||||
|
||||
switch(intf_type){
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
ret = hal_vo_set_mipi_tx_phy_cfg(dev, frame_rate, sync_timing, &hal_ctx->mipi_phy_cfg,
|
||||
hal_ctx->special_timing[dev].vo_special_timing_sel);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
ret = hal_vo_enable_lvds_phy_cfg(clk_hz);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_disable_dev_phy_cfg(xmedia_intf_type intf_type)
|
||||
{
|
||||
switch(intf_type){
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
hal_vo_set_mipi_tx_phy_reset();
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
hal_vo_disable_lvds_phy_cfg();
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 vo_calc_dev_phy_clk_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_vo_intf_config *intf_config)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
|
||||
switch(intf_config->intf_type){
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
ret = vo_calculate_mipi_phy_cfg(dev, clk_hz, &intf_config->mipi_attr, &hal_ctx->mipi_phy_cfg);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef VO_KERNEL
|
||||
xmedia_void hal_vo_set_gamma_addr(xmedia_vo_dev dev)
|
||||
{
|
||||
hal_vo_gamma_set_addr(dev, g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_gamma_enable(dev, enable);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_gamma_table(xmedia_vo_dev dev, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
hal_vo_gamma_set_table(dev, g_vo_gamma_buf[dev].gamma_virtual_addr, g_vo_gamma_buf[dev].gamma_mem_len, gamma_table);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_gamma_table(xmedia_vo_dev dev, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
hal_vo_gamma_get_table(dev, g_vo_gamma_buf[dev].gamma_virtual_addr, g_vo_gamma_buf[dev].gamma_mem_len, gamma_table);
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_reg_record(xmedia_void)
|
||||
{
|
||||
|
||||
xmedia_u32 idx, section_num;
|
||||
xmedia_ulong offset = 0;
|
||||
xmedia_u32 malloc_size = 0;
|
||||
|
||||
section_num = sizeof(g_vo_reg_offset) / sizeof(xmedia_ulong) / OFFSET_ELE_NUM;
|
||||
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
malloc_size += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
|
||||
if (g_vo_reg_record != XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"g_vo_reg_record is not null,please check!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
} else {
|
||||
g_vo_reg_record = (xmedia_u8 *)osal_kmalloc(malloc_size, osal_gfp_kernel);
|
||||
}
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
osal_memcpy((xmedia_void *)((xmedia_uintptr_t)g_vo_reg_record + offset),
|
||||
(xmedia_void *)((xmedia_uintptr_t)g_p_vout_reg + g_vo_reg_offset[idx][0]), g_vo_reg_offset[idx][1]);
|
||||
offset += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_reg_restore(xmedia_void)
|
||||
{
|
||||
xmedia_u32 idx;
|
||||
xmedia_u32 section_num;
|
||||
xmedia_ulong offset = 0;
|
||||
|
||||
if (g_vo_reg_record == XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"g_vo_reg_record is null,please check!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
section_num = sizeof(g_vo_reg_offset) / sizeof(xmedia_ulong) / OFFSET_ELE_NUM;
|
||||
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
osal_memcpy((xmedia_void *)(xmedia_uintptr_t)((xmedia_ulong)(xmedia_uintptr_t)g_p_vout_reg + g_vo_reg_offset[idx][0]),
|
||||
(xmedia_void *)(xmedia_uintptr_t)((xmedia_ulong)(xmedia_uintptr_t)g_vo_reg_record + offset),
|
||||
g_vo_reg_offset[idx][1]);
|
||||
offset += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
osal_kfree(g_vo_reg_record);
|
||||
g_vo_reg_record = XMEDIA_NULL;
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_chip_cfg.h"
|
||||
#define VO_IRQ_NAME "intr_vo"
|
||||
#define VO_INTF_NOT_MIPI_MAX_WHIDTH 1920
|
||||
#define VO_INTF_NOT_MIPI_MAX_CLK 148500000
|
||||
#define VO_INTF_MIPI_MAX_CLK 297000000
|
||||
#define VO_IRQ_NUM_7606V1 47
|
||||
|
||||
xmedia_s32 g_vo_irq = VO_IRQ_NUM_7606V1;
|
||||
|
||||
static vo_base_cap g_vo_cap;
|
||||
static xmedia_bool g_vo_cap_is_inited = XMEDIA_FALSE;
|
||||
static vo_layer_cap g_layer_capability[XMEDIA_VO_LAYER_MAX];
|
||||
static vo_dev_cap g_dev_capability[XMEDIA_VO_DEV_MAX];
|
||||
|
||||
static xmedia_void vo_init_chip_capacity(xmedia_void)
|
||||
{
|
||||
g_vo_cap.irq_name = VO_IRQ_NAME;
|
||||
g_vo_cap.irq_num = g_vo_irq;
|
||||
g_vo_cap.irq_cpumask = 0;
|
||||
g_vo_cap.vo_phy_addr = 0x11420000;
|
||||
g_vo_cap.chip_name = "xm7606v1";
|
||||
g_vo_cap.chip_revision = 0;
|
||||
g_vo_cap.chip_type = 0;
|
||||
g_vo_cap.board_id =0;
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_void vo_init_chip_dev_capacity(xmedia_void)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
g_dev_capability[i].support_video_layer_num = 1;
|
||||
g_dev_capability[i].support_gfx_layer_num = 1;
|
||||
g_dev_capability[i].support_max_layer_num = 2;
|
||||
g_dev_capability[i].support_intf_num = 1;
|
||||
g_dev_capability[i].support_csc_num = 3;
|
||||
if(i == XMEDIA_VO_DEV_1) {
|
||||
g_dev_capability[i].max_size.width = 1920;
|
||||
g_dev_capability[i].max_size.height = 1080;
|
||||
} else {
|
||||
g_dev_capability[i].max_size.width = 3840;
|
||||
g_dev_capability[i].max_size.height = 2160;
|
||||
}
|
||||
g_dev_capability[i].max_frame_rate = 60;
|
||||
g_dev_capability[i].support_ink = XMEDIA_TRUE;
|
||||
g_dev_capability[i].support_attach_layer = XMEDIA_FALSE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_void vo_init_chip_layer_capacity(xmedia_void)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < XMEDIA_VO_LAYER_MAX; i++) {
|
||||
g_layer_capability[i].support_hdr = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_flip = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_mirror = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_zme = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_dcmp = XMEDIA_FALSE;
|
||||
|
||||
g_layer_capability[i].support_region = XMEDIA_TRUE;
|
||||
g_layer_capability[i].region_num = 4;
|
||||
if(i == XMEDIA_VO_DEV_1) {
|
||||
g_layer_capability[i].max_read_size.width = 1920;
|
||||
g_layer_capability[i].max_read_size.height = 1080;
|
||||
} else {
|
||||
g_layer_capability[i].max_read_size.width = 3840;
|
||||
g_layer_capability[i].max_read_size.height = 2160;
|
||||
}
|
||||
g_layer_capability[i].min_out_size.width = 32;
|
||||
g_layer_capability[i].min_out_size.height = 32;
|
||||
|
||||
g_layer_capability[i].support_max_bit_width = 8;
|
||||
g_layer_capability[i].support_pixformat_num = 5;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_bt656_attr(xmedia_vo_dev dev, xmedia_vo_bt656_attr *bt656_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
if (bt656_attr->data_type != XMEDIA_INTF_BT_DATA_TYPE_YUV422_8BIT) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf not support data_type(%d) !\n", dev, bt656_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_UYVY) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_VYUY) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_YUYV) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_YVYU)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf not support data_seq(%d) !\n", dev, bt656_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_PAL) && (intf_sync != XMEDIA_VO_INTF_SYNC_NTSC) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_960H_PAL) && (intf_sync != XMEDIA_VO_INTF_SYNC_960H_NTSC)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_bt1120_attr(xmedia_vo_dev dev, xmedia_vo_bt1120_attr *bt1120_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
if (bt1120_attr->data_type != XMEDIA_INTF_BT_DATA_TYPE_YUV422_8BIT) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf not support data_type(%d) !\n", dev, bt1120_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((bt1120_attr->data_seq != XMEDIA_INTF_BT1120_DATA_SEQ_UVUV) &&
|
||||
(bt1120_attr->data_seq != XMEDIA_INTF_BT1120_DATA_SEQ_VUVU)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf not support data_seq(%d) !\n", dev, bt1120_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_1080P24) && (intf_sync != XMEDIA_VO_INTF_SYNC_1080P25) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_1080P30) && (intf_sync != XMEDIA_VO_INTF_SYNC_1080I50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_1080I60) && (intf_sync != XMEDIA_VO_INTF_SYNC_1080P50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_1080P60) && (intf_sync != XMEDIA_VO_INTF_SYNC_720P50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_720P60) && (intf_sync != XMEDIA_VO_INTF_SYNC_576P50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_480P60) && (intf_sync != XMEDIA_VO_INTF_SYNC_960H_PAL) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_960H_NTSC)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_lcd_sync(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
xmedia_intf_lcd_data_type data_type = lcd_attr->data_type;
|
||||
xmedia_vo_lcd_data_mode data_mode = lcd_attr->data_mode;
|
||||
//XMEDIA_VO_INTF_SYNC_USER lcd 用户自定义时序 是否会有问题????
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_320x240_50) && (intf_sync != XMEDIA_VO_INTF_SYNC_240x320_50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 6bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_320x240_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 8bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB565_16BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 16bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 18bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_800x480_50) && (intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 24bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_lcd_attr(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
xmedia_intf_lcd_data_type data_type = lcd_attr->data_type;
|
||||
xmedia_vo_lcd_data_mode data_mode = lcd_attr->data_mode;
|
||||
|
||||
if ((data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB565_16BIT) && (data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT) &&
|
||||
(data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_type(%d) !\n", dev, data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((data_mode != XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_mode != XMEDIA_VO_LCD_DATA_MODE_PARA)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_mode(%d) !\n", dev, data_mode);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_RGB) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_RBG) &&
|
||||
(lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_GRB) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_GBR) &&
|
||||
(lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_BRG) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_BGR)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_seq(%d) !\n", dev, lcd_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) {
|
||||
if ((data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT) && (data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf support 18&24 bit in serial mode(%d) !\n", dev, data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
return vo_check_lcd_sync(dev, lcd_attr, intf_sync);
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_mipi_attr(xmedia_vo_dev dev, xmedia_vo_mipi_attr *mipi_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (!(CHIP_ONLY_SUPPORT_MIPITX() || CHIP_BOTH_SUPPORT_MIPITX_LVDSTX())) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf not support, CHIP_TYPE err!\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
#endif
|
||||
xmedia_s32 i, j;
|
||||
for (i = XMEDIA_VO_MIPI_LANE_DATA0; i < XMEDIA_VO_MIPI_LANE_MAX - 1; i++) {
|
||||
for (j = i + 1; j < XMEDIA_VO_MIPI_LANE_MAX; j++) {
|
||||
if (mipi_attr->lane_sel[i] == mipi_attr->lane_sel[j]) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf not support duplicate (lane sel[%d] and lane_sel[%d])!\n",
|
||||
dev, mipi_attr->lane_sel[i], mipi_attr->lane_sel[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if (mipi_attr->lane_sel[i] >= XMEDIA_VO_MIPI_LANE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf, mipi lane sel is out of support(%d) !\n",
|
||||
dev, mipi_attr->lane_sel[i]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if (mipi_attr->lane_sel[j] >= XMEDIA_VO_MIPI_LANE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf, mipi lane sel is out of support(%d) !\n",
|
||||
dev, mipi_attr->lane_sel[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = XMEDIA_VO_MIPI_LANE_DATA0; i < XMEDIA_VO_MIPI_LANE_MAX; i++) {
|
||||
if ((mipi_attr->lane_pn_swap[i] != XMEDIA_TRUE) && (mipi_attr->lane_pn_swap[i] != XMEDIA_FALSE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf, mipi lane swap is out of support(%d) !\n",
|
||||
dev, mipi_attr->lane_pn_swap[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
if ((mipi_attr->data_type != XMEDIA_INTF_MIPI_DSI_DATA_TYPE_YUV422_16BIT) &&
|
||||
(mipi_attr->data_type != XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB666_18BIT) &&
|
||||
(mipi_attr->data_type != XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB888_24BIT)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_type(%d) !\n", dev, mipi_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
//需要测试是否支持所有的这些分辨率
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) &&
|
||||
(((intf_sync >= XMEDIA_VO_INTF_SYNC_3840x2160_50) && (intf_sync <= XMEDIA_VO_INTF_SYNC_4096x2160_60)) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_7680x4320_30) || (intf_sync == XMEDIA_VO_INTF_SYNC_PAL) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_NTSC) || (intf_sync == XMEDIA_VO_INTF_SYNC_960H_PAL) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_960H_NTSC) || (intf_sync == XMEDIA_VO_INTF_SYNC_1080I50) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_1080I60))) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mipi intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (mipi_attr->mipi_lane_num < XMEDIA_VO_MIPI_LANE_DEFAULT || mipi_attr->mipi_lane_num >= XMEDIA_VO_MIPI_LANE_NUM_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev %d not support mipi_lane_num %d", dev, mipi_attr->mipi_lane_num);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (mipi_attr->mipi_lane_num == XMEDIA_VO_MIPI_LANE_DEFAULT) {
|
||||
mipi_attr->mipi_lane_num = XMEDIA_VO_MIPI_LANE_NUM4;
|
||||
VO_TRACE(MODULE_DBG_INFO, "mipi_lane_num %d\n", mipi_attr->mipi_lane_num);
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_lvds_attr(xmedia_vo_dev dev, xmedia_vo_lvds_attr *lvds_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
xmedia_s32 i, j;
|
||||
#ifdef VO_KERNEL
|
||||
if (!(CHIP_ONLY_SUPPORT_LVDSTX() || CHIP_BOTH_SUPPORT_MIPITX_LVDSTX())) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf not support, CHIP_TYPE err!\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
#endif
|
||||
if ((lvds_attr->data_type != XMEDIA_INTF_LVDS_DATA_TYPE_RGB666_18BIT) &&
|
||||
(lvds_attr->data_type != XMEDIA_INTF_LVDS_DATA_TYPE_RGB888_24BIT)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf not support data_type(%d) !\n", dev, lvds_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((lvds_attr->format != XMEDIA_INTF_LVDS_FORMAT_VESA) && (lvds_attr->format != XMEDIA_INTF_LVDS_FORMAT_JEIDA)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf not support format(%d) !\n", dev, lvds_attr->format);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
for (i = XMEDIA_VO_LVDS_LANE_DATA0; i < XMEDIA_VO_LVDS_LANE_MAX - 1; i++) {
|
||||
for (j = i + 1; j < XMEDIA_VO_LVDS_LANE_MAX; j++) {
|
||||
if (lvds_attr->lane_sel[i] == lvds_attr->lane_sel[j]) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf not support duplicate (lane sel[%d] and lane_sel[%d])!\n",
|
||||
dev, lvds_attr->lane_sel[i], lvds_attr->lane_sel[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if (lvds_attr->lane_sel[i] >= XMEDIA_VO_LVDS_LANE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf, lvds lane sel is out of support(%d) !\n",
|
||||
dev, lvds_attr->lane_sel[i]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if (lvds_attr->lane_sel[j] >= XMEDIA_VO_LVDS_LANE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf, lvds lane sel is out of support(%d) !\n",
|
||||
dev, lvds_attr->lane_sel[j]);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//需要测试是否支持所有的这些分辨率
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) &&
|
||||
(((intf_sync >= XMEDIA_VO_INTF_SYNC_1920x2160_30) && (intf_sync <= XMEDIA_VO_INTF_SYNC_4096x2160_60)) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_7680x4320_30) || (intf_sync == XMEDIA_VO_INTF_SYNC_1920x1200_60) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_PAL) || (intf_sync == XMEDIA_VO_INTF_SYNC_NTSC) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_960H_PAL) || (intf_sync == XMEDIA_VO_INTF_SYNC_960H_NTSC) ||
|
||||
(intf_sync == XMEDIA_VO_INTF_SYNC_1080I50) || (intf_sync == XMEDIA_VO_INTF_SYNC_1080I60))) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lvds intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_dev_size(xmedia_vo_dev dev, xmedia_intf_type intf_type,
|
||||
xmedia_video_size *dev_size) {
|
||||
if (VO_CHECK_VIRT_DEV(dev) == XMEDIA_TRUE) {
|
||||
if (dev_size->width > g_dev_capability[dev].max_size.width ||
|
||||
dev_size->height > g_dev_capability[dev].max_size.height) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev%d not support dev_size_width %d\n", dev, dev_size->width);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
} else {
|
||||
if (dev_size->width > g_dev_capability[dev].max_size.width) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev%d not support dev_size_width %d\n", dev, dev_size->width);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//只有mipi支持 width>1920以上时序
|
||||
if ((dev_size->width > VO_INTF_NOT_MIPI_MAX_WHIDTH) && (intf_type != XMEDIA_INTF_TYPE_MIPI_DSI)) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "only mipi width support 1920+\n");
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_intf(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_video_size *dev_size)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
if (vo_check_dev_size(dev, config->intf_config.intf_type, dev_size) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
//虚拟设备不需要后续的check
|
||||
if (VO_CHECK_VIRT_DEV(dev) == XMEDIA_TRUE) {
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
switch (config->intf_config.intf_type){
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
ret = vo_check_bt656_attr(dev, &(config->intf_config.bt656_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
ret = vo_check_bt1120_attr(dev, &(config->intf_config.bt1120_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
ret = vo_check_lcd_attr(dev, &(config->intf_config.lcd_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MIPI_DSI:
|
||||
ret = vo_check_mipi_attr(dev, &(config->intf_config.mipi_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LVDS:
|
||||
ret = vo_check_lvds_attr(dev, &(config->intf_config.lvds_attr), config->intf_sync);
|
||||
break;
|
||||
default:
|
||||
ret = XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_clk(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_u32 clk)
|
||||
{
|
||||
//dev=0 且 mipi 端子才支持297M时钟,否则只支持148.5M
|
||||
if ((dev == XMEDIA_VO_DEV_0) && (config->intf_config.intf_type == XMEDIA_INTF_TYPE_MIPI_DSI)) {
|
||||
if (clk > VO_INTF_MIPI_MAX_CLK) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hal_vo_check_clk err, clk %d\n", clk);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
} else {
|
||||
if (clk > VO_INTF_NOT_MIPI_MAX_CLK) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hal_vo_check_clk err, clk %d\n", clk);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_csc_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config,
|
||||
xmedia_vo_dev_csc *dev_csc)
|
||||
{
|
||||
xmedia_bool mipi_rgb_en;
|
||||
|
||||
if (dev_csc->color_info.color_gamut == XMEDIA_VIDEO_COLOR_GAMUT_BT2020) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) color gamut should be bt601 or 709\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (((intf_config->intf_type == XMEDIA_INTF_TYPE_LCD) || (intf_config->intf_type == XMEDIA_INTF_TYPE_LVDS)) &&
|
||||
(dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_YUV)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) lcd/lvds should be output rgb\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (((intf_config->intf_type == XMEDIA_INTF_TYPE_BT656) || (intf_config->intf_type == XMEDIA_INTF_TYPE_BT1120)) &&
|
||||
(dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_RGB)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) bt656/bt1120 should be output yuv\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (intf_config->intf_type == XMEDIA_INTF_TYPE_MIPI_DSI) {
|
||||
if ((intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB666_18BIT) ||
|
||||
(intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB888_24BIT)){
|
||||
mipi_rgb_en = XMEDIA_TRUE;
|
||||
} else {
|
||||
mipi_rgb_en = XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
if ((mipi_rgb_en == XMEDIA_TRUE) && (dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_YUV)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d color space should be same as mipi output(%d,%d)\n",
|
||||
dev, mipi_rgb_en, dev_csc->color_info.color_space);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((mipi_rgb_en == XMEDIA_FALSE) && (dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_RGB)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d color space should be same as mipi output(%d,%d)\n",
|
||||
dev, mipi_rgb_en, dev_csc->color_info.color_space);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_gamma_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config)
|
||||
{
|
||||
if ((intf_config->intf_type == XMEDIA_INTF_TYPE_BT656) || (intf_config->intf_type == XMEDIA_INTF_TYPE_BT1120)) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG,"Vo dev(%d) yuv output not support gamma set\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if ((intf_config->intf_type == XMEDIA_INTF_TYPE_MIPI_DSI) &&
|
||||
(intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_YUV422_16BIT)) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG,"Vo dev(%d) yuv output not support gamma set\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_check_chip_type(vo_chip_type board_id)
|
||||
{
|
||||
if (board_id == VO_CHIP_TYPE_XM7606V1) {
|
||||
return XMEDIA_TRUE;
|
||||
} else {
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_layer_cap(xmedia_vo_layer layer, xmedia_u32 max_width, xmedia_u32 max_height,
|
||||
xmedia_vo_layer_config *layer_config)
|
||||
{
|
||||
if ((layer_config->img_size.width < g_layer_capability[layer].min_out_size.width) ||
|
||||
(layer_config->img_size.height < g_layer_capability[layer].min_out_size.height)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d image size(%d, %d) is illegaled, should biger than (%d,%d)!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height,
|
||||
g_layer_capability[layer].min_out_size.width, g_layer_capability[layer].min_out_size.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (layer_config->img_size.width > max_width || layer_config->img_size.height > max_height) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d image size width(%d %d) is illegaled, should less than(%d %d)!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height, max_width, max_height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((IS_ALIGN(layer_config->img_size.width, 2) != XMEDIA_TRUE) ||
|
||||
(IS_ALIGN(layer_config->img_size.height, 2) != XMEDIA_TRUE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d img size(%d, %d) dosen't aligned by 2 pixel!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_400)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d pix_format %d doesn't support!\n", layer, layer_config->pix_format);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
if (layer_config->bit_width != XMEDIA_VIDEO_DATA_WIDTH_8) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d bit_width %d doesn't support!\n", layer, layer_config->bit_width);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
if (layer_config->part_mode >= XMEDIA_VO_PARTITION_MODE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d part mode %d is illegal!\n", layer, layer_config->part_mode);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_layer_frame(xmedia_vo_layer layer, xmedia_video_frame_info *frame_info)
|
||||
{
|
||||
xmedia_u32 valid_width;
|
||||
xmedia_u32 valid_height;
|
||||
|
||||
valid_width = g_layer_capability[layer].min_out_size.width;
|
||||
valid_height = g_layer_capability[layer].min_out_size.height;
|
||||
if ((frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_400)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input pixel format %d!\n", frame_info->frame.pixel_fmt);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((frame_info->frame.width < valid_width) || (frame_info->frame.height < valid_height) ||
|
||||
(IS_ALIGN(frame_info->frame.width, 2) != XMEDIA_TRUE) ||
|
||||
(IS_ALIGN(frame_info->frame.width, 2) != XMEDIA_TRUE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"pic width(%d) is smaller than min width 32 or pic height(%d) is smaller than"
|
||||
"min height 32 or not align2!!\n", frame_info->frame.width, frame_info->frame.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.dynamic_range != XMEDIA_VIDEO_DYNAMIC_RANGE_SDR) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input dynamic range%d!\n", frame_info->frame.dynamic_range);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input compress mode%d!\n", frame_info->frame.compress_mode);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input video format%d!\n", frame_info->frame.video_fmt);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.bit_width != XMEDIA_VIDEO_DATA_WIDTH_8) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input bit width%d!\n", frame_info->frame.bit_width);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((frame_info->frame.color_info.color_space != XMEDIA_VIDEO_COLOR_SPACE_YUV) ||
|
||||
(frame_info->frame.color_info.color_gamut == XMEDIA_VIDEO_COLOR_GAMUT_BT2020) ||
|
||||
(frame_info->frame.color_info.color_gamut >= XMEDIA_VIDEO_COLOR_GAMUT_MAX) ||
|
||||
(frame_info->frame.color_info.quantify_range >= XMEDIA_VIDEO_COLOR_RANGE_MAX)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input color info:space-gamut-range(%d-%d-%d)!\n",
|
||||
frame_info->frame.color_info.color_space,
|
||||
frame_info->frame.color_info.color_gamut,frame_info->frame.color_info.quantify_range);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_init_chip_capaciblity(xmedia_void)
|
||||
{
|
||||
if (g_vo_cap_is_inited == XMEDIA_TRUE) {
|
||||
return;
|
||||
}
|
||||
g_vo_cap_is_inited = XMEDIA_TRUE;
|
||||
|
||||
vo_init_chip_capacity();
|
||||
vo_init_chip_dev_capacity();
|
||||
vo_init_chip_layer_capacity();
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vo_get_chip_revision(xmedia_void)
|
||||
{
|
||||
return g_vo_cap.chip_revision;
|
||||
}
|
||||
|
||||
vo_base_cap *hal_vo_get_chip_capacity(xmedia_void)
|
||||
{
|
||||
return &g_vo_cap;
|
||||
}
|
||||
|
||||
vo_layer_cap *hal_get_layer_chip_capacity(xmedia_vo_layer layer)
|
||||
{
|
||||
return &g_layer_capability[layer];
|
||||
}
|
||||
|
||||
vo_dev_cap *hal_get_dev_chip_capacity(xmedia_vo_dev dev)
|
||||
{
|
||||
return &g_dev_capability[dev];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CHIP_CFG_H__
|
||||
#define __HAL_VO_CHIP_CFG_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
#include "xmedia_vo.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VO_CHIP_INTF_TYPE_BT656 = 1 << 0,
|
||||
VO_CHIP_INTF_TYPE_BT1120 = 1 << 1,
|
||||
VO_CHIP_INTF_TYPE_LCD = 1 << 2,
|
||||
VO_CHIP_INTF_TYPE_LVDS = 1 << 3,
|
||||
VO_CHIP_INTF_TYPE_MIPI_DSI = 1 << 4,
|
||||
VO_CHIP_INTF_TYPE_MAX
|
||||
} vo_chip_intf_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CHIP_TYPE_XM7606V1,
|
||||
VO_CHIP_TYPE_MAX
|
||||
} vo_chip_type;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool support_hdr;
|
||||
xmedia_bool support_flip;
|
||||
xmedia_bool support_mirror;
|
||||
xmedia_bool support_zme;
|
||||
xmedia_bool support_dcmp;
|
||||
xmedia_bool support_region;
|
||||
xmedia_u32 region_num;
|
||||
xmedia_video_size max_read_size;
|
||||
xmedia_video_size min_out_size;
|
||||
xmedia_u32 support_max_bit_width;
|
||||
xmedia_u32 support_pixformat_num;
|
||||
} vo_layer_cap;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 support_video_layer_num;
|
||||
xmedia_u32 support_gfx_layer_num;
|
||||
xmedia_u32 support_max_layer_num;
|
||||
xmedia_u32 support_intf_num;
|
||||
xmedia_u32 support_csc_num;
|
||||
xmedia_video_size max_size;
|
||||
xmedia_bool support_ink;
|
||||
xmedia_bool support_attach_layer;
|
||||
xmedia_u32 max_frame_rate;
|
||||
} vo_dev_cap;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u64 vo_phy_addr;
|
||||
xmedia_u32 board_id;
|
||||
xmedia_u32 irq_num;
|
||||
xmedia_u32 irq_cpumask;
|
||||
xmedia_u32 chip_revision;
|
||||
xmedia_u32 chip_type;
|
||||
xmedia_char *chip_name;
|
||||
xmedia_char *irq_name;
|
||||
} vo_base_cap;
|
||||
|
||||
xmedia_bool hal_vo_check_chip_type(vo_chip_type board_id);
|
||||
xmedia_void hal_vo_init_chip_capaciblity(xmedia_void);
|
||||
xmedia_u32 hal_vo_get_chip_revision(xmedia_void);
|
||||
xmedia_s32 hal_vo_check_layer_cap(xmedia_vo_layer layer, xmedia_u32 max_width, xmedia_u32 max_height,
|
||||
xmedia_vo_layer_config *layer_config);
|
||||
xmedia_s32 hal_vo_check_dev_intf(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_video_size *dev_size);
|
||||
xmedia_s32 hal_vo_check_clk(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_u32 clk);
|
||||
xmedia_s32 hal_vo_check_dev_size(xmedia_vo_dev dev, xmedia_u32 width, xmedia_u32 height);
|
||||
xmedia_s32 hal_vo_check_dev_csc_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config,
|
||||
xmedia_vo_dev_csc *dev_csc);
|
||||
xmedia_s32 hal_vo_check_dev_gamma_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config);
|
||||
xmedia_s32 hal_vo_check_layer_frame(xmedia_vo_layer layer, xmedia_video_frame_info *frame_info);
|
||||
vo_base_cap *hal_vo_get_chip_capacity(xmedia_void);
|
||||
vo_layer_cap* hal_get_layer_chip_capacity(xmedia_vo_layer layer);
|
||||
vo_dev_cap* hal_get_dev_chip_capacity(xmedia_vo_dev dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO__CHIP_CFG_H__ */
|
||||
+17373
File diff suppressed because it is too large
Load Diff
+7889
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_INTF_H__
|
||||
#define __HAL_VO_INTF_H__
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
#include "hal_vo_clock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum{
|
||||
VO_INTF_HS_MODE_RF = 0, //vsyn对应的上升沿和下降沿都有效
|
||||
VO_INTF_HS_MODE_RF_NONE, //vsyn对应的上升沿和下降沿都无效
|
||||
VO_INTF_HS_MODE_FALLING,
|
||||
VO_INTF_HS_MODE_RISING,
|
||||
VO_INTF_HS_MODE_MAX,
|
||||
}vo_intf_hs_mode;
|
||||
|
||||
typedef struct{
|
||||
xmedia_bool hcds_en;
|
||||
xmedia_bool hcds_mode;
|
||||
xmedia_u8 hcds_coef_0;
|
||||
xmedia_u8 hcds_coef_1;
|
||||
xmedia_u8 hcds_coef_2;
|
||||
xmedia_u8 hcds_coef_3;
|
||||
}vo_intf_hcds;
|
||||
|
||||
typedef struct{
|
||||
xmedia_bool clip_en;
|
||||
xmedia_u32 clip_l;
|
||||
xmedia_u32 clip_h;
|
||||
}vo_intf_clip;
|
||||
|
||||
typedef struct{
|
||||
xmedia_u16 top_start;
|
||||
xmedia_u16 top_end;
|
||||
xmedia_u16 bottom_start;
|
||||
xmedia_u16 bottom_end;
|
||||
}vo_intf_bt_sync;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool ink_en;
|
||||
xmedia_bool cross_en;
|
||||
xmedia_bool color_reverse;
|
||||
xmedia_u32 color;
|
||||
xmedia_u32 x;
|
||||
xmedia_u32 y;
|
||||
} vo_csc_ink_info;
|
||||
|
||||
typedef struct {
|
||||
vo_clock_priority_sel vo_clock_priority_sel; //debug 接口 1:lcd分频器优先,0:固定频点优先
|
||||
xmedia_bool vo_special_timing_sel; //true表示使用固定分频,需要配置特殊时序,否则使用默认时序
|
||||
xmedia_u32 fixed_clk_htotal;
|
||||
xmedia_u32 fixed_clk_hbb;
|
||||
xmedia_u32 fixed_clk_hfb;
|
||||
xmedia_u32 vs_st_v_filed;
|
||||
xmedia_u32 vs_end_v_filed;
|
||||
} vo_intf_special_timing;
|
||||
|
||||
typedef struct{
|
||||
xmedia_u32 phy_clk_cfg; //mipi phy clock 需要配置给mipi ctrl,根据dev clk_hz 和 mipi ctrl计算公式得到
|
||||
xmedia_u32 phy_vid_hline_time; //mipi phy hline time
|
||||
xmedia_u32 phy_lanebyte_clock_hz;
|
||||
xmedia_u32 phy_master_swap; //mipi lane序配置
|
||||
xmedia_s32 phy_htotal_adjust;
|
||||
xmedia_s32 phy_vsync_adjust;
|
||||
xmedia_vo_mipi_lane_num phy_lane_num; //mipi lane数量
|
||||
} mipi_phy_config;
|
||||
|
||||
typedef struct {
|
||||
xmedia_s32 size;
|
||||
xmedia_u8 *array;
|
||||
} vo_mipi_lcd_config;
|
||||
|
||||
xmedia_void hal_vo_set_intf_fifo(xmedia_vo_dev dev, xmedia_u32 fifo);
|
||||
xmedia_void hal_vo_set_intf_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_enable(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_chk_sum_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_hs_mode(xmedia_vo_dev dev, vo_intf_hs_mode hs_mode);
|
||||
xmedia_void hal_vo_set_intf_mux(xmedia_vo_dev dev, xmedia_intf_type intf);
|
||||
xmedia_void hal_vo_set_intf_regup(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_cnt_pos(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_intf_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing, vo_intf_special_timing *special_timing);
|
||||
xmedia_void hal_vo_set_intf_sync_inverse(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_intf_vtt_sel(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_bool cnt_mode);
|
||||
xmedia_void hal_vo_set_intf_vtt_mode(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_bool frame_mode);
|
||||
xmedia_void hal_vo_set_intf_vtt_thd(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_u32 vtt_thd);
|
||||
xmedia_void hal_vo_get_intf_state(xmedia_vo_dev dev, xmedia_bool *btm, xmedia_u16 *vcnt, xmedia_u8 *vstate);
|
||||
xmedia_void hal_vo_get_intf_checksum_value(xmedia_vo_dev dev, xmedia_u32 *y, xmedia_u32 *u, xmedia_u32 *v);
|
||||
xmedia_void hal_vo_set_intf_bt_mode(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_yc_order(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_uv_order(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_vbit_mode(xmedia_vo_dev dev, xmedia_bool sync_mode);
|
||||
xmedia_void hal_vo_set_intf_bt_bit_inverse(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_bt_user_sync(xmedia_vo_dev dev, vo_intf_bt_sync *sync);
|
||||
xmedia_void hal_vo_set_intf_lcd_mode(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_lcd_rgb_order(xmedia_vo_dev dev, xmedia_u8 order0, xmedia_u8 order1);
|
||||
xmedia_void hal_vo_set_intf_lcd_bit_inverse(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_mute_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_mute_enable(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_mute_pattern_mode(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_mute_data_mode(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_checkbar_size(xmedia_vo_dev dev, xmedia_u8 width, xmedia_u8 height);
|
||||
xmedia_void hal_vo_set_intf_cbar_sel(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_mute_color(xmedia_vo_dev dev, xmedia_u32 white_color, xmedia_u32 black_color);
|
||||
xmedia_void hal_vo_set_intf_ink(xmedia_vo_dev dev, vo_csc_ink_info *ink_info);
|
||||
xmedia_void hal_vo_set_intf_clip(xmedia_vo_dev dev, vo_intf_clip *intf_clip);
|
||||
xmedia_void hal_vo_set_intf_csc_en(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_csc_en(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_csc(xmedia_vo_dev dev, vo_csc_coef *intf_csc);
|
||||
xmedia_void hal_vo_set_intf_hcds(xmedia_vo_dev dev, vo_intf_hcds *intf_hcds);
|
||||
xmedia_void hal_vo_set_intf_dither_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_dither_thd(xmedia_vo_dev dev, xmedia_u8 thd_h, xmedia_u8 thd_l);
|
||||
xmedia_void hal_vo_set_bt656_intf_cfg(xmedia_vo_dev dev, xmedia_vo_bt656_attr *bt656_attr);
|
||||
xmedia_void hal_vo_set_bt1120_intf_cfg(xmedia_vo_dev dev, xmedia_vo_bt1120_attr *bt1120_attr);
|
||||
xmedia_void hal_vo_set_lcd_intf_cfg(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr);
|
||||
xmedia_void hal_vo_set_mipi_intf_cfg(xmedia_vo_dev dev, xmedia_vo_mipi_attr *mipi_attr);
|
||||
xmedia_void hal_vo_set_lvds_intf_cfg(xmedia_vo_dev dev, xmedia_vo_lvds_attr *lvds_attr);
|
||||
xmedia_s32 hal_vo_set_mipi_tx_phy_cfg(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_user_sync_timing *sync_timing, mipi_phy_config *mipi_phy_cfg, xmedia_bool special_timing_sel);
|
||||
xmedia_void hal_vo_set_mipi_tx_phy_reset(xmedia_void);
|
||||
xmedia_s32 hal_vo_enable_lvds_phy_cfg(xmedia_u32 clk_hz);
|
||||
xmedia_s32 hal_vo_disable_lvds_phy_cfg(xmedia_void);
|
||||
xmedia_s32 vo_calculate_mipi_phy_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_vo_mipi_attr *mipi_attr,
|
||||
mipi_phy_config* mipi_phy_cfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifdef VO_BOOT
|
||||
#include <string.h>
|
||||
#include "xmedia_vo.h"
|
||||
#endif
|
||||
#include "hal_vo.h"
|
||||
#include "hal_vo_disp.h"
|
||||
#include "hal_vo_reg.h"
|
||||
#include "sys_drv.h"
|
||||
#include "hal_vo_clock.h"
|
||||
|
||||
extern s_vout_regs_type *g_p_vout_reg;
|
||||
|
||||
xmedia_void hal_vo_clock_init(vo_clock_config * vo_clock)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
osal_memset(vo_clock, 0, sizeof(vo_clock_config));
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_REAL_DEV_NUM; i++) {
|
||||
vo_clock->dev_clock_info[i].clock_sel = VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
for(i = VO_CRG_CLOCK_TYPE_MCU;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
vo_clock->intf_clock_info[i].intf_sel_dev = XMEDIA_VO_REAL_DEV_NUM;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_clock_deinit(xmedia_void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//vo top 门控使能
|
||||
xmedia_void hal_vo_set_clock_gate(vo_clock_config * vo_clock, xmedia_bool enable)
|
||||
{
|
||||
hal_reg_vout_set_cfg_ck_dyn_gt_en_dma(g_p_vout_reg, enable);
|
||||
hal_reg_vout_set_cfg_ck_dyn_gt_en(g_p_vout_reg, enable);
|
||||
vo_clock->vo_top_clock_gate = enable;
|
||||
return;
|
||||
}
|
||||
|
||||
static vo_clock_src_sel vo_fix_clk_sel(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz)
|
||||
{
|
||||
if ((0 < clk_hz) && (clk_hz <= VO_CLOCK_SRC_13_5MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_13_5MHZ;
|
||||
return VO_CLOCK_SRC_SEL_13_5MHZ;
|
||||
} else if ((VO_CLOCK_SRC_13_5MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_27MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_27MHZ;
|
||||
return VO_CLOCK_SRC_SEL_27MHZ;
|
||||
} else if ((VO_CLOCK_SRC_27MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_37_125MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_37_125MHZ;
|
||||
return VO_CLOCK_SRC_SEL_37_125MHZ;
|
||||
} else if ((VO_CLOCK_SRC_37_125MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_74_25MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_74_25MHZ;
|
||||
return VO_CLOCK_SRC_SEL_74_25MHZ;
|
||||
} else if ((VO_CLOCK_SRC_74_25MHZ < clk_hz) && (clk_hz <= VO_CLOCK_SRC_148_5MHZ)) {
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = VO_CLOCK_SRC_148_5MHZ;
|
||||
return VO_CLOCK_SRC_SEL_148_5MHZ;
|
||||
} else {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "not match normal Hz! Use LCD or PLL Hz!\n");
|
||||
return VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static vo_clock_ppc_sel vo_get_ppc_clock(vo_clock_config *vo_clock)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
xmedia_u32 intf_clk_hz = 0;
|
||||
xmedia_u32 ppc_clk_hz = 0;
|
||||
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_DEV_1; i++) {
|
||||
hal_vo_get_intf_clock(vo_clock, i, &intf_clk_hz);
|
||||
ppc_clk_hz = (intf_clk_hz > ppc_clk_hz) ? intf_clk_hz : ppc_clk_hz;
|
||||
}
|
||||
|
||||
if (ppc_clk_hz <= 50000000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_50MHZ;
|
||||
} else if (ppc_clk_hz <= 100000000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_100MHZ;
|
||||
} else if (ppc_clk_hz <= 150000000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_150MHZ;
|
||||
} else if (ppc_clk_hz <= 200000000) {
|
||||
return VO_CLOCK_SRC_PPC_SEL_200MHZ;
|
||||
} else {
|
||||
return VO_CLOCK_SRC_PPC_SEL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static vo_clock_src_sel vo_div_clk_sel(vo_clock_config *vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_u32 clk_hz)
|
||||
{
|
||||
xmedia_bool lcd_use_flag = XMEDIA_TRUE;
|
||||
xmedia_u32 i;
|
||||
|
||||
//判断lcd分频能否使用
|
||||
if (clk_hz <= LCD_FREQUENCY_DIVIDER_MAX) {
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_REAL_DEV_NUM; i++) {
|
||||
//lcd分频已使能&&不是本dev使用&&分频频率不同 则无法使用lcd分频
|
||||
if ((vo_clock->dev_clock_info[i].clock_sel == VO_CLOCK_SRC_SEL_LCD) &&
|
||||
(i != dev) && (vo_clock->dev_clock_info[i].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_hz != clk_hz)) {
|
||||
lcd_use_flag = XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
//配置lcd分频
|
||||
if (lcd_use_flag == XMEDIA_TRUE) {
|
||||
return VO_CLOCK_SRC_SEL_LCD;
|
||||
}
|
||||
}
|
||||
return VO_CLOCK_SRC_SEL_MAX;
|
||||
}
|
||||
|
||||
static vo_div_clock_type vo_clk_sel_to_div_type(vo_clock_src_sel clk_sel)
|
||||
{
|
||||
switch (clk_sel) {
|
||||
case VO_CLOCK_SRC_SEL_LCD:
|
||||
return VO_DIV_CLOCK_TYPE_LCD;
|
||||
default :
|
||||
return VO_DIV_CLOCK_TYPE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
//crg 分频时钟配置
|
||||
xmedia_s32 hal_vo_set_dev_div_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz,
|
||||
xmedia_bool *vo_special_timing_sel, xmedia_bool vo_lcd_divider_priority)
|
||||
{
|
||||
vo_clock_src_sel clk_sel;
|
||||
vo_clock_ppc_sel vo_ppc_sel;
|
||||
vo_div_clock_type div_type;
|
||||
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
//debug状态位检测,优先使用lcd分频器 or 优先使用固定频点
|
||||
if (vo_lcd_divider_priority == XMEDIA_TRUE) {
|
||||
clk_sel = vo_div_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
//分频器无法使用,尝试使用固定频点
|
||||
clk_sel = vo_fix_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
} else {
|
||||
div_type = vo_clk_sel_to_div_type(clk_sel);
|
||||
if (div_type == VO_DIV_CLOCK_TYPE_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//使用lcd分频器
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = 0;
|
||||
vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz = clk_hz;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CFG, &clk_hz);
|
||||
}
|
||||
} else {
|
||||
clk_sel = vo_fix_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel != VO_CLOCK_SRC_SEL_MAX) {
|
||||
//使用固定频点
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
} else {
|
||||
clk_sel = vo_div_clk_sel(vo_clock, dev, clk_hz);
|
||||
if (clk_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
div_type = vo_clk_sel_to_div_type(clk_sel);
|
||||
if (div_type == VO_DIV_CLOCK_TYPE_MAX) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//使用lcd分频
|
||||
vo_clock->dev_clock_info[dev].clock_sel = clk_sel;
|
||||
vo_clock->dev_clock_info[dev].fixed_clock_hz = 0;
|
||||
vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz = clk_hz;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CFG, &clk_hz);
|
||||
}
|
||||
}
|
||||
|
||||
//都使用校正后的特殊时序,不同的是依照 分频器时钟值/固定频点值 计算出不同的矫正时序
|
||||
*vo_special_timing_sel = XMEDIA_TRUE;
|
||||
|
||||
//时钟源选择配置
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_HD_CKSEL, &vo_clock->dev_clock_info[dev].clock_sel);
|
||||
|
||||
vo_clock->dev_clock_info[dev].clock_hz = clk_hz;
|
||||
|
||||
//ppc 时钟配置
|
||||
vo_ppc_sel = vo_get_ppc_clock(vo_clock);
|
||||
if (vo_ppc_sel != VO_CLOCK_SRC_PPC_SEL_MAX) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_PPC_CKSEL, &vo_ppc_sel);
|
||||
}else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
//crg时钟 分频器使能
|
||||
xmedia_void hal_vo_set_dev_div_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_en)
|
||||
{
|
||||
xmedia_bool lcd_div_freq_en = XMEDIA_FALSE;
|
||||
xmedia_u32 i;
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel == VO_CLOCK_SRC_SEL_LCD) {
|
||||
vo_clock->dev_clock_info[dev].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_en = clk_en;
|
||||
}
|
||||
//有可能两个dev用同一个分屏器的频点,判断是否是所有dev分频器的使能状态
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_REAL_DEV_NUM; i++) {
|
||||
lcd_div_freq_en |= vo_clock->dev_clock_info[i].freq_clock[VO_DIV_CLOCK_TYPE_LCD].div_clock_en;
|
||||
}
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_DIV_CKEN, &lcd_div_freq_en);
|
||||
return;
|
||||
}
|
||||
|
||||
//crg时钟 vou软复位请求
|
||||
xmedia_void hal_vo_set_clock_reset_enable(vo_clock_config * vo_clock, xmedia_bool reset_en)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
xmedia_u32 i;
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_SRST_REQ, &reset_en);
|
||||
//软复位 暂定状态将会改变 其他配置呢 div配置及门控使能 intf门控使能等????
|
||||
for(i = XMEDIA_VO_DEV_0;i < XMEDIA_VO_REAL_DEV_NUM; i++) {
|
||||
vo_clock->dev_clock_info[i].dev_clock_gate = XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_clock_reset_sta(xmedia_void)
|
||||
{
|
||||
xmedia_bool state;
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_SRST_GET, &state);
|
||||
return state;
|
||||
}
|
||||
|
||||
//crg时钟 vou dev0/dev1门控使能
|
||||
xmedia_void hal_vo_set_dev_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_en)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_VOU_HD_CKEN, &clk_en);
|
||||
vo_clock->dev_clock_info[dev].dev_clock_gate = clk_en;
|
||||
|
||||
return;
|
||||
}
|
||||
xmedia_bool vo_check_intf_sel_dev(vo_clock_config * vo_clock,
|
||||
vo_crg_intf_type crg_int_type, xmedia_vo_dev dev)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
for(i = VO_CRG_CLOCK_TYPE_MCU;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
//dev是否已经被其他intf选定了
|
||||
if ((vo_clock->intf_clock_info[i].intf_sel_dev == dev) && (crg_int_type != i)) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static vo_crg_intf_type hal_vo_swap_intf_type(xmedia_intf_type intf_type)
|
||||
{
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
return VO_CRG_CLOCK_TYPE_BT;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
return VO_CRG_CLOCK_TYPE_LCD;
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
return VO_CRG_CLOCK_TYPE_MCU;
|
||||
default:
|
||||
return VO_CRG_CLOCK_TYPE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_detach_dev(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_u32 i;
|
||||
|
||||
for(i = VO_CRG_CLOCK_TYPE_MCU;i < VO_CRG_CLOCK_TYPE_MAX; i++) {
|
||||
if ((vo_clock->intf_clock_info[i].intf_sel_dev == dev) && (hal_vo_swap_intf_type(intf_type) == i)) {
|
||||
vo_clock->intf_clock_info[i].intf_sel_dev = XMEDIA_VO_REAL_DEV_NUM;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//crg intf 时钟 通道选择
|
||||
xmedia_s32 hal_vo_set_intf_clock(vo_clock_config * vo_clock,
|
||||
xmedia_vo_dev dev, xmedia_bool clk_reverse_en, xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = dev;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_BT, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_HD_CKSEL, &dev); //bt接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_PCTRL, &clk_reverse_en); //bt接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_BT].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_BT].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
if (vo_check_intf_sel_dev(vo_clock, VO_CRG_CLOCK_TYPE_LCD, dev) == XMEDIA_SUCCESS) {
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_HD_CKSEL, &dev); //lcd接口时钟通道选择 hd0 hd1
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_PCTRL, &clk_reverse_en); //lcd接口时钟反向
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LCD].intf_sel_dev = dev;
|
||||
vo_clock->intf_clock_info[VO_CRG_CLOCK_TYPE_LCD].intf_reverse_en = clk_reverse_en;
|
||||
break;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
//todo ???? mcu 接口时钟
|
||||
break;
|
||||
default:
|
||||
VO_TRACE(MODULE_DBG_ERR, "intf type error!\n");
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
//crg intf 接口时钟门控使能
|
||||
xmedia_void hal_vo_set_intf_clock_enable(vo_clock_config * vo_clock,
|
||||
xmedia_intf_type intf_type, xmedia_bool clock_enable)
|
||||
{
|
||||
xmedia_chn_info vo_chn_info = {0};
|
||||
vo_chn_info.mod_id = MOD_ID_VO;
|
||||
vo_chn_info.dev_id = 0;
|
||||
vo_chn_info.chn_id = 0;
|
||||
|
||||
switch(intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_BT_CKEN, &clock_enable); //bt时钟使能
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
drv_sys_mod_ctrl(&vo_chn_info, SYS_VO_LCD_CKEN, &clock_enable); //lcd时钟使能
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
break;
|
||||
default:
|
||||
VO_TRACE(MODULE_DBG_ERR, "intf type error!\n");
|
||||
return;
|
||||
}
|
||||
vo_clock->intf_clock_info[hal_vo_swap_intf_type(intf_type)].intf_clock_gate = clock_enable;
|
||||
return;
|
||||
}
|
||||
|
||||
//获取接口实际配置时钟
|
||||
xmedia_s32 hal_vo_get_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 *clock_hz)
|
||||
{
|
||||
vo_div_clock_type div_type;
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel == VO_CLOCK_SRC_SEL_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "clock_sel error!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (vo_clock->dev_clock_info[dev].clock_sel != VO_CLOCK_SRC_SEL_LCD) {
|
||||
*clock_hz = vo_clock->dev_clock_info[dev].fixed_clock_hz;
|
||||
} else {
|
||||
div_type = vo_clk_sel_to_div_type(vo_clock->dev_clock_info[dev].clock_sel);
|
||||
*clock_hz = vo_clock->dev_clock_info[dev].freq_clock[div_type].div_clock_hz;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CLOCK_H__
|
||||
#define __HAL_VO_CLOCK_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef enum {
|
||||
VO_MIPITX_PLL_REF_CKSEL_24M = 0,
|
||||
VO_MIPITX_PLL_REF_CKSEL_36M,
|
||||
VO_MIPITX_PLL_REF_CKSEL_MAX
|
||||
} vo_mipitx_pll_ref_cksel;
|
||||
|
||||
#define LCD_FREQUENCY_DIVIDER_MAX (148.5 * 1000 * 1000)
|
||||
#define PLL_FREQUENCY_DIVIDER_MAX (297 * 1000 * 1000)
|
||||
|
||||
#define LCD_DIV_2_POWER_27 (1 << 27) //2的27次方
|
||||
#define LCD_DIV_2_POWER_24 (1 << 24) //2的24次方
|
||||
#define LCD_DIV_SORCE_FRE (1375*1000*1000) //lcd源频率
|
||||
|
||||
#define VO_CLOCK_SRC_13_5MHZ 13500000
|
||||
#define VO_CLOCK_SRC_27MHZ 27000000
|
||||
#define VO_CLOCK_SRC_37_125MHZ 37125000
|
||||
#define VO_CLOCK_SRC_74_25MHZ 74250000
|
||||
#define VO_CLOCK_SRC_148_5MHZ 148500000
|
||||
#define VO_CLOCK_SRC_297MHZ 297000000
|
||||
#define VO_CLOCK_SRC_343_75MHZ 343750000
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_SRC_SEL_148_5MHZ,
|
||||
VO_CLOCK_SRC_SEL_74_25MHZ,
|
||||
VO_CLOCK_SRC_SEL_37_125MHZ,
|
||||
VO_CLOCK_SRC_SEL_27MHZ,
|
||||
VO_CLOCK_SRC_SEL_13_5MHZ,
|
||||
VO_CLOCK_SRC_SEL_LCD,
|
||||
VO_CLOCK_SRC_SEL_MAX,
|
||||
}vo_clock_src_sel;
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_SRC_PPC_SEL_200MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_150MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_100MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_50MHZ,
|
||||
VO_CLOCK_SRC_PPC_SEL_MAX,
|
||||
}vo_clock_ppc_sel;
|
||||
|
||||
typedef enum {
|
||||
VO_DIV_CLOCK_TYPE_LCD,
|
||||
VO_DIV_CLOCK_TYPE_MAX,
|
||||
} vo_div_clock_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CRG_CLOCK_TYPE_MCU,
|
||||
VO_CRG_CLOCK_TYPE_BT,
|
||||
VO_CRG_CLOCK_TYPE_LCD,
|
||||
VO_CRG_CLOCK_TYPE_MAX,
|
||||
} vo_crg_intf_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CLOCK_PRIORITY_SEL_NORMAL,
|
||||
VO_CLOCK_PRIORITY_SEL_LCD,
|
||||
VO_CLOCK_PRIORITY_SEL_FIX,
|
||||
VO_CLOCK_PRIORITY_SEL_MAX,
|
||||
} vo_clock_priority_sel;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool div_clock_en; //分频器使能状态 dev0 dev1 共用同一分频器时 需判断两个dev的使能状态来使能分频器
|
||||
xmedia_u32 div_clock_hz; //分频器频率
|
||||
} vo_div_clock_info;
|
||||
|
||||
typedef struct {
|
||||
vo_clock_src_sel clock_sel; //dev 时钟源选择
|
||||
xmedia_bool vo_lvds_sel; //lvds时需要配1 选择LVDS TXPHY PLL_CLKOUT,否则配0 选择SOC时钟
|
||||
xmedia_u32 clock_hz;
|
||||
xmedia_u32 fixed_clock_hz; //固定频点时钟
|
||||
vo_div_clock_info freq_clock[VO_DIV_CLOCK_TYPE_MAX];//dev 分频器信息
|
||||
xmedia_bool dev_clock_gate; //dev时钟门控
|
||||
} vo_dev_clock_info;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool intf_clock_gate; //intf时钟门控
|
||||
xmedia_vo_dev intf_sel_dev; //接口时钟通道选择
|
||||
xmedia_bool intf_reverse_en;
|
||||
} vo_intf_clock_info;
|
||||
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool vo_top_clock_gate; //vo top层动态时钟门控
|
||||
vo_dev_clock_info dev_clock_info[XMEDIA_VO_REAL_DEV_NUM]; //dev时钟信息
|
||||
vo_intf_clock_info intf_clock_info[VO_CRG_CLOCK_TYPE_MAX]; //intf时钟信息
|
||||
} vo_clock_config;
|
||||
|
||||
#define VO_MIPI_PLL_FREF VO_MIPITX_PLL_REF_CKSEL_24M //24MHz pll原始频率
|
||||
|
||||
xmedia_void hal_vo_clock_init(vo_clock_config * vo_clock);
|
||||
xmedia_void hal_vo_clock_deinit(xmedia_void);
|
||||
xmedia_void hal_vo_set_clock_gate(vo_clock_config * vo_clock, xmedia_bool enable);
|
||||
xmedia_s32 hal_vo_set_dev_div_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 clk_hz,
|
||||
xmedia_bool *vo_special_timing_sel, xmedia_bool vo_lcd_divider_priority);
|
||||
|
||||
xmedia_void hal_vo_set_dev_div_clock_enable(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_bool clk_en);
|
||||
xmedia_void hal_vo_set_clock_reset_enable(vo_clock_config * vo_clock, xmedia_bool reset_en);
|
||||
xmedia_bool hal_vo_get_clock_reset_sta(xmedia_void);
|
||||
xmedia_void hal_vo_set_dev_clock_enable(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_bool clk_en);
|
||||
xmedia_s32 hal_vo_set_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_bool clk_reverse_en,
|
||||
xmedia_intf_type intf_type);
|
||||
xmedia_void hal_vo_set_intf_clock_enable(vo_clock_config * vo_clock, xmedia_intf_type intf_type,
|
||||
xmedia_bool clock_enable);
|
||||
xmedia_void hal_vo_set_intf_detach_dev(vo_clock_config * vo_clock, xmedia_vo_dev dev,
|
||||
xmedia_intf_type intf_type);
|
||||
xmedia_s32 hal_vo_get_intf_clock(vo_clock_config * vo_clock, xmedia_vo_dev dev, xmedia_u32 *clock_hz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
|
||||
#define VO_CSC_TABLE_MAX 61
|
||||
|
||||
typedef struct{
|
||||
vo_csc_type type;
|
||||
const vo_csc_coef *matrix;
|
||||
} vo_csc_type_matrix;
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv601limit = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv601limit = {
|
||||
880, 0, 0, 0, 899, 0, 0, 0, 899,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv601limit = {
|
||||
1024, 102, 196, 0, 1014, -113, 0, -74, 1007,
|
||||
-16, -128, -128,
|
||||
-16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv601limit = {
|
||||
880, 90, 173, 0, 891, -99, 0, -65, 864,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv709limit = {
|
||||
1024, -118, -213, 0, 1043, 117, 0, 77, 1050,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv709limit = {
|
||||
880, -103, -187, 0, 916, 102, 0, 67, 922,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv709limit = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
-16, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv709limit = {
|
||||
880, 0, 0, 0, 899, 0, 0, 0, 899,
|
||||
0, -128, -128,
|
||||
16, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv601full = {
|
||||
1192, 0, 0, 0, 1165, 0, 0, 0, 1165,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv601full = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv601full = {
|
||||
1192, 117, 222, 0, 1154, -128, 0, -84, 1146,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv601full = {
|
||||
1024, 102, 196, 0, 1014, -113, 0, -74, 1007,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_yuv709full = {
|
||||
1192, -137, -248, 0, 1188, 133, 0, 87, 1194,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_yuv709full = {
|
||||
1024, -118, -213, 0, 1043, 117, 0, 77, 1050,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_yuv709full = {
|
||||
1192, 0, 0, 0, 1165, 0, 0, 0, 1165,
|
||||
-16, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_yuv709full = {
|
||||
1024, 0, 0, 0, 1024, 0, 0, 0, 1024,
|
||||
0, -128, -128,
|
||||
0, 128, 128,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_rgbfull = {
|
||||
1192, 0, 1634, 1192, -400, -833, 1192, 2066, 0,
|
||||
-16, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_rgbfull = {
|
||||
1024, 0, 1040, 1024, -344, -706, 1024, 1774, 0,
|
||||
0, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_rgbfull = {
|
||||
1192, 0, 1836, 1192, -218, -547, 1192, 2166, 0,
|
||||
-16, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_rgbfull = {
|
||||
1024, 0, 1577, 1024, -187, -470, 1024, 1860, 0,
|
||||
0, -128, -128,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601limit_to_rgblimit = {
|
||||
1024, 0, 1404, 1024, -344, -716, 1024, 1775, 0,
|
||||
-16, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv601full_to_rgblimit = {
|
||||
880, 0, 1233, 880, -302, -629, 880, 1559, 0,
|
||||
0, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709limit_to_rgblimit = {
|
||||
1024, 0, 1578, 1024, -187, -470, 1024, 1861, 0,
|
||||
-16, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const vo_csc_coef g_csc_yuv709full_to_rgblimit = {
|
||||
880, 0, 1385, 880, -164, -413, 880, 1634, 0,
|
||||
0, -128, -128,
|
||||
16, 16, 16,
|
||||
};
|
||||
|
||||
const int g_sin_table[VO_CSC_TABLE_MAX] = {
|
||||
-500, -485, -469, -454, -438, -422, -407, -391, -374, -358,
|
||||
-342, -325, -309, -292, -276, -259, -242, -225, -208, -191,
|
||||
-174, -156, -139, -122, -104, -87, -70, -52, -35, -17,
|
||||
0, 17, 35, 52, 70, 87, 104, 122, 139, 156,
|
||||
174, 191, 208, 225, 242, 259, 276, 292, 309, 325,
|
||||
342, 358, 374, 391, 407, 422, 438, 454, 469, 485,
|
||||
500
|
||||
};
|
||||
|
||||
const int g_cos_table[VO_CSC_TABLE_MAX] = {
|
||||
866, 875, 883, 891, 899, 906, 914, 921, 927, 934,
|
||||
940, 946, 951, 956, 961, 966, 970, 974, 978, 982,
|
||||
985, 988, 990, 993, 995, 996, 998, 999, 999, 1000,
|
||||
1000, 1000, 999, 999, 998, 996, 995, 993, 990, 988,
|
||||
985, 982, 978, 974, 970, 966, 961, 956, 951, 946,
|
||||
940, 934, 927, 921, 914, 906, 899, 891, 883, 875,
|
||||
866
|
||||
};
|
||||
|
||||
//后面需要根据算法提供的参数进行更新
|
||||
static vo_csc_type_matrix g_type_to_matrix[VO_CSC_MAX] = {
|
||||
{ VO_CSC_YUV2RGB_601_LIMIT2FULL, &g_csc_yuv601limit_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_709_LIMIT2FULL, &g_csc_yuv709limit_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_601_FULL2LIMIT, &g_csc_yuv601full_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_709_FULL2LIMIT, &g_csc_yuv709full_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_601_FULL2FULL, &g_csc_yuv601full_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_709_FULL2FULL, &g_csc_yuv709full_to_rgbfull },
|
||||
{ VO_CSC_YUV2RGB_601_LIMIT2LIMIT, &g_csc_yuv601limit_to_rgblimit },
|
||||
{ VO_CSC_YUV2RGB_709_LIMIT2LIMIT, &g_csc_yuv709limit_to_rgblimit },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_LIMIT2LIMIT, &g_csc_yuv601limit_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_601_709_LIMIT2LIMIT, &g_csc_yuv601limit_to_yuv709limit },
|
||||
{ VO_CSC_YUV2YUV_709_601_LIMIT2LIMIT, &g_csc_yuv709limit_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_709_709_LIMIT2LIMIT, &g_csc_yuv709limit_to_yuv709limit },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_FULL2FULL, &g_csc_yuv601full_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_601_709_FULL2FULL, &g_csc_yuv601full_to_yuv709full },
|
||||
{ VO_CSC_YUV2YUV_709_601_FULL2FULL, &g_csc_yuv709full_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_709_709_FULL2FULL, &g_csc_yuv709full_to_yuv709full },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_LIMIT2FULL, &g_csc_yuv601limit_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_601_709_LIMIT2FULL, &g_csc_yuv601limit_to_yuv709full },
|
||||
{ VO_CSC_YUV2YUV_709_601_LIMIT2FULL, &g_csc_yuv709limit_to_yuv601full },
|
||||
{ VO_CSC_YUV2YUV_709_709_LIMIT2FULL, &g_csc_yuv709limit_to_yuv709full },
|
||||
|
||||
{ VO_CSC_YUV2YUV_601_601_FULL2LIMIT, &g_csc_yuv601full_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_601_709_FULL2LIMIT, &g_csc_yuv601full_to_yuv709limit },
|
||||
{ VO_CSC_YUV2YUV_709_601_FULL2LIMIT, &g_csc_yuv709full_to_yuv601limit },
|
||||
{ VO_CSC_YUV2YUV_709_709_FULL2LIMIT, &g_csc_yuv709full_to_yuv709limit },
|
||||
};
|
||||
|
||||
static xmedia_s32 vo_get_base_matrix_by_type(vo_csc_type csc_type, const vo_csc_coef **csc_tmp)
|
||||
{
|
||||
xmedia_u32 loop;
|
||||
xmedia_u32 len;
|
||||
|
||||
len = sizeof(g_type_to_matrix) / sizeof(vo_csc_type_matrix);
|
||||
for (loop = 0; loop < len; loop++) {
|
||||
if (g_type_to_matrix[loop].type == csc_type) {
|
||||
if (g_type_to_matrix[loop].matrix != XMEDIA_NULL) {
|
||||
*csc_tmp = g_type_to_matrix[loop].matrix;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
}
|
||||
return XMEDIA_FAILURE;
|
||||
};
|
||||
|
||||
static xmedia_bool vo_check_csc_type(vo_csc_type type)
|
||||
{
|
||||
if ((type >= VO_CSC_YUV2RGB_601_LIMIT2FULL) && (type <= VO_CSC_YUV2RGB_709_LIMIT2LIMIT)) {
|
||||
return XMEDIA_TRUE;
|
||||
}
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_csc_coef_convert(vo_pic_info *src_pic_info, vo_csc_coef *pst_csc_matrix)
|
||||
{
|
||||
xmedia_s32 luma = 0;
|
||||
xmedia_s32 contrast = 0;
|
||||
xmedia_s32 hue = 0;
|
||||
xmedia_s32 satu = 0;
|
||||
const vo_csc_coef *base_csc_matrix = XMEDIA_NULL;
|
||||
|
||||
luma = (xmedia_s32)src_pic_info->luma * 64 / 100 - 32;
|
||||
contrast = ((xmedia_s32)src_pic_info->contrast - 50) * 2 + 100;
|
||||
hue = (xmedia_s32)src_pic_info->hue * 60 / 100;
|
||||
satu = ((xmedia_s32)src_pic_info->saturation - 50) * 2 + 100;
|
||||
if (hue >= VO_CSC_TABLE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hue %d error!\n", hue);
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
if (vo_get_base_matrix_by_type(src_pic_info->csc_type, &base_csc_matrix) != XMEDIA_SUCCESS) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo_get_base_matrix_by_type error!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
pst_csc_matrix->csc_offset_in0 = base_csc_matrix->csc_offset_in0;
|
||||
pst_csc_matrix->csc_offset_in1 = base_csc_matrix->csc_offset_in1;
|
||||
pst_csc_matrix->csc_offset_in2 = base_csc_matrix->csc_offset_in2;
|
||||
pst_csc_matrix->csc_offset_out0 = base_csc_matrix->csc_offset_out0;
|
||||
pst_csc_matrix->csc_offset_out1 = base_csc_matrix->csc_offset_out1;
|
||||
pst_csc_matrix->csc_offset_out2 = base_csc_matrix->csc_offset_out2;
|
||||
|
||||
/* C_ratio的调节范围一般是0~1.99, C_ratio=s32Contrast/100
|
||||
* S的调节范围一般为0~1.99,S=s32Satu/100
|
||||
* 色调调节参数的范围一般为-30°~30°,通过查表法求得COS和SIN值并/1000
|
||||
*/
|
||||
if (vo_check_csc_type(src_pic_info->csc_type) == XMEDIA_TRUE) {
|
||||
/* 此公式仅用于YUV->RGB转换,RGB->YUV转换不可用此公式 */
|
||||
pst_csc_matrix->csc_coef0 = (contrast * base_csc_matrix->csc_coef0) / 100;
|
||||
pst_csc_matrix->csc_coef1 = (contrast * satu * ((base_csc_matrix->csc_coef1 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef2 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef2 = (contrast * satu * ((base_csc_matrix->csc_coef1 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef2 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef3 = (contrast * base_csc_matrix->csc_coef3) / 100;
|
||||
pst_csc_matrix->csc_coef4 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef5 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef5 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef5 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef6 = (contrast * base_csc_matrix->csc_coef6) / 100;
|
||||
pst_csc_matrix->csc_coef7 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef8 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef8 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_sin_table[hue] +
|
||||
base_csc_matrix->csc_coef8 * g_cos_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_offset_in0 += (contrast != 0) ? (luma * 100 / contrast) : luma * 100;
|
||||
} else {
|
||||
/* 此公式仅用于RGB->YUV转换,YUV->RGB转换不可用此公式,
|
||||
* YUV->YUV仅调节图像效果可用此公式,因为常量矩阵为单位矩阵 */
|
||||
pst_csc_matrix->csc_coef0 = (contrast * base_csc_matrix->csc_coef0) / 100;
|
||||
pst_csc_matrix->csc_coef1 = (contrast * base_csc_matrix->csc_coef1) / 100;
|
||||
pst_csc_matrix->csc_coef2 = (contrast * base_csc_matrix->csc_coef2) / 100;
|
||||
pst_csc_matrix->csc_coef3 = (contrast * satu * ((base_csc_matrix->csc_coef3 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef3 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef4 = (contrast * satu * ((base_csc_matrix->csc_coef4 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef4 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef5 = (contrast * satu * ((base_csc_matrix->csc_coef5 * g_cos_table[hue] +
|
||||
base_csc_matrix->csc_coef5 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef6 = (contrast * satu * ((base_csc_matrix->csc_coef6 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef6 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef7 = (contrast * satu * ((base_csc_matrix->csc_coef7 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef7 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_coef8 = (contrast * satu * ((base_csc_matrix->csc_coef8 * g_cos_table[hue] -
|
||||
base_csc_matrix->csc_coef8 * g_sin_table[hue]) / 1000)) / 10000;
|
||||
pst_csc_matrix->csc_offset_out0 += luma;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CSC_H__
|
||||
#define __HAL_VO_CSC_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
xmedia_s32 csc_coef0;
|
||||
xmedia_s32 csc_coef1;
|
||||
xmedia_s32 csc_coef2;
|
||||
|
||||
xmedia_s32 csc_coef3;
|
||||
xmedia_s32 csc_coef4;
|
||||
xmedia_s32 csc_coef5;
|
||||
|
||||
xmedia_s32 csc_coef6;
|
||||
xmedia_s32 csc_coef7;
|
||||
xmedia_s32 csc_coef8;
|
||||
|
||||
xmedia_s32 csc_offset_in0;
|
||||
xmedia_s32 csc_offset_in1;
|
||||
xmedia_s32 csc_offset_in2;
|
||||
xmedia_s32 csc_offset_out0;
|
||||
xmedia_s32 csc_offset_out1;
|
||||
xmedia_s32 csc_offset_out2;
|
||||
} vo_csc_coef;
|
||||
|
||||
xmedia_s32 hal_vo_csc_coef_convert(vo_pic_info *src_pic_info, vo_csc_coef *pst_csc_matrix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
@@ -0,0 +1,722 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_disp.h"
|
||||
#include "hal_vo_reg.h"
|
||||
|
||||
extern s_vout_regs_type *g_p_vout_reg;
|
||||
|
||||
xmedia_void hal_vo_set_top_regup(xmedia_bool enable)
|
||||
{
|
||||
hal_reg_vout_set_cfg_regup_en(g_p_vout_reg, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_top_regup(xmedia_bool *enable)
|
||||
{
|
||||
*enable = hal_reg_vout_get_top_regup_sta(g_p_vout_reg);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_video_regup(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
*enable = hal_reg_vout_get_v0_regup_sta(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_intf_regup(xmedia_vo_dev dev, xmedia_bool *state)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
*state = hal_reg_vout_get_intf_regup_sta(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_version0(xmedia_u32 *version)
|
||||
{
|
||||
*version = hal_reg_vout_get_vout_ver_0(g_p_vout_reg);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_version1(xmedia_u32 *version)
|
||||
{
|
||||
*version = hal_reg_vout_get_vout_ver_1(g_p_vout_reg);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mem_ctrl(xmedia_u32 speed)
|
||||
{
|
||||
hal_reg_vout_set_cfg_rfs_sram_ctrl(g_p_vout_reg, speed);
|
||||
hal_reg_vout_set_cfg_ras_sram_ctrl(g_p_vout_reg, speed);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vo_get_mask_interrupt_state(xmedia_void)
|
||||
{
|
||||
xmedia_u32 mask_state;
|
||||
mask_state = hal_reg_vout_reg_read((xmedia_uintptr_t)&(g_p_vout_reg->vout_int_sta.u32));
|
||||
return mask_state;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_clear_mask_interrupt_state(vo_isr_interrupt_type int_mask)
|
||||
{
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_VTT0) {
|
||||
hal_reg_vout_set_cfg_intf_vt_int_0_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_VTT1) {
|
||||
hal_reg_vout_set_cfg_intf_vt_int_1_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_VTT2) {
|
||||
hal_reg_vout_set_cfg_intf_vt_int_2_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_VTT3) {
|
||||
hal_reg_vout_set_cfg_intf_vt_int_3_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_UFINT) {
|
||||
hal_reg_vout_set_cfg_intf_underflow_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_LOW_DELAY_CERR) {
|
||||
hal_reg_vout_set_cfg_low_delay_c_err_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_LOW_DELAY_YERR) {
|
||||
hal_reg_vout_set_cfg_low_delay_y_err_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_BUSR_ERR) {
|
||||
hal_reg_vout_set_cfg_axi_bus_rerr_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_BUSW_ERR) {
|
||||
hal_reg_vout_set_cfg_axi_bus_werr_clr(g_p_vout_reg, XMEDIA_TRUE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mask_interrupt_enable(vo_isr_interrupt_type int_mask,xmedia_bool enable)
|
||||
{
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_VTT0) {
|
||||
hal_reg_vout_set_cfg_intf_vt_int_0_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_VTT1) {
|
||||
hal_reg_vout_set_cfg_intf_vt_int_1_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_VTT2) {
|
||||
hal_reg_vout_set_cfg_intf_vt_int_2_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_VTT3) {
|
||||
hal_reg_vout_set_cfg_intf_vt_int_3_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_DHD0_UFINT) {
|
||||
hal_reg_vout_set_cfg_intf_underflow_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_LOW_DELAY_CERR) {
|
||||
hal_reg_vout_set_cfg_low_delay_c_err_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_LOW_DELAY_YERR) {
|
||||
hal_reg_vout_set_cfg_low_delay_y_err_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_BUSR_ERR) {
|
||||
hal_reg_vout_set_cfg_axi_bus_rerr_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
if (int_mask & VO_ISR_INTERRUPT_TYPE_BUSW_ERR) {
|
||||
hal_reg_vout_set_cfg_axi_bus_werr_msk(g_p_vout_reg, enable);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vo_get_unmask_interrupt_state(xmedia_void)
|
||||
{
|
||||
xmedia_u32 unmask_state;
|
||||
unmask_state = hal_reg_vout_reg_read((xmedia_uintptr_t)&(g_p_vout_reg->vout_int_src_sta.u32));
|
||||
return unmask_state;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_clear_lowband_state(xmedia_bool enable)
|
||||
{
|
||||
hal_reg_vout_set_cfg_uf_clr(g_p_vout_reg, enable);
|
||||
return;
|
||||
}
|
||||
xmedia_bool hal_vo_disp_get_dma_busy_state(xmedia_void)
|
||||
{
|
||||
xmedia_bool state = 0;
|
||||
state |= hal_reg_vout_get_rdma_busy_g0(g_p_vout_reg);
|
||||
state |= hal_reg_vout_get_rdma1_busy_v0_c(g_p_vout_reg);
|
||||
state |= hal_reg_vout_get_rdma1_busy_v0_y(g_p_vout_reg);
|
||||
state |= hal_reg_vout_get_rdma_busy_v0_c(g_p_vout_reg);
|
||||
state |= hal_reg_vout_get_rdma_busy_v0_y(g_p_vout_reg);
|
||||
return state;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_cbm_bgcolor(xmedia_vo_dev dev, xmedia_u32 bgcolor)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_bk_color(g_p_vout_reg, bgcolor);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_cbm_bgcolor(xmedia_vo_dev dev, xmedia_u32 *bgcolor)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
*bgcolor = hal_reg_vout_get_cfg_bk_color(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dma_standing(xmedia_vo_dev dev, xmedia_u8 value)
|
||||
{
|
||||
hal_reg_vout_set_cfg_axi_rd_ost_num(g_p_vout_reg, value);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_u8 hal_vo_get_dma_standing(xmedia_void)
|
||||
{
|
||||
return hal_reg_vout_get_cfg_axi_rd_ost_num(g_p_vout_reg);
|
||||
}
|
||||
|
||||
//v0 层的封装寄存器
|
||||
xmedia_void hal_vo_set_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_layer_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
*enable = hal_reg_vout_get_cfg_layer_en(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//两个及时寄存器
|
||||
xmedia_void hal_vo_set_regup_mode(xmedia_vo_layer layer, xmedia_bool filed_en)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_regup_mode(g_p_vout_reg, filed_en);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_regup_field(xmedia_vo_layer layer, xmedia_bool bottom_en)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_regup_field(g_p_vout_reg, bottom_en);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_alpha(xmedia_vo_layer layer, xmedia_u8 alpha)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_galpha(g_p_vout_reg, alpha);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_alpha_enable(xmedia_vo_layer layer, xmedia_bool alpha_en)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_galpha_en(g_p_vout_reg, alpha_en);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_alpha_blend_mode(xmedia_vo_layer layer, xmedia_bool alpha_blend_en)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_blend_mode(g_p_vout_reg, alpha_blend_en);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_src_pixel_format(xmedia_vo_layer layer, vo_pixel_format format, xmedia_bool uv_order)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_src_fmt(g_p_vout_reg, format);
|
||||
hal_reg_vout_set_cfg_src_uv_order(g_p_vout_reg, uv_order);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_multi_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_multi_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_video_regup_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_v0upd_cfg_regup_en(g_p_vout_reg, enable);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_bgcolor(xmedia_vo_layer layer, xmedia_u32 bgcolor)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_v0bk_cfg_bk_color(g_p_vout_reg, bgcolor);
|
||||
hal_reg_vout_set_cfg_mrg0_mute_color(g_p_vout_reg, bgcolor);
|
||||
hal_reg_vout_set_cfg_mrg1_mute_color(g_p_vout_reg, bgcolor);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_bgcolor(xmedia_vo_layer layer, xmedia_u32 *bgcolor)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
*bgcolor = hal_reg_vout_get_v0bk_cfg_bk_color(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mute_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
//此接口用于single模式,由于7206相对于7605 删除了独立的单区域模式,所以layer mute直接使用 mrg0_mute_en即可
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_mrg0_mute_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_mute_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
//此接口用于single模式,由于7206相对于7605 删除了独立的单区域模式,所以layer mute直接使用 mrg0_mute_en即可
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
*enable = hal_reg_vout_get_cfg_mrg0_mute_en(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mute_color(xmedia_vo_layer layer, xmedia_u32 bgcolor)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_v0bk_cfg_bk_color(g_p_vout_reg, bgcolor);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mute_pattern_mode(xmedia_vo_layer layer, xmedia_bool value)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_mute_pat(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mute_data_mode(xmedia_vo_layer layer, xmedia_bool value)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_mute_mode(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_checkbar_size(xmedia_vo_layer layer, xmedia_u8 width, xmedia_u8 height)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_checker_h(g_p_vout_reg, width);
|
||||
hal_reg_vout_set_cfg_checker_v(g_p_vout_reg, height);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* 层相对窗口 的rect
|
||||
*/
|
||||
xmedia_void hal_vo_set_disp_rect (xmedia_vo_layer layer, xmedia_video_rect *disp_rect)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
#if 0
|
||||
hal_reg_vout_set_cfg_disp_xpos(g_p_vout_reg, disp_rect->x);
|
||||
hal_reg_vout_set_cfg_disp_ypos(g_p_vout_reg, disp_rect->y);
|
||||
hal_reg_vout_set_cfg_disp_v(g_p_vout_reg, disp_rect->height - 1);
|
||||
hal_reg_vout_set_cfg_disp_h(g_p_vout_reg, disp_rect->width - 1);
|
||||
#endif
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_disp_rect (xmedia_vo_layer layer, xmedia_video_rect *disp_rect)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
#if 0
|
||||
disp_rect->x = hal_reg_vout_get_cfg_disp_xpos(g_p_vout_reg);
|
||||
disp_rect->y = hal_reg_vout_get_cfg_disp_ypos(g_p_vout_reg);
|
||||
disp_rect->height= hal_reg_vout_get_cfg_disp_v(g_p_vout_reg);
|
||||
disp_rect->width = hal_reg_vout_get_cfg_disp_h(g_p_vout_reg);
|
||||
#endif
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_src_rect (xmedia_vo_layer layer, xmedia_video_rect *src_rect)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_src_xpos(g_p_vout_reg, src_rect->x);
|
||||
hal_reg_vout_set_cfg_src_ypos(g_p_vout_reg, src_rect->y);
|
||||
hal_reg_vout_set_cfg_src_v(g_p_vout_reg, src_rect->height - 1);
|
||||
hal_reg_vout_set_cfg_src_h(g_p_vout_reg, src_rect->width - 1);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_src_rect (xmedia_vo_layer layer, xmedia_video_rect *src_rect)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
src_rect->x = hal_reg_vout_get_cfg_src_xpos(g_p_vout_reg);
|
||||
src_rect->y = hal_reg_vout_get_cfg_src_ypos(g_p_vout_reg);
|
||||
src_rect->width = hal_reg_vout_get_cfg_src_v(g_p_vout_reg);
|
||||
src_rect->height = hal_reg_vout_get_cfg_src_h(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg_mixer_prio(xmedia_vo_layer layer, vo_mrg_mix_prio prio_id)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_mixer_prio(g_p_vout_reg, prio_id);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
if (region_id == 0) {
|
||||
hal_reg_vout_set_cfg_mrg0_en(g_p_vout_reg, enable);
|
||||
} else if (region_id == 1) {
|
||||
hal_reg_vout_set_cfg_mrg1_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg_mute_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
if (region_id == 0) {
|
||||
hal_reg_vout_set_cfg_mrg0_mute_en(g_p_vout_reg, enable);
|
||||
} else if (region_id == 1) {
|
||||
hal_reg_vout_set_cfg_mrg1_mute_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
} {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool *enable)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
if (region_id == 0) {
|
||||
*enable = hal_reg_vout_get_cfg_mrg0_en(g_p_vout_reg);
|
||||
} else if (region_id == 1) {
|
||||
*enable = hal_reg_vout_get_cfg_mrg1_en(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
} {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg_src_rect (xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *src_rect)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
if (region_id == 0) {
|
||||
hal_reg_vout_set_cfg_mrg0_src_xpos(g_p_vout_reg, src_rect->x);
|
||||
hal_reg_vout_set_cfg_mrg0_src_ypos(g_p_vout_reg, src_rect->y);
|
||||
hal_reg_vout_set_cfg_mrg0_src_h(g_p_vout_reg, src_rect->width - 1);
|
||||
hal_reg_vout_set_cfg_mrg0_src_v(g_p_vout_reg, src_rect->height - 1);
|
||||
} else if (region_id == 1) {
|
||||
hal_reg_vout_set_cfg_mrg1_src_xpos(g_p_vout_reg, src_rect->x);
|
||||
hal_reg_vout_set_cfg_mrg1_src_ypos(g_p_vout_reg, src_rect->y);
|
||||
hal_reg_vout_set_cfg_mrg1_src_h(g_p_vout_reg, src_rect->width - 1);
|
||||
hal_reg_vout_set_cfg_mrg1_src_v(g_p_vout_reg, src_rect->height - 1);
|
||||
}else {
|
||||
;
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_lba_color(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_u32 color)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
if (region_id == 0) {
|
||||
hal_reg_vout_set_cfg_lba0_color(g_p_vout_reg, color);
|
||||
} else if (region_id == 1) {
|
||||
hal_reg_vout_set_cfg_lba1_color(g_p_vout_reg, color);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
} {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_lba_rect(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *lba_rect)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
if (region_id == 0) {
|
||||
hal_reg_vout_set_cfg_mrg0_disp_xpos(g_p_vout_reg, lba_rect->x);
|
||||
hal_reg_vout_set_cfg_mrg0_disp_ypos(g_p_vout_reg, lba_rect->y);
|
||||
hal_reg_vout_set_cfg_mrg0_disp_h(g_p_vout_reg, lba_rect->width - 1);
|
||||
hal_reg_vout_set_cfg_mrg0_disp_v(g_p_vout_reg, lba_rect->height - 1);
|
||||
} else if (region_id == 1) {
|
||||
hal_reg_vout_set_cfg_mrg1_disp_xpos(g_p_vout_reg, lba_rect->x);
|
||||
hal_reg_vout_set_cfg_mrg1_disp_ypos(g_p_vout_reg, lba_rect->y);
|
||||
hal_reg_vout_set_cfg_mrg1_disp_h(g_p_vout_reg, lba_rect->width - 1);
|
||||
hal_reg_vout_set_cfg_mrg1_disp_v(g_p_vout_reg, lba_rect->height - 1);
|
||||
}else {
|
||||
;
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg_dst_rect (xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *dst_rect)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
if (region_id == 0) {
|
||||
hal_reg_vout_set_cfg_mrg0_src_xpos(g_p_vout_reg, dst_rect->x);
|
||||
hal_reg_vout_set_cfg_mrg0_src_ypos(g_p_vout_reg, dst_rect->y);
|
||||
hal_reg_vout_set_cfg_mrg0_src_h(g_p_vout_reg, dst_rect->width - 1);
|
||||
hal_reg_vout_set_cfg_mrg0_src_v(g_p_vout_reg, dst_rect->height - 1);
|
||||
}
|
||||
else if (region_id == 1) {
|
||||
hal_reg_vout_set_cfg_mrg1_src_xpos(g_p_vout_reg, dst_rect->x);
|
||||
hal_reg_vout_set_cfg_mrg1_src_ypos(g_p_vout_reg, dst_rect->y);
|
||||
hal_reg_vout_set_cfg_mrg1_src_h(g_p_vout_reg, dst_rect->width - 1);
|
||||
hal_reg_vout_set_cfg_mrg1_src_v(g_p_vout_reg, dst_rect->height - 1);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg0_addr(xmedia_vo_layer layer, vo_addr *addr)
|
||||
{
|
||||
xmedia_u32 addr_y_l = addr->lum_addr & 0xFFFFFFFF;
|
||||
xmedia_u32 addr_y_h = (addr->lum_addr & 0xFFFFFFFF00000000) >> 32;
|
||||
xmedia_u32 addr_c_l = addr->chm_addr & 0xFFFFFFFF;
|
||||
xmedia_u32 addr_c_h = (addr->chm_addr & 0xFFFFFFFF00000000) >> 32;
|
||||
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_mrg0_src_stride_c(g_p_vout_reg, addr->chm_stride);
|
||||
hal_reg_vout_set_cfg_mrg0_src_addr_c_l(g_p_vout_reg, addr_c_l);
|
||||
hal_reg_vout_set_cfg_mrg0_src_addr_c_h(g_p_vout_reg, addr_c_h);
|
||||
hal_reg_vout_set_cfg_mrg0_src_stride_y(g_p_vout_reg, addr->lum_stride);
|
||||
hal_reg_vout_set_cfg_mrg0_src_addr_y_l(g_p_vout_reg, addr_y_l);
|
||||
hal_reg_vout_set_cfg_mrg0_src_addr_y_h(g_p_vout_reg, addr_y_h);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg1_addr(xmedia_vo_layer layer, vo_addr *addr)
|
||||
{
|
||||
xmedia_u32 addr_y_l = addr->lum_addr & 0xFFFFFFFF;
|
||||
xmedia_u32 addr_y_h = (addr->lum_addr & 0xFFFFFFFF00000000) >> 32;
|
||||
xmedia_u32 addr_c_l = addr->chm_addr & 0xFFFFFFFF;
|
||||
xmedia_u32 addr_c_h = (addr->chm_addr & 0xFFFFFFFF00000000) >> 32;
|
||||
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_mrg1_src_stride_c(g_p_vout_reg, addr->chm_stride);
|
||||
hal_reg_vout_set_cfg_mrg1_src_addr_c_l(g_p_vout_reg, addr_c_l);
|
||||
hal_reg_vout_set_cfg_mrg1_src_addr_c_h(g_p_vout_reg, addr_c_h);
|
||||
hal_reg_vout_set_cfg_mrg1_src_stride_y(g_p_vout_reg, addr->lum_stride);
|
||||
hal_reg_vout_set_cfg_mrg1_src_addr_y_l(g_p_vout_reg, addr_y_l);
|
||||
hal_reg_vout_set_cfg_mrg1_src_addr_y_h(g_p_vout_reg, addr_y_h);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg_addr(xmedia_vo_layer layer, xmedia_u32 region_id,vo_addr *addr)
|
||||
{
|
||||
if (region_id == 0) {
|
||||
hal_vo_set_mrg0_addr(layer, addr);
|
||||
} else if (region_id == 1) {
|
||||
hal_vo_set_mrg1_addr(layer, addr);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg_mute_color(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_u32 bgcolor)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
if (region_id == 0) {
|
||||
hal_reg_vout_set_cfg_mrg0_mute_color(g_p_vout_reg, bgcolor);
|
||||
} else if (region_id == 1) {
|
||||
hal_reg_vout_set_cfg_mrg1_mute_color(g_p_vout_reg, bgcolor);
|
||||
}
|
||||
else {
|
||||
;
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_csc_en(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_csc_en(g_p_vout_reg,enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg0_csc(xmedia_vo_layer layer,vo_csc_coef *csc)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_mrg0_csc_offset_in_2(g_p_vout_reg,csc->csc_offset_in2);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_offset_in_1(g_p_vout_reg,csc->csc_offset_in1);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_offset_in_0(g_p_vout_reg,csc->csc_offset_in0);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_offset_out_2(g_p_vout_reg,csc->csc_offset_out2);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_offset_out_1(g_p_vout_reg,csc->csc_offset_out1);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_offset_out_0(g_p_vout_reg,csc->csc_offset_out0);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_0(g_p_vout_reg,csc->csc_coef0);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_1(g_p_vout_reg,csc->csc_coef1);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_2(g_p_vout_reg,csc->csc_coef2);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_3(g_p_vout_reg,csc->csc_coef3);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_4(g_p_vout_reg,csc->csc_coef4);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_5(g_p_vout_reg,csc->csc_coef5);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_6(g_p_vout_reg,csc->csc_coef6);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_7(g_p_vout_reg,csc->csc_coef7);
|
||||
hal_reg_vout_set_cfg_mrg0_csc_matrix_8(g_p_vout_reg,csc->csc_coef8);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg1_csc(xmedia_vo_layer layer,vo_csc_coef *csc)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_mrg1_csc_offset_in_2(g_p_vout_reg,csc->csc_offset_in2);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_offset_in_1(g_p_vout_reg,csc->csc_offset_in1);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_offset_in_0(g_p_vout_reg,csc->csc_offset_in0);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_offset_out_2(g_p_vout_reg,csc->csc_offset_out2);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_offset_out_1(g_p_vout_reg,csc->csc_offset_out1);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_offset_out_0(g_p_vout_reg,csc->csc_offset_out0);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_0(g_p_vout_reg,csc->csc_coef0);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_1(g_p_vout_reg,csc->csc_coef1);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_2(g_p_vout_reg,csc->csc_coef2);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_3(g_p_vout_reg,csc->csc_coef3);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_4(g_p_vout_reg,csc->csc_coef4);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_5(g_p_vout_reg,csc->csc_coef5);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_6(g_p_vout_reg,csc->csc_coef6);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_7(g_p_vout_reg,csc->csc_coef7);
|
||||
hal_reg_vout_set_cfg_mrg1_csc_matrix_8(g_p_vout_reg,csc->csc_coef8);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_mrg_csc(xmedia_vo_layer layer, xmedia_u32 region_id, vo_csc_coef *csc)
|
||||
{
|
||||
if (region_id == 0) {
|
||||
hal_vo_set_mrg0_csc(layer, csc);
|
||||
} else if (region_id == 1) {
|
||||
hal_vo_set_mrg1_csc(layer, csc);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_csc_mode(xmedia_vo_layer layer, xmedia_bool csc_mode)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_csc_mode(g_p_vout_reg, csc_mode);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_DISP_H__
|
||||
#define __HAL_VO_DISP_H__
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VO_MRG_MIX_PRIO_RDMA0 = 0,
|
||||
VO_MRG_MIX_PRIO_RDMA1,
|
||||
VO_MRG_MIX_PRIO_MAX,
|
||||
} vo_mrg_mix_prio;
|
||||
|
||||
typedef enum {
|
||||
VO_MIX_PRIO_VIDEO = 0,
|
||||
VO_MIX_PRIO_GFX,
|
||||
VO_MIX_PRIO_MAX,
|
||||
} vo_mix_prio;
|
||||
|
||||
typedef enum {
|
||||
VO_PIXEL_FMT_YUV_400 = 0,
|
||||
VO_PIXEL_FMT_YUV_420,
|
||||
VO_PIXEL_FMT_YUV_422,
|
||||
VO_PIXEL_FMT_YUV_MAX
|
||||
} vo_pixel_format;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool vcus_mode;
|
||||
xmedia_bool hcus_mode;
|
||||
xmedia_u8 hcus_coef0;
|
||||
xmedia_u8 hcus_coef1;
|
||||
xmedia_u8 hcus_coef2;
|
||||
xmedia_u8 hcus_coef3;
|
||||
xmedia_u8 vcus_coef0;
|
||||
xmedia_u8 vcus_coef1;
|
||||
xmedia_u8 vcus_coef2;
|
||||
xmedia_u8 vcus_coef3;
|
||||
} vo_video_cus;
|
||||
|
||||
xmedia_void hal_vo_set_top_regup(xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_top_regup(xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_video_regup(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_intf_regup(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_get_version0(xmedia_u32 *version);
|
||||
xmedia_void hal_vo_get_version1(xmedia_u32 *version);
|
||||
xmedia_void hal_vo_set_mem_ctrl(xmedia_u32 speed);
|
||||
xmedia_u32 hal_vo_get_mask_interrupt_state(xmedia_void);
|
||||
xmedia_void hal_vo_clear_mask_interrupt_state(vo_isr_interrupt_type int_mask);
|
||||
xmedia_void hal_vo_set_mask_interrupt_enable(vo_isr_interrupt_type int_mask,xmedia_bool enable);
|
||||
xmedia_u32 hal_vo_get_unmask_interrupt_state(xmedia_void);
|
||||
xmedia_void hal_vo_clear_lowband_state(xmedia_bool enable);
|
||||
xmedia_bool hal_vo_disp_get_dma_busy_state(xmedia_void);
|
||||
xmedia_void hal_vo_set_cbm_mixer_prio(xmedia_vo_dev dev, vo_mix_prio prio_id);
|
||||
xmedia_void hal_vo_set_cbm_bgcolor(xmedia_vo_dev dev, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_get_cbm_bgcolor(xmedia_vo_dev dev, xmedia_u32 *bgcolor);
|
||||
xmedia_void hal_vo_set_dma_standing(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_u8 hal_vo_get_dma_standing(xmedia_void);
|
||||
xmedia_void hal_vo_set_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
//两个及时寄存器
|
||||
xmedia_void hal_vo_set_regup_mode(xmedia_vo_layer layer, xmedia_bool filed_en);
|
||||
xmedia_void hal_vo_set_regup_field(xmedia_vo_layer layer, xmedia_bool bottom_en);
|
||||
xmedia_void hal_vo_set_alpha(xmedia_vo_layer layer, xmedia_u8 alpha);
|
||||
xmedia_void hal_vo_set_alpha_enable(xmedia_vo_layer layer, xmedia_bool alpha_en);
|
||||
xmedia_void hal_vo_set_alpha_blend_mode(xmedia_vo_layer layer, xmedia_bool alpha_blend_en);
|
||||
xmedia_void hal_vo_set_src_pixel_format(xmedia_vo_layer layer, vo_pixel_format format, xmedia_bool uv_order);
|
||||
xmedia_void hal_vo_set_multi_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_multi_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_bgcolor(xmedia_vo_layer layer, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_get_bgcolor(xmedia_vo_layer layer, xmedia_u32 *bgcolor);
|
||||
xmedia_void hal_vo_set_mute_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_mute_enable(xmedia_vo_layer layer, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_video_regup_enable(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mute_color(xmedia_vo_layer layer, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_mute_pattern_mode(xmedia_vo_layer layer, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_mute_data_mode(xmedia_vo_layer layer, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_checkbar_size(xmedia_vo_layer layer, xmedia_u8 width, xmedia_u8 height);
|
||||
xmedia_void hal_vo_set_disp_rect (xmedia_vo_layer layer, xmedia_video_rect *disp_rect);
|
||||
xmedia_void hal_vo_get_disp_rect (xmedia_vo_layer layer, xmedia_video_rect *disp_rect);
|
||||
xmedia_void hal_vo_set_src_rect (xmedia_vo_layer layer, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_get_src_rect (xmedia_vo_layer layer, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_set_addr (xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_mixer_prio(xmedia_vo_layer layer, vo_mrg_mix_prio prio_id);
|
||||
xmedia_void hal_vo_set_mrg_rdma1_en(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mrg_mute_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_mrg_sort(xmedia_vo_layer layer, xmedia_u16 sort);
|
||||
xmedia_void hal_vo_set_mrg_src_rect (xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *src_rect);
|
||||
xmedia_void hal_vo_set_mrg_dst_rect (xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *dst_rect);
|
||||
xmedia_void hal_vo_set_mrg0_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg1_addr(xmedia_vo_layer layer, vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_addr(xmedia_vo_layer layer, xmedia_u32 region_id,vo_addr *addr);
|
||||
xmedia_void hal_vo_set_mrg_mute_color(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_u32 bgcolor);
|
||||
xmedia_void hal_vo_set_cus(xmedia_vo_layer layer, vo_video_cus *cus);
|
||||
xmedia_void hal_vo_set_csc_en(xmedia_vo_layer layer, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_mrg0_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg1_csc(xmedia_vo_layer layer,vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_mrg_csc(xmedia_vo_layer layer, xmedia_u32 region_id, vo_csc_coef *csc);
|
||||
xmedia_void hal_vo_set_csc_mode(xmedia_vo_layer layer, xmedia_bool csc_mode);
|
||||
xmedia_void hal_vo_set_lba_color(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_u32 color);
|
||||
xmedia_void hal_vo_set_lba_rect(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_video_rect *lba_rect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_reg.h"
|
||||
#include "hal_vo_gamma.h"
|
||||
|
||||
extern s_vout_regs_type *g_p_vout_reg;
|
||||
|
||||
xmedia_void hal_vo_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_gamma_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_get_table_size(xmedia_void)
|
||||
{
|
||||
return VO_GAMMA_MAP_SIZE * sizeof(xmedia_u8);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_set_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
xmedia_s32 i;
|
||||
for (i = 0;i < VO_GAMMA_MAP_SIZE; i++) {
|
||||
((xmedia_u8 *)gamma_virtual_addr)[i] = gamma_table->gamma_table[i];
|
||||
}
|
||||
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_para_2_update(g_p_vout_reg, XMEDIA_TRUE);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_get_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
xmedia_s32 i;
|
||||
|
||||
for (i = 0;i < VO_GAMMA_MAP_SIZE; i++) {
|
||||
gamma_table->gamma_table[i] = ((xmedia_u8 *)gamma_virtual_addr)[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_gamma_set_addr(xmedia_vo_dev dev, xmedia_u64 addr)
|
||||
{
|
||||
xmedia_u32 addr_l = addr & 0xFFFFFFFF;
|
||||
xmedia_u32 addr_h = (addr & 0xFFFFFFFF00000000) >> 32;
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_para_2_addr_h(g_p_vout_reg, addr_h);
|
||||
hal_reg_vout_set_cfg_para_2_addr_l(g_p_vout_reg, addr_l);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_GAMMA_H__
|
||||
#define __HAL_VO_GAMMA_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
xmedia_void hal_vo_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_s32 hal_vo_gamma_get_table_size(xmedia_void);
|
||||
xmedia_void hal_vo_gamma_set_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table);
|
||||
xmedia_void hal_vo_gamma_get_table(xmedia_vo_dev dev, xmedia_void *gamma_virtual_addr,
|
||||
xmedia_u32 gamma_mem_len, xmedia_vo_gamma_table *gamma_table);
|
||||
xmedia_void hal_vo_gamma_set_addr(xmedia_vo_dev dev, xmedia_u64 addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO_IP_CSC_H__ */
|
||||
|
||||
@@ -0,0 +1,965 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifdef VO_KERNEL
|
||||
#include "osal.h"
|
||||
#endif
|
||||
#include "hal_vo.h"
|
||||
#include "hal_vo_chip_cfg.h"
|
||||
#include "hal_vo_reg.h"
|
||||
#include "hal_vo_disp.h"
|
||||
#include "hal_vo_intf.h"
|
||||
#include "hal_vo_clock.h"
|
||||
#include "hal_vo_gamma.h"
|
||||
#ifdef VO_KERNEL
|
||||
#include "drv_vo_buf.h"
|
||||
#include "drv_ddr_ost_qos.h"
|
||||
#include "drv_vo_dev.h"
|
||||
#endif
|
||||
#ifdef VO_BOOT
|
||||
#include "drv_vo_comm.h"
|
||||
#endif
|
||||
|
||||
|
||||
static vo_hal_context vo_hal_ctx;
|
||||
|
||||
#define vo_reg_addr_offset(REG) ((xmedia_ulong) & (((s_vout_regs_type *)0)->REG))
|
||||
#define OFFSET_ELE_NUM 2
|
||||
#ifdef VO_KERNEL
|
||||
static xmedia_ulong g_vo_reg_offset[][OFFSET_ELE_NUM] = {
|
||||
{ vo_reg_addr_offset(vout_top_ctrl), 0x30c },
|
||||
{ vo_reg_addr_offset(vout_v0_ctrl), 0x348 },
|
||||
{ vo_reg_addr_offset(vout_intf_ctrl), 0x22c },
|
||||
{ vo_reg_addr_offset(vout_intf_hcds_ctrl), 0x38 },
|
||||
};
|
||||
static xmedia_u8 *g_vo_reg_record = XMEDIA_NULL;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
xmedia_u64 gamma_phy_addr;
|
||||
xmedia_void *gamma_virtual_addr;
|
||||
xmedia_u32 gamma_mem_len;
|
||||
} vo_dev_gamma_buf;
|
||||
|
||||
#define VO_BASE_ADDR 0x11280000
|
||||
s_vout_regs_type *g_p_vout_reg = (s_vout_regs_type *)VO_BASE_ADDR;
|
||||
|
||||
#define VO_FIFO_DEPTH 959
|
||||
#define VO_MMZ_NAME_SIZE 128
|
||||
#define VO_DEFAULT_OST_VALUE 8
|
||||
#ifdef VO_KERNEL
|
||||
static vo_dev_gamma_buf g_vo_gamma_buf[XMEDIA_VO_REAL_DEV_NUM];
|
||||
#endif
|
||||
vo_hal_context *hal_vo_get_hal_context(xmedia_void)
|
||||
{
|
||||
return &vo_hal_ctx;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_reg_map(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_p_vout_reg == XMEDIA_NULL) {
|
||||
g_p_vout_reg = (s_vout_regs_type *)osal_ioremap_nocache(VO_BASE_ADDR, sizeof(s_vout_regs_type));
|
||||
if (g_p_vout_reg == XMEDIA_NULL) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void vo_reg_unmap(xmedia_void)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_p_vout_reg != XMEDIA_NULL) {
|
||||
osal_iounmap((xmedia_void *)g_p_vout_reg);
|
||||
g_p_vout_reg = XMEDIA_NULL;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_init(xmedia_vo_dev dev)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
xmedia_char mmz_user_name[VO_MMZ_NAME_SIZE];
|
||||
xmedia_vo_gamma_table gamma_table;
|
||||
xmedia_u32 i = 0;
|
||||
|
||||
g_vo_gamma_buf[dev].gamma_mem_len = hal_vo_gamma_get_table_size();
|
||||
osal_snprintf(mmz_user_name, sizeof(mmz_user_name), "vo_gamma_dev%u", dev);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = drv_vo_mmz_alloc(mmz_user_name,
|
||||
g_vo_gamma_buf[dev].gamma_mem_len, XMEDIA_NULL);
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr == XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"drv_vo_mmz_alloc error!\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = drv_vo_mmz_map(g_vo_gamma_buf[dev].gamma_phy_addr,
|
||||
g_vo_gamma_buf[dev].gamma_mem_len);
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr == XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
VO_TRACE(MODULE_DBG_ERR,"drv_vo_mmz_map return NULL!\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
for (i = 0; i < VO_GAMMA_MAP_SIZE; i++) {
|
||||
gamma_table.gamma_table[i] = i;
|
||||
}
|
||||
hal_vo_set_gamma_table(dev, &gamma_table);
|
||||
return XMEDIA_SUCCESS;
|
||||
err_out:
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_unmap(g_vo_gamma_buf[dev].gamma_virtual_addr);
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
}
|
||||
return XMEDIA_FAILURE;
|
||||
#endif
|
||||
#ifdef VO_BOOT
|
||||
return XMEDIA_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_gamma_deinit(xmedia_vo_dev dev)
|
||||
{
|
||||
#ifdef VO_KERNEL
|
||||
if (g_vo_gamma_buf[dev].gamma_virtual_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_unmap(g_vo_gamma_buf[dev].gamma_virtual_addr);
|
||||
g_vo_gamma_buf[dev].gamma_virtual_addr = XMEDIA_NULL;
|
||||
}
|
||||
|
||||
if (g_vo_gamma_buf[dev].gamma_phy_addr != XMEDIA_NULL) {
|
||||
drv_vo_mmz_free(g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
g_vo_gamma_buf[dev].gamma_phy_addr = XMEDIA_NULL;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
#endif
|
||||
#ifdef VO_BOOT
|
||||
return XMEDIA_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_init(xmedia_void)
|
||||
{
|
||||
xmedia_u32 ret;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
osal_memset(hal_ctx, 0, sizeof(vo_hal_context));
|
||||
|
||||
hal_vo_init_chip_capaciblity();
|
||||
ret = vo_reg_map();
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
hal_vo_clock_init(&hal_ctx->clock_config);
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_deinit(xmedia_void)
|
||||
{
|
||||
//关闭所有的时钟todo
|
||||
hal_vo_clock_deinit();
|
||||
vo_reg_unmap();
|
||||
return;
|
||||
}
|
||||
|
||||
vo_base_cap* hal_vo_get_capacity(xmedia_void)
|
||||
{
|
||||
return hal_vo_get_chip_capacity();
|
||||
}
|
||||
|
||||
vo_layer_cap* hal_get_layer_capacity(xmedia_u32 layer)
|
||||
{
|
||||
return hal_get_layer_chip_capacity(layer);
|
||||
}
|
||||
|
||||
vo_dev_cap* hal_get_dev_capacity(xmedia_vo_dev dev)
|
||||
{
|
||||
return hal_get_dev_chip_capacity(dev);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_clock_gate_enable(xmedia_bool clk_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_clock_gate(&hal_ctx->clock_config, clk_en);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_clock_reset(xmedia_bool reset_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_clock_reset_enable(&hal_ctx->clock_config, reset_en);
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_crg_clock_reset_state(xmedia_void)
|
||||
{
|
||||
return hal_vo_get_clock_reset_sta();
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_clock_sel_priority(xmedia_vo_dev dev, vo_clock_priority_sel vo_clock_priority_sel)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_ctx->special_timing[dev].vo_clock_priority_sel = vo_clock_priority_sel;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_crg_clock(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_bool clk_reverse_en,
|
||||
xmedia_intf_type intf_type)
|
||||
{
|
||||
xmedia_bool vo_lcd_divider_priority = XMEDIA_FALSE;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
//根据时钟判断是否需要使用特殊时序配置
|
||||
if (hal_ctx->special_timing[dev].vo_clock_priority_sel == VO_CLOCK_PRIORITY_SEL_LCD) {
|
||||
vo_lcd_divider_priority = XMEDIA_TRUE;
|
||||
} else if (hal_ctx->special_timing[dev].vo_clock_priority_sel == VO_CLOCK_PRIORITY_SEL_FIX) {
|
||||
vo_lcd_divider_priority = XMEDIA_FALSE;
|
||||
} else {
|
||||
//debug没有设置lcd分频器时,对接口类型做二次判断,lcd/lvds优先使用LCD分频器
|
||||
if ((intf_type == XMEDIA_INTF_TYPE_LCD) || (intf_type == XMEDIA_INTF_TYPE_LVDS) ||
|
||||
(intf_type == XMEDIA_INTF_TYPE_MCU)) {
|
||||
vo_lcd_divider_priority = XMEDIA_TRUE;
|
||||
}
|
||||
}
|
||||
ret = hal_vo_set_dev_div_clock(&hal_ctx->clock_config, dev, clk_hz,
|
||||
&hal_ctx->special_timing[dev].vo_special_timing_sel, vo_lcd_divider_priority);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = hal_vo_set_intf_clock(&hal_ctx->clock_config, dev, clk_reverse_en, intf_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_clock_enable(xmedia_vo_dev dev, xmedia_intf_type intf_type, xmedia_bool clk_en)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_dev_div_clock_enable(&hal_ctx->clock_config, dev, clk_en);
|
||||
hal_vo_set_dev_clock_enable(&hal_ctx->clock_config, dev, clk_en);
|
||||
hal_vo_set_intf_clock_enable(&hal_ctx->clock_config, intf_type, clk_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_crg_intf_detach_dev(xmedia_vo_dev dev, xmedia_intf_type intf_type)
|
||||
{
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
hal_vo_set_intf_detach_dev(&hal_ctx->clock_config, dev, intf_type);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_top_regup_enable(xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_top_regup(enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_top_regup_enable(xmedia_void)
|
||||
{
|
||||
xmedia_bool enable = XMEDIA_FALSE;
|
||||
hal_vo_get_top_regup(&enable);
|
||||
return enable;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_regup_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_intf_regup(dev, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_dev_intf_regup_state(xmedia_vo_dev dev)
|
||||
{
|
||||
xmedia_bool state = XMEDIA_FALSE;
|
||||
hal_vo_get_intf_regup(dev, &state);
|
||||
return state;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_regup_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_video_regup_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_layer_regup_enable(xmedia_vo_layer layer)
|
||||
{
|
||||
xmedia_bool enable = XMEDIA_FALSE;
|
||||
hal_vo_get_video_regup(layer, &enable);
|
||||
return enable;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_interrupt_state(vo_int_state_type type, xmedia_u32 *state)
|
||||
{
|
||||
if (type == VO_INT_STATE_TYPE_MASK) {
|
||||
*state = hal_vo_get_mask_interrupt_state();
|
||||
} else if (type == VO_INT_STATE_TYPE_UNMASK) {
|
||||
*state = hal_vo_get_unmask_interrupt_state();
|
||||
} else {
|
||||
*state = hal_vo_get_mask_interrupt_state();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_clean_interrupt_state(vo_int_state_type type, vo_isr_interrupt_type state)
|
||||
{
|
||||
if (type == VO_INT_STATE_TYPE_UNMASK) {
|
||||
hal_vo_clear_lowband_state(XMEDIA_TRUE);
|
||||
} else {
|
||||
hal_vo_clear_mask_interrupt_state(state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_interrupt_enable(vo_isr_interrupt_type int_type, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mask_interrupt_enable(int_type, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_int_mode(xmedia_vo_dev dev, xmedia_u32 vtt_id, vo_isr_field_flag int_mode)
|
||||
{
|
||||
xmedia_bool frame_mode;
|
||||
|
||||
if ((int_mode == VO_ISR_FIELD_FLAG_TOP) || (int_mode == VO_ISR_FIELD_FLAG_BOTTOM) ||
|
||||
(int_mode == VO_ISR_FIELD_FLAG_TOP_BOTTOM)) {
|
||||
frame_mode = XMEDIA_TRUE;
|
||||
} else {
|
||||
frame_mode = XMEDIA_FALSE;
|
||||
}
|
||||
hal_vo_set_intf_vtt_mode(dev, vtt_id, frame_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_thd(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_u32 thd)
|
||||
{
|
||||
//设置中断有效区计数
|
||||
hal_vo_set_intf_vtt_sel(dev, vtt_id, 1);
|
||||
hal_vo_set_intf_vtt_thd(dev, vtt_id, thd);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_state(xmedia_vo_dev dev, xmedia_bool *btm, xmedia_u16 *vcnt, xmedia_u8 *vstate)
|
||||
{
|
||||
hal_vo_get_intf_state(dev, btm, vcnt, vstate);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_mixer_prio(xmedia_vo_dev dev, vo_mix_prio prio_id)
|
||||
{
|
||||
//不支持图形视频调层
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_bgcolor(xmedia_vo_dev dev, xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_cbm_bgcolor(dev, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_bgcolor(xmedia_vo_dev dev, xmedia_u32 *bgcolor)
|
||||
{
|
||||
xmedia_u32 color;
|
||||
hal_vo_get_cbm_bgcolor(dev, &color);
|
||||
*bgcolor = color;
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_csc_en(xmedia_vo_dev dev, xmedia_bool csc_en)
|
||||
{
|
||||
//接口csc删除
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_csc_en(xmedia_vo_dev dev, xmedia_bool *csc_en)
|
||||
{
|
||||
//接口csc删除
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_dev_csc_coef(xmedia_vo_dev dev, vo_pic_info* pic_info)
|
||||
{
|
||||
//接口csc删除
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
/*以下关于特殊时序计算均参考 “VOUT_MIPI 时序配置说明.excel”,
|
||||
*以下计算得到的值都是非-1 计算,而excel中的寄存器值都是-1运算
|
||||
*/
|
||||
static xmedia_void hal_vo_calc_special_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing)
|
||||
{
|
||||
xmedia_s32 cycle_n = 0;
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
vo_intf_special_timing * special_timing = &hal_ctx->special_timing[dev];
|
||||
xmedia_u32 fixed_clock_hz;
|
||||
|
||||
switch(intf_config->intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
//cycle_n表示单个像素时钟倍数,lcd串行配置为3,并行为1,bt656并行yuv为2
|
||||
cycle_n = hal_vo_get_cyc_pre_pixel(intf_config);
|
||||
if (hal_vo_get_intf_clock(&hal_ctx->clock_config, dev, &fixed_clock_hz) != XMEDIA_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
/* =INT(1/I4/(I9+I10+I11+I12)/(1/(I26/I23)/10^6))
|
||||
* (1/(frame_rate * (vbb + vfb + vact))) / (1/((fixed_clock_Mz/cycle_n) * 10^6))
|
||||
* ((fixed_clock_Mz/cycle_n) * 10^6) / (frame_rate * (vbb + vfb + vact))
|
||||
* (fixed_clock_hz/cycle_n) / (frame_rate * (vbb + vfb + vact))
|
||||
*/
|
||||
special_timing->fixed_clk_htotal = (fixed_clock_hz / cycle_n) / (frame_rate * (sync_timing->vbb +
|
||||
sync_timing->vfb + sync_timing->vact));
|
||||
/* (I27-I31-1)/2-1
|
||||
* (special_timing->fixed_clk_htotal - sync_timing->hact) / 2
|
||||
* 表格运算会出现小数,和逻辑沟通,向下取整忽略小数部分
|
||||
*/
|
||||
special_timing->fixed_clk_hbb = (special_timing->fixed_clk_htotal - sync_timing->hact) / 2;
|
||||
/* I27-(I31+1)-(I29+1)-1
|
||||
* fixed_clk_hfb - hact - hbb
|
||||
*/
|
||||
special_timing->fixed_clk_hfb = special_timing->fixed_clk_htotal - sync_timing->hact -
|
||||
special_timing->fixed_clk_hbb;
|
||||
|
||||
special_timing->vs_st_v_filed = sync_timing->vfb;
|
||||
special_timing->vs_end_v_filed = special_timing->vs_st_v_filed + sync_timing->vpw;
|
||||
VO_TRACE(MODULE_DBG_DEBUG,
|
||||
"fixed_clk_htotal %d fixed_clock_hz %d fixed_clk_hbb %d fixed_clk_hfb %d\n",
|
||||
special_timing->fixed_clk_htotal, fixed_clock_hz,
|
||||
special_timing->fixed_clk_hbb, special_timing->fixed_clk_hfb);
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "vs_st_v_filed %d vs_end_v_filed %d\n",
|
||||
special_timing->vs_st_v_filed, special_timing->vs_end_v_filed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing)
|
||||
{
|
||||
|
||||
vo_hal_context *hal_ctx = hal_vo_get_hal_context();
|
||||
#ifdef VO_KERNEL
|
||||
ddr_ost_info ost_value;
|
||||
#endif
|
||||
hal_vo_set_intf_cnt_pos(dev);
|
||||
|
||||
if (hal_ctx->special_timing[dev].vo_special_timing_sel) {
|
||||
hal_vo_calc_special_timing(dev, frame_rate, intf_config, sync_timing);
|
||||
}
|
||||
hal_vo_set_intf_timing(dev, frame_rate, intf_config, sync_timing, &hal_ctx->special_timing[dev]);
|
||||
hal_vo_set_intf_fifo(dev, VO_FIFO_DEPTH);
|
||||
#ifdef VO_KERNEL
|
||||
drv_ddr_get_ost(XMEDIA_MOD_ID_VO, &ost_value);
|
||||
if (ost_value.rd_ost >= VO_DEFAULT_OST_VALUE) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev %d rd_ost error! ost_value.rd_ost %d use default value %d\n", dev,
|
||||
ost_value.rd_ost, VO_DEFAULT_OST_VALUE);
|
||||
ost_value.rd_ost = VO_DEFAULT_OST_VALUE;
|
||||
}
|
||||
#endif
|
||||
#ifdef VO_BOOT
|
||||
hal_vo_set_dma_standing(dev, 8);
|
||||
#endif
|
||||
switch(intf_config->intf_type){
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
hal_vo_set_bt656_intf_cfg(dev, &(intf_config->bt656_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
hal_vo_set_bt1120_intf_cfg(dev, &(intf_config->bt1120_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
hal_vo_set_lcd_intf_cfg(dev, &(intf_config->lcd_attr));
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
hal_vo_set_mcu_intf_cfg(dev, &(intf_config->mcu_attr));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//intf 时钟相关绑定及门控 在前级set crg中做了
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
xmedia_void hal_vo_set_dev_intf_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_intf_enable(dev, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_dev_intf_enable(xmedia_vo_dev dev, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_intf_enable(dev, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_enable(layer,enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_bg_color(xmedia_vo_layer layer, xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_bgcolor(layer, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_mute_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mute_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_csc_en(xmedia_vo_layer layer, xmedia_bool csc_en)
|
||||
{
|
||||
hal_vo_set_csc_en(layer, csc_en);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_set_layer_csc_coef(xmedia_vo_layer layer, vo_pic_info* pic_info)
|
||||
{
|
||||
vo_csc_coef csc_matrix;
|
||||
hal_vo_set_alpha(layer, 0xFF);
|
||||
if (hal_vo_csc_coef_convert(pic_info, &csc_matrix) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
//vo输入肯定是yuv数据
|
||||
hal_vo_set_csc_mode(layer, XMEDIA_TRUE);
|
||||
//hal_vo_get_multi_enable(layer, &multi_en);
|
||||
//不需要再指定 单区域 或者 多区域模式
|
||||
hal_vo_set_mrg0_csc(layer, &csc_matrix);
|
||||
hal_vo_set_mrg1_csc(layer, &csc_matrix);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_disp_rect(xmedia_vo_layer layer, xmedia_video_rect *disp_rect)
|
||||
{
|
||||
hal_vo_set_disp_rect(layer, disp_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_disp_rect(xmedia_vo_layer layer, xmedia_video_rect *disp_rect)
|
||||
{
|
||||
hal_vo_get_disp_rect(layer, disp_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
//单区域模式 设定真实内容相对于层的rect
|
||||
xmedia_void hal_vo_set_layer_reso_rect(xmedia_vo_layer layer, xmedia_video_rect *reso_rect)
|
||||
{
|
||||
hal_vo_set_src_rect(layer, reso_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_reso_rect(xmedia_vo_layer layer, xmedia_video_rect *reso_rect)
|
||||
{
|
||||
hal_vo_get_src_rect(layer, reso_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_cus(xmedia_vo_layer layer, vo_video_cus *cus)
|
||||
{
|
||||
if (layer == XMEDIA_VO_LAYER_V0) {
|
||||
hal_reg_vout_set_cfg_vcus_coef_0(g_p_vout_reg, cus->vcus_coef0);
|
||||
hal_reg_vout_set_cfg_vcus_coef_1(g_p_vout_reg, cus->vcus_coef1);
|
||||
hal_reg_vout_set_cfg_hcus_coef_0(g_p_vout_reg, cus->hcus_coef0);
|
||||
hal_reg_vout_set_cfg_hcus_coef_1(g_p_vout_reg, cus->hcus_coef1);
|
||||
} else if (layer == XMEDIA_VO_LAYER_V1) {
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_pixel_format(xmedia_vo_layer layer, xmedia_video_pixel_format pix_format)
|
||||
{
|
||||
vo_pixel_format format = VO_PIXEL_FMT_YUV_420;
|
||||
xmedia_bool uv_order = 0;
|
||||
vo_video_cus cus;
|
||||
cus.vcus_coef0 = 0x3f;
|
||||
cus.hcus_coef0 = 0x3f;
|
||||
cus.vcus_coef1 = 1;
|
||||
cus.hcus_coef1 = 1;
|
||||
hal_vo_set_cus(layer, &cus);
|
||||
|
||||
//注意下逻辑的排序与应用理解的UV是方向的
|
||||
if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 1;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 0;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) {
|
||||
format = VO_PIXEL_FMT_YUV_422;
|
||||
uv_order = 1;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) {
|
||||
format = VO_PIXEL_FMT_YUV_422;
|
||||
uv_order = 0;
|
||||
} else if (pix_format == XMEDIA_VIDEO_PIXEL_FMT_YUV_400) {
|
||||
format = VO_PIXEL_FMT_YUV_400;
|
||||
uv_order = 0;
|
||||
} else {
|
||||
format = VO_PIXEL_FMT_YUV_420;
|
||||
uv_order = 1;
|
||||
}
|
||||
hal_vo_set_src_pixel_format(layer, format, uv_order);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//单区域和多区域控制
|
||||
xmedia_void hal_vo_set_layer_multi_enable(xmedia_vo_layer layer, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_multi_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_multi_enable(xmedia_vo_layer layer, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_multi_enable(layer, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_layer_region_enable(xmedia_vo_layer layer, xmedia_u32 region_id, xmedia_bool *enable)
|
||||
{
|
||||
hal_vo_get_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_mrg_enable(xmedia_vo_layer layer, xmedia_u32 region_id,
|
||||
xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_mrg_enable(layer, region_id, enable);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_region_mute_color(xmedia_vo_layer layer, xmedia_u32 region_id,
|
||||
xmedia_u32 bgcolor)
|
||||
{
|
||||
hal_vo_set_mrg_mute_color(layer, region_id, bgcolor);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_single_region_cfg(xmedia_vo_layer layer, vo_layer_single_cfg *single_cfg)
|
||||
{
|
||||
//真实内容 相对于显示窗口的rect
|
||||
hal_vo_set_src_rect(layer, &(single_cfg->frame_rect));
|
||||
hal_vo_set_mute_enable(layer, single_cfg->mute_en);
|
||||
|
||||
//逻辑不分单区域和多区域模式,单区域即只配置一个0显示区域即可
|
||||
hal_vo_set_mrg_enable(layer, 0, !(single_cfg->mute_en));
|
||||
hal_vo_set_mrg_src_rect(layer,0, &(single_cfg->video_rect));
|
||||
//LBA
|
||||
hal_vo_set_lba_color(layer, 0, single_cfg->lba_color);
|
||||
hal_vo_set_lba_rect(layer, 0, &(single_cfg->lba_rect));
|
||||
|
||||
hal_vo_set_mrg_addr(layer,0, &(single_cfg->frame_addr));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_multi_region_cfg(xmedia_vo_layer layer, vo_layer_multi_cfg *multi_cfg)
|
||||
{
|
||||
xmedia_u32 id;
|
||||
id = multi_cfg->region_id;
|
||||
hal_vo_set_mrg_enable(layer, id, multi_cfg->region[id].enable);
|
||||
hal_vo_set_mrg_src_rect(layer,id, &(multi_cfg->region[id].src_rect));
|
||||
hal_vo_set_mrg_addr(layer,id, &(multi_cfg->region[id].region_addr));
|
||||
|
||||
hal_vo_set_lba_color(layer, id, multi_cfg->region[id].lba_color);
|
||||
hal_vo_set_lba_rect(layer, id, &(multi_cfg->region[id].lba_rect));
|
||||
|
||||
hal_vo_set_mrg_mixer_prio(layer, VO_MRG_MIX_PRIO_RDMA0);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_dev_debug_pattern(xmedia_vo_dev dev, vo_pattern_info *pattern_info)
|
||||
{
|
||||
hal_vo_set_intf_mute_enable(dev, pattern_info->pattern_en);
|
||||
hal_vo_set_intf_mute_pattern_mode(dev, pattern_info->pattern_mode);
|
||||
hal_vo_set_intf_mute_data_mode(dev, pattern_info->data_mode);
|
||||
hal_vo_set_intf_mute_color(dev, pattern_info->color, pattern_info->color);
|
||||
hal_vo_set_intf_cbar_sel(dev, pattern_info->rgb);
|
||||
if (pattern_info->pattern_mode == VO_PATTERN_MODE_CHECKER) {
|
||||
hal_vo_set_intf_checkbar_size(dev, pattern_info->width, pattern_info->height);
|
||||
//重复????
|
||||
hal_vo_set_intf_mute_color(dev, pattern_info->color, !(pattern_info->color));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_layer_debug_pattern(xmedia_vo_layer layer, vo_pattern_info *pattern_info)
|
||||
{
|
||||
vo_pattern_mode mode = VO_PATTERN_MODE_FULLCOLOR;
|
||||
|
||||
mode = pattern_info->pattern_mode;
|
||||
if ((mode != VO_PATTERN_MODE_FULLCOLOR) && (mode != VO_PATTERN_MODE_CHECKER)) {
|
||||
mode = VO_PATTERN_MODE_FULLCOLOR;
|
||||
}
|
||||
hal_vo_set_mute_enable(layer, pattern_info->pattern_en);
|
||||
hal_vo_set_mute_pattern_mode(layer, pattern_info->pattern_mode);
|
||||
hal_vo_set_mute_data_mode(layer, pattern_info->data_mode);
|
||||
hal_vo_set_mute_color(layer, pattern_info->color);
|
||||
if (mode == VO_PATTERN_MODE_CHECKER) {
|
||||
hal_vo_set_checkbar_size(layer, pattern_info->width, pattern_info->height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_debug_ink(xmedia_vo_dev dev, vo_csc_ink_info *ink_info)
|
||||
{
|
||||
hal_vo_set_intf_ink(dev, ink_info);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_debug_checksum(xmedia_vo_dev dev, xmedia_u32 *y, xmedia_u32 *u, xmedia_u32 *v)
|
||||
{
|
||||
hal_vo_get_intf_checksum_value(dev, y, u, v);
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_enable_dev_phy_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_u32 frame_rate,
|
||||
xmedia_vo_user_sync_timing *sync_timing, xmedia_intf_type intf_type)
|
||||
{
|
||||
switch(intf_type){
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_disable_dev_phy_cfg(xmedia_intf_type intf_type)
|
||||
{
|
||||
switch(intf_type){
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
//todo????
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_s32 vo_calc_dev_phy_clk_cfg(xmedia_vo_dev dev, xmedia_u32 clk_hz, xmedia_vo_intf_config *intf_config)
|
||||
{
|
||||
xmedia_s32 ret = XMEDIA_SUCCESS;
|
||||
switch(intf_config->intf_type){
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#ifdef VO_KERNEL
|
||||
xmedia_void hal_vo_set_gamma_addr(xmedia_vo_dev dev)
|
||||
{
|
||||
hal_vo_gamma_set_addr(dev, g_vo_gamma_buf[dev].gamma_phy_addr);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_gamma_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
hal_vo_gamma_enable(dev, enable);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_gamma_table(xmedia_vo_dev dev, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
hal_vo_gamma_set_table(dev, g_vo_gamma_buf[dev].gamma_virtual_addr, g_vo_gamma_buf[dev].gamma_mem_len, gamma_table);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_gamma_table(xmedia_vo_dev dev, xmedia_vo_gamma_table *gamma_table)
|
||||
{
|
||||
hal_vo_gamma_get_table(dev, g_vo_gamma_buf[dev].gamma_virtual_addr, g_vo_gamma_buf[dev].gamma_mem_len, gamma_table);
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_reg_record(xmedia_void)
|
||||
{
|
||||
xmedia_u32 idx, section_num;
|
||||
xmedia_ulong offset = 0;
|
||||
xmedia_u32 malloc_size = 0;
|
||||
|
||||
section_num = sizeof(g_vo_reg_offset) / sizeof(xmedia_ulong) / VO_OFFSET_ELE_NUM;
|
||||
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
malloc_size += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
|
||||
if (g_vo_reg_record != XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"g_vo_reg_record is not null,please check!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
} else {
|
||||
g_vo_reg_record = (xmedia_u8 *)osal_kmalloc(malloc_size, osal_gfp_kernel);
|
||||
}
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
osal_memcpy((xmedia_void *)((xmedia_uintptr_t)g_vo_reg_record + offset),
|
||||
(xmedia_void *)((xmedia_uintptr_t)g_p_vout_reg + g_vo_reg_offset[idx][0]), g_vo_reg_offset[idx][1]);
|
||||
offset += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_reg_restore(xmedia_void)
|
||||
{
|
||||
xmedia_u32 idx;
|
||||
xmedia_u32 section_num;
|
||||
xmedia_ulong offset = 0;
|
||||
|
||||
if (g_vo_reg_record == XMEDIA_NULL) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"g_vo_reg_record is null,please check!\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
section_num = sizeof(g_vo_reg_offset) / sizeof(xmedia_ulong) / VO_OFFSET_ELE_NUM;
|
||||
|
||||
for (idx = 0; idx < section_num; idx++) {
|
||||
osal_memcpy((xmedia_void *)(xmedia_uintptr_t)((xmedia_ulong)(xmedia_uintptr_t)g_p_vout_reg + g_vo_reg_offset[idx][0]),
|
||||
(xmedia_void *)(xmedia_uintptr_t)((xmedia_ulong)(xmedia_uintptr_t)g_vo_reg_record + offset),
|
||||
g_vo_reg_offset[idx][1]);
|
||||
offset += g_vo_reg_offset[idx][1];
|
||||
}
|
||||
osal_kfree(g_vo_reg_record);
|
||||
g_vo_reg_record = XMEDIA_NULL;
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
*乘以2是因为mcu采用的时钟2倍频方案,也就是一个clk_vo 传输一个mcu scl,
|
||||
*具体mcu cyc_pre_pixel参考逻辑提供的 “时钟频点计算表格.xlsx”
|
||||
*/
|
||||
static xmedia_u32 vo_get_mcu_intf_cyc_pre_pixel(xmedia_intf_mcu_data_type data_type)
|
||||
{
|
||||
switch (data_type) {
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_8BIT_16BPP_RGB565_8080I:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_8BIT_18BPP_RGB666_8080I:
|
||||
return 6;//3 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_8BIT_16BPP_RGB565_8080II:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_8BIT_18BPP_RGB666_8080II:
|
||||
return 6;//3 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_16BPP_RGB565_8080I:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080I_OPTION1:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080I_OPTION2:
|
||||
return 6;//3 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_16BPP_RGB565_8080II:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080II_OPTION1:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080II_OPTION2:
|
||||
return 6;//3 * 2
|
||||
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_16BPP_RGB565_8080I:
|
||||
return 2;//1 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION1:
|
||||
return 3;//1.5 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION2:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION3:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION4:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION5:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_16BPP_RGB565_8080II:
|
||||
return 2;//1 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION1:
|
||||
return 3;//1.5 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION2:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION3:
|
||||
return 4;//2 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION4:
|
||||
return 4;//2 *2
|
||||
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_18BIT_16BPP_RGB565_8080I:
|
||||
return 2;//1 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_18BIT_18BPP_RGB666_8080I:
|
||||
return 2;//1 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_18BIT_16BPP_RGB565_8080II:
|
||||
return 2;//1 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_18BIT_18BPP_RGB666_8080II:
|
||||
return 2;//1 * 2
|
||||
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB565_OPTION1:
|
||||
return 36;//18 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB666_OPTION1:
|
||||
return 54;//27 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB565_OPTION2:
|
||||
return 64;//32 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB666_OPTION2:
|
||||
return 96;//48 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_4LINE_RGB565:
|
||||
return 32;//16 * 2
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_4LINE_RGB666:
|
||||
return 48;//24 * 2
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vo_get_cyc_pre_pixel(xmedia_vo_intf_config *intf_config)
|
||||
{
|
||||
switch (intf_config->intf_type) {
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
return 2;
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
return 1;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
if (intf_config->lcd_attr.data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) {
|
||||
return 3;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
return vo_get_mcu_intf_cyc_pre_pixel(intf_config->mcu_attr.data_type);
|
||||
default:
|
||||
VO_TRACE(MODULE_DBG_ERR,"vo_get_cyc_pre_pixel error,please check!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_get_dma_busy_state(xmedia_void)
|
||||
{
|
||||
return hal_vo_disp_get_dma_busy_state();
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_underflow_clr(xmedia_bool enable)
|
||||
{
|
||||
hal_reg_vout_set_cfg_intf_underflow_clr(g_p_vout_reg, enable);
|
||||
hal_vo_clear_lowband_state(enable);
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_do_low_band(xmedia_bool enable)
|
||||
{
|
||||
hal_vo_set_clock_gate_enable(enable);
|
||||
hal_reg_vout_set_cfg_para_0_update(g_p_vout_reg, enable);
|
||||
hal_reg_vout_set_cfg_para_2_update(g_p_vout_reg, enable);
|
||||
hal_vo_set_top_regup_enable(XMEDIA_TRUE);
|
||||
}
|
||||
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo_chip_cfg.h"
|
||||
#ifdef VO_KERNEL
|
||||
#include "comm_version.h"
|
||||
#endif
|
||||
#define VO_IRQ_NAME "intr_vo"
|
||||
#define VO_INTF_NOT_MIPI_MAX_WHIDTH 1920
|
||||
#define VO_INTF_NOT_MCU_MAX_CLK 74250000
|
||||
#define VO_INTF_MCU_MAX_CLK 148500000
|
||||
#define VO_IRQ_NUM_7606V1 47
|
||||
|
||||
xmedia_s32 g_vo_irq = VO_IRQ_NUM_7606V1;
|
||||
|
||||
static vo_base_cap g_vo_cap;
|
||||
static vo_layer_cap g_layer_capability[XMEDIA_VO_LAYER_MAX];
|
||||
static vo_dev_cap g_dev_capability[XMEDIA_VO_DEV_MAX];
|
||||
|
||||
static xmedia_void vo_init_chip_capacity(xmedia_void)
|
||||
{
|
||||
g_vo_cap.irq_name = VO_IRQ_NAME;
|
||||
g_vo_cap.irq_num = g_vo_irq;
|
||||
g_vo_cap.irq_cpumask = 0;
|
||||
g_vo_cap.chip_name = "xm7606v1";
|
||||
g_vo_cap.chip_revision = 0;
|
||||
g_vo_cap.chip_type = 0;
|
||||
g_vo_cap.board_id =0;
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_void vo_init_chip_dev_capacity(xmedia_void)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < XMEDIA_VO_DEV_MAX; i++) {
|
||||
g_dev_capability[i].support = XMEDIA_TRUE;
|
||||
g_dev_capability[i].support_video_layer_num = 1;
|
||||
g_dev_capability[i].support_gfx_layer_num = 1;
|
||||
g_dev_capability[i].support_max_layer_num = 2;
|
||||
g_dev_capability[i].support_intf_num = 1;
|
||||
g_dev_capability[i].support_csc_num = 3;
|
||||
g_dev_capability[i].max_size.width = 1920;
|
||||
g_dev_capability[i].max_size.height = 1080;
|
||||
g_dev_capability[i].max_frame_rate = 60;
|
||||
g_dev_capability[i].support_ink = XMEDIA_TRUE;
|
||||
g_dev_capability[i].support_attach_layer = XMEDIA_FALSE;
|
||||
if (VO_CHECK_VAILD_DEV(i) == XMEDIA_FALSE) {
|
||||
g_dev_capability[i].support = XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_void vo_init_chip_layer_capacity(xmedia_void)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < XMEDIA_VO_LAYER_MAX; i++) {
|
||||
g_layer_capability[i].support = XMEDIA_TRUE;
|
||||
g_layer_capability[i].support_hdr = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_flip = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_mirror = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_zme = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_dcmp = XMEDIA_FALSE;
|
||||
g_layer_capability[i].support_region = XMEDIA_TRUE;
|
||||
g_layer_capability[i].region_num = 2;
|
||||
g_layer_capability[i].max_read_size.width = 1920;
|
||||
g_layer_capability[i].max_read_size.height = 1080;
|
||||
g_layer_capability[i].min_out_size.width = 32;
|
||||
g_layer_capability[i].min_out_size.height = 32;
|
||||
g_layer_capability[i].support_max_bit_width = 8;
|
||||
g_layer_capability[i].support_pixformat_num = 5;
|
||||
if (VO_CHECK_VAILD_LAYER(i) == XMEDIA_FALSE) {
|
||||
g_layer_capability[i].support = XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_bt656_attr(xmedia_vo_dev dev, xmedia_vo_bt656_attr *bt656_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
if (bt656_attr->data_type != XMEDIA_INTF_BT_DATA_TYPE_YUV422_8BIT) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf not support data_type(%d) !\n", dev, bt656_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_UYVY) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_VYUY) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_YUYV) &&
|
||||
(bt656_attr->data_seq != XMEDIA_INTF_BT601_BT656_DATA_SEQ_YVYU)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf not support data_seq(%d) !\n", dev, bt656_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (intf_sync != XMEDIA_VO_INTF_SYNC_USER) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt656 intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_bt1120_attr(xmedia_vo_dev dev, xmedia_vo_bt1120_attr *bt1120_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
if (bt1120_attr->data_type != XMEDIA_INTF_BT_DATA_TYPE_YUV422_8BIT) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf not support data_type(%d) !\n", dev, bt1120_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((bt1120_attr->data_seq != XMEDIA_INTF_BT1120_DATA_SEQ_UVUV) &&
|
||||
(bt1120_attr->data_seq != XMEDIA_INTF_BT1120_DATA_SEQ_VUVU)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf not support data_seq(%d) !\n", dev, bt1120_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) && (intf_sync != XMEDIA_VO_INTF_SYNC_720P50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_720P60) && (intf_sync != XMEDIA_VO_INTF_SYNC_576P50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_480P60)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d bt1120 intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_lcd_sync(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
xmedia_intf_lcd_data_type data_type = lcd_attr->data_type;
|
||||
xmedia_vo_lcd_data_mode data_mode = lcd_attr->data_mode;
|
||||
//XMEDIA_VO_INTF_SYNC_USER lcd 用户自定义时序 是否会有问题????
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_320x240_50) && (intf_sync != XMEDIA_VO_INTF_SYNC_240x320_50) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 6bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_320x240_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 8bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB565_16BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 16bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 18bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA) && (data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_240x320_60) && (intf_sync != XMEDIA_VO_INTF_SYNC_640x480_60) &&
|
||||
(intf_sync != XMEDIA_VO_INTF_SYNC_800x480_50) && (intf_sync != XMEDIA_VO_INTF_SYNC_USER)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"For LCD 24bit intface,dev %d intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_lcd_attr(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
xmedia_intf_lcd_data_type data_type = lcd_attr->data_type;
|
||||
xmedia_vo_lcd_data_mode data_mode = lcd_attr->data_mode;
|
||||
|
||||
if ((data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB565_16BIT) && (data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT) &&
|
||||
(data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_type(%d) !\n", dev, data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((data_mode != XMEDIA_VO_LCD_DATA_MODE_SERIAL) && (data_mode != XMEDIA_VO_LCD_DATA_MODE_PARA)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_mode(%d) !\n", dev, data_mode);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_RGB) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_RBG) &&
|
||||
(lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_GRB) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_GBR) &&
|
||||
(lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_BRG) && (lcd_attr->data_seq != XMEDIA_INTF_LCD_DATA_SEQ_BGR)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf not support data_seq(%d) !\n", dev, lcd_attr->data_seq);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (data_mode == XMEDIA_VO_LCD_DATA_MODE_SERIAL) {
|
||||
if ((data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT) && (data_type != XMEDIA_INTF_LCD_DATA_TYPE_RGB888_24BIT)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd intf support 18&24 bit in serial mode(%d) !\n", dev, data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
return vo_check_lcd_sync(dev, lcd_attr, intf_sync);
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_mcu_attr(xmedia_vo_dev dev, xmedia_vo_mcu_attr *lcd_attr,
|
||||
xmedia_vo_intf_sync intf_sync)
|
||||
{
|
||||
if ((lcd_attr->te_mode_en != XMEDIA_TRUE) && (lcd_attr->te_mode_en != XMEDIA_FALSE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd attr te_mode_en not support (%d) !\n", dev, lcd_attr->te_mode_en);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((lcd_attr->data_type < XMEDIA_VO_MCU_DATA_TYPE_8BIT_16BPP_RGB565_8080I) ||
|
||||
(lcd_attr->data_type > XMEDIA_VO_MCU_DATA_TYPE_4LINE_RGB666)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d lcd attr data_type not support (%d) !\n", dev, lcd_attr->data_type);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((intf_sync != XMEDIA_VO_INTF_SYNC_USER) && (intf_sync != XMEDIA_VO_INTF_SYNC_320x240_60)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d mcu intf, intfsync %d illegal!\n", dev, intf_sync);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_check_dev_size(xmedia_vo_dev dev, xmedia_intf_type intf_type,
|
||||
xmedia_video_size *dev_size) {
|
||||
if (VO_CHECK_VIRT_DEV(dev) == XMEDIA_TRUE) {
|
||||
if (dev_size->width > g_dev_capability[dev].max_size.width ||
|
||||
dev_size->height > g_dev_capability[dev].max_size.height) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev%d not support dev_size_width %d\n", dev, dev_size->width);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
} else {
|
||||
if (dev_size->width > g_dev_capability[dev].max_size.width) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "dev%d not support dev_size_width %d\n", dev, dev_size->width);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
//只有mipi支持 width>1920以上时序
|
||||
if ((dev_size->width > VO_INTF_NOT_MIPI_MAX_WHIDTH) && (intf_type != XMEDIA_INTF_TYPE_MIPI_DSI)) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "only mipi width support 1920+\n");
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_intf(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_video_size *dev_size)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
if (vo_check_dev_size(dev, config->intf_config.intf_type, dev_size) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
//虚拟设备不需要后续的check
|
||||
if (VO_CHECK_VIRT_DEV(dev) == XMEDIA_TRUE) {
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
switch (config->intf_config.intf_type){
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
ret = vo_check_bt656_attr(dev, &(config->intf_config.bt656_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
ret = vo_check_bt1120_attr(dev, &(config->intf_config.bt1120_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
ret = vo_check_lcd_attr(dev, &(config->intf_config.lcd_attr), config->intf_sync);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
ret = vo_check_mcu_attr(dev, &(config->intf_config.mcu_attr), config->intf_sync);
|
||||
break;
|
||||
default:
|
||||
ret = XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_clk(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_u32 clk)
|
||||
{
|
||||
//MCU端子为了支持spi mcu跑到320x240 p30 放开到148.5
|
||||
if (config->intf_config.intf_type == XMEDIA_INTF_TYPE_MCU) {
|
||||
if (clk > VO_INTF_MCU_MAX_CLK) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hal_vo_check_clk err, clk %d\n", clk);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
} else {
|
||||
if (clk > VO_INTF_NOT_MCU_MAX_CLK) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"hal_vo_check_clk err, clk %d\n", clk);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_csc_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config,
|
||||
xmedia_vo_dev_csc *dev_csc)
|
||||
{
|
||||
xmedia_bool mipi_rgb_en;
|
||||
|
||||
if (dev_csc->color_info.color_gamut == XMEDIA_VIDEO_COLOR_GAMUT_BT2020) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) color gamut should be bt601 or 709\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (((intf_config->intf_type == XMEDIA_INTF_TYPE_LCD) || (intf_config->intf_type == XMEDIA_INTF_TYPE_LVDS) ||
|
||||
(intf_config->intf_type == XMEDIA_INTF_TYPE_MCU)) &&
|
||||
(dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_YUV)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) lcd/lvds should be output rgb\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (((intf_config->intf_type == XMEDIA_INTF_TYPE_BT656) || (intf_config->intf_type == XMEDIA_INTF_TYPE_BT1120)) &&
|
||||
(dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_RGB)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Vo dev(%d) bt656/bt1120 should be output yuv\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (intf_config->intf_type == XMEDIA_INTF_TYPE_MIPI_DSI) {
|
||||
if ((intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB666_18BIT) ||
|
||||
(intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_RGB888_24BIT)){
|
||||
mipi_rgb_en = XMEDIA_TRUE;
|
||||
} else {
|
||||
mipi_rgb_en = XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
if ((mipi_rgb_en == XMEDIA_TRUE) && (dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_YUV)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d color space should be same as mipi output(%d,%d)\n",
|
||||
dev, mipi_rgb_en, dev_csc->color_info.color_space);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if ((mipi_rgb_en == XMEDIA_FALSE) && (dev_csc->color_info.color_space == XMEDIA_VIDEO_COLOR_SPACE_RGB)){
|
||||
VO_TRACE(MODULE_DBG_ERR,"dev %d color space should be same as mipi output(%d,%d)\n",
|
||||
dev, mipi_rgb_en, dev_csc->color_info.color_space);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_dev_gamma_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config)
|
||||
{
|
||||
if ((intf_config->intf_type == XMEDIA_INTF_TYPE_BT656) || (intf_config->intf_type == XMEDIA_INTF_TYPE_BT1120)) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG,"Vo dev(%d) yuv output not support gamma set\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
if ((intf_config->intf_type == XMEDIA_INTF_TYPE_MIPI_DSI) &&
|
||||
(intf_config->mipi_attr.data_type == XMEDIA_INTF_MIPI_DSI_DATA_TYPE_YUV422_16BIT)) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG,"Vo dev(%d) yuv output not support gamma set\n", dev);
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_bool hal_vo_check_chip_type(vo_chip_type board_id)
|
||||
{
|
||||
if (board_id == VO_CHIP_TYPE_XM7606V1) {
|
||||
return XMEDIA_TRUE;
|
||||
} else {
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_layer_cap(xmedia_vo_layer layer, xmedia_u32 max_width, xmedia_u32 max_height,
|
||||
xmedia_vo_layer_config *layer_config)
|
||||
{
|
||||
if ((layer_config->img_size.width < g_layer_capability[layer].min_out_size.width) ||
|
||||
(layer_config->img_size.height < g_layer_capability[layer].min_out_size.height)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d image size(%d, %d) is illegaled, should biger than (%d,%d)!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height,
|
||||
g_layer_capability[layer].min_out_size.width, g_layer_capability[layer].min_out_size.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (layer_config->img_size.width > max_width || layer_config->img_size.height > max_height) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d image size width(%d %d) is illegaled, should less than(%d %d)!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height, max_width, max_height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((IS_ALIGN(layer_config->img_size.width, 2) != XMEDIA_TRUE) ||
|
||||
(IS_ALIGN(layer_config->img_size.height, 2) != XMEDIA_TRUE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d img size(%d, %d) dosen't aligned by 2 pixel!\n",
|
||||
layer, layer_config->img_size.width, layer_config->img_size.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) &&
|
||||
(layer_config->pix_format != XMEDIA_VIDEO_PIXEL_FMT_YUV_400)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d pix_format %d doesn't support!\n", layer, layer_config->pix_format);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
if (layer_config->bit_width != XMEDIA_VIDEO_DATA_WIDTH_8) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d bit_width %d doesn't support!\n", layer, layer_config->bit_width);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
if (layer_config->part_mode >= XMEDIA_VO_PARTITION_MODE_MAX) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"layer %d part mode %d is illegal!\n", layer, layer_config->part_mode);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vo_check_layer_frame(xmedia_vo_layer layer, xmedia_video_frame_info *frame_info)
|
||||
{
|
||||
xmedia_u32 valid_width;
|
||||
xmedia_u32 valid_height;
|
||||
|
||||
valid_width = g_layer_capability[layer].min_out_size.width;
|
||||
valid_height = g_layer_capability[layer].min_out_size.height;
|
||||
if ((frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_422) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_422) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_SEMIPLANAR_420) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420) &&
|
||||
(frame_info->frame.pixel_fmt != XMEDIA_VIDEO_PIXEL_FMT_YUV_400)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input pixel format %d!\n", frame_info->frame.pixel_fmt);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((frame_info->frame.width < valid_width) || (frame_info->frame.height < valid_height) ||
|
||||
(IS_ALIGN(frame_info->frame.width, 2) != XMEDIA_TRUE) ||
|
||||
(IS_ALIGN(frame_info->frame.width, 2) != XMEDIA_TRUE)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"pic width(%d) is smaller than min width 32 or pic height(%d) is smaller than"
|
||||
"min height 32 or not align2!!\n", frame_info->frame.width, frame_info->frame.height);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.dynamic_range != XMEDIA_VIDEO_DYNAMIC_RANGE_SDR) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input dynamic range%d!\n", frame_info->frame.dynamic_range);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.compress_mode != XMEDIA_VIDEO_COMPRESS_MODE_NONE) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input compress mode%d!\n", frame_info->frame.compress_mode);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((frame_info->frame.video_fmt != XMEDIA_VIDEO_FMT_LINEAR) &&
|
||||
(frame_info->frame.video_fmt != XMEDIA_VIDEO_FMT_TILE_32x4) &&
|
||||
(frame_info->frame.video_fmt != XMEDIA_VIDEO_FMT_TILE_64x4)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input video format%d!\n", frame_info->frame.video_fmt);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (frame_info->frame.bit_width != XMEDIA_VIDEO_DATA_WIDTH_8) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input bit width%d!\n", frame_info->frame.bit_width);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((frame_info->frame.color_info.color_space != XMEDIA_VIDEO_COLOR_SPACE_YUV) ||
|
||||
(frame_info->frame.color_info.color_gamut == XMEDIA_VIDEO_COLOR_GAMUT_BT2020) ||
|
||||
(frame_info->frame.color_info.color_gamut >= XMEDIA_VIDEO_COLOR_GAMUT_MAX) ||
|
||||
(frame_info->frame.color_info.quantify_range >= XMEDIA_VIDEO_COLOR_RANGE_MAX)) {
|
||||
VO_TRACE(MODULE_DBG_ERR,"Unsupport input color info:space-gamut-range(%d-%d-%d)!\n",
|
||||
frame_info->frame.color_info.color_space,
|
||||
frame_info->frame.color_info.color_gamut,frame_info->frame.color_info.quantify_range);
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_init_chip_capaciblity(xmedia_void)
|
||||
{
|
||||
vo_init_chip_capacity();
|
||||
vo_init_chip_dev_capacity();
|
||||
vo_init_chip_layer_capacity();
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vo_get_chip_revision(xmedia_void)
|
||||
{
|
||||
return g_vo_cap.chip_revision;
|
||||
}
|
||||
|
||||
vo_base_cap *hal_vo_get_chip_capacity(xmedia_void)
|
||||
{
|
||||
return &g_vo_cap;
|
||||
}
|
||||
|
||||
vo_layer_cap *hal_get_layer_chip_capacity(xmedia_vo_layer layer)
|
||||
{
|
||||
return &g_layer_capability[layer];
|
||||
}
|
||||
|
||||
vo_dev_cap *hal_get_dev_chip_capacity(xmedia_vo_dev dev)
|
||||
{
|
||||
return &g_dev_capability[dev];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_CHIP_CFG_H__
|
||||
#define __HAL_VO_CHIP_CFG_H__
|
||||
|
||||
#include "drv_vo_comm.h"
|
||||
#ifdef VO_BOOT
|
||||
#include "xmedia_vo.h"
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VO_CHIP_INTF_TYPE_BT656 = 1 << 0,
|
||||
VO_CHIP_INTF_TYPE_BT1120 = 1 << 1,
|
||||
VO_CHIP_INTF_TYPE_LCD = 1 << 2,
|
||||
VO_CHIP_INTF_TYPE_LVDS = 1 << 3,
|
||||
VO_CHIP_INTF_TYPE_MIPI_DSI = 1 << 4,
|
||||
VO_CHIP_INTF_TYPE_MAX
|
||||
} vo_chip_intf_type;
|
||||
|
||||
typedef enum {
|
||||
VO_CHIP_TYPE_XM7606V1,
|
||||
VO_CHIP_TYPE_MAX
|
||||
} vo_chip_type;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool support;
|
||||
xmedia_bool support_hdr;
|
||||
xmedia_bool support_flip;
|
||||
xmedia_bool support_mirror;
|
||||
xmedia_bool support_zme;
|
||||
xmedia_bool support_dcmp;
|
||||
xmedia_bool support_region;
|
||||
xmedia_u32 region_num;
|
||||
xmedia_video_size max_read_size;
|
||||
xmedia_video_size min_out_size;
|
||||
xmedia_u32 support_max_bit_width;
|
||||
xmedia_u32 support_pixformat_num;
|
||||
} vo_layer_cap;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool support;
|
||||
xmedia_u32 support_video_layer_num;
|
||||
xmedia_u32 support_gfx_layer_num;
|
||||
xmedia_u32 support_max_layer_num;
|
||||
xmedia_u32 support_intf_num;
|
||||
xmedia_u32 support_csc_num;
|
||||
xmedia_video_size max_size;
|
||||
xmedia_bool support_ink;
|
||||
xmedia_bool support_attach_layer;
|
||||
xmedia_u32 max_frame_rate;
|
||||
} vo_dev_cap;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 board_id;
|
||||
xmedia_u32 irq_num;
|
||||
xmedia_u32 irq_cpumask;
|
||||
xmedia_u32 chip_revision;
|
||||
xmedia_u32 chip_type;
|
||||
xmedia_char *chip_name;
|
||||
xmedia_char *irq_name;
|
||||
} vo_base_cap;
|
||||
|
||||
xmedia_bool hal_vo_check_chip_type(vo_chip_type board_id);
|
||||
xmedia_void hal_vo_init_chip_capaciblity(xmedia_void);
|
||||
xmedia_u32 hal_vo_get_chip_revision(xmedia_void);
|
||||
xmedia_s32 hal_vo_check_layer_cap(xmedia_vo_layer layer, xmedia_u32 max_width, xmedia_u32 max_height,
|
||||
xmedia_vo_layer_config *layer_config);
|
||||
xmedia_s32 hal_vo_check_dev_intf(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_video_size *dev_size);
|
||||
xmedia_s32 hal_vo_check_clk(xmedia_vo_dev dev, xmedia_vo_dev_config *config, xmedia_u32 clk);
|
||||
xmedia_s32 hal_vo_check_dev_size(xmedia_vo_dev dev, xmedia_u32 width, xmedia_u32 height);
|
||||
xmedia_s32 hal_vo_check_dev_csc_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config,
|
||||
xmedia_vo_dev_csc *dev_csc);
|
||||
xmedia_s32 hal_vo_check_dev_gamma_cap(xmedia_vo_dev dev, xmedia_vo_intf_config *intf_config);
|
||||
xmedia_s32 hal_vo_check_layer_frame(xmedia_vo_layer layer, xmedia_video_frame_info *frame_info);
|
||||
vo_base_cap *hal_vo_get_chip_capacity(xmedia_void);
|
||||
vo_layer_cap* hal_get_layer_chip_capacity(xmedia_vo_layer layer);
|
||||
vo_dev_cap* hal_get_dev_chip_capacity(xmedia_vo_dev dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HAL_VO__CHIP_CFG_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,976 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hal_vo.h"
|
||||
#include "hal_vo_intf.h"
|
||||
#include "hal_vo_reg.h"
|
||||
#include "hal_vo_clock.h"
|
||||
#ifdef VO_BOOT
|
||||
#include "drv_vo_comm.h"
|
||||
#endif
|
||||
#ifdef VO_KERNEL
|
||||
#include "osal.h"
|
||||
#endif
|
||||
extern s_vout_regs_type *g_p_vout_reg;
|
||||
extern vo_dts_lcd_config g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MAX];
|
||||
#define MCU_CMD_PACKAGE_MAX_SIZE (64 * 4)
|
||||
|
||||
#define VO_REGUP_POS_VALUE 1
|
||||
#define VO_PARA_POS_VALUE 2
|
||||
#define VO_PREFETCH_POS_VALUE 3
|
||||
#define VO_START_POS_VALUE 4
|
||||
|
||||
xmedia_void hal_vo_set_intf_fifo(xmedia_vo_dev dev, xmedia_u32 fifo)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_intf_sfifo_thd(g_p_vout_reg, fifo);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_chk_sum_en(g_p_vout_reg, enable);
|
||||
hal_reg_vout_set_cfg_intf_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_intf_enable(xmedia_vo_dev dev, xmedia_bool *enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
*enable = hal_reg_vout_get_cfg_intf_en(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_chk_sum_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_chk_sum_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//for mipi
|
||||
xmedia_void hal_vo_set_intf_hs_mode(xmedia_vo_dev dev, vo_intf_hs_mode hs_mode)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_hs_mode(g_p_vout_reg, hs_mode);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_mux(xmedia_vo_dev dev, xmedia_intf_type intf)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
switch (intf) {
|
||||
case XMEDIA_INTF_TYPE_LCD:
|
||||
hal_reg_vout_set_cfg_intf_sel(g_p_vout_reg, 1);
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_BT656:
|
||||
case XMEDIA_INTF_TYPE_BT1120:
|
||||
hal_reg_vout_set_cfg_intf_sel(g_p_vout_reg, 0);
|
||||
if (intf == XMEDIA_INTF_TYPE_BT1120) {
|
||||
hal_reg_vout_set_cfg_bt_mode(g_p_vout_reg, 1);
|
||||
} else {
|
||||
hal_reg_vout_set_cfg_bt_mode(g_p_vout_reg, 0);
|
||||
}
|
||||
break;
|
||||
case XMEDIA_INTF_TYPE_MCU:
|
||||
hal_reg_vout_set_cfg_intf_sel(g_p_vout_reg, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_regup(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_intfupd_cfg_regup_en(g_p_vout_reg, enable);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//默认从消隐区开始计数
|
||||
xmedia_void hal_vo_set_intf_cnt_pos(xmedia_vo_dev dev)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_regup_pos(g_p_vout_reg, VO_REGUP_POS_VALUE);
|
||||
hal_reg_vout_set_cfg_para_pos(g_p_vout_reg, VO_PARA_POS_VALUE);
|
||||
hal_reg_vout_set_cfg_prefetch_pos(g_p_vout_reg, VO_PREFETCH_POS_VALUE);
|
||||
hal_reg_vout_set_cfg_start_pos(g_p_vout_reg, VO_START_POS_VALUE);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing,
|
||||
vo_intf_special_timing *special_timing)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_interlaced(g_p_vout_reg, !(sync_timing->iop)); //逐隔行 配置
|
||||
hal_reg_vout_set_cfg_de_inv(g_p_vout_reg,sync_timing->idv); //数据有效信号的极性
|
||||
hal_reg_vout_set_cfg_hs_inv(g_p_vout_reg,sync_timing->ihs); //水平有效信号的极性
|
||||
hal_reg_vout_set_cfg_vs_inv(g_p_vout_reg,sync_timing->ivs); //垂直有效信号的极性
|
||||
if (sync_timing->iop == 0) {
|
||||
hal_reg_vout_set_cfg_vact(g_p_vout_reg, sync_timing->vact * 2 - 1);//垂直有效区
|
||||
} else {
|
||||
hal_reg_vout_set_cfg_vact(g_p_vout_reg, sync_timing->vact - 1);
|
||||
}
|
||||
hal_reg_vout_set_cfg_vbb(g_p_vout_reg,sync_timing->vbb - 1); //垂直消隐后肩
|
||||
hal_reg_vout_set_cfg_vfb(g_p_vout_reg,sync_timing->vfb - 1); //垂直消隐前肩
|
||||
hal_reg_vout_set_cfg_hact(g_p_vout_reg,sync_timing->hact - 1); //水平有效区
|
||||
hal_reg_vout_set_cfg_bvbb(g_p_vout_reg,sync_timing->bvbb - 1); //底场垂直消隐后肩
|
||||
hal_reg_vout_set_cfg_bvfb(g_p_vout_reg,sync_timing->bvfb - 1); //底场垂直消隐前肩
|
||||
hal_reg_vout_set_cfg_hs_width(g_p_vout_reg,sync_timing->hpw); //水平脉冲宽度
|
||||
if (special_timing->vo_special_timing_sel) {
|
||||
hal_reg_vout_set_cfg_hbb(g_p_vout_reg,special_timing->fixed_clk_hbb - 1); //水平消隐后肩
|
||||
hal_reg_vout_set_cfg_hfb(g_p_vout_reg,special_timing->fixed_clk_hfb - 1); //水平消隐前肩
|
||||
//vsync lcd mipi lvds 都需要使用,vsync的起始点和结束点
|
||||
hal_reg_vout_set_cfg_vs_st_h_field0(g_p_vout_reg, special_timing->fixed_clk_hfb - 1);
|
||||
hal_reg_vout_set_cfg_vs_end_h_field0(g_p_vout_reg, special_timing->fixed_clk_hfb - 1);
|
||||
hal_reg_vout_set_cfg_vs_st_v_field0(g_p_vout_reg, special_timing->vs_st_v_filed);
|
||||
hal_reg_vout_set_cfg_vs_end_v_field0(g_p_vout_reg, special_timing->vs_end_v_filed);
|
||||
} else {
|
||||
hal_reg_vout_set_cfg_hbb(g_p_vout_reg,sync_timing->hbb - 1); //水平消隐后肩
|
||||
hal_reg_vout_set_cfg_hfb(g_p_vout_reg,sync_timing->hfb - 1); //水平消隐前肩
|
||||
//vsync lcd mipi lvds 都需要使用,vsync的起始点和结束点
|
||||
hal_reg_vout_set_cfg_vs_st_h_field0(g_p_vout_reg, sync_timing->hbb - 1);
|
||||
hal_reg_vout_set_cfg_vs_end_h_field0(g_p_vout_reg, sync_timing->hbb - 1);
|
||||
hal_reg_vout_set_cfg_vs_st_v_field0(g_p_vout_reg, sync_timing->vfb);
|
||||
hal_reg_vout_set_cfg_vs_end_v_field0(g_p_vout_reg, sync_timing->vfb + sync_timing->vpw);
|
||||
}
|
||||
|
||||
hal_reg_vout_set_cfg_field_tog(g_p_vout_reg, 0x0); //场模式用的 暂时不管
|
||||
hal_reg_vout_set_cfg_bfield_tog(g_p_vout_reg, 0x0); //场模式用的 暂时不管
|
||||
hal_reg_vout_set_cfg_vs_st_h_field1(g_p_vout_reg, 0x0); //场模式用的 暂时不管
|
||||
hal_reg_vout_set_cfg_vs_end_h_field1(g_p_vout_reg, 0x0); //场模式用的 暂时不管
|
||||
hal_reg_vout_set_cfg_vs_st_v_field1(g_p_vout_reg, 0x0); //场模式用的 暂时不管
|
||||
hal_reg_vout_set_cfg_vs_end_v_field1(g_p_vout_reg, 0x0); //场模式用的 暂时不管
|
||||
|
||||
/*
|
||||
* 目前还有以下参数没用到
|
||||
* xmedia_u16 hmid; //底场同步水平有效区域
|
||||
* xmedia_bool synm; //同步模式(0 表示比如BT656时序,1表示像LCD那样的信号)
|
||||
* xmedia_u8 intfb; //隔行输出的位宽y
|
||||
*/
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//主要给LCD用,BT用内同步
|
||||
xmedia_void hal_vo_set_intf_sync_inverse(xmedia_vo_dev dev)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_field_tog(g_p_vout_reg, 0x0); //(0->vbb+bvbb+1)
|
||||
hal_reg_vout_set_cfg_bfield_tog(g_p_vout_reg, 0x0);
|
||||
hal_reg_vout_set_cfg_vs_st_h_field0(g_p_vout_reg, 0x0);
|
||||
hal_reg_vout_set_cfg_vs_end_h_field0(g_p_vout_reg, 0x1);
|
||||
hal_reg_vout_set_cfg_vs_st_v_field0(g_p_vout_reg, 0x0); //行翻转点起始
|
||||
hal_reg_vout_set_cfg_vs_end_v_field0(g_p_vout_reg, 0x1); //(0,vfb+vbb+1)
|
||||
hal_reg_vout_set_cfg_vs_st_v_field1(g_p_vout_reg, 0x0);
|
||||
hal_reg_vout_set_cfg_vs_end_v_field1(g_p_vout_reg, 0x1);
|
||||
hal_reg_vout_set_cfg_vs_st_h_field1(g_p_vout_reg, 0x0);
|
||||
hal_reg_vout_set_cfg_vs_end_h_field1(g_p_vout_reg, 0x1);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//垂直中断起始行配置:有效区或者消隐区计数
|
||||
xmedia_void hal_vo_set_intf_vtt_sel(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_bool cnt_mode)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
if (vtt_id == 0) {
|
||||
hal_reg_vout_set_cfg_vt_int_cnt_sel_0(g_p_vout_reg, cnt_mode);
|
||||
}
|
||||
if (vtt_id == 1) {
|
||||
hal_reg_vout_set_cfg_vt_int_cnt_sel_1(g_p_vout_reg, cnt_mode);
|
||||
}
|
||||
if (vtt_id == 2) {
|
||||
hal_reg_vout_set_cfg_vt_int_cnt_sel_2(g_p_vout_reg, cnt_mode);
|
||||
}
|
||||
if (vtt_id == 3) {
|
||||
hal_reg_vout_set_cfg_vt_int_cnt_sel_3(g_p_vout_reg, cnt_mode);
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//帧模式还是场模式
|
||||
xmedia_void hal_vo_set_intf_vtt_mode(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_bool frame_mode)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
if (vtt_id == 0) {
|
||||
hal_reg_vout_set_cfg_vt_int_mode_0(g_p_vout_reg, frame_mode);
|
||||
}
|
||||
if (vtt_id == 1) {
|
||||
hal_reg_vout_set_cfg_vt_int_mode_1(g_p_vout_reg, frame_mode);
|
||||
}
|
||||
if (vtt_id == 2) {
|
||||
hal_reg_vout_set_cfg_vt_int_mode_2(g_p_vout_reg, frame_mode);
|
||||
}
|
||||
if (vtt_id == 3) {
|
||||
hal_reg_vout_set_cfg_vt_int_mode_3(g_p_vout_reg, frame_mode);
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//中断阈值
|
||||
xmedia_void hal_vo_set_intf_vtt_thd(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_u32 vtt_thd)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
if (vtt_id == 0) {
|
||||
hal_reg_vout_set_cfg_vt_int_thd_0(g_p_vout_reg, vtt_thd);
|
||||
}
|
||||
if (vtt_id == 1) {
|
||||
hal_reg_vout_set_cfg_vt_int_thd_1(g_p_vout_reg, vtt_thd);
|
||||
}
|
||||
if (vtt_id == 2) {
|
||||
hal_reg_vout_set_cfg_vt_int_thd_2(g_p_vout_reg, vtt_thd);
|
||||
}
|
||||
if (vtt_id == 3) {
|
||||
hal_reg_vout_set_cfg_vt_int_thd_3(g_p_vout_reg, vtt_thd);
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_intf_state(xmedia_vo_dev dev, xmedia_bool *btm, xmedia_u16 *vcnt, xmedia_u8 *vstate)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
*btm = hal_reg_vout_get_field_flag_ppc(g_p_vout_reg);
|
||||
*vstate = hal_reg_vout_get_vstate(g_p_vout_reg);
|
||||
if (hal_reg_vout_get_cfg_vt_int_cnt_sel_0(g_p_vout_reg) == 0) {
|
||||
*vcnt = hal_reg_vout_get_vcnt_st_vblk(g_p_vout_reg);
|
||||
} else if (hal_reg_vout_get_cfg_vt_int_cnt_sel_0(g_p_vout_reg) == 1) {
|
||||
*vcnt = hal_reg_vout_get_vcnt_st_vact(g_p_vout_reg);
|
||||
} else {
|
||||
*vcnt = hal_reg_vout_get_vcnt_st_vblk(g_p_vout_reg);
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_intf_checksum_value(xmedia_vo_dev dev, xmedia_u32 *y, xmedia_u32 *u, xmedia_u32 *v)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
*y = hal_reg_vout_get_intf_y_sum(g_p_vout_reg);
|
||||
*u = hal_reg_vout_get_intf_u_sum(g_p_vout_reg);
|
||||
*v = hal_reg_vout_get_intf_v_sum(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_bt_mode(xmedia_vo_dev dev, xmedia_bool value)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_bt_mode(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_bt_yc_order(xmedia_vo_dev dev, xmedia_bool value)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_bt_yc_order(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_bt_uv_order(xmedia_vo_dev dev, xmedia_bool value)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_bt_uv_order(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
//场消隐还是自定义
|
||||
xmedia_void hal_vo_set_intf_bt_vbit_mode(xmedia_vo_dev dev, xmedia_bool sync_mode)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_vbit_mode(g_p_vout_reg, sync_mode);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_bt_bit_inverse(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_bt_bit_inv(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_bt_user_sync(xmedia_vo_dev dev, vo_intf_bt_sync *sync)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_vbit_st(g_p_vout_reg, sync->top_start);
|
||||
hal_reg_vout_set_cfg_vbit_end(g_p_vout_reg, sync->top_end);
|
||||
hal_reg_vout_set_cfg_bvbit_st(g_p_vout_reg, sync->bottom_start);
|
||||
hal_reg_vout_set_cfg_bvbit_end(g_p_vout_reg, sync->bottom_end);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_lcd_mode(xmedia_vo_dev dev, xmedia_bool value)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_lcd_mode(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_lcd_rgb_order(xmedia_vo_dev dev, xmedia_u8 order0, xmedia_u8 order1)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_lcd_rgb_order_0(g_p_vout_reg, order0);
|
||||
hal_reg_vout_set_cfg_lcd_rgb_order_1(g_p_vout_reg, order1);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_lcd_bit_inverse(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_lcd_bit_inv(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_mute_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_voutintf_cfg_mute_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_get_intf_mute_enable(xmedia_vo_dev dev, xmedia_bool *enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
*enable = hal_reg_vout_get_voutintf_cfg_mute_en(g_p_vout_reg);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_mute_pattern_mode(xmedia_vo_dev dev, xmedia_u8 value)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_voutintf_cfg_mute_pat(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_mute_data_mode(xmedia_vo_dev dev, xmedia_u8 value)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_voutintf_cfg_mute_mode(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_checkbar_size(xmedia_vo_dev dev, xmedia_u8 width, xmedia_u8 height)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_voutintf_cfg_checker_h(g_p_vout_reg, width);
|
||||
hal_reg_vout_set_voutintf_cfg_checker_v(g_p_vout_reg, height);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_cbar_sel(xmedia_vo_dev dev, xmedia_u8 value)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_cbar_sel(g_p_vout_reg, value);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_mute_color(xmedia_vo_dev dev, xmedia_u32 white_color, xmedia_u32 black_color)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_voutintf_cfg_mute_color(g_p_vout_reg, white_color);
|
||||
hal_reg_vout_set_intfmutebk_cfg_bk_color(g_p_vout_reg, black_color);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_ink(xmedia_vo_dev dev, vo_csc_ink_info *ink_info)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_ink_en(g_p_vout_reg, ink_info->ink_en);
|
||||
hal_reg_vout_set_cfg_cross_en(g_p_vout_reg, ink_info->cross_en);
|
||||
hal_reg_vout_set_cfg_cross_color_mode(g_p_vout_reg, ink_info->color_reverse);
|
||||
hal_reg_vout_set_cfg_cross_color(g_p_vout_reg, ink_info->color);
|
||||
hal_reg_vout_set_cfg_y_pos(g_p_vout_reg, ink_info->y);
|
||||
hal_reg_vout_set_cfg_x_pos(g_p_vout_reg, ink_info->x);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_clip(xmedia_vo_dev dev, vo_intf_clip *intf_clip)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_clip_yuv_l(g_p_vout_reg, intf_clip->clip_l);
|
||||
hal_reg_vout_set_cfg_clip_yuv_h(g_p_vout_reg, intf_clip->clip_h);
|
||||
hal_reg_vout_set_cfg_clip_en(g_p_vout_reg, intf_clip->clip_en);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_hcds(xmedia_vo_dev dev, vo_intf_hcds *intf_hcds)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_hcds_coef_0(g_p_vout_reg, intf_hcds->hcds_coef_0);
|
||||
hal_reg_vout_set_cfg_hcds_coef_1(g_p_vout_reg, intf_hcds->hcds_coef_1);
|
||||
hal_reg_vout_set_cfg_hcds_coef_2(g_p_vout_reg, intf_hcds->hcds_coef_2);
|
||||
hal_reg_vout_set_cfg_hcds_coef_3(g_p_vout_reg, intf_hcds->hcds_coef_3);
|
||||
// 0:丢点模式, 1:二阶滤波
|
||||
hal_reg_vout_set_cfg_hcds_mode(g_p_vout_reg, intf_hcds->hcds_mode);
|
||||
hal_reg_vout_set_cfg_hcds_en(g_p_vout_reg, intf_hcds->hcds_en);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_dither_enable(xmedia_vo_dev dev, xmedia_bool enable)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_dither_en(g_p_vout_reg, enable);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_intf_dither_thd(xmedia_vo_dev dev, xmedia_u8 thd_h, xmedia_u8 thd_l)
|
||||
{
|
||||
if (dev == XMEDIA_VO_DEV_0) {
|
||||
hal_reg_vout_set_cfg_dither_thd_h(g_p_vout_reg, thd_h);
|
||||
hal_reg_vout_set_cfg_dither_thd_l(g_p_vout_reg, thd_l);
|
||||
} else {
|
||||
;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
//接口数据顺序要要注意下视频格式输出的顺序
|
||||
xmedia_void hal_vo_set_bt656_intf_cfg(xmedia_vo_dev dev, xmedia_vo_bt656_attr *bt656_attr)
|
||||
{
|
||||
vo_intf_hcds intf_hcds;
|
||||
vo_intf_clip intf_clip;
|
||||
|
||||
hal_vo_set_intf_mux(dev, XMEDIA_INTF_TYPE_BT656);
|
||||
intf_hcds.hcds_en = XMEDIA_TRUE;
|
||||
intf_hcds.hcds_mode = 0;
|
||||
intf_hcds.hcds_coef_0 = 127;
|
||||
intf_hcds.hcds_coef_1 = 1;
|
||||
intf_hcds.hcds_coef_2 = 32;
|
||||
intf_hcds.hcds_coef_3 = 96;
|
||||
hal_vo_set_intf_hcds(dev, &intf_hcds);
|
||||
intf_clip.clip_en = XMEDIA_TRUE;
|
||||
intf_clip.clip_l = 0x101010;
|
||||
intf_clip.clip_h = 0xEBF0F0;
|
||||
hal_vo_set_intf_clip(dev, &intf_clip);
|
||||
switch(bt656_attr->data_seq){
|
||||
case XMEDIA_INTF_BT601_BT656_DATA_SEQ_YUYV:
|
||||
hal_vo_set_intf_bt_yc_order(dev, 1);
|
||||
hal_vo_set_intf_bt_uv_order(dev, 0);
|
||||
break;
|
||||
case XMEDIA_INTF_BT601_BT656_DATA_SEQ_YVYU:
|
||||
hal_vo_set_intf_bt_yc_order(dev, 1);
|
||||
hal_vo_set_intf_bt_uv_order(dev, 1);
|
||||
break;
|
||||
case XMEDIA_INTF_BT601_BT656_DATA_SEQ_UYVY:
|
||||
hal_vo_set_intf_bt_yc_order(dev, 0);
|
||||
hal_vo_set_intf_bt_uv_order(dev, 0);
|
||||
break;
|
||||
case XMEDIA_INTF_BT601_BT656_DATA_SEQ_VYUY:
|
||||
hal_vo_set_intf_bt_yc_order(dev, 0);
|
||||
hal_vo_set_intf_bt_uv_order(dev, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_bt1120_intf_cfg(xmedia_vo_dev dev, xmedia_vo_bt1120_attr *bt1120_attr)
|
||||
{
|
||||
vo_intf_hcds intf_hcds;
|
||||
vo_intf_clip intf_clip;
|
||||
|
||||
hal_vo_set_intf_mux(dev, XMEDIA_INTF_TYPE_BT1120);
|
||||
hal_vo_set_intf_dither_enable(dev, XMEDIA_FALSE);
|
||||
intf_hcds.hcds_en = XMEDIA_TRUE;
|
||||
intf_hcds.hcds_mode = 0;
|
||||
intf_hcds.hcds_coef_0 = 127;
|
||||
intf_hcds.hcds_coef_1 = 1;
|
||||
intf_hcds.hcds_coef_2 = 32;
|
||||
intf_hcds.hcds_coef_3 = 96;
|
||||
hal_vo_set_intf_hcds(dev, &intf_hcds);
|
||||
intf_clip.clip_en = XMEDIA_TRUE;
|
||||
intf_clip.clip_l = 0x101010;
|
||||
intf_clip.clip_h = 0xEBF0F0;
|
||||
hal_vo_set_intf_clip(dev, &intf_clip);
|
||||
hal_vo_set_intf_bt_yc_order(dev, 0);
|
||||
switch(bt1120_attr->data_seq){
|
||||
case XMEDIA_INTF_BT1120_DATA_SEQ_VUVU:
|
||||
hal_vo_set_intf_bt_uv_order(dev, 1);
|
||||
break;
|
||||
case XMEDIA_INTF_BT1120_DATA_SEQ_UVUV:
|
||||
hal_vo_set_intf_bt_uv_order(dev, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xmedia_void hal_vo_set_lcd_intf_cfg(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr)
|
||||
{
|
||||
xmedia_u8 data_seq = 0;
|
||||
|
||||
hal_vo_set_intf_mux(dev, XMEDIA_INTF_TYPE_LCD);
|
||||
switch(lcd_attr->data_mode){
|
||||
case XMEDIA_VO_LCD_DATA_MODE_SERIAL:
|
||||
if (lcd_attr->data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT) {
|
||||
hal_vo_set_intf_lcd_mode(dev, 0);
|
||||
} else {
|
||||
hal_vo_set_intf_lcd_mode(dev, 1);
|
||||
}
|
||||
break;
|
||||
case XMEDIA_VO_LCD_DATA_MODE_PARA:
|
||||
if (lcd_attr->data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB565_16BIT) {
|
||||
hal_vo_set_intf_lcd_mode(dev, 2);
|
||||
} else if (lcd_attr->data_type == XMEDIA_INTF_LCD_DATA_TYPE_RGB666_18BIT) {
|
||||
hal_vo_set_intf_lcd_mode(dev, 3);
|
||||
} else {
|
||||
hal_vo_set_intf_lcd_mode(dev, 4);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
*逻辑和实际lcd的颜色是不一致的
|
||||
* PLCD:
|
||||
* LCD_RGB = LOGIC_BGR LCD_RBG = LOGIC_GBR LCD_BGR = LOGIC_RGB
|
||||
* LCD_GRB = LOGIC_BRG LCD_GBR = LOGIC_GRB LCD_BRG = LOGIC_RBG
|
||||
* SLCD:
|
||||
* LCD_RGB = LOGIC_RGB LCD_RBG = LOGIC_RBG LCD_BGR = LOGIC_BGR
|
||||
* LCD_GRB = LOGIC_GRB LCD_GBR = LOGIC_BRG LCD_BRG = LOGIC_GBR
|
||||
*/
|
||||
switch(lcd_attr->data_seq){
|
||||
case XMEDIA_INTF_LCD_DATA_SEQ_RGB:
|
||||
data_seq = lcd_attr->data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA ? 5 : 0;
|
||||
break;
|
||||
case XMEDIA_INTF_LCD_DATA_SEQ_RBG:
|
||||
data_seq = lcd_attr->data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA ? 3 : 1;
|
||||
break;
|
||||
case XMEDIA_INTF_LCD_DATA_SEQ_GRB:
|
||||
data_seq = lcd_attr->data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA ? 4 : 2;
|
||||
break;
|
||||
case XMEDIA_INTF_LCD_DATA_SEQ_GBR:
|
||||
data_seq = lcd_attr->data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA ? 2 : 4;
|
||||
break;
|
||||
case XMEDIA_INTF_LCD_DATA_SEQ_BRG:
|
||||
data_seq = lcd_attr->data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA ? 1 : 3;
|
||||
break;
|
||||
case XMEDIA_INTF_LCD_DATA_SEQ_BGR:
|
||||
data_seq = lcd_attr->data_mode == XMEDIA_VO_LCD_DATA_MODE_PARA ? 0 : 5;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hal_vo_set_intf_lcd_rgb_order(dev, data_seq, data_seq);
|
||||
hal_vo_set_intf_dither_enable(dev, XMEDIA_TRUE);
|
||||
hal_vo_set_intf_dither_thd(dev, 255, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
static xmedia_void vo_data_type_to_hal_type(xmedia_intf_mcu_data_type data_type, xmedia_u32 *hal_data_type,
|
||||
xmedia_u32 *hal_wr_mode)
|
||||
{
|
||||
switch (data_type) {
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_8BIT_16BPP_RGB565_8080I:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_8BIT_18BPP_RGB666_8080I:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_8BIT_16BPP_RGB565_8080II:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_8BIT_18BPP_RGB666_8080II:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_16BPP_RGB565_8080I:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080I_OPTION1:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080I_OPTION2:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_16BPP_RGB565_8080II:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080II_OPTION1:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080II_OPTION2:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_16BPP_RGB565_8080I:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION1:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION2:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION3:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION4:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION5:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_16BPP_RGB565_8080II:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION1:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION2:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION3:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION4:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_18BIT_16BPP_RGB565_8080I:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_18BIT_18BPP_RGB666_8080I:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_18BIT_16BPP_RGB565_8080II:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_18BIT_18BPP_RGB666_8080II:
|
||||
*hal_data_type = data_type;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB565_OPTION1:
|
||||
*hal_data_type = 26;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB666_OPTION1:
|
||||
*hal_data_type = 27;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB565_OPTION2:
|
||||
*hal_data_type = 29;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB666_OPTION2:
|
||||
*hal_data_type = 30;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_4LINE_RGB565:
|
||||
*hal_data_type = 32;
|
||||
*hal_wr_mode = 1;
|
||||
break;
|
||||
case XMEDIA_VO_MCU_DATA_TYPE_4LINE_RGB666:
|
||||
*hal_data_type = 33;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
default:
|
||||
*hal_data_type = 0;
|
||||
*hal_wr_mode = 2;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// MCU 屏写参数
|
||||
static xmedia_s32 vo_mcu_write_cmd(xmedia_u8 lut_mcu[], xmedia_u32 para_size)
|
||||
{
|
||||
// 查询等待
|
||||
while((hal_reg_vout_get_mcu_wr_cmd_state(g_p_vout_reg) != 0) ||
|
||||
(hal_reg_vout_get_mcu_rd_cmd_state(g_p_vout_reg) == 1) ||
|
||||
(hal_reg_vout_get_mcu_rd_pixel_state(g_p_vout_reg) == 1));
|
||||
|
||||
// 配置屏命令类型 写参数
|
||||
hal_reg_vout_set_cfg_mcu_cmd_mode(g_p_vout_reg, 0x1);
|
||||
// 参数个数 减一配置
|
||||
hal_reg_vout_set_cfg_mcu_wrcmd_size(g_p_vout_reg, para_size - 1);
|
||||
// 配置写参数寄存器
|
||||
osal_memcpy((xmedia_void*)&(g_p_vout_reg->vout_mcu_screen_wr_para), lut_mcu, para_size * 4);
|
||||
// 等待参数全部写入参数RAM中
|
||||
while(hal_reg_vout_get_mcu_wr_cmd_state(g_p_vout_reg) != 1) ;
|
||||
// 使能参数更新到MCU屏
|
||||
hal_reg_vout_set_cfg_mcu_wrcmd_start(g_p_vout_reg, XMEDIA_TRUE);
|
||||
while(hal_reg_vout_get_mcu_wr_cmd_state(g_p_vout_reg) != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_dts_array_to_cmd_package(xmedia_u8 *cmd_buf, xmedia_u32 *cmd_index)
|
||||
{
|
||||
xmedia_s32 index = *cmd_index;
|
||||
xmedia_u8 *cmd_buf_tmp = cmd_buf;
|
||||
xmedia_u32 one_cmd_len = 0;
|
||||
xmedia_u32 one_cmd_len_4byte_align = 0;
|
||||
xmedia_u32 cmd_buf_fill_size = 0;
|
||||
xmedia_u32 i = 0;
|
||||
if (*cmd_index >= g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].size) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "convert end *cmd_index %d\n", *cmd_index);
|
||||
return cmd_buf_fill_size;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
one_cmd_len = g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].array[index];
|
||||
//碰到延时指令 直接跳出 进入下次循环的延时处理
|
||||
if (one_cmd_len == 0) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "need delay %d ms break!!!\n", g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].array[index + 1]);
|
||||
break;
|
||||
}
|
||||
//命令长度对4取整
|
||||
one_cmd_len_4byte_align = ((one_cmd_len / 4) + ((one_cmd_len % 4) ? 1 : 0)) * 4;
|
||||
//超出单次传送命令包长度
|
||||
if((cmd_buf_fill_size + one_cmd_len_4byte_align) >= MCU_CMD_PACKAGE_MAX_SIZE) {
|
||||
*cmd_index = index;
|
||||
break;
|
||||
}
|
||||
//单个命令起始位置
|
||||
index++;
|
||||
osal_memcpy(cmd_buf_tmp, (g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].array + index), one_cmd_len);
|
||||
//索引按实际命令累加
|
||||
index += one_cmd_len;
|
||||
//按4byte对齐累加
|
||||
cmd_buf_tmp += one_cmd_len_4byte_align;
|
||||
cmd_buf_fill_size += one_cmd_len_4byte_align;
|
||||
*cmd_index = index;
|
||||
|
||||
if (index == g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].size) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "read end success\n");
|
||||
break;
|
||||
} else if (index > g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].size) {
|
||||
VO_TRACE(MODULE_DBG_ERR, "size error please check!!!\n");
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0;i < (cmd_buf_fill_size / 4); i++) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "0x%02x 0x%02x 0x%02x 0x%02x \n", cmd_buf[i*4], cmd_buf[i*4 + 1],cmd_buf[i*4 + 2],cmd_buf[i*4 + 3]);
|
||||
}
|
||||
|
||||
return cmd_buf_fill_size;
|
||||
}
|
||||
|
||||
static xmedia_s32 vo_dts_do_delay(xmedia_u8 *cmd_buf, xmedia_u32 *cmd_index)
|
||||
{
|
||||
xmedia_s32 index = *cmd_index;
|
||||
xmedia_u8 *cmd_buf_tmp = cmd_buf;
|
||||
xmedia_u32 one_cmd_len = 0;
|
||||
if (*cmd_index >= g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].size) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "convert end *cmd_index %d\n", *cmd_index);
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
one_cmd_len = g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].array[index];
|
||||
if (one_cmd_len == 0) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "need delay %d ms!!!\n", g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].array[index + 1]);
|
||||
cmd_buf_tmp[0] = 0;
|
||||
cmd_buf_tmp[1] = g_vo_dts_lcd_config[VO_DTS_LCD_TYPE_MCU].array[index + 1];
|
||||
index +=2;
|
||||
*cmd_index = index;
|
||||
return XMEDIA_TRUE;
|
||||
} else {
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
//mcu屏参初始化 todo ????
|
||||
xmedia_void hal_vo_set_mcu_intf_cfg(xmedia_vo_dev dev, xmedia_vo_mcu_attr *mcu_attr)
|
||||
{
|
||||
vo_intf_hcds intf_hcds;
|
||||
xmedia_u32 hal_data_type;
|
||||
xmedia_u32 hal_wr_mode;
|
||||
xmedia_u8 *cmd_buf;
|
||||
xmedia_s32 cmd_buf_fill_size = 0;
|
||||
xmedia_u32 cmd_index = 0;
|
||||
xmedia_s32 ret = XMEDIA_FALSE;
|
||||
hal_vo_set_intf_mux(dev, XMEDIA_INTF_TYPE_MCU);
|
||||
|
||||
vo_data_type_to_hal_type(mcu_attr->data_type, &hal_data_type, &hal_wr_mode);
|
||||
hal_reg_vout_set_cfg_mcu_mode(g_p_vout_reg, hal_data_type);
|
||||
|
||||
//mcu屏软复位
|
||||
hal_reg_vout_set_cfg_mcu_rst_ctrl(g_p_vout_reg, XMEDIA_TRUE);
|
||||
osal_udelay(1*1000);
|
||||
hal_reg_vout_set_cfg_mcu_rst_ctrl(g_p_vout_reg, XMEDIA_FALSE);
|
||||
osal_udelay(10*1000);
|
||||
hal_reg_vout_set_cfg_mcu_rst_ctrl(g_p_vout_reg, XMEDIA_TRUE);
|
||||
osal_udelay(120*1000);
|
||||
|
||||
cmd_buf = (xmedia_u8 *)osal_vmalloc(MCU_CMD_PACKAGE_MAX_SIZE);
|
||||
while(1) {
|
||||
osal_memset(cmd_buf, 0, MCU_CMD_PACKAGE_MAX_SIZE);
|
||||
//处理屏参中穿插的延时指令 可能有连续延时指令 所以while循环处理
|
||||
while(1) {
|
||||
ret = vo_dts_do_delay(cmd_buf, &cmd_index);
|
||||
if (ret == XMEDIA_TRUE) {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "do delay %d ms!!!\n", cmd_buf[1]);
|
||||
osal_udelay(cmd_buf[1] * 1000);
|
||||
cmd_buf[1] = 0;
|
||||
} else {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "do delay success!!!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
//传屏参
|
||||
cmd_buf_fill_size = vo_dts_array_to_cmd_package(cmd_buf, &cmd_index);
|
||||
if (cmd_buf_fill_size > 0) {
|
||||
vo_mcu_write_cmd(cmd_buf, (cmd_buf_fill_size / 4));
|
||||
} else {
|
||||
VO_TRACE(MODULE_DBG_DEBUG, "set mcu param end!!!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
osal_vfree(cmd_buf);
|
||||
|
||||
osal_udelay(10*1000);
|
||||
|
||||
//565 666
|
||||
hal_reg_vout_set_cfg_mcu_wr_fmt(g_p_vout_reg, hal_wr_mode);
|
||||
|
||||
//rgb888 下采样
|
||||
hal_vo_set_intf_dither_enable(dev, XMEDIA_TRUE);
|
||||
hal_vo_set_intf_dither_thd(dev, 255, 0);
|
||||
|
||||
// 使用TE帧同步
|
||||
hal_reg_vout_set_cfg_mcu_sync_type(g_p_vout_reg, mcu_attr->te_mode_en);
|
||||
// Write memory start
|
||||
hal_reg_vout_set_cfg_mcu_wrram_cmd(g_p_vout_reg, 0x2c);
|
||||
// Write memory continue
|
||||
hal_reg_vout_set_cfg_mcu_wrramc_cmd(g_p_vout_reg, 0x3c);
|
||||
|
||||
intf_hcds.hcds_en = XMEDIA_TRUE;
|
||||
intf_hcds.hcds_mode = 0;
|
||||
intf_hcds.hcds_coef_0 = 127;
|
||||
intf_hcds.hcds_coef_1 = 1;
|
||||
intf_hcds.hcds_coef_2 = 32;
|
||||
intf_hcds.hcds_coef_3 = 96;
|
||||
hal_vo_set_intf_hcds(dev, &intf_hcds);
|
||||
|
||||
hal_reg_vout_set_cfg_mcu_wrram_en(g_p_vout_reg, 0x1); // 当前帧写display data到屏幕frame ram命令使能
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_VO_INTF_H__
|
||||
#define __HAL_VO_INTF_H__
|
||||
|
||||
#include "hal_vo_csc.h"
|
||||
#include "hal_vo_clock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum{
|
||||
VO_INTF_HS_MODE_RF = 0, //vsyn对应的上升沿和下降沿都有效
|
||||
VO_INTF_HS_MODE_RF_NONE, //vsyn对应的上升沿和下降沿都无效
|
||||
VO_INTF_HS_MODE_FALLING,
|
||||
VO_INTF_HS_MODE_RISING,
|
||||
VO_INTF_HS_MODE_MAX,
|
||||
}vo_intf_hs_mode;
|
||||
|
||||
typedef struct{
|
||||
xmedia_bool hcds_en;
|
||||
xmedia_bool hcds_mode;
|
||||
xmedia_u8 hcds_coef_0;
|
||||
xmedia_u8 hcds_coef_1;
|
||||
xmedia_u8 hcds_coef_2;
|
||||
xmedia_u8 hcds_coef_3;
|
||||
}vo_intf_hcds;
|
||||
|
||||
typedef struct{
|
||||
xmedia_bool clip_en;
|
||||
xmedia_u32 clip_l;
|
||||
xmedia_u32 clip_h;
|
||||
}vo_intf_clip;
|
||||
|
||||
typedef struct{
|
||||
xmedia_u16 top_start;
|
||||
xmedia_u16 top_end;
|
||||
xmedia_u16 bottom_start;
|
||||
xmedia_u16 bottom_end;
|
||||
}vo_intf_bt_sync;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool ink_en;
|
||||
xmedia_bool cross_en;
|
||||
xmedia_bool color_reverse;
|
||||
xmedia_u32 color;
|
||||
xmedia_u32 x;
|
||||
xmedia_u32 y;
|
||||
} vo_csc_ink_info;
|
||||
|
||||
typedef struct {
|
||||
vo_clock_priority_sel vo_clock_priority_sel; //debug 接口 1:lcd分频器优先,0:固定频点优先
|
||||
xmedia_bool vo_special_timing_sel; //true表示使用固定分频,需要配置特殊时序,否则使用默认时序
|
||||
xmedia_u32 fixed_clk_htotal;
|
||||
xmedia_u32 fixed_clk_hbb;
|
||||
xmedia_u32 fixed_clk_hfb;
|
||||
xmedia_u32 vs_st_v_filed;
|
||||
xmedia_u32 vs_end_v_filed;
|
||||
} vo_intf_special_timing;
|
||||
|
||||
typedef enum{
|
||||
VO_DTS_LCD_TYPE_MIPI = 0,
|
||||
VO_DTS_LCD_TYPE_MCU,
|
||||
VO_DTS_LCD_TYPE_MAX,
|
||||
}vo_dts_lcd_type;
|
||||
|
||||
typedef struct {
|
||||
xmedia_s32 size;
|
||||
xmedia_u8 *array;
|
||||
} vo_dts_lcd_config;
|
||||
|
||||
xmedia_void hal_vo_set_intf_fifo(xmedia_vo_dev dev, xmedia_u32 fifo);
|
||||
xmedia_void hal_vo_set_intf_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_enable(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_chk_sum_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_hs_mode(xmedia_vo_dev dev, vo_intf_hs_mode hs_mode);
|
||||
xmedia_void hal_vo_set_intf_mux(xmedia_vo_dev dev, xmedia_intf_type intf);
|
||||
xmedia_void hal_vo_set_intf_regup(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_cnt_pos(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_intf_timing(xmedia_vo_dev dev, xmedia_u32 frame_rate,
|
||||
xmedia_vo_intf_config *intf_config, xmedia_vo_user_sync_timing *sync_timing, vo_intf_special_timing *special_timing);
|
||||
xmedia_void hal_vo_set_intf_sync_inverse(xmedia_vo_dev dev);
|
||||
xmedia_void hal_vo_set_intf_vtt_sel(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_bool cnt_mode);
|
||||
xmedia_void hal_vo_set_intf_vtt_mode(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_bool frame_mode);
|
||||
xmedia_void hal_vo_set_intf_vtt_thd(xmedia_vo_dev dev, xmedia_u32 vtt_id, xmedia_u32 vtt_thd);
|
||||
xmedia_void hal_vo_get_intf_state(xmedia_vo_dev dev, xmedia_bool *btm, xmedia_u16 *vcnt, xmedia_u8 *vstate);
|
||||
xmedia_void hal_vo_get_intf_checksum_value(xmedia_vo_dev dev, xmedia_u32 *y, xmedia_u32 *u, xmedia_u32 *v);
|
||||
xmedia_void hal_vo_set_intf_bt_mode(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_yc_order(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_uv_order(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_bt_vbit_mode(xmedia_vo_dev dev, xmedia_bool sync_mode);
|
||||
xmedia_void hal_vo_set_intf_bt_bit_inverse(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_bt_user_sync(xmedia_vo_dev dev, vo_intf_bt_sync *sync);
|
||||
xmedia_void hal_vo_set_intf_lcd_mode(xmedia_vo_dev dev, xmedia_bool value);
|
||||
xmedia_void hal_vo_set_intf_lcd_rgb_order(xmedia_vo_dev dev, xmedia_u8 order0, xmedia_u8 order1);
|
||||
xmedia_void hal_vo_set_intf_lcd_bit_inverse(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_mute_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_mute_enable(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_mute_pattern_mode(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_mute_data_mode(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_checkbar_size(xmedia_vo_dev dev, xmedia_u8 width, xmedia_u8 height);
|
||||
xmedia_void hal_vo_set_intf_cbar_sel(xmedia_vo_dev dev, xmedia_u8 value);
|
||||
xmedia_void hal_vo_set_intf_mute_color(xmedia_vo_dev dev, xmedia_u32 white_color, xmedia_u32 black_color);
|
||||
xmedia_void hal_vo_set_intf_ink(xmedia_vo_dev dev, vo_csc_ink_info *ink_info);
|
||||
xmedia_void hal_vo_set_intf_clip(xmedia_vo_dev dev, vo_intf_clip *intf_clip);
|
||||
xmedia_void hal_vo_set_intf_csc_en(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_get_intf_csc_en(xmedia_vo_dev dev, xmedia_bool *enable);
|
||||
xmedia_void hal_vo_set_intf_csc(xmedia_vo_dev dev, vo_csc_coef *intf_csc);
|
||||
xmedia_void hal_vo_set_intf_hcds(xmedia_vo_dev dev, vo_intf_hcds *intf_hcds);
|
||||
xmedia_void hal_vo_set_intf_dither_enable(xmedia_vo_dev dev, xmedia_bool enable);
|
||||
xmedia_void hal_vo_set_intf_dither_thd(xmedia_vo_dev dev, xmedia_u8 thd_h, xmedia_u8 thd_l);
|
||||
xmedia_void hal_vo_set_bt656_intf_cfg(xmedia_vo_dev dev, xmedia_vo_bt656_attr *bt656_attr);
|
||||
xmedia_void hal_vo_set_bt1120_intf_cfg(xmedia_vo_dev dev, xmedia_vo_bt1120_attr *bt1120_attr);
|
||||
xmedia_void hal_vo_set_lcd_intf_cfg(xmedia_vo_dev dev, xmedia_vo_lcd_attr *lcd_attr);
|
||||
xmedia_void hal_vo_set_mcu_intf_cfg(xmedia_vo_dev dev, xmedia_vo_mcu_attr *mcu_attr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+373
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __XMEDIA_VO_H__
|
||||
#define __XMEDIA_VO_H__
|
||||
|
||||
#include "drv_sys_comm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define VO_GAMMA_MAP_SIZE 256
|
||||
typedef xmedia_s32 xmedia_vo_chn;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VO_DEV_0 = 0,
|
||||
XMEDIA_VO_DEV_1,
|
||||
XMEDIA_VO_DEV_VIRT_0,
|
||||
XMEDIA_VO_DEV_VIRT_1,
|
||||
XMEDIA_VO_DEV_MAX
|
||||
}xmedia_vo_dev;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VO_LAYER_V0 = 0,
|
||||
XMEDIA_VO_LAYER_V1,
|
||||
XMEDIA_VO_LAYER_VIRT_V0,
|
||||
XMEDIA_VO_LAYER_VIRT_V1,
|
||||
XMEDIA_VO_LAYER_MAX
|
||||
}xmedia_vo_layer;
|
||||
|
||||
//定义输出接口时序
|
||||
typedef enum {
|
||||
XMEDIA_VO_INTF_SYNC_PAL = 0,
|
||||
XMEDIA_VO_INTF_SYNC_NTSC,
|
||||
|
||||
XMEDIA_VO_INTF_SYNC_1080P24,
|
||||
XMEDIA_VO_INTF_SYNC_1080P25,
|
||||
XMEDIA_VO_INTF_SYNC_1080P30,
|
||||
|
||||
XMEDIA_VO_INTF_SYNC_720P50,
|
||||
XMEDIA_VO_INTF_SYNC_720P60,
|
||||
XMEDIA_VO_INTF_SYNC_1080I50,
|
||||
XMEDIA_VO_INTF_SYNC_1080I60,
|
||||
XMEDIA_VO_INTF_SYNC_1080P50,
|
||||
XMEDIA_VO_INTF_SYNC_1080P60,
|
||||
|
||||
XMEDIA_VO_INTF_SYNC_576P50 = 11,
|
||||
XMEDIA_VO_INTF_SYNC_480P60,
|
||||
|
||||
XMEDIA_VO_INTF_SYNC_800x600_60 = 13,
|
||||
XMEDIA_VO_INTF_SYNC_1024x768_60,
|
||||
XMEDIA_VO_INTF_SYNC_1280x1024_60,
|
||||
XMEDIA_VO_INTF_SYNC_1366x768_60,
|
||||
XMEDIA_VO_INTF_SYNC_1440x900_60,
|
||||
XMEDIA_VO_INTF_SYNC_1280x800_60,
|
||||
XMEDIA_VO_INTF_SYNC_1600x1200_60,
|
||||
XMEDIA_VO_INTF_SYNC_1680x1050_60,
|
||||
XMEDIA_VO_INTF_SYNC_1920x1200_60,
|
||||
XMEDIA_VO_INTF_SYNC_640x480_60,
|
||||
XMEDIA_VO_INTF_SYNC_960H_PAL,
|
||||
XMEDIA_VO_INTF_SYNC_960H_NTSC,
|
||||
XMEDIA_VO_INTF_SYNC_1920x2160_30,
|
||||
XMEDIA_VO_INTF_SYNC_2560x1440_30,
|
||||
XMEDIA_VO_INTF_SYNC_2560x1440_60,
|
||||
XMEDIA_VO_INTF_SYNC_2560x1600_60,
|
||||
|
||||
XMEDIA_VO_INTF_SYNC_3840x2160_24 = 29,
|
||||
XMEDIA_VO_INTF_SYNC_3840x2160_25,
|
||||
XMEDIA_VO_INTF_SYNC_3840x2160_30,
|
||||
XMEDIA_VO_INTF_SYNC_3840x2160_50,
|
||||
XMEDIA_VO_INTF_SYNC_3840x2160_60,
|
||||
XMEDIA_VO_INTF_SYNC_4096x2160_24,
|
||||
XMEDIA_VO_INTF_SYNC_4096x2160_25,
|
||||
XMEDIA_VO_INTF_SYNC_4096x2160_30,
|
||||
XMEDIA_VO_INTF_SYNC_4096x2160_50,
|
||||
XMEDIA_VO_INTF_SYNC_4096x2160_60,
|
||||
|
||||
XMEDIA_VO_INTF_SYNC_320x240_60 = 39,
|
||||
XMEDIA_VO_INTF_SYNC_320x240_50,
|
||||
XMEDIA_VO_INTF_SYNC_240x320_50,
|
||||
XMEDIA_VO_INTF_SYNC_240x320_60,
|
||||
XMEDIA_VO_INTF_SYNC_800x600_50,
|
||||
XMEDIA_VO_INTF_SYNC_800x480_50,
|
||||
XMEDIA_VO_INTF_SYNC_720x1280_60,
|
||||
XMEDIA_VO_INTF_SYNC_1080x1920_60,
|
||||
XMEDIA_VO_INTF_SYNC_7680x4320_30,
|
||||
XMEDIA_VO_INTF_SYNC_USER = 48,
|
||||
|
||||
XMEDIA_VO_INTF_SYNC_MAX
|
||||
}xmedia_vo_intf_sync;
|
||||
|
||||
//定义设备模式
|
||||
typedef enum{
|
||||
XMEDIA_VO_DEV_MODE_VIDEO_GRAPHIC = 0,
|
||||
XMEDIA_VO_DEV_MODE_VIDEO,
|
||||
XMEDIA_VO_DEV_MODE_GRAPHIC,
|
||||
XMEDIA_VO_DEV_MODE_MAX
|
||||
}xmedia_vo_dev_mode;
|
||||
|
||||
//定义lcd的数据传输模式
|
||||
typedef enum {
|
||||
XMEDIA_VO_LCD_DATA_MODE_SERIAL = 0,
|
||||
XMEDIA_VO_LCD_DATA_MODE_PARA,
|
||||
XMEDIA_VO_LCD_DATA_MODE_MAX
|
||||
} xmedia_vo_lcd_data_mode;
|
||||
|
||||
//定义视频分割模式
|
||||
typedef enum {
|
||||
XMEDIA_VO_PARTITION_MODE_SINGLE = 0, //单区域模式,用软件将多张图片进行拼接显示在硬件的一个区域上
|
||||
XMEDIA_VO_PARTITION_MODE_MULTI, //多区域模式,每个区域对应硬件的一个区域
|
||||
XMEDIA_VO_PARTITION_MODE_MAX,
|
||||
}xmedia_vo_partition_mode;
|
||||
|
||||
//定义局部放大类型
|
||||
typedef enum {
|
||||
XMEDIA_VO_ZOOM_IN_RECT = 0,
|
||||
XMEDIA_VO_ZOOM_IN_RATIO,
|
||||
XMEDIA_VO_ZOOM_IN_MAX
|
||||
} xmedia_vo_zoom_in_type;
|
||||
|
||||
//定义视频低延时模式
|
||||
typedef enum {
|
||||
XMEDIA_VO_LOW_DELAY_NONE = 0, //普通模式
|
||||
XMEDIA_VO_LOW_DELAY_NORMAL, //软件低延时
|
||||
XMEDIA_VO_LOW_DELAY_MAX
|
||||
} xmedia_vo_low_delay_mode;
|
||||
|
||||
//定义用户同步时序
|
||||
typedef struct {
|
||||
xmedia_u16 vact; //垂直有效区
|
||||
xmedia_u16 vbb; //垂直消隐后肩
|
||||
xmedia_u16 vfb; //垂直消隐前肩
|
||||
|
||||
xmedia_u16 hact; //水平有效区
|
||||
xmedia_u16 hbb; //水平消隐后肩
|
||||
xmedia_u16 hfb; //水平消隐前肩
|
||||
xmedia_u16 hmid; //底场同步水平有效区域
|
||||
|
||||
xmedia_u16 bvact; //底场垂直有效区
|
||||
xmedia_u16 bvbb; //底场垂直消隐后肩
|
||||
xmedia_u16 bvfb; //底场垂直消隐前肩
|
||||
|
||||
xmedia_u16 hpw; //水平脉冲宽度
|
||||
xmedia_u16 vpw; //垂直脉冲宽度
|
||||
|
||||
xmedia_bool idv; //数据有效信号的极性
|
||||
xmedia_bool ihs; //水平有效信号的极性
|
||||
xmedia_bool ivs; //垂直有效信号的极性
|
||||
|
||||
xmedia_bool synm; //同步模式
|
||||
xmedia_bool iop; //隔行或者逐行显示(0表示隔行,1表示逐行)
|
||||
xmedia_u8 intfb; //隔行输出的位宽
|
||||
} xmedia_vo_user_sync_timing;
|
||||
|
||||
//定义用户同步信息
|
||||
typedef struct {
|
||||
xmedia_vo_user_sync_timing timing_info; //输出接口的时序信息
|
||||
xmedia_u32 frame_rate; //用户同步输出帧率
|
||||
xmedia_bool clk_reverse_en; //时钟是否翻转
|
||||
} xmedia_vo_user_sync_config;
|
||||
|
||||
//定义BT656的属性
|
||||
typedef struct {
|
||||
xmedia_intf_bt_data_type data_type;
|
||||
xmedia_intf_bt601_bt656_data_seq data_seq;
|
||||
} xmedia_vo_bt656_attr;
|
||||
|
||||
//定义BT1120的属性
|
||||
typedef struct {
|
||||
xmedia_intf_bt_data_type data_type;
|
||||
xmedia_intf_bt1120_data_seq data_seq;
|
||||
} xmedia_vo_bt1120_attr;
|
||||
|
||||
//定义LCD的属性
|
||||
typedef struct {
|
||||
xmedia_intf_lcd_data_type data_type;
|
||||
xmedia_vo_lcd_data_mode data_mode;
|
||||
xmedia_intf_lcd_data_seq data_seq;
|
||||
} xmedia_vo_lcd_attr;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VO_MIPI_LANE_DATA0 = 0,
|
||||
XMEDIA_VO_MIPI_LANE_DATA1,
|
||||
XMEDIA_VO_MIPI_LANE_CLK,
|
||||
XMEDIA_VO_MIPI_LANE_DATA2,
|
||||
XMEDIA_VO_MIPI_LANE_DATA3,
|
||||
XMEDIA_VO_MIPI_LANE_MAX
|
||||
}xmedia_vo_mipi_lane;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VO_MIPI_LANE_DEFAULT = 0,
|
||||
XMEDIA_VO_MIPI_LANE_NUM1,
|
||||
XMEDIA_VO_MIPI_LANE_NUM2,
|
||||
XMEDIA_VO_MIPI_LANE_NUM3,
|
||||
XMEDIA_VO_MIPI_LANE_NUM4,
|
||||
XMEDIA_VO_MIPI_LANE_NUM_MAX
|
||||
}xmedia_vo_mipi_lane_num;
|
||||
|
||||
//定义MIPI的属性
|
||||
typedef struct {
|
||||
xmedia_intf_mipi_dsi_data_type data_type;
|
||||
xmedia_bool lane_pn_swap[XMEDIA_VO_MIPI_LANE_MAX];
|
||||
xmedia_vo_mipi_lane lane_sel[XMEDIA_VO_MIPI_LANE_MAX];
|
||||
xmedia_s32 mipi_htotal_adjust;
|
||||
xmedia_s32 mipi_vsync_adjust;
|
||||
xmedia_vo_mipi_lane_num mipi_lane_num;
|
||||
} xmedia_vo_mipi_attr;
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VO_LVDS_LANE_DATA0 = 0,
|
||||
XMEDIA_VO_LVDS_LANE_DATA1,
|
||||
XMEDIA_VO_LVDS_LANE_DATA2,
|
||||
XMEDIA_VO_LVDS_LANE_DATA3,
|
||||
XMEDIA_VO_LVDS_LANE_CLK,
|
||||
XMEDIA_VO_LVDS_LANE_MAX
|
||||
}xmedia_vo_lvds_lane;
|
||||
|
||||
//定义LVDS的属性
|
||||
typedef struct {
|
||||
xmedia_intf_lvds_data_type data_type;
|
||||
xmedia_intf_lvds_format format;
|
||||
xmedia_vo_lvds_lane lane_sel[XMEDIA_VO_LVDS_LANE_MAX];
|
||||
xmedia_bool lane_pn_swap[XMEDIA_VO_LVDS_LANE_MAX];
|
||||
} xmedia_vo_lvds_attr;
|
||||
|
||||
//定义mcu的数据传输模式
|
||||
typedef enum {
|
||||
XMEDIA_VO_MCU_DATA_TYPE_8BIT_16BPP_RGB565_8080I = 0,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_8BIT_18BPP_RGB666_8080I,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_8BIT_16BPP_RGB565_8080II,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_8BIT_18BPP_RGB666_8080II,
|
||||
|
||||
XMEDIA_VO_MCU_DATA_TYPE_9BIT_16BPP_RGB565_8080I,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080I_OPTION1,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080I_OPTION2,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_9BIT_16BPP_RGB565_8080II,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080II_OPTION1,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_9BIT_18BPP_RGB666_8080II_OPTION2,
|
||||
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_16BPP_RGB565_8080I,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION1,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION2,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION3,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION4,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080I_OPTION5,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_16BPP_RGB565_8080II,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION1,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION2,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION3,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_16BIT_18BPP_RGB666_8080II_OPTION4,
|
||||
|
||||
XMEDIA_VO_MCU_DATA_TYPE_18BIT_16BPP_RGB565_8080I,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_18BIT_18BPP_RGB666_8080I,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_18BIT_16BPP_RGB565_8080II,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_18BIT_18BPP_RGB666_8080II,
|
||||
|
||||
XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB565_OPTION1,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB666_OPTION1,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB565_OPTION2,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_3LINE_RGB666_OPTION2,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_4LINE_RGB565,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_4LINE_RGB666,
|
||||
XMEDIA_VO_MCU_DATA_TYPE_MAX
|
||||
} xmedia_intf_mcu_data_type;
|
||||
|
||||
//定义MCU的属性
|
||||
typedef struct {
|
||||
xmedia_bool te_mode_en;
|
||||
xmedia_intf_mcu_data_type data_type;
|
||||
} xmedia_vo_mcu_attr;
|
||||
|
||||
//定义输出接口信息
|
||||
typedef struct {
|
||||
xmedia_intf_type intf_type;
|
||||
union {
|
||||
xmedia_vo_bt656_attr bt656_attr;
|
||||
xmedia_vo_bt1120_attr bt1120_attr;
|
||||
xmedia_vo_lcd_attr lcd_attr;
|
||||
xmedia_vo_mipi_attr mipi_attr;
|
||||
xmedia_vo_lvds_attr lvds_attr;
|
||||
xmedia_vo_mcu_attr mcu_attr;
|
||||
};
|
||||
} xmedia_vo_intf_config;
|
||||
|
||||
//定义设备属性
|
||||
typedef struct {
|
||||
xmedia_u32 bg_color; //设备的背景色,RGB格式
|
||||
xmedia_vo_intf_config intf_config; //输出接口属性
|
||||
xmedia_vo_intf_sync intf_sync; //输出接口的时序
|
||||
xmedia_vo_user_sync_config user_sync_config; //用户同步属性
|
||||
} xmedia_vo_dev_config;
|
||||
|
||||
//定义设备的csc属性
|
||||
typedef struct {
|
||||
xmedia_vo_dev_mode mode; //设备模式
|
||||
xmedia_video_color_descript color_info; //颜色信息,包含输出色域空间,色域范围和量化范围
|
||||
xmedia_u32 luma; //亮度范围为[0, 100],默认50
|
||||
xmedia_u32 contrast; //对比度度范围为[0, 100],默认50
|
||||
xmedia_u32 hue; //色度范围为[0, 100],默认50
|
||||
xmedia_u32 saturation; //饱和度范围为[0, 100],默认50
|
||||
} xmedia_vo_dev_csc;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u8 gamma_table[VO_GAMMA_MAP_SIZE];
|
||||
} xmedia_vo_gamma_table;
|
||||
|
||||
//定义设备的gamma属性
|
||||
typedef struct {
|
||||
xmedia_bool gamma_en; //gamma使能状态
|
||||
xmedia_vo_gamma_table gamma_table; //gamma表
|
||||
} xmedia_vo_dev_gamma;
|
||||
|
||||
//定义视频层输出属性
|
||||
typedef struct {
|
||||
xmedia_video_size img_size; //视频层的画布尺寸
|
||||
xmedia_video_pixel_format pix_format; //视频层的像素格式
|
||||
xmedia_video_data_width bit_width;; //视频层数据位宽
|
||||
xmedia_u32 disp_buf_len; //显示buf的长度
|
||||
xmedia_vo_partition_mode part_mode; //视频层的分割模式
|
||||
} xmedia_vo_layer_config;
|
||||
|
||||
//定义通道属性
|
||||
typedef struct {
|
||||
xmedia_u32 zorder; //通道顺序
|
||||
xmedia_video_rect out_rect; //输出通道的分辨率和位置
|
||||
xmedia_u32 bg_color; //输出通道区域背景色
|
||||
xmedia_video_rect region_rect;//输出通道的区域分辨率和位置
|
||||
} xmedia_vo_chn_attr;
|
||||
|
||||
//定义通道局部放大属性
|
||||
typedef struct {
|
||||
xmedia_u32 x_ratio; //范围为[0,1000]; x_ratio = x * 1000 / W, x是局部放大的起始位置,W是通道帧的宽度
|
||||
xmedia_u32 y_ratio; //范围为[0,1000]; y_ratio = y * 1000 / H, y是局部放大的起始位置,H是通道帧的高度
|
||||
xmedia_u32 w_ratio; //范围为[0,1000]; w_ratio = x * 1000 / W, w是局部放大的宽度,W是通道帧的宽度
|
||||
xmedia_u32 h_ratio; //范围为[0,1000]; h_ratio = h * 1000 / H, h是局部放大的高度,H是通道帧的高度
|
||||
} xmedia_vo_zoom_ratio;
|
||||
|
||||
typedef struct {
|
||||
xmedia_vo_zoom_in_type zoom_type; //选择局部放大类型
|
||||
union {
|
||||
xmedia_video_rect zoom_rect; //按窗口局部放大
|
||||
xmedia_vo_zoom_ratio zoom_ratio; //按比例局部放大
|
||||
};
|
||||
} xmedia_vo_zoom_attr;
|
||||
|
||||
//定义边框属性
|
||||
typedef struct{
|
||||
xmedia_u32 width;
|
||||
xmedia_u32 color;
|
||||
}xmedia_vo_border;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool border_en;
|
||||
xmedia_vo_border border;
|
||||
} xmedia_vo_border_attr;
|
||||
|
||||
//定义镜像属性
|
||||
typedef struct {
|
||||
xmedia_bool mirror_en;
|
||||
xmedia_bool flip_en;
|
||||
} xmedia_vo_mirror_attr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
ccflags-y += -I$(srctree)/product/update
|
||||
|
||||
obj-y += xmedia_main.o
|
||||
@@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
#include "update.h"
|
||||
|
||||
static int do_xmediaapp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
auto_update();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(xmediaapp, 1, 0, do_xmediaapp,
|
||||
"xmediaapp - Xmedia Application.\n",
|
||||
"Run auto update and others business.\n");
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
ccflags-y += -I$(srctree)/product/update/flash
|
||||
ccflags-y += -I$(srctree)/product/update/store
|
||||
|
||||
obj-y += auto_update_adapter.o
|
||||
obj-y += update.o
|
||||
|
||||
obj-y += flash/
|
||||
obj-y += store/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __AUTO_UPDATE_ADAPTER_H__
|
||||
#define __AUTO_UPDATE_ADAPTER_H__
|
||||
|
||||
/*
|
||||
* On success, return 0. otherwise it will return -1.
|
||||
*/
|
||||
int do_auto_update(void);
|
||||
|
||||
#endif
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __CHIP_ADAPTER_H__
|
||||
#define __CHIP_ADAPTER_H__
|
||||
|
||||
#ifndef LOAD_ADDR
|
||||
|
||||
#if defined(CONFIG_TARGET_XM720XXX)
|
||||
#define LOAD_ADDR ((unsigned char *)0x42000000)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TARGET_XM760XXX)
|
||||
#define LOAD_ADDR ((unsigned char *)0x41000000)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TARGET_RATELVXX)
|
||||
#define LOAD_ADDR ((unsigned char *)0x3a000000)
|
||||
#endif
|
||||
|
||||
#endif /* LOAD_ADDR */
|
||||
|
||||
typedef enum {
|
||||
AD_BOOTFROM_EMMC = 0xF1,
|
||||
AD_BOOTFROM_NAND,
|
||||
AD_BOOTFROM_SPINAND,
|
||||
AD_BOOTFROM_SPINOR,
|
||||
AD_BOOTFROM_BUTT
|
||||
} AD_BOOT_TYPE;
|
||||
|
||||
#if defined(CONFIG_TARGET_RATELVXX)
|
||||
static int get_boot_info(void)
|
||||
{
|
||||
unsigned int reg_val, boot_mode;
|
||||
int boot_media = 0xFF;
|
||||
|
||||
reg_val = readl(REG_START_FLAG);
|
||||
boot_mode = BOOT_SOURCE(reg_val);
|
||||
|
||||
switch (boot_mode) {
|
||||
case BOOT_FROM_NAND:
|
||||
boot_media = AD_BOOTFROM_NAND;
|
||||
break;
|
||||
case BOOT_FROM_SPI:
|
||||
boot_media = AD_BOOTFROM_SPINOR;
|
||||
break;
|
||||
case BOOT_FROM_EMMC:
|
||||
boot_media = AD_BOOTFROM_EMMC;
|
||||
break;
|
||||
default:
|
||||
#ifdef CONFIG_LOTUS_FPGA
|
||||
boot_media = AD_BOOTFROM_SPINOR;
|
||||
#else
|
||||
boot_media = 0xFF;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return boot_media;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_TARGET_XMORCA)
|
||||
static int get_boot_info(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl((void *)(SYS_CTRL_REG_BASE + REG_SYSSTAT));
|
||||
if (get_sys_boot_mode(reg) == BOOT_FROM_SPI_NOR) {
|
||||
/* SFC_DEVICE_MODE:0:SPINOR 1:SPINAND */
|
||||
if (get_spi_device_type(reg)) {
|
||||
/* SPINAND */
|
||||
return AD_BOOTFROM_NAND;
|
||||
} else {
|
||||
/* SPINOR */
|
||||
return AD_BOOTFROM_SPINOR;
|
||||
}
|
||||
} else if (get_sys_boot_mode(reg) == BOOT_FROM_SPI_NAND) {
|
||||
return AD_BOOTFROM_NAND;
|
||||
} else if (get_sys_boot_mode(reg) == BOOT_FROM_EMMC_4BITS ||
|
||||
get_sys_boot_mode(reg) == BOOT_FROM_EMMC_8BITS) {
|
||||
return AD_BOOTFROM_EMMC;
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
#else
|
||||
/* CONFIG_TARGET_XM720XXX | CONFIG_TARGET_XM760XXX */
|
||||
static int get_boot_info(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl((void *)(SYS_CTRL_REG_BASE + REG_SYSSTAT));
|
||||
if (get_sys_boot_mode(reg) == BOOT_FROM_SPI) {
|
||||
/* SFC_DEVICE_MODE:0:SPINOR 1:SPINAND */
|
||||
if (get_spi_device_type(reg)) {
|
||||
/* SPINAND */
|
||||
return AD_BOOTFROM_NAND;
|
||||
} else {
|
||||
/* SPINOR */
|
||||
return AD_BOOTFROM_SPINOR;
|
||||
}
|
||||
} else if (get_sys_boot_mode(reg) == BOOT_FROM_NAND) {
|
||||
return AD_BOOTFROM_NAND;
|
||||
} else if (get_sys_boot_mode(reg) == BOOT_FROM_EMMC) {
|
||||
return AD_BOOTFROM_EMMC;
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
#endif /* CONFIG_TARGET_RATELVXX */
|
||||
|
||||
#endif /* __CHIP_ADAPTER_H__ */
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
ccflags-y += -I$(srctree)/product/update
|
||||
ccflags-y += -I$(srctree)/lotus/misc
|
||||
|
||||
obj-$(CONFIG_CMD_SF) += au_spinor_flash.o
|
||||
obj-$(CONFIG_CMD_NAND) += au_nand_flash.o
|
||||
obj-$(CONFIG_SUPPORT_EMMC_BOOT) += au_emmc_flash.o
|
||||
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
#include <mmc.h>
|
||||
#include <sparse_format.h>
|
||||
#include <unsparse.h>
|
||||
|
||||
#include "update_comm.h"
|
||||
|
||||
#define EMMC_SUCCESS UP_SUCCESS
|
||||
#define EMMC_FAILURE UP_FAILURE
|
||||
|
||||
#define EMMC_BLOCK_SHIFT 9
|
||||
#define EMMC_BLOCK_SIZE (1 << EMMC_BLOCK_SHIFT)
|
||||
|
||||
int au_emmc_flash_init(void)
|
||||
{
|
||||
struct mmc *mmc = find_mmc_device(0);
|
||||
|
||||
if (!mmc) {
|
||||
printf("%s:find mmc device failed\n", __func__);
|
||||
return EMMC_FAILURE;
|
||||
}
|
||||
|
||||
(void)mmc_init(mmc);
|
||||
|
||||
return EMMC_SUCCESS;
|
||||
}
|
||||
|
||||
int au_emmc_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
#if 0
|
||||
struct mmc *mmc = find_mmc_device(0);
|
||||
|
||||
if (!mmc) {
|
||||
printf("%s:find mmc device failed\n", __func__);
|
||||
return EMMC_FAILURE;
|
||||
}
|
||||
|
||||
if (len % MMC_MAX_BLOCK_LEN) {
|
||||
blk_derase(mmc_get_blk_desc(mmc), (offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT) + 1);
|
||||
} else {
|
||||
blk_derase(mmc_get_blk_desc(mmc), (offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT));
|
||||
}
|
||||
#endif
|
||||
return EMMC_SUCCESS;
|
||||
}
|
||||
|
||||
int au_emmc_flash_write(unsigned long offset, unsigned long len,
|
||||
unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
struct mmc *mmc = find_mmc_device(0);
|
||||
|
||||
if (!mmc) {
|
||||
printf("%s:find mmc device failed\n", __func__);
|
||||
return EMMC_FAILURE;
|
||||
}
|
||||
|
||||
if (len % MMC_MAX_BLOCK_LEN) {
|
||||
blk_dwrite(mmc_get_blk_desc(mmc), (offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT) + 1, buf);
|
||||
} else {
|
||||
blk_dwrite(mmc_get_blk_desc(mmc), (offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT), buf);
|
||||
}
|
||||
|
||||
return EMMC_SUCCESS;
|
||||
}
|
||||
|
||||
int au_emmc_flash_ext4_write(unsigned long offset, unsigned long len,
|
||||
unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
struct mmc *mmc = find_mmc_device(0);
|
||||
int retlen;
|
||||
|
||||
if (!mmc) {
|
||||
printf("%s:find mmc device failed\n", __func__);
|
||||
return EMMC_FAILURE;
|
||||
}
|
||||
|
||||
if (len % MMC_MAX_BLOCK_LEN)
|
||||
retlen = ext4_unsparse(mmc, 0, buf,
|
||||
(offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT) + 1);
|
||||
else
|
||||
retlen = ext4_unsparse(mmc, 0, buf,
|
||||
(offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT));
|
||||
return retlen;
|
||||
}
|
||||
|
||||
int au_emmc_flash_get_block_size(void)
|
||||
{
|
||||
return (int)EMMC_BLOCK_SIZE;
|
||||
}
|
||||
#endif // CONFIG_AUTO_UPDATE
|
||||
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __AU_EMMC_FLASH_H__
|
||||
#define __AU_EMMC_FLASH_H__
|
||||
|
||||
#ifdef CONFIG_SUPPORT_EMMC_BOOT
|
||||
int au_emmc_flash_init(void);
|
||||
int au_emmc_flash_erase(unsigned long offset, unsigned long len);
|
||||
int au_emmc_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_emmc_flash_ext4_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_emmc_flash_get_block_size(void);
|
||||
#else
|
||||
int au_emmc_flash_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_emmc_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int au_emmc_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_emmc_flash_ext4_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_emmc_flash_get_block_size(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,217 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
#include <nand.h>
|
||||
#include "update_comm.h"
|
||||
|
||||
#define PERCENT_VALUE 100
|
||||
#define NAND_SUCCESS UP_SUCCESS
|
||||
#define NAND_FAILURE UP_FAILURE
|
||||
|
||||
static struct mtd_info *g_nand_flash = NULL;
|
||||
|
||||
static void schedule_notify(unsigned long offset, unsigned long len, unsigned long off_start)
|
||||
{
|
||||
int percent_complete = -1;
|
||||
unsigned long long n;
|
||||
|
||||
do {
|
||||
n = (unsigned long long)(offset - off_start) * PERCENT_VALUE;
|
||||
int percent;
|
||||
|
||||
do_div(n, len);
|
||||
percent = (int)n;
|
||||
|
||||
/* output progress message only at whole percent
|
||||
* steps to reduce the number of messages
|
||||
* printed on (slow) serial consoles
|
||||
*/
|
||||
if (percent != percent_complete)
|
||||
printf("\rOperation at 0x%lx -- %3d%% complete.", offset, percent);
|
||||
} while (0);
|
||||
}
|
||||
|
||||
int au_nand_flash_init(void)
|
||||
{
|
||||
g_nand_flash = nand_info[0];
|
||||
if (g_nand_flash == NULL) {
|
||||
printf("nand_info() fail.\n");
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
int au_nand_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
int ret;
|
||||
unsigned long erase_len;
|
||||
unsigned long erase_step;
|
||||
unsigned long length;
|
||||
nand_erase_options_t opts;
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (nand_flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
|
||||
length = len;
|
||||
erase_step = nand_flash->erasesize;
|
||||
erase_len = length;
|
||||
opts.length = erase_step;
|
||||
opts.offset = offset;
|
||||
opts.quiet = 1;
|
||||
|
||||
while (length > 0) {
|
||||
if (length < erase_step)
|
||||
erase_step = length;
|
||||
|
||||
ret = nand_erase_opts(nand_flash, &opts);
|
||||
if (ret) {
|
||||
printf("nand_erase_opts() fail.\n");
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
length -= erase_step;
|
||||
opts.offset += erase_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(opts.offset, erase_len, offset);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
int au_nand_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
unsigned long offset_notify;
|
||||
unsigned long write_start;
|
||||
unsigned long write_len;
|
||||
unsigned long write_step;
|
||||
size_t length;
|
||||
unsigned char *pbuf = buf;
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (nand_flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
offset = offset & (nand_flash->writesize - 1) ? (size_t)(offset +
|
||||
(nand_flash->writesize - offset % nand_flash->writesize)) : offset;
|
||||
|
||||
length = len & (nand_flash->erasesize - 1) ? (size_t)(len +
|
||||
(nand_flash->erasesize - len % nand_flash->erasesize)) : len;
|
||||
|
||||
write_step = length;
|
||||
write_start = offset;
|
||||
offset_notify = offset;
|
||||
write_len = length;
|
||||
|
||||
while (length > 0) {
|
||||
size_t rw_size = write_step;
|
||||
|
||||
ret = nand_write_skip_bad(nand_flash, (size_t)offset, &rw_size, NULL, lim, (u_char *)pbuf, 0);
|
||||
if (ret) {
|
||||
printf("NAND write to offset %lx failed %d\n", offset, ret);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
offset += write_step;
|
||||
pbuf += write_step;
|
||||
length -= write_step;
|
||||
offset_notify += write_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset_notify, write_len, write_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
int au_nand_flash_yaffs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
size_t rw_size = len;
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (nand_flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
ret = nand_write_yaffs_skip_bad(nand_flash, offset, &rw_size, (u_char *)buf);
|
||||
if (ret) {
|
||||
printf("Write yaffs fail !!\n");
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
printf("Write yaffs done\n");
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
int au_nand_flash_ubifs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = au_nand_flash_write(offset, len, lim, buf);
|
||||
|
||||
printf("Write ubifs done\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get count of area's bad block for nand flash */
|
||||
int au_nand_flash_get_bad_blkcnt(unsigned long offset, unsigned long len)
|
||||
{
|
||||
int count = 0;
|
||||
unsigned long block_offset = 0;
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (nand_flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
if (offset & (nand_flash->erasesize - 1))
|
||||
block_offset = offset & (nand_flash->erasesize - 1);
|
||||
|
||||
if (len & (nand_flash->erasesize - 1))
|
||||
len = ALIGN(len, nand_flash->erasesize);
|
||||
|
||||
for (int i = 0; i < len / nand_flash->erasesize; i++) {
|
||||
if (nand_block_isbad(nand_flash, offset))
|
||||
count++;
|
||||
offset += nand_flash->erasesize - block_offset;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int au_nand_flash_get_page_size(int with_oob)
|
||||
{
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (with_oob) {
|
||||
return (nand_flash->writesize + nand_flash->oobsize);
|
||||
} else {
|
||||
return (nand_flash->writesize);
|
||||
}
|
||||
}
|
||||
|
||||
int au_nand_flash_get_erase_size(void)
|
||||
{
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
return nand_flash->erasesize;
|
||||
}
|
||||
|
||||
#endif // CONFIG_AUTO_UPDATE
|
||||
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __AU_NAND_FLASH_H__
|
||||
#define __AU_NAND_FLASH_H__
|
||||
|
||||
#ifdef CONFIG_CMD_NAND
|
||||
int au_nand_flash_init(void);
|
||||
int au_nand_flash_erase(unsigned long offset, unsigned long len);
|
||||
int au_nand_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_nand_flash_yaffs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_nand_flash_ubifs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_nand_flash_get_bad_blkcnt(unsigned long offset, unsigned long len);
|
||||
int au_nand_flash_get_page_size(int with_oob);
|
||||
int au_nand_flash_get_erase_size(void);
|
||||
#else
|
||||
int au_nand_flash_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_yaffs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_ubifs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_get_bad_blkcnt(unsigned long offset, unsigned long len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int au_nand_flash_get_pages_size(int with_oob)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int au_nand_flash_get_erase_size(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,205 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
#include <spi_flash.h>
|
||||
#include "update_comm.h"
|
||||
|
||||
#define PERCENT_VALUE 100
|
||||
#define SPINOR_SUCCESS UP_SUCCESS
|
||||
#define SPINOR_FAILURE UP_FAILURE
|
||||
|
||||
static struct spi_flash *g_spinor_flash;
|
||||
|
||||
static void schedule_notify(unsigned long offset, unsigned long len, unsigned long off_start)
|
||||
{
|
||||
int percent_complete = -1;
|
||||
unsigned long long n;
|
||||
|
||||
do {
|
||||
n = (unsigned long long)(offset - off_start) * PERCENT_VALUE;
|
||||
int percent;
|
||||
|
||||
do_div(n, len);
|
||||
percent = (int)n;
|
||||
|
||||
/* output progress message only at whole percent
|
||||
* steps to reduce the number of messages
|
||||
* printed on (slow) serial consoles
|
||||
*/
|
||||
if (percent != percent_complete) {
|
||||
printf("\rOperation at 0x%lx -- %3d%% complete.", offset, percent);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
int au_spinor_flash_init(void)
|
||||
{
|
||||
g_spinor_flash = spi_flash_probe(0, 0, 0, 0);
|
||||
if (g_spinor_flash == NULL) {
|
||||
printf("spi_flash_probe fail.\n");
|
||||
return SPINOR_FAILURE;
|
||||
};
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
int au_spinor_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
int ret = SPINOR_SUCCESS;
|
||||
struct spi_flash *flash = g_spinor_flash;
|
||||
struct mtd_info_ex *spiflash_info = get_spiflash_info();
|
||||
unsigned long erase_start, erase_len, erase_step;
|
||||
|
||||
if (flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
erase_start = offset;
|
||||
erase_len = len;
|
||||
erase_step = spiflash_info->erasesize;
|
||||
|
||||
while (len > 0) {
|
||||
if (len < erase_step)
|
||||
erase_step = len;
|
||||
#if (UBOOTVERSION == 202001)
|
||||
ret = spi_flash_erase(flash, (u32)offset, erase_step);
|
||||
#elif (UBOOTVERSION == 201611)
|
||||
ret = flash->erase(flash, (u32)offset, erase_step);
|
||||
#else
|
||||
printf("%s:invalid uboot version!\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("%s: erase fail.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
len -= erase_step;
|
||||
offset += erase_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset, erase_len, erase_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
int au_spinor_flash_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
int ret;
|
||||
struct spi_flash *flash = g_spinor_flash;
|
||||
unsigned long write_start, write_len, write_step;
|
||||
unsigned char *pbuf = buf;
|
||||
struct mtd_info_ex *spiflash_info = get_spiflash_info();
|
||||
|
||||
if (flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
write_start = offset;
|
||||
write_len = len;
|
||||
write_step = spiflash_info->erasesize;
|
||||
|
||||
while (len > 0) {
|
||||
if (len < write_step)
|
||||
write_step = len;
|
||||
|
||||
ret = flash->write(flash, offset, write_step, pbuf);
|
||||
if (ret) {
|
||||
printf("SPINOR write to offset %lx failed %d\n", offset, ret);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
offset += write_step;
|
||||
pbuf += write_step;
|
||||
len -= write_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset, write_len, write_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
int au_spinor_flash_jffs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
int ret;
|
||||
struct spi_flash *flash = g_spinor_flash;
|
||||
unsigned long write_start, write_len, write_step;
|
||||
unsigned char *pbuf = buf;
|
||||
struct mtd_info_ex *spiflash_info = get_spiflash_info();
|
||||
|
||||
if (flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
write_start = offset;
|
||||
write_len = len;
|
||||
write_step = spiflash_info->erasesize;
|
||||
|
||||
while (len > 0) {
|
||||
if (len < write_step)
|
||||
write_step = len;
|
||||
|
||||
ret = flash->write(flash, offset, write_step, pbuf);
|
||||
if (ret) {
|
||||
printf("SPINOR write to offset %lx failed %d\n", offset, ret);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
offset += write_step;
|
||||
pbuf += write_step;
|
||||
len -= write_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset, write_len, write_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
int au_spinor_flash_ubifs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
int ret;
|
||||
struct spi_flash *flash = g_spinor_flash;
|
||||
unsigned long write_start, write_len, write_step;
|
||||
unsigned char *pbuf = buf;
|
||||
struct mtd_info_ex *spiflash_info = get_spiflash_info();
|
||||
|
||||
if (flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
write_start = offset;
|
||||
write_len = len;
|
||||
write_step = spiflash_info->erasesize;
|
||||
|
||||
while (len > 0) {
|
||||
if (len < write_step)
|
||||
write_step = len;
|
||||
|
||||
ret = flash->write(flash, offset, write_step, pbuf);
|
||||
if (ret) {
|
||||
printf("SPINOR write to offset %lx failed %d\n", offset, ret);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
offset += write_step;
|
||||
pbuf += write_step;
|
||||
len -= write_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset, write_len, write_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __AU_SPINORE_FLASH_H__
|
||||
#define __AU_SPINORE_FLASH_H__
|
||||
|
||||
#ifdef CONFIG_CMD_SF
|
||||
int au_spinor_flash_init(void);
|
||||
int au_spinor_flash_erase(unsigned long offset, unsigned long len);
|
||||
int au_spinor_flash_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf);
|
||||
int au_spinor_flash_jffs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf);
|
||||
int au_spinor_flash_ubifs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf);
|
||||
#else
|
||||
int au_spinor_flash_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_spinor_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_spinor_flash_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_spinor_flash_jffs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_spinor_flash_ubifs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
ccflags-y += -I$(srctree)/product/update
|
||||
|
||||
obj-y += store_mmc.o
|
||||
obj-y += store_usb.o
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_SD_UPDATE == 1)
|
||||
#include <mmc.h>
|
||||
#include "update_comm.h"
|
||||
|
||||
int store_mmc_init(void)
|
||||
{
|
||||
struct mmc *mmc;
|
||||
unsigned int dev_num = 0;
|
||||
|
||||
agin:
|
||||
mmc = find_mmc_device(dev_num);
|
||||
if (mmc == NULL) {
|
||||
printf("No mmc driver found!\n");
|
||||
return UP_FAILURE;
|
||||
}
|
||||
|
||||
if (!IS_SD(mmc)) {
|
||||
dev_num++;
|
||||
goto agin;
|
||||
}
|
||||
|
||||
if (((unsigned long)mmc->block_dev.vendor[0] == 0) ||
|
||||
((unsigned long)mmc->block_dev.product[0] == 0)) {
|
||||
printf("*No SD card found!\n");
|
||||
return UP_FAILURE;
|
||||
}
|
||||
return UP_SUCCESS;
|
||||
}
|
||||
|
||||
void store_mmc_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
int mmc_get_target_dev(void)
|
||||
{
|
||||
struct mmc *mmc = NULL;
|
||||
int dev_num = 0;
|
||||
|
||||
agin:
|
||||
mmc = find_mmc_device(dev_num);
|
||||
if (mmc == NULL) {
|
||||
printf("Error: No mmc driver found!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!IS_SD(mmc)) {
|
||||
dev_num++;
|
||||
goto agin;
|
||||
}
|
||||
|
||||
return dev_num;
|
||||
}
|
||||
|
||||
#endif // CONFIG_AUTO_SD_UPDATE
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __STORE_MMC_H__
|
||||
#define __STORE_MMC_H__
|
||||
|
||||
int store_mmc_init(void);
|
||||
|
||||
int store_mmc_deinit(void);
|
||||
|
||||
int mmc_get_target_dev(void);
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_USB_UPDATE == 1)
|
||||
#include <usb.h>
|
||||
#include "update_comm.h"
|
||||
|
||||
int store_usb_init(void)
|
||||
{
|
||||
int ret;
|
||||
#ifndef CONFIG_XMEDIA_MC
|
||||
try_again:
|
||||
if (usb_stop() < 0) {
|
||||
debug("usb_stop failed\n");
|
||||
return UP_FAILURE;
|
||||
}
|
||||
/* delay for 1000 ms */
|
||||
mdelay(1000);
|
||||
ret = usb_init();
|
||||
if (ret == -ESRCH) {
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
debug("usb_init failed!\n");
|
||||
return UP_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* check whether a storage device is attached (assume that it's
|
||||
* a USB memory stick, since nothing else should be attached).
|
||||
*/
|
||||
ret = usb_stor_scan(0);
|
||||
if (ret == -1) {
|
||||
debug("No USB device found. Not initialized!\n");
|
||||
return UP_FAILURE;
|
||||
} else {
|
||||
return UP_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
return UP_FAILURE;
|
||||
}
|
||||
|
||||
void store_usb_deinit(void)
|
||||
{
|
||||
#ifndef CONFIG_XMEDIA_MC
|
||||
usb_stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // CONFIG_AUTO_USB_UPDATE
|
||||
@@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __STORE_USB_H__
|
||||
#define __STORE_USB_H__
|
||||
|
||||
int store_usb_init(void);
|
||||
|
||||
int store_usb_deinit(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
#include <linux/io.h>
|
||||
#include "update_comm.h"
|
||||
#include "auto_update_adapter.h"
|
||||
|
||||
#if defined(CONFIG_TARGET_RATELVXX)
|
||||
static int check_update_button(void)
|
||||
{
|
||||
/* to add some judgement if neccessary */
|
||||
unsigned int sd_update_flag;
|
||||
|
||||
printf("board check_update_button bootflag:0x%x REG_ROM_RUN_TIME:%d\n",
|
||||
readl(REG_START_FLAG), readl(REG_ROM_RUN_TIME));
|
||||
|
||||
/* sd update */
|
||||
sd_update_flag = readl(REG_START_FLAG);
|
||||
if (SD_UPDATE_MODE(sd_update_flag))
|
||||
return UP_TRUE;
|
||||
|
||||
/* usb device update */
|
||||
if (SD_UDISK_UPDATE_CHECK_NEED(sd_update_flag))
|
||||
return UP_TRUE; /* update enable */
|
||||
else
|
||||
return UP_FALSE;
|
||||
}
|
||||
|
||||
static void clear_update_flag(void)
|
||||
{
|
||||
/* REG_UPDATE_MODE_CLEAR: write only */
|
||||
writel(0, REG_START_FLAG);
|
||||
}
|
||||
|
||||
#else /* CONFIG_TARGET_RATELVXX */
|
||||
|
||||
#define REG_SYS_BOOT6 0x0148
|
||||
#define SD_UPDAT_MAGIC 0x444f574e
|
||||
|
||||
#define BIT_UPDATE_FLAG 2
|
||||
#define BIT_UPDATE_FLAG_CLEAR 0
|
||||
#define REG_SYS_STAT 0x008C
|
||||
#define REG_MISC_CTRL51 0x8200
|
||||
|
||||
#ifndef REG_SC_DDRT14
|
||||
#define REG_SC_DDRT14 0x00C8
|
||||
#endif
|
||||
|
||||
#define REG_UPDATE_MODE (SYS_CTRL_REG_BASE + REG_SYS_STAT)
|
||||
#define REG_UPDATE_MODE_CLEAR (SYS_CTRL_REG_BASE + REG_MISC_CTRL51)
|
||||
#define REG_BOOTSTRAP_FLAG (SYS_CTRL_REG_BASE + REG_SC_DDRT14)
|
||||
|
||||
static int check_update_button(void)
|
||||
{
|
||||
unsigned int sd_update_flag;
|
||||
unsigned int update_mode = 0;
|
||||
|
||||
/* sd update */
|
||||
sd_update_flag = readl(SYS_CTRL_REG_BASE + REG_SYS_BOOT6);
|
||||
if (sd_update_flag == SD_UPDAT_MAGIC) {
|
||||
printf("SD card upgrade\n");
|
||||
return UP_TRUE;
|
||||
}
|
||||
|
||||
/* usb device update */
|
||||
update_mode = readl(REG_UPDATE_MODE);
|
||||
update_mode = ((update_mode >> BIT_UPDATE_FLAG) & 0x01);
|
||||
if (update_mode) {
|
||||
printf("U disk upgrade\n");
|
||||
return UP_TRUE;
|
||||
} else {
|
||||
printf("Upgrade flag disabled\n");
|
||||
return UP_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_update_flag(void)
|
||||
{
|
||||
unsigned int clear_value = 0x1;
|
||||
|
||||
clear_value = (clear_value << BIT_UPDATE_FLAG_CLEAR);
|
||||
/* update mode clear */
|
||||
writel(clear_value, REG_UPDATE_MODE_CLEAR);
|
||||
/* set bootstrap flag */
|
||||
/* 0:主flash, 主uboot分区启动 */
|
||||
writel(0x00, REG_BOOTSTRAP_FLAG);
|
||||
}
|
||||
#endif /* CONFIG_TARGET_RATELVXX */
|
||||
|
||||
void auto_update(void)
|
||||
{
|
||||
int update_flag = -1;
|
||||
|
||||
printf("%s entry.\n", __func__);
|
||||
|
||||
if (check_update_button()) {
|
||||
update_flag = do_auto_update();
|
||||
clear_update_flag();
|
||||
if (update_flag == 0) {
|
||||
printf("%s ok, reset.\n", __func__);
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s exit.\n", __func__);
|
||||
}
|
||||
|
||||
#endif // CONFIG_AUTO_UPDATE == 1
|
||||
@@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __UPDATE_H__
|
||||
#define __UPDATE_H__
|
||||
|
||||
void auto_update(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __UPDATE_COMM_H__
|
||||
#define __UPDATE_COMM_H__
|
||||
|
||||
#define UP_TRUE 1
|
||||
#define UP_FALSE 0
|
||||
|
||||
#define UP_SUCCESS 0
|
||||
#define UP_FAILURE -1
|
||||
|
||||
#define AU_DEBUG 1
|
||||
#undef debug_print
|
||||
#ifdef AU_DEBUG
|
||||
#define debug_print(fmt, args...) printf(fmt, ##args)
|
||||
#else
|
||||
#define debug_print(fmt, args...)
|
||||
#endif /* AU_DEBUG */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user