From 6596afd48af4d07c8b454849b2fe7e628974f3ef Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 26 Jun 2013 00:15:24 -0400 Subject: [PATCH] drm/radeon/kms: add dpm support for btc (v3) This adds dpm support for btc asics. This includes: - clockgating - dynamic engine clock scaling - dynamic memory clock scaling - dynamic voltage scaling - dynamic pcie gen1/gen2 switching (requires additional acpi support) Set radeon.dpm=1 to enable. v2: reduce stack usage v3: attempt to fix state enable Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/Makefile | 2 +- drivers/gpu/drm/radeon/btc_dpm.c | 2188 +++++++++++++++++++++++++ drivers/gpu/drm/radeon/btc_dpm.h | 32 + drivers/gpu/drm/radeon/btcd.h | 181 ++ drivers/gpu/drm/radeon/ni.c | 21 + drivers/gpu/drm/radeon/radeon_asic.c | 12 + drivers/gpu/drm/radeon/radeon_asic.h | 6 + drivers/gpu/drm/radeon/radeon_pm.c | 3 + drivers/gpu/drm/radeon/radeon_ucode.h | 15 + drivers/gpu/drm/radeon/rv770_smc.c | 81 + 10 files changed, 2540 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/radeon/btc_dpm.c create mode 100644 drivers/gpu/drm/radeon/btc_dpm.h create mode 100644 drivers/gpu/drm/radeon/btcd.h diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 7092c96295b3..af3dd8fa0ca3 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -78,7 +78,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \ r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ - rv770_smc.o cypress_dpm.o + rv770_smc.o cypress_dpm.o btc_dpm.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c new file mode 100644 index 000000000000..221d4c6b95c5 --- /dev/null +++ b/drivers/gpu/drm/radeon/btc_dpm.c @@ -0,0 +1,2188 @@ +/* + * Copyright 2011 Advanced Micro Devices, Inc. + * + * 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: Alex Deucher + */ + +#include "drmP.h" +#include "radeon.h" +#include "btcd.h" +#include "r600_dpm.h" +#include "cypress_dpm.h" +#include "btc_dpm.h" +#include "atom.h" + +#define MC_CG_ARB_FREQ_F0 0x0a +#define MC_CG_ARB_FREQ_F1 0x0b +#define MC_CG_ARB_FREQ_F2 0x0c +#define MC_CG_ARB_FREQ_F3 0x0d + +#define MC_CG_SEQ_DRAMCONF_S0 0x05 +#define MC_CG_SEQ_DRAMCONF_S1 0x06 +#define MC_CG_SEQ_YCLK_SUSPEND 0x04 +#define MC_CG_SEQ_YCLK_RESUME 0x0a + +#define SMC_RAM_END 0x8000 + +#ifndef BTC_MGCG_SEQUENCE +#define BTC_MGCG_SEQUENCE 300 + +struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps); +struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev); +struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev); + + +//********* BARTS **************// +static const u32 barts_cgcg_cgls_default[] = +{ + /* Register, Value, Mask bits */ + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff +}; +#define BARTS_CGCG_CGLS_DEFAULT_LENGTH sizeof(barts_cgcg_cgls_default) / (3 * sizeof(u32)) + +static const u32 barts_cgcg_cgls_disable[] = +{ + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x00000644, 0x000f7912, 0x001f4180, + 0x00000644, 0x000f3812, 0x001f4180 +}; +#define BARTS_CGCG_CGLS_DISABLE_LENGTH sizeof(barts_cgcg_cgls_disable) / (3 * sizeof(u32)) + +static const u32 barts_cgcg_cgls_enable[] = +{ + /* 0x0000c124, 0x84180000, 0x00180000, */ + 0x00000644, 0x000f7892, 0x001f4080, + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff +}; +#define BARTS_CGCG_CGLS_ENABLE_LENGTH sizeof(barts_cgcg_cgls_enable) / (3 * sizeof(u32)) + +static const u32 barts_mgcg_default[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x00005448, 0x00000100, 0xffffffff, + 0x000055e4, 0x00600100, 0xffffffff, + 0x0000160c, 0x00000100, 0xffffffff, + 0x0000c164, 0x00000100, 0xffffffff, + 0x00008a18, 0x00000100, 0xffffffff, + 0x0000897c, 0x06000100, 0xffffffff, + 0x00008b28, 0x00000100, 0xffffffff, + 0x00009144, 0x00000100, 0xffffffff, + 0x00009a60, 0x00000100, 0xffffffff, + 0x00009868, 0x00000100, 0xffffffff, + 0x00008d58, 0x00000100, 0xffffffff, + 0x00009510, 0x00000100, 0xffffffff, + 0x0000949c, 0x00000100, 0xffffffff, + 0x00009654, 0x00000100, 0xffffffff, + 0x00009030, 0x00000100, 0xffffffff, + 0x00009034, 0x00000100, 0xffffffff, + 0x00009038, 0x00000100, 0xffffffff, + 0x0000903c, 0x00000100, 0xffffffff, + 0x00009040, 0x00000100, 0xffffffff, + 0x0000a200, 0x00000100, 0xffffffff, + 0x0000a204, 0x00000100, 0xffffffff, + 0x0000a208, 0x00000100, 0xffffffff, + 0x0000a20c, 0x00000100, 0xffffffff, + 0x0000977c, 0x00000100, 0xffffffff, + 0x00003f80, 0x00000100, 0xffffffff, + 0x0000a210, 0x00000100, 0xffffffff, + 0x0000a214, 0x00000100, 0xffffffff, + 0x000004d8, 0x00000100, 0xffffffff, + 0x00009784, 0x00000100, 0xffffffff, + 0x00009698, 0x00000100, 0xffffffff, + 0x000004d4, 0x00000200, 0xffffffff, + 0x000004d0, 0x00000000, 0xffffffff, + 0x000030cc, 0x00000100, 0xffffffff, + 0x0000d0c0, 0xff000100, 0xffffffff, + 0x0000802c, 0x40000000, 0xffffffff, + 0x0000915c, 0x00010000, 0xffffffff, + 0x00009160, 0x00030002, 0xffffffff, + 0x00009164, 0x00050004, 0xffffffff, + 0x00009168, 0x00070006, 0xffffffff, + 0x00009178, 0x00070000, 0xffffffff, + 0x0000917c, 0x00030002, 0xffffffff, + 0x00009180, 0x00050004, 0xffffffff, + 0x0000918c, 0x00010006, 0xffffffff, + 0x00009190, 0x00090008, 0xffffffff, + 0x00009194, 0x00070000, 0xffffffff, + 0x00009198, 0x00030002, 0xffffffff, + 0x0000919c, 0x00050004, 0xffffffff, + 0x000091a8, 0x00010006, 0xffffffff, + 0x000091ac, 0x00090008, 0xffffffff, + 0x000091b0, 0x00070000, 0xffffffff, + 0x000091b4, 0x00030002, 0xffffffff, + 0x000091b8, 0x00050004, 0xffffffff, + 0x000091c4, 0x00010006, 0xffffffff, + 0x000091c8, 0x00090008, 0xffffffff, + 0x000091cc, 0x00070000, 0xffffffff, + 0x000091d0, 0x00030002, 0xffffffff, + 0x000091d4, 0x00050004, 0xffffffff, + 0x000091e0, 0x00010006, 0xffffffff, + 0x000091e4, 0x00090008, 0xffffffff, + 0x000091e8, 0x00000000, 0xffffffff, + 0x000091ec, 0x00070000, 0xffffffff, + 0x000091f0, 0x00030002, 0xffffffff, + 0x000091f4, 0x00050004, 0xffffffff, + 0x00009200, 0x00010006, 0xffffffff, + 0x00009204, 0x00090008, 0xffffffff, + 0x00009208, 0x00070000, 0xffffffff, + 0x0000920c, 0x00030002, 0xffffffff, + 0x00009210, 0x00050004, 0xffffffff, + 0x0000921c, 0x00010006, 0xffffffff, + 0x00009220, 0x00090008, 0xffffffff, + 0x00009224, 0x00070000, 0xffffffff, + 0x00009228, 0x00030002, 0xffffffff, + 0x0000922c, 0x00050004, 0xffffffff, + 0x00009238, 0x00010006, 0xffffffff, + 0x0000923c, 0x00090008, 0xffffffff, + 0x00009294, 0x00000000, 0xffffffff, + 0x0000802c, 0x40010000, 0xffffffff, + 0x0000915c, 0x00010000, 0xffffffff, + 0x00009160, 0x00030002, 0xffffffff, + 0x00009164, 0x00050004, 0xffffffff, + 0x00009168, 0x00070006, 0xffffffff, + 0x00009178, 0x00070000, 0xffffffff, + 0x0000917c, 0x00030002, 0xffffffff, + 0x00009180, 0x00050004, 0xffffffff, + 0x0000918c, 0x00010006, 0xffffffff, + 0x00009190, 0x00090008, 0xffffffff, + 0x00009194, 0x00070000, 0xffffffff, + 0x00009198, 0x00030002, 0xffffffff, + 0x0000919c, 0x00050004, 0xffffffff, + 0x000091a8, 0x00010006, 0xffffffff, + 0x000091ac, 0x00090008, 0xffffffff, + 0x000091b0, 0x00070000, 0xffffffff, + 0x000091b4, 0x00030002, 0xffffffff, + 0x000091b8, 0x00050004, 0xffffffff, + 0x000091c4, 0x00010006, 0xffffffff, + 0x000091c8, 0x00090008, 0xffffffff, + 0x000091cc, 0x00070000, 0xffffffff, + 0x000091d0, 0x00030002, 0xffffffff, + 0x000091d4, 0x00050004, 0xffffffff, + 0x000091e0, 0x00010006, 0xffffffff, + 0x000091e4, 0x00090008, 0xffffffff, + 0x000091e8, 0x00000000, 0xffffffff, + 0x000091ec, 0x00070000, 0xffffffff, + 0x000091f0, 0x00030002, 0xffffffff, + 0x000091f4, 0x00050004, 0xffffffff, + 0x00009200, 0x00010006, 0xffffffff, + 0x00009204, 0x00090008, 0xffffffff, + 0x00009208, 0x00070000, 0xffffffff, + 0x0000920c, 0x00030002, 0xffffffff, + 0x00009210, 0x00050004, 0xffffffff, + 0x0000921c, 0x00010006, 0xffffffff, + 0x00009220, 0x00090008, 0xffffffff, + 0x00009224, 0x00070000, 0xffffffff, + 0x00009228, 0x00030002, 0xffffffff, + 0x0000922c, 0x00050004, 0xffffffff, + 0x00009238, 0x00010006, 0xffffffff, + 0x0000923c, 0x00090008, 0xffffffff, + 0x00009294, 0x00000000, 0xffffffff, + 0x0000802c, 0xc0000000, 0xffffffff, + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff +}; +#define BARTS_MGCG_DEFAULT_LENGTH sizeof(barts_mgcg_default) / (3 * sizeof(u32)) + +static const u32 barts_mgcg_disable[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x000008f8, 0x00000000, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000001, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000002, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000003, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x00009150, 0x00600000, 0xffffffff +}; +#define BARTS_MGCG_DISABLE_LENGTH sizeof(barts_mgcg_disable) / (3 * sizeof(u32)) + +static const u32 barts_mgcg_enable[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x000008f8, 0x00000000, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000001, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000002, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000003, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x00009150, 0x81944000, 0xffffffff +}; +#define BARTS_MGCG_ENABLE_LENGTH sizeof(barts_mgcg_enable) / (3 * sizeof(u32)) + +//********* CAICOS **************// +static const u32 caicos_cgcg_cgls_default[] = +{ + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff +}; +#define CAICOS_CGCG_CGLS_DEFAULT_LENGTH sizeof(caicos_cgcg_cgls_default) / (3 * sizeof(u32)) + +static const u32 caicos_cgcg_cgls_disable[] = +{ + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x00000644, 0x000f7912, 0x001f4180, + 0x00000644, 0x000f3812, 0x001f4180 +}; +#define CAICOS_CGCG_CGLS_DISABLE_LENGTH sizeof(caicos_cgcg_cgls_disable) / (3 * sizeof(u32)) + +static const u32 caicos_cgcg_cgls_enable[] = +{ + /* 0x0000c124, 0x84180000, 0x00180000, */ + 0x00000644, 0x000f7892, 0x001f4080, + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff +}; +#define CAICOS_CGCG_CGLS_ENABLE_LENGTH sizeof(caicos_cgcg_cgls_enable) / (3 * sizeof(u32)) + +static const u32 caicos_mgcg_default[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x00005448, 0x00000100, 0xffffffff, + 0x000055e4, 0x00600100, 0xffffffff, + 0x0000160c, 0x00000100, 0xffffffff, + 0x0000c164, 0x00000100, 0xffffffff, + 0x00008a18, 0x00000100, 0xffffffff, + 0x0000897c, 0x06000100, 0xffffffff, + 0x00008b28, 0x00000100, 0xffffffff, + 0x00009144, 0x00000100, 0xffffffff, + 0x00009a60, 0x00000100, 0xffffffff, + 0x00009868, 0x00000100, 0xffffffff, + 0x00008d58, 0x00000100, 0xffffffff, + 0x00009510, 0x00000100, 0xffffffff, + 0x0000949c, 0x00000100, 0xffffffff, + 0x00009654, 0x00000100, 0xffffffff, + 0x00009030, 0x00000100, 0xffffffff, + 0x00009034, 0x00000100, 0xffffffff, + 0x00009038, 0x00000100, 0xffffffff, + 0x0000903c, 0x00000100, 0xffffffff, + 0x00009040, 0x00000100, 0xffffffff, + 0x0000a200, 0x00000100, 0xffffffff, + 0x0000a204, 0x00000100, 0xffffffff, + 0x0000a208, 0x00000100, 0xffffffff, + 0x0000a20c, 0x00000100, 0xffffffff, + 0x0000977c, 0x00000100, 0xffffffff, + 0x00003f80, 0x00000100, 0xffffffff, + 0x0000a210, 0x00000100, 0xffffffff, + 0x0000a214, 0x00000100, 0xffffffff, + 0x000004d8, 0x00000100, 0xffffffff, + 0x00009784, 0x00000100, 0xffffffff, + 0x00009698, 0x00000100, 0xffffffff, + 0x000004d4, 0x00000200, 0xffffffff, + 0x000004d0, 0x00000000, 0xffffffff, + 0x000030cc, 0x00000100, 0xffffffff, + 0x0000d0c0, 0xff000100, 0xffffffff, + 0x0000915c, 0x00010000, 0xffffffff, + 0x00009160, 0x00030002, 0xffffffff, + 0x00009164, 0x00050004, 0xffffffff, + 0x00009168, 0x00070006, 0xffffffff, + 0x00009178, 0x00070000, 0xffffffff, + 0x0000917c, 0x00030002, 0xffffffff, + 0x00009180, 0x00050004, 0xffffffff, + 0x0000918c, 0x00010006, 0xffffffff, + 0x00009190, 0x00090008, 0xffffffff, + 0x00009194, 0x00070000, 0xffffffff, + 0x00009198, 0x00030002, 0xffffffff, + 0x0000919c, 0x00050004, 0xffffffff, + 0x000091a8, 0x00010006, 0xffffffff, + 0x000091ac, 0x00090008, 0xffffffff, + 0x000091e8, 0x00000000, 0xffffffff, + 0x00009294, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff +}; +#define CAICOS_MGCG_DEFAULT_LENGTH sizeof(caicos_mgcg_default) / (3 * sizeof(u32)) + +static const u32 caicos_mgcg_disable[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x000008f8, 0x00000000, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000001, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000002, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000003, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x00009150, 0x00600000, 0xffffffff +}; +#define CAICOS_MGCG_DISABLE_LENGTH sizeof(caicos_mgcg_disable) / (3 * sizeof(u32)) + +static const u32 caicos_mgcg_enable[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x000008f8, 0x00000000, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000001, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000002, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000003, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x00009150, 0x46944040, 0xffffffff +}; +#define CAICOS_MGCG_ENABLE_LENGTH sizeof(caicos_mgcg_enable) / (3 * sizeof(u32)) + +//********* TURKS **************// +static const u32 turks_cgcg_cgls_default[] = +{ + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff +}; +#define TURKS_CGCG_CGLS_DEFAULT_LENGTH sizeof(turks_cgcg_cgls_default) / (3 * sizeof(u32)) + +static const u32 turks_cgcg_cgls_disable[] = +{ + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x00000644, 0x000f7912, 0x001f4180, + 0x00000644, 0x000f3812, 0x001f4180 +}; +#define TURKS_CGCG_CGLS_DISABLE_LENGTH sizeof(turks_cgcg_cgls_disable) / (3 * sizeof(u32)) + +static const u32 turks_cgcg_cgls_enable[] = +{ + /* 0x0000c124, 0x84180000, 0x00180000, */ + 0x00000644, 0x000f7892, 0x001f4080, + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000020, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000021, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000022, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000023, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000024, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000025, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000026, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000027, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000028, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000029, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000002a, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x0000002b, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff +}; +#define TURKS_CGCG_CGLS_ENABLE_LENGTH sizeof(turks_cgcg_cgls_enable) / (3 * sizeof(u32)) + +// These are the sequences for turks_mgcg_shls +static const u32 turks_mgcg_default[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x00005448, 0x00000100, 0xffffffff, + 0x000055e4, 0x00600100, 0xffffffff, + 0x0000160c, 0x00000100, 0xffffffff, + 0x0000c164, 0x00000100, 0xffffffff, + 0x00008a18, 0x00000100, 0xffffffff, + 0x0000897c, 0x06000100, 0xffffffff, + 0x00008b28, 0x00000100, 0xffffffff, + 0x00009144, 0x00000100, 0xffffffff, + 0x00009a60, 0x00000100, 0xffffffff, + 0x00009868, 0x00000100, 0xffffffff, + 0x00008d58, 0x00000100, 0xffffffff, + 0x00009510, 0x00000100, 0xffffffff, + 0x0000949c, 0x00000100, 0xffffffff, + 0x00009654, 0x00000100, 0xffffffff, + 0x00009030, 0x00000100, 0xffffffff, + 0x00009034, 0x00000100, 0xffffffff, + 0x00009038, 0x00000100, 0xffffffff, + 0x0000903c, 0x00000100, 0xffffffff, + 0x00009040, 0x00000100, 0xffffffff, + 0x0000a200, 0x00000100, 0xffffffff, + 0x0000a204, 0x00000100, 0xffffffff, + 0x0000a208, 0x00000100, 0xffffffff, + 0x0000a20c, 0x00000100, 0xffffffff, + 0x0000977c, 0x00000100, 0xffffffff, + 0x00003f80, 0x00000100, 0xffffffff, + 0x0000a210, 0x00000100, 0xffffffff, + 0x0000a214, 0x00000100, 0xffffffff, + 0x000004d8, 0x00000100, 0xffffffff, + 0x00009784, 0x00000100, 0xffffffff, + 0x00009698, 0x00000100, 0xffffffff, + 0x000004d4, 0x00000200, 0xffffffff, + 0x000004d0, 0x00000000, 0xffffffff, + 0x000030cc, 0x00000100, 0xffffffff, + 0x0000d0c0, 0x00000100, 0xffffffff, + 0x0000915c, 0x00010000, 0xffffffff, + 0x00009160, 0x00030002, 0xffffffff, + 0x00009164, 0x00050004, 0xffffffff, + 0x00009168, 0x00070006, 0xffffffff, + 0x00009178, 0x00070000, 0xffffffff, + 0x0000917c, 0x00030002, 0xffffffff, + 0x00009180, 0x00050004, 0xffffffff, + 0x0000918c, 0x00010006, 0xffffffff, + 0x00009190, 0x00090008, 0xffffffff, + 0x00009194, 0x00070000, 0xffffffff, + 0x00009198, 0x00030002, 0xffffffff, + 0x0000919c, 0x00050004, 0xffffffff, + 0x000091a8, 0x00010006, 0xffffffff, + 0x000091ac, 0x00090008, 0xffffffff, + 0x000091b0, 0x00070000, 0xffffffff, + 0x000091b4, 0x00030002, 0xffffffff, + 0x000091b8, 0x00050004, 0xffffffff, + 0x000091c4, 0x00010006, 0xffffffff, + 0x000091c8, 0x00090008, 0xffffffff, + 0x000091cc, 0x00070000, 0xffffffff, + 0x000091d0, 0x00030002, 0xffffffff, + 0x000091d4, 0x00050004, 0xffffffff, + 0x000091e0, 0x00010006, 0xffffffff, + 0x000091e4, 0x00090008, 0xffffffff, + 0x000091e8, 0x00000000, 0xffffffff, + 0x000091ec, 0x00070000, 0xffffffff, + 0x000091f0, 0x00030002, 0xffffffff, + 0x000091f4, 0x00050004, 0xffffffff, + 0x00009200, 0x00010006, 0xffffffff, + 0x00009204, 0x00090008, 0xffffffff, + 0x00009208, 0x00070000, 0xffffffff, + 0x0000920c, 0x00030002, 0xffffffff, + 0x00009210, 0x00050004, 0xffffffff, + 0x0000921c, 0x00010006, 0xffffffff, + 0x00009220, 0x00090008, 0xffffffff, + 0x00009294, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000010, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000011, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000012, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000013, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000014, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000015, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000016, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000017, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000018, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000019, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001a, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x0000001b, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff +}; +#define TURKS_MGCG_DEFAULT_LENGTH sizeof(turks_mgcg_default) / (3 * sizeof(u32)) + +static const u32 turks_mgcg_disable[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x000008f8, 0x00000000, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000001, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000002, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x000008f8, 0x00000003, 0xffffffff, + 0x000008fc, 0xffffffff, 0xffffffff, + 0x00009150, 0x00600000, 0xffffffff +}; +#define TURKS_MGCG_DISABLE_LENGTH sizeof(turks_mgcg_disable) / (3 * sizeof(u32)) + +static const u32 turks_mgcg_enable[] = +{ + 0x0000802c, 0xc0000000, 0xffffffff, + 0x000008f8, 0x00000000, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000001, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000002, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x000008f8, 0x00000003, 0xffffffff, + 0x000008fc, 0x00000000, 0xffffffff, + 0x00009150, 0x6e944000, 0xffffffff +}; +#define TURKS_MGCG_ENABLE_LENGTH sizeof(turks_mgcg_enable) / (3 * sizeof(u32)) + +#endif + +#ifndef BTC_SYSLS_SEQUENCE +#define BTC_SYSLS_SEQUENCE 100 + + +//********* BARTS **************// +static const u32 barts_sysls_default[] = +{ + /* Register, Value, Mask bits */ + 0x000055e8, 0x00000000, 0xffffffff, + 0x0000d0bc, 0x00000000, 0xffffffff, + 0x000015c0, 0x000c1401, 0xffffffff, + 0x0000264c, 0x000c0400, 0xffffffff, + 0x00002648, 0x000c0400, 0xffffffff, + 0x00002650, 0x000c0400, 0xffffffff, + 0x000020b8, 0x000c0400, 0xffffffff, + 0x000020bc, 0x000c0400, 0xffffffff, + 0x000020c0, 0x000c0c80, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680fff, 0xffffffff, + 0x000004c8, 0x00000001, 0xffffffff, + 0x000064ec, 0x00000000, 0xffffffff, + 0x00000c7c, 0x00000000, 0xffffffff, + 0x00006dfc, 0x00000000, 0xffffffff +}; +#define BARTS_SYSLS_DEFAULT_LENGTH sizeof(barts_sysls_default) / (3 * sizeof(u32)) + +static const u32 barts_sysls_disable[] = +{ + 0x000055e8, 0x00000000, 0xffffffff, + 0x0000d0bc, 0x00000000, 0xffffffff, + 0x000015c0, 0x00041401, 0xffffffff, + 0x0000264c, 0x00040400, 0xffffffff, + 0x00002648, 0x00040400, 0xffffffff, + 0x00002650, 0x00040400, 0xffffffff, + 0x000020b8, 0x00040400, 0xffffffff, + 0x000020bc, 0x00040400, 0xffffffff, + 0x000020c0, 0x00040c80, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680000, 0xffffffff, + 0x000004c8, 0x00000001, 0xffffffff, + 0x000064ec, 0x00007ffd, 0xffffffff, + 0x00000c7c, 0x0000ff00, 0xffffffff, + 0x00006dfc, 0x0000007f, 0xffffffff +}; +#define BARTS_SYSLS_DISABLE_LENGTH sizeof(barts_sysls_disable) / (3 * sizeof(u32)) + +static const u32 barts_sysls_enable[] = +{ + 0x000055e8, 0x00000001, 0xffffffff, + 0x0000d0bc, 0x00000100, 0xffffffff, + 0x000015c0, 0x000c1401, 0xffffffff, + 0x0000264c, 0x000c0400, 0xffffffff, + 0x00002648, 0x000c0400, 0xffffffff, + 0x00002650, 0x000c0400, 0xffffffff, + 0x000020b8, 0x000c0400, 0xffffffff, + 0x000020bc, 0x000c0400, 0xffffffff, + 0x000020c0, 0x000c0c80, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680fff, 0xffffffff, + 0x000004c8, 0x00000000, 0xffffffff, + 0x000064ec, 0x00000000, 0xffffffff, + 0x00000c7c, 0x00000000, 0xffffffff, + 0x00006dfc, 0x00000000, 0xffffffff +}; +#define BARTS_SYSLS_ENABLE_LENGTH sizeof(barts_sysls_enable) / (3 * sizeof(u32)) + +//********* CAICOS **************// +static const u32 caicos_sysls_default[] = +{ + 0x000055e8, 0x00000000, 0xffffffff, + 0x0000d0bc, 0x00000000, 0xffffffff, + 0x000015c0, 0x000c1401, 0xffffffff, + 0x0000264c, 0x000c0400, 0xffffffff, + 0x00002648, 0x000c0400, 0xffffffff, + 0x00002650, 0x000c0400, 0xffffffff, + 0x000020b8, 0x000c0400, 0xffffffff, + 0x000020bc, 0x000c0400, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680fff, 0xffffffff, + 0x000004c8, 0x00000001, 0xffffffff, + 0x000064ec, 0x00000000, 0xffffffff, + 0x00000c7c, 0x00000000, 0xffffffff, + 0x00006dfc, 0x00000000, 0xffffffff +}; +#define CAICOS_SYSLS_DEFAULT_LENGTH sizeof(caicos_sysls_default) / (3 * sizeof(u32)) + +static const u32 caicos_sysls_disable[] = +{ + 0x000055e8, 0x00000000, 0xffffffff, + 0x0000d0bc, 0x00000000, 0xffffffff, + 0x000015c0, 0x00041401, 0xffffffff, + 0x0000264c, 0x00040400, 0xffffffff, + 0x00002648, 0x00040400, 0xffffffff, + 0x00002650, 0x00040400, 0xffffffff, + 0x000020b8, 0x00040400, 0xffffffff, + 0x000020bc, 0x00040400, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680000, 0xffffffff, + 0x000004c8, 0x00000001, 0xffffffff, + 0x000064ec, 0x00007ffd, 0xffffffff, + 0x00000c7c, 0x0000ff00, 0xffffffff, + 0x00006dfc, 0x0000007f, 0xffffffff +}; +#define CAICOS_SYSLS_DISABLE_LENGTH sizeof(caicos_sysls_disable) / (3 * sizeof(u32)) + +static const u32 caicos_sysls_enable[] = +{ + 0x000055e8, 0x00000001, 0xffffffff, + 0x0000d0bc, 0x00000100, 0xffffffff, + 0x000015c0, 0x000c1401, 0xffffffff, + 0x0000264c, 0x000c0400, 0xffffffff, + 0x00002648, 0x000c0400, 0xffffffff, + 0x00002650, 0x000c0400, 0xffffffff, + 0x000020b8, 0x000c0400, 0xffffffff, + 0x000020bc, 0x000c0400, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680fff, 0xffffffff, + 0x000064ec, 0x00000000, 0xffffffff, + 0x00000c7c, 0x00000000, 0xffffffff, + 0x00006dfc, 0x00000000, 0xffffffff, + 0x000004c8, 0x00000000, 0xffffffff +}; +#define CAICOS_SYSLS_ENABLE_LENGTH sizeof(caicos_sysls_enable) / (3 * sizeof(u32)) + +//********* TURKS **************// +static const u32 turks_sysls_default[] = +{ + 0x000055e8, 0x00000000, 0xffffffff, + 0x0000d0bc, 0x00000000, 0xffffffff, + 0x000015c0, 0x000c1401, 0xffffffff, + 0x0000264c, 0x000c0400, 0xffffffff, + 0x00002648, 0x000c0400, 0xffffffff, + 0x00002650, 0x000c0400, 0xffffffff, + 0x000020b8, 0x000c0400, 0xffffffff, + 0x000020bc, 0x000c0400, 0xffffffff, + 0x000020c0, 0x000c0c80, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680fff, 0xffffffff, + 0x000004c8, 0x00000001, 0xffffffff, + 0x000064ec, 0x00000000, 0xffffffff, + 0x00000c7c, 0x00000000, 0xffffffff, + 0x00006dfc, 0x00000000, 0xffffffff +}; +#define TURKS_SYSLS_DEFAULT_LENGTH sizeof(turks_sysls_default) / (3 * sizeof(u32)) + +static const u32 turks_sysls_disable[] = +{ + 0x000055e8, 0x00000000, 0xffffffff, + 0x0000d0bc, 0x00000000, 0xffffffff, + 0x000015c0, 0x00041401, 0xffffffff, + 0x0000264c, 0x00040400, 0xffffffff, + 0x00002648, 0x00040400, 0xffffffff, + 0x00002650, 0x00040400, 0xffffffff, + 0x000020b8, 0x00040400, 0xffffffff, + 0x000020bc, 0x00040400, 0xffffffff, + 0x000020c0, 0x00040c80, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680000, 0xffffffff, + 0x000004c8, 0x00000001, 0xffffffff, + 0x000064ec, 0x00007ffd, 0xffffffff, + 0x00000c7c, 0x0000ff00, 0xffffffff, + 0x00006dfc, 0x0000007f, 0xffffffff +}; +#define TURKS_SYSLS_DISABLE_LENGTH sizeof(turks_sysls_disable) / (3 * sizeof(u32)) + +static const u32 turks_sysls_enable[] = +{ + 0x000055e8, 0x00000001, 0xffffffff, + 0x0000d0bc, 0x00000100, 0xffffffff, + 0x000015c0, 0x000c1401, 0xffffffff, + 0x0000264c, 0x000c0400, 0xffffffff, + 0x00002648, 0x000c0400, 0xffffffff, + 0x00002650, 0x000c0400, 0xffffffff, + 0x000020b8, 0x000c0400, 0xffffffff, + 0x000020bc, 0x000c0400, 0xffffffff, + 0x000020c0, 0x000c0c80, 0xffffffff, + 0x0000f4a0, 0x000000c0, 0xffffffff, + 0x0000f4a4, 0x00680fff, 0xffffffff, + 0x000004c8, 0x00000000, 0xffffffff, + 0x000064ec, 0x00000000, 0xffffffff, + 0x00000c7c, 0x00000000, 0xffffffff, + 0x00006dfc, 0x00000000, 0xffffffff +}; +#define TURKS_SYSLS_ENABLE_LENGTH sizeof(turks_sysls_enable) / (3 * sizeof(u32)) + +#endif + +static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev, + bool enable) +{ + struct rv7xx_power_info *pi = rv770_get_pi(rdev); + u32 tmp, bif; + + tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); + if (enable) { + if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) && + (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) { + if (!pi->boot_in_gen2) { + bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK; + bif |= CG_CLIENT_REQ(0xd); + WREG32(CG_BIF_REQ_AND_RSP, bif); + + tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK; + tmp |= LC_HW_VOLTAGE_IF_CONTROL(1); + tmp |= LC_GEN2_EN_STRAP; + + tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT; + WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp); + udelay(10); + tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; + WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp); + } + } + } else { + if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) || + (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) { + if (!pi->boot_in_gen2) { + bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK; + bif |= CG_CLIENT_REQ(0xd); + WREG32(CG_BIF_REQ_AND_RSP, bif); + + tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK; + tmp &= ~LC_GEN2_EN_STRAP; + } + WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp); + } + } +} + +static void btc_enable_dynamic_pcie_gen2(struct radeon_device *rdev, + bool enable) +{ + btc_enable_bif_dynamic_pcie_gen2(rdev, enable); + + if (enable) + WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE); + else + WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE); +} + +static int btc_disable_ulv(struct radeon_device *rdev) +{ + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + + if (eg_pi->ulv.supported) { + if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) != PPSMC_Result_OK) + return -EINVAL; + } + return 0; +} + +static int btc_populate_ulv_state(struct radeon_device *rdev, + RV770_SMC_STATETABLE *table) +{ + int ret = -EINVAL; + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl; + + if (ulv_pl->vddc) { + ret = cypress_convert_power_level_to_smc(rdev, + ulv_pl, + &table->ULVState.levels[0], + PPSMC_DISPLAY_WATERMARK_LOW); + if (ret == 0) { + table->ULVState.levels[0].arbValue = MC_CG_ARB_FREQ_F0; + table->ULVState.levels[0].ACIndex = 1; + + table->ULVState.levels[1] = table->ULVState.levels[0]; + table->ULVState.levels[2] = table->ULVState.levels[0]; + + table->ULVState.flags |= PPSMC_SWSTATE_FLAG_DC; + + WREG32(CG_ULV_CONTROL, BTC_CGULVCONTROL_DFLT); + WREG32(CG_ULV_PARAMETER, BTC_CGULVPARAMETER_DFLT); + } + } + + return ret; +} + +static int btc_populate_smc_acpi_state(struct radeon_device *rdev, + RV770_SMC_STATETABLE *table) +{ + int ret = cypress_populate_smc_acpi_state(rdev, table); + + if (ret == 0) { + table->ACPIState.levels[0].ACIndex = 0; + table->ACPIState.levels[1].ACIndex = 0; + table->ACPIState.levels[2].ACIndex = 0; + } + + return ret; +} + +static void btc_program_mgcg_hw_sequence(struct radeon_device *rdev, + const u32 *sequence, u32 count) +{ + u32 i, length = count * 3; + u32 tmp; + + for (i = 0; i < length; i+=3) { + tmp = RREG32(sequence[i]); + tmp &= ~sequence[i+2]; + tmp |= sequence[i+1] & sequence[i+2]; + WREG32(sequence[i], tmp); + } +} + +static void btc_cg_clock_gating_default(struct radeon_device *rdev) +{ + u32 count; + const u32 *p = NULL; + + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_cgcg_cgls_default; + count = BARTS_CGCG_CGLS_DEFAULT_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_cgcg_cgls_default; + count = TURKS_CGCG_CGLS_DEFAULT_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_cgcg_cgls_default; + count = CAICOS_CGCG_CGLS_DEFAULT_LENGTH; + } else + return; + + btc_program_mgcg_hw_sequence(rdev, p, count); +} + +static void btc_cg_clock_gating_enable(struct radeon_device *rdev, + bool enable) +{ + u32 count; + const u32 *p = NULL; + + if (enable) { + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_cgcg_cgls_enable; + count = BARTS_CGCG_CGLS_ENABLE_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_cgcg_cgls_enable; + count = TURKS_CGCG_CGLS_ENABLE_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_cgcg_cgls_enable; + count = CAICOS_CGCG_CGLS_ENABLE_LENGTH; + } else + return; + } else { + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_cgcg_cgls_disable; + count = BARTS_CGCG_CGLS_DISABLE_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_cgcg_cgls_disable; + count = TURKS_CGCG_CGLS_DISABLE_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_cgcg_cgls_disable; + count = CAICOS_CGCG_CGLS_DISABLE_LENGTH; + } else + return; + } + + btc_program_mgcg_hw_sequence(rdev, p, count); +} + +static void btc_mg_clock_gating_default(struct radeon_device *rdev) +{ + u32 count; + const u32 *p = NULL; + + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_mgcg_default; + count = BARTS_MGCG_DEFAULT_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_mgcg_default; + count = TURKS_MGCG_DEFAULT_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_mgcg_default; + count = CAICOS_MGCG_DEFAULT_LENGTH; + } else + return; + + btc_program_mgcg_hw_sequence(rdev, p, count); +} + +static void btc_mg_clock_gating_enable(struct radeon_device *rdev, + bool enable) +{ + u32 count; + const u32 *p = NULL; + + if (enable) { + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_mgcg_enable; + count = BARTS_MGCG_ENABLE_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_mgcg_enable; + count = TURKS_MGCG_ENABLE_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_mgcg_enable; + count = CAICOS_MGCG_ENABLE_LENGTH; + } else + return; + } else { + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_mgcg_disable[0]; + count = BARTS_MGCG_DISABLE_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_mgcg_disable[0]; + count = TURKS_MGCG_DISABLE_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_mgcg_disable[0]; + count = CAICOS_MGCG_DISABLE_LENGTH; + } else + return; + } + + btc_program_mgcg_hw_sequence(rdev, p, count); +} + +static void btc_ls_clock_gating_default(struct radeon_device *rdev) +{ + u32 count; + const u32 *p = NULL; + + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_sysls_default; + count = BARTS_SYSLS_DEFAULT_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_sysls_default; + count = TURKS_SYSLS_DEFAULT_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_sysls_default; + count = CAICOS_SYSLS_DEFAULT_LENGTH; + } else + return; + + btc_program_mgcg_hw_sequence(rdev, p, count); +} + +static void btc_ls_clock_gating_enable(struct radeon_device *rdev, + bool enable) +{ + u32 count; + const u32 *p = NULL; + + if (enable) { + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_sysls_enable; + count = BARTS_SYSLS_ENABLE_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_sysls_enable; + count = TURKS_SYSLS_ENABLE_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_sysls_enable; + count = CAICOS_SYSLS_ENABLE_LENGTH; + } else + return; + } else { + if (rdev->family == CHIP_BARTS) { + p = (const u32 *)&barts_sysls_disable; + count = BARTS_SYSLS_DISABLE_LENGTH; + } else if (rdev->family == CHIP_TURKS) { + p = (const u32 *)&turks_sysls_disable; + count = TURKS_SYSLS_DISABLE_LENGTH; + } else if (rdev->family == CHIP_CAICOS) { + p = (const u32 *)&caicos_sysls_disable; + count = CAICOS_SYSLS_DISABLE_LENGTH; + } else + return; + } + + btc_program_mgcg_hw_sequence(rdev, p, count); +} + +static bool btc_dpm_enabled(struct radeon_device *rdev) +{ + if (rv770_is_smc_running(rdev)) + return true; + else + return false; +} + +static int btc_init_smc_table(struct radeon_device *rdev) +{ + struct rv7xx_power_info *pi = rv770_get_pi(rdev); + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps; + RV770_SMC_STATETABLE *table = &pi->smc_statetable; + int ret; + + memset(table, 0, sizeof(RV770_SMC_STATETABLE)); + + cypress_populate_smc_voltage_tables(rdev, table); + + switch (rdev->pm.int_thermal_type) { + case THERMAL_TYPE_EVERGREEN: + case THERMAL_TYPE_EMC2103_WITH_INTERNAL: + table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL; + break; + case THERMAL_TYPE_NONE: + table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE; + break; + default: + table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL; + break; + } + + if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC) + table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; + + if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) + table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT; + + if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC) + table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; + + if (pi->mem_gddr5) + table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5; + + ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table); + if (ret) + return ret; + + if (eg_pi->sclk_deep_sleep) + WREG32_P(SCLK_PSKIP_CNTL, PSKIP_ON_ALLOW_STOP_HI(32), + ~PSKIP_ON_ALLOW_STOP_HI_MASK); + + ret = btc_populate_smc_acpi_state(rdev, table); + if (ret) + return ret; + + if (eg_pi->ulv.supported) { + ret = btc_populate_ulv_state(rdev, table); + if (ret) + eg_pi->ulv.supported = false; + } + + table->driverState = table->initialState; + + return rv770_copy_bytes_to_smc(rdev, + pi->state_table_start, + (u8 *)table, + sizeof(RV770_SMC_STATETABLE), + pi->sram_end); +} + +static int btc_reset_to_default(struct radeon_device *rdev) +{ + if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK) + return -EINVAL; + + return 0; +} + +static void btc_stop_smc(struct radeon_device *rdev) +{ + int i; + + for (i = 0; i < rdev->usec_timeout; i++) { + if (((RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK) >> LB_SYNC_RESET_SEL_SHIFT) != 1) + break; + udelay(1); + } + udelay(100); + + r7xx_stop_smc(rdev); +} + +static void btc_read_arb_registers(struct radeon_device *rdev) +{ + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + struct evergreen_arb_registers *arb_registers = + &eg_pi->bootup_arb_registers; + + arb_registers->mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING); + arb_registers->mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); + arb_registers->mc_arb_rfsh_rate = RREG32(MC_ARB_RFSH_RATE); + arb_registers->mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME); +} + + +static void btc_set_arb0_registers(struct radeon_device *rdev, + struct evergreen_arb_registers *arb_registers) +{ + u32 val; + + WREG32(MC_ARB_DRAM_TIMING, arb_registers->mc_arb_dram_timing); + WREG32(MC_ARB_DRAM_TIMING2, arb_registers->mc_arb_dram_timing2); + + val = (arb_registers->mc_arb_rfsh_rate & POWERMODE0_MASK) >> + POWERMODE0_SHIFT; + WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK); + + val = (arb_registers->mc_arb_burst_time & STATE0_MASK) >> + STATE0_SHIFT; + WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK); +} + +static void btc_set_boot_state_timing(struct radeon_device *rdev) +{ + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + + if (eg_pi->ulv.supported) + btc_set_arb0_registers(rdev, &eg_pi->bootup_arb_registers); +} + +static bool btc_is_state_ulv_compatible(struct radeon_device *rdev, + struct radeon_ps *radeon_state) +{ + struct rv7xx_ps *state = rv770_get_ps(radeon_state); + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl; + + if (state->low.mclk != ulv_pl->mclk) + return false; + + if (state->low.vddci != ulv_pl->vddci) + return false; + + /* XXX check minclocks, etc. */ + + return true; +} + + +static int btc_set_ulv_dram_timing(struct radeon_device *rdev) +{ + u32 val; + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl; + + radeon_atom_set_engine_dram_timings(rdev, + ulv_pl->sclk, + ulv_pl->mclk); + + val = rv770_calculate_memory_refresh_rate(rdev, ulv_pl->sclk); + WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK); + + val = cypress_calculate_burst_time(rdev, ulv_pl->sclk, ulv_pl->mclk); + WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK); + + return 0; +} + +static int btc_enable_ulv(struct radeon_device *rdev) +{ + if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) != PPSMC_Result_OK) + return -EINVAL; + + return 0; +} + +static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev) +{ + int ret = 0; + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps; + + if (eg_pi->ulv.supported) { + if (btc_is_state_ulv_compatible(rdev, radeon_new_state)) { + // Set ARB[0] to reflect the DRAM timing needed for ULV. + ret = btc_set_ulv_dram_timing(rdev); + if (ret == 0) + ret = btc_enable_ulv(rdev); + } + } + + return ret; +} + +static bool btc_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg) +{ + bool result = true; + + switch (in_reg) { + case MC_SEQ_RAS_TIMING >> 2: + *out_reg = MC_SEQ_RAS_TIMING_LP >> 2; + break; + case MC_SEQ_CAS_TIMING >> 2: + *out_reg = MC_SEQ_CAS_TIMING_LP >> 2; + break; + case MC_SEQ_MISC_TIMING >> 2: + *out_reg = MC_SEQ_MISC_TIMING_LP >> 2; + break; + case MC_SEQ_MISC_TIMING2 >> 2: + *out_reg = MC_SEQ_MISC_TIMING2_LP >> 2; + break; + case MC_SEQ_RD_CTL_D0 >> 2: + *out_reg = MC_SEQ_RD_CTL_D0_LP >> 2; + break; + case MC_SEQ_RD_CTL_D1 >> 2: + *out_reg = MC_SEQ_RD_CTL_D1_LP >> 2; + break; + case MC_SEQ_WR_CTL_D0 >> 2: + *out_reg = MC_SEQ_WR_CTL_D0_LP >> 2; + break; + case MC_SEQ_WR_CTL_D1 >> 2: + *out_reg = MC_SEQ_WR_CTL_D1_LP >> 2; + break; + case MC_PMG_CMD_EMRS >> 2: + *out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2; + break; + case MC_PMG_CMD_MRS >> 2: + *out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2; + break; + case MC_PMG_CMD_MRS1 >> 2: + *out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2; + break; + default: + result = false; + break; + } + + return result; +} + +static void btc_set_valid_flag(struct evergreen_mc_reg_table *table) +{ + u8 i, j; + + for (i = 0; i < table->last; i++) { + for (j = 1; j < table->num_entries; j++) { + if (table->mc_reg_table_entry[j-1].mc_data[i] != + table->mc_reg_table_entry[j].mc_data[i]) { + table->valid_flag |= (1 << i); + break; + } + } + } +} + +static int btc_set_mc_special_registers(struct radeon_device *rdev, + struct evergreen_mc_reg_table *table) +{ + struct rv7xx_power_info *pi = rv770_get_pi(rdev); + u8 i, j, k; + u32 tmp; + + for (i = 0, j = table->last; i < table->last; i++) { + switch (table->mc_reg_address[i].s1) { + case MC_SEQ_MISC1 >> 2: + tmp = RREG32(MC_PMG_CMD_EMRS); + table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2; + table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + ((tmp & 0xffff0000)) | + ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16); + } + j++; + + if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) + return -EINVAL; + + tmp = RREG32(MC_PMG_CMD_MRS); + table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2; + table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (tmp & 0xffff0000) | + (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); + if (!pi->mem_gddr5) + table->mc_reg_table_entry[k].mc_data[j] |= 0x100; + } + j++; + + if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) + return -EINVAL; + break; + case MC_SEQ_RESERVE_M >> 2: + tmp = RREG32(MC_PMG_CMD_MRS1); + table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2; + table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2; + for (k = 0; k < table->num_entries; k++) { + table->mc_reg_table_entry[k].mc_data[j] = + (tmp & 0xffff0000) | + (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); + } + j++; + + if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) + return -EINVAL; + break; + default: + break; + } + } + + table->last = j; + + return 0; +} + +static void btc_set_s0_mc_reg_index(struct evergreen_mc_reg_table *table) +{ + u32 i; + u16 address; + + for (i = 0; i < table->last; i++) { + table->mc_reg_address[i].s0 = + btc_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ? + address : table->mc_reg_address[i].s1; + } +} + +static int btc_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table, + struct evergreen_mc_reg_table *eg_table) +{ + u8 i, j; + + if (table->last > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE) + return -EINVAL; + + if (table->num_entries > MAX_AC_TIMING_ENTRIES) + return -EINVAL; + + for (i = 0; i < table->last; i++) + eg_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1; + eg_table->last = table->last; + + for (i = 0; i < table->num_entries; i++) { + eg_table->mc_reg_table_entry[i].mclk_max = + table->mc_reg_table_entry[i].mclk_max; + for(j = 0; j < table->last; j++) + eg_table->mc_reg_table_entry[i].mc_data[j] = + table->mc_reg_table_entry[i].mc_data[j]; + } + eg_table->num_entries = table->num_entries; + + return 0; +} + +static int btc_initialize_mc_reg_table(struct radeon_device *rdev) +{ + int ret; + struct atom_mc_reg_table *table; + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + struct evergreen_mc_reg_table *eg_table = &eg_pi->mc_reg_table; + u8 module_index = rv770_get_memory_module_index(rdev); + + table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL); + if (!table) + return -ENOMEM; + + /* Program additional LP registers that are no longer programmed by VBIOS */ + WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING)); + WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING)); + WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING)); + WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2)); + WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0)); + WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1)); + WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0)); + WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1)); + WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS)); + WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS)); + WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1)); + + ret = radeon_atom_init_mc_reg_table(rdev, module_index, table); + + if (ret) + goto init_mc_done; + + ret = btc_copy_vbios_mc_reg_table(table, eg_table); + + if (ret) + goto init_mc_done; + + btc_set_s0_mc_reg_index(eg_table); + ret = btc_set_mc_special_registers(rdev, eg_table); + + if (ret) + goto init_mc_done; + + btc_set_valid_flag(eg_table); + +init_mc_done: + kfree(table); + + return ret; +} + +static void btc_init_stutter_mode(struct radeon_device *rdev) +{ + struct rv7xx_power_info *pi = rv770_get_pi(rdev); + u32 tmp; + + if (pi->mclk_stutter_mode_threshold) { + if (pi->mem_gddr5) { + tmp = RREG32(MC_PMG_AUTO_CFG); + if ((0x200 & tmp) == 0) { + tmp = (tmp & 0xfffffc0b) | 0x204; + WREG32(MC_PMG_AUTO_CFG, tmp); + } + } + } +} + +void btc_dpm_reset_asic(struct radeon_device *rdev) +{ + rv770_restrict_performance_levels_before_switch(rdev); + btc_disable_ulv(rdev); + btc_set_boot_state_timing(rdev); + rv770_set_boot_state(rdev); +} + +int btc_dpm_set_power_state(struct radeon_device *rdev) +{ + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + + btc_disable_ulv(rdev); + btc_set_boot_state_timing(rdev); + rv770_restrict_performance_levels_before_switch(rdev); + + if (eg_pi->pcie_performance_request) + cypress_notify_link_speed_change_before_state_change(rdev); + + rv770_halt_smc(rdev); + cypress_upload_sw_state(rdev); + + if (eg_pi->dynamic_ac_timing) + cypress_upload_mc_reg_table(rdev); + + cypress_program_memory_timing_parameters(rdev); + + rv770_resume_smc(rdev); + rv770_set_sw_state(rdev); + + if (eg_pi->pcie_performance_request) + cypress_notify_link_speed_change_after_state_change(rdev); + + btc_set_power_state_conditionally_enable_ulv(rdev); + +#if 0 + /* XXX */ + rv770_unrestrict_performance_levels_after_switch(rdev); +#endif + + return 0; +} + +int btc_dpm_enable(struct radeon_device *rdev) +{ + struct rv7xx_power_info *pi = rv770_get_pi(rdev); + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + + if (pi->gfx_clock_gating) + btc_cg_clock_gating_default(rdev); + + if (btc_dpm_enabled(rdev)) + return -EINVAL; + + if (pi->mg_clock_gating) + btc_mg_clock_gating_default(rdev); + + if (eg_pi->ls_clock_gating) + btc_ls_clock_gating_default(rdev); + + if (pi->voltage_control) { + rv770_enable_voltage_control(rdev, true); + cypress_construct_voltage_tables(rdev); + } + + if (pi->mvdd_control) + cypress_get_mvdd_configuration(rdev); + + if (eg_pi->dynamic_ac_timing) + btc_initialize_mc_reg_table(rdev); + + if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS) + rv770_enable_backbias(rdev, true); + + if (pi->dynamic_ss) + cypress_enable_spread_spectrum(rdev, true); + + if (pi->thermal_protection) + rv770_enable_thermal_protection(rdev, true); + + rv770_setup_bsp(rdev); + rv770_program_git(rdev); + rv770_program_tp(rdev); + rv770_program_tpp(rdev); + rv770_program_sstp(rdev); + rv770_program_engine_speed_parameters(rdev); + cypress_enable_display_gap(rdev); + rv770_program_vc(rdev); + + if (pi->dynamic_pcie_gen2) + btc_enable_dynamic_pcie_gen2(rdev, true); + + if (rv770_upload_firmware(rdev)) + return -EINVAL; + + cypress_get_table_locations(rdev); + btc_init_smc_table(rdev); + + if (eg_pi->dynamic_ac_timing) + cypress_populate_mc_reg_table(rdev); + + cypress_program_response_times(rdev); + r7xx_start_smc(rdev); + cypress_notify_smc_display_change(rdev, false); + cypress_enable_sclk_control(rdev, true); + + if (eg_pi->memory_transition) + cypress_enable_mclk_control(rdev, true); + + cypress_start_dpm(rdev); + + if (pi->gfx_clock_gating) + btc_cg_clock_gating_enable(rdev, true); + + if (pi->mg_clock_gating) + btc_mg_clock_gating_enable(rdev, true); + + if (eg_pi->ls_clock_gating) + btc_ls_clock_gating_enable(rdev, true); + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { + PPSMC_Result result; + + rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + rdev->irq.dpm_thermal = true; + radeon_irq_set(rdev); + result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); + + if (result != PPSMC_Result_OK) + DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); + } + + rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); + + btc_init_stutter_mode(rdev); + + return 0; +}; + +void btc_dpm_disable(struct radeon_device *rdev) +{ + struct rv7xx_power_info *pi = rv770_get_pi(rdev); + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + + if (!btc_dpm_enabled(rdev)) + return; + + rv770_clear_vc(rdev); + + if (pi->thermal_protection) + rv770_enable_thermal_protection(rdev, false); + + if (pi->dynamic_pcie_gen2) + btc_enable_dynamic_pcie_gen2(rdev, false); + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { + rdev->irq.dpm_thermal = false; + radeon_irq_set(rdev); + } + + if (pi->gfx_clock_gating) + btc_cg_clock_gating_enable(rdev, false); + + if (pi->mg_clock_gating) + btc_mg_clock_gating_enable(rdev, false); + + if (eg_pi->ls_clock_gating) + btc_ls_clock_gating_enable(rdev, false); + + rv770_stop_dpm(rdev); + btc_reset_to_default(rdev); + btc_stop_smc(rdev); + cypress_enable_spread_spectrum(rdev, false); +} + +void btc_dpm_setup_asic(struct radeon_device *rdev) +{ + struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + + rv770_get_memory_type(rdev); + rv740_read_clock_registers(rdev); + btc_read_arb_registers(rdev); + rv770_read_voltage_smio_registers(rdev); + + if (eg_pi->pcie_performance_request) + cypress_advertise_gen2_capability(rdev); + + rv770_get_pcie_gen2_status(rdev); + rv770_enable_acpi_pm(rdev); +} + +int btc_dpm_init(struct radeon_device *rdev) +{ + struct rv7xx_power_info *pi; + struct evergreen_power_info *eg_pi; + int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); + u16 data_offset, size; + u8 frev, crev; + struct atom_clock_dividers dividers; + int ret; + + eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL); + if (eg_pi == NULL) + return -ENOMEM; + rdev->pm.dpm.priv = eg_pi; + pi = &eg_pi->rv7xx; + + rv770_get_max_vddc(rdev); + + eg_pi->ulv.supported = false; + pi->acpi_vddc = 0; + eg_pi->acpi_vddci = 0; + pi->min_vddc_in_table = 0; + pi->max_vddc_in_table = 0; + + ret = rv7xx_parse_power_table(rdev); + if (ret) + return ret; + + if (rdev->pm.dpm.voltage_response_time == 0) + rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT; + if (rdev->pm.dpm.backbias_response_time == 0) + rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT; + + ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, + 0, false, ÷rs); + if (ret) + pi->ref_div = dividers.ref_div + 1; + else + pi->ref_div = R600_REFERENCEDIVIDER_DFLT; + + pi->mclk_strobe_mode_threshold = 40000; + pi->mclk_edc_enable_threshold = 40000; + eg_pi->mclk_edc_wr_enable_threshold = 40000; + + pi->voltage_control = + radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC); + + pi->mvdd_control = + radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC); + + eg_pi->vddci_control = + radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI); + + if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, + &frev, &crev, &data_offset)) { + pi->sclk_ss = true; + pi->mclk_ss = true; + pi->dynamic_ss = true; + } else { + pi->sclk_ss = false; + pi->mclk_ss = false; + pi->dynamic_ss = true; + } + + pi->asi = RV770_ASI_DFLT; + pi->pasi = CYPRESS_HASI_DFLT; + pi->vrc = CYPRESS_VRC_DFLT; + + pi->power_gating = false; + + pi->gfx_clock_gating = true; + + pi->mg_clock_gating = true; + pi->mgcgtssm = true; + eg_pi->ls_clock_gating = false; + eg_pi->sclk_deep_sleep = false; + + pi->dynamic_pcie_gen2 = true; + + if (pi->gfx_clock_gating && + (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) + pi->thermal_protection = true; + else + pi->thermal_protection = false; + + pi->display_gap = true; + + if (rdev->flags & RADEON_IS_MOBILITY) + pi->dcodt = true; + else + pi->dcodt = false; + + pi->ulps = true; + + eg_pi->dynamic_ac_timing = true; + eg_pi->abm = true; + eg_pi->mcls = true; + eg_pi->light_sleep = true; + eg_pi->memory_transition = true; +#if defined(CONFIG_ACPI) + eg_pi->pcie_performance_request = + radeon_acpi_is_pcie_performance_request_supported(rdev); +#else + eg_pi->pcie_performance_request = false; +#endif + + if (rdev->family == CHIP_BARTS) + eg_pi->dll_default_on = true; + else + eg_pi->dll_default_on = false; + + eg_pi->sclk_deep_sleep = false; + if (ASIC_IS_LOMBOK(rdev)) + pi->mclk_stutter_mode_threshold = 30000; + else + pi->mclk_stutter_mode_threshold = 0; + + pi->sram_end = SMC_RAM_END; + + return 0; +} + +void btc_dpm_fini(struct radeon_device *rdev) +{ + int i; + + for (i = 0; i < rdev->pm.dpm.num_ps; i++) { + kfree(rdev->pm.dpm.ps[i].ps_priv); + } + kfree(rdev->pm.dpm.ps); + kfree(rdev->pm.dpm.priv); +} diff --git a/drivers/gpu/drm/radeon/btc_dpm.h b/drivers/gpu/drm/radeon/btc_dpm.h new file mode 100644 index 000000000000..a095d4054fcb --- /dev/null +++ b/drivers/gpu/drm/radeon/btc_dpm.h @@ -0,0 +1,32 @@ +/* + * Copyright 2011 Advanced Micro Devices, Inc. + * + * 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. + * + */ +#ifndef __BTC_DPM_H__ +#define __BTC_DPM_H__ + +#define BARTS_MGCGCGTSSMCTRL_DFLT 0x81944000 +#define TURKS_MGCGCGTSSMCTRL_DFLT 0x6e944000 +#define CAICOS_MGCGCGTSSMCTRL_DFLT 0x46944040 +#define BTC_CGULVPARAMETER_DFLT 0x00040035 +#define BTC_CGULVCONTROL_DFLT 0x00001450 + +#endif diff --git a/drivers/gpu/drm/radeon/btcd.h b/drivers/gpu/drm/radeon/btcd.h new file mode 100644 index 000000000000..29e32de7e025 --- /dev/null +++ b/drivers/gpu/drm/radeon/btcd.h @@ -0,0 +1,181 @@ +/* + * Copyright 2010 Advanced Micro Devices, Inc. + * + * 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: Alex Deucher + */ +#ifndef _BTCD_H_ +#define _BTCD_H_ + +/* pm registers */ + +#define GENERAL_PWRMGT 0x63c +# define GLOBAL_PWRMGT_EN (1 << 0) +# define STATIC_PM_EN (1 << 1) +# define THERMAL_PROTECTION_DIS (1 << 2) +# define THERMAL_PROTECTION_TYPE (1 << 3) +# define ENABLE_GEN2PCIE (1 << 4) +# define ENABLE_GEN2XSP (1 << 5) +# define SW_SMIO_INDEX(x) ((x) << 6) +# define SW_SMIO_INDEX_MASK (3 << 6) +# define SW_SMIO_INDEX_SHIFT 6 +# define LOW_VOLT_D2_ACPI (1 << 8) +# define LOW_VOLT_D3_ACPI (1 << 9) +# define VOLT_PWRMGT_EN (1 << 10) +# define BACKBIAS_PAD_EN (1 << 18) +# define BACKBIAS_VALUE (1 << 19) +# define DYN_SPREAD_SPECTRUM_EN (1 << 23) +# define AC_DC_SW (1 << 24) + +#define CG_BIF_REQ_AND_RSP 0x7f4 +#define CG_CLIENT_REQ(x) ((x) << 0) +#define CG_CLIENT_REQ_MASK (0xff << 0) +#define CG_CLIENT_REQ_SHIFT 0 +#define CG_CLIENT_RESP(x) ((x) << 8) +#define CG_CLIENT_RESP_MASK (0xff << 8) +#define CG_CLIENT_RESP_SHIFT 8 +#define CLIENT_CG_REQ(x) ((x) << 16) +#define CLIENT_CG_REQ_MASK (0xff << 16) +#define CLIENT_CG_REQ_SHIFT 16 +#define CLIENT_CG_RESP(x) ((x) << 24) +#define CLIENT_CG_RESP_MASK (0xff << 24) +#define CLIENT_CG_RESP_SHIFT 24 + +#define SCLK_PSKIP_CNTL 0x8c0 +#define PSKIP_ON_ALLOW_STOP_HI(x) ((x) << 16) +#define PSKIP_ON_ALLOW_STOP_HI_MASK (0xff << 16) +#define PSKIP_ON_ALLOW_STOP_HI_SHIFT 16 + +#define CG_ULV_CONTROL 0x8c8 +#define CG_ULV_PARAMETER 0x8cc + +#define MC_ARB_DRAM_TIMING 0x2774 +#define MC_ARB_DRAM_TIMING2 0x2778 + +#define MC_ARB_RFSH_RATE 0x27b0 +#define POWERMODE0(x) ((x) << 0) +#define POWERMODE0_MASK (0xff << 0) +#define POWERMODE0_SHIFT 0 +#define POWERMODE1(x) ((x) << 8) +#define POWERMODE1_MASK (0xff << 8) +#define POWERMODE1_SHIFT 8 +#define POWERMODE2(x) ((x) << 16) +#define POWERMODE2_MASK (0xff << 16) +#define POWERMODE2_SHIFT 16 +#define POWERMODE3(x) ((x) << 24) +#define POWERMODE3_MASK (0xff << 24) +#define POWERMODE3_SHIFT 24 + +#define MC_ARB_BURST_TIME 0x2808 +#define STATE0(x) ((x) << 0) +#define STATE0_MASK (0x1f << 0) +#define STATE0_SHIFT 0 +#define STATE1(x) ((x) << 5) +#define STATE1_MASK (0x1f << 5) +#define STATE1_SHIFT 5 +#define STATE2(x) ((x) << 10) +#define STATE2_MASK (0x1f << 10) +#define STATE2_SHIFT 10 +#define STATE3(x) ((x) << 15) +#define STATE3_MASK (0x1f << 15) +#define STATE3_SHIFT 15 + +#define MC_SEQ_RAS_TIMING 0x28a0 +#define MC_SEQ_CAS_TIMING 0x28a4 +#define MC_SEQ_MISC_TIMING 0x28a8 +#define MC_SEQ_MISC_TIMING2 0x28ac + +#define MC_SEQ_RD_CTL_D0 0x28b4 +#define MC_SEQ_RD_CTL_D1 0x28b8 +#define MC_SEQ_WR_CTL_D0 0x28bc +#define MC_SEQ_WR_CTL_D1 0x28c0 + +#define MC_PMG_AUTO_CFG 0x28d4 + +#define MC_SEQ_STATUS_M 0x29f4 +# define PMG_PWRSTATE (1 << 16) + +#define MC_SEQ_MISC0 0x2a00 +#define MC_SEQ_MISC0_GDDR5_SHIFT 28 +#define MC_SEQ_MISC0_GDDR5_MASK 0xf0000000 +#define MC_SEQ_MISC0_GDDR5_VALUE 5 +#define MC_SEQ_MISC1 0x2a04 +#define MC_SEQ_RESERVE_M 0x2a08 +#define MC_PMG_CMD_EMRS 0x2a0c + +#define MC_SEQ_MISC3 0x2a2c + +#define MC_SEQ_MISC5 0x2a54 +#define MC_SEQ_MISC6 0x2a58 + +#define MC_SEQ_MISC7 0x2a64 + +#define MC_SEQ_CG 0x2a68 +#define CG_SEQ_REQ(x) ((x) << 0) +#define CG_SEQ_REQ_MASK (0xff << 0) +#define CG_SEQ_REQ_SHIFT 0 +#define CG_SEQ_RESP(x) ((x) << 8) +#define CG_SEQ_RESP_MASK (0xff << 8) +#define CG_SEQ_RESP_SHIFT 8 +#define SEQ_CG_REQ(x) ((x) << 16) +#define SEQ_CG_REQ_MASK (0xff << 16) +#define SEQ_CG_REQ_SHIFT 16 +#define SEQ_CG_RESP(x) ((x) << 24) +#define SEQ_CG_RESP_MASK (0xff << 24) +#define SEQ_CG_RESP_SHIFT 24 +#define MC_SEQ_RAS_TIMING_LP 0x2a6c +#define MC_SEQ_CAS_TIMING_LP 0x2a70 +#define MC_SEQ_MISC_TIMING_LP 0x2a74 +#define MC_SEQ_MISC_TIMING2_LP 0x2a78 +#define MC_SEQ_WR_CTL_D0_LP 0x2a7c +#define MC_SEQ_WR_CTL_D1_LP 0x2a80 +#define MC_SEQ_PMG_CMD_EMRS_LP 0x2a84 +#define MC_SEQ_PMG_CMD_MRS_LP 0x2a88 + +#define MC_PMG_CMD_MRS 0x2aac + +#define MC_SEQ_RD_CTL_D0_LP 0x2b1c +#define MC_SEQ_RD_CTL_D1_LP 0x2b20 + +#define MC_PMG_CMD_MRS1 0x2b44 +#define MC_SEQ_PMG_CMD_MRS1_LP 0x2b48 + +#define LB_SYNC_RESET_SEL 0x6b28 +#define LB_SYNC_RESET_SEL_MASK (3 << 0) +#define LB_SYNC_RESET_SEL_SHIFT 0 + +/* PCIE link stuff */ +#define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ +# define LC_GEN2_EN_STRAP (1 << 0) +# define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) +# define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) +# define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) +# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) +# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 +# define LC_CURRENT_DATA_RATE (1 << 11) +# define LC_HW_VOLTAGE_IF_CONTROL(x) ((x) << 12) +# define LC_HW_VOLTAGE_IF_CONTROL_MASK (3 << 12) +# define LC_HW_VOLTAGE_IF_CONTROL_SHIFT 12 +# define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) +# define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) +# define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) +# define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) + +#endif diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index c73d71340d27..74077626256a 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -180,13 +180,16 @@ extern int sumo_rlc_init(struct radeon_device *rdev); MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); MODULE_FIRMWARE("radeon/BARTS_me.bin"); MODULE_FIRMWARE("radeon/BARTS_mc.bin"); +MODULE_FIRMWARE("radeon/BARTS_smc.bin"); MODULE_FIRMWARE("radeon/BTC_rlc.bin"); MODULE_FIRMWARE("radeon/TURKS_pfp.bin"); MODULE_FIRMWARE("radeon/TURKS_me.bin"); MODULE_FIRMWARE("radeon/TURKS_mc.bin"); +MODULE_FIRMWARE("radeon/TURKS_smc.bin"); MODULE_FIRMWARE("radeon/CAICOS_pfp.bin"); MODULE_FIRMWARE("radeon/CAICOS_me.bin"); MODULE_FIRMWARE("radeon/CAICOS_mc.bin"); +MODULE_FIRMWARE("radeon/CAICOS_smc.bin"); MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin"); MODULE_FIRMWARE("radeon/CAYMAN_me.bin"); MODULE_FIRMWARE("radeon/CAYMAN_mc.bin"); @@ -683,6 +686,7 @@ int ni_init_microcode(struct radeon_device *rdev) const char *chip_name; const char *rlc_chip_name; size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size; + size_t smc_req_size = 0; char fw_name[30]; int err; @@ -703,6 +707,7 @@ int ni_init_microcode(struct radeon_device *rdev) me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; mc_req_size = BTC_MC_UCODE_SIZE * 4; + smc_req_size = ALIGN(BARTS_SMC_UCODE_SIZE, 4); break; case CHIP_TURKS: chip_name = "TURKS"; @@ -711,6 +716,7 @@ int ni_init_microcode(struct radeon_device *rdev) me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; mc_req_size = BTC_MC_UCODE_SIZE * 4; + smc_req_size = ALIGN(TURKS_SMC_UCODE_SIZE, 4); break; case CHIP_CAICOS: chip_name = "CAICOS"; @@ -719,6 +725,7 @@ int ni_init_microcode(struct radeon_device *rdev) me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; mc_req_size = BTC_MC_UCODE_SIZE * 4; + smc_req_size = ALIGN(CAICOS_SMC_UCODE_SIZE, 4); break; case CHIP_CAYMAN: chip_name = "CAYMAN"; @@ -789,6 +796,20 @@ int ni_init_microcode(struct radeon_device *rdev) err = -EINVAL; } } + + if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAICOS)) { + snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); + err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev); + if (err) + goto out; + if (rdev->smc_fw->size != smc_req_size) { + printk(KERN_ERR + "ni_mc: Bogus length %zu in firmware \"%s\"\n", + rdev->mc_fw->size, fw_name); + err = -EINVAL; + } + } + out: platform_device_unregister(pdev); diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 4ca134bef689..f9c3f1c1f3e2 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1722,6 +1722,18 @@ static struct radeon_asic btc_asic = { .set_uvd_clocks = &evergreen_set_uvd_clocks, .get_temperature = &evergreen_get_temp, }, + .dpm = { + .init = &btc_dpm_init, + .setup_asic = &btc_dpm_setup_asic, + .enable = &btc_dpm_enable, + .disable = &btc_dpm_disable, + .set_power_state = &btc_dpm_set_power_state, + .display_configuration_changed = &cypress_dpm_display_configuration_changed, + .fini = &btc_dpm_fini, + .get_sclk = &rv770_dpm_get_sclk, + .get_mclk = &rv770_dpm_get_mclk, + .print_power_state = &rv770_dpm_print_power_state, + }, .pflip = { .pre_page_flip = &evergreen_pre_page_flip, .page_flip = &evergreen_page_flip, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index c9a17e0a5f91..c41a54523a1d 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -536,6 +536,12 @@ void cypress_dpm_disable(struct radeon_device *rdev); int cypress_dpm_set_power_state(struct radeon_device *rdev); void cypress_dpm_display_configuration_changed(struct radeon_device *rdev); void cypress_dpm_fini(struct radeon_device *rdev); +int btc_dpm_init(struct radeon_device *rdev); +void btc_dpm_setup_asic(struct radeon_device *rdev); +int btc_dpm_enable(struct radeon_device *rdev); +void btc_dpm_disable(struct radeon_device *rdev); +int btc_dpm_set_power_state(struct radeon_device *rdev); +void btc_dpm_fini(struct radeon_device *rdev); /* * cayman diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index e1d07969f5f0..7e4377f8c477 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1046,6 +1046,9 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_JUNIPER: case CHIP_CYPRESS: case CHIP_HEMLOCK: + case CHIP_BARTS: + case CHIP_TURKS: + case CHIP_CAICOS: if (radeon_dpm == 1) rdev->pm.pm_method = PM_METHOD_DPM; else diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h index cb9c8135875d..e592e2704577 100644 --- a/drivers/gpu/drm/radeon/radeon_ucode.h +++ b/drivers/gpu/drm/radeon/radeon_ucode.h @@ -85,4 +85,19 @@ #define CYPRESS_SMC_INT_VECTOR_START 0xffc0 #define CYPRESS_SMC_INT_VECTOR_SIZE 0x0040 +#define BARTS_SMC_UCODE_START 0x0100 +#define BARTS_SMC_UCODE_SIZE 0x6107 +#define BARTS_SMC_INT_VECTOR_START 0xffc0 +#define BARTS_SMC_INT_VECTOR_SIZE 0x0040 + +#define TURKS_SMC_UCODE_START 0x0100 +#define TURKS_SMC_UCODE_SIZE 0x605b +#define TURKS_SMC_INT_VECTOR_START 0xffc0 +#define TURKS_SMC_INT_VECTOR_SIZE 0x0040 + +#define CAICOS_SMC_UCODE_START 0x0100 +#define CAICOS_SMC_UCODE_SIZE 0x5fbd +#define CAICOS_SMC_INT_VECTOR_START 0xffc0 +#define CAICOS_SMC_INT_VECTOR_SIZE 0x0040 + #endif diff --git a/drivers/gpu/drm/radeon/rv770_smc.c b/drivers/gpu/drm/radeon/rv770_smc.c index 168aedbffa7e..0078c599248f 100644 --- a/drivers/gpu/drm/radeon/rv770_smc.c +++ b/drivers/gpu/drm/radeon/rv770_smc.c @@ -194,6 +194,66 @@ static const u8 cypress_smc_int_vectors[] = 0x04, 0xF6, 0x04, 0xF6 }; +static const u8 barts_smc_int_vectors[] = +{ + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x12, 0xAA, + 0x0C, 0x2F, 0x15, 0xF6, + 0x15, 0xF6, 0x05, 0x0A, + 0x05, 0x0A, 0x05, 0x0A +}; + +static const u8 turks_smc_int_vectors[] = +{ + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x12, 0xAA, + 0x0C, 0x2F, 0x15, 0xF6, + 0x15, 0xF6, 0x05, 0x0A, + 0x05, 0x0A, 0x05, 0x0A +}; + +static const u8 caicos_smc_int_vectors[] = +{ + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x0C, 0x14, + 0x0C, 0x14, 0x12, 0xAA, + 0x0C, 0x2F, 0x15, 0xF6, + 0x15, 0xF6, 0x05, 0x0A, + 0x05, 0x0A, 0x05, 0x0A +}; + int rv770_set_smc_sram_address(struct radeon_device *rdev, u16 smc_address, u16 limit) { @@ -463,6 +523,27 @@ int rv770_load_smc_ucode(struct radeon_device *rdev, int_vect_start_address = CYPRESS_SMC_INT_VECTOR_START; int_vect_size = CYPRESS_SMC_INT_VECTOR_SIZE; break; + case CHIP_BARTS: + ucode_start_address = BARTS_SMC_UCODE_START; + ucode_size = BARTS_SMC_UCODE_SIZE; + int_vect = (const u8 *)&barts_smc_int_vectors; + int_vect_start_address = BARTS_SMC_INT_VECTOR_START; + int_vect_size = BARTS_SMC_INT_VECTOR_SIZE; + break; + case CHIP_TURKS: + ucode_start_address = TURKS_SMC_UCODE_START; + ucode_size = TURKS_SMC_UCODE_SIZE; + int_vect = (const u8 *)&turks_smc_int_vectors; + int_vect_start_address = TURKS_SMC_INT_VECTOR_START; + int_vect_size = TURKS_SMC_INT_VECTOR_SIZE; + break; + case CHIP_CAICOS: + ucode_start_address = CAICOS_SMC_UCODE_START; + ucode_size = CAICOS_SMC_UCODE_SIZE; + int_vect = (const u8 *)&caicos_smc_int_vectors; + int_vect_start_address = CAICOS_SMC_INT_VECTOR_START; + int_vect_size = CAICOS_SMC_INT_VECTOR_SIZE; + break; default: DRM_ERROR("unknown asic in smc ucode loader\n"); BUG(); -- 2.30.2