diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 09a28923f46..b5713eedd6e 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \ radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ - r600_blit_kms.o + r600_blit_kms.o radeon_pm.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 5c7fe52de30..1cefdbcc085 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -311,6 +311,8 @@ int r420_init(struct radeon_device *rdev) } /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* Get vram informations */ r300_vram_info(rdev); /* Initialize memory controller (also test AGP) */ diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index a555b7b19b4..f7435185c0a 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -260,6 +260,8 @@ int r520_init(struct radeon_device *rdev) } /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* Get vram informations */ r520_vram_info(rdev); /* Initialize memory controller (also test AGP) */ diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 35360b09df3..8d6bc12192d 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1621,10 +1621,13 @@ int r600_init(struct radeon_device *rdev) r600_scratch_init(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); r = radeon_clocks_init(rdev); if (r) return r; + /* Initialize power management */ + radeon_pm_init(rdev); /* Fence driver */ r = radeon_fence_driver_init(rdev); if (r) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index ea3efd7ae85..9f0bd984788 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -139,6 +139,10 @@ struct radeon_clock { uint32_t default_sclk; }; +/* + * Power management + */ +int radeon_pm_init(struct radeon_device *rdev); /* * Fences. @@ -622,7 +626,9 @@ struct radeon_asic { uint64_t dst_offset, unsigned num_pages, struct radeon_fence *fence); + uint32_t (*get_engine_clock)(struct radeon_device *rdev); void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); + uint32_t (*get_memory_clock)(struct radeon_device *rdev); void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock); void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); void (*set_clock_gating)(struct radeon_device *rdev, int enable); @@ -953,7 +959,9 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) #define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f)) +#define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev)) #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) +#define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev)) #define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l)) #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e)) diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index d38f9963282..94991edc839 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -31,10 +31,13 @@ /* * common functions */ +uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev); void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); +uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev); void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); +uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev); void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock); void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); @@ -93,7 +96,9 @@ static struct radeon_asic r100_asic = { .copy_blit = &r100_copy_blit, .copy_dma = NULL, .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = NULL, .set_memory_clock = NULL, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_legacy_set_clock_gating, @@ -145,7 +150,9 @@ static struct radeon_asic r300_asic = { .copy_blit = &r100_copy_blit, .copy_dma = &r300_copy_dma, .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = NULL, .set_memory_clock = NULL, .set_pcie_lanes = &rv370_set_pcie_lanes, .set_clock_gating = &radeon_legacy_set_clock_gating, @@ -181,7 +188,9 @@ static struct radeon_asic r420_asic = { .copy_blit = &r100_copy_blit, .copy_dma = &r300_copy_dma, .copy = &r100_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, .set_pcie_lanes = &rv370_set_pcie_lanes, .set_clock_gating = &radeon_atom_set_clock_gating, @@ -222,7 +231,9 @@ static struct radeon_asic rs400_asic = { .copy_blit = &r100_copy_blit, .copy_dma = &r300_copy_dma, .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = NULL, .set_memory_clock = NULL, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_legacy_set_clock_gating, @@ -267,7 +278,9 @@ static struct radeon_asic rs600_asic = { .copy_blit = &r100_copy_blit, .copy_dma = &r300_copy_dma, .copy = &r100_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_atom_set_clock_gating, @@ -305,7 +318,9 @@ static struct radeon_asic rs690_asic = { .copy_blit = &r100_copy_blit, .copy_dma = &r300_copy_dma, .copy = &r300_copy_dma, + .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_atom_set_clock_gating, @@ -349,7 +364,9 @@ static struct radeon_asic rv515_asic = { .copy_blit = &r100_copy_blit, .copy_dma = &r300_copy_dma, .copy = &r100_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, .set_pcie_lanes = &rv370_set_pcie_lanes, .set_clock_gating = &radeon_atom_set_clock_gating, @@ -384,7 +401,9 @@ static struct radeon_asic r520_asic = { .copy_blit = &r100_copy_blit, .copy_dma = &r300_copy_dma, .copy = &r100_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, .set_pcie_lanes = &rv370_set_pcie_lanes, .set_clock_gating = &radeon_atom_set_clock_gating, @@ -445,7 +464,9 @@ static struct radeon_asic r600_asic = { .copy_blit = &r600_copy_blit, .copy_dma = &r600_copy_blit, .copy = &r600_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_atom_set_clock_gating, @@ -481,7 +502,9 @@ static struct radeon_asic rv770_asic = { .copy_blit = &r600_copy_blit, .copy_dma = &r600_copy_blit, .copy = &r600_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, .set_memory_clock = &radeon_atom_set_memory_clock, .set_pcie_lanes = NULL, .set_clock_gating = &radeon_atom_set_clock_gating, diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 80aacded85a..2ed88a82093 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1133,6 +1133,24 @@ void radeon_atom_static_pwrmgt_setup(struct radeon_device *rdev, int enable) atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev) +{ + GET_ENGINE_CLOCK_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + return args.ulReturnEngineClock; +} + +uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) +{ + GET_MEMORY_CLOCK_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + return args.ulReturnMemoryClock; +} + void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock) { diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index f5c32a766b1..a8135416762 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c @@ -32,7 +32,7 @@ #include "atom.h" /* 10 khz */ -static uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) +uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) { struct radeon_pll *spll = &rdev->clock.spll; uint32_t fb_div, ref_div, post_div, sclk; diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c new file mode 100644 index 00000000000..46146c6a2a0 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -0,0 +1,65 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Rafał Miłecki + */ +#include "drmP.h" +#include "radeon.h" + +int radeon_debugfs_pm_init(struct radeon_device *rdev); + +int radeon_pm_init(struct radeon_device *rdev) +{ + if (radeon_debugfs_pm_init(rdev)) { + DRM_ERROR("Failed to register debugfs file for CP !\n"); + } + + return 0; +} + +/* + * Debugfs info + */ +#if defined(CONFIG_DEBUG_FS) + +static int radeon_debugfs_pm_info(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct radeon_device *rdev = dev->dev_private; + + seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev)); + seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev)); + + return 0; +} + +static struct drm_info_list radeon_pm_info_list[] = { + {"radeon_pm_info", radeon_debugfs_pm_info, 0, NULL}, +}; +#endif + +int radeon_debugfs_pm_init(struct radeon_device *rdev) +{ +#if defined(CONFIG_DEBUG_FS) + return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list)); +#else + return 0; +#endif +} diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 942754c39be..5f117cd8736 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -488,6 +488,8 @@ int rs600_init(struct radeon_device *rdev) } /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* Get vram informations */ rs600_vram_info(rdev); /* Initialize memory controller (also test AGP) */ diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 025e3225346..27547175cf9 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -706,6 +706,8 @@ int rs690_init(struct radeon_device *rdev) } /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* Get vram informations */ rs690_vram_info(rdev); /* Initialize memory controller (also test AGP) */ diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 03c052d892c..7935f793bf6 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -587,6 +587,8 @@ int rv515_init(struct radeon_device *rdev) } /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); + /* Initialize power management */ + radeon_pm_init(rdev); /* Get vram informations */ rv515_vram_info(rdev); /* Initialize memory controller (also test AGP) */ diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index ae074fdf804..b0efd0ddae7 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -983,10 +983,13 @@ int rv770_init(struct radeon_device *rdev) r600_scratch_init(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); r = radeon_clocks_init(rdev); if (r) return r; + /* Initialize power management */ + radeon_pm_init(rdev); /* Fence driver */ r = radeon_fence_driver_init(rdev); if (r)