Re: [PATCH v6 06/12] intel-ipu3: css: Add support for firmware management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 Hi Yong,

Continuing my review. Sorry for the delay.

On Fri, Mar 30, 2018 at 11:15 AM Yong Zhi <yong.zhi@xxxxxxxxx> wrote:
>
> Introduce functions to load and install ImgU FW blobs.
>
> Signed-off-by: Yong Zhi <yong.zhi@xxxxxxxxx>
> ---
>  drivers/media/pci/intel/ipu3/ipu3-abi.h    | 1888 ++++++++++++++++++++++++++++
>  drivers/media/pci/intel/ipu3/ipu3-css-fw.c |  261 ++++
>  drivers/media/pci/intel/ipu3/ipu3-css-fw.h |  198 +++
>  3 files changed, 2347 insertions(+)
>  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-abi.h
>  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css-fw.c
>  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css-fw.h
>
> diff --git a/drivers/media/pci/intel/ipu3/ipu3-abi.h b/drivers/media/pci/intel/ipu3/ipu3-abi.h
> new file mode 100644
> index 000000000000..24102647a89e
> --- /dev/null
> +++ b/drivers/media/pci/intel/ipu3/ipu3-abi.h
[snip]
> +/* SYSTEM_REQ_0_5_0_IMGHMMADR */
> +#define IMGU_REG_SYSTEM_REQ                    0x18
> +#define IMGU_SYSTEM_REQ_FREQ_MASK              0x3f
> +#define IMGU_SYSTEM_REQ_FREQ_DIVIDER           25
> +#define IMGU_REG_INT_STATUS                    0x30
> +#define IMGU_REG_INT_ENABLE                    0x34
> +#define IMGU_REG_INT_CSS_IRQ                   (1 << 31)

BIT(31)

[snip]
> +       IMGU_ABI_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8, /* Legacy YUV420.
> +                                                        * UY odd line;
> +                                                        * VY even line
> +                                                        */
> +       IMGU_ABI_FRAME_FORMAT_CSI_MIPI_YUV420_10,/* 10 bit per Y/U/V. Y odd
> +                                                 * line; UYVY interleaved
> +                                                 * even line
> +                                                 */
> +       IMGU_ABI_FRAME_FORMAT_YCgCo444_16, /* Internal format for ISP2.7,

Macros and enums should be uppercase.

[snip]
> +struct imgu_abi_shd_intra_frame_operations_data {
> +       struct imgu_abi_acc_operation
> +               operation_list[IMGU_ABI_SHD_MAX_OPERATIONS] IPU3_ALIGN;
> +       struct imgu_abi_acc_process_lines_cmd_data
> +               process_lines_data[IMGU_ABI_SHD_MAX_PROCESS_LINES] IPU3_ALIGN;
> +       struct imgu_abi_shd_transfer_luts_set_data
> +               transfer_data[IMGU_ABI_SHD_MAX_TRANSFERS] IPU3_ALIGN;
> +} __packed;
> +
> +struct imgu_abi_shd_config {
> +       struct ipu3_uapi_shd_config_static shd IMGU_ABI_PAD;
> +       struct imgu_abi_shd_intra_frame_operations_data shd_ops IMGU_ABI_PAD;
> +       struct ipu3_uapi_shd_lut shd_lut IMGU_ABI_PAD;

Definitions of both IPU3_ALIGN and IMGU_ABI_PAD seem to be equivalent.
Could we remove one and use the other everywhere?

[snip]
> +struct imgu_abi_osys_scaler_params {
> +       __u32 inp_buf_y_st_addr;
> +       __u32 inp_buf_y_line_stride;
> +       __u32 inp_buf_y_buffer_stride;
> +       __u32 inp_buf_u_st_addr;
> +       __u32 inp_buf_v_st_addr;
> +       __u32 inp_buf_uv_line_stride;
> +       __u32 inp_buf_uv_buffer_stride;
> +       __u32 inp_buf_chunk_width;
> +       __u32 inp_buf_nr_buffers;
> +       /* Output buffers */
> +       __u32 out_buf_y_st_addr;
> +       __u32 out_buf_y_line_stride;
> +       __u32 out_buf_y_buffer_stride;
> +       __u32 out_buf_u_st_addr;
> +       __u32 out_buf_v_st_addr;
> +       __u32 out_buf_uv_line_stride;
> +       __u32 out_buf_uv_buffer_stride;
> +       __u32 out_buf_nr_buffers;
> +       /* Intermediate buffers */
> +       __u32 int_buf_y_st_addr;
> +       __u32 int_buf_y_line_stride;
> +       __u32 int_buf_u_st_addr;
> +       __u32 int_buf_v_st_addr;
> +       __u32 int_buf_uv_line_stride;
> +       __u32 int_buf_height;
> +       __u32 int_buf_chunk_width;
> +       __u32 int_buf_chunk_height;
> +       /* Context buffers */
> +       __u32 ctx_buf_hor_y_st_addr;
> +       __u32 ctx_buf_hor_u_st_addr;
> +       __u32 ctx_buf_hor_v_st_addr;
> +       __u32 ctx_buf_ver_y_st_addr;
> +       __u32 ctx_buf_ver_u_st_addr;
> +       __u32 ctx_buf_ver_v_st_addr;
> +       /* Addresses for release-input and process-output tokens */
> +       __u32 release_inp_buf_addr;
> +       __u32 release_inp_buf_en;
> +       __u32 release_out_buf_en;
> +       __u32 process_out_buf_addr;
> +       /* Settings dimensions, padding, cropping */
> +       __u32 input_image_y_width;
> +       __u32 input_image_y_height;
> +       __u32 input_image_y_start_column;
> +       __u32 input_image_uv_start_column;
> +       __u32 input_image_y_left_pad;
> +       __u32 input_image_uv_left_pad;
> +       __u32 input_image_y_right_pad;
> +       __u32 input_image_uv_right_pad;
> +       __u32 input_image_y_top_pad;
> +       __u32 input_image_uv_top_pad;
> +       __u32 input_image_y_bottom_pad;
> +       __u32 input_image_uv_bottom_pad;
> +       __u32 processing_mode;
> +#define IMGU_ABI_OSYS_PROCMODE_BYPASS          0
> +#define IMGU_ABI_OSYS_PROCMODE_UPSCALE         1
> +#define IMGU_ABI_OSYS_PROCMODE_DOWNSCALE       2

