[Meego-kernel] [MFLD Camera - PATCH v3 8/9] MFLD isp css HW subsystem implemenation to access and control ISP HW block.
Zhang, Xiaolin
xiaolin.zhang at intel.com
Wed Dec 1 10:54:36 PST 2010
>From d5e30a49993e76821456b87d18f5a2ab25276bd6 Mon Sep 17 00:00:00 2001
From: Xiaolin Zhang <xiaolin.zhang at intel.com>
Date: Wed, 1 Dec 2010 22:29:07 +0800
Subject: [MFLD Camera - PATCH v3 8/9] MFLD isp css HW subsystem implemenation to access and control ISP HW block.
Signed-off-by: Xiaolin Zhang <xiaolin.zhang at intel.com>
---
drivers/media/video/mfld_ci/mfldisp/css/sh_css.c | 3411 ++++++++++++++++++++
drivers/media/video/mfld_ci/mfldisp/css/sh_css.h | 697 ++++
.../video/mfld_ci/mfldisp/css/sh_css_binary.c | 407 +++
.../video/mfld_ci/mfldisp/css/sh_css_binary.h | 177 +
.../media/video/mfld_ci/mfldisp/css/sh_css_debug.c | 513 +++
.../media/video/mfld_ci/mfldisp/css/sh_css_debug.h | 41 +
.../media/video/mfld_ci/mfldisp/css/sh_css_frame.c | 465 +++
.../media/video/mfld_ci/mfldisp/css/sh_css_frame.h | 222 ++
.../media/video/mfld_ci/mfldisp/css/sh_css_hrt.c | 2332 +++++++++++++
.../media/video/mfld_ci/mfldisp/css/sh_css_hrt.h | 374 +++
.../video/mfld_ci/mfldisp/css/sh_css_internal.h | 162 +
.../media/video/mfld_ci/mfldisp/css/sh_css_isp.h | 335 ++
.../video/mfld_ci/mfldisp/css/sh_css_params.c | 1725 ++++++++++
.../video/mfld_ci/mfldisp/css/sh_css_params.h | 374 +++
.../media/video/mfld_ci/mfldisp/css/sh_css_sp.c | 691 ++++
.../media/video/mfld_ci/mfldisp/css/sh_css_sp.h | 156 +
.../media/video/mfld_ci/mfldisp/css/sh_css_uds.c | 398 +++
.../media/video/mfld_ci/mfldisp/css/sh_css_uds.h | 100 +
18 files changed, 12580 insertions(+), 0 deletions(-)
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css.c
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_binary.c
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_binary.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_debug.c
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_debug.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_frame.c
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_frame.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_hrt.c
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_hrt.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_internal.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_isp.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_params.c
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_params.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_sp.c
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_sp.h
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_uds.c
create mode 100644 drivers/media/video/mfld_ci/mfldisp/css/sh_css_uds.h
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css.c b/drivers/media/video/mfld_ci/mfldisp/css/sh_css.c
new file mode 100644
index 0000000..5548205
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css.c
@@ -0,0 +1,3411 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef HRT_KERNEL
+#include <string.h> /* for memcpy */
+#endif
+
+#ifdef HRT_CSIM
+#include "hive_isp_css_dma_set_hrt.h"
+#endif
+
+#include "sh_css.h"
+#include "sh_css_hrt.h"
+#include "sh_css_binary.h"
+#include "sh_css_internal.h"
+#include "sh_css_uds.h"
+#include "sh_css_sp.h"
+#if defined(HRT_CSIM) || defined(HRT_FPGA)
+#include "sh_css_debug.h"
+#endif
+#include "sp/sp_defs.h"
+
+/* for JPEG, we don't know the length of the image upfront,
+ * but since we support sensor upto 16MP, we take this as
+ * upper limit.
+ */
+#define JPEG_BYTES (16 * 1024 * 1024)
+
+#define PC_HISTOGRAM 0
+
+#define CHECK_INIT() \
+ do { \
+ if (!my_css.initialized) { \
+ return sh_css_err_not_initialized; \
+ } \
+ } while (0)
+
+#define CHECK_RES(width, height) \
+ do { \
+ if ((width) == 0 || \
+ (height) == 0 || \
+ (width) & 0x1 || \
+ (height) & 0x1) { \
+ return sh_css_err_illegal_resolution; \
+ } \
+ } while (0)
+
+#define CHECK_INPUT(must_be_raw) \
+ do { \
+ if (my_css.input_width == 0 || \
+ my_css.input_height == 0) { \
+ return sh_css_err_input_resolution_not_set; \
+ } \
+ if (my_css.input_effective_info.width == 0 || \
+ my_css.input_effective_info.height == 0) { \
+ return sh_css_err_effective_input_resolution_not_set; \
+ } \
+ if ((must_be_raw) && \
+ !input_format_is_raw(my_css.input_format)) { \
+ return sh_css_err_unsupported_input_format; \
+ } \
+ } while (0)
+
+#define CHECK_FRAME_INFO(info) \
+ do { \
+ if ((info).width == 0 || (info).height == 0) { \
+ return sh_css_err_illegal_resolution; \
+ } \
+ } while (0)
+
+#define CHECK_VF_INFO(info) \
+ do { \
+ CHECK_FRAME_INFO(info); \
+ if ((info).width > 1280) { \
+ return sh_css_err_viewfinder_resolution_too_wide; \
+ } \
+ } while (0)
+
+#define CHECK_VF_OUT_INFO(out_info, vf_info) \
+ do { \
+ CHECK_FRAME_INFO(out_info); \
+ CHECK_FRAME_INFO(vf_info); \
+ if ((vf_info).width > (out_info).width || \
+ (vf_info).height > (out_info).height) { \
+ return \
+ sh_css_err_viewfinder_resolution_exceeds_output; \
+ } \
+ } while (0)
+
+/* we don't compare the height here since the output frame is usually
+ a couple of lines bigger than the height of the binary info.
+ For the padded width however, we do check equility because this is
+ not expected to differ. A difference there would indicate an erroneous
+ situation. */
+#define CHECK_INFOS_MATCH(frame_info, binary_info) \
+ do { \
+ if ((frame_info).padded_width != (binary_info).padded_width || \
+ (frame_info).height < (binary_info).height || \
+ (frame_info).format != (binary_info).format) { \
+ return sh_css_err_frames_mismatch; \
+ } \
+ } while (0)
+
+#define CHECK_PTR_ARG(ptr) \
+ do { \
+ if ((ptr) == NULL) { \
+ return sh_css_err_invalid_arguments; \
+ } \
+ } while (0)
+
+#define DEFAULT_FRAME_INFO \
+{ \
+ .width = 0, \
+ .height = 0, \
+ .format = sh_css_frame_format_yuv420, \
+ .vraw_bit_depth = 0, \
+ .raw_bayer_order = sh_css_bayer_order_grbg, \
+}
+
+enum sh_css_mode {
+ sh_css_mode_preview,
+ sh_css_mode_video,
+ sh_css_mode_capture
+};
+
+enum sh_css_state {
+ sh_css_state_idle,
+ sh_css_state_executing,
+ sh_css_state_executing_sp_only,
+};
+
+struct sh_css_pipeline_stage {
+ struct sh_css_binary *binary;
+ struct sh_css_binary_args args;
+ ShBool out_frame_allocated;
+ ShBool vf_frame_allocated;
+ struct sh_css_pipeline_stage *next;
+};
+
+struct sh_css_pipeline {
+ unsigned int length;
+ struct sh_css_pipeline_stage *stages;
+ ShBool reload;
+ enum sh_css_input_mode input_mode;
+ struct sh_css_pipeline_stage *current_stage;
+ struct sh_css_params *isp_parameters;
+};
+
+struct sh_css_preview_settings {
+ struct sh_css_params *isp_parameters;
+ enum sh_css_input_mode input_mode;
+ struct sh_css_frame_info output_info;
+ struct sh_css_pipeline pipeline;
+ struct sh_css_binary *preview_binary;
+ struct sh_css_binary *vf_pp_binary;
+ struct sh_css_frame *ref_frames[2];
+ struct sh_css_frame *prev_ref_frame;
+ struct sh_css_frame *prev_out_frame;
+ ShBool dz_used;
+};
+
+#define DEFAULT_PREVIEW_SETTINGS \
+{ \
+ .isp_parameters = NULL, \
+ .input_mode = sh_css_input_mode_sensor, \
+ .output_info = DEFAULT_FRAME_INFO, \
+ .preview_binary = NULL, \
+ .vf_pp_binary = NULL, \
+ .ref_frames = { NULL, NULL }, \
+ .prev_ref_frame = NULL, \
+ .prev_out_frame = NULL, \
+ .dz_used = ShTrue, \
+}
+
+struct sh_css_capture_settings {
+ struct sh_css_params *isp_parameters;
+ enum sh_css_input_mode input_mode;
+ enum sh_css_capture_mode mode;
+ ShBool xnr;
+ ShBool bayer_ds;
+ struct sh_css_binary *copy_binary;
+ struct sh_css_binary *primary_binary;
+ struct sh_css_binary *pregdc_binary;
+ struct sh_css_binary *gdc_binary;
+ struct sh_css_binary *postgdc_binary;
+ struct sh_css_binary *xnr_binary;
+ struct sh_css_binary *vf_pp_binary;
+ struct sh_css_frame_info output_info;
+ struct sh_css_frame_info vf_info;
+ struct sh_css_pipeline pipeline;
+ struct sh_css_frame *output_frame;
+ ShBool online;
+ const struct sh_css_morph_table *id_morph_table;
+};
+
+#define DEFAULT_CAPTURE_SETTINGS \
+{ \
+ .isp_parameters = NULL, \
+ .input_mode = sh_css_input_mode_sensor, \
+ .mode = sh_css_capture_mode_primary, \
+ .xnr = ShFalse, \
+ .bayer_ds = ShFalse, \
+ .copy_binary = NULL, \
+ .primary_binary = NULL, \
+ .pregdc_binary = NULL, \
+ .gdc_binary = NULL, \
+ .postgdc_binary = NULL, \
+ .xnr_binary = NULL, \
+ .vf_pp_binary = NULL, \
+ .output_info = DEFAULT_FRAME_INFO, \
+ .vf_info = DEFAULT_FRAME_INFO, \
+ .output_frame = NULL, \
+ .online = ShTrue, \
+ .id_morph_table = NULL, \
+}
+
+struct sh_css_video_settings {
+ struct sh_css_binary *video_binary;
+ struct sh_css_binary *vf_pp_binary;
+ struct sh_css_params *isp_parameters;
+ enum sh_css_input_mode input_mode;
+ struct sh_css_frame_info output_info;
+ struct sh_css_frame_info vf_info;
+ struct sh_css_frame *ref_frames[2];
+ struct sh_css_frame *prev_ref_frame;
+ unsigned int dvs_vector_x;
+ unsigned int dvs_vector_y;
+ unsigned int dvs_envelope_width;
+ unsigned int dvs_envelope_height;
+ struct sh_css_frame *vf_pp_in_frame;
+ struct sh_css_pipeline pipeline;
+};
+
+#define DEFAULT_VIDEO_SETTINGS \
+{ \
+ .video_binary = NULL, \
+ .vf_pp_binary = NULL, \
+ .isp_parameters = NULL, \
+ .input_mode = sh_css_input_mode_sensor, \
+ .output_info = DEFAULT_FRAME_INFO, \
+ .vf_info = DEFAULT_FRAME_INFO, \
+ .ref_frames = { NULL, NULL }, \
+ .prev_ref_frame = NULL, \
+ .dvs_vector_x = 0, \
+ .dvs_vector_y = 0, \
+ .dvs_envelope_width = 0, \
+ .dvs_envelope_height = 0, \
+}
+
+struct sh_css {
+ struct sh_css_preview_settings preview_settings;
+ struct sh_css_capture_settings capture_settings;
+ struct sh_css_video_settings video_settings;
+ unsigned int ch_id;
+ unsigned int input_width;
+ unsigned int input_height;
+ struct sh_css_frame_info input_effective_info;
+ enum sh_css_input_format input_format;
+ enum sh_css_mode mode;
+ enum sh_css_mipi_port mipi_port;
+ unsigned int mipi_num_lanes;
+ unsigned int mipi_timeout;
+ unsigned int mipi_comp_bpp;
+ unsigned int mipi_uncomp_bpp;
+ enum sh_css_mipi_compression mipi_comp;
+ ShBool dump_debug;
+ struct sh_css_histogram *pc_histogram;
+ void *(*malloc) (size_t size);
+ void (*free) (void *ptr);
+ enum sh_css_state state;
+ ShBool two_pixels_per_clock;
+ enum sh_css_bayer_order bayer_order;
+ ShBool tpg_running;
+ ShBool prbs_running;
+ enum sh_css_interrupt_setting irq_setting;
+ struct sh_css_params *default_params;
+ const struct sh_css_overlay *vf_overlay;
+ ShBool initialized;
+ ShBool if_block_fifo_no_reqs;
+};
+
+#define DEFAULT_CSS \
+{ \
+ .preview_settings = DEFAULT_PREVIEW_SETTINGS, \
+ .capture_settings = DEFAULT_CAPTURE_SETTINGS, \
+ .video_settings = DEFAULT_VIDEO_SETTINGS, \
+ .ch_id = 0, \
+ .input_width = 0, \
+ .input_height = 0, \
+ .input_effective_info = DEFAULT_FRAME_INFO, \
+ .input_format = sh_css_input_format_raw_10, \
+ .mode = -1, \
+ .mipi_port = sh_css_mipi_port_1lane, \
+ .mipi_num_lanes = 1, \
+ .mipi_timeout = 0xffff4, \
+ .mipi_comp_bpp = 0, \
+ .mipi_uncomp_bpp = 0, \
+ .mipi_comp = sh_css_mipi_compression_none, \
+ .dump_debug = ShFalse, \
+ .pc_histogram = NULL, \
+ .malloc = NULL, \
+ .free = NULL, \
+ .state = sh_css_state_idle, \
+ .two_pixels_per_clock = ShFalse, \
+ .bayer_order = sh_css_bayer_order_grbg, \
+ .tpg_running = ShFalse, \
+ .prbs_running = ShFalse, \
+ .default_params = NULL, \
+ .vf_overlay = NULL, \
+ .initialized = ShTrue, \
+ .if_block_fifo_no_reqs = ShFalse, \
+}
+
+int (*sh_css_printf) (const char *fmt, ...) = NULL;
+static struct sh_css_frame *copy_frame;
+
+static struct sh_css my_css;
+
+/* Input network configuration functions */
+static sh_css_err
+get_copy_out_frame_format(enum sh_css_frame_format *format)
+{
+ switch (my_css.input_format) {
+ case sh_css_input_format_yuv420_8_legacy:
+ case sh_css_input_format_yuv420_8:
+ *format = sh_css_frame_format_yuv420;
+ break;
+ case sh_css_input_format_yuv420_10:
+ *format = sh_css_frame_format_yuv420_16;
+ break;
+ case sh_css_input_format_yuv422_8:
+ *format = sh_css_frame_format_yuv422;
+ break;
+ case sh_css_input_format_yuv422_10:
+ *format = sh_css_frame_format_yuv422_16;
+ break;
+ case sh_css_input_format_rgb_444:
+ case sh_css_input_format_rgb_555:
+ case sh_css_input_format_rgb_565:
+ if (*format != sh_css_frame_format_rgba888)
+ *format = sh_css_frame_format_rgb565;
+ break;
+ case sh_css_input_format_rgb_666:
+ case sh_css_input_format_rgb_888:
+ *format = sh_css_frame_format_rgba888;
+ break;
+ case sh_css_input_format_raw_6:
+ case sh_css_input_format_raw_7:
+ case sh_css_input_format_raw_8:
+ case sh_css_input_format_raw_10:
+ case sh_css_input_format_raw_12:
+ case sh_css_input_format_raw_14:
+ case sh_css_input_format_raw_16:
+ if (*format != sh_css_frame_format_raw8 &&
+ *format != sh_css_frame_format_raw16)
+ *format = sh_css_frame_format_vraw16;
+ break;
+ case sh_css_input_format_binary_8:
+ *format = sh_css_frame_format_binary_8;
+ break;
+ default:
+ return sh_css_err_internal_error;
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_format_bits_per_pixel(enum sh_css_input_format format,
+ ShBool two_ppc,
+ unsigned int *bits_per_pixel)
+{
+ switch (format) {
+ case sh_css_input_format_yuv420_8_legacy:
+ case sh_css_input_format_yuv420_8:
+ case sh_css_input_format_yuv422_8:
+ case sh_css_input_format_rgb_888:
+ case sh_css_input_format_raw_8:
+ *bits_per_pixel = 8;
+ break;
+ case sh_css_input_format_yuv420_10:
+ case sh_css_input_format_yuv422_10:
+ case sh_css_input_format_raw_10:
+ *bits_per_pixel = 10;
+ break;
+ case sh_css_input_format_rgb_444:
+ *bits_per_pixel = 4;
+ break;
+ case sh_css_input_format_rgb_555:
+ *bits_per_pixel = 5;
+ break;
+ case sh_css_input_format_rgb_565:
+ *bits_per_pixel = 565;
+ break;
+ case sh_css_input_format_rgb_666:
+ case sh_css_input_format_raw_6:
+ *bits_per_pixel = 6;
+ break;
+ case sh_css_input_format_raw_7:
+ *bits_per_pixel = 7;
+ break;
+ case sh_css_input_format_raw_12:
+ *bits_per_pixel = 12;
+ break;
+ case sh_css_input_format_raw_14:
+ if (two_ppc)
+ *bits_per_pixel = 14;
+ else
+ *bits_per_pixel = 12;
+ break;
+ case sh_css_input_format_raw_16:
+ if (two_ppc)
+ *bits_per_pixel = 16;
+ else
+ *bits_per_pixel = 12;
+ break;
+ default:
+ return sh_css_err_invalid_frame_format;
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_host_to_isp_format(enum sh_css_frame_format from,
+ enum ShImageFormat *to)
+{
+ switch (from) {
+ case sh_css_frame_format_nv11:
+ *to = IMAGEFORMAT_NV11;
+ break;
+ case sh_css_frame_format_nv21:
+ *to = IMAGEFORMAT_NV21;
+ break;
+ case sh_css_frame_format_nv12:
+ *to = IMAGEFORMAT_NV12;
+ break;
+ case sh_css_frame_format_nv61:
+ *to = IMAGEFORMAT_NV61;
+ break;
+ case sh_css_frame_format_nv16:
+ *to = IMAGEFORMAT_NV16;
+ break;
+ case sh_css_frame_format_yv12:
+ *to = IMAGEFORMAT_YV12;
+ break;
+ case sh_css_frame_format_yuv420:
+ *to = IMAGEFORMAT_YUV420;
+ break;
+ case sh_css_frame_format_yv16:
+ *to = IMAGEFORMAT_YV16;
+ break;
+ case sh_css_frame_format_yuv422:
+ *to = IMAGEFORMAT_YUV422;
+ break;
+ case sh_css_frame_format_yuv444:
+ *to = IMAGEFORMAT_YUV444;
+ break;
+ case sh_css_frame_format_yuv420_16:
+ *to = IMAGEFORMAT_YUV420_16;
+ break;
+ case sh_css_frame_format_yuv422_16:
+ *to = IMAGEFORMAT_YUV422_16;
+ break;
+ case sh_css_frame_format_yuyv:
+ *to = IMAGEFORMAT_YUYV;
+ break;
+ case sh_css_frame_format_uyvy:
+ *to = IMAGEFORMAT_UYVY;
+ break;
+ case sh_css_frame_format_raw8:
+ *to = IMAGEFORMAT_RAW8;
+ break;
+ case sh_css_frame_format_raw16:
+ *to = IMAGEFORMAT_RAW16;
+ break;
+ case sh_css_frame_format_vraw16:
+ *to = IMAGEFORMAT_VRAW;
+ break;
+ case sh_css_frame_format_rgba888:
+ *to = IMAGEFORMAT_RGBA888;
+ break;
+ case sh_css_frame_format_planar_rgb888:
+ *to = IMAGEFORMAT_PLANAR_RGB888;
+ break;
+ case sh_css_frame_format_rgb565:
+ *to = IMAGEFORMAT_RGB565;
+ break;
+ case sh_css_frame_format_qplane6:
+ *to = IMAGEFORMAT_QPLANE6;
+ break;
+ case sh_css_frame_format_plane6:
+ *to = IMAGEFORMAT_PLANE6;
+ break;
+ case sh_css_frame_format_yuv_line:
+ *to = IMAGEFORMAT_YUV_LINE;
+ break;
+ default:
+ return sh_css_err_invalid_frame_format;
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_to_isp_stream_format(enum sh_css_input_format from,
+ unsigned int two_pixels_per_clock,
+ enum ShStreamFormat *to,
+ unsigned int *bits_per_pixel)
+{
+ return_on_error(sh_css_input_format_bits_per_pixel(from,
+ two_pixels_per_clock,
+ bits_per_pixel));
+ switch (from) {
+ case sh_css_input_format_yuv420_8_legacy:
+ *to = ShStreamFormat_yuv420_legacy;
+ break;
+ case sh_css_input_format_yuv420_8:
+ case sh_css_input_format_yuv420_10:
+ *to = ShStreamFormat_yuv420;
+ *to = ShStreamFormat_yuv420;
+ break;
+ case sh_css_input_format_yuv422_8:
+ case sh_css_input_format_yuv422_10:
+ *to = ShStreamFormat_yuv422;
+ *to = ShStreamFormat_yuv422;
+ break;
+ case sh_css_input_format_rgb_444:
+ case sh_css_input_format_rgb_555:
+ case sh_css_input_format_rgb_565:
+ case sh_css_input_format_rgb_666:
+ case sh_css_input_format_rgb_888:
+ *to = ShStreamFormat_rgb;
+ break;
+ case sh_css_input_format_raw_6:
+ case sh_css_input_format_raw_7:
+ case sh_css_input_format_raw_8:
+ case sh_css_input_format_raw_10:
+ case sh_css_input_format_raw_12:
+ case sh_css_input_format_raw_14:
+ case sh_css_input_format_raw_16:
+ *to = ShStreamFormat_raw;
+ break;
+ default:
+ return sh_css_err_invalid_frame_format;
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_isp_to_host_format(enum ShImageFormat from,
+ enum sh_css_frame_format *to)
+{
+ switch (from) {
+ case IMAGEFORMAT_NV11:
+ *to = sh_css_frame_format_nv11;
+ break;
+ case IMAGEFORMAT_NV21:
+ *to = sh_css_frame_format_nv21;
+ break;
+ case IMAGEFORMAT_NV12:
+ *to = sh_css_frame_format_nv12;
+ break;
+ case IMAGEFORMAT_NV61:
+ *to = sh_css_frame_format_nv61;
+ break;
+ case IMAGEFORMAT_NV16:
+ *to = sh_css_frame_format_nv16;
+ break;
+ case IMAGEFORMAT_YV12:
+ *to = sh_css_frame_format_yv12;
+ break;
+ case IMAGEFORMAT_YUV420:
+ *to = sh_css_frame_format_yuv420;
+ break;
+ case IMAGEFORMAT_YV16:
+ *to = sh_css_frame_format_yv16;
+ break;
+ case IMAGEFORMAT_YUV422:
+ *to = sh_css_frame_format_yuv422;
+ break;
+ case IMAGEFORMAT_YUV444:
+ *to = sh_css_frame_format_yuv444;
+ break;
+ case IMAGEFORMAT_YUV420_16:
+ *to = sh_css_frame_format_yuv420_16;
+ break;
+ case IMAGEFORMAT_YUV422_16:
+ *to = sh_css_frame_format_yuv422_16;
+ break;
+ case IMAGEFORMAT_YUYV:
+ *to = sh_css_frame_format_yuyv;
+ break;
+ case IMAGEFORMAT_UYVY:
+ *to = sh_css_frame_format_uyvy;
+ break;
+ case IMAGEFORMAT_RAW8:
+ *to = sh_css_frame_format_raw8;
+ break;
+ case IMAGEFORMAT_RAW16:
+ *to = sh_css_frame_format_raw16;
+ break;
+ case IMAGEFORMAT_VRAW:
+ *to = sh_css_frame_format_vraw16;
+ break;
+ case IMAGEFORMAT_PLANAR_RGB888:
+ *to = sh_css_frame_format_planar_rgb888;
+ break;
+ case IMAGEFORMAT_RGBA888:
+ *to = sh_css_frame_format_rgba888;
+ break;
+ case IMAGEFORMAT_RGB565:
+ *to = sh_css_frame_format_rgb565;
+ break;
+ case IMAGEFORMAT_QPLANE6:
+ *to = sh_css_frame_format_qplane6;
+ break;
+ case IMAGEFORMAT_PLANE6:
+ *to = sh_css_frame_format_plane6;
+ break;
+ case IMAGEFORMAT_YUV_LINE:
+ *to = sh_css_frame_format_yuv_line;
+ break;
+ default:
+ return sh_css_err_invalid_frame_format;
+ }
+ return sh_css_success;
+}
+
+/* compute the log2 of the downscale factor needed to get closest
+ * to the requested viewfinder resolution on the upper side. The output cannot
+ * be smaller than the requested viewfinder resolution.
+ */
+sh_css_err
+sh_css_vf_downscale_log2(const struct sh_css_frame_info *out_info,
+ const struct sh_css_frame_info *vf_info,
+ unsigned int *downscale_log2)
+{
+ unsigned int ds_log2 = 0, out_width = out_info->padded_width;
+
+ if (out_width == 0)
+ return 0;
+
+ /* downscale until width smaller than the viewfinder width. We don't
+ * test for the height since the vmem buffers only put restrictions on
+ * the width of a line, not on the number of lines in a frame.
+ */
+ while (out_width >= vf_info->width) {
+ ds_log2++;
+ out_width /= 2;
+ }
+ /* now width is smaller, so we go up one step */
+ if (ds_log2 > 0 && out_width * 2 < 1280)
+ ds_log2--;
+ /* TODO: use actual max input resolution of vf_pp binary */
+ if ((out_info->width >> ds_log2) >= 1280)
+ return sh_css_err_viewfinder_resolution_too_wide;
+ *downscale_log2 = ds_log2;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_format_type(enum sh_css_input_format input_format,
+ enum sh_css_mipi_compression compression,
+ unsigned int *fmt_type)
+{
+#ifndef CSS_RECEIVER
+ /* if we don't have a CSS reciever, then we always use format type 0 */
+ *fmt_type = 0;
+ return sh_css_success;
+#endif
+ if (compression != sh_css_mipi_compression_none) {
+ switch (input_format) {
+ case sh_css_input_format_raw_6:
+ *fmt_type = 6;
+ break;
+ case sh_css_input_format_raw_7:
+ *fmt_type = 7;
+ break;
+ case sh_css_input_format_raw_8:
+ *fmt_type = 8;
+ break;
+ case sh_css_input_format_raw_10:
+ *fmt_type = 10;
+ break;
+ case sh_css_input_format_raw_12:
+ *fmt_type = 12;
+ break;
+ case sh_css_input_format_raw_14:
+ *fmt_type = 14;
+ break;
+ case sh_css_input_format_raw_16:
+ *fmt_type = 16;
+ break;
+ default:
+ return sh_css_err_internal_error;
+ }
+ return sh_css_success;
+ }
+ /* This mapping comes from the Arasan CSS function spec
+ * (CSS_func_spec1.08_ahb_sep29_08.pdf).
+ */
+ switch (input_format) {
+ case sh_css_input_format_rgb_888:
+ *fmt_type = 0;
+ break;
+ case sh_css_input_format_rgb_555:
+ *fmt_type = 1;
+ break;
+ case sh_css_input_format_rgb_444:
+ *fmt_type = 2;
+ break;
+ case sh_css_input_format_rgb_565:
+ *fmt_type = 3;
+ break;
+ case sh_css_input_format_rgb_666:
+ *fmt_type = 4;
+ break;
+ case sh_css_input_format_raw_8:
+ *fmt_type = 5;
+ break;
+ case sh_css_input_format_raw_10:
+ *fmt_type = 6;
+ break;
+ case sh_css_input_format_raw_6:
+ *fmt_type = 7;
+ break;
+ case sh_css_input_format_raw_7:
+ *fmt_type = 8;
+ break;
+ case sh_css_input_format_raw_12:
+ *fmt_type = 9;
+ break;
+ case sh_css_input_format_raw_14:
+ *fmt_type = 10;
+ break;
+ case sh_css_input_format_yuv420_8:
+ *fmt_type = 11;
+ break;
+ case sh_css_input_format_yuv420_10:
+ *fmt_type = 12;
+ break;
+ case sh_css_input_format_yuv422_8:
+ *fmt_type = 13;
+ break;
+ case sh_css_input_format_yuv422_10:
+ *fmt_type = 14;
+ break;
+ case sh_css_input_format_binary_8:
+ *fmt_type = 15;
+ break;
+ case sh_css_input_format_yuv420_8_legacy:
+ *fmt_type = 16;
+ break;
+ case sh_css_input_format_raw_16:
+ *fmt_type = 17;
+ break; /* This is not specified by Arasan, so we use
+ * 17 for now.
+ */
+ default:
+ return sh_css_err_internal_error;
+ }
+ return sh_css_success;
+}
+
+/* ISP expects GRBG bayer order, we skip one line and/or one row
+ * to correct in case the input bayer order is different.
+ */
+static unsigned int
+lines_needed_for_bayer_order(void)
+{
+ if (my_css.bayer_order == sh_css_bayer_order_bggr ||
+ my_css.bayer_order == sh_css_bayer_order_gbrg) {
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned int
+columns_needed_for_bayer_order(void)
+{
+ if (my_css.bayer_order == sh_css_bayer_order_rggb ||
+ my_css.bayer_order == sh_css_bayer_order_gbrg) {
+ return 1;
+ }
+ return 0;
+}
+
+static sh_css_err
+extra_lines_available(unsigned int *extra)
+{
+ unsigned int needed = my_css.input_effective_info.height +
+ 2 * lines_needed_for_bayer_order();
+
+ if (needed > my_css.input_height)
+ return sh_css_err_not_enough_input_lines;
+
+ *extra = MIN(my_css.input_height - needed, OUT_CROP_POS_Y);
+ return sh_css_success;
+}
+
+static sh_css_err
+input_start_column(struct sh_css_binary *binary,
+ unsigned int *start_column)
+{
+ unsigned int in = my_css.input_width,
+ bin_in = binary->in_frame_info.width,
+ for_bayer = columns_needed_for_bayer_order(), start;
+
+ if (bin_in + 2 * for_bayer > in)
+ return sh_css_err_not_enough_input_columns;
+
+#ifndef HRT_CSIM
+ /* On the hardware, we want to use the middle of the input, so we
+ * divide the start column by 2. On the simulator, we cannot handle
+ * extra columns at the end of the frame.
+ */
+ start = (in - bin_in) / 2;
+ /* in case the number of extra columns is 2 or odd, we round the start
+ column down */
+ start &= ~0x1;
+#else
+ start = in - bin_in;
+#endif
+ /* now we add the one column (if needed) to correct for the bayer
+ * order).
+ */
+ start += for_bayer;
+ *start_column = start;
+ return sh_css_success;
+}
+
+static sh_css_err
+input_start_line(struct sh_css_binary *binary, unsigned int *start_line)
+{
+ unsigned int in = my_css.input_height,
+ bin_in = binary->in_frame_info.height,
+ for_bayer = lines_needed_for_bayer_order(), start;
+
+ if (bin_in + 2 * for_bayer > in)
+ return sh_css_err_not_enough_input_lines;
+
+#ifndef HRT_CSIM
+ /* On the hardware, we want to use the middle of the input, so we
+ * divide the start line by 2. On the simulator, we cannot handle extra
+ * lines at the end of the frame.
+ */
+ start = (in - bin_in) / 2;
+ /* in case the number of extra lines is 2 or odd, we round the start
+ * line down.
+ */
+ start &= ~0x1;
+#else
+ start = in - bin_in;
+#endif
+ /* now we add the one line (if needed) to correct for the bayer order */
+ start += for_bayer;
+ *start_line = start;
+ return sh_css_success;
+}
+
+static sh_css_err
+program_input_formatter(struct sh_css_binary *binary)
+{
+ unsigned int start_line, start_column = 0,
+ cropped_height, cropped_width, left_padding,
+ num_vectors,
+ buffer_height = 2, buffer_width = binary->in_max_width,
+ two_ppc = my_css.two_pixels_per_clock,
+ vmem_increment = 0,
+ deinterleaving = 0,
+ deinterleaving_b = 0,
+ width_a = 0,
+ width_b = 0,
+ bits_per_pixel,
+ vectors_per_buffer,
+ vectors_per_line = 0,
+ buffers_per_line = 0,
+ buf_offset_b = 0,
+ line_width = 0, width_b_factor = 1, start_column_b;
+ enum sh_css_input_format input_format = binary->input_format;
+ struct sh_css_if_config if_a_config, if_b_config;
+
+ /* TODO: check to see if input is RAW and if current mode interprets
+ * RAW data in any particular bayer order. copy binary with output
+ * format other than vraw16 should not result in dropping lines and/or
+ * columns.
+ */
+ return_on_error(input_start_line(binary, &start_line));
+ cropped_height = binary->in_frame_info.height;
+
+ cropped_width = binary->in_frame_info.width;
+ left_padding =
+ binary->filter_columns ? 2 * ISP_NWAY - binary->filter_columns : 0;
+
+ if (left_padding)
+ num_vectors = CEIL_DIV(cropped_width + left_padding, ISP_NWAY);
+ else {
+ return_on_error(input_start_column(binary, &start_column));
+ num_vectors = binary->input_buf_vectors;
+ }
+
+ start_column_b = start_column;
+ cropped_width += binary->filter_columns;
+
+ bits_per_pixel = sh_css_hrt_if_prim_vec_align()*8 / ISP_NWAY;
+ switch (input_format) {
+ case sh_css_input_format_yuv420_8_legacy:
+ if (two_ppc) {
+ vmem_increment = 1;
+ deinterleaving = 1;
+ deinterleaving_b = 1;
+ /* half lines */
+ width_a = cropped_width * deinterleaving / 2;
+ width_b_factor = 2;
+ /* full lines */
+ width_b = width_a * width_b_factor;
+ buffer_width *= deinterleaving * 2;
+ /* Patch from bayer to yuv */
+ num_vectors = num_vectors / 2 * deinterleaving;
+ buf_offset_b = buffer_width;
+ vectors_per_line = num_vectors / buffer_height;
+ /* Even lines are half size */
+ line_width =
+ vectors_per_line * sh_css_hrt_if_prim_vec_align() /
+ 2;
+ start_column /= 2;
+ } else {
+ vmem_increment = 1;
+ deinterleaving = 3;
+ width_a = cropped_width * deinterleaving / 2;
+ buffer_width = buffer_width * deinterleaving / 2;
+ /* Patch from bayer to yuv */
+ num_vectors = num_vectors / 4 * deinterleaving;
+ start_column = start_column * deinterleaving / 2;
+ }
+ break;
+ case sh_css_input_format_yuv420_8:
+ case sh_css_input_format_yuv420_10:
+ if (two_ppc) {
+ vmem_increment = 1;
+ deinterleaving = 1;
+ width_a = width_b = cropped_width * deinterleaving / 2;
+ buffer_width *= deinterleaving * 2;
+ /* Patch from bayer to yuv */
+ num_vectors = num_vectors / 2 * deinterleaving;
+ buf_offset_b = buffer_width;
+ vectors_per_line = num_vectors / buffer_height;
+ /* Even lines are half size */
+ line_width =
+ vectors_per_line * sh_css_hrt_if_prim_vec_align() /
+ 2;
+ start_column *= deinterleaving;
+ start_column /= 2;
+ start_column_b = start_column;
+ } else {
+ vmem_increment = 1;
+ deinterleaving = 1;
+ width_a = cropped_width * deinterleaving;
+ buffer_width *= deinterleaving * 2;
+ /* Patch from bayer to yuv */
+ num_vectors = num_vectors / 2 * deinterleaving;
+ start_column *= deinterleaving;
+ }
+ break;
+ case sh_css_input_format_yuv422_8:
+ case sh_css_input_format_yuv422_10:
+ if (two_ppc) {
+ vmem_increment = 1;
+ deinterleaving = 1;
+ width_a = width_b = cropped_width * deinterleaving;
+ buffer_width *= deinterleaving * 2;
+ /* Patch from bayer to yuv */
+ num_vectors = num_vectors / 2 * deinterleaving;
+ buf_offset_b = buffer_width;
+ start_column *= deinterleaving;
+ start_column_b = start_column;
+ } else {
+ vmem_increment = 1;
+ deinterleaving = 2;
+ width_a = cropped_width * deinterleaving;
+ buffer_width *= deinterleaving;
+ /* Patch from bayer to yuv */
+ num_vectors = num_vectors / 2 * deinterleaving;
+ start_column *= deinterleaving;
+ }
+ break;
+ case sh_css_input_format_rgb_444:
+ case sh_css_input_format_rgb_555:
+ case sh_css_input_format_rgb_565:
+ case sh_css_input_format_rgb_666:
+ case sh_css_input_format_rgb_888:
+ if (two_ppc) {
+ deinterleaving = 2; /* BR in if_a, G in if_b */
+ deinterleaving_b = 1; /* BR in if_a, G in if_b */
+ buffers_per_line = 4;
+ start_column_b = start_column;
+ start_column *= deinterleaving;
+ start_column_b *= deinterleaving_b;
+ } else {
+ deinterleaving = 3; /* BGR */
+ buffers_per_line = 3;
+ start_column *= deinterleaving;
+ }
+ vmem_increment = 1;
+ width_a = cropped_width * deinterleaving;
+ width_b = cropped_width * deinterleaving_b;
+ buffer_width *= buffers_per_line;
+ /* Patch from bayer to rgb */
+ num_vectors = num_vectors / 2 * deinterleaving;
+ buf_offset_b = buffer_width * 4 / buffers_per_line;
+ break;
+ case sh_css_input_format_raw_6:
+ case sh_css_input_format_raw_7:
+ case sh_css_input_format_raw_8:
+ case sh_css_input_format_raw_10:
+ case sh_css_input_format_raw_12:
+ if (two_ppc) {
+ vmem_increment = 2;
+ deinterleaving = 1;
+ width_a = width_b = cropped_width / 2;
+ start_column /= 2;
+ start_column_b = start_column;
+ buf_offset_b = sh_css_hrt_if_prim_vec_align();
+ } else {
+ vmem_increment = 1;
+ deinterleaving = 2;
+ width_a = cropped_width;
+ }
+ buffer_height *= 2;
+ break;
+ case sh_css_input_format_raw_14:
+ case sh_css_input_format_raw_16:
+ if (two_ppc) {
+ vmem_increment = 1;
+ deinterleaving = 2;
+ width_a = width_b = cropped_width;
+ buf_offset_b = buffer_width * 2;
+ bits_per_pixel *= 2;
+ } else {
+ vmem_increment = 1;
+ deinterleaving = 2;
+ width_a = cropped_width;
+ start_column /= deinterleaving;
+ }
+ buffer_height *= 2;
+ break;
+ case sh_css_input_format_binary_8:
+ break;
+ }
+ if (width_a == 0)
+ return sh_css_err_unsupported_input_mode;
+
+ if (two_ppc)
+ left_padding /= 2;
+
+ /* Hack : need proper fix (from Lex) */
+ if (left_padding)
+ vectors_per_line = num_vectors;
+ if (!vectors_per_line) {
+ vectors_per_line = num_vectors / buffer_height;
+ line_width = vectors_per_line*sh_css_hrt_if_prim_vec_align();
+ }
+ if (!line_width)
+ line_width = vectors_per_line * sh_css_hrt_if_prim_vec_align();
+ if (!buffers_per_line)
+ buffers_per_line = deinterleaving;
+
+ vectors_per_buffer = buffer_height * buffer_width / ISP_NWAY;
+
+ if_a_config.start_line = start_line;
+ if_a_config.start_column = start_column;
+ if_a_config.left_padding = left_padding / deinterleaving;
+ if_a_config.cropped_height = cropped_height;
+ if_a_config.cropped_width = width_a;
+ if_a_config.deinterleaving = deinterleaving;
+ if_a_config.buf_vecs = vectors_per_buffer;
+ if_a_config.buf_start_index = 0;
+ if_a_config.buf_increment = vmem_increment;
+ if_a_config.buf_eol_offset =
+ buffer_width * bits_per_pixel/8 - line_width;
+ if_a_config.yuv420 = input_format == sh_css_input_format_yuv420_8
+ || input_format == sh_css_input_format_yuv420_10;
+
+ if (two_ppc) {
+ if (deinterleaving_b) {
+ deinterleaving = deinterleaving_b;
+ width_b = cropped_width * deinterleaving;
+ buffer_width *= deinterleaving;
+ /* Patch from bayer to rgb */
+ num_vectors =
+ num_vectors / 2 * deinterleaving * width_b_factor;
+ vectors_per_line = num_vectors / buffer_height;
+ line_width =
+ vectors_per_line * sh_css_hrt_if_prim_vec_align();
+ }
+ if_b_config.start_line = start_line;
+ if_b_config.start_column = start_column_b;
+ if_b_config.left_padding = left_padding / deinterleaving;
+ if_b_config.cropped_height = cropped_height;
+ if_b_config.cropped_width = width_b;
+ if_b_config.deinterleaving = deinterleaving;
+ if_b_config.buf_vecs = vectors_per_buffer;
+ if_b_config.buf_start_index =
+ buf_offset_b / sh_css_hrt_if_prim_vec_align();
+ if_b_config.buf_increment = vmem_increment;
+ if_b_config.buf_eol_offset =
+ buffer_width * bits_per_pixel/8 - line_width;
+ if_b_config.yuv420 =
+ input_format == sh_css_input_format_yuv420_8
+ || input_format == sh_css_input_format_yuv420_10;
+ sh_css_sp_set_if_configs(&if_a_config, &if_b_config,
+ my_css.if_block_fifo_no_reqs);
+ } else {
+ sh_css_sp_set_if_configs(&if_a_config, NULL,
+ my_css.if_block_fifo_no_reqs);
+ }
+ sh_css_input_enable_block_fifo_no_reqs(ShFalse);
+ return sh_css_success;
+}
+
+static sh_css_err
+sh_css_config_input_network(struct sh_css_pipeline *pipeline,
+ enum sh_css_input_mode input_mode)
+{
+ struct sh_css_binary *binary = NULL;
+ unsigned int fmt_type;
+
+ if (pipeline)
+ binary = pipeline->stages[0].binary;
+
+ return_on_error(sh_css_input_format_type(my_css.input_format,
+ my_css.mipi_comp, &fmt_type));
+ sh_css_sp_program_input_circuit(fmt_type, my_css.ch_id, input_mode);
+ if (binary && binary->online)
+ return_on_error(program_input_formatter(binary));
+
+ if (input_mode == sh_css_input_mode_tpg ||
+ input_mode == sh_css_input_mode_prbs) {
+ unsigned int hblank_cycles = 100, vblank_lines = 6,
+ width, height, vblank_cycles;
+ if (binary) {
+ width = binary->in_frame_info.width;
+ height = binary->in_frame_info.height;
+ } else {
+ width = my_css.input_width;
+ height = my_css.input_height;
+ }
+ vblank_cycles = vblank_lines * (width + hblank_cycles);
+ sh_css_sp_configure_sync_gen(width, height, hblank_cycles,
+ vblank_cycles);
+ } else if (input_mode == sh_css_input_mode_sensor) {
+ sh_css_sp_program_css_receiver(my_css.mipi_port,
+ my_css.mipi_num_lanes,
+ my_css.mipi_timeout,
+ my_css.mipi_comp,
+ my_css.mipi_comp_bpp,
+ my_css.mipi_uncomp_bpp);
+ }
+ return sh_css_success;
+}
+
+static sh_css_err
+allocate_default_params(void)
+{
+ if (my_css.default_params)
+ return sh_css_success;
+ return_on_error(sh_css_params_allocate(&my_css.default_params));
+ return_on_error(sh_css_params_default(my_css.default_params));
+ return sh_css_success;
+}
+
+static ShBool
+input_format_is_raw(enum sh_css_input_format format)
+{
+ return format == sh_css_input_format_raw_6 ||
+ format == sh_css_input_format_raw_7 ||
+ format == sh_css_input_format_raw_8 ||
+ format == sh_css_input_format_raw_10 ||
+ format == sh_css_input_format_raw_12;
+ /* raw_14 and raw_16 are not supported as input formats to the ISP.
+ * They can only be copied to a frame in memory using the
+ * copy binary.
+ */
+}
+
+static inline void
+wait_for_if_setup(void)
+{
+ /* wait for IF to be ready */
+#ifdef HRT_CSIM
+ unsigned int i;
+ for (i = 0; i < 10000; i++)
+ hrt_sleep();
+#endif
+}
+
+static sh_css_err
+start_binary(struct sh_css_binary *binary,
+ struct sh_css_binary_args *args)
+{
+ if (binary->params)
+ return_on_error(sh_css_params_write_to_ddr
+ (binary->params, binary));
+ if (binary->enable_uds || binary->can_scale) {
+ struct sh_css_uds_params params;
+ if (sh_css_uds_configure(¶ms, &binary->uds_config))
+ sh_css_sp_uds_reconfigure(¶ms, &binary->uds_config);
+ }
+ if (binary->mode == sh_css_binary_mode_vf_pp)
+ sh_css_sp_set_overlay(args->vf_overlay);
+ if (binary->mode == sh_css_binary_mode_xnr)
+ sh_css_sp_set_enable_xnr(args->enable_xnr);
+ return_on_error(sh_css_sp_write_frame_pointers(args));
+ sh_css_sp_start_isp(binary->id);
+ my_css.state = sh_css_state_executing;
+ if (binary->online)
+ wait_for_if_setup();
+ return sh_css_success;
+}
+
+/* Pipeline:
+ * To organize the several different binaries for each type of mode,
+ * we use a pipeline. A pipeline contains a number of stages, each with
+ * their own binary and frame pointers.
+ * When stages are added to a pipeline, output frames that are not passed
+ * from outside are automatically allocated.
+ * When input frames are not passed from outside, each stage will use the
+ * output frame of the previous stage as input (the full resolution output,
+ * not the viewfinder output).
+ * Pipelines must be cleaned and re-created when settings of the binaries
+ * change.
+ */
+static sh_css_err
+sh_css_pipeline_stage_destroy(struct sh_css_pipeline_stage *me)
+{
+ if (me->out_frame_allocated)
+ sh_css_free(me->args.out_frame);
+ if (me->vf_frame_allocated)
+ sh_css_free(me->args.out_vf_frame);
+ sh_css_free(me);
+ return sh_css_success;
+}
+
+static void
+sh_css_binary_args_reset(struct sh_css_binary_args *args)
+{
+ args->in_frame = NULL;
+ args->out_frame = NULL;
+ args->in_ref_frame = NULL;
+ args->out_ref_frame = NULL;
+ args->out_vf_frame = NULL;
+ args->dvs_crop_x = 0;
+ args->dvs_crop_y = 0;
+ args->dvs_envelope_width = 0;
+ args->dvs_envelope_height = 0;
+ args->dz_used = NULL;
+ args->vf_overlay = NULL;
+ args->enable_xnr = my_css.capture_settings.xnr;
+}
+
+static sh_css_err
+sh_css_pipeline_stage_create(struct sh_css_pipeline_stage **me,
+ struct sh_css_binary *binary,
+ struct sh_css_frame *in_frame,
+ struct sh_css_frame *out_frame,
+ struct sh_css_frame *vf_frame)
+{
+ struct sh_css_pipeline_stage *stage = sh_css_malloc(sizeof(*stage));
+ if (!stage)
+ return sh_css_err_cannot_allocate_memory;
+ stage->binary = binary;
+ stage->out_frame_allocated = ShFalse;
+ stage->vf_frame_allocated = ShFalse;
+ stage->next = NULL;
+ sh_css_binary_args_reset(&stage->args);
+
+ if (!in_frame && !binary->online)
+ return sh_css_err_internal_error;
+
+ if (!out_frame) {
+ sh_css_err ret =
+ sh_css_frame_allocate_from_info(&out_frame,
+ &binary->out_frame_info);
+ if (ret != sh_css_success) {
+ sh_css_free(stage);
+ return ret;
+ }
+ stage->out_frame_allocated = ShTrue;
+ }
+ if (!vf_frame && binary->enable_vf_veceven) {
+ sh_css_err ret = sh_css_frame_allocate_from_info(&vf_frame,
+ &binary->
+ vf_frame_info);
+ if (ret != sh_css_success) {
+ if (stage->out_frame_allocated)
+ sh_css_free(out_frame);
+ sh_css_free(stage);
+ return ret;
+ }
+ stage->vf_frame_allocated = ShTrue;
+ }
+ /* Temporary hack: GDC needs an internal frame, this will be removed by
+ * Michie once the gdc/postgdc rewrite is complete.
+ */
+ if (binary->mode == sh_css_binary_mode_gdc) {
+ /* never mind the memory leaks here, it's only temporary */
+ struct sh_css_frame *plane6_frame = NULL;
+ struct sh_css_frame_info info = binary->out_frame_info;
+ sh_css_err ret;
+ info.format = sh_css_frame_format_plane6;
+ ret = sh_css_frame_allocate_from_info(&plane6_frame, &info);
+ if (ret != sh_css_success)
+ return ret;
+ stage->args.out_ref_frame = plane6_frame;
+ }
+ stage->args.in_frame = in_frame;
+ stage->args.out_frame = out_frame;
+ stage->args.out_vf_frame = vf_frame;
+ *me = stage;
+
+ if ((binary->mode == sh_css_binary_mode_copy) && (out_frame != NULL)) {
+ sh_css_printf(KERN_DEBUG "%s, Copy raw frame %x\n",
+ __func__, out_frame);
+ copy_frame = out_frame;
+ }
+ return sh_css_success;
+}
+
+static sh_css_err
+sh_css_pipeline_init(struct sh_css_pipeline *me)
+{
+ me->length = 0;
+ me->stages = NULL;
+ me->reload = ShTrue;
+ me->input_mode = sh_css_input_mode_sensor;
+ me->current_stage = NULL;
+ return sh_css_success;
+}
+
+static sh_css_err
+sh_css_pipeline_add_stage(struct sh_css_pipeline *me,
+ struct sh_css_binary *binary,
+ struct sh_css_frame *in_frame,
+ struct sh_css_frame *out_frame,
+ struct sh_css_frame *vf_frame,
+ struct sh_css_pipeline_stage **stage)
+{
+ struct sh_css_pipeline_stage *last = me->stages, *new_stage = NULL;
+
+ while (last && last->next)
+ last = last->next;
+
+ /* if in_frame is not set, we use the out_frame from the previous
+ * stage, if no previous stage, it's an error.
+ */
+ if (!in_frame && !binary->online) {
+ if (last)
+ in_frame = last->args.out_frame;
+ if (!in_frame)
+ return sh_css_err_internal_error;
+ }
+ return_on_error(sh_css_pipeline_stage_create(&new_stage, binary,
+ in_frame, out_frame,
+ vf_frame));
+ if (last)
+ last->next = new_stage;
+ else
+ me->stages = new_stage;
+ me->length++;
+ if (stage)
+ *stage = new_stage;
+ return sh_css_success;
+}
+
+static sh_css_err
+sh_css_pipeline_get_stage(struct sh_css_pipeline *me,
+ enum sh_css_binary_mode mode,
+ struct sh_css_pipeline_stage **stage)
+{
+ struct sh_css_pipeline_stage *s;
+ for (s = me->stages; s; s = s->next) {
+ if (s->binary->mode == mode) {
+ *stage = s;
+ return sh_css_success;
+ }
+ }
+ return sh_css_err_internal_error;
+}
+
+static sh_css_err
+sh_css_pipeline_restart(struct sh_css_pipeline *me)
+{
+ me->current_stage = NULL;
+ return sh_css_success;
+}
+
+static sh_css_err
+sh_css_pipeline_clean(struct sh_css_pipeline *me)
+{
+ struct sh_css_pipeline_stage *s = me->stages;
+
+ while (s) {
+ struct sh_css_pipeline_stage *next = s->next;
+ sh_css_pipeline_stage_destroy(s);
+ s = next;
+ }
+ return sh_css_pipeline_init(me);
+}
+
+static sh_css_err
+sh_css_pipeline_start_next_stage(struct sh_css_pipeline *me,
+ ShBool *done)
+{
+ struct sh_css_pipeline_stage *stage;
+ struct sh_css_params *params = NULL;
+ if (me->current_stage)
+ stage = me->current_stage->next;
+ else
+ stage = me->stages;
+
+ if (!stage) {
+ if (done)
+ *done = ShTrue;
+ return sh_css_success;
+ }
+
+ if (stage->binary->mode == sh_css_binary_mode_vf_pp)
+ stage->args.vf_overlay = my_css.vf_overlay;
+
+ if (stage->binary->mode != sh_css_binary_mode_copy &&
+ stage->binary->mode != sh_css_binary_mode_bayer_ds &&
+ stage->binary->mode != sh_css_binary_mode_vf_pp)
+ /* we don't pass the parameters if they're not used by the
+ binary to prevent unnecessary writes to DDR. */
+ params = me->isp_parameters;
+ return_on_error(sh_css_binary_set_active
+ (stage->binary, &stage->args, params));
+ return_on_error(start_binary(stage->binary, &stage->args));
+ me->current_stage = stage;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_overlay_set_for_viewfinder(const struct sh_css_overlay *overlay)
+{
+ CHECK_INIT();
+ my_css.vf_overlay = overlay;
+ return sh_css_success;
+}
+
+/* CSS receiver programming */
+sh_css_err
+sh_css_input_configure_port(enum sh_css_mipi_port port,
+ unsigned int num_lanes,
+ unsigned int timeout)
+{
+ CHECK_INIT();
+ if (port == sh_css_mipi_port_1lane && num_lanes > 1)
+ return sh_css_err_conflicting_mipi_settings;
+ if (num_lanes > 4)
+ return sh_css_err_conflicting_mipi_settings;
+ my_css.mipi_port = port;
+ my_css.mipi_num_lanes = num_lanes;
+ my_css.mipi_timeout = timeout;
+
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_set_compression(enum sh_css_mipi_compression comp,
+ unsigned int compressed_bits_per_pixel,
+ unsigned int uncompressed_bits_per_pixel)
+{
+ CHECK_INIT();
+ if (comp == sh_css_mipi_compression_none) {
+ if (compressed_bits_per_pixel || uncompressed_bits_per_pixel)
+ return sh_css_err_conflicting_mipi_settings;
+ } else {
+ if (compressed_bits_per_pixel < 6 ||
+ compressed_bits_per_pixel > 8)
+ return sh_css_err_conflicting_mipi_settings;
+ if (uncompressed_bits_per_pixel != 10 &&
+ uncompressed_bits_per_pixel != 12)
+ return sh_css_err_conflicting_mipi_settings;
+ }
+ my_css.mipi_comp = comp;
+ my_css.mipi_comp_bpp = compressed_bits_per_pixel;
+ my_css.mipi_uncomp_bpp = uncompressed_bits_per_pixel;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_copy_frame(const struct sh_css_frame *in_frame,
+ struct sh_css_frame *out_frame)
+{
+ CHECK_INIT();
+ sh_css_sp_si_set_input_pointers(in_frame->planes.yuv.Y.data,
+ in_frame->planes.yuv.U.data,
+ in_frame->planes.yuv.V.data);
+ sh_css_sp_si_set_output_pointers(out_frame->planes.yuv.Y.data,
+ out_frame->planes.yuv.U.data,
+ out_frame->planes.yuv.V.data);
+ sh_css_sp_si_set_frame_size(in_frame->info.padded_width,
+ in_frame->info.height);
+ sh_css_sp_copy_frame();
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_tpg_configure(unsigned int x_mask,
+ int x_delta,
+ unsigned int y_mask,
+ int y_delta,
+ unsigned int xy_mask)
+{
+ CHECK_INIT();
+ sh_css_sp_configure_tpg(x_mask, y_mask, x_delta, y_delta, xy_mask);
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_prbs_set_seed(int seed)
+{
+ CHECK_INIT();
+ sh_css_sp_configure_prbs(seed);
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_xnr_start(struct sh_css_frame *in_frame,
+ struct sh_css_frame *out_frame)
+{
+ struct sh_css_binary_descr xnr_descr;
+ struct sh_css_binary *binary;
+ struct sh_css_binary_args args;
+ struct sh_css_params *params;
+
+ CHECK_INIT();
+
+ params = my_css.capture_settings.isp_parameters;
+ if (in_frame->info.format != sh_css_frame_format_yuv420)
+ return sh_css_err_unsupported_configuration;
+
+ xnr_descr.mode = sh_css_binary_mode_xnr;
+ xnr_descr.online = ShFalse;
+ xnr_descr.in_info = &in_frame->info;
+ xnr_descr.out_info = &out_frame->info;
+ xnr_descr.vf_info = NULL;
+ xnr_descr.extra_lines = 0;
+ return_on_error(sh_css_binary_find(&xnr_descr, &binary));
+
+ sh_css_binary_args_reset(&args);
+ args.in_frame = in_frame;
+ args.out_frame = out_frame;
+ return_on_error(sh_css_binary_set_active(binary, &args, params));
+ start_binary(binary, &args);
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_init(void *(*malloc_func) (size_t size),
+ void (*free_func) (void *ptr),
+ enum sh_css_interrupt_setting irq_setting)
+{
+ static struct sh_css default_css = DEFAULT_CSS;
+
+ if (malloc_func == NULL || free_func == NULL)
+ return sh_css_err_invalid_arguments;
+
+ memcpy(&my_css, &default_css, sizeof(my_css));
+
+ my_css.malloc = malloc_func;
+ my_css.free = free_func;
+ my_css.irq_setting = irq_setting;
+
+#ifdef HRT_CSIM
+ hrt_isp_css_dma_set();
+#endif
+
+ if (my_css.irq_setting != sh_css_interrupt_setting_disabled) {
+ ShBool is_edge =
+ my_css.irq_setting == sh_css_interrupt_setting_edge;
+ /* Enable IRQ when SP goes to idle */
+ sh_css_hrt_irq_enable(hrt_isp_css_irq_sp, ShTrue, is_edge);
+ sh_css_hrt_irq_enable_sp(ShTrue);
+ sh_css_hrt_irq_clear_all();
+ }
+
+ my_css.initialized = ShTrue;
+ /* TODO: init zoom factor to 64, 64 and do this in uds_functions.host.h
+ */
+ sh_css_set_zoom_factor(61, 61);
+
+ return_on_error(sh_css_params_init());
+ sh_css_binary_init();
+ sh_css_sp_init();
+ return_on_error(sh_css_pipeline_init
+ (&my_css.preview_settings.pipeline));
+ return_on_error(sh_css_pipeline_init(&my_css.video_settings.pipeline));
+ return_on_error(sh_css_pipeline_init
+ (&my_css.capture_settings.pipeline));
+ return sh_css_success;
+}
+
+void *
+sh_css_malloc(size_t size)
+{
+ if (size > 0 && my_css.malloc)
+ return my_css.malloc(size);
+ return NULL;
+}
+
+void
+sh_css_free(void *ptr)
+{
+ if (ptr && my_css.free)
+ my_css.free(ptr);
+}
+
+sh_css_err
+sh_css_set_print_function(int (*func) (const char *fmt, ...))
+{
+ /*CHECK_INIT();*/
+ sh_css_printf = func;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_uninit(void)
+{
+ CHECK_INIT();
+#if defined(HRT_CSIM) && PC_HISTOGRAM
+ if (my_css.pc_histogram)
+ sh_css_histogram_free(my_css.pc_histogram);
+#endif
+ sh_css_params_uninit();
+ sh_css_binary_uninit();
+ my_css.initialized = ShFalse;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_enable_debug(ShBool enable)
+{
+ CHECK_INIT();
+ my_css.dump_debug = enable;
+ return sh_css_success;
+}
+
+const char *
+sh_css_err_string(sh_css_err error)
+{
+ switch (error) {
+ case sh_css_success:
+ return "success";
+ case sh_css_err_internal_error:
+ return "internal error";
+ case sh_css_err_conflicting_mipi_settings:
+ return "conflicting mipi settings";
+ case sh_css_err_unsupported_configuration:
+ return "unsupported configuration";
+ case sh_css_err_mode_does_not_have_viewfinder:
+ return "mode does not have viewfinder output";
+ case sh_css_err_input_resolution_not_set:
+ return "input resolution has not been set";
+ case sh_css_err_unsupported_input_mode:
+ return "input mode is not supported";
+ case sh_css_err_isp_parameters_not_set:
+ return "ISP parameters have not been set";
+ case sh_css_err_cannot_allocate_memory:
+ return "cannot allocate memory";
+ case sh_css_err_invalid_arguments:
+ return "invalid argument(s)";
+ case sh_css_err_too_may_colors:
+ return "overlay contains too many colors";
+ case sh_css_err_overlay_frame_missing:
+ return "overlay does not contain a frame";
+ case sh_css_err_overlay_frames_too_big:
+ return "overlay frames are too big";
+ case sh_css_err_unsupported_frame_format:
+ return "unsupported frame format";
+ case sh_css_err_frames_mismatch:
+ return "frames mismatch";
+ case sh_css_err_overlay_not_set:
+ return "overlay not set";
+ case sh_css_err_not_implemented:
+ return "feature is not implemented yet";
+ case sh_css_err_invalid_frame_format:
+ return "invalid frame format";
+ case sh_css_err_unsupported_resolution:
+ return "resolution is not supported";
+ case sh_css_err_scaling_factor_out_of_range:
+ return "scaling factor out of range";
+ case sh_css_err_cannot_obtain_shading_table:
+ return "failed to obtain shading table";
+ case sh_css_err_interrupt_error:
+ return "cannot handle interrupt";
+ case sh_css_err_unexpected_interrupt:
+ return "encountered unexpected interrupt";
+ case sh_css_err_system_not_idle:
+ return "system is not idle";
+ case sh_css_err_unsupported_input_format:
+ return "input format is not supported by this mode";
+ case sh_css_err_interrupts_not_enabled:
+ return "interrupts have not been enabled";
+ case sh_css_err_not_enough_input_lines:
+ return
+ "input height is insufficient for this resolution"
+ " and bayer order";
+ case sh_css_err_not_enough_input_columns:
+ return
+ "input width is insufficient for this resolution"
+ " and bayer order";
+ case sh_css_err_not_initialized:
+ return "the API is not initialized yet";
+ case sh_css_err_illegal_resolution:
+ return "unsupported resolution";
+ case sh_css_err_effective_input_resolution_not_set:
+ return "the effective input resolution has not been set";
+ case sh_css_err_viewfinder_resolution_too_wide:
+ return
+ "the viewfinder resolution exceeds the maximum width"
+ " of 1280 pixels";
+ case sh_css_err_viewfinder_resolution_exceeds_output:
+ return
+ "the viewfinder resolution exceeds the width of the output";
+ case sh_css_err_mode_does_not_have_grid:
+ return "this mode does not have a 3a/dis grid";
+ }
+ return "unknown error";
+}
+
+#if defined(HRT_CSIM) && PC_HISTOGRAM
+static void
+make_pc_histogram(void)
+{
+ if (my_css.pc_histogram == NULL)
+ sh_css_histogram_allocate(2048, &my_css.pc_histogram);
+
+ if (my_css.pc_histogram) {
+ do {
+ unsigned int pc = hrt_ctl_program_counter(ISP), val;
+ /* just in case the ISP messes up, we don't want to
+ write outside the array */
+ pc = MAX(pc, 2047);
+ val =
+ hrt_isp_css_mm_load_int(my_css.pc_histogram->data +
+ pc * sizeof(unsigned int));
+ val++;
+ hrt_isp_css_mm_store_int(my_css.pc_histogram->data +
+ pc * sizeof(unsigned int),
+ val);
+ } while (!hrt_ctl_is_ready(ISP));
+ } else {
+ sh_css_hrt_isp_wait();
+ }
+}
+#endif
+
+static sh_css_err
+start_next_binary(ShBool *done)
+{
+ struct sh_css_pipeline *pipeline = NULL;
+ ShBool sp_only = my_css.state == sh_css_state_executing_sp_only;
+
+ if (my_css.state == sh_css_state_idle) {
+ *done = ShFalse;
+ return sh_css_success;
+ }
+ if (sp_only) {
+ sh_css_hrt_sp_wait();
+ my_css.capture_settings.output_frame->planes.binary.size =
+ sh_css_sp_get_binary_copy_size();
+ }
+ /* Handle to allow calling dump_debug_info and friends from gdb */
+ if (my_css.dump_debug)
+ sh_css_dump_debug_info();
+ if (!sp_only) {
+#if defined(HRT_CSIM) && PC_HISTOGRAM
+ make_pc_histogram();
+#else
+ sh_css_hrt_isp_wait();
+#endif
+ sh_css_hrt_sp_wait();
+ }
+ if (my_css.dump_debug)
+ sh_css_dump_if_state();
+ my_css.state = sh_css_state_idle;
+#if defined(HRT_CSIM) || defined(HRT_FPGA)
+ return_on_error(sh_css_check_system_idle());
+#endif
+ if (sp_only)
+ *done = ShTrue;
+ else {
+ if (my_css.mode == sh_css_mode_preview)
+ pipeline = &my_css.preview_settings.pipeline;
+ else if (my_css.mode == sh_css_mode_video)
+ pipeline = &my_css.video_settings.pipeline;
+ else
+ pipeline = &my_css.capture_settings.pipeline;
+ return_on_error(sh_css_pipeline_start_next_stage
+ (pipeline, done));
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_handle_interrupt(enum sh_css_interrupt_info *info,
+ ShBool *more_interrupts)
+{
+ enum hrt_isp_css_irq irq;
+ enum hrt_isp_css_irq_status status;
+ ShBool done = ShFalse;
+ enum sh_css_interrupt_info irq_info = sh_css_interrupt_info_none;
+
+ CHECK_INIT();
+ if (more_interrupts)
+ *more_interrupts = ShFalse;
+ status = sh_css_hrt_irq_get_id(&irq);
+ if (status == hrt_isp_css_irq_status_error)
+ return sh_css_err_interrupt_error;
+
+ switch (irq) {
+ case hrt_isp_css_irq_sp:
+ sh_css_hrt_irq_clear_sp();
+ return_on_error(start_next_binary(&done));
+ if (done)
+ irq_info = sh_css_interrupt_info_frame_done;
+ break;
+ default:
+ return sh_css_err_unexpected_interrupt;
+ }
+
+ if (info)
+ *info = irq_info;
+ if (more_interrupts)
+ *more_interrupts = (status == hrt_isp_css_irq_status_more_irqs);
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_mmu_set_page_table_base_address(void *base_address)
+{
+ CHECK_INIT();
+ sh_css_hrt_mmu_set_page_table_base_address(base_address);
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_mmu_invalidate_cache(void)
+{
+ sh_css_hrt_mmu_invalidate_cache();
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_enable_interrupt(enum sh_css_interrupt_info info,
+ ShBool enable)
+{
+ enum hrt_isp_css_irq irq = -1;
+
+ CHECK_INIT();
+ if (my_css.irq_setting == sh_css_interrupt_setting_disabled)
+ return sh_css_err_interrupts_not_enabled;
+
+ switch (info) {
+ case sh_css_interrupt_info_css_receiver_error:
+ irq = hrt_isp_css_irq_mipi;
+ break;
+ case sh_css_interrupt_info_css_receiver_fifo_overflow:
+ irq = hrt_isp_css_irq_mipi_fifo_full;
+ break;
+ case sh_css_interrupt_info_css_receiver_sof:
+ irq = hrt_isp_css_irq_mipi_sof;
+ break;
+ case sh_css_interrupt_info_css_receiver_eof:
+ irq = hrt_isp_css_irq_mipi_eof;
+ break;
+ case sh_css_interrupt_info_css_receiver_sol:
+ irq = hrt_isp_css_irq_mipi_sol;
+ break;
+ case sh_css_interrupt_info_css_receiver_eol:
+ irq = hrt_isp_css_irq_mipi_eol;
+ break;
+#ifdef CSS_RECEIVER
+ case sh_css_interrupt_info_css_receiver_sideband_changed:
+ irq = hrt_isp_css_irq_sideband_changed;
+ break;
+ case sh_css_interrupt_info_css_receiver_gen_short_0:
+ irq = hrt_isp_css_irq_css_gen_short_0;
+ break;
+ case sh_css_interrupt_info_css_receiver_gen_short_1:
+ irq = hrt_isp_css_irq_css_gen_short_1;
+ break;
+#endif
+ case sh_css_interrupt_info_if_prim_error:
+ irq = hrt_isp_css_irq_ift_prim;
+ break;
+ case sh_css_interrupt_info_if_prim_b_error:
+ irq = hrt_isp_css_irq_ift_prim_b;
+ break;
+ case sh_css_interrupt_info_if_sec_error:
+ irq = hrt_isp_css_irq_ift_sec;
+ break;
+ case sh_css_interrupt_info_stream_to_mem_error:
+ irq = hrt_isp_css_irq_ift_mem_cpy;
+ break;
+ case sh_css_interrupt_info_sync_gen_sof:
+ irq = hrt_isp_css_irq_syncgen_sof;
+ break;
+ case sh_css_interrupt_info_sync_gen_eof:
+ irq = hrt_isp_css_irq_syncgen_eof;
+ break;
+ case sh_css_interrupt_info_sync_gen_sol:
+ irq = hrt_isp_css_irq_syncgen_sol;
+ break;
+ case sh_css_interrupt_info_sync_gen_eol:
+ irq = hrt_isp_css_irq_syncgen_eol;
+ break;
+ default:
+ return sh_css_err_invalid_arguments;
+ }
+
+ if (enable) {
+ ShBool is_edge =
+ my_css.irq_setting == sh_css_interrupt_setting_edge;
+ sh_css_hrt_irq_enable(irq, ShTrue, is_edge);
+ } else {
+ sh_css_hrt_irq_disable(irq);
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_wait_for_completion(void)
+{
+ unsigned int irq_st;
+ ShBool done = ShFalse;
+
+ CHECK_INIT();
+ return_on_error(start_next_binary(&done));
+ if (my_css.dump_debug) {
+ irq_st = sh_css_hrt_receiver_get_interrupt_status(
+ sh_css_mipi_port_4lane);
+ printk(KERN_DEBUG "atomisp: css_receiver_irq_status is %x\n",
+ irq_st);
+ }
+ if (!done)
+ sh_css_wait_for_completion();
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_uv_offset_is_zero(ShBool *uv_offset_is_zero)
+{
+ if (uv_offset_is_zero)
+ *uv_offset_is_zero = UVOFFSET_IS_0;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_set_resolution(unsigned int width, unsigned int height)
+{
+ CHECK_INIT();
+ CHECK_RES(width, height);
+ my_css.input_width = width;
+ my_css.input_height = height;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_get_resolution(unsigned int *width, unsigned int *height)
+{
+ CHECK_INIT();
+ *width = my_css.input_width;
+ *height = my_css.input_height;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_set_effective_resolution(unsigned int width, unsigned int height)
+{
+ CHECK_INIT();
+ CHECK_RES(width, height);
+ my_css.input_effective_info.width = width;
+ my_css.input_effective_info.padded_width = width;
+ my_css.input_effective_info.height = height;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_set_format(enum sh_css_input_format format)
+{
+ CHECK_INIT();
+ my_css.input_format = format;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_set_two_pixels_per_clock(ShBool two_pixels_per_clock)
+{
+ CHECK_INIT();
+ my_css.two_pixels_per_clock = two_pixels_per_clock;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_set_bayer_order(enum sh_css_bayer_order bayer_order)
+{
+ CHECK_INIT();
+ my_css.bayer_order = bayer_order;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_set_channel(unsigned int channel_id)
+{
+ CHECK_INIT();
+ my_css.ch_id = channel_id;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_input_enable_block_fifo_no_reqs(ShBool enable)
+{
+ my_css.if_block_fifo_no_reqs = enable;
+ return sh_css_success;
+}
+
+/*================================== Preview Code =========================== */
+static sh_css_err
+invalidate_preview_binaries(void)
+{
+ my_css.preview_settings.pipeline.reload = ShTrue;
+ my_css.preview_settings.preview_binary = NULL;
+ my_css.preview_settings.vf_pp_binary = NULL;
+ return sh_css_success;
+}
+
+static sh_css_err
+load_preview_binaries(void)
+{
+ struct sh_css_binary_descr prev_descr, vf_pp_descr;
+ struct sh_css_frame_info prev_in_info, prev_out_info, ref_info;
+ unsigned int padded_width = 0;
+
+ if (my_css.preview_settings.preview_binary &&
+ my_css.preview_settings.vf_pp_binary)
+ return sh_css_success;
+
+ CHECK_INPUT(ShTrue);
+ CHECK_FRAME_INFO(my_css.preview_settings.output_info);
+
+ prev_in_info = my_css.input_effective_info;
+ prev_in_info.padded_width = prev_in_info.width;
+ prev_out_info = my_css.preview_settings.output_info;
+ prev_out_info.format = sh_css_frame_format_yuv420;
+
+ /* preview binary description */
+ prev_descr.mode = sh_css_binary_mode_preview;
+ prev_descr.online = ShTrue;
+ prev_descr.stream_format = my_css.input_format;
+ prev_descr.two_ppc = my_css.two_pixels_per_clock;
+ prev_descr.in_info = &prev_in_info;
+ prev_descr.out_info = &prev_out_info;
+ prev_descr.vf_info = NULL;
+ return_on_error(extra_lines_available(&prev_descr.extra_lines));
+
+ /* vf_pp description */
+ vf_pp_descr.mode = sh_css_binary_mode_vf_pp;
+ vf_pp_descr.online = ShFalse;
+ vf_pp_descr.in_info = &prev_out_info;
+ vf_pp_descr.out_info = &my_css.preview_settings.output_info;
+ vf_pp_descr.vf_info = NULL;
+ vf_pp_descr.extra_lines = 0;
+
+ /* let all binaries express their requirements for the with */
+ return_on_error(sh_css_binary_padded_width(&prev_descr,
+ &prev_out_info.
+ padded_width));
+ return_on_error(sh_css_binary_padded_width
+ (&vf_pp_descr, &padded_width));
+ my_css.preview_settings.output_info.padded_width = padded_width;
+
+ /* now select the binaries, using the padded width that is okay for all
+ * binaries.
+ */
+ return_on_error(sh_css_binary_find(&prev_descr,
+ &my_css.preview_settings.
+ preview_binary));
+ return_on_error(sh_css_binary_find
+ (&vf_pp_descr, &my_css.preview_settings.vf_pp_binary));
+
+ ref_info = my_css.preview_settings.preview_binary->int_out_frame_info;
+ ref_info.format = sh_css_frame_format_yuv420;
+ if (my_css.preview_settings.ref_frames[0])
+ sh_css_frame_free(my_css.preview_settings.ref_frames[0]);
+ return_on_error(sh_css_frame_allocate_from_info
+ (&my_css.preview_settings.ref_frames[0], &ref_info));
+ if (my_css.preview_settings.ref_frames[1])
+ sh_css_frame_free(my_css.preview_settings.ref_frames[1]);
+ return_on_error(sh_css_frame_allocate_from_info
+ (&my_css.preview_settings.ref_frames[1], &ref_info));
+ my_css.preview_settings.prev_ref_frame =
+ my_css.preview_settings.ref_frames[0];
+#if defined(HRT_CSIM) || defined(HRT_RTL)
+ sh_css_frame_zero(my_css.preview_settings.prev_ref_frame);
+#endif
+
+ return sh_css_success;
+}
+
+#define PREVIEW_VF_PP 1
+
+sh_css_err
+sh_css_preview_start(struct sh_css_frame *out_frame)
+{
+ struct sh_css_pipeline *me = &my_css.preview_settings.pipeline;
+ struct sh_css_pipeline_stage *preview_stage;
+#if PREVIEW_VF_PP
+ struct sh_css_pipeline_stage *vf_pp_stage;
+#endif
+ struct sh_css_frame *in_ref_frame;
+ struct sh_css_binary *preview_binary, *vf_pp_binary;
+
+ CHECK_INIT();
+ CHECK_PTR_ARG(out_frame);
+ if (!my_css.preview_settings.isp_parameters) {
+ allocate_default_params();
+ my_css.preview_settings.isp_parameters = my_css.default_params;
+ }
+ return_on_error(load_preview_binaries());
+ CHECK_INFOS_MATCH(out_frame->info,
+ my_css.preview_settings.vf_pp_binary->out_frame_info);
+ preview_binary = my_css.preview_settings.preview_binary;
+ vf_pp_binary = my_css.preview_settings.vf_pp_binary;
+ if (me->reload) {
+ return_on_error(sh_css_pipeline_clean(me));
+#if PREVIEW_VF_PP
+ return_on_error(sh_css_pipeline_add_stage(me, preview_binary,
+ NULL, NULL, NULL,
+ NULL));
+ return_on_error(sh_css_pipeline_add_stage
+ (me, vf_pp_binary, NULL, out_frame, NULL,
+ NULL));
+#else
+ return_on_error(sh_css_pipeline_add_stage(me, preview_binary,
+ NULL, out_frame, NULL,
+ NULL));
+#endif
+ return_on_error(sh_css_config_input_network(me,
+ my_css.
+ preview_settings.
+ input_mode));
+ me->reload = ShFalse;
+ } else {
+ return_on_error(sh_css_pipeline_restart(me));
+ }
+#if PREVIEW_VF_PP
+ return_on_error(sh_css_pipeline_get_stage(me,
+ sh_css_binary_mode_vf_pp,
+ &vf_pp_stage));
+#endif
+ return_on_error(sh_css_pipeline_get_stage(me,
+ preview_binary->mode,
+ &preview_stage));
+
+#if PREVIEW_VF_PP
+ vf_pp_stage->args.out_frame = out_frame;
+#else
+ preview_stage->args.out_frame = out_frame;
+#endif
+ me->input_mode = my_css.preview_settings.input_mode;
+ me->isp_parameters = my_css.preview_settings.isp_parameters;
+
+ /* if dz was not used, the reference input is in the previous output
+ * frame, otherwise it is in the prev_ref_frame.
+ */
+ if (!my_css.preview_settings.dz_used)
+ in_ref_frame = my_css.preview_settings.prev_out_frame;
+ else
+ in_ref_frame = my_css.preview_settings.prev_ref_frame;
+
+ /* switch the reference frame buffers */
+ if (in_ref_frame == my_css.preview_settings.ref_frames[0])
+ my_css.preview_settings.prev_ref_frame =
+ my_css.preview_settings.ref_frames[1];
+ else
+ my_css.preview_settings.prev_ref_frame =
+ my_css.preview_settings.ref_frames[0];
+
+ my_css.preview_settings.prev_out_frame = preview_stage->args.out_frame;
+
+ /* update the arguments with the latest info */
+ preview_stage->args.in_ref_frame = in_ref_frame;
+ preview_stage->args.out_ref_frame =
+ my_css.preview_settings.prev_ref_frame;
+ preview_stage->args.dz_used = &my_css.preview_settings.dz_used;
+
+ my_css.mode = sh_css_mode_preview;
+ return sh_css_pipeline_start_next_stage(me, NULL);
+}
+
+sh_css_err
+sh_css_preview_get_output_frame_info(struct sh_css_frame_info *info)
+{
+ CHECK_INIT();
+ return_on_error(load_preview_binaries());
+ *info = my_css.preview_settings.output_info;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_preview_configure_output(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format)
+{
+ CHECK_INIT();
+ CHECK_RES(width, height);
+ if (my_css.preview_settings.output_info.width != width ||
+ my_css.preview_settings.output_info.height != height ||
+ my_css.preview_settings.output_info.format != format) {
+ sh_css_frame_info_init(&my_css.preview_settings.output_info,
+ width, height, format, 0);
+ invalidate_preview_binaries();
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_preview_set_input_mode(enum sh_css_input_mode mode)
+{
+ CHECK_INIT();
+ if (mode == sh_css_input_mode_memory)
+ return sh_css_err_unsupported_input_mode;
+ my_css.preview_settings.input_mode = mode;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_preview_set_isp_parameters(struct sh_css_params *params)
+{
+ CHECK_INIT();
+ my_css.preview_settings.isp_parameters = params;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_preview_get_grid_info(struct sh_css_grid_info *info)
+{
+ CHECK_INIT();
+ return_on_error(load_preview_binaries());
+ return_on_error(sh_css_binary_grid_info
+ (my_css.preview_settings.preview_binary, info));
+ return sh_css_success;
+}
+
+/*================================== Video Code ============================= */
+static void
+invalidate_video_binaries(void)
+{
+ my_css.video_settings.pipeline.reload = ShTrue;
+ my_css.video_settings.video_binary = NULL;
+ my_css.video_settings.vf_pp_binary = NULL;
+}
+
+static sh_css_err
+load_video_binaries(void)
+{
+ struct sh_css_binary_descr video_descr, vf_pp_descr;
+ struct sh_css_frame_info video_vf_info, video_in_info,
+ video_out_info, ref_info;
+ unsigned int dx, dy;
+ ShBool online;
+ enum sh_css_binary_mode mode = sh_css_binary_mode_video;
+
+ /* we only test the video_binary because offline video doesn't need a
+ * vf_pp binary. Both are always reset together anyway.
+ */
+ if (my_css.video_settings.video_binary)
+ return sh_css_success;
+ online = my_css.video_settings.input_mode != sh_css_input_mode_memory;
+ CHECK_INPUT(ShTrue);
+ if (online) {
+ CHECK_VF_OUT_INFO(my_css.video_settings.output_info,
+ my_css.video_settings.vf_info);
+ } else {
+ CHECK_FRAME_INFO(my_css.video_settings.output_info);
+ }
+
+ return_on_error(sh_css_get_zoom_factor(&dx, &dy));
+ if (dx == 64 && dy == 64 &&
+ my_css.input_effective_info.width ==
+ my_css.video_settings.output_info.width
+ + my_css.video_settings.dvs_envelope_width &&
+ my_css.input_effective_info.height ==
+ my_css.video_settings.output_info.height
+ + my_css.video_settings.dvs_envelope_height) {
+ mode = sh_css_binary_mode_video_nodz;
+ }
+ video_in_info = my_css.input_effective_info;
+ /* for offline video we must make sure the input info has all bits
+ * needed.
+ */
+ video_in_info.format = sh_css_frame_format_vraw16;
+ video_in_info.padded_width = video_in_info.width;
+ return_on_error(sh_css_input_format_bits_per_pixel(my_css.input_format,
+ my_css.
+ two_pixels_per_clock,
+ &video_in_info.
+ vraw_bit_depth));
+ video_out_info = my_css.video_settings.output_info;
+ video_vf_info = my_css.video_settings.vf_info;
+ video_vf_info.format = sh_css_frame_format_yuv420;
+
+ /* video binary */
+ video_descr.mode = mode;
+ video_descr.online = online;
+ video_descr.stream_format = my_css.input_format;
+ video_descr.two_ppc = my_css.two_pixels_per_clock;
+ video_descr.in_info = &video_in_info;
+ video_descr.out_info = &video_out_info;
+ video_descr.vf_info = online ? &video_vf_info : NULL;
+ return_on_error(extra_lines_available(&video_descr.extra_lines));
+
+ return_on_error(sh_css_binary_padded_width(&video_descr,
+ &my_css.video_settings.
+ output_info.padded_width));
+ video_out_info.padded_width =
+ my_css.video_settings.output_info.padded_width;
+ return_on_error(sh_css_binary_find
+ (&video_descr, &my_css.video_settings.video_binary));
+ ref_info = my_css.video_settings.video_binary->int_out_frame_info;
+ ref_info.format = sh_css_frame_format_yuv420;
+
+ if (online) {
+ /* vf_pp binary */
+ vf_pp_descr.mode = sh_css_binary_mode_vf_pp;
+ vf_pp_descr.online = ShFalse;
+ vf_pp_descr.in_info =
+ &my_css.video_settings.video_binary->vf_frame_info;
+ vf_pp_descr.out_info = &my_css.video_settings.vf_info;
+ vf_pp_descr.vf_info = NULL;
+ vf_pp_descr.extra_lines = 0;
+ return_on_error(sh_css_binary_padded_width(&vf_pp_descr,
+ &my_css.
+ video_settings.
+ vf_info.
+ padded_width));
+ return_on_error(sh_css_binary_find
+ (&vf_pp_descr,
+ &my_css.video_settings.vf_pp_binary));
+ }
+
+ if (my_css.video_settings.ref_frames[0])
+ sh_css_frame_free(my_css.video_settings.ref_frames[0]);
+ return_on_error(sh_css_frame_allocate_from_info
+ (&my_css.video_settings.ref_frames[0], &ref_info));
+ if (my_css.video_settings.ref_frames[1])
+ sh_css_frame_free(my_css.video_settings.ref_frames[1]);
+ return_on_error(sh_css_frame_allocate_from_info
+ (&my_css.video_settings.ref_frames[1], &ref_info));
+ my_css.video_settings.prev_ref_frame =
+ my_css.video_settings.ref_frames[0];
+#if defined(HRT_CSIM) || defined(HRT_RTL)
+ sh_css_frame_zero(my_css.video_settings.prev_ref_frame);
+#endif
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_start(struct sh_css_frame *in_frame,
+ struct sh_css_frame *out_frame,
+ struct sh_css_frame *vf_frame)
+{
+ struct sh_css_pipeline *me = &my_css.video_settings.pipeline;
+ struct sh_css_pipeline_stage *video_stage, *vf_pp_stage;
+ struct sh_css_frame *in_ref_frame;
+ unsigned int crop_out_x = 0, crop_out_y = 0;
+ struct sh_css_binary *video_binary, *vf_pp_binary;
+
+ CHECK_INIT();
+ CHECK_PTR_ARG(out_frame);
+ if (!my_css.video_settings.isp_parameters) {
+ allocate_default_params();
+ my_css.video_settings.isp_parameters = my_css.default_params;
+ }
+ return_on_error(load_video_binaries());
+ video_binary = my_css.video_settings.video_binary;
+ vf_pp_binary = my_css.video_settings.vf_pp_binary;
+ if (in_frame) {
+ if (vf_frame)
+ return sh_css_err_mode_does_not_have_viewfinder;
+ } else {
+ CHECK_PTR_ARG(vf_frame);
+ CHECK_INFOS_MATCH(vf_frame->info,
+ my_css.video_settings.vf_pp_binary->
+ out_frame_info);
+ }
+ CHECK_INFOS_MATCH(out_frame->info,
+ my_css.video_settings.video_binary->out_frame_info);
+ if (me->reload) {
+ return_on_error(sh_css_pipeline_clean(me));
+ return_on_error(sh_css_pipeline_add_stage(me, video_binary,
+ in_frame, out_frame,
+ NULL, &video_stage));
+ if (!in_frame) {
+ return_on_error(sh_css_pipeline_add_stage
+ (me, vf_pp_binary,
+ video_stage->args.out_vf_frame,
+ vf_frame, NULL, &vf_pp_stage));
+ }
+ return_on_error(sh_css_config_input_network(me,
+ my_css.
+ video_settings.
+ input_mode));
+ me->reload = ShFalse;
+ } else {
+ return_on_error(sh_css_pipeline_restart(me));
+ }
+ if (in_frame) {
+ return_on_error(sh_css_pipeline_get_stage(me,
+ video_binary->mode,
+ &video_stage));
+ } else {
+ return_on_error(sh_css_pipeline_get_stage(me,
+ video_binary->mode,
+ &video_stage));
+ return_on_error(sh_css_pipeline_get_stage(me,
+ vf_pp_binary->mode,
+ &vf_pp_stage));
+ }
+ me->input_mode = my_css.video_settings.input_mode;
+ me->isp_parameters = my_css.video_settings.isp_parameters;
+
+ in_ref_frame = my_css.video_settings.prev_ref_frame;
+ /* switch the reference frame buffers */
+ if (in_ref_frame == my_css.video_settings.ref_frames[0])
+ my_css.video_settings.prev_ref_frame =
+ my_css.video_settings.ref_frames[1];
+ else
+ my_css.video_settings.prev_ref_frame =
+ my_css.video_settings.ref_frames[0];
+
+ if (my_css.video_settings.dvs_envelope_width ||
+ my_css.video_settings.dvs_envelope_height) {
+ int env_width = my_css.video_settings.dvs_envelope_width,
+ env_height = my_css.video_settings.dvs_envelope_height,
+ crop_x = env_width / 2 + my_css.video_settings.dvs_vector_x,
+ crop_y =
+ env_height / 2 + my_css.video_settings.dvs_vector_y;
+ crop_out_x =
+ (unsigned int) MAX(MIN(crop_x, (env_width - 1)), 0);
+ crop_out_y =
+ (unsigned int) MAX(MIN(crop_y, (env_height - 1)), 0);
+
+ sh_css_uds_set_zoom_center(crop_out_x, crop_out_y);
+ }
+
+ /* update the arguments with the latest info */
+ video_stage->args.in_ref_frame = in_ref_frame;
+ video_stage->args.out_frame = out_frame;
+ video_stage->args.out_ref_frame = my_css.video_settings.prev_ref_frame;
+ video_stage->args.dvs_crop_x = crop_out_x;
+ video_stage->args.dvs_crop_y = crop_out_y;
+ video_stage->args.dvs_envelope_width =
+ my_css.video_settings.dvs_envelope_width;
+ video_stage->args.dvs_envelope_height =
+ my_css.video_settings.dvs_envelope_height;
+ if (!in_frame)
+ vf_pp_stage->args.out_frame = vf_frame;
+
+ my_css.mode = sh_css_mode_video;
+ return sh_css_pipeline_start_next_stage(me, NULL);
+}
+
+sh_css_err
+sh_css_video_get_output_frame_info(struct sh_css_frame_info *info)
+{
+ CHECK_INIT();
+ return_on_error(load_video_binaries());
+ *info = my_css.video_settings.output_info;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_get_viewfinder_frame_info(struct sh_css_frame_info *info)
+{
+ CHECK_INIT();
+ return_on_error(load_video_binaries());
+ if (my_css.video_settings.input_mode == sh_css_input_mode_memory) {
+ /* offline video does not generate viewfinder output */
+ return sh_css_err_mode_does_not_have_viewfinder;
+ } else {
+ *info = my_css.video_settings.vf_info;
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_get_grid_info(struct sh_css_grid_info *info)
+{
+ CHECK_INIT();
+ return_on_error(load_video_binaries());
+ return_on_error(sh_css_binary_grid_info
+ (my_css.video_settings.video_binary, info));
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_configure_output(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format)
+{
+ CHECK_INIT();
+ CHECK_RES(width, height);
+ if (my_css.video_settings.output_info.width != width ||
+ my_css.video_settings.output_info.height != height ||
+ my_css.video_settings.output_info.format != format) {
+ sh_css_frame_info_init(&my_css.video_settings.output_info,
+ width, height, format, 0);
+ invalidate_video_binaries();
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_configure_viewfinder(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format)
+{
+ CHECK_INIT();
+ CHECK_RES(width, height);
+ if (my_css.video_settings.vf_info.width != width ||
+ my_css.video_settings.vf_info.height != height ||
+ my_css.video_settings.vf_info.format != format) {
+ sh_css_frame_info_init(&my_css.video_settings.vf_info,
+ width, height, format, 0);
+ invalidate_video_binaries();
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_set_isp_parameters(struct sh_css_params *params)
+{
+ CHECK_INIT();
+ my_css.video_settings.isp_parameters = params;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_set_input_mode(enum sh_css_input_mode mode)
+{
+ enum sh_css_input_mode prev = my_css.video_settings.input_mode;
+
+ CHECK_INIT();
+ if (prev != mode) {
+ if (mode == sh_css_input_mode_memory
+ || prev == sh_css_input_mode_memory) {
+ /* if we switch from online to offline, we need to
+ reload the binary */
+ invalidate_video_binaries();
+ }
+ }
+ my_css.video_settings.input_mode = mode;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_set_dis_vector(unsigned int x, unsigned int y)
+{
+ CHECK_INIT();
+ my_css.video_settings.dvs_vector_x = x;
+ my_css.video_settings.dvs_vector_y = y;
+ return sh_css_success;
+}
+
+/* Specify the envelope to be used for DIS. */
+sh_css_err
+sh_css_video_set_dis_envelope(unsigned int width, unsigned int height)
+{
+ CHECK_INIT();
+ my_css.video_settings.dvs_envelope_width = width;
+ my_css.video_settings.dvs_envelope_height = height;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_video_get_dis_envelope(unsigned int *width, unsigned int *height)
+{
+ CHECK_INIT();
+ *width = my_css.video_settings.dvs_envelope_width;
+ *height = my_css.video_settings.dvs_envelope_height;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_set_zoom_factor(unsigned int dx, unsigned int dy)
+{
+ unsigned int old_dx, old_dy;
+ ShBool was_zoomed, is_zoomed;
+
+ CHECK_INIT();
+ sh_css_uds_get_zoom_factor(&old_dx, &old_dy);
+ is_zoomed = (dx < 64) || (dy < 64);
+ was_zoomed = (old_dx < 64) || (old_dy < 64);
+
+ if (is_zoomed != was_zoomed) {
+ /* for video with/without zoom, we use different binaries */
+ invalidate_video_binaries();
+ }
+ sh_css_uds_set_zoom_factor(dx, dy);
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_get_zoom_factor(unsigned int *dx, unsigned int *dy)
+{
+ CHECK_INIT();
+ sh_css_uds_get_zoom_factor(dx, dy);
+ return sh_css_success;
+}
+
+/*================================ Capture Code ============================= */
+static sh_css_err
+load_copy_binaries(void)
+{
+ struct sh_css_binary_descr copy_descr;
+
+ if (my_css.capture_settings.copy_binary)
+ return sh_css_success;
+
+ CHECK_FRAME_INFO(my_css.capture_settings.output_info);
+ if (my_css.capture_settings.bayer_ds)
+ copy_descr.mode = sh_css_binary_mode_bayer_ds;
+ else
+ copy_descr.mode = sh_css_binary_mode_copy;
+
+ copy_descr.online = ShTrue;
+ copy_descr.stream_format = my_css.input_format;
+ copy_descr.two_ppc = my_css.two_pixels_per_clock;
+ copy_descr.in_info = &my_css.input_effective_info;
+ copy_descr.out_info = &my_css.capture_settings.output_info;
+ copy_descr.vf_info = NULL;
+ copy_descr.extra_lines = 0;
+ return_on_error(get_copy_out_frame_format
+ (&my_css.capture_settings.output_info.format));
+ return_on_error(sh_css_input_format_bits_per_pixel
+ (my_css.input_format, my_css.two_pixels_per_clock,
+ &my_css.capture_settings.output_info.vraw_bit_depth));
+ return_on_error(sh_css_binary_padded_width
+ (©_descr,
+ &my_css.capture_settings.output_info.padded_width));
+ return_on_error(sh_css_binary_find
+ (©_descr, &my_css.capture_settings.copy_binary));
+ return sh_css_success;
+}
+
+static sh_css_err
+load_primary_binaries(void)
+{
+ struct sh_css_binary_descr copy_descr, prim_descr, vf_pp_descr,
+ xnr_descr;
+ ShBool online;
+ struct sh_css_frame_info copy_in_info, prim_in_info,
+ prim_out_info, prim_vf_info;
+ unsigned int padded_width = 0, filter_columns = 0;
+
+ if (my_css.capture_settings.primary_binary)
+ return sh_css_success;
+
+ CHECK_VF_OUT_INFO(my_css.capture_settings.output_info,
+ my_css.capture_settings.vf_info);
+ online = my_css.capture_settings.online;
+ prim_in_info = my_css.input_effective_info;
+ prim_in_info.format = sh_css_frame_format_vraw16;
+ return_on_error(sh_css_input_format_bits_per_pixel(my_css.input_format,
+ my_css.
+ two_pixels_per_clock,
+ &prim_in_info.
+ vraw_bit_depth));
+ prim_out_info = my_css.capture_settings.output_info;
+ prim_vf_info = my_css.capture_settings.vf_info;
+ prim_vf_info.format = sh_css_frame_format_yuv420;
+ if (!online) {
+ copy_in_info = my_css.input_effective_info;
+ copy_descr.mode = sh_css_binary_mode_copy;
+ copy_descr.online = ShTrue;
+ copy_descr.stream_format = my_css.input_format;
+ copy_descr.two_ppc = my_css.two_pixels_per_clock;
+ copy_descr.in_info = ©_in_info;
+ copy_descr.out_info = &prim_in_info;
+ copy_descr.vf_info = NULL;
+ return_on_error(extra_lines_available(©_descr.extra_lines));
+ }
+ prim_descr.mode = sh_css_binary_mode_primary;
+ prim_descr.online = online;
+ prim_descr.stream_format = my_css.input_format;
+ prim_descr.two_ppc = my_css.two_pixels_per_clock;
+ prim_descr.in_info = &prim_in_info;
+ prim_descr.out_info = &prim_out_info;
+ prim_descr.vf_info = &prim_vf_info;
+ return_on_error(extra_lines_available(&prim_descr.extra_lines));
+
+ return_on_error(sh_css_binary_padded_width(&prim_descr, &padded_width));
+ return_on_error(sh_css_binary_filter_columns
+ (&prim_descr, &filter_columns));
+ if (!online) {
+ unsigned int left_padding = 0;
+ struct sh_css_binary *copy_binary;
+ return_on_error(sh_css_binary_padded_width
+ (©_descr, &padded_width));
+ return_on_error(sh_css_binary_filter_columns
+ (©_descr, &filter_columns));
+ copy_in_info.padded_width = padded_width;
+ return_on_error(sh_css_binary_find(©_descr,
+ &my_css.capture_settings.
+ copy_binary));
+ copy_binary = my_css.capture_settings.copy_binary;
+ prim_in_info.padded_width = padded_width;
+ my_css.capture_settings.copy_binary->filter_columns =
+ filter_columns;
+ if (filter_columns)
+ left_padding = 2 * ISP_NWAY - filter_columns;
+ copy_binary->int_out_frame_info.width += left_padding;
+ copy_binary->int_out_frame_info.padded_width += left_padding;
+ copy_binary->out_frame_info.width += left_padding;
+ copy_binary->out_frame_info.padded_width += left_padding;
+ } else {
+ prim_in_info.padded_width = prim_in_info.width;
+ }
+
+ if (my_css.capture_settings.xnr) {
+ prim_out_info.format = sh_css_frame_format_yuv420;
+ xnr_descr.mode = sh_css_binary_mode_xnr;
+ xnr_descr.online = ShFalse;
+ xnr_descr.in_info = &prim_out_info;
+ xnr_descr.out_info = &my_css.capture_settings.output_info;
+ xnr_descr.vf_info = NULL;
+ xnr_descr.extra_lines = 0;
+ return_on_error(sh_css_binary_padded_width
+ (&xnr_descr, &padded_width));
+ }
+
+ prim_out_info.padded_width = padded_width;
+ my_css.capture_settings.output_info.padded_width = padded_width;
+ return_on_error(sh_css_binary_find(&prim_descr,
+ &my_css.capture_settings.
+ primary_binary));
+ if (my_css.capture_settings.xnr) {
+ return_on_error(sh_css_binary_find(&xnr_descr,
+ &my_css.capture_settings.
+ xnr_binary));
+ }
+
+ /* the vf_pp input frame depends on the primary vf output. */
+ vf_pp_descr.mode = sh_css_binary_mode_vf_pp;
+ vf_pp_descr.online = ShFalse;
+ vf_pp_descr.in_info =
+ &my_css.capture_settings.primary_binary->vf_frame_info;
+ vf_pp_descr.out_info = &my_css.capture_settings.vf_info;
+ vf_pp_descr.vf_info = NULL;
+ vf_pp_descr.extra_lines = 0;
+
+ return_on_error(sh_css_binary_padded_width(&vf_pp_descr,
+ &my_css.capture_settings.
+ vf_info.padded_width));
+ return_on_error(sh_css_binary_find
+ (&vf_pp_descr, &my_css.capture_settings.vf_pp_binary));
+
+ return sh_css_success;
+}
+
+static sh_css_err
+load_advanced_binaries(void)
+{
+ struct sh_css_binary_descr copy_descr, pre_descr, gdc_descr,
+ post_descr, vf_pp_descr, xnr_descr;
+ struct sh_css_frame_info copy_in_info, pre_in_info, gdc_in_info,
+ post_in_info, post_out_info, post_vf_info;
+ unsigned int padded_width = 0;
+
+ if (my_css.capture_settings.copy_binary)
+ return sh_css_success;
+
+ CHECK_VF_OUT_INFO(my_css.capture_settings.output_info,
+ my_css.capture_settings.vf_info);
+
+ /* frame formats */
+ copy_in_info = my_css.input_effective_info;
+ pre_in_info = my_css.capture_settings.output_info;
+ gdc_in_info = my_css.capture_settings.output_info;
+ post_in_info = my_css.capture_settings.output_info;
+ post_out_info = my_css.capture_settings.output_info;
+ pre_in_info.format = sh_css_frame_format_vraw16;
+ return_on_error(sh_css_input_format_bits_per_pixel(my_css.input_format,
+ my_css.
+ two_pixels_per_clock,
+ &pre_in_info.
+ vraw_bit_depth));
+ gdc_in_info.format = sh_css_frame_format_qplane6;
+ post_in_info.format = sh_css_frame_format_yuv420_16;
+ post_vf_info = my_css.capture_settings.vf_info;
+ post_vf_info.format = sh_css_frame_format_yuv420;
+
+ /* copy binary */
+ copy_descr.mode = sh_css_binary_mode_copy;
+ copy_descr.online = ShTrue;
+ copy_descr.stream_format = my_css.input_format;
+ copy_descr.two_ppc = my_css.two_pixels_per_clock;
+ copy_descr.in_info = ©_in_info;
+ copy_descr.out_info = &pre_in_info;
+ copy_descr.vf_info = NULL;
+ return_on_error(extra_lines_available(©_descr.extra_lines));
+
+ /* pre-gdc binary */
+ pre_descr.mode = sh_css_binary_mode_pre_gdc;
+ pre_descr.online = ShFalse;
+ pre_descr.in_info = &pre_in_info;
+ pre_descr.out_info = &gdc_in_info;
+ pre_descr.vf_info = NULL;
+ return_on_error(extra_lines_available(&pre_descr.extra_lines));
+
+ /* gdc binary */
+ gdc_descr.mode = sh_css_binary_mode_gdc;
+ gdc_descr.online = ShFalse;
+ gdc_descr.in_info = &gdc_in_info;
+ gdc_descr.out_info = &post_in_info;
+ gdc_descr.vf_info = NULL;
+ return_on_error(extra_lines_available(&gdc_descr.extra_lines));
+
+ /* post-gdc binary */
+ post_descr.mode = sh_css_binary_mode_post_gdc;
+ post_descr.online = ShFalse;
+ post_descr.in_info = &post_in_info;
+ post_descr.out_info = &post_out_info;
+ post_descr.vf_info = &post_vf_info;
+ return_on_error(extra_lines_available(&post_descr.extra_lines));
+
+ if (my_css.capture_settings.xnr) {
+ post_out_info.format = sh_css_frame_format_yuv420;
+ xnr_descr.mode = sh_css_binary_mode_xnr;
+ xnr_descr.online = ShFalse;
+ xnr_descr.in_info = &post_out_info;
+ xnr_descr.out_info = &my_css.capture_settings.output_info;
+ xnr_descr.vf_info = NULL;
+ xnr_descr.extra_lines = 0;
+ return_on_error(sh_css_binary_padded_width
+ (&xnr_descr, &padded_width));
+ }
+ return_on_error(sh_css_binary_padded_width(©_descr, &padded_width));
+ return_on_error(sh_css_binary_padded_width(&pre_descr, &padded_width));
+ return_on_error(sh_css_binary_padded_width(&gdc_descr, &padded_width));
+ return_on_error(sh_css_binary_padded_width(&post_descr, &padded_width));
+ /* now tell each of the binaries which width to use */
+ pre_in_info.padded_width = padded_width;
+ gdc_in_info.padded_width = padded_width;
+ post_in_info.padded_width = padded_width;
+ post_out_info.padded_width = padded_width;
+ my_css.capture_settings.output_info.padded_width = padded_width;
+
+ return_on_error(sh_css_binary_find(©_descr,
+ &my_css.capture_settings.
+ copy_binary));
+ return_on_error(sh_css_binary_find
+ (&pre_descr, &my_css.capture_settings.pregdc_binary));
+ return_on_error(sh_css_binary_find
+ (&gdc_descr, &my_css.capture_settings.gdc_binary));
+ return_on_error(sh_css_binary_find
+ (&post_descr, &my_css.capture_settings.postgdc_binary));
+
+ /* vf_pp binary */
+ vf_pp_descr.mode = sh_css_binary_mode_vf_pp;
+ vf_pp_descr.online = ShFalse;
+ vf_pp_descr.in_info =
+ &my_css.capture_settings.postgdc_binary->vf_frame_info;
+ vf_pp_descr.out_info = &my_css.capture_settings.vf_info;
+ vf_pp_descr.vf_info = NULL;
+ vf_pp_descr.extra_lines = 0;
+ return_on_error(sh_css_binary_padded_width(&vf_pp_descr,
+ &my_css.capture_settings.
+ vf_info.padded_width));
+ return_on_error(sh_css_binary_find
+ (&vf_pp_descr, &my_css.capture_settings.vf_pp_binary));
+ if (my_css.capture_settings.xnr)
+ return_on_error(sh_css_binary_find(&xnr_descr,
+ &my_css.capture_settings.
+ xnr_binary));
+
+ return sh_css_success;
+}
+
+static sh_css_err
+load_capture_binaries(void)
+{
+ /* in primary or advanced, the input format must be raw */
+ CHECK_INPUT(my_css.capture_settings.mode != sh_css_capture_mode_raw);
+ switch (my_css.capture_settings.mode) {
+ case sh_css_capture_mode_raw:
+ if (my_css.input_format == sh_css_input_format_binary_8) {
+ /* this is handled by the SP, no ISP binaries needed. */
+ my_css.capture_settings.output_info.padded_width =
+ JPEG_BYTES;
+ my_css.capture_settings.output_info.width = JPEG_BYTES;
+ my_css.capture_settings.output_info.height = 1;
+ return sh_css_success;
+ } else {
+ return load_copy_binaries();
+ }
+ case sh_css_capture_mode_primary:
+ return load_primary_binaries();
+ case sh_css_capture_mode_advanced:
+ return load_advanced_binaries();
+ }
+ return sh_css_success;
+}
+
+static void
+invalidate_capture_binaries(void)
+{
+ my_css.capture_settings.pipeline.reload = ShTrue;
+ my_css.capture_settings.copy_binary = NULL;
+ my_css.capture_settings.primary_binary = NULL;
+ my_css.capture_settings.pregdc_binary = NULL;
+ my_css.capture_settings.gdc_binary = NULL;
+ my_css.capture_settings.postgdc_binary = NULL;
+ my_css.capture_settings.xnr_binary = NULL;
+ my_css.capture_settings.vf_pp_binary = NULL;
+}
+
+/* start the binary copy function on the SP */
+static sh_css_err
+start_binary_copy_on_sp(struct sh_css_frame *out_frame)
+{
+ my_css.capture_settings.output_frame = out_frame;
+ return_on_error(sh_css_config_input_network(NULL,
+ my_css.capture_settings.
+ input_mode));
+ sh_css_sp_start_binary_copy(out_frame->planes.binary.data.data,
+ out_frame->data_bytes,
+ my_css.two_pixels_per_clock);
+ my_css.mode = sh_css_mode_capture;
+ my_css.state = sh_css_state_executing_sp_only;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_start(struct sh_css_frame *out_frame,
+ struct sh_css_frame *vf_frame)
+{
+ ShBool xnr = my_css.capture_settings.xnr,
+ raw = my_css.capture_settings.mode == sh_css_capture_mode_raw;
+ struct sh_css_pipeline *me = &my_css.capture_settings.pipeline;
+ struct sh_css_pipeline_stage *out_stage, *vf_pp_stage;
+ struct sh_css_binary *copy_binary,
+ *primary_binary,
+ *vf_pp_binary,
+ *pregdc_binary, *gdc_binary, *postgdc_binary, *xnr_binary;
+
+ CHECK_INIT();
+ CHECK_PTR_ARG(out_frame);
+ if (my_css.capture_settings.mode == sh_css_capture_mode_raw) {
+ if (my_css.input_format == sh_css_input_format_binary_8) {
+ return_on_error(start_binary_copy_on_sp(out_frame));
+ wait_for_if_setup();
+ return sh_css_success;
+ }
+ } else {
+ CHECK_PTR_ARG(vf_frame);
+ }
+ if (!my_css.capture_settings.isp_parameters) {
+ allocate_default_params();
+ my_css.capture_settings.isp_parameters = my_css.default_params;
+ }
+ return_on_error(load_capture_binaries());
+ CHECK_INFOS_MATCH(out_frame->info, my_css.capture_settings.output_info);
+ if (my_css.capture_settings.mode == sh_css_capture_mode_raw && vf_frame)
+ return sh_css_err_mode_does_not_have_viewfinder;
+
+ if (vf_frame)
+ CHECK_INFOS_MATCH(vf_frame->info,
+ my_css.capture_settings.vf_info);
+
+ copy_binary = my_css.capture_settings.copy_binary;
+ primary_binary = my_css.capture_settings.primary_binary;
+ vf_pp_binary = my_css.capture_settings.vf_pp_binary;
+ pregdc_binary = my_css.capture_settings.pregdc_binary;
+ gdc_binary = my_css.capture_settings.gdc_binary;
+ postgdc_binary = my_css.capture_settings.postgdc_binary;
+ xnr_binary = my_css.capture_settings.xnr_binary;
+
+ if (me->reload) {
+ struct sh_css_pipeline_stage *post_stage;
+ return_on_error(sh_css_pipeline_clean(me));
+ if (my_css.capture_settings.copy_binary)
+ return_on_error(sh_css_pipeline_add_stage
+ (me, copy_binary, NULL,
+ raw ? out_frame : NULL, NULL,
+ &post_stage));
+ if (my_css.capture_settings.mode == sh_css_capture_mode_primary)
+ return_on_error(sh_css_pipeline_add_stage
+ (me, primary_binary, NULL,
+ xnr ? NULL : out_frame, NULL,
+ &post_stage));
+ if (my_css.capture_settings.mode ==
+ sh_css_capture_mode_advanced) {
+ return_on_error(sh_css_pipeline_add_stage
+ (me, pregdc_binary, NULL, NULL, NULL,
+ NULL));
+ return_on_error(sh_css_pipeline_add_stage
+ (me, gdc_binary, NULL, NULL, NULL,
+ NULL));
+ return_on_error(sh_css_pipeline_add_stage
+ (me, postgdc_binary, NULL,
+ xnr ? NULL : out_frame, NULL,
+ &post_stage));
+ }
+ if (xnr)
+ return_on_error(sh_css_pipeline_add_stage
+ (me, xnr_binary, NULL, out_frame, NULL,
+ NULL));
+ if (my_css.capture_settings.mode != sh_css_capture_mode_raw)
+ return_on_error(sh_css_pipeline_add_stage
+ (me, vf_pp_binary,
+ post_stage->args.out_vf_frame,
+ vf_frame, NULL, NULL));
+ return_on_error(sh_css_config_input_network
+ (me, my_css.capture_settings.input_mode));
+ me->reload = ShFalse;
+ } else
+ return_on_error(sh_css_pipeline_restart(me));
+
+ if (my_css.capture_settings.mode == sh_css_capture_mode_raw) {
+ return_on_error(sh_css_pipeline_get_stage(me,
+ copy_binary->mode,
+ &out_stage));
+ } else {
+ if (my_css.capture_settings.xnr)
+ return_on_error(
+ sh_css_pipeline_get_stage(me,
+ xnr_binary->mode,
+ &out_stage));
+ else if (my_css.capture_settings.mode ==
+ sh_css_capture_mode_primary)
+ return_on_error(sh_css_pipeline_get_stage
+ (me, primary_binary->mode, &out_stage));
+ else
+ return_on_error(
+ sh_css_pipeline_get_stage(me,
+ postgdc_binary->mode,
+ &out_stage));
+ return_on_error(sh_css_pipeline_get_stage
+ (me, vf_pp_binary->mode, &vf_pp_stage));
+ }
+ if (my_css.capture_settings.mode != sh_css_capture_mode_raw) {
+ vf_pp_stage->args.out_frame = vf_frame;
+ if (my_css.capture_settings.mode == sh_css_capture_mode_advanced
+ && !sh_css_params_get_morph_table(my_css.capture_settings.
+ isp_parameters)) {
+ unsigned int width, height;
+
+ width = ((64 / ISP_VEC_NELEMS) *
+ my_css.capture_settings.gdc_binary->
+ s3atbl_width) + 1;
+ height =
+ ((64 / ISP_VEC_NELEMS) *
+ my_css.capture_settings.gdc_binary->
+ s3atbl_height) + 1;
+ return_on_error(sh_css_params_default_morph_table
+ (&my_css.capture_settings.
+ id_morph_table, width, height));
+ sh_css_params_set_morph_table(my_css.capture_settings.
+ isp_parameters,
+ my_css.capture_settings.
+ id_morph_table);
+ }
+ }
+ out_stage->args.out_frame = out_frame;
+ me->input_mode = my_css.capture_settings.input_mode;
+ me->isp_parameters = my_css.capture_settings.isp_parameters;
+ my_css.mode = sh_css_mode_capture;
+ return sh_css_pipeline_start_next_stage(me, NULL);
+}
+
+sh_css_err
+sh_css_capture_get_output_frame_info(struct sh_css_frame_info *info)
+{
+ CHECK_INIT();
+ return_on_error(load_capture_binaries());
+ if (my_css.capture_settings.mode == sh_css_capture_mode_raw &&
+ my_css.input_format == sh_css_input_format_binary_8)
+ sh_css_frame_info_init(info, JPEG_BYTES, 1,
+ sh_css_frame_format_binary_8,
+ JPEG_BYTES);
+ else {
+ *info = my_css.capture_settings.output_info;
+ if (info->format == sh_css_frame_format_vraw16)
+ return_on_error(sh_css_input_format_bits_per_pixel
+ (my_css.input_format,
+ my_css.two_pixels_per_clock,
+ &info->vraw_bit_depth));
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_get_viewfinder_frame_info(struct sh_css_frame_info *info)
+{
+ CHECK_INIT();
+ return_on_error(load_capture_binaries());
+ if (my_css.capture_settings.mode == sh_css_capture_mode_raw)
+ return sh_css_err_mode_does_not_have_viewfinder;
+ *info = my_css.capture_settings.vf_info;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_get_grid_info(struct sh_css_grid_info *info)
+{
+ CHECK_INIT();
+ if (my_css.capture_settings.mode == sh_css_capture_mode_raw)
+ return sh_css_err_mode_does_not_have_grid;
+ return_on_error(load_capture_binaries());
+ if (my_css.capture_settings.mode == sh_css_capture_mode_primary)
+ return_on_error(sh_css_binary_grid_info
+ (my_css.capture_settings.primary_binary, info));
+ else
+ return_on_error(sh_css_binary_grid_info
+ (my_css.capture_settings.pregdc_binary, info));
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_set_mode(enum sh_css_capture_mode mode)
+{
+ CHECK_INIT();
+ if (mode != my_css.capture_settings.mode) {
+ my_css.capture_settings.mode = mode;
+ invalidate_capture_binaries();
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_enable_xnr(ShBool enable)
+{
+ CHECK_INIT();
+ my_css.capture_settings.xnr = enable;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_enable_bayer_downscaling(ShBool enable)
+{
+ CHECK_INIT();
+ my_css.capture_settings.bayer_ds = enable;
+ my_css.capture_settings.copy_binary = NULL;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_configure_output(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format)
+{
+ CHECK_INIT();
+ CHECK_RES(width, height);
+ if (my_css.capture_settings.output_info.width != width ||
+ my_css.capture_settings.output_info.height != height ||
+ my_css.capture_settings.output_info.format != format) {
+ sh_css_frame_info_init(&my_css.capture_settings.output_info,
+ width, height, format, 0);
+ invalidate_capture_binaries();
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_configure_viewfinder(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format)
+{
+ CHECK_INIT();
+ CHECK_RES(width, height);
+ if (my_css.capture_settings.vf_info.width != width ||
+ my_css.capture_settings.vf_info.height != height ||
+ my_css.capture_settings.vf_info.format != format) {
+ sh_css_frame_info_init(&my_css.capture_settings.vf_info,
+ width, height, format, 0);
+ invalidate_capture_binaries();
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_set_isp_parameters(struct sh_css_params *params)
+{
+ CHECK_INIT();
+ my_css.capture_settings.isp_parameters = params;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_set_input_mode(enum sh_css_input_mode mode)
+{
+ CHECK_INIT();
+ my_css.capture_settings.input_mode = mode;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_capture_enable_online(ShBool enable)
+{
+ CHECK_INIT();
+ my_css.capture_settings.online = enable;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_histogram_allocate(unsigned int num_elements,
+ struct sh_css_histogram **histogram)
+{
+ struct sh_css_histogram *me = sh_css_malloc(sizeof(*me));
+
+ if (me == NULL)
+ return sh_css_err_cannot_allocate_memory;
+ me->num_elements = num_elements;
+ me->data = hrt_isp_css_mm_alloc(num_elements * sizeof(unsigned int));
+ if (me->data == NULL) {
+ sh_css_free(me);
+ return sh_css_err_cannot_allocate_memory;
+ }
+ *histogram = me;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_histogram_free(struct sh_css_histogram *me)
+{
+ if (me->data)
+ hrt_isp_css_mm_free(me->data);
+ sh_css_free(me);
+ return sh_css_success;
+}
+
+static sh_css_err
+check_overlay(const struct sh_css_overlay *overlay)
+{
+ if (overlay->frame == NULL)
+ return sh_css_err_overlay_frame_missing;
+ if (overlay->frame->info.padded_width > SP_MAX_OVERLAY_WIDTH)
+ return sh_css_err_overlay_frames_too_big;
+ if (overlay->frame->info.format != sh_css_frame_format_yuv420)
+ return sh_css_err_unsupported_frame_format;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_overlay_frame(const struct sh_css_overlay *overlay,
+ struct sh_css_frame *input_frame,
+ struct sh_css_frame *output_frame,
+ unsigned int overlay_start_x,
+ unsigned int overlay_start_y)
+{
+ unsigned int max_x, max_y;
+
+ CHECK_INIT();
+ /* all frames must be non-NULL */
+ if (overlay == NULL)
+ return sh_css_err_overlay_not_set;
+ if (input_frame == NULL || output_frame == NULL)
+ return sh_css_err_invalid_arguments;
+
+ return_on_error(check_overlay(overlay));
+
+ /* all frames must be the same size */
+ if (output_frame->info.height != input_frame->info.height ||
+ output_frame->info.padded_width != input_frame->info.padded_width ||
+ output_frame->info.format != sh_css_frame_format_yuv420 ||
+ input_frame->info.format != sh_css_frame_format_yuv420)
+ return sh_css_err_frames_mismatch;
+ if (input_frame->info.padded_width > SP_MAX_ELEMS_PER_LINE)
+ return sh_css_err_overlay_frames_too_big;
+ max_x = input_frame->info.padded_width -
+ overlay->frame->info.padded_width - 1;
+ max_y = input_frame->info.height - overlay->frame->info.height - 1;
+ overlay_start_x = MAX(overlay_start_x, max_x);
+ overlay_start_y = MAX(overlay_start_y, max_y);
+ sh_css_sp_si_set_overlay_position(overlay_start_x, overlay_start_y);
+ sh_css_sp_si_set_overlay_frame_size(overlay->frame->info.padded_width,
+ overlay->frame->info.height);
+ sh_css_sp_si_set_frame_size(input_frame->info.padded_width,
+ input_frame->info.height);
+ sh_css_sp_si_set_input_pointers(input_frame->planes.yuv.Y.data,
+ input_frame->planes.yuv.U.data,
+ input_frame->planes.yuv.V.data);
+ sh_css_sp_si_set_output_pointers(output_frame->planes.yuv.Y.data,
+ output_frame->planes.yuv.U.data,
+ output_frame->planes.yuv.V.data);
+ sh_css_sp_si_set_overlay_pointers(overlay->frame->planes.yuv.Y.data,
+ overlay->frame->planes.yuv.U.data,
+ overlay->frame->planes.yuv.V.data);
+ sh_css_sp_si_set_overlay_bg_color(overlay->bg_y,
+ overlay->bg_u, overlay->bg_v);
+ sh_css_sp_si_start_from_ddr();
+ sh_css_hrt_sp_wait();
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_get_y_histogram(const struct sh_css_frame *input_frame,
+ struct sh_css_histogram *histogram)
+{
+ CHECK_INIT();
+ if (input_frame->info.padded_width > SP_MAX_ELEMS_PER_LINE)
+ return sh_css_err_overlay_frames_too_big;
+ if (input_frame->info.format != sh_css_frame_format_yuv420)
+ return sh_css_err_frames_mismatch;
+ sh_css_sp_histogram_set_pointer(histogram->data);
+ sh_css_sp_histogram_set_input_pointers(input_frame->planes.yuv.Y.data,
+ input_frame->planes.yuv.U.data,
+ input_frame->planes.yuv.V.data);
+ sh_css_sp_histogram_generate();
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_send_input_frame(unsigned short *data,
+ unsigned int width,
+ unsigned int height)
+{
+ CHECK_INIT();
+ sh_css_hrt_send_input_frame(data, width, height, my_css.ch_id,
+ my_css.input_format,
+ my_css.two_pixels_per_clock);
+ return sh_css_success;
+}
+sh_css_err
+sh_css_capture_get_output_raw_frame_info(struct sh_css_frame_info *info)
+{
+ CHECK_INIT();
+ return_on_error(load_capture_binaries());
+ sh_css_binary_print(my_css.capture_settings.primary_binary);
+ if (my_css.capture_settings.primary_binary)
+ *info = my_css.capture_settings.primary_binary->in_frame_info;
+ else
+ return sh_css_err_internal_error;
+ return sh_css_success;
+}
+
+struct sh_css_frame *sh_css_get_raw_frame(void)
+{
+ return (struct sh_css_frame *)copy_frame;
+}
+
+sh_css_err
+sh_css_convert_raw_frame(struct sh_css_frame *frame, __u32 width, __u32 height)
+{
+ __u32 i, j, k;
+ unsigned short *buffer = kmalloc((width * 2), GFP_KERNEL);
+ unsigned short *buf = kmalloc((width*2), GFP_KERNEL);
+ void *addr = frame->data;
+ __u8 bit_depth = frame->info.vraw_bit_depth;
+
+ if (!buffer || !buf) {
+ printk(KERN_ERR "out of memory.\n");
+ return sh_css_err_internal_error;
+ }
+ printk(KERN_DEBUG "func %s, raw_bit_depth %d\n", __func__, bit_depth);
+
+ for (i = 0; i < height; i++) {
+ hrt_isp_css_mm_load(addr, buffer, width * 2);
+ for (j = 0; j < width; j += (ISP_VEC_NELEMS*2)) {
+ for (k = 0; k < ISP_VEC_NELEMS; k++) {
+ ((unsigned short *)buf)[j+k*2] =
+ ((buffer[j+k] << (16 - bit_depth)));
+ }
+ for (k = 0; k < ISP_VEC_NELEMS; k++) {
+ ((unsigned short *)buf)[j+k*2+1] =
+ ((buffer[j+ISP_VEC_NELEMS+k] <<
+ (16 - bit_depth)));
+ }
+ }
+
+ hrt_isp_css_mm_store(addr, buf, width*2);
+ addr = addr + (width * 2);
+ }
+
+ kfree(buffer);
+ kfree(buf);
+ return sh_css_success;
+}
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css.h
new file mode 100644
index 0000000..7a8fba1
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css.h
@@ -0,0 +1,697 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SHCSS_H_
+#define _SHCSS_H_
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#else
+#include <stdarg.h> /* for the print function */
+#include <stdlib.h> /* for size_t */
+#endif
+
+#define SH_CSS_MAJOR 0
+#define SH_CSS_MINOR 2
+#define SH_CSS_REVISION 4
+
+/* Errors, these values are used as the return value for most
+ functions in this API. These can be translated into a human readable
+ string (see below). */
+
+#define sh_css_err int
+
+enum {
+ sh_css_success,
+ sh_css_err_internal_error,
+ sh_css_err_conflicting_mipi_settings,
+ sh_css_err_unsupported_configuration,
+ sh_css_err_mode_does_not_have_viewfinder,
+ sh_css_err_input_resolution_not_set,
+ sh_css_err_unsupported_input_mode,
+ sh_css_err_isp_parameters_not_set,
+ sh_css_err_cannot_allocate_memory,
+ sh_css_err_invalid_arguments,
+ sh_css_err_too_may_colors,
+ sh_css_err_overlay_frame_missing,
+ sh_css_err_overlay_frames_too_big,
+ sh_css_err_unsupported_frame_format,
+ sh_css_err_frames_mismatch,
+ sh_css_err_overlay_not_set,
+ sh_css_err_not_implemented,
+ sh_css_err_invalid_frame_format,
+ sh_css_err_unsupported_resolution,
+ sh_css_err_scaling_factor_out_of_range,
+ sh_css_err_cannot_obtain_shading_table,
+ sh_css_err_interrupt_error,
+ sh_css_err_unexpected_interrupt,
+ sh_css_err_interrupts_not_enabled,
+ sh_css_err_system_not_idle,
+ sh_css_err_unsupported_input_format,
+ sh_css_err_not_enough_input_lines,
+ sh_css_err_not_enough_input_columns,
+ sh_css_err_not_initialized,
+ sh_css_err_illegal_resolution,
+ sh_css_err_effective_input_resolution_not_set,
+ sh_css_err_viewfinder_resolution_too_wide,
+ sh_css_err_viewfinder_resolution_exceeds_output,
+ sh_css_err_mode_does_not_have_grid
+};
+
+/* Input modes, these enumerate all supported input modes:
+ * - Sensor: data from a sensor coming into the MIPI interface
+ * - FIFO: data from the host coming into the GP FIFO
+ * - TPG: data coming from the test pattern generator
+ * - PRBS: data coming from the Pseudo Random Bit Sequence
+ * - Memory: data coming from DDR
+ */
+enum sh_css_input_mode {
+ sh_css_input_mode_sensor,
+ sh_css_input_mode_fifo,
+ sh_css_input_mode_tpg,
+ sh_css_input_mode_prbs,
+ sh_css_input_mode_memory
+};
+
+/* The MIPI interface can be used in two modes, one with one
+ * lane and one with 4 lanes.
+ */
+enum sh_css_mipi_port {
+ sh_css_mipi_port_1lane,
+ sh_css_mipi_port_4lane
+};
+
+/* The MIPI interface supports 2 types of compression or can
+ * be run without compression.
+ */
+enum sh_css_mipi_compression {
+ sh_css_mipi_compression_none,
+ sh_css_mipi_compression_1,
+ sh_css_mipi_compression_2
+};
+
+/* The ISP streaming input interface supports the following formats.
+ * These match the corresponding MIPI formats.
+ */
+enum sh_css_input_format {
+ sh_css_input_format_yuv420_8_legacy, /* 8 bits per subpixel */
+ sh_css_input_format_yuv420_8, /* 8 bits per subpixel */
+ sh_css_input_format_yuv420_10, /* 10 bits per subpixel */
+ sh_css_input_format_yuv422_8, /* UYVY..UVYV, 8 bits per subpixel */
+ sh_css_input_format_yuv422_10, /* UYVY..UVYV, 10 bits per subpixel */
+ sh_css_input_format_rgb_444, /* BGR..BGR, 4 bits per subpixel */
+ sh_css_input_format_rgb_555, /* BGR..BGR, 5 bits per subpixel */
+ sh_css_input_format_rgb_565, /* BGR..BGR, 5 bits B and $, 6 bits G */
+ sh_css_input_format_rgb_666, /* BGR..BGR, 6 bits per subpixel */
+ sh_css_input_format_rgb_888, /* BGR..BGR, 8 bits per subpixel */
+ sh_css_input_format_raw_6, /* RAW data, 6 bits per pixel */
+ sh_css_input_format_raw_7, /* RAW data, 7 bits per pixel */
+ sh_css_input_format_raw_8, /* RAW data, 8 bits per pixel */
+ sh_css_input_format_raw_10, /* RAW data, 10 bits per pixel */
+ sh_css_input_format_raw_12, /* RAW data, 12 bits per pixel */
+ sh_css_input_format_raw_14, /* RAW data, 14 bits per pixel */
+ sh_css_input_format_raw_16, /* RAW data, 16 bits per pixel */
+ sh_css_input_format_binary_8, /* Binary byte stream. */
+};
+
+/* Specify the capture mode, this can be RAW (simply copy sensor input to DDR),
+ * Primary ISP or the Advanced ISP.
+ */
+enum sh_css_capture_mode {
+ sh_css_capture_mode_raw, /* no processing, only copy input to
+ output, no viewfinder output */
+ sh_css_capture_mode_primary, /* primary ISP */
+ sh_css_capture_mode_advanced, /* advanced ISP */
+};
+
+/* Interrupt info enumeration.
+ * This lists all possible interrupts for use by the appliation layer.
+ * Note that the sh_css API uses some internal interrupts, these are not listed
+ * here.
+ */
+enum sh_css_interrupt_info {
+ /* the current frame is done and a new one can be started */
+ sh_css_interrupt_info_frame_done,
+ /* the css receiver has encountered an error */
+ sh_css_interrupt_info_css_receiver_error,
+ /* the FIFO in the csi receiver has overflown */
+ sh_css_interrupt_info_css_receiver_fifo_overflow,
+ /* the css receiver received the start of frame */
+ sh_css_interrupt_info_css_receiver_sof,
+ /* the css receiver received the end of frame */
+ sh_css_interrupt_info_css_receiver_eof,
+ /* the css receiver received the start of line */
+ sh_css_interrupt_info_css_receiver_sol,
+ /* the css receiver received the end of line */
+ sh_css_interrupt_info_css_receiver_eol,
+ /* the css receiver received a change in side band signals */
+ sh_css_interrupt_info_css_receiver_sideband_changed,
+ /* generic short packets (0) */
+ sh_css_interrupt_info_css_receiver_gen_short_0,
+ /* generic short packets (1) */
+ sh_css_interrupt_info_css_receiver_gen_short_1,
+ /* the primary input formatter (A) has encountered an error */
+ sh_css_interrupt_info_if_prim_error,
+ /* the primary input formatter (B) has encountered an error */
+ sh_css_interrupt_info_if_prim_b_error,
+ /* the secondary input formatter has encountered an error */
+ sh_css_interrupt_info_if_sec_error,
+ /* the stream-to-memory device has encountered an error */
+ sh_css_interrupt_info_stream_to_mem_error,
+ /* the sync generator generated the start of frame */
+ sh_css_interrupt_info_sync_gen_sof,
+ /* the sync generator generated the end of frame */
+ sh_css_interrupt_info_sync_gen_eof,
+ /* the sync generator generated the start of line */
+ sh_css_interrupt_info_sync_gen_sol,
+ /* the sync generator generated the end of line */
+ sh_css_interrupt_info_sync_gen_eol,
+ /* no info available for the caller, used for internal interrupts */
+ sh_css_interrupt_info_none,
+};
+
+/* Enumeration used to select whether interrupts should be used, and if so,
+ * whether they are edge or pulse triggered.
+ * If interrupts are not used, the blocking function
+ * sh_css_wait_for_completion() must be used.
+ */
+enum sh_css_interrupt_setting {
+ sh_css_interrupt_setting_disabled,
+ sh_css_interrupt_setting_edge,
+ sh_css_interrupt_setting_pulse
+};
+
+/* Histogram. This contains num_elements values of type unsigned int.
+ * The data pointer is a DDR pointer (virtual address).
+ */
+struct sh_css_histogram {
+ unsigned int num_elements;
+ void *data; /* pointer to DDR, aka hmm_ptr when hmm is used */
+};
+
+#include "sh_css_frame.h"
+
+/* Overlay:
+ * this is the structure describing the entire overlay.
+ * An overlay consists of a frame (of type sh_css_frame_format_yuv420),
+ * the background color (yuv) and the blending ratios for the subpixels
+ * of the input data and the overlay data.
+ * All pixels in the overlay that are not equal to the background are
+ * overlaid, taking their blending ratio into account. The blending ratio
+ * should be specified between 0 and 100.
+ */
+struct sh_css_overlay {
+ /* the frame containing the overlay data The overlay frame width should
+ * be the multiples of 2*ISP_VEC_NELEMS. The overlay frame height
+ * should be the multiples of 2.
+ */
+ struct sh_css_frame *frame;
+ /* Y value of overlay background */
+ unsigned char bg_y;
+ /* U value of overlay background */
+ char bg_u;
+ /* V value of overlay background */
+ char bg_v;
+ /* the blending percent of input data for Y subpixels */
+ unsigned char blend_input_perc_y;
+ /* the blending percent of input data for U subpixels */
+ unsigned char blend_input_perc_u;
+ /* the blending percent of input data for V subpixels */
+ unsigned char blend_input_perc_v;
+ /* the blending percent of overlay data for Y subpixels */
+ unsigned char blend_overlay_perc_y;
+ /* the blending percent of overlay data for U subpixels */
+ unsigned char blend_overlay_perc_u;
+ /* the blending percent of overlay data for V subpixels */
+ unsigned char blend_overlay_perc_v;
+ /* the overlay start x pixel position on output frame It should be the
+ multiples of 2*ISP_VEC_NELEMS. */
+ unsigned int overlay_start_x;
+ /* the overlay start y pixel position on output frame It should be the
+ multiples of 2. */
+ unsigned int overlay_start_y;
+};
+
+/* structure that describes the 3A and DIS grids */
+struct sh_css_grid_info {
+ unsigned int width_3a;
+ unsigned int height_3a;
+ unsigned int bqs_per_grid_cell_3a;
+ unsigned int width_dis;
+ unsigned int height_dis;
+ unsigned int bqs_per_grid_cell_dis;
+ unsigned int dis_horicoef_num;
+ unsigned int dis_vertcoef_num;
+};
+
+#include "sh_css_params.h"
+#include "sh_css_debug.h"
+
+/* ===== GENERIC ===== */
+
+/* Initialize the API. This is required before any other function in this
+ * API can be called.
+ * Arguments:
+ * - malloc_func: memory allocation function such as malloc or kalloc.
+ * - free_func: memory free function such as free or kfree
+ * - irq_setting: the way interrupts should be used (or not)
+ */
+sh_css_err
+sh_css_init(void *(*malloc_func) (size_t size),
+ void (*free_func) (void *ptr),
+ enum sh_css_interrupt_setting irq_setting);
+
+/* Uninitialize the API. This cleans up all internal data structures. */
+sh_css_err
+sh_css_uninit(void);
+
+/* Enable debugging, this will make the API print debug info while
+ * waiting for the ISP and SP to complete.
+ */
+sh_css_err
+sh_css_enable_debug(ShBool enable);
+
+/* Set the print function. This function is used to print debug information
+ * if debugging is enable. An example of the argument is printf.
+ */
+sh_css_err
+sh_css_set_print_function(int (*func) (const char *fmt, ...));
+
+/* When an interrupt occurs from the ISP_CSS, use this function to get
+ * information about this interrupt. Since multiple interrupts can occur
+ * at the same time, this function returns whether there are more interrupts
+ * pending. This function should be called until this return value becomes
+ * false.
+ */
+sh_css_err
+sh_css_handle_interrupt(enum sh_css_interrupt_info *info,
+ ShBool *more_interrupts);
+sh_css_err
+sh_css_mmu_set_page_table_base_address(void *base_address);
+
+sh_css_err
+sh_css_mmu_invalidate_cache(void);
+
+/* Enable or disable certain interrupts. The interrupt info type is used
+ * here to indicate the interrupt to enable or disable.
+ */
+sh_css_err
+sh_css_enable_interrupt(enum sh_css_interrupt_info info, ShBool enable);
+
+/* Allocate a histogram. */
+sh_css_err
+sh_css_histogram_allocate(unsigned int num_elements,
+ struct sh_css_histogram **histogram);
+
+/* Free a histogram */
+sh_css_err
+sh_css_histogram_free(struct sh_css_histogram *histogram);
+
+/* Translate an error value to a human readable string. This string is
+ * constant and should not be freed by the caller.
+ */
+const char *
+sh_css_err_string(sh_css_err error);
+
+/* Return ShTrue if UV values range from 0 to 255 and ShFalse if UV values
+ * range from -127 to 128.
+ */
+sh_css_err
+sh_css_uv_offset_is_zero(ShBool *uv_offset_is_zero);
+
+/* When interrupts are disabled, use this function to wait for a particular
+ * ISP mode to complete.
+ */
+sh_css_err
+sh_css_wait_for_completion(void);
+
+/* Set the current input resolution. This needs to be called every time the
+ * sensor resolution changes.
+ */
+sh_css_err
+sh_css_input_set_resolution(unsigned int width, unsigned int height);
+
+/* Get the currently set input resolution. */
+sh_css_err
+sh_css_input_get_resolution(unsigned int *width, unsigned int *height);
+
+/* Set the part of the input resolution that will be the input to the ISP.
+ * The difference between the input resolution and effective input resolution
+ * will be cropped off. When the effective input resolution is exceeds the
+ * output resolution, the ISP will downscale the input to the output resolution
+ * in the domain.
+ * Note that the effective input resolution cannot be smaller than the output
+ * resolution.
+ */
+sh_css_err
+sh_css_input_set_effective_resolution(unsigned int width, unsigned int height);
+
+/* Specify the format of the input data. This format is used for all input
+ * sources except memory (mipi receiver, prbs, tpg, fifo).
+ */
+sh_css_err
+sh_css_input_set_format(enum sh_css_input_format format);
+
+/* Translate an input format and mipi compression pair to the fmt_type.
+ * This is normally done by the sensor, but when using the input fifo, this
+ * format type must be sumitted correctly by the application.
+ */
+sh_css_err
+sh_css_input_format_type(enum sh_css_input_format input_format,
+ enum sh_css_mipi_compression compression,
+ unsigned int *fmt_type);
+
+/* Specify that the input will be sent as 2 pixels per clock.
+ * The default is one pixel per clock.
+ */
+sh_css_err
+sh_css_input_set_two_pixels_per_clock(ShBool two_pixels_per_clock);
+
+/* Specify the bayer order of the input. The default is grbg. */
+sh_css_err
+sh_css_input_set_bayer_order(enum sh_css_bayer_order bayer_order);
+
+/* Specify which channel carries the input for the CSS. */
+sh_css_err
+sh_css_input_set_channel(unsigned int channel_id);
+sh_css_err
+sh_css_input_enable_block_fifo_no_reqs(ShBool enable);
+
+/* Configure the MIPI receiver:
+ * - port: select the 1lane or 4lane port
+ * - num_lanes: this argument is only valid for the 4lane port. it specifies
+ * how many of these 4 lanes are in use. Valid values are 1, 2,
+ * 3 or 4.
+ * - timeout: this specifies the timeout after which a timeout interrupt is
+ * generated.
+ * The timeout is specified in terms of <TO BE CLARIFIED>.
+ */
+sh_css_err
+sh_css_input_configure_port(enum sh_css_mipi_port port,
+ unsigned int num_lanes, unsigned int timeout);
+
+/* Specify the number of bits per compressed and uncompressed pixel for a given
+ * compression mode.
+ */
+sh_css_err
+sh_css_input_set_compression(enum sh_css_mipi_compression comp,
+ unsigned int compressed_bits_per_pixel,
+ unsigned int uncompressed_bits_per_pixel);
+
+/* Configure the Test Pattern Generator, the way these values are used to
+ * generate the pattern can be seen in the HRT extension for the test pattern
+ * generator:
+ * devices/test_pat_gen/hrt/include/test_pat_gen.h: hrt_calc_tpg_data().
+ */
+sh_css_err
+sh_css_tpg_configure(unsigned int x_mask, int x_delta,
+ unsigned int y_mask, int y_delta, unsigned int xy_mask);
+
+/* Seed the for the Pseudo Random Bit Sequence */
+sh_css_err
+sh_css_prbs_set_seed(int seed);
+
+/* Digital zoom: this feature can be configured with a zoom factor
+ * which determines the amount of zoom and a zoom center which determines
+ * the point to zoom in at.
+ * This feature is currently available only for video, but will become
+ * available for preview and capture as well. */
+
+/* Set the digital zoom factor, this is a logarithmic scale. The actual zoom
+ * factor will be 64/x.
+ */
+sh_css_err
+sh_css_set_zoom_factor(unsigned int dx, unsigned int dy);
+
+/* Get the current zoom factor. This will return the same values as were set
+ * during the last video_set_zoom_factor() call.
+ */
+sh_css_err
+sh_css_get_zoom_factor(unsigned int *dx, unsigned int *dy);
+
+/* Specify the overlay to be used for each viewfinder frame generated.
+ * This overlay will remain active until it is reset by passing NULL to
+ * this same function.
+ */
+sh_css_err
+sh_css_overlay_set_for_viewfinder(const struct sh_css_overlay *overlay);
+
+/* ===== PREVIEW ===== */
+
+/* Start the ISP in preview mode, this will run the preview ISP on one frame.
+ * After this has completed, it needs to be started again for the next frame.
+ */
+sh_css_err
+sh_css_preview_start(struct sh_css_frame *out_frame);
+
+/* Specify the input mode used by the preview ISP. */
+sh_css_err
+sh_css_preview_set_input_mode(enum sh_css_input_mode mode);
+
+/* Specify the output resolution to be used by the preview ISP. */
+sh_css_err
+sh_css_preview_configure_output(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format);
+
+/* Set the ISP parameter struct to be used for preview. This pointer must remain
+ * valid until either the API is unitialized or a new pointer is provided.
+ */
+sh_css_err
+sh_css_preview_set_isp_parameters(struct sh_css_params *params);
+
+/* Get the information about the output frames, this contains the resolution
+ * and the stride. To allocate frames, use the information returned here.
+ */
+sh_css_err
+sh_css_preview_get_output_frame_info(struct sh_css_frame_info *info);
+
+sh_css_err
+sh_css_preview_get_grid_info(struct sh_css_grid_info *info);
+
+/* ===== CAPTURE ===== */
+
+/* Start the ISP in capture mode:
+ * - out_frame: pointer to the output frame
+ * - vf_frame: pointer to the viewfinder frame
+ */
+sh_css_err
+sh_css_capture_start(struct sh_css_frame *out_frame,
+ struct sh_css_frame *vf_frame);
+
+/* Specify the mode used for capturing. */
+sh_css_err
+sh_css_capture_set_mode(enum sh_css_capture_mode mode);
+
+/* Enable the eXtra Noise Reduction as a post processing step. This will be
+ * run on both the captured output and the viewfinder output.
+ */
+sh_css_err
+sh_css_capture_enable_xnr(ShBool enable);
+
+/* Enable the bayer downscaling binary instead of the regular copy binary.
+ * This means the sensor input will be downscaled instead of cropped.
+ * Note: this feature is still in beta stage, do not use.
+ */
+sh_css_err
+sh_css_capture_enable_bayer_downscaling(ShBool enable);
+
+/* Specify the output resolution for captured images. */
+sh_css_err
+sh_css_capture_configure_output(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format);
+
+/* Specify the viewfinder resolution. Note that this resolution currently
+ * has to be a division of the captured output by a power of 2. The API will
+ * automatically select the resolution that's closest to the one requested
+ * here.
+ */
+sh_css_err
+sh_css_capture_configure_viewfinder(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format);
+
+/* Specify the ISP parameter struct to be used for the capture mode. The
+ * same restrictions apply as for sh_css_preview_set_isp_parameters.
+ */
+sh_css_err
+sh_css_capture_set_isp_parameters(struct sh_css_params *params);
+
+/* Set the input mode to be used for the capture mode.
+ * When this is set to sh_css_input_mode_memory, the primary/advanced
+ * mode will be run in offline mode. This means that the copy binary runs
+ * first to write the frame from sensor into DDR.
+ */
+sh_css_err
+sh_css_capture_set_input_mode(enum sh_css_input_mode mode);
+
+/* Enable or disable online binaries if available. Default is enabled. */
+sh_css_err
+sh_css_capture_enable_online(ShBool enable);
+
+/* Retrieve the format and resolution of the output frames. Note that this
+ * can differ from the requested resolution.
+ */
+sh_css_err
+sh_css_capture_get_output_frame_info(struct sh_css_frame_info *info);
+
+/* Retrieve the format and resolution of the viewfinder frames. Note that this
+ * can differ from the requested resolution.
+ */
+sh_css_err
+sh_css_capture_get_viewfinder_frame_info(struct sh_css_frame_info *info);
+
+sh_css_err
+sh_css_capture_get_grid_info(struct sh_css_grid_info *info);
+
+/* ===== VIDEO ===== */
+
+/* Start the video ISP for one frame:
+ * - in_frame: pointer to the input frame, this argument is only used if the
+ * input_mode is set to sh_css_input_mode_memory.
+ * - out_frame: pointer to the output frame.
+ * - vf_frame: pointer to the viewfinder output frame.
+ */
+sh_css_err
+sh_css_video_start(struct sh_css_frame *in_frame,
+ struct sh_css_frame *out_frame,
+ struct sh_css_frame *vf_frame);
+
+/* Specify the output resolution for output frames. Note that the actual
+ * resolution can be different from the requested resolution.
+ */
+sh_css_err
+sh_css_video_configure_output(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format);
+
+/* Specify the viewfinder resolution. Note that this resolution currently has
+ * to be a division of the captured output by a power of 2. The API will
+ * automatically select the resolution that's closest to the one requested
+ * here.
+ */
+sh_css_err
+sh_css_video_configure_viewfinder(unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format);
+
+/* Specify the ISP parameter struct to be used for the capture mode.
+ * The same restrictions apply as for sh_css_preview_set_isp_parameters.
+ */
+sh_css_err
+sh_css_video_set_isp_parameters(struct sh_css_params *params);
+
+/* Set the input mode to be used for the capture mode. */
+sh_css_err
+sh_css_video_set_input_mode(enum sh_css_input_mode mode);
+
+/* Set the motion vector for Digital Image Stabilization (DIS).
+ * These positions are normally calculated using the DIS statistics.
+ */
+sh_css_err
+sh_css_video_set_dis_vector(unsigned int x, unsigned int y);
+
+/* Specify the envelope to be used for DIS. */
+sh_css_err
+sh_css_video_set_dis_envelope(unsigned int width, unsigned int height);
+
+/* Retrieve the envelope to be used for DIS. */
+sh_css_err
+sh_css_video_get_dis_envelope(unsigned int *width, unsigned int *height);
+
+/* Retrieve the format and resolution of the output frames. Note that this
+ * can differ from the requested resolution.
+ */
+sh_css_err
+sh_css_video_get_output_frame_info(struct sh_css_frame_info *info);
+
+/* Retrieve the format and resolution of the viewfinder frames. Note that this
+ * can differ from the requested resolution.
+ */
+sh_css_err
+sh_css_video_get_viewfinder_frame_info(struct sh_css_frame_info *info);
+
+sh_css_err
+sh_css_video_get_grid_info(struct sh_css_grid_info *info);
+
+/* ===== OTHER ===== */
+
+/* These functions are part of the API mostly for demo purposes, they are not
+ * meant to be used in product applications. */
+
+/* Offline overlaying. This overlays the input_frame with the overlay
+ * and writes the output into the output_frame. The overlay_start_x and
+ * overlay_start_y determine the coordinate of where to start the overlaying.
+ * This allows for overlays that are smaller than the input frame which
+ * reduces memory consumption, especially when a library of overlay
+ * images is used.
+ */
+sh_css_err
+sh_css_overlay_frame(const struct sh_css_overlay *overlay,
+ struct sh_css_frame *input_frame,
+ struct sh_css_frame *output_frame,
+ unsigned int overlay_start_x,
+ unsigned int overlay_start_y);
+
+/* Run the XNR mode offline on a frame.
+ * This is the same XNR as can be enabled in the capture mode, we provide this
+ * function mostly for demonstration reasons.
+ */
+sh_css_err
+sh_css_xnr_start(struct sh_css_frame *in_frame, struct sh_css_frame *out_frame);
+
+/* Copy a frame. This function is currently mostly used for FPGA platforms
+ * where the connection between the host and DDR is very slow.
+ * This function is executed on the SP, using the DMA.
+ */
+sh_css_err
+sh_css_copy_frame(const struct sh_css_frame *in_frame,
+ struct sh_css_frame *out_frame);
+
+/* Generate a luminance histogram from a frame. The width of the frame
+ * cannot exceed 640 pixels and the frame must be a yuv420 frame.
+ */
+sh_css_err
+sh_css_get_y_histogram(const struct sh_css_frame *input_frame,
+ struct sh_css_histogram *histogram);
+
+/* Send streaming data into the css input FIFO. This is for testing purposes
+ * only. This uses the channel ID and input format as set by the user with
+ * the regular functions for this.
+ * This function blocks until the entire frame has been written into the
+ * input FIFO.
+ */
+sh_css_err
+sh_css_send_input_frame(unsigned short *data,
+ unsigned int width,
+ unsigned int height);
+
+struct sh_css_frame *sh_css_get_raw_frame(void);
+
+sh_css_err sh_css_convert_raw_frame(struct sh_css_frame *frame,
+ __u32 width, __u32 height);
+
+sh_css_err
+sh_css_capture_get_output_raw_frame_info(struct sh_css_frame_info *info);
+#endif /* _SHCSS_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_binary.c b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_binary.c
new file mode 100644
index 0000000..89388bd
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_binary.c
@@ -0,0 +1,407 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "sh_css_binary.h"
+#include "sh_css.h"
+#include "sh_css_internal.h"
+#include "sh_css_hrt.h"
+#include "sh_css_uds.h"
+#include "sh_css_sp.h"
+
+#include "isp/modes/vf_pp/vf_pp.host.h"
+#ifndef SYSTEM_isp_css_dev_tb
+#include "isp/modes/primary/16mp/primary_16mp.host.h"
+#endif
+#ifndef SYSTEM_hive_isp_css_2400_system
+#ifndef SYSTEM_isp_css_dev_tb
+#include "isp/modes/primary/14mp/primary_14mp.host.h"
+#endif
+#include "isp/modes/copy/var/copy_var.host.h"
+#include "isp/modes/primary/small/primary_small.host.h"
+#include "isp/modes/primary/var/primary_var.host.h"
+#include "isp/modes/primary/ds/primary_ds.host.h"
+#include "isp/modes/preview/var/preview_var.host.h"
+#include "isp/modes/preview/ds/preview_ds.host.h"
+#include "isp/modes/video/offline/video_offline.host.h"
+#include "isp/modes/video/online_nodz/video_online_nodz.host.h"
+#include "isp/modes/video/online/video_online.host.h"
+#include "isp/modes/video/online_ds/video_online_ds.host.h"
+#include "isp/modes/pregdc/var/pregdc_var.host.h"
+#include "isp/modes/gdc/var/gdc_var.host.h"
+#include "isp/modes/postgdc/var/postgdc_var.host.h"
+#include "isp/modes/xnr/var/xnr_var.host.h"
+#include "isp/modes/bayer_ds/var/bayer_ds_var.host.h"
+#endif
+
+#define FIXED_OUTPUT_FORMAT sh_css_frame_format_yuv420
+
+static struct sh_css_binary *all_binaries[sh_css_binary_num_modes],
+ *active_binary = NULL;
+
+#define ADD_BINARY_INFO(binary_name) \
+ return_on_error(add_binary(&binary_name##_binary_info))
+
+static sh_css_err
+add_binary(struct sh_css_binary *binary)
+{
+ binary->xmem_addr = binary->load();
+ if (binary->xmem_addr == NULL)
+ return sh_css_err_cannot_allocate_memory;
+ /* Prepend new binary information */
+ binary->next = all_binaries[binary->mode];
+ all_binaries[binary->mode] = binary;
+ return sh_css_success;
+}
+
+void
+sh_css_binary_print(const struct sh_css_binary *bi)
+{
+ sh_css_print("id = %d\n", bi->id);
+ sh_css_print("mode = %d\n", bi->mode);
+ sh_css_print("variable_width = %d\n", bi->variable_width);
+ sh_css_print("variable_output_format = %d\n",
+ bi->variable_output_format);
+ sh_css_print("can_scale = %d\n", bi->can_scale);
+ sh_css_print("in_max_width = %d\n", bi->in_max_width);
+ sh_css_print
+ ("out_min_width = %d, out_max_width = %d, out_step_width = %d\n",
+ bi->out_min_width, bi->out_max_width, bi->out_step_width);
+ sh_css_print("filter_rows = %d, filter_columns = %d\n", bi->filter_rows,
+ bi->filter_columns);
+ sh_css_print("input: %dx%d, format = %d, padded width = %d\n",
+ bi->in_frame_info.width, bi->in_frame_info.height,
+ bi->in_frame_info.format, bi->in_frame_info.padded_width);
+ sh_css_print("int out:%dx%d, format = %d, padded width = %d\n",
+ bi->int_out_frame_info.width,
+ bi->int_out_frame_info.height,
+ bi->int_out_frame_info.format,
+ bi->int_out_frame_info.padded_width);
+ sh_css_print("out: %dx%d, format = %d, padded width = %d\n",
+ bi->out_frame_info.width, bi->out_frame_info.height,
+ bi->out_frame_info.format,
+ bi->out_frame_info.padded_width);
+ sh_css_print("vf out: %dx%d, format = %d, padded width = %d\n",
+ bi->vf_frame_info.width, bi->vf_frame_info.height,
+ bi->vf_frame_info.format, bi->vf_frame_info.padded_width);
+ sh_css_print("variable_input = %d\n", bi->variable_input);
+ sh_css_print("use_dma_proxy = %d\n", bi->use_dma_proxy);
+ sh_css_print("online = %d\n", bi->online);
+ sh_css_print("dirty = %d\n", bi->dirty);
+ sh_css_print("input_buf_vectors = %d\n", bi->input_buf_vectors);
+ sh_css_print("deci_factor_log2 = %d\n", bi->deci_factor_log2);
+ sh_css_print("vf_downscale_log2 = %d\n", bi->vf_downscale_log2);
+ sh_css_print("dis_deci_factor_log2 = %d\n", bi->dis_deci_factor_log2);
+ sh_css_print("dis_horicoef_num = %d, dis_vertcoef_num = %d\n",
+ bi->dis_horicoef_num, bi->dis_vertcoef_num);
+ sh_css_print("dis_horiproj_num = %d, dis_vertproj_num = %d\n",
+ bi->dis_horiproj_num, bi->dis_vertproj_num);
+ sh_css_print("sctbl_width_per_color = %d\n", bi->sctbl_width_per_color);
+ sh_css_print("s3atbl_width = %d\n", bi->s3atbl_width);
+ sh_css_print("s3atbl_height = %d\n", bi->s3atbl_height);
+ sh_css_print("s3atbl_use_dmem = %d\n", bi->s3atbl_use_dmem);
+ sh_css_print("xmem_addr = %p\n", bi->xmem_addr);
+ sh_css_print("enable_yee = %d\n", bi->enable_yee);
+ sh_css_print("enable_sc = %d\n", bi->enable_sc);
+ sh_css_print("enable_s3a = %d\n", bi->enable_s3a);
+ sh_css_print("enable_vf_veceven = %d\n", bi->enable_vf_veceven);
+ sh_css_print("enable_tnr = %d\n", bi->enable_tnr);
+ sh_css_print("enable_macc = %d\n", bi->enable_macc);
+ sh_css_print("enable_dis = %d\n", bi->enable_dis);
+ sh_css_print("enable_uds = %d\n", bi->enable_uds);
+ sh_css_print("enable_fpnr = %d\n", bi->enable_fpnr);
+}
+
+sh_css_err
+sh_css_binary_set_active(struct sh_css_binary *binary,
+ struct sh_css_binary_args *args,
+ struct sh_css_params *params)
+{
+ void *xmem_map_addr = sh_css_params_ddr_address_map();
+
+ if (binary == active_binary && binary->dirty == ShFalse)
+ return sh_css_success;
+ binary->params = params;
+
+ if (params) {
+ return_on_error(sh_css_params_set_current_binary(binary));
+ /* we need to write the params to DDR here because they are
+ * used when the binary is initialized.
+ */
+ return_on_error(sh_css_params_write_to_ddr(params, binary));
+ }
+
+ /* Upload the binary to the ISP and communicate pointers in address
+ * map to ISP.
+ */
+ return_on_error(sh_css_sp_init_binary(binary, xmem_map_addr));
+ sh_css_sp_set_dvs_cropping(binary, args);
+ sh_css_sp_init_isp(binary->id);
+ sh_css_hrt_isp_wait();
+ sh_css_hrt_sp_wait();
+ if (binary->enable_uds || binary->can_scale)
+ return_on_error(sh_css_uds_init(binary->in_frame_info.width,
+ binary->in_frame_info.height,
+ binary->in_frame_info.width / 2,
+ binary->in_frame_info.height /
+ 2,
+ binary->int_out_frame_info.
+ width,
+ binary->int_out_frame_info.
+ height,
+ binary->int_out_frame_info.
+ width / 2,
+ binary->int_out_frame_info.
+ height / 2,
+ binary->uds_config.use_bci));
+ binary->dirty = ShFalse;
+ active_binary = binary;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_binary_grid_info(struct sh_css_binary *binary,
+ struct sh_css_grid_info *info)
+{
+ /* for DIS, we use a division instead of a ceil_div. If this is smaller
+ * than the 3a grid size, it indicates that the outer values are not
+ * valid for DIS.
+ */
+ info->width_dis = binary->int_out_frame_info.padded_width >>
+ (binary->dis_deci_factor_log2 + 1);
+ info->height_dis = binary->int_out_frame_info.height >>
+ (binary->dis_deci_factor_log2 + 1);
+ info->bqs_per_grid_cell_dis = 1 << binary->dis_deci_factor_log2;
+ info->width_3a = binary->s3atbl_width;
+ info->height_3a = binary->s3atbl_height;
+ info->bqs_per_grid_cell_3a = (1 << binary->deci_factor_log2);
+ info->dis_horicoef_num = sizeof(short) *SDIS_COEF_TYPES *
+ MAX_SDIS_HORICOEF_NUM;
+ info->dis_vertcoef_num = sizeof(short) *SDIS_COEF_TYPES *
+ MAX_SDIS_VERTCOEF_NUM;
+
+ return sh_css_success;
+}
+
+/* When binaries are put at the beginning, they will only
+ * be selected if no other primary matches.
+ */
+sh_css_err
+sh_css_binary_init(void)
+{
+#ifdef SYSTEM_hive_isp_css_2400_system
+ ADD_BINARY_INFO(isp_vf_pp);
+ ADD_BINARY_INFO(isp_primary_16mp);
+#else
+ ADD_BINARY_INFO(isp_primary_ds);
+#ifndef SYSTEM_isp_css_dev_tb
+ /* these 3 binaries are not available on the FPGA system */
+ ADD_BINARY_INFO(isp_primary_var);
+ ADD_BINARY_INFO(isp_primary_14mp);
+ ADD_BINARY_INFO(isp_primary_16mp);
+#endif
+ ADD_BINARY_INFO(isp_primary_small);
+ ADD_BINARY_INFO(isp_vf_pp);
+ ADD_BINARY_INFO(isp_copy_var);
+ ADD_BINARY_INFO(isp_preview_ds);
+ ADD_BINARY_INFO(isp_preview_var);
+ ADD_BINARY_INFO(isp_video_offline);
+ ADD_BINARY_INFO(isp_video_online_ds);
+ ADD_BINARY_INFO(isp_video_online);
+ ADD_BINARY_INFO(isp_video_online_nodz);
+ ADD_BINARY_INFO(isp_pregdc_var);
+ ADD_BINARY_INFO(isp_gdc_var);
+ ADD_BINARY_INFO(isp_postgdc_var);
+ ADD_BINARY_INFO(isp_xnr_var);
+ ADD_BINARY_INFO(isp_bayer_ds_var);
+#endif
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_binary_uninit(void)
+{
+ unsigned int i;
+ struct sh_css_binary *b;
+
+ for (i = 0; i < sh_css_binary_num_modes; i++) {
+ for (b = all_binaries[i]; b; b = b->next) {
+ if (b->xmem_addr)
+ hrt_isp_css_mm_free(b->xmem_addr);
+ b->xmem_addr = NULL;
+ }
+ all_binaries[i] = NULL;
+ }
+ return sh_css_success;
+}
+
+static sh_css_err
+find_binary(enum sh_css_binary_mode mode,
+ ShBool online,
+ ShBool two_ppc,
+ enum sh_css_input_format stream_format,
+ const struct sh_css_frame_info *req_in_info,
+ const struct sh_css_frame_info *req_out_info,
+ const struct sh_css_frame_info *req_vf_info,
+ struct sh_css_binary **binary,
+ unsigned int *padded_width,
+ unsigned int *filter_columns,
+ unsigned int extra_lines)
+{
+ struct sh_css_binary *candidate;
+ unsigned int dvs_envelope_width = 0, dvs_envelope_height = 0;
+
+ return_on_error(sh_css_video_get_dis_envelope(&dvs_envelope_width,
+ &dvs_envelope_height));
+
+ for (candidate = all_binaries[mode]; candidate;
+ candidate = candidate->next) {
+ unsigned f_columns = filter_columns ? *filter_columns : 0;
+ unsigned int out_padded_width, in_padded_width, left_padding =
+ 0;
+ ShBool need_scaling = ShFalse;
+ struct sh_css_frame_info out_info = *req_out_info,
+ in_info = *req_in_info;
+
+ if (!candidate->enable_dis_crop ||
+ (dvs_envelope_width == 0 && dvs_envelope_height == 0)) {
+ need_scaling =
+ !sh_css_frame_info_equal_resolution(&in_info,
+ &out_info);
+ in_info.height += extra_lines;
+ if (candidate->filter_rows)
+ out_info.height -=
+ candidate->filter_rows - extra_lines;
+ else
+ out_info.height += extra_lines;
+ }
+
+ if (filter_columns)
+ f_columns = MAX(candidate->filter_columns, f_columns);
+ if (candidate->filter_columns)
+ left_padding = ISP_NWAY - candidate->filter_columns;
+
+ /* if the candidate generates a viewfinder image, it must be
+ * specified.
+ */
+ if (candidate->enable_vf_veceven && !req_vf_info)
+ continue;
+ if (!candidate->can_scale && need_scaling)
+ continue;
+ if (!candidate->variable_input && candidate->online != online)
+ continue;
+ if (mode == sh_css_binary_mode_gdc) {
+ /* otherwise advanced 1080p breaks since 1920 is not a
+ * multiple of the step size. TODO: fix advanced to
+ * work with 2048 pixels width.
+ */
+ out_padded_width =
+ CEIL_MUL(out_info.width + left_padding,
+ 2 * ISP_VEC_NELEMS);
+ } else {
+ out_padded_width =
+ CEIL_MUL(out_info.width + left_padding,
+ candidate->out_step_width);
+ }
+ in_padded_width =
+ CEIL_MUL(in_info.width + left_padding, 2 * ISP_VEC_NELEMS);
+ if (candidate->variable_width) {
+ if (out_padded_width < candidate->out_min_width ||
+ out_padded_width > candidate->out_max_width)
+ continue;
+ } else {
+ if (candidate->in_frame_info.padded_width !=
+ in_padded_width
+ || candidate->out_frame_info.padded_width !=
+ out_padded_width)
+ continue;
+ }
+ if (!candidate->variable_output_format) {
+ enum sh_css_frame_format out_format;
+ return_on_error(sh_css_isp_to_host_format(
+ candidate->isp_output_format,
+ &out_format));
+ if (req_out_info->format != out_format)
+ continue;
+ }
+
+ /* reconfigure any variable properties of the binary */
+ if (binary) {
+ return_on_error(
+ candidate->fill_binary_info(candidate,
+ online,
+ two_ppc,
+ stream_format,
+ &in_info,
+ &out_info,
+ req_vf_info));
+ *binary = candidate;
+ } else if (padded_width) {
+ *padded_width = out_padded_width;
+ } else {
+ *filter_columns = f_columns;
+ candidate->filter_columns = f_columns;
+ }
+ return sh_css_success;
+ }
+ return sh_css_err_internal_error;
+}
+
+sh_css_err
+sh_css_binary_find(struct sh_css_binary_descr *descr,
+ struct sh_css_binary **binary)
+{
+ return find_binary(descr->mode, descr->online, descr->two_ppc,
+ descr->stream_format,
+ descr->in_info, descr->out_info, descr->vf_info,
+ binary, NULL, NULL, descr->extra_lines);
+}
+
+sh_css_err
+sh_css_binary_padded_width(struct sh_css_binary_descr *descr,
+ unsigned int *padded_width)
+{
+ unsigned int p_width = 0;
+
+ return_on_error(find_binary(descr->mode, descr->online, descr->two_ppc,
+ descr->stream_format,
+ descr->in_info, descr->out_info,
+ descr->vf_info, NULL, &p_width, NULL,
+ descr->extra_lines));
+ *padded_width = MAX(p_width, *padded_width);
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_binary_filter_columns(struct sh_css_binary_descr *descr,
+ unsigned int *filter_columns)
+{
+ unsigned int f_columns = *filter_columns;
+
+ return_on_error(find_binary
+ (descr->mode, descr->online, descr->stream_format,
+ descr->two_ppc, descr->in_info, descr->out_info,
+ descr->vf_info, NULL, NULL, &f_columns,
+ descr->extra_lines));
+ *filter_columns = MAX(f_columns, *filter_columns);
+ return sh_css_success;
+}
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_binary.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_binary.h
new file mode 100644
index 0000000..1717aaf
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_binary.h
@@ -0,0 +1,177 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SHCSS_BINARY_H_
+#define _SHCSS_BINARY_H_
+
+enum sh_css_binary_mode {
+ sh_css_binary_mode_copy,
+ sh_css_binary_mode_preview,
+ sh_css_binary_mode_primary,
+ sh_css_binary_mode_video,
+ sh_css_binary_mode_video_nodz,
+ sh_css_binary_mode_pre_gdc,
+ sh_css_binary_mode_gdc,
+ sh_css_binary_mode_post_gdc,
+ sh_css_binary_mode_xnr,
+ sh_css_binary_mode_bayer_ds,
+ sh_css_binary_mode_vf_pp,
+ sh_css_binary_num_modes /* this one must be the last in the enum */
+};
+
+struct sh_css_binary;
+
+#include <hmm/hmm.h>
+
+#include "sh_css.h"
+#include "sh_css_uds.h"
+#include "sh_css_internal.h"
+
+struct sh_css_binary_descr {
+ enum sh_css_binary_mode mode;
+ ShBool online;
+ ShBool two_ppc;
+ enum sh_css_input_format stream_format;
+ struct sh_css_frame_info *in_info;
+ struct sh_css_frame_info *out_info;
+ struct sh_css_frame_info *vf_info;
+ unsigned int extra_lines; /* extra lines available */
+};
+
+/* this struct contains all arguments that can be passed to
+ a binary. It depends on the binary which ones are used. */
+struct sh_css_binary_args {
+ struct sh_css_frame *in_frame; /* input frame */
+ struct sh_css_frame *in_ref_frame; /* reference input frame */
+ struct sh_css_frame *out_frame; /* output frame */
+ struct sh_css_frame *out_ref_frame; /* reference output frame */
+ struct sh_css_frame *out_vf_frame; /* viewfinder output frame */
+ unsigned int dvs_crop_x; /* crop settings for DVS */
+ unsigned int dvs_crop_y;
+ unsigned int dvs_envelope_width;
+ unsigned int dvs_envelope_height;
+ /* output:indicates whether digital zoom is used. Depending on the
+ binary, this can mean that the reference output is in the output
+ frame. */
+ ShBool *dz_used;
+ ShBool enable_xnr;
+ const struct sh_css_overlay *vf_overlay;
+};
+
+struct sh_css_binary {
+ enum isp_binary_id id;
+ enum sh_css_binary_mode mode;
+ ShBool variable_width;
+ ShBool variable_output_format;
+ enum ShImageFormat isp_output_format;
+ ShBool can_scale;
+ /* Maximal horizontal resolution in pixels */
+ unsigned int in_max_width;
+ /* Minimal horizontal resolution in pixels */
+ unsigned int out_min_width;
+ /* Maximal horizontal resolution in pixels */
+ unsigned int out_max_width;
+ /* Horizontal resolution step size in pixels */
+ unsigned int out_step_width;
+ /* number of extra rows needed to initialize filters */
+ unsigned int filter_rows;
+ /* number of extra columns needed to initialize filters */
+ unsigned int filter_columns;
+ enum sh_css_input_format input_format;
+ struct sh_css_frame_info in_frame_info;
+ /* internal output frame with possibly 8 extra lines and columns */
+ struct sh_css_frame_info int_out_frame_info;
+ struct sh_css_frame_info out_frame_info;
+ struct sh_css_frame_info vf_frame_info;
+ int input_buf_vectors;
+ int deci_factor_log2;
+ int dis_deci_factor_log2;
+ int vf_downscale_log2;
+ int sctbl_width_per_color;
+ int s3atbl_use_dmem;
+ int s3atbl_width;
+ int s3atbl_height;
+ int dis_horicoef_num;
+ int dis_vertcoef_num;
+ int dis_horiproj_num;
+ int dis_vertproj_num;
+ int enable_yee;
+ int enable_sc;
+ int enable_s3a;
+ int enable_vf_veceven;
+ int enable_tnr;
+ int enable_macc;
+ int enable_dis;
+ int enable_dis_crop;
+ int enable_uds;
+ int enable_fpnr;
+ int variable_input;
+ int use_dma_proxy;
+ void *xmem_addr;
+ ShBool dirty;
+ sh_css_err(*fill_binary_info)(struct sh_css_binary *new_binary_info,
+ ShBool online,
+ ShBool two_ppc,
+ enum sh_css_input_format stream_format,
+ const struct sh_css_frame_info *in_info,
+ const struct sh_css_frame_info *out_info,
+ const struct sh_css_frame_info *vf_info);
+ void *(*load) (void);
+ struct sh_css_params *params;
+ ShBool online;
+ ShBool two_ppc;
+ struct sh_css_uds_config uds_config;
+ struct sh_css_binary *next;
+};
+
+sh_css_err
+sh_css_binary_init(void);
+
+sh_css_err
+sh_css_binary_uninit(void);
+
+void
+sh_css_binary_print(const struct sh_css_binary *binary);
+
+sh_css_err
+sh_css_binary_set_active(struct sh_css_binary *binary,
+ struct sh_css_binary_args *args,
+ struct sh_css_params *params);
+
+sh_css_err
+sh_css_binary_find(struct sh_css_binary_descr *descr,
+ struct sh_css_binary **binary);
+
+sh_css_err
+sh_css_binary_padded_width(struct sh_css_binary_descr *descr,
+ unsigned int *padded_width);
+
+sh_css_err
+sh_css_binary_filter_columns(struct sh_css_binary_descr *descr,
+ unsigned int *columns);
+
+sh_css_err
+sh_css_binary_grid_info(struct sh_css_binary *binary,
+ struct sh_css_grid_info *info);
+
+#endif /* _SHCSS_BINARY_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_debug.c b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_debug.c
new file mode 100644
index 0000000..941347d
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_debug.c
@@ -0,0 +1,513 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "sh_css_debug.h"
+#include "sh_css.h"
+#include "sh_css_hrt.h"
+#include "sh_css_internal.h"
+
+static void
+print_cell_state(struct sh_css_cell_state *state, const char *cell)
+{
+ sh_css_print("%s state:\n", cell);
+ sh_css_print(" PC: %x\n", state->pc);
+ sh_css_print(" Status register : %x\n", state->status_register);
+ sh_css_print(" is broken: %d\n", state->is_broken);
+ sh_css_print(" is idle: %d\n", state->is_idle);
+ sh_css_print(" is sleeping: %d\n", state->is_sleeping);
+ sh_css_print(" is stalling: %d\n", state->is_stalling);
+}
+
+void
+sh_css_dump_isp_state(void)
+{
+ struct sh_css_cell_state state;
+ struct sh_css_isp_stall_state stall_state;
+ sh_css_hrt_isp_get_state(&state, &stall_state);
+ print_cell_state(&state, "ISP");
+ printk(KERN_EMERG "dump begin...\n");
+ if (state.is_stalling) {
+ sh_css_print(" FIFO 0 stalled: %d\n", stall_state.fifo0);
+ sh_css_print(" FIFO 1 stalled: %d\n", stall_state.fifo1);
+ sh_css_print(" FIFO 2 stalled: %d\n", stall_state.fifo2);
+ sh_css_print(" FIFO 3 stalled: %d\n", stall_state.fifo3);
+ sh_css_print(" FIFO 4 stalled: %d\n", stall_state.fifo4);
+ sh_css_print(" FIFO 5 stalled: %d\n", stall_state.fifo5);
+ sh_css_print(" status & control stalled: %d\n",
+ stall_state.stat_ctrl);
+ sh_css_print(" dmem stalled: %d\n", stall_state.dmem);
+ sh_css_print(" vmem stalled: %d\n", stall_state.vmem);
+ sh_css_print(" vamem1 stalled: %d\n", stall_state.vamem1);
+ sh_css_print(" vamem2 stalled: %d\n", stall_state.vamem2);
+ }
+}
+
+void
+sh_css_dump_sp_state(void)
+{
+ struct sh_css_cell_state state;
+ struct sh_css_sp_stall_state stall_state;
+ sh_css_hrt_sp_get_state(&state, &stall_state);
+ print_cell_state(&state, "SP");
+ if (state.is_stalling) {
+ sh_css_print(" FIFO 0 stalled: %d\n", stall_state.fifo0);
+ sh_css_print(" FIFO 1 stalled: %d\n", stall_state.fifo1);
+ sh_css_print(" FIFO 2 stalled: %d\n", stall_state.fifo2);
+ sh_css_print(" FIFO 3 stalled: %d\n", stall_state.fifo3);
+ sh_css_print(" FIFO 4 stalled: %d\n", stall_state.fifo4);
+ sh_css_print(" FIFO 5 stalled: %d\n", stall_state.fifo5);
+ sh_css_print(" FIFO 6 stalled: %d\n", stall_state.fifo6);
+ sh_css_print(" FIFO 7 stalled: %d\n", stall_state.fifo7);
+ sh_css_print(" dmem stalled: %d\n", stall_state.dmem);
+ sh_css_print(" control master stalled: %d\n",
+ stall_state.control_master);
+ sh_css_print(" i-cache master stalled: %d\n",
+ stall_state.icache_master);
+ }
+}
+
+static void
+print_if_state(struct sh_css_if_state *state)
+{
+ unsigned int val;
+ sh_css_print("InputFormatter State:\n");
+ sh_css_print(" Configuration:\n");
+ sh_css_print(" Software reset: %s\n",
+ state->reset ? "Active" : "Not active");
+ sh_css_print(" Start line: %d\n", state->start_line);
+ sh_css_print(" Start column: %d\n",
+ state->start_column);
+ sh_css_print(" Cropped height: %d\n",
+ state->cropped_height);
+ sh_css_print(" Cropped width: %d\n",
+ state->cropped_width);
+ sh_css_print(" Vertical decimation: %d\n",
+ state->ver_decimation);
+ sh_css_print(" Horizontal decimation: %d\n",
+ state->hor_decimation);
+ sh_css_print(" Deinterleaving: %d\n",
+ state->deinterleaving);
+ sh_css_print(" Left padding: %d\n",
+ state->left_padding);
+ sh_css_print(" End-of-line offset (bytes): %d\n",
+ state->eol_offset);
+ sh_css_print(" VMEM start address: 0x%06X\n",
+ state->vmem_start_address);
+ sh_css_print(" VMEM end address: 0x%06X\n",
+ state->vmem_end_address);
+ sh_css_print(" VMEM increment: 0x%06X\n",
+ state->vmem_increment);
+ sh_css_print(" YUV 420 format: %d\n", state->yuv420);
+ sh_css_print(" Vsync: Active %s\n",
+ state->vsync_active_low ? "low" : "high");
+ sh_css_print(" Hsync: Active %s\n",
+ state->hsync_active_low ? "low" : "high");
+ sh_css_print(" Sensor stalling: %s\n",
+ state->allow_fifo_overflow ? "Allowed" : "Not allowed");
+ sh_css_print(" FSM Status\n");
+ val = state->fsm_sync_status;
+ sh_css_print(" FSM Synchronization Status 0x%X: ", val);
+ if (val > 7)
+ sh_css_print("ERROR : ");
+
+ switch (val & 0x7) {
+ case 0:
+ sh_css_print("idle\n");
+ break;
+ case 1:
+ sh_css_print("request frame\n");
+ break;
+ case 2:
+ sh_css_print("request lines\n");
+ break;
+ case 3:
+ sh_css_print("request vectors\n");
+ break;
+ case 4:
+ sh_css_print("send acknowledge\n");
+ break;
+ default:
+ sh_css_print("unknown\n");
+ break;
+ }
+ sh_css_print(" FSM Synchronization Counter %d\n",
+ state->fsm_sync_counter);
+ val = state->fsm_crop_status;
+ sh_css_print(" FSM Crop Status 0x%X: ",
+ val);
+ if (val > 7)
+ sh_css_print("ERROR : ");
+ switch (val & 0x7) {
+ case 0:
+ sh_css_print("idle\n");
+ break;
+ case 1:
+ sh_css_print("wait line\n");
+ break;
+ case 2:
+ sh_css_print("crop line\n");
+ break;
+ case 3:
+ sh_css_print("crop pixel\n");
+ break;
+ case 4:
+ sh_css_print("pass pixel\n");
+ break;
+ case 5:
+ sh_css_print("pass line\n");
+ break;
+ case 6:
+ sh_css_print("lost line\n");
+ break;
+ default:
+ sh_css_print("unknown\n");
+ break;
+ }
+
+ sh_css_print(" FSM Crop Line Counter %d\n",
+ state->fsm_crop_line_counter);
+ sh_css_print(" FSM Crop Pixel Counter %d\n",
+ state->fsm_crop_pixel_counter);
+ sh_css_print(" FSM Deinterleaving idx buffer %d\n",
+ state->fsm_deinterleaving_index);
+ sh_css_print(" FSM Decimation H decimation counter %d\n",
+ state->fsm_dec_h_counter);
+ sh_css_print(" FSM Decimation V decimation counter %d\n",
+ state->fsm_dec_v_counter);
+ sh_css_print(" FSM Decimation block V decimation counter %d\n",
+ state->fsm_dec_block_v_counter);
+
+ val = state->fsm_padding_status;
+ sh_css_print(" FSM Padding Status 0x%X: ", val);
+ if (val > 7)
+ sh_css_print("ERROR : ");
+
+ switch (val & 0x7) {
+ case 0:
+ sh_css_print("idle\n");
+ break;
+ case 1:
+ sh_css_print("left pad\n");
+ break;
+ case 2:
+ sh_css_print("write\n");
+ break;
+ case 3:
+ sh_css_print("right pad\n");
+ break;
+ case 4:
+ sh_css_print("send end of line\n");
+ break;
+ default:
+ sh_css_print("unknown\n");
+ break;
+ }
+ sh_css_print("FSM Padding element index counter %d\n",
+ state->fsm_padding_elem_counter);
+ sh_css_print("FSM Vector support error %d\n",
+ state->fsm_vector_support_error);
+ sh_css_print("FSM Vector support buf full %d\n",
+ state->fsm_vector_buffer_full);
+ sh_css_print("FSM Vector support %d\n",
+ state->vector_support);
+ sh_css_print("Fifo sensor data lost %d\n",
+ state->sensor_data_lost);
+}
+
+void
+sh_css_dump_if_state(void)
+{
+ struct sh_css_if_state state;
+ sh_css_hrt_if_prim_a_get_state(&state);
+ print_if_state(&state);
+ sh_css_dump_pif_isp_fifo_state();
+}
+
+void
+sh_css_dump_dma_state(void)
+{
+ struct sh_css_dma_state state;
+ int i, ch_id, num_ports = 3, num_channels = 8;
+
+ sh_css_hrt_dma_get_state(&state);
+ sh_css_print("DMA dump status:\n\t");
+ sh_css_print("FSM Command flag state:\n\t\t");
+ if (state.fsm_command_idle)
+ sh_css_print("IDLE\n\t\t");
+ if (state.fsm_command_run)
+ sh_css_print("RUN\n\t\t");
+ if (state.fsm_command_stalling)
+ sh_css_print("STALL\n\t\t");
+ if (state.fsm_command_error)
+ sh_css_print("ERROR\n\t\t");
+ ch_id = state.last_command_channel;
+ sh_css_print("last command received (0x%x) : ", state.last_command);
+ if (state.last_command == sh_css_dma_command_read)
+ sh_css_print(" Read 2D Block with settings from ch:%d", ch_id);
+ if (state.last_command == sh_css_dma_command_write)
+ sh_css_print(" Write 2D Block with settings from ch:%d", ch_id);
+ if (state.last_command == sh_css_dma_command_set_channel)
+ sh_css_print(" Set Channel:%d", ch_id);
+ if (state.last_command == sh_css_dma_command_set_param)
+ sh_css_print(" Set Param:%d on Channel:%d",
+ state.last_command_param, ch_id);
+ if (state.last_command == sh_css_dma_command_read_spec)
+ sh_css_print(" Read Specific 2D Block on ch:%d", ch_id);
+ if (state.last_command == sh_css_dma_command_write_spec)
+ sh_css_print(" Write Specific 2D Block on ch:%d", ch_id);
+ if (state.last_command == sh_css_dma_command_init)
+ sh_css_print(" Init 2D Block on Device A on ch:%d", ch_id);
+ if (state.last_command == sh_css_dma_command_init_spec)
+ sh_css_print(" Init Specific 2D Block on ch:%d", ch_id);
+ if (state.last_command == sh_css_dma_command_reset)
+ sh_css_print(" DMA SW Reset");
+ sh_css_print("\n\t");
+ sh_css_print("DMA registers, connection group 0\n\t");
+ sh_css_print("Cmd Fifo Command 0x%x\n\t\t", state.current_command);
+ sh_css_print("Cmd Fifo Address A 0x%x\n\t\t", state.current_addr_a);
+ sh_css_print("Cmd Fifo Address B 0x%x\n\t\t", state.current_addr_b);
+ sh_css_print("FSM Ctrl flag and state:\n\t\t\t");
+ if (state.fsm_ctrl_idle)
+ sh_css_print("IDLE -> ");
+ if (state.fsm_ctrl_run)
+ sh_css_print("RUN -> ");
+ if (state.fsm_ctrl_stalling)
+ sh_css_print("STALL -> ");
+ if (state.fsm_ctrl_error)
+ sh_css_print("ERROR -> ");
+ if (state.fsm_ctrl_state == sh_css_dma_ctrl_state_idle)
+ sh_css_print("Idle state\n\t\t");
+ if (state.fsm_ctrl_state == sh_css_dma_ctrl_state_req_rcv)
+ sh_css_print("Req Rcv state\n\t\t");
+ if (state.fsm_ctrl_state == sh_css_dma_ctrl_state_rcv)
+ sh_css_print("Rcv state\n\t\t");
+ if (state.fsm_ctrl_state == sh_css_dma_ctrl_state_rcv_req)
+ sh_css_print("Rcv Req state\n\t\t");
+ if (state.fsm_ctrl_state == sh_css_dma_ctrl_state_init)
+ sh_css_print("Init state\n\t\t");
+ sh_css_print("FSM Ctrl source dev : %d\n\t\t",
+ state.fsm_ctrl_source_dev);
+ sh_css_print("FSM Ctrl source addr : 0x%x\n\t\t",
+ state.fsm_ctrl_source_addr);
+ sh_css_print("FSM Ctrl source stride : 0x%x\n\t\t",
+ state.fsm_ctrl_source_stride);
+ sh_css_print("FSM Ctrl source width : %d\n\t\t",
+ state.fsm_ctrl_source_width);
+ sh_css_print("FSM Ctrl source height : %d\n\t\t",
+ state.fsm_ctrl_source_height);
+ sh_css_print("FSM Ctrl pack source dev : %d\n\t\t",
+ state.fsm_ctrl_pack_source_dev);
+ sh_css_print("FSM Ctrl pack dest dev : %d\n\t\t",
+ state.fsm_ctrl_pack_dest_dev);
+ sh_css_print("FSM Ctrl dest addr : 0x%x\n\t\t",
+ state.fsm_ctrl_dest_addr);
+ sh_css_print("FSM Ctrl dest stride : 0x%x\n\t\t",
+ state.fsm_ctrl_dest_stride);
+ sh_css_print("FSM Ctrl pack source width : %d\n\t\t",
+ state.fsm_ctrl_pack_source_width);
+ sh_css_print("FSM Ctrl pack dest height : %d\n\t\t",
+ state.fsm_ctrl_pack_dest_height);
+ sh_css_print("FSM Ctrl pack dest width : %d\n\t\t",
+ state.fsm_ctrl_pack_dest_width);
+ sh_css_print("FSM Ctrl pack source elems : %d\n\t\t",
+ state.fsm_ctrl_pack_source_elems);
+ sh_css_print("FSM Ctrl pack dest elems : %d\n\t\t",
+ state.fsm_ctrl_pack_dest_elems);
+ sh_css_print("FSM Ctrl pack extension : %d\n\t\t",
+ state.fsm_ctrl_pack_extension);
+ sh_css_print("FSM Pack flag state\t\t\t");
+ if (state.pack_idle)
+ sh_css_print("IDLE\t\t");
+ if (state.pack_run)
+ sh_css_print("RUN\t\t");
+ if (state.pack_stalling)
+ sh_css_print("STALL\t\t");
+ if (state.pack_error)
+ sh_css_print("ERROR\t\t");
+ sh_css_print("FSM Pack cnt height : %d\n\t\t",
+ state.pack_cnt_height);
+ sh_css_print("FSM Pack src cnt width : %d\n\t\t",
+ state.pack_src_cnt_width);
+ sh_css_print("FSM Pack dest cnt width : %d\n\t\t",
+ state.pack_dest_cnt_width);
+ sh_css_print("FSM Read state\n\t\t");
+ if (state.read_state == sh_css_dma_rw_state_idle)
+ sh_css_print("\tIdle state\n\t\t");
+ if (state.read_state == sh_css_dma_rw_state_req)
+ sh_css_print("\tReq state\n\t\t");
+ if (state.read_state == sh_css_dma_rw_state_next_line)
+ sh_css_print("\tNext line\n\t\t");
+ if (state.read_state == sh_css_dma_rw_state_unlock_channel)
+ sh_css_print("\tUnlock channel\n\t\t");
+ sh_css_print("FSM Read cnt height : %d\n\t\t",
+ state.read_cnt_height);
+ sh_css_print("FSM Read cnt width : %d\n\t\t",
+ state.read_cnt_width);
+ sh_css_print("FSM Write state\n\t\t\t");
+ if (state.write_state == sh_css_dma_rw_state_idle)
+ sh_css_print("\tIdle state\n\t\t");
+ if (state.write_state == sh_css_dma_rw_state_req)
+ sh_css_print("\tReq state\n\t\t");
+ if (state.write_state == sh_css_dma_rw_state_next_line)
+ sh_css_print("\tNext line\n\t\t");
+ if (state.write_state == sh_css_dma_rw_state_unlock_channel)
+ sh_css_print("\tUnlock channel\n\t\t");
+ sh_css_print("FSM Write height : %d\n\t\t",
+ state.write_height);
+ sh_css_print("FSM Write width : %d\n\t\t",
+ state.write_width);
+ sh_css_print("\n\t");
+ for (i = 0; i < num_ports; i++) {
+ sh_css_print("DMA device interface %d\n", i);
+ sh_css_print("\t\tDMA internal side state\n\t\t\t");
+ sh_css_print("CS: %d - We_n: %d - Run: %d - Ack: %d\n",
+ state.port_states[i].req_cs,
+ state.port_states[i].req_we_n,
+ state.port_states[i].req_run,
+ state.port_states[i].req_ack);
+ sh_css_print("\t\tMaster Output side state\n\t\t\t");
+ sh_css_print("CS: %d - We_n: %d - Run: s%d - Ack: %d\n",
+ state.port_states[i].send_cs,
+ state.port_states[i].send_we_n,
+ state.port_states[i].send_run,
+ state.port_states[i].send_ack);
+ sh_css_print("\t\tFifo state\n\t\t\t");
+ if (state.port_states[i].fifo_state ==
+ sh_css_dma_fifo_state_will_be_full) {
+ sh_css_print("FiFo will be full\n");
+ }
+ if (state.port_states[i].fifo_state ==
+ sh_css_dma_fifo_state_full) {
+ sh_css_print("Fifo Full\n");
+ }
+ if (state.port_states[i].fifo_state ==
+ sh_css_dma_fifo_state_empty) {
+ sh_css_print("Fifo Empty\n");
+ }
+ sh_css_print("\t\tFifo counter %d\n\t",
+ state.port_states[i].fifo_counter);
+ }
+ sh_css_print("\n\t");
+ for (i = 0; i < num_channels; i++) {
+ struct sh_css_dma_channel_state *ch;
+ ch = &(state.channel_states[i]);
+ sh_css_print("DMA channel register %d\n\t\t", i);
+ sh_css_print("Connection : %d\n\t\t", ch->connection);
+ sh_css_print("Sign extend: : %d\n\t\t", ch->sign_extend);
+ sh_css_print("Reverse elems : %d\n\t\t",
+ ch->reverse_elem_order);
+ sh_css_print("Stride Dev A : 0x%x\n\t\t", ch->stride_a);
+ sh_css_print("Elems Dev A : %d\n\t\t", ch->elems_a);
+ sh_css_print("Cropping Dev A : %d\n\t\t", ch->cropping_a);
+ sh_css_print("Width Dev A : %d\n\t\t", ch->width_a);
+ sh_css_print("Stride Dev B : 0x%x\n\t\t", ch->stride_b);
+ sh_css_print("Elems Dev B : %d\n\t\t", ch->elems_b);
+ sh_css_print("Cropping Dev B : %d\n\t\t", ch->cropping_b);
+ sh_css_print("Width Dev B : %d\n\t\t", ch->width_b);
+ sh_css_print("Height : %d\n\t", ch->height);
+ }
+ sh_css_print("\n");
+}
+
+static void
+print_fifo_channel_state(struct sh_css_fifo_channel_state *state,
+ const char *descr)
+{
+ sh_css_print("FIFO channel: %s\n", descr);
+ sh_css_print(" source valid: %d\n", state->src_valid);
+ sh_css_print(" fifo accept: %d\n", state->fifo_accept);
+ sh_css_print(" fifo valid: %d\n", state->fifo_valid);
+ sh_css_print(" sink accept: %d\n", state->sink_accept);
+}
+
+void
+sh_css_dump_pif_isp_fifo_state(void)
+{
+ struct sh_css_fifo_channel_state pif_to_isp,
+ isp_to_pif;
+ sh_css_hrt_fifo_channel_get_state(sh_css_hrt_fifo_isp_to_if_prim_a,
+ &isp_to_pif);
+ sh_css_hrt_fifo_channel_get_state(sh_css_hrt_fifo_if_prim_a_to_isp,
+ &pif_to_isp);
+ print_fifo_channel_state(&pif_to_isp, "Primary IF A to ISP");
+ print_fifo_channel_state(&isp_to_pif, "ISP to Primary IF A)");
+}
+
+void
+sh_css_dump_dma_sp_fifo_state(void)
+{
+ struct sh_css_fifo_channel_state dma_to_sp,
+ sp_to_dma;
+ sh_css_hrt_fifo_channel_get_state(sh_css_hrt_fifo_dma_to_sp,
+ &dma_to_sp);
+ sh_css_hrt_fifo_channel_get_state(sh_css_hrt_fifo_sp_to_dma,
+ &sp_to_dma);
+ print_fifo_channel_state(&dma_to_sp, "DMA to SP");
+ print_fifo_channel_state(&sp_to_dma, "SP to DMA");
+}
+
+void
+sh_css_dump_dma_isp_fifo_state(void)
+{
+ struct sh_css_fifo_channel_state dma_to_isp,
+ isp_to_dma;
+ sh_css_hrt_fifo_channel_get_state(sh_css_hrt_fifo_dma_to_isp,
+ &dma_to_isp);
+ sh_css_hrt_fifo_channel_get_state(sh_css_hrt_fifo_isp_to_dma,
+ &isp_to_dma);
+ print_fifo_channel_state(&dma_to_isp, "DMA to ISP");
+ print_fifo_channel_state(&isp_to_dma, "ISP to DMA");
+}
+
+void
+sh_css_dump_isp_sp_fifo_state(void)
+{
+ struct sh_css_fifo_channel_state sp_to_isp,
+ isp_to_sp;
+ sh_css_hrt_fifo_channel_get_state(sh_css_hrt_fifo_sp_to_isp,
+ &sp_to_isp);
+ sh_css_hrt_fifo_channel_get_state(sh_css_hrt_fifo_isp_to_sp,
+ &isp_to_sp);
+ print_fifo_channel_state(&sp_to_isp, "SP to ISP");
+ print_fifo_channel_state(&isp_to_sp, "ISP to SP");
+}
+
+void
+sh_css_dump_debug_info(void)
+{
+ sh_css_dump_if_state();
+ sh_css_dump_isp_state();
+ sh_css_dump_isp_sp_fifo_state();
+ sh_css_dump_sp_state();
+ sh_css_dump_dma_isp_fifo_state();
+ sh_css_dump_dma_sp_fifo_state();
+ sh_css_dump_dma_state();
+}
+
+sh_css_err
+sh_css_check_system_idle(void)
+{
+ if (!sh_css_hrt_system_is_idle())
+ return sh_css_err_system_not_idle;
+ return sh_css_success;
+}
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_debug.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_debug.h
new file mode 100644
index 0000000..4824b84
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_debug.h
@@ -0,0 +1,41 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SHCSS_DEBUG_H_
+#define _SHCSS_DEBUG_H_
+
+#include "sh_css.h"
+
+void sh_css_dump_if_state(void);
+void sh_css_dump_isp_state(void);
+void sh_css_dump_sp_state(void);
+void sh_css_dump_dma_state(void);
+void sh_css_dump_debug_info(void);
+void sh_css_dump_dma_isp_fifo_state(void);
+void sh_css_dump_dma_sp_fifo_state(void);
+void sh_css_dump_pif_isp_fifo_state(void);
+void sh_css_dump_isp_sp_fifo_state(void);
+
+sh_css_err sh_css_check_system_idle(void);
+
+#endif /* _SHCSS_DEBUG_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_frame.c b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_frame.c
new file mode 100644
index 0000000..0b75953
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_frame.c
@@ -0,0 +1,465 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "sh_css_frame.h"
+#include "sh_css_internal.h"
+#include "sh_css_hrt.h"
+#include "sh_css.h"
+
+#ifdef HRT_CSIM
+/* The outer border (right and bottom) of the ISP output does not
+ * get written. To avoid warnings in CSIM, we set it to all zeroes here.
+ */
+static void
+zero_border(struct sh_css_frame_plane *plane)
+{
+ unsigned int num_lines = MIN(16, plane->height),
+ start_line = plane->height - num_lines,
+ stride = plane->stride, bytes = num_lines * stride, i;
+ void *ptr = plane->data + start_line * stride;
+
+ for (i = 0; i < (bytes / sizeof(int)); i++, ptr += sizeof(int))
+ hrt_isp_css_mm_store_int(ptr, 0);
+}
+#endif
+
+static sh_css_err
+allocate_frame_data(struct sh_css_frame *frame, unsigned int bytes)
+{
+#ifdef SYSTEM_isp_css_dev_tb
+ if (frame->contiguous)
+ frame->data = hrt_isp_css_mm_alloc_contiguous(bytes);
+ else
+ frame->data = hrt_isp_css_mm_alloc(bytes);
+#else
+ frame->data = hrt_isp_css_mm_alloc(bytes);
+#endif
+ if (frame->data == NULL)
+ return sh_css_err_cannot_allocate_memory;
+ frame->data_bytes = bytes;
+ return sh_css_success;
+}
+
+static void
+init_plane(struct sh_css_frame_plane *plane,
+ unsigned int width,
+ unsigned int stride,
+ unsigned int height,
+ void *data)
+{
+ plane->height = height;
+ plane->width = width;
+ plane->stride = stride;
+ plane->data = data;
+#ifdef HRT_CSIM
+ zero_border(plane);
+#endif
+}
+
+static sh_css_err
+allocate_single_plane(struct sh_css_frame *frame,
+ struct sh_css_frame_plane *plane,
+ unsigned int subpixels_per_line,
+ unsigned int bits_per_pixel)
+{
+ unsigned int stride, height = frame->info.height;
+
+ stride = hrt_isp_css_stride_of_image_in_ddr(subpixels_per_line,
+ bits_per_pixel);
+ return_on_error(allocate_frame_data(frame, stride * height));
+ init_plane(plane, subpixels_per_line, stride, height, frame->data);
+ return sh_css_success;
+}
+
+static sh_css_err
+allocate_nv_planes(struct sh_css_frame *frame,
+ unsigned int horizontal_decimation,
+ unsigned int vertical_decimation)
+{
+ unsigned int y_width = frame->info.padded_width,
+ y_height = frame->info.height,
+ uv_width = 2 * (y_width / horizontal_decimation),
+ uv_height = y_height / vertical_decimation,
+ y_stride, y_bytes, uv_bytes, uv_stride;
+
+ y_stride = hrt_isp_css_stride_of_image_in_ddr(y_width, 8);
+ uv_stride = hrt_isp_css_stride_of_image_in_ddr(uv_width, 8);
+ y_bytes = y_stride * y_height;
+ uv_bytes = uv_stride * uv_height;
+ return_on_error(allocate_frame_data(frame, y_bytes + uv_bytes));
+ init_plane(&frame->planes.nv.Y, y_width, y_stride,
+ y_height, frame->data);
+ init_plane(&frame->planes.nv.UV, uv_width, uv_stride,
+ uv_height, frame->data + y_bytes);
+ return sh_css_success;
+}
+
+static sh_css_err
+allocate_yuv_planes(struct sh_css_frame *frame,
+ unsigned int horizontal_decimation,
+ unsigned int vertical_decimation,
+ ShBool swap_uv,
+ unsigned int bits_per_element)
+{
+ unsigned int y_width = frame->info.padded_width,
+ y_height = frame->info.height,
+ uv_width = y_width / horizontal_decimation,
+ uv_height = y_height / vertical_decimation,
+ y_stride, y_bytes, uv_bytes, uv_stride;
+
+ y_stride =
+ hrt_isp_css_stride_of_image_in_ddr(y_width, bits_per_element);
+ uv_stride =
+ hrt_isp_css_stride_of_image_in_ddr(uv_width, bits_per_element);
+ y_bytes = y_stride * y_height;
+ uv_bytes = uv_stride * uv_height;
+ return_on_error(allocate_frame_data(frame, y_bytes + 2 * uv_bytes));
+ init_plane(&frame->planes.yuv.Y, y_width, y_stride, y_height,
+ frame->data);
+ if (swap_uv) {
+ init_plane(&frame->planes.yuv.V, uv_width, uv_stride,
+ uv_height, frame->data + y_bytes);
+ init_plane(&frame->planes.yuv.U, uv_width, uv_stride,
+ uv_height, frame->data + y_bytes + uv_bytes);
+ } else {
+ init_plane(&frame->planes.yuv.U, uv_width, uv_stride,
+ uv_height, frame->data + y_bytes);
+ init_plane(&frame->planes.yuv.V, uv_width, uv_stride,
+ uv_height, frame->data + y_bytes + uv_bytes);
+ }
+ return sh_css_success;
+}
+
+static sh_css_err
+allocate_rgb_planes(struct sh_css_frame *frame, unsigned int bits_per_element)
+{
+ unsigned int width = frame->info.width,
+ height = frame->info.height, stride, bytes;
+
+ stride = hrt_isp_css_stride_of_image_in_ddr(width, bits_per_element);
+ bytes = stride * height;
+ return_on_error(allocate_frame_data(frame, 3 * bytes));
+ init_plane(&frame->planes.planar_rgb.R, width, stride,
+ height, frame->data);
+ init_plane(&frame->planes.planar_rgb.G, width, stride,
+ height, frame->data + 1 * bytes);
+ init_plane(&frame->planes.planar_rgb.B, width, stride,
+ height, frame->data + 2 * bytes);
+ return sh_css_success;
+}
+
+static sh_css_err
+allocate_plane6_planes(struct sh_css_frame *frame, unsigned int decimation)
+{
+ unsigned int width = frame->info.padded_width / decimation,
+ height = frame->info.height, bytes, stride;
+
+ stride = hrt_isp_css_stride_of_image_in_ddr(width, 16);
+ bytes = stride * height;
+
+ return_on_error(allocate_frame_data(frame, 6 * bytes));
+ init_plane(&frame->planes.plane6.R, width, stride,
+ height, frame->data + 0 * bytes);
+ init_plane(&frame->planes.plane6.RatB, width, stride,
+ height, frame->data + 1 * bytes);
+ init_plane(&frame->planes.plane6.Gr, width, stride,
+ height, frame->data + 2 * bytes);
+ init_plane(&frame->planes.plane6.Gb, width, stride,
+ height, frame->data + 3 * bytes);
+ init_plane(&frame->planes.plane6.B, width, stride,
+ height, frame->data + 4 * bytes);
+ init_plane(&frame->planes.plane6.BatR, width, stride,
+ height, frame->data + 5 * bytes);
+ return sh_css_success;
+}
+
+static sh_css_err
+allocate_frame(struct sh_css_frame **frame,
+ unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format,
+ unsigned int padded_width,
+ ShBool contiguous)
+{
+ struct sh_css_frame *me = sh_css_malloc(sizeof(*me));
+
+ if (!me)
+ return sh_css_err_cannot_allocate_memory;
+ me->info.width = width;
+ me->info.height = height;
+ me->info.format = format;
+ me->info.padded_width = padded_width;
+ me->contiguous = contiguous;
+
+ switch (me->info.format) {
+ case sh_css_frame_format_raw8:
+ return_on_error(allocate_single_plane
+ (me, &me->planes.raw, padded_width, 8));
+ break;
+ case sh_css_frame_format_raw16:
+ return_on_error(allocate_single_plane
+ (me, &me->planes.raw, padded_width, 16));
+ break;
+ case sh_css_frame_format_vraw16:
+ return_on_error(allocate_single_plane
+ (me, &me->planes.raw, padded_width, 16));
+ break;
+ case sh_css_frame_format_rgb565:
+ return_on_error(allocate_single_plane
+ (me, &me->planes.rgb, padded_width, 16));
+ break;
+ case sh_css_frame_format_rgba888:
+ return_on_error(allocate_single_plane
+ (me, &me->planes.rgb, padded_width * 4, 8));
+ break;
+ case sh_css_frame_format_planar_rgb888:
+ return_on_error(allocate_rgb_planes(me, 8));
+ break;
+ /* yuyv and uyvu have the same frame layout, only the data
+ * positioning differs.
+ */
+ case sh_css_frame_format_yuyv:
+ case sh_css_frame_format_uyvy:
+ return_on_error(allocate_single_plane
+ (me, &me->planes.yuyv, padded_width * 2, 8));
+ break;
+ case sh_css_frame_format_nv11:
+ return_on_error(allocate_nv_planes(me, 4, 1));
+ break;
+ /* nv12 and nv21 have the same frame layout, only the data
+ * positioning differs.
+ */
+ case sh_css_frame_format_yuv_line:
+ case sh_css_frame_format_nv12:
+ case sh_css_frame_format_nv21:
+ return_on_error(allocate_nv_planes(me, 2, 2));
+ break;
+ /* nv16 and nv61 have the same frame layout, only the data
+ * positioning differs.
+ */
+ case sh_css_frame_format_nv16:
+ case sh_css_frame_format_nv61:
+ return_on_error(allocate_nv_planes(me, 2, 1));
+ break;
+ case sh_css_frame_format_yuv420:
+ return_on_error(allocate_yuv_planes(me, 2, 2, ShFalse, 8));
+ break;
+ case sh_css_frame_format_yuv422:
+ return_on_error(allocate_yuv_planes(me, 2, 1, ShFalse, 8));
+ break;
+ case sh_css_frame_format_yuv444:
+ return_on_error(allocate_yuv_planes(me, 1, 1, ShFalse, 8));
+ break;
+ case sh_css_frame_format_yuv420_16:
+ return_on_error(allocate_yuv_planes(me, 2, 2, ShFalse, 16));
+ break;
+ case sh_css_frame_format_yuv422_16:
+ return_on_error(allocate_yuv_planes(me, 2, 1, ShFalse, 16));
+ break;
+ case sh_css_frame_format_yv12:
+ return_on_error(allocate_yuv_planes(me, 2, 2, ShTrue, 8));
+ break;
+ case sh_css_frame_format_yv16:
+ return_on_error(allocate_yuv_planes(me, 2, 1, ShTrue, 8));
+ break;
+ case sh_css_frame_format_plane6:
+ return_on_error(allocate_plane6_planes(me, 1));
+ break;
+ case sh_css_frame_format_qplane6:
+ return_on_error(allocate_plane6_planes(me, 2));
+ break;
+ case sh_css_frame_format_binary_8:
+ return_on_error(allocate_single_plane
+ (me, &me->planes.binary.data, padded_width, 8));
+ me->planes.binary.size = 0;
+ break;
+ default:
+ sh_css_free(me);
+ return sh_css_err_invalid_frame_format;
+ }
+ *frame = me;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_frame_allocate(struct sh_css_frame **frame,
+ unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format,
+ unsigned int padded_width)
+{
+ return allocate_frame(frame, width, height, format, padded_width,
+ ShFalse);
+}
+
+sh_css_err
+sh_css_frame_allocate_from_info(struct sh_css_frame **frame,
+ const struct sh_css_frame_info *info)
+{
+ return_on_error(sh_css_frame_allocate(frame,
+ info->width,
+ info->height,
+ info->format,
+ info->padded_width));
+ (*frame)->info.vraw_bit_depth = info->vraw_bit_depth;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_frame_allocate_contiguous(struct sh_css_frame **frame,
+ unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format,
+ unsigned int padded_width)
+{
+ return allocate_frame(frame, width, height, format, padded_width,
+ ShTrue);
+}
+
+sh_css_err
+sh_css_frame_allocate_contiguous_from_info(struct sh_css_frame **frame,
+ const struct sh_css_frame_info
+ *info)
+{
+ return_on_error(sh_css_frame_allocate_contiguous(frame,
+ info->width,
+ info->height,
+ info->format,
+ info->padded_width));
+ (*frame)->info.vraw_bit_depth = info->vraw_bit_depth;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_frame_free(struct sh_css_frame *frame)
+{
+ if (frame == NULL)
+ return sh_css_err_invalid_arguments;
+ hrt_isp_css_mm_free(frame->data);
+ sh_css_free(frame);
+ return sh_css_success;
+}
+
+void
+sh_css_frame_print(const struct sh_css_frame *frame, const char *descr)
+{
+ sh_css_print("frame %s (%p):\n", descr, frame);
+ sh_css_print(" resolution = %dx%d\n",
+ frame->info.width, frame->info.height);
+ sh_css_print(" padded width = %d\n", frame->info.padded_width);
+ sh_css_print(" format = %d\n", frame->info.format);
+ sh_css_print(" is contiguous = %s\n",
+ frame->contiguous ? "yes" : "no");
+ switch (frame->info.format) {
+ case sh_css_frame_format_yuv_line:
+ case sh_css_frame_format_nv12:
+ case sh_css_frame_format_nv16:
+ case sh_css_frame_format_nv21:
+ case sh_css_frame_format_nv61:
+ sh_css_print(" Y = %p\n", frame->planes.nv.Y.data);
+ sh_css_print(" UV = %p\n", frame->planes.nv.UV.data);
+ break;
+ case sh_css_frame_format_yuv420:
+ case sh_css_frame_format_yuv422:
+ case sh_css_frame_format_yuv444:
+ case sh_css_frame_format_yv12:
+ case sh_css_frame_format_yv16:
+ case sh_css_frame_format_yuv420_16:
+ case sh_css_frame_format_yuv422_16:
+ sh_css_print(" Y = %p\n", frame->planes.yuv.Y.data);
+ sh_css_print(" U = %p\n", frame->planes.yuv.U.data);
+ sh_css_print(" V = %p\n", frame->planes.yuv.V.data);
+ break;
+ case sh_css_frame_format_vraw16:
+ sh_css_print(" RAW = %p\n", frame->planes.raw.data);
+ break;
+ case sh_css_frame_format_rgba888:
+ case sh_css_frame_format_rgb565:
+ sh_css_print(" RGB = %p\n", frame->planes.rgb.data);
+ break;
+ case sh_css_frame_format_qplane6:
+ case sh_css_frame_format_plane6:
+ sh_css_print(" R = %p\n", frame->planes.plane6.R.data);
+ sh_css_print(" RatB = %p\n", frame->planes.plane6.RatB.data);
+ sh_css_print(" Gr = %p\n", frame->planes.plane6.Gr.data);
+ sh_css_print(" Gb = %p\n", frame->planes.plane6.Gb.data);
+ sh_css_print(" B = %p\n", frame->planes.plane6.B.data);
+ sh_css_print(" BatR = %p\n", frame->planes.plane6.BatR.data);
+ break;
+ case sh_css_frame_format_binary_8:
+ sh_css_print(" Binary data = %p\n", frame->planes.binary.data);
+ break;
+ default:
+ sh_css_print(" unknown frame type\n");
+ break;
+ }
+}
+
+ShBool
+sh_css_frame_info_equal_resolution(const struct sh_css_frame_info *info_a,
+ const struct sh_css_frame_info *info_b)
+{
+ if (!info_a || !info_b)
+ return ShFalse;
+ return (info_a->width == info_b->width) &&
+ (info_a->height == info_b->height);
+}
+
+void
+sh_css_frame_info_init(struct sh_css_frame_info *info,
+ unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format,
+ unsigned int padded_width)
+{
+ info->width = width;
+ info->height = height;
+ info->format = format;
+ info->padded_width = padded_width;
+}
+
+ShBool
+sh_css_frame_equal_types(const struct sh_css_frame *frame_a,
+ const struct sh_css_frame *frame_b)
+{
+ const struct sh_css_frame_info *info_a = &frame_a->info,
+ *info_b = &frame_b->info;
+ if (!info_a || !info_b)
+ return ShFalse;
+ if (info_a->format != info_b->format)
+ return ShFalse;
+ if (info_a->padded_width != info_b->padded_width)
+ return ShFalse;
+ return sh_css_frame_info_equal_resolution(info_a, info_b);
+}
+
+void
+sh_css_frame_zero(struct sh_css_frame *frame)
+{
+ unsigned int i;
+ void *ptr = frame->data;
+
+ for (i = 0; i < frame->data_bytes / sizeof(int);
+ i++, ptr += sizeof(int))
+ hrt_isp_css_mm_store_int(ptr, 0);
+}
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_frame.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_frame.h
new file mode 100644
index 0000000..85e8267
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_frame.h
@@ -0,0 +1,222 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SHCSS_FRAME_H_
+#define _SHCSS_FRAME_H_
+
+#define ShBool int
+enum {
+ ShFalse,
+ ShTrue
+};
+
+/* Frame formats, some of these come from fourcc.org, others are
+ better explained by video4linux2. The NV11 seems to be described only
+ on MSDN pages, but even those seem to be gone now.
+ Frames can come in many forms, the main categories are RAW, RGB and YUV
+ (or YCbCr). The YUV frames come in 4 flavors, determined by how the U and V
+ values are subsampled:
+ 1. YUV420: hor = 2, ver = 2
+ 2. YUV411: hor = 4, ver = 1
+ 3. YUV422: hor = 2, ver = 1
+ 4. YUV444: hor = 1, ver = 1
+ */
+enum sh_css_frame_format {
+ sh_css_frame_format_nv11, /* 12 bit YUV 411, Y, UV plane */
+ sh_css_frame_format_nv12, /* 12 bit YUV 420, Y, UV plane */
+ sh_css_frame_format_nv16, /* 16 bit YUV 422, Y, UV plane */
+ sh_css_frame_format_yuv420, /* 12 bit YUV 420, Y, U, V plane */
+ sh_css_frame_format_yuv422, /* 16 bit YUV 422, Y, U, V plane */
+ sh_css_frame_format_yuyv, /* 16 bit YUV 422, YUYV interleaved */
+ sh_css_frame_format_uyvy, /* 16 bit YUV 422, UYVY interleaved */
+ sh_css_frame_format_yuv444, /* 24 bit YUV 444, Y, U, V plane */
+ sh_css_frame_format_yuv420_16, /* Same as yuv420, 16 bits per subpixel
+ */
+ sh_css_frame_format_yuv422_16, /* Same as yuv422, 16 bits per subpixel
+ */
+ sh_css_frame_format_raw8, /* 8 bit RAW, 1 plane */
+ sh_css_frame_format_raw16, /* 16 bit RAW, 1 plane */
+ sh_css_frame_format_vraw16, /* 16 bit RAW, 1 plane, vectorized. For
+ internal use only. */
+ sh_css_frame_format_rgba888, /* 32 bit RGBA, 1 plane, A=Alpha unused
+ */
+ sh_css_frame_format_rgb565, /* 16 bit RGB, 1 plane. Each 3 sub
+ pixels are packed into one 16 bit
+ value, 5 bits for R, 6 bits for G
+ and 5 bits for B. */
+ sh_css_frame_format_planar_rgb888, /* 24 bit RGB, 3 planes */
+ sh_css_frame_format_qplane6, /* Internal, for advanced ISP */
+ sh_css_frame_format_plane6, /* Internal, for advanced ISP */
+ sh_css_frame_format_nv21, /* 12 bit YUV 420, Y, VU plane */
+ sh_css_frame_format_nv61, /* 16 bit YUV 422, Y, VU plane */
+ sh_css_frame_format_yv12, /* 12 bit YUV 420, Y, V, U plane */
+ sh_css_frame_format_yv16, /* 16 bit YUV 422, Y, V, U plane */
+ sh_css_frame_format_yuv_line, /* 12 bit YUV 420, Y, UV
+ line-interleaved plane. For internal
+ use only. */
+ sh_css_frame_format_binary_8, /* byte stream, used for jpeg. For
+ frames of this type, we set the
+ height to 1 and the width to the
+ number of allocated bytes. */
+};
+
+struct sh_css_frame_plane {
+ unsigned int height; /* height of a plane in lines */
+ unsigned int width; /* width of a line, in DMA elements, note that
+ for RGB565 the three subpixels are stored in
+ one element. For all other formats this is
+ the number of subpixels per line. */
+ unsigned int stride; /* stride of a line in bytes */
+ void *data; /* pointer that points into frame data */
+};
+
+struct sh_css_frame_binary_plane {
+ unsigned int size;
+ struct sh_css_frame_plane data;
+};
+
+struct sh_css_frame_yuv_planes {
+ struct sh_css_frame_plane Y;
+ struct sh_css_frame_plane U;
+ struct sh_css_frame_plane V;
+};
+
+struct sh_css_frame_nv_planes {
+ struct sh_css_frame_plane Y;
+ struct sh_css_frame_plane UV;
+};
+
+struct sh_css_frame_rgb_planes {
+ struct sh_css_frame_plane R;
+ struct sh_css_frame_plane G;
+ struct sh_css_frame_plane B;
+};
+
+struct sh_css_frame_plane6_planes {
+ struct sh_css_frame_plane R;
+ struct sh_css_frame_plane RatB;
+ struct sh_css_frame_plane Gr;
+ struct sh_css_frame_plane Gb;
+ struct sh_css_frame_plane B;
+ struct sh_css_frame_plane BatR;
+};
+
+/* For RAW input, the bayer order needs to be specified separately. There
+ are 4 possible orders. The name is constructed by taking the first two
+ colors on the first line and the first two colors from the second line.
+grbg: GRGRGRGR
+ BGBGBGBG
+rgbg: RGRGRGRG
+ GBGBGBGB
+bggr: BGBGBGBG
+ GRGRGRGR
+gbrg: GBGBGBGB
+ RGRGRGRG
+ */
+enum sh_css_bayer_order {
+ sh_css_bayer_order_grbg,
+ sh_css_bayer_order_rggb,
+ sh_css_bayer_order_bggr,
+ sh_css_bayer_order_gbrg
+};
+
+/* Frame info struct:
+ This structure describes a frame. It contains the resolution and strides.
+ */
+struct sh_css_frame_info {
+ /* width in valid data in pixels (not subpixels) */
+ unsigned int width;
+ /* height in lines of valid image data */
+ unsigned int height;
+ /* width of a line in memory, in pixels */
+ unsigned int padded_width;
+ /* format of the data in this frame */
+ enum sh_css_frame_format format;
+ /* number of valid bits per pixel, only valid for vraw16 frames. */
+ unsigned int vraw_bit_depth;
+ /* bayer order of raw data, only valid for raw8 and raw16 frames. */
+ enum sh_css_bayer_order raw_bayer_order;
+};
+
+struct sh_css_frame {
+ struct sh_css_frame_info info;
+ /* pointer to start of image data in memory */
+ void *data;
+ /* size of data pointer in bytes */
+ unsigned int data_bytes;
+ /* indicate whether memory is allocated physically contiguously */
+ ShBool contiguous;
+ union {
+ struct sh_css_frame_plane raw;
+ struct sh_css_frame_plane rgb;
+ struct sh_css_frame_rgb_planes planar_rgb;
+ struct sh_css_frame_plane yuyv;
+ struct sh_css_frame_yuv_planes yuv;
+ struct sh_css_frame_nv_planes nv;
+ struct sh_css_frame_plane6_planes plane6;
+ struct sh_css_frame_binary_plane binary;
+ } planes;
+};
+
+#include "sh_css.h"
+
+/* Allocate a frame of a certain resolution and format. */
+sh_css_err
+sh_css_frame_allocate(struct sh_css_frame **frame,
+ unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format,
+ unsigned int padded_width);
+
+/* Allocate a frame using the resolution and format from a frame info struct. */
+sh_css_err
+sh_css_frame_allocate_from_info(struct sh_css_frame **frame,
+ const struct sh_css_frame_info *info);
+
+/* Free a frame */
+sh_css_err
+sh_css_frame_free(struct sh_css_frame *frame);
+
+/* Print out information of a frame. This uses the print function as set via
+ sh_css_set_print_function. If this has not been set, no output will be
+ printed. */
+void
+sh_css_frame_print(const struct sh_css_frame *frame,
+ const char *descr);
+
+/* ===== FPGA display frames ====== */
+/* Contiguous frame allocation, only for FPGA display driver which needs
+ physically contiguous memory. */
+sh_css_err
+sh_css_frame_allocate_contiguous(struct sh_css_frame **frame,
+ unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format,
+ unsigned int padded_width);
+
+sh_css_err
+sh_css_frame_allocate_contiguous_from_info(struct sh_css_frame **frame,
+ const struct sh_css_frame_info
+ *info);
+
+#endif /* _SHCSS_FRAME_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_hrt.c b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_hrt.c
new file mode 100644
index 0000000..2bd28bc
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_hrt.c
@@ -0,0 +1,2332 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+#include "sh_css_hrt.h"
+#include "sh_css_internal.h"
+#ifdef USE_DYNAMIC_BIN
+#include <mfldisp_internal.h>
+#else
+#include "sp.map.h"
+#endif
+
+#ifdef HRT_ISP_CSS_CUSTOM_HOST
+#ifndef HRT_USE_VIR_ADDRS
+#define HRT_USE_VIR_ADDRS
+#endif
+#include <hive_isp_css_custom_host_hrt.h>
+#endif
+#if defined(_HIVE_ISP_CSS_FPGA_SYSTEM)
+/* we need the regular HRT in this case. */
+#include <api.h>
+#include <hive_types.h>
+#ifdef _HIVE_ISP_CSS_FPGA_SYSTEM
+#include <isp_css_dev_tb.h>
+#else
+#include <hive_isp_css_system.h>
+#endif
+#include <irq_controller.h>
+#include <inputformatter.h>
+#include <dma_v1.h>
+#include <gp_regs.h>
+#include <mmu.h>
+#include <gdc.h>
+#ifdef CSS_RECEIVER
+#include <css_receiver_ahb_hrt.h>
+#endif
+#include <sp_hrt.h>
+#else
+/* for ASIC, we use the stripped HRT */
+#include <master_port.h>
+#include <bits.h>
+#include <sp_hrt.h>
+#include <irq_controller_defs.h>
+#include <if_defs.h>
+#include <dma_v1_defs.h>
+#include <gp_regs_defs.h>
+#include <mmu_defs.h>
+#ifdef CSS_RECEIVER
+#include <css_receiver_ahb_defs.h>
+#endif
+#endif
+#include <hive_isp_css_streaming_monitors_types_hrt.h>
+#include <hive_isp_css_if_hrt.h>
+#include <hive_isp_css_streaming_to_mipi_types_hrt.h>
+
+#ifdef HRT_CSIM
+#define sh_css_start_sp_function(func) \
+ hrt_cell_start_function(SP, func)
+#else
+#define sh_css_start_sp_function(func) \
+ sh_css_start_sp(HIVE_ADDR_ ## func ## _entry)
+#endif
+enum sh_css_mipi_data_type {
+ sh_css_mipi_data_type_regular,
+ sh_css_mipi_data_type_yuv420,
+ sh_css_mipi_data_type_yuv420_legacy,
+ sh_css_mipi_data_type_rgb,
+};
+
+#if defined(_HIVE_ISP_CSS_FPGA_SYSTEM)
+/* these are unsigned long pointers such that we can simply
+ * add the register index to get the right address.
+ */
+static unsigned long *mmu_base_address =
+ (unsigned long *)(hrt_master_to_slave_address(
+ HOST_MASTER, hrt_mmu_slave_port(MMU)));
+static unsigned long *gdc_lut_base_address =
+ (unsigned long *)(hrt_master_to_slave_address(
+ HOST_MASTER, hrt_gdc_slave_port(GDC)));
+static unsigned long *dma_base_address =
+ (unsigned long *)(hrt_master_to_slave_address(
+ HOST_MASTER, _hrt_dma_v1_slave_port(DMA)));
+static unsigned long *if_prim_a_base_address =
+ (unsigned long *)(hrt_master_to_slave_address(
+ HOST_MASTER, hrt_if_slave_port(IF_PRIM)));
+static unsigned long *if_prim_b_base_address =
+ (unsigned long *)(hrt_master_to_slave_address(
+ HOST_MASTER, hrt_if_slave_port(IF_PRIM_B)));
+static unsigned char *sp_dmem_base_address =
+ (unsigned char *)(hrt_mem_master_port_address(SP, hrt_sp_dmem(SP)));
+static unsigned long *sp_sc_base_address =
+ (unsigned long *)(hrt_master_to_slave_address(
+ HOST_MASTER, _hrt_sc_slave(SP)) +
+ _hrt_cell_stat_ctrl_base(SP));
+static unsigned long *isp_sc_base_address =
+ (unsigned long *)(hrt_master_to_slave_address(
+ HOST_MASTER, _hrt_sc_slave(ISP)) +
+ _hrt_cell_stat_ctrl_base(ISP));
+static unsigned long *str_monitor_base_address =
+ (unsigned long *) hrt_master_to_slave_address(
+ HOST_MASTER, hrt_gp_regs_slave_port(GP_REGS));
+static unsigned long *irq_ctrl_base_address =
+ (unsigned long *) hrt_master_to_slave_address(
+ HOST_MASTER, hrt_irq_controller_slave_port(IRQ_CTRL));
+static unsigned long *gp_fifo_base_address =
+ (unsigned long *) HRTCAT(GP_FIFO, _snd_address);
+#ifdef CSS_RECEIVER
+/* FPGA system does not have a css receiver */
+static unsigned long *css_rx_base_address =
+ (unsigned long *) hrt_master_to_slave_address(
+ HOST_MASTER,
+ hrt_css_receiver_ahb_slave_port(CSS_RECEIVER));
+#endif
+
+static unsigned int sp_pc_reg = _hrt_cell_debug_pc_register(SP);
+static unsigned int sp_stalling_bit = _hrt_cell_stalling_flag_bit(SP);
+static unsigned int sp_sleeping_bit = _hrt_cell_sleeping_irq_mask_flag_bit(SP);
+static unsigned int sp_broken_bit = _hrt_cell_broken_flag_bit(SP);
+static unsigned int isp_pc_reg = _hrt_cell_debug_pc_register(ISP);
+static unsigned int isp_stalling_bit = _hrt_cell_stalling_flag_bit(ISP);
+static unsigned int isp_sleeping_bit =
+ _hrt_cell_sleeping_irq_mask_flag_bit(ISP);
+static unsigned int isp_broken_bit = _hrt_cell_broken_flag_bit(ISP);
+#define SP_MSINK_BIT(sink) \
+ _hrt_cell_msink_stalling_flag_bit(SP, HRTCAT(HRT_PROC_TYPE(SP), sink))
+#define SP_MSINK_REG(sink) \
+ _hrt_cell_msink_stalling_flag_register(SP, HRTCAT(HRT_PROC_TYPE(SP),\
+ sink))
+#define ISP_MSINK_BIT(sink) \
+ _hrt_cell_msink_stalling_flag_bit(ISP, HRTCAT(HRT_PROC_TYPE(ISP), sink))
+#define ISP_MSINK_REG(sink) \
+ _hrt_cell_msink_stalling_flag_register(ISP, HRTCAT(HRT_PROC_TYPE(ISP),\
+ sink))
+/* ISP master sink stalling */
+enum isp_sink_bit {
+ isp_ctrl_sink_bit =
+ ISP_MSINK_BIT(_base_config_mem_loc_mt_am_inst_0_op0),
+ isp_dmem_sink_bit = ISP_MSINK_BIT(_base_dmem_loc_mt_am_inst_1_op0),
+ isp_vmem_sink_bit = ISP_MSINK_BIT(_simd_vmem_loc_mt_am_inst_2_op0),
+ isp_fifo0_sink_bit = ISP_MSINK_BIT(_simd_fifo_loc_mt_am_inst_3_op0),
+ isp_fifo1_sink_bit = ISP_MSINK_BIT(_simd_fifo_loc_mt_am_inst_3_op1),
+ isp_fifo2_sink_bit = ISP_MSINK_BIT(_simd_fifo_loc_mt_am_inst_3_op2),
+ isp_fifo3_sink_bit = ISP_MSINK_BIT(_simd_fifo_loc_mt_am_inst_3_op3),
+ isp_fifo4_sink_bit = ISP_MSINK_BIT(_simd_fifo_loc_mt_am_inst_3_op4),
+ isp_fifo5_sink_bit = ISP_MSINK_BIT(_simd_fifo_loc_mt_am_inst_3_op5),
+ isp_vamem1_sink_bit = ISP_MSINK_BIT(_simd_vamem1_loc_mt_am_inst_4_op0),
+ isp_vamem2_sink_bit = ISP_MSINK_BIT(_simd_vamem2_loc_mt_am_inst_5_op0)
+};
+
+enum {
+ isp_ctrl_sink_reg =
+ ISP_MSINK_REG(_base_config_mem_loc_mt_am_inst_0_op0),
+ isp_dmem_sink_reg = ISP_MSINK_REG(_base_dmem_loc_mt_am_inst_1_op0),
+ isp_vmem_sink_reg = ISP_MSINK_REG(_simd_vmem_loc_mt_am_inst_2_op0),
+ isp_fifo0_sink_reg = ISP_MSINK_REG(_simd_fifo_loc_mt_am_inst_3_op0),
+ isp_fifo1_sink_reg = ISP_MSINK_REG(_simd_fifo_loc_mt_am_inst_3_op1),
+ isp_fifo2_sink_reg = ISP_MSINK_REG(_simd_fifo_loc_mt_am_inst_3_op2),
+ isp_fifo3_sink_reg = ISP_MSINK_REG(_simd_fifo_loc_mt_am_inst_3_op3),
+ isp_fifo4_sink_reg = ISP_MSINK_REG(_simd_fifo_loc_mt_am_inst_3_op4),
+ isp_fifo5_sink_reg = ISP_MSINK_REG(_simd_fifo_loc_mt_am_inst_3_op5),
+ isp_vamem1_sink_reg = ISP_MSINK_REG(_simd_vamem1_loc_mt_am_inst_4_op0),
+ isp_vamem2_sink_reg = ISP_MSINK_REG(_simd_vamem2_loc_mt_am_inst_5_op0)
+};
+
+/* SP master sink stalling */
+enum sp_sink_bit {
+ sp_fifo0_sink_bit = SP_MSINK_BIT(_fifo_loc_mt_am_inst_0_op0),
+ sp_fifo1_sink_bit = SP_MSINK_BIT(_fifo_loc_mt_am_inst_0_op1),
+ sp_fifo2_sink_bit = SP_MSINK_BIT(_fifo_loc_mt_am_inst_0_op2),
+ sp_fifo3_sink_bit = SP_MSINK_BIT(_fifo_loc_mt_am_inst_0_op3),
+ sp_fifo4_sink_bit = SP_MSINK_BIT(_fifo_loc_mt_am_inst_0_op4),
+ sp_fifo5_sink_bit = SP_MSINK_BIT(_fifo_loc_mt_am_inst_0_op5),
+ sp_fifo6_sink_bit = SP_MSINK_BIT(_fifo_loc_mt_am_inst_0_op6),
+ sp_fifo7_sink_bit = SP_MSINK_BIT(_fifo_loc_mt_am_inst_0_op7),
+ sp_dmem_sink_bit = SP_MSINK_BIT(_dmem_loc_mt_am_inst_1_op0),
+ sp_ctrl_mt_sink_bit = SP_MSINK_BIT(_xmem_loc_mt_am_inst_2_op0),
+ sp_icache_mt_sink_bit =
+ SP_MSINK_BIT(_config_icache_conf_icache_loc_mt_am_inst_3_op0),
+};
+
+enum sp_sink_reg {
+ sp_fifo0_sink_reg = SP_MSINK_REG(_fifo_loc_mt_am_inst_0_op0),
+ sp_fifo1_sink_reg = SP_MSINK_REG(_fifo_loc_mt_am_inst_0_op1),
+ sp_fifo2_sink_reg = SP_MSINK_REG(_fifo_loc_mt_am_inst_0_op2),
+ sp_fifo3_sink_reg = SP_MSINK_REG(_fifo_loc_mt_am_inst_0_op3),
+ sp_fifo4_sink_reg = SP_MSINK_REG(_fifo_loc_mt_am_inst_0_op4),
+ sp_fifo5_sink_reg = SP_MSINK_REG(_fifo_loc_mt_am_inst_0_op5),
+ sp_fifo6_sink_reg = SP_MSINK_REG(_fifo_loc_mt_am_inst_0_op6),
+ sp_fifo7_sink_reg = SP_MSINK_REG(_fifo_loc_mt_am_inst_0_op7),
+ sp_dmem_sink_reg = SP_MSINK_REG(_dmem_loc_mt_am_inst_1_op0),
+ sp_ctrl_mt_sink_reg = SP_MSINK_REG(_xmem_loc_mt_am_inst_2_op0),
+ sp_icache_mt_sink_reg =
+ SP_MSINK_REG(_config_icache_conf_icache_loc_mt_am_inst_3_op0)
+};
+
+#ifndef HRT_CSIM
+static unsigned int sp_start_addr_reg = _hrt_cell_start_address_register(SP);
+static unsigned int sp_start_bit = _hrt_cell_start_flag_bit(SP);
+static unsigned int sp_run_bit = _hrt_cell_run_flag_bit(SP);
+static unsigned int sp_icache_addr_reg =
+ _hrt_cell_base_address_lowest_register(SP,
+ _hrt_cell_icache_master_interface(SP));
+static unsigned int sp_icache_inv_reg =
+ _hrt_cell_cache_invalidate_flag_register(SP, _hrt_cell_icache(SP));
+static unsigned int sp_icache_inv_bit =
+ _hrt_cell_cache_invalidate_flag_bit(SP, _hrt_cell_icache(SP));
+#endif
+static unsigned int sp_irq_ready_reg =
+ _hrt_cell_ready_irq_mask_flag_register(SP);
+static unsigned int sp_irq_clear_reg = _hrt_cell_irq_clr_flag_register(SP);
+static unsigned int sp_idle_bit = _hrt_cell_ready_flag_bit(SP);
+static unsigned int sp_irq_ready_bit = _hrt_cell_ready_irq_mask_flag_bit(SP);
+static unsigned int sp_irq_clear_bit = _hrt_cell_irq_clr_flag_bit(SP);
+static unsigned int isp_idle_bit = _hrt_cell_ready_flag_bit(ISP);
+#else
+static unsigned long *mmu_base_address = (unsigned long *)0x10250000;
+static unsigned long *gdc_lut_base_address = (unsigned long *)0x10180000;
+static unsigned long *dma_base_address = (unsigned long *)0x10240000;
+static unsigned long *if_prim_a_base_address = (unsigned long *)0x10210000;
+static unsigned long *if_prim_b_base_address = (unsigned long *)0x10270000;
+static unsigned char *sp_dmem_base_address = (unsigned char *)0x10100000;
+static unsigned long *sp_sc_base_address = (unsigned long *)0x10104000;
+static unsigned long *isp_sc_base_address = (unsigned long *)0x10020000;
+static unsigned long *str_monitor_base_address = (unsigned long *)0x10200000;
+static unsigned long *irq_ctrl_base_address = (unsigned long *)0x10200500;
+static unsigned long *gp_fifo_base_address = (unsigned long *)0x10200304;
+static unsigned long *css_rx_base_address = (unsigned long *)0x10260000;
+static unsigned int sp_pc_reg = 0x9;
+static unsigned int sp_stalling_bit = 0x7;
+static unsigned int sp_sleeping_bit = 0xB;
+static unsigned int sp_broken_bit = 0x4;
+static unsigned int isp_pc_reg = 0x5;
+static unsigned int isp_stalling_bit = 0x7;
+static unsigned int isp_sleeping_bit = 0xB;
+static unsigned int isp_broken_bit = 0x4;
+enum isp_sink_bit {
+ isp_ctrl_sink_bit = 0x0,
+ isp_dmem_sink_bit = 0x1,
+ isp_vmem_sink_bit = 0x2,
+ isp_fifo0_sink_bit = 0x3,
+ isp_fifo1_sink_bit = 0x4,
+ isp_fifo2_sink_bit = 0x5,
+ isp_fifo3_sink_bit = 0x6,
+ isp_fifo4_sink_bit = 0x7,
+ isp_fifo5_sink_bit = 0x8,
+ isp_vamem1_sink_bit = 0x9,
+ isp_vamem2_sink_bit = 0xA
+};
+
+enum {
+ isp_ctrl_sink_reg = 0x6,
+ isp_dmem_sink_reg = 0x6,
+ isp_vmem_sink_reg = 0x6,
+ isp_fifo0_sink_reg = 0x6,
+ isp_fifo1_sink_reg = 0x6,
+ isp_fifo2_sink_reg = 0x6,
+ isp_fifo3_sink_reg = 0x6,
+ isp_fifo4_sink_reg = 0x6,
+ isp_fifo5_sink_reg = 0x6,
+ isp_vamem1_sink_reg = 0x6,
+ isp_vamem2_sink_reg = 0x6
+};
+
+enum sp_sink_bit {
+ sp_fifo0_sink_bit = 0x0,
+ sp_fifo1_sink_bit = 0x1,
+ sp_fifo2_sink_bit = 0x2,
+ sp_fifo3_sink_bit = 0x3,
+ sp_fifo4_sink_bit = 0x4,
+ sp_fifo5_sink_bit = 0x5,
+ sp_fifo6_sink_bit = 0x6,
+ sp_fifo7_sink_bit = 0x7,
+ sp_dmem_sink_bit = 0x8,
+ sp_ctrl_mt_sink_bit = 0x9,
+ sp_icache_mt_sink_bit = 0xA,
+};
+
+enum sp_sink_reg {
+ sp_fifo0_sink_reg = 0xA,
+ sp_fifo1_sink_reg = 0xA,
+ sp_fifo2_sink_reg = 0xA,
+ sp_fifo3_sink_reg = 0xA,
+ sp_fifo4_sink_reg = 0xA,
+ sp_fifo5_sink_reg = 0xA,
+ sp_fifo6_sink_reg = 0xA,
+ sp_fifo7_sink_reg = 0xA,
+ sp_dmem_sink_reg = 0xA,
+ sp_ctrl_mt_sink_reg = 0xA,
+ sp_icache_mt_sink_reg = 0xA
+};
+
+/* initializers with 0x0 are commented out to
+ * avoid warnings from checkpatch.pl.
+ */
+#ifndef HRT_CSIM
+static unsigned int sp_start_addr_reg = 0x1;
+static unsigned int sp_start_bit = 0x1;
+static unsigned int sp_run_bit = 0x3;
+static unsigned int sp_icache_addr_reg = 0x5;
+static unsigned int sp_icache_inv_reg/* = 0x0*/;
+static unsigned int sp_icache_inv_bit = 0xC;
+#endif
+static unsigned int sp_irq_ready_reg/* = 0x0*/;
+static unsigned int sp_irq_clear_reg/* = 0x0*/;
+static unsigned int sp_idle_bit = 0x5;
+static unsigned int sp_irq_ready_bit = 0xA;
+static unsigned int sp_irq_clear_bit = 0x8;
+static unsigned int isp_idle_bit = 0x5;
+#endif
+static unsigned int sp_sc_reg;
+static unsigned int isp_sc_reg;
+static unsigned int curr_ch_id, curr_fmt_type;
+
+unsigned int
+sh_css_hrt_sp_dmem_load_32(unsigned int address)
+{
+ unsigned long addr = (unsigned long)(sp_dmem_base_address + address);
+ return hrt_master_port_uload_32(addr);
+}
+
+void
+sh_css_hrt_sp_dmem_store_32(unsigned int address, unsigned int value)
+{
+ unsigned long addr = (unsigned long)(sp_dmem_base_address + address);
+ hrt_master_port_store_32(addr, value);
+}
+
+static void
+sh_css_sp_ctrl_store(unsigned int reg, unsigned int value)
+{
+ unsigned int addr = (unsigned int)(sp_sc_base_address + reg);
+ hrt_master_port_store_32(addr, value);
+}
+
+static unsigned long
+sh_css_sp_ctrl_load(unsigned int reg)
+{
+ unsigned int addr = (unsigned int)(sp_sc_base_address + reg);
+ return hrt_master_port_uload_32(addr);
+}
+
+static unsigned long
+sh_css_isp_ctrl_load(unsigned int reg)
+{
+ unsigned int addr = (unsigned int)(isp_sc_base_address + reg);
+ return hrt_master_port_uload_32(addr);
+}
+
+static unsigned int
+isp_ctrl_get_bit(unsigned int reg, unsigned int bit)
+{
+ unsigned long val;
+ val = sh_css_isp_ctrl_load(reg);
+ return (val & (1U << bit)) != 0;
+}
+
+static void
+sh_css_sp_ctrl_set_bits(unsigned int reg, unsigned long bits)
+{
+ unsigned long val;
+ val = sh_css_sp_ctrl_load(reg);
+ val |= bits;
+ sh_css_sp_ctrl_store(reg, val);
+}
+
+static unsigned int
+sp_ctrl_get_bit(unsigned int reg, unsigned int bit)
+{
+ unsigned long val;
+ val = sh_css_sp_ctrl_load(reg);
+ return (val & (1U << bit)) != 0;
+}
+
+static void
+sh_css_sp_ctrl_reset_bits(unsigned int reg, unsigned long bits)
+{
+ unsigned long val;
+ val = sh_css_sp_ctrl_load(reg);
+ val &= ~bits;
+ sh_css_sp_ctrl_store(reg, val);
+}
+
+#ifndef HRT_CSIM
+static void
+sh_css_start_sp(unsigned int start_address)
+{
+ /* set the start address */
+ sh_css_sp_ctrl_store(sp_start_addr_reg, start_address);
+ /* set the run bit and the start bit with a read-modify-write */
+ sh_css_sp_ctrl_set_bits(sp_sc_reg,
+ 1UL<<sp_start_bit | 1UL<<sp_run_bit);
+}
+#endif
+
+void
+sh_css_hrt_irq_enable_sp(ShBool enable)
+{
+ if (enable)
+ sh_css_sp_ctrl_set_bits(sp_irq_ready_reg,
+ 1UL<<sp_irq_ready_bit);
+ else
+ sh_css_sp_ctrl_reset_bits(sp_irq_ready_reg,
+ 1UL<<sp_irq_ready_bit);
+}
+
+void
+sh_css_hrt_irq_clear_sp(void)
+{
+ sh_css_sp_ctrl_set_bits(sp_irq_clear_reg, 1UL<<sp_irq_clear_bit);
+}
+
+static int
+sh_css_cell_is_ready(unsigned long *status_reg, unsigned int ready_bit)
+{
+ unsigned long ready_reg;
+ ready_reg = hrt_master_port_uload_32((unsigned long)status_reg);
+ return (ready_reg & (1U << ready_bit)) != 0;
+}
+
+static void
+sh_css_cell_wait(unsigned long *status_reg, unsigned int ready_bit)
+{
+ int count = 0;
+ while ((!sh_css_cell_is_ready(status_reg, ready_bit)) &&
+ (count < 80000)) {
+ count++;
+ hrt_sleep();
+ }
+ if (count == 80000) {
+ printk(KERN_INFO, "atomisp: cell (ISP Processor) time out\n");
+ sh_css_dump_debug_info();
+ }
+}
+
+void
+sh_css_hrt_sp_wait(void)
+{
+ sh_css_cell_wait(sp_sc_base_address + sp_sc_reg, sp_idle_bit);
+}
+
+void
+sh_css_hrt_sp_start_dma_proxy_run(void)
+{
+ sh_css_start_sp_function(sp_dma_proxy_run);
+}
+
+void
+sh_css_hrt_sp_start_dma_proxy_init(void)
+{
+ sh_css_start_sp_function(sp_dma_proxy_init);
+}
+
+void
+sh_css_hrt_sp_start_si(void)
+{
+ sh_css_start_sp_function(super_impose_offline);
+}
+
+void
+sh_css_hrt_sp_start_histogram(void)
+{
+ sh_css_start_sp_function(sp_gen_histogram);
+}
+
+void
+sh_css_hrt_sp_start_copy_frame(void)
+{
+ sh_css_start_sp_function(copy_frame);
+}
+
+void
+sh_css_hrt_sp_start_copy_binary_data(void)
+{
+ sh_css_start_sp_function(sp_bin_copy);
+}
+
+void
+sh_css_hrt_sp_start_isp(void)
+{
+ sh_css_start_sp_function(sp_start_isp);
+}
+
+void
+sh_css_hrt_isp_wait(void)
+{
+ sh_css_cell_wait(isp_sc_base_address + isp_sc_reg, isp_idle_bit);
+}
+#if defined(HRT_CSIM)
+void *
+sh_css_hrt_sp_load_program(void)
+{
+ return hrt_isp_css_load_sp_program(sp);
+}
+#else
+
+static void
+store_sp_text_section(unsigned int pmem_offset,
+ unsigned int blob_offset,
+ unsigned int size,
+ const char *blob,
+ void *target_addr)
+{
+ /* we don't have pmem, only icache, so ignore this offset. */
+ pmem_offset = pmem_offset;
+ hrt_isp_css_mm_store(target_addr, blob + blob_offset, size);
+}
+
+/* this must be a macro because the first argument is a memory
+ * identifier which we must discard.
+ */
+#define store_sp_data_section(mem, mem_offset, from, size, blob, text_addr) \
+ sp_dmem_store(mem_offset, blob + from, size)
+static void
+sp_dmem_store(unsigned int offset, const char *data, unsigned int size)
+{
+ unsigned long addr = (unsigned long)(sp_dmem_base_address + offset);
+ hrt_master_port_store(addr, data, size);
+}
+
+#define store_sp_bss_section(mem, mem_offset, size, blob, text_addr) \
+ sp_dmem_zero(mem_offset, size)
+static void
+sp_dmem_zero(unsigned int offset, unsigned int size)
+{
+ unsigned long addr = (unsigned long)(sp_dmem_base_address + offset);
+ hrt_master_port_set(addr, 0, size);
+}
+#define no_store_view_table(from, size, blob, text_addr)
+
+void *
+sh_css_hrt_sp_load_program(void)
+{
+ void *target_addr;
+ const char *blob;
+
+ target_addr = hrt_isp_css_mm_alloc(_hrt_text_size_of_sp);
+#ifdef USE_DYNAMIC_BIN
+ blob = _hrt_blob_sp;
+#else
+ blob = _hrt_blob_sp.data;
+#endif
+ _hrt_transfer_embedded_sp(store_sp_text_section,
+ store_sp_data_section,
+ store_sp_bss_section,
+ no_store_view_table,
+ blob,
+ target_addr);
+ /* now we program the base address into the icache and
+ * invalidate the cache.
+ */
+ sh_css_sp_ctrl_store(sp_icache_addr_reg, (unsigned long)target_addr);
+ sh_css_sp_ctrl_set_bits(sp_icache_inv_reg, 1UL << sp_icache_inv_bit);
+
+ return target_addr;
+}
+#endif
+
+void
+sh_css_hrt_sp_get_state(struct sh_css_cell_state *state,
+ struct sh_css_sp_stall_state *stall_state)
+{
+ unsigned int sc;
+
+ sc = sh_css_sp_ctrl_load(sp_sc_reg);
+ state->pc = sh_css_sp_ctrl_load(sp_pc_reg);
+ state->status_register = sc;
+ state->is_broken = (sc & (1U << sp_broken_bit)) != 0;
+ state->is_idle = (sc & (1U << sp_idle_bit)) != 0;
+ state->is_sleeping = (sc & (1U << sp_sleeping_bit)) != 0;
+ state->is_stalling = (sc & (1U << sp_stalling_bit)) != 0;
+ stall_state->fifo0 =
+ sp_ctrl_get_bit(sp_fifo0_sink_bit, sp_fifo0_sink_reg);
+ stall_state->fifo1 =
+ sp_ctrl_get_bit(sp_fifo1_sink_bit, sp_fifo1_sink_reg);
+ stall_state->fifo2 =
+ sp_ctrl_get_bit(sp_fifo2_sink_bit, sp_fifo2_sink_reg);
+ stall_state->fifo3 =
+ sp_ctrl_get_bit(sp_fifo3_sink_bit, sp_fifo3_sink_reg);
+ stall_state->fifo4 =
+ sp_ctrl_get_bit(sp_fifo4_sink_bit, sp_fifo4_sink_reg);
+ stall_state->fifo5 =
+ sp_ctrl_get_bit(sp_fifo5_sink_bit, sp_fifo5_sink_reg);
+ stall_state->fifo6 =
+ sp_ctrl_get_bit(sp_fifo6_sink_bit, sp_fifo6_sink_reg);
+ stall_state->fifo7 =
+ sp_ctrl_get_bit(sp_fifo7_sink_bit, sp_fifo7_sink_reg);
+ stall_state->dmem =
+ sp_ctrl_get_bit(sp_dmem_sink_bit, sp_dmem_sink_reg);
+ stall_state->control_master =
+ sp_ctrl_get_bit(sp_ctrl_mt_sink_bit, sp_ctrl_mt_sink_reg);
+ stall_state->icache_master =
+ sp_ctrl_get_bit(sp_icache_mt_sink_bit, sp_icache_mt_sink_reg);
+}
+
+void
+sh_css_hrt_isp_get_state(struct sh_css_cell_state *state,
+ struct sh_css_isp_stall_state *stall_state)
+{
+ unsigned int sc;
+ sc = sh_css_isp_ctrl_load(isp_sc_reg);
+ state->pc = sh_css_isp_ctrl_load(isp_pc_reg);
+ state->status_register = sc;
+ state->is_broken = isp_ctrl_get_bit(isp_sc_reg, isp_broken_bit);
+ state->is_idle = isp_ctrl_get_bit(isp_sc_reg, isp_idle_bit);
+ state->is_sleeping = isp_ctrl_get_bit(isp_sc_reg, isp_sleeping_bit);
+ state->is_stalling = isp_ctrl_get_bit(isp_sc_reg, isp_stalling_bit);
+ stall_state->stat_ctrl =
+ isp_ctrl_get_bit(isp_ctrl_sink_bit, isp_ctrl_sink_reg);
+ stall_state->dmem =
+ isp_ctrl_get_bit(isp_dmem_sink_bit, isp_dmem_sink_reg);
+#ifndef SYSTEM_hive_isp_css_2400_system
+ stall_state->vmem =
+ isp_ctrl_get_bit(isp_vmem_sink_bit, isp_vmem_sink_reg);
+ stall_state->fifo0 =
+ isp_ctrl_get_bit(isp_fifo0_sink_bit, isp_fifo0_sink_reg);
+ stall_state->fifo1 =
+ isp_ctrl_get_bit(isp_fifo1_sink_bit, isp_fifo1_sink_reg);
+ stall_state->fifo2 =
+ isp_ctrl_get_bit(isp_fifo2_sink_bit, isp_fifo2_sink_reg);
+ stall_state->fifo3 =
+ isp_ctrl_get_bit(isp_fifo3_sink_bit, isp_fifo3_sink_reg);
+ stall_state->fifo4 =
+ isp_ctrl_get_bit(isp_fifo4_sink_bit, isp_fifo4_sink_reg);
+ stall_state->fifo5 =
+ isp_ctrl_get_bit(isp_fifo5_sink_bit, isp_fifo5_sink_reg);
+#else
+ stall_state->vmem = ShFalse;
+ stall_state->fifo0 = ShFalse;
+ stall_state->fifo1 = ShFalse;
+ stall_state->fifo2 = ShFalse;
+ stall_state->fifo3 = ShFalse;
+ stall_state->fifo4 = ShFalse;
+ stall_state->fifo5 = ShFalse;
+#endif
+ stall_state->vamem1 =
+ isp_ctrl_get_bit(isp_vamem1_sink_bit, isp_vamem1_sink_reg);
+ stall_state->vamem2 =
+ isp_ctrl_get_bit(isp_vamem2_sink_bit, isp_vamem2_sink_reg);
+}
+
+static inline unsigned long
+_sh_css_dma_get_register(unsigned int addr)
+{
+ unsigned int bus_addr = (unsigned int)(dma_base_address + addr);
+ return hrt_master_port_load_32(bus_addr);
+}
+
+/* Command FSM state */
+static inline unsigned
+sh_css_dma_get_command_fsm_state(void)
+{
+ return _sh_css_dma_get_register(_hrt_dma_v1_sel_comp(0));
+}
+
+/* Get channel parameters */
+static inline unsigned
+_sh_css_dma_get_channel_parameter(int ch, int param)
+{
+ return _sh_css_dma_get_register(
+ hrt_dma_v1_channel_parameter_register_address(ch, param));
+}
+
+static inline unsigned
+sh_css_dma_get_channel_connection(int channel)
+{
+ return _hrt_dma_v1_get_connection(
+ _sh_css_dma_get_channel_parameter(channel, 0));
+}
+
+static inline unsigned
+sh_css_dma_get_channel_extension(int channel)
+{
+ return _hrt_dma_v1_get_extension(
+ _sh_css_dma_get_channel_parameter(channel, 0));
+}
+
+static inline unsigned
+sh_css_dma_get_channel_element_order(int channel)
+{
+ return _hrt_dma_v1_get_element_order(
+ _sh_css_dma_get_channel_parameter(channel, 0));
+}
+
+static inline unsigned
+sh_css_dma_get_channel_stride_A(int channel)
+{
+ return _sh_css_dma_get_channel_parameter(channel, 1);
+}
+
+static inline unsigned
+sh_css_dma_get_channel_elements_A(int channel)
+{
+ return _hrt_dma_v1_get_elements(
+ _sh_css_dma_get_channel_parameter(channel, 2));
+}
+
+static inline unsigned
+sh_css_dma_get_channel_cropping_A(int channel)
+{
+ return _hrt_dma_v1_get_cropping(
+ _sh_css_dma_get_channel_parameter(channel, 2));
+}
+
+static inline unsigned
+sh_css_dma_get_channel_width_A(int channel)
+{
+ return _sh_css_dma_get_channel_parameter(channel, 3);
+}
+
+static inline unsigned
+sh_css_dma_get_channel_stride_B(int channel)
+{
+ return _sh_css_dma_get_channel_parameter(channel, 4);
+}
+
+static inline unsigned
+sh_css_dma_get_channel_elements_B(int channel)
+{
+ return _hrt_dma_v1_get_elements(
+ _sh_css_dma_get_channel_parameter(channel, 5));
+}
+
+static inline unsigned
+sh_css_dma_get_channel_cropping_B(int channel)
+{
+ return _hrt_dma_v1_get_cropping(
+ _sh_css_dma_get_channel_parameter(channel, 5));
+}
+
+static inline unsigned
+sh_css_dma_get_channel_width_B(int channel)
+{
+ return _sh_css_dma_get_channel_parameter(channel, 6);
+}
+
+static inline unsigned
+sh_css_dma_get_channel_height(int channel)
+{
+ return _sh_css_dma_get_channel_parameter(channel, 7);
+}
+
+/* Connection group */
+
+static inline unsigned
+_sh_css_dma_get_conn_group_info(int info_id, int comp_id, int gr_id)
+{
+ return _sh_css_dma_get_register(
+ hrt_dma_v1_conn_group_info_register_address(info_id,
+ comp_id, gr_id));
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_command(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(0, 0, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_address_A(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(0, 1, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_address_B(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(0, 2, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_state(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(0, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_request_device(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(1, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_request_address(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(2, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_request_stride(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(3, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_request_width(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(4, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_request_height(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(5, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_pack_request_device(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(6, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_pack_write_device(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(7, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_write_address(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(8, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_write_stride(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(9, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_pack_request_width(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(10, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_pack_write_height(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(11, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_pack_write_width(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(12, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_pack_request_elems(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(13, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_pack_write_elems(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(14, 3, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_control_pack_extension_and_elem_order(int
+ gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(15, 3, gr_id);
+}
+
+static inline unsigned sh_css_dma_get_conn_group_fsm_pack_state(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(0, 4, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_pack_counter_height(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(1, 4, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_pack_request_counter_width(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(2, 4, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_pack_write_counter_width(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(3, 4, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_request_state(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(0, 5, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_request_counter_height(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(1, 5, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_request_counter_width(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(2, 5, gr_id);
+}
+
+static inline unsigned
+sh_css_dma_get_conn_group_fsm_write_height(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(1, 6, gr_id);
+}
+
+static inline unsigned sh_css_dma_get_conn_group_fsm_write_width(int gr_id)
+{
+ return _sh_css_dma_get_conn_group_info(2, 6, gr_id);
+}
+
+/* Device Interface */
+static inline unsigned
+_sh_css_dma_get_device_interface_info(int info_id, int dev_id)
+{
+ return _sh_css_dma_get_register(
+ hrt_dma_v1_device_interface_info_register_address(info_id,
+ dev_id));
+}
+
+static inline unsigned
+sh_css_dma_get_device_interface_request_side_state(int dev_id)
+{
+ return _sh_css_dma_get_device_interface_info(0, dev_id);
+}
+
+static inline unsigned
+sh_css_dma_get_device_interface_send_side_state(int dev_id)
+{
+ return _sh_css_dma_get_device_interface_info(1, dev_id);
+}
+
+static inline unsigned
+sh_css_dma_get_device_interface_fifo_state(int dev_id)
+{
+ return _sh_css_dma_get_device_interface_info(2, dev_id);
+}
+
+void
+sh_css_hrt_dma_get_state(struct sh_css_dma_state *state)
+{
+ int tmp, i, num_ports = 3, num_channels = 8;
+ tmp = sh_css_dma_get_command_fsm_state();
+ state->fsm_command_idle = tmp & 0x1;
+ state->fsm_command_run = tmp & 0x2;
+ state->fsm_command_stalling = tmp & 0x4;
+ state->fsm_command_error = tmp & 0x8;
+ state->last_command_channel = (tmp>>8 & 0xFF);
+ state->last_command_param = (tmp>>16 & 0xF);
+ tmp = (tmp>>4) & 0xF;
+ if (tmp == 0)
+ state->last_command = sh_css_dma_command_read;
+ if (tmp == 1)
+ state->last_command = sh_css_dma_command_write;
+ if (tmp == 2)
+ state->last_command = sh_css_dma_command_set_channel;
+ if (tmp == 3)
+ state->last_command = sh_css_dma_command_set_param;
+ if (tmp == 4)
+ state->last_command = sh_css_dma_command_read_spec;
+ if (tmp == 5)
+ state->last_command = sh_css_dma_command_write_spec;
+ if (tmp == 8)
+ state->last_command = sh_css_dma_command_init;
+ if (tmp == 12)
+ state->last_command = sh_css_dma_command_init_spec;
+ if (tmp == 15)
+ state->last_command = sh_css_dma_command_reset;
+ state->current_command = sh_css_dma_get_conn_group_command(0);
+ state->current_addr_a = sh_css_dma_get_conn_group_address_A(0);
+ state->current_addr_b = sh_css_dma_get_conn_group_address_B(0);
+ tmp = sh_css_dma_get_conn_group_fsm_control_state(0);
+ state->fsm_ctrl_idle = tmp & 0x1;
+ state->fsm_ctrl_run = tmp & 0x2;
+ state->fsm_ctrl_stalling = tmp & 0x4;
+ state->fsm_ctrl_error = tmp & 0x8;
+ tmp = tmp >> 4;
+ if (tmp == 0)
+ state->fsm_ctrl_state = sh_css_dma_ctrl_state_idle;
+ if (tmp == 1)
+ state->fsm_ctrl_state = sh_css_dma_ctrl_state_req_rcv;
+ if (tmp == 2)
+ state->fsm_ctrl_state = sh_css_dma_ctrl_state_rcv;
+ if (tmp == 3)
+ state->fsm_ctrl_state = sh_css_dma_ctrl_state_rcv_req;
+ if (tmp == 4)
+ state->fsm_ctrl_state = sh_css_dma_ctrl_state_init;
+ state->fsm_ctrl_source_dev =
+ sh_css_dma_get_conn_group_fsm_control_request_device(0);
+ state->fsm_ctrl_source_addr =
+ sh_css_dma_get_conn_group_fsm_control_request_address(0);
+ state->fsm_ctrl_source_stride =
+ sh_css_dma_get_conn_group_fsm_control_request_stride(0);
+ state->fsm_ctrl_source_width =
+ sh_css_dma_get_conn_group_fsm_control_request_width(0);
+ state->fsm_ctrl_source_height =
+ sh_css_dma_get_conn_group_fsm_control_request_height(0);
+ state->fsm_ctrl_pack_source_dev =
+ sh_css_dma_get_conn_group_fsm_control_pack_request_device(0);
+ state->fsm_ctrl_pack_dest_dev =
+ sh_css_dma_get_conn_group_fsm_control_pack_write_device(0);
+ state->fsm_ctrl_dest_addr =
+ sh_css_dma_get_conn_group_fsm_control_write_address(0);
+ state->fsm_ctrl_dest_stride =
+ sh_css_dma_get_conn_group_fsm_control_write_stride(0);
+ state->fsm_ctrl_pack_source_width =
+ sh_css_dma_get_conn_group_fsm_control_pack_request_width(0);
+ state->fsm_ctrl_pack_dest_height =
+ sh_css_dma_get_conn_group_fsm_control_pack_write_height(0);
+ state->fsm_ctrl_pack_dest_width =
+ sh_css_dma_get_conn_group_fsm_control_pack_write_width(0);
+ state->fsm_ctrl_pack_source_elems =
+ sh_css_dma_get_conn_group_fsm_control_pack_request_elems(0);
+ state->fsm_ctrl_pack_dest_elems =
+ sh_css_dma_get_conn_group_fsm_control_pack_write_elems(0);
+ state->fsm_ctrl_pack_extension =
+ sh_css_dma_get_conn_group_fsm_control_pack_extension_and_elem_order(0);
+ tmp = sh_css_dma_get_conn_group_fsm_pack_state(0);
+ state->pack_idle = tmp & 0x1;
+ state->pack_run = tmp & 0x2;
+ state->pack_stalling = tmp & 0x4;
+ state->pack_error = tmp & 0x8;
+ state->pack_cnt_height =
+ sh_css_dma_get_conn_group_fsm_pack_counter_height(0);
+ state->pack_src_cnt_width =
+ sh_css_dma_get_conn_group_fsm_pack_request_counter_width(0);
+ state->pack_dest_cnt_width =
+ sh_css_dma_get_conn_group_fsm_pack_write_counter_width(0);
+ tmp = sh_css_dma_get_conn_group_fsm_request_state(0) & 0x3;
+ if (tmp == 0)
+ state->read_state = sh_css_dma_rw_state_idle;
+ if (tmp == 1)
+ state->read_state = sh_css_dma_rw_state_req;
+ if (tmp == 2)
+ state->read_state = sh_css_dma_rw_state_next_line;
+ if (tmp == 3)
+ state->read_state = sh_css_dma_rw_state_unlock_channel;
+ state->read_cnt_height =
+ sh_css_dma_get_conn_group_fsm_request_counter_height(0);
+ state->read_cnt_width =
+ sh_css_dma_get_conn_group_fsm_request_counter_width(0);
+ tmp = sh_css_dma_get_conn_group_fsm_request_state(0) & 0x3;
+ if (tmp == 0)
+ state->write_state = sh_css_dma_rw_state_idle;
+ if (tmp == 1)
+ state->write_state = sh_css_dma_rw_state_req;
+ if (tmp == 2)
+ state->write_state = sh_css_dma_rw_state_next_line;
+ if (tmp == 3)
+ state->write_state = sh_css_dma_rw_state_unlock_channel;
+ state->write_height =
+ sh_css_dma_get_conn_group_fsm_write_height(0);
+ state->write_width = sh_css_dma_get_conn_group_fsm_write_width(0);
+ for (i = 0; i < num_ports; i++) {
+ tmp =
+ sh_css_dma_get_device_interface_request_side_state(i);
+ state->port_states[i].req_cs = (tmp & 0x1) != 0;
+ state->port_states[i].req_we_n = (tmp & 0x2) != 0;
+ state->port_states[i].req_run = (tmp & 0x4) != 0;
+ state->port_states[i].req_ack = (tmp & 0x8) != 0;
+ tmp = sh_css_dma_get_device_interface_send_side_state(i);
+ state->port_states[i].send_cs = (tmp & 0x1) != 0;
+ state->port_states[i].send_we_n = (tmp & 0x2) != 0;
+ state->port_states[i].send_run = (tmp & 0x4) != 0;
+ state->port_states[i].send_ack = (tmp & 0x8) != 0;
+ tmp = sh_css_dma_get_device_interface_fifo_state(i);
+ if (tmp & 0x1) {
+ state->port_states[i].fifo_state =
+ sh_css_dma_fifo_state_will_be_full;
+ }
+ if (tmp & 0x2) {
+ state->port_states[i].fifo_state =
+ sh_css_dma_fifo_state_full;
+ }
+ if (tmp & 0x4) {
+ state->port_states[i].fifo_state =
+ sh_css_dma_fifo_state_empty;
+ }
+ state->port_states[i].fifo_counter = tmp >> 3;
+ }
+ for (i = 0; i < num_channels; i++) {
+ state->channel_states[i].connection =
+ sh_css_dma_get_channel_connection(i);
+ state->channel_states[i].sign_extend =
+ sh_css_dma_get_channel_extension(i);
+ state->channel_states[i].reverse_elem_order =
+ sh_css_dma_get_channel_element_order(i);
+ state->channel_states[i].height =
+ sh_css_dma_get_channel_height(i);
+ state->channel_states[i].stride_a =
+ sh_css_dma_get_channel_stride_A(i);
+ state->channel_states[i].elems_a =
+ sh_css_dma_get_channel_elements_A(i);
+ state->channel_states[i].cropping_a =
+ sh_css_dma_get_channel_cropping_A(i);
+ state->channel_states[i].width_a =
+ sh_css_dma_get_channel_width_A(i);
+ state->channel_states[i].stride_b =
+ sh_css_dma_get_channel_stride_B(i);
+ state->channel_states[i].elems_b =
+ sh_css_dma_get_channel_elements_B(i);
+ state->channel_states[i].cropping_b =
+ sh_css_dma_get_channel_cropping_B(i);
+ state->channel_states[i].width_b =
+ sh_css_dma_get_channel_width_B(i);
+ }
+}
+
+static inline void
+_sh_css_gdc_set_lut_entry(unsigned int index, unsigned int val)
+{
+ hrt_master_port_store_32(gdc_lut_base_address + index, val);
+}
+
+void
+sh_css_hrt_gdc_set_lut(int lut[4][HRT_GDC_N])
+{
+ unsigned int i, entry_0, entry_1, entry_2, entry_3,
+ word_0, word_1, lut_offset = HRT_GDC_LUT_IDX;
+
+ for (i = 0; i < HRT_GDC_N; i++) {
+ entry_0 = lut[0][i] & HRT_GDC_BCI_COEF_MASK;
+ entry_1 = lut[1][i] & HRT_GDC_BCI_COEF_MASK;
+ entry_2 = lut[2][i] & HRT_GDC_BCI_COEF_MASK;
+ entry_3 = lut[3][i] & HRT_GDC_BCI_COEF_MASK;
+ word_0 = entry_0 | (entry_1 << HRT_GDC_BCI_COEF_BITS);
+ word_1 = entry_2 | (entry_3 << HRT_GDC_BCI_COEF_BITS);
+ _sh_css_gdc_set_lut_entry(lut_offset++, word_0);
+ _sh_css_gdc_set_lut_entry(lut_offset++, word_1);
+ }
+}
+
+static inline void
+_sh_css_mmu_set_register(unsigned int index, unsigned int value)
+{
+ hrt_master_port_store_32(mmu_base_address + index, value);
+}
+
+void
+sh_css_hrt_mmu_set_page_table_base_address(void *base_address)
+{
+ _sh_css_mmu_set_register(_HRT_MMU_PAGE_TABLE_BASE_ADDRESS_REG_IDX,
+ (unsigned long)base_address);
+}
+
+void
+sh_css_hrt_mmu_invalidate_cache(void)
+{
+ _sh_css_mmu_set_register(_HRT_MMU_INVALIDATE_TLB_REG_IDX, 1);
+}
+
+static inline unsigned long
+_sh_css_if_get_register(unsigned long *base, unsigned addr)
+{
+ unsigned int bus_addr = (unsigned int)(base + addr);
+ return hrt_master_port_load_32(bus_addr);
+}
+
+static inline unsigned
+sh_css_if_get_start_line(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_START_LINE_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_start_column(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_START_COLUMN_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_cropped_height(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_CROPPED_HEIGHT_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_cropped_width(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_CROPPED_WIDTH_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_vertical_decimation(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_VERTICAL_DECIMATION_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_horizontal_decimation(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_HORIZONTAL_DECIMATION_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_v_deinterleaving(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_V_DEINTERLEAVING_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_h_deinterleaving(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_H_DEINTERLEAVING_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_leftpadding_width(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_LEFTPADDING_WIDTH_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_vmem_start_address(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_VMEM_START_ADDRESS_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_end_of_line_offset(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_END_OF_LINE_OFFSET_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_vmem_end_address(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_VMEM_END_ADDRESS_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_allow_fifo_overflow(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_ALLOW_FIFO_OVERFLOW_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_vmem_increment(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_VMEM_INCREMENT_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_sync_counter(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase, HIVE_IF_FSM_SYNC_COUNTER);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_crop_status(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase, HIVE_IF_FSM_CROP_STATUS);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_crop_line_counter(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_CROP_LINE_COUNTER);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_crop_pixel_counter(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_CROP_PIXEL_COUNTER);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_deinterleaving_index(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_DEINTERLEAVING_IDX);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_dec_h_counter(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_DECIMATION_H_COUNTER);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_dec_v_counter(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_DECIMATION_V_COUNTER);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_dec_block_v_counter(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_DECIMATION_BLOCK_V_COUNTER);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_padding_status(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_PADDING_STATUS);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_padding_elem_counter(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_PADDING_ELEMENT_COUNTER);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_vector_support_error(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_VECTOR_SUPPORT_ERROR);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_vector_buffer_full(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_VECTOR_SUPPORT_BUFF_FULL);
+}
+
+static inline unsigned
+sh_css_if_get_vector_support(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FSM_VECTOR_SUPPORT);
+}
+
+static inline unsigned
+sh_css_if_get_sensor_data_lost(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_FIFO_SENSOR_DATA_LOST);
+}
+
+static inline unsigned
+sh_css_if_get_reset(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase, HIVE_IF_RESET_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_fsm_sync_status(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase, HIVE_IF_FSM_SYNC_STATUS);
+}
+
+static inline unsigned
+sh_css_if_get_yuv_420_format(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_YUV_420_FORMAT_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_vsynck_active_low(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_VSYNCK_ACTIVE_LOW_ADDRESS);
+}
+
+static inline unsigned
+sh_css_if_get_hsynck_active_low(unsigned long *ifbase)
+{
+ return _sh_css_if_get_register(ifbase,
+ HIVE_IF_HSYNCK_ACTIVE_LOW_ADDRESS);
+}
+
+static void
+sh_css_if_get_state(unsigned long *ifbase, struct sh_css_if_state *state)
+{
+ state->reset = sh_css_if_get_reset(ifbase);
+ state->start_line = sh_css_if_get_start_line(ifbase);
+ state->start_column = sh_css_if_get_start_column(ifbase);
+ state->cropped_height = sh_css_if_get_cropped_height(ifbase);
+ state->cropped_width = sh_css_if_get_cropped_width(ifbase);
+ state->ver_decimation = sh_css_if_get_vertical_decimation(ifbase);
+ state->hor_decimation = sh_css_if_get_horizontal_decimation(ifbase);
+ state->deinterleaving = sh_css_if_get_h_deinterleaving(ifbase);
+ state->left_padding = sh_css_if_get_leftpadding_width(ifbase);
+ state->eol_offset = sh_css_if_get_end_of_line_offset(ifbase);
+ state->vmem_start_address = sh_css_if_get_vmem_start_address(ifbase);
+ state->vmem_end_address = sh_css_if_get_vmem_end_address(ifbase);
+ state->vmem_increment = sh_css_if_get_vmem_increment(ifbase);
+ state->yuv420 = sh_css_if_get_yuv_420_format(ifbase);
+ state->vsync_active_low = sh_css_if_get_vsynck_active_low(ifbase);
+ state->hsync_active_low = sh_css_if_get_hsynck_active_low(ifbase);
+ state->allow_fifo_overflow = sh_css_if_get_allow_fifo_overflow(ifbase);
+ state->fsm_sync_status = sh_css_if_get_fsm_sync_status(ifbase);
+ state->fsm_sync_counter = sh_css_if_get_fsm_sync_counter(ifbase);
+ state->fsm_crop_status = sh_css_if_get_fsm_crop_status(ifbase);
+ state->fsm_crop_line_counter =
+ sh_css_if_get_fsm_crop_line_counter(ifbase);
+ state->fsm_crop_pixel_counter =
+ sh_css_if_get_fsm_crop_pixel_counter(ifbase);
+ state->fsm_deinterleaving_index =
+ sh_css_if_get_fsm_deinterleaving_index(ifbase);
+ state->fsm_dec_h_counter = sh_css_if_get_fsm_dec_h_counter(ifbase);
+ state->fsm_dec_v_counter = sh_css_if_get_fsm_dec_v_counter(ifbase);
+ state->fsm_dec_block_v_counter =
+ sh_css_if_get_fsm_dec_block_v_counter(ifbase);
+ state->fsm_padding_status = sh_css_if_get_fsm_padding_status(ifbase);
+ state->fsm_padding_elem_counter =
+ sh_css_if_get_fsm_padding_elem_counter(ifbase);
+ state->fsm_vector_support_error =
+ sh_css_if_get_fsm_vector_support_error(ifbase);
+ state->fsm_vector_buffer_full =
+ sh_css_if_get_fsm_vector_buffer_full(ifbase);
+ state->vector_support = sh_css_if_get_vector_support(ifbase);
+ state->sensor_data_lost = sh_css_if_get_sensor_data_lost(ifbase);
+}
+
+unsigned int
+sh_css_hrt_if_prim_vec_align(void)
+{
+ return _HRT_IF_VEC_ALIGN(IF_PRIM);
+}
+
+void
+sh_css_hrt_if_prim_a_get_state(struct sh_css_if_state *state)
+{
+ sh_css_if_get_state(if_prim_a_base_address, state);
+}
+
+void
+sh_css_hrt_if_prim_b_get_state(struct sh_css_if_state *state)
+{
+ sh_css_if_get_state(if_prim_b_base_address, state);
+}
+
+/* Streaming monitors */
+static inline unsigned long
+sh_css_stream_monitor_get_register(unsigned addr)
+{
+ unsigned int bus_addr = (unsigned int)(str_monitor_base_address + addr);
+ return hrt_master_port_load_32(bus_addr);
+}
+
+static inline unsigned int
+sh_css_sp_stream_monitor_get_status(void)
+{
+ return sh_css_stream_monitor_get_register(HIVE_GP_REGS_SP_STREAM_STAT);
+}
+
+static inline unsigned int
+sh_css_isp_stream_monitor_get_status(void)
+{
+ return sh_css_stream_monitor_get_register(HIVE_GP_REGS_ISP_STREAM_STAT);
+}
+
+static inline unsigned int
+sh_css_mod_stream_monitor_get_status(void)
+{
+ return sh_css_stream_monitor_get_register(HIVE_GP_REGS_MOD_STREAM_STAT);
+}
+
+/* use the following function if the stream stat word is already available. */
+static inline unsigned int
+sh_css_get_stream_stat_valid(unsigned int stream_stat_word,
+ unsigned int port_id)
+{
+ return ((stream_stat_word) >>
+ (((port_id * 2) + _hive_str_mon_valid_offset))) & 0x1;
+}
+
+static inline unsigned int
+sh_css_get_stream_stat_accept(unsigned int stream_stat_word,
+ unsigned int port_id)
+{
+ return ((stream_stat_word) >>
+ (((port_id * 2) + _hive_str_mon_accept_offset))) & 0x1;
+}
+
+/* Following functions are intended for single bit lookup.
+ * If multiple valid/accept bits are required from the same words
+ * use the hrt_get_*_stream_stat_word in combination with
+ * hrt_gets_stream_valid/accept functions.
+ */
+static inline unsigned int
+sh_css_get_sp_stream_stat_valid(unsigned int port_id)
+{
+ unsigned int status;
+ status = sh_css_sp_stream_monitor_get_status();
+ return sh_css_get_stream_stat_valid(status, port_id);
+}
+
+static inline unsigned int
+sh_css_get_sp_stream_stat_accept(unsigned int port_id)
+{
+ unsigned int status;
+ status = sh_css_sp_stream_monitor_get_status();
+ return sh_css_get_stream_stat_accept(status, port_id);
+}
+
+static inline unsigned int
+sh_css_get_isp_stream_stat_valid(unsigned int port_id)
+{
+ unsigned int status;
+ status = sh_css_isp_stream_monitor_get_status();
+ return sh_css_get_stream_stat_valid(status, port_id);
+}
+
+static inline unsigned int
+sh_css_get_isp_stream_stat_accept(unsigned int port_id)
+{
+ unsigned int status;
+ status = sh_css_isp_stream_monitor_get_status();
+ return sh_css_get_stream_stat_accept(status, port_id);
+}
+
+static inline unsigned int
+sh_css_get_mod_stream_stat_valid(unsigned int port_id)
+{
+ unsigned int status;
+ status = sh_css_mod_stream_monitor_get_status();
+ return sh_css_get_stream_stat_valid(status, port_id);
+}
+
+static inline unsigned int
+sh_css_get_mod_stream_stat_accept(unsigned int port_id)
+{
+ unsigned int status;
+ status = sh_css_mod_stream_monitor_get_status();
+ return sh_css_get_stream_stat_accept(status, port_id);
+}
+
+ShBool
+sh_css_hrt_system_is_idle(void)
+{
+ ShBool not_idle = ShFalse;
+
+ not_idle |= !sh_css_cell_is_ready(isp_sc_base_address + isp_sc_reg,
+ isp_idle_bit);
+ /* ISP to SP */
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_SND_SP);
+ not_idle |=
+ sh_css_get_sp_stream_stat_valid(SP_STR_MON_PORT_RCV_ISP);
+ /* SP to ISP */
+ not_idle |=
+ sh_css_get_sp_stream_stat_valid(SP_STR_MON_PORT_SND_ISP);
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_RCV_SP);
+ /* IF_PRIM_A to ISP */
+ not_idle |=
+ sh_css_get_mod_stream_stat_valid(MOD_STR_MON_PORT_SND_PIF_A);
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_RCV_PIF_A);
+ /* ISP to IF_PRIM_A */
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_SND_PIF_A);
+ not_idle |=
+ sh_css_get_mod_stream_stat_valid(MOD_STR_MON_PORT_RCV_PIF_A);
+ /* IF_PRIM_B to ISP */
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_RCV_PIF_B);
+ /* ISP to IF_PRIM_B */
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_SND_PIF_B);
+ /* DMA to SP */
+#ifndef SYSTEM_hive_isp_css_2400_system
+ not_idle |=
+ sh_css_get_mod_stream_stat_valid(MOD_STR_MON_PORT_SND_DMA);
+#endif
+ not_idle |=
+ sh_css_get_sp_stream_stat_valid(SP_STR_MON_PORT_RCV_DMA);
+ /* SP to DMA */
+ not_idle |=
+ sh_css_get_sp_stream_stat_valid(SP_STR_MON_PORT_SND_DMA);
+#ifndef SYSTEM_hive_isp_css_2400_system
+ not_idle |=
+ sh_css_get_mod_stream_stat_valid(MOD_STR_MON_PORT_RCV_DMA);
+#endif
+ /* DMA to ISP */
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_RCV_DMA);
+ /* ISP to DMA */
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_SND_DMA);
+ /* GDC to SP/ISP */
+ not_idle |=
+ sh_css_get_mod_stream_stat_valid(MOD_STR_MON_PORT_SND_GDC);
+ not_idle |=
+ sh_css_get_sp_stream_stat_valid(SP_STR_MON_PORT_RCV_GDC);
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_RCV_GDC);
+ /* SP/ISP to GDC */
+ not_idle |=
+ sh_css_get_sp_stream_stat_valid(SP_STR_MON_PORT_SND_GDC);
+ not_idle |=
+ sh_css_get_isp_stream_stat_valid(ISP_STR_MON_PORT_SND_GDC);
+ not_idle |=
+ sh_css_get_mod_stream_stat_valid(MOD_STR_MON_PORT_RCV_GDC);
+ /* Stream2Mem to SP */
+ not_idle |=
+ sh_css_get_mod_stream_stat_valid(MOD_STR_MON_PORT_SND_MC);
+ not_idle |=
+ sh_css_get_sp_stream_stat_valid(SP_STR_MON_PORT_RCV_MC);
+ /* SP to Stream2Mem */
+ not_idle |=
+ sh_css_get_sp_stream_stat_valid(SP_STR_MON_PORT_SND_MC);
+ not_idle |=
+ sh_css_get_mod_stream_stat_valid(MOD_STR_MON_PORT_RCV_MC);
+ return !not_idle;
+}
+
+void
+sh_css_hrt_fifo_channel_get_state(enum sh_css_fifo_channel channel,
+ struct sh_css_fifo_channel_state *state)
+{
+ switch (channel) {
+ case sh_css_hrt_fifo_isp_to_sp:
+ state->src_valid = sh_css_get_isp_stream_stat_valid(
+ ISP_STR_MON_PORT_SND_SP);
+ state->fifo_accept = sh_css_get_isp_stream_stat_accept(
+ ISP_STR_MON_PORT_SND_SP);
+ state->fifo_valid = sh_css_get_sp_stream_stat_valid(
+ SP_STR_MON_PORT_RCV_ISP);
+ state->sink_accept = sh_css_get_sp_stream_stat_accept(
+ SP_STR_MON_PORT_RCV_ISP);
+ break;
+ case sh_css_hrt_fifo_sp_to_isp:
+ state->src_valid = sh_css_get_sp_stream_stat_valid(
+ SP_STR_MON_PORT_SND_ISP);
+ state->fifo_accept = sh_css_get_sp_stream_stat_accept(
+ SP_STR_MON_PORT_SND_ISP);
+ state->fifo_valid = sh_css_get_isp_stream_stat_valid(
+ ISP_STR_MON_PORT_RCV_SP);
+ state->sink_accept = sh_css_get_isp_stream_stat_accept(
+ ISP_STR_MON_PORT_RCV_SP);
+ break;
+ case sh_css_hrt_fifo_isp_to_if_prim_a:
+ state->src_valid = sh_css_get_isp_stream_stat_valid(
+ ISP_STR_MON_PORT_SND_PIF_A);
+ state->fifo_accept = sh_css_get_isp_stream_stat_accept(
+ ISP_STR_MON_PORT_SND_PIF_A);
+ state->fifo_valid = sh_css_get_mod_stream_stat_valid(
+ MOD_STR_MON_PORT_RCV_PIF_A);
+ state->sink_accept = sh_css_get_mod_stream_stat_accept(
+ MOD_STR_MON_PORT_RCV_PIF_A);
+ break;
+ case sh_css_hrt_fifo_if_prim_a_to_isp:
+ state->src_valid = sh_css_get_mod_stream_stat_valid(
+ MOD_STR_MON_PORT_SND_PIF_A);
+ state->fifo_accept = sh_css_get_mod_stream_stat_accept(
+ MOD_STR_MON_PORT_SND_PIF_A);
+ state->fifo_valid = sh_css_get_isp_stream_stat_valid(
+ ISP_STR_MON_PORT_RCV_PIF_A);
+ state->sink_accept = sh_css_get_isp_stream_stat_accept(
+ ISP_STR_MON_PORT_RCV_PIF_A);
+ break;
+ case sh_css_hrt_fifo_isp_to_if_prim_b:
+ state->src_valid = sh_css_get_isp_stream_stat_valid(
+ ISP_STR_MON_PORT_SND_PIF_B);
+ state->fifo_accept = sh_css_get_isp_stream_stat_accept(
+ ISP_STR_MON_PORT_SND_PIF_B);
+ state->fifo_valid = ShFalse; /* no monitor connected */
+ state->sink_accept = ShFalse; /* no monitor connected */
+ break;
+ case sh_css_hrt_fifo_if_prim_b_to_isp:
+ state->src_valid = ShFalse; /* no monitor connected */
+ state->fifo_accept = ShFalse; /* no monitor connected */
+ state->fifo_valid = sh_css_get_isp_stream_stat_valid(
+ ISP_STR_MON_PORT_RCV_PIF_B);
+ state->sink_accept = sh_css_get_isp_stream_stat_accept(
+ ISP_STR_MON_PORT_RCV_PIF_B);
+ break;
+ case sh_css_hrt_fifo_isp_to_dma:
+ state->src_valid = sh_css_get_isp_stream_stat_valid(
+ ISP_STR_MON_PORT_SND_DMA);
+ state->fifo_accept = sh_css_get_isp_stream_stat_accept(
+ ISP_STR_MON_PORT_SND_DMA);
+ state->fifo_valid = sh_css_get_mod_stream_stat_valid(
+ MOD_STR_MON_PORT_RCV_DMA);
+ state->sink_accept = sh_css_get_mod_stream_stat_accept(
+ MOD_STR_MON_PORT_RCV_DMA);
+ break;
+ case sh_css_hrt_fifo_dma_to_isp:
+ state->src_valid = sh_css_get_mod_stream_stat_valid(
+ MOD_STR_MON_PORT_SND_DMA);
+ state->fifo_accept = sh_css_get_mod_stream_stat_accept(
+ MOD_STR_MON_PORT_SND_DMA);
+ state->fifo_valid = sh_css_get_isp_stream_stat_valid(
+ ISP_STR_MON_PORT_RCV_DMA);
+ state->sink_accept = sh_css_get_isp_stream_stat_accept(
+ ISP_STR_MON_PORT_RCV_DMA);
+ break;
+ case sh_css_hrt_fifo_sp_to_dma:
+ state->src_valid = sh_css_get_sp_stream_stat_valid(
+ SP_STR_MON_PORT_SND_DMA);
+ state->fifo_accept = sh_css_get_sp_stream_stat_accept(
+ SP_STR_MON_PORT_SND_DMA);
+ state->fifo_valid = sh_css_get_mod_stream_stat_valid(
+ MOD_STR_MON_PORT_RCV_DMA);
+ state->sink_accept = sh_css_get_mod_stream_stat_accept(
+ MOD_STR_MON_PORT_RCV_DMA);
+ break;
+ case sh_css_hrt_fifo_dma_to_sp:
+ state->src_valid = sh_css_get_mod_stream_stat_valid(
+ MOD_STR_MON_PORT_SND_DMA);
+ state->fifo_accept = sh_css_get_mod_stream_stat_accept(
+ MOD_STR_MON_PORT_SND_DMA);
+ state->fifo_valid = sh_css_get_sp_stream_stat_valid(
+ SP_STR_MON_PORT_RCV_DMA);
+ state->sink_accept = sh_css_get_sp_stream_stat_accept(
+ SP_STR_MON_PORT_RCV_DMA);
+ break;
+ }
+}
+
+static inline unsigned long
+_sh_css_irq_get_reg(unsigned addr)
+{
+ unsigned int bus_addr = (unsigned int)(irq_ctrl_base_address + addr);
+ return hrt_master_port_load_32(bus_addr);
+}
+
+static inline void
+_sh_css_irq_set_reg(unsigned addr, unsigned long value)
+{
+ hrt_master_port_store_32(irq_ctrl_base_address + addr, value);
+}
+
+/* set register */
+static inline void
+sh_css_irq_set_edge_reg(unsigned long val)
+{
+ _sh_css_irq_set_reg(_HRT_IRQ_CONTROLLER_EDGE_REG_IDX, val);
+}
+
+static inline void
+sh_css_irq_set_mask_reg(unsigned long val)
+{
+ _sh_css_irq_set_reg(_HRT_IRQ_CONTROLLER_MASK_REG_IDX, val);
+}
+
+static inline void
+sh_css_irq_clear_status_reg(unsigned long val)
+{
+ _sh_css_irq_set_reg(_HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, val);
+}
+
+static inline void
+sh_css_irq_set_enable_reg(unsigned long val)
+{
+ _sh_css_irq_set_reg(_HRT_IRQ_CONTROLLER_ENABLE_REG_IDX, val);
+}
+
+static inline void
+sh_css_irq_set_edge_not_pulse_reg(unsigned long val)
+{
+ _sh_css_irq_set_reg(_HRT_IRQ_CONTROLLER_EDGE_NOT_PULSE_REG_IDX, val);
+}
+
+static inline unsigned
+sh_css_irq_get_edge_reg(void)
+{
+ return _sh_css_irq_get_reg(_HRT_IRQ_CONTROLLER_EDGE_REG_IDX);
+}
+
+static inline unsigned
+sh_css_irq_get_mask_reg(void)
+{
+ return _sh_css_irq_get_reg(_HRT_IRQ_CONTROLLER_MASK_REG_IDX);
+}
+
+static inline unsigned
+sh_css_irq_get_status_reg(void)
+{
+ return _sh_css_irq_get_reg(_HRT_IRQ_CONTROLLER_STATUS_REG_IDX);
+}
+
+static inline unsigned
+sh_css_irq_get_enable_reg(void)
+{
+ return _sh_css_irq_get_reg(_HRT_IRQ_CONTROLLER_ENABLE_REG_IDX);
+}
+
+static inline unsigned
+sh_css_irq_get_edge_not_pulse_reg(void)
+{
+ return _sh_css_irq_get_reg(_HRT_IRQ_CONTROLLER_EDGE_NOT_PULSE_REG_IDX);
+}
+
+static inline void
+sh_css_irq_clear_all(void)
+{
+ sh_css_irq_clear_status_reg(0xFFFFFFFF);
+}
+
+static inline void
+sh_css_irq_enable(enum hrt_isp_css_irq irq_id,
+ ShBool rising_edge_in,
+ ShBool edge_not_pulse_out)
+{
+ unsigned int mask = sh_css_irq_get_mask_reg();
+ unsigned int enable = sh_css_irq_get_enable_reg();
+ unsigned int edge_in = sh_css_irq_get_edge_reg();
+ unsigned int edge_out = sh_css_irq_get_edge_not_pulse_reg();
+ unsigned int me = 1u << irq_id;
+
+ mask |= me;
+ enable |= me;
+ if (rising_edge_in)
+ edge_in |= me;
+ if (edge_not_pulse_out)
+ edge_out |= me;
+
+ /* to avoid mishaps configuration must follow the following order */
+ /* rising edge at input */
+ sh_css_irq_set_edge_reg(edge_in);
+ /* enable interrupt to output */
+ sh_css_irq_set_enable_reg(enable);
+ /* unmask interrupt from input */
+ sh_css_irq_set_mask_reg(mask);
+ /* output is given as edge, not pulse */
+ sh_css_irq_set_edge_not_pulse_reg(edge_out);
+ /* clear current irq only */
+ sh_css_irq_clear_status_reg(me);
+}
+
+static inline void
+sh_css_irq_disable(enum hrt_isp_css_irq irq_id)
+{
+ unsigned int mask = sh_css_irq_get_mask_reg();
+ unsigned int enable = sh_css_irq_get_enable_reg();
+ unsigned int me = 1u << irq_id;
+
+ mask &= ~me;
+ enable &= ~me;
+
+ /* enable interrupt to output */
+ sh_css_irq_set_enable_reg(enable);
+ /* unmask interrupt from input */
+ sh_css_irq_set_mask_reg(mask);
+ /* clear current irq only */
+ sh_css_irq_clear_status_reg(me);
+}
+
+static inline enum hrt_isp_css_irq_status
+sh_css_irq_get_id(enum hrt_isp_css_irq *irq_id)
+{
+ unsigned int irq_status = sh_css_irq_get_status_reg();
+ unsigned int irq_mask = sh_css_irq_get_mask_reg();
+ unsigned int i;
+ int irq_idx_found = -1;
+ enum hrt_isp_css_irq_status status = hrt_isp_css_irq_status_success;
+
+ /* find the first irq bit */
+ for (i = 0;
+ (i < hrt_isp_css_irq_num_irqs) && (irq_idx_found == -1);
+ i++) {
+ if (irq_status & (1u << i))
+ irq_idx_found = i;
+ }
+ if (irq_idx_found == -1)
+ return hrt_isp_css_irq_status_error;
+
+ /* now check whether there are more bits set */
+ for (i = irq_idx_found + 1; (i < hrt_isp_css_irq_num_irqs)
+ && (status == hrt_isp_css_irq_status_success); i++) {
+ if (irq_status & (1u << i))
+ status = hrt_isp_css_irq_status_more_irqs;
+ }
+
+ /* now we clear the irq status bit, to avoid generating a
+ * new IRQ, we must set the mask temporarily to zero.
+ */
+ sh_css_irq_set_mask_reg(0);
+ sh_css_irq_clear_status_reg(1u << irq_idx_found);
+ sh_css_irq_set_mask_reg(irq_mask);
+ if (irq_id)
+ *irq_id = (enum hrt_isp_css_irq) irq_idx_found;
+ return status;
+}
+
+void
+sh_css_hrt_irq_enable(enum hrt_isp_css_irq irq,
+ ShBool rising_edge_in,
+ ShBool edge_not_pulse_out)
+{
+ sh_css_irq_enable(irq, rising_edge_in, edge_not_pulse_out);
+}
+
+void
+sh_css_hrt_irq_disable(enum hrt_isp_css_irq irq)
+{
+ sh_css_irq_disable(irq);
+}
+
+void
+sh_css_hrt_irq_clear_all(void)
+{
+ sh_css_irq_clear_all();
+}
+
+enum hrt_isp_css_irq_status
+sh_css_hrt_irq_get_id(enum hrt_isp_css_irq *irq)
+{
+ return sh_css_irq_get_id(irq);
+}
+
+/* Streaming to MIPI */
+static inline unsigned
+_sh_css_wrap_marker(unsigned marker)
+{
+ return marker |
+ (curr_ch_id << HIVE_STR_TO_MIPI_CH_ID_LSB) |
+ (curr_fmt_type << _HIVE_STR_TO_MIPI_FMT_TYPE_LSB);
+}
+
+static inline void
+_sh_css_fifo_snd(unsigned token)
+{
+ hrt_master_port_store_32(gp_fifo_base_address, token);
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_data_a(unsigned int data)
+{
+ unsigned int token = (1 << HIVE_STR_TO_MIPI_VALID_A_BIT) |
+ (data << HIVE_STR_TO_MIPI_DATA_A_LSB);
+ _sh_css_fifo_snd(token);
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_data_b(unsigned int data)
+{
+ unsigned int token = (1 << HIVE_STR_TO_MIPI_VALID_B_BIT) |
+ (data << _HIVE_STR_TO_MIPI_DATA_B_LSB);
+ _sh_css_fifo_snd(token);
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_data(unsigned int a, unsigned int b)
+{
+ unsigned int token = ((1 << HIVE_STR_TO_MIPI_VALID_A_BIT) |
+ (1 << HIVE_STR_TO_MIPI_VALID_B_BIT) |
+ (a << HIVE_STR_TO_MIPI_DATA_A_LSB) |
+ (b << _HIVE_STR_TO_MIPI_DATA_B_LSB));
+ _sh_css_fifo_snd(token);
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_sol(void)
+{
+ _sh_css_fifo_snd(_sh_css_wrap_marker(1 << HIVE_STR_TO_MIPI_SOL_BIT));
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_eol(void)
+{
+ _sh_css_fifo_snd(_sh_css_wrap_marker(1 << HIVE_STR_TO_MIPI_EOL_BIT));
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_sof(void)
+{
+ _sh_css_fifo_snd(_sh_css_wrap_marker(1 << HIVE_STR_TO_MIPI_SOF_BIT));
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_eof(void)
+{
+ _sh_css_fifo_snd(_sh_css_wrap_marker(1 << HIVE_STR_TO_MIPI_EOF_BIT));
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_ch_id(unsigned int ch_id)
+{
+ curr_ch_id = ch_id & _HIVE_ISP_CH_ID_MASK;
+ /* we send an zero marker, this will wrap the ch_id and
+ * fmt_type automatically.
+ */
+ _sh_css_fifo_snd(_sh_css_wrap_marker(0));
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_fmt_type(unsigned int fmt_type)
+{
+ curr_fmt_type = fmt_type & _HIVE_ISP_FMT_TYPE_MASK;
+ /* we send an zero marker, this will wrap the ch_id and
+ * fmt_type automatically.
+ */
+ _sh_css_fifo_snd(_sh_css_wrap_marker(0));
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_ch_id_and_fmt_type(unsigned int ch_id,
+ unsigned int fmt_type)
+{
+ curr_ch_id = ch_id & _HIVE_ISP_CH_ID_MASK;
+ curr_fmt_type = fmt_type & _HIVE_ISP_FMT_TYPE_MASK;
+ /* we send an zero marker, this will wrap the ch_id and
+ * fmt_type automatically.
+ */
+ _sh_css_fifo_snd(_sh_css_wrap_marker(0));
+}
+
+static inline void
+sh_css_streaming_to_mipi_send_empty_token(void)
+{
+ _sh_css_fifo_snd(_sh_css_wrap_marker(0));
+}
+
+static inline void
+sh_css_streaming_to_mipi_start_frame(unsigned int ch_id,
+ unsigned int fmt_type)
+{
+ sh_css_streaming_to_mipi_send_ch_id_and_fmt_type(ch_id, fmt_type);
+ sh_css_streaming_to_mipi_send_sof();
+}
+
+static void
+sh_css_streaming_to_mipi_end_frame(unsigned int marker_cycles)
+{
+ unsigned int i;
+ for (i = 0; i < marker_cycles; i++)
+ sh_css_streaming_to_mipi_send_empty_token();
+ sh_css_streaming_to_mipi_send_eof();
+}
+
+static void
+sh_css_streaming_to_mipi_send_line(unsigned short *data,
+ unsigned int width,
+ unsigned int hblank_cycles,
+ unsigned int marker_cycles,
+ unsigned int two_ppc,
+ enum sh_css_mipi_data_type type)
+{
+ unsigned int i, is_rgb = 0, is_legacy = 0;
+
+ if (type == sh_css_mipi_data_type_rgb)
+ is_rgb = 1;
+
+ if (type == sh_css_mipi_data_type_yuv420_legacy)
+ is_legacy = 1;
+
+ for (i = 0; i < hblank_cycles; i++)
+ sh_css_streaming_to_mipi_send_empty_token();
+ sh_css_streaming_to_mipi_send_sol();
+ for (i = 0; i < marker_cycles; i++)
+ sh_css_streaming_to_mipi_send_empty_token();
+ for (i = 0; i < width; i++, data++) {
+ /* for RGB in two_ppc, we only actually send 2 pixels per
+ * clock in the even pixels (0, 2 etc). In the other cycles,
+ * we only send 1 pixel, to data[0].
+ */
+ unsigned int send_two_pixels = two_ppc;
+ if ((is_rgb || is_legacy) && (i % 3 == 2))
+ send_two_pixels = 0;
+ if (send_two_pixels) {
+ if (i + 1 == width) {
+ /* for jpg (binary) copy, this can occur
+ * if the file contains an odd number of bytes.
+ */
+ sh_css_streaming_to_mipi_send_data(data[0],
+ 0);
+ } else {
+ sh_css_streaming_to_mipi_send_data(data[0],
+ data
+ [1]);
+ }
+ data++;
+ i++;
+ } else if (two_ppc && is_legacy) {
+ sh_css_streaming_to_mipi_send_data_b(data[0]);
+ } else {
+ sh_css_streaming_to_mipi_send_data_a(data[0]);
+ }
+ hrt_sleep();
+ }
+ for (i = 0; i < hblank_cycles; i++)
+ sh_css_streaming_to_mipi_send_empty_token();
+ sh_css_streaming_to_mipi_send_eol();
+}
+
+/* Send a frame of data into the input network via the GP FIFO.
+ * Parameters:
+ * - data: array of 16 bit values that contains all data for the frame.
+ * - width: width of a line in number of subpixels, for yuv420 it is the
+ * number of Y components per line.
+ * - height: height of the frame in number of lines.
+ * - ch_id: channel ID.
+ * - fmt_type: format type.
+ * - hblank_cycles: length of horizontal blanking in cycles.
+ * - marker_cycles: number of empty cycles after start-of-line and before
+ * end-of-frame.
+ * - two_ppc: boolean, describes whether to send one or two pixels per clock
+ * cycle. In this mode, we sent pixels N and N+1 in the same cycle,
+ * to IF_PRIM_A and IF_PRIM_B respectively. The caller must make
+ * sure the input data has been formatted correctly for this.
+ * For example, for RGB formats this means that unused values
+ * must be inserted.
+ * - yuv420: boolean, describes whether (non-legacy) yuv420 data is used. In
+ * this mode, the odd lines (1,3,5 etc) are half as long as the
+ * even lines (2,4,6 etc).
+ * Note that the first line is odd (1) and the second line is even
+ * (2).
+ *
+ * This function does not do any reordering of pixels, the caller must make
+ * sure the data is in the righ format. Please refer to the CSS receiver
+ * documentation for details on the data formats.
+ */
+static void
+sh_css_streaming_to_mipi_send_frame(unsigned short *data,
+ unsigned int width,
+ unsigned int height,
+ unsigned int ch_id,
+ unsigned int fmt_type,
+ unsigned int hblank_cycles,
+ unsigned int marker_cycles,
+ unsigned int two_ppc,
+ enum sh_css_mipi_data_type type)
+{
+ unsigned int i;
+
+ sh_css_streaming_to_mipi_start_frame(ch_id, fmt_type);
+ for (i = 0; i < height; i++) {
+ if ((type == sh_css_mipi_data_type_yuv420) &&
+ (i & 1) == 1) {
+ sh_css_streaming_to_mipi_send_line(data, 2 * width,
+ hblank_cycles,
+ marker_cycles,
+ two_ppc, type);
+ data += 2 * width;
+ } else {
+ sh_css_streaming_to_mipi_send_line(data, width,
+ hblank_cycles,
+ marker_cycles,
+ two_ppc, type);
+ data += width;
+ }
+ }
+ sh_css_streaming_to_mipi_end_frame(marker_cycles);
+}
+
+void
+sh_css_hrt_send_input_frame(unsigned short *data,
+ unsigned int width,
+ unsigned int height,
+ unsigned int ch_id,
+ enum sh_css_input_format input_format,
+ ShBool two_ppc)
+{
+ unsigned int fmt_type, hblank_cycles, marker_cycles;
+ enum sh_css_mipi_data_type str_to_mipi_type;
+
+ hblank_cycles = 187;
+ marker_cycles = 6;
+ sh_css_input_format_type(input_format,
+ sh_css_mipi_compression_none,
+ &fmt_type);
+ str_to_mipi_type = sh_css_mipi_data_type_regular;
+ if (input_format == sh_css_input_format_yuv420_8_legacy) {
+ str_to_mipi_type =
+ sh_css_mipi_data_type_yuv420_legacy;
+ } else if (input_format == sh_css_input_format_yuv420_8 ||
+ input_format == sh_css_input_format_yuv420_10) {
+ str_to_mipi_type =
+ sh_css_mipi_data_type_yuv420;
+ } else if (input_format >= sh_css_input_format_rgb_444 &&
+ input_format <= sh_css_input_format_rgb_888) {
+ str_to_mipi_type =
+ sh_css_mipi_data_type_rgb;
+ }
+ sh_css_streaming_to_mipi_send_frame(data, width, height,
+ ch_id, fmt_type, hblank_cycles, marker_cycles,
+ two_ppc, str_to_mipi_type);
+}
+
+#ifdef CSS_RECEIVER
+static inline unsigned long
+_sh_css_rx_get_register(enum sh_css_mipi_port port, unsigned int reg)
+{
+ unsigned int bus_addr = (unsigned int)(css_rx_base_address + reg);
+ if (port == sh_css_mipi_port_1lane)
+ bus_addr += hrt_css_receiver_ahb_1_lane_port_offset;
+ else
+ bus_addr += hrt_css_receiver_ahb_4_lane_port_offset;
+ return hrt_master_port_load_32(bus_addr);
+}
+
+static inline void
+_sh_css_rx_set_register(enum sh_css_mipi_port port,
+ unsigned int reg,
+ unsigned long val)
+{
+ unsigned int bus_addr = (unsigned int)(css_rx_base_address + reg);
+ if (port == sh_css_mipi_port_1lane)
+ bus_addr += hrt_css_receiver_ahb_1_lane_port_offset;
+ else
+ bus_addr += hrt_css_receiver_ahb_4_lane_port_offset;
+ hrt_master_port_store_32(bus_addr, val);
+}
+
+static inline void
+_sh_css_rx_set_bits(enum sh_css_mipi_port port,
+ unsigned int reg,
+ unsigned long bits)
+{
+ unsigned long val;
+ val = _sh_css_rx_get_register(port, reg);
+ val |= bits;
+ _sh_css_rx_set_register(port, reg, val);
+}
+
+static inline void
+_sh_css_rx_reset_bits(enum sh_css_mipi_port port,
+ unsigned int reg,
+ unsigned long bits)
+{
+ unsigned long val;
+ val = _sh_css_rx_get_register(port, reg);
+ val &= ~bits;
+ _sh_css_rx_set_register(port, reg, val);
+}
+#endif
+
+void
+sh_css_hrt_receiver_enable_error_interrupts(enum sh_css_mipi_port port,
+ ShBool enable)
+{
+#ifdef CSS_RECIEVER
+ unsigned long bits;
+ bits = _HRT_CSS_RECEIVER_AHB_IRQ_OVERRUN_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_SLEEP_MODE_ENTRY_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_SLEEP_MODE_EXIT_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_SOT_HS_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_SOT_SYNC_HS_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_CONTROL_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ECC_DOUBLE_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ECC_CORRECTED_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ECC_NO_CORRECTION_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_CRC_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ID_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_FRAME_SYNC_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_FRAME_DATA_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_DATA_TIMEOUT_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ESCAPE_BIT;
+ if (enable)
+ _sh_css_rx_set_bits(_HRT_CSS_RECEIVER_AHB_IRQ_ENABLE_REG_IDX,
+ bits);
+ else
+ _sh_css_rx_reset_bits(_HRT_CSS_RECEIVER_AHB_IRQ_ENABLE_REG_IDX,
+ bits);
+#else
+ port = port;
+ enable = enable;
+#endif
+}
+
+unsigned long
+sh_css_hrt_receiver_get_interrupt_status(enum sh_css_mipi_port port)
+{
+#ifdef CSS_RECEIVER
+ return _sh_css_rx_get_register(port,
+ _HRT_CSS_RECEIVER_AHB_IRQ_STATUS_REG_IDX);
+#else
+ port = port;
+ return 0;
+#endif
+}
+
+void
+sh_css_hrt_receiver_clear_interrupts(enum sh_css_mipi_port port)
+{
+#ifdef CSS_RECEIVER
+ unsigned long bits;
+ bits = _HRT_CSS_RECEIVER_AHB_IRQ_OVERRUN_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_SLEEP_MODE_ENTRY_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_SLEEP_MODE_EXIT_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_SOT_HS_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_SOT_SYNC_HS_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_CONTROL_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ECC_DOUBLE_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ECC_CORRECTED_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ECC_NO_CORRECTION_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_CRC_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ID_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_FRAME_SYNC_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_FRAME_DATA_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_DATA_TIMEOUT_BIT |
+ _HRT_CSS_RECEIVER_AHB_IRQ_ERR_ESCAPE_BIT;
+ _sh_css_rx_set_bits(port,
+ _HRT_CSS_RECEIVER_AHB_IRQ_STATUS_REG_IDX, bits);
+#else
+ port = port;
+#endif
+}
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_hrt.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_hrt.h
new file mode 100644
index 0000000..871baa5
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_hrt.h
@@ -0,0 +1,374 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+/* This module provides access to the CSS hardware. This includes access to
+ local memories, registers and starting processors. */
+
+#ifndef _SHCSS_HRT_H_
+#define _SHCSS_HRT_H_
+
+#include <hmm/hmm.h>
+
+/* here we include some system header files that provide constants and such
+ about the system and the ISP processor. */
+#include <hive_isp_css_host_ids_hrt.h>
+#include <hive_isp_css_defs.h>
+#ifdef _HIVE_ISP_CSS_FPGA_SYSTEM
+#include <isp2300_medfield_demo_params.h>
+#else
+#include <isp2300_medfield_params.h>
+#endif
+
+/* The following files provide access to types and memory related functions
+ that contain system specific behavior. */
+#include <hive_isp_css_irq_types_hrt.h>
+#include <hive_isp_css_mm_hrt.h>
+#include <hive_isp_css_ddr_hrt.h>
+#include <hive_isp_css_program_load_hrt.h>
+
+#include "sh_css.h"
+
+enum sh_css_fifo_channel {
+ /* SP <-> ISP */
+ sh_css_hrt_fifo_isp_to_sp,
+ sh_css_hrt_fifo_sp_to_isp,
+ /* ISP <-> PRIM IF A */
+ sh_css_hrt_fifo_isp_to_if_prim_a,
+ sh_css_hrt_fifo_if_prim_a_to_isp,
+ /* ISP <-> PRIM IF B (only ISP side) */
+ sh_css_hrt_fifo_isp_to_if_prim_b,
+ sh_css_hrt_fifo_if_prim_b_to_isp,
+ /* ISP <-> DMA */
+ sh_css_hrt_fifo_isp_to_dma,
+ sh_css_hrt_fifo_dma_to_isp,
+ /* SP <-> DMA */
+ sh_css_hrt_fifo_sp_to_dma,
+ sh_css_hrt_fifo_dma_to_sp
+};
+
+enum sh_css_dma_ctrl_state {
+ sh_css_dma_ctrl_state_idle,
+ sh_css_dma_ctrl_state_req_rcv,
+ sh_css_dma_ctrl_state_rcv,
+ sh_css_dma_ctrl_state_rcv_req,
+ sh_css_dma_ctrl_state_init
+};
+
+enum sh_css_dma_command {
+ sh_css_dma_command_read,
+ sh_css_dma_command_write,
+ sh_css_dma_command_set_channel,
+ sh_css_dma_command_set_param,
+ sh_css_dma_command_read_spec,
+ sh_css_dma_command_write_spec,
+ sh_css_dma_command_init,
+ sh_css_dma_command_init_spec,
+ sh_css_dma_command_reset
+};
+
+enum sh_css_dma_rw_state {
+ sh_css_dma_rw_state_idle,
+ sh_css_dma_rw_state_req,
+ sh_css_dma_rw_state_next_line,
+ sh_css_dma_rw_state_unlock_channel
+};
+
+enum sh_css_dma_fifo_state {
+ sh_css_dma_fifo_state_will_be_full,
+ sh_css_dma_fifo_state_full,
+ sh_css_dma_fifo_state_empty
+};
+
+struct sh_css_dma_port_state {
+ ShBool req_cs;
+ ShBool req_we_n;
+ ShBool req_run;
+ ShBool req_ack;
+ ShBool send_cs;
+ ShBool send_we_n;
+ ShBool send_run;
+ ShBool send_ack;
+ enum sh_css_dma_fifo_state fifo_state;
+ int fifo_counter;
+};
+
+struct sh_css_dma_channel_state {
+ int connection;
+ ShBool sign_extend;
+ ShBool reverse_elem_order;
+ int height;
+ int stride_a;
+ int elems_a;
+ int cropping_a;
+ int width_a;
+ int stride_b;
+ int elems_b;
+ int cropping_b;
+ int width_b;
+};
+
+struct sh_css_dma_state {
+ ShBool fsm_command_idle;
+ ShBool fsm_command_run;
+ ShBool fsm_command_stalling;
+ ShBool fsm_command_error;
+ enum sh_css_dma_command last_command;
+ int last_command_channel;
+ int last_command_param;
+ enum sh_css_dma_command current_command;
+ int current_addr_a;
+ int current_addr_b;
+ ShBool fsm_ctrl_idle;
+ ShBool fsm_ctrl_run;
+ ShBool fsm_ctrl_stalling;
+ ShBool fsm_ctrl_error;
+ enum sh_css_dma_ctrl_state fsm_ctrl_state;
+ int fsm_ctrl_source_dev;
+ int fsm_ctrl_source_addr;
+ int fsm_ctrl_source_stride;
+ int fsm_ctrl_source_width;
+ int fsm_ctrl_source_height;
+ int fsm_ctrl_pack_source_dev;
+ int fsm_ctrl_pack_dest_dev;
+ int fsm_ctrl_dest_addr;
+ int fsm_ctrl_dest_stride;
+ int fsm_ctrl_pack_source_width;
+ int fsm_ctrl_pack_dest_height;
+ int fsm_ctrl_pack_dest_width;
+ int fsm_ctrl_pack_source_elems;
+ int fsm_ctrl_pack_dest_elems;
+ int fsm_ctrl_pack_extension;
+ int pack_idle;
+ int pack_run;
+ int pack_stalling;
+ int pack_error;
+ int pack_cnt_height;
+ int pack_src_cnt_width;
+ int pack_dest_cnt_width;
+ enum sh_css_dma_rw_state read_state;
+ int read_cnt_height;
+ int read_cnt_width;
+ enum sh_css_dma_rw_state write_state;
+ int write_height;
+ int write_width;
+ struct sh_css_dma_port_state port_states[3];
+ struct sh_css_dma_channel_state channel_states[8];
+};
+
+struct sh_css_if_state {
+ int reset,
+ start_line,
+ start_column,
+ cropped_height,
+ cropped_width,
+ ver_decimation,
+ hor_decimation,
+ deinterleaving,
+ left_padding,
+ eol_offset,
+ vmem_start_address,
+ vmem_end_address,
+ vmem_increment,
+ yuv420,
+ vsync_active_low,
+ hsync_active_low,
+ allow_fifo_overflow,
+ fsm_sync_status,
+ fsm_sync_counter,
+ fsm_crop_status,
+ fsm_crop_line_counter,
+ fsm_crop_pixel_counter,
+ fsm_deinterleaving_index,
+ fsm_dec_h_counter,
+ fsm_dec_v_counter,
+ fsm_dec_block_v_counter,
+ fsm_padding_status,
+ fsm_padding_elem_counter,
+ fsm_vector_support_error,
+ fsm_vector_buffer_full,
+ vector_support,
+ sensor_data_lost;
+};
+
+struct sh_css_cell_state {
+ int pc;
+ int status_register;
+ ShBool is_broken;
+ ShBool is_idle;
+ ShBool is_sleeping;
+ ShBool is_stalling;
+};
+
+struct sh_css_sp_stall_state {
+ ShBool fifo0;
+ ShBool fifo1;
+ ShBool fifo2;
+ ShBool fifo3;
+ ShBool fifo4;
+ ShBool fifo5;
+ ShBool fifo6;
+ ShBool fifo7;
+ ShBool dmem;
+ ShBool control_master;
+ ShBool icache_master;
+};
+
+struct sh_css_isp_stall_state {
+ ShBool fifo0;
+ ShBool fifo1;
+ ShBool fifo2;
+ ShBool fifo3;
+ ShBool fifo4;
+ ShBool fifo5;
+ ShBool stat_ctrl;
+ ShBool dmem;
+ ShBool vmem;
+ ShBool vamem1;
+ ShBool vamem2;
+};
+
+struct sh_css_fifo_channel_state {
+ ShBool src_valid;
+ ShBool fifo_accept;
+ ShBool fifo_valid;
+ ShBool sink_accept;
+};
+
+/* SP access */
+unsigned int
+sh_css_hrt_sp_dmem_load_32(unsigned int address);
+
+void
+sh_css_hrt_sp_dmem_store_32(unsigned int address, unsigned int value);
+
+void
+sh_css_hrt_sp_start_dma_proxy_init(void);
+
+void
+sh_css_hrt_sp_start_dma_proxy_run(void);
+
+void
+sh_css_hrt_sp_start_si(void);
+
+void
+sh_css_hrt_sp_start_histogram(void);
+
+void
+sh_css_hrt_sp_start_copy_frame(void);
+
+void
+sh_css_hrt_sp_start_copy_binary_data(void);
+
+void
+sh_css_hrt_sp_start_isp(void);
+
+void
+sh_css_hrt_sp_wait(void);
+
+void *
+sh_css_hrt_sp_load_program(void);
+
+void
+sh_css_hrt_sp_get_state(struct sh_css_cell_state *state,
+ struct sh_css_sp_stall_state *stall_state);
+
+/* ISP access */
+void
+sh_css_hrt_isp_wait(void);
+
+void
+sh_css_hrt_isp_get_state(struct sh_css_cell_state *state,
+ struct sh_css_isp_stall_state *stall_state);
+
+void
+sh_css_hrt_fifo_channel_get_state(enum sh_css_fifo_channel,
+ struct sh_css_fifo_channel_state *state);
+
+/* Input formatters */
+unsigned int
+sh_css_hrt_if_prim_vec_align(void);
+
+void
+sh_css_hrt_if_prim_a_get_state(struct sh_css_if_state *state);
+
+void
+sh_css_hrt_if_prim_b_get_state(struct sh_css_if_state *state);
+
+ShBool
+sh_css_hrt_system_is_idle(void);
+
+void
+sh_css_hrt_dma_get_state(struct sh_css_dma_state *state);
+
+/* Interrupts */
+void
+sh_css_hrt_irq_enable(enum hrt_isp_css_irq irq,
+ ShBool rising_edge_in,
+ ShBool edge_not_pulse_out);
+
+void
+sh_css_hrt_irq_enable_sp(ShBool enable);
+
+void
+sh_css_hrt_irq_disable(enum hrt_isp_css_irq irq);
+
+void
+sh_css_hrt_irq_clear_all(void);
+
+enum hrt_isp_css_irq_status
+sh_css_hrt_irq_get_id(enum hrt_isp_css_irq *irq);
+
+void
+sh_css_hrt_irq_clear_sp(void);
+
+/* GDC */
+void
+sh_css_hrt_gdc_set_lut(int data[4][HRT_GDC_N]);
+
+/* MMU */
+void
+sh_css_hrt_mmu_set_page_table_base_address(void *base_address);
+
+void
+sh_css_hrt_mmu_invalidate_cache(void);
+
+void
+sh_css_hrt_send_input_frame(unsigned short *data,
+ unsigned int width,
+ unsigned int height,
+ unsigned int ch_id,
+ enum sh_css_input_format input_format,
+ ShBool two_ppc);
+
+/* CSS Receiver */
+void
+sh_css_hrt_receiver_enable_error_interrupts(enum sh_css_mipi_port port,
+ ShBool enable);
+
+unsigned long
+sh_css_hrt_receiver_get_interrupt_status(enum sh_css_mipi_port port);
+
+void
+sh_css_hrt_receiver_clear_interrupts(enum sh_css_mipi_port port);
+
+#endif /* _SHCSS_HRT_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_internal.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_internal.h
new file mode 100644
index 0000000..cd283b8
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_internal.h
@@ -0,0 +1,162 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SHCSS_INTERNAL_H_
+#define _SHCSS_INTERNAL_H_
+
+#include <hmm/hmm.h>
+
+struct sh_css_if_config;
+
+#include "sh_css.h"
+#include "sh_css_binary.h"
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef CEIL_DIV
+#define CEIL_DIV(a, b) (((a)+(b)-1)/(b))
+#endif
+
+#ifndef CEIL_MUL
+#define CEIL_MUL(a, b) (CEIL_DIV(a, b) * b)
+#endif
+
+#define sh_css_print(fmt, s...) \
+ do { \
+ if (sh_css_printf) { \
+ printk(KERN_INFO "%s: ", "atomisp");\
+ sh_css_printf(fmt, ## s); \
+ } \
+ } while (0)
+
+#define return_on_error(expr) \
+ do { \
+ sh_css_err err = expr; \
+ if (err != sh_css_success) { \
+ printk(KERN_INFO "%s: ", "atomisp");\
+ printk(KERN_ERR "%s:%d\n", __func__, __LINE__); \
+ return err; \
+ } \
+ } while (0)
+
+struct sh_css_if_config {
+ unsigned int start_line;
+ unsigned int start_column;
+ unsigned int left_padding;
+ unsigned int cropped_height;
+ unsigned int cropped_width;
+ unsigned int deinterleaving;
+ unsigned int buf_vecs;
+ unsigned int buf_start_index;
+ unsigned int buf_increment;
+ unsigned int buf_eol_offset;
+ ShBool yuv420;
+};
+
+extern int (*sh_css_printf) (const char *fmt, ...);
+
+int
+sh_css_isp_grid_deci_factor_log2(int width, int height);
+
+void *
+sh_css_params_ddr_address_map(void);
+
+sh_css_err
+sh_css_params_write_to_ddr(struct sh_css_params *params,
+ const struct sh_css_binary *binary_info);
+
+sh_css_err
+sh_css_params_set_current_binary(const struct sh_css_binary *binary);
+
+sh_css_err
+sh_css_params_init(void);
+
+void
+sh_css_params_uninit(void);
+
+sh_css_err
+sh_css_params_default_morph_table(const struct sh_css_morph_table **table,
+ unsigned int width,
+ unsigned int height);
+
+void *
+sh_css_malloc(size_t size);
+
+void
+sh_css_free(void *ptr);
+
+/* Check two frames for equality (format, resolution, bits per element) */
+ShBool
+sh_css_frame_equal_types(const struct sh_css_frame *frame_a,
+ const struct sh_css_frame *frame_b);
+
+ShBool
+sh_css_frame_info_equal_resolution(const struct sh_css_frame_info *info_a,
+ const struct sh_css_frame_info *info_b);
+
+void
+sh_css_frame_info_init(struct sh_css_frame_info *info,
+ unsigned int width,
+ unsigned int height,
+ enum sh_css_frame_format format,
+ unsigned int padded_width);
+
+/* Initialize frame with zeroes, should only be used to avoid warnings
+ in simulations */
+void
+sh_css_frame_zero(struct sh_css_frame *frame);
+
+/* get the number of valid bits per pixel element given a certain input format.
+ For rgb565, this returns 565, for all other formats it's the actual
+ bit depth. */
+sh_css_err
+sh_css_input_format_bits_per_pixel(enum sh_css_input_format format,
+ ShBool two_pixels_per_clock,
+ unsigned int *bits_per_pixel);
+
+sh_css_err
+sh_css_host_to_isp_format(enum sh_css_frame_format from,
+ enum ShImageFormat *to);
+
+sh_css_err
+sh_css_isp_to_host_format(enum ShImageFormat from,
+ enum sh_css_frame_format *to);
+
+sh_css_err
+sh_css_to_isp_stream_format(enum sh_css_input_format from,
+ unsigned int two_pixels_per_clock,
+ enum ShStreamFormat *to,
+ unsigned int *bits_per_pixel);
+
+sh_css_err
+sh_css_vf_downscale_log2(const struct sh_css_frame_info *out_info,
+ const struct sh_css_frame_info *vf_info,
+ unsigned int *downscale_log2);
+
+#endif /* _ISPPARAMS_INTERNAL_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_isp.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_isp.h
new file mode 100644
index 0000000..c23b8ed
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_isp.h
@@ -0,0 +1,335 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SHCSS_ISP_H_
+#define _SHCSS_ISP_H_
+
+#include <defs.h>
+#include "sh_css_frame.h"
+#include "sh_css_binary.h"
+#include "sh_css_internal.h"
+#include "sh_css_sp.h"
+#include "sh_css_hrt.h"
+#include "isp/modes/common/defs.h"
+
+#define FIXED_RES(var_name) \
+ (VARIABLE_RESOLUTION && isp_frame_out_dimx == 0 ? 0 : var_name)
+
+#define CONCAT(a, b) HRTCAT(a, b)
+
+#define DEFAULT_FRAME_INFO(fixed_width) \
+{ \
+ .format = sh_css_frame_format_vraw16, \
+ .width = fixed_width, \
+ .height = 0, \
+ .padded_width = fixed_width, \
+ .vraw_bit_depth = 0, \
+ .raw_bayer_order = sh_css_bayer_order_grbg, \
+}
+
+#if !defined(ISP_USE_IF)
+#define ISP_USE_IF 0
+#endif
+
+#if MODE == M_COPY
+#define MY_MODE sh_css_binary_mode_copy
+#elif MODE == M_PRIMARY
+#define MY_MODE sh_css_binary_mode_primary
+#elif MODE == M_PREVIEW
+#define MY_MODE sh_css_binary_mode_preview
+#elif MODE == M_VIDEO
+#if ENABLE_UDS || CAN_SCALE
+#define MY_MODE sh_css_binary_mode_video
+#else
+#define MY_MODE sh_css_binary_mode_video_nodz
+#endif
+#elif MODE == M_PREGDC
+#define MY_MODE sh_css_binary_mode_pre_gdc
+#elif MODE == M_GDC
+#define MY_MODE sh_css_binary_mode_gdc
+#elif MODE == M_POSTGDC
+#define MY_MODE sh_css_binary_mode_post_gdc
+#elif MODE == M_XNR
+#define MY_MODE sh_css_binary_mode_xnr
+#elif MODE == M_VF_PP
+#define MY_MODE sh_css_binary_mode_vf_pp
+#elif MODE == M_BAYER_DS
+#define MY_MODE sh_css_binary_mode_bayer_ds
+#else
+#error unknown binary mode
+#endif
+
+#if ENABLE_UDS || CAN_SCALE
+#define MY_UDS_CONFIG \
+{ \
+ .number_of_chunks = UDS_NUMBER_OF_CHUNKS, \
+ .bpp = UDS_BPP, \
+ .use_bci = UDS_USE_BCI, \
+ .woix = UDS_WOIX, \
+ .woiy = UDS_WOIY, \
+ .no_user_zoom = (MODE == M_VF_PP) \
+}
+#else
+#define MY_UDS_CONFIG \
+{ \
+ .number_of_chunks = 0, \
+ .bpp = 0, \
+ .use_bci = 0, \
+ .woix = 0, \
+ .woiy = 0, \
+ .no_user_zoom = 0 \
+}
+#endif
+
+#if !ISP_VARIABLE_INPUT && ISP_USE_IF == 1
+#define MY_ONLINE 1
+#else
+#define MY_ONLINE 0
+#endif
+
+#if VARIABLE_RESOLUTION
+#define DEFAULT_IN_WIDTH 0
+#define DEFAULT_OUT_WIDTH 0
+#else
+#define DEFAULT_IN_WIDTH INPUT_ELEMENTS_PER_LINE
+#define DEFAULT_OUT_WIDTH OUTPUT_Y_FRAME_WIDTH
+#endif
+
+#if VARIABLE_OUTPUT_FORMAT
+#define DEFAULT_OUTPUT_FORMAT IMAGEFORMAT_VRAW
+#else
+#define DEFAULT_OUTPUT_FORMAT OUTPUT_IMAGE_FORMAT
+#endif
+
+#define DEFAULT_BINARY_INFO {\
+ .id = BINARY,\
+ .mode = MY_MODE,\
+ .variable_width = VARIABLE_RESOLUTION,\
+ .variable_output_format = VARIABLE_OUTPUT_FORMAT,\
+ .isp_output_format = DEFAULT_OUTPUT_FORMAT,\
+ .can_scale = CAN_SCALE,\
+ .in_max_width = MAX_ELEMENTS_PER_INPUT_LINE,\
+ .out_min_width = MIN_ELEMENTS_PER_LINE,\
+ .out_max_width = MAX_ELEMENTS_PER_LINE,\
+ .out_step_width = STEP_ELEMENTS_PER_LINE,\
+ .filter_rows = FILTER_ROWS,\
+ .filter_columns = FILTER_COLUMNS,\
+ .input_format = sh_css_input_format_raw_10,\
+ .in_frame_info = DEFAULT_FRAME_INFO(DEFAULT_IN_WIDTH),\
+ .int_out_frame_info = DEFAULT_FRAME_INFO(0),\
+ .out_frame_info = DEFAULT_FRAME_INFO(DEFAULT_OUT_WIDTH),\
+ .vf_frame_info = DEFAULT_FRAME_INFO(0),\
+ .input_buf_vectors = 0,\
+ .deci_factor_log2 = 0,\
+ .dis_deci_factor_log2 = 0,\
+ .vf_downscale_log2 = 0,\
+ .sctbl_width_per_color = 0,\
+ .s3atbl_use_dmem = S3ATBL_USE_DMEM,\
+ .s3atbl_width = 0,\
+ .s3atbl_height = 0,\
+ .dis_horicoef_num = 0,\
+ .dis_vertcoef_num = 0,\
+ .dis_horiproj_num = 0,\
+ .dis_vertproj_num = 0,\
+ .enable_yee = ENABLE_YEE,\
+ .enable_sc = ENABLE_SC,\
+ .enable_s3a = ENABLE_S3A,\
+ .enable_vf_veceven = ENABLE_VF_VECEVEN && MODE != M_PREVIEW,\
+ .enable_tnr = ENABLE_TNR,\
+ .enable_macc = ENABLE_MACC,\
+ .enable_dis = ENABLE_SDIS,\
+ .enable_dis_crop = ENABLE_DIS_CROP,\
+ .enable_uds = ENABLE_UDS,\
+ .enable_fpnr = ENABLE_FPNR,\
+ .variable_input = ISP_VARIABLE_INPUT,\
+ .use_dma_proxy = USE_DMA_PROXY,\
+ .xmem_addr = NULL,\
+ .dirty = ShTrue,\
+ .fill_binary_info = fill_binary_info,\
+ .load = load_binary,\
+ .params = NULL,\
+ .online = MY_ONLINE,\
+ .two_ppc = 0,\
+ .uds_config = MY_UDS_CONFIG,\
+ .next = NULL,\
+}
+
+static void *
+load_binary(void)
+{
+ return hrt_isp_css_load_isp_program_for_dma(BINARY);
+}
+
+static sh_css_err
+fill_binary_info(struct sh_css_binary *binary,
+ ShBool online,
+ ShBool two_ppc,
+ enum sh_css_input_format stream_format,
+ const struct sh_css_frame_info *in_info,
+ const struct sh_css_frame_info *out_info,
+ const struct sh_css_frame_info *vf_info)
+{
+ /* we assign these variables because they are used in some macros from
+ defs.h. yes, this is extremely ugly indeed. */
+ enum ShImageFormat isp_output_image_format;
+ enum ShStreamFormat isp_input_stream_format = ShStreamFormat_raw;
+ struct sh_css_frame_info int_out_info = *out_info;
+ int isp_frame_in_dimx;
+ int isp_frame_in_dimy;
+ int isp_frame_out_dimx;
+ int isp_frame_out_dimy;
+ int isp_frame_cropped_dimx;
+ int isp_frame_cropped_dimy;
+ /* the 3A grid operates before bayer downscaling, so we need to use the
+ input resolution here */
+ int isp_deci_log_factor;
+ unsigned isp_vf_downscale_bits = 0;
+ unsigned bits_per_pixel;
+ unsigned dvs_envelope_width = 0, dvs_envelope_height = 0;
+
+ return_on_error(sh_css_video_get_dis_envelope(&dvs_envelope_width,
+ &dvs_envelope_height));
+ if (binary->enable_dis_crop &&
+ (dvs_envelope_width > 0 || dvs_envelope_height > 0)) {
+ int_out_info.width += dvs_envelope_width;
+ int_out_info.padded_width += dvs_envelope_width;
+ int_out_info.height += dvs_envelope_height;
+ } else {
+ int_out_info.height += binary->filter_rows;
+ }
+ isp_frame_in_dimx = in_info->padded_width;
+ isp_frame_in_dimy = in_info->height;
+ isp_frame_out_dimx = int_out_info.padded_width;
+ isp_frame_out_dimy = int_out_info.height;
+ isp_frame_cropped_dimx = out_info->padded_width;
+ isp_frame_cropped_dimy = out_info->height;
+ isp_deci_log_factor =
+ sh_css_isp_grid_deci_factor_log2(in_info->padded_width,
+ in_info->height);
+
+ return_on_error(sh_css_host_to_isp_format(int_out_info.format,
+ &isp_output_image_format));
+ if (vf_info) {
+ return_on_error(
+ sh_css_vf_downscale_log2(out_info,
+ vf_info,
+ &isp_vf_downscale_bits));
+ }
+
+ /* not all binaries actually use these variables */
+ (void) isp_frame_in_dimx;
+ (void) isp_frame_in_dimy;
+ (void) isp_frame_out_dimx;
+ (void) isp_frame_out_dimy;
+ (void) isp_frame_cropped_dimx;
+ (void) isp_frame_cropped_dimy;
+ (void) isp_deci_log_factor;
+ (void) isp_vf_downscale_bits;
+
+ /* we assign fields that can be variable */
+ binary->input_buf_vectors = FIXED_RES(INPUT_BUF_VECTORS);
+ binary->deci_factor_log2 = DECI_FACTOR_LOG2;
+ binary->dis_deci_factor_log2 = SDIS_DECI_FACTOR_LOG2;
+ binary->vf_downscale_log2 = VF_LOG_DOWNSCALE;
+ binary->online = online;
+ binary->two_ppc = two_ppc;
+ if (online) {
+ return_on_error(
+ sh_css_to_isp_stream_format(stream_format,
+ two_ppc,
+ &isp_input_stream_format,
+ &bits_per_pixel));
+ } else {
+ bits_per_pixel = in_info->vraw_bit_depth;
+ }
+ /* input info */
+ binary->input_format = stream_format;
+ return_on_error(sh_css_isp_to_host_format(INPUT_IMAGE_FORMAT,
+ &binary->in_frame_info.
+ format));
+ binary->in_frame_info.width = in_info->width;
+ binary->in_frame_info.padded_width = FIXED_RES(INPUT_ELEMENTS_PER_LINE);
+ binary->in_frame_info.height = FIXED_RES(FRAME_IN_DIMY);
+ if (!online &&
+ binary->in_frame_info.format == sh_css_frame_format_vraw16) {
+ binary->in_frame_info.vraw_bit_depth = bits_per_pixel;
+ }
+ /* output info */
+ return_on_error(sh_css_isp_to_host_format(OUTPUT_IMAGE_FORMAT,
+ &binary->int_out_frame_info.
+ format));
+ binary->int_out_frame_info.width = int_out_info.width;
+ binary->int_out_frame_info.padded_width =
+ FIXED_RES(OUTPUT_Y_FRAME_WIDTH);
+ binary->int_out_frame_info.height = FIXED_RES(OUTPUT_Y_FRAME_HEIGHT);
+ if (online &&
+ binary->int_out_frame_info.format == sh_css_frame_format_vraw16) {
+ binary->int_out_frame_info.vraw_bit_depth = bits_per_pixel;
+ }
+ binary->out_frame_info = binary->int_out_frame_info;
+ if (binary->enable_dis_crop &&
+ (dvs_envelope_width > 0 || dvs_envelope_height > 0)) {
+ binary->out_frame_info.width -= dvs_envelope_width;
+ binary->out_frame_info.padded_width -= dvs_envelope_width;
+ binary->out_frame_info.height -= dvs_envelope_height;
+ } else {
+ binary->out_frame_info.height -= binary->filter_rows;
+ }
+
+ /* viewfinder output info */
+ if (vf_info) {
+ binary->vf_frame_info.format = sh_css_frame_format_yuv420;
+ if (binary->enable_dis_crop &&
+ (dvs_envelope_width > 0 || dvs_envelope_height > 0)) {
+ binary->vf_frame_info.padded_width =
+ FIXED_RES(CROP_VFOUT_Y_FRAME_WIDTH);
+ binary->vf_frame_info.height =
+ FIXED_RES(CROP_VFOUT_Y_FRAME_HEIGHT);
+ } else {
+ binary->vf_frame_info.padded_width =
+ FIXED_RES(VFOUT_Y_FRAME_WIDTH);
+ binary->vf_frame_info.height =
+ out_info->height >> binary->vf_downscale_log2;
+ }
+ /* the valid width of the vf_veceven output is the downscaled
+ version of the valid width of the regular output. */
+ binary->vf_frame_info.width =
+ binary->out_frame_info.width >> isp_vf_downscale_bits;
+ } else {
+ binary->vf_frame_info.format = sh_css_frame_format_yuv420;
+ binary->vf_frame_info.width = 0;
+ binary->vf_frame_info.padded_width = 0;
+ binary->vf_frame_info.height = 0;
+ }
+ binary->sctbl_width_per_color = FIXED_RES(SCTBL_WIDTH_PER_COLOR);
+ binary->s3atbl_width = FIXED_RES(S3ATBL_WIDTH);
+ binary->s3atbl_height = FIXED_RES(S3ATBL_HEIGHT);
+ binary->dis_horicoef_num = FIXED_RES(SDIS_HORICOEF_NUM);
+ binary->dis_vertcoef_num = FIXED_RES(SDIS_VERTCOEF_NUM);
+ binary->dis_horiproj_num = FIXED_RES(SDIS_HORIPROJ_NUM);
+ binary->dis_vertproj_num = FIXED_RES(SDIS_VERTPROJ_NUM);
+ binary->dirty = ShTrue;
+ return sh_css_success;
+}
+
+#endif /* _SHCSS_ISP_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_params.c b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_params.c
new file mode 100644
index 0000000..611ee02
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_params.c
@@ -0,0 +1,1725 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <hmm/hmm.h>
+
+#include "sh_css.h"
+#include "sh_css_params.h"
+#include "sh_css_internal.h"
+#include "sh_css_hrt.h"
+#include "isp/modes/common/defs.h"
+#include "isp/modes/common/isp_params.h"
+#include "sp/sp_defs.h"
+
+#define sISP_REG_BIT ISP_VEC_ELEMBITS
+#define uISP_REG_BIT (sISP_REG_BIT-1)
+#define sSHIFT (16-(sISP_REG_BIT))
+#define uSHIFT (16-(uISP_REG_BIT))
+#define sFRACTION_BITS_FITTING(a) (a-sSHIFT)
+#define uFRACTION_BITS_FITTING(a) (a-uSHIFT)
+/* a:fraction bits for 16bit precision, b:fraction bits for ISP precision */
+#define sDIGIT_FITTING(v, a, b) \
+ (((v)>>sSHIFT) >> (sFRACTION_BITS_FITTING(a)-(b)))
+#define uDIGIT_FITTING(v, a, b) \
+ (((v)>>uSHIFT) >> (uFRACTION_BITS_FITTING(a)-(b)))
+
+#define XMEM_ISPPARM_BYTES \
+ (sizeof(struct s_ispparm))
+#define XMEM_CTCTBL_BYTES \
+ (sizeof(unsigned short) *CTCTBL_SIZE)
+#define XMEM_GAMMATBL_BYTES \
+ (sizeof(unsigned short) *GAMMATBL_SIZE)
+#define XMEM_MACCTBL_BYTES \
+ (sizeof(short) *MACCTBL_SIZE)
+#define XMEM_FPNTBL_BYTES \
+ (sizeof(unsigned char) *MAX_LINES_PER_FRAME * MAX_ELEMENTS_PER_LINE)
+#define XMEM_SCTBL_BYTES \
+ (sizeof(unsigned short) *SCTBL_HEIGHT * SCTBL_WIDTH)
+#define XMEM_S3ATBL_BYTES \
+ (sizeof(struct s_s3a_output) *MAX_S3ATBL_WIDTH * MAX_S3ATBL_HEIGHT)
+#define XMEM_S3ATBL_HI_LO_BYTES \
+ (S3ATBL_HI_LO_STRIDE_BYTES * MAX_S3ATBL_HEIGHT)
+#define SDIS_HORICOEF_TBL_BYTES \
+ (sizeof(short) *SDIS_COEF_TYPES * MAX_SDIS_HORICOEF_NUM)
+#define SDIS_VERTCOEF_TBL_BYTES \
+ (sizeof(short) *SDIS_COEF_TYPES * MAX_SDIS_VERTCOEF_NUM)
+#define SDIS_HORIPROJ_TBL_BYTES \
+ (sizeof(int) *SDIS_COEF_TYPES * MAX_SDIS_HORIPROJ_NUM)
+#define SDIS_VERTPROJ_TBL_BYTES \
+ (sizeof(int) *SDIS_COEF_TYPES * MAX_SDIS_VERTPROJ_NUM)
+
+#define SDIS_HORICOEF_TBL_SHORTS \
+ (SDIS_HORICOEF_TBL_BYTES / sizeof(short))
+#define SDIS_VERTCOEF_TBL_SHORTS \
+ (SDIS_VERTCOEF_TBL_BYTES / sizeof(short))
+
+struct sh_css_fpn_table {
+ short *data;
+ unsigned int width;
+ unsigned int height;
+ unsigned int shift;
+};
+
+/* most of the contents of the parameters are pointers that we
+ * allocate dynamically because not many binaries need all of these
+ * parameters. In fact, most need only the isp_parameters.
+ */
+struct sh_css_params {
+ struct s_ispparm isp_parameters;
+ struct sh_css_fpn_table *fpn_table;
+ const struct sh_css_morph_table *morph_table;
+ const short *macc_table;
+ unsigned short *gamma_table;
+ unsigned short *ctc_table;
+ ShBool isp_params_changed;
+ ShBool fpn_table_changed;
+ ShBool morph_table_changed;
+ ShBool macc_table_changed;
+ ShBool gamma_table_changed;
+ ShBool ctc_table_changed;
+ ShBool sc_table_stored;
+};
+
+static unsigned short *g_s3a_tbl_hi;
+static unsigned short *g_s3a_tbl_lo;
+
+static struct sh_css_shading_table *
+ (*get_shading_table) (unsigned int frame_width,
+ unsigned int frame_height,
+ unsigned int table_width,
+ unsigned int table_height) = NULL;
+
+static short curr_macc_table[MACCTBL_SIZE];
+static short dis_horicoef_tbl[SDIS_HORICOEF_TBL_SHORTS];
+static short dis_vertcoef_tbl[SDIS_VERTCOEF_TBL_SHORTS];
+static ShBool dis_coef_table_changed;
+static const struct sh_css_binary *current_binary;
+static struct xmem_address_map xmem_ptrs;
+static void *xmem_map_addr;
+static struct sh_css_params *current_isp_params;
+
+static unsigned short default_gamma_table[GAMMATBL_SIZE] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 16,
+ 17, 18, 19, 20, 21, 23, 24, 25,
+ 27, 28, 29, 31, 32, 33, 35, 36,
+ 38, 39, 41, 42, 44, 45, 47, 48,
+ 49, 51, 52, 54, 55, 57, 58, 60,
+ 61, 62, 64, 65, 66, 68, 69, 70,
+ 71, 72, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 93, 94,
+ 95, 96, 97, 98, 98, 99, 100, 101,
+ 102, 102, 103, 104, 105, 105, 106, 107,
+ 108, 108, 109, 110, 110, 111, 112, 112,
+ 113, 114, 114, 115, 116, 116, 117, 118,
+ 118, 119, 120, 120, 121, 121, 122, 123,
+ 123, 124, 125, 125, 126, 126, 127, 127, /* 128 */
+ 128, 129, 129, 130, 130, 131, 131, 132,
+ 132, 133, 134, 134, 135, 135, 136, 136,
+ 137, 137, 138, 138, 139, 139, 140, 140,
+ 141, 141, 142, 142, 143, 143, 144, 144,
+ 145, 145, 145, 146, 146, 147, 147, 148,
+ 148, 149, 149, 150, 150, 150, 151, 151,
+ 152, 152, 152, 153, 153, 154, 154, 155,
+ 155, 155, 156, 156, 156, 157, 157, 158,
+ 158, 158, 159, 159, 160, 160, 160, 161,
+ 161, 161, 162, 162, 162, 163, 163, 163,
+ 164, 164, 164, 165, 165, 165, 166, 166,
+ 166, 167, 167, 167, 168, 168, 168, 169,
+ 169, 169, 170, 170, 170, 170, 171, 171,
+ 171, 172, 172, 172, 172, 173, 173, 173,
+ 174, 174, 174, 174, 175, 175, 175, 176,
+ 176, 176, 176, 177, 177, 177, 177, 178, /* 256 */
+ 178, 178, 178, 179, 179, 179, 179, 180,
+ 180, 180, 180, 181, 181, 181, 181, 182,
+ 182, 182, 182, 182, 183, 183, 183, 183,
+ 184, 184, 184, 184, 184, 185, 185, 185,
+ 185, 186, 186, 186, 186, 186, 187, 187,
+ 187, 187, 187, 188, 188, 188, 188, 188,
+ 189, 189, 189, 189, 189, 190, 190, 190,
+ 190, 190, 191, 191, 191, 191, 191, 192,
+ 192, 192, 192, 192, 192, 193, 193, 193,
+ 193, 193, 194, 194, 194, 194, 194, 194,
+ 195, 195, 195, 195, 195, 195, 196, 196,
+ 196, 196, 196, 196, 197, 197, 197, 197,
+ 197, 197, 198, 198, 198, 198, 198, 198,
+ 198, 199, 199, 199, 199, 199, 199, 200,
+ 200, 200, 200, 200, 200, 200, 201, 201,
+ 201, 201, 201, 201, 201, 202, 202, 202, /* 384 */
+ 202, 202, 202, 202, 203, 203, 203, 203,
+ 203, 203, 203, 204, 204, 204, 204, 204,
+ 204, 204, 204, 205, 205, 205, 205, 205,
+ 205, 205, 205, 206, 206, 206, 206, 206,
+ 206, 206, 206, 207, 207, 207, 207, 207,
+ 207, 207, 207, 208, 208, 208, 208, 208,
+ 208, 208, 208, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 211, 211, 211,
+ 211, 211, 211, 211, 211, 211, 212, 212,
+ 212, 212, 212, 212, 212, 212, 212, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 214, 214, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 216, 216, 216, 216, 216,
+ 216, 216, 216, 216, 216, 217, 217, 217, /* 512 */
+ 217, 217, 217, 217, 217, 217, 217, 218,
+ 218, 218, 218, 218, 218, 218, 218, 218,
+ 218, 219, 219, 219, 219, 219, 219, 219,
+ 219, 219, 219, 220, 220, 220, 220, 220,
+ 220, 220, 220, 220, 220, 221, 221, 221,
+ 221, 221, 221, 221, 221, 221, 221, 221,
+ 222, 222, 222, 222, 222, 222, 222, 222,
+ 222, 222, 223, 223, 223, 223, 223, 223,
+ 223, 223, 223, 223, 223, 224, 224, 224,
+ 224, 224, 224, 224, 224, 224, 224, 224,
+ 225, 225, 225, 225, 225, 225, 225, 225,
+ 225, 225, 225, 226, 226, 226, 226, 226,
+ 226, 226, 226, 226, 226, 226, 226, 227,
+ 227, 227, 227, 227, 227, 227, 227, 227,
+ 227, 227, 228, 228, 228, 228, 228, 228,
+ 228, 228, 228, 228, 228, 228, 229, 229,
+ 229, 229, 229, 229, 229, 229, 229, 229,
+ 229, 229, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 231, 231,
+ 231, 231, 231, 231, 231, 231, 231, 231,
+ 231, 231, 231, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 233,
+ 233, 233, 233, 233, 233, 233, 233, 233,
+ 233, 233, 233, 233, 234, 234, 234, 234,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 234, 235, 235, 235, 235, 235, 235, 235,
+ 235, 235, 235, 235, 235, 235, 236, 236,
+ 236, 236, 236, 236, 236, 236, 236, 236,
+ 236, 236, 236, 236, 237, 237, 237, 237,
+ 237, 237, 237, 237, 237, 237, 237, 237,
+ 237, 237, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 239, 239, 239, 239, 239, 239, 239, 239,
+ 239, 239, 239, 239, 239, 239, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 243, 243, 243, 243, 243, 243,
+ 243, 243, 243, 243, 243, 243, 243, 243,
+ 243, 244, 244, 244, 244, 244, 244, 244,
+ 244, 244, 244, 244, 244, 244, 244, 244,
+ 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 246,
+ 246, 246, 246, 246, 246, 246, 246, 246,
+ 246, 246, 246, 246, 246, 246, 246, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 249,
+ 249, 249, 249, 249, 249, 249, 249, 249,
+ 249, 249, 249, 249, 249, 249, 249, 250,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 250, 250, 250, 250, 250, 250, 251,
+ 251, 251, 251, 251, 251, 251, 251, 251,
+ 251, 251, 251, 251, 251, 251, 251, 252,
+ 252, 252, 252, 252, 252, 252, 252, 252,
+ 252, 252, 252, 252, 252, 252, 252, 253,
+ 253, 253, 253, 253, 253, 253, 253, 253,
+ 253, 253, 253, 253, 253, 253, 253, 253,
+ 254, 254, 254, 254, 254, 254, 254, 254,
+ 254, 254, 254, 254, 254, 254, 254, 254,
+ 255, 255, 255, 255, 255, 255, 255, 255
+};
+
+static unsigned short default_ctc_table[CTCTBL_SIZE] = {
+ 0, 0, 256, 384, 384, 497, 765, 806,
+ 837, 851, 888, 901, 957, 981, 993, 1001,
+ 1011, 1029, 1028, 1039, 1062, 1059, 1073, 1080,
+ 1083, 1085, 1085, 1098, 1080, 1084, 1085, 1093,
+ 1078, 1073, 1070, 1069, 1077, 1066, 1072, 1063,
+ 1053, 1044, 1046, 1053, 1039, 1028, 1025, 1024,
+ 1012, 1013, 1016, 996, 992, 990, 990, 980,
+ 969, 968, 961, 955, 951, 949, 933, 930,
+ 929, 925, 921, 916, 906, 901, 895, 893,
+ 886, 877, 872, 869, 866, 861, 857, 849,
+ 845, 838, 836, 832, 823, 821, 815, 813,
+ 809, 805, 796, 793, 790, 785, 784, 778,
+ 772, 768, 766, 763, 758, 752, 749, 745,
+ 741, 740, 736, 730, 726, 724, 723, 718,
+ 711, 709, 706, 704, 701, 698, 691, 689,
+ 688, 683, 683, 678, 675, 673, 671, 669,
+ 666, 663, 661, 660, 656, 656, 653, 650,
+ 648, 647, 646, 643, 639, 638, 637, 635,
+ 633, 632, 629, 627, 626, 625, 622, 621,
+ 618, 618, 614, 614, 612, 609, 606, 606,
+ 603, 600, 600, 597, 594, 591, 590, 586,
+ 582, 581, 578, 575, 572, 569, 563, 560,
+ 557, 554, 551, 548, 545, 539, 536, 533,
+ 529, 527, 524, 519, 516, 513, 510, 507,
+ 504, 501, 498, 493, 491, 488, 485, 484,
+ 480, 476, 474, 471, 467, 466, 464, 460,
+ 459, 455, 453, 449, 447, 446, 443, 441,
+ 438, 435, 432, 432, 429, 427, 426, 422,
+ 419, 418, 416, 414, 412, 410, 408, 406,
+ 404, 402, 401, 398, 397, 395, 393, 390,
+ 389, 388, 387, 384, 382, 380, 378, 377,
+ 376, 375, 372, 370, 368, 368, 366, 364,
+ 363, 361, 360, 358, 357, 355, 354, 352,
+ 351, 350, 349, 346, 345, 344, 344, 342,
+ 340, 339, 337, 337, 336, 335, 333, 331,
+ 330, 329, 328, 326, 326, 324, 324, 322,
+ 321, 320, 318, 318, 318, 317, 315, 313,
+ 312, 311, 311, 310, 308, 307, 306, 306,
+ 304, 304, 302, 301, 300, 300, 299, 297,
+ 297, 296, 296, 294, 294, 292, 291, 291,
+ 291, 290, 288, 287, 286, 286, 287, 285,
+ 284, 283, 282, 282, 281, 281, 279, 278,
+ 278, 278, 276, 276, 275, 274, 274, 273,
+ 271, 270, 269, 268, 268, 267, 265, 262,
+ 261, 260, 260, 259, 257, 254, 252, 252,
+ 251, 251, 249, 246, 245, 244, 243, 242,
+ 240, 239, 239, 237, 235, 235, 233, 231,
+ 232, 230, 229, 226, 225, 224, 225, 224,
+ 223, 220, 219, 219, 218, 217, 217, 214,
+ 213, 213, 212, 211, 209, 209, 209, 208,
+ 206, 205, 204, 203, 204, 203, 201, 200,
+ 199, 197, 198, 198, 197, 195, 194, 194,
+ 193, 192, 192, 191, 189, 190, 189, 188,
+ 186, 187, 186, 185, 185, 184, 183, 181,
+ 183, 182, 181, 180, 179, 178, 178, 178,
+ 177, 176, 175, 176, 175, 174, 174, 173,
+ 172, 173, 172, 171, 170, 170, 169, 169,
+ 169, 168, 167, 166, 167, 167, 166, 165,
+ 164, 164, 164, 163, 164, 163, 162, 163,
+ 162, 161, 160, 161, 160, 160, 160, 159,
+ 158, 157, 158, 158, 157, 157, 156, 156,
+ 156, 156, 155, 155, 154, 154, 154, 154,
+ 154, 153, 152, 153, 152, 152, 151, 152,
+ 151, 152, 151, 150, 150, 149, 149, 150,
+ 149, 149, 148, 148, 148, 149, 148, 147,
+ 146, 146, 147, 146, 147, 146, 145, 146,
+ 146, 145, 144, 145, 144, 145, 144, 144,
+ 143, 143, 143, 144, 143, 142, 142, 142,
+ 142, 142, 142, 141, 141, 141, 141, 140,
+ 140, 141, 140, 140, 141, 140, 139, 139,
+ 139, 140, 139, 139, 138, 138, 137, 139,
+ 138, 138, 138, 137, 138, 137, 137, 137,
+ 137, 136, 137, 136, 136, 136, 136, 135,
+ 136, 135, 135, 135, 135, 136, 135, 135,
+ 134, 134, 133, 135, 134, 134, 134, 133,
+ 134, 133, 134, 133, 133, 132, 133, 133,
+ 132, 133, 132, 132, 132, 132, 131, 131,
+ 131, 132, 131, 131, 130, 131, 130, 132,
+ 131, 130, 130, 129, 130, 129, 130, 129,
+ 129, 129, 130, 129, 128, 128, 128, 128,
+ 129, 128, 128, 127, 127, 128, 128, 127,
+ 127, 126, 126, 127, 127, 126, 126, 126,
+ 127, 126, 126, 126, 125, 125, 126, 125,
+ 125, 124, 124, 124, 125, 125, 124, 124,
+ 123, 124, 124, 123, 123, 122, 122, 122,
+ 122, 122, 121, 120, 120, 119, 118, 118,
+ 118, 117, 117, 116, 115, 115, 115, 114,
+ 114, 113, 113, 112, 111, 111, 111, 110,
+ 110, 109, 109, 108, 108, 108, 107, 107,
+ 106, 106, 105, 105, 105, 104, 104, 103,
+ 103, 102, 102, 102, 102, 101, 101, 100,
+ 100, 99, 99, 99, 99, 99, 99, 98,
+ 97, 98, 97, 97, 97, 96, 96, 95,
+ 96, 95, 96, 95, 95, 94, 94, 95,
+ 94, 94, 94, 93, 93, 92, 93, 93,
+ 93, 93, 92, 92, 91, 92, 92, 92,
+ 91, 91, 90, 90, 91, 91, 91, 90,
+ 90, 90, 90, 91, 90, 90, 90, 89,
+ 89, 89, 90, 89, 89, 89, 89, 89,
+ 88, 89, 89, 88, 88, 88, 88, 87,
+ 89, 88, 88, 88, 88, 88, 87, 88,
+ 88, 88, 87, 87, 87, 87, 87, 88,
+ 87, 87, 87, 87, 87, 87, 88, 87,
+ 87, 87, 87, 86, 86, 87, 87, 87,
+ 87, 86, 86, 86, 87, 87, 86, 87,
+ 86, 86, 86, 87, 87, 86, 86, 86,
+ 86, 86, 87, 87, 86, 85, 85, 85,
+ 84, 85, 85, 84, 84, 83, 83, 82,
+ 82, 82, 81, 81, 80, 79, 79, 79,
+ 78, 77, 77, 76, 76, 76, 75, 74,
+ 74, 74, 73, 73, 72, 71, 71, 71,
+ 70, 70, 69, 69, 68, 68, 67, 67,
+ 67, 66, 66, 65, 65, 64, 64, 63,
+ 62, 62, 62, 61, 60, 60, 59, 59,
+ 58, 58, 57, 57, 56, 56, 56, 55,
+ 55, 54, 55, 55, 54, 53, 53, 52,
+ 53, 53, 52, 51, 51, 50, 51, 50,
+ 49, 49, 50, 49, 49, 48, 48, 47,
+ 47, 48, 46, 45, 45, 45, 46, 45,
+ 45, 44, 45, 45, 45, 43, 42, 42,
+ 41, 43, 41, 40, 40, 39, 40, 41,
+ 39, 39, 39, 39, 39, 38, 35, 35,
+ 34, 37, 36, 34, 33, 33, 33, 35,
+ 34, 32, 32, 31, 32, 30, 29, 26,
+ 25, 25, 27, 26, 23, 23, 23, 25,
+ 24, 24, 22, 21, 20, 19, 16, 14,
+ 13, 13, 13, 10, 9, 7, 7, 7,
+ 12, 12, 12, 7, 0, 0, 0, 0
+};
+
+/* multiple axis color correction table,
+ * 64values = 2x2matrix for 16area, [s2.11].
+ */
+static const short default_macc_table[MACCTBL_SIZE] = {
+ 8192, 0, 0, 8192, 8192, 0, 0, 8192, 8192, 0, 0, 8192, 8192, 0, 0, 8192,
+ 8192, 0, 0, 8192, 8192, 0, 0, 8192, 8192, 0, 0, 8192, 8192, 0, 0, 8192,
+ 8192, 0, 0, 8192, 8192, 0, 0, 8192, 8192, 0, 0, 8192, 8192, 0, 0, 8192,
+ 8192, 0, 0, 8192, 8192, 0, 0, 8192, 8192, 0, 0, 8192, 8192, 0, 0, 8192
+};
+
+static const struct sh_css_isp_3a_config default_3a_config = {
+ .ae_y_coef_r = 25559,
+ .ae_y_coef_g = 32768,
+ .ae_y_coef_b = 7209,
+ .awb_lg_r = 65535,
+ .awb_lg_g = 65535,
+ .awb_lg_b = 65535,
+ .af_fir1_coef = {-3344, -6104, -19143, 19143, 6104, 3344, 0},
+ .af_fir2_coef = {1027, 0, -9219, 16384, -9219, 1027, 0}
+};
+
+static const struct sh_css_isp_wb_config default_wb_config = {
+ .integer_bits = 1,
+ .gr = 32768,
+ .r = 49152,
+ .b = 39321,
+ .gb = 32768
+};
+
+static const struct sh_css_isp_cc_config default_cc_config = {
+ .fraction_bits = 8,
+ .matrix = {255, 29, 120, 0, -374, -342, 0, -672, 301},
+};
+
+static const struct sh_css_isp_tnr_config default_tnr_config = {
+ .gain = 32768,
+ .threshold_y = 32,
+ .threshold_uv = 32,
+};
+
+static const struct sh_css_isp_ob_config default_ob_config = {
+ .mode = sh_css_isp_ob_mode_none,
+ .level_gr = 0,
+ .level_r = 0,
+ .level_b = 0,
+ .level_gb = 0,
+ .start_position = 0,
+ .end_position = 0
+};
+
+static const struct sh_css_isp_dp_config default_dp_config = {
+ .threshold = 8192,
+ .gain = 2048
+};
+
+static const struct sh_css_isp_nr_config default_nr_config = {
+ .gain = 16384,
+ .direction = 1280,
+ .threshold_cb = 0,
+ .threshold_cr = 0
+};
+
+static const struct sh_css_isp_ee_config default_ee_config = {
+ .gain = 8192,
+ .threshold = 128,
+ .detail_gain = 2048
+};
+
+static const struct sh_css_isp_de_config default_de_config = {
+ .pixelnoise = 0,
+ .c1_coring_threshold = 0,
+ .c2_coring_threshold = 0
+};
+
+static const struct sh_css_isp_gc_config default_gc_config = {
+ .gain_k1 = 2457, /* (1<<13) * 0.3 */
+ .gain_k2 = 2457 /* idem */
+};
+
+unsigned int
+sh_css_get_coord_table_ext_width(void)
+{
+ return GDC_COORD_TABLE_EXT_WIDTH;
+}
+
+int
+sh_css_get_gdc_coord_one(void)
+{
+ return HRT_GDC_COORD_ONE;
+}
+
+void
+sh_css_params_dis_get_coefficients(short **horizontal_coefficients,
+ short **vertical_coefficients)
+{
+ *horizontal_coefficients = dis_horicoef_tbl;
+ *vertical_coefficients = dis_vertcoef_tbl;
+ dis_coef_table_changed = ShTrue;
+}
+
+void
+sh_css_params_dis_get_projections(int *horizontal_projections,
+ int *vertical_projections)
+{
+ unsigned int actual_horiproj_num,
+ actual_vertproj_num,
+ actual_horiproj_size,
+ actual_vertproj_size, xmem_horiproj_size, xmem_vertproj_size, i;
+ int *hori_ptr = horizontal_projections,
+ *vert_ptr = vertical_projections;
+ void *xmem_hori_ptr = xmem_ptrs.sdis_horiproj,
+ *xmem_vert_ptr = xmem_ptrs.sdis_vertproj;
+
+ if (current_binary == NULL)
+ return;
+
+ actual_horiproj_num = current_binary->int_out_frame_info.height >>
+ (current_binary->dis_deci_factor_log2 + 1);
+ actual_vertproj_num =
+ current_binary->int_out_frame_info.padded_width >>
+ (current_binary->dis_deci_factor_log2 + 1);
+ actual_horiproj_size = actual_horiproj_num * sizeof(int);
+ actual_vertproj_size = actual_vertproj_num * sizeof(int);
+ xmem_horiproj_size = current_binary->dis_horiproj_num * sizeof(int);
+ xmem_vertproj_size = current_binary->dis_vertproj_num * sizeof(int);
+
+ for (i = 0; i < SDIS_COEF_TYPES; i++) {
+ hrt_isp_css_mm_load(xmem_hori_ptr, hori_ptr,
+ actual_horiproj_size);
+ xmem_hori_ptr += xmem_horiproj_size; /* skip padding area */
+ hori_ptr += actual_horiproj_num;
+
+ hrt_isp_css_mm_load(xmem_vert_ptr, vert_ptr,
+ actual_vertproj_size);
+ xmem_vert_ptr += xmem_vertproj_size; /* skip padding area */
+ vert_ptr += actual_vertproj_num;
+ }
+}
+
+void
+sh_css_params_dis_clear_coefficients(void)
+{
+ int i, j;
+ short *hori_ptr = dis_horicoef_tbl, *vert_ptr = dis_vertcoef_tbl;
+
+ for (i = 0; i < SDIS_COEF_TYPES; i++) {
+ for (j = 0; j < MAX_SDIS_HORICOEF_NUM; j++, hori_ptr++)
+ *hori_ptr = 1;
+ for (j = 0; j < MAX_SDIS_VERTCOEF_NUM; j++, vert_ptr++)
+ *vert_ptr = 1;
+ }
+ dis_coef_table_changed = ShTrue;
+}
+
+static void
+get_3a_stats_from_dmem(struct sh_css_isp_3a_output *output)
+{
+ unsigned int bytes;
+
+ bytes = current_binary->s3atbl_width *
+ current_binary->s3atbl_height * sizeof(*output);
+ hrt_isp_css_mm_load(xmem_ptrs.s3a_tbl, output, bytes);
+}
+
+static int
+merge_hi14bit_lo14bit(unsigned short hi, unsigned short lo)
+{
+ int val = (int) ((((unsigned int) hi << 14) & 0xfffc000) |
+ ((unsigned int) lo & 0x3fff));
+ return val;
+}
+
+static inline long calc_timediff(struct timeval *t0, struct timeval *t1)
+{
+ long diff;
+
+ if (t0->tv_sec != t1->tv_sec)
+ diff = 1000000;
+ else
+ diff = 0;
+ return diff + t1->tv_usec - t0->tv_usec;
+}
+
+static void
+get_3a_stats_from_vmem(struct sh_css_isp_3a_output *output)
+{
+ unsigned short *hi, *lo;
+ int readbytes, chunk, rest, kmax, i, j, k, elm, ofs;
+
+ readbytes = sizeof(unsigned short) *
+ S3ATBL_HI_LO_STRIDE * current_binary->s3atbl_height;
+ /* Do we need locks here ? */
+ hi = g_s3a_tbl_hi;
+ lo = g_s3a_tbl_lo;
+
+ chunk = (ISP_VEC_NELEMS >> current_binary->deci_factor_log2);
+ chunk = MAX(chunk, 1);
+
+ for (i = 0; i < current_binary->s3atbl_height; i++) {
+ elm = i * S3ATBL_HI_LO_STRIDE;
+ rest = current_binary->s3atbl_width;
+ j = 0;
+ while (j < current_binary->s3atbl_width) {
+ kmax = (rest > chunk) ? chunk : rest;
+ ofs = i * current_binary->s3atbl_width + j;
+ for (k = 0; k < kmax; k++, elm++)
+ output[ofs + k].ae_Y =
+ merge_hi14bit_lo14bit(hi[elm], lo[elm]);
+ for (k = 0; k < kmax; k++, elm++)
+ output[ofs + k].awb_cnt =
+ merge_hi14bit_lo14bit(hi[elm], lo[elm]);
+ for (k = 0; k < kmax; k++, elm++)
+ output[ofs + k].awb_GR =
+ merge_hi14bit_lo14bit(hi[elm], lo[elm]);
+ for (k = 0; k < kmax; k++, elm++)
+ output[ofs + k].awb_R =
+ merge_hi14bit_lo14bit(hi[elm], lo[elm]);
+ for (k = 0; k < kmax; k++, elm++)
+ output[ofs + k].awb_B =
+ merge_hi14bit_lo14bit(hi[elm], lo[elm]);
+ for (k = 0; k < kmax; k++, elm++)
+ output[ofs + k].awb_GB =
+ merge_hi14bit_lo14bit(hi[elm], lo[elm]);
+ for (k = 0; k < kmax; k++, elm++)
+ output[ofs + k].af_hpf1 =
+ merge_hi14bit_lo14bit(hi[elm], lo[elm]);
+ for (k = 0; k < kmax; k++, elm++)
+ output[ofs + k].af_hpf2 =
+ merge_hi14bit_lo14bit(hi[elm], lo[elm]);
+ j += kmax;
+ rest -= kmax;
+ }
+ }
+}
+
+void
+sh_css_params_3a_get_statistics(struct sh_css_isp_3a_output *output)
+{
+ if (current_binary->s3atbl_use_dmem)
+ get_3a_stats_from_dmem(output);
+ else
+ get_3a_stats_from_vmem(output);
+}
+
+void
+sh_css_params_3a_configure(struct sh_css_params *params,
+ const struct sh_css_isp_3a_config *config_3a)
+{
+ unsigned int i;
+ /* coefficients to calculate Y */
+ params->isp_parameters.ae_Ycoef_R =
+ uDIGIT_FITTING(config_3a->ae_y_coef_r, 16, AE_YCOEF_SHIFT);
+ params->isp_parameters.ae_Ycoef_G =
+ uDIGIT_FITTING(config_3a->ae_y_coef_g, 16, AE_YCOEF_SHIFT);
+ params->isp_parameters.ae_Ycoef_B =
+ uDIGIT_FITTING(config_3a->ae_y_coef_b, 16, AE_YCOEF_SHIFT);
+
+ /* awb level gate */
+ params->isp_parameters.awb_lg_Rmax = uDIGIT_FITTING(config_3a->awb_lg_r,
+ 16, ISP_BAYER_BITS);
+ params->isp_parameters.awb_lg_Gmax = uDIGIT_FITTING(config_3a->awb_lg_g,
+ 16, ISP_BAYER_BITS);
+ params->isp_parameters.awb_lg_Bmax = uDIGIT_FITTING(config_3a->awb_lg_b,
+ 16, ISP_BAYER_BITS);
+
+ /* af fir coefficients */
+ for (i = 0; i < 7; ++i) {
+ params->isp_parameters.af_fir1[i] =
+ sDIGIT_FITTING(config_3a->af_fir1_coef[i], 15,
+ AF_FIR_SHIFT);
+ params->isp_parameters.af_fir2[i] =
+ sDIGIT_FITTING(config_3a->af_fir2_coef[i], 15,
+ AF_FIR_SHIFT);
+ }
+ params->isp_params_changed = ShTrue;
+}
+
+void *
+sh_css_params_ddr_address_map(void)
+{
+ if (xmem_map_addr == NULL) {
+ xmem_map_addr =
+ hrt_isp_css_mm_calloc(align(sizeof(xmem_ptrs),
+ XMEM_BYTES_PER_WORD));
+ /* Copy XMEM address map to XMEM for SP access */
+ hrt_isp_css_mm_store(xmem_map_addr, &xmem_ptrs,
+ sizeof(xmem_ptrs));
+ }
+ return xmem_map_addr;
+}
+
+/* ****************************************************
+ * Each coefficient is stored as 7bits to fit 2 of them into one
+ * ISP vector element, so we will store 4 coefficents on every
+ * memory word (32bits)
+ *
+ * 0: Coefficient 0 used bits
+ * 1: Coefficient 1 used bits
+ * 2: Coefficient 2 used bits
+ * 3: Coefficient 3 used bit3
+ * x: not used
+ *
+ * xx33333332222222 | xx11111110000000
+ *
+ * ***************************************************
+ */
+static void
+store_fpntbl(struct sh_css_fpn_table *table, void *ptr)
+{
+ unsigned int i, j;
+ short *data_ptr = table->data;
+
+ for (i = 0; i < table->height; i++) {
+ for (j = 0; j < table->width; j += 4, ptr += 4, data_ptr += 4) {
+ int data = data_ptr[0] << 0 |
+ data_ptr[1] << 7 |
+ data_ptr[2] << 16 | data_ptr[3] << 23;
+ hrt_isp_css_mm_store_int(ptr, data);
+ }
+ }
+}
+
+static void
+convert_raw_to_fpn(struct sh_css_fpn_table *table)
+{
+ short maxval = 0;
+ unsigned int i;
+
+ /* Find the maximum value in the table */
+ for (i = 0; i < table->height * table->width; i++) {
+ short val = table->data[i];
+ /* Make sure FPN value can be represented in 13-bit unsigned
+ * number (ISP precision - 1), but note that actual input range
+ * depends on precision of input frame data.
+ */
+ if (val < 0 || val > 8191) {
+ sh_css_print("Error: FPN table value '%d' out "
+ "of range [0..8191]\n", val);
+ return;
+ }
+ maxval = MAX(maxval, val);
+ }
+ /* Find the lowest shift value to remap the values in the range
+ * 0..maxval to 0..2^shiftval*63.
+ */
+ table->shift = 0;
+ while (maxval > 63) {
+ maxval /= 2;
+ table->shift++;
+ }
+ /* Adjust the values in the table for the shift value */
+ for (i = 0; i < table->height * table->width; i++)
+ ((unsigned short *) table->data)[i] >>= table->shift;
+}
+
+sh_css_err
+sh_css_params_set_black_frame(struct sh_css_params *params,
+ const struct sh_css_frame *raw_black_frame)
+{
+ /* this function desperately needs to be moved to the ISP or SP such
+ * that it can use the DMA.
+ */
+ unsigned int height = raw_black_frame->info.height,
+ width = raw_black_frame->info.padded_width, y, x, k, data;
+ void *ptr = raw_black_frame->planes.raw.data;
+
+ if (params->fpn_table == NULL) {
+ params->fpn_table = sh_css_malloc(sizeof(*params->fpn_table));
+ if (params->fpn_table == NULL)
+ return sh_css_err_cannot_allocate_memory;
+ params->fpn_table->data = NULL;
+ params->fpn_table->width = 0;
+ params->fpn_table->height = 0;
+ params->fpn_table->shift = 0;
+ }
+ if (params->fpn_table->data &&
+ (params->fpn_table->width != width ||
+ params->fpn_table->height != height)) {
+ sh_css_free(params->fpn_table->data);
+ params->fpn_table->data = NULL;
+ }
+ if (params->fpn_table->data == NULL) {
+ params->fpn_table->data =
+ sh_css_malloc(height * width * sizeof(short));
+ if (!params->fpn_table->data)
+ return sh_css_err_cannot_allocate_memory;
+ params->fpn_table->width = width;
+ params->fpn_table->height = height;
+ params->fpn_table->shift = 0;
+ }
+
+ /* store raw to fpntbl */
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x += (ISP_NWAY * 2)) {
+ int ofs = y * width + x;
+ for (k = 0; k < ISP_NWAY; k += 2) {
+ hrt_isp_css_mm_load(ptr, &data, sizeof(int));
+ params->fpn_table->data[ofs + 2 * k] =
+ (short) (data & 0xFFFF);
+ params->fpn_table->data[ofs + 2 * k + 2] =
+ (short) ((data >> 16) & 0xFFFF);
+ ptr += 4; /* byte system address */
+ }
+ for (k = 0; k < ISP_NWAY; k += 2) {
+ hrt_isp_css_mm_load(ptr, &data, sizeof(int));
+ params->fpn_table->data[ofs + 2 * k + 1] =
+ (short) (data & 0xFFFF);
+ params->fpn_table->data[ofs + 2 * k + 3] =
+ (short) ((data >> 16) & 0xFFFF);
+ ptr += 4; /* byte system address */
+ }
+ }
+ }
+
+ /* raw -> fpn */
+ convert_raw_to_fpn(params->fpn_table);
+
+ /* overwrite isp parameter */
+ params->isp_parameters.fpn_shift = params->fpn_table->shift;
+ params->isp_parameters.fpn_enabled = 1;
+ params->fpn_table_changed = ShTrue;
+ params->isp_params_changed = ShTrue;
+ return sh_css_success;
+}
+
+struct sh_css_shading_table *
+sh_css_shading_table_alloc(unsigned int width,
+ unsigned int height,
+ unsigned int fraction_bits)
+{
+ unsigned int i;
+ struct sh_css_shading_table *me = sh_css_malloc(sizeof(*me));
+
+ if (me == NULL)
+ return NULL;
+ me->width = width;
+ me->height = height;
+ me->fraction_bits = fraction_bits;
+ for (i = 0; i < sh_css_num_sc_colors; i++) {
+ me->data[i] =
+ sh_css_malloc(width * height * sizeof(*me->data[0]));
+ if (me->data[i] == NULL) {
+ unsigned int j;
+ for (j = 0; j < i; j++)
+ sh_css_free(me->data[j]);
+ sh_css_free(me);
+ return NULL;
+ }
+ }
+ return me;
+}
+
+void
+sh_css_shading_table_free(struct sh_css_shading_table *table)
+{
+ unsigned int i;
+
+ if (table == NULL)
+ return;
+ for (i = 0; i < sh_css_num_sc_colors; i++) {
+ if (table->data[i])
+ sh_css_free(table->data[i]);
+ }
+ sh_css_free(table);
+}
+
+void
+sh_css_set_get_shading_table(struct sh_css_shading_table *
+ (*get_table) (unsigned int frame_width,
+ unsigned int frame_height,
+ unsigned int table_width,
+ unsigned int table_height))
+{
+ get_shading_table = get_table;
+}
+
+static sh_css_err
+store_sctbl(const struct sh_css_binary *binary, void *ddr_addr, int *shift)
+{
+ struct sh_css_shading_table *sctbl = NULL;
+ unsigned int aligned_width_per_color,
+ row_padding, i, j, k,
+ frame_width, frame_height, table_width, table_height;
+
+ aligned_width_per_color = align(binary->sctbl_width_per_color,
+ ISP_VEC_NELEMS);
+ frame_width = binary->in_frame_info.padded_width;
+ frame_height = binary->in_frame_info.height;
+ table_width =
+ CEIL_DIV(frame_width, 2 * (1 << binary->deci_factor_log2)) + 1;
+ table_height =
+ CEIL_DIV(frame_height, 2 * (1 << binary->deci_factor_log2)) + 1;
+ if (get_shading_table) {
+ sctbl = get_shading_table(frame_width, frame_height,
+ table_width, table_height);
+ if (sctbl == NULL)
+ return sh_css_err_cannot_obtain_shading_table;
+ } else {
+ /* initialize table with ones, shift becomes zero */
+ unsigned int i, elems;
+
+ elems =
+ table_height * SCTBL_NUM_COLORS * aligned_width_per_color;
+
+ for (i = 0; i < elems; i++, ddr_addr += sizeof(short))
+ hrt_isp_css_mm_store_short(ddr_addr, 1);
+ *shift = 0;
+ return sh_css_success;
+ }
+
+ *shift = sctbl->fraction_bits;
+ row_padding = aligned_width_per_color - sctbl->width;
+ for (i = 0; i < sctbl->height; i++) {
+ for (j = 0; j < SCTBL_NUM_COLORS; j++) {
+ hrt_isp_css_mm_store(ddr_addr,
+ &sctbl->data[j][i * sctbl->width],
+ sctbl->width * sizeof(short));
+ ddr_addr += sctbl->width * sizeof(short);
+ for (k = 0; k < row_padding;
+ k++, ddr_addr += sizeof(short))
+ hrt_isp_css_mm_store_short(ddr_addr, 0);
+ }
+ }
+ sh_css_shading_table_free(sctbl);
+ return sh_css_success;
+}
+
+void
+sh_css_params_configure_wb(struct sh_css_params *params,
+ const struct sh_css_isp_wb_config *wb_config)
+{
+ params->isp_parameters.wb_gain_shift =
+ uISP_REG_BIT - wb_config->integer_bits;
+ params->isp_parameters.wb_gain_GR =
+ uDIGIT_FITTING(wb_config->gr, 16 - wb_config->integer_bits,
+ params->isp_parameters.wb_gain_shift);
+ params->isp_parameters.wb_gain_R =
+ uDIGIT_FITTING(wb_config->r, 16 - wb_config->integer_bits,
+ params->isp_parameters.wb_gain_shift);
+ params->isp_parameters.wb_gain_B =
+ uDIGIT_FITTING(wb_config->b, 16 - wb_config->integer_bits,
+ params->isp_parameters.wb_gain_shift);
+ params->isp_parameters.wb_gain_GB =
+ uDIGIT_FITTING(wb_config->gb, 16 - wb_config->integer_bits,
+ params->isp_parameters.wb_gain_shift);
+ params->isp_params_changed = ShTrue;
+}
+
+void
+sh_css_params_configure_cc(struct sh_css_params *params,
+ const struct sh_css_isp_cc_config *cc_config)
+{
+ params->isp_parameters.csc_coef_shift = (int) cc_config->fraction_bits;
+ params->isp_parameters.YC1C2YCBCR00 = (int) cc_config->matrix[0];
+ params->isp_parameters.YC1C2YCBCR01 = (int) cc_config->matrix[1];
+ params->isp_parameters.YC1C2YCBCR02 = (int) cc_config->matrix[2];
+ params->isp_parameters.YC1C2YCBCR10 = (int) cc_config->matrix[3];
+ params->isp_parameters.YC1C2YCBCR11 = (int) cc_config->matrix[4];
+ params->isp_parameters.YC1C2YCBCR12 = (int) cc_config->matrix[5];
+ params->isp_parameters.YC1C2YCBCR20 = (int) cc_config->matrix[6];
+ params->isp_parameters.YC1C2YCBCR21 = (int) cc_config->matrix[7];
+ params->isp_parameters.YC1C2YCBCR22 = (int) cc_config->matrix[8];
+ params->isp_params_changed = ShTrue;
+}
+
+void
+sh_css_params_configure_tnr(struct sh_css_params *params,
+ const struct sh_css_isp_tnr_config *tnr_config)
+{
+ params->isp_parameters.tnr_coef =
+ uDIGIT_FITTING(tnr_config->gain, 16, TNR_COEF_SHIFT);
+ params->isp_parameters.tnr_threshold_Y =
+ uDIGIT_FITTING(tnr_config->threshold_y, 16, ISP_BAYER_BITS);
+ params->isp_parameters.tnr_threshold_C =
+ uDIGIT_FITTING(tnr_config->threshold_uv, 16, ISP_BAYER_BITS);
+ params->isp_params_changed = ShTrue;
+}
+
+void
+sh_css_params_configure_ob(struct sh_css_params *params,
+ const struct sh_css_isp_ob_config *ob_config)
+{
+ switch (ob_config->mode) {
+ case sh_css_isp_ob_mode_fixed:
+ params->isp_parameters.ob_blacklevel_GR =
+ uDIGIT_FITTING(ob_config->level_gr, 16, ISP_BAYER_BITS);
+ params->isp_parameters.ob_blacklevel_R =
+ uDIGIT_FITTING(ob_config->level_r, 16, ISP_BAYER_BITS);
+ params->isp_parameters.ob_blacklevel_B =
+ uDIGIT_FITTING(ob_config->level_b, 16, ISP_BAYER_BITS);
+ params->isp_parameters.ob_blacklevel_GB =
+ uDIGIT_FITTING(ob_config->level_gb, 16, ISP_BAYER_BITS);
+ params->isp_parameters.obarea_startBQ = 0;
+ params->isp_parameters.obarea_lengthBQ = 0;
+ params->isp_parameters.obarea_lengthBQ_inverse = 0;
+ break;
+ case sh_css_isp_ob_mode_raster:
+ params->isp_parameters.ob_blacklevel_GR = 0;
+ params->isp_parameters.ob_blacklevel_R = 0;
+ params->isp_parameters.ob_blacklevel_B = 0;
+ params->isp_parameters.ob_blacklevel_GB = 0;
+ params->isp_parameters.obarea_startBQ =
+ ob_config->start_position;
+ params->isp_parameters.obarea_lengthBQ =
+ ((ob_config->end_position - ob_config->start_position) + 1);
+ params->isp_parameters.obarea_lengthBQ_inverse =
+ (1 << 12) / params->isp_parameters.obarea_lengthBQ;
+ break;
+ default:
+ params->isp_parameters.ob_blacklevel_GR = 0;
+ params->isp_parameters.ob_blacklevel_R = 0;
+ params->isp_parameters.ob_blacklevel_B = 0;
+ params->isp_parameters.ob_blacklevel_GB = 0;
+ params->isp_parameters.obarea_startBQ = 0;
+ params->isp_parameters.obarea_lengthBQ = 0;
+ params->isp_parameters.obarea_lengthBQ_inverse = 0;
+ break;
+ }
+ params->isp_params_changed = ShTrue;
+}
+
+void
+sh_css_params_configure_dp(struct sh_css_params *params,
+ const struct sh_css_isp_dp_config *dp_config)
+{
+ params->isp_parameters.dp_threshold_single_when_2adjacent_on =
+ BAYER_MAXVAL;
+ params->isp_parameters.dp_threshold_2adjacent_when_2adjacent_on =
+ uDIGIT_FITTING(dp_config->threshold, 16, ISP_BAYER_BITS);
+ params->isp_parameters.dp_threshold_single_when_2adjacent_off =
+ uDIGIT_FITTING(dp_config->threshold, 16, ISP_BAYER_BITS);
+ params->isp_parameters.dp_threshold_2adjacent_when_2adjacent_off =
+ BAYER_MAXVAL;
+ params->isp_parameters.dp_gain =
+ uDIGIT_FITTING(dp_config->gain, 8, DP_GAIN_SHIFT);
+ params->isp_params_changed = ShTrue;
+}
+
+void
+sh_css_params_configure_nree(struct sh_css_params *params,
+ const struct sh_css_isp_nr_config *nr_config,
+ const struct sh_css_isp_ee_config *ee_config)
+{
+ int asiWk1, asiWk2, asiWk3;
+
+ /* BNR (Bayer Noise Reduction) */
+ params->isp_parameters.bnr_threshold_low =
+ uDIGIT_FITTING(nr_config->direction, 16, ISP_BAYER_BITS);
+ params->isp_parameters.bnr_threshold_width_log2 =
+ uFRACTION_BITS_FITTING(8);
+ params->isp_parameters.bnr_threshold_width =
+ 1 << params->isp_parameters.bnr_threshold_width_log2;
+ params->isp_parameters.bnr_gain_all =
+ uDIGIT_FITTING(nr_config->gain, 16, BNR_GAIN_SHIFT);
+ params->isp_parameters.bnr_gain_dir =
+ uDIGIT_FITTING(nr_config->gain, 16, BNR_GAIN_SHIFT);
+ params->isp_parameters.bnr_clip =
+ uDIGIT_FITTING(16384, 16, ISP_BAYER_BITS);
+
+ /* YNR (Y Noise Reduction), YEE (Y Edge Enhancement) */
+ asiWk1 = (int) ee_config->gain;
+ asiWk2 = asiWk1 / 8;
+ asiWk3 = asiWk1 / 4;
+ params->isp_parameters.ynr_threshold =
+ uDIGIT_FITTING(8192, 16, ISP_BAYER_BITS);
+ params->isp_parameters.ynr_gain_dir =
+ params->isp_parameters.bnr_gain_dir / 2;
+ params->isp_parameters.ynr_gain_all =
+ params->isp_parameters.bnr_gain_all / 2;
+ params->isp_parameters.ynryee_dirthreshold_s =
+ MIN((uDIGIT_FITTING(nr_config->direction, 16, ISP_BAYER_BITS) << 1),
+ BAYER_MAXVAL);
+ params->isp_parameters.ynryee_dirthreshold_g =
+ MIN((uDIGIT_FITTING(nr_config->direction, 16, ISP_BAYER_BITS) << 4),
+ BAYER_MAXVAL);
+ params->isp_parameters.ynryee_dirthreshold_width_log2 =
+ uFRACTION_BITS_FITTING(8);
+ params->isp_parameters.ynryee_dirthreshold_width =
+ 1 << params->isp_parameters.ynryee_dirthreshold_width_log2;
+ params->isp_parameters.yee_detailgain =
+ uDIGIT_FITTING(ee_config->detail_gain, 11, YEE_DETAILGAIN_SHIFT);
+ params->isp_parameters.yee_coring_s =
+ (uDIGIT_FITTING(56, 16, ISP_BAYER_BITS) *
+ ee_config->threshold) >> 8;
+ params->isp_parameters.yee_coring_g =
+ (uDIGIT_FITTING(224, 16, ISP_BAYER_BITS) *
+ ee_config->threshold) >> 8;
+ /* 8; // *1.125 ->[s4.8] */
+ params->isp_parameters.yee_scale_plus_s =
+ (asiWk1 + asiWk2) >> (11 - YEE_SCALE_SHIFT);
+ /* 8; // ( * -.25)->[s4.8] */
+ params->isp_parameters.yee_scale_plus_g =
+ (0 - asiWk3) >> (11 - YEE_SCALE_SHIFT);
+ /* 8; // *0.875 ->[s4.8] */
+ params->isp_parameters.yee_scale_minus_s =
+ (asiWk1 - asiWk2) >> (11 - YEE_SCALE_SHIFT);
+ /* 8; // ( *.25 ) ->[s4.8] */
+ params->isp_parameters.yee_scale_minus_g =
+ (asiWk3) >> (11 - YEE_SCALE_SHIFT);
+ params->isp_parameters.yee_clip_plus_s =
+ uDIGIT_FITTING(32760, 16, ISP_BAYER_BITS);
+ params->isp_parameters.yee_clip_plus_g = 0;
+ params->isp_parameters.yee_clip_minus_s =
+ uDIGIT_FITTING(504, 16, ISP_BAYER_BITS);
+ params->isp_parameters.yee_clip_minus_g =
+ uDIGIT_FITTING(32256, 16, ISP_BAYER_BITS);
+ params->isp_parameters.ynryee_Yclip = BAYER_MAXVAL;
+ params->isp_params_changed = ShTrue;
+}
+
+void
+sh_css_params_configure_de(struct sh_css_params *params,
+ const struct sh_css_isp_de_config *de_config)
+{
+ params->isp_parameters.de_pixelnoise =
+ uDIGIT_FITTING(de_config->pixelnoise, 16, ISP_BAYER_BITS);
+ params->isp_parameters.de_C1_coring_threshold =
+ uDIGIT_FITTING(de_config->c1_coring_threshold, 16, ISP_BAYER_BITS);
+ params->isp_parameters.de_C2_coring_threshold =
+ uDIGIT_FITTING(de_config->c2_coring_threshold, 16, ISP_BAYER_BITS);
+ params->isp_params_changed = ShTrue;
+}
+
+void
+sh_css_params_configure_gc(struct sh_css_params *params,
+ const struct sh_css_isp_gc_config *gc_config)
+{
+ params->isp_parameters.gamma_gain_k1 = gc_config->gain_k1;
+ params->isp_parameters.gamma_gain_k2 = gc_config->gain_k2;
+ params->isp_params_changed = ShTrue;
+}
+
+void
+sh_css_params_set_gamma_table(struct sh_css_params *params,
+ unsigned short *gamma_table)
+{
+ params->gamma_table = gamma_table;
+ params->gamma_table_changed = ShTrue;
+}
+
+void
+sh_css_params_get_gamma_table(struct sh_css_params *params,
+ unsigned short *gamma_table)
+{
+ memcpy(gamma_table, params->gamma_table, GAMMATBL_SIZE);
+}
+
+void
+sh_css_params_set_ctc_table(struct sh_css_params *params,
+ unsigned short *ctc_table)
+{
+ params->ctc_table = ctc_table;
+ params->ctc_table_changed = ShTrue;
+}
+
+void
+sh_css_params_get_default_gamma_table(const unsigned short **gamma_table)
+{
+ *gamma_table = default_gamma_table;
+}
+
+void
+sh_css_params_get_default_ctc_table(const unsigned short **ctc_table)
+{
+ *ctc_table = default_ctc_table;
+}
+
+void
+sh_css_params_get_default_macc_table(const short **macc_table)
+{
+ *macc_table = default_macc_table;
+}
+
+void
+sh_css_params_get_default_3a_config(const struct sh_css_isp_3a_config **config)
+{
+ *config = &default_3a_config;
+}
+
+void
+sh_css_params_get_default_wb_config(const struct sh_css_isp_wb_config **config)
+{
+ *config = &default_wb_config;
+}
+
+void
+sh_css_params_get_default_cc_config(const struct sh_css_isp_cc_config **config)
+{
+ *config = &default_cc_config;
+}
+
+void
+sh_css_params_get_default_tnr_config(const struct sh_css_isp_tnr_config
+ **config)
+{
+ *config = &default_tnr_config;
+}
+
+void
+sh_css_params_get_default_ob_config(const struct sh_css_isp_ob_config **config)
+{
+ *config = &default_ob_config;
+}
+
+void
+sh_css_params_get_default_dp_config(const struct sh_css_isp_dp_config **config)
+{
+ *config = &default_dp_config;
+}
+
+void
+sh_css_params_get_default_nr_config(const struct sh_css_isp_nr_config **config)
+{
+ *config = &default_nr_config;
+}
+
+void
+sh_css_params_get_default_ee_config(const struct sh_css_isp_ee_config **config)
+{
+ *config = &default_ee_config;
+}
+
+void
+sh_css_params_get_default_de_config(const struct sh_css_isp_de_config **config)
+{
+ *config = &default_de_config;
+}
+
+void
+sh_css_params_get_default_gc_config(const struct sh_css_isp_gc_config **config)
+{
+ *config = &default_gc_config;
+}
+
+void
+sh_css_params_set_macc_table(struct sh_css_params *params,
+ const short *macc_table)
+{
+ params->macc_table = macc_table;
+ params->macc_table_changed = ShTrue;
+}
+
+void
+sh_css_morph_table_free(struct sh_css_morph_table *me)
+{
+ unsigned int i;
+
+ if (me == NULL)
+ return;
+
+ for (i = 0; i < sh_css_morph_table_num_planes; i++) {
+ if (me->coordinates_x[i])
+ sh_css_free(me->coordinates_x[i]);
+ if (me->coordinates_y[i])
+ sh_css_free(me->coordinates_y[i]);
+ }
+ sh_css_free(me);
+}
+
+struct sh_css_morph_table *
+sh_css_morph_table_allocate(unsigned int width, unsigned int height)
+{
+ unsigned int i;
+ struct sh_css_morph_table *me = sh_css_malloc(sizeof(*me));
+
+ if (!me)
+ return NULL;
+
+ for (i = 0; i < sh_css_morph_table_num_planes; i++) {
+ me->coordinates_x[i] = NULL;
+ me->coordinates_y[i] = NULL;
+ }
+
+ for (i = 0; i < sh_css_morph_table_num_planes; i++) {
+ me->coordinates_x[i] =
+ sh_css_malloc(height * GDC_COORD_TABLE_EXT_WIDTH *
+ sizeof(*me->coordinates_x[i]));
+ me->coordinates_y[i] =
+ sh_css_malloc(height * GDC_COORD_TABLE_EXT_WIDTH *
+ sizeof(*me->coordinates_y[i]));
+ if (!me->coordinates_x[i] || !me->coordinates_y[i]) {
+ sh_css_morph_table_free(me);
+ return NULL;
+ }
+ }
+ me->width = width;
+ me->height = height;
+ return me;
+}
+
+sh_css_err
+sh_css_params_default_morph_table(const struct sh_css_morph_table **table,
+ unsigned int width,
+ unsigned int height)
+{
+ unsigned int i, j, k,
+ step = (ISP_VEC_NELEMS / 16) * 128,
+ table_width = GDC_COORD_TABLE_EXT_WIDTH;
+ short start_x[sh_css_morph_table_num_planes] = { -8, 0, -8, 0, 0, -8 },
+ start_y[sh_css_morph_table_num_planes] = {
+ 0, 0, -8, -8, -8, 0};
+ struct sh_css_morph_table *tab =
+ sh_css_morph_table_allocate(width, height);
+ if (!tab)
+ return sh_css_err_cannot_allocate_memory;
+
+ for (i = 0; i < sh_css_morph_table_num_planes; i++) {
+ short val_y = start_y[i];
+ for (j = 0; j < height; j++) {
+ short val_x = start_x[i];
+ unsigned short *x_ptr =
+ &tab->coordinates_x[i][j * table_width], *y_ptr =
+ &tab->coordinates_y[i][j * table_width];
+ for (k = 0; k < width;
+ k++, x_ptr++, y_ptr++, val_x += step) {
+ if (k == 0)
+ *x_ptr = 0;
+ else if (k == width - 1)
+ *x_ptr = val_x + 2 * start_x[i];
+ else
+ *x_ptr = val_x;
+ if (j == 0)
+ *y_ptr = 0;
+ else
+ *y_ptr = val_y;
+ }
+ val_y += step;
+ }
+ }
+ *table = tab;
+
+ return sh_css_success;
+}
+
+void
+sh_css_params_set_morph_table(struct sh_css_params *params,
+ const struct sh_css_morph_table *table)
+{
+ params->morph_table = table;
+ params->morph_table_changed = ShTrue;
+}
+
+const struct sh_css_morph_table *
+sh_css_params_get_morph_table(const struct sh_css_params *params)
+{
+ return params->morph_table;
+}
+
+static sh_css_err
+alloc(void **ptr, unsigned int bytes)
+{
+ void *p = hrt_isp_css_mm_alloc(bytes);
+ if (p == NULL)
+ return sh_css_err_cannot_allocate_memory;
+ *ptr = p;
+ return sh_css_success;
+}
+
+static void
+safe_free(void *ptr)
+{
+ if (ptr)
+ hrt_isp_css_mm_free(ptr);
+}
+
+sh_css_err
+sh_css_params_init(void)
+{
+ /* check to make sure the exported macros match the internal ones */
+ if (sh_css_num_macc_axes != NUM_MACC_AXES)
+ return sh_css_err_internal_error;
+ if (sh_css_ctc_table_size != CTCTBL_SIZE)
+ return sh_css_err_internal_error;
+ if (sh_css_gamma_table_size != GAMMATBL_SIZE)
+ return sh_css_err_internal_error;
+ if (sh_css_num_dis_coef_types != SDIS_COEF_TYPES)
+ return sh_css_err_internal_error;
+ if (sh_css_ctc_coef_shift != CTC_COEF_PIXELVAL_SHIFT)
+ return sh_css_err_internal_error;
+ if (sh_css_gamma_gain_k_shift != GAMMA_GAIN_K_SHIFT)
+ return sh_css_err_internal_error;
+ if (sizeof(struct s_s3a_output) != sizeof(struct sh_css_isp_3a_output))
+ return sh_css_err_internal_error;
+
+ return_on_error(alloc(&xmem_ptrs.isp_param, XMEM_ISPPARM_BYTES));
+ return_on_error(alloc(&xmem_ptrs.ctc_tbl, XMEM_CTCTBL_BYTES));
+ return_on_error(alloc(&xmem_ptrs.gamma_tbl, XMEM_GAMMATBL_BYTES));
+ return_on_error(alloc(&xmem_ptrs.macc_tbl, XMEM_MACCTBL_BYTES));
+ return_on_error(alloc(&xmem_ptrs.fpn_tbl, XMEM_FPNTBL_BYTES));
+ return_on_error(alloc(&xmem_ptrs.sc_tbl, XMEM_SCTBL_BYTES));
+ return_on_error(alloc(&xmem_ptrs.s3a_tbl, XMEM_S3ATBL_BYTES));
+ return_on_error(alloc(&xmem_ptrs.s3a_tbl_hi, XMEM_S3ATBL_HI_LO_BYTES));
+ return_on_error(alloc(&xmem_ptrs.s3a_tbl_lo, XMEM_S3ATBL_HI_LO_BYTES));
+ return_on_error(alloc
+ (&xmem_ptrs.sdis_horicoef, SDIS_HORICOEF_TBL_BYTES));
+ return_on_error(alloc
+ (&xmem_ptrs.sdis_vertcoef, SDIS_VERTCOEF_TBL_BYTES));
+ return_on_error(alloc
+ (&xmem_ptrs.sdis_horiproj, SDIS_HORIPROJ_TBL_BYTES));
+ return_on_error(alloc
+ (&xmem_ptrs.sdis_vertproj, SDIS_VERTPROJ_TBL_BYTES));
+
+#if DUMP_BAYER
+#error DUMP_BAYER currently not supported (alloc must be binary independent)
+ xmem_ptrs.bayer0 =
+ hrt_isp_css_alloc_image_in_ddr(binary_info->elems_per_line,
+ binary_info->lines_per_frame,
+ ELEMS_PER_XWORD);
+ xmem_ptrs.bayer1 =
+ hrt_isp_css_alloc_image_in_ddr(binary_info->elems_per_line,
+ binary_info->lines_per_frame,
+ ELEMS_PER_XWORD);
+#endif
+
+ return_on_error(alloc(&xmem_ptrs.tetra_r_x, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc(&xmem_ptrs.tetra_r_y, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc
+ (&xmem_ptrs.tetra_gr_x, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc
+ (&xmem_ptrs.tetra_gr_y, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc
+ (&xmem_ptrs.tetra_gb_x, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc
+ (&xmem_ptrs.tetra_gb_y, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc(&xmem_ptrs.tetra_b_x, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc(&xmem_ptrs.tetra_b_y, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc
+ (&xmem_ptrs.tetra_ratb_x, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc
+ (&xmem_ptrs.tetra_ratb_y, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc
+ (&xmem_ptrs.tetra_batr_x, GDC_BYTES_PER_COORD_TABLE));
+ return_on_error(alloc
+ (&xmem_ptrs.tetra_batr_y, GDC_BYTES_PER_COORD_TABLE));
+
+ g_s3a_tbl_hi = hmm_vmap(xmem_ptrs.s3a_tbl_hi);
+ g_s3a_tbl_lo = hmm_vmap(xmem_ptrs.s3a_tbl_lo);
+ return sh_css_success;
+}
+
+void
+sh_css_params_uninit(void)
+{
+ safe_free(xmem_ptrs.isp_param);
+ safe_free(xmem_ptrs.ctc_tbl);
+ safe_free(xmem_ptrs.gamma_tbl);
+ safe_free(xmem_ptrs.macc_tbl);
+ safe_free(xmem_ptrs.fpn_tbl);
+ safe_free(xmem_ptrs.sc_tbl);
+ safe_free(xmem_ptrs.s3a_tbl);
+ safe_free(xmem_ptrs.s3a_tbl_hi);
+ safe_free(xmem_ptrs.s3a_tbl_lo);
+ safe_free(xmem_ptrs.sdis_horicoef);
+ safe_free(xmem_ptrs.sdis_vertcoef);
+ safe_free(xmem_ptrs.sdis_horiproj);
+ safe_free(xmem_ptrs.sdis_vertproj);
+ safe_free(xmem_ptrs.tetra_r_x);
+ safe_free(xmem_ptrs.tetra_r_y);
+ safe_free(xmem_ptrs.tetra_gr_x);
+ safe_free(xmem_ptrs.tetra_gr_y);
+ safe_free(xmem_ptrs.tetra_gb_x);
+ safe_free(xmem_ptrs.tetra_gb_y);
+ safe_free(xmem_ptrs.tetra_b_x);
+ safe_free(xmem_ptrs.tetra_b_y);
+ safe_free(xmem_ptrs.tetra_ratb_x);
+ safe_free(xmem_ptrs.tetra_ratb_y);
+ safe_free(xmem_ptrs.tetra_batr_x);
+ safe_free(xmem_ptrs.tetra_batr_y);
+}
+
+static void write_morph_plane(unsigned short *data, unsigned int height,
+ void *dest)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < GDC_COORD_TABLE_EXT_WIDTH; j++) {
+ hrt_isp_css_mm_store_short(dest, *data);
+ dest += sizeof(short);
+ data++;
+ }
+ }
+}
+
+sh_css_err
+sh_css_params_write_to_ddr(struct sh_css_params *params,
+ const struct sh_css_binary *binary_info)
+{
+ if (current_isp_params != params) {
+ params->isp_params_changed = ShTrue;
+ params->fpn_table_changed = ShTrue;
+ params->morph_table_changed = ShTrue;
+ params->macc_table_changed = ShTrue;
+ params->gamma_table_changed = ShTrue;
+ params->ctc_table_changed = ShTrue;
+ params->sc_table_stored = ShFalse;
+ }
+ current_isp_params = params;
+
+ if (binary_info->enable_fpnr &&
+ params->isp_parameters.fpn_enabled == 1 &&
+ params->fpn_table_changed) {
+ store_fpntbl(params->fpn_table, xmem_ptrs.fpn_tbl);
+ params->fpn_table_changed = ShFalse;
+ }
+#ifdef HRT_CSIM
+ else if (binary_info->enable_fpnr &&
+ params->isp_parameters.fpn_enabled == 0 &&
+ params->fpn_table_changed) {
+ unsigned int i, elems;
+ void *ptr = xmem_ptrs.fpn_tbl;
+ elems = binary_info->in_frame_info.height *
+ binary_info->in_frame_info.padded_width;
+ /* prevent warnings when reading fpn table in csim. Actual
+ values are not used when fpn is disabled. */
+ for (i = 0; i < elems; i += sizeof(int), ptr += sizeof(int))
+ hrt_isp_css_mm_store_int(ptr, 0);
+ params->fpn_table_changed = ShFalse;
+ }
+#endif
+ if (binary_info->enable_sc && !params->sc_table_stored) {
+ return_on_error(store_sctbl(binary_info,
+ xmem_ptrs.sc_tbl,
+ ¶ms->isp_parameters.
+ sc_gain_shift));
+ params->sc_table_stored = ShTrue;
+ }
+
+ if (params->isp_params_changed) {
+ hrt_isp_css_mm_store(xmem_ptrs.isp_param,
+ ¶ms->isp_parameters,
+ sizeof(struct s_ispparm));
+ params->isp_params_changed = ShFalse;
+#ifdef HRT_CSIM
+ {
+ /* ispparm struct is read with DMA which reads
+ multiples of the DDR word with (32 bytes):
+ HIVE_ISP_DDR_WORD_BITS. So we pad with zeroes to
+ prevent warnings in csim. */
+ unsigned int aligned_width =
+ align(sizeof(struct s_ispparm),
+ HIVE_ISP_DDR_WORD_BITS / 8), i;
+ for (i = 0;
+ i < aligned_width - sizeof(struct s_ispparm);
+ i++) {
+ hrt_isp_css_mm_store_char(xmem_ptrs.isp_param +
+ sizeof(struct
+ s_ispparm) + i,
+ 0);
+ }
+ }
+#endif
+ }
+
+ if (params->ctc_table && params->ctc_table_changed) {
+ hrt_isp_css_mm_store(xmem_ptrs.ctc_tbl,
+ params->ctc_table, XMEM_CTCTBL_BYTES);
+ params->ctc_table_changed = ShFalse;
+ }
+ if (params->gamma_table && params->gamma_table_changed) {
+ hrt_isp_css_mm_store(xmem_ptrs.gamma_tbl,
+ params->gamma_table, XMEM_GAMMATBL_BYTES);
+ params->gamma_table_changed = ShFalse;
+ }
+ if (binary_info->enable_macc &&
+ params->macc_table && params->macc_table_changed) {
+ unsigned int i;
+ for (i = 0; i < MACCTBL_SIZE; i++)
+ curr_macc_table[i] =
+ sDIGIT_FITTING(params->macc_table[i], 13,
+ MACC_COEF_SHIFT);
+ hrt_isp_css_mm_store(xmem_ptrs.macc_tbl, curr_macc_table,
+ XMEM_MACCTBL_BYTES);
+ params->macc_table_changed = ShFalse;
+ }
+
+ if (binary_info->enable_dis && dis_coef_table_changed) {
+ unsigned int actual_horicoef_num,
+ actual_vertcoef_num,
+ actual_horicoef_size,
+ actual_vertcoef_size,
+ hori_padding,
+ vert_padding,
+ i, j,
+ dis_deci_factor = 1 << binary_info->dis_deci_factor_log2;
+ short *hori_ptr = dis_horicoef_tbl,
+ *vert_ptr = dis_vertcoef_tbl;
+ void *xmem_hori_ptr = xmem_ptrs.sdis_horicoef,
+ *xmem_vert_ptr = xmem_ptrs.sdis_vertcoef;
+
+ /* why multiply with dis_deci_factor?? */
+ actual_horicoef_num =
+ binary_info->int_out_frame_info.padded_width /
+ (2 * dis_deci_factor) * dis_deci_factor;
+ actual_vertcoef_num =
+ binary_info->int_out_frame_info.height /
+ (2 * dis_deci_factor) * dis_deci_factor;
+ actual_horicoef_size = actual_horicoef_num * sizeof(short);
+ actual_vertcoef_size = actual_vertcoef_num * sizeof(short);
+ hori_padding =
+ binary_info->dis_horicoef_num - actual_horicoef_num;
+ vert_padding =
+ binary_info->dis_vertcoef_num - actual_vertcoef_num;
+ for (i = 0; i < SDIS_COEF_TYPES; i++) {
+ hrt_isp_css_mm_store(xmem_hori_ptr, hori_ptr,
+ actual_horicoef_size);
+ xmem_hori_ptr += actual_horicoef_size;
+ hori_ptr += actual_horicoef_num;
+ for (j = 0; j < hori_padding;
+ j++, xmem_hori_ptr += sizeof(short))
+ hrt_isp_css_mm_store_short(xmem_hori_ptr, 0);
+ }
+ for (i = 0; i < SDIS_COEF_TYPES; i++) {
+ hrt_isp_css_mm_store(xmem_vert_ptr, vert_ptr,
+ actual_vertcoef_size);
+ xmem_vert_ptr += actual_vertcoef_size;
+ vert_ptr += actual_vertcoef_num;
+ for (j = 0; j < vert_padding;
+ j++, xmem_vert_ptr += sizeof(short))
+ hrt_isp_css_mm_store_short(xmem_vert_ptr, 0);
+ }
+ dis_coef_table_changed = ShFalse;
+ }
+
+ if (params->morph_table && params->morph_table_changed) {
+ unsigned int i;
+ void *virt_addr_tetra_x[sh_css_morph_table_num_planes] = {
+ xmem_ptrs.tetra_r_x,
+ xmem_ptrs.tetra_gr_x,
+ xmem_ptrs.tetra_gb_x,
+ xmem_ptrs.tetra_b_x,
+ xmem_ptrs.tetra_ratb_x,
+ xmem_ptrs.tetra_batr_x
+ };
+ void *virt_addr_tetra_y[sh_css_morph_table_num_planes] = {
+ xmem_ptrs.tetra_r_y,
+ xmem_ptrs.tetra_gr_y,
+ xmem_ptrs.tetra_gb_y,
+ xmem_ptrs.tetra_b_y,
+ xmem_ptrs.tetra_ratb_y,
+ xmem_ptrs.tetra_batr_y
+ };
+ const struct sh_css_morph_table *table = params->morph_table;
+
+ for (i = 0; i < sh_css_morph_table_num_planes; i++) {
+ write_morph_plane(table->coordinates_x[i],
+ table->height,
+ virt_addr_tetra_x[i]);
+ write_morph_plane(table->coordinates_y[i],
+ table->height,
+ virt_addr_tetra_y[i]);
+
+#if 0
+ hrt_isp_css_write_image_to_ddr(
+ table->coordinates_x[i],
+ GDC_COORD_TABLE_EXT_WIDTH,
+ table->height,
+ GDC_COORDS_PER_XMEM_ADDR,
+ 0, virt_addr_tetra_x[i]);
+ hrt_isp_css_write_image_to_ddr(
+ table->coordinates_y[i],
+ GDC_COORD_TABLE_EXT_WIDTH,
+ table->height,
+ GDC_COORDS_PER_XMEM_ADDR,
+ 0, virt_addr_tetra_y[i]);
+#endif
+ }
+ params->morph_table_changed = ShFalse;
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_params_set_current_binary(const struct sh_css_binary *binary)
+{
+ current_binary = binary;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_params_allocate(struct sh_css_params **params)
+{
+ struct sh_css_params *me = sh_css_malloc(sizeof(*me));
+ if (me == NULL)
+ return sh_css_err_cannot_allocate_memory;
+ if (params)
+ *params = me;
+ /* trick to get the FPN table initialized with zeroes in csim */
+ me->fpn_table_changed = ShTrue;
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_params_free(struct sh_css_params *params)
+{
+ if (params == NULL)
+ return sh_css_err_invalid_arguments;
+ sh_css_free(params);
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_params_default(struct sh_css_params *params)
+{
+ sh_css_params_3a_configure(params, &default_3a_config);
+ sh_css_params_configure_wb(params, &default_wb_config);
+ sh_css_params_configure_cc(params, &default_cc_config);
+ sh_css_params_configure_tnr(params, &default_tnr_config);
+ sh_css_params_configure_ob(params, &default_ob_config);
+ sh_css_params_configure_dp(params, &default_dp_config);
+ sh_css_params_configure_nree(params, &default_nr_config,
+ &default_ee_config);
+ sh_css_params_configure_de(params, &default_de_config);
+ sh_css_params_configure_gc(params, &default_gc_config);
+ sh_css_params_set_macc_table(params, default_macc_table);
+ sh_css_params_set_gamma_table(params, default_gamma_table);
+ sh_css_params_set_ctc_table(params, default_ctc_table);
+ sh_css_params_dis_clear_coefficients();
+ params->fpn_table = NULL;
+ params->morph_table = NULL;
+ return sh_css_success;
+}
+
+int
+sh_css_isp_grid_deci_factor_log2(int width, int height)
+{
+ int fact, fact1;
+ fact = 5;
+ while (ISP_BQ_GRID_WIDTH(width, fact - 1) <= MAX_BQ_GRID_WIDTH &&
+ ISP_BQ_GRID_HEIGHT(height, fact - 1) <= MAX_BQ_GRID_HEIGHT &&
+ fact > 3)
+ fact--;
+
+ /* fact1 satisfies the specification of gird size. fact and fact1 is
+ not the same for some resolution (fact=4 and fact1=5 for 5mp). */
+ if (width >= 2560)
+ fact1 = 5;
+ else if (width >= 1280)
+ fact1 = 4;
+ else
+ fact1 = 3;
+ return MAX(fact, fact1);
+}
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_params.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_params.h
new file mode 100644
index 0000000..2598230
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_params.h
@@ -0,0 +1,374 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SHCSS_PARAMS_H_
+#define _SHCSS_PARAMS_H_
+
+/* These constants are hardcoded to avoid exporting detailed isp header
+ * files (isp.h). We verify their values when the API is initialized.
+ */
+#define sh_css_num_macc_axes 16
+#define sh_css_morph_table_num_planes 6
+#define sh_css_num_sc_colors 4
+#define sh_css_ctc_table_size 1024
+#define sh_css_gamma_table_size 1024
+#define sh_css_num_dis_coef_types 8
+#define sh_css_ctc_coef_shift 13
+#define sh_css_gamma_gain_k_shift 13
+
+unsigned int sh_css_get_coord_table_ext_width(void);
+int sh_css_get_gdc_coord_one(void);
+
+/* Fixed point types.
+ * NOTE: the 16 bit fixed point types actually occupy 32 bits
+ * to save on extension operations in the ISP code.
+ */
+#define u0_16 unsigned int /* unsigned 0.16 fixed point type */
+#define u2_14 unsigned int /* unsigned 2.14 fixed point type */
+#define u5_11 unsigned int /* unsigned 5.11 fixed point type */
+#define u8_8 unsigned int /* unsigned 8.8 fixed point type */
+#define s0_15 signed int /* signed 0.15 fixed point type */
+
+enum sh_css_isp_ob_mode {
+ sh_css_isp_ob_mode_none,
+ sh_css_isp_ob_mode_fixed,
+ sh_css_isp_ob_mode_raster
+};
+
+/* White Balance (Gain Adjust) */
+struct sh_css_isp_wb_config {
+ unsigned int integer_bits;
+ unsigned int gr; /* unsigned <integer_bits>.<16-integer_bits> */
+ unsigned int r; /* unsigned <integer_bits>.<16-integer_bits> */
+ unsigned int b; /* unsigned <integer_bits>.<16-integer_bits> */
+ unsigned int gb; /* unsigned <integer_bits>.<16-integer_bits> */
+};
+
+/* Color Space Conversion settings */
+struct sh_css_isp_cc_config {
+ unsigned int fraction_bits;
+ int matrix[3 * 3]; /* RGB2YUV Color matrix, signed
+ <13-fraction_bits>.<fraction_bits> */
+};
+
+/* Morphing table for advanced ISP.
+ * Each line of width elements takes up COORD_TABLE_EXT_WIDTH elements
+ * in memory.
+ */
+struct sh_css_morph_table {
+ unsigned int height;
+ unsigned int width; /* number of valid elements per line */
+ unsigned short *coordinates_x[sh_css_morph_table_num_planes];
+ unsigned short *coordinates_y[sh_css_morph_table_num_planes];
+};
+
+/* Shading correction */
+enum sh_css_sc_color {
+ sh_css_sc_color_gr,
+ sh_css_sc_color_r,
+ sh_css_sc_color_b,
+ sh_css_sc_color_gb
+};
+
+struct sh_css_shading_table {
+ /* number of data points per line per color (bayer quads) */
+ unsigned int width;
+ /* number of lines of data points per color (bayer quads) */
+ unsigned int height;
+ /* bits of fraction part for shading table values */
+ unsigned int fraction_bits;
+ /* one table for each color (use sh_css_sc_color to index) */
+ unsigned short *data[sh_css_num_sc_colors];
+};
+
+/* Temporal noise reduction configuration */
+struct sh_css_isp_tnr_config {
+ u0_16 gain; /* [gain] Strength of NR */
+ u0_16 threshold_y; /* [intensity] Motion sensitivity for Y */
+ u0_16 threshold_uv; /* [intensity] Motion sensitivity for U/V */
+};
+
+/* Optical black level configuration */
+struct sh_css_isp_ob_config {
+ /* Obtical black level mode (Fixed / Raster) */
+ enum sh_css_isp_ob_mode mode;
+ /* [intensity] optical black level for GR (relevant for fixed mode) */
+ u0_16 level_gr;
+ /* [intensity] optical black level for R (relevant for fixed mode) */
+ u0_16 level_r;
+ /* [intensity] optical black level for B (relevant for fixed mode) */
+ u0_16 level_b;
+ /* [intensity] optical black level for GB (relevant for fixed mode) */
+ u0_16 level_gb;
+ /* [BQ] 0..63 start position of OB area (relevant for raster mode) */
+ unsigned short start_position;
+ /* [BQ] start..63 end position of OB area (relevant for raster mode) */
+ unsigned short end_position;
+};
+
+/* Defect pixel correction configuration */
+struct sh_css_isp_dp_config {
+ /* [intensity] The threshold of defect Pixel Correction, representing
+ * the permissible difference of intensity between one pixel and its
+ * surrounding pixels. Smaller values result in more frequent pixel
+ * corrections.
+ */
+ u0_16 threshold;
+ /* [gain] The sensitivity of mis-correction. ISP will miss a lot of
+ * defects if the value is set too large.
+ */
+ u8_8 gain;
+};
+
+/* Configuration used by Bayer noise reduction and YCC noise reduction */
+struct sh_css_isp_nr_config {
+ /* [gain] Strength of noise reduction for both Bayer NR & YCC NR (Used
+ * by Bayer NR and YCC NR).
+ */
+ u0_16 gain;
+ /* [intensity] Sensitivity of Edge (Used by Bayer NR) */
+ u0_16 direction;
+ /* [intensity] coring threshold for Cb (Used by YCC NR) */
+ u0_16 threshold_cb;
+ /* [intensity] coring threshold for Cr (Used by YCC NR) */
+ u0_16 threshold_cr;
+};
+
+/* Edge enhancement (sharpen) configuration */
+struct sh_css_isp_ee_config {
+ /* [gain] The strength of sharpness. */
+ u5_11 gain;
+ /* [intensity] The threshold that divides noises from edge. */
+ u8_8 threshold;
+ /* [gain] The strength of sharpness in pell-mell area. */
+ u5_11 detail_gain;
+};
+
+struct sh_css_isp_de_config {
+ u0_16 pixelnoise;
+ u0_16 c1_coring_threshold;
+ u0_16 c2_coring_threshold;
+};
+
+struct sh_css_isp_gc_config {
+ int gain_k1;
+ int gain_k2;
+};
+
+struct sh_css_isp_3a_config {
+ u0_16 ae_y_coef_r; /* [gain] Weight of R for Y */
+ u0_16 ae_y_coef_g; /* [gain] Weight of G for Y */
+ u0_16 ae_y_coef_b; /* [gain] Weight of B for Y */
+ u0_16 awb_lg_r; /* [intensity] AWB level gate for R */
+ u0_16 awb_lg_g; /* [intensity] AWB level gate for G */
+ u0_16 awb_lg_b; /* [intensity] AWB level gate for B */
+ s0_15 af_fir1_coef[7]; /* [factor] AF FIR coefficients of fir1 */
+ s0_15 af_fir2_coef[7]; /* [factor] AF FIR coefficients of fir2 */
+};
+
+struct sh_css_isp_3a_output {
+ int ae_Y;
+ int awb_cnt;
+ int awb_GR;
+ int awb_R;
+ int awb_B;
+ int awb_GB;
+ int af_hpf1;
+ int af_hpf2;
+};
+
+struct sh_css_params;
+
+#include "sh_css.h"
+
+sh_css_err
+sh_css_params_allocate(struct sh_css_params **params);
+
+sh_css_err
+sh_css_params_free(struct sh_css_params *params);
+
+sh_css_err
+sh_css_params_default(struct sh_css_params *params);
+
+/* DIS */
+/* get the pointers to the dis coefficient tables.
+ * These tables will then be written by the caller and the
+ * values will be sent to the ISP upon the next start of frame.
+ */
+void
+sh_css_params_dis_get_coefficients(short **vertical_coefs,
+ short **horizontal_coefs);
+
+void
+sh_css_params_dis_clear_coefficients(void);
+
+void
+sh_css_params_dis_get_projections(int *horizontal_projections,
+ int *vertical_projections);
+
+/* 3A */
+void
+sh_css_params_3a_get_statistics(struct sh_css_isp_3a_output *output);
+
+void
+sh_css_params_3a_configure(struct sh_css_params *params,
+ const struct sh_css_isp_3a_config *config_3a);
+
+/* FPN */
+sh_css_err
+sh_css_params_set_black_frame(struct sh_css_params *params,
+ const struct sh_css_frame *raw_black_frame);
+
+/* Advanced (GDC) */
+void
+sh_css_params_set_morph_table(struct sh_css_params *params,
+ const struct sh_css_morph_table *table);
+
+const struct sh_css_morph_table *
+sh_css_params_get_morph_table(const struct sh_css_params *params);
+
+/* White Balance */
+void
+sh_css_params_configure_wb(struct sh_css_params *params,
+ const struct sh_css_isp_wb_config *wb_config);
+
+/* Color Correction */
+void
+sh_css_params_configure_cc(struct sh_css_params *params,
+ const struct sh_css_isp_cc_config *cc_config);
+
+/* TNR */
+void
+sh_css_params_configure_tnr(struct sh_css_params *params,
+ const struct sh_css_isp_tnr_config *tnr_config);
+
+/* Objective Black */
+void
+sh_css_params_configure_ob(struct sh_css_params *params,
+ const struct sh_css_isp_ob_config *ob_config);
+
+/* Dead Pixel */
+void
+sh_css_params_configure_dp(struct sh_css_params *params,
+ const struct sh_css_isp_dp_config *dp_config);
+
+/* Noise Reduction and Edge Enhancement */
+void
+sh_css_params_configure_nree(struct sh_css_params *params,
+ const struct sh_css_isp_nr_config *nr_config,
+ const struct sh_css_isp_ee_config *ee_config);
+
+/* Demosaic */
+void
+sh_css_params_configure_de(struct sh_css_params *params,
+ const struct sh_css_isp_de_config *de_config);
+
+/* Gamma Correction */
+void
+sh_css_params_configure_gc(struct sh_css_params *params,
+ const struct sh_css_isp_gc_config *gc_config);
+
+void
+sh_css_params_set_gamma_table(struct sh_css_params *params,
+ unsigned short *gamma_table);
+
+void
+sh_css_params_get_gamma_table(struct sh_css_params *params,
+ unsigned short *gamma_table);
+
+void
+sh_css_params_set_ctc_table(struct sh_css_params *params,
+ unsigned short *ctc_table);
+
+/* Multi-Access Color Correction */
+void
+sh_css_params_set_macc_table(struct sh_css_params *params,
+ const short *macc_table);
+
+/* Morphing table support */
+struct sh_css_morph_table *
+sh_css_morph_table_allocate(unsigned int width, unsigned int height);
+
+void
+sh_css_morph_table_free(struct sh_css_morph_table *me);
+
+/* shading table handling */
+void
+sh_css_shading_table_free(struct sh_css_shading_table *table);
+
+struct sh_css_shading_table *
+sh_css_shading_table_alloc(unsigned int width,
+ unsigned int height,
+ unsigned int
+ fraction_bits);
+
+/* Access to default parameters */
+void
+sh_css_params_get_default_gamma_table(const unsigned short **gamma_table);
+
+void
+sh_css_params_get_default_ctc_table(const unsigned short **ctc_table);
+
+void
+sh_css_params_get_default_macc_table(const short **macc_table);
+
+void
+sh_css_params_get_default_3a_config(const struct sh_css_isp_3a_config **config);
+
+void
+sh_css_params_get_default_wb_config(const struct sh_css_isp_wb_config **config);
+
+void
+sh_css_params_get_default_cc_config(const struct sh_css_isp_cc_config **config);
+
+void
+sh_css_params_get_default_tnr_config(const struct sh_css_isp_tnr_config
+ **config);
+
+void
+sh_css_params_get_default_ob_config(const struct sh_css_isp_ob_config **config);
+
+void
+sh_css_params_get_default_dp_config(const struct sh_css_isp_dp_config **config);
+
+void
+sh_css_params_get_default_nr_config(const struct sh_css_isp_nr_config **config);
+
+void
+sh_css_params_get_default_ee_config(const struct sh_css_isp_ee_config **config);
+
+void
+sh_css_params_get_default_de_config(const struct sh_css_isp_de_config **config);
+
+void
+sh_css_params_get_default_gc_config(const struct sh_css_isp_gc_config **config);
+
+/* ugly, needs cleanup */
+void
+sh_css_set_get_shading_table(struct sh_css_shading_table *
+ (*get_table) (unsigned int frame_width,
+ unsigned int frame_height,
+ unsigned int table_width,
+ unsigned int table_height));
+
+#endif /* _SHCSS_PARAMS_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_sp.c b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_sp.c
new file mode 100644
index 0000000..abd2379
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_sp.c
@@ -0,0 +1,691 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "sh_css.h"
+#include "sh_css_binary.h"
+#include "sh_css_sp.h"
+#include "sh_css_hrt.h"
+#include "sp/sp_defs.h"
+
+#ifndef C_RUN
+#define HRT_NO_BLOB_sp
+#include "sp.map.h"
+#endif
+
+/* int on SP is 4 bytes */
+#define SP_INT_BYTES 4
+
+/* HIVE_ADDR_<variable> are macros generated by HiveCC, they
+ are in the sp.map.h file */
+#define store_sp_int(var, value) \
+ sh_css_hrt_sp_dmem_store_32((unsigned)_sp_var_addr(var), \
+ (unsigned int)(value))
+
+#define store_sp_ptr(var, value) \
+ sh_css_hrt_sp_dmem_store_32((unsigned)_sp_var_addr(var), \
+ (unsigned int)(value))
+
+#define store_sp_uint(var, value) \
+ sh_css_hrt_sp_dmem_store_32((unsigned)_sp_var_addr(var), \
+ (unsigned int)(value))
+
+#define load_sp_uint(var) \
+ sh_css_hrt_sp_dmem_load_32((unsigned)_sp_var_addr(var))
+
+#define load_sp_array_uint(array, index) \
+ sh_css_hrt_sp_dmem_load_32((unsigned)_sp_var_addr(array) + \
+ (index)*SP_INT_BYTES)
+
+#define store_sp_array_uint(array, index, value) \
+ sh_css_hrt_sp_dmem_store_32((unsigned)_sp_var_addr(array) + \
+ (index)*SP_INT_BYTES, value)
+
+/* Generic part */
+void
+sh_css_sp_init(void)
+{
+ /*printk(KERN_INFO "function %s, line %d\n", __func__, __LINE__);*/
+ sh_css_hrt_sp_load_program();
+ sh_css_hrt_sp_start_dma_proxy_init();
+ /*sh_css_dump_sp_state();*/
+ sh_css_hrt_sp_wait();
+ /*printk(KERN_INFO "function %s, line %d\n", __func__, __LINE__);*/
+ /*sh_css_dump_sp_state();*/
+}
+
+/* Super Impose API */
+void
+sh_css_sp_si_set_frame_size(unsigned int width, unsigned int height)
+{
+ store_sp_int(sp_frame_height, height);
+ store_sp_int(sp_frame_width, width);
+}
+
+void
+sh_css_sp_si_set_input_pointers(unsigned char *y_ptr,
+ signed char *u_ptr,
+ signed char *v_ptr)
+{
+ store_sp_ptr(sp_input_y_addr, y_ptr);
+ store_sp_ptr(sp_input_u_addr, u_ptr);
+ store_sp_ptr(sp_input_v_addr, v_ptr);
+}
+
+void
+sh_css_sp_si_set_output_pointers(unsigned char *y_ptr,
+ signed char *u_ptr,
+ signed char *v_ptr)
+{
+ store_sp_ptr(sp_output_y_addr, y_ptr);
+ store_sp_ptr(sp_output_u_addr, u_ptr);
+ store_sp_ptr(sp_output_v_addr, v_ptr);
+}
+
+void
+sh_css_sp_si_set_overlay_pointers(unsigned char *y_ptr,
+ signed char *u_ptr,
+ signed char *v_ptr)
+{
+ store_sp_ptr(sp_overlay_y_addr, y_ptr);
+ store_sp_ptr(sp_overlay_u_addr, u_ptr);
+ store_sp_ptr(sp_overlay_v_addr, v_ptr);
+}
+
+void
+sh_css_sp_si_set_overlay_bg_color(unsigned int bg_y, int bg_u, int bg_v)
+{
+ store_sp_uint(sp_overlay_bg_y, bg_y);
+ store_sp_int(sp_overlay_bg_u, bg_u);
+ store_sp_int(sp_overlay_bg_v, bg_v);
+}
+
+void
+sh_css_sp_si_set_overlay_position(unsigned int x, unsigned int y)
+{
+ store_sp_uint(sp_overlay_start_x, x);
+ store_sp_uint(sp_overlay_start_y, y);
+}
+
+void
+sh_css_sp_si_set_overlay_frame_size(unsigned int width, unsigned int height)
+{
+ store_sp_uint(sp_overlay_width, width);
+ store_sp_uint(sp_overlay_height, height);
+}
+
+void
+sh_css_sp_si_start_from_ddr(void)
+{
+ sh_css_hrt_sp_start_si();
+}
+
+/* Histogram API */
+void
+sh_css_sp_histogram_set_pointer(unsigned char *ptr)
+{
+ store_sp_ptr(sp_histo_addr, ptr);
+}
+
+void
+sh_css_sp_histogram_set_input_pointers(unsigned char *y_ptr,
+ signed char *u_ptr,
+ signed char *v_ptr)
+{
+ store_sp_ptr(sp_input_y_addr, y_ptr);
+ store_sp_ptr(sp_input_u_addr, u_ptr);
+ store_sp_ptr(sp_input_v_addr, v_ptr);
+}
+
+void
+sh_css_sp_histogram_generate(void)
+{
+ sh_css_hrt_sp_start_histogram();
+ sh_css_hrt_sp_wait();
+}
+
+/* DMA Proxy API */
+void
+sh_css_sp_dma_proxy_start(void)
+{
+ sh_css_hrt_sp_start_dma_proxy_run();
+}
+
+void
+sh_css_sp_copy_frame(void)
+{
+ sh_css_hrt_sp_start_copy_frame();
+ sh_css_hrt_sp_wait();
+}
+
+void
+dump_sp_debug(void)
+{
+ int i;
+ unsigned sp_error = load_sp_uint(sp_error);
+ sh_css_print("sp_error = 0x%x\n", sp_error);
+
+ for (i = 0; i < 16; i++) {
+ unsigned sp_debug = load_sp_array_uint(sp_debug, i);
+ sh_css_print("sp_debug[%d] = %d\n", i, sp_debug);
+ }
+}
+
+void
+sh_css_sp_start_binary_copy(unsigned char *out_ptr,
+ unsigned int bytes,
+ int two_ppc)
+{
+ store_sp_ptr(sp_bin_copy_out, out_ptr);
+ store_sp_uint(sp_bin_copy_bytes_available, bytes);
+ store_sp_int(sp_2ppc, two_ppc);
+ sh_css_hrt_sp_start_copy_binary_data();
+}
+
+unsigned int
+sh_css_sp_get_binary_copy_size(void)
+{
+ return load_sp_uint(sp_bin_copy_bytes_copied);
+}
+
+static inline sh_css_err
+set_input_frame_buffer(const struct sh_css_frame *frame)
+{
+ if (frame == NULL)
+ return sh_css_err_invalid_arguments;
+
+ switch (frame->info.format) {
+ case sh_css_frame_format_yuv_line:
+ store_sp_ptr(sp_frame_ptr_y_in, frame->planes.nv.Y.data);
+ store_sp_ptr(sp_frame_ptr_uv_in, frame->planes.nv.UV.data);
+ break;
+ case sh_css_frame_format_qplane6:
+ store_sp_ptr(sp_frame_ptr_qplane_r,
+ frame->planes.plane6.R.data);
+ store_sp_ptr(sp_frame_ptr_qplane_ratb,
+ frame->planes.plane6.RatB.data);
+ store_sp_ptr(sp_frame_ptr_qplane_gr,
+ frame->planes.plane6.Gr.data);
+ store_sp_ptr(sp_frame_ptr_qplane_gb,
+ frame->planes.plane6.Gb.data);
+ store_sp_ptr(sp_frame_ptr_qplane_b,
+ frame->planes.plane6.B.data);
+ store_sp_ptr(sp_frame_ptr_qplane_batr,
+ frame->planes.plane6.BatR.data);
+ break;
+ case sh_css_frame_format_yuv420_16:
+ store_sp_ptr(sp_frame_ptr_yuv_16_y, frame->planes.yuv.Y.data);
+ store_sp_ptr(sp_frame_ptr_yuv_16_u, frame->planes.yuv.U.data);
+ store_sp_ptr(sp_frame_ptr_yuv_16_v, frame->planes.yuv.V.data);
+ break;
+ case sh_css_frame_format_vraw16:
+ store_sp_ptr(sp_frame_ptr_raw, frame->planes.raw.data);
+ break;
+ case sh_css_frame_format_yuv420:
+ store_sp_ptr(sp_frame_ptr_y_in, frame->planes.yuv.Y.data);
+ store_sp_ptr(sp_frame_ptr_u_in, frame->planes.yuv.U.data);
+ store_sp_ptr(sp_frame_ptr_v_in, frame->planes.yuv.V.data);
+ break;
+ default:
+ return sh_css_err_unsupported_frame_format;
+ }
+ return sh_css_success;
+}
+
+static inline sh_css_err
+set_output_frame_buffer(const struct sh_css_frame *frame)
+{
+ if (frame == NULL)
+ return sh_css_err_invalid_arguments;
+
+ switch (frame->info.format) {
+ case sh_css_frame_format_yuv420:
+ case sh_css_frame_format_yuv422:
+ case sh_css_frame_format_yuv444:
+ case sh_css_frame_format_yv12:
+ case sh_css_frame_format_yv16:
+ case sh_css_frame_format_yuv420_16:
+ case sh_css_frame_format_yuv422_16:
+ store_sp_ptr(sp_frame_ptr_y, frame->planes.yuv.Y.data);
+ store_sp_ptr(sp_frame_ptr_u, frame->planes.yuv.U.data);
+ store_sp_ptr(sp_frame_ptr_v, frame->planes.yuv.V.data);
+ break;
+ case sh_css_frame_format_nv11:
+ case sh_css_frame_format_nv12:
+ case sh_css_frame_format_nv16:
+ case sh_css_frame_format_nv21:
+ case sh_css_frame_format_nv61:
+ case sh_css_frame_format_yuv_line:
+ store_sp_ptr(sp_frame_ptr_y, frame->planes.nv.Y.data);
+ store_sp_ptr(sp_frame_ptr_uv, frame->planes.nv.UV.data);
+ break;
+ case sh_css_frame_format_yuyv:
+ case sh_css_frame_format_uyvy:
+ store_sp_ptr(sp_frame_ptr_uv, frame->planes.yuyv.data);
+ break;
+ case sh_css_frame_format_rgb565:
+ case sh_css_frame_format_rgba888:
+ store_sp_ptr(sp_frame_ptr_uv, frame->planes.rgb.data);
+ break;
+ case sh_css_frame_format_planar_rgb888:
+ store_sp_ptr(sp_frame_ptr_y, frame->planes.planar_rgb.R.data);
+ store_sp_ptr(sp_frame_ptr_u, frame->planes.planar_rgb.G.data);
+ store_sp_ptr(sp_frame_ptr_v, frame->planes.planar_rgb.B.data);
+ break;
+ case sh_css_frame_format_raw8:
+ case sh_css_frame_format_raw16:
+ case sh_css_frame_format_vraw16:
+ store_sp_ptr(sp_frame_ptr_raw, frame->planes.raw.data);
+ break;
+ case sh_css_frame_format_qplane6:
+ store_sp_ptr(sp_frame_ptr_qplane_r,
+ frame->planes.plane6.R.data);
+ store_sp_ptr(sp_frame_ptr_qplane_ratb,
+ frame->planes.plane6.RatB.data);
+ store_sp_ptr(sp_frame_ptr_qplane_gr,
+ frame->planes.plane6.Gr.data);
+ store_sp_ptr(sp_frame_ptr_qplane_gb,
+ frame->planes.plane6.Gb.data);
+ store_sp_ptr(sp_frame_ptr_qplane_b,
+ frame->planes.plane6.B.data);
+ store_sp_ptr(sp_frame_ptr_qplane_batr,
+ frame->planes.plane6.BatR.data);
+ break;
+ default:
+ return sh_css_err_unsupported_frame_format;
+ }
+ return sh_css_success;
+}
+
+static inline sh_css_err
+set_ref_out_frame_buffer(const struct sh_css_frame *frame)
+{
+ if (frame == NULL)
+ return sh_css_err_invalid_arguments;
+
+ switch (frame->info.format) {
+ case sh_css_frame_format_yuv420:
+ store_sp_ptr(sp_frame_ptr_y_tnr, frame->planes.yuv.Y.data);
+ store_sp_ptr(sp_frame_ptr_uv_tnr, frame->planes.yuv.U.data);
+ break;
+ case sh_css_frame_format_plane6:
+ store_sp_ptr(sp_frame_ptr_plane_r, frame->planes.plane6.R.data);
+ store_sp_ptr(sp_frame_ptr_plane_ratb,
+ frame->planes.plane6.RatB.data);
+ store_sp_ptr(sp_frame_ptr_plane_gr,
+ frame->planes.plane6.Gr.data);
+ store_sp_ptr(sp_frame_ptr_plane_gb,
+ frame->planes.plane6.Gb.data);
+ store_sp_ptr(sp_frame_ptr_plane_b, frame->planes.plane6.B.data);
+ store_sp_ptr(sp_frame_ptr_plane_batr,
+ frame->planes.plane6.BatR.data);
+ break;
+ default:
+ return sh_css_err_unsupported_frame_format;
+ }
+ return sh_css_success;
+}
+
+static inline sh_css_err
+set_ref_in_frame_buffer(const struct sh_css_frame *frame)
+{
+ if (frame == NULL)
+ return sh_css_err_invalid_arguments;
+
+ switch (frame->info.format) {
+ case sh_css_frame_format_yuv420:
+ store_sp_ptr(sp_frame_ptr_y_prev, frame->planes.yuv.Y.data);
+ store_sp_ptr(sp_frame_ptr_uv_prev, frame->planes.yuv.U.data);
+ break;
+ default:
+ return sh_css_err_unsupported_frame_format;
+ }
+ return sh_css_success;
+}
+
+static inline sh_css_err
+set_view_finder_buffer(const struct sh_css_frame *frame)
+{
+ if (frame == NULL)
+ return sh_css_err_invalid_arguments;
+
+ switch (frame->info.format) {
+ case sh_css_frame_format_yuv420:
+ store_sp_ptr(sp_frame_ptr_vfout_y, frame->planes.yuv.Y.data);
+ store_sp_ptr(sp_frame_ptr_vfout_u, frame->planes.yuv.U.data);
+ store_sp_ptr(sp_frame_ptr_vfout_v, frame->planes.yuv.V.data);
+ break;
+ default:
+ return sh_css_err_unsupported_frame_format;
+ }
+ return sh_css_success;
+}
+
+static inline sh_css_err
+set_vf_overlay_buffer(const struct sh_css_frame *frame)
+{
+ if (frame == NULL)
+ return sh_css_err_invalid_arguments;
+
+ switch (frame->info.format) {
+ case sh_css_frame_format_yuv420:
+ store_sp_ptr(sp_frame_ptr_overlay_y, frame->planes.yuv.Y.data);
+ store_sp_ptr(sp_frame_ptr_overlay_u, frame->planes.yuv.U.data);
+ store_sp_ptr(sp_frame_ptr_overlay_v, frame->planes.yuv.V.data);
+ break;
+ default:
+ return sh_css_err_unsupported_frame_format;
+ }
+ return sh_css_success;
+}
+
+sh_css_err
+sh_css_sp_write_frame_pointers(struct sh_css_binary_args *args)
+{
+ if (args->in_frame)
+ return_on_error(set_input_frame_buffer(args->in_frame));
+ if (args->in_ref_frame)
+ return_on_error(set_ref_in_frame_buffer(args->in_ref_frame));
+ if (args->out_vf_frame)
+ return_on_error(set_view_finder_buffer(args->out_vf_frame));
+ if (args->out_ref_frame)
+ return_on_error(set_ref_out_frame_buffer(args->out_ref_frame));
+ if (args->out_frame)
+ return_on_error(set_output_frame_buffer(args->out_frame));
+ if (args->vf_overlay)
+ return_on_error(set_vf_overlay_buffer(args->vf_overlay->frame));
+ return sh_css_success;
+}
+
+void
+sh_css_sp_uds_reconfigure(struct sh_css_uds_params *params,
+ struct sh_css_uds_config *config)
+{
+ unsigned int i;
+
+ store_sp_uint(sp_uds_num_chunks, config->number_of_chunks);
+ store_sp_uint(sp_uds_dx, params->dx);
+ store_sp_uint(sp_uds_dy, params->dy);
+ store_sp_uint(sp_uds_woix, params->woix);
+ store_sp_uint(sp_uds_woiy, config->woiy);
+ store_sp_uint(sp_uds_bpp, config->bpp);
+ store_sp_uint(sp_uds_bci, config->use_bci);
+ store_sp_uint(sp_uds_icx_left_rounded_y,
+ params->uds_chunk_data[0].icx_left_rounded);
+ store_sp_uint(sp_uds_oxdim_floored_y,
+ params->uds_chunk_data[0].oxdim_floored);
+ store_sp_int(sp_uds_iy_topleft_y, params->uds_chunk_data[0].iy_topleft);
+ store_sp_uint(sp_uds_chunk_cnt_y, params->uds_chunk_data[0].chunk_cnt);
+ store_sp_uint(sp_uds_woix_last_y, params->uds_chunk_data[0].woix_last);
+ store_sp_uint(sp_uds_oxdim_last_y,
+ params->uds_chunk_data[0].oxdim_last);
+ store_sp_uint(sp_uds_dma_pixel_block_width_a_in_y,
+ params->uds_chunk_data[0].dma_pixel_block_width_a_in);
+ store_sp_uint(sp_uds_dma_pixel_block_width_b_in_y,
+ params->uds_chunk_data[0].dma_pixel_block_width_b_in);
+
+ for (i = 0; i < config->number_of_chunks; i++) {
+ store_sp_array_uint(sp_uds_ipx_start_array_y, i,
+ params->uds_chunk_data[0].
+ ipx_start_array[i]);
+ store_sp_array_uint(sp_uds_ibuf_offset_y, i,
+ params->uds_chunk_data[0].ibuf_offset[i]);
+ store_sp_array_uint(sp_uds_obuf_offset_y, i,
+ params->uds_chunk_data[0].obuf_offset[i]);
+ }
+
+ store_sp_uint(sp_uds_icx_left_rounded_u,
+ params->uds_chunk_data[1].icx_left_rounded);
+ store_sp_uint(sp_uds_oxdim_floored_u,
+ params->uds_chunk_data[1].oxdim_floored);
+ store_sp_int(sp_uds_iy_topleft_u, params->uds_chunk_data[1].iy_topleft);
+ store_sp_uint(sp_uds_chunk_cnt_u, params->uds_chunk_data[1].chunk_cnt);
+ store_sp_uint(sp_uds_woix_last_u, params->uds_chunk_data[1].woix_last);
+ store_sp_uint(sp_uds_oxdim_last_u,
+ params->uds_chunk_data[1].oxdim_last);
+ store_sp_uint(sp_uds_dma_pixel_block_width_a_in_u,
+ params->uds_chunk_data[1].dma_pixel_block_width_a_in);
+ store_sp_uint(sp_uds_dma_pixel_block_width_b_in_u,
+ params->uds_chunk_data[1].dma_pixel_block_width_b_in);
+
+ for (i = 0; i < config->number_of_chunks; i++) {
+ store_sp_array_uint(sp_uds_ipx_start_array_u, i,
+ params->uds_chunk_data[1].
+ ipx_start_array[i]);
+ store_sp_array_uint(sp_uds_ibuf_offset_u, i,
+ params->uds_chunk_data[1].ibuf_offset[i]);
+ store_sp_array_uint(sp_uds_obuf_offset_u, i,
+ params->uds_chunk_data[1].obuf_offset[i]);
+ }
+}
+
+void
+sh_css_sp_set_overlay(const struct sh_css_overlay *overlay)
+{
+ if (overlay == NULL) {
+ store_sp_int(sp_si_overlay_width, 0);
+ store_sp_int(sp_si_overlay_height, 0);
+ } else {
+ int blend_shift,
+ ratio100,
+ blend_input_y,
+ blend_input_u,
+ blend_input_v,
+ blend_overlay_y, blend_overlay_u, blend_overlay_v;
+
+ blend_shift = 12;
+ ratio100 = 1 << blend_shift;
+ blend_input_y =
+ (ratio100 * overlay->blend_input_perc_y + 50) / 100;
+ blend_input_u =
+ (ratio100 * overlay->blend_input_perc_u + 50) / 100;
+ blend_input_v =
+ (ratio100 * overlay->blend_input_perc_v + 50) / 100;
+ blend_overlay_y =
+ (ratio100 * overlay->blend_overlay_perc_y + 50) / 100;
+ blend_overlay_u =
+ (ratio100 * overlay->blend_overlay_perc_u + 50) / 100;
+ blend_overlay_v =
+ (ratio100 * overlay->blend_overlay_perc_v + 50) / 100;
+ store_sp_int(sp_si_bg_y, (int) overlay->bg_y);
+ store_sp_int(sp_si_bg_u, (int) overlay->bg_u);
+ store_sp_int(sp_si_bg_v, (int) overlay->bg_v);
+ store_sp_int(sp_si_blend_shift, blend_shift);
+ store_sp_int(sp_si_blend_input_y, blend_input_y);
+ store_sp_int(sp_si_blend_input_u, blend_input_u);
+ store_sp_int(sp_si_blend_input_v, blend_input_v);
+ store_sp_int(sp_si_blend_overlay_y, blend_overlay_y);
+ store_sp_int(sp_si_blend_overlay_u, blend_overlay_u);
+ store_sp_int(sp_si_blend_overlay_v, blend_overlay_v);
+ store_sp_int(sp_si_overlay_width,
+ (int) overlay->frame->info.width);
+ store_sp_int(sp_si_overlay_height,
+ (int) overlay->frame->info.height);
+ store_sp_int(sp_si_overlay_start_x,
+ (int) overlay->overlay_start_x);
+ store_sp_int(sp_si_overlay_start_y,
+ (int) overlay->overlay_start_y);
+ }
+}
+
+void
+sh_css_sp_set_enable_xnr(ShBool enable_xnr)
+{
+ store_sp_int(sp_enable_xnr, enable_xnr);
+}
+
+sh_css_err
+sh_css_sp_init_binary(const struct sh_css_binary *binary, void *xmem_map_addr)
+{
+ enum ShImageFormat isp_out_format, isp_vf_pp_format;
+ enum ShStreamFormat isp_in_stream_format = ShStreamFormat_raw;
+ unsigned bits_per_pixel;
+
+ if (binary->online) {
+ return_on_error(sh_css_to_isp_stream_format
+ (binary->input_format, binary->two_ppc,
+ &isp_in_stream_format, &bits_per_pixel));
+ } else {
+ bits_per_pixel = binary->in_frame_info.vraw_bit_depth;
+ }
+ return_on_error(sh_css_host_to_isp_format
+ (binary->int_out_frame_info.format, &isp_out_format));
+ return_on_error(sh_css_host_to_isp_format
+ (binary->vf_frame_info.format, &isp_vf_pp_format));
+
+ store_sp_int(hres_in, binary->in_frame_info.padded_width);
+ store_sp_int(vres_in, binary->in_frame_info.height);
+ store_sp_int(hres, binary->int_out_frame_info.padded_width);
+ store_sp_int(vres, binary->int_out_frame_info.height);
+ store_sp_int(output_image_format, isp_out_format);
+ store_sp_int(input_stream_format, isp_in_stream_format);
+ store_sp_int(bits_per_pixel, bits_per_pixel);
+ store_sp_int(deci_log_factor, binary->deci_factor_log2);
+ store_sp_int(vf_log_scale, binary->vf_downscale_log2);
+ store_sp_int(sp_online, binary->online);
+ store_sp_int(sp_2ppc, binary->two_ppc);
+ store_sp_ptr(xmem_bin_addr, binary->xmem_addr);
+ store_sp_ptr(xmem_map_addr, xmem_map_addr);
+ store_sp_int(sp_frame_cropped_dimx,
+ binary->out_frame_info.padded_width);
+ store_sp_int(sp_frame_cropped_dimy, binary->out_frame_info.height);
+ return sh_css_success;
+}
+
+void
+sh_css_sp_set_dvs_cropping(const struct sh_css_binary *binary,
+ const struct sh_css_binary_args *args)
+{
+ store_sp_int(sp_out_crop_pos_x,
+ (MAX(binary->filter_columns, args->dvs_crop_x) / 2) * 2);
+ store_sp_int(sp_out_crop_pos_y,
+ (MAX(binary->filter_rows, args->dvs_crop_y) / 2) * 2);
+}
+
+void
+sh_css_sp_set_if_configs(const struct sh_css_if_config *config_a,
+ const struct sh_css_if_config *config_b,
+ ShBool block_fifo_no_reqs)
+{
+ store_sp_int(sp_if_block_fifo_no_reqs, block_fifo_no_reqs);
+ store_sp_int(sp_if_a_changed, 1);
+ store_sp_int(sp_if_a_start_line, config_a->start_line);
+ store_sp_int(sp_if_a_start_column, config_a->start_column);
+ store_sp_int(sp_if_a_left_padding, config_a->left_padding);
+ store_sp_int(sp_if_a_cropped_height, config_a->cropped_height);
+ store_sp_int(sp_if_a_cropped_width, config_a->cropped_width);
+ store_sp_int(sp_if_a_deinterleaving, config_a->deinterleaving);
+ store_sp_int(sp_if_a_buf_vecs, config_a->buf_vecs);
+ store_sp_int(sp_if_a_buf_start_index, config_a->buf_start_index);
+ store_sp_int(sp_if_a_buf_increment, config_a->buf_increment);
+ store_sp_int(sp_if_a_buf_eol_offset, config_a->buf_eol_offset);
+ store_sp_int(sp_if_a_yuv420, config_a->yuv420);
+ if (config_b) {
+ store_sp_int(sp_if_b_changed, 1);
+ store_sp_int(sp_if_b_start_line, config_b->start_line);
+ store_sp_int(sp_if_b_start_column, config_b->start_column);
+ store_sp_int(sp_if_b_left_padding, config_b->left_padding);
+ store_sp_int(sp_if_b_cropped_height, config_b->cropped_height);
+ store_sp_int(sp_if_b_cropped_width, config_b->cropped_width);
+ store_sp_int(sp_if_b_deinterleaving, config_b->deinterleaving);
+ store_sp_int(sp_if_b_buf_vecs, config_b->buf_vecs);
+ store_sp_int(sp_if_b_buf_start_index,
+ config_b->buf_start_index);
+ store_sp_int(sp_if_b_buf_increment, config_b->buf_increment);
+ store_sp_int(sp_if_b_buf_eol_offset, config_b->buf_eol_offset);
+ store_sp_int(sp_if_b_yuv420, config_b->yuv420);
+ }
+}
+
+void
+sh_css_sp_program_input_circuit(int fmt_type,
+ int ch_id,
+ enum sh_css_input_mode input_mode)
+{
+ store_sp_int(sp_fmt_type, fmt_type);
+ store_sp_int(sp_ch_id, ch_id);
+ store_sp_int(sp_input_mode, input_mode);
+ store_sp_int(sp_program_input_circuit, 1);
+}
+
+void
+sh_css_sp_program_css_receiver(enum sh_css_mipi_port port,
+ int num_lanes,
+ int timeout,
+ enum sh_css_mipi_compression comp,
+ int comp_bpp,
+ int uncomp_bpp)
+{
+ store_sp_int(sp_mipi_port, port);
+ store_sp_int(sp_mipi_num_lanes, num_lanes);
+ store_sp_int(sp_mipi_timeout, timeout);
+ store_sp_int(sp_mipi_comp, comp);
+ store_sp_int(sp_mipi_comp_bpp, comp_bpp);
+ store_sp_int(sp_mipi_uncomp_bpp, uncomp_bpp);
+}
+
+void
+sh_css_sp_configure_sync_gen(int width, int height,
+ int hblank_cycles,
+ int vblank_cycles)
+{
+ store_sp_int(sp_sync_gen_width, width);
+ store_sp_int(sp_sync_gen_height, height);
+ store_sp_int(sp_sync_gen_hblank_cycles, hblank_cycles);
+ store_sp_int(sp_sync_gen_vblank_cycles, vblank_cycles);
+}
+
+void
+sh_css_sp_configure_tpg(int x_mask,
+ int y_mask,
+ int x_delta,
+ int y_delta,
+ int xy_mask)
+{
+ store_sp_int(sp_tpg_x_mask, x_mask);
+ store_sp_int(sp_tpg_y_mask, y_mask);
+ store_sp_int(sp_tpg_x_delta, x_delta);
+ store_sp_int(sp_tpg_y_delta, y_delta);
+ store_sp_int(sp_tpg_xy_mask, xy_mask);
+}
+
+void
+sh_css_sp_configure_prbs(int seed)
+{
+ store_sp_int(sp_prbs_seed, seed);
+}
+
+void
+sh_css_sp_start_isp(enum isp_binary_id id)
+{
+ store_sp_int(sp_init_isp, 0);
+ store_sp_int(sp_isp_binary_id, id);
+ sh_css_hrt_sp_start_isp();
+}
+
+void
+sh_css_sp_init_isp(enum isp_binary_id id)
+{
+ store_sp_int(sp_init_isp, 1);
+ store_sp_int(sp_isp_binary_id, id);
+ sh_css_hrt_sp_start_isp();
+}
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_sp.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_sp.h
new file mode 100644
index 0000000..d8975eb
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_sp.h
@@ -0,0 +1,156 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SP_HOST_H_
+#define _SP_HOST_H_
+
+#include "sh_css.h"
+
+void
+sh_css_sp_init(void);
+
+/* Super Impose API */
+void
+sh_css_sp_si_set_frame_size(unsigned int width, unsigned int height);
+
+void
+sh_css_sp_si_set_overlay_position(unsigned int x, unsigned int y);
+
+void
+sh_css_sp_si_set_overlay_frame_size(unsigned int width, unsigned int height);
+
+void
+sh_css_sp_si_set_input_pointers(unsigned char *y_ptr,
+ signed char *u_ptr,
+ signed char *v_ptr);
+
+void
+sh_css_sp_si_set_output_pointers(unsigned char *y_ptr,
+ signed char *u_ptr,
+ signed char *v_ptr);
+
+void
+sh_css_sp_si_set_overlay_pointers(unsigned char *y_ptr,
+ signed char *u_ptr,
+ signed char *v_ptr);
+void
+sh_css_sp_si_set_overlay_bg_color(unsigned int bg_y,
+ int bg_u,
+ int bg_v);
+
+void
+sh_css_sp_si_start_from_ddr(void);
+
+/* Histogram API */
+void
+sh_css_sp_histogram_set_pointer(unsigned char *ptr);
+
+void
+sh_css_sp_histogram_set_input_pointers(unsigned char *y_ptr,
+ signed char *u_ptr,
+ signed char *v_ptr);
+
+void
+sh_css_sp_histogram_generate(void);
+
+/* DMA Proxy API */
+void
+sh_css_sp_dma_proxy_start(void);
+
+/* Frame copy API */
+void
+sh_css_sp_copy_frame(void);
+
+/* Binary frame copy */
+void
+sh_css_sp_start_binary_copy(unsigned char *out_ptr,
+ unsigned int bytes,
+ int two_ppc);
+
+unsigned int
+sh_css_sp_get_binary_copy_size(void);
+
+void
+sh_css_sp_start_isp(enum isp_binary_id id);
+
+void
+sh_css_sp_init_isp(enum isp_binary_id id);
+
+void
+dump_sp_debug(void);
+
+sh_css_err
+sh_css_sp_write_frame_pointers(struct sh_css_binary_args *args);
+
+void
+sh_css_sp_uds_reconfigure(struct sh_css_uds_params *params,
+ struct sh_css_uds_config *config);
+
+void
+sh_css_sp_set_overlay(const struct sh_css_overlay *overlay);
+
+void
+sh_css_sp_set_enable_xnr(ShBool enable_xnr);
+
+sh_css_err
+sh_css_sp_init_binary(const struct sh_css_binary *binary,
+ void *xmem_map_addr);
+
+void
+sh_css_sp_set_dvs_cropping(const struct sh_css_binary *binary,
+ const struct sh_css_binary_args *args);
+
+void
+sh_css_sp_set_if_configs(const struct sh_css_if_config *config_a,
+ const struct sh_css_if_config *config_b,
+ ShBool block_fifo_no_reqs);
+
+void
+sh_css_sp_program_input_circuit(int fmt_type,
+ int ch_id,
+ enum sh_css_input_mode input_mode);
+
+void
+sh_css_sp_program_css_receiver(enum sh_css_mipi_port port,
+ int num_lanes,
+ int timeout,
+ enum sh_css_mipi_compression comp,
+ int comp_bpp, int uncomp_bpp);
+
+void
+sh_css_sp_configure_sync_gen(int width,
+ int height,
+ int hblank_cycles,
+ int vblank_cycles);
+
+void
+sh_css_sp_configure_tpg(int x_mask,
+ int y_mask,
+ int x_delta,
+ int y_delta,
+ int xy_mask);
+
+void
+sh_css_sp_configure_prbs(int seed);
+
+#endif /* _SP_HOST_H_ */
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_uds.c b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_uds.c
new file mode 100644
index 0000000..e7774fd
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_uds.c
@@ -0,0 +1,398 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "sh_css.h"
+#include "sh_css_uds.h"
+#include "sh_css_binary.h"
+#include "sh_css_internal.h"
+
+#define MAX_LINE_DIM 1000
+/* CLIP the input Y coordinate within the limits of [0, ..., ) */
+#define UDS_CLIP_Y 1
+
+/* Digital Zoom lookup table. See documentation for more details about the
+ contents of this table. */
+struct sh_css_zoom_table {
+ int data[4][UDS_SCALING_N];
+ unsigned int coef_bits;
+};
+
+static unsigned uds_elements_per_xmem_addr;
+static unsigned uds_xmem_byte_mask;
+static unsigned uds_vmem_vecelem_mask;
+static unsigned curr_ip_xres_lum, curr_ip_yres_lum;
+static unsigned curr_ip_xres_chr, curr_ip_yres_chr;
+static unsigned curr_op_xres_lum, curr_op_yres_lum;
+static unsigned curr_op_xres_chr, curr_op_yres_chr;
+/* User specifies this. */
+static unsigned curr_dx, curr_dy, curr_xc, curr_yc;
+/* Computed based on user specified zoom parameters (curr_*) and the ratio
+ between input and output resolution. */
+static unsigned effe_dx, effe_dy;
+static int init_done;
+static int params_changed;
+
+static struct sh_css_zoom_table zoom_table = {
+ .data = {{0, 0, 0, 0, 0, 0, -1, -1,
+ -1, -2, -2, -3, -3, -4, -4, -5,
+ -6, -6, -7, -7, -8, -9, -9, -10,
+ -11, -11, -12, -13, -13, -14, -14, -15,
+ -16, -16, -16, -17, -17, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -17, -17, -16, -15, -15, -14, -13,
+ -12, -11, -9, -8, -7, -5, -3, -1},
+ {0, 2, 4, 7, 9, 12, 16, 19,
+ 23, 27, 31, 35, 39, 43, 48, 53,
+ 58, 62, 67, 73, 78, 83, 88, 94,
+ 99, 105, 110, 116, 121, 127, 132, 138,
+ 144, 149, 154, 160, 165, 170, 176, 181,
+ 186, 191, 195, 200, 205, 209, 213, 218,
+ 222, 225, 229, 232, 236, 239, 241, 244,
+ 246, 248, 250, 252, 253, 254, 255, 255},
+ {256, 255, 255, 254, 253, 252, 250, 248,
+ 246, 244, 241, 239, 236, 232, 229, 225,
+ 222, 218, 213, 209, 205, 200, 195, 191,
+ 186, 181, 176, 170, 165, 160, 154, 149,
+ 144, 138, 132, 127, 121, 116, 110, 105,
+ 99, 94, 88, 83, 78, 73, 67, 62,
+ 58, 53, 48, 43, 39, 35, 31, 27,
+ 23, 19, 16, 12, 9, 7, 4, 2},
+ {0, -1, -3, -5, -6, -8, -9, -10,
+ -12, -13, -14, -15, -16, -15, -17, -17,
+ -18, -18, -17, -19, -19, -18, -18, -19,
+ -18, -19, -18, -17, -17, -17, -16, -16,
+ -16, -15, -14, -14, -13, -12, -12, -12,
+ -11, -11, -9, -9, -9, -8, -6, -6,
+ -6, -5, -4, -3, -4, -3, -2, -2,
+ -1, 0, -1, 0, 1, 0, 0, 0}
+ },
+ .coef_bits = HRT_GDC_BCI_COEF_BITS,
+};
+
+sh_css_err
+sh_css_uds_init(unsigned ip_xres_lum,
+ unsigned ip_yres_lum,
+ unsigned ip_xres_chr,
+ unsigned ip_yres_chr,
+ unsigned op_xres_lum,
+ unsigned op_yres_lum,
+ unsigned op_xres_chr,
+ unsigned op_yres_chr,
+ unsigned uds_use_bci)
+{
+ /* Configure the GDC accelerator with the known parameters at this
+ * point in time. Configure the bi-cubic coeffient LUT, if needed.
+ * Should it be adjusted for the down scale or we can use the same
+ * values?
+ */
+
+ if (uds_use_bci)
+ sh_css_hrt_gdc_set_lut(zoom_table.data);
+
+ curr_ip_xres_lum = ip_xres_lum;
+ curr_ip_yres_lum = ip_yres_lum;
+ curr_ip_xres_chr = ip_xres_chr;
+ curr_ip_yres_chr = ip_yres_chr;
+
+ curr_op_xres_lum = op_xres_lum;
+ curr_op_yres_lum = op_yres_lum;
+ curr_op_xres_chr = op_xres_chr;
+ curr_op_yres_chr = op_yres_chr;
+
+ curr_xc = curr_op_xres_lum / 2;
+ curr_yc = curr_op_yres_lum / 2;
+
+ init_done = 1;
+ params_changed = 1;
+
+ return sh_css_success;
+}
+
+void
+sh_css_uds_set_zoom_center(unsigned xc, unsigned yc)
+{
+ if (curr_xc != xc || curr_yc != yc)
+ params_changed = 1;
+
+ curr_xc = xc;
+ curr_yc = yc;
+}
+
+void
+sh_css_uds_get_zoom_center(unsigned *xc, unsigned *yc)
+{
+ *xc = curr_xc;
+ *yc = curr_yc;
+}
+
+void
+sh_css_uds_set_zoom_factor(unsigned dx, unsigned dy)
+{
+ dx = MAX(MIN(dx, 1023), 1);
+ dy = MAX(MIN(dy, 1023), 1);
+
+ if (curr_dx != dx || curr_dy != dy)
+ params_changed = 1;
+ curr_dx = dx;
+ curr_dy = dy;
+}
+
+void
+sh_css_uds_get_zoom_factor(unsigned *factor_x, unsigned *factor_y)
+{
+ *factor_x = curr_dx;
+ *factor_y = curr_dy;
+}
+
+static sh_css_err
+chunk_line(struct sh_css_uds_params *params,
+ unsigned plane,
+ unsigned curr_ip_xres,
+ unsigned curr_op_xres,
+ unsigned ixdim,
+ unsigned iydim,
+ unsigned xc_plane,
+ unsigned yc_plane,
+ unsigned uds_interp_envelope,
+ unsigned uds_woix,
+ unsigned uds_number_of_chunks)
+{
+ unsigned icx_left;
+ unsigned icx_right;
+ unsigned icx_left_rounded;
+ unsigned xmem_vec_count;
+ unsigned vmem_vec_count;
+ unsigned i;
+ unsigned line_length;
+ unsigned ixdim_ipxfrx;
+ unsigned ipxfrx_start_first;
+ unsigned ipxfrx_start_done;
+ unsigned ixdim_ipxfrx_last;
+ unsigned ixdim_guaranteed;
+ unsigned oxdim_nolut;
+ unsigned oxdim_done;
+ unsigned chunk_counter;
+ unsigned oxdim_floored;
+ int iy_topleft; /* Can be negative... */
+ unsigned chunk_cnt;
+ unsigned woix_last;
+ unsigned oxdim_last;
+ unsigned ipx_start_array[UDS_MAX_CHUNKS];
+ unsigned ibuf_offset[UDS_MAX_CHUNKS];
+ unsigned obuf_offset[UDS_MAX_CHUNKS];
+
+ iy_topleft = yc_plane - (iydim - 1) / 2;
+ icx_left = xc_plane - (ixdim - 1) / 2;
+
+ /* Some protection, required especially for the zoom factor of one
+ and downscale case.Zoom factor of one and below can result in
+ some negative values. */
+ iy_topleft = ((int) iy_topleft < 0) ? 0 : iy_topleft;
+ icx_left = ((int) icx_left < 0) ? 0 : icx_left;
+ icx_left_rounded = icx_left & uds_xmem_byte_mask;
+ icx_right = icx_left + ixdim - 1 + uds_interp_envelope - 1;
+
+#if ISP_VEC_NELEMS == 16
+ /* In the demo system, the bus is 32 bytes wide, in case the pixels are
+ 8 bits, therefore, one xmem word contains 32 pixels. One VMEM word
+ contains 16 pixels only, therefore, icx_left and icx_left_rounded are
+ computed wrt. the xmem and not vmem!
+ When providing the offset where the GDC must read from, we must take
+ into account an eventual additional shift for one VMEM word!
+ Similarly, the fractional start X must be explicitelly limited within
+ [0, 16*GDC_N_SCALING). */
+ xmem_vec_count = (icx_right + uds_elements_per_xmem_addr - 1) /
+ (uds_elements_per_xmem_addr) -
+ icx_left / (uds_elements_per_xmem_addr);
+ vmem_vec_count =
+ (uds_elements_per_xmem_addr * xmem_vec_count) / (ISP_VEC_NELEMS);
+#elif ISP_VEC_NELEMS == 64
+ /* In the asic system, the bus is 32 bytes wide, in case the pixels are
+ 8 bits, therefore, one xmem word contains 32 pixels.
+ One VMEM word contains 64 pixels, therefore, icx_left and
+ icx_left_rounded are computed wrt. the vmem and not xmem! */
+ vmem_vec_count = (icx_right + ISP_VEC_NELEMS - 1) / (ISP_VEC_NELEMS)
+ - icx_left / (ISP_VEC_NELEMS);
+ xmem_vec_count =
+ (ISP_VEC_NELEMS / uds_elements_per_xmem_addr) * vmem_vec_count;
+#endif
+
+ /* Determine the number of chunks (iterations) */
+ /* Determine the ipx_start, oxdim for all the iterations */
+ chunk_counter = 0;
+ oxdim_done = 0;
+ ipxfrx_start_first = (icx_left - icx_left_rounded) * UDS_SCALING_N;
+ ixdim_guaranteed = uds_woix - ISP_VEC_NELEMS + 1;
+ oxdim_nolut = ((ixdim_guaranteed - uds_interp_envelope) *
+ UDS_SCALING_N) / effe_dx;
+
+ /* Floored to the nearest lower multiple of the NWAY */
+ oxdim_floored = oxdim_nolut & uds_vmem_vecelem_mask;
+
+ /* Everything related to ipxfrx is multiplied by UDS_SCALING_N,
+ so frx is in {0, UDS_SCALING_N-1} */
+ ixdim_ipxfrx = oxdim_floored * effe_dx;
+ ipxfrx_start_done = ipxfrx_start_first;
+
+ line_length = (effe_dx >= UDS_SCALING_N) ? curr_ip_xres : curr_op_xres;
+
+ while ((oxdim_done + oxdim_floored) < curr_op_xres) {
+ ipx_start_array[chunk_counter] = ipxfrx_start_done %
+ (UDS_SCALING_N * ISP_VEC_NELEMS);
+ ibuf_offset[chunk_counter] =
+ (ipxfrx_start_done / UDS_SCALING_N) / ISP_VEC_NELEMS;
+ obuf_offset[chunk_counter] = oxdim_done / ISP_VEC_NELEMS;
+
+ ipxfrx_start_done += ixdim_ipxfrx;
+ oxdim_done += oxdim_floored;
+ chunk_counter += 1;
+ }
+
+ /* And, now, the special stuff for the last iteration: */
+ ipx_start_array[chunk_counter] = ipxfrx_start_done %
+ (UDS_SCALING_N * ISP_VEC_NELEMS);
+ ibuf_offset[chunk_counter] = (ipxfrx_start_done / UDS_SCALING_N) /
+ ISP_VEC_NELEMS;
+ obuf_offset[chunk_counter] = oxdim_done / ISP_VEC_NELEMS;
+ oxdim_last = curr_op_xres - oxdim_done;
+
+ ixdim_ipxfrx_last =
+ (oxdim_last * effe_dx) + uds_interp_envelope * UDS_SCALING_N;
+ woix_last =
+ ((ipx_start_array[chunk_counter] +
+ ixdim_ipxfrx_last) / UDS_SCALING_N + 1 + ISP_VEC_NELEMS - 1) &
+ uds_vmem_vecelem_mask;
+ if (oxdim_last != 0)
+ chunk_counter++;
+
+ chunk_cnt = chunk_counter;
+
+ params->uds_chunk_data[plane].vectors_per_line_in = vmem_vec_count;
+ params->uds_chunk_data[plane].vectors_per_line_out =
+ curr_op_xres / ISP_VEC_NELEMS;
+ params->uds_chunk_data[plane].icx_left_rounded = icx_left_rounded;
+ params->uds_chunk_data[plane].oxdim_floored = oxdim_floored;
+ params->uds_chunk_data[plane].iy_topleft = iy_topleft;
+ params->uds_chunk_data[plane].chunk_cnt = chunk_cnt;
+ params->uds_chunk_data[plane].woix_last = woix_last;
+ params->uds_chunk_data[plane].oxdim_last = oxdim_last;
+ params->uds_chunk_data[plane].dma_pixel_block_width_a_in =
+ vmem_vec_count;
+ params->uds_chunk_data[plane].dma_pixel_block_width_b_in =
+ xmem_vec_count;
+
+ for (i = 0; i < chunk_cnt; i++) {
+ params->uds_chunk_data[plane].ipx_start_array[i] =
+ ipx_start_array[i];
+ params->uds_chunk_data[plane].ibuf_offset[i] = ibuf_offset[i];
+ params->uds_chunk_data[plane].obuf_offset[i] = obuf_offset[i];
+ }
+
+ if (chunk_cnt > uds_number_of_chunks) {
+ sh_css_print("UDS: Number of computed chunks, %d is bigger than"
+ " the allocated for this mode/system, %d!\n",
+ chunk_cnt, uds_number_of_chunks);
+ return sh_css_err_scaling_factor_out_of_range;
+ }
+
+ return sh_css_success;
+}
+
+ShBool
+sh_css_uds_configure(struct sh_css_uds_params *params,
+ struct sh_css_uds_config *config)
+{
+ int ixdim_y, iydim_y, ixdim_u, iydim_u;
+ unsigned int uds_interp_envelope, uds_bpp_ceiled, i, j;
+
+ if (!init_done)
+ return ShFalse;
+
+ if (config->no_user_zoom) {
+ /* WHY? when zoom is disabled, we recalculate everything for
+ every frame. "Seems expensive to me. Well, this seems to be a
+ waste of my time". */
+ params_changed = 1;
+ effe_dx = (UDS_SCALING_N * curr_ip_xres_lum) / curr_op_xres_lum;
+ effe_dy = (UDS_SCALING_N * curr_ip_yres_lum) / curr_op_yres_lum;
+ } else {
+ effe_dx = (curr_dx * curr_ip_xres_lum) / curr_op_xres_lum;
+ effe_dy = (curr_dy * curr_ip_yres_lum) / curr_op_yres_lum;
+ }
+
+ if (!params_changed)
+ return ShFalse;
+
+ params->dx = effe_dx;
+ params->dy = effe_dy;
+ params->woix = config->woix;
+
+ if (config->use_bci)
+ uds_interp_envelope = UDS_BCI_INTERP_ENVELOPE;
+ else
+ uds_interp_envelope = UDS_BLI_INTERP_ENVELOPE;
+
+ /* Computing how many pixels and lines are required at the input.
+ This is needed in order to determin the first and the last input
+ pixel/line. We need to have an additional margin to the right and
+ bottom, due to the fact that we are running bilinear/bicubic
+ interpolation. We are ceiling the number of needed pixels per line,
+ envelope is BCI, BLI dependent */
+ ixdim_y = (curr_op_xres_lum * effe_dx + UDS_SCALING_N - 1) /
+ UDS_SCALING_N + uds_interp_envelope;
+ ixdim_u = (curr_op_xres_chr * effe_dx + UDS_SCALING_N - 1) /
+ UDS_SCALING_N + uds_interp_envelope;
+ iydim_y = (curr_op_yres_lum * effe_dy + UDS_SCALING_N - 1) /
+ UDS_SCALING_N + uds_interp_envelope;
+ iydim_u = (curr_op_yres_chr * effe_dy + UDS_SCALING_N - 1) /
+ UDS_SCALING_N + uds_interp_envelope;
+
+ for (j = 0; j < UDS_MAX_PLANES; j++) {
+ for (i = 0; i < UDS_MAX_CHUNKS; i++) {
+ params->uds_chunk_data[j].ipx_start_array[i] = 0xbabe;
+ params->uds_chunk_data[j].ibuf_offset[i] = 0xbabe;
+ params->uds_chunk_data[j].obuf_offset[i] = 0xbabe;
+ }
+ }
+
+ /* Determining the facts related to chunking the input line: Y */
+ /* Compute the DMA-related values: Y */
+ uds_bpp_ceiled = CEIL_DIV(config->bpp, 8) * 8;
+ uds_elements_per_xmem_addr = CEIL_DIV(XMEM_WIDTH_BITS, uds_bpp_ceiled);
+ /* for 256bit XMEM, it is 31dec => ~(31dec) = ...11100000b */
+ uds_xmem_byte_mask = ~(uds_elements_per_xmem_addr - 1);
+ /* for 64-way VMEM, it is 15dec => ~(15dec) = ...11110000b */
+ uds_vmem_vecelem_mask = ~(ISP_VEC_NELEMS - 1);
+
+ /* For Luma */
+ chunk_line(params, 0, curr_ip_xres_lum, curr_op_xres_lum, ixdim_y,
+ iydim_y, curr_xc, curr_yc, uds_interp_envelope, config->woix,
+ config->number_of_chunks);
+ /* For Chroma */
+ chunk_line(params, 1, curr_ip_xres_chr, curr_op_xres_chr, ixdim_u,
+ iydim_u, curr_xc / 2, curr_yc / 2, uds_interp_envelope,
+ config->woix, config->number_of_chunks);
+
+ params_changed = 0;
+ return ShTrue;
+}
diff --git a/drivers/media/video/mfld_ci/mfldisp/css/sh_css_uds.h b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_uds.h
new file mode 100644
index 0000000..9a054b1
--- /dev/null
+++ b/drivers/media/video/mfld_ci/mfldisp/css/sh_css_uds.h
@@ -0,0 +1,100 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef _SHCSS_UDS_H_
+#define _SHCSS_UDS_H_
+
+#include "sh_css.h"
+#include "sh_css_hrt.h"
+#include "isp/modes/common/defs.h"
+
+struct sh_css_uds_chunk {
+ /* Can be removed, equal to dma_pixel_block_width_a_in */
+ unsigned vectors_per_line_in;
+ /* Can be removed, equal to oxres/nway */
+ unsigned vectors_per_line_out;
+ unsigned icx_left_rounded;
+ unsigned oxdim_floored;
+ int iy_topleft; /* Can be negative... */
+ unsigned chunk_cnt;
+ unsigned woix_last;
+ unsigned oxdim_last;
+ unsigned dma_pixel_block_width_a_in;
+ unsigned dma_pixel_block_width_b_in;
+ unsigned ipx_start_array[UDS_MAX_CHUNKS];
+ unsigned ibuf_offset[UDS_MAX_CHUNKS];
+ unsigned obuf_offset[UDS_MAX_CHUNKS];
+};
+
+struct sh_css_uds_params {
+ unsigned dx;
+ unsigned dy;
+ unsigned woix;
+ struct sh_css_uds_chunk uds_chunk_data[UDS_MAX_PLANES];
+};
+
+struct sh_css_uds_config {
+ unsigned number_of_chunks;
+ unsigned bpp;
+ unsigned use_bci;
+ unsigned woix;
+ unsigned woiy;
+ unsigned no_user_zoom;
+};
+
+/* - Initializes GDC block HW for the Digitial Zoom mode */
+/* - Initializes the LUT of scaling factors */
+/* - Default values for zoom factor and zoom center */
+sh_css_err
+sh_css_uds_init(unsigned ip_xres_lum,
+ unsigned ip_yres_lum,
+ unsigned ip_xres_chr,
+ unsigned ip_yres_chr,
+ unsigned op_xres_lum,
+ unsigned op_yres_lum,
+ unsigned op_xres_chr,
+ unsigned op_yres_chr,
+ unsigned uds_use_bci);
+
+/* - Initializes GDC block HW for the Scaling mode
+ - Initializes the LUT of scaling factors
+ - Default values for zoom factor and zoom center
+ returns whether the parameters have changed or not
+ Only when changed will the argument struct have valid values. */
+ShBool
+sh_css_uds_configure(struct sh_css_uds_params *params,
+ struct sh_css_uds_config *config);
+
+void
+sh_css_uds_set_zoom_factor(unsigned factor_x, unsigned factor_y);
+
+void
+sh_css_uds_get_zoom_factor(unsigned *factor_x, unsigned *factor_y);
+
+void
+sh_css_uds_set_zoom_center(unsigned center_x, unsigned center_y);
+
+void
+sh_css_uds_get_zoom_center(unsigned *center_x, unsigned *center_y);
+
+#endif /* _SHCSS_UDS_H_ */
--
1.6.2.5
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0008-MFLD-isp-css-HW-subsystem-implemenation-to-access-an.patch
Type: application/octet-stream
Size: 406829 bytes
Desc: 0008-MFLD-isp-css-HW-subsystem-implemenation-to-access-an.patch
URL: <http://lists.meego.com/pipermail/meego-kernel/attachments/20101202/74f55bee/attachment-0001.obj>
More information about the MeeGo-kernel
mailing list