/**
 * @brief       PGP Manager (Assign)
 * @author      AXELL CORPORATION
 * @description PGP Manager Layer.
 * @note        none
 * @history     2017_02_22  初版
 * @history     2017_10_26  Ver2.0
 * @history     2018_01_24  Ver2.1 [#1767] ディザリング機能を有効にしても適切なパイプラインが割当てられない不具合対応
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017 AXELL CORPORATION, all rights reserved.
 */
/* DOM-IGNORE-END */

#include <stdio.h>
#include "pgpmgr_common.h"

#define PIPELINE_SIZE_FULLHD   1920
#define PIPELINE_SIZE_VGA      768


/* パイプラインハンドルの設定内容から割り当て先を選択します */
static int32_t PgpMgrAssignPipeline(AG903_PgpMgrPipelineHandle *handle)
{
    int32_t pipeline_no;
    PgpMgrContext *ctx = PgpGetContext();

    /* フレーム保存パイプラインに割り当て可能な場合は、フレーム保存パイプラインに割り当てます */
    if ((handle->thr_enable == false) && (handle->dgc_enable == false) && (handle->hsv1_enable == false) &&
        (handle->spf_enable == false) && (handle->hgm_enable == false) && (handle->lbl_enable == false) &&
        (handle->ifc_enable == false) &&
        (handle->input_format != AG903_PGP_MGR_INPUT_FMT_YCBCR422_W_IP) && (handle->scale_enable == false) &&
        (handle->csc1_enable == false) && (handle->nrf_enable == false) &&
        (handle->output_dither_enable == false) &&
        ((ctx->assign_pipeline[AG903_PGP_MGR_FRAME_PIPELINE0] == NULL) || (ctx->assign_pipeline[AG903_PGP_MGR_FRAME_PIPELINE1] == NULL))) {
        if (ctx->assign_pipeline[AG903_PGP_MGR_FRAME_PIPELINE1] != NULL) {
            pipeline_no = AG903_PGP_MGR_FRAME_PIPELINE0;
        } else {
            pipeline_no = AG903_PGP_MGR_FRAME_PIPELINE1;
        }
    /* 入力画像処理パイプラインに割り当て可能な場合は、入力画像処理パイプラインに割り当てます */
    } else if ((handle->thr_enable == false) && (handle->dgc_enable == false) && (handle->hsv1_enable == false) &&
        (handle->spf_enable == false) && (handle->hgm_enable == false) && (handle->lbl_enable == false) &&
        (handle->ifc_enable == false) &&
        (((ctx->assign_pipeline[AG903_PGP_MGR_INPUT_PIPELINE0] == NULL) && (handle->input_hsize <= PIPELINE_SIZE_FULLHD)) ||
        ((ctx->assign_pipeline[AG903_PGP_MGR_INPUT_PIPELINE1] == NULL) && (handle->input_hsize <= PIPELINE_SIZE_VGA)))) {
        if ((ctx->assign_pipeline[AG903_PGP_MGR_INPUT_PIPELINE1] == NULL) && (handle->input_hsize <= PIPELINE_SIZE_VGA)) {
            pipeline_no = AG903_PGP_MGR_INPUT_PIPELINE1;
        } else {
            pipeline_no = AG903_PGP_MGR_INPUT_PIPELINE0;
        }
    /* 演算処理パイプラインに割当て可能な場合は、 演算処理パイプラインに割り当てます*/
    } else if (((ctx->assign_pipeline[AG903_PGP_MGR_CALC_PIPELINE0] == NULL) && (handle->input_hsize <= PIPELINE_SIZE_FULLHD)) ||
        ((ctx->assign_pipeline[AG903_PGP_MGR_CALC_PIPELINE1] == NULL) && (handle->input_hsize <= PIPELINE_SIZE_VGA))) {
        if ((ctx->assign_pipeline[AG903_PGP_MGR_CALC_PIPELINE1] == NULL) && (handle->input_hsize <= PIPELINE_SIZE_VGA)) {
            pipeline_no = AG903_PGP_MGR_CALC_PIPELINE1;
        } else {
            pipeline_no = AG903_PGP_MGR_CALC_PIPELINE0;
        }
    } else {
        /* 割り当て失敗 */
        pipeline_no = -1;
    }
    return pipeline_no;
}