Could we move it to a separate enum, to be consistent with other
structs? (e.g. imgu_abi_osys_frame_params::format)

> +       __u32 scaling_ratio;
> +       __u32 y_left_phase_init;
> +       __u32 uv_left_phase_init;
> +       __u32 y_top_phase_init;
> +       __u32 uv_top_phase_init;
> +       __u32 coeffs_exp_shift;
> +       __u32 out_y_left_crop;
> +       __u32 out_uv_left_crop;
> +       __u32 out_y_top_crop;
> +       __u32 out_uv_top_crop;
> +} __packed;
> +
> +struct imgu_abi_osys_scaler {
> +       struct imgu_abi_osys_scaler_params param IPU3_ALIGN;
> +} __packed;
> +
> +struct imgu_abi_osys_frame_params {
> +       /* Output pins */
> +       __u32 enable;
> +       __u32 format;           /* enum imgu_abi_osys_format */
> +       __u32 flip;
> +       __u32 mirror;
> +       __u32 tiling;           /* enum imgu_abi_osys_tiling */
> +       __u32 width;
> +       __u32 height;
> +       __u32 stride;
> +       __u32 scaled;
> +} __packed;
[snip]
> +/* Defect pixel correction */
> +
> +struct imgu_abi_dpc_config {
> +       __u8 __reserved[240832];
> +} __packed;

Do we need this structure? One could just add a reserved field in the
parent structure. Also, just to confirm, is 240832 really the right
value here? Where does it come from? Please create a macro for it,
possibly further breaking it down into the values used to compute this
number.

