text: /*
   *
   * (C) COPYRIGHT 2014-2015 ARM Limited. All rights reserved.
   *
   * This program is free software and is provided to you under the terms of the
   * GNU General Public License version 2 as published by the Free Software
   * Foundation, and any use by you of this program is subject to the terms
   * of such GNU licence.
   *
   * A copy of the licence is included with the program, and can also be obtained
   * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   * Boston, MA  02110-1301, USA.
   *
   */
  
  
  
  /*
   * Backend-specific Power Manager definitions
   */
  
  #ifndef _KBASE_PM_HWACCESS_DEFS_H_
  #define _KBASE_PM_HWACCESS_DEFS_H_
  
  #include "mali_kbase_pm_ca_fixed.h"
  #if !MALI_CUSTOMER_RELEASE
  #include "mali_kbase_pm_ca_random.h"
  #endif
  
  #include "mali_kbase_pm_always_on.h"
  #include "mali_kbase_pm_coarse_demand.h"
  #include "mali_kbase_pm_demand.h"
  #if !MALI_CUSTOMER_RELEASE
  #include "mali_kbase_pm_demand_always_powered.h"
  #include "mali_kbase_pm_fast_start.h"
  #endif
  
  /* Forward definition - see mali_kbase.h */
  struct kbase_device;
  struct kbase_jd_atom;
  
  /**
   * enum kbase_pm_core_type - The types of core in a GPU.
   *
   * These enumerated values are used in calls to
   * - kbase_pm_get_present_cores()
   * - kbase_pm_get_active_cores()
   * - kbase_pm_get_trans_cores()
   * - kbase_pm_get_ready_cores().
   *
   * They specify which type of core should be acted on.  These values are set in
   * a manner that allows core_type_to_reg() function to be simpler and more
   * efficient.
   *
   * @KBASE_PM_CORE_L2: The L2 cache
   * @KBASE_PM_CORE_SHADER: Shader cores
   * @KBASE_PM_CORE_TILER: Tiler cores
   */
  enum kbase_pm_core_type {
  	KBASE_PM_CORE_L2 = L2_PRESENT_LO,
  	KBASE_PM_CORE_SHADER = SHADER_PRESENT_LO,
  	KBASE_PM_CORE_TILER = TILER_PRESENT_LO
  };
  /* MTK DVFS */
  #define MTK_MT6735_GPU_LIMIT_COUNT 2
  
  typedef struct _mtk_gpu_freq_limit_data{
      const int actual_freq_index_count;
      const int virtual_freq_index_count;
      const int *virtual_freq_index;
  }mtk_gpu_freq_limit_data;
  
  extern mtk_gpu_freq_limit_data mt6735_gpu_freq_limit_data[];
  
  /**
   * struct kbasep_pm_metrics_data - Metrics data collected for use by the power
   *                                 management framework.
   *
   *  @time_period_start: time at which busy/idle measurements started
   *  @time_busy: number of ns the GPU was busy executing jobs since the
   *          @time_period_start timestamp.
   *  @time_idle: number of ns since time_period_start the GPU was not executing
   *          jobs since the @time_period_start timestamp.
   *  @prev_busy: busy time in ns of previous time period.
   *           Updated when metrics are reset.
   *  @prev_idle: idle time in ns of previous time period
   *           Updated when metrics are reset.
   *  @gpu_active: true when the GPU is executing jobs. false when
   *           not. Updated when the job scheduler informs us a job in submitted
   *           or removed from a GPU slot.
   *  @busy_cl: number of ns the GPU was busy executing CL jobs. Note that
   *           if two CL jobs were active for 400ns, this value would be updated
   *           with 800.
   *  @busy_gl: number of ns the GPU was busy executing GL jobs. Note that
   *           if two GL jobs were active for 400ns, this value would be updated
   *           with 800.
   *  @active_cl_ctx: number of CL jobs active on the GPU. Array is per-device.
   *  @active_gl_ctx: number of GL jobs active on the GPU. Array is per-slot. As
   *           GL jobs never run on slot 2 this slot is not recorded.
   *  @lock: spinlock protecting the kbasep_pm_metrics_data structure
   *  @timer: timer to regularly make DVFS decisions based on the power
   *           management metrics.
   *  @timer_active: boolean indicating @timer is running
   *  @platform_data: pointer to data controlled by platform specific code
   *  @kbdev: pointer to kbase device for which metrics are collected
   *
   */
  struct kbasep_pm_metrics_data {
  	int vsync_hit;
  	ktime_t time_period_start;
  	u32 time_busy;
  	u32 time_idle;
  	bool gpu_active;
  	u32 busy_cl[2];
  	u32 busy_gl;
  	u32 active_cl_ctx[2];
  	u32 active_gl_ctx[2]; /* GL jobs can only run on 2 of the 3 job slots */
  	spinlock_t lock;
  
  #ifdef CONFIG_MALI_MIDGARD_DVFS
  	struct hrtimer timer;
  	bool timer_active;
  #endif
  
  	void *platform_data;
  	struct kbase_device *kbdev;
  };
  
  enum kbase_pm_dvfs_action {
  	KBASE_PM_DVFS_NOP,	    /**< No change in clock frequency is requested */
  	KBASE_PM_DVFS_CLOCK_UP,	    /**< The clock frequency should be increased if possible */
  	KBASE_PM_DVFS_CLOCK_DOWN,    /**< The clock frequency should be decreased if possible */
  	KBASE_PM_DVFS_NONSENSE       /* [MTK] clear state, no need to do dvfs action */
  };
  
  union kbase_pm_policy_data {
  	struct kbasep_pm_policy_always_on always_on;
  	struct kbasep_pm_policy_coarse_demand coarse_demand;
  	struct kbasep_pm_policy_demand demand;
  #if !MALI_CUSTOMER_RELEASE
  	struct kbasep_pm_policy_demand_always_powered demand_always_powered;
  	struct kbasep_pm_policy_fast_start fast_start;
  #endif
  };
  
  union kbase_pm_ca_policy_data {
  	struct kbasep_pm_ca_policy_fixed fixed;
  #if !MALI_CUSTOMER_RELEASE
  	struct kbasep_pm_ca_policy_random random;
  #endif
  };
  
  /**
   * struct kbase_pm_backend_data - Data stored per device for power management.
   *
   * This structure contains data for the power management framework. There is one
   * instance of this structure per device in the system.
   *
   * @ca_current_policy: The policy that is currently actively controlling core
   *                     availability.
   * @pm_current_policy: The policy that is currently actively controlling the
   *                     power state.
   * @ca_policy_data:    Private data for current CA policy
   * @pm_policy_data:    Private data for current PM policy
   * @ca_in_transition:  Flag indicating when core availability policy is
   *                     transitioning cores. The core availability policy must
   *                     set this when a change in core availability is occurring.
   *                     power_change_lock must be held when accessing this.
   * @reset_done:        Flag when a reset is complete
   * @reset_done_wait:   Wait queue to wait for changes to @reset_done
   * @l2_powered_wait:   Wait queue for whether the l2 cache has been powered as
   *                     requested
   * @l2_powered:        State indicating whether all the l2 caches are powered.
   *                     Non-zero indicates they're *all* powered
   *                     Zero indicates that some (or all) are not powered
   * @gpu_cycle_counter_requests: The reference count of active gpu cycle counter
   *                              users
   * @gpu_cycle_counter_requests_lock: Lock to protect @gpu_cycle_counter_requests
   * @desired_shader_state: A bit mask identifying the shader cores that the
   *                        power policy would like to be on. The current state
   *                        of the cores may be different, but there should be
   *                        transitions in progress that will eventually achieve
   *                        this state (assuming that the policy doesn't change
   *                        its mind in the mean time).
   * @powering_on_shader_state: A bit mask indicating which shader cores are
   *                            currently in a power-on transition
   * @desired_tiler_state: A bit mask identifying the tiler cores that the power
   *                       policy would like to be on. See @desired_shader_state
   * @powering_on_tiler_state: A bit mask indicating which tiler core are
   *                           currently in a power-on transition
   * @powering_on_l2_state: A bit mask indicating which l2-caches are currently
   *                        in a power-on transition
   * @gpu_in_desired_state: This flag is set if the GPU is powered as requested
   *                        by the desired_xxx_state variables
   * @gpu_in_desired_state_wait: Wait queue set when @gpu_in_desired_state != 0
   * @gpu_powered:       Set to true when the GPU is powered and register
   *                     accesses are possible, false otherwise
   * @instr_enabled:     Set to true when instrumentation is enabled,
   *                     false otherwise
   * @cg1_disabled:      Set if the policy wants to keep the second core group
   *                     powered off
   * @driver_ready_for_irqs: Debug state indicating whether sufficient
   *                         initialization of the driver has occurred to handle
   *                         IRQs
   * @gpu_powered_lock:  Spinlock that must be held when writing @gpu_powered or
   *                     accessing @driver_ready_for_irqs
   * @metrics:           Structure to hold metrics for the GPU
   * @gpu_poweroff_pending: number of poweroff timer ticks until the GPU is
   *                        powered off
   * @shader_poweroff_pending_time: number of poweroff timer ticks until shaders
   *                        are powered off
   * @gpu_poweroff_timer: Timer for powering off GPU
   * @gpu_poweroff_wq:   Workqueue to power off GPU on when timer fires
   * @gpu_poweroff_work: Workitem used on @gpu_poweroff_wq
   * @shader_poweroff_pending: Bit mask of shaders to be powered off on next
   *                           timer callback
   * @poweroff_timer_needed: true if the poweroff timer is currently running,
   *                         false otherwise
   * @callback_power_on: Callback when the GPU needs to be turned on. See
   *                     &struct kbase_pm_callback_conf
   * @callback_power_off: Callback when the GPU may be turned off. See
   *                     &struct kbase_pm_callback_conf
   * @callback_power_suspend: Callback when a suspend occurs and the GPU needs to
   *                          be turned off. See &struct kbase_pm_callback_conf
   * @callback_power_resume: Callback when a resume occurs and the GPU needs to
   *                          be turned on. See &struct kbase_pm_callback_conf
   * @callback_power_runtime_on: Callback when the GPU needs to be turned on. See
   *                             &struct kbase_pm_callback_conf
   * @callback_power_runtime_off: Callback when the GPU may be turned off. See
   *                              &struct kbase_pm_callback_conf
   * @callback_cci_snoop_ctrl: Callback when the GPU L2 power may transition.
   *                           If enable is set then snoops should be enabled
   *                           otherwise snoops should be disabled
   *
   * Note:
   * During an IRQ, @ca_current_policy or @pm_current_policy can be NULL when the
   * policy is being changed with kbase_pm_ca_set_policy() or
   * kbase_pm_set_policy(). The change is protected under
   * kbase_device.pm.power_change_lock. Direct access to this
   * from IRQ context must therefore check for NULL. If NULL, then
   * kbase_pm_ca_set_policy() or kbase_pm_set_policy() will re-issue the policy
   * functions that would have been done under IRQ.
   */
  struct kbase_pm_backend_data {
  	const struct kbase_pm_ca_policy *ca_current_policy;
  	const struct kbase_pm_policy *pm_current_policy;
  	union kbase_pm_ca_policy_data ca_policy_data;
  	union kbase_pm_policy_data pm_policy_data;
  	bool ca_in_transition;
  	bool reset_done;
  	wait_queue_head_t reset_done_wait;
  	wait_queue_head_t l2_powered_wait;
  	int l2_powered;
  	int gpu_cycle_counter_requests;
  	spinlock_t gpu_cycle_counter_requests_lock;
  
  	u64 desired_shader_state;
  	u64 powering_on_shader_state;
  	u64 desired_tiler_state;
  	u64 powering_on_tiler_state;
  	u64 powering_on_l2_state;
  
  	bool gpu_in_desired_state;
  	wait_queue_head_t gpu_in_desired_state_wait;
  
  	bool gpu_powered;
  
  	bool instr_enabled;
  
  	bool cg1_disabled;
  
  #ifdef CONFIG_MALI_DEBUG
  	bool driver_ready_for_irqs;
  #endif /* CONFIG_MALI_DEBUG */
  
  	spinlock_t gpu_powered_lock;
  
  
  	struct kbasep_pm_metrics_data metrics;
  
  	int gpu_poweroff_pending;
  	int shader_poweroff_pending_time;
  
  	struct hrtimer gpu_poweroff_timer;
  	struct workqueue_struct *gpu_poweroff_wq;
  	struct work_struct gpu_poweroff_work;
  
  	u64 shader_poweroff_pending;
  
  	bool poweroff_timer_needed;
  
  	int (*callback_power_on)(struct kbase_device *kbdev);
  	void (*callback_power_off)(struct kbase_device *kbdev);
  	void (*callback_power_suspend)(struct kbase_device *kbdev);
  	void (*callback_power_resume)(struct kbase_device *kbdev);
  	int (*callback_power_runtime_on)(struct kbase_device *kbdev);
  	void (*callback_power_runtime_off)(struct kbase_device *kbdev);
  
  };
  
  
  /* List of policy IDs */
  enum kbase_pm_policy_id {
  	KBASE_PM_POLICY_ID_DEMAND = 1,
  	KBASE_PM_POLICY_ID_ALWAYS_ON,
  	KBASE_PM_POLICY_ID_COARSE_DEMAND,
  #if !MALI_CUSTOMER_RELEASE
  	KBASE_PM_POLICY_ID_DEMAND_ALWAYS_POWERED,
  	KBASE_PM_POLICY_ID_FAST_START
  #endif
  };
  
  typedef u32 kbase_pm_policy_flags;
  
  /**
   * struct kbase_pm_policy - Power policy structure.
   *
   * Each power policy exposes a (static) instance of this structure which
   * contains function pointers to the policy's methods.
   *
   * @name:               The name of this policy
   * @init:               Function called when the policy is selected
   * @term:               Function called when the policy is unselected
   * @get_core_mask:      Function called to get the current shader core mask
   * @get_core_active:    Function called to get the current overall GPU power
   *                      state
   * @flags:              Field indicating flags for this policy
   * @id:                 Field indicating an ID for this policy. This is not
   *                      necessarily the same as its index in the list returned
   *                      by kbase_pm_list_policies().
   *                      It is used purely for debugging.
   */
  struct kbase_pm_policy {
  	char *name;
  
  	/**
  	 * Function called when the policy is selected
  	 *
  	 * This should initialize the kbdev->pm.pm_policy_data structure. It
  	 * should not attempt to make any changes to hardware state.
  	 *
  	 * It is undefined what state the cores are in when the function is
  	 * called.
  	 *
  	 * @kbdev: The kbase device structure for the device (must be a
  	 *         valid pointer)
  	 */
  	void (*init)(struct kbase_device *kbdev);
  
  	/**
  	 * Function called when the policy is unselected.
  	 *
  	 * @kbdev: The kbase device structure for the device (must be a
  	 *         valid pointer)
  	 */
  	void (*term)(struct kbase_device *kbdev);
  
  	/**
  	 * Function called to get the current shader core mask
  	 *
  	 * The returned mask should meet or exceed (kbdev->shader_needed_bitmap
  	 * | kbdev->shader_inuse_bitmap).
  	 *
  	 * @kbdev: The kbase device structure for the device (must be a
  	 *         valid pointer)
  	 *
  	 * Return: The mask of shader cores to be powered
  	 */
  	u64 (*get_core_mask)(struct kbase_device *kbdev);
  
  	/**
  	 * Function called to get the current overall GPU power state
  	 *
  	 * This function should consider the state of kbdev->pm.active_count. If
  	 * this count is greater than 0 then there is at least one active
  	 * context on the device and the GPU should be powered. If it is equal
  	 * to 0 then there are no active contexts and the GPU could be powered
  	 * off if desired.
  	 *
  	 * @kbdev: The kbase device structure for the device (must be a
  	 *         valid pointer)
  	 *
  	 * Return: true if the GPU should be powered, false otherwise
  	 */
  	bool (*get_core_active)(struct kbase_device *kbdev);
  
  	kbase_pm_policy_flags flags;
  	enum kbase_pm_policy_id id;
  };
  
  
  enum kbase_pm_ca_policy_id {
  	KBASE_PM_CA_POLICY_ID_FIXED = 1,
  	KBASE_PM_CA_POLICY_ID_RANDOM
  };
  
  typedef u32 kbase_pm_ca_policy_flags;
  
  /**
   * struct kbase_pm_ca_policy - Core availability policy structure.
   *
   * Each core availability policy exposes a (static) instance of this structure
   * which contains function pointers to the policy's methods.
   *
   * @name:               The name of this policy
   * @init:               Function called when the policy is selected
   * @term:               Function called when the policy is unselected
   * @get_core_mask:      Function called to get the current shader core
   *                      availability mask
   * @update_core_status: Function called to update the current core status
   * @flags:              Field indicating flags for this policy
   * @id:                 Field indicating an ID for this policy. This is not
   *                      necessarily the same as its index in the list returned
   *                      by kbase_pm_list_policies().
   *                      It is used purely for debugging.
   */
  struct kbase_pm_ca_policy {
  	char *name;
  
  	/**
  	 * Function called when the policy is selected
  	 *
  	 * This should initialize the kbdev->pm.ca_policy_data structure. It
  	 * should not attempt to make any changes to hardware state.
  	 *
  	 * It is undefined what state the cores are in when the function is
  	 * called.
  	 *
  	 * @kbdev The kbase device structure for the device (must be a
  	 *        valid pointer)
  	 */
  	void (*init)(struct kbase_device *kbdev);
  
  	/**
  	 * Function called when the policy is unselected.
  	 *
  	 * @kbdev The kbase device structure for the device (must be a
  	 *        valid pointer)
  	 */
  	void (*term)(struct kbase_device *kbdev);
  
  	/**
  	 * Function called to get the current shader core availability mask
  	 *
  	 * When a change in core availability is occurring, the policy must set
  	 * kbdev->pm.ca_in_transition to true. This is to indicate that
  	 * reporting changes in power state cannot be optimized out, even if
  	 * kbdev->pm.desired_shader_state remains unchanged. This must be done
  	 * by any functions internal to the Core Availability Policy that change
  	 * the return value of kbase_pm_ca_policy::get_core_mask.
  	 *
  	 * @kbdev The kbase device structure for the device (must be a
  	 *              valid pointer)
  	 *
  	 * Return: The current core availability mask
  	 */
  	u64 (*get_core_mask)(struct kbase_device *kbdev);
  
  	/**
  	 * Function called to update the current core status
  	 *
  	 * If none of the cores in core group 0 are ready or transitioning, then
  	 * the policy must ensure that the next call to get_core_mask does not
  	 * return 0 for all cores in core group 0. It is an error to disable
  	 * core group 0 through the core availability policy.
  	 *
  	 * When a change in core availability has finished, the policy must set
  	 * kbdev->pm.ca_in_transition to false. This is to indicate that
  	 * changes in power state can once again be optimized out when
  	 * kbdev->pm.desired_shader_state is unchanged.
  	 *
  	 * @kbdev:               The kbase device structure for the device
  	 *                       (must be a valid pointer)
  	 * @cores_ready:         The mask of cores currently powered and
  	 *                       ready to run jobs
  	 * @cores_transitioning: The mask of cores currently transitioning
  	 *                       power state
  	 */
  	void (*update_core_status)(struct kbase_device *kbdev, u64 cores_ready,
  						u64 cores_transitioning);
  
  	kbase_pm_ca_policy_flags flags;
  
  	/**
  	 * Field indicating an ID for this policy. This is not necessarily the
  	 * same as its index in the list returned by kbase_pm_list_policies().
  	 * It is used purely for debugging.
  	 */
  	enum kbase_pm_ca_policy_id id;
  };
  
  #endif /* _KBASE_PM_HWACCESS_DEFS_H_ */
  