msm: camera: sensor: Add changes for XCFA in TPG

Add generic changes to support RGBIR, 3x3 and 4x4
XCFA from TPG XML.

CRs-Fixed: 3175994
External Impact: No
Change-Id: I129e20eb5db2bf2f168202f4854de62926eb613b
Signed-off-by: Rishab Garg <quic_rishabg@quicinc.com>
This commit is contained in:
Rishab Garg
2022-02-03 11:54:15 +05:30
committed by Camera Software Integration
parent 80f7e36a9e
commit 9cbc7cd024
6 changed files with 904 additions and 73 deletions

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2021, The Linux Foundation. All rights reserved. * Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include "cam_tpg_core.h" #include "cam_tpg_core.h"
@@ -388,15 +389,31 @@ static int cam_tpg_validate_cmd_descriptor(
break; break;
} }
case TPG_CMD_TYPE_STREAM_CONFIG: { case TPG_CMD_TYPE_STREAM_CONFIG: {
if (cmd_header->size != sizeof(struct tpg_stream_config_t)) { if (cmd_header->cmd_version == 3 &&
cmd_header->size != sizeof(struct tpg_stream_config_v3_t)) {
CAM_ERR(CAM_TPG, "Got invalid stream config command recv: %d exp: %d", CAM_ERR(CAM_TPG, "Got invalid stream config command recv: %d exp: %d",
cmd_header->size, cmd_header->size,
sizeof(struct tpg_stream_config_t)); sizeof(struct tpg_stream_config_v3_t));
rc = -EINVAL;
goto end;
} else if (cmd_header->cmd_version == 2 &&
cmd_header->size != sizeof(struct tpg_stream_config_t)) {
CAM_ERR(CAM_TPG, "Got invalid stream config cmd recv: %d exp: %d",
cmd_header->size,
sizeof(struct tpg_stream_config_t));
rc = -EINVAL;
goto end;
} else if (cmd_header->cmd_version == 1 &&
cmd_header->size != sizeof(struct tpg_old_stream_config_t)) {
CAM_ERR(CAM_TPG, "Got invalid stream config cmd recv: %d exp: %d",
cmd_header->size,
sizeof(struct tpg_old_stream_config_t));
rc = -EINVAL; rc = -EINVAL;
goto end; goto end;
} }
CAM_INFO(CAM_TPG, "Got stream config cmd");
*cmd_type = TPG_CMD_TYPE_STREAM_CONFIG; *cmd_type = TPG_CMD_TYPE_STREAM_CONFIG;
break; break;
} }
@@ -437,6 +454,7 @@ static int cam_tpg_cmd_buf_parse(
for (i = 0; i < packet->num_cmd_buf; i++) { for (i = 0; i < packet->num_cmd_buf; i++) {
uint32_t cmd_type = TPG_CMD_TYPE_INVALID; uint32_t cmd_type = TPG_CMD_TYPE_INVALID;
uintptr_t cmd_addr; uintptr_t cmd_addr;
struct tpg_command_header_t *cmd_header = NULL;
cmd_desc = (struct cam_cmd_buf_desc *) cmd_desc = (struct cam_cmd_buf_desc *)
((uint32_t *)&packet->payload + ((uint32_t *)&packet->payload +
@@ -448,14 +466,24 @@ static int cam_tpg_cmd_buf_parse(
if (rc < 0) if (rc < 0)
goto end; goto end;
cmd_header = (struct tpg_command_header_t *)cmd_addr;
switch (cmd_type) { switch (cmd_type) {
case TPG_CMD_TYPE_GLOBAL_CONFIG: case TPG_CMD_TYPE_GLOBAL_CONFIG:
rc = tpg_hw_copy_global_config(&tpg_dev->tpg_hw, rc = tpg_hw_copy_global_config(&tpg_dev->tpg_hw,
(struct tpg_global_config_t *)cmd_addr); (struct tpg_global_config_t *)cmd_addr);
break; break;
case TPG_CMD_TYPE_STREAM_CONFIG: { case TPG_CMD_TYPE_STREAM_CONFIG: {
rc = tpg_hw_add_stream(&tpg_dev->tpg_hw, if (cmd_header->cmd_version == 3) {
(struct tpg_stream_config_t *)cmd_addr); rc = tpg_hw_add_stream_v3(&tpg_dev->tpg_hw,
(struct tpg_stream_config_v3_t *)cmd_addr);
CAM_DBG(CAM_TPG, "Stream config v3");
} else if (cmd_header->cmd_version == 1 ||
cmd_header->cmd_version == 2) {
rc = tpg_hw_add_stream(&tpg_dev->tpg_hw,
(struct tpg_stream_config_t *)cmd_addr);
CAM_DBG(CAM_TPG, "Stream config");
}
break; break;
} }
case TPG_CMD_TYPE_ILLUMINATION_CONFIG: case TPG_CMD_TYPE_ILLUMINATION_CONFIG:

View File

@@ -228,6 +228,75 @@ int dump_stream_configs(int hw_idx,
return 0; return 0;
} }
int dump_stream_configs_v3(int hw_idx,
int stream_idx,
struct tpg_stream_config_v3_t *stream)
{
#ifdef __TPG_DEBUG_DUMP__
CAM_DBG(CAM_TPG, "TPG[%d][%d] pattern_type : %s",
hw_idx,
stream_idx,
tpg_pattern_type_strings[stream->pattern_type]);
CAM_DBG(CAM_TPG, "TPG[%d][%d] cb_mode : %s",
hw_idx,
stream_idx,
tpg_color_bar_mode_strings[stream->cb_mode]);
CAM_DBG(CAM_TPG, "TPG[%d][%d] frame_count : %d",
hw_idx,
stream_idx,
stream->frame_count);
CAM_DBG(CAM_TPG, "TPG[%d][%d] stream_type : %s",
hw_idx,
stream_idx,
tpg_stream_type_strings[stream->stream_type]);
CAM_DBG(CAM_TPG, "TPG[%d][%d] left : %d",
hw_idx,
stream_idx,
stream->stream_dimension.left);
CAM_DBG(CAM_TPG, "TPG[%d][%d] top : %d",
hw_idx,
stream_idx,
stream->stream_dimension.top);
CAM_DBG(CAM_TPG, "TPG[%d][%d] width : %d",
hw_idx,
stream_idx,
stream->stream_dimension.width);
CAM_DBG(CAM_TPG, "TPG[%d][%d] height : %d",
hw_idx,
stream_idx,
stream->stream_dimension.height);
CAM_DBG(CAM_TPG, "TPG[%d][%d] pixel_depth : %d",
hw_idx,
stream_idx,
stream->pixel_depth);
CAM_DBG(CAM_TPG, "TPG[%d][%d] cfa_arrangement : %d",
hw_idx,
stream_idx,
stream->cfa_arrangement);
CAM_DBG(CAM_TPG, "TPG[%d][%d] output_format : %s",
hw_idx,
stream_idx,
tpg_image_format_type_strings[stream->output_format]);
CAM_DBG(CAM_TPG, "TPG[%d][%d] vc : 0x%x",
hw_idx,
stream_idx,
stream->vc);
CAM_DBG(CAM_TPG, "TPG[%d][%d] dt : 0x%x",
hw_idx,
stream_idx,
stream->dt);
CAM_DBG(CAM_TPG, "TPG[%d][%d] hbi : %d",
hw_idx,
stream_idx,
stream->hbi);
CAM_DBG(CAM_TPG, "TPG[%d][%d] vbi : %d",
hw_idx,
stream_idx,
stream->vbi);
#endif
return 0;
}
static int tpg_hw_soc_disable(struct tpg_hw *hw) static int tpg_hw_soc_disable(struct tpg_hw *hw)
{ {
@@ -239,13 +308,15 @@ static int tpg_hw_soc_disable(struct tpg_hw *hw)
} }
rc = cam_soc_util_disable_platform_resource(hw->soc_info, true, false); rc = cam_soc_util_disable_platform_resource(hw->soc_info, true, false);
if (rc) if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] Disable platform failed %d", CAM_ERR(CAM_TPG, "TPG[%d] Disable platform failed %d",
hw->hw_idx, rc); hw->hw_idx, rc);
return rc;
}
if ((rc = cam_cpas_stop(hw->cpas_handle))) { if ((rc = cam_cpas_stop(hw->cpas_handle))) {
CAM_ERR(CAM_TPG, "TPG[%d] CPAS stop failed", CAM_ERR(CAM_TPG, "TPG[%d] CPAS stop failed",
hw->hw_idx); hw->hw_idx);
return rc;
} else { } else {
hw->state = TPG_HW_STATE_HW_DISABLED; hw->state = TPG_HW_STATE_HW_DISABLED;
} }
@@ -280,7 +351,7 @@ static int tpg_hw_soc_enable(
rc = cam_cpas_start(hw->cpas_handle, &ahb_vote, &axi_vote); rc = cam_cpas_start(hw->cpas_handle, &ahb_vote, &axi_vote);
if (rc) { if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] CPAS start failed", CAM_ERR(CAM_TPG, "TPG[%d] CPAS start failed",
hw->hw_idx); hw->hw_idx);
rc = -EFAULT; rc = -EFAULT;
goto end; goto end;
} }
@@ -289,7 +360,7 @@ static int tpg_hw_soc_enable(
clk_level, false); clk_level, false);
if (rc) { if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] enable platform failed", CAM_ERR(CAM_TPG, "TPG[%d] enable platform failed",
hw->hw_idx); hw->hw_idx);
goto stop_cpas; goto stop_cpas;
} }
hw->state = TPG_HW_STATE_HW_ENABLED; hw->state = TPG_HW_STATE_HW_ENABLED;
@@ -354,12 +425,67 @@ static int tpg_hw_start_default_new(struct tpg_hw *hw)
return 0; return 0;
} }
static int tpg_hw_start_default_new_v3(struct tpg_hw *hw)
{
int i = 0;
uint32_t stream_idx = 0;
int num_vcs = 0;
struct global_config_args globalargs = {0};
if (!hw || !hw->hw_info ||
!hw->hw_info->ops || !hw->hw_info->ops->process_cmd) {
CAM_ERR(CAM_TPG, "Invalid argument");
return -EINVAL;
}
dump_global_configs(hw->hw_idx, &hw->global_config);
for (i = 0; i < hw->hw_info->max_vc_channels; i++) {
int dt_slot = 0;
struct vc_config_args_v3 vc_config = {0};
struct list_head *pos = NULL, *pos_next = NULL;
struct tpg_hw_stream_v3 *entry = NULL, *vc_stream_entry = NULL;
if (hw->vc_slots[i].vc == -1)
break;
num_vcs++;
vc_config.vc_slot = i;
vc_config.num_dts = hw->vc_slots[i].stream_count;
vc_stream_entry = list_first_entry(&hw->vc_slots[i].head,
struct tpg_hw_stream_v3, list);
vc_config.stream = &vc_stream_entry->stream;
hw->hw_info->ops->process_cmd(hw,
TPG_CONFIG_VC, &vc_config);
list_for_each_safe(pos, pos_next, &hw->vc_slots[i].head) {
struct dt_config_args_v3 dt_config = {0};
entry = list_entry(pos, struct tpg_hw_stream_v3, list);
dump_stream_configs_v3(hw->hw_idx,
stream_idx++,
&entry->stream);
dt_config.vc_slot = i;
dt_config.dt_slot = dt_slot++;
dt_config.stream = &entry->stream;
hw->hw_info->ops->process_cmd(hw, TPG_CONFIG_DT, &dt_config);
}
}
globalargs.num_vcs = num_vcs;
globalargs.globalconfig = &hw->global_config;
hw->hw_info->ops->process_cmd(hw,
TPG_CONFIG_CTRL, &globalargs);
return 0;
}
int tpg_hw_dump_status(struct tpg_hw *hw) int tpg_hw_dump_status(struct tpg_hw *hw)
{ {
if (!hw || !hw->hw_info || !hw->hw_info->ops) if (!hw || !hw->hw_info || !hw->hw_info->ops)
return -EINVAL; return -EINVAL;
switch (hw->hw_info->version) { switch (hw->hw_info->version) {
case TPG_HW_VERSION_1_3: case TPG_HW_VERSION_1_3:
case TPG_HW_VERSION_1_3_1:
if (hw->hw_info->ops->dump_status) if (hw->hw_info->ops->dump_status)
hw->hw_info->ops->dump_status(hw, NULL); hw->hw_info->ops->dump_status(hw, NULL);
break; break;
@@ -385,14 +511,18 @@ int tpg_hw_start(struct tpg_hw *hw)
break; break;
case TPG_HW_VERSION_1_2: case TPG_HW_VERSION_1_2:
case TPG_HW_VERSION_1_3: case TPG_HW_VERSION_1_3:
case TPG_HW_VERSION_1_3_1:
if (hw->hw_info->ops->start) if (hw->hw_info->ops->start)
hw->hw_info->ops->start(hw, NULL); hw->hw_info->ops->start(hw, NULL);
tpg_hw_start_default_new(hw); if (hw->stream_version == 1)
tpg_hw_start_default_new(hw);
else if (hw->stream_version == 3)
tpg_hw_start_default_new_v3(hw);
cam_tpg_mem_dmp(hw->soc_info); cam_tpg_mem_dmp(hw->soc_info);
break; break;
default: default:
CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version", CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
hw->hw_idx); hw->hw_idx);
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
@@ -412,13 +542,25 @@ int tpg_hw_stop(struct tpg_hw *hw)
case TPG_HW_VERSION_1_1: case TPG_HW_VERSION_1_1:
case TPG_HW_VERSION_1_2: case TPG_HW_VERSION_1_2:
case TPG_HW_VERSION_1_3: case TPG_HW_VERSION_1_3:
if (hw->hw_info->ops->stop) case TPG_HW_VERSION_1_3_1:
if (hw->hw_info->ops->stop) {
rc = hw->hw_info->ops->stop(hw, NULL); rc = hw->hw_info->ops->stop(hw, NULL);
if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] hw stop failed %d",
hw->hw_idx, rc);
return rc;
}
}
rc = tpg_hw_soc_disable(hw); rc = tpg_hw_soc_disable(hw);
if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] hw soc disable failed %d",
hw->hw_idx, rc);
return rc;
}
break; break;
default: default:
CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version", CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
hw->hw_idx); hw->hw_idx);
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
@@ -441,11 +583,12 @@ int tpg_hw_acquire(struct tpg_hw *hw,
case TPG_HW_VERSION_1_1: case TPG_HW_VERSION_1_1:
case TPG_HW_VERSION_1_2: case TPG_HW_VERSION_1_2:
case TPG_HW_VERSION_1_3: case TPG_HW_VERSION_1_3:
case TPG_HW_VERSION_1_3_1:
// Start Cpas and enable required clocks // Start Cpas and enable required clocks
break; break;
default: default:
CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version", CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
hw->hw_idx); hw->hw_idx);
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
@@ -465,10 +608,11 @@ int tpg_hw_release(struct tpg_hw *hw)
case TPG_HW_VERSION_1_1: case TPG_HW_VERSION_1_1:
case TPG_HW_VERSION_1_2: case TPG_HW_VERSION_1_2:
case TPG_HW_VERSION_1_3: case TPG_HW_VERSION_1_3:
case TPG_HW_VERSION_1_3_1:
break; break;
default: default:
CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version", CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
hw->hw_idx); hw->hw_idx);
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
@@ -526,14 +670,26 @@ static int tpg_hw_configure_init_settings(
case TPG_HW_VERSION_1_1: case TPG_HW_VERSION_1_1:
case TPG_HW_VERSION_1_2: case TPG_HW_VERSION_1_2:
case TPG_HW_VERSION_1_3: case TPG_HW_VERSION_1_3:
case TPG_HW_VERSION_1_3_1:
clk_level = get_tpg_clk_level(hw); clk_level = get_tpg_clk_level(hw);
rc = tpg_hw_soc_enable(hw, clk_level); rc = tpg_hw_soc_enable(hw, clk_level);
if (hw->hw_info->ops->init) if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] hw soc enable failed %d",
hw->hw_idx, rc);
return rc;
}
if (hw->hw_info->ops->init) {
rc = hw->hw_info->ops->init(hw, settings); rc = hw->hw_info->ops->init(hw, settings);
if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] hw soc enable failed %d",
hw->hw_idx, rc);
return rc;
}
}
break; break;
default: default:
CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version", CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
hw->hw_idx); hw->hw_idx);
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
@@ -541,6 +697,47 @@ static int tpg_hw_configure_init_settings(
return rc; return rc;
} }
static int tpg_hw_configure_init_settings_v3(
struct tpg_hw *hw,
struct tpg_hw_initsettings_v3 *settings)
{
int rc = 0;
if (!hw || !hw->hw_info || !hw->hw_info->ops)
return -EINVAL;
mutex_lock(&hw->mutex);
switch (hw->hw_info->version) {
case TPG_HW_VERSION_1_0:
case TPG_HW_VERSION_1_1:
case TPG_HW_VERSION_1_2:
case TPG_HW_VERSION_1_3:
case TPG_HW_VERSION_1_3_1:
rc = tpg_hw_soc_enable(hw, CAM_SVS_VOTE);
if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] hw soc enable failed %d",
hw->hw_idx, rc);
return rc;
}
if (hw->hw_info->ops->init) {
rc = hw->hw_info->ops->init(hw, settings);
if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] hw soc enable failed %d",
hw->hw_idx, rc);
return rc;
}
}
break;
default:
CAM_ERR(CAM_TPG, "TPG[%d] Unsupported HW Version",
hw->hw_idx);
rc = -EINVAL;
break;
}
mutex_unlock(&hw->mutex);
return rc;
}
int tpg_hw_config( int tpg_hw_config(
struct tpg_hw *hw, struct tpg_hw *hw,
enum tpg_hw_cmd_t config_cmd, enum tpg_hw_cmd_t config_cmd,
@@ -553,12 +750,17 @@ int tpg_hw_config(
switch (config_cmd) { switch (config_cmd) {
case TPG_HW_CMD_INIT_CONFIG: case TPG_HW_CMD_INIT_CONFIG:
//validate_stream_list(hw); //validate_stream_list(hw);
tpg_hw_configure_init_settings(hw, if (hw->stream_version == 1) {
(struct tpg_hw_initsettings *)config_args); tpg_hw_configure_init_settings(hw,
(struct tpg_hw_initsettings *)config_args);
} else if (hw->stream_version == 3) {
tpg_hw_configure_init_settings_v3(hw,
(struct tpg_hw_initsettings_v3 *)config_args);
}
break; break;
default: default:
CAM_ERR(CAM_TPG, "TPG[%d] Unsupported hw config command", CAM_ERR(CAM_TPG, "TPG[%d] Unsupported hw config command",
hw->hw_idx); hw->hw_idx);
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
@@ -569,6 +771,7 @@ int tpg_hw_free_streams(struct tpg_hw *hw)
{ {
struct list_head *pos = NULL, *pos_next = NULL; struct list_head *pos = NULL, *pos_next = NULL;
struct tpg_hw_stream *entry; struct tpg_hw_stream *entry;
struct tpg_hw_stream_v3 *entry_v3;
int i = 0; int i = 0;
if (!hw) if (!hw)
@@ -583,10 +786,19 @@ int tpg_hw_free_streams(struct tpg_hw *hw)
hw->vc_slots[i].slot_id = i; hw->vc_slots[i].slot_id = i;
hw->vc_slots[i].vc = -1; hw->vc_slots[i].vc = -1;
hw->vc_slots[i].stream_count = 0; hw->vc_slots[i].stream_count = 0;
list_for_each_safe(pos, pos_next, &hw->vc_slots[i].head) {
entry = list_entry(pos, struct tpg_hw_stream, list); if (hw->stream_version == 1) {
list_del(pos); list_for_each_safe(pos, pos_next, &hw->vc_slots[i].head) {
kfree(entry); entry = list_entry(pos, struct tpg_hw_stream, list);
list_del(pos);
kfree(entry);
}
} else if (hw->stream_version == 3) {
list_for_each_safe(pos, pos_next, &hw->vc_slots[i].head) {
entry_v3 = list_entry(pos, struct tpg_hw_stream_v3, list);
list_del(pos);
kfree(entry_v3);
}
} }
INIT_LIST_HEAD(&(hw->vc_slots[i].head)); INIT_LIST_HEAD(&(hw->vc_slots[i].head));
} }
@@ -671,6 +883,65 @@ static int assign_vc_slot(
return rc; return rc;
} }
static int assign_vc_slot_v3(
struct tpg_hw *hw,
int vc,
struct tpg_hw_stream_v3 *stream
)
{
int rc = -EINVAL, i = 0, slot_matched = 0;
if (!hw || !stream)
return -EINVAL;
for (i = 0; i < hw->hw_info->max_vc_channels; i++) {
/* Found a matching slot */
if (hw->vc_slots[i].vc == vc) {
slot_matched = 1;
if (hw->vc_slots[i].stream_count
< hw->hw_info->max_dt_channels_per_vc) {
list_add_tail(&stream->list, &hw->vc_slots[i].head);
hw->vc_slots[i].stream_count++;
hw->vc_slots[i].vc = vc;
rc = 0;
CAM_DBG(CAM_TPG, "vc[%d]dt[%d]=>slot[%d]",
vc,
stream->stream.dt,
i);
} else {
/**
* already slot was assigned for this vc
* however this slot have been filled with
* full streams
*/
rc = -EINVAL;
CAM_ERR(CAM_TPG, "vc[%d]dt[%d]=>slot[%d] is overlfown",
vc, stream->stream.dt, i);
}
break;
}
/**
* none of the above slots matched, and now found an empty slot
* so assigning stream to that slot
*/
if (hw->vc_slots[i].vc == -1) {
list_add_tail(&stream->list, &hw->vc_slots[i].head);
hw->vc_slots[i].stream_count++;
hw->vc_slots[i].vc = vc;
hw->vc_count++;
rc = 0;
CAM_DBG(CAM_TPG, "vc[%d]dt[%d]=>slot[%d]", vc, stream->stream.dt, i);
break;
}
}
if ((slot_matched == 0) && (rc != 0))
CAM_ERR(CAM_TPG, "No slot matched");
return rc;
}
int tpg_hw_reset(struct tpg_hw *hw) int tpg_hw_reset(struct tpg_hw *hw)
{ {
int rc = 0; int rc = 0;
@@ -686,13 +957,15 @@ int tpg_hw_reset(struct tpg_hw *hw)
mutex_lock(&hw->mutex); mutex_lock(&hw->mutex);
if (hw->state != TPG_HW_STATE_HW_DISABLED) { if (hw->state != TPG_HW_STATE_HW_DISABLED) {
rc = cam_soc_util_disable_platform_resource(hw->soc_info, true, false); rc = cam_soc_util_disable_platform_resource(hw->soc_info, true, false);
if (rc) if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] Disable platform failed %d", hw->hw_idx, rc); CAM_ERR(CAM_TPG, "TPG[%d] Disable platform failed %d", hw->hw_idx, rc);
return rc;
}
rc = cam_cpas_stop(hw->cpas_handle); rc = cam_cpas_stop(hw->cpas_handle);
if (rc) if (rc) {
CAM_ERR(CAM_TPG, "TPG[%d] CPAS stop failed", hw->hw_idx); CAM_ERR(CAM_TPG, "TPG[%d] CPAS stop failed", hw->hw_idx);
return rc;
}
hw->state = TPG_HW_STATE_HW_DISABLED; hw->state = TPG_HW_STATE_HW_DISABLED;
} }
mutex_unlock(&hw->mutex); mutex_unlock(&hw->mutex);
@@ -711,11 +984,12 @@ int tpg_hw_add_stream(
return -EINVAL; return -EINVAL;
} }
hw->stream_version = 1;
mutex_lock(&hw->mutex); mutex_lock(&hw->mutex);
stream = kzalloc(sizeof(struct tpg_hw_stream), GFP_KERNEL); stream = kzalloc(sizeof(struct tpg_hw_stream), GFP_KERNEL);
if (!stream) { if (!stream) {
CAM_ERR(CAM_TPG, "TPG[%d] stream allocation failed", CAM_ERR(CAM_TPG, "TPG[%d] stream allocation failed",
hw->hw_idx); hw->hw_idx);
mutex_unlock(&hw->mutex); mutex_unlock(&hw->mutex);
return -ENOMEM; return -ENOMEM;
} }
@@ -727,3 +1001,33 @@ int tpg_hw_add_stream(
mutex_unlock(&hw->mutex); mutex_unlock(&hw->mutex);
return rc; return rc;
} }
int tpg_hw_add_stream_v3(
struct tpg_hw *hw,
struct tpg_stream_config_v3_t *cmd)
{
int rc = 0;
struct tpg_hw_stream_v3 *stream = NULL;
if (!hw || !cmd) {
CAM_ERR(CAM_TPG, "Invalid params");
return -EINVAL;
}
hw->stream_version = 3;
mutex_lock(&hw->mutex);
stream = kzalloc(sizeof(struct tpg_hw_stream_v3), GFP_KERNEL);
if (!stream) {
CAM_ERR(CAM_TPG, "TPG[%d] stream allocation failed",
hw->hw_idx);
mutex_unlock(&hw->mutex);
return -ENOMEM;
}
memcpy(&stream->stream,
cmd,
sizeof(struct tpg_stream_config_v3_t));
rc = assign_vc_slot_v3(hw, stream->stream.vc, stream);
mutex_unlock(&hw->mutex);
return rc;
}

View File

@@ -12,10 +12,11 @@
#include "cam_soc_util.h" #include "cam_soc_util.h"
#include <cam_cpas_api.h> #include <cam_cpas_api.h>
#include <media/cam_sensor.h> #include <media/cam_sensor.h>
#define TPG_HW_VERSION_1_0 0x10000000 #define TPG_HW_VERSION_1_0 0x10000000
#define TPG_HW_VERSION_1_1 0x10000001 #define TPG_HW_VERSION_1_1 0x10000001
#define TPG_HW_VERSION_1_2 0x10000002 #define TPG_HW_VERSION_1_2 0x10000002
#define TPG_HW_VERSION_1_3 0x10000003 #define TPG_HW_VERSION_1_3 0x10000003
#define TPG_HW_VERSION_1_3_1 0x10000004
struct tpg_hw; struct tpg_hw;
@@ -109,20 +110,34 @@ struct tpg_hw_stream {
struct list_head list; struct list_head list;
}; };
/**
* tpg_hw_stream_v3 : tpg hw stream version 2
*
* @stream : tpg stream version 2
* @list : entry to tpg stream list
*/
struct tpg_hw_stream_v3 {
struct tpg_stream_config_v3_t stream;
struct list_head list;
};
/** /**
* tpg_hw : tpg hw * tpg_hw : tpg hw
* *
* @hw_idx : hw id * @hw_idx : hw id
* @state : tpg hw state * @stream_version : stream version
* @cpas_handle : handle to cpas * @state : tpg hw state
* @hw_info : tp hw info * @cpas_handle : handle to cpas
* @soc_info : soc info * @hw_info : tp hw info
* @mutex : lock * @soc_info : soc info
* @stream_list : list of tpg stream * @mutex : lock
* @global_config : global configuration * @stream_list : list of tpg stream
* @global_config : global configuration
*/ */
struct tpg_hw { struct tpg_hw {
uint32_t hw_idx; uint32_t hw_idx;
uint32_t stream_version;
uint32_t state; uint32_t state;
uint32_t cpas_handle; uint32_t cpas_handle;
uint32_t vc_count; uint32_t vc_count;
@@ -189,6 +204,33 @@ struct dt_config_args {
struct tpg_stream_config_t *stream; struct tpg_stream_config_t *stream;
}; };
/**
* @vc_config_args_v3 : arguments for vc config process cmd version 2
*
* @vc_slot : slot to configure this vc
* @num_dts : number of dts in this vc
* @stream : output stream version 2
*/
struct vc_config_args_v3 {
uint32_t vc_slot;
uint32_t num_dts;
struct tpg_stream_config_v3_t *stream;
};
/**
* dt_config_args_v3 : arguments for dt config process cmd version 2
*
* @vc_slot : vc slot to configure this dt
* @dt_slot : dt slot to configure this dt
* @stream : stream packet to configure for this dt version 2
*/
struct dt_config_args_v3 {
uint32_t vc_slot;
uint32_t dt_slot;
struct tpg_stream_config_v3_t *stream;
};
/** /**
* global_config_args : tpg global config args * global_config_args : tpg global config args
* *
@@ -213,6 +255,20 @@ struct tpg_hw_initsettings {
uint32_t num_streams; uint32_t num_streams;
}; };
/**
* tpg_hw_initsettings_v3 : initial configurations version 2
*
* @global_config : global configuration
* @streamconfigs : array of stream configurations version 2
* @num_streams : number of streams in strea config array
*/
struct tpg_hw_initsettings_v3 {
struct tpg_global_config_t globalconfig;
struct tpg_stream_config_v3_t *streamconfigs;
uint32_t num_streams;
};
/** /**
* @brief dump the tpg memory info * @brief dump the tpg memory info
* *
@@ -243,6 +299,18 @@ int dump_global_configs(int idx, struct tpg_global_config_t *global);
*/ */
int dump_stream_configs(int hw_idx, int stream_idx, struct tpg_stream_config_t *stream); int dump_stream_configs(int hw_idx, int stream_idx, struct tpg_stream_config_t *stream);
/**
* @brief : dump stream config command version 2
*
* @param hw_idx: hw index
* @param stream_idx: stream index
* @param stream: stream config command version 2
*
* @return : 0 on success
*/
int dump_stream_configs_v3(int hw_idx, int stream_idx, struct tpg_stream_config_v3_t *stream);
/** /**
* @brief : dump any hw status registers * @brief : dump any hw status registers
* *
@@ -327,6 +395,17 @@ int tpg_hw_reset(struct tpg_hw *hw);
*/ */
int tpg_hw_add_stream(struct tpg_hw *hw, struct tpg_stream_config_t *cmd); int tpg_hw_add_stream(struct tpg_hw *hw, struct tpg_stream_config_t *cmd);
/**
* @brief : tp hw add stream version 2
*
* @param hw: tpg hw instance
* @param cmd: tpg hw command version 2
*
* @return : 0 on success
*/
int tpg_hw_add_stream_v3(struct tpg_hw *hw, struct tpg_stream_config_v3_t *cmd);
/** /**
* @brief : copy global config command * @brief : copy global config command
* *

View File

@@ -15,10 +15,19 @@ enum tpg_hw_v_1_3_encode_fomat_t {
}; };
#define FRAME_INTERLEAVE 0x0 #define FRAME_INTERLEAVE 0x0
#define LINE_INTERLEAVE 0x1 #define LINE_INTERLEAVE 0x1
#define SHDR_INTERLEAVE 0x2 #define SHDR_INTERLEAVE 0x2
#define SPARSE_PD_INTERLEAVE 0x3 #define SPARSE_PD_INTERLEAVE 0x3
#define CFA_PATTERN_ROW_WIDTH 8
#define CFA_PATTERN_BITS_PER_INDEX 2
#define Invalid 0x0
#define Red 0x0
#define Green 0x1
#define Blue 0x2
#define IR 0x3
#define Mono 0x3
static int get_tpg_vc_dt_pattern_id( static int get_tpg_vc_dt_pattern_id(
enum tpg_interleaving_format_t vc_dt_pattern) enum tpg_interleaving_format_t vc_dt_pattern)
{ {
@@ -82,7 +91,6 @@ static int configure_global_configs(
(1 << tpg_reg->tpg_en_shift_val); (1 << tpg_reg->tpg_en_shift_val);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl); cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
CAM_DBG(CAM_TPG, "tpg[%d] tpg_ctrl=0x%x", hw->hw_idx, val); CAM_DBG(CAM_TPG, "tpg[%d] tpg_ctrl=0x%x", hw->hw_idx, val);
return 0; return 0;
} }
@@ -129,6 +137,149 @@ static int get_tpg_payload_mode(enum tpg_pattern_t pattern)
return COLOR_BARS; return COLOR_BARS;
} }
static int get_pixel_coordinate(
int cfa_pattern_start_index,
int cfa_pattern_end_index,
uint32_t *val,
struct tpg_stream_config_v3_t *configs)
{
uint32_t shift = 0;
int idx = 0;
int i = 0;
int j = 0;
*val = 0;
for (i = cfa_pattern_start_index; i < cfa_pattern_end_index; i++) {
for (j = 0; j < configs->cfa_info.pattern_width; j++) {
shift = ((i * CFA_PATTERN_ROW_WIDTH) + j) *
CFA_PATTERN_BITS_PER_INDEX;
idx = i * configs->cfa_info.pattern_height + j;
*val |= (configs->cfa_info.pixel_coordinate[idx].pixel_type) << shift;
}
}
return 0;
}
static int configure_xcfa_array_v3(
struct tpg_hw *hw,
struct tpg_stream_config_v3_t *configs)
{
struct cam_hw_soc_info *soc_info = NULL;
struct cam_tpg_ver_1_3_reg_offset *tpg_reg = NULL;
uint32_t val = 0;
if (!hw || !hw->hw_info || !hw->hw_info->hw_data) {
CAM_ERR(CAM_TPG, "invalid params");
return -EINVAL;
}
tpg_reg = hw->hw_info->hw_data;
soc_info = hw->soc_info;
switch (configs->xcfa_type) {
case XCFA_TYPE_RGBIR:
get_pixel_coordinate(0, 2, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color0);
get_pixel_coordinate(2, configs->cfa_info.pattern_height, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color1);
break;
case XCFA_TYPE_QUADCFA:
get_pixel_coordinate(0, 2, &val, configs);
CAM_DBG(CAM_TPG, "val = 0x%x", val);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color0);
get_pixel_coordinate(2, configs->cfa_info.pattern_height, &val, configs);
CAM_DBG(CAM_TPG, "val = 0x%x", val);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color1);
break;
case XCFA_TYPE_THREEXTHREECFA:
get_pixel_coordinate(0, 2, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color0);
get_pixel_coordinate(2, 4, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color1);
get_pixel_coordinate(4, configs->cfa_info.pattern_height, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color2);
break;
case XCFA_TYPE_FOURXFOURCFA:
get_pixel_coordinate(0, 2, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color0);
get_pixel_coordinate(2, 4, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color1);
get_pixel_coordinate(4, 6, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color2);
get_pixel_coordinate(6, configs->cfa_info.pattern_height, &val, configs);
cam_io_w_mb(val,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc0_color_bar_cfa_color3);
break;
default:
break;
}
return 0;
}
static int configure_dt_v3(
struct tpg_hw *hw,
uint32_t vc_slot,
uint32_t dt_slot,
struct tpg_stream_config_v3_t *stream)
{
uint32_t val;
struct cam_hw_soc_info *soc_info = NULL;
struct cam_tpg_ver_1_3_reg_offset *tpg_reg = NULL;
if (!hw || !hw->hw_info || !hw->hw_info->hw_data) {
CAM_ERR(CAM_TPG, "invalid params");
return -EINVAL;
}
tpg_reg = hw->hw_info->hw_data;
soc_info = hw->soc_info;
CAM_DBG(CAM_TPG, "TPG[%d] slot(%d,%d) <= dt:%d",
hw->hw_idx,
vc_slot,
dt_slot,
stream->dt);
val = (((stream->stream_dimension.width & 0xFFFF) << 16) |
(stream->stream_dimension.height & 0xFFFF));
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_dt_0_cfg_0 +
(0x60 * vc_slot) + (dt_slot * 0x0c));
CAM_DBG(CAM_TPG, "TPG[%d] vc%d_dt%d_cfg_0=0x%x",
hw->hw_idx,
vc_slot, dt_slot, val);
cam_io_w_mb(stream->dt,
soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_dt_0_cfg_1 +
(0x60 * vc_slot) + (dt_slot * 0x0c));
CAM_DBG(CAM_TPG, "TPG[%d] vc%d_dt%d_cfg_1=0x%x",
hw->hw_idx,
vc_slot, dt_slot, stream->dt);
val = ((get_tpg_encode_format(stream->pixel_depth) & 0xF) <<
tpg_reg->tpg_dt_encode_format_shift) |
get_tpg_payload_mode(stream->pattern_type);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_dt_0_cfg_2 +
(0x60 * vc_slot) + (dt_slot * 0x0c));
CAM_DBG(CAM_TPG, "TPG[%d] vc%d_dt%d_cfg_2=0x%x",
hw->hw_idx,
vc_slot, dt_slot, val);
return 0;
}
static int configure_dt( static int configure_dt(
struct tpg_hw *hw, struct tpg_hw *hw,
uint32_t vc_slot, uint32_t vc_slot,
@@ -184,6 +335,100 @@ static int configure_dt(
return 0; return 0;
} }
#define VC1_GAIN 0x100
static int configure_vc_v3(
struct tpg_hw *hw,
uint32_t vc_slot,
int num_dts,
struct tpg_stream_config_v3_t *stream)
{
uint32_t val = 0;
struct cam_hw_soc_info *soc_info = NULL;
struct cam_tpg_ver_1_3_reg_offset *tpg_reg = NULL;
if (!hw || !hw->hw_info || !hw->hw_info->hw_data) {
CAM_ERR(CAM_TPG, "invalid params");
return -EINVAL;
}
tpg_reg = hw->hw_info->hw_data;
soc_info = hw->soc_info;
/* Use CFA pattern here */
if (stream->output_format == TPG_IMAGE_FORMAT_QCFA)
val |= (1 << tpg_reg->tpg_color_bar_qcfa_en_shift);
if (stream->cb_mode == TPG_COLOR_BAR_MODE_SPLIT)
val |= (1 << tpg_reg->tpg_split_en_shift);
if (stream->cfa_info_exist != 0) {
val |= ((stream->cfa_info.pattern_height - 1) << tpg_reg->tpg_size_y_shift);
val |= ((stream->cfa_info.pattern_width - 1) << tpg_reg->tpg_size_x_shift);
val |= (1 << tpg_reg->tpg_xcfa_en_shift);
configure_xcfa_array_v3(hw, stream);
}
CAM_DBG(CAM_TPG, "TPG[%d] period: %d", hw->hw_idx, stream->rotate_period);
val |= ((stream->rotate_period & 0x3F) <<
tpg_reg->tpg_color_bar_qcfa_rotate_period_shift);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_color_bar_cfg + (0x60 * vc_slot));
CAM_DBG(CAM_TPG, "TPG[%d] vc%d_color_bar_cfg=0x%x",
hw->hw_idx,
vc_slot, val);
val = stream->hbi;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_hbi_cfg + (0x60 * vc_slot));
CAM_DBG(CAM_TPG, "TPG[%d] vc%d_hbi_cfg=0x%x",
hw->hw_idx,
vc_slot, val);
val = stream->vbi;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_vbi_cfg + (0x60 * vc_slot));
CAM_DBG(CAM_TPG, "TPG[%d] vc%d_vbi_cgf=0x%x",
hw->hw_idx,
vc_slot, val);
cam_io_w_mb(0x12345678,
soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_lfsr_seed + (0x60 * vc_slot));
val = ((0 << tpg_reg->tpg_num_frames_shift_val) |
((num_dts-1) << tpg_reg->tpg_num_dts_shift_val) |
stream->vc);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_cfg0 + (0x60 * vc_slot));
CAM_DBG(CAM_TPG, "TPG[%d] vc%d_cfg0=0x%x",
hw->hw_idx,
vc_slot, val);
if (hw->hw_info->shdr_overlap == 1) {
cam_io_w_mb(hw->hw_info->shdr_overlap << tpg_reg->tpg_overlap_shdr_en_shift,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
}
if (hw->hw_info->shdr_offset_num_batch >= 0 && vc_slot > 0) {
val = (VC1_GAIN << tpg_reg->tpg_gain_shift);
val |= (hw->hw_info->shdr_offset_num_batch <<
tpg_reg->tpg_shdr_offset_num_batch_shift);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc1_gain_cfg + (0x60 * (vc_slot-1)));
val = ((stream->shdr_line_offset0 * vc_slot)
<< tpg_reg->tpg_shdr_line_offset0_shift);
val |= ((stream->shdr_line_offset1 * vc_slot)
<< tpg_reg->tpg_shdr_line_offset1_shift);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc1_shdr_cfg + (0x60 * (vc_slot-1)));
CAM_DBG(CAM_TPG, "TPG[%d] vc%d_cfg0=0x%x shdr",
hw->hw_idx,
vc_slot, val);
}
return 0;
}
#define RGGB_IR_0 0x00770091 #define RGGB_IR_0 0x00770091
#define RGGB_IR_1 0x00770019 #define RGGB_IR_1 0x00770019
#define RGGB_2x2 0x05055A5A #define RGGB_2x2 0x05055A5A
@@ -258,7 +503,7 @@ static int configure_vc(
CAM_ERR(CAM_TPG, "invalid params"); CAM_ERR(CAM_TPG, "invalid params");
return -EINVAL; return -EINVAL;
} }
tpg_reg = hw->hw_info->hw_data; tpg_reg = hw->hw_info->hw_data;
soc_info = hw->soc_info; soc_info = hw->soc_info;
/* Use CFA pattern here */ /* Use CFA pattern here */
@@ -309,7 +554,7 @@ static int configure_vc(
tpg_reg->tpg_vc0_lfsr_seed + (0x60 * vc_slot)); tpg_reg->tpg_vc0_lfsr_seed + (0x60 * vc_slot));
val = ((0 << tpg_reg->tpg_num_frames_shift_val) | val = ((0 << tpg_reg->tpg_num_frames_shift_val) |
((num_dts-1) << tpg_reg->tpg_num_dts_shift_val) | ((num_dts-1) << tpg_reg->tpg_num_dts_shift_val) |
stream->vc); stream->vc);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_cfg0 + (0x60 * vc_slot)); tpg_reg->tpg_vc0_cfg0 + (0x60 * vc_slot));
@@ -320,7 +565,7 @@ static int configure_vc(
cam_io_w_mb(hw->hw_info->shdr_overlap << tpg_reg->tpg_overlap_shdr_en_shift, cam_io_w_mb(hw->hw_info->shdr_overlap << tpg_reg->tpg_overlap_shdr_en_shift,
soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl); soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
} }
if (hw->hw_info->shdr_offset_num_batch >= 0 && vc_slot > 0) { if (hw->hw_info->shdr_offset_num_batch >= 0 && vc_slot > 0) {
val = (VC1_GAIN << tpg_reg->tpg_gain_shift); val = (VC1_GAIN << tpg_reg->tpg_gain_shift);
val |= (hw->hw_info->shdr_offset_num_batch << val |= (hw->hw_info->shdr_offset_num_batch <<
tpg_reg->tpg_shdr_offset_num_batch_shift); tpg_reg->tpg_shdr_offset_num_batch_shift);
@@ -336,7 +581,6 @@ static int configure_vc(
hw->hw_idx, hw->hw_idx,
vc_slot, val); vc_slot, val);
} }
return 0; return 0;
} }
@@ -391,32 +635,60 @@ int tpg_hw_v_1_3_process_cmd(
switch(cmd) { switch(cmd) {
case TPG_CONFIG_VC: case TPG_CONFIG_VC:
{ {
struct vc_config_args *vc_config = if (hw->stream_version == 1) {
(struct vc_config_args *)arg; struct vc_config_args *vc_config =
(struct vc_config_args *)arg;
if (vc_config == NULL) { if (vc_config == NULL) {
CAM_ERR(CAM_TPG, "invalid argument"); CAM_ERR(CAM_TPG, "invalid argument");
return -EINVAL; return -EINVAL;
}
rc = configure_vc(hw,
vc_config->vc_slot,
vc_config->num_dts,
vc_config->stream);
} else if (hw->stream_version == 3) {
struct vc_config_args_v3 *vc_config_v3 =
(struct vc_config_args_v3 *)arg;
if (vc_config_v3 == NULL) {
CAM_ERR(CAM_TPG, "invalid argument");
return -EINVAL;
}
rc = configure_vc_v3(hw,
vc_config_v3->vc_slot,
vc_config_v3->num_dts,
vc_config_v3->stream);
} }
rc = configure_vc(hw,
vc_config->vc_slot,
vc_config->num_dts,
vc_config->stream);
} }
break; break;
case TPG_CONFIG_DT: case TPG_CONFIG_DT:
{ {
struct dt_config_args *dt_config = if (hw->stream_version == 1) {
(struct dt_config_args *)arg; struct dt_config_args *dt_config =
(struct dt_config_args *)arg;
if (dt_config == NULL) { if (dt_config == NULL) {
CAM_ERR(CAM_TPG, "invalid argument"); CAM_ERR(CAM_TPG, "invalid argument");
return -EINVAL; return -EINVAL;
}
rc = configure_dt(hw,
dt_config->vc_slot,
dt_config->dt_slot,
dt_config->stream);
} else if (hw->stream_version == 3) {
struct dt_config_args_v3 *dt_config_v3 =
(struct dt_config_args_v3 *)arg;
if (dt_config_v3 == NULL) {
CAM_ERR(CAM_TPG, "invalid argument");
return -EINVAL;
}
rc = configure_dt_v3(hw,
dt_config_v3->vc_slot,
dt_config_v3->dt_slot,
dt_config_v3->stream);
} }
rc = configure_dt(hw,
dt_config->vc_slot,
dt_config->dt_slot,
dt_config->stream);
} }
break; break;
case TPG_CONFIG_CTRL: case TPG_CONFIG_CTRL:

View File

@@ -35,7 +35,7 @@ struct tpg_hw_info tpg_v_1_3_hw_info = {
}; };
struct tpg_hw_info tpg_v_1_3_1_hw_info = { struct tpg_hw_info tpg_v_1_3_1_hw_info = {
.version = TPG_HW_VERSION_1_3, .version = TPG_HW_VERSION_1_3_1,
.max_vc_channels = 4, .max_vc_channels = 4,
.max_dt_channels_per_vc = 4, .max_dt_channels_per_vc = 4,
.ops = &tpg_hw_v_1_3_ops, .ops = &tpg_hw_v_1_3_ops,

View File

@@ -163,6 +163,33 @@ enum tpg_phy_type_t {
TPG_PHY_TYPE_MAX, TPG_PHY_TYPE_MAX,
}; };
enum tpg_pixel_type_t {
TPG_PIXEL_TYPE_INVALID = 0,
TPG_PIXEL_TYPE_RED,
TPG_PIXEL_TYPE_GREEN,
TPG_PIXEL_TYPE_BLUE,
TPG_PIXEL_TYPE_IR,
TPG_PIXEL_TYPE_MONO,
};
enum tpg_exposure_type_t {
TPG_EXPOSUREL_TYPE_INVALID = 0,
TPG_EXPOSURE_TYPE_LONG,
TPG_EXPOSURE_TYPE_MIDDLE,
TPG_EXPOSURE_TYPE_SHORT,
};
enum xcfa_type_t {
XCFA_TYPE_BAYER = 0,
XCFA_TYPE_QUADCFA,
XCFA_TYPE_THREEXTHREECFA,
XCFA_TYPE_FOURXFOURCFA,
XCFA_TYPE_RGBIR,
XCFA_TYPE_RGBWC,
XCFA_TYPE_RGBWK,
XCFA_TYPE_UNCONVENTIONAL_BAYER,
};
enum tpg_interleaving_format_t { enum tpg_interleaving_format_t {
TPG_INTERLEAVING_FORMAT_INVALID = 0, TPG_INTERLEAVING_FORMAT_INVALID = 0,
TPG_INTERLEAVING_FORMAT_FRAME, TPG_INTERLEAVING_FORMAT_FRAME,
@@ -738,6 +765,37 @@ struct tpg_command_header_t {
uint32_t cmd_version; uint32_t cmd_version;
} __attribute__((packed)); } __attribute__((packed));
/**
* tpg_pixel_coordinate_t : pixel coordinate structure
*
* @xcoordinate : X coordinate
* @ycoordinate : Y coordiante
* @pixel_type : red green blue ir mono
*/
struct tpg_pixel_coordinate_t {
uint32_t xcoordinate;
uint32_t ycoordinate;
uint32_t exposure_type;
uint32_t pixel_type;
} __attribute__((packed));
/**
* tpg_cfa_information_t : tpg cfa information structure
*
* @number_of_pixel_per_color : number of pixel per color
* @pattern_width : pattern width
* @pattern_height : pattern height
* @pixel_coordinate_count : pixel coordinate count
* @pixel_coordinate : pixel coordinate array
*/
struct tpg_cfa_information_t {
uint32_t number_of_pixel_per_color;
uint32_t pattern_width;
uint32_t pattern_height;
uint32_t pixel_coordinate_count;
struct tpg_pixel_coordinate_t pixel_coordinate[64];
} __attribute__((packed));
/** /**
* tpg_global_config_t : global configuration command structure * tpg_global_config_t : global configuration command structure
* *
@@ -769,6 +827,45 @@ struct tpg_global_config_t {
uint32_t reserved[4]; uint32_t reserved[4];
} __attribute__((packed)); } __attribute__((packed));
/**
* tpg_old_stream_config_t : stream configuration command
*
* @header: common tpg command header
* @pattern_type : tpg pattern type used in this stream
* @cb_mode : tpg color bar mode used in this stream
* @frame_count : frame count in case of trigger burst mode
* @stream_type : type of stream like image pdaf etc
* @stream_dimension : Dimension of the stream
* @pixel_depth : bits per each pixel
* @cfa_arrangement : color filter arragement
* @output_format : output image format
* @hbi : horizontal blanking intervel
* @vbi : vertical blanking intervel
* @vc : virtual channel of this stream
* @dt : data type of this stream
* @skip_pattern : skip pattern for this stream
* @rotate_period : rotate period for this stream
* @reserved : reserved for future use
*/
struct tpg_old_stream_config_t {
struct tpg_command_header_t header;
enum tpg_pattern_t pattern_type;
enum tpg_color_bar_mode_t cb_mode;
uint32_t frame_count;
enum tpg_stream_t stream_type;
struct stream_dimension stream_dimension;
uint8_t pixel_depth;
enum tpg_cfa_arrangement_t cfa_arrangement;
enum tpg_image_format_t output_format;
uint32_t hbi;
uint32_t vbi;
uint16_t vc;
uint16_t dt;
uint32_t skip_pattern;
uint32_t rotate_period;
uint32_t reserved[4];
} __attribute__((packed));
/** /**
* tpg_stream_config_t : stream configuration command * tpg_stream_config_t : stream configuration command
* *
@@ -786,10 +883,11 @@ struct tpg_global_config_t {
* @vc : virtual channel of this stream * @vc : virtual channel of this stream
* @dt : data type of this stream * @dt : data type of this stream
* @skip_pattern : skip pattern for this stream * @skip_pattern : skip pattern for this stream
* @rotate_period : rotate period for this stream
* @xcfa_debug : for xcfa debug; * @xcfa_debug : for xcfa debug;
* @shdr_line_offset0 : for shdr line offset0 * @shdr_line_offset0 : for shdr line offset0
* @shdr_line_offset1 : for shdr line offset1 * @shdr_line_offset1 : for shdr line offset1
* @reserved : reserved for future use * @reserved : reserved for future use
*/ */
struct tpg_stream_config_t { struct tpg_stream_config_t {
struct tpg_command_header_t header; struct tpg_command_header_t header;
@@ -813,6 +911,56 @@ struct tpg_stream_config_t {
uint32_t reserved[4]; uint32_t reserved[4];
} __attribute__((packed)); } __attribute__((packed));
/**
* tpg_stream_config_t : stream configuration command
*
* @header: common tpg command header
* @pattern_type : tpg pattern type used in this stream
* @cb_mode : tpg color bar mode used in this stream
* @frame_count : frame count in case of trigger burst mode
* @stream_type : type of stream like image pdaf etc
* @stream_dimension : Dimension of the stream
* @pixel_depth : bits per each pixel
* @cfa_arrangement : color filter arragement
* @output_format : output image format
* @hbi : horizontal blanking intervel
* @vbi : vertical blanking intervel
* @vc : virtual channel of this stream
* @dt : data type of this stream
* @skip_pattern : skip pattern for this stream
* @rotate_period : rotate period for this stream
* @shdr_line_offset0 : for shdr line offset0
* @shdr_line_offset1 : for shdr line offset1
* @cfa_info_exist : cfa info exists
* @cfa_info : cfa information
* @xcfa_type : xcfa type
* @reserved : reserved for future use
*/
struct tpg_stream_config_v3_t {
struct tpg_command_header_t header;
uint32_t pattern_type;
uint32_t cb_mode;
uint32_t frame_count;
uint32_t stream_type;
struct stream_dimension stream_dimension;
uint32_t pixel_depth;
uint32_t cfa_arrangement;
uint32_t output_format;
uint32_t hbi;
uint32_t vbi;
uint16_t vc;
uint16_t dt;
uint32_t skip_pattern;
uint32_t rotate_period;
uint32_t xcfa_debug;
uint32_t shdr_line_offset0;
uint32_t shdr_line_offset1;
uint32_t cfa_info_exist;
struct tpg_cfa_information_t cfa_info;
uint32_t xcfa_type;
uint32_t reserved[5];
} __attribute__((packed));
/** /**
* tpg_illumination_control : illumianation control command * tpg_illumination_control : illumianation control command
* *