text: /*
   * Copyright (c) 2011-2020 yanggq.young@allwinnertech.com
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 as published by
   * the Free Software Foundation.
   */
  #ifndef __AW_PM_H__
  #define __AW_PM_H__
  
  #include "axp_depend.h"
  #include <linux/types.h>
  #include "../../../drivers/soc/allwinner/pm/pm.h"
  
  #define BITMAP(bit) (0x1<<bit)
  
  /**max device number of pmu*/
  #define PMU_MAX_DEVS        2
  
  /**
  *@name PMU command
  *@{
  */
  #define AW_PMU_SET          0x10
  #define AW_PMU_VALID        0x20
  /**
  *@}
  */
  
  /*
  * the wakeup source of main cpu: cpu0
  */
  /* external interrupt, pmu event for ex.    */
  #define CPU0_WAKEUP_MSGBOX      (1<<0)
  /* key event    */
  #define CPU0_WAKEUP_KEY         (1<<1)
  #define CPU0_WAKEUP_EXINT	(1<<2)
  #define CPU0_WAKEUP_IR		(1<<3)
  #define CPU0_WAKEUP_ALARM	(1<<4)
  #define CPU0_WAKEUP_USB		(1<<5)
  #define CPU0_WAKEUP_TIMEOUT	(1<<6)
  #define CPU0_WAKEUP_GPIO	(1<<7)
  
  /* the wakeup source of assistant cpu: cpus */
  #define CPUS_WAKEUP_LOWBATT     (1<<12)
  #define CPUS_WAKEUP_USB         (1<<13)
  #define CPUS_WAKEUP_AC          (1<<14)
  #define CPUS_WAKEUP_ASCEND      (1<<15)
  #define CPUS_WAKEUP_DESCEND     (1<<16)
  #define CPUS_WAKEUP_SHORT_KEY   (1<<17)
  #define CPUS_WAKEUP_LONG_KEY    (1<<18)
  #define CPUS_WAKEUP_IR          (1<<19)
  #define CPUS_WAKEUP_ALM0        (1<<20)
  #define CPUS_WAKEUP_ALM1        (1<<21)
  #define CPUS_WAKEUP_TIMEOUT     (1<<22)
  #define CPUS_WAKEUP_GPIO        (1<<23)
  #define CPUS_WAKEUP_USBMOUSE    (1<<24)
  #define CPUS_WAKEUP_LRADC       (1<<25)
  #define CPUS_WAKEUP_WLAN        (1<<26)
  #define CPUS_WAKEUP_CODEC       (1<<27)
  #define CPUS_WAKEUP_BAT_TEMP    (1<<28)
  #define CPUS_WAKEUP_FULLBATT    (1<<29)
  #define CPUS_WAKEUP_HMIC        (1<<30)
  #define CPUS_WAKEUP_POWER_EXP   (1<<31)
  #define CPUS_WAKEUP_KEY         (CPUS_WAKEUP_SHORT_KEY | CPUS_WAKEUP_LONG_KEY)
  
  /* for format all the wakeup gpio into one word.*/
  #define GPIO_PL_MAX_NUM		    (11)    /* 0-11 */
  #define GPIO_PM_MAX_NUM		    (11)    /* 0-11 */
  #define GPIO_AXP_MAX_NUM	    (7)	    /* 0-7 */
  
  #define WAKEUP_GPIO_PL(num)         (1 << (num))
  #define WAKEUP_GPIO_PM(num)         (1 << (num + 12))
  #define WAKEUP_GPIO_AXP(num)        (1 << (num + 24))
  #define WAKEUP_GPIO_GROUP(group)    (1 << (group - 'A'))
  
  #if defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN8IW8P1) \
  	|| defined(CONFIG_ARCH_SUN50IW1P1) \
  	|| defined(CONFIG_ARCH_SUN50IW2P1) \
  	|| defined(CONFIG_ARCH_SUN8IW10P1) \
  	|| defined(CONFIG_ARCH_SUN8IW11P1)
  #define IO_NUM (2)
  #elif defined(CONFIG_ARCH_SUN9IW1P1)
  #define PLL_NUM (12)
  #define BUS_NUM (15)
  #define IO_NUM (2)
  #else
  #define IO_NUM (2)
  #endif
  
  #if defined(CONFIG_ARCH_SUN9IW1P1)
  typedef struct {
  	int n;
  	int p;
  	int divi; /* input_div */
  	int divo; /* output_div */
  } pll_para_t;
  #elif defined(CONFIG_ARCH_SUN8IW6P1) || \
  	defined(CONFIG_ARCH_SUN8IW8P1) || \
  	defined(CONFIG_ARCH_SUN8IW10P1) || \
  	defined(CONFIG_ARCH_SUN8IW11P1)  || \
  	defined(CONFIG_ARCH_SUN50IW1P1) || \
  	defined(CONFIG_ARCH_SUN50IW2P1)
  typedef struct {
  	unsigned int factor1;
  	unsigned int factor2;
  	unsigned int factor3;
  	unsigned int factor4;
  } pll_para_t;
  #else
  typedef struct {
  	unsigned int n;	/* for a83, pll6, n*/
  	unsigned int k;			/* div1 */
  	unsigned int m;			/* div2 */
  	unsigned int p;
  } pll_para_t;
  #endif
  
  typedef struct {
  	unsigned int src;
  	unsigned int pre_div;
  	unsigned int div_ratio;
  	unsigned int n;
  	unsigned int m;
  } bus_para_t;
  
  /* for bitmap macro definition */
  #define PM_PLL_C0	(0)
  #define PM_PLL_C1	(1)
  #define PM_PLL_AUDIO	(2)
  #define PM_PLL_VIDEO0	(3)
  #define PM_PLL_VE	(4)
  #define PM_PLL_DRAM	(5)
  #define PM_PLL_PERIPH	(6)
  #define PM_PLL_GPU	(7)
  #define PM_PLL_HSIC	(8)
  #define PM_PLL_DE	(9)
  #define PM_PLL_VIDEO1	(10)
  #define PLL_PERIPH1	(11)
  #define PLL_DRAM1	(12)
  #define PLL_MIPI	(13)
  #define PLL_NUM		(14)
  
  #define BUS_C0      (0)
  #define BUS_C1      (1)
  #define BUS_AXI0    (2)
  #define BUS_AXI1    (3)
  #define BUS_AHB1    (4)
  #define BUS_AHB2    (5)
  #define BUS_APB1    (6)
  #define BUS_APB2    (7)
  #define BUS_NUM	    (8)
  
  #define OSC_HOSC_BIT	    (3)
  #define OSC_LOSC_BIT	    (2)
  #define OSC_LDO1_BIT	    (1)
  #define OSC_LDO0_BIT	    (0)
  
  typedef enum {
  	CLK_SRC_NONE = 0x0, /* invalid source clock id */
  
  	CLK_SRC_LOSC,   /* LOSC, 33/50/67:32768Hz, 73:16MHz/512=31250*/
  	CLK_SRC_IOSC,   /* InternalOSC,  33/50/67:700KHZ, 73:16MHz*/
  	CLK_SRC_HOSC,   /* HOSC, 24MHZ clock*/
  	CLK_SRC_AXI,    /* AXI clock*/
  	CLK_SRC_16M,    /* 16M for the backdoor*/
  
  	CLK_SRC_PLL1,   /* PLL1 clock */
  	CLK_SRC_PLL2,   /* PLL2 clock */
  	CLK_SRC_PLL3,   /* PLL3 clock */
  	CLK_SRC_PLL4,   /* PLL4 clock */
  	CLK_SRC_PLL5,   /* PLL5 clock */
  	CLK_SRC_PLL6,   /* PLL6 clock */
  	CLK_SRC_PLL7,   /* PLL7 clock */
  	CLK_SRC_PLL8,   /* PLL8 clock */
  	CLK_SRC_PLL9,   /* PLL9 clock */
  	CLK_SRC_PLL10,  /* PLL10 clock */
  	CLK_SRC_PLL11,  /* PLL10 clock */
  
  	CLK_SRC_CPUS,   /* cpus clock */
  	CLK_SRC_C0,     /* cluster0 clock */
  	CLK_SRC_C1,     /* cluster1 clock */
  	CLK_SRC_AXI0,   /* AXI0 clock */
  	CLK_SRC_AXI1,   /* AXI0 clock */
  	CLK_SRC_AHB0,   /* AHB0 clock */
  	CLK_SRC_AHB1,   /* AHB1 clock */
  	CLK_SRC_AHB2,   /* AHB2 clock */
  	CLK_SRC_APB0,   /* APB0 clock */
  	CLK_SRC_APB1,   /* APB1 clock */
  	CLK_SRC_APB2,   /* APB2 clock */
  } clk_src_e;
  
  typedef struct {
  	/*
  	 * for state bitmap:
  	 * bitx = 1: keep state.
  	 * bitx = 0: mean close corresponding power src.
     */
  	unsigned int state;
  	/* bitx=1, the corresponding state is effect,
  	 * otherwise, the corresponding power is in charge in device driver.
  	 *	sys_mask&state		: bitx=1,
  	 *			mean the power is on,
  	 *			for the "on" state power,
  	 *			u need care about the voltage.;
  	 *  ((~sys_mask)|state)	: bitx=0, mean the power is close;
  	 *
  	 * pwr_dm_state bitmap
  	 * actually: we care about the pwr_dm voltage,
  	 *   such as: we want to keep the vdd_sys at 1.0v at standby period.
  	 * we actually do not care how to do it.
  	 * it can be sure that cpus can do it with the pmu's help.
     */
  	unsigned int sys_mask;
  	unsigned int volt[VCC_MAX_INDEX]; /* unsigned short is 16bit width. */
  } pwr_dm_state_t;
  
  /* selfresh_flag must be compatible with vdd_sys pwr state.*/
  typedef struct pm_dram_para {
  	unsigned int selfresh_flag;
  	unsigned int crc_en;
  	unsigned int crc_start;
  	unsigned int crc_len;
  } pm_dram_para_t;
  
  typedef struct cpus_clk_para {
      unsigned int cpus_id;
  } cpus_para_t;
  
  typedef struct io_state_config {
      unsigned int paddr;
      unsigned int value_mask; /* specify the effect bit.*/
      unsigned int value;
  } io_state_config_t;
  
  typedef struct soc_io_para {
      /*
       *	hold: mean before power off vdd_sys, whether hold gpio pad or not.
       *	this flag only effect: when vdd_sys is powered_off;
       *	this flag only affect hold&unhold operation.
       *	the recommended hold sequence is as follow:
       *	backup_io_cfg -> cfg_io(enter_low_power_mode)
       *  -> hold -> assert vdd_sys_reset -> poweroff vdd_sys.
       *  the recommended unhold sequence is as follow:
       *  poweron vdd_sys -> de_assert vdd_sys -> restore_io_cfg -> unhold.
       * */
      unsigned int hold_flag;
  
  
      /*
       * note: only specific bit mark by value_mask is effect.
       * IO_NUM: only uart and jtag needed care.
       * */
      io_state_config_t io_state[IO_NUM];
  } soc_io_para_t;
  
  typedef struct cpux_clk_para {
      /*
       * Hosc: losc: ldo1: ldo0
       * the osc bit map is as follow:
       * bit3: bit2: bit1:bit0
       * Hosc: losc: ldo1: ldo0
       */
      int osc_en;
  
      /*
       * for a83, pll bitmap as follow:
       *
       * pll11(video1):	pll10(de):  pll9(hsic)
       * bit7:	    bit6:	bit5:	    bit4:
       * pll8(gpu): pll6(periph): pll5(dram): pll4(ve):
       * bit3:		bit2:		bit1:	    bit0
       * pll3(video):	pll2(audio):	c1cpux:	    c0cpux
       *
       *
       *
       * */
  
      /* for disable bitmap:
       * bitx = 0: close
       * bitx = 1: do not care.
       */
      int init_pll_dis;
  
      /* for enable bitmap:
       * bitx = 0: do not care.
       * bitx = 1: open
       */
      int exit_pll_en;
  
      /*
       * set corresponding bit if it's pll factors need to be set some value.
       */
      int pll_change;
  
      /*
       * fill in the enabled pll freq factor sequently.
       * unit is khz pll6: 0x90041811
       * factor n/m/k/p already do the pretreatment of the minus one
       */
      pll_para_t pll_factor[PLL_NUM];
  
      /*
       * **********A31************
       * at a31 platform, the clk relationship is as follow:
       * pll1->cpu -> axi
       *	     -> atb/apb
       * ahb1 -> apb1
       * apb2
       * so, at a31, only cpu:ahb1:apb2 need be cared.
       *
       * *********A80************
       * at a83 platform, the clk relationship is as follow:
       * c1 -> axi1
       * c0 -> axi0
       * gtbus
       * ahb0
       * ahb1
       * ahb2
       * apb0
       * apb1
       * so, at a80, c1:c0:gtbus:ahb0:ahb1:ahb2:apb0:apb1 need be cared.
       *
       * *********A83************
       * at a83 platform, the clk relationship is as follow:
       * c1 -> axi1
       * c0 -> axi0
       * ahb1 -> apb1
       * apb2
       * ahb2
       * so, at a83, only c1:c0:ahb1:apb2:ahb2 need be cared.
       *
       * normally, only clk src need be cared.
       * the bus bitmap as follow:
       * for a83, bus_en:
       * bit4: bit3: bit2: bit1: bit0
       * ahb2: apb2: ahb1: c1:   c0
       *
       * for a31, bus_en:
       * bit2:bit1:bit0
       * cpu:ahb1:apb2
       *
       * for a80, bus_en:
       * bit7: bit6:  bit5:  bit4: bit3: bit2: bit1: bit0
       * c1:   c0:    gtbus: ahb0: ahb1: ahb2: apb0: apb1
       */
      int bus_change;
  
      /*
       * bus_src: ahb1, apb2 src;
       * option:  pllx:axi:hosc:losc
       */
      bus_para_t bus_factor[BUS_NUM];
  
  } cpux_clk_para_t;
  
  typedef struct soc_pwr_dep {
      /*
       * id of scene_lock
       */
      unsigned int id;
  
      pwr_dm_state_t soc_pwr_dm_state;
      pm_dram_para_t soc_dram_state;
      soc_io_para_t soc_io_state;
      cpux_clk_para_t cpux_clk_state;
  
  } soc_pwr_dep_t;
  
  typedef struct extended_standby {
  	/*
  	 * id of extended standby
  	 */
  	unsigned int id;
  	unsigned int pmu_id;
  	/* for: 808 || 809+806 || 803 || 813
  	 * support 4 pmu: each pmu_id range is: 0-255;
  	 * pmu_id <--> pmu_name have directly mapping,
  	 * u can get the pmu_name from sys_config.fex files.;
  	 * bitmap as follow:
  	 * pmu0: 0-7 bit; pmu1: 8-15 bit; pmu2: 16-23 bit; pmu3: 24-31 bit
  	 */
  
  
  	unsigned int soc_id;
  	/* a33, a80, a83,...,
  	 * for compatible reason, different soc,
  	 * each bit have different meaning.
  	 */
  
  	pwr_dm_state_t soc_pwr_dm_state;
  	pm_dram_para_t soc_dram_state;
  	soc_io_para_t soc_io_state;
  	cpux_clk_para_t cpux_clk_state;
  } extended_standby_t;
  
  
  #define CPUS_ENABLE_POWER_EXP   (1<<31)
  #define CPUS_WAKEUP_POWER_STA   (1<<1)
  #define CPUS_WAKEUP_POWER_CSM   (1<<0)
  typedef struct sst_power_info_para {
  	/*
  	 * define for sun9iw1p1
  	 * power_reg bit0 ~ 7 AXP_main REG10, bit 8~15 AXP_main REG12
  	 * power_reg bit16~23 AXP_slav REG10, bit24~31 AXP_slav REG11
  	 *
  	 * AXP_main REG10: 0-off, 1-on
  	 * bit7   bit6   bit5   bit4   bit3   bit2   bit1   bit0
  	 * aldo2  aldo1  dcdc5  dcdc4  dcdc3  dcdc2  dcdc1  dc5ldo
  	 *
  	 * REG12:
  	 * bit0~5:0-off, 1-on,
  	 * bit6~7: 0-on, 1-off, dc1sw's power come from dcdc1
  	 * bit7   bit6   bit5   bit4   bit3   bit2   bit1   bit0
  	 * dc1sw  swout  aldo3  dldo2  dldo1  eldo3  eldo2  eldo1
  	 *
  	 * AXP_slave REG10: 0-off, 1-on. dcdc b&c is not used, ignore them.
  	 * bit7   bit6   bit5   bit4   bit3   bit2   bit1   bit0
  	 * aldo3  aldo2  aldo1  dcdce  dcdcd  dcdcc  dcdcb  dcdca
  	 *
  	 * AXP_slave REG11: 0-off, 1-on
  	 * bit7   bit6   bit5   bit4   bit3   bit2   bit1   bit0
  	 * swout  cldo3  cldo2  cldo1  bldo4  bldo3  bldo2  bldo1
  	 */
  	/*
  	 * define for sun8iw5p1
  	 * power_reg0 ~ 7 AXP_main REG10,  8~15 AXP_main REG12
  	 * power_reg16~32 null
  	 *
  	 * AXP_main REG10: 0-off, 1-on
  	 * bit7   bit6	 bit5   bit4   bit3   bit2   bit1   bit0
  	 * aldo2  aldo1  dcdc5  dcdc4  dcdc3  dcdc2  dcdc1  dc5ldo
  	 *
  	 * REG12: 0-off, 1-on
  	 * bit7   bit6   bit5   bit4   bit3   bit2   bit1   bit0
  	 * dc1sw  dldo4  dldo3  dldo2  dldo1  eldo3  eldo2  eldo1
  	 *
  	 * REG13: bit16 aldo3, 0-off, 1-on
  	 * REG90: bit17 gpio0/ldo, 0-off, 1-on
  	 * REG92: bit18 gpio1/ldo, 0-off, 1-on
  	 */
  	/* enable bit */
  	/* registers of power state should be */
  	/* the max power of system, signed, power mabe negative when charge */
  	unsigned int enable;
  	unsigned int power_reg;
  	signed int system_power;
  } sst_power_info_para_t;
  
  /* cpus wakeup event types */
  /* cpux resume code src */
  /* cpux resume code length */
  /* cpux resume entry */
  /* wakeup after timeout seconds */
  typedef	struct super_standby_para {
  	unsigned int event;
  	unsigned int resume_code_src;
  	unsigned int resume_code_length;
  	unsigned int resume_entry;
  	unsigned int timeout;
  	unsigned int gpio_enable_bitmap;
  	unsigned int cpux_gpiog_bitmap;
  	unsigned int pextended_standby;
  } super_standby_para_t;
  
  /* cpus wakeup event types */
  /* wakeup after timeout seconds */
  typedef	struct normal_standby_para {
  	unsigned int event;
  	unsigned int timeout;
  	unsigned int gpio_enable_bitmap;
  	unsigned int cpux_gpiog_bitmap;
  	unsigned int pextended_standby;
  } normal_standby_para_t;
  
  
  /* define cpus wakeup src */
  #define CPUS_MEM_WAKEUP              (CPUS_WAKEUP_LOWBATT |\
  					CPUS_WAKEUP_USB |\
  					CPUS_WAKEUP_AC |\
  					CPUS_WAKEUP_DESCEND |\
  					CPUS_WAKEUP_ASCEND |\
  					CPUS_WAKEUP_ALM0 |\
  					CPUS_WAKEUP_GPIO |\
  					CPUS_WAKEUP_IR)
  
  #define CPUS_BOOTFAST_WAKEUP         (CPUS_WAKEUP_LOWBATT |\
  					CPUS_WAKEUP_LONG_KEY |\
  					CPUS_WAKEUP_ALM0 |\
  					CPUS_WAKEUP_USB |\
  					CPUS_WAKEUP_AC)
  
  /*used in normal standby*/
  #define CPU0_MEM_WAKEUP              (CPU0_WAKEUP_MSGBOX |\
  					CPU0_WAKEUP_EXINT |\
  					CPU0_WAKEUP_ALARM)
  #define CPU0_BOOTFAST_WAKEUP         (CPU0_WAKEUP_MSGBOX)
  
  
  /**
  *@brief struct of pmu device arg
  */
  struct aw_pmu_arg {
      unsigned int  twi_port;		/**<twi port for pmu chip   */
      unsigned char dev_addr;		/**<address of pmu device   */
      unsigned int soc_power_tree[VCC_MAX_INDEX];  /* power tree struct point */
  };
  
  
  /**
   *@brief struct of standby
   *event: <event type for system wakeup
   *axp_event: <axp event type for system wakeup
   *debug_mask: debug mask
   *timeout: <time to power off system from now, based on second
   */
  struct aw_standby_para {
  	unsigned int event;
  	unsigned int axp_event;
  	unsigned int debug_mask;
  	signed int   timeout;
  	unsigned int gpio_enable_bitmap;
  	unsigned int cpux_gpiog_bitmap;
  	unsigned int pextended_standby;
  };
  
  /**
  *@brief struct of power management info
  */
  struct aw_pm_info {
      /* standby parameter            */
      struct aw_standby_para		standby_para;
      /**<args used by main function  */
      struct aw_pmu_arg			pmu_arg;
  #if defined(CONFIG_ARCH_SUN8IW10P1) || defined(CONFIG_ARCH_SUN8IW11P1)
      dram_para_t                         dram_para;
      unsigned long                       resume_addr;
  #endif
  };
  
  typedef struct sst_dram_info {
  	unsigned int dram_crc_enable;
  	unsigned int dram_crc_src;
  	unsigned int dram_crc_len;
  	unsigned int dram_crc_error;
  	unsigned int dram_crc_total_count;
  	unsigned int dram_crc_error_count;
  } sst_dram_info_t;
  
  typedef struct standby_info_para {
  	sst_power_info_para_t power_state; /* size 3W=12B */
  	sst_dram_info_t dram_state; /*size 6W=24B */
  } standby_info_para_t;
  
  typedef enum event_cpu_id {
      CPUS_ID,
      CPU0_ID,
  } event_cpu_id_e;
  
  typedef struct standby_space_cfg {
      struct device_node *np;
      phys_addr_t standby_mem_base;
      phys_addr_t extended_standby_mem_base;
      phys_addr_t mem_offset;
      size_t mem_size;
  } standby_space_cfg_t;
  
  extern unsigned int parse_wakeup_gpio_group_map(char *s, unsigned int size,
  					unsigned int gpio_map);
  
  extern unsigned int parse_wakeup_event(char *s, unsigned int size,
  				unsigned int event);
  
  extern unsigned int parse_wakeup_gpio_map(char *s, unsigned int size,
  				unsigned int gpio_map);
  
  extern unsigned int show_gpio_config(char *s, unsigned int size);
  
  #endif /* __AW_PM_H__ */
  