]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/gpu/drm/radeon/radeon.h
drm/radeon/dpm: add checks against vblank time
[linux-imx.git] / drivers / gpu / drm / radeon / radeon.h
index aeec346c8d3160007e1451b893025567ab065261..9b7025d02cd0cf42504d08fca87d6daf640c876d 100644 (file)
@@ -96,6 +96,7 @@ extern int radeon_pcie_gen2;
 extern int radeon_msi;
 extern int radeon_lockup_timeout;
 extern int radeon_fastfb;
+extern int radeon_dpm;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -199,6 +200,7 @@ struct radeon_clock {
        uint32_t default_mclk;
        uint32_t default_sclk;
        uint32_t default_dispclk;
+       uint32_t current_dispclk;
        uint32_t dp_extclk;
        uint32_t max_pixel_clock;
 };
@@ -218,6 +220,10 @@ int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
                                   u32 clock,
                                   bool strobe_mode,
                                   struct atom_clock_dividers *dividers);
+int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,
+                                       u32 clock,
+                                       bool strobe_mode,
+                                       struct atom_mpll_param *mpll_param);
 void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type);
 int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,
                                          u16 voltage_level, u8 voltage_type,
@@ -226,6 +232,11 @@ void radeon_atom_set_engine_dram_timings(struct radeon_device *rdev,
                                         u32 eng_clock, u32 mem_clock);
 int radeon_atom_get_voltage_step(struct radeon_device *rdev,
                                 u8 voltage_type, u16 *voltage_step);
+int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
+                            u16 voltage_id, u16 *voltage);
+int radeon_atom_get_leakage_vddc_based_on_leakage_idx(struct radeon_device *rdev,
+                                                     u16 *voltage,
+                                                     u16 leakage_idx);
 int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,
                                      u8 voltage_type,
                                      u16 nominal_voltage,
@@ -235,9 +246,10 @@ int radeon_atom_get_min_voltage(struct radeon_device *rdev,
 int radeon_atom_get_max_voltage(struct radeon_device *rdev,
                                u8 voltage_type, u16 *max_voltage);
 int radeon_atom_get_voltage_table(struct radeon_device *rdev,
-                                 u8 voltage_type,
+                                 u8 voltage_type, u8 voltage_mode,
                                  struct atom_voltage_table *voltage_table);
-bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev, u8 voltage_type);
+bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
+                                u8 voltage_type, u8 voltage_mode);
 void radeon_atom_update_memory_dll(struct radeon_device *rdev,
                                   u32 mem_clock);
 void radeon_atom_set_ac_timing(struct radeon_device *rdev,
@@ -680,6 +692,7 @@ struct radeon_irq {
        bool                            hpd[RADEON_MAX_HPD_PINS];
        bool                            afmt[RADEON_MAX_AFMT_BLOCKS];
        union radeon_irq_stat_regs      stat_regs;
+       bool                            dpm_thermal;
 };
 
 int radeon_irq_kms_init(struct radeon_device *rdev);
@@ -966,6 +979,7 @@ struct radeon_cs_parser {
        u32                     cs_flags;
        u32                     ring;
        s32                     priority;
+       struct ww_acquire_ctx   ticket;
 };
 
 extern int radeon_cs_finish_pages(struct radeon_cs_parser *p);
@@ -1043,6 +1057,7 @@ struct radeon_wb {
 enum radeon_pm_method {
        PM_METHOD_PROFILE,
        PM_METHOD_DYNPM,
+       PM_METHOD_DPM,
 };
 
 enum radeon_dynpm_state {
@@ -1068,11 +1083,24 @@ enum radeon_voltage_type {
 };
 
 enum radeon_pm_state_type {
+       /* not used for dpm */
        POWER_STATE_TYPE_DEFAULT,
        POWER_STATE_TYPE_POWERSAVE,
+       /* user selectable states */
        POWER_STATE_TYPE_BATTERY,
        POWER_STATE_TYPE_BALANCED,
        POWER_STATE_TYPE_PERFORMANCE,
+       /* internal states */
+       POWER_STATE_TYPE_INTERNAL_UVD,
+       POWER_STATE_TYPE_INTERNAL_UVD_SD,
+       POWER_STATE_TYPE_INTERNAL_UVD_HD,
+       POWER_STATE_TYPE_INTERNAL_UVD_HD2,
+       POWER_STATE_TYPE_INTERNAL_UVD_MVC,
+       POWER_STATE_TYPE_INTERNAL_BOOT,
+       POWER_STATE_TYPE_INTERNAL_THERMAL,
+       POWER_STATE_TYPE_INTERNAL_ACPI,
+       POWER_STATE_TYPE_INTERNAL_ULV,
+       POWER_STATE_TYPE_INTERNAL_3DPERF,
 };
 
 enum radeon_pm_profile_type {
@@ -1101,12 +1129,16 @@ struct radeon_pm_profile {
 
 enum radeon_int_thermal_type {
        THERMAL_TYPE_NONE,
+       THERMAL_TYPE_EXTERNAL,
+       THERMAL_TYPE_EXTERNAL_GPIO,
        THERMAL_TYPE_RV6XX,
        THERMAL_TYPE_RV770,
+       THERMAL_TYPE_ADT7473_WITH_INTERNAL,
        THERMAL_TYPE_EVERGREEN,
        THERMAL_TYPE_SUMO,
        THERMAL_TYPE_NI,
        THERMAL_TYPE_SI,
+       THERMAL_TYPE_EMC2103_WITH_INTERNAL,
        THERMAL_TYPE_CI,
 };
 
@@ -1161,6 +1193,201 @@ struct radeon_power_state {
  */
 #define RADEON_MODE_OVERCLOCK_MARGIN 500 /* 5 MHz */
 
+enum radeon_dpm_auto_throttle_src {
+       RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL,
+       RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL
+};
+
+enum radeon_dpm_event_src {
+       RADEON_DPM_EVENT_SRC_ANALOG = 0,
+       RADEON_DPM_EVENT_SRC_EXTERNAL = 1,
+       RADEON_DPM_EVENT_SRC_DIGITAL = 2,
+       RADEON_DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,
+       RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
+};
+
+struct radeon_ps {
+       u32 caps; /* vbios flags */
+       u32 class; /* vbios flags */
+       u32 class2; /* vbios flags */
+       /* UVD clocks */
+       u32 vclk;
+       u32 dclk;
+       /* asic priv */
+       void *ps_priv;
+};
+
+struct radeon_dpm_thermal {
+       /* thermal interrupt work */
+       struct work_struct work;
+       /* low temperature threshold */
+       int                min_temp;
+       /* high temperature threshold */
+       int                max_temp;
+       /* was interrupt low to high or high to low */
+       bool               high_to_low;
+};
+
+enum radeon_clk_action
+{
+       RADEON_SCLK_UP = 1,
+       RADEON_SCLK_DOWN
+};
+
+struct radeon_blacklist_clocks
+{
+       u32 sclk;
+       u32 mclk;
+       enum radeon_clk_action action;
+};
+
+struct radeon_clock_and_voltage_limits {
+       u32 sclk;
+       u32 mclk;
+       u32 vddc;
+       u32 vddci;
+};
+
+struct radeon_clock_array {
+       u32 count;
+       u32 *values;
+};
+
+struct radeon_clock_voltage_dependency_entry {
+       u32 clk;
+       u16 v;
+};
+
+struct radeon_clock_voltage_dependency_table {
+       u32 count;
+       struct radeon_clock_voltage_dependency_entry *entries;
+};
+
+struct radeon_cac_leakage_entry {
+       u16 vddc;
+       u32 leakage;
+};
+
+struct radeon_cac_leakage_table {
+       u32 count;
+       struct radeon_cac_leakage_entry *entries;
+};
+
+struct radeon_phase_shedding_limits_entry {
+       u16 voltage;
+       u32 sclk;
+       u32 mclk;
+};
+
+struct radeon_phase_shedding_limits_table {
+       u32 count;
+       struct radeon_phase_shedding_limits_entry *entries;
+};
+
+struct radeon_ppm_table {
+       u8 ppm_design;
+       u16 cpu_core_number;
+       u32 platform_tdp;
+       u32 small_ac_platform_tdp;
+       u32 platform_tdc;
+       u32 small_ac_platform_tdc;
+       u32 apu_tdp;
+       u32 dgpu_tdp;
+       u32 dgpu_ulv_power;
+       u32 tj_max;
+};
+
+struct radeon_dpm_dynamic_state {
+       struct radeon_clock_voltage_dependency_table vddc_dependency_on_sclk;
+       struct radeon_clock_voltage_dependency_table vddci_dependency_on_mclk;
+       struct radeon_clock_voltage_dependency_table vddc_dependency_on_mclk;
+       struct radeon_clock_voltage_dependency_table vddc_dependency_on_dispclk;
+       struct radeon_clock_array valid_sclk_values;
+       struct radeon_clock_array valid_mclk_values;
+       struct radeon_clock_and_voltage_limits max_clock_voltage_on_dc;
+       struct radeon_clock_and_voltage_limits max_clock_voltage_on_ac;
+       u32 mclk_sclk_ratio;
+       u32 sclk_mclk_delta;
+       u16 vddc_vddci_delta;
+       u16 min_vddc_for_pcie_gen2;
+       struct radeon_cac_leakage_table cac_leakage_table;
+       struct radeon_phase_shedding_limits_table phase_shedding_limits_table;
+       struct radeon_ppm_table *ppm_table;
+};
+
+struct radeon_dpm_fan {
+       u16 t_min;
+       u16 t_med;
+       u16 t_high;
+       u16 pwm_min;
+       u16 pwm_med;
+       u16 pwm_high;
+       u8 t_hyst;
+       u32 cycle_delay;
+       u16 t_max;
+       bool ucode_fan_control;
+};
+
+enum radeon_pcie_gen {
+       RADEON_PCIE_GEN1 = 0,
+       RADEON_PCIE_GEN2 = 1,
+       RADEON_PCIE_GEN3 = 2,
+       RADEON_PCIE_GEN_INVALID = 0xffff
+};
+
+enum radeon_dpm_forced_level {
+       RADEON_DPM_FORCED_LEVEL_AUTO = 0,
+       RADEON_DPM_FORCED_LEVEL_LOW = 1,
+       RADEON_DPM_FORCED_LEVEL_HIGH = 2,
+};
+
+struct radeon_dpm {
+       struct radeon_ps        *ps;
+       /* number of valid power states */
+       int                     num_ps;
+       /* current power state that is active */
+       struct radeon_ps        *current_ps;
+       /* requested power state */
+       struct radeon_ps        *requested_ps;
+       /* boot up power state */
+       struct radeon_ps        *boot_ps;
+       /* default uvd power state */
+       struct radeon_ps        *uvd_ps;
+       enum radeon_pm_state_type state;
+       enum radeon_pm_state_type user_state;
+       u32                     platform_caps;
+       u32                     voltage_response_time;
+       u32                     backbias_response_time;
+       void                    *priv;
+       u32                     new_active_crtcs;
+       int                     new_active_crtc_count;
+       u32                     current_active_crtcs;
+       int                     current_active_crtc_count;
+       struct radeon_dpm_dynamic_state dyn_state;
+       struct radeon_dpm_fan fan;
+       u32 tdp_limit;
+       u32 near_tdp_limit;
+       u32 near_tdp_limit_adjusted;
+       u32 sq_ramping_threshold;
+       u32 cac_leakage;
+       u16 tdp_od_limit;
+       u32 tdp_adjustment;
+       u16 load_line_slope;
+       bool power_control;
+       bool ac_power;
+       /* special states active */
+       bool                    thermal_active;
+       bool                    uvd_active;
+       /* thermal handling */
+       struct radeon_dpm_thermal thermal;
+       /* forced levels */
+       enum radeon_dpm_forced_level forced_level;
+};
+
+void radeon_dpm_enable_power_state(struct radeon_device *rdev,
+                                   enum radeon_pm_state_type dpm_state);
+
+
 struct radeon_pm {
        struct mutex            mutex;
        /* write locked while reprogramming mclk */
@@ -1214,6 +1441,9 @@ struct radeon_pm {
        /* internal thermal controller on rv6xx+ */
        enum radeon_int_thermal_type int_thermal_type;
        struct device           *int_hwmon_dev;
+       /* dpm */
+       bool                    dpm_enabled;
+       struct radeon_dpm       dpm;
 };
 
 int radeon_pm_get_type_index(struct radeon_device *rdev,
@@ -1415,7 +1645,7 @@ struct radeon_asic {
                bool (*sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
                void (*set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
        } hpd;
-       /* power management */
+       /* static power management */
        struct {
                void (*misc)(struct radeon_device *rdev);
                void (*prepare)(struct radeon_device *rdev);
@@ -1432,6 +1662,24 @@ struct radeon_asic {
                int (*set_uvd_clocks)(struct radeon_device *rdev, u32 vclk, u32 dclk);
                int (*get_temperature)(struct radeon_device *rdev);
        } pm;
+       /* dynamic power management */
+       struct {
+               int (*init)(struct radeon_device *rdev);
+               void (*setup_asic)(struct radeon_device *rdev);
+               int (*enable)(struct radeon_device *rdev);
+               void (*disable)(struct radeon_device *rdev);
+               int (*pre_set_power_state)(struct radeon_device *rdev);
+               int (*set_power_state)(struct radeon_device *rdev);
+               void (*post_set_power_state)(struct radeon_device *rdev);
+               void (*display_configuration_changed)(struct radeon_device *rdev);
+               void (*fini)(struct radeon_device *rdev);
+               u32 (*get_sclk)(struct radeon_device *rdev, bool low);
+               u32 (*get_mclk)(struct radeon_device *rdev, bool low);
+               void (*print_power_state)(struct radeon_device *rdev, struct radeon_ps *ps);
+               void (*debugfs_print_current_performance_level)(struct radeon_device *rdev, struct seq_file *m);
+               int (*force_performance_level)(struct radeon_device *rdev, enum radeon_dpm_forced_level level);
+               bool (*vblank_too_short)(struct radeon_device *rdev);
+       } dpm;
        /* pageflipping */
        struct {
                void (*pre_page_flip)(struct radeon_device *rdev, int crtc);
@@ -1809,6 +2057,7 @@ struct radeon_device {
        const struct firmware *uvd_fw;  /* UVD firmware */
        const struct firmware *mec_fw;  /* CIK MEC firmware */
        const struct firmware *sdma_fw; /* CIK SDMA firmware */
+       const struct firmware *smc_fw;  /* SMC firmware */
        struct r600_blit r600_blit;
        struct r600_vram_scratch vram_scratch;
        int msi_enabled; /* msi enabled */
@@ -1890,6 +2139,12 @@ void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v);
 #define WREG32_RCU(reg, v) r600_rcu_wreg(rdev, (reg), (v))
 #define RREG32_CG(reg) eg_cg_rreg(rdev, (reg))
 #define WREG32_CG(reg, v) eg_cg_wreg(rdev, (reg), (v))
+#define RREG32_PIF_PHY0(reg) eg_pif_phy0_rreg(rdev, (reg))
+#define WREG32_PIF_PHY0(reg, v) eg_pif_phy0_wreg(rdev, (reg), (v))
+#define RREG32_PIF_PHY1(reg) eg_pif_phy1_rreg(rdev, (reg))
+#define WREG32_PIF_PHY1(reg, v) eg_pif_phy1_wreg(rdev, (reg), (v))
+#define RREG32_UVD_CTX(reg) r600_uvd_ctx_rreg(rdev, (reg))
+#define WREG32_UVD_CTX(reg, v) r600_uvd_ctx_wreg(rdev, (reg), (v))
 #define WREG32_P(reg, val, mask)                               \
        do {                                                    \
                uint32_t tmp_ = RREG32(reg);                    \
@@ -1976,6 +2231,51 @@ static inline void eg_cg_wreg(struct radeon_device *rdev, u32 reg, u32 v)
        WREG32(EVERGREEN_CG_IND_DATA, (v));
 }
 
+static inline u32 eg_pif_phy0_rreg(struct radeon_device *rdev, u32 reg)
+{
+       u32 r;
+
+       WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
+       r = RREG32(EVERGREEN_PIF_PHY0_DATA);
+       return r;
+}
+
+static inline void eg_pif_phy0_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+       WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
+       WREG32(EVERGREEN_PIF_PHY0_DATA, (v));
+}
+
+static inline u32 eg_pif_phy1_rreg(struct radeon_device *rdev, u32 reg)
+{
+       u32 r;
+
+       WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
+       r = RREG32(EVERGREEN_PIF_PHY1_DATA);
+       return r;
+}
+
+static inline void eg_pif_phy1_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+       WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
+       WREG32(EVERGREEN_PIF_PHY1_DATA, (v));
+}
+
+static inline u32 r600_uvd_ctx_rreg(struct radeon_device *rdev, u32 reg)
+{
+       u32 r;
+
+       WREG32(R600_UVD_CTX_INDEX, ((reg) & 0x1ff));
+       r = RREG32(R600_UVD_CTX_DATA);
+       return r;
+}
+
+static inline void r600_uvd_ctx_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+       WREG32(R600_UVD_CTX_INDEX, ((reg) & 0x1ff));
+       WREG32(R600_UVD_CTX_DATA, (v));
+}
+
 void r100_pll_errata_after_index(struct radeon_device *rdev);
 
 
@@ -2026,6 +2326,15 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
 #define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN))
 #define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE))
 
+#define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \
+                             (rdev->ddev->pdev->device == 0x6850) || \
+                             (rdev->ddev->pdev->device == 0x6858) || \
+                             (rdev->ddev->pdev->device == 0x6859) || \
+                             (rdev->ddev->pdev->device == 0x6840) || \
+                             (rdev->ddev->pdev->device == 0x6841) || \
+                             (rdev->ddev->pdev->device == 0x6842) || \
+                             (rdev->ddev->pdev->device == 0x6843))
+
 /*
  * BIOS helpers.
  */
@@ -2124,6 +2433,21 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
 #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
 #define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev))
 #define radeon_get_gpu_clock_counter(rdev) (rdev)->asic->get_gpu_clock_counter((rdev))
+#define radeon_dpm_init(rdev) rdev->asic->dpm.init((rdev))
+#define radeon_dpm_setup_asic(rdev) rdev->asic->dpm.setup_asic((rdev))
+#define radeon_dpm_enable(rdev) rdev->asic->dpm.enable((rdev))
+#define radeon_dpm_disable(rdev) rdev->asic->dpm.disable((rdev))
+#define radeon_dpm_pre_set_power_state(rdev) rdev->asic->dpm.pre_set_power_state((rdev))
+#define radeon_dpm_set_power_state(rdev) rdev->asic->dpm.set_power_state((rdev))
+#define radeon_dpm_post_set_power_state(rdev) rdev->asic->dpm.post_set_power_state((rdev))
+#define radeon_dpm_display_configuration_changed(rdev) rdev->asic->dpm.display_configuration_changed((rdev))
+#define radeon_dpm_fini(rdev) rdev->asic->dpm.fini((rdev))
+#define radeon_dpm_get_sclk(rdev, l) rdev->asic->dpm.get_sclk((rdev), (l))
+#define radeon_dpm_get_mclk(rdev, l) rdev->asic->dpm.get_mclk((rdev), (l))
+#define radeon_dpm_print_power_state(rdev, ps) rdev->asic->dpm.print_power_state((rdev), (ps))
+#define radeon_dpm_debugfs_print_current_performance_level(rdev, m) rdev->asic->dpm.debugfs_print_current_performance_level((rdev), (m))
+#define radeon_dpm_force_performance_level(rdev, l) rdev->asic->dpm.force_performance_level((rdev), (l))
+#define radeon_dpm_vblank_too_short(rdev) rdev->asic->dpm.vblank_too_short((rdev))
 
 /* Common functions */
 /* AGP */
@@ -2243,6 +2567,10 @@ extern int ni_mc_load_microcode(struct radeon_device *rdev);
 #if defined(CONFIG_ACPI)
 extern int radeon_acpi_init(struct radeon_device *rdev);
 extern void radeon_acpi_fini(struct radeon_device *rdev);
+extern bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev);
+extern int radeon_acpi_pcie_performance_request(struct radeon_device *rdev,
+                                               u8 perf_req, bool advertise);
+extern int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev);
 #else
 static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; }
 static inline void radeon_acpi_fini(struct radeon_device *rdev) { }