/* 指定したパイプラインに対してフレーム間演算のスレーブ側パイプラインハンドルの割り当てが可能かチェックします */
static int32_t PgpMgrCheckSlaveAssignPipeline(AG903_PgpMgrPipelineHandle *handle, uint32_t pipeline)
{
    PgpMgrContext *ctx = PgpGetContext();

    switch (pipeline) {
        case AG903_PGP_MGR_CALC_PIPELINE0:
            if ((ctx->assign_pipeline[AG903_PGP_MGR_CALC_PIPELINE0] == NULL) && handle->input_hsize <= PIPELINE_SIZE_FULLHD) {
                return 0;
            }
            break;
        case AG903_PGP_MGR_CALC_PIPELINE1:
        default:
            if ((ctx->assign_pipeline[AG903_PGP_MGR_CALC_PIPELINE1] == NULL) && handle->input_hsize <= PIPELINE_SIZE_VGA) {
                return 0;
            }
            break;
    } 
    return -AG903_EINVAL;
}


/* VRAM入力ハンドルの割り当てを行ないます */
static int32_t PgpMgrAssignVRAMInput(AG903_PgpMgrVRAMInputHandle *handle)
{
    int32_t vram_port_no;

    /* VRAM入力ハンドルは複数のパイプラインで共有可能なので、既に割り当て済の場合は処理を抜けます */
    if (handle->port_no != -1) {
        return handle->port_no;
    }

    /* 時分割動作無効時は空いているVRAM入力ポート選択し、有効時は交互に割り当てます */
    PgpMgrContext *ctx = PgpGetContext();
    if (ctx->pipeline_time_sharing_enable == false) {
        if (ctx->assign_vram[0] == NULL) {
            vram_port_no = 0;
        } else if (ctx->assign_vram[1] == NULL) {
            vram_port_no = 1;
        } else {
            /* 割り当て失敗 */
            vram_port_no = -1;
        }
    } else {
        static int32_t next_vram_port_no = 0;
        vram_port_no = next_vram_port_no;
        next_vram_port_no = (next_vram_port_no == 0) ? 1 : 0;
    }
    return vram_port_no;
}


/* パイプラインの割り当て情報を更新するためのマクロ */
#define SET_PIPELINE_ASSIGN_INFO(handle, pipeline) \
            if (ctx->pipeline_time_sharing_enable == false) { \
                ctx->assign_pipeline[(pipeline)] = (handle); \
            }; \
            (handle)->is_assign = true; \
            (handle)->is_dirty = false; \
            (handle)->pipeline_no = (pipeline);
/* VRAM入力割り当て情報を更新するためのマクロ */
#define SET_VRAM_ASSIGN_INFO(handle, vram_port_no) \
            if (ctx->pipeline_time_sharing_enable == false) { \
                ctx->assign_vram[(vram_port_no)] = (handle); \
            } \
            (handle)->is_dirty = false; \
            (handle)->port_no = (vram_port_no);


/**
 * @brief   パイプラインハンドルの割り当てを行ないます。
 * @param   handle [in] 割り当てを行なうパイプラインハンドルを指定します。
 * @return  パイプライン番号 割り当て成功時
 * @return  -AG903_EINVAL 割り当て失敗の場合
 * @note    本関数はユーザー側が直接使用することはありません。
*/
int32_t PgpMgrAssignPipelineHandle(AG903_PgpMgrPipelineHandle *handle)
{
    int32_t pipeline_no = PgpMgrAssignPipeline(handle);
    _Bool input_vram = false;
    int32_t vram_port_no = 0;
    PgpMgrContext *ctx = PgpGetContext();

    /* パイプラインへの入力ソースがVRAM入力の場合、VRAM入力の割り当てを行ないます */
    AG903_PgpMgrVRAMInputHandle *vram_handle = (AG903_PgpMgrVRAMInputHandle *)handle->input_handle;
    if (vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
        input_vram = true;
        vram_port_no = PgpMgrAssignVRAMInput(vram_handle);
    }

    /* 割り当て失敗の場合はエラーとします */
    if ((pipeline_no == -1) || (vram_port_no == -1)) {
        return -AG903_EINVAL;
    }

    /* 入力ソースがVRAM入力の場合、VRAM入力ハンドルの設定を更新します */
    if (input_vram == true) {
        /* VRAM入力の割り当て情報を更新します */
        SET_VRAM_ASSIGN_INFO(vram_handle, vram_port_no);
        /* VRAM入力のポート番号は割り当て時に決定するため、パイプラインの入力ポートの値をこのタイミングで更新します */
        handle->input_port = vram_port_no == 0 ? AG903_PGP_MGR_INPUT_PORT_VRAM_0 : AG903_PGP_MGR_INPUT_PORT_VRAM_1;
    }

    /* パイプラインの割り当て情報を更新します */
    SET_PIPELINE_ASSIGN_INFO(handle, pipeline_no);
    return pipeline_no;
}