[snip]
> +struct imgu_abi_acc_param {
> +       struct imgu_abi_stripe_data stripe;
> +       __u8 padding[8];
> +       struct imgu_abi_input_feeder_config input_feeder;
> +       struct ipu3_uapi_bnr_static_config bnr;
> +       struct ipu3_uapi_bnr_static_config_green_disparity green_disparity
> +               IPU3_ALIGN;
> +       struct ipu3_uapi_dm_config dm IPU3_ALIGN;
> +       struct ipu3_uapi_ccm_mat_config ccm IPU3_ALIGN;
> +       struct ipu3_uapi_gamma_config gamma IPU3_ALIGN;
> +       struct ipu3_uapi_csc_mat_config csc IPU3_ALIGN;
> +       struct ipu3_uapi_cds_params cds IPU3_ALIGN;
> +       struct imgu_abi_shd_config shd IPU3_ALIGN;
> +       struct imgu_abi_dvs_stat_config dvs_stat;
> +       __u8 padding1[224];     /* reserved for lace_stat */
> +       struct ipu3_uapi_yuvp1_iefd_config iefd IPU3_ALIGN;
> +       struct ipu3_uapi_yuvp1_yds_config yds_c0 IPU3_ALIGN;
> +       struct ipu3_uapi_yuvp1_chnr_config chnr_c0 IPU3_ALIGN;
> +       struct ipu3_uapi_yuvp1_y_ee_nr_config y_ee_nr IPU3_ALIGN;
> +       struct ipu3_uapi_yuvp1_yds_config yds IPU3_ALIGN;
> +       struct ipu3_uapi_yuvp1_chnr_config chnr IPU3_ALIGN;
> +       struct ipu3_uapi_yuvp2_y_tm_lut_static_config ytm IPU3_ALIGN;
> +       struct ipu3_uapi_yuvp1_yds_config yds2 IPU3_ALIGN;
> +       struct ipu3_uapi_yuvp2_tcc_static_config tcc IPU3_ALIGN;
> +       struct imgu_abi_dpc_config dpc IPU3_ALIGN;
> +       struct imgu_abi_bds_config bds;
> +       struct ipu3_uapi_anr_config anr;
> +       struct imgu_abi_awb_fr_config awb_fr;
> +       struct imgu_abi_ae_config ae;
> +       struct imgu_abi_af_config af;
> +       struct imgu_abi_awb_config awb;
> +       struct imgu_abi_osys_config osys;

Why some fields here need and some don't need the IPU3_ALIGN specifier?

[snip]
> +/*
> + * Frame info struct. This describes the contents of an image frame buffer.
> + */
> +struct imgu_abi_frame_sp_info {
> +       struct imgu_abi_sp_resolution res;
> +       u16 padded_width;               /* stride of line in memory
> +                                        * (in pixels)
> +                                        */
> +       u8 format;                      /* format of the frame data */
> +       u8 raw_bit_depth;               /* number of valid bits per pixel,
> +                                        * only valid for RAW bayer frames
> +                                        */
> +       u8 raw_bayer_order;             /* bayer order, only valid
> +                                        * for RAW bayer frames
> +                                        */
> +       u8 raw_type;            /* To choose the proper raw frame type. for
> +                                * Legacy SKC pipes/Default is set to
> +                                * IMGU_ABI_RAW_TYPE_BAYER. For RGB IR sensor -
> +                                * driver should set it to:
> +                                * IronGr case - IMGU_ABI_RAW_TYPE_IR_ON_GR
> +                                * IronGb case - IMGU_ABI_RAW_TYPE_IR_ON_GB
> +                                */
> +#define IMGU_ABI_RAW_TYPE_BAYER                0
> +#define IMGU_ABI_RAW_TYPE_IR_ON_GR     1
> +#define IMGU_ABI_RAW_TYPE_IR_ON_GB     2

Can we have a separate enum for this, consistently with other structs
defined earlier?

[snip]
> +/* Information for a single pipeline stage */
> +struct imgu_abi_sp_stage {
> +       /* Multiple boolean flags can be stored in an integer */
> +       u8 num;                         /* Stage number */
> +       u8 isp_online;
> +       u8 isp_copy_vf;
> +       u8 isp_copy_output;
> +       u8 sp_enable_xnr;
> +       u8 isp_deci_log_factor;
> +       u8 isp_vf_downscale_bits;
> +       u8 deinterleaved;
> +       /*
> +        * NOTE: Programming the input circuit can only be done at the
> +        * start of a session. It is illegal to program it during execution
> +        * The input circuit defines the connectivity
> +        */
> +       u8 program_input_circuit;
> +       u8 func;
> +#define IMGU_ABI_STAGE_FUNC_RAW_COPY   0
> +#define IMGU_ABI_STAGE_FUNC_BIN_COPY   1
> +#define IMGU_ABI_STAGE_FUNC_ISYS_COPY  2
> +#define IMGU_ABI_STAGE_FUNC_NO_FUNC    3

Enum please.

> +       u8 stage_type;                  /* The type of the pipe-stage */
> +#define IMGU_ABI_STAGE_TYPE_SP         0
> +#define IMGU_ABI_STAGE_TYPE_ISP                1

Enum please.

[snip]
> +/*
> + * Blob descriptor.
> + * This structure describes an SP or ISP blob.
> + * It describes the test, data and bss sections as well as position in a
> + * firmware file.
> + * For convenience, it contains dynamic data after loading.
> + */
> +struct imgu_abi_blob_info {
> +       /* Static blob data */
> +       u32 offset;                     /* Blob offset in fw file */
> +       struct imgu_abi_isp_param_memory_offsets memory_offsets;
> +                                       /* offset wrt hdr in bytes */
> +       u32 prog_name_offset;           /* offset wrt hdr in bytes */
> +       u32 size;                       /* Size of blob */
> +       u32 padding_size;               /* total cummulative of bytes added
> +                                        * due to section alignment
> +                                        */
> +       u32 icache_source;              /* Position of icache in blob */
> +       u32 icache_size;                /* Size of icache section */
> +       u32 icache_padding;     /* added due to icache section alignment */
> +       u32 text_source;                /* Position of text in blob */
> +       u32 text_size;                  /* Size of text section */
> +       u32 text_padding;       /* bytes added due to text section alignment */
> +       u32 data_source;                /* Position of data in blob */
> +       u32 data_target;                /* Start of data in SP dmem */
> +       u32 data_size;                  /* Size of text section */
> +       u32 data_padding;       /* bytes added due to data section alignment */
> +       u32 bss_target;         /* Start position of bss in SP dmem */
> +       u32 bss_size;                   /* Size of bss section
> +                                        * Dynamic data filled by loader
> +                                        */
> +       const void *code __aligned(8);  /* Code section absolute pointer */
> +                                       /* within fw, code = icache + text */
> +       const void *data __aligned(8);  /* Data section absolute pointer */
> +                                       /* within fw, data = data + bss */

How are these pointers used? I couldn't find any code referencing
them. Are you sure these are kernel pointers (e.g. not just some
offsets)?

[snip]
> +struct imgu_abi_binary_input_info {
> +       u32 min_width;
> +       u32 min_height;
> +       u32 max_width;
> +       u32 max_height;
> +       u32 source;                     /* memory, sensor, variable */
> +#define IMGU_ABI_BINARY_INPUT_SOURCE_SENSOR    0
> +#define IMGU_ABI_BINARY_INPUT_SOURCE_MEMORY    1
> +#define IMGU_ABI_BINARY_INPUT_SOURCE_VARIABLE  2

Enum please.

[snip]
> +/* Information for a pipeline */
> +struct imgu_abi_sp_pipeline {
> +       u32 pipe_id;                    /* the pipe ID */
> +       u32 pipe_num;                   /* the dynamic pipe number */
> +       u32 thread_id;                  /* the sp thread ID */
> +       u32 pipe_config;                /* the pipe config */
> +#define IMGU_ABI_PIPE_CONFIG_ACQUIRE_ISP       (1 << 31)
> +       u32 pipe_qos_config;            /* Bitmap of multiple QOS extension fw
> +                                        * state, 0xffffffff indicates non
> +                                        * QOS pipe.
> +                                        */
> +       u32 inout_port_config;
> +#define IMGU_ABI_PORT_CONFIG_TYPE_INPUT_HOST           (1 << 0)
> +#define IMGU_ABI_PORT_CONFIG_TYPE_INPUT_COPYSINK       (1 << 1)
> +#define IMGU_ABI_PORT_CONFIG_TYPE_INPUT_TAGGERSINK     (1 << 2)
> +#define IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_HOST          (1 << 4)
> +#define IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_COPYSINK      (1 << 5)
> +#define IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_TAGGERSINK    (1 << 6)
> +       u32 required_bds_factor;
> +       u32 dvs_frame_delay;
> +       u32 num_stages;         /* the pipe config */
> +       u32 running;                    /* needed for pipe termination */
> +       imgu_addr_t sp_stage_addr[IMGU_ABI_MAX_STAGES];
> +       imgu_addr_t scaler_pp_lut;      /* Early bound LUT */
> +       u32 stage;                      /* stage ptr is only used on sp */
> +       s32 num_execs;                  /* number of times to run if this is
> +                                        * an acceleration pipe.
> +                                        */
> +       union {
> +               struct {
> +                       u32 bytes_available;
> +

The message is cut off here for me. Please split this patch for next
respin. Possibly 1 patch for registers and enums at the top, then 1
patch for structs and 1 more patch for the code being added in this
patch.

Best regards,
Tomasz



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux