#ifndef DYN_PM_CTX_H
#define DYN_PM_CTX_H
/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/

/* used to track what was done */
#define STATE_VOLT_PM_ENA		BIT(0)
#define STATE_SS_ENA			BIT(1)
#define STATE_THERMAL_PROTECTION_ENA	BIT(2)

/* volt caps */
#define VOLT_CAPS_VDDC_CTL_ENA			BIT(0)
#define VOLT_CAPS_MVDD_CTL_ENA			BIT(1)
#define VOLT_CAPS_VDDCI_CTL_ENA			BIT(2)
#define VOLT_CAPS_VDDC_PHASE_SHED_CTL_ENA	BIT(3)

/* misc caps */
#define MISC_CAPS_ENG_CLK_SS_ENA		BIT(0)
#define MISC_CAPS_MEM_CLK_SS_ENA		BIT(1)
#define MISC_CAPS_THERMAL_PROTECTION_ENA	BIT(2)
#define MISC_CAPS_VRAM_IS_GDDR5			BIT(3)

#define SPECIAL_MC_REGS_N_MAX 4

struct ctx {
	struct pci_dev *dev;
	
	/* seems related to smc "sp" block */
	u32 bs_p;
	u32 p_bs_p;	
	u32 d_sp; 
	u32 p_sp;
	
	u8 state; /* track what was enabled */

	u8 volt_caps;
	u32 platform_caps; /* from atombios pp */
	u8 misc_caps;

	struct atb_volt_tbl atb_vddc_tbl;
	struct atb_volt_tbl atb_mvddc_tbl;
	struct atb_volt_tbl atb_vddci_tbl;
	struct atb_volt_tbl atb_vddc_phase_shed_tbl;

	struct atb_volt_on_clk_dep_tbl atb_vddc_dep_on_sclk_tbl;
	struct atb_cac_lkge_tbl atb_cac_lkge_tbl;
	struct atb_vddc_phase_shed_limits_tbl atb_vddc_phase_shed_limits_tbl;

	u32 atb_cac_lkge;
	u16 atb_load_line_slope;

	/*
	 * We do not store the atb_boot, since the clks and volts are wrong.
	 * the initial state is a combination of data from the firmware info
	 * tbl and the boot state!
	 */
	struct atb_pp_state atb_emergency;	/* only one level */
	struct atb_pp_state atb_ulv;		/* only one level */
	struct atb_pp_state atb_performance;

	/*--------------------------------------------------------------------*/
	struct atb_mc_reg_tbl atb_mc_reg_tbl;
	u32 atb_mc_regs_valid;

	/* upstream: "no room in bios, then regs added on the fly"... */
	u8 special_mc_regs_n;
	u8 special_mc_regs_valid;
	u32 special_mc_regs_addrs[SPECIAL_MC_REGS_N_MAX];
	u32 special_mc_regs_sets[ATB_MC_REG_SETS_N_MAX][SPECIAL_MC_REGS_N_MAX];
	/*--------------------------------------------------------------------*/
	
	u16 core_ref_clk;
	u16 gpu_aux_clk; /* usually derived from above */
	u16 mem_ref_clk;

	u8 pcie_root_speeds_mask;
	u8 default_pcie_lanes_n;

	u32 cus_n_max;

	u32 atb_tdp_limit;
	u32 atb_near_tdp_limit;

	u16 atb_back_bias_time;
	u16 atb_volt_time;

	u32 atb_sq_ramping_threshold;
};

long ctx_init(struct pci_dev *dev, struct ctx *ctx);
void ctx_free(struct ctx *ctx);
#endif