/**
 * @brief   フレーム間演算ハンドルの割り当てを行ないます。
 * @param   handle [in] 割り当てを行なうフレーム間演算ハンドルを指定します。
 * @return  パイプライン番号 割り当て成功時
 * @return  -AG903_EINVAL 割り当て失敗の場合
 * @note    本関数はユーザー側が直接使用することはありません。
*/
int32_t PgpMgrAssignFrameCalcHandle(AG903_PgpMgrFrameCalcHandle *handle)
{
    int32_t master_pipeline_no, slave_pipeline_no;
    int32_t master_vram_port_no = 0, slave_vram_port_no;
    AG903_PgpMgrVRAMInputHandle *master_vram_handle;
    AG903_PgpMgrVRAMInputHandle *slave_vram_handle;
    PgpMgrContext *ctx = PgpGetContext();

    /* マスタのパイプライン割り当てを行ないます */
    master_pipeline_no = PgpMgrAssignPipeline(handle->master_handle);
    if (master_pipeline_no == -1) {
        return -AG903_EINVAL;
    }
    /* マスタ側パイプラインへの入力ソースがVRAM入力の場合、VRAM入力の割り当てを行ないます */
    master_vram_handle = (AG903_PgpMgrVRAMInputHandle *)handle->master_handle->input_handle;
    if (master_vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
        master_vram_port_no = PgpMgrAssignVRAMInput(master_vram_handle);
        if (master_vram_port_no == -1) {
            return -AG903_EINVAL;
        }
    }
    if (handle->slave_pipeline == true) {
        AG903_PgpMgrPipelineHandle *slave = (AG903_PgpMgrPipelineHandle *)handle->slave_handle;
        slave_pipeline_no = (master_pipeline_no == AG903_PGP_MGR_CALC_PIPELINE0) ?
                                AG903_PGP_MGR_CALC_PIPELINE1 : AG903_PGP_MGR_CALC_PIPELINE0;
        if (PgpMgrCheckSlaveAssignPipeline(slave, slave_pipeline_no) != 0) {
            return -AG903_EINVAL;
        }
        /* スレーブ側パイプラインへの入力ソースがVRAM入力の場合、VRAM入力の割り当てを行ないます */
        slave_vram_handle = (AG903_PgpMgrVRAMInputHandle *)slave->input_handle;
        if (slave_vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
            /* マスタ、スレーブが同じVRAM入力ハンドルを共有する場合、割り当て等の処理はスキップします */
            if (master_vram_handle == slave_vram_handle) {
                slave_vram_port_no = master_vram_port_no;
            } else {
                slave_vram_port_no = PgpMgrAssignVRAMInput(slave_vram_handle);
                if (slave_vram_port_no == -1) {
                    return -AG903_EINVAL;
                }
                /* VRAM入力側もデータ構造を更新します */
                SET_VRAM_ASSIGN_INFO(slave_vram_handle, slave_vram_port_no);
            }
            /* VRAM入力のポート番号は割り当て時に決定するため、パイプラインの入力ポートの値をこのタイミングで更新します */
            slave->input_port = slave_vram_port_no == 0 ? AG903_PGP_MGR_INPUT_PORT_VRAM_0 : AG903_PGP_MGR_INPUT_PORT_VRAM_1;
        }
        /* スレーブ側が割り当て可能な場合は割り当て先を管理するデータ構造にハンドルを保持します */
        SET_PIPELINE_ASSIGN_INFO(slave, slave_pipeline_no);
    } else {
        /* スレーブがVRAM入力の場合、マスタのパイプライン番号からVRAM入力ポートを決定します */
        slave_vram_handle = (AG903_PgpMgrVRAMInputHandle *)handle->slave_handle;
        slave_vram_port_no = (master_pipeline_no == AG903_PGP_MGR_CALC_PIPELINE0) ? 2 : 3;
        SET_VRAM_ASSIGN_INFO(slave_vram_handle, slave_vram_port_no);
    }
    /* マスタ側入力ソースがVRAM入力の場合、VRAM入力ハンドルの設定を更新します */
    if (master_vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
        /* VRAM入力の割り当て情報を更新します */
        SET_VRAM_ASSIGN_INFO(master_vram_handle, master_vram_port_no);
        /* VRAM入力のポート番号は割り当て時に決定するため、パイプラインの入力ポートの値をこのタイミングで更新します */
        handle->master_handle->input_port = master_vram_port_no == 0 ? AG903_PGP_MGR_INPUT_PORT_VRAM_0 : AG903_PGP_MGR_INPUT_PORT_VRAM_1;
    }
    /* パイプラインの割り当て情報を更新します */
    SET_PIPELINE_ASSIGN_INFO(handle->master_handle, master_pipeline_no);
    return master_pipeline_no;
}


