linux/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Support for Intel Camera Imaging ISP subsystem.
   4 * Copyright (c) 2015, Intel Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 */
  15
  16#include <linux/string.h> /* for memcpy() */
  17
  18#include "system_global.h"
  19
  20#ifdef ISP2401
  21
  22#include "ia_css_isys.h"
  23#include "ia_css_debug.h"
  24#include "math_support.h"
  25#include "virtual_isys.h"
  26#include "isp.h"
  27#include "sh_css_defs.h"
  28
  29/*************************************************
  30 *
  31 * Forwarded Declaration
  32 *
  33 *************************************************/
  34
  35static bool create_input_system_channel(
  36    isp2401_input_system_cfg_t  *cfg,
  37    bool                        metadata,
  38    input_system_channel_t      *channel);
  39
  40static void destroy_input_system_channel(
  41    input_system_channel_t      *channel);
  42
  43static bool create_input_system_input_port(
  44    isp2401_input_system_cfg_t          *cfg,
  45    input_system_input_port_t   *input_port);
  46
  47static void destroy_input_system_input_port(
  48    input_system_input_port_t   *input_port);
  49
  50static bool calculate_input_system_channel_cfg(
  51    input_system_channel_t              *channel,
  52    input_system_input_port_t   *input_port,
  53    isp2401_input_system_cfg_t          *isys_cfg,
  54    input_system_channel_cfg_t  *channel_cfg,
  55    bool metadata);
  56
  57static bool calculate_input_system_input_port_cfg(
  58    input_system_channel_t              *channel,
  59    input_system_input_port_t   *input_port,
  60    isp2401_input_system_cfg_t          *isys_cfg,
  61    input_system_input_port_cfg_t       *input_port_cfg);
  62
  63static bool acquire_sid(
  64    stream2mmio_ID_t    stream2mmio,
  65    stream2mmio_sid_ID_t        *sid);
  66
  67static void release_sid(
  68    stream2mmio_ID_t    stream2mmio,
  69    stream2mmio_sid_ID_t        *sid);
  70
  71static bool acquire_ib_buffer(
  72    s32 bits_per_pixel,
  73    s32 pixels_per_line,
  74    s32 lines_per_frame,
  75    s32 align_in_bytes,
  76    bool online,
  77    isp2401_ib_buffer_t *buf);
  78
  79static void release_ib_buffer(
  80    isp2401_ib_buffer_t *buf);
  81
  82static bool acquire_dma_channel(
  83    isys2401_dma_ID_t   dma_id,
  84    isys2401_dma_channel        *channel);
  85
  86static void release_dma_channel(
  87    isys2401_dma_ID_t   dma_id,
  88    isys2401_dma_channel        *channel);
  89
  90static bool acquire_be_lut_entry(
  91    csi_rx_backend_ID_t         backend,
  92    csi_mipi_packet_type_t              packet_type,
  93    csi_rx_backend_lut_entry_t  *entry);
  94
  95static void release_be_lut_entry(
  96    csi_rx_backend_ID_t         backend,
  97    csi_mipi_packet_type_t              packet_type,
  98    csi_rx_backend_lut_entry_t  *entry);
  99
 100static bool calculate_tpg_cfg(
 101    input_system_channel_t              *channel,
 102    input_system_input_port_t   *input_port,
 103    isp2401_input_system_cfg_t          *isys_cfg,
 104    pixelgen_tpg_cfg_t          *cfg);
 105
 106static bool calculate_prbs_cfg(
 107    input_system_channel_t              *channel,
 108    input_system_input_port_t   *input_port,
 109    isp2401_input_system_cfg_t          *isys_cfg,
 110    pixelgen_prbs_cfg_t         *cfg);
 111
 112static bool calculate_fe_cfg(
 113    const isp2401_input_system_cfg_t    *isys_cfg,
 114    csi_rx_frontend_cfg_t               *cfg);
 115
 116static bool calculate_be_cfg(
 117    const input_system_input_port_t     *input_port,
 118    const isp2401_input_system_cfg_t    *isys_cfg,
 119    bool                                metadata,
 120    csi_rx_backend_cfg_t                *cfg);
 121
 122static bool calculate_stream2mmio_cfg(
 123    const isp2401_input_system_cfg_t    *isys_cfg,
 124    bool                                metadata,
 125    stream2mmio_cfg_t           *cfg);
 126
 127static bool calculate_ibuf_ctrl_cfg(
 128    const input_system_channel_t        *channel,
 129    const input_system_input_port_t     *input_port,
 130    const isp2401_input_system_cfg_t    *isys_cfg,
 131    ibuf_ctrl_cfg_t                     *cfg);
 132
 133static bool calculate_isys2401_dma_cfg(
 134    const input_system_channel_t        *channel,
 135    const isp2401_input_system_cfg_t    *isys_cfg,
 136    isys2401_dma_cfg_t          *cfg);
 137
 138static bool calculate_isys2401_dma_port_cfg(
 139    const isp2401_input_system_cfg_t    *isys_cfg,
 140    bool                                raw_packed,
 141    bool                                metadata,
 142    isys2401_dma_port_cfg_t             *cfg);
 143
 144static csi_mipi_packet_type_t get_csi_mipi_packet_type(
 145    int32_t data_type);
 146
 147static int32_t calculate_stride(
 148    s32 bits_per_pixel,
 149    s32 pixels_per_line,
 150    bool        raw_packed,
 151    int32_t     align_in_bytes);
 152
 153/* end of Forwarded Declaration */
 154
 155/**************************************************
 156 *
 157 * Public Methods
 158 *
 159 **************************************************/
 160ia_css_isys_error_t ia_css_isys_stream_create(
 161    ia_css_isys_descr_t *isys_stream_descr,
 162    ia_css_isys_stream_h        isys_stream,
 163    uint32_t isys_stream_id)
 164{
 165        ia_css_isys_error_t rc;
 166
 167        if (!isys_stream_descr || !isys_stream ||
 168            isys_stream_id >= SH_CSS_MAX_ISYS_CHANNEL_NODES)
 169                return  false;
 170
 171        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
 172                            "ia_css_isys_stream_create() enter:\n");
 173
 174        /*Reset isys_stream to 0*/
 175        memset(isys_stream, 0, sizeof(*isys_stream));
 176        isys_stream->enable_metadata = isys_stream_descr->metadata.enable;
 177        isys_stream->id = isys_stream_id;
 178
 179        isys_stream->linked_isys_stream_id = isys_stream_descr->linked_isys_stream_id;
 180        rc = create_input_system_input_port(isys_stream_descr,
 181                                            &isys_stream->input_port);
 182        if (!rc)
 183                return false;
 184
 185        rc = create_input_system_channel(isys_stream_descr, false,
 186                                         &isys_stream->channel);
 187        if (!rc) {
 188                destroy_input_system_input_port(&isys_stream->input_port);
 189                return false;
 190        }
 191
 192#ifdef ISP2401
 193        /*
 194         * Early polling is required for timestamp accuracy in certain cause.
 195         * The ISYS HW polling is started on
 196         * ia_css_isys_stream_capture_indication() instead of
 197         * ia_css_pipeline_sp_wait_for_isys_stream_N() as isp processing of
 198         * capture takes longer than getting an ISYS frame
 199         */
 200        isys_stream->polling_mode = isys_stream_descr->polling_mode;
 201
 202#endif
 203        /* create metadata channel */
 204        if (isys_stream_descr->metadata.enable) {
 205                rc = create_input_system_channel(isys_stream_descr, true,
 206                                                 &isys_stream->md_channel);
 207                if (!rc) {
 208                        destroy_input_system_input_port(&isys_stream->input_port);
 209                        destroy_input_system_channel(&isys_stream->channel);
 210                        return false;
 211                }
 212        }
 213        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
 214                            "ia_css_isys_stream_create() leave:\n");
 215
 216        return true;
 217}
 218
 219void ia_css_isys_stream_destroy(
 220    ia_css_isys_stream_h        isys_stream)
 221{
 222        destroy_input_system_input_port(&isys_stream->input_port);
 223        destroy_input_system_channel(&isys_stream->channel);
 224        if (isys_stream->enable_metadata) {
 225                /* Destroy metadata channel only if its allocated*/
 226                destroy_input_system_channel(&isys_stream->md_channel);
 227        }
 228}
 229
 230ia_css_isys_error_t ia_css_isys_stream_calculate_cfg(
 231    ia_css_isys_stream_h                isys_stream,
 232    ia_css_isys_descr_t         *isys_stream_descr,
 233    ia_css_isys_stream_cfg_t    *isys_stream_cfg)
 234{
 235        ia_css_isys_error_t rc;
 236
 237        if (!isys_stream_cfg            ||
 238            !isys_stream_descr  ||
 239            !isys_stream)
 240                return false;
 241
 242        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
 243                            "ia_css_isys_stream_calculate_cfg() enter:\n");
 244
 245        rc  = calculate_input_system_channel_cfg(
 246                  &isys_stream->channel,
 247                  &isys_stream->input_port,
 248                  isys_stream_descr,
 249                  &isys_stream_cfg->channel_cfg,
 250                  false);
 251        if (!rc)
 252                return false;
 253
 254        /* configure metadata channel */
 255        if (isys_stream_descr->metadata.enable) {
 256                isys_stream_cfg->enable_metadata = true;
 257                rc  = calculate_input_system_channel_cfg(
 258                          &isys_stream->md_channel,
 259                          &isys_stream->input_port,
 260                          isys_stream_descr,
 261                          &isys_stream_cfg->md_channel_cfg,
 262                          true);
 263                if (!rc)
 264                        return false;
 265        }
 266
 267        rc = calculate_input_system_input_port_cfg(
 268                 &isys_stream->channel,
 269                 &isys_stream->input_port,
 270                 isys_stream_descr,
 271                 &isys_stream_cfg->input_port_cfg);
 272        if (!rc)
 273                return false;
 274
 275        isys_stream->valid = 1;
 276        isys_stream_cfg->valid = 1;
 277        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
 278                            "ia_css_isys_stream_calculate_cfg() leave:\n");
 279        return rc;
 280}
 281
 282/* end of Public Methods */
 283
 284/**************************************************
 285 *
 286 * Private Methods
 287 *
 288 **************************************************/
 289static bool create_input_system_channel(
 290    isp2401_input_system_cfg_t  *cfg,
 291    bool                        metadata,
 292    input_system_channel_t      *me)
 293{
 294        bool rc = true;
 295
 296        me->dma_id = ISYS2401_DMA0_ID;
 297
 298        switch (cfg->input_port_id) {
 299        case INPUT_SYSTEM_CSI_PORT0_ID:
 300        case INPUT_SYSTEM_PIXELGEN_PORT0_ID:
 301                me->stream2mmio_id = STREAM2MMIO0_ID;
 302                me->ibuf_ctrl_id = IBUF_CTRL0_ID;
 303                break;
 304
 305        case INPUT_SYSTEM_CSI_PORT1_ID:
 306        case INPUT_SYSTEM_PIXELGEN_PORT1_ID:
 307                me->stream2mmio_id = STREAM2MMIO1_ID;
 308                me->ibuf_ctrl_id = IBUF_CTRL1_ID;
 309                break;
 310
 311        case INPUT_SYSTEM_CSI_PORT2_ID:
 312        case INPUT_SYSTEM_PIXELGEN_PORT2_ID:
 313                me->stream2mmio_id = STREAM2MMIO2_ID;
 314                me->ibuf_ctrl_id = IBUF_CTRL2_ID;
 315                break;
 316        default:
 317                rc = false;
 318                break;
 319        }
 320
 321        if (!rc)
 322                return false;
 323
 324        if (!acquire_sid(me->stream2mmio_id, &me->stream2mmio_sid_id)) {
 325                return false;
 326        }
 327
 328        if (!acquire_ib_buffer(
 329                metadata ? cfg->metadata.bits_per_pixel :
 330                cfg->input_port_resolution.bits_per_pixel,
 331                metadata ? cfg->metadata.pixels_per_line :
 332                cfg->input_port_resolution.pixels_per_line,
 333                metadata ? cfg->metadata.lines_per_frame :
 334                cfg->input_port_resolution.lines_per_frame,
 335                metadata ? cfg->metadata.align_req_in_bytes :
 336                cfg->input_port_resolution.align_req_in_bytes,
 337                cfg->online,
 338                &me->ib_buffer)) {
 339                release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id);
 340                return false;
 341        }
 342
 343        if (!acquire_dma_channel(me->dma_id, &me->dma_channel)) {
 344                release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id);
 345                release_ib_buffer(&me->ib_buffer);
 346                return false;
 347        }
 348
 349        return true;
 350}
 351
 352static void destroy_input_system_channel(
 353    input_system_channel_t      *me)
 354{
 355        release_sid(me->stream2mmio_id,
 356                    &me->stream2mmio_sid_id);
 357
 358        release_ib_buffer(&me->ib_buffer);
 359
 360        release_dma_channel(me->dma_id, &me->dma_channel);
 361}
 362
 363static bool create_input_system_input_port(
 364    isp2401_input_system_cfg_t          *cfg,
 365    input_system_input_port_t   *me)
 366{
 367        csi_mipi_packet_type_t packet_type;
 368        bool rc = true;
 369
 370        switch (cfg->input_port_id) {
 371        case INPUT_SYSTEM_CSI_PORT0_ID:
 372                me->csi_rx.frontend_id = CSI_RX_FRONTEND0_ID;
 373                me->csi_rx.backend_id = CSI_RX_BACKEND0_ID;
 374
 375                packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
 376                me->csi_rx.packet_type = packet_type;
 377
 378                rc = acquire_be_lut_entry(
 379                         me->csi_rx.backend_id,
 380                         packet_type,
 381                         &me->csi_rx.backend_lut_entry);
 382                break;
 383        case INPUT_SYSTEM_PIXELGEN_PORT0_ID:
 384                me->pixelgen.pixelgen_id = PIXELGEN0_ID;
 385                break;
 386        case INPUT_SYSTEM_CSI_PORT1_ID:
 387                me->csi_rx.frontend_id = CSI_RX_FRONTEND1_ID;
 388                me->csi_rx.backend_id = CSI_RX_BACKEND1_ID;
 389
 390                packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
 391                me->csi_rx.packet_type = packet_type;
 392
 393                rc = acquire_be_lut_entry(
 394                         me->csi_rx.backend_id,
 395                         packet_type,
 396                         &me->csi_rx.backend_lut_entry);
 397                break;
 398        case INPUT_SYSTEM_PIXELGEN_PORT1_ID:
 399                me->pixelgen.pixelgen_id = PIXELGEN1_ID;
 400
 401                break;
 402        case INPUT_SYSTEM_CSI_PORT2_ID:
 403                me->csi_rx.frontend_id = CSI_RX_FRONTEND2_ID;
 404                me->csi_rx.backend_id = CSI_RX_BACKEND2_ID;
 405
 406                packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
 407                me->csi_rx.packet_type = packet_type;
 408
 409                rc = acquire_be_lut_entry(
 410                         me->csi_rx.backend_id,
 411                         packet_type,
 412                         &me->csi_rx.backend_lut_entry);
 413                break;
 414        case INPUT_SYSTEM_PIXELGEN_PORT2_ID:
 415                me->pixelgen.pixelgen_id = PIXELGEN2_ID;
 416                break;
 417        default:
 418                rc = false;
 419                break;
 420        }
 421
 422        me->source_type = cfg->mode;
 423
 424        /* for metadata */
 425        me->metadata.packet_type = CSI_MIPI_PACKET_TYPE_UNDEFINED;
 426        if (rc && cfg->metadata.enable) {
 427                me->metadata.packet_type = get_csi_mipi_packet_type(
 428                                               cfg->metadata.fmt_type);
 429                rc = acquire_be_lut_entry(
 430                         me->csi_rx.backend_id,
 431                         me->metadata.packet_type,
 432                         &me->metadata.backend_lut_entry);
 433        }
 434
 435        return rc;
 436}
 437
 438static void destroy_input_system_input_port(
 439    input_system_input_port_t   *me)
 440{
 441        if (me->source_type == INPUT_SYSTEM_SOURCE_TYPE_SENSOR) {
 442                release_be_lut_entry(
 443                    me->csi_rx.backend_id,
 444                    me->csi_rx.packet_type,
 445                    &me->csi_rx.backend_lut_entry);
 446        }
 447
 448        if (me->metadata.packet_type != CSI_MIPI_PACKET_TYPE_UNDEFINED) {
 449                /*Free the backend lut allocated for metadata*/
 450                release_be_lut_entry(
 451                    me->csi_rx.backend_id,
 452                    me->metadata.packet_type,
 453                    &me->metadata.backend_lut_entry);
 454        }
 455}
 456
 457static bool calculate_input_system_channel_cfg(
 458    input_system_channel_t              *channel,
 459    input_system_input_port_t   *input_port,
 460    isp2401_input_system_cfg_t          *isys_cfg,
 461    input_system_channel_cfg_t  *channel_cfg,
 462    bool metadata)
 463{
 464        bool rc;
 465
 466        rc = calculate_stream2mmio_cfg(isys_cfg, metadata,
 467                                       &channel_cfg->stream2mmio_cfg);
 468        if (!rc)
 469                return false;
 470
 471        rc = calculate_ibuf_ctrl_cfg(
 472                 channel,
 473                 input_port,
 474                 isys_cfg,
 475                 &channel_cfg->ibuf_ctrl_cfg);
 476        if (!rc)
 477                return false;
 478        if (metadata)
 479                channel_cfg->ibuf_ctrl_cfg.stores_per_frame =
 480                    isys_cfg->metadata.lines_per_frame;
 481
 482        rc = calculate_isys2401_dma_cfg(
 483                 channel,
 484                 isys_cfg,
 485                 &channel_cfg->dma_cfg);
 486        if (!rc)
 487                return false;
 488
 489        rc = calculate_isys2401_dma_port_cfg(
 490                 isys_cfg,
 491                 false,
 492                 metadata,
 493                 &channel_cfg->dma_src_port_cfg);
 494        if (!rc)
 495                return false;
 496
 497        rc = calculate_isys2401_dma_port_cfg(
 498                 isys_cfg,
 499                 isys_cfg->raw_packed,
 500                 metadata,
 501                 &channel_cfg->dma_dest_port_cfg);
 502        if (!rc)
 503                return false;
 504
 505        return true;
 506}
 507
 508static bool calculate_input_system_input_port_cfg(
 509    input_system_channel_t              *channel,
 510    input_system_input_port_t   *input_port,
 511    isp2401_input_system_cfg_t          *isys_cfg,
 512    input_system_input_port_cfg_t       *input_port_cfg)
 513{
 514        bool rc;
 515
 516        switch (input_port->source_type) {
 517        case INPUT_SYSTEM_SOURCE_TYPE_SENSOR:
 518                rc  = calculate_fe_cfg(
 519                          isys_cfg,
 520                          &input_port_cfg->csi_rx_cfg.frontend_cfg);
 521
 522                rc &= calculate_be_cfg(
 523                          input_port,
 524                          isys_cfg,
 525                          false,
 526                          &input_port_cfg->csi_rx_cfg.backend_cfg);
 527
 528                if (rc && isys_cfg->metadata.enable)
 529                        rc &= calculate_be_cfg(input_port, isys_cfg, true,
 530                                               &input_port_cfg->csi_rx_cfg.md_backend_cfg);
 531                break;
 532        case INPUT_SYSTEM_SOURCE_TYPE_TPG:
 533                rc = calculate_tpg_cfg(
 534                         channel,
 535                         input_port,
 536                         isys_cfg,
 537                         &input_port_cfg->pixelgen_cfg.tpg_cfg);
 538                break;
 539        case INPUT_SYSTEM_SOURCE_TYPE_PRBS:
 540                rc = calculate_prbs_cfg(
 541                         channel,
 542                         input_port,
 543                         isys_cfg,
 544                         &input_port_cfg->pixelgen_cfg.prbs_cfg);
 545                break;
 546        default:
 547                rc = false;
 548                break;
 549        }
 550
 551        return rc;
 552}
 553
 554static bool acquire_sid(
 555    stream2mmio_ID_t    stream2mmio,
 556    stream2mmio_sid_ID_t        *sid)
 557{
 558        return ia_css_isys_stream2mmio_sid_rmgr_acquire(stream2mmio, sid);
 559}
 560
 561static void release_sid(
 562    stream2mmio_ID_t    stream2mmio,
 563    stream2mmio_sid_ID_t        *sid)
 564{
 565        ia_css_isys_stream2mmio_sid_rmgr_release(stream2mmio, sid);
 566}
 567
 568/* See also: ia_css_dma_configure_from_info() */
 569static int32_t calculate_stride(
 570    s32 bits_per_pixel,
 571    s32 pixels_per_line,
 572    bool        raw_packed,
 573    int32_t align_in_bytes)
 574{
 575        s32 bytes_per_line;
 576        s32 pixels_per_word;
 577        s32 words_per_line;
 578        s32 pixels_per_line_padded;
 579
 580        pixels_per_line_padded = CEIL_MUL(pixels_per_line, align_in_bytes);
 581
 582        if (!raw_packed)
 583                bits_per_pixel = CEIL_MUL(bits_per_pixel, 8);
 584
 585        pixels_per_word = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
 586        words_per_line  = ceil_div(pixels_per_line_padded, pixels_per_word);
 587        bytes_per_line  = HIVE_ISP_DDR_WORD_BYTES * words_per_line;
 588
 589        return bytes_per_line;
 590}
 591
 592static bool acquire_ib_buffer(
 593    s32 bits_per_pixel,
 594    s32 pixels_per_line,
 595    s32 lines_per_frame,
 596    s32 align_in_bytes,
 597    bool online,
 598    isp2401_ib_buffer_t *buf)
 599{
 600        buf->stride = calculate_stride(bits_per_pixel, pixels_per_line, false,
 601                                       align_in_bytes);
 602        if (online)
 603                buf->lines = 4; /* use double buffering for online usecases */
 604        else
 605                buf->lines = 2;
 606
 607        (void)(lines_per_frame);
 608        return ia_css_isys_ibuf_rmgr_acquire(buf->stride * buf->lines,
 609                                             &buf->start_addr);
 610}
 611
 612static void release_ib_buffer(
 613    isp2401_ib_buffer_t *buf)
 614{
 615        ia_css_isys_ibuf_rmgr_release(&buf->start_addr);
 616}
 617
 618static bool acquire_dma_channel(
 619    isys2401_dma_ID_t   dma_id,
 620    isys2401_dma_channel        *channel)
 621{
 622        return ia_css_isys_dma_channel_rmgr_acquire(dma_id, channel);
 623}
 624
 625static void release_dma_channel(
 626    isys2401_dma_ID_t   dma_id,
 627    isys2401_dma_channel        *channel)
 628{
 629        ia_css_isys_dma_channel_rmgr_release(dma_id, channel);
 630}
 631
 632static bool acquire_be_lut_entry(
 633    csi_rx_backend_ID_t         backend,
 634    csi_mipi_packet_type_t              packet_type,
 635    csi_rx_backend_lut_entry_t  *entry)
 636{
 637        return ia_css_isys_csi_rx_lut_rmgr_acquire(backend, packet_type, entry);
 638}
 639
 640static void release_be_lut_entry(
 641    csi_rx_backend_ID_t         backend,
 642    csi_mipi_packet_type_t              packet_type,
 643    csi_rx_backend_lut_entry_t  *entry)
 644{
 645        ia_css_isys_csi_rx_lut_rmgr_release(backend, packet_type, entry);
 646}
 647
 648static bool calculate_tpg_cfg(
 649    input_system_channel_t              *channel,
 650    input_system_input_port_t   *input_port,
 651    isp2401_input_system_cfg_t          *isys_cfg,
 652    pixelgen_tpg_cfg_t          *cfg)
 653{
 654        memcpy(cfg, &isys_cfg->tpg_port_attr, sizeof(pixelgen_tpg_cfg_t));
 655
 656        return true;
 657}
 658
 659static bool calculate_prbs_cfg(
 660    input_system_channel_t              *channel,
 661    input_system_input_port_t   *input_port,
 662    isp2401_input_system_cfg_t          *isys_cfg,
 663    pixelgen_prbs_cfg_t         *cfg)
 664{
 665        memcpy(cfg, &isys_cfg->prbs_port_attr, sizeof(pixelgen_prbs_cfg_t));
 666
 667        return true;
 668}
 669
 670static bool calculate_fe_cfg(
 671    const isp2401_input_system_cfg_t    *isys_cfg,
 672    csi_rx_frontend_cfg_t               *cfg)
 673{
 674        cfg->active_lanes = isys_cfg->csi_port_attr.active_lanes;
 675        return true;
 676}
 677
 678static bool calculate_be_cfg(
 679    const input_system_input_port_t     *input_port,
 680    const isp2401_input_system_cfg_t    *isys_cfg,
 681    bool                                metadata,
 682    csi_rx_backend_cfg_t                *cfg)
 683{
 684        memcpy(&cfg->lut_entry,
 685              metadata ? &input_port->metadata.backend_lut_entry :
 686                         &input_port->csi_rx.backend_lut_entry,
 687              sizeof(csi_rx_backend_lut_entry_t));
 688
 689        cfg->csi_mipi_cfg.virtual_channel = isys_cfg->csi_port_attr.ch_id;
 690        if (metadata) {
 691                cfg->csi_mipi_packet_type = get_csi_mipi_packet_type(
 692                                                isys_cfg->metadata.fmt_type);
 693                cfg->csi_mipi_cfg.comp_enable = false;
 694                cfg->csi_mipi_cfg.data_type = isys_cfg->metadata.fmt_type;
 695        } else {
 696                cfg->csi_mipi_packet_type = get_csi_mipi_packet_type(
 697                                                isys_cfg->csi_port_attr.fmt_type);
 698                cfg->csi_mipi_cfg.data_type = isys_cfg->csi_port_attr.fmt_type;
 699                cfg->csi_mipi_cfg.comp_enable = isys_cfg->csi_port_attr.comp_enable;
 700                cfg->csi_mipi_cfg.comp_scheme = isys_cfg->csi_port_attr.comp_scheme;
 701                cfg->csi_mipi_cfg.comp_predictor = isys_cfg->csi_port_attr.comp_predictor;
 702                cfg->csi_mipi_cfg.comp_bit_idx = cfg->csi_mipi_cfg.data_type -
 703                                                 MIPI_FORMAT_CUSTOM0;
 704        }
 705
 706        return true;
 707}
 708
 709static bool calculate_stream2mmio_cfg(
 710    const isp2401_input_system_cfg_t    *isys_cfg,
 711    bool                                metadata,
 712    stream2mmio_cfg_t           *cfg
 713)
 714{
 715        cfg->bits_per_pixel = metadata ? isys_cfg->metadata.bits_per_pixel :
 716                              isys_cfg->input_port_resolution.bits_per_pixel;
 717
 718        cfg->enable_blocking =
 719            ((isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_TPG) ||
 720             (isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS));
 721
 722        return true;
 723}
 724
 725static bool calculate_ibuf_ctrl_cfg(
 726    const input_system_channel_t        *channel,
 727    const input_system_input_port_t     *input_port,
 728    const isp2401_input_system_cfg_t    *isys_cfg,
 729    ibuf_ctrl_cfg_t                     *cfg)
 730{
 731        const s32 bits_per_byte = 8;
 732        s32 bits_per_pixel;
 733        s32 bytes_per_pixel;
 734        s32 left_padding;
 735
 736        (void)input_port;
 737
 738        bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel;
 739        bytes_per_pixel = ceil_div(bits_per_pixel, bits_per_byte);
 740
 741        left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS)
 742                       * bytes_per_pixel;
 743
 744        cfg->online     = isys_cfg->online;
 745
 746        cfg->dma_cfg.channel    = channel->dma_channel;
 747        cfg->dma_cfg.cmd        = _DMA_V2_MOVE_A2B_NO_SYNC_CHK_COMMAND;
 748
 749        cfg->dma_cfg.shift_returned_items       = 0;
 750        cfg->dma_cfg.elems_per_word_in_ibuf     = 0;
 751        cfg->dma_cfg.elems_per_word_in_dest     = 0;
 752
 753        cfg->ib_buffer.start_addr               = channel->ib_buffer.start_addr;
 754        cfg->ib_buffer.stride                   = channel->ib_buffer.stride;
 755        cfg->ib_buffer.lines                    = channel->ib_buffer.lines;
 756
 757        /*
 758        #ifndef ISP2401
 759         * zhengjie.lu@intel.com:
 760        #endif
 761         * "dest_buf_cfg" should be part of the input system output
 762         * port configuration.
 763         *
 764         * TODO: move "dest_buf_cfg" to the input system output
 765         * port configuration.
 766         */
 767
 768        /* input_buf addr only available in sched mode;
 769           this buffer is allocated in isp, crun mode addr
 770           can be passed by after ISP allocation */
 771        if (cfg->online) {
 772                cfg->dest_buf_cfg.start_addr    = ISP_INPUT_BUF_START_ADDR + left_padding;
 773                cfg->dest_buf_cfg.stride        = bytes_per_pixel
 774                                              * isys_cfg->output_port_attr.max_isp_input_width;
 775                cfg->dest_buf_cfg.lines         = LINES_OF_ISP_INPUT_BUF;
 776        } else if (isys_cfg->raw_packed) {
 777                cfg->dest_buf_cfg.stride        = calculate_stride(bits_per_pixel,
 778                                              isys_cfg->input_port_resolution.pixels_per_line,
 779                                              isys_cfg->raw_packed,
 780                                              isys_cfg->input_port_resolution.align_req_in_bytes);
 781        } else {
 782                cfg->dest_buf_cfg.stride        = channel->ib_buffer.stride;
 783        }
 784
 785        /*
 786        #ifndef ISP2401
 787         * zhengjie.lu@intel.com:
 788        #endif
 789         * "items_per_store" is hard coded as "1", which is ONLY valid
 790         * when the CSI-MIPI long packet is transferred.
 791         *
 792         * TODO: After the 1st stage of MERR+,  make the proper solution to
 793         * configure "items_per_store" so that it can also handle the CSI-MIPI
 794         * short packet.
 795         */
 796        cfg->items_per_store            = 1;
 797
 798        cfg->stores_per_frame           = isys_cfg->input_port_resolution.lines_per_frame;
 799
 800        cfg->stream2mmio_cfg.sync_cmd   = _STREAM2MMIO_CMD_TOKEN_SYNC_FRAME;
 801
 802        /* TODO: Define conditions as when to use store words vs store packets */
 803        cfg->stream2mmio_cfg.store_cmd  = _STREAM2MMIO_CMD_TOKEN_STORE_PACKETS;
 804
 805        return true;
 806}
 807
 808static bool calculate_isys2401_dma_cfg(
 809    const input_system_channel_t        *channel,
 810    const isp2401_input_system_cfg_t    *isys_cfg,
 811    isys2401_dma_cfg_t          *cfg)
 812{
 813        cfg->channel    = channel->dma_channel;
 814
 815        /* only online/sensor mode goto vmem
 816           offline/buffered_sensor, tpg and prbs will go to ddr */
 817        if (isys_cfg->online)
 818                cfg->connection = isys2401_dma_ibuf_to_vmem_connection;
 819        else
 820                cfg->connection = isys2401_dma_ibuf_to_ddr_connection;
 821
 822        cfg->extension  = isys2401_dma_zero_extension;
 823        cfg->height     = 1;
 824
 825        return true;
 826}
 827
 828/* See also: ia_css_dma_configure_from_info() */
 829static bool calculate_isys2401_dma_port_cfg(
 830    const isp2401_input_system_cfg_t    *isys_cfg,
 831    bool                                raw_packed,
 832    bool                                metadata,
 833    isys2401_dma_port_cfg_t             *cfg)
 834{
 835        s32 bits_per_pixel;
 836        s32 pixels_per_line;
 837        s32 align_req_in_bytes;
 838
 839        /* TODO: Move metadata away from isys_cfg to application layer */
 840        if (metadata) {
 841                bits_per_pixel = isys_cfg->metadata.bits_per_pixel;
 842                pixels_per_line = isys_cfg->metadata.pixels_per_line;
 843                align_req_in_bytes = isys_cfg->metadata.align_req_in_bytes;
 844        } else {
 845                bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel;
 846                pixels_per_line = isys_cfg->input_port_resolution.pixels_per_line;
 847                align_req_in_bytes = isys_cfg->input_port_resolution.align_req_in_bytes;
 848        }
 849
 850        cfg->stride     = calculate_stride(bits_per_pixel, pixels_per_line, raw_packed,
 851                                       align_req_in_bytes);
 852
 853        if (!raw_packed)
 854                bits_per_pixel = CEIL_MUL(bits_per_pixel, 8);
 855
 856        cfg->elements   = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
 857        cfg->cropping   = 0;
 858        cfg->width      = CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES);
 859
 860        return true;
 861}
 862
 863static csi_mipi_packet_type_t get_csi_mipi_packet_type(
 864    int32_t data_type)
 865{
 866        csi_mipi_packet_type_t packet_type;
 867
 868        packet_type = CSI_MIPI_PACKET_TYPE_RESERVED;
 869
 870        if (data_type >= 0 && data_type <= MIPI_FORMAT_SHORT8)
 871                packet_type = CSI_MIPI_PACKET_TYPE_SHORT;
 872
 873        if (data_type > MIPI_FORMAT_SHORT8 && data_type <= N_MIPI_FORMAT)
 874                packet_type = CSI_MIPI_PACKET_TYPE_LONG;
 875
 876        return packet_type;
 877}
 878
 879/* end of Private Methods */
 880#endif
 881