/**
 * @brief           SPC Primitive Header
 * @author          AXELL CORPORATION
 * @description     SPC Primitive提供ヘッダ。<p>SPC Primitive使用時にincludeして下さい。
 * @note            none
 * @history         2017_02_22  初版
 * @history         2017_10_26  Ver2.0
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017 AXELL CORPORATION, all rights reserved.
 */

#ifndef _SPCPRM_H_
#define _SPCPRM_H_
/* DOM-IGNORE-END */

#include <stdint.h>
#include "lib_common/AG903_common.h"

#ifdef __cplusplus
extern "C" {
#endif

#define AG903_SPC_SWRSTMSK_REG_NUM			(5)		/** ソフトウェアリセットマスク設定レジスタ数 */
#define AG903_SPC_CA5CTRL_REG_NUM			(11)	/** Cortex-A5設定レジスタ数 */

#define	AG903_SPC_ETHER_MII					(0)		/** イーサネットPHY選択 MII */
#define	AG903_SPC_ETHER_RMII				(1)		/** イーサネットPHY選択 RMII */

#define	AG903_SPC_IDECLK_PLL0DIV4			(0)		/** IDE用クロック選択 PLL0出力4分周 */
#define	AG903_SPC_IDECLK_PLL0DIV3			(1)		/** IDE用クロック選択 PLL0出力3分周 */

#define	AG903_SPC_USBCTRL_CLKSEL_MIIRXCLK	(0)		/** USBPHY供給クロック MII_RXCLK */
#define	AG903_SPC_USBCTRL_CLKSEL_XOUT		(1)		/** USBPHY供給クロック X_OUT */

#define AG903_SPC_USBCTRL_XTLSEL_12MHZ		(0)		/** USBPHY入力クロック周波数 12MHz */
#define AG903_SPC_USBCTRL_XTLSEL_30MHZ		(1)		/** USBPHY入力クロック周波数 30MHz */


/** PLL1クロックソース選択 */
enum  _AG903_SSC_PLL1_CLKSRC {
	AG903_SPC_PLL1_CLKSRC_XOUT = 0,		/** XOUT/OSC */
	AG903_SPC_PLL1_CLKSRC_MIIRXCLK,		/** MIIRXCLK */
	AG903_SPC_PLL1_CLKSRC_DVOCLK,		/** DVOCLK */
};

/** PLL2クロックソース選択 */
enum  _AG903_SSC_PLL2_CLKSRC {
	AG903_SPC_PLL2_CLKSRC_XOUT = 0,		/** XOUT/OSC */
	AG903_SPC_PLL2_CLKSRC_MIITXCLK,		/** MIITXCLK */
	AG903_SPC_PLL2_CLKSRC_DVO,			/** DVO[13]  */
};

/** PLL3クロックソース選択 */
enum  _AG903_SSC_PLL3_CLKSRC {
	AG903_SPC_PLL3_CLKSRC_XOUT = 0,		/** XOUT/OSC */
	AG903_SPC_PLL3_CLKSRC_DVOCLK,		/** DVOCLK */
	AG903_SPC_PLL3_CLKSRC_DVO,			/** DVO[13] */
	AG903_SPC_PLL3_CLKSRC_SSPSEL,		/** SSPクロック選択結果(以下) */
};

/** PLL3クロックソース選択[SSP] */
enum  _AG903_SSC_PLL3_CLKSRC_SSP {
	AG903_SPC_PLL3_CLKSRC_SSP0 = 0,		/** SSP0 */
	AG903_SPC_PLL3_CLKSRC_SSP1,			/** SSP1 */
	AG903_SPC_PLL3_CLKSRC_SSP2,			/** SSP2 */
	AG903_SPC_PLL3_CLKSRC_SSP3,			/** SSP3 */
};

/** PLLAクロックソース選択 */
enum  _AG903_SSC_PLLA_CLKSRC {
	AG903_SPC_PLLA_CLKSRC_OSC = 0,		/** OSC */
	AG903_SPC_PLLA_CLKSRC_DVOCLK,		/** DVOCLK */
	AG903_SPC_PLLA_CLKSRC_DVO,			/** DVO[13] */
};

/** キャプチャ用ドットクロック0 クロックソース選択 */
enum  _AG903_SSC_CP0_CLKSRC {
	AG903_SPC_CP0_CLKSRC_DVOCLK = 0,	/** DVOCLK */
	AG903_SPC_CP0_CLKSRC_PLL1,			/** PLL2 */
	AG903_SPC_CP0_CLKSRC_PLL3,			/** DVO[13] */
};

/** キャプチャ用ドットクロック1 クロックソース選択 */
enum  _AG903_SSC_CP1_CLKSRC {
	AG903_SPC_CP1_CLKSRC_PLL3 = 0,		/** PLL3 */
	AG903_SPC_CP1_CLKSRC_PLL2,			/** PLL2 */
	AG903_SPC_CP1_CLKSRC_DVO,			/** DVO[13] */
};

/** LVDSトランスミッタCH0 クロックソース選択 */
enum  _AG903_SSC_LVDS_CLKSRC {
	AG903_SPC_LVDS_CLKSRC_DSP0 = 0,		/** 表示用ドットクロック0 */
	AG903_SPC_LVDS_CLKSRC_DSP1,			/** 表示用ドットクロック1 */
};

/** 表示用ドットクロック0 クロックソース選択 */
enum  _AG903_SSC_DT0_CLKSRC {
	AG903_SPC_DT0_CLKSRC_PLL1 = 0,		/** PLL1 */
	AG903_SPC_DT0_CLKSRC_DVOCLK,		/** DVOCLK */
};

/** 表示用ドットクロック1 クロックソース選択 */
enum  _AG903_SSC_DT1_CLKSRC {
	AG903_SPC_DT1_CLKSRC_DSP0 = 0,		/** 表示用ドットクロック0 */
	AG903_SPC_DT1_CLKSRC_PLL2,			/** PLL2 */
	AG903_SPC_DT1_CLKSRC_DVO,			/** DVO[13] */
};

/** HD-Audio用ロック クロックソース選択 */
enum  _AG903_SSC_HDA_CLKSRC {
	AG903_SPC_HDA_CLKSRC_XOUT = 0,		/** XOUT/OSC */
	AG903_SPC_HDA_CLKSRC_USBPHY,		/** USB-PHY */
	AG903_SPC_HDA_CLKSRC_PLL3,			/** DVO[13] */
};

/** SSPnクロックソース選択 */
enum  _AG903_SSC_SSP_CLKSRC {
	AG903_SPC_SSP_CLKSRC_MCLK = 0,		/** SSPn_MCLK */
	AG903_SPC_SSP_CLKSRC_ALT,			/** ALT_CLK0 */
	AG903_SPC_SSP_CLKSRC_XOUT,			/** XOUT/OSC */
	AG903_SPC_SSP_CLKSRC_PLL3,			/** PLL3 */
	AG903_SPC_SSP_CLKSRC_PLL0,			/** PLL0 2分周 */
};

/** PLLx FRANGE選択 */
enum AG903_SPC_PLL_FR_ENUM{
     AG903_SPC_PLL_FR_20_40MHZ = 0,		/** 20-40MHz */
     AG903_SPC_PLL_FR_40_75MHZ,			/** 40-75MHz */
     AG903_SPC_PLL_FR_75_150MHZ,		/** 75-150MHz */
     AG903_SPC_PLL_FR_150_300MHZ,		/** 150-300MHz */
};


/** PLLn設定パラメータ */
typedef struct _AG903_SPCPrmPllnParam{
	uint8_t		src;		/** ソースクロック (PLL0設定時無効) */
	uint8_t		ns;			/** 逓倍率 */
	uint8_t		ms;			/** プリスケーラ分周比 */
	uint8_t		div;		/** ポストスケーラ分周比 (分周比=div+1) */
	uint8_t		frange;		/** 動作レンジ (PLL0設定時無効) */
	uint8_t		en;			/** PLL ON/OFF (true=ON) */
	uint8_t		reserve[2];	/** 予約 */
}AG903_SPCPrmPllnParam;

/** PLLA設定パラメータ */
typedef struct _AG903_SPCPrmPllaParam{
	uint8_t		src;		/** ソースクロック */
	uint8_t		ns;			/** 逓倍率 */
	uint8_t		ms;			/** プリスケーラ分周比 */
	uint8_t		fr;			/** ポストスケーラ1分周比 (分周比=div+1) */
	uint8_t		div;		/** ポストスケーラ2分周比 (分周比=div+1) */
	uint8_t		en;			/** PLL ON/OFF (true=ON) */
	uint8_t		cc;			/** PLLAループフィルタ設定 */
	uint8_t		reserve[2];	/** 予約 */
}AG903_SPCPrmPllaParam;

/** SDRAMコントローラタイミング設定パラメータ */
typedef struct _AG903_SPCPrmSdmcMiscParam{
	uint8_t		hclk_sel;	/** HCLK端子出力タイミング */
	uint8_t		rclk_sel;	/** 読み出しデータ取り込みレジスタのクロック位相調整 */
	uint8_t		wclk_sel;	/** 書き込みデータ出力レジスタのクロック位相調整 */
	uint8_t		sref_ack;	/** セルフリフレッシュ制御状態 */
	uint8_t		sref_req;	/** セルフリフレッシュ制御要求 */
	uint8_t		clk_sel;	/** クロック設定 */
	uint8_t		reserve[2];	/** 予約 */
}AG903_SPCPrmSdmcMiscParam;

/** クロックソース選択設定 */
typedef struct _AG903_SPCPrmClkSel{
	uint8_t		cp1;		/** キャプチャ用ドットクロック1 */
	uint8_t		cp0;		/** キャプチャ用ドットクロック2 */
	uint8_t		lvds;		/** LVDSトランスミッタCH0 */
	uint8_t		dt1;		/** 表示用ドットクロック1 */
	uint8_t		dt0;		/** 表示用ドットクロック0 */
	uint8_t		hda;		/** HD-Audio用クロック */
	uint8_t		reserve[2];	/** 予約 */
}AG903_SPCPrmClkSel;

/** SSPクロックソース選択設定 */
typedef struct _AG903_SPCPrmSspClkSel{
	uint8_t		pll3;		/** PLL3入力クロック */
	uint8_t		ssp3;		/** SSP3用SSPクロック */
	uint8_t		ssp2;		/** SSP2用SSPクロック */
	uint8_t		ssp1;		/** SSP1用SSPクロック */
	uint8_t		ssp0;		/** SSP0用SSPクロック */
	uint8_t		reserve[3];	/** 予約 */
}AG903_SPCPrmSspClkSel;

/** SSPクロックソース分周設定 */
typedef struct _AG903_SPCPrmSspClkDiv{
	uint8_t		ssp3;	/** SSP3用SSPクロック */
	uint8_t		ssp2;	/** SSP2用SSPクロック */
	uint8_t		ssp1;	/** SSP1用SSPクロック */
	uint8_t		ssp0;	/** SSP0用SSPクロック */
}AG903_SPCPrmSspClkDiv;

/** ビデオADC設定パラメータ */
typedef struct _AG903_SPCPrmVideoAdcParam{
	uint8_t		clmp_en3;		/** クランプ設定 [CH3] */
	uint8_t		clmp_en2;		/** クランプ設定 [CH2] */
	uint8_t		clmp_en1;		/** クランプ設定 [CH1] */
	uint8_t		clmp_en0;		/** クランプ設定 [CH0] */
	uint8_t		clmp_lv3;		/** クランプレベル [CH3] */
	uint8_t		clmp_lv2;		/** クランプレベル [CH2] */
	uint8_t		clmp_lv1;		/** クランプレベル [CH1] */
	uint8_t		clmp_lv0;		/** クランプレベル [CH0] */
	uint8_t		gain3;			/** 入力ゲイン調整 [CH3] */
	uint8_t		gain2;			/** 入力ゲイン調整 [CH2] */
	uint8_t		gain1;			/** 入力ゲイン調整 [CH1] */
	uint8_t		gain0;			/** 入力ゲイン調整 [CH0] */
	uint8_t		clmp_imp;		/** クランプ入力インピーダンス */
	uint8_t		aaf_ctrl;		/** AAF Control */
	uint8_t		qntzr_bias_up;	/** Quantizer bias UP */
	uint8_t		input_range;	/** Analog input range */
	uint8_t		ref_bias_up;	/** Reference Amps Bias UP */
	uint8_t		reserve[3];		/** 予約 */
}AG903_SPCPrmVideoAdcParam;

/** ビデオADC動作設定パラメータ */
typedef struct _AG903_SPCPrmVideoAdcEnable{
	uint8_t		adc;		/** 動作設定 [ADC全体] */
	uint8_t		ch3;		/** 動作設定 [CH3] */
	uint8_t		ch2;		/** 動作設定 [CH2] */
	uint8_t		ch1;		/** 動作設定 [CH1] */
	uint8_t		ch0;		/** 動作設定 [CH0] */
	uint8_t		reserve[3];	/** 予約 */
}AG903_SPCPrmVideoAdcEnable;

/** USBマクロ設定パラメータ */
typedef struct _AG903_SPCPrmUsbMiscCtrl{
	uint8_t		suspend;	/** サスペンド設定 */
	uint8_t		wakeup;		/** 対向remote wakeup設定 */
	uint8_t		squelch;	/** スケルチ回路基準電位 */
	uint8_t		pll_aliv;	/** クロック出力 [USB48M] */
	uint8_t		xtl_sel;	/** 入力クロック周波数 */
	uint8_t		oscout;		/** クロック出力 [CLKOSCO] */
	uint8_t		reserve[2];	/** 予約 */
}AG903_SPCPrmUsbMiscCtrl;


void AG903_SPCPrmGetBootupStatus(uint8_t* pwr, uint8_t* wdt_rst, uint8_t* hw_rst);
void AG903_SPCPrmClrBootupStatus(uint8_t pwr, uint8_t wdt_rst, uint8_t hw_rst);
void AG903_SPCPrmSetFcsCtrl(uint8_t slf_refresh, uint8_t pll0_rst, uint8_t cpu_msk, uint8_t enable);
void AG903_SPCPrmGetFcsCtrl(uint8_t* slf_refresh, uint8_t* pll0_rst, uint8_t* cpu_msk, uint8_t* enable);
void AG903_SPCPrmSwReset(void);
void AG903_SPCPrmGetFcsIntStatus(uint8_t* status);
void AG903_SPCPrmClrFcsIntStatus(void);
void AG903_SPCPrmSetFcsIntEnable(uint8_t enable);
void AG903_SPCPrmGetFcsIntEnable(uint8_t* enable);
void AG903_SPCPrmSetSoftResetSetup(uint8_t wait, uint8_t active);
void AG903_SPCPrmGetSoftResetSetup(uint8_t* wait, uint8_t* active);
void AG903_SPCPrmSetPll0Ctrl(AG903_SPCPrmPllnParam* param);
void AG903_SPCPrmGetPll0Ctrl(AG903_SPCPrmPllnParam* param, uint8_t* status);
void AG903_SPCPrmSetDdrPhyPll(uint8_t enable);
void AG903_SPCPrmGetDdrPhyPll(uint8_t* enable);
void AG903_SPCPrmSetDdrPhyDll(uint8_t frange, uint8_t enable);
void AG903_SPCPrmGetDdrPhyDll(uint8_t* frange, uint8_t* enable);
void AG903_SPCPrmSetAhbClkCtrl(uint32_t clk_en);
void AG903_SPCPrmGetAhbClkCtrl(uint32_t* clk_en);
void AG903_SPCPrmSetApbClkCtrl(uint32_t clk_en);
void AG903_SPCPrmGetApbClkCtrl(uint32_t* clk_en);
void AG903_SPCPrmSetAxiClkCtrl1(uint32_t clk_en);
void AG903_SPCPrmGetAxiClkCtrl1(uint32_t* clk_en);
void AG903_SPCPrmSetAxiClkCtrl2(uint32_t clk_en);
void AG903_SPCPrmGetAxiClkCtrl2(uint32_t* clk_en);
void AG903_SPCPrmSetPll1Ctrl(AG903_SPCPrmPllnParam* param);
void AG903_SPCPrmGetPll1Ctrl(AG903_SPCPrmPllnParam* param);
void AG903_SPCPrmSetPll2Ctrl(AG903_SPCPrmPllnParam* param);
void AG903_SPCPrmGetPll2Ctrl(AG903_SPCPrmPllnParam* param);
void AG903_SPCPrmSetPll3Ctrl(AG903_SPCPrmPllnParam* param);
void AG903_SPCPrmGetPll3Ctrl(AG903_SPCPrmPllnParam* param);
void AG903_SPCPrmSetPllACtrl(AG903_SPCPrmPllaParam* param);
void AG903_SPCPrmGetPllACtrl(AG903_SPCPrmPllaParam* param);
void AG903_SPCPrmSetSwResetMask(uint8_t reg_no, uint32_t msk);
void AG903_SPCPrmGetSwResetMask(uint8_t reg_no, uint32_t* msk);
void AG903_SPCPrmSetApbSdmcClkCtrl(uint8_t sdmclk, uint32_t pclk);
void AG903_SPCPrmGetApbSdmcClkCtrl(uint8_t* sdmclk, uint32_t* pclk);
void AG903_SPCPrmSetMiscClkCtrl(uint32_t sclk);
void AG903_SPCPrmGetMiscClkCtrl(uint32_t* sclk);
void AG903_SPCPrmGetPinStatus(uint8_t* test, uint8_t* mode);
void AG903_SPCPrmSetSdmcMiscCtrl(AG903_SPCPrmSdmcMiscParam* param);
void AG903_SPCPrmGetSdmcMiscCtrl(AG903_SPCPrmSdmcMiscParam* param);
void AG903_SPCPrmSetDdrMiscCtrl(uint8_t refresh);
void AG903_SPCPrmGetDdrMiscCtrl(uint8_t* init, uint8_t* refresh);
void AG903_SPCPrmSetSpiromMiscCtrl(uint8_t addr_cyc);
void AG903_SPCPrmGetSpiromMiscCtrl(uint8_t* addr_cyc);
void AG903_SPCPrmSetClkSrc(AG903_SPCPrmClkSel* clk_src);
void AG903_SPCPrmGetClkSrc(AG903_SPCPrmClkSel* clk_src);
void AG903_SPCPrmSetSspClkSrc(AG903_SPCPrmSspClkSel* clk_src);
void AG903_SPCPrmGetSspClkSrc(AG903_SPCPrmSspClkSel* clk_src);
void AG903_SPCPrmSetSspClkDiv(AG903_SPCPrmSspClkDiv* clk_div);
void AG903_SPCPrmGetSspClkDiv(AG903_SPCPrmSspClkDiv* clk_div);
void AG903_SPCPrmSetEtherPhy(uint8_t phy);
void AG903_SPCPrmGetEtherPhy(uint8_t* phy);
void AG903_SPCPrmSetCpuMiscCtrl(uint8_t reg_no, uint32_t val);
void AG903_SPCPrmGetCpuMiscCtrl(uint8_t reg_no, uint32_t* val);
void AG903_SPCPrmSetVideoAdcCtrl(AG903_SPCPrmVideoAdcParam* param, AG903_SPCPrmVideoAdcEnable* enable);
void AG903_SPCPrmGetVideoAdcCtrl(AG903_SPCPrmVideoAdcParam* param, AG903_SPCPrmVideoAdcEnable* enable);
void AG903_SPCPrmSetLvdsTx(uint8_t rf_ch0, uint8_t rf_ch1);
void AG903_SPCPrmGetLvdsTx(uint8_t* rf_ch0, uint8_t* rf_ch1);
void AG903_SPCPrmSetUsbMiscCtrl1(uint8_t clk_div, uint8_t clk_sel);
void AG903_SPCPrmGetUsbMiscCtrl1(uint8_t* clk_div, uint8_t* clk_sel, uint8_t* vbus, uint8_t* vprtct);
void AG903_SPCPrmSetUsbMiscCtrl2(AG903_SPCPrmUsbMiscCtrl* param);
void AG903_SPCPrmGetUsbMiscCtrl2(AG903_SPCPrmUsbMiscCtrl* param);
void AG903_SPCPrmSetDdrPhySetup(uint8_t pd_gain, uint8_t afl_gain);
void AG903_SPCPrmGetDdrPhySetup(uint8_t* pd_gain, uint8_t* afl_gain);
void AG903_SPCPrmSetBootSwapCtrl(uint8_t swap);
void AG903_SPCPrmGetBootSwapCtrl(uint8_t* swap);
void AG903_SPCPrmSetIdeClk(uint8_t clk_sel);
void AG903_SPCPrmGetIdeClk(uint8_t* clk_sel);


#ifdef __cplusplus
}
#endif
#endif /* _SPCPRM_H_ */