/* 引数で指定されたパイプラインに強制割り当て可能かチェックします */
static int32_t PgpMgrCheckForceAssignPipeline(uint32_t pipeline)
{
    int32_t i;
    PgpMgrContext *ctx = PgpGetContext();

    /* 指定したパイプラインに他のパイプラインハンドルが割り当て済であるかチェックします */
    if (ctx->assign_pipeline[pipeline] != NULL) {
        return -AG903_EINVAL;
    }
    for (i = 0; i < AG903_PGP_MGR_MAX_PIPELINE_HANDLE; i++) {
        if ((ctx->pipeline_handles[i].is_used == true) && (ctx->pipeline_handles[i].is_assign == true) &&
                                                          ((uint32_t)ctx->pipeline_handles[i].pipeline_no == pipeline)) {
            return -AG903_EINVAL;
        }
    }
    return 0;
}

/* パイプラインの強制割り当て情報を更新するためのマクロ */
#define SET_PIPELINE_FORCE_ASSIGN_INFO(handle, pipeline) \
            ctx->assign_pipeline[(pipeline)] = (handle); \
            (handle)->is_assign = true; \
            (handle)->is_dirty = false; \
            (handle)->pipeline_no = (pipeline);

/**
 * @brief   パイプラインハンドルを指定した物理パイプラインに強制割り当てを行ないます。
 * @param   handle [in] 割り当てを行なうパイプラインハンドルを指定します。
 * @param   pipeline [in] 割り当て先パイプライン番号
 * @return  パイプライン番号 割り当て成功時
 * @return  -AG903_EINVAL 割り当て失敗の場合
 * @note    本関数はユーザー側が直接使用することはありません。
*/
int32_t PgpMgrForceAssignPipelineHandle(AG903_PgpMgrPipelineHandle *handle, uint32_t pipeline)
{
    int32_t vram_port_no;
    AG903_PgpMgrVRAMInputHandle *vram_handle;
    PgpMgrContext *ctx = PgpGetContext();

    /* 強制割り当て可能かチェックします */
    if (PgpMgrCheckForceAssignPipeline(pipeline) != 0) {
        return -AG903_EINVAL;
    }

    /* パイプラインへの入力ソースがVRAM入力であるかチェックします */
    vram_handle = (AG903_PgpMgrVRAMInputHandle *)handle->input_handle;
    if (vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
        vram_port_no = PgpMgrAssignVRAMInput(vram_handle);

        /* VRAM入力の割り当てに失敗した場合はエラーとします */
        if (vram_port_no == -1) {
            return -AG903_EINVAL;
        }
        /* 割り当て可能な場合は割り当て先を管理するデータ構造にハンドルを保持します */
        SET_VRAM_ASSIGN_INFO(vram_handle, vram_port_no);
        /* VRAM入力のポート番号は割り当て時に決定するため、パイプラインの入力ポートの値をこのタイミングで更新します */
        handle->input_port = vram_port_no == 0 ? AG903_PGP_MGR_INPUT_PORT_VRAM_0 : AG903_PGP_MGR_INPUT_PORT_VRAM_1;
    }

    /* 割り当て可能な場合は割り当て先を管理するデータ構造にハンドルを保持します */
    SET_PIPELINE_FORCE_ASSIGN_INFO(handle, pipeline);
    return pipeline;
}


/**
 * @brief   フレーム間演算ンハンドルを指定した物理パイプラインに強制割り当てを行ないます。
 * @param   handle [in] 割り当てを行なうフレーム間演算ハンドルを指定します。
 * @param   pipeline [in] 割り当て先パイプライン番号(マスタ側)
 * @return  パイプライン番号 割り当て成功時
 * @return  -AG903_EINVAL 割り当て失敗の場合
 * @note    スレーブがパイプラインハンドルの場合、割り当て先はマスタ側とは異なる演算処理パイプラインになります。<p>
 *          本関数はユーザー側が直接使用することはありません。
*/
int32_t PgpMgrForceAssignFrameCalcHandle(AG903_PgpMgrFrameCalcHandle *handle, uint32_t pipeline)
{
    int32_t master_vram_port_no = -1, slave_vram_port_no = -1;
    AG903_PgpMgrVRAMInputHandle *master_vram_handle;
    AG903_PgpMgrVRAMInputHandle *slave_vram_handle;
    PgpMgrContext *ctx = PgpGetContext();

    /* マスタ側は演算処理パイプライン以外はエラーとします */
    switch (pipeline) {
        case AG903_PGP_MGR_CALC_PIPELINE0:
        case AG903_PGP_MGR_CALC_PIPELINE1:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* マスタ側パイプラインハンドルの強制割り当て可能かチェックします */
    if (PgpMgrCheckForceAssignPipeline(pipeline) != 0) {
        return -AG903_EINVAL;
    }
    /* パイプラインへの入力ソースがVRAM入力の場合は割り当てを行ないます */
    master_vram_handle = (AG903_PgpMgrVRAMInputHandle *)handle->master_handle->input_handle;
    if (master_vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
        master_vram_port_no = PgpMgrAssignVRAMInput(master_vram_handle);
        /* VRAM入力の割り当てに失敗した場合はエラーとします */
        if (master_vram_port_no == -1) {
            return -AG903_EINVAL;
        }
    }

    if (handle->slave_pipeline == true) {
        uint32_t slave_pipeline = (pipeline == AG903_PGP_MGR_CALC_PIPELINE0) ? AG903_PGP_MGR_CALC_PIPELINE1 : AG903_PGP_MGR_CALC_PIPELINE0;
        AG903_PgpMgrPipelineHandle *slave = (AG903_PgpMgrPipelineHandle *)handle->slave_handle;
        /* スレーブ側がパイプラインハンドルの場合、マスタとは別の演算処理パイプラインに割り当て可能かチェックします */
        if (PgpMgrCheckForceAssignPipeline(slave_pipeline) != 0) {
            return -AG903_EINVAL;
        }
        /* パイプラインへの入力ソースがVRAM入力の場合は割り当てを行ないます */
        slave_vram_handle = (AG903_PgpMgrVRAMInputHandle *)slave->input_handle;
        if (slave_vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
            /* マスタ、スレーブが同じVRAM入力ハンドルを共有する場合、割り当て等の処理はスキップします */
            if (master_vram_handle == slave_vram_handle) {
                slave_vram_port_no = master_vram_port_no;
            } else {
                slave_vram_port_no = PgpMgrAssignVRAMInput(slave_vram_handle);
                /* VRAM入力の割り当てに失敗した場合はエラーとします */
                if (slave_vram_port_no == -1) {
                    return -AG903_EINVAL;
                }
                /* VRAM入力側もデータ構造を更新します */
               SET_VRAM_ASSIGN_INFO(slave_vram_handle, slave_vram_port_no);
            }
            /* VRAM入力のポート番号は割り当て時に決定するため、パイプラインの入力ポートの値をこのタイミングで更新します */
            slave->input_port = slave_vram_port_no == 0 ? AG903_PGP_MGR_INPUT_PORT_VRAM_0 : AG903_PGP_MGR_INPUT_PORT_VRAM_1;
        }
        /* スレーブ側が割り当て可能な場合は割り当て先を管理するデータ構造にハンドルを保持します */
        SET_PIPELINE_FORCE_ASSIGN_INFO(slave, slave_pipeline);
    } else {
        /* スレーブがVRAM入力の場合、マスタのパイプライン番号からVRAM入力ポートを決定します */
        slave_vram_handle = (AG903_PgpMgrVRAMInputHandle *)handle->slave_handle;
        slave_vram_port_no = (pipeline == AG903_PGP_MGR_CALC_PIPELINE0) ? 2 : 3;
        SET_VRAM_ASSIGN_INFO(slave_vram_handle, slave_vram_port_no);
    }

    /* マスタ側割り当て先を管理するデータ構造にハンドルを保持します */
    SET_PIPELINE_FORCE_ASSIGN_INFO(handle->master_handle, pipeline);
    /* マスタ側入力がVRAM入力の場合はおなじくデータ構造を更新します */
    if (master_vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
        SET_VRAM_ASSIGN_INFO(master_vram_handle, master_vram_port_no);
        /* VRAM入力のポート番号は割り当て時に決定するため、パイプラインの入力ポートの値をこのタイミングで更新します */
        handle->master_handle->input_port = master_vram_port_no == 0 ? AG903_PGP_MGR_INPUT_PORT_VRAM_0 : AG903_PGP_MGR_INPUT_PORT_VRAM_1;
    }
    return pipeline;
}


/**
 * @brief   パイプラインハンドルが指定した物理パイプラインに割り当て可能かチェックします。
 * @param   handle [in] 割り当てチェックを行なうパイプラインハンドルを指定します。
 * @param   pipeline [in] 割り当て先パイプライン番号
 * @return  AG903_ENONE 割り当て成功時
 * @return  -AG903_EINVAL 割り当て失敗の場合
 * @note    本関数はユーザー側が直接使用することはありません。
*/
int32_t PgpMgrCheckAssignPipelineHandle(AG903_PgpMgrPipelineHandle *handle, uint32_t pipeline)
{
    switch (pipeline) {
        case AG903_PGP_MGR_CALC_PIPELINE0:
            /* 演算処理パイプラインは全ての機能を持ち合わせるため、サイズ制限のみチェック */
            if (handle->input_hsize > PIPELINE_SIZE_FULLHD) {
                return -AG903_EINVAL;
            }
            break;
        case AG903_PGP_MGR_CALC_PIPELINE1:
            /* 演算処理パイプラインは全ての機能を持ち合わせるため、サイズ制限のみチェック */
            if (handle->input_hsize > PIPELINE_SIZE_VGA) {
                return -AG903_EINVAL;
            }
            break;
        case AG903_PGP_MGR_INPUT_PIPELINE0:
            /* サイズ制限と、演算処理パイプラインの機能が有効であるかチェック */
            if ((handle->input_hsize > PIPELINE_SIZE_FULLHD) || (handle->thr_enable == true) || (handle->dgc_enable == true) ||
                (handle->hsv1_enable == true) || (handle->spf_enable == true) || (handle->hgm_enable == true) ||
                (handle->lbl_enable == true) || (handle->ifc_enable == true)) {
                return -AG903_EINVAL;
            }
            break;
        case AG903_PGP_MGR_INPUT_PIPELINE1:
            /* サイズ制限と、演算処理パイプラインの機能が有効であるかチェック */
            if ((handle->input_hsize > PIPELINE_SIZE_VGA) || (handle->thr_enable == true) || (handle->dgc_enable == true) ||
                (handle->hsv1_enable == true) || (handle->spf_enable == true) || (handle->hgm_enable == true) ||
                (handle->lbl_enable == true) || (handle->ifc_enable == true)) {
                return -AG903_EINVAL;
            }
            break;
        case AG903_PGP_MGR_FRAME_PIPELINE0:
        case AG903_PGP_MGR_FRAME_PIPELINE1:
            /* 演算処理パイプライン、入力画像処パイプラインの機能が有効であるかチェック */
            if ((handle->thr_enable == true) || (handle->dgc_enable == true) || (handle->hsv1_enable == true) ||
                (handle->spf_enable == true) || (handle->hgm_enable == true) || (handle->lbl_enable == true) ||
                (handle->ifc_enable == true) ||
                (handle->scale_enable == true) || (handle->csc1_enable == true) || (handle->nrf_enable == true) ||
                (handle->input_format == AG903_PGP_MGR_INPUT_FMT_YCBCR422_W_IP)) {
                return -AG903_EINVAL;
            }
            break;
    }
    return AG903_ENONE;
}
