1926deccbSFrançois Tigeot /*
2926deccbSFrançois Tigeot * Copyright 2011 Advanced Micro Devices, Inc.
3926deccbSFrançois Tigeot *
4926deccbSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a
5926deccbSFrançois Tigeot * copy of this software and associated documentation files (the "Software"),
6926deccbSFrançois Tigeot * to deal in the Software without restriction, including without limitation
7926deccbSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8926deccbSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the
9926deccbSFrançois Tigeot * Software is furnished to do so, subject to the following conditions:
10926deccbSFrançois Tigeot *
11926deccbSFrançois Tigeot * The above copyright notice and this permission notice shall be included in
12926deccbSFrançois Tigeot * all copies or substantial portions of the Software.
13926deccbSFrançois Tigeot *
14926deccbSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15926deccbSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16926deccbSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17926deccbSFrançois Tigeot * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18926deccbSFrançois Tigeot * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19926deccbSFrançois Tigeot * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20926deccbSFrançois Tigeot * OTHER DEALINGS IN THE SOFTWARE.
21926deccbSFrançois Tigeot *
22926deccbSFrançois Tigeot * Authors: Alex Deucher
23926deccbSFrançois Tigeot */
2457e252bfSMichael Neumann #include <linux/firmware.h>
25*3f2dd94aSFrançois Tigeot #include <linux/slab.h>
26fcd4983fSzrj #include <linux/module.h>
27fcd4983fSzrj #include <drm/drmP.h>
28926deccbSFrançois Tigeot #include "radeon.h"
29926deccbSFrançois Tigeot #include "radeon_asic.h"
30c59a5c48SFrançois Tigeot #include "radeon_audio.h"
3183b4b9b9SFrançois Tigeot #include <drm/radeon_drm.h>
32926deccbSFrançois Tigeot #include "sid.h"
33926deccbSFrançois Tigeot #include "atom.h"
34926deccbSFrançois Tigeot #include "si_blit_shaders.h"
3557e252bfSMichael Neumann #include "clearstate_si.h"
3657e252bfSMichael Neumann #include "radeon_ucode.h"
37926deccbSFrançois Tigeot
38b403bed8SMichael Neumann
39fcd4983fSzrj MODULE_FIRMWARE("radeon/TAHITI_pfp.bin");
40fcd4983fSzrj MODULE_FIRMWARE("radeon/TAHITI_me.bin");
4157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TAHITI_ce.bin");
4257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TAHITI_mc.bin");
43c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
4457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
4557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TAHITI_smc.bin");
46cb754608SImre Vadász
47cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_pfp.bin");
48cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_me.bin");
49cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_ce.bin");
50cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_mc.bin");
51cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_rlc.bin");
52cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_smc.bin");
53cb754608SImre Vadász
5457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
5557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
5657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
5757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
58c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
5957e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
6057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
61cb754608SImre Vadász
62cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_pfp.bin");
63cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_me.bin");
64cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_ce.bin");
65cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_mc.bin");
66cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_rlc.bin");
67cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_smc.bin");
681dedbd3bSFrançois Tigeot MODULE_FIRMWARE("radeon/pitcairn_k_smc.bin");
69cb754608SImre Vadász
7057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_pfp.bin");
7157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_me.bin");
7257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_ce.bin");
7357e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_mc.bin");
74c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/VERDE_mc2.bin");
7557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_rlc.bin");
7657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_smc.bin");
77cb754608SImre Vadász
78cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_pfp.bin");
79cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_me.bin");
80cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_ce.bin");
81cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_mc.bin");
82cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_rlc.bin");
83cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_smc.bin");
841dedbd3bSFrançois Tigeot MODULE_FIRMWARE("radeon/verde_k_smc.bin");
85cb754608SImre Vadász
8657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_pfp.bin");
8757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_me.bin");
8857e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_ce.bin");
8957e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_mc.bin");
90c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/OLAND_mc2.bin");
9157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
9257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_smc.bin");
93cb754608SImre Vadász
94cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_pfp.bin");
95cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_me.bin");
96cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_ce.bin");
97cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_mc.bin");
98cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_rlc.bin");
99cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_smc.bin");
1001dedbd3bSFrançois Tigeot MODULE_FIRMWARE("radeon/oland_k_smc.bin");
101cb754608SImre Vadász
10257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
10357e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_me.bin");
10457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
10557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_mc.bin");
106c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
10757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
10857e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
10957e252bfSMichael Neumann
110cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_pfp.bin");
111cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_me.bin");
112cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_ce.bin");
113cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_mc.bin");
114cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_rlc.bin");
115cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_smc.bin");
1161dedbd3bSFrançois Tigeot MODULE_FIRMWARE("radeon/hainan_k_smc.bin");
1174be47400SFrançois Tigeot MODULE_FIRMWARE("radeon/banks_k_2_smc.bin");
1184be47400SFrançois Tigeot
1194be47400SFrançois Tigeot MODULE_FIRMWARE("radeon/si58_mc.bin");
120cb754608SImre Vadász
121c6f73aabSFrançois Tigeot static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh);
12257e252bfSMichael Neumann static void si_pcie_gen3_enable(struct radeon_device *rdev);
12357e252bfSMichael Neumann static void si_program_aspm(struct radeon_device *rdev);
1244cd92098Szrj static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
1254cd92098Szrj bool enable);
126c6f73aabSFrançois Tigeot static void si_init_pg(struct radeon_device *rdev);
127c6f73aabSFrançois Tigeot static void si_init_cg(struct radeon_device *rdev);
1284cd92098Szrj static void si_fini_pg(struct radeon_device *rdev);
1294cd92098Szrj static void si_fini_cg(struct radeon_device *rdev);
1304cd92098Szrj static void si_rlc_stop(struct radeon_device *rdev);
13157e252bfSMichael Neumann
132*3f2dd94aSFrançois Tigeot static const u32 crtc_offsets[] =
133*3f2dd94aSFrançois Tigeot {
134*3f2dd94aSFrançois Tigeot EVERGREEN_CRTC0_REGISTER_OFFSET,
135*3f2dd94aSFrançois Tigeot EVERGREEN_CRTC1_REGISTER_OFFSET,
136*3f2dd94aSFrançois Tigeot EVERGREEN_CRTC2_REGISTER_OFFSET,
137*3f2dd94aSFrançois Tigeot EVERGREEN_CRTC3_REGISTER_OFFSET,
138*3f2dd94aSFrançois Tigeot EVERGREEN_CRTC4_REGISTER_OFFSET,
139*3f2dd94aSFrançois Tigeot EVERGREEN_CRTC5_REGISTER_OFFSET
140*3f2dd94aSFrançois Tigeot };
141*3f2dd94aSFrançois Tigeot
142*3f2dd94aSFrançois Tigeot static const u32 si_disp_int_status[] =
143*3f2dd94aSFrançois Tigeot {
144*3f2dd94aSFrançois Tigeot DISP_INTERRUPT_STATUS,
145*3f2dd94aSFrançois Tigeot DISP_INTERRUPT_STATUS_CONTINUE,
146*3f2dd94aSFrançois Tigeot DISP_INTERRUPT_STATUS_CONTINUE2,
147*3f2dd94aSFrançois Tigeot DISP_INTERRUPT_STATUS_CONTINUE3,
148*3f2dd94aSFrançois Tigeot DISP_INTERRUPT_STATUS_CONTINUE4,
149*3f2dd94aSFrançois Tigeot DISP_INTERRUPT_STATUS_CONTINUE5
150*3f2dd94aSFrançois Tigeot };
151*3f2dd94aSFrançois Tigeot
152*3f2dd94aSFrançois Tigeot #define DC_HPDx_CONTROL(x) (DC_HPD1_CONTROL + (x * 0xc))
153*3f2dd94aSFrançois Tigeot #define DC_HPDx_INT_CONTROL(x) (DC_HPD1_INT_CONTROL + (x * 0xc))
154*3f2dd94aSFrançois Tigeot #define DC_HPDx_INT_STATUS_REG(x) (DC_HPD1_INT_STATUS + (x * 0xc))
155*3f2dd94aSFrançois Tigeot
15657e252bfSMichael Neumann static const u32 verde_rlc_save_restore_register_list[] =
15757e252bfSMichael Neumann {
15857e252bfSMichael Neumann (0x8000 << 16) | (0x98f4 >> 2),
15957e252bfSMichael Neumann 0x00000000,
16057e252bfSMichael Neumann (0x8040 << 16) | (0x98f4 >> 2),
16157e252bfSMichael Neumann 0x00000000,
16257e252bfSMichael Neumann (0x8000 << 16) | (0xe80 >> 2),
16357e252bfSMichael Neumann 0x00000000,
16457e252bfSMichael Neumann (0x8040 << 16) | (0xe80 >> 2),
16557e252bfSMichael Neumann 0x00000000,
16657e252bfSMichael Neumann (0x8000 << 16) | (0x89bc >> 2),
16757e252bfSMichael Neumann 0x00000000,
16857e252bfSMichael Neumann (0x8040 << 16) | (0x89bc >> 2),
16957e252bfSMichael Neumann 0x00000000,
17057e252bfSMichael Neumann (0x8000 << 16) | (0x8c1c >> 2),
17157e252bfSMichael Neumann 0x00000000,
17257e252bfSMichael Neumann (0x8040 << 16) | (0x8c1c >> 2),
17357e252bfSMichael Neumann 0x00000000,
17457e252bfSMichael Neumann (0x9c00 << 16) | (0x98f0 >> 2),
17557e252bfSMichael Neumann 0x00000000,
17657e252bfSMichael Neumann (0x9c00 << 16) | (0xe7c >> 2),
17757e252bfSMichael Neumann 0x00000000,
17857e252bfSMichael Neumann (0x8000 << 16) | (0x9148 >> 2),
17957e252bfSMichael Neumann 0x00000000,
18057e252bfSMichael Neumann (0x8040 << 16) | (0x9148 >> 2),
18157e252bfSMichael Neumann 0x00000000,
18257e252bfSMichael Neumann (0x9c00 << 16) | (0x9150 >> 2),
18357e252bfSMichael Neumann 0x00000000,
18457e252bfSMichael Neumann (0x9c00 << 16) | (0x897c >> 2),
18557e252bfSMichael Neumann 0x00000000,
18657e252bfSMichael Neumann (0x9c00 << 16) | (0x8d8c >> 2),
18757e252bfSMichael Neumann 0x00000000,
18857e252bfSMichael Neumann (0x9c00 << 16) | (0xac54 >> 2),
18957e252bfSMichael Neumann 0X00000000,
19057e252bfSMichael Neumann 0x3,
19157e252bfSMichael Neumann (0x9c00 << 16) | (0x98f8 >> 2),
19257e252bfSMichael Neumann 0x00000000,
19357e252bfSMichael Neumann (0x9c00 << 16) | (0x9910 >> 2),
19457e252bfSMichael Neumann 0x00000000,
19557e252bfSMichael Neumann (0x9c00 << 16) | (0x9914 >> 2),
19657e252bfSMichael Neumann 0x00000000,
19757e252bfSMichael Neumann (0x9c00 << 16) | (0x9918 >> 2),
19857e252bfSMichael Neumann 0x00000000,
19957e252bfSMichael Neumann (0x9c00 << 16) | (0x991c >> 2),
20057e252bfSMichael Neumann 0x00000000,
20157e252bfSMichael Neumann (0x9c00 << 16) | (0x9920 >> 2),
20257e252bfSMichael Neumann 0x00000000,
20357e252bfSMichael Neumann (0x9c00 << 16) | (0x9924 >> 2),
20457e252bfSMichael Neumann 0x00000000,
20557e252bfSMichael Neumann (0x9c00 << 16) | (0x9928 >> 2),
20657e252bfSMichael Neumann 0x00000000,
20757e252bfSMichael Neumann (0x9c00 << 16) | (0x992c >> 2),
20857e252bfSMichael Neumann 0x00000000,
20957e252bfSMichael Neumann (0x9c00 << 16) | (0x9930 >> 2),
21057e252bfSMichael Neumann 0x00000000,
21157e252bfSMichael Neumann (0x9c00 << 16) | (0x9934 >> 2),
21257e252bfSMichael Neumann 0x00000000,
21357e252bfSMichael Neumann (0x9c00 << 16) | (0x9938 >> 2),
21457e252bfSMichael Neumann 0x00000000,
21557e252bfSMichael Neumann (0x9c00 << 16) | (0x993c >> 2),
21657e252bfSMichael Neumann 0x00000000,
21757e252bfSMichael Neumann (0x9c00 << 16) | (0x9940 >> 2),
21857e252bfSMichael Neumann 0x00000000,
21957e252bfSMichael Neumann (0x9c00 << 16) | (0x9944 >> 2),
22057e252bfSMichael Neumann 0x00000000,
22157e252bfSMichael Neumann (0x9c00 << 16) | (0x9948 >> 2),
22257e252bfSMichael Neumann 0x00000000,
22357e252bfSMichael Neumann (0x9c00 << 16) | (0x994c >> 2),
22457e252bfSMichael Neumann 0x00000000,
22557e252bfSMichael Neumann (0x9c00 << 16) | (0x9950 >> 2),
22657e252bfSMichael Neumann 0x00000000,
22757e252bfSMichael Neumann (0x9c00 << 16) | (0x9954 >> 2),
22857e252bfSMichael Neumann 0x00000000,
22957e252bfSMichael Neumann (0x9c00 << 16) | (0x9958 >> 2),
23057e252bfSMichael Neumann 0x00000000,
23157e252bfSMichael Neumann (0x9c00 << 16) | (0x995c >> 2),
23257e252bfSMichael Neumann 0x00000000,
23357e252bfSMichael Neumann (0x9c00 << 16) | (0x9960 >> 2),
23457e252bfSMichael Neumann 0x00000000,
23557e252bfSMichael Neumann (0x9c00 << 16) | (0x9964 >> 2),
23657e252bfSMichael Neumann 0x00000000,
23757e252bfSMichael Neumann (0x9c00 << 16) | (0x9968 >> 2),
23857e252bfSMichael Neumann 0x00000000,
23957e252bfSMichael Neumann (0x9c00 << 16) | (0x996c >> 2),
24057e252bfSMichael Neumann 0x00000000,
24157e252bfSMichael Neumann (0x9c00 << 16) | (0x9970 >> 2),
24257e252bfSMichael Neumann 0x00000000,
24357e252bfSMichael Neumann (0x9c00 << 16) | (0x9974 >> 2),
24457e252bfSMichael Neumann 0x00000000,
24557e252bfSMichael Neumann (0x9c00 << 16) | (0x9978 >> 2),
24657e252bfSMichael Neumann 0x00000000,
24757e252bfSMichael Neumann (0x9c00 << 16) | (0x997c >> 2),
24857e252bfSMichael Neumann 0x00000000,
24957e252bfSMichael Neumann (0x9c00 << 16) | (0x9980 >> 2),
25057e252bfSMichael Neumann 0x00000000,
25157e252bfSMichael Neumann (0x9c00 << 16) | (0x9984 >> 2),
25257e252bfSMichael Neumann 0x00000000,
25357e252bfSMichael Neumann (0x9c00 << 16) | (0x9988 >> 2),
25457e252bfSMichael Neumann 0x00000000,
25557e252bfSMichael Neumann (0x9c00 << 16) | (0x998c >> 2),
25657e252bfSMichael Neumann 0x00000000,
25757e252bfSMichael Neumann (0x9c00 << 16) | (0x8c00 >> 2),
25857e252bfSMichael Neumann 0x00000000,
25957e252bfSMichael Neumann (0x9c00 << 16) | (0x8c14 >> 2),
26057e252bfSMichael Neumann 0x00000000,
26157e252bfSMichael Neumann (0x9c00 << 16) | (0x8c04 >> 2),
26257e252bfSMichael Neumann 0x00000000,
26357e252bfSMichael Neumann (0x9c00 << 16) | (0x8c08 >> 2),
26457e252bfSMichael Neumann 0x00000000,
26557e252bfSMichael Neumann (0x8000 << 16) | (0x9b7c >> 2),
26657e252bfSMichael Neumann 0x00000000,
26757e252bfSMichael Neumann (0x8040 << 16) | (0x9b7c >> 2),
26857e252bfSMichael Neumann 0x00000000,
26957e252bfSMichael Neumann (0x8000 << 16) | (0xe84 >> 2),
27057e252bfSMichael Neumann 0x00000000,
27157e252bfSMichael Neumann (0x8040 << 16) | (0xe84 >> 2),
27257e252bfSMichael Neumann 0x00000000,
27357e252bfSMichael Neumann (0x8000 << 16) | (0x89c0 >> 2),
27457e252bfSMichael Neumann 0x00000000,
27557e252bfSMichael Neumann (0x8040 << 16) | (0x89c0 >> 2),
27657e252bfSMichael Neumann 0x00000000,
27757e252bfSMichael Neumann (0x8000 << 16) | (0x914c >> 2),
27857e252bfSMichael Neumann 0x00000000,
27957e252bfSMichael Neumann (0x8040 << 16) | (0x914c >> 2),
28057e252bfSMichael Neumann 0x00000000,
28157e252bfSMichael Neumann (0x8000 << 16) | (0x8c20 >> 2),
28257e252bfSMichael Neumann 0x00000000,
28357e252bfSMichael Neumann (0x8040 << 16) | (0x8c20 >> 2),
28457e252bfSMichael Neumann 0x00000000,
28557e252bfSMichael Neumann (0x8000 << 16) | (0x9354 >> 2),
28657e252bfSMichael Neumann 0x00000000,
28757e252bfSMichael Neumann (0x8040 << 16) | (0x9354 >> 2),
28857e252bfSMichael Neumann 0x00000000,
28957e252bfSMichael Neumann (0x9c00 << 16) | (0x9060 >> 2),
29057e252bfSMichael Neumann 0x00000000,
29157e252bfSMichael Neumann (0x9c00 << 16) | (0x9364 >> 2),
29257e252bfSMichael Neumann 0x00000000,
29357e252bfSMichael Neumann (0x9c00 << 16) | (0x9100 >> 2),
29457e252bfSMichael Neumann 0x00000000,
29557e252bfSMichael Neumann (0x9c00 << 16) | (0x913c >> 2),
29657e252bfSMichael Neumann 0x00000000,
29757e252bfSMichael Neumann (0x8000 << 16) | (0x90e0 >> 2),
29857e252bfSMichael Neumann 0x00000000,
29957e252bfSMichael Neumann (0x8000 << 16) | (0x90e4 >> 2),
30057e252bfSMichael Neumann 0x00000000,
30157e252bfSMichael Neumann (0x8000 << 16) | (0x90e8 >> 2),
30257e252bfSMichael Neumann 0x00000000,
30357e252bfSMichael Neumann (0x8040 << 16) | (0x90e0 >> 2),
30457e252bfSMichael Neumann 0x00000000,
30557e252bfSMichael Neumann (0x8040 << 16) | (0x90e4 >> 2),
30657e252bfSMichael Neumann 0x00000000,
30757e252bfSMichael Neumann (0x8040 << 16) | (0x90e8 >> 2),
30857e252bfSMichael Neumann 0x00000000,
30957e252bfSMichael Neumann (0x9c00 << 16) | (0x8bcc >> 2),
31057e252bfSMichael Neumann 0x00000000,
31157e252bfSMichael Neumann (0x9c00 << 16) | (0x8b24 >> 2),
31257e252bfSMichael Neumann 0x00000000,
31357e252bfSMichael Neumann (0x9c00 << 16) | (0x88c4 >> 2),
31457e252bfSMichael Neumann 0x00000000,
31557e252bfSMichael Neumann (0x9c00 << 16) | (0x8e50 >> 2),
31657e252bfSMichael Neumann 0x00000000,
31757e252bfSMichael Neumann (0x9c00 << 16) | (0x8c0c >> 2),
31857e252bfSMichael Neumann 0x00000000,
31957e252bfSMichael Neumann (0x9c00 << 16) | (0x8e58 >> 2),
32057e252bfSMichael Neumann 0x00000000,
32157e252bfSMichael Neumann (0x9c00 << 16) | (0x8e5c >> 2),
32257e252bfSMichael Neumann 0x00000000,
32357e252bfSMichael Neumann (0x9c00 << 16) | (0x9508 >> 2),
32457e252bfSMichael Neumann 0x00000000,
32557e252bfSMichael Neumann (0x9c00 << 16) | (0x950c >> 2),
32657e252bfSMichael Neumann 0x00000000,
32757e252bfSMichael Neumann (0x9c00 << 16) | (0x9494 >> 2),
32857e252bfSMichael Neumann 0x00000000,
32957e252bfSMichael Neumann (0x9c00 << 16) | (0xac0c >> 2),
33057e252bfSMichael Neumann 0x00000000,
33157e252bfSMichael Neumann (0x9c00 << 16) | (0xac10 >> 2),
33257e252bfSMichael Neumann 0x00000000,
33357e252bfSMichael Neumann (0x9c00 << 16) | (0xac14 >> 2),
33457e252bfSMichael Neumann 0x00000000,
33557e252bfSMichael Neumann (0x9c00 << 16) | (0xae00 >> 2),
33657e252bfSMichael Neumann 0x00000000,
33757e252bfSMichael Neumann (0x9c00 << 16) | (0xac08 >> 2),
33857e252bfSMichael Neumann 0x00000000,
33957e252bfSMichael Neumann (0x9c00 << 16) | (0x88d4 >> 2),
34057e252bfSMichael Neumann 0x00000000,
34157e252bfSMichael Neumann (0x9c00 << 16) | (0x88c8 >> 2),
34257e252bfSMichael Neumann 0x00000000,
34357e252bfSMichael Neumann (0x9c00 << 16) | (0x88cc >> 2),
34457e252bfSMichael Neumann 0x00000000,
34557e252bfSMichael Neumann (0x9c00 << 16) | (0x89b0 >> 2),
34657e252bfSMichael Neumann 0x00000000,
34757e252bfSMichael Neumann (0x9c00 << 16) | (0x8b10 >> 2),
34857e252bfSMichael Neumann 0x00000000,
34957e252bfSMichael Neumann (0x9c00 << 16) | (0x8a14 >> 2),
35057e252bfSMichael Neumann 0x00000000,
35157e252bfSMichael Neumann (0x9c00 << 16) | (0x9830 >> 2),
35257e252bfSMichael Neumann 0x00000000,
35357e252bfSMichael Neumann (0x9c00 << 16) | (0x9834 >> 2),
35457e252bfSMichael Neumann 0x00000000,
35557e252bfSMichael Neumann (0x9c00 << 16) | (0x9838 >> 2),
35657e252bfSMichael Neumann 0x00000000,
35757e252bfSMichael Neumann (0x9c00 << 16) | (0x9a10 >> 2),
35857e252bfSMichael Neumann 0x00000000,
35957e252bfSMichael Neumann (0x8000 << 16) | (0x9870 >> 2),
36057e252bfSMichael Neumann 0x00000000,
36157e252bfSMichael Neumann (0x8000 << 16) | (0x9874 >> 2),
36257e252bfSMichael Neumann 0x00000000,
36357e252bfSMichael Neumann (0x8001 << 16) | (0x9870 >> 2),
36457e252bfSMichael Neumann 0x00000000,
36557e252bfSMichael Neumann (0x8001 << 16) | (0x9874 >> 2),
36657e252bfSMichael Neumann 0x00000000,
36757e252bfSMichael Neumann (0x8040 << 16) | (0x9870 >> 2),
36857e252bfSMichael Neumann 0x00000000,
36957e252bfSMichael Neumann (0x8040 << 16) | (0x9874 >> 2),
37057e252bfSMichael Neumann 0x00000000,
37157e252bfSMichael Neumann (0x8041 << 16) | (0x9870 >> 2),
37257e252bfSMichael Neumann 0x00000000,
37357e252bfSMichael Neumann (0x8041 << 16) | (0x9874 >> 2),
37457e252bfSMichael Neumann 0x00000000,
37557e252bfSMichael Neumann 0x00000000
37657e252bfSMichael Neumann };
377b403bed8SMichael Neumann
378f43cf1b1SMichael Neumann static const u32 tahiti_golden_rlc_registers[] =
379f43cf1b1SMichael Neumann {
380f43cf1b1SMichael Neumann 0xc424, 0xffffffff, 0x00601005,
381f43cf1b1SMichael Neumann 0xc47c, 0xffffffff, 0x10104040,
382f43cf1b1SMichael Neumann 0xc488, 0xffffffff, 0x0100000a,
383f43cf1b1SMichael Neumann 0xc314, 0xffffffff, 0x00000800,
384f43cf1b1SMichael Neumann 0xc30c, 0xffffffff, 0x800000f4,
385f43cf1b1SMichael Neumann 0xf4a8, 0xffffffff, 0x00000000
386f43cf1b1SMichael Neumann };
387f43cf1b1SMichael Neumann
388f43cf1b1SMichael Neumann static const u32 tahiti_golden_registers[] =
389f43cf1b1SMichael Neumann {
390f43cf1b1SMichael Neumann 0x9a10, 0x00010000, 0x00018208,
391f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000,
392f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400,
393f43cf1b1SMichael Neumann 0x9838, 0x0002021c, 0x00020200,
394f43cf1b1SMichael Neumann 0xc78, 0x00000080, 0x00000000,
395f43cf1b1SMichael Neumann 0xd030, 0x000300c0, 0x00800040,
396f43cf1b1SMichael Neumann 0xd830, 0x000300c0, 0x00800040,
397f43cf1b1SMichael Neumann 0x5bb0, 0x000000f0, 0x00000070,
398f43cf1b1SMichael Neumann 0x5bc0, 0x00200000, 0x50100000,
399f43cf1b1SMichael Neumann 0x7030, 0x31000311, 0x00000011,
400f43cf1b1SMichael Neumann 0x277c, 0x00000003, 0x000007ff,
401f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000,
402f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007,
403f43cf1b1SMichael Neumann 0x8b24, 0xffffffff, 0x00ffffff,
404f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
405f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x4e000000,
406f43cf1b1SMichael Neumann 0x28350, 0x3f3f3fff, 0x2a00126a,
407f43cf1b1SMichael Neumann 0x30, 0x000000ff, 0x0040,
408f43cf1b1SMichael Neumann 0x34, 0x00000040, 0x00004040,
409f43cf1b1SMichael Neumann 0x9100, 0x07ffffff, 0x03000000,
410f43cf1b1SMichael Neumann 0x8e88, 0x01ff1f3f, 0x00000000,
411f43cf1b1SMichael Neumann 0x8e84, 0x01ff1f3f, 0x00000000,
412f43cf1b1SMichael Neumann 0x9060, 0x0000007f, 0x00000020,
413f43cf1b1SMichael Neumann 0x9508, 0x00010000, 0x00010000,
414f43cf1b1SMichael Neumann 0xac14, 0x00000200, 0x000002fb,
415f43cf1b1SMichael Neumann 0xac10, 0xffffffff, 0x0000543b,
416f43cf1b1SMichael Neumann 0xac0c, 0xffffffff, 0xa9210876,
417f43cf1b1SMichael Neumann 0x88d0, 0xffffffff, 0x000fff40,
418f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
419f43cf1b1SMichael Neumann 0x1410, 0x20000000, 0x20fffed8,
420f43cf1b1SMichael Neumann 0x15c0, 0x000c0fc0, 0x000c0400
421f43cf1b1SMichael Neumann };
422f43cf1b1SMichael Neumann
423f43cf1b1SMichael Neumann static const u32 tahiti_golden_registers2[] =
424f43cf1b1SMichael Neumann {
425f43cf1b1SMichael Neumann 0xc64, 0x00000001, 0x00000001
426f43cf1b1SMichael Neumann };
427f43cf1b1SMichael Neumann
428f43cf1b1SMichael Neumann static const u32 pitcairn_golden_rlc_registers[] =
429f43cf1b1SMichael Neumann {
430f43cf1b1SMichael Neumann 0xc424, 0xffffffff, 0x00601004,
431f43cf1b1SMichael Neumann 0xc47c, 0xffffffff, 0x10102020,
432f43cf1b1SMichael Neumann 0xc488, 0xffffffff, 0x01000020,
433f43cf1b1SMichael Neumann 0xc314, 0xffffffff, 0x00000800,
434f43cf1b1SMichael Neumann 0xc30c, 0xffffffff, 0x800000a4
435f43cf1b1SMichael Neumann };
436f43cf1b1SMichael Neumann
437f43cf1b1SMichael Neumann static const u32 pitcairn_golden_registers[] =
438f43cf1b1SMichael Neumann {
439f43cf1b1SMichael Neumann 0x9a10, 0x00010000, 0x00018208,
440f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000,
441f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400,
442f43cf1b1SMichael Neumann 0x9838, 0x0002021c, 0x00020200,
443f43cf1b1SMichael Neumann 0xc78, 0x00000080, 0x00000000,
444f43cf1b1SMichael Neumann 0xd030, 0x000300c0, 0x00800040,
445f43cf1b1SMichael Neumann 0xd830, 0x000300c0, 0x00800040,
446f43cf1b1SMichael Neumann 0x5bb0, 0x000000f0, 0x00000070,
447f43cf1b1SMichael Neumann 0x5bc0, 0x00200000, 0x50100000,
448f43cf1b1SMichael Neumann 0x7030, 0x31000311, 0x00000011,
449f43cf1b1SMichael Neumann 0x2ae4, 0x00073ffe, 0x000022a2,
450f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000,
451f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007,
452f43cf1b1SMichael Neumann 0x8b24, 0xffffffff, 0x00ffffff,
453f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
454f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x4e000000,
455f43cf1b1SMichael Neumann 0x28350, 0x3f3f3fff, 0x2a00126a,
456f43cf1b1SMichael Neumann 0x30, 0x000000ff, 0x0040,
457f43cf1b1SMichael Neumann 0x34, 0x00000040, 0x00004040,
458f43cf1b1SMichael Neumann 0x9100, 0x07ffffff, 0x03000000,
459f43cf1b1SMichael Neumann 0x9060, 0x0000007f, 0x00000020,
460f43cf1b1SMichael Neumann 0x9508, 0x00010000, 0x00010000,
461f43cf1b1SMichael Neumann 0xac14, 0x000003ff, 0x000000f7,
462f43cf1b1SMichael Neumann 0xac10, 0xffffffff, 0x00000000,
463f43cf1b1SMichael Neumann 0xac0c, 0xffffffff, 0x32761054,
464f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
465f43cf1b1SMichael Neumann 0x15c0, 0x000c0fc0, 0x000c0400
466f43cf1b1SMichael Neumann };
467f43cf1b1SMichael Neumann
468f43cf1b1SMichael Neumann static const u32 verde_golden_rlc_registers[] =
469f43cf1b1SMichael Neumann {
470f43cf1b1SMichael Neumann 0xc424, 0xffffffff, 0x033f1005,
471f43cf1b1SMichael Neumann 0xc47c, 0xffffffff, 0x10808020,
472f43cf1b1SMichael Neumann 0xc488, 0xffffffff, 0x00800008,
473f43cf1b1SMichael Neumann 0xc314, 0xffffffff, 0x00001000,
474f43cf1b1SMichael Neumann 0xc30c, 0xffffffff, 0x80010014
475f43cf1b1SMichael Neumann };
476f43cf1b1SMichael Neumann
477f43cf1b1SMichael Neumann static const u32 verde_golden_registers[] =
478f43cf1b1SMichael Neumann {
479f43cf1b1SMichael Neumann 0x9a10, 0x00010000, 0x00018208,
480f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000,
481f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400,
482f43cf1b1SMichael Neumann 0x9838, 0x0002021c, 0x00020200,
483f43cf1b1SMichael Neumann 0xc78, 0x00000080, 0x00000000,
484f43cf1b1SMichael Neumann 0xd030, 0x000300c0, 0x00800040,
485f43cf1b1SMichael Neumann 0xd030, 0x000300c0, 0x00800040,
486f43cf1b1SMichael Neumann 0xd830, 0x000300c0, 0x00800040,
487f43cf1b1SMichael Neumann 0xd830, 0x000300c0, 0x00800040,
488f43cf1b1SMichael Neumann 0x5bb0, 0x000000f0, 0x00000070,
489f43cf1b1SMichael Neumann 0x5bc0, 0x00200000, 0x50100000,
490f43cf1b1SMichael Neumann 0x7030, 0x31000311, 0x00000011,
491f43cf1b1SMichael Neumann 0x2ae4, 0x00073ffe, 0x000022a2,
492f43cf1b1SMichael Neumann 0x2ae4, 0x00073ffe, 0x000022a2,
493f43cf1b1SMichael Neumann 0x2ae4, 0x00073ffe, 0x000022a2,
494f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000,
495f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000,
496f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000,
497f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007,
498f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007,
499f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007,
500f43cf1b1SMichael Neumann 0x8b24, 0xffffffff, 0x00ffffff,
501f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
502f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x4e000000,
503f43cf1b1SMichael Neumann 0x28350, 0x3f3f3fff, 0x0000124a,
504f43cf1b1SMichael Neumann 0x28350, 0x3f3f3fff, 0x0000124a,
505f43cf1b1SMichael Neumann 0x28350, 0x3f3f3fff, 0x0000124a,
506f43cf1b1SMichael Neumann 0x30, 0x000000ff, 0x0040,
507f43cf1b1SMichael Neumann 0x34, 0x00000040, 0x00004040,
508f43cf1b1SMichael Neumann 0x9100, 0x07ffffff, 0x03000000,
509f43cf1b1SMichael Neumann 0x9100, 0x07ffffff, 0x03000000,
510f43cf1b1SMichael Neumann 0x8e88, 0x01ff1f3f, 0x00000000,
511f43cf1b1SMichael Neumann 0x8e88, 0x01ff1f3f, 0x00000000,
512f43cf1b1SMichael Neumann 0x8e88, 0x01ff1f3f, 0x00000000,
513f43cf1b1SMichael Neumann 0x8e84, 0x01ff1f3f, 0x00000000,
514f43cf1b1SMichael Neumann 0x8e84, 0x01ff1f3f, 0x00000000,
515f43cf1b1SMichael Neumann 0x8e84, 0x01ff1f3f, 0x00000000,
516f43cf1b1SMichael Neumann 0x9060, 0x0000007f, 0x00000020,
517f43cf1b1SMichael Neumann 0x9508, 0x00010000, 0x00010000,
518f43cf1b1SMichael Neumann 0xac14, 0x000003ff, 0x00000003,
519f43cf1b1SMichael Neumann 0xac14, 0x000003ff, 0x00000003,
520f43cf1b1SMichael Neumann 0xac14, 0x000003ff, 0x00000003,
521f43cf1b1SMichael Neumann 0xac10, 0xffffffff, 0x00000000,
522f43cf1b1SMichael Neumann 0xac10, 0xffffffff, 0x00000000,
523f43cf1b1SMichael Neumann 0xac10, 0xffffffff, 0x00000000,
524f43cf1b1SMichael Neumann 0xac0c, 0xffffffff, 0x00001032,
525f43cf1b1SMichael Neumann 0xac0c, 0xffffffff, 0x00001032,
526f43cf1b1SMichael Neumann 0xac0c, 0xffffffff, 0x00001032,
527f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
528f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
529f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
530f43cf1b1SMichael Neumann 0x15c0, 0x000c0fc0, 0x000c0400
531f43cf1b1SMichael Neumann };
532f43cf1b1SMichael Neumann
533f43cf1b1SMichael Neumann static const u32 oland_golden_rlc_registers[] =
534f43cf1b1SMichael Neumann {
535f43cf1b1SMichael Neumann 0xc424, 0xffffffff, 0x00601005,
536f43cf1b1SMichael Neumann 0xc47c, 0xffffffff, 0x10104040,
537f43cf1b1SMichael Neumann 0xc488, 0xffffffff, 0x0100000a,
538f43cf1b1SMichael Neumann 0xc314, 0xffffffff, 0x00000800,
539f43cf1b1SMichael Neumann 0xc30c, 0xffffffff, 0x800000f4
540f43cf1b1SMichael Neumann };
541f43cf1b1SMichael Neumann
542f43cf1b1SMichael Neumann static const u32 oland_golden_registers[] =
543f43cf1b1SMichael Neumann {
544f43cf1b1SMichael Neumann 0x9a10, 0x00010000, 0x00018208,
545f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000,
546f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400,
547f43cf1b1SMichael Neumann 0x9838, 0x0002021c, 0x00020200,
548f43cf1b1SMichael Neumann 0xc78, 0x00000080, 0x00000000,
549f43cf1b1SMichael Neumann 0xd030, 0x000300c0, 0x00800040,
550f43cf1b1SMichael Neumann 0xd830, 0x000300c0, 0x00800040,
551f43cf1b1SMichael Neumann 0x5bb0, 0x000000f0, 0x00000070,
552f43cf1b1SMichael Neumann 0x5bc0, 0x00200000, 0x50100000,
553f43cf1b1SMichael Neumann 0x7030, 0x31000311, 0x00000011,
554f43cf1b1SMichael Neumann 0x2ae4, 0x00073ffe, 0x000022a2,
555f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000,
556f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007,
557f43cf1b1SMichael Neumann 0x8b24, 0xffffffff, 0x00ffffff,
558f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
559f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x4e000000,
560f43cf1b1SMichael Neumann 0x28350, 0x3f3f3fff, 0x00000082,
561f43cf1b1SMichael Neumann 0x30, 0x000000ff, 0x0040,
562f43cf1b1SMichael Neumann 0x34, 0x00000040, 0x00004040,
563f43cf1b1SMichael Neumann 0x9100, 0x07ffffff, 0x03000000,
564f43cf1b1SMichael Neumann 0x9060, 0x0000007f, 0x00000020,
565f43cf1b1SMichael Neumann 0x9508, 0x00010000, 0x00010000,
566f43cf1b1SMichael Neumann 0xac14, 0x000003ff, 0x000000f3,
567f43cf1b1SMichael Neumann 0xac10, 0xffffffff, 0x00000000,
568f43cf1b1SMichael Neumann 0xac0c, 0xffffffff, 0x00003210,
569f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
570f43cf1b1SMichael Neumann 0x15c0, 0x000c0fc0, 0x000c0400
571f43cf1b1SMichael Neumann };
572f43cf1b1SMichael Neumann
573f43cf1b1SMichael Neumann static const u32 hainan_golden_registers[] =
574f43cf1b1SMichael Neumann {
575f43cf1b1SMichael Neumann 0x9a10, 0x00010000, 0x00018208,
576f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000,
577f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400,
578f43cf1b1SMichael Neumann 0x9838, 0x0002021c, 0x00020200,
579f43cf1b1SMichael Neumann 0xd0c0, 0xff000fff, 0x00000100,
580f43cf1b1SMichael Neumann 0xd030, 0x000300c0, 0x00800040,
581f43cf1b1SMichael Neumann 0xd8c0, 0xff000fff, 0x00000100,
582f43cf1b1SMichael Neumann 0xd830, 0x000300c0, 0x00800040,
583f43cf1b1SMichael Neumann 0x2ae4, 0x00073ffe, 0x000022a2,
584f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000,
585f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007,
586f43cf1b1SMichael Neumann 0x8b24, 0xffffffff, 0x00ffffff,
587f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
588f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x4e000000,
589f43cf1b1SMichael Neumann 0x28350, 0x3f3f3fff, 0x00000000,
590f43cf1b1SMichael Neumann 0x30, 0x000000ff, 0x0040,
591f43cf1b1SMichael Neumann 0x34, 0x00000040, 0x00004040,
592f43cf1b1SMichael Neumann 0x9100, 0x03e00000, 0x03600000,
593f43cf1b1SMichael Neumann 0x9060, 0x0000007f, 0x00000020,
594f43cf1b1SMichael Neumann 0x9508, 0x00010000, 0x00010000,
595f43cf1b1SMichael Neumann 0xac14, 0x000003ff, 0x000000f1,
596f43cf1b1SMichael Neumann 0xac10, 0xffffffff, 0x00000000,
597f43cf1b1SMichael Neumann 0xac0c, 0xffffffff, 0x00003210,
598f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
599f43cf1b1SMichael Neumann 0x15c0, 0x000c0fc0, 0x000c0400
600f43cf1b1SMichael Neumann };
601f43cf1b1SMichael Neumann
602f43cf1b1SMichael Neumann static const u32 hainan_golden_registers2[] =
603f43cf1b1SMichael Neumann {
604f43cf1b1SMichael Neumann 0x98f8, 0xffffffff, 0x02010001
605f43cf1b1SMichael Neumann };
606f43cf1b1SMichael Neumann
607f43cf1b1SMichael Neumann static const u32 tahiti_mgcg_cgcg_init[] =
608f43cf1b1SMichael Neumann {
609f43cf1b1SMichael Neumann 0xc400, 0xffffffff, 0xfffffffc,
610f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
611f43cf1b1SMichael Neumann 0x9a60, 0xffffffff, 0x00000100,
612f43cf1b1SMichael Neumann 0x92a4, 0xffffffff, 0x00000100,
613f43cf1b1SMichael Neumann 0xc164, 0xffffffff, 0x00000100,
614f43cf1b1SMichael Neumann 0x9774, 0xffffffff, 0x00000100,
615f43cf1b1SMichael Neumann 0x8984, 0xffffffff, 0x06000100,
616f43cf1b1SMichael Neumann 0x8a18, 0xffffffff, 0x00000100,
617f43cf1b1SMichael Neumann 0x92a0, 0xffffffff, 0x00000100,
618f43cf1b1SMichael Neumann 0xc380, 0xffffffff, 0x00000100,
619f43cf1b1SMichael Neumann 0x8b28, 0xffffffff, 0x00000100,
620f43cf1b1SMichael Neumann 0x9144, 0xffffffff, 0x00000100,
621f43cf1b1SMichael Neumann 0x8d88, 0xffffffff, 0x00000100,
622f43cf1b1SMichael Neumann 0x8d8c, 0xffffffff, 0x00000100,
623f43cf1b1SMichael Neumann 0x9030, 0xffffffff, 0x00000100,
624f43cf1b1SMichael Neumann 0x9034, 0xffffffff, 0x00000100,
625f43cf1b1SMichael Neumann 0x9038, 0xffffffff, 0x00000100,
626f43cf1b1SMichael Neumann 0x903c, 0xffffffff, 0x00000100,
627f43cf1b1SMichael Neumann 0xad80, 0xffffffff, 0x00000100,
628f43cf1b1SMichael Neumann 0xac54, 0xffffffff, 0x00000100,
629f43cf1b1SMichael Neumann 0x897c, 0xffffffff, 0x06000100,
630f43cf1b1SMichael Neumann 0x9868, 0xffffffff, 0x00000100,
631f43cf1b1SMichael Neumann 0x9510, 0xffffffff, 0x00000100,
632f43cf1b1SMichael Neumann 0xaf04, 0xffffffff, 0x00000100,
633f43cf1b1SMichael Neumann 0xae04, 0xffffffff, 0x00000100,
634f43cf1b1SMichael Neumann 0x949c, 0xffffffff, 0x00000100,
635f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
636f43cf1b1SMichael Neumann 0x9160, 0xffffffff, 0x00010000,
637f43cf1b1SMichael Neumann 0x9164, 0xffffffff, 0x00030002,
638f43cf1b1SMichael Neumann 0x9168, 0xffffffff, 0x00040007,
639f43cf1b1SMichael Neumann 0x916c, 0xffffffff, 0x00060005,
640f43cf1b1SMichael Neumann 0x9170, 0xffffffff, 0x00090008,
641f43cf1b1SMichael Neumann 0x9174, 0xffffffff, 0x00020001,
642f43cf1b1SMichael Neumann 0x9178, 0xffffffff, 0x00040003,
643f43cf1b1SMichael Neumann 0x917c, 0xffffffff, 0x00000007,
644f43cf1b1SMichael Neumann 0x9180, 0xffffffff, 0x00060005,
645f43cf1b1SMichael Neumann 0x9184, 0xffffffff, 0x00090008,
646f43cf1b1SMichael Neumann 0x9188, 0xffffffff, 0x00030002,
647f43cf1b1SMichael Neumann 0x918c, 0xffffffff, 0x00050004,
648f43cf1b1SMichael Neumann 0x9190, 0xffffffff, 0x00000008,
649f43cf1b1SMichael Neumann 0x9194, 0xffffffff, 0x00070006,
650f43cf1b1SMichael Neumann 0x9198, 0xffffffff, 0x000a0009,
651f43cf1b1SMichael Neumann 0x919c, 0xffffffff, 0x00040003,
652f43cf1b1SMichael Neumann 0x91a0, 0xffffffff, 0x00060005,
653f43cf1b1SMichael Neumann 0x91a4, 0xffffffff, 0x00000009,
654f43cf1b1SMichael Neumann 0x91a8, 0xffffffff, 0x00080007,
655f43cf1b1SMichael Neumann 0x91ac, 0xffffffff, 0x000b000a,
656f43cf1b1SMichael Neumann 0x91b0, 0xffffffff, 0x00050004,
657f43cf1b1SMichael Neumann 0x91b4, 0xffffffff, 0x00070006,
658f43cf1b1SMichael Neumann 0x91b8, 0xffffffff, 0x0008000b,
659f43cf1b1SMichael Neumann 0x91bc, 0xffffffff, 0x000a0009,
660f43cf1b1SMichael Neumann 0x91c0, 0xffffffff, 0x000d000c,
661f43cf1b1SMichael Neumann 0x91c4, 0xffffffff, 0x00060005,
662f43cf1b1SMichael Neumann 0x91c8, 0xffffffff, 0x00080007,
663f43cf1b1SMichael Neumann 0x91cc, 0xffffffff, 0x0000000b,
664f43cf1b1SMichael Neumann 0x91d0, 0xffffffff, 0x000a0009,
665f43cf1b1SMichael Neumann 0x91d4, 0xffffffff, 0x000d000c,
666f43cf1b1SMichael Neumann 0x91d8, 0xffffffff, 0x00070006,
667f43cf1b1SMichael Neumann 0x91dc, 0xffffffff, 0x00090008,
668f43cf1b1SMichael Neumann 0x91e0, 0xffffffff, 0x0000000c,
669f43cf1b1SMichael Neumann 0x91e4, 0xffffffff, 0x000b000a,
670f43cf1b1SMichael Neumann 0x91e8, 0xffffffff, 0x000e000d,
671f43cf1b1SMichael Neumann 0x91ec, 0xffffffff, 0x00080007,
672f43cf1b1SMichael Neumann 0x91f0, 0xffffffff, 0x000a0009,
673f43cf1b1SMichael Neumann 0x91f4, 0xffffffff, 0x0000000d,
674f43cf1b1SMichael Neumann 0x91f8, 0xffffffff, 0x000c000b,
675f43cf1b1SMichael Neumann 0x91fc, 0xffffffff, 0x000f000e,
676f43cf1b1SMichael Neumann 0x9200, 0xffffffff, 0x00090008,
677f43cf1b1SMichael Neumann 0x9204, 0xffffffff, 0x000b000a,
678f43cf1b1SMichael Neumann 0x9208, 0xffffffff, 0x000c000f,
679f43cf1b1SMichael Neumann 0x920c, 0xffffffff, 0x000e000d,
680f43cf1b1SMichael Neumann 0x9210, 0xffffffff, 0x00110010,
681f43cf1b1SMichael Neumann 0x9214, 0xffffffff, 0x000a0009,
682f43cf1b1SMichael Neumann 0x9218, 0xffffffff, 0x000c000b,
683f43cf1b1SMichael Neumann 0x921c, 0xffffffff, 0x0000000f,
684f43cf1b1SMichael Neumann 0x9220, 0xffffffff, 0x000e000d,
685f43cf1b1SMichael Neumann 0x9224, 0xffffffff, 0x00110010,
686f43cf1b1SMichael Neumann 0x9228, 0xffffffff, 0x000b000a,
687f43cf1b1SMichael Neumann 0x922c, 0xffffffff, 0x000d000c,
688f43cf1b1SMichael Neumann 0x9230, 0xffffffff, 0x00000010,
689f43cf1b1SMichael Neumann 0x9234, 0xffffffff, 0x000f000e,
690f43cf1b1SMichael Neumann 0x9238, 0xffffffff, 0x00120011,
691f43cf1b1SMichael Neumann 0x923c, 0xffffffff, 0x000c000b,
692f43cf1b1SMichael Neumann 0x9240, 0xffffffff, 0x000e000d,
693f43cf1b1SMichael Neumann 0x9244, 0xffffffff, 0x00000011,
694f43cf1b1SMichael Neumann 0x9248, 0xffffffff, 0x0010000f,
695f43cf1b1SMichael Neumann 0x924c, 0xffffffff, 0x00130012,
696f43cf1b1SMichael Neumann 0x9250, 0xffffffff, 0x000d000c,
697f43cf1b1SMichael Neumann 0x9254, 0xffffffff, 0x000f000e,
698f43cf1b1SMichael Neumann 0x9258, 0xffffffff, 0x00100013,
699f43cf1b1SMichael Neumann 0x925c, 0xffffffff, 0x00120011,
700f43cf1b1SMichael Neumann 0x9260, 0xffffffff, 0x00150014,
701f43cf1b1SMichael Neumann 0x9264, 0xffffffff, 0x000e000d,
702f43cf1b1SMichael Neumann 0x9268, 0xffffffff, 0x0010000f,
703f43cf1b1SMichael Neumann 0x926c, 0xffffffff, 0x00000013,
704f43cf1b1SMichael Neumann 0x9270, 0xffffffff, 0x00120011,
705f43cf1b1SMichael Neumann 0x9274, 0xffffffff, 0x00150014,
706f43cf1b1SMichael Neumann 0x9278, 0xffffffff, 0x000f000e,
707f43cf1b1SMichael Neumann 0x927c, 0xffffffff, 0x00110010,
708f43cf1b1SMichael Neumann 0x9280, 0xffffffff, 0x00000014,
709f43cf1b1SMichael Neumann 0x9284, 0xffffffff, 0x00130012,
710f43cf1b1SMichael Neumann 0x9288, 0xffffffff, 0x00160015,
711f43cf1b1SMichael Neumann 0x928c, 0xffffffff, 0x0010000f,
712f43cf1b1SMichael Neumann 0x9290, 0xffffffff, 0x00120011,
713f43cf1b1SMichael Neumann 0x9294, 0xffffffff, 0x00000015,
714f43cf1b1SMichael Neumann 0x9298, 0xffffffff, 0x00140013,
715f43cf1b1SMichael Neumann 0x929c, 0xffffffff, 0x00170016,
716f43cf1b1SMichael Neumann 0x9150, 0xffffffff, 0x96940200,
717f43cf1b1SMichael Neumann 0x8708, 0xffffffff, 0x00900100,
718f43cf1b1SMichael Neumann 0xc478, 0xffffffff, 0x00000080,
719f43cf1b1SMichael Neumann 0xc404, 0xffffffff, 0x0020003f,
720f43cf1b1SMichael Neumann 0x30, 0xffffffff, 0x0000001c,
721f43cf1b1SMichael Neumann 0x34, 0x000f0000, 0x000f0000,
722f43cf1b1SMichael Neumann 0x160c, 0xffffffff, 0x00000100,
723f43cf1b1SMichael Neumann 0x1024, 0xffffffff, 0x00000100,
724f43cf1b1SMichael Neumann 0x102c, 0x00000101, 0x00000000,
725f43cf1b1SMichael Neumann 0x20a8, 0xffffffff, 0x00000104,
726f43cf1b1SMichael Neumann 0x264c, 0x000c0000, 0x000c0000,
727f43cf1b1SMichael Neumann 0x2648, 0x000c0000, 0x000c0000,
728f43cf1b1SMichael Neumann 0x55e4, 0xff000fff, 0x00000100,
729f43cf1b1SMichael Neumann 0x55e8, 0x00000001, 0x00000001,
730f43cf1b1SMichael Neumann 0x2f50, 0x00000001, 0x00000001,
731f43cf1b1SMichael Neumann 0x30cc, 0xc0000fff, 0x00000104,
732f43cf1b1SMichael Neumann 0xc1e4, 0x00000001, 0x00000001,
733f43cf1b1SMichael Neumann 0xd0c0, 0xfffffff0, 0x00000100,
734f43cf1b1SMichael Neumann 0xd8c0, 0xfffffff0, 0x00000100
735f43cf1b1SMichael Neumann };
736f43cf1b1SMichael Neumann
737f43cf1b1SMichael Neumann static const u32 pitcairn_mgcg_cgcg_init[] =
738f43cf1b1SMichael Neumann {
739f43cf1b1SMichael Neumann 0xc400, 0xffffffff, 0xfffffffc,
740f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
741f43cf1b1SMichael Neumann 0x9a60, 0xffffffff, 0x00000100,
742f43cf1b1SMichael Neumann 0x92a4, 0xffffffff, 0x00000100,
743f43cf1b1SMichael Neumann 0xc164, 0xffffffff, 0x00000100,
744f43cf1b1SMichael Neumann 0x9774, 0xffffffff, 0x00000100,
745f43cf1b1SMichael Neumann 0x8984, 0xffffffff, 0x06000100,
746f43cf1b1SMichael Neumann 0x8a18, 0xffffffff, 0x00000100,
747f43cf1b1SMichael Neumann 0x92a0, 0xffffffff, 0x00000100,
748f43cf1b1SMichael Neumann 0xc380, 0xffffffff, 0x00000100,
749f43cf1b1SMichael Neumann 0x8b28, 0xffffffff, 0x00000100,
750f43cf1b1SMichael Neumann 0x9144, 0xffffffff, 0x00000100,
751f43cf1b1SMichael Neumann 0x8d88, 0xffffffff, 0x00000100,
752f43cf1b1SMichael Neumann 0x8d8c, 0xffffffff, 0x00000100,
753f43cf1b1SMichael Neumann 0x9030, 0xffffffff, 0x00000100,
754f43cf1b1SMichael Neumann 0x9034, 0xffffffff, 0x00000100,
755f43cf1b1SMichael Neumann 0x9038, 0xffffffff, 0x00000100,
756f43cf1b1SMichael Neumann 0x903c, 0xffffffff, 0x00000100,
757f43cf1b1SMichael Neumann 0xad80, 0xffffffff, 0x00000100,
758f43cf1b1SMichael Neumann 0xac54, 0xffffffff, 0x00000100,
759f43cf1b1SMichael Neumann 0x897c, 0xffffffff, 0x06000100,
760f43cf1b1SMichael Neumann 0x9868, 0xffffffff, 0x00000100,
761f43cf1b1SMichael Neumann 0x9510, 0xffffffff, 0x00000100,
762f43cf1b1SMichael Neumann 0xaf04, 0xffffffff, 0x00000100,
763f43cf1b1SMichael Neumann 0xae04, 0xffffffff, 0x00000100,
764f43cf1b1SMichael Neumann 0x949c, 0xffffffff, 0x00000100,
765f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
766f43cf1b1SMichael Neumann 0x9160, 0xffffffff, 0x00010000,
767f43cf1b1SMichael Neumann 0x9164, 0xffffffff, 0x00030002,
768f43cf1b1SMichael Neumann 0x9168, 0xffffffff, 0x00040007,
769f43cf1b1SMichael Neumann 0x916c, 0xffffffff, 0x00060005,
770f43cf1b1SMichael Neumann 0x9170, 0xffffffff, 0x00090008,
771f43cf1b1SMichael Neumann 0x9174, 0xffffffff, 0x00020001,
772f43cf1b1SMichael Neumann 0x9178, 0xffffffff, 0x00040003,
773f43cf1b1SMichael Neumann 0x917c, 0xffffffff, 0x00000007,
774f43cf1b1SMichael Neumann 0x9180, 0xffffffff, 0x00060005,
775f43cf1b1SMichael Neumann 0x9184, 0xffffffff, 0x00090008,
776f43cf1b1SMichael Neumann 0x9188, 0xffffffff, 0x00030002,
777f43cf1b1SMichael Neumann 0x918c, 0xffffffff, 0x00050004,
778f43cf1b1SMichael Neumann 0x9190, 0xffffffff, 0x00000008,
779f43cf1b1SMichael Neumann 0x9194, 0xffffffff, 0x00070006,
780f43cf1b1SMichael Neumann 0x9198, 0xffffffff, 0x000a0009,
781f43cf1b1SMichael Neumann 0x919c, 0xffffffff, 0x00040003,
782f43cf1b1SMichael Neumann 0x91a0, 0xffffffff, 0x00060005,
783f43cf1b1SMichael Neumann 0x91a4, 0xffffffff, 0x00000009,
784f43cf1b1SMichael Neumann 0x91a8, 0xffffffff, 0x00080007,
785f43cf1b1SMichael Neumann 0x91ac, 0xffffffff, 0x000b000a,
786f43cf1b1SMichael Neumann 0x91b0, 0xffffffff, 0x00050004,
787f43cf1b1SMichael Neumann 0x91b4, 0xffffffff, 0x00070006,
788f43cf1b1SMichael Neumann 0x91b8, 0xffffffff, 0x0008000b,
789f43cf1b1SMichael Neumann 0x91bc, 0xffffffff, 0x000a0009,
790f43cf1b1SMichael Neumann 0x91c0, 0xffffffff, 0x000d000c,
791f43cf1b1SMichael Neumann 0x9200, 0xffffffff, 0x00090008,
792f43cf1b1SMichael Neumann 0x9204, 0xffffffff, 0x000b000a,
793f43cf1b1SMichael Neumann 0x9208, 0xffffffff, 0x000c000f,
794f43cf1b1SMichael Neumann 0x920c, 0xffffffff, 0x000e000d,
795f43cf1b1SMichael Neumann 0x9210, 0xffffffff, 0x00110010,
796f43cf1b1SMichael Neumann 0x9214, 0xffffffff, 0x000a0009,
797f43cf1b1SMichael Neumann 0x9218, 0xffffffff, 0x000c000b,
798f43cf1b1SMichael Neumann 0x921c, 0xffffffff, 0x0000000f,
799f43cf1b1SMichael Neumann 0x9220, 0xffffffff, 0x000e000d,
800f43cf1b1SMichael Neumann 0x9224, 0xffffffff, 0x00110010,
801f43cf1b1SMichael Neumann 0x9228, 0xffffffff, 0x000b000a,
802f43cf1b1SMichael Neumann 0x922c, 0xffffffff, 0x000d000c,
803f43cf1b1SMichael Neumann 0x9230, 0xffffffff, 0x00000010,
804f43cf1b1SMichael Neumann 0x9234, 0xffffffff, 0x000f000e,
805f43cf1b1SMichael Neumann 0x9238, 0xffffffff, 0x00120011,
806f43cf1b1SMichael Neumann 0x923c, 0xffffffff, 0x000c000b,
807f43cf1b1SMichael Neumann 0x9240, 0xffffffff, 0x000e000d,
808f43cf1b1SMichael Neumann 0x9244, 0xffffffff, 0x00000011,
809f43cf1b1SMichael Neumann 0x9248, 0xffffffff, 0x0010000f,
810f43cf1b1SMichael Neumann 0x924c, 0xffffffff, 0x00130012,
811f43cf1b1SMichael Neumann 0x9250, 0xffffffff, 0x000d000c,
812f43cf1b1SMichael Neumann 0x9254, 0xffffffff, 0x000f000e,
813f43cf1b1SMichael Neumann 0x9258, 0xffffffff, 0x00100013,
814f43cf1b1SMichael Neumann 0x925c, 0xffffffff, 0x00120011,
815f43cf1b1SMichael Neumann 0x9260, 0xffffffff, 0x00150014,
816f43cf1b1SMichael Neumann 0x9150, 0xffffffff, 0x96940200,
817f43cf1b1SMichael Neumann 0x8708, 0xffffffff, 0x00900100,
818f43cf1b1SMichael Neumann 0xc478, 0xffffffff, 0x00000080,
819f43cf1b1SMichael Neumann 0xc404, 0xffffffff, 0x0020003f,
820f43cf1b1SMichael Neumann 0x30, 0xffffffff, 0x0000001c,
821f43cf1b1SMichael Neumann 0x34, 0x000f0000, 0x000f0000,
822f43cf1b1SMichael Neumann 0x160c, 0xffffffff, 0x00000100,
823f43cf1b1SMichael Neumann 0x1024, 0xffffffff, 0x00000100,
824f43cf1b1SMichael Neumann 0x102c, 0x00000101, 0x00000000,
825f43cf1b1SMichael Neumann 0x20a8, 0xffffffff, 0x00000104,
826f43cf1b1SMichael Neumann 0x55e4, 0xff000fff, 0x00000100,
827f43cf1b1SMichael Neumann 0x55e8, 0x00000001, 0x00000001,
828f43cf1b1SMichael Neumann 0x2f50, 0x00000001, 0x00000001,
829f43cf1b1SMichael Neumann 0x30cc, 0xc0000fff, 0x00000104,
830f43cf1b1SMichael Neumann 0xc1e4, 0x00000001, 0x00000001,
831f43cf1b1SMichael Neumann 0xd0c0, 0xfffffff0, 0x00000100,
832f43cf1b1SMichael Neumann 0xd8c0, 0xfffffff0, 0x00000100
833f43cf1b1SMichael Neumann };
834f43cf1b1SMichael Neumann
835f43cf1b1SMichael Neumann static const u32 verde_mgcg_cgcg_init[] =
836f43cf1b1SMichael Neumann {
837f43cf1b1SMichael Neumann 0xc400, 0xffffffff, 0xfffffffc,
838f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
839f43cf1b1SMichael Neumann 0x9a60, 0xffffffff, 0x00000100,
840f43cf1b1SMichael Neumann 0x92a4, 0xffffffff, 0x00000100,
841f43cf1b1SMichael Neumann 0xc164, 0xffffffff, 0x00000100,
842f43cf1b1SMichael Neumann 0x9774, 0xffffffff, 0x00000100,
843f43cf1b1SMichael Neumann 0x8984, 0xffffffff, 0x06000100,
844f43cf1b1SMichael Neumann 0x8a18, 0xffffffff, 0x00000100,
845f43cf1b1SMichael Neumann 0x92a0, 0xffffffff, 0x00000100,
846f43cf1b1SMichael Neumann 0xc380, 0xffffffff, 0x00000100,
847f43cf1b1SMichael Neumann 0x8b28, 0xffffffff, 0x00000100,
848f43cf1b1SMichael Neumann 0x9144, 0xffffffff, 0x00000100,
849f43cf1b1SMichael Neumann 0x8d88, 0xffffffff, 0x00000100,
850f43cf1b1SMichael Neumann 0x8d8c, 0xffffffff, 0x00000100,
851f43cf1b1SMichael Neumann 0x9030, 0xffffffff, 0x00000100,
852f43cf1b1SMichael Neumann 0x9034, 0xffffffff, 0x00000100,
853f43cf1b1SMichael Neumann 0x9038, 0xffffffff, 0x00000100,
854f43cf1b1SMichael Neumann 0x903c, 0xffffffff, 0x00000100,
855f43cf1b1SMichael Neumann 0xad80, 0xffffffff, 0x00000100,
856f43cf1b1SMichael Neumann 0xac54, 0xffffffff, 0x00000100,
857f43cf1b1SMichael Neumann 0x897c, 0xffffffff, 0x06000100,
858f43cf1b1SMichael Neumann 0x9868, 0xffffffff, 0x00000100,
859f43cf1b1SMichael Neumann 0x9510, 0xffffffff, 0x00000100,
860f43cf1b1SMichael Neumann 0xaf04, 0xffffffff, 0x00000100,
861f43cf1b1SMichael Neumann 0xae04, 0xffffffff, 0x00000100,
862f43cf1b1SMichael Neumann 0x949c, 0xffffffff, 0x00000100,
863f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
864f43cf1b1SMichael Neumann 0x9160, 0xffffffff, 0x00010000,
865f43cf1b1SMichael Neumann 0x9164, 0xffffffff, 0x00030002,
866f43cf1b1SMichael Neumann 0x9168, 0xffffffff, 0x00040007,
867f43cf1b1SMichael Neumann 0x916c, 0xffffffff, 0x00060005,
868f43cf1b1SMichael Neumann 0x9170, 0xffffffff, 0x00090008,
869f43cf1b1SMichael Neumann 0x9174, 0xffffffff, 0x00020001,
870f43cf1b1SMichael Neumann 0x9178, 0xffffffff, 0x00040003,
871f43cf1b1SMichael Neumann 0x917c, 0xffffffff, 0x00000007,
872f43cf1b1SMichael Neumann 0x9180, 0xffffffff, 0x00060005,
873f43cf1b1SMichael Neumann 0x9184, 0xffffffff, 0x00090008,
874f43cf1b1SMichael Neumann 0x9188, 0xffffffff, 0x00030002,
875f43cf1b1SMichael Neumann 0x918c, 0xffffffff, 0x00050004,
876f43cf1b1SMichael Neumann 0x9190, 0xffffffff, 0x00000008,
877f43cf1b1SMichael Neumann 0x9194, 0xffffffff, 0x00070006,
878f43cf1b1SMichael Neumann 0x9198, 0xffffffff, 0x000a0009,
879f43cf1b1SMichael Neumann 0x919c, 0xffffffff, 0x00040003,
880f43cf1b1SMichael Neumann 0x91a0, 0xffffffff, 0x00060005,
881f43cf1b1SMichael Neumann 0x91a4, 0xffffffff, 0x00000009,
882f43cf1b1SMichael Neumann 0x91a8, 0xffffffff, 0x00080007,
883f43cf1b1SMichael Neumann 0x91ac, 0xffffffff, 0x000b000a,
884f43cf1b1SMichael Neumann 0x91b0, 0xffffffff, 0x00050004,
885f43cf1b1SMichael Neumann 0x91b4, 0xffffffff, 0x00070006,
886f43cf1b1SMichael Neumann 0x91b8, 0xffffffff, 0x0008000b,
887f43cf1b1SMichael Neumann 0x91bc, 0xffffffff, 0x000a0009,
888f43cf1b1SMichael Neumann 0x91c0, 0xffffffff, 0x000d000c,
889f43cf1b1SMichael Neumann 0x9200, 0xffffffff, 0x00090008,
890f43cf1b1SMichael Neumann 0x9204, 0xffffffff, 0x000b000a,
891f43cf1b1SMichael Neumann 0x9208, 0xffffffff, 0x000c000f,
892f43cf1b1SMichael Neumann 0x920c, 0xffffffff, 0x000e000d,
893f43cf1b1SMichael Neumann 0x9210, 0xffffffff, 0x00110010,
894f43cf1b1SMichael Neumann 0x9214, 0xffffffff, 0x000a0009,
895f43cf1b1SMichael Neumann 0x9218, 0xffffffff, 0x000c000b,
896f43cf1b1SMichael Neumann 0x921c, 0xffffffff, 0x0000000f,
897f43cf1b1SMichael Neumann 0x9220, 0xffffffff, 0x000e000d,
898f43cf1b1SMichael Neumann 0x9224, 0xffffffff, 0x00110010,
899f43cf1b1SMichael Neumann 0x9228, 0xffffffff, 0x000b000a,
900f43cf1b1SMichael Neumann 0x922c, 0xffffffff, 0x000d000c,
901f43cf1b1SMichael Neumann 0x9230, 0xffffffff, 0x00000010,
902f43cf1b1SMichael Neumann 0x9234, 0xffffffff, 0x000f000e,
903f43cf1b1SMichael Neumann 0x9238, 0xffffffff, 0x00120011,
904f43cf1b1SMichael Neumann 0x923c, 0xffffffff, 0x000c000b,
905f43cf1b1SMichael Neumann 0x9240, 0xffffffff, 0x000e000d,
906f43cf1b1SMichael Neumann 0x9244, 0xffffffff, 0x00000011,
907f43cf1b1SMichael Neumann 0x9248, 0xffffffff, 0x0010000f,
908f43cf1b1SMichael Neumann 0x924c, 0xffffffff, 0x00130012,
909f43cf1b1SMichael Neumann 0x9250, 0xffffffff, 0x000d000c,
910f43cf1b1SMichael Neumann 0x9254, 0xffffffff, 0x000f000e,
911f43cf1b1SMichael Neumann 0x9258, 0xffffffff, 0x00100013,
912f43cf1b1SMichael Neumann 0x925c, 0xffffffff, 0x00120011,
913f43cf1b1SMichael Neumann 0x9260, 0xffffffff, 0x00150014,
914f43cf1b1SMichael Neumann 0x9150, 0xffffffff, 0x96940200,
915f43cf1b1SMichael Neumann 0x8708, 0xffffffff, 0x00900100,
916f43cf1b1SMichael Neumann 0xc478, 0xffffffff, 0x00000080,
917f43cf1b1SMichael Neumann 0xc404, 0xffffffff, 0x0020003f,
918f43cf1b1SMichael Neumann 0x30, 0xffffffff, 0x0000001c,
919f43cf1b1SMichael Neumann 0x34, 0x000f0000, 0x000f0000,
920f43cf1b1SMichael Neumann 0x160c, 0xffffffff, 0x00000100,
921f43cf1b1SMichael Neumann 0x1024, 0xffffffff, 0x00000100,
922f43cf1b1SMichael Neumann 0x102c, 0x00000101, 0x00000000,
923f43cf1b1SMichael Neumann 0x20a8, 0xffffffff, 0x00000104,
924f43cf1b1SMichael Neumann 0x264c, 0x000c0000, 0x000c0000,
925f43cf1b1SMichael Neumann 0x2648, 0x000c0000, 0x000c0000,
926f43cf1b1SMichael Neumann 0x55e4, 0xff000fff, 0x00000100,
927f43cf1b1SMichael Neumann 0x55e8, 0x00000001, 0x00000001,
928f43cf1b1SMichael Neumann 0x2f50, 0x00000001, 0x00000001,
929f43cf1b1SMichael Neumann 0x30cc, 0xc0000fff, 0x00000104,
930f43cf1b1SMichael Neumann 0xc1e4, 0x00000001, 0x00000001,
931f43cf1b1SMichael Neumann 0xd0c0, 0xfffffff0, 0x00000100,
932f43cf1b1SMichael Neumann 0xd8c0, 0xfffffff0, 0x00000100
933f43cf1b1SMichael Neumann };
934f43cf1b1SMichael Neumann
935f43cf1b1SMichael Neumann static const u32 oland_mgcg_cgcg_init[] =
936f43cf1b1SMichael Neumann {
937f43cf1b1SMichael Neumann 0xc400, 0xffffffff, 0xfffffffc,
938f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
939f43cf1b1SMichael Neumann 0x9a60, 0xffffffff, 0x00000100,
940f43cf1b1SMichael Neumann 0x92a4, 0xffffffff, 0x00000100,
941f43cf1b1SMichael Neumann 0xc164, 0xffffffff, 0x00000100,
942f43cf1b1SMichael Neumann 0x9774, 0xffffffff, 0x00000100,
943f43cf1b1SMichael Neumann 0x8984, 0xffffffff, 0x06000100,
944f43cf1b1SMichael Neumann 0x8a18, 0xffffffff, 0x00000100,
945f43cf1b1SMichael Neumann 0x92a0, 0xffffffff, 0x00000100,
946f43cf1b1SMichael Neumann 0xc380, 0xffffffff, 0x00000100,
947f43cf1b1SMichael Neumann 0x8b28, 0xffffffff, 0x00000100,
948f43cf1b1SMichael Neumann 0x9144, 0xffffffff, 0x00000100,
949f43cf1b1SMichael Neumann 0x8d88, 0xffffffff, 0x00000100,
950f43cf1b1SMichael Neumann 0x8d8c, 0xffffffff, 0x00000100,
951f43cf1b1SMichael Neumann 0x9030, 0xffffffff, 0x00000100,
952f43cf1b1SMichael Neumann 0x9034, 0xffffffff, 0x00000100,
953f43cf1b1SMichael Neumann 0x9038, 0xffffffff, 0x00000100,
954f43cf1b1SMichael Neumann 0x903c, 0xffffffff, 0x00000100,
955f43cf1b1SMichael Neumann 0xad80, 0xffffffff, 0x00000100,
956f43cf1b1SMichael Neumann 0xac54, 0xffffffff, 0x00000100,
957f43cf1b1SMichael Neumann 0x897c, 0xffffffff, 0x06000100,
958f43cf1b1SMichael Neumann 0x9868, 0xffffffff, 0x00000100,
959f43cf1b1SMichael Neumann 0x9510, 0xffffffff, 0x00000100,
960f43cf1b1SMichael Neumann 0xaf04, 0xffffffff, 0x00000100,
961f43cf1b1SMichael Neumann 0xae04, 0xffffffff, 0x00000100,
962f43cf1b1SMichael Neumann 0x949c, 0xffffffff, 0x00000100,
963f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
964f43cf1b1SMichael Neumann 0x9160, 0xffffffff, 0x00010000,
965f43cf1b1SMichael Neumann 0x9164, 0xffffffff, 0x00030002,
966f43cf1b1SMichael Neumann 0x9168, 0xffffffff, 0x00040007,
967f43cf1b1SMichael Neumann 0x916c, 0xffffffff, 0x00060005,
968f43cf1b1SMichael Neumann 0x9170, 0xffffffff, 0x00090008,
969f43cf1b1SMichael Neumann 0x9174, 0xffffffff, 0x00020001,
970f43cf1b1SMichael Neumann 0x9178, 0xffffffff, 0x00040003,
971f43cf1b1SMichael Neumann 0x917c, 0xffffffff, 0x00000007,
972f43cf1b1SMichael Neumann 0x9180, 0xffffffff, 0x00060005,
973f43cf1b1SMichael Neumann 0x9184, 0xffffffff, 0x00090008,
974f43cf1b1SMichael Neumann 0x9188, 0xffffffff, 0x00030002,
975f43cf1b1SMichael Neumann 0x918c, 0xffffffff, 0x00050004,
976f43cf1b1SMichael Neumann 0x9190, 0xffffffff, 0x00000008,
977f43cf1b1SMichael Neumann 0x9194, 0xffffffff, 0x00070006,
978f43cf1b1SMichael Neumann 0x9198, 0xffffffff, 0x000a0009,
979f43cf1b1SMichael Neumann 0x919c, 0xffffffff, 0x00040003,
980f43cf1b1SMichael Neumann 0x91a0, 0xffffffff, 0x00060005,
981f43cf1b1SMichael Neumann 0x91a4, 0xffffffff, 0x00000009,
982f43cf1b1SMichael Neumann 0x91a8, 0xffffffff, 0x00080007,
983f43cf1b1SMichael Neumann 0x91ac, 0xffffffff, 0x000b000a,
984f43cf1b1SMichael Neumann 0x91b0, 0xffffffff, 0x00050004,
985f43cf1b1SMichael Neumann 0x91b4, 0xffffffff, 0x00070006,
986f43cf1b1SMichael Neumann 0x91b8, 0xffffffff, 0x0008000b,
987f43cf1b1SMichael Neumann 0x91bc, 0xffffffff, 0x000a0009,
988f43cf1b1SMichael Neumann 0x91c0, 0xffffffff, 0x000d000c,
989f43cf1b1SMichael Neumann 0x91c4, 0xffffffff, 0x00060005,
990f43cf1b1SMichael Neumann 0x91c8, 0xffffffff, 0x00080007,
991f43cf1b1SMichael Neumann 0x91cc, 0xffffffff, 0x0000000b,
992f43cf1b1SMichael Neumann 0x91d0, 0xffffffff, 0x000a0009,
993f43cf1b1SMichael Neumann 0x91d4, 0xffffffff, 0x000d000c,
994f43cf1b1SMichael Neumann 0x9150, 0xffffffff, 0x96940200,
995f43cf1b1SMichael Neumann 0x8708, 0xffffffff, 0x00900100,
996f43cf1b1SMichael Neumann 0xc478, 0xffffffff, 0x00000080,
997f43cf1b1SMichael Neumann 0xc404, 0xffffffff, 0x0020003f,
998f43cf1b1SMichael Neumann 0x30, 0xffffffff, 0x0000001c,
999f43cf1b1SMichael Neumann 0x34, 0x000f0000, 0x000f0000,
1000f43cf1b1SMichael Neumann 0x160c, 0xffffffff, 0x00000100,
1001f43cf1b1SMichael Neumann 0x1024, 0xffffffff, 0x00000100,
1002f43cf1b1SMichael Neumann 0x102c, 0x00000101, 0x00000000,
1003f43cf1b1SMichael Neumann 0x20a8, 0xffffffff, 0x00000104,
1004f43cf1b1SMichael Neumann 0x264c, 0x000c0000, 0x000c0000,
1005f43cf1b1SMichael Neumann 0x2648, 0x000c0000, 0x000c0000,
1006f43cf1b1SMichael Neumann 0x55e4, 0xff000fff, 0x00000100,
1007f43cf1b1SMichael Neumann 0x55e8, 0x00000001, 0x00000001,
1008f43cf1b1SMichael Neumann 0x2f50, 0x00000001, 0x00000001,
1009f43cf1b1SMichael Neumann 0x30cc, 0xc0000fff, 0x00000104,
1010f43cf1b1SMichael Neumann 0xc1e4, 0x00000001, 0x00000001,
1011f43cf1b1SMichael Neumann 0xd0c0, 0xfffffff0, 0x00000100,
1012f43cf1b1SMichael Neumann 0xd8c0, 0xfffffff0, 0x00000100
1013f43cf1b1SMichael Neumann };
1014f43cf1b1SMichael Neumann
1015f43cf1b1SMichael Neumann static const u32 hainan_mgcg_cgcg_init[] =
1016f43cf1b1SMichael Neumann {
1017f43cf1b1SMichael Neumann 0xc400, 0xffffffff, 0xfffffffc,
1018f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
1019f43cf1b1SMichael Neumann 0x9a60, 0xffffffff, 0x00000100,
1020f43cf1b1SMichael Neumann 0x92a4, 0xffffffff, 0x00000100,
1021f43cf1b1SMichael Neumann 0xc164, 0xffffffff, 0x00000100,
1022f43cf1b1SMichael Neumann 0x9774, 0xffffffff, 0x00000100,
1023f43cf1b1SMichael Neumann 0x8984, 0xffffffff, 0x06000100,
1024f43cf1b1SMichael Neumann 0x8a18, 0xffffffff, 0x00000100,
1025f43cf1b1SMichael Neumann 0x92a0, 0xffffffff, 0x00000100,
1026f43cf1b1SMichael Neumann 0xc380, 0xffffffff, 0x00000100,
1027f43cf1b1SMichael Neumann 0x8b28, 0xffffffff, 0x00000100,
1028f43cf1b1SMichael Neumann 0x9144, 0xffffffff, 0x00000100,
1029f43cf1b1SMichael Neumann 0x8d88, 0xffffffff, 0x00000100,
1030f43cf1b1SMichael Neumann 0x8d8c, 0xffffffff, 0x00000100,
1031f43cf1b1SMichael Neumann 0x9030, 0xffffffff, 0x00000100,
1032f43cf1b1SMichael Neumann 0x9034, 0xffffffff, 0x00000100,
1033f43cf1b1SMichael Neumann 0x9038, 0xffffffff, 0x00000100,
1034f43cf1b1SMichael Neumann 0x903c, 0xffffffff, 0x00000100,
1035f43cf1b1SMichael Neumann 0xad80, 0xffffffff, 0x00000100,
1036f43cf1b1SMichael Neumann 0xac54, 0xffffffff, 0x00000100,
1037f43cf1b1SMichael Neumann 0x897c, 0xffffffff, 0x06000100,
1038f43cf1b1SMichael Neumann 0x9868, 0xffffffff, 0x00000100,
1039f43cf1b1SMichael Neumann 0x9510, 0xffffffff, 0x00000100,
1040f43cf1b1SMichael Neumann 0xaf04, 0xffffffff, 0x00000100,
1041f43cf1b1SMichael Neumann 0xae04, 0xffffffff, 0x00000100,
1042f43cf1b1SMichael Neumann 0x949c, 0xffffffff, 0x00000100,
1043f43cf1b1SMichael Neumann 0x802c, 0xffffffff, 0xe0000000,
1044f43cf1b1SMichael Neumann 0x9160, 0xffffffff, 0x00010000,
1045f43cf1b1SMichael Neumann 0x9164, 0xffffffff, 0x00030002,
1046f43cf1b1SMichael Neumann 0x9168, 0xffffffff, 0x00040007,
1047f43cf1b1SMichael Neumann 0x916c, 0xffffffff, 0x00060005,
1048f43cf1b1SMichael Neumann 0x9170, 0xffffffff, 0x00090008,
1049f43cf1b1SMichael Neumann 0x9174, 0xffffffff, 0x00020001,
1050f43cf1b1SMichael Neumann 0x9178, 0xffffffff, 0x00040003,
1051f43cf1b1SMichael Neumann 0x917c, 0xffffffff, 0x00000007,
1052f43cf1b1SMichael Neumann 0x9180, 0xffffffff, 0x00060005,
1053f43cf1b1SMichael Neumann 0x9184, 0xffffffff, 0x00090008,
1054f43cf1b1SMichael Neumann 0x9188, 0xffffffff, 0x00030002,
1055f43cf1b1SMichael Neumann 0x918c, 0xffffffff, 0x00050004,
1056f43cf1b1SMichael Neumann 0x9190, 0xffffffff, 0x00000008,
1057f43cf1b1SMichael Neumann 0x9194, 0xffffffff, 0x00070006,
1058f43cf1b1SMichael Neumann 0x9198, 0xffffffff, 0x000a0009,
1059f43cf1b1SMichael Neumann 0x919c, 0xffffffff, 0x00040003,
1060f43cf1b1SMichael Neumann 0x91a0, 0xffffffff, 0x00060005,
1061f43cf1b1SMichael Neumann 0x91a4, 0xffffffff, 0x00000009,
1062f43cf1b1SMichael Neumann 0x91a8, 0xffffffff, 0x00080007,
1063f43cf1b1SMichael Neumann 0x91ac, 0xffffffff, 0x000b000a,
1064f43cf1b1SMichael Neumann 0x91b0, 0xffffffff, 0x00050004,
1065f43cf1b1SMichael Neumann 0x91b4, 0xffffffff, 0x00070006,
1066f43cf1b1SMichael Neumann 0x91b8, 0xffffffff, 0x0008000b,
1067f43cf1b1SMichael Neumann 0x91bc, 0xffffffff, 0x000a0009,
1068f43cf1b1SMichael Neumann 0x91c0, 0xffffffff, 0x000d000c,
1069f43cf1b1SMichael Neumann 0x91c4, 0xffffffff, 0x00060005,
1070f43cf1b1SMichael Neumann 0x91c8, 0xffffffff, 0x00080007,
1071f43cf1b1SMichael Neumann 0x91cc, 0xffffffff, 0x0000000b,
1072f43cf1b1SMichael Neumann 0x91d0, 0xffffffff, 0x000a0009,
1073f43cf1b1SMichael Neumann 0x91d4, 0xffffffff, 0x000d000c,
1074f43cf1b1SMichael Neumann 0x9150, 0xffffffff, 0x96940200,
1075f43cf1b1SMichael Neumann 0x8708, 0xffffffff, 0x00900100,
1076f43cf1b1SMichael Neumann 0xc478, 0xffffffff, 0x00000080,
1077f43cf1b1SMichael Neumann 0xc404, 0xffffffff, 0x0020003f,
1078f43cf1b1SMichael Neumann 0x30, 0xffffffff, 0x0000001c,
1079f43cf1b1SMichael Neumann 0x34, 0x000f0000, 0x000f0000,
1080f43cf1b1SMichael Neumann 0x160c, 0xffffffff, 0x00000100,
1081f43cf1b1SMichael Neumann 0x1024, 0xffffffff, 0x00000100,
1082f43cf1b1SMichael Neumann 0x20a8, 0xffffffff, 0x00000104,
1083f43cf1b1SMichael Neumann 0x264c, 0x000c0000, 0x000c0000,
1084f43cf1b1SMichael Neumann 0x2648, 0x000c0000, 0x000c0000,
1085f43cf1b1SMichael Neumann 0x2f50, 0x00000001, 0x00000001,
1086f43cf1b1SMichael Neumann 0x30cc, 0xc0000fff, 0x00000104,
1087f43cf1b1SMichael Neumann 0xc1e4, 0x00000001, 0x00000001,
1088f43cf1b1SMichael Neumann 0xd0c0, 0xfffffff0, 0x00000100,
1089f43cf1b1SMichael Neumann 0xd8c0, 0xfffffff0, 0x00000100
1090f43cf1b1SMichael Neumann };
1091f43cf1b1SMichael Neumann
1092f43cf1b1SMichael Neumann static u32 verde_pg_init[] =
1093f43cf1b1SMichael Neumann {
1094f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x40000,
1095f43cf1b1SMichael Neumann 0x3538, 0xffffffff, 0x200010ff,
1096f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1097f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1098f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1099f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1100f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1101f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x7007,
1102f43cf1b1SMichael Neumann 0x3538, 0xffffffff, 0x300010ff,
1103f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1104f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1105f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1106f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1107f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1108f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x400000,
1109f43cf1b1SMichael Neumann 0x3538, 0xffffffff, 0x100010ff,
1110f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1111f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1112f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1113f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1114f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1115f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x120200,
1116f43cf1b1SMichael Neumann 0x3538, 0xffffffff, 0x500010ff,
1117f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1118f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1119f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1120f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1121f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1122f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x1e1e16,
1123f43cf1b1SMichael Neumann 0x3538, 0xffffffff, 0x600010ff,
1124f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1125f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1126f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1127f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1128f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1129f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x171f1e,
1130f43cf1b1SMichael Neumann 0x3538, 0xffffffff, 0x700010ff,
1131f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1132f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1133f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1134f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1135f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1136f43cf1b1SMichael Neumann 0x353c, 0xffffffff, 0x0,
1137f43cf1b1SMichael Neumann 0x3538, 0xffffffff, 0x9ff,
1138f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x0,
1139f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x10000800,
1140f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xf,
1141f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xf,
1142f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x4,
1143f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x1000051e,
1144f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xffff,
1145f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xffff,
1146f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x8,
1147f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x80500,
1148f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x12,
1149f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x9050c,
1150f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x1d,
1151f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xb052c,
1152f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x2a,
1153f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x1053e,
1154f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x2d,
1155f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x10546,
1156f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x30,
1157f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xa054e,
1158f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x3c,
1159f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x1055f,
1160f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x3f,
1161f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x10567,
1162f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x42,
1163f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x1056f,
1164f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x45,
1165f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x10572,
1166f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x48,
1167f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x20575,
1168f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x4c,
1169f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x190801,
1170f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x67,
1171f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x1082a,
1172f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x6a,
1173f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x1b082d,
1174f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x87,
1175f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x310851,
1176f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xba,
1177f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x891,
1178f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xbc,
1179f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x893,
1180f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xbe,
1181f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x20895,
1182f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xc2,
1183f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x20899,
1184f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xc6,
1185f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x2089d,
1186f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xca,
1187f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x8a1,
1188f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xcc,
1189f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x8a3,
1190f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xce,
1191f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x308a5,
1192f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0xd3,
1193f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x6d08cd,
1194f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x142,
1195f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x2000095a,
1196f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x1,
1197f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x144,
1198f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x301f095b,
1199f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x165,
1200f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xc094d,
1201f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x173,
1202f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xf096d,
1203f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x184,
1204f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x15097f,
1205f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x19b,
1206f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xc0998,
1207f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x1a9,
1208f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x409a7,
1209f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x1af,
1210f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0xcdc,
1211f43cf1b1SMichael Neumann 0x3500, 0xffffffff, 0x1b1,
1212f43cf1b1SMichael Neumann 0x3504, 0xffffffff, 0x800,
1213f43cf1b1SMichael Neumann 0x3508, 0xffffffff, 0x6c9b2000,
1214f43cf1b1SMichael Neumann 0x3510, 0xfc00, 0x2000,
1215f43cf1b1SMichael Neumann 0x3544, 0xffffffff, 0xfc0,
1216f43cf1b1SMichael Neumann 0x28d4, 0x00000100, 0x100
1217f43cf1b1SMichael Neumann };
1218f43cf1b1SMichael Neumann
si_init_golden_registers(struct radeon_device * rdev)1219f43cf1b1SMichael Neumann static void si_init_golden_registers(struct radeon_device *rdev)
1220f43cf1b1SMichael Neumann {
1221f43cf1b1SMichael Neumann switch (rdev->family) {
1222f43cf1b1SMichael Neumann case CHIP_TAHITI:
1223f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1224f43cf1b1SMichael Neumann tahiti_golden_registers,
1225f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(tahiti_golden_registers));
1226f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1227f43cf1b1SMichael Neumann tahiti_golden_rlc_registers,
1228f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(tahiti_golden_rlc_registers));
1229f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1230f43cf1b1SMichael Neumann tahiti_mgcg_cgcg_init,
1231f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(tahiti_mgcg_cgcg_init));
1232f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1233f43cf1b1SMichael Neumann tahiti_golden_registers2,
1234f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(tahiti_golden_registers2));
1235f43cf1b1SMichael Neumann break;
1236f43cf1b1SMichael Neumann case CHIP_PITCAIRN:
1237f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1238f43cf1b1SMichael Neumann pitcairn_golden_registers,
1239f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(pitcairn_golden_registers));
1240f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1241f43cf1b1SMichael Neumann pitcairn_golden_rlc_registers,
1242f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(pitcairn_golden_rlc_registers));
1243f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1244f43cf1b1SMichael Neumann pitcairn_mgcg_cgcg_init,
1245f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(pitcairn_mgcg_cgcg_init));
1246f43cf1b1SMichael Neumann break;
1247f43cf1b1SMichael Neumann case CHIP_VERDE:
1248f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1249f43cf1b1SMichael Neumann verde_golden_registers,
1250f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(verde_golden_registers));
1251f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1252f43cf1b1SMichael Neumann verde_golden_rlc_registers,
1253f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(verde_golden_rlc_registers));
1254f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1255f43cf1b1SMichael Neumann verde_mgcg_cgcg_init,
1256f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(verde_mgcg_cgcg_init));
1257f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1258f43cf1b1SMichael Neumann verde_pg_init,
1259f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(verde_pg_init));
1260f43cf1b1SMichael Neumann break;
1261f43cf1b1SMichael Neumann case CHIP_OLAND:
1262f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1263f43cf1b1SMichael Neumann oland_golden_registers,
1264f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(oland_golden_registers));
1265f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1266f43cf1b1SMichael Neumann oland_golden_rlc_registers,
1267f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(oland_golden_rlc_registers));
1268f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1269f43cf1b1SMichael Neumann oland_mgcg_cgcg_init,
1270f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init));
1271f43cf1b1SMichael Neumann break;
1272f43cf1b1SMichael Neumann case CHIP_HAINAN:
1273f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1274f43cf1b1SMichael Neumann hainan_golden_registers,
1275f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(hainan_golden_registers));
1276f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1277f43cf1b1SMichael Neumann hainan_golden_registers2,
1278f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(hainan_golden_registers2));
1279f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
1280f43cf1b1SMichael Neumann hainan_mgcg_cgcg_init,
1281f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init));
1282f43cf1b1SMichael Neumann break;
1283f43cf1b1SMichael Neumann default:
1284f43cf1b1SMichael Neumann break;
1285f43cf1b1SMichael Neumann }
1286f43cf1b1SMichael Neumann }
1287f43cf1b1SMichael Neumann
1288c59a5c48SFrançois Tigeot /**
1289c59a5c48SFrançois Tigeot * si_get_allowed_info_register - fetch the register for the info ioctl
1290c59a5c48SFrançois Tigeot *
1291c59a5c48SFrançois Tigeot * @rdev: radeon_device pointer
1292c59a5c48SFrançois Tigeot * @reg: register offset in bytes
1293c59a5c48SFrançois Tigeot * @val: register value
1294c59a5c48SFrançois Tigeot *
1295c59a5c48SFrançois Tigeot * Returns 0 for success or -EINVAL for an invalid register
1296c59a5c48SFrançois Tigeot *
1297c59a5c48SFrançois Tigeot */
si_get_allowed_info_register(struct radeon_device * rdev,u32 reg,u32 * val)1298c59a5c48SFrançois Tigeot int si_get_allowed_info_register(struct radeon_device *rdev,
1299c59a5c48SFrançois Tigeot u32 reg, u32 *val)
1300c59a5c48SFrançois Tigeot {
1301c59a5c48SFrançois Tigeot switch (reg) {
1302c59a5c48SFrançois Tigeot case GRBM_STATUS:
1303c59a5c48SFrançois Tigeot case GRBM_STATUS2:
1304c59a5c48SFrançois Tigeot case GRBM_STATUS_SE0:
1305c59a5c48SFrançois Tigeot case GRBM_STATUS_SE1:
1306c59a5c48SFrançois Tigeot case SRBM_STATUS:
1307c59a5c48SFrançois Tigeot case SRBM_STATUS2:
1308c59a5c48SFrançois Tigeot case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET):
1309c59a5c48SFrançois Tigeot case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET):
1310c59a5c48SFrançois Tigeot case UVD_STATUS:
1311c59a5c48SFrançois Tigeot *val = RREG32(reg);
1312c59a5c48SFrançois Tigeot return 0;
1313c59a5c48SFrançois Tigeot default:
1314c59a5c48SFrançois Tigeot return -EINVAL;
1315c59a5c48SFrançois Tigeot }
1316c59a5c48SFrançois Tigeot }
1317c59a5c48SFrançois Tigeot
1318b403bed8SMichael Neumann #define PCIE_BUS_CLK 10000
1319b403bed8SMichael Neumann #define TCLK (PCIE_BUS_CLK / 10)
1320b403bed8SMichael Neumann
1321b403bed8SMichael Neumann /**
1322b403bed8SMichael Neumann * si_get_xclk - get the xclk
1323b403bed8SMichael Neumann *
1324b403bed8SMichael Neumann * @rdev: radeon_device pointer
1325b403bed8SMichael Neumann *
1326b403bed8SMichael Neumann * Returns the reference clock used by the gfx engine
1327b403bed8SMichael Neumann * (SI).
1328b403bed8SMichael Neumann */
si_get_xclk(struct radeon_device * rdev)1329b403bed8SMichael Neumann u32 si_get_xclk(struct radeon_device *rdev)
1330b403bed8SMichael Neumann {
1331b403bed8SMichael Neumann u32 reference_clock = rdev->clock.spll.reference_freq;
1332b403bed8SMichael Neumann u32 tmp;
1333b403bed8SMichael Neumann
1334b403bed8SMichael Neumann tmp = RREG32(CG_CLKPIN_CNTL_2);
1335b403bed8SMichael Neumann if (tmp & MUX_TCLK_TO_XCLK)
1336b403bed8SMichael Neumann return TCLK;
1337b403bed8SMichael Neumann
1338b403bed8SMichael Neumann tmp = RREG32(CG_CLKPIN_CNTL);
1339b403bed8SMichael Neumann if (tmp & XTALIN_DIVIDE)
1340b403bed8SMichael Neumann return reference_clock / 4;
1341b403bed8SMichael Neumann
1342b403bed8SMichael Neumann return reference_clock;
1343b403bed8SMichael Neumann }
1344926deccbSFrançois Tigeot
1345926deccbSFrançois Tigeot /* get temperature in millidegrees */
si_get_temp(struct radeon_device * rdev)1346926deccbSFrançois Tigeot int si_get_temp(struct radeon_device *rdev)
1347926deccbSFrançois Tigeot {
1348926deccbSFrançois Tigeot u32 temp;
1349926deccbSFrançois Tigeot int actual_temp = 0;
1350926deccbSFrançois Tigeot
1351926deccbSFrançois Tigeot temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >>
1352926deccbSFrançois Tigeot CTF_TEMP_SHIFT;
1353926deccbSFrançois Tigeot
1354926deccbSFrançois Tigeot if (temp & 0x200)
1355926deccbSFrançois Tigeot actual_temp = 255;
1356926deccbSFrançois Tigeot else
1357926deccbSFrançois Tigeot actual_temp = temp & 0x1ff;
1358926deccbSFrançois Tigeot
1359926deccbSFrançois Tigeot actual_temp = (actual_temp * 1000);
1360926deccbSFrançois Tigeot
1361926deccbSFrançois Tigeot return actual_temp;
1362926deccbSFrançois Tigeot }
1363926deccbSFrançois Tigeot
1364926deccbSFrançois Tigeot #define TAHITI_IO_MC_REGS_SIZE 36
1365926deccbSFrançois Tigeot
1366926deccbSFrançois Tigeot static const u32 tahiti_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1367926deccbSFrançois Tigeot {0x0000006f, 0x03044000},
1368926deccbSFrançois Tigeot {0x00000070, 0x0480c018},
1369926deccbSFrançois Tigeot {0x00000071, 0x00000040},
1370926deccbSFrançois Tigeot {0x00000072, 0x01000000},
1371926deccbSFrançois Tigeot {0x00000074, 0x000000ff},
1372926deccbSFrançois Tigeot {0x00000075, 0x00143400},
1373926deccbSFrançois Tigeot {0x00000076, 0x08ec0800},
1374926deccbSFrançois Tigeot {0x00000077, 0x040000cc},
1375926deccbSFrançois Tigeot {0x00000079, 0x00000000},
1376926deccbSFrançois Tigeot {0x0000007a, 0x21000409},
1377926deccbSFrançois Tigeot {0x0000007c, 0x00000000},
1378926deccbSFrançois Tigeot {0x0000007d, 0xe8000000},
1379926deccbSFrançois Tigeot {0x0000007e, 0x044408a8},
1380926deccbSFrançois Tigeot {0x0000007f, 0x00000003},
1381926deccbSFrançois Tigeot {0x00000080, 0x00000000},
1382926deccbSFrançois Tigeot {0x00000081, 0x01000000},
1383926deccbSFrançois Tigeot {0x00000082, 0x02000000},
1384926deccbSFrançois Tigeot {0x00000083, 0x00000000},
1385926deccbSFrançois Tigeot {0x00000084, 0xe3f3e4f4},
1386926deccbSFrançois Tigeot {0x00000085, 0x00052024},
1387926deccbSFrançois Tigeot {0x00000087, 0x00000000},
1388926deccbSFrançois Tigeot {0x00000088, 0x66036603},
1389926deccbSFrançois Tigeot {0x00000089, 0x01000000},
1390926deccbSFrançois Tigeot {0x0000008b, 0x1c0a0000},
1391926deccbSFrançois Tigeot {0x0000008c, 0xff010000},
1392926deccbSFrançois Tigeot {0x0000008e, 0xffffefff},
1393926deccbSFrançois Tigeot {0x0000008f, 0xfff3efff},
1394926deccbSFrançois Tigeot {0x00000090, 0xfff3efbf},
1395926deccbSFrançois Tigeot {0x00000094, 0x00101101},
1396926deccbSFrançois Tigeot {0x00000095, 0x00000fff},
1397926deccbSFrançois Tigeot {0x00000096, 0x00116fff},
1398926deccbSFrançois Tigeot {0x00000097, 0x60010000},
1399926deccbSFrançois Tigeot {0x00000098, 0x10010000},
1400926deccbSFrançois Tigeot {0x00000099, 0x00006000},
1401926deccbSFrançois Tigeot {0x0000009a, 0x00001000},
1402926deccbSFrançois Tigeot {0x0000009f, 0x00a77400}
1403926deccbSFrançois Tigeot };
1404926deccbSFrançois Tigeot
1405926deccbSFrançois Tigeot static const u32 pitcairn_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1406926deccbSFrançois Tigeot {0x0000006f, 0x03044000},
1407926deccbSFrançois Tigeot {0x00000070, 0x0480c018},
1408926deccbSFrançois Tigeot {0x00000071, 0x00000040},
1409926deccbSFrançois Tigeot {0x00000072, 0x01000000},
1410926deccbSFrançois Tigeot {0x00000074, 0x000000ff},
1411926deccbSFrançois Tigeot {0x00000075, 0x00143400},
1412926deccbSFrançois Tigeot {0x00000076, 0x08ec0800},
1413926deccbSFrançois Tigeot {0x00000077, 0x040000cc},
1414926deccbSFrançois Tigeot {0x00000079, 0x00000000},
1415926deccbSFrançois Tigeot {0x0000007a, 0x21000409},
1416926deccbSFrançois Tigeot {0x0000007c, 0x00000000},
1417926deccbSFrançois Tigeot {0x0000007d, 0xe8000000},
1418926deccbSFrançois Tigeot {0x0000007e, 0x044408a8},
1419926deccbSFrançois Tigeot {0x0000007f, 0x00000003},
1420926deccbSFrançois Tigeot {0x00000080, 0x00000000},
1421926deccbSFrançois Tigeot {0x00000081, 0x01000000},
1422926deccbSFrançois Tigeot {0x00000082, 0x02000000},
1423926deccbSFrançois Tigeot {0x00000083, 0x00000000},
1424926deccbSFrançois Tigeot {0x00000084, 0xe3f3e4f4},
1425926deccbSFrançois Tigeot {0x00000085, 0x00052024},
1426926deccbSFrançois Tigeot {0x00000087, 0x00000000},
1427926deccbSFrançois Tigeot {0x00000088, 0x66036603},
1428926deccbSFrançois Tigeot {0x00000089, 0x01000000},
1429926deccbSFrançois Tigeot {0x0000008b, 0x1c0a0000},
1430926deccbSFrançois Tigeot {0x0000008c, 0xff010000},
1431926deccbSFrançois Tigeot {0x0000008e, 0xffffefff},
1432926deccbSFrançois Tigeot {0x0000008f, 0xfff3efff},
1433926deccbSFrançois Tigeot {0x00000090, 0xfff3efbf},
1434926deccbSFrançois Tigeot {0x00000094, 0x00101101},
1435926deccbSFrançois Tigeot {0x00000095, 0x00000fff},
1436926deccbSFrançois Tigeot {0x00000096, 0x00116fff},
1437926deccbSFrançois Tigeot {0x00000097, 0x60010000},
1438926deccbSFrançois Tigeot {0x00000098, 0x10010000},
1439926deccbSFrançois Tigeot {0x00000099, 0x00006000},
1440926deccbSFrançois Tigeot {0x0000009a, 0x00001000},
1441926deccbSFrançois Tigeot {0x0000009f, 0x00a47400}
1442926deccbSFrançois Tigeot };
1443926deccbSFrançois Tigeot
1444926deccbSFrançois Tigeot static const u32 verde_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1445926deccbSFrançois Tigeot {0x0000006f, 0x03044000},
1446926deccbSFrançois Tigeot {0x00000070, 0x0480c018},
1447926deccbSFrançois Tigeot {0x00000071, 0x00000040},
1448926deccbSFrançois Tigeot {0x00000072, 0x01000000},
1449926deccbSFrançois Tigeot {0x00000074, 0x000000ff},
1450926deccbSFrançois Tigeot {0x00000075, 0x00143400},
1451926deccbSFrançois Tigeot {0x00000076, 0x08ec0800},
1452926deccbSFrançois Tigeot {0x00000077, 0x040000cc},
1453926deccbSFrançois Tigeot {0x00000079, 0x00000000},
1454926deccbSFrançois Tigeot {0x0000007a, 0x21000409},
1455926deccbSFrançois Tigeot {0x0000007c, 0x00000000},
1456926deccbSFrançois Tigeot {0x0000007d, 0xe8000000},
1457926deccbSFrançois Tigeot {0x0000007e, 0x044408a8},
1458926deccbSFrançois Tigeot {0x0000007f, 0x00000003},
1459926deccbSFrançois Tigeot {0x00000080, 0x00000000},
1460926deccbSFrançois Tigeot {0x00000081, 0x01000000},
1461926deccbSFrançois Tigeot {0x00000082, 0x02000000},
1462926deccbSFrançois Tigeot {0x00000083, 0x00000000},
1463926deccbSFrançois Tigeot {0x00000084, 0xe3f3e4f4},
1464926deccbSFrançois Tigeot {0x00000085, 0x00052024},
1465926deccbSFrançois Tigeot {0x00000087, 0x00000000},
1466926deccbSFrançois Tigeot {0x00000088, 0x66036603},
1467926deccbSFrançois Tigeot {0x00000089, 0x01000000},
1468926deccbSFrançois Tigeot {0x0000008b, 0x1c0a0000},
1469926deccbSFrançois Tigeot {0x0000008c, 0xff010000},
1470926deccbSFrançois Tigeot {0x0000008e, 0xffffefff},
1471926deccbSFrançois Tigeot {0x0000008f, 0xfff3efff},
1472926deccbSFrançois Tigeot {0x00000090, 0xfff3efbf},
1473926deccbSFrançois Tigeot {0x00000094, 0x00101101},
1474926deccbSFrançois Tigeot {0x00000095, 0x00000fff},
1475926deccbSFrançois Tigeot {0x00000096, 0x00116fff},
1476926deccbSFrançois Tigeot {0x00000097, 0x60010000},
1477926deccbSFrançois Tigeot {0x00000098, 0x10010000},
1478926deccbSFrançois Tigeot {0x00000099, 0x00006000},
1479926deccbSFrançois Tigeot {0x0000009a, 0x00001000},
1480926deccbSFrançois Tigeot {0x0000009f, 0x00a37400}
1481926deccbSFrançois Tigeot };
1482926deccbSFrançois Tigeot
1483b403bed8SMichael Neumann static const u32 oland_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1484b403bed8SMichael Neumann {0x0000006f, 0x03044000},
1485b403bed8SMichael Neumann {0x00000070, 0x0480c018},
1486b403bed8SMichael Neumann {0x00000071, 0x00000040},
1487b403bed8SMichael Neumann {0x00000072, 0x01000000},
1488b403bed8SMichael Neumann {0x00000074, 0x000000ff},
1489b403bed8SMichael Neumann {0x00000075, 0x00143400},
1490b403bed8SMichael Neumann {0x00000076, 0x08ec0800},
1491b403bed8SMichael Neumann {0x00000077, 0x040000cc},
1492b403bed8SMichael Neumann {0x00000079, 0x00000000},
1493b403bed8SMichael Neumann {0x0000007a, 0x21000409},
1494b403bed8SMichael Neumann {0x0000007c, 0x00000000},
1495b403bed8SMichael Neumann {0x0000007d, 0xe8000000},
1496b403bed8SMichael Neumann {0x0000007e, 0x044408a8},
1497b403bed8SMichael Neumann {0x0000007f, 0x00000003},
1498b403bed8SMichael Neumann {0x00000080, 0x00000000},
1499b403bed8SMichael Neumann {0x00000081, 0x01000000},
1500b403bed8SMichael Neumann {0x00000082, 0x02000000},
1501b403bed8SMichael Neumann {0x00000083, 0x00000000},
1502b403bed8SMichael Neumann {0x00000084, 0xe3f3e4f4},
1503b403bed8SMichael Neumann {0x00000085, 0x00052024},
1504b403bed8SMichael Neumann {0x00000087, 0x00000000},
1505b403bed8SMichael Neumann {0x00000088, 0x66036603},
1506b403bed8SMichael Neumann {0x00000089, 0x01000000},
1507b403bed8SMichael Neumann {0x0000008b, 0x1c0a0000},
1508b403bed8SMichael Neumann {0x0000008c, 0xff010000},
1509b403bed8SMichael Neumann {0x0000008e, 0xffffefff},
1510b403bed8SMichael Neumann {0x0000008f, 0xfff3efff},
1511b403bed8SMichael Neumann {0x00000090, 0xfff3efbf},
1512b403bed8SMichael Neumann {0x00000094, 0x00101101},
1513b403bed8SMichael Neumann {0x00000095, 0x00000fff},
1514b403bed8SMichael Neumann {0x00000096, 0x00116fff},
1515b403bed8SMichael Neumann {0x00000097, 0x60010000},
1516b403bed8SMichael Neumann {0x00000098, 0x10010000},
1517b403bed8SMichael Neumann {0x00000099, 0x00006000},
1518b403bed8SMichael Neumann {0x0000009a, 0x00001000},
1519b403bed8SMichael Neumann {0x0000009f, 0x00a17730}
1520b403bed8SMichael Neumann };
1521b403bed8SMichael Neumann
1522f43cf1b1SMichael Neumann static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1523f43cf1b1SMichael Neumann {0x0000006f, 0x03044000},
1524f43cf1b1SMichael Neumann {0x00000070, 0x0480c018},
1525f43cf1b1SMichael Neumann {0x00000071, 0x00000040},
1526f43cf1b1SMichael Neumann {0x00000072, 0x01000000},
1527f43cf1b1SMichael Neumann {0x00000074, 0x000000ff},
1528f43cf1b1SMichael Neumann {0x00000075, 0x00143400},
1529f43cf1b1SMichael Neumann {0x00000076, 0x08ec0800},
1530f43cf1b1SMichael Neumann {0x00000077, 0x040000cc},
1531f43cf1b1SMichael Neumann {0x00000079, 0x00000000},
1532f43cf1b1SMichael Neumann {0x0000007a, 0x21000409},
1533f43cf1b1SMichael Neumann {0x0000007c, 0x00000000},
1534f43cf1b1SMichael Neumann {0x0000007d, 0xe8000000},
1535f43cf1b1SMichael Neumann {0x0000007e, 0x044408a8},
1536f43cf1b1SMichael Neumann {0x0000007f, 0x00000003},
1537f43cf1b1SMichael Neumann {0x00000080, 0x00000000},
1538f43cf1b1SMichael Neumann {0x00000081, 0x01000000},
1539f43cf1b1SMichael Neumann {0x00000082, 0x02000000},
1540f43cf1b1SMichael Neumann {0x00000083, 0x00000000},
1541f43cf1b1SMichael Neumann {0x00000084, 0xe3f3e4f4},
1542f43cf1b1SMichael Neumann {0x00000085, 0x00052024},
1543f43cf1b1SMichael Neumann {0x00000087, 0x00000000},
1544f43cf1b1SMichael Neumann {0x00000088, 0x66036603},
1545f43cf1b1SMichael Neumann {0x00000089, 0x01000000},
1546f43cf1b1SMichael Neumann {0x0000008b, 0x1c0a0000},
1547f43cf1b1SMichael Neumann {0x0000008c, 0xff010000},
1548f43cf1b1SMichael Neumann {0x0000008e, 0xffffefff},
1549f43cf1b1SMichael Neumann {0x0000008f, 0xfff3efff},
1550f43cf1b1SMichael Neumann {0x00000090, 0xfff3efbf},
1551f43cf1b1SMichael Neumann {0x00000094, 0x00101101},
1552f43cf1b1SMichael Neumann {0x00000095, 0x00000fff},
1553f43cf1b1SMichael Neumann {0x00000096, 0x00116fff},
1554f43cf1b1SMichael Neumann {0x00000097, 0x60010000},
1555f43cf1b1SMichael Neumann {0x00000098, 0x10010000},
1556f43cf1b1SMichael Neumann {0x00000099, 0x00006000},
1557f43cf1b1SMichael Neumann {0x0000009a, 0x00001000},
1558f43cf1b1SMichael Neumann {0x0000009f, 0x00a07730}
1559f43cf1b1SMichael Neumann };
1560f43cf1b1SMichael Neumann
1561926deccbSFrançois Tigeot /* ucode loading */
si_mc_load_microcode(struct radeon_device * rdev)1562c6f73aabSFrançois Tigeot int si_mc_load_microcode(struct radeon_device *rdev)
1563926deccbSFrançois Tigeot {
1564cb754608SImre Vadász const __be32 *fw_data = NULL;
1565cb754608SImre Vadász const __le32 *new_fw_data = NULL;
15661dedbd3bSFrançois Tigeot u32 running;
1567cb754608SImre Vadász u32 *io_mc_regs = NULL;
1568cb754608SImre Vadász const __le32 *new_io_mc_regs = NULL;
1569c6f73aabSFrançois Tigeot int i, regs_size, ucode_size;
1570926deccbSFrançois Tigeot
1571926deccbSFrançois Tigeot if (!rdev->mc_fw)
1572926deccbSFrançois Tigeot return -EINVAL;
1573926deccbSFrançois Tigeot
1574cb754608SImre Vadász if (rdev->new_fw) {
1575cb754608SImre Vadász const struct mc_firmware_header_v1_0 *hdr =
1576cb754608SImre Vadász (const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data;
1577cb754608SImre Vadász
1578cb754608SImre Vadász radeon_ucode_print_mc_hdr(&hdr->header);
1579cb754608SImre Vadász regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
1580cb754608SImre Vadász new_io_mc_regs = (const __le32 *)
1581c59a5c48SFrançois Tigeot (rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
1582cb754608SImre Vadász ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
1583cb754608SImre Vadász new_fw_data = (const __le32 *)
1584c59a5c48SFrançois Tigeot (rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
1585cb754608SImre Vadász } else {
1586c6f73aabSFrançois Tigeot ucode_size = rdev->mc_fw->datasize / 4;
1587c6f73aabSFrançois Tigeot
1588926deccbSFrançois Tigeot switch (rdev->family) {
1589926deccbSFrançois Tigeot case CHIP_TAHITI:
1590926deccbSFrançois Tigeot io_mc_regs = (u32 *)&tahiti_io_mc_regs;
1591926deccbSFrançois Tigeot regs_size = TAHITI_IO_MC_REGS_SIZE;
1592926deccbSFrançois Tigeot break;
1593926deccbSFrançois Tigeot case CHIP_PITCAIRN:
1594926deccbSFrançois Tigeot io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
1595926deccbSFrançois Tigeot regs_size = TAHITI_IO_MC_REGS_SIZE;
1596926deccbSFrançois Tigeot break;
1597926deccbSFrançois Tigeot case CHIP_VERDE:
1598926deccbSFrançois Tigeot default:
1599926deccbSFrançois Tigeot io_mc_regs = (u32 *)&verde_io_mc_regs;
1600926deccbSFrançois Tigeot regs_size = TAHITI_IO_MC_REGS_SIZE;
1601926deccbSFrançois Tigeot break;
1602b403bed8SMichael Neumann case CHIP_OLAND:
1603b403bed8SMichael Neumann io_mc_regs = (u32 *)&oland_io_mc_regs;
1604b403bed8SMichael Neumann regs_size = TAHITI_IO_MC_REGS_SIZE;
1605b403bed8SMichael Neumann break;
1606f43cf1b1SMichael Neumann case CHIP_HAINAN:
1607f43cf1b1SMichael Neumann io_mc_regs = (u32 *)&hainan_io_mc_regs;
1608f43cf1b1SMichael Neumann regs_size = TAHITI_IO_MC_REGS_SIZE;
1609f43cf1b1SMichael Neumann break;
1610926deccbSFrançois Tigeot }
1611cb754608SImre Vadász fw_data = (const __be32 *)rdev->mc_fw->data;
1612cb754608SImre Vadász }
1613926deccbSFrançois Tigeot
1614926deccbSFrançois Tigeot running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
1615926deccbSFrançois Tigeot
1616926deccbSFrançois Tigeot if (running == 0) {
1617926deccbSFrançois Tigeot /* reset the engine and set to writable */
1618926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1619926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
1620926deccbSFrançois Tigeot
1621926deccbSFrançois Tigeot /* load mc io regs */
1622926deccbSFrançois Tigeot for (i = 0; i < regs_size; i++) {
1623cb754608SImre Vadász if (rdev->new_fw) {
1624cb754608SImre Vadász WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++));
1625cb754608SImre Vadász WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++));
1626cb754608SImre Vadász } else {
1627926deccbSFrançois Tigeot WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
1628926deccbSFrançois Tigeot WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
1629926deccbSFrançois Tigeot }
1630cb754608SImre Vadász }
1631926deccbSFrançois Tigeot /* load the MC ucode */
1632cb754608SImre Vadász for (i = 0; i < ucode_size; i++) {
1633cb754608SImre Vadász if (rdev->new_fw)
1634cb754608SImre Vadász WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++));
1635cb754608SImre Vadász else
1636926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
1637cb754608SImre Vadász }
1638926deccbSFrançois Tigeot
1639926deccbSFrançois Tigeot /* put the engine back into the active state */
1640926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1641926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
1642926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
1643926deccbSFrançois Tigeot
1644926deccbSFrançois Tigeot /* wait for training to complete */
1645926deccbSFrançois Tigeot for (i = 0; i < rdev->usec_timeout; i++) {
1646926deccbSFrançois Tigeot if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
1647926deccbSFrançois Tigeot break;
1648c4ef309bSzrj udelay(1);
1649926deccbSFrançois Tigeot }
1650926deccbSFrançois Tigeot for (i = 0; i < rdev->usec_timeout; i++) {
1651926deccbSFrançois Tigeot if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
1652926deccbSFrançois Tigeot break;
1653c4ef309bSzrj udelay(1);
1654926deccbSFrançois Tigeot }
1655926deccbSFrançois Tigeot }
1656926deccbSFrançois Tigeot
1657926deccbSFrançois Tigeot return 0;
1658926deccbSFrançois Tigeot }
1659926deccbSFrançois Tigeot
si_init_microcode(struct radeon_device * rdev)1660926deccbSFrançois Tigeot static int si_init_microcode(struct radeon_device *rdev)
1661926deccbSFrançois Tigeot {
1662926deccbSFrançois Tigeot const char *chip_name;
1663cb754608SImre Vadász const char *new_chip_name;
1664926deccbSFrançois Tigeot size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
1665c6f73aabSFrançois Tigeot size_t smc_req_size, mc2_req_size;
1666926deccbSFrançois Tigeot char fw_name[30];
1667926deccbSFrançois Tigeot int err;
1668cb754608SImre Vadász int new_fw = 0;
16691dedbd3bSFrançois Tigeot bool new_smc = false;
16704be47400SFrançois Tigeot bool si58_fw = false;
16714be47400SFrançois Tigeot bool banks2_fw = false;
1672926deccbSFrançois Tigeot
1673926deccbSFrançois Tigeot DRM_DEBUG("\n");
1674926deccbSFrançois Tigeot
1675926deccbSFrançois Tigeot switch (rdev->family) {
1676926deccbSFrançois Tigeot case CHIP_TAHITI:
1677926deccbSFrançois Tigeot chip_name = "TAHITI";
1678cb754608SImre Vadász new_chip_name = "tahiti";
1679926deccbSFrançois Tigeot pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1680926deccbSFrançois Tigeot me_req_size = SI_PM4_UCODE_SIZE * 4;
1681926deccbSFrançois Tigeot ce_req_size = SI_CE_UCODE_SIZE * 4;
1682926deccbSFrançois Tigeot rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1683926deccbSFrançois Tigeot mc_req_size = SI_MC_UCODE_SIZE * 4;
1684c6f73aabSFrançois Tigeot mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;
168557e252bfSMichael Neumann smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
1686926deccbSFrançois Tigeot break;
1687926deccbSFrançois Tigeot case CHIP_PITCAIRN:
1688926deccbSFrançois Tigeot chip_name = "PITCAIRN";
16894be47400SFrançois Tigeot if ((rdev->pdev->revision == 0x81) &&
16904be47400SFrançois Tigeot ((rdev->pdev->device == 0x6810) ||
16914be47400SFrançois Tigeot (rdev->pdev->device == 0x6811)))
16921dedbd3bSFrançois Tigeot new_smc = true;
1693cb754608SImre Vadász new_chip_name = "pitcairn";
1694926deccbSFrançois Tigeot pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1695926deccbSFrançois Tigeot me_req_size = SI_PM4_UCODE_SIZE * 4;
1696926deccbSFrançois Tigeot ce_req_size = SI_CE_UCODE_SIZE * 4;
1697926deccbSFrançois Tigeot rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1698926deccbSFrançois Tigeot mc_req_size = SI_MC_UCODE_SIZE * 4;
1699c6f73aabSFrançois Tigeot mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;
170057e252bfSMichael Neumann smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
1701926deccbSFrançois Tigeot break;
1702926deccbSFrançois Tigeot case CHIP_VERDE:
1703926deccbSFrançois Tigeot chip_name = "VERDE";
17044be47400SFrançois Tigeot if (((rdev->pdev->device == 0x6820) &&
17054be47400SFrançois Tigeot ((rdev->pdev->revision == 0x81) ||
17064be47400SFrançois Tigeot (rdev->pdev->revision == 0x83))) ||
17074be47400SFrançois Tigeot ((rdev->pdev->device == 0x6821) &&
17084be47400SFrançois Tigeot ((rdev->pdev->revision == 0x83) ||
17094be47400SFrançois Tigeot (rdev->pdev->revision == 0x87))) ||
17104be47400SFrançois Tigeot ((rdev->pdev->revision == 0x87) &&
17114be47400SFrançois Tigeot ((rdev->pdev->device == 0x6823) ||
17124be47400SFrançois Tigeot (rdev->pdev->device == 0x682b))))
17131dedbd3bSFrançois Tigeot new_smc = true;
1714cb754608SImre Vadász new_chip_name = "verde";
1715926deccbSFrançois Tigeot pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1716926deccbSFrançois Tigeot me_req_size = SI_PM4_UCODE_SIZE * 4;
1717926deccbSFrançois Tigeot ce_req_size = SI_CE_UCODE_SIZE * 4;
1718926deccbSFrançois Tigeot rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1719926deccbSFrançois Tigeot mc_req_size = SI_MC_UCODE_SIZE * 4;
1720c6f73aabSFrançois Tigeot mc2_req_size = VERDE_MC_UCODE_SIZE * 4;
172157e252bfSMichael Neumann smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
1722926deccbSFrançois Tigeot break;
1723b403bed8SMichael Neumann case CHIP_OLAND:
1724b403bed8SMichael Neumann chip_name = "OLAND";
17254be47400SFrançois Tigeot if (((rdev->pdev->revision == 0x81) &&
17264be47400SFrançois Tigeot ((rdev->pdev->device == 0x6600) ||
17271dedbd3bSFrançois Tigeot (rdev->pdev->device == 0x6604) ||
17284be47400SFrançois Tigeot (rdev->pdev->device == 0x6605) ||
17294be47400SFrançois Tigeot (rdev->pdev->device == 0x6610))) ||
17304be47400SFrançois Tigeot ((rdev->pdev->revision == 0x83) &&
17314be47400SFrançois Tigeot (rdev->pdev->device == 0x6610)))
17321dedbd3bSFrançois Tigeot new_smc = true;
1733cb754608SImre Vadász new_chip_name = "oland";
1734b403bed8SMichael Neumann pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1735b403bed8SMichael Neumann me_req_size = SI_PM4_UCODE_SIZE * 4;
1736b403bed8SMichael Neumann ce_req_size = SI_CE_UCODE_SIZE * 4;
1737b403bed8SMichael Neumann rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1738c6f73aabSFrançois Tigeot mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
173957e252bfSMichael Neumann smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
1740b403bed8SMichael Neumann break;
1741f43cf1b1SMichael Neumann case CHIP_HAINAN:
1742f43cf1b1SMichael Neumann chip_name = "HAINAN";
17434be47400SFrançois Tigeot if (((rdev->pdev->revision == 0x81) &&
17444be47400SFrançois Tigeot (rdev->pdev->device == 0x6660)) ||
17454be47400SFrançois Tigeot ((rdev->pdev->revision == 0x83) &&
17464be47400SFrançois Tigeot ((rdev->pdev->device == 0x6660) ||
17474be47400SFrançois Tigeot (rdev->pdev->device == 0x6663) ||
17481dedbd3bSFrançois Tigeot (rdev->pdev->device == 0x6665) ||
17494be47400SFrançois Tigeot (rdev->pdev->device == 0x6667))))
17501dedbd3bSFrançois Tigeot new_smc = true;
17514be47400SFrançois Tigeot else if ((rdev->pdev->revision == 0xc3) &&
17524be47400SFrançois Tigeot (rdev->pdev->device == 0x6665))
17534be47400SFrançois Tigeot banks2_fw = true;
1754cb754608SImre Vadász new_chip_name = "hainan";
1755f43cf1b1SMichael Neumann pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1756f43cf1b1SMichael Neumann me_req_size = SI_PM4_UCODE_SIZE * 4;
1757f43cf1b1SMichael Neumann ce_req_size = SI_CE_UCODE_SIZE * 4;
1758f43cf1b1SMichael Neumann rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1759c6f73aabSFrançois Tigeot mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
176057e252bfSMichael Neumann smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
1761f43cf1b1SMichael Neumann break;
1762c4ef309bSzrj default: BUG();
1763926deccbSFrançois Tigeot }
1764926deccbSFrançois Tigeot
17654be47400SFrançois Tigeot /* this memory configuration requires special firmware */
17664be47400SFrançois Tigeot if (((RREG32(MC_SEQ_MISC0) & 0xff000000) >> 24) == 0x58)
17674be47400SFrançois Tigeot si58_fw = true;
17684be47400SFrançois Tigeot
1769cb754608SImre Vadász DRM_INFO("Loading %s Microcode\n", new_chip_name);
1770926deccbSFrançois Tigeot
1771cb754608SImre Vadász ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", new_chip_name);
177271187b16SFrançois Tigeot err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
1773cb754608SImre Vadász if (err) {
1774926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name);
177571187b16SFrançois Tigeot err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
1776fcd4983fSzrj if (err)
1777926deccbSFrançois Tigeot goto out;
1778926deccbSFrançois Tigeot if (rdev->pfp_fw->datasize != pfp_req_size) {
1779*3f2dd94aSFrançois Tigeot pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1780926deccbSFrançois Tigeot rdev->pfp_fw->datasize, fw_name);
1781926deccbSFrançois Tigeot err = -EINVAL;
1782926deccbSFrançois Tigeot goto out;
1783926deccbSFrançois Tigeot }
1784cb754608SImre Vadász } else {
1785cb754608SImre Vadász err = radeon_ucode_validate(rdev->pfp_fw);
1786cb754608SImre Vadász if (err) {
1787a85cb24fSFrançois Tigeot pr_err("si_cp: validation failed for firmware \"%s\"\n",
1788cb754608SImre Vadász fw_name);
1789cb754608SImre Vadász goto out;
1790cb754608SImre Vadász } else {
1791cb754608SImre Vadász new_fw++;
1792cb754608SImre Vadász }
1793cb754608SImre Vadász }
1794926deccbSFrançois Tigeot
1795cb754608SImre Vadász ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", new_chip_name);
179671187b16SFrançois Tigeot err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
1797cb754608SImre Vadász if (err) {
1798926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name);
179971187b16SFrançois Tigeot err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
1800fcd4983fSzrj if (err)
1801926deccbSFrançois Tigeot goto out;
1802926deccbSFrançois Tigeot if (rdev->me_fw->datasize != me_req_size) {
1803*3f2dd94aSFrançois Tigeot pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1804926deccbSFrançois Tigeot rdev->me_fw->datasize, fw_name);
1805926deccbSFrançois Tigeot err = -EINVAL;
1806926deccbSFrançois Tigeot }
1807cb754608SImre Vadász } else {
1808cb754608SImre Vadász err = radeon_ucode_validate(rdev->me_fw);
1809cb754608SImre Vadász if (err) {
1810*3f2dd94aSFrançois Tigeot pr_err("si_cp: validation failed for firmware \"%s\"\n",
1811cb754608SImre Vadász fw_name);
1812cb754608SImre Vadász goto out;
1813cb754608SImre Vadász } else {
1814cb754608SImre Vadász new_fw++;
1815cb754608SImre Vadász }
1816cb754608SImre Vadász }
1817926deccbSFrançois Tigeot
1818cb754608SImre Vadász ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_ce", new_chip_name);
181971187b16SFrançois Tigeot err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
1820cb754608SImre Vadász if (err) {
1821926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_ce", chip_name);
182271187b16SFrançois Tigeot err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
1823fcd4983fSzrj if (err)
1824926deccbSFrançois Tigeot goto out;
1825926deccbSFrançois Tigeot if (rdev->ce_fw->datasize != ce_req_size) {
1826*3f2dd94aSFrançois Tigeot pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1827926deccbSFrançois Tigeot rdev->ce_fw->datasize, fw_name);
1828926deccbSFrançois Tigeot err = -EINVAL;
1829926deccbSFrançois Tigeot }
1830cb754608SImre Vadász } else {
1831cb754608SImre Vadász err = radeon_ucode_validate(rdev->ce_fw);
1832cb754608SImre Vadász if (err) {
1833*3f2dd94aSFrançois Tigeot pr_err("si_cp: validation failed for firmware \"%s\"\n",
1834cb754608SImre Vadász fw_name);
1835cb754608SImre Vadász goto out;
1836cb754608SImre Vadász } else {
1837cb754608SImre Vadász new_fw++;
1838cb754608SImre Vadász }
1839cb754608SImre Vadász }
1840926deccbSFrançois Tigeot
1841cb754608SImre Vadász ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", new_chip_name);
184271187b16SFrançois Tigeot err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
1843cb754608SImre Vadász if (err) {
1844cb754608SImre Vadász ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", chip_name);
184571187b16SFrançois Tigeot err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
1846fcd4983fSzrj if (err)
1847926deccbSFrançois Tigeot goto out;
1848926deccbSFrançois Tigeot if (rdev->rlc_fw->datasize != rlc_req_size) {
1849*3f2dd94aSFrançois Tigeot pr_err("si_rlc: Bogus length %zu in firmware \"%s\"\n",
1850926deccbSFrançois Tigeot rdev->rlc_fw->datasize, fw_name);
1851926deccbSFrançois Tigeot err = -EINVAL;
1852926deccbSFrançois Tigeot }
1853cb754608SImre Vadász } else {
1854cb754608SImre Vadász err = radeon_ucode_validate(rdev->rlc_fw);
1855cb754608SImre Vadász if (err) {
1856*3f2dd94aSFrançois Tigeot pr_err("si_cp: validation failed for firmware \"%s\"\n",
1857cb754608SImre Vadász fw_name);
1858cb754608SImre Vadász goto out;
1859cb754608SImre Vadász } else {
1860cb754608SImre Vadász new_fw++;
1861cb754608SImre Vadász }
1862cb754608SImre Vadász }
1863926deccbSFrançois Tigeot
18644be47400SFrançois Tigeot if (si58_fw)
1865a85cb24fSFrançois Tigeot snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_si58_mc");
18664be47400SFrançois Tigeot else
1867a85cb24fSFrançois Tigeot snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", new_chip_name);
186871187b16SFrançois Tigeot err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1869cb754608SImre Vadász if (err) {
1870c6f73aabSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc2", chip_name);
187171187b16SFrançois Tigeot err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1872c6f73aabSFrançois Tigeot if (err) {
1873926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", chip_name);
187471187b16SFrançois Tigeot err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1875fcd4983fSzrj if (err)
1876926deccbSFrançois Tigeot goto out;
1877c6f73aabSFrançois Tigeot }
1878c6f73aabSFrançois Tigeot if ((rdev->mc_fw->datasize != mc_req_size) &&
1879c6f73aabSFrançois Tigeot (rdev->mc_fw->datasize != mc2_req_size)) {
1880*3f2dd94aSFrançois Tigeot pr_err("si_mc: Bogus length %zu in firmware \"%s\"\n",
1881926deccbSFrançois Tigeot rdev->mc_fw->datasize, fw_name);
1882926deccbSFrançois Tigeot err = -EINVAL;
1883926deccbSFrançois Tigeot }
1884c6f73aabSFrançois Tigeot DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->datasize);
1885cb754608SImre Vadász } else {
1886cb754608SImre Vadász err = radeon_ucode_validate(rdev->mc_fw);
1887cb754608SImre Vadász if (err) {
1888a85cb24fSFrançois Tigeot pr_err("si_cp: validation failed for firmware \"%s\"\n",
1889cb754608SImre Vadász fw_name);
1890cb754608SImre Vadász goto out;
1891cb754608SImre Vadász } else {
1892cb754608SImre Vadász new_fw++;
1893cb754608SImre Vadász }
1894cb754608SImre Vadász }
1895926deccbSFrançois Tigeot
18964be47400SFrançois Tigeot if (banks2_fw)
18974be47400SFrançois Tigeot snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_banks_k_2_smc");
18984be47400SFrançois Tigeot else if (new_smc)
18991dedbd3bSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_k_smc", new_chip_name);
19001dedbd3bSFrançois Tigeot else
1901cb754608SImre Vadász ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_smc", new_chip_name);
190271187b16SFrançois Tigeot err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
1903cb754608SImre Vadász if (err) {
190457e252bfSMichael Neumann ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_smc", chip_name);
190571187b16SFrançois Tigeot err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
190657e252bfSMichael Neumann if (err) {
1907*3f2dd94aSFrançois Tigeot pr_err("smc: error loading firmware \"%s\"\n", fw_name);
190857e252bfSMichael Neumann release_firmware(rdev->smc_fw);
190957e252bfSMichael Neumann rdev->smc_fw = NULL;
19104cd92098Szrj err = 0;
191157e252bfSMichael Neumann } else if (rdev->smc_fw->datasize != smc_req_size) {
1912*3f2dd94aSFrançois Tigeot pr_err("si_smc: Bogus length %zu in firmware \"%s\"\n",
191357e252bfSMichael Neumann rdev->smc_fw->datasize, fw_name);
191457e252bfSMichael Neumann err = -EINVAL;
191557e252bfSMichael Neumann }
1916cb754608SImre Vadász } else {
1917cb754608SImre Vadász err = radeon_ucode_validate(rdev->smc_fw);
1918cb754608SImre Vadász if (err) {
1919*3f2dd94aSFrançois Tigeot pr_err("si_cp: validation failed for firmware \"%s\"\n",
1920cb754608SImre Vadász fw_name);
1921cb754608SImre Vadász goto out;
1922cb754608SImre Vadász } else {
1923cb754608SImre Vadász new_fw++;
1924cb754608SImre Vadász }
1925cb754608SImre Vadász }
192657e252bfSMichael Neumann
1927cb754608SImre Vadász if (new_fw == 0) {
1928cb754608SImre Vadász rdev->new_fw = false;
1929cb754608SImre Vadász } else if (new_fw < 6) {
1930a85cb24fSFrançois Tigeot pr_err("si_fw: mixing new and old firmware!\n");
1931cb754608SImre Vadász err = -EINVAL;
1932cb754608SImre Vadász } else {
1933cb754608SImre Vadász rdev->new_fw = true;
1934cb754608SImre Vadász }
1935926deccbSFrançois Tigeot out:
1936926deccbSFrançois Tigeot if (err) {
1937926deccbSFrançois Tigeot if (err != -EINVAL)
1938a85cb24fSFrançois Tigeot pr_err("si_cp: Failed to load firmware \"%s\"\n",
1939926deccbSFrançois Tigeot fw_name);
1940fcd4983fSzrj release_firmware(rdev->pfp_fw);
1941926deccbSFrançois Tigeot rdev->pfp_fw = NULL;
1942fcd4983fSzrj release_firmware(rdev->me_fw);
1943926deccbSFrançois Tigeot rdev->me_fw = NULL;
1944fcd4983fSzrj release_firmware(rdev->ce_fw);
1945926deccbSFrançois Tigeot rdev->ce_fw = NULL;
1946fcd4983fSzrj release_firmware(rdev->rlc_fw);
1947926deccbSFrançois Tigeot rdev->rlc_fw = NULL;
1948fcd4983fSzrj release_firmware(rdev->mc_fw);
1949926deccbSFrançois Tigeot rdev->mc_fw = NULL;
1950fcd4983fSzrj release_firmware(rdev->smc_fw);
195157e252bfSMichael Neumann rdev->smc_fw = NULL;
195257e252bfSMichael Neumann }
1953926deccbSFrançois Tigeot return err;
1954926deccbSFrançois Tigeot }
1955926deccbSFrançois Tigeot
1956926deccbSFrançois Tigeot /* watermark setup */
dce6_line_buffer_adjust(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,struct drm_display_mode * mode,struct drm_display_mode * other_mode)1957926deccbSFrançois Tigeot static u32 dce6_line_buffer_adjust(struct radeon_device *rdev,
1958926deccbSFrançois Tigeot struct radeon_crtc *radeon_crtc,
1959926deccbSFrançois Tigeot struct drm_display_mode *mode,
1960926deccbSFrançois Tigeot struct drm_display_mode *other_mode)
1961926deccbSFrançois Tigeot {
19624cd92098Szrj u32 tmp, buffer_alloc, i;
19634cd92098Szrj u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
1964926deccbSFrançois Tigeot /*
1965926deccbSFrançois Tigeot * Line Buffer Setup
1966926deccbSFrançois Tigeot * There are 3 line buffers, each one shared by 2 display controllers.
1967926deccbSFrançois Tigeot * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
1968926deccbSFrançois Tigeot * the display controllers. The paritioning is done via one of four
1969926deccbSFrançois Tigeot * preset allocations specified in bits 21:20:
1970926deccbSFrançois Tigeot * 0 - half lb
1971926deccbSFrançois Tigeot * 2 - whole lb, other crtc must be disabled
1972926deccbSFrançois Tigeot */
1973926deccbSFrançois Tigeot /* this can get tricky if we have two large displays on a paired group
1974926deccbSFrançois Tigeot * of crtcs. Ideally for multiple large displays we'd assign them to
1975926deccbSFrançois Tigeot * non-linked crtcs for maximum line buffer allocation.
1976926deccbSFrançois Tigeot */
1977926deccbSFrançois Tigeot if (radeon_crtc->base.enabled && mode) {
19784cd92098Szrj if (other_mode) {
1979926deccbSFrançois Tigeot tmp = 0; /* 1/2 */
19804cd92098Szrj buffer_alloc = 1;
19814cd92098Szrj } else {
1982926deccbSFrançois Tigeot tmp = 2; /* whole */
19834cd92098Szrj buffer_alloc = 2;
19844cd92098Szrj }
19854cd92098Szrj } else {
1986926deccbSFrançois Tigeot tmp = 0;
19874cd92098Szrj buffer_alloc = 0;
19884cd92098Szrj }
1989926deccbSFrançois Tigeot
1990926deccbSFrançois Tigeot WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset,
1991926deccbSFrançois Tigeot DC_LB_MEMORY_CONFIG(tmp));
1992926deccbSFrançois Tigeot
19934cd92098Szrj WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
19944cd92098Szrj DMIF_BUFFERS_ALLOCATED(buffer_alloc));
19954cd92098Szrj for (i = 0; i < rdev->usec_timeout; i++) {
19964cd92098Szrj if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
19974cd92098Szrj DMIF_BUFFERS_ALLOCATED_COMPLETED)
19984cd92098Szrj break;
19994cd92098Szrj udelay(1);
20004cd92098Szrj }
20014cd92098Szrj
2002926deccbSFrançois Tigeot if (radeon_crtc->base.enabled && mode) {
2003926deccbSFrançois Tigeot switch (tmp) {
2004926deccbSFrançois Tigeot case 0:
2005926deccbSFrançois Tigeot default:
2006926deccbSFrançois Tigeot return 4096 * 2;
2007926deccbSFrançois Tigeot case 2:
2008926deccbSFrançois Tigeot return 8192 * 2;
2009926deccbSFrançois Tigeot }
2010926deccbSFrançois Tigeot }
2011926deccbSFrançois Tigeot
2012926deccbSFrançois Tigeot /* controller not enabled, so no lb used */
2013926deccbSFrançois Tigeot return 0;
2014926deccbSFrançois Tigeot }
2015926deccbSFrançois Tigeot
si_get_number_of_dram_channels(struct radeon_device * rdev)2016926deccbSFrançois Tigeot static u32 si_get_number_of_dram_channels(struct radeon_device *rdev)
2017926deccbSFrançois Tigeot {
2018926deccbSFrançois Tigeot u32 tmp = RREG32(MC_SHARED_CHMAP);
2019926deccbSFrançois Tigeot
2020926deccbSFrançois Tigeot switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
2021926deccbSFrançois Tigeot case 0:
2022926deccbSFrançois Tigeot default:
2023926deccbSFrançois Tigeot return 1;
2024926deccbSFrançois Tigeot case 1:
2025926deccbSFrançois Tigeot return 2;
2026926deccbSFrançois Tigeot case 2:
2027926deccbSFrançois Tigeot return 4;
2028926deccbSFrançois Tigeot case 3:
2029926deccbSFrançois Tigeot return 8;
2030926deccbSFrançois Tigeot case 4:
2031926deccbSFrançois Tigeot return 3;
2032926deccbSFrançois Tigeot case 5:
2033926deccbSFrançois Tigeot return 6;
2034926deccbSFrançois Tigeot case 6:
2035926deccbSFrançois Tigeot return 10;
2036926deccbSFrançois Tigeot case 7:
2037926deccbSFrançois Tigeot return 12;
2038926deccbSFrançois Tigeot case 8:
2039926deccbSFrançois Tigeot return 16;
2040926deccbSFrançois Tigeot }
2041926deccbSFrançois Tigeot }
2042926deccbSFrançois Tigeot
2043926deccbSFrançois Tigeot struct dce6_wm_params {
2044926deccbSFrançois Tigeot u32 dram_channels; /* number of dram channels */
2045926deccbSFrançois Tigeot u32 yclk; /* bandwidth per dram data pin in kHz */
2046926deccbSFrançois Tigeot u32 sclk; /* engine clock in kHz */
2047926deccbSFrançois Tigeot u32 disp_clk; /* display clock in kHz */
2048926deccbSFrançois Tigeot u32 src_width; /* viewport width */
2049926deccbSFrançois Tigeot u32 active_time; /* active display time in ns */
2050926deccbSFrançois Tigeot u32 blank_time; /* blank time in ns */
2051926deccbSFrançois Tigeot bool interlaced; /* mode is interlaced */
2052926deccbSFrançois Tigeot fixed20_12 vsc; /* vertical scale ratio */
2053926deccbSFrançois Tigeot u32 num_heads; /* number of active crtcs */
2054926deccbSFrançois Tigeot u32 bytes_per_pixel; /* bytes per pixel display + overlay */
2055926deccbSFrançois Tigeot u32 lb_size; /* line buffer allocated to pipe */
2056926deccbSFrançois Tigeot u32 vtaps; /* vertical scaler taps */
2057926deccbSFrançois Tigeot };
2058926deccbSFrançois Tigeot
dce6_dram_bandwidth(struct dce6_wm_params * wm)2059926deccbSFrançois Tigeot static u32 dce6_dram_bandwidth(struct dce6_wm_params *wm)
2060926deccbSFrançois Tigeot {
2061926deccbSFrançois Tigeot /* Calculate raw DRAM Bandwidth */
2062926deccbSFrançois Tigeot fixed20_12 dram_efficiency; /* 0.7 */
2063926deccbSFrançois Tigeot fixed20_12 yclk, dram_channels, bandwidth;
2064926deccbSFrançois Tigeot fixed20_12 a;
2065926deccbSFrançois Tigeot
2066926deccbSFrançois Tigeot a.full = dfixed_const(1000);
2067926deccbSFrançois Tigeot yclk.full = dfixed_const(wm->yclk);
2068926deccbSFrançois Tigeot yclk.full = dfixed_div(yclk, a);
2069926deccbSFrançois Tigeot dram_channels.full = dfixed_const(wm->dram_channels * 4);
2070926deccbSFrançois Tigeot a.full = dfixed_const(10);
2071926deccbSFrançois Tigeot dram_efficiency.full = dfixed_const(7);
2072926deccbSFrançois Tigeot dram_efficiency.full = dfixed_div(dram_efficiency, a);
2073926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(dram_channels, yclk);
2074926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
2075926deccbSFrançois Tigeot
2076926deccbSFrançois Tigeot return dfixed_trunc(bandwidth);
2077926deccbSFrançois Tigeot }
2078926deccbSFrançois Tigeot
dce6_dram_bandwidth_for_display(struct dce6_wm_params * wm)2079926deccbSFrançois Tigeot static u32 dce6_dram_bandwidth_for_display(struct dce6_wm_params *wm)
2080926deccbSFrançois Tigeot {
2081926deccbSFrançois Tigeot /* Calculate DRAM Bandwidth and the part allocated to display. */
2082926deccbSFrançois Tigeot fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
2083926deccbSFrançois Tigeot fixed20_12 yclk, dram_channels, bandwidth;
2084926deccbSFrançois Tigeot fixed20_12 a;
2085926deccbSFrançois Tigeot
2086926deccbSFrançois Tigeot a.full = dfixed_const(1000);
2087926deccbSFrançois Tigeot yclk.full = dfixed_const(wm->yclk);
2088926deccbSFrançois Tigeot yclk.full = dfixed_div(yclk, a);
2089926deccbSFrançois Tigeot dram_channels.full = dfixed_const(wm->dram_channels * 4);
2090926deccbSFrançois Tigeot a.full = dfixed_const(10);
2091926deccbSFrançois Tigeot disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
2092926deccbSFrançois Tigeot disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
2093926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(dram_channels, yclk);
2094926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
2095926deccbSFrançois Tigeot
2096926deccbSFrançois Tigeot return dfixed_trunc(bandwidth);
2097926deccbSFrançois Tigeot }
2098926deccbSFrançois Tigeot
dce6_data_return_bandwidth(struct dce6_wm_params * wm)2099926deccbSFrançois Tigeot static u32 dce6_data_return_bandwidth(struct dce6_wm_params *wm)
2100926deccbSFrançois Tigeot {
2101926deccbSFrançois Tigeot /* Calculate the display Data return Bandwidth */
2102926deccbSFrançois Tigeot fixed20_12 return_efficiency; /* 0.8 */
2103926deccbSFrançois Tigeot fixed20_12 sclk, bandwidth;
2104926deccbSFrançois Tigeot fixed20_12 a;
2105926deccbSFrançois Tigeot
2106926deccbSFrançois Tigeot a.full = dfixed_const(1000);
2107926deccbSFrançois Tigeot sclk.full = dfixed_const(wm->sclk);
2108926deccbSFrançois Tigeot sclk.full = dfixed_div(sclk, a);
2109926deccbSFrançois Tigeot a.full = dfixed_const(10);
2110926deccbSFrançois Tigeot return_efficiency.full = dfixed_const(8);
2111926deccbSFrançois Tigeot return_efficiency.full = dfixed_div(return_efficiency, a);
2112926deccbSFrançois Tigeot a.full = dfixed_const(32);
2113926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(a, sclk);
2114926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
2115926deccbSFrançois Tigeot
2116926deccbSFrançois Tigeot return dfixed_trunc(bandwidth);
2117926deccbSFrançois Tigeot }
2118926deccbSFrançois Tigeot
dce6_get_dmif_bytes_per_request(struct dce6_wm_params * wm)2119926deccbSFrançois Tigeot static u32 dce6_get_dmif_bytes_per_request(struct dce6_wm_params *wm)
2120926deccbSFrançois Tigeot {
2121926deccbSFrançois Tigeot return 32;
2122926deccbSFrançois Tigeot }
2123926deccbSFrançois Tigeot
dce6_dmif_request_bandwidth(struct dce6_wm_params * wm)2124926deccbSFrançois Tigeot static u32 dce6_dmif_request_bandwidth(struct dce6_wm_params *wm)
2125926deccbSFrançois Tigeot {
2126926deccbSFrançois Tigeot /* Calculate the DMIF Request Bandwidth */
2127926deccbSFrançois Tigeot fixed20_12 disp_clk_request_efficiency; /* 0.8 */
2128926deccbSFrançois Tigeot fixed20_12 disp_clk, sclk, bandwidth;
2129926deccbSFrançois Tigeot fixed20_12 a, b1, b2;
2130926deccbSFrançois Tigeot u32 min_bandwidth;
2131926deccbSFrançois Tigeot
2132926deccbSFrançois Tigeot a.full = dfixed_const(1000);
2133926deccbSFrançois Tigeot disp_clk.full = dfixed_const(wm->disp_clk);
2134926deccbSFrançois Tigeot disp_clk.full = dfixed_div(disp_clk, a);
2135926deccbSFrançois Tigeot a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm) / 2);
2136926deccbSFrançois Tigeot b1.full = dfixed_mul(a, disp_clk);
2137926deccbSFrançois Tigeot
2138926deccbSFrançois Tigeot a.full = dfixed_const(1000);
2139926deccbSFrançois Tigeot sclk.full = dfixed_const(wm->sclk);
2140926deccbSFrançois Tigeot sclk.full = dfixed_div(sclk, a);
2141926deccbSFrançois Tigeot a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm));
2142926deccbSFrançois Tigeot b2.full = dfixed_mul(a, sclk);
2143926deccbSFrançois Tigeot
2144926deccbSFrançois Tigeot a.full = dfixed_const(10);
2145926deccbSFrançois Tigeot disp_clk_request_efficiency.full = dfixed_const(8);
2146926deccbSFrançois Tigeot disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
2147926deccbSFrançois Tigeot
2148926deccbSFrançois Tigeot min_bandwidth = min(dfixed_trunc(b1), dfixed_trunc(b2));
2149926deccbSFrançois Tigeot
2150926deccbSFrançois Tigeot a.full = dfixed_const(min_bandwidth);
2151926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(a, disp_clk_request_efficiency);
2152926deccbSFrançois Tigeot
2153926deccbSFrançois Tigeot return dfixed_trunc(bandwidth);
2154926deccbSFrançois Tigeot }
2155926deccbSFrançois Tigeot
dce6_available_bandwidth(struct dce6_wm_params * wm)2156926deccbSFrançois Tigeot static u32 dce6_available_bandwidth(struct dce6_wm_params *wm)
2157926deccbSFrançois Tigeot {
2158926deccbSFrançois Tigeot /* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
2159926deccbSFrançois Tigeot u32 dram_bandwidth = dce6_dram_bandwidth(wm);
2160926deccbSFrançois Tigeot u32 data_return_bandwidth = dce6_data_return_bandwidth(wm);
2161926deccbSFrançois Tigeot u32 dmif_req_bandwidth = dce6_dmif_request_bandwidth(wm);
2162926deccbSFrançois Tigeot
2163926deccbSFrançois Tigeot return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
2164926deccbSFrançois Tigeot }
2165926deccbSFrançois Tigeot
dce6_average_bandwidth(struct dce6_wm_params * wm)2166926deccbSFrançois Tigeot static u32 dce6_average_bandwidth(struct dce6_wm_params *wm)
2167926deccbSFrançois Tigeot {
2168926deccbSFrançois Tigeot /* Calculate the display mode Average Bandwidth
2169926deccbSFrançois Tigeot * DisplayMode should contain the source and destination dimensions,
2170926deccbSFrançois Tigeot * timing, etc.
2171926deccbSFrançois Tigeot */
2172926deccbSFrançois Tigeot fixed20_12 bpp;
2173926deccbSFrançois Tigeot fixed20_12 line_time;
2174926deccbSFrançois Tigeot fixed20_12 src_width;
2175926deccbSFrançois Tigeot fixed20_12 bandwidth;
2176926deccbSFrançois Tigeot fixed20_12 a;
2177926deccbSFrançois Tigeot
2178926deccbSFrançois Tigeot a.full = dfixed_const(1000);
2179926deccbSFrançois Tigeot line_time.full = dfixed_const(wm->active_time + wm->blank_time);
2180926deccbSFrançois Tigeot line_time.full = dfixed_div(line_time, a);
2181926deccbSFrançois Tigeot bpp.full = dfixed_const(wm->bytes_per_pixel);
2182926deccbSFrançois Tigeot src_width.full = dfixed_const(wm->src_width);
2183926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(src_width, bpp);
2184926deccbSFrançois Tigeot bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
2185926deccbSFrançois Tigeot bandwidth.full = dfixed_div(bandwidth, line_time);
2186926deccbSFrançois Tigeot
2187926deccbSFrançois Tigeot return dfixed_trunc(bandwidth);
2188926deccbSFrançois Tigeot }
2189926deccbSFrançois Tigeot
dce6_latency_watermark(struct dce6_wm_params * wm)2190926deccbSFrançois Tigeot static u32 dce6_latency_watermark(struct dce6_wm_params *wm)
2191926deccbSFrançois Tigeot {
2192926deccbSFrançois Tigeot /* First calcualte the latency in ns */
2193926deccbSFrançois Tigeot u32 mc_latency = 2000; /* 2000 ns. */
2194926deccbSFrançois Tigeot u32 available_bandwidth = dce6_available_bandwidth(wm);
2195926deccbSFrançois Tigeot u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
2196926deccbSFrançois Tigeot u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
2197926deccbSFrançois Tigeot u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
2198926deccbSFrançois Tigeot u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
2199926deccbSFrançois Tigeot (wm->num_heads * cursor_line_pair_return_time);
2200926deccbSFrançois Tigeot u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
2201926deccbSFrançois Tigeot u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
2202926deccbSFrançois Tigeot u32 tmp, dmif_size = 12288;
2203926deccbSFrançois Tigeot fixed20_12 a, b, c;
2204926deccbSFrançois Tigeot
2205926deccbSFrançois Tigeot if (wm->num_heads == 0)
2206926deccbSFrançois Tigeot return 0;
2207926deccbSFrançois Tigeot
2208926deccbSFrançois Tigeot a.full = dfixed_const(2);
2209926deccbSFrançois Tigeot b.full = dfixed_const(1);
2210926deccbSFrançois Tigeot if ((wm->vsc.full > a.full) ||
2211926deccbSFrançois Tigeot ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
2212926deccbSFrançois Tigeot (wm->vtaps >= 5) ||
2213926deccbSFrançois Tigeot ((wm->vsc.full >= a.full) && wm->interlaced))
2214926deccbSFrançois Tigeot max_src_lines_per_dst_line = 4;
2215926deccbSFrançois Tigeot else
2216926deccbSFrançois Tigeot max_src_lines_per_dst_line = 2;
2217926deccbSFrançois Tigeot
2218926deccbSFrançois Tigeot a.full = dfixed_const(available_bandwidth);
2219926deccbSFrançois Tigeot b.full = dfixed_const(wm->num_heads);
2220926deccbSFrançois Tigeot a.full = dfixed_div(a, b);
2221a85cb24fSFrançois Tigeot tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
2222a85cb24fSFrançois Tigeot tmp = min(dfixed_trunc(a), tmp);
2223926deccbSFrançois Tigeot
2224a85cb24fSFrançois Tigeot lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
2225926deccbSFrançois Tigeot
2226926deccbSFrançois Tigeot a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
2227926deccbSFrançois Tigeot b.full = dfixed_const(1000);
2228926deccbSFrançois Tigeot c.full = dfixed_const(lb_fill_bw);
2229926deccbSFrançois Tigeot b.full = dfixed_div(c, b);
2230926deccbSFrançois Tigeot a.full = dfixed_div(a, b);
2231926deccbSFrançois Tigeot line_fill_time = dfixed_trunc(a);
2232926deccbSFrançois Tigeot
2233926deccbSFrançois Tigeot if (line_fill_time < wm->active_time)
2234926deccbSFrançois Tigeot return latency;
2235926deccbSFrançois Tigeot else
2236926deccbSFrançois Tigeot return latency + (line_fill_time - wm->active_time);
2237926deccbSFrançois Tigeot
2238926deccbSFrançois Tigeot }
2239926deccbSFrançois Tigeot
dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params * wm)2240926deccbSFrançois Tigeot static bool dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params *wm)
2241926deccbSFrançois Tigeot {
2242926deccbSFrançois Tigeot if (dce6_average_bandwidth(wm) <=
2243926deccbSFrançois Tigeot (dce6_dram_bandwidth_for_display(wm) / wm->num_heads))
2244926deccbSFrançois Tigeot return true;
2245926deccbSFrançois Tigeot else
2246926deccbSFrançois Tigeot return false;
2247926deccbSFrançois Tigeot };
2248926deccbSFrançois Tigeot
dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params * wm)2249926deccbSFrançois Tigeot static bool dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params *wm)
2250926deccbSFrançois Tigeot {
2251926deccbSFrançois Tigeot if (dce6_average_bandwidth(wm) <=
2252926deccbSFrançois Tigeot (dce6_available_bandwidth(wm) / wm->num_heads))
2253926deccbSFrançois Tigeot return true;
2254926deccbSFrançois Tigeot else
2255926deccbSFrançois Tigeot return false;
2256926deccbSFrançois Tigeot };
2257926deccbSFrançois Tigeot
dce6_check_latency_hiding(struct dce6_wm_params * wm)2258926deccbSFrançois Tigeot static bool dce6_check_latency_hiding(struct dce6_wm_params *wm)
2259926deccbSFrançois Tigeot {
2260926deccbSFrançois Tigeot u32 lb_partitions = wm->lb_size / wm->src_width;
2261926deccbSFrançois Tigeot u32 line_time = wm->active_time + wm->blank_time;
2262926deccbSFrançois Tigeot u32 latency_tolerant_lines;
2263926deccbSFrançois Tigeot u32 latency_hiding;
2264926deccbSFrançois Tigeot fixed20_12 a;
2265926deccbSFrançois Tigeot
2266926deccbSFrançois Tigeot a.full = dfixed_const(1);
2267926deccbSFrançois Tigeot if (wm->vsc.full > a.full)
2268926deccbSFrançois Tigeot latency_tolerant_lines = 1;
2269926deccbSFrançois Tigeot else {
2270926deccbSFrançois Tigeot if (lb_partitions <= (wm->vtaps + 1))
2271926deccbSFrançois Tigeot latency_tolerant_lines = 1;
2272926deccbSFrançois Tigeot else
2273926deccbSFrançois Tigeot latency_tolerant_lines = 2;
2274926deccbSFrançois Tigeot }
2275926deccbSFrançois Tigeot
2276926deccbSFrançois Tigeot latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
2277926deccbSFrançois Tigeot
2278926deccbSFrançois Tigeot if (dce6_latency_watermark(wm) <= latency_hiding)
2279926deccbSFrançois Tigeot return true;
2280926deccbSFrançois Tigeot else
2281926deccbSFrançois Tigeot return false;
2282926deccbSFrançois Tigeot }
2283926deccbSFrançois Tigeot
dce6_program_watermarks(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,u32 lb_size,u32 num_heads)2284926deccbSFrançois Tigeot static void dce6_program_watermarks(struct radeon_device *rdev,
2285926deccbSFrançois Tigeot struct radeon_crtc *radeon_crtc,
2286926deccbSFrançois Tigeot u32 lb_size, u32 num_heads)
2287926deccbSFrançois Tigeot {
2288926deccbSFrançois Tigeot struct drm_display_mode *mode = &radeon_crtc->base.mode;
228957e252bfSMichael Neumann struct dce6_wm_params wm_low, wm_high;
229057e252bfSMichael Neumann u32 dram_channels;
2291a85cb24fSFrançois Tigeot u32 active_time;
2292926deccbSFrançois Tigeot u32 line_time = 0;
2293926deccbSFrançois Tigeot u32 latency_watermark_a = 0, latency_watermark_b = 0;
2294926deccbSFrançois Tigeot u32 priority_a_mark = 0, priority_b_mark = 0;
2295926deccbSFrançois Tigeot u32 priority_a_cnt = PRIORITY_OFF;
2296926deccbSFrançois Tigeot u32 priority_b_cnt = PRIORITY_OFF;
2297926deccbSFrançois Tigeot u32 tmp, arb_control3;
2298926deccbSFrançois Tigeot fixed20_12 a, b, c;
2299926deccbSFrançois Tigeot
2300926deccbSFrançois Tigeot if (radeon_crtc->base.enabled && num_heads && mode) {
2301a85cb24fSFrançois Tigeot active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
2302a85cb24fSFrançois Tigeot (u32)mode->clock);
2303a85cb24fSFrançois Tigeot line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
2304a85cb24fSFrançois Tigeot (u32)mode->clock);
2305a85cb24fSFrançois Tigeot line_time = min(line_time, (u32)65535);
2306926deccbSFrançois Tigeot priority_a_cnt = 0;
2307926deccbSFrançois Tigeot priority_b_cnt = 0;
2308926deccbSFrançois Tigeot
2309926deccbSFrançois Tigeot if (rdev->family == CHIP_ARUBA)
231057e252bfSMichael Neumann dram_channels = evergreen_get_number_of_dram_channels(rdev);
2311926deccbSFrançois Tigeot else
231257e252bfSMichael Neumann dram_channels = si_get_number_of_dram_channels(rdev);
231357e252bfSMichael Neumann
231457e252bfSMichael Neumann /* watermark for high clocks */
231557e252bfSMichael Neumann if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
231657e252bfSMichael Neumann wm_high.yclk =
231757e252bfSMichael Neumann radeon_dpm_get_mclk(rdev, false) * 10;
231857e252bfSMichael Neumann wm_high.sclk =
231957e252bfSMichael Neumann radeon_dpm_get_sclk(rdev, false) * 10;
232057e252bfSMichael Neumann } else {
232157e252bfSMichael Neumann wm_high.yclk = rdev->pm.current_mclk * 10;
232257e252bfSMichael Neumann wm_high.sclk = rdev->pm.current_sclk * 10;
232357e252bfSMichael Neumann }
232457e252bfSMichael Neumann
232557e252bfSMichael Neumann wm_high.disp_clk = mode->clock;
232657e252bfSMichael Neumann wm_high.src_width = mode->crtc_hdisplay;
2327a85cb24fSFrançois Tigeot wm_high.active_time = active_time;
232857e252bfSMichael Neumann wm_high.blank_time = line_time - wm_high.active_time;
232957e252bfSMichael Neumann wm_high.interlaced = false;
233057e252bfSMichael Neumann if (mode->flags & DRM_MODE_FLAG_INTERLACE)
233157e252bfSMichael Neumann wm_high.interlaced = true;
233257e252bfSMichael Neumann wm_high.vsc = radeon_crtc->vsc;
233357e252bfSMichael Neumann wm_high.vtaps = 1;
233457e252bfSMichael Neumann if (radeon_crtc->rmx_type != RMX_OFF)
233557e252bfSMichael Neumann wm_high.vtaps = 2;
233657e252bfSMichael Neumann wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
233757e252bfSMichael Neumann wm_high.lb_size = lb_size;
233857e252bfSMichael Neumann wm_high.dram_channels = dram_channels;
233957e252bfSMichael Neumann wm_high.num_heads = num_heads;
234057e252bfSMichael Neumann
234157e252bfSMichael Neumann /* watermark for low clocks */
234257e252bfSMichael Neumann if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
234357e252bfSMichael Neumann wm_low.yclk =
234457e252bfSMichael Neumann radeon_dpm_get_mclk(rdev, true) * 10;
234557e252bfSMichael Neumann wm_low.sclk =
234657e252bfSMichael Neumann radeon_dpm_get_sclk(rdev, true) * 10;
234757e252bfSMichael Neumann } else {
234857e252bfSMichael Neumann wm_low.yclk = rdev->pm.current_mclk * 10;
234957e252bfSMichael Neumann wm_low.sclk = rdev->pm.current_sclk * 10;
235057e252bfSMichael Neumann }
235157e252bfSMichael Neumann
235257e252bfSMichael Neumann wm_low.disp_clk = mode->clock;
235357e252bfSMichael Neumann wm_low.src_width = mode->crtc_hdisplay;
2354a85cb24fSFrançois Tigeot wm_low.active_time = active_time;
235557e252bfSMichael Neumann wm_low.blank_time = line_time - wm_low.active_time;
235657e252bfSMichael Neumann wm_low.interlaced = false;
235757e252bfSMichael Neumann if (mode->flags & DRM_MODE_FLAG_INTERLACE)
235857e252bfSMichael Neumann wm_low.interlaced = true;
235957e252bfSMichael Neumann wm_low.vsc = radeon_crtc->vsc;
236057e252bfSMichael Neumann wm_low.vtaps = 1;
236157e252bfSMichael Neumann if (radeon_crtc->rmx_type != RMX_OFF)
236257e252bfSMichael Neumann wm_low.vtaps = 2;
236357e252bfSMichael Neumann wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
236457e252bfSMichael Neumann wm_low.lb_size = lb_size;
236557e252bfSMichael Neumann wm_low.dram_channels = dram_channels;
236657e252bfSMichael Neumann wm_low.num_heads = num_heads;
2367926deccbSFrançois Tigeot
2368926deccbSFrançois Tigeot /* set for high clocks */
236957e252bfSMichael Neumann latency_watermark_a = min(dce6_latency_watermark(&wm_high), (u32)65535);
2370926deccbSFrançois Tigeot /* set for low clocks */
237157e252bfSMichael Neumann latency_watermark_b = min(dce6_latency_watermark(&wm_low), (u32)65535);
2372926deccbSFrançois Tigeot
2373926deccbSFrançois Tigeot /* possibly force display priority to high */
2374926deccbSFrançois Tigeot /* should really do this at mode validation time... */
237557e252bfSMichael Neumann if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
237657e252bfSMichael Neumann !dce6_average_bandwidth_vs_available_bandwidth(&wm_high) ||
237757e252bfSMichael Neumann !dce6_check_latency_hiding(&wm_high) ||
237857e252bfSMichael Neumann (rdev->disp_priority == 2)) {
237957e252bfSMichael Neumann DRM_DEBUG_KMS("force priority to high\n");
238057e252bfSMichael Neumann priority_a_cnt |= PRIORITY_ALWAYS_ON;
238157e252bfSMichael Neumann priority_b_cnt |= PRIORITY_ALWAYS_ON;
238257e252bfSMichael Neumann }
238357e252bfSMichael Neumann if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
238457e252bfSMichael Neumann !dce6_average_bandwidth_vs_available_bandwidth(&wm_low) ||
238557e252bfSMichael Neumann !dce6_check_latency_hiding(&wm_low) ||
2386926deccbSFrançois Tigeot (rdev->disp_priority == 2)) {
2387926deccbSFrançois Tigeot DRM_DEBUG_KMS("force priority to high\n");
2388926deccbSFrançois Tigeot priority_a_cnt |= PRIORITY_ALWAYS_ON;
2389926deccbSFrançois Tigeot priority_b_cnt |= PRIORITY_ALWAYS_ON;
2390926deccbSFrançois Tigeot }
2391926deccbSFrançois Tigeot
2392926deccbSFrançois Tigeot a.full = dfixed_const(1000);
2393926deccbSFrançois Tigeot b.full = dfixed_const(mode->clock);
2394926deccbSFrançois Tigeot b.full = dfixed_div(b, a);
2395926deccbSFrançois Tigeot c.full = dfixed_const(latency_watermark_a);
2396926deccbSFrançois Tigeot c.full = dfixed_mul(c, b);
2397926deccbSFrançois Tigeot c.full = dfixed_mul(c, radeon_crtc->hsc);
2398926deccbSFrançois Tigeot c.full = dfixed_div(c, a);
2399926deccbSFrançois Tigeot a.full = dfixed_const(16);
2400926deccbSFrançois Tigeot c.full = dfixed_div(c, a);
2401926deccbSFrançois Tigeot priority_a_mark = dfixed_trunc(c);
2402926deccbSFrançois Tigeot priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK;
2403926deccbSFrançois Tigeot
2404926deccbSFrançois Tigeot a.full = dfixed_const(1000);
2405926deccbSFrançois Tigeot b.full = dfixed_const(mode->clock);
2406926deccbSFrançois Tigeot b.full = dfixed_div(b, a);
2407926deccbSFrançois Tigeot c.full = dfixed_const(latency_watermark_b);
2408926deccbSFrançois Tigeot c.full = dfixed_mul(c, b);
2409926deccbSFrançois Tigeot c.full = dfixed_mul(c, radeon_crtc->hsc);
2410926deccbSFrançois Tigeot c.full = dfixed_div(c, a);
2411926deccbSFrançois Tigeot a.full = dfixed_const(16);
2412926deccbSFrançois Tigeot c.full = dfixed_div(c, a);
2413926deccbSFrançois Tigeot priority_b_mark = dfixed_trunc(c);
2414926deccbSFrançois Tigeot priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
2415c59a5c48SFrançois Tigeot
2416c59a5c48SFrançois Tigeot /* Save number of lines the linebuffer leads before the scanout */
2417c59a5c48SFrançois Tigeot radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
2418926deccbSFrançois Tigeot }
2419926deccbSFrançois Tigeot
2420926deccbSFrançois Tigeot /* select wm A */
2421926deccbSFrançois Tigeot arb_control3 = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
2422926deccbSFrançois Tigeot tmp = arb_control3;
2423926deccbSFrançois Tigeot tmp &= ~LATENCY_WATERMARK_MASK(3);
2424926deccbSFrançois Tigeot tmp |= LATENCY_WATERMARK_MASK(1);
2425926deccbSFrançois Tigeot WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
2426926deccbSFrançois Tigeot WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
2427926deccbSFrançois Tigeot (LATENCY_LOW_WATERMARK(latency_watermark_a) |
2428926deccbSFrançois Tigeot LATENCY_HIGH_WATERMARK(line_time)));
2429926deccbSFrançois Tigeot /* select wm B */
2430926deccbSFrançois Tigeot tmp = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
2431926deccbSFrançois Tigeot tmp &= ~LATENCY_WATERMARK_MASK(3);
2432926deccbSFrançois Tigeot tmp |= LATENCY_WATERMARK_MASK(2);
2433926deccbSFrançois Tigeot WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
2434926deccbSFrançois Tigeot WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
2435926deccbSFrançois Tigeot (LATENCY_LOW_WATERMARK(latency_watermark_b) |
2436926deccbSFrançois Tigeot LATENCY_HIGH_WATERMARK(line_time)));
2437926deccbSFrançois Tigeot /* restore original selection */
2438926deccbSFrançois Tigeot WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, arb_control3);
2439926deccbSFrançois Tigeot
2440926deccbSFrançois Tigeot /* write the priority marks */
2441926deccbSFrançois Tigeot WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
2442926deccbSFrançois Tigeot WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
2443926deccbSFrançois Tigeot
244457e252bfSMichael Neumann /* save values for DPM */
244557e252bfSMichael Neumann radeon_crtc->line_time = line_time;
244657e252bfSMichael Neumann radeon_crtc->wm_high = latency_watermark_a;
244757e252bfSMichael Neumann radeon_crtc->wm_low = latency_watermark_b;
2448926deccbSFrançois Tigeot }
2449926deccbSFrançois Tigeot
dce6_bandwidth_update(struct radeon_device * rdev)2450926deccbSFrançois Tigeot void dce6_bandwidth_update(struct radeon_device *rdev)
2451926deccbSFrançois Tigeot {
2452926deccbSFrançois Tigeot struct drm_display_mode *mode0 = NULL;
2453926deccbSFrançois Tigeot struct drm_display_mode *mode1 = NULL;
2454926deccbSFrançois Tigeot u32 num_heads = 0, lb_size;
2455926deccbSFrançois Tigeot int i;
2456926deccbSFrançois Tigeot
2457591d5043SFrançois Tigeot if (!rdev->mode_info.mode_config_initialized)
2458591d5043SFrançois Tigeot return;
2459591d5043SFrançois Tigeot
2460926deccbSFrançois Tigeot radeon_update_display_priority(rdev);
2461926deccbSFrançois Tigeot
2462926deccbSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i++) {
2463926deccbSFrançois Tigeot if (rdev->mode_info.crtcs[i]->base.enabled)
2464926deccbSFrançois Tigeot num_heads++;
2465926deccbSFrançois Tigeot }
2466926deccbSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i += 2) {
2467926deccbSFrançois Tigeot mode0 = &rdev->mode_info.crtcs[i]->base.mode;
2468926deccbSFrançois Tigeot mode1 = &rdev->mode_info.crtcs[i+1]->base.mode;
2469926deccbSFrançois Tigeot lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1);
2470926deccbSFrançois Tigeot dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
2471926deccbSFrançois Tigeot lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0);
2472926deccbSFrançois Tigeot dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads);
2473926deccbSFrançois Tigeot }
2474926deccbSFrançois Tigeot }
2475926deccbSFrançois Tigeot
2476926deccbSFrançois Tigeot /*
2477926deccbSFrançois Tigeot * Core functions
2478926deccbSFrançois Tigeot */
si_tiling_mode_table_init(struct radeon_device * rdev)2479926deccbSFrançois Tigeot static void si_tiling_mode_table_init(struct radeon_device *rdev)
2480926deccbSFrançois Tigeot {
2481d78d3a22SFrançois Tigeot u32 *tile = rdev->config.si.tile_mode_array;
2482d78d3a22SFrançois Tigeot const u32 num_tile_mode_states =
2483d78d3a22SFrançois Tigeot ARRAY_SIZE(rdev->config.si.tile_mode_array);
2484d78d3a22SFrançois Tigeot u32 reg_offset, split_equal_to_row_size;
2485926deccbSFrançois Tigeot
2486926deccbSFrançois Tigeot switch (rdev->config.si.mem_row_size_in_kb) {
2487926deccbSFrançois Tigeot case 1:
2488926deccbSFrançois Tigeot split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB;
2489926deccbSFrançois Tigeot break;
2490926deccbSFrançois Tigeot case 2:
2491926deccbSFrançois Tigeot default:
2492926deccbSFrançois Tigeot split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB;
2493926deccbSFrançois Tigeot break;
2494926deccbSFrançois Tigeot case 4:
2495926deccbSFrançois Tigeot split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB;
2496926deccbSFrançois Tigeot break;
2497926deccbSFrançois Tigeot }
2498926deccbSFrançois Tigeot
2499d78d3a22SFrançois Tigeot for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2500d78d3a22SFrançois Tigeot tile[reg_offset] = 0;
2501d78d3a22SFrançois Tigeot
2502d78d3a22SFrançois Tigeot switch(rdev->family) {
2503d78d3a22SFrançois Tigeot case CHIP_TAHITI:
2504d78d3a22SFrançois Tigeot case CHIP_PITCAIRN:
2505d78d3a22SFrançois Tigeot /* non-AA compressed depth or any compressed stencil */
2506d78d3a22SFrançois Tigeot tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2507926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2508926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2509926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2510926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2511926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2512926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2513926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2514d78d3a22SFrançois Tigeot /* 2xAA/4xAA compressed depth only */
2515d78d3a22SFrançois Tigeot tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2516926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2517926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2518926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2519926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2520926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2521926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2522926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2523d78d3a22SFrançois Tigeot /* 8xAA compressed depth only */
2524d78d3a22SFrançois Tigeot tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2525926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2526926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2527926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2528926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2529926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2530926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2531926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2532d78d3a22SFrançois Tigeot /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
2533d78d3a22SFrançois Tigeot tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2534926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2535926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2536926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2537926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2538926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2539926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2540926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2541d78d3a22SFrançois Tigeot /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
2542d78d3a22SFrançois Tigeot tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2543926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2544926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2545926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2546926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2547926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2548926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2549926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2550d78d3a22SFrançois Tigeot /* Uncompressed 16bpp depth - and stencil buffer allocated with it */
2551d78d3a22SFrançois Tigeot tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2552926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2553926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2554926deccbSFrançois Tigeot TILE_SPLIT(split_equal_to_row_size) |
2555926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2556926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2557926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2558926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2559d78d3a22SFrançois Tigeot /* Uncompressed 32bpp depth - and stencil buffer allocated with it */
2560d78d3a22SFrançois Tigeot tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2561926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2562926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2563926deccbSFrançois Tigeot TILE_SPLIT(split_equal_to_row_size) |
2564926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2565926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2566926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2567926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2568d78d3a22SFrançois Tigeot /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
2569d78d3a22SFrançois Tigeot tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2570926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2571926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2572926deccbSFrançois Tigeot TILE_SPLIT(split_equal_to_row_size) |
2573926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2574926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2575926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2576926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2577d78d3a22SFrançois Tigeot /* 1D and 1D Array Surfaces */
2578d78d3a22SFrançois Tigeot tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2579926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2580926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2581926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2582926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2583926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2584926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2585926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2586d78d3a22SFrançois Tigeot /* Displayable maps. */
2587d78d3a22SFrançois Tigeot tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2588926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2589926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2590926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2591926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2592926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2593926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2594926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2595d78d3a22SFrançois Tigeot /* Display 8bpp. */
2596d78d3a22SFrançois Tigeot tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2597926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2598926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2599926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2600926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2601926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2602926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2603926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2604d78d3a22SFrançois Tigeot /* Display 16bpp. */
2605d78d3a22SFrançois Tigeot tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2606926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2607926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2608926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2609926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2610926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2611926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2612926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2613d78d3a22SFrançois Tigeot /* Display 32bpp. */
2614d78d3a22SFrançois Tigeot tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2615926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2616926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2617926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2618926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2619926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2620926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2621926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2622d78d3a22SFrançois Tigeot /* Thin. */
2623d78d3a22SFrançois Tigeot tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2624926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2625926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2626926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2627926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2628926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2629926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2630926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2631d78d3a22SFrançois Tigeot /* Thin 8 bpp. */
2632d78d3a22SFrançois Tigeot tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2633926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2634926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2635926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2636926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2637926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2638926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2639926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2640d78d3a22SFrançois Tigeot /* Thin 16 bpp. */
2641d78d3a22SFrançois Tigeot tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2642926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2643926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2644926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2645926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2646926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2647926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2648926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2649d78d3a22SFrançois Tigeot /* Thin 32 bpp. */
2650d78d3a22SFrançois Tigeot tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2651926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2652926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2653926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2654926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2655926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2656926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2657926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2658d78d3a22SFrançois Tigeot /* Thin 64 bpp. */
2659d78d3a22SFrançois Tigeot tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2660926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2661926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2662926deccbSFrançois Tigeot TILE_SPLIT(split_equal_to_row_size) |
2663926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2664926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2665926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2666926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2667d78d3a22SFrançois Tigeot /* 8 bpp PRT. */
2668d78d3a22SFrançois Tigeot tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2669926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2670926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2671926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2672926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2673926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2674926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2675926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2676d78d3a22SFrançois Tigeot /* 16 bpp PRT */
2677d78d3a22SFrançois Tigeot tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2678926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2679926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2680926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2681926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2682926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2683926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2684926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2685d78d3a22SFrançois Tigeot /* 32 bpp PRT */
2686d78d3a22SFrançois Tigeot tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2687926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2688926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2689926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2690926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2691926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2692926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2693926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2694d78d3a22SFrançois Tigeot /* 64 bpp PRT */
2695d78d3a22SFrançois Tigeot tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2696926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2697926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2698926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2699926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_16_BANK) |
2700926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2701926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2702926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2703d78d3a22SFrançois Tigeot /* 128 bpp PRT */
2704d78d3a22SFrançois Tigeot tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2705926deccbSFrançois Tigeot MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2706926deccbSFrançois Tigeot PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2707926deccbSFrançois Tigeot TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
2708926deccbSFrançois Tigeot NUM_BANKS(ADDR_SURF_8_BANK) |
2709926deccbSFrançois Tigeot BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2710926deccbSFrançois Tigeot BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2711926deccbSFrançois Tigeot MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2712d78d3a22SFrançois Tigeot
2713d78d3a22SFrançois Tigeot for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2714d78d3a22SFrançois Tigeot WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2715926deccbSFrançois Tigeot break;
2716d78d3a22SFrançois Tigeot
2717d78d3a22SFrançois Tigeot case CHIP_VERDE:
2718d78d3a22SFrançois Tigeot case CHIP_OLAND:
2719d78d3a22SFrançois Tigeot case CHIP_HAINAN:
2720d78d3a22SFrançois Tigeot /* non-AA compressed depth or any compressed stencil */
2721d78d3a22SFrançois Tigeot tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2722ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2723ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2724ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2725ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2726ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2727ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2728ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2729d78d3a22SFrançois Tigeot /* 2xAA/4xAA compressed depth only */
2730d78d3a22SFrançois Tigeot tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2731ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2732ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2733ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2734ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2735ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2736ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2737ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2738d78d3a22SFrançois Tigeot /* 8xAA compressed depth only */
2739d78d3a22SFrançois Tigeot tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2740ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2741ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2742ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2743ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2744ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2745ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2746ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2747d78d3a22SFrançois Tigeot /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
2748d78d3a22SFrançois Tigeot tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2749ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2750ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2751ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2752ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2753ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2754ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2755ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2756d78d3a22SFrançois Tigeot /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
2757d78d3a22SFrançois Tigeot tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2758ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2759ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2760ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2761ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2762ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2763ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2764ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2765d78d3a22SFrançois Tigeot /* Uncompressed 16bpp depth - and stencil buffer allocated with it */
2766d78d3a22SFrançois Tigeot tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2767ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2768ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2769ee479021SImre Vadász TILE_SPLIT(split_equal_to_row_size) |
2770ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2771ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2772ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2773ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2774d78d3a22SFrançois Tigeot /* Uncompressed 32bpp depth - and stencil buffer allocated with it */
2775d78d3a22SFrançois Tigeot tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2776ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2777ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2778ee479021SImre Vadász TILE_SPLIT(split_equal_to_row_size) |
2779ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2780ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2781ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2782ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2783d78d3a22SFrançois Tigeot /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
2784d78d3a22SFrançois Tigeot tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2785ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2786ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2787ee479021SImre Vadász TILE_SPLIT(split_equal_to_row_size) |
2788ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2789ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2790ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2791ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2792d78d3a22SFrançois Tigeot /* 1D and 1D Array Surfaces */
2793d78d3a22SFrançois Tigeot tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2794ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2795ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2796ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2797ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2798ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2799ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2800ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2801d78d3a22SFrançois Tigeot /* Displayable maps. */
2802d78d3a22SFrançois Tigeot tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2803ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2804ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2805ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2806ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2807ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2808ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2809ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2810d78d3a22SFrançois Tigeot /* Display 8bpp. */
2811d78d3a22SFrançois Tigeot tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2812ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2813ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2814ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2815ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2816ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2817ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2818ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2819d78d3a22SFrançois Tigeot /* Display 16bpp. */
2820d78d3a22SFrançois Tigeot tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2821ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2822ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2823ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2824ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2825ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2826ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2827ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2828d78d3a22SFrançois Tigeot /* Display 32bpp. */
2829d78d3a22SFrançois Tigeot tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2830ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2831ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2832ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2833ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2834ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2835ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2836ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2837d78d3a22SFrançois Tigeot /* Thin. */
2838d78d3a22SFrançois Tigeot tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2839ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2840ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2841ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2842ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2843ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2844ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2845ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2846d78d3a22SFrançois Tigeot /* Thin 8 bpp. */
2847d78d3a22SFrançois Tigeot tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2848ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2849ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2850ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2851ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2852ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2853ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2854ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2855d78d3a22SFrançois Tigeot /* Thin 16 bpp. */
2856d78d3a22SFrançois Tigeot tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2857ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2858ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2859ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2860ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2861ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2862ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2863ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2864d78d3a22SFrançois Tigeot /* Thin 32 bpp. */
2865d78d3a22SFrançois Tigeot tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2866ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2867ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2868ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2869ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2870ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2871ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2872ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2873d78d3a22SFrançois Tigeot /* Thin 64 bpp. */
2874d78d3a22SFrançois Tigeot tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2875ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2876ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2877ee479021SImre Vadász TILE_SPLIT(split_equal_to_row_size) |
2878ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2879ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2880ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2881ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2882d78d3a22SFrançois Tigeot /* 8 bpp PRT. */
2883d78d3a22SFrançois Tigeot tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2884ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2885ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2886ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2887ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2888ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2889ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2890ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2891d78d3a22SFrançois Tigeot /* 16 bpp PRT */
2892d78d3a22SFrançois Tigeot tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2893ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2894ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2895ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2896ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2897ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2898ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2899ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2900d78d3a22SFrançois Tigeot /* 32 bpp PRT */
2901d78d3a22SFrançois Tigeot tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2902ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2903ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2904ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2905ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2906ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2907ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2908ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2909d78d3a22SFrançois Tigeot /* 64 bpp PRT */
2910d78d3a22SFrançois Tigeot tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2911ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2912ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2913ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2914ee479021SImre Vadász NUM_BANKS(ADDR_SURF_16_BANK) |
2915ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2916ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2917ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2918d78d3a22SFrançois Tigeot /* 128 bpp PRT */
2919d78d3a22SFrançois Tigeot tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2920ee479021SImre Vadász MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2921ee479021SImre Vadász PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2922ee479021SImre Vadász TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
2923ee479021SImre Vadász NUM_BANKS(ADDR_SURF_8_BANK) |
2924ee479021SImre Vadász BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2925ee479021SImre Vadász BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2926ee479021SImre Vadász MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2927d78d3a22SFrançois Tigeot
2928d78d3a22SFrançois Tigeot for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2929d78d3a22SFrançois Tigeot WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2930ee479021SImre Vadász break;
2931d78d3a22SFrançois Tigeot
2932ee479021SImre Vadász default:
2933ee479021SImre Vadász DRM_ERROR("unknown asic: 0x%x\n", rdev->family);
2934a7a95252SDavid Shao }
2935d78d3a22SFrançois Tigeot }
2936926deccbSFrançois Tigeot
si_select_se_sh(struct radeon_device * rdev,u32 se_num,u32 sh_num)2937926deccbSFrançois Tigeot static void si_select_se_sh(struct radeon_device *rdev,
2938926deccbSFrançois Tigeot u32 se_num, u32 sh_num)
2939926deccbSFrançois Tigeot {
2940926deccbSFrançois Tigeot u32 data = INSTANCE_BROADCAST_WRITES;
2941926deccbSFrançois Tigeot
2942926deccbSFrançois Tigeot if ((se_num == 0xffffffff) && (sh_num == 0xffffffff))
2943f43cf1b1SMichael Neumann data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
2944926deccbSFrançois Tigeot else if (se_num == 0xffffffff)
2945926deccbSFrançois Tigeot data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num);
2946926deccbSFrançois Tigeot else if (sh_num == 0xffffffff)
2947926deccbSFrançois Tigeot data |= SH_BROADCAST_WRITES | SE_INDEX(se_num);
2948926deccbSFrançois Tigeot else
2949926deccbSFrançois Tigeot data |= SH_INDEX(sh_num) | SE_INDEX(se_num);
2950926deccbSFrançois Tigeot WREG32(GRBM_GFX_INDEX, data);
2951926deccbSFrançois Tigeot }
2952926deccbSFrançois Tigeot
si_create_bitmask(u32 bit_width)2953926deccbSFrançois Tigeot static u32 si_create_bitmask(u32 bit_width)
2954926deccbSFrançois Tigeot {
2955926deccbSFrançois Tigeot u32 i, mask = 0;
2956926deccbSFrançois Tigeot
2957926deccbSFrançois Tigeot for (i = 0; i < bit_width; i++) {
2958926deccbSFrançois Tigeot mask <<= 1;
2959926deccbSFrançois Tigeot mask |= 1;
2960926deccbSFrançois Tigeot }
2961926deccbSFrançois Tigeot return mask;
2962926deccbSFrançois Tigeot }
2963926deccbSFrançois Tigeot
si_get_cu_enabled(struct radeon_device * rdev,u32 cu_per_sh)2964926deccbSFrançois Tigeot static u32 si_get_cu_enabled(struct radeon_device *rdev, u32 cu_per_sh)
2965926deccbSFrançois Tigeot {
2966926deccbSFrançois Tigeot u32 data, mask;
2967926deccbSFrançois Tigeot
2968926deccbSFrançois Tigeot data = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
2969926deccbSFrançois Tigeot if (data & 1)
2970926deccbSFrançois Tigeot data &= INACTIVE_CUS_MASK;
2971926deccbSFrançois Tigeot else
2972926deccbSFrançois Tigeot data = 0;
2973926deccbSFrançois Tigeot data |= RREG32(GC_USER_SHADER_ARRAY_CONFIG);
2974926deccbSFrançois Tigeot
2975926deccbSFrançois Tigeot data >>= INACTIVE_CUS_SHIFT;
2976926deccbSFrançois Tigeot
2977926deccbSFrançois Tigeot mask = si_create_bitmask(cu_per_sh);
2978926deccbSFrançois Tigeot
2979926deccbSFrançois Tigeot return ~data & mask;
2980926deccbSFrançois Tigeot }
2981926deccbSFrançois Tigeot
si_setup_spi(struct radeon_device * rdev,u32 se_num,u32 sh_per_se,u32 cu_per_sh)2982926deccbSFrançois Tigeot static void si_setup_spi(struct radeon_device *rdev,
2983926deccbSFrançois Tigeot u32 se_num, u32 sh_per_se,
2984926deccbSFrançois Tigeot u32 cu_per_sh)
2985926deccbSFrançois Tigeot {
2986926deccbSFrançois Tigeot int i, j, k;
2987926deccbSFrançois Tigeot u32 data, mask, active_cu;
2988926deccbSFrançois Tigeot
2989926deccbSFrançois Tigeot for (i = 0; i < se_num; i++) {
2990926deccbSFrançois Tigeot for (j = 0; j < sh_per_se; j++) {
2991926deccbSFrançois Tigeot si_select_se_sh(rdev, i, j);
2992926deccbSFrançois Tigeot data = RREG32(SPI_STATIC_THREAD_MGMT_3);
2993926deccbSFrançois Tigeot active_cu = si_get_cu_enabled(rdev, cu_per_sh);
2994926deccbSFrançois Tigeot
2995926deccbSFrançois Tigeot mask = 1;
2996926deccbSFrançois Tigeot for (k = 0; k < 16; k++) {
2997926deccbSFrançois Tigeot mask <<= k;
2998926deccbSFrançois Tigeot if (active_cu & mask) {
2999926deccbSFrançois Tigeot data &= ~mask;
3000926deccbSFrançois Tigeot WREG32(SPI_STATIC_THREAD_MGMT_3, data);
3001926deccbSFrançois Tigeot break;
3002926deccbSFrançois Tigeot }
3003926deccbSFrançois Tigeot }
3004926deccbSFrançois Tigeot }
3005926deccbSFrançois Tigeot }
3006926deccbSFrançois Tigeot si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3007926deccbSFrançois Tigeot }
3008926deccbSFrançois Tigeot
si_get_rb_disabled(struct radeon_device * rdev,u32 max_rb_num_per_se,u32 sh_per_se)3009926deccbSFrançois Tigeot static u32 si_get_rb_disabled(struct radeon_device *rdev,
3010c6f73aabSFrançois Tigeot u32 max_rb_num_per_se,
3011926deccbSFrançois Tigeot u32 sh_per_se)
3012926deccbSFrançois Tigeot {
3013926deccbSFrançois Tigeot u32 data, mask;
3014926deccbSFrançois Tigeot
3015926deccbSFrançois Tigeot data = RREG32(CC_RB_BACKEND_DISABLE);
3016926deccbSFrançois Tigeot if (data & 1)
3017926deccbSFrançois Tigeot data &= BACKEND_DISABLE_MASK;
3018926deccbSFrançois Tigeot else
3019926deccbSFrançois Tigeot data = 0;
3020926deccbSFrançois Tigeot data |= RREG32(GC_USER_RB_BACKEND_DISABLE);
3021926deccbSFrançois Tigeot
3022926deccbSFrançois Tigeot data >>= BACKEND_DISABLE_SHIFT;
3023926deccbSFrançois Tigeot
3024c6f73aabSFrançois Tigeot mask = si_create_bitmask(max_rb_num_per_se / sh_per_se);
3025926deccbSFrançois Tigeot
3026926deccbSFrançois Tigeot return data & mask;
3027926deccbSFrançois Tigeot }
3028926deccbSFrançois Tigeot
si_setup_rb(struct radeon_device * rdev,u32 se_num,u32 sh_per_se,u32 max_rb_num_per_se)3029926deccbSFrançois Tigeot static void si_setup_rb(struct radeon_device *rdev,
3030926deccbSFrançois Tigeot u32 se_num, u32 sh_per_se,
3031c6f73aabSFrançois Tigeot u32 max_rb_num_per_se)
3032926deccbSFrançois Tigeot {
3033926deccbSFrançois Tigeot int i, j;
3034926deccbSFrançois Tigeot u32 data, mask;
3035926deccbSFrançois Tigeot u32 disabled_rbs = 0;
3036926deccbSFrançois Tigeot u32 enabled_rbs = 0;
3037926deccbSFrançois Tigeot
3038926deccbSFrançois Tigeot for (i = 0; i < se_num; i++) {
3039926deccbSFrançois Tigeot for (j = 0; j < sh_per_se; j++) {
3040926deccbSFrançois Tigeot si_select_se_sh(rdev, i, j);
3041c6f73aabSFrançois Tigeot data = si_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se);
3042926deccbSFrançois Tigeot disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH);
3043926deccbSFrançois Tigeot }
3044926deccbSFrançois Tigeot }
3045926deccbSFrançois Tigeot si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3046926deccbSFrançois Tigeot
3047926deccbSFrançois Tigeot mask = 1;
3048c6f73aabSFrançois Tigeot for (i = 0; i < max_rb_num_per_se * se_num; i++) {
3049926deccbSFrançois Tigeot if (!(disabled_rbs & mask))
3050926deccbSFrançois Tigeot enabled_rbs |= mask;
3051926deccbSFrançois Tigeot mask <<= 1;
3052926deccbSFrançois Tigeot }
3053926deccbSFrançois Tigeot
3054c6f73aabSFrançois Tigeot rdev->config.si.backend_enable_mask = enabled_rbs;
3055c6f73aabSFrançois Tigeot
3056926deccbSFrançois Tigeot for (i = 0; i < se_num; i++) {
3057926deccbSFrançois Tigeot si_select_se_sh(rdev, i, 0xffffffff);
3058926deccbSFrançois Tigeot data = 0;
3059926deccbSFrançois Tigeot for (j = 0; j < sh_per_se; j++) {
3060926deccbSFrançois Tigeot switch (enabled_rbs & 3) {
3061926deccbSFrançois Tigeot case 1:
3062926deccbSFrançois Tigeot data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
3063926deccbSFrançois Tigeot break;
3064926deccbSFrançois Tigeot case 2:
3065926deccbSFrançois Tigeot data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2);
3066926deccbSFrançois Tigeot break;
3067926deccbSFrançois Tigeot case 3:
3068926deccbSFrançois Tigeot default:
3069926deccbSFrançois Tigeot data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2);
3070926deccbSFrançois Tigeot break;
3071926deccbSFrançois Tigeot }
3072926deccbSFrançois Tigeot enabled_rbs >>= 2;
3073926deccbSFrançois Tigeot }
3074926deccbSFrançois Tigeot WREG32(PA_SC_RASTER_CONFIG, data);
3075926deccbSFrançois Tigeot }
3076926deccbSFrançois Tigeot si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3077926deccbSFrançois Tigeot }
3078926deccbSFrançois Tigeot
si_gpu_init(struct radeon_device * rdev)3079926deccbSFrançois Tigeot static void si_gpu_init(struct radeon_device *rdev)
3080926deccbSFrançois Tigeot {
3081926deccbSFrançois Tigeot u32 gb_addr_config = 0;
3082926deccbSFrançois Tigeot u32 mc_shared_chmap, mc_arb_ramcfg;
3083926deccbSFrançois Tigeot u32 sx_debug_1;
3084926deccbSFrançois Tigeot u32 hdp_host_path_cntl;
3085926deccbSFrançois Tigeot u32 tmp;
3086926deccbSFrançois Tigeot int i, j;
3087926deccbSFrançois Tigeot
3088926deccbSFrançois Tigeot switch (rdev->family) {
3089926deccbSFrançois Tigeot case CHIP_TAHITI:
3090926deccbSFrançois Tigeot rdev->config.si.max_shader_engines = 2;
3091926deccbSFrançois Tigeot rdev->config.si.max_tile_pipes = 12;
3092926deccbSFrançois Tigeot rdev->config.si.max_cu_per_sh = 8;
3093926deccbSFrançois Tigeot rdev->config.si.max_sh_per_se = 2;
3094926deccbSFrançois Tigeot rdev->config.si.max_backends_per_se = 4;
3095926deccbSFrançois Tigeot rdev->config.si.max_texture_channel_caches = 12;
3096926deccbSFrançois Tigeot rdev->config.si.max_gprs = 256;
3097926deccbSFrançois Tigeot rdev->config.si.max_gs_threads = 32;
3098926deccbSFrançois Tigeot rdev->config.si.max_hw_contexts = 8;
3099926deccbSFrançois Tigeot
3100926deccbSFrançois Tigeot rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3101926deccbSFrançois Tigeot rdev->config.si.sc_prim_fifo_size_backend = 0x100;
3102926deccbSFrançois Tigeot rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3103926deccbSFrançois Tigeot rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3104926deccbSFrançois Tigeot gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
3105926deccbSFrançois Tigeot break;
3106926deccbSFrançois Tigeot case CHIP_PITCAIRN:
3107926deccbSFrançois Tigeot rdev->config.si.max_shader_engines = 2;
3108926deccbSFrançois Tigeot rdev->config.si.max_tile_pipes = 8;
3109926deccbSFrançois Tigeot rdev->config.si.max_cu_per_sh = 5;
3110926deccbSFrançois Tigeot rdev->config.si.max_sh_per_se = 2;
3111926deccbSFrançois Tigeot rdev->config.si.max_backends_per_se = 4;
3112926deccbSFrançois Tigeot rdev->config.si.max_texture_channel_caches = 8;
3113926deccbSFrançois Tigeot rdev->config.si.max_gprs = 256;
3114926deccbSFrançois Tigeot rdev->config.si.max_gs_threads = 32;
3115926deccbSFrançois Tigeot rdev->config.si.max_hw_contexts = 8;
3116926deccbSFrançois Tigeot
3117926deccbSFrançois Tigeot rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3118926deccbSFrançois Tigeot rdev->config.si.sc_prim_fifo_size_backend = 0x100;
3119926deccbSFrançois Tigeot rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3120926deccbSFrançois Tigeot rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3121926deccbSFrançois Tigeot gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
3122926deccbSFrançois Tigeot break;
3123926deccbSFrançois Tigeot case CHIP_VERDE:
3124926deccbSFrançois Tigeot default:
3125926deccbSFrançois Tigeot rdev->config.si.max_shader_engines = 1;
3126926deccbSFrançois Tigeot rdev->config.si.max_tile_pipes = 4;
3127f43cf1b1SMichael Neumann rdev->config.si.max_cu_per_sh = 5;
3128926deccbSFrançois Tigeot rdev->config.si.max_sh_per_se = 2;
3129926deccbSFrançois Tigeot rdev->config.si.max_backends_per_se = 4;
3130926deccbSFrançois Tigeot rdev->config.si.max_texture_channel_caches = 4;
3131926deccbSFrançois Tigeot rdev->config.si.max_gprs = 256;
3132926deccbSFrançois Tigeot rdev->config.si.max_gs_threads = 32;
3133926deccbSFrançois Tigeot rdev->config.si.max_hw_contexts = 8;
3134926deccbSFrançois Tigeot
3135926deccbSFrançois Tigeot rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3136926deccbSFrançois Tigeot rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3137926deccbSFrançois Tigeot rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3138926deccbSFrançois Tigeot rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3139926deccbSFrançois Tigeot gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
3140926deccbSFrançois Tigeot break;
3141b403bed8SMichael Neumann case CHIP_OLAND:
3142b403bed8SMichael Neumann rdev->config.si.max_shader_engines = 1;
3143b403bed8SMichael Neumann rdev->config.si.max_tile_pipes = 4;
3144b403bed8SMichael Neumann rdev->config.si.max_cu_per_sh = 6;
3145b403bed8SMichael Neumann rdev->config.si.max_sh_per_se = 1;
3146b403bed8SMichael Neumann rdev->config.si.max_backends_per_se = 2;
3147b403bed8SMichael Neumann rdev->config.si.max_texture_channel_caches = 4;
3148b403bed8SMichael Neumann rdev->config.si.max_gprs = 256;
3149b403bed8SMichael Neumann rdev->config.si.max_gs_threads = 16;
3150b403bed8SMichael Neumann rdev->config.si.max_hw_contexts = 8;
3151b403bed8SMichael Neumann
3152b403bed8SMichael Neumann rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3153b403bed8SMichael Neumann rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3154b403bed8SMichael Neumann rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3155b403bed8SMichael Neumann rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3156b403bed8SMichael Neumann gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
3157b403bed8SMichael Neumann break;
3158f43cf1b1SMichael Neumann case CHIP_HAINAN:
3159f43cf1b1SMichael Neumann rdev->config.si.max_shader_engines = 1;
3160f43cf1b1SMichael Neumann rdev->config.si.max_tile_pipes = 4;
3161f43cf1b1SMichael Neumann rdev->config.si.max_cu_per_sh = 5;
3162f43cf1b1SMichael Neumann rdev->config.si.max_sh_per_se = 1;
3163f43cf1b1SMichael Neumann rdev->config.si.max_backends_per_se = 1;
3164f43cf1b1SMichael Neumann rdev->config.si.max_texture_channel_caches = 2;
3165f43cf1b1SMichael Neumann rdev->config.si.max_gprs = 256;
3166f43cf1b1SMichael Neumann rdev->config.si.max_gs_threads = 16;
3167f43cf1b1SMichael Neumann rdev->config.si.max_hw_contexts = 8;
3168f43cf1b1SMichael Neumann
3169f43cf1b1SMichael Neumann rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3170f43cf1b1SMichael Neumann rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3171f43cf1b1SMichael Neumann rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3172f43cf1b1SMichael Neumann rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3173f43cf1b1SMichael Neumann gb_addr_config = HAINAN_GB_ADDR_CONFIG_GOLDEN;
3174f43cf1b1SMichael Neumann break;
3175926deccbSFrançois Tigeot }
3176926deccbSFrançois Tigeot
3177926deccbSFrançois Tigeot /* Initialize HDP */
3178926deccbSFrançois Tigeot for (i = 0, j = 0; i < 32; i++, j += 0x18) {
3179926deccbSFrançois Tigeot WREG32((0x2c14 + j), 0x00000000);
3180926deccbSFrançois Tigeot WREG32((0x2c18 + j), 0x00000000);
3181926deccbSFrançois Tigeot WREG32((0x2c1c + j), 0x00000000);
3182926deccbSFrançois Tigeot WREG32((0x2c20 + j), 0x00000000);
3183926deccbSFrançois Tigeot WREG32((0x2c24 + j), 0x00000000);
3184926deccbSFrançois Tigeot }
3185926deccbSFrançois Tigeot
3186926deccbSFrançois Tigeot WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
3187c59a5c48SFrançois Tigeot WREG32(SRBM_INT_CNTL, 1);
3188c59a5c48SFrançois Tigeot WREG32(SRBM_INT_ACK, 1);
3189926deccbSFrançois Tigeot
3190926deccbSFrançois Tigeot evergreen_fix_pci_max_read_req_size(rdev);
3191926deccbSFrançois Tigeot
3192926deccbSFrançois Tigeot WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
3193926deccbSFrançois Tigeot
3194926deccbSFrançois Tigeot mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
3195926deccbSFrançois Tigeot mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
3196926deccbSFrançois Tigeot
3197926deccbSFrançois Tigeot rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes;
3198926deccbSFrançois Tigeot rdev->config.si.mem_max_burst_length_bytes = 256;
3199926deccbSFrançois Tigeot tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
3200926deccbSFrançois Tigeot rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
3201926deccbSFrançois Tigeot if (rdev->config.si.mem_row_size_in_kb > 4)
3202926deccbSFrançois Tigeot rdev->config.si.mem_row_size_in_kb = 4;
3203926deccbSFrançois Tigeot /* XXX use MC settings? */
3204926deccbSFrançois Tigeot rdev->config.si.shader_engine_tile_size = 32;
3205926deccbSFrançois Tigeot rdev->config.si.num_gpus = 1;
3206926deccbSFrançois Tigeot rdev->config.si.multi_gpu_tile_size = 64;
3207926deccbSFrançois Tigeot
3208926deccbSFrançois Tigeot /* fix up row size */
3209926deccbSFrançois Tigeot gb_addr_config &= ~ROW_SIZE_MASK;
3210926deccbSFrançois Tigeot switch (rdev->config.si.mem_row_size_in_kb) {
3211926deccbSFrançois Tigeot case 1:
3212926deccbSFrançois Tigeot default:
3213926deccbSFrançois Tigeot gb_addr_config |= ROW_SIZE(0);
3214926deccbSFrançois Tigeot break;
3215926deccbSFrançois Tigeot case 2:
3216926deccbSFrançois Tigeot gb_addr_config |= ROW_SIZE(1);
3217926deccbSFrançois Tigeot break;
3218926deccbSFrançois Tigeot case 4:
3219926deccbSFrançois Tigeot gb_addr_config |= ROW_SIZE(2);
3220926deccbSFrançois Tigeot break;
3221926deccbSFrançois Tigeot }
3222926deccbSFrançois Tigeot
3223926deccbSFrançois Tigeot /* setup tiling info dword. gb_addr_config is not adequate since it does
3224926deccbSFrançois Tigeot * not have bank info, so create a custom tiling dword.
3225926deccbSFrançois Tigeot * bits 3:0 num_pipes
3226926deccbSFrançois Tigeot * bits 7:4 num_banks
3227926deccbSFrançois Tigeot * bits 11:8 group_size
3228926deccbSFrançois Tigeot * bits 15:12 row_size
3229926deccbSFrançois Tigeot */
3230926deccbSFrançois Tigeot rdev->config.si.tile_config = 0;
3231926deccbSFrançois Tigeot switch (rdev->config.si.num_tile_pipes) {
3232926deccbSFrançois Tigeot case 1:
3233926deccbSFrançois Tigeot rdev->config.si.tile_config |= (0 << 0);
3234926deccbSFrançois Tigeot break;
3235926deccbSFrançois Tigeot case 2:
3236926deccbSFrançois Tigeot rdev->config.si.tile_config |= (1 << 0);
3237926deccbSFrançois Tigeot break;
3238926deccbSFrançois Tigeot case 4:
3239926deccbSFrançois Tigeot rdev->config.si.tile_config |= (2 << 0);
3240926deccbSFrançois Tigeot break;
3241926deccbSFrançois Tigeot case 8:
3242926deccbSFrançois Tigeot default:
3243926deccbSFrançois Tigeot /* XXX what about 12? */
3244926deccbSFrançois Tigeot rdev->config.si.tile_config |= (3 << 0);
3245926deccbSFrançois Tigeot break;
3246926deccbSFrançois Tigeot }
3247926deccbSFrançois Tigeot switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
3248926deccbSFrançois Tigeot case 0: /* four banks */
3249926deccbSFrançois Tigeot rdev->config.si.tile_config |= 0 << 4;
3250926deccbSFrançois Tigeot break;
3251926deccbSFrançois Tigeot case 1: /* eight banks */
3252926deccbSFrançois Tigeot rdev->config.si.tile_config |= 1 << 4;
3253926deccbSFrançois Tigeot break;
3254926deccbSFrançois Tigeot case 2: /* sixteen banks */
3255926deccbSFrançois Tigeot default:
3256926deccbSFrançois Tigeot rdev->config.si.tile_config |= 2 << 4;
3257926deccbSFrançois Tigeot break;
3258926deccbSFrançois Tigeot }
3259926deccbSFrançois Tigeot rdev->config.si.tile_config |=
3260926deccbSFrançois Tigeot ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
3261926deccbSFrançois Tigeot rdev->config.si.tile_config |=
3262926deccbSFrançois Tigeot ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
3263926deccbSFrançois Tigeot
3264926deccbSFrançois Tigeot WREG32(GB_ADDR_CONFIG, gb_addr_config);
3265926deccbSFrançois Tigeot WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
3266f43cf1b1SMichael Neumann WREG32(DMIF_ADDR_CALC, gb_addr_config);
3267926deccbSFrançois Tigeot WREG32(HDP_ADDR_CONFIG, gb_addr_config);
3268926deccbSFrançois Tigeot WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
3269926deccbSFrançois Tigeot WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
3270f43cf1b1SMichael Neumann if (rdev->has_uvd) {
3271f43cf1b1SMichael Neumann WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
3272f43cf1b1SMichael Neumann WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
3273f43cf1b1SMichael Neumann WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
3274f43cf1b1SMichael Neumann }
3275926deccbSFrançois Tigeot
3276926deccbSFrançois Tigeot si_tiling_mode_table_init(rdev);
3277926deccbSFrançois Tigeot
3278926deccbSFrançois Tigeot si_setup_rb(rdev, rdev->config.si.max_shader_engines,
3279926deccbSFrançois Tigeot rdev->config.si.max_sh_per_se,
3280926deccbSFrançois Tigeot rdev->config.si.max_backends_per_se);
3281926deccbSFrançois Tigeot
3282926deccbSFrançois Tigeot si_setup_spi(rdev, rdev->config.si.max_shader_engines,
3283926deccbSFrançois Tigeot rdev->config.si.max_sh_per_se,
3284926deccbSFrançois Tigeot rdev->config.si.max_cu_per_sh);
3285926deccbSFrançois Tigeot
3286c6f73aabSFrançois Tigeot rdev->config.si.active_cus = 0;
3287c6f73aabSFrançois Tigeot for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
3288c6f73aabSFrançois Tigeot for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
3289c6f73aabSFrançois Tigeot rdev->config.si.active_cus +=
3290c6f73aabSFrançois Tigeot hweight32(si_get_cu_active_bitmap(rdev, i, j));
3291c6f73aabSFrançois Tigeot }
3292c6f73aabSFrançois Tigeot }
3293926deccbSFrançois Tigeot
3294926deccbSFrançois Tigeot /* set HW defaults for 3D engine */
3295926deccbSFrançois Tigeot WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
3296926deccbSFrançois Tigeot ROQ_IB2_START(0x2b)));
3297926deccbSFrançois Tigeot WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
3298926deccbSFrançois Tigeot
3299926deccbSFrançois Tigeot sx_debug_1 = RREG32(SX_DEBUG_1);
3300926deccbSFrançois Tigeot WREG32(SX_DEBUG_1, sx_debug_1);
3301926deccbSFrançois Tigeot
3302926deccbSFrançois Tigeot WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
3303926deccbSFrançois Tigeot
3304926deccbSFrançois Tigeot WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_frontend) |
3305926deccbSFrançois Tigeot SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_backend) |
3306926deccbSFrançois Tigeot SC_HIZ_TILE_FIFO_SIZE(rdev->config.si.sc_hiz_tile_fifo_size) |
3307926deccbSFrançois Tigeot SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.si.sc_earlyz_tile_fifo_size)));
3308926deccbSFrançois Tigeot
3309926deccbSFrançois Tigeot WREG32(VGT_NUM_INSTANCES, 1);
3310926deccbSFrançois Tigeot
3311926deccbSFrançois Tigeot WREG32(CP_PERFMON_CNTL, 0);
3312926deccbSFrançois Tigeot
3313926deccbSFrançois Tigeot WREG32(SQ_CONFIG, 0);
3314926deccbSFrançois Tigeot
3315926deccbSFrançois Tigeot WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
3316926deccbSFrançois Tigeot FORCE_EOV_MAX_REZ_CNT(255)));
3317926deccbSFrançois Tigeot
3318926deccbSFrançois Tigeot WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
3319926deccbSFrançois Tigeot AUTO_INVLD_EN(ES_AND_GS_AUTO));
3320926deccbSFrançois Tigeot
3321926deccbSFrançois Tigeot WREG32(VGT_GS_VERTEX_REUSE, 16);
3322926deccbSFrançois Tigeot WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
3323926deccbSFrançois Tigeot
3324926deccbSFrançois Tigeot WREG32(CB_PERFCOUNTER0_SELECT0, 0);
3325926deccbSFrançois Tigeot WREG32(CB_PERFCOUNTER0_SELECT1, 0);
3326926deccbSFrançois Tigeot WREG32(CB_PERFCOUNTER1_SELECT0, 0);
3327926deccbSFrançois Tigeot WREG32(CB_PERFCOUNTER1_SELECT1, 0);
3328926deccbSFrançois Tigeot WREG32(CB_PERFCOUNTER2_SELECT0, 0);
3329926deccbSFrançois Tigeot WREG32(CB_PERFCOUNTER2_SELECT1, 0);
3330926deccbSFrançois Tigeot WREG32(CB_PERFCOUNTER3_SELECT0, 0);
3331926deccbSFrançois Tigeot WREG32(CB_PERFCOUNTER3_SELECT1, 0);
3332926deccbSFrançois Tigeot
3333926deccbSFrançois Tigeot tmp = RREG32(HDP_MISC_CNTL);
3334926deccbSFrançois Tigeot tmp |= HDP_FLUSH_INVALIDATE_CACHE;
3335926deccbSFrançois Tigeot WREG32(HDP_MISC_CNTL, tmp);
3336926deccbSFrançois Tigeot
3337926deccbSFrançois Tigeot hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
3338926deccbSFrançois Tigeot WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
3339926deccbSFrançois Tigeot
3340926deccbSFrançois Tigeot WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
3341926deccbSFrançois Tigeot
3342c4ef309bSzrj udelay(50);
3343926deccbSFrançois Tigeot }
3344926deccbSFrançois Tigeot
3345926deccbSFrançois Tigeot /*
3346926deccbSFrançois Tigeot * GPU scratch registers helpers function.
3347926deccbSFrançois Tigeot */
si_scratch_init(struct radeon_device * rdev)3348926deccbSFrançois Tigeot static void si_scratch_init(struct radeon_device *rdev)
3349926deccbSFrançois Tigeot {
3350926deccbSFrançois Tigeot int i;
3351926deccbSFrançois Tigeot
3352926deccbSFrançois Tigeot rdev->scratch.num_reg = 7;
3353926deccbSFrançois Tigeot rdev->scratch.reg_base = SCRATCH_REG0;
3354926deccbSFrançois Tigeot for (i = 0; i < rdev->scratch.num_reg; i++) {
3355926deccbSFrançois Tigeot rdev->scratch.free[i] = true;
3356926deccbSFrançois Tigeot rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
3357926deccbSFrançois Tigeot }
3358926deccbSFrançois Tigeot }
3359926deccbSFrançois Tigeot
si_fence_ring_emit(struct radeon_device * rdev,struct radeon_fence * fence)3360926deccbSFrançois Tigeot void si_fence_ring_emit(struct radeon_device *rdev,
3361926deccbSFrançois Tigeot struct radeon_fence *fence)
3362926deccbSFrançois Tigeot {
3363926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[fence->ring];
3364926deccbSFrançois Tigeot u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
3365926deccbSFrançois Tigeot
3366926deccbSFrançois Tigeot /* flush read cache over gart */
3367926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3368926deccbSFrançois Tigeot radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
3369926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3370926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
3371926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
3372926deccbSFrançois Tigeot PACKET3_TC_ACTION_ENA |
3373926deccbSFrançois Tigeot PACKET3_SH_KCACHE_ACTION_ENA |
3374926deccbSFrançois Tigeot PACKET3_SH_ICACHE_ACTION_ENA);
3375926deccbSFrançois Tigeot radeon_ring_write(ring, 0xFFFFFFFF);
3376926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3377926deccbSFrançois Tigeot radeon_ring_write(ring, 10); /* poll interval */
3378926deccbSFrançois Tigeot /* EVENT_WRITE_EOP - flush caches, send int */
3379926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
3380926deccbSFrançois Tigeot radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5));
3381c6f73aabSFrançois Tigeot radeon_ring_write(ring, lower_32_bits(addr));
3382926deccbSFrançois Tigeot radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
3383926deccbSFrançois Tigeot radeon_ring_write(ring, fence->seq);
3384926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3385926deccbSFrançois Tigeot }
3386926deccbSFrançois Tigeot
3387926deccbSFrançois Tigeot /*
3388926deccbSFrançois Tigeot * IB stuff
3389926deccbSFrançois Tigeot */
si_ring_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)3390926deccbSFrançois Tigeot void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3391926deccbSFrançois Tigeot {
3392926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[ib->ring];
33937dcf36dcSFrançois Tigeot unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
3394926deccbSFrançois Tigeot u32 header;
3395926deccbSFrançois Tigeot
3396926deccbSFrançois Tigeot if (ib->is_const_ib) {
3397926deccbSFrançois Tigeot /* set switch buffer packet before const IB */
3398926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
3399926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3400926deccbSFrançois Tigeot
3401926deccbSFrançois Tigeot header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
3402926deccbSFrançois Tigeot } else {
3403926deccbSFrançois Tigeot u32 next_rptr;
3404926deccbSFrançois Tigeot if (ring->rptr_save_reg) {
3405926deccbSFrançois Tigeot next_rptr = ring->wptr + 3 + 4 + 8;
3406926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3407926deccbSFrançois Tigeot radeon_ring_write(ring, ((ring->rptr_save_reg -
3408926deccbSFrançois Tigeot PACKET3_SET_CONFIG_REG_START) >> 2));
3409926deccbSFrançois Tigeot radeon_ring_write(ring, next_rptr);
3410926deccbSFrançois Tigeot } else if (rdev->wb.enabled) {
3411926deccbSFrançois Tigeot next_rptr = ring->wptr + 5 + 4 + 8;
3412926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
3413926deccbSFrançois Tigeot radeon_ring_write(ring, (1 << 8));
3414926deccbSFrançois Tigeot radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
3415c6f73aabSFrançois Tigeot radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr));
3416926deccbSFrançois Tigeot radeon_ring_write(ring, next_rptr);
3417926deccbSFrançois Tigeot }
3418926deccbSFrançois Tigeot
3419926deccbSFrançois Tigeot header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
3420926deccbSFrançois Tigeot }
3421926deccbSFrançois Tigeot
3422926deccbSFrançois Tigeot radeon_ring_write(ring, header);
3423926deccbSFrançois Tigeot radeon_ring_write(ring,
3424926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
3425926deccbSFrançois Tigeot (2 << 0) |
3426926deccbSFrançois Tigeot #endif
3427926deccbSFrançois Tigeot (ib->gpu_addr & 0xFFFFFFFC));
3428926deccbSFrançois Tigeot radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
34297dcf36dcSFrançois Tigeot radeon_ring_write(ring, ib->length_dw | (vm_id << 24));
3430926deccbSFrançois Tigeot
3431926deccbSFrançois Tigeot if (!ib->is_const_ib) {
3432926deccbSFrançois Tigeot /* flush read cache over gart for this vmid */
3433926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3434926deccbSFrançois Tigeot radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
34357dcf36dcSFrançois Tigeot radeon_ring_write(ring, vm_id);
3436926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
3437926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
3438926deccbSFrançois Tigeot PACKET3_TC_ACTION_ENA |
3439926deccbSFrançois Tigeot PACKET3_SH_KCACHE_ACTION_ENA |
3440926deccbSFrançois Tigeot PACKET3_SH_ICACHE_ACTION_ENA);
3441926deccbSFrançois Tigeot radeon_ring_write(ring, 0xFFFFFFFF);
3442926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3443926deccbSFrançois Tigeot radeon_ring_write(ring, 10); /* poll interval */
3444926deccbSFrançois Tigeot }
3445926deccbSFrançois Tigeot }
3446926deccbSFrançois Tigeot
3447926deccbSFrançois Tigeot /*
3448926deccbSFrançois Tigeot * CP.
3449926deccbSFrançois Tigeot */
si_cp_enable(struct radeon_device * rdev,bool enable)3450926deccbSFrançois Tigeot static void si_cp_enable(struct radeon_device *rdev, bool enable)
3451926deccbSFrançois Tigeot {
3452926deccbSFrançois Tigeot if (enable)
3453926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, 0);
3454926deccbSFrançois Tigeot else {
3455c6f73aabSFrançois Tigeot if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
3456926deccbSFrançois Tigeot radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
3457926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));
3458926deccbSFrançois Tigeot WREG32(SCRATCH_UMSK, 0);
3459926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3460926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3461926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3462926deccbSFrançois Tigeot }
3463c4ef309bSzrj udelay(50);
3464926deccbSFrançois Tigeot }
3465926deccbSFrançois Tigeot
si_cp_load_microcode(struct radeon_device * rdev)3466926deccbSFrançois Tigeot static int si_cp_load_microcode(struct radeon_device *rdev)
3467926deccbSFrançois Tigeot {
3468926deccbSFrançois Tigeot int i;
3469926deccbSFrançois Tigeot
3470cb754608SImre Vadász if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
3471926deccbSFrançois Tigeot return -EINVAL;
3472926deccbSFrançois Tigeot
3473926deccbSFrançois Tigeot si_cp_enable(rdev, false);
3474926deccbSFrançois Tigeot
3475cb754608SImre Vadász if (rdev->new_fw) {
3476cb754608SImre Vadász const struct gfx_firmware_header_v1_0 *pfp_hdr =
3477cb754608SImre Vadász (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
3478cb754608SImre Vadász const struct gfx_firmware_header_v1_0 *ce_hdr =
3479cb754608SImre Vadász (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
3480cb754608SImre Vadász const struct gfx_firmware_header_v1_0 *me_hdr =
3481cb754608SImre Vadász (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
3482cb754608SImre Vadász const __le32 *fw_data;
3483cb754608SImre Vadász u32 fw_size;
3484cb754608SImre Vadász
3485cb754608SImre Vadász radeon_ucode_print_gfx_hdr(&pfp_hdr->header);
3486cb754608SImre Vadász radeon_ucode_print_gfx_hdr(&ce_hdr->header);
3487cb754608SImre Vadász radeon_ucode_print_gfx_hdr(&me_hdr->header);
3488cb754608SImre Vadász
3489cb754608SImre Vadász /* PFP */
3490cb754608SImre Vadász fw_data = (const __le32 *)
3491c59a5c48SFrançois Tigeot (rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
3492cb754608SImre Vadász fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
3493cb754608SImre Vadász WREG32(CP_PFP_UCODE_ADDR, 0);
3494cb754608SImre Vadász for (i = 0; i < fw_size; i++)
3495cb754608SImre Vadász WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
3496cb754608SImre Vadász WREG32(CP_PFP_UCODE_ADDR, 0);
3497cb754608SImre Vadász
3498cb754608SImre Vadász /* CE */
3499cb754608SImre Vadász fw_data = (const __le32 *)
3500c59a5c48SFrançois Tigeot (rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
3501cb754608SImre Vadász fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
3502cb754608SImre Vadász WREG32(CP_CE_UCODE_ADDR, 0);
3503cb754608SImre Vadász for (i = 0; i < fw_size; i++)
3504cb754608SImre Vadász WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
3505cb754608SImre Vadász WREG32(CP_CE_UCODE_ADDR, 0);
3506cb754608SImre Vadász
3507cb754608SImre Vadász /* ME */
3508cb754608SImre Vadász fw_data = (const __be32 *)
3509c59a5c48SFrançois Tigeot (rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
3510cb754608SImre Vadász fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
3511cb754608SImre Vadász WREG32(CP_ME_RAM_WADDR, 0);
3512cb754608SImre Vadász for (i = 0; i < fw_size; i++)
3513cb754608SImre Vadász WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++));
3514cb754608SImre Vadász WREG32(CP_ME_RAM_WADDR, 0);
3515cb754608SImre Vadász } else {
3516cb754608SImre Vadász const __be32 *fw_data;
3517cb754608SImre Vadász
3518926deccbSFrançois Tigeot /* PFP */
3519926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->pfp_fw->data;
3520926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0);
3521926deccbSFrançois Tigeot for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
3522926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
3523926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0);
3524926deccbSFrançois Tigeot
3525926deccbSFrançois Tigeot /* CE */
3526926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->ce_fw->data;
3527926deccbSFrançois Tigeot WREG32(CP_CE_UCODE_ADDR, 0);
3528926deccbSFrançois Tigeot for (i = 0; i < SI_CE_UCODE_SIZE; i++)
3529926deccbSFrançois Tigeot WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
3530926deccbSFrançois Tigeot WREG32(CP_CE_UCODE_ADDR, 0);
3531926deccbSFrançois Tigeot
3532926deccbSFrançois Tigeot /* ME */
3533926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->me_fw->data;
3534926deccbSFrançois Tigeot WREG32(CP_ME_RAM_WADDR, 0);
3535926deccbSFrançois Tigeot for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
3536926deccbSFrançois Tigeot WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
3537926deccbSFrançois Tigeot WREG32(CP_ME_RAM_WADDR, 0);
3538cb754608SImre Vadász }
3539926deccbSFrançois Tigeot
3540926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0);
3541926deccbSFrançois Tigeot WREG32(CP_CE_UCODE_ADDR, 0);
3542926deccbSFrançois Tigeot WREG32(CP_ME_RAM_WADDR, 0);
3543926deccbSFrançois Tigeot WREG32(CP_ME_RAM_RADDR, 0);
3544926deccbSFrançois Tigeot return 0;
3545926deccbSFrançois Tigeot }
3546926deccbSFrançois Tigeot
si_cp_start(struct radeon_device * rdev)3547926deccbSFrançois Tigeot static int si_cp_start(struct radeon_device *rdev)
3548926deccbSFrançois Tigeot {
3549926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3550926deccbSFrançois Tigeot int r, i;
3551926deccbSFrançois Tigeot
3552926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, 7 + 4);
3553926deccbSFrançois Tigeot if (r) {
3554926deccbSFrançois Tigeot DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3555926deccbSFrançois Tigeot return r;
3556926deccbSFrançois Tigeot }
3557926deccbSFrançois Tigeot /* init the CP */
3558926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
3559926deccbSFrançois Tigeot radeon_ring_write(ring, 0x1);
3560926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0);
3561926deccbSFrançois Tigeot radeon_ring_write(ring, rdev->config.si.max_hw_contexts - 1);
3562926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
3563926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3564926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3565926deccbSFrançois Tigeot
3566926deccbSFrançois Tigeot /* init the CE partitions */
3567926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
3568926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
3569926deccbSFrançois Tigeot radeon_ring_write(ring, 0xc000);
3570926deccbSFrançois Tigeot radeon_ring_write(ring, 0xe000);
3571c6f73aabSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring, false);
3572926deccbSFrançois Tigeot
3573926deccbSFrançois Tigeot si_cp_enable(rdev, true);
3574926deccbSFrançois Tigeot
3575926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, si_default_size + 10);
3576926deccbSFrançois Tigeot if (r) {
3577926deccbSFrançois Tigeot DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3578926deccbSFrançois Tigeot return r;
3579926deccbSFrançois Tigeot }
3580926deccbSFrançois Tigeot
3581926deccbSFrançois Tigeot /* setup clear context state */
3582926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
3583926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
3584926deccbSFrançois Tigeot
3585926deccbSFrançois Tigeot for (i = 0; i < si_default_size; i++)
3586926deccbSFrançois Tigeot radeon_ring_write(ring, si_default_state[i]);
3587926deccbSFrançois Tigeot
3588926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
3589926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
3590926deccbSFrançois Tigeot
3591926deccbSFrançois Tigeot /* set clear context state */
3592926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
3593926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3594926deccbSFrançois Tigeot
3595926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
3596926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000316);
3597926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
3598926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */
3599926deccbSFrançois Tigeot
3600c6f73aabSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring, false);
3601926deccbSFrançois Tigeot
3602926deccbSFrançois Tigeot for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) {
3603926deccbSFrançois Tigeot ring = &rdev->ring[i];
3604926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, 2);
3605926deccbSFrançois Tigeot
3606926deccbSFrançois Tigeot /* clear the compute context state */
3607926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0));
3608926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
3609926deccbSFrançois Tigeot
3610c6f73aabSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring, false);
3611926deccbSFrançois Tigeot }
3612926deccbSFrançois Tigeot
3613926deccbSFrançois Tigeot return 0;
3614926deccbSFrançois Tigeot }
3615926deccbSFrançois Tigeot
si_cp_fini(struct radeon_device * rdev)3616926deccbSFrançois Tigeot static void si_cp_fini(struct radeon_device *rdev)
3617926deccbSFrançois Tigeot {
3618926deccbSFrançois Tigeot struct radeon_ring *ring;
3619926deccbSFrançois Tigeot si_cp_enable(rdev, false);
3620926deccbSFrançois Tigeot
3621926deccbSFrançois Tigeot ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3622926deccbSFrançois Tigeot radeon_ring_fini(rdev, ring);
3623926deccbSFrançois Tigeot radeon_scratch_free(rdev, ring->rptr_save_reg);
3624926deccbSFrançois Tigeot
3625926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
3626926deccbSFrançois Tigeot radeon_ring_fini(rdev, ring);
3627926deccbSFrançois Tigeot radeon_scratch_free(rdev, ring->rptr_save_reg);
3628926deccbSFrançois Tigeot
3629926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
3630926deccbSFrançois Tigeot radeon_ring_fini(rdev, ring);
3631926deccbSFrançois Tigeot radeon_scratch_free(rdev, ring->rptr_save_reg);
3632926deccbSFrançois Tigeot }
3633926deccbSFrançois Tigeot
si_cp_resume(struct radeon_device * rdev)3634926deccbSFrançois Tigeot static int si_cp_resume(struct radeon_device *rdev)
3635926deccbSFrançois Tigeot {
3636926deccbSFrançois Tigeot struct radeon_ring *ring;
3637926deccbSFrançois Tigeot u32 tmp;
3638926deccbSFrançois Tigeot u32 rb_bufsz;
3639926deccbSFrançois Tigeot int r;
3640926deccbSFrançois Tigeot
36414cd92098Szrj si_enable_gui_idle_interrupt(rdev, false);
3642926deccbSFrançois Tigeot
3643926deccbSFrançois Tigeot WREG32(CP_SEM_WAIT_TIMER, 0x0);
3644926deccbSFrançois Tigeot WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
3645926deccbSFrançois Tigeot
3646926deccbSFrançois Tigeot /* Set the write pointer delay */
3647926deccbSFrançois Tigeot WREG32(CP_RB_WPTR_DELAY, 0);
3648926deccbSFrançois Tigeot
3649926deccbSFrançois Tigeot WREG32(CP_DEBUG, 0);
3650926deccbSFrançois Tigeot WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
3651926deccbSFrançois Tigeot
3652926deccbSFrançois Tigeot /* ring 0 - compute and gfx */
3653926deccbSFrançois Tigeot /* Set ring buffer size */
3654926deccbSFrançois Tigeot ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
36554cd92098Szrj rb_bufsz = order_base_2(ring->ring_size / 8);
36564cd92098Szrj tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3657926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
3658926deccbSFrançois Tigeot tmp |= BUF_SWAP_32BIT;
3659926deccbSFrançois Tigeot #endif
3660926deccbSFrançois Tigeot WREG32(CP_RB0_CNTL, tmp);
3661926deccbSFrançois Tigeot
3662926deccbSFrançois Tigeot /* Initialize the ring buffer's read and write pointers */
3663926deccbSFrançois Tigeot WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
3664926deccbSFrançois Tigeot ring->wptr = 0;
3665926deccbSFrançois Tigeot WREG32(CP_RB0_WPTR, ring->wptr);
3666926deccbSFrançois Tigeot
3667926deccbSFrançois Tigeot /* set the wb address whether it's enabled or not */
3668926deccbSFrançois Tigeot WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
3669926deccbSFrançois Tigeot WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
3670926deccbSFrançois Tigeot
3671926deccbSFrançois Tigeot if (rdev->wb.enabled)
3672926deccbSFrançois Tigeot WREG32(SCRATCH_UMSK, 0xff);
3673926deccbSFrançois Tigeot else {
3674926deccbSFrançois Tigeot tmp |= RB_NO_UPDATE;
3675926deccbSFrançois Tigeot WREG32(SCRATCH_UMSK, 0);
3676926deccbSFrançois Tigeot }
3677926deccbSFrançois Tigeot
3678c4ef309bSzrj mdelay(1);
3679926deccbSFrançois Tigeot WREG32(CP_RB0_CNTL, tmp);
3680926deccbSFrançois Tigeot
3681926deccbSFrançois Tigeot WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
3682926deccbSFrançois Tigeot
3683926deccbSFrançois Tigeot /* ring1 - compute only */
3684926deccbSFrançois Tigeot /* Set ring buffer size */
3685926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
36864cd92098Szrj rb_bufsz = order_base_2(ring->ring_size / 8);
36874cd92098Szrj tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3688926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
3689926deccbSFrançois Tigeot tmp |= BUF_SWAP_32BIT;
3690926deccbSFrançois Tigeot #endif
3691926deccbSFrançois Tigeot WREG32(CP_RB1_CNTL, tmp);
3692926deccbSFrançois Tigeot
3693926deccbSFrançois Tigeot /* Initialize the ring buffer's read and write pointers */
3694926deccbSFrançois Tigeot WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
3695926deccbSFrançois Tigeot ring->wptr = 0;
3696926deccbSFrançois Tigeot WREG32(CP_RB1_WPTR, ring->wptr);
3697926deccbSFrançois Tigeot
3698926deccbSFrançois Tigeot /* set the wb address whether it's enabled or not */
3699926deccbSFrançois Tigeot WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC);
3700926deccbSFrançois Tigeot WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
3701926deccbSFrançois Tigeot
3702c4ef309bSzrj mdelay(1);
3703926deccbSFrançois Tigeot WREG32(CP_RB1_CNTL, tmp);
3704926deccbSFrançois Tigeot
3705926deccbSFrançois Tigeot WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
3706926deccbSFrançois Tigeot
3707926deccbSFrançois Tigeot /* ring2 - compute only */
3708926deccbSFrançois Tigeot /* Set ring buffer size */
3709926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
37104cd92098Szrj rb_bufsz = order_base_2(ring->ring_size / 8);
37114cd92098Szrj tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3712926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
3713926deccbSFrançois Tigeot tmp |= BUF_SWAP_32BIT;
3714926deccbSFrançois Tigeot #endif
3715926deccbSFrançois Tigeot WREG32(CP_RB2_CNTL, tmp);
3716926deccbSFrançois Tigeot
3717926deccbSFrançois Tigeot /* Initialize the ring buffer's read and write pointers */
3718926deccbSFrançois Tigeot WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
3719926deccbSFrançois Tigeot ring->wptr = 0;
3720926deccbSFrançois Tigeot WREG32(CP_RB2_WPTR, ring->wptr);
3721926deccbSFrançois Tigeot
3722926deccbSFrançois Tigeot /* set the wb address whether it's enabled or not */
3723926deccbSFrançois Tigeot WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC);
3724926deccbSFrançois Tigeot WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF);
3725926deccbSFrançois Tigeot
3726c4ef309bSzrj mdelay(1);
3727926deccbSFrançois Tigeot WREG32(CP_RB2_CNTL, tmp);
3728926deccbSFrançois Tigeot
3729926deccbSFrançois Tigeot WREG32(CP_RB2_BASE, ring->gpu_addr >> 8);
3730926deccbSFrançois Tigeot
3731926deccbSFrançois Tigeot /* start the rings */
3732926deccbSFrançois Tigeot si_cp_start(rdev);
3733926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
3734926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = true;
3735926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = true;
3736926deccbSFrançois Tigeot r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
3737926deccbSFrançois Tigeot if (r) {
3738926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3739926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3740926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3741926deccbSFrançois Tigeot return r;
3742926deccbSFrançois Tigeot }
3743926deccbSFrançois Tigeot r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
3744926deccbSFrançois Tigeot if (r) {
3745926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3746926deccbSFrançois Tigeot }
3747926deccbSFrançois Tigeot r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
3748926deccbSFrançois Tigeot if (r) {
3749926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3750926deccbSFrançois Tigeot }
3751926deccbSFrançois Tigeot
37524cd92098Szrj si_enable_gui_idle_interrupt(rdev, true);
37534cd92098Szrj
3754c6f73aabSFrançois Tigeot if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
3755c6f73aabSFrançois Tigeot radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
3756c6f73aabSFrançois Tigeot
3757926deccbSFrançois Tigeot return 0;
3758926deccbSFrançois Tigeot }
3759926deccbSFrançois Tigeot
si_gpu_check_soft_reset(struct radeon_device * rdev)37604cd92098Szrj u32 si_gpu_check_soft_reset(struct radeon_device *rdev)
3761926deccbSFrançois Tigeot {
3762b403bed8SMichael Neumann u32 reset_mask = 0;
3763b403bed8SMichael Neumann u32 tmp;
3764926deccbSFrançois Tigeot
3765b403bed8SMichael Neumann /* GRBM_STATUS */
3766b403bed8SMichael Neumann tmp = RREG32(GRBM_STATUS);
3767b403bed8SMichael Neumann if (tmp & (PA_BUSY | SC_BUSY |
3768b403bed8SMichael Neumann BCI_BUSY | SX_BUSY |
3769b403bed8SMichael Neumann TA_BUSY | VGT_BUSY |
3770b403bed8SMichael Neumann DB_BUSY | CB_BUSY |
3771b403bed8SMichael Neumann GDS_BUSY | SPI_BUSY |
3772b403bed8SMichael Neumann IA_BUSY | IA_BUSY_NO_DMA))
3773b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GFX;
3774b403bed8SMichael Neumann
3775b403bed8SMichael Neumann if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
3776b403bed8SMichael Neumann CP_BUSY | CP_COHERENCY_BUSY))
3777b403bed8SMichael Neumann reset_mask |= RADEON_RESET_CP;
3778b403bed8SMichael Neumann
3779b403bed8SMichael Neumann if (tmp & GRBM_EE_BUSY)
3780b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
3781b403bed8SMichael Neumann
3782b403bed8SMichael Neumann /* GRBM_STATUS2 */
3783b403bed8SMichael Neumann tmp = RREG32(GRBM_STATUS2);
3784b403bed8SMichael Neumann if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
3785b403bed8SMichael Neumann reset_mask |= RADEON_RESET_RLC;
3786b403bed8SMichael Neumann
3787b403bed8SMichael Neumann /* DMA_STATUS_REG 0 */
3788b403bed8SMichael Neumann tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
3789b403bed8SMichael Neumann if (!(tmp & DMA_IDLE))
3790b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA;
3791b403bed8SMichael Neumann
3792b403bed8SMichael Neumann /* DMA_STATUS_REG 1 */
3793b403bed8SMichael Neumann tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
3794b403bed8SMichael Neumann if (!(tmp & DMA_IDLE))
3795b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA1;
3796b403bed8SMichael Neumann
3797b403bed8SMichael Neumann /* SRBM_STATUS2 */
3798b403bed8SMichael Neumann tmp = RREG32(SRBM_STATUS2);
3799b403bed8SMichael Neumann if (tmp & DMA_BUSY)
3800b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA;
3801b403bed8SMichael Neumann
3802b403bed8SMichael Neumann if (tmp & DMA1_BUSY)
3803b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA1;
3804b403bed8SMichael Neumann
3805b403bed8SMichael Neumann /* SRBM_STATUS */
3806b403bed8SMichael Neumann tmp = RREG32(SRBM_STATUS);
3807b403bed8SMichael Neumann
3808b403bed8SMichael Neumann if (tmp & IH_BUSY)
3809b403bed8SMichael Neumann reset_mask |= RADEON_RESET_IH;
3810b403bed8SMichael Neumann
3811b403bed8SMichael Neumann if (tmp & SEM_BUSY)
3812b403bed8SMichael Neumann reset_mask |= RADEON_RESET_SEM;
3813b403bed8SMichael Neumann
3814b403bed8SMichael Neumann if (tmp & GRBM_RQ_PENDING)
3815b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GRBM;
3816b403bed8SMichael Neumann
3817b403bed8SMichael Neumann if (tmp & VMC_BUSY)
3818b403bed8SMichael Neumann reset_mask |= RADEON_RESET_VMC;
3819b403bed8SMichael Neumann
3820b403bed8SMichael Neumann if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
3821b403bed8SMichael Neumann MCC_BUSY | MCD_BUSY))
3822b403bed8SMichael Neumann reset_mask |= RADEON_RESET_MC;
3823b403bed8SMichael Neumann
3824b403bed8SMichael Neumann if (evergreen_is_display_hung(rdev))
3825b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DISPLAY;
3826b403bed8SMichael Neumann
3827b403bed8SMichael Neumann /* VM_L2_STATUS */
3828b403bed8SMichael Neumann tmp = RREG32(VM_L2_STATUS);
3829b403bed8SMichael Neumann if (tmp & L2_BUSY)
3830b403bed8SMichael Neumann reset_mask |= RADEON_RESET_VMC;
3831b403bed8SMichael Neumann
3832b403bed8SMichael Neumann /* Skip MC reset as it's mostly likely not hung, just busy */
3833b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_MC) {
3834b403bed8SMichael Neumann DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
3835b403bed8SMichael Neumann reset_mask &= ~RADEON_RESET_MC;
3836926deccbSFrançois Tigeot }
3837926deccbSFrançois Tigeot
3838b403bed8SMichael Neumann return reset_mask;
3839b403bed8SMichael Neumann }
3840926deccbSFrançois Tigeot
si_gpu_soft_reset(struct radeon_device * rdev,u32 reset_mask)3841b403bed8SMichael Neumann static void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
3842b403bed8SMichael Neumann {
3843b403bed8SMichael Neumann struct evergreen_mc_save save;
3844b403bed8SMichael Neumann u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
3845b403bed8SMichael Neumann u32 tmp;
3846b403bed8SMichael Neumann
3847b403bed8SMichael Neumann if (reset_mask == 0)
3848926deccbSFrançois Tigeot return;
3849926deccbSFrançois Tigeot
3850b403bed8SMichael Neumann dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
3851b403bed8SMichael Neumann
3852b403bed8SMichael Neumann evergreen_print_gpu_status_regs(rdev);
3853b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
3854b403bed8SMichael Neumann RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
3855b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
3856b403bed8SMichael Neumann RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
3857926deccbSFrançois Tigeot
38584cd92098Szrj /* disable PG/CG */
38594cd92098Szrj si_fini_pg(rdev);
38604cd92098Szrj si_fini_cg(rdev);
38614cd92098Szrj
38624cd92098Szrj /* stop the rlc */
38634cd92098Szrj si_rlc_stop(rdev);
38644cd92098Szrj
3865926deccbSFrançois Tigeot /* Disable CP parsing/prefetching */
3866926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
3867926deccbSFrançois Tigeot
3868b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA) {
3869b403bed8SMichael Neumann /* dma0 */
3870b403bed8SMichael Neumann tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
3871b403bed8SMichael Neumann tmp &= ~DMA_RB_ENABLE;
3872b403bed8SMichael Neumann WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
3873b403bed8SMichael Neumann }
3874b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA1) {
3875b403bed8SMichael Neumann /* dma1 */
3876b403bed8SMichael Neumann tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
3877b403bed8SMichael Neumann tmp &= ~DMA_RB_ENABLE;
3878b403bed8SMichael Neumann WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
3879b403bed8SMichael Neumann }
3880b403bed8SMichael Neumann
3881c4ef309bSzrj udelay(50);
3882b403bed8SMichael Neumann
3883b403bed8SMichael Neumann evergreen_mc_stop(rdev, &save);
3884b403bed8SMichael Neumann if (evergreen_mc_wait_for_idle(rdev)) {
3885b403bed8SMichael Neumann dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
3886b403bed8SMichael Neumann }
3887b403bed8SMichael Neumann
3888b403bed8SMichael Neumann if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) {
3889b403bed8SMichael Neumann grbm_soft_reset = SOFT_RESET_CB |
3890926deccbSFrançois Tigeot SOFT_RESET_DB |
3891926deccbSFrançois Tigeot SOFT_RESET_GDS |
3892926deccbSFrançois Tigeot SOFT_RESET_PA |
3893926deccbSFrançois Tigeot SOFT_RESET_SC |
3894926deccbSFrançois Tigeot SOFT_RESET_BCI |
3895926deccbSFrançois Tigeot SOFT_RESET_SPI |
3896926deccbSFrançois Tigeot SOFT_RESET_SX |
3897926deccbSFrançois Tigeot SOFT_RESET_TC |
3898926deccbSFrançois Tigeot SOFT_RESET_TA |
3899926deccbSFrançois Tigeot SOFT_RESET_VGT |
3900b403bed8SMichael Neumann SOFT_RESET_IA;
3901926deccbSFrançois Tigeot }
3902926deccbSFrançois Tigeot
3903b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_CP) {
3904b403bed8SMichael Neumann grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
3905926deccbSFrançois Tigeot
3906b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_GRBM;
3907926deccbSFrançois Tigeot }
3908926deccbSFrançois Tigeot
3909926deccbSFrançois Tigeot if (reset_mask & RADEON_RESET_DMA)
3910b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DMA;
3911b403bed8SMichael Neumann
3912b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA1)
3913b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DMA1;
3914b403bed8SMichael Neumann
3915b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DISPLAY)
3916b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DC;
3917b403bed8SMichael Neumann
3918b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_RLC)
3919b403bed8SMichael Neumann grbm_soft_reset |= SOFT_RESET_RLC;
3920b403bed8SMichael Neumann
3921b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_SEM)
3922b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_SEM;
3923b403bed8SMichael Neumann
3924b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_IH)
3925b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_IH;
3926b403bed8SMichael Neumann
3927b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_GRBM)
3928b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_GRBM;
3929b403bed8SMichael Neumann
3930b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_VMC)
3931b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_VMC;
3932b403bed8SMichael Neumann
3933b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_MC)
3934b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_MC;
3935b403bed8SMichael Neumann
3936b403bed8SMichael Neumann if (grbm_soft_reset) {
3937b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET);
3938b403bed8SMichael Neumann tmp |= grbm_soft_reset;
3939b403bed8SMichael Neumann dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
3940b403bed8SMichael Neumann WREG32(GRBM_SOFT_RESET, tmp);
3941b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET);
3942b403bed8SMichael Neumann
3943c4ef309bSzrj udelay(50);
3944b403bed8SMichael Neumann
3945b403bed8SMichael Neumann tmp &= ~grbm_soft_reset;
3946b403bed8SMichael Neumann WREG32(GRBM_SOFT_RESET, tmp);
3947b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET);
3948b403bed8SMichael Neumann }
3949b403bed8SMichael Neumann
3950b403bed8SMichael Neumann if (srbm_soft_reset) {
3951b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET);
3952b403bed8SMichael Neumann tmp |= srbm_soft_reset;
3953b403bed8SMichael Neumann dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
3954b403bed8SMichael Neumann WREG32(SRBM_SOFT_RESET, tmp);
3955b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET);
3956b403bed8SMichael Neumann
3957c4ef309bSzrj udelay(50);
3958b403bed8SMichael Neumann
3959b403bed8SMichael Neumann tmp &= ~srbm_soft_reset;
3960b403bed8SMichael Neumann WREG32(SRBM_SOFT_RESET, tmp);
3961b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET);
3962b403bed8SMichael Neumann }
3963926deccbSFrançois Tigeot
3964926deccbSFrançois Tigeot /* Wait a little for things to settle down */
3965c4ef309bSzrj udelay(50);
3966926deccbSFrançois Tigeot
3967926deccbSFrançois Tigeot evergreen_mc_resume(rdev, &save);
3968c4ef309bSzrj udelay(50);
3969b403bed8SMichael Neumann
3970b403bed8SMichael Neumann evergreen_print_gpu_status_regs(rdev);
3971926deccbSFrançois Tigeot }
3972926deccbSFrançois Tigeot
si_set_clk_bypass_mode(struct radeon_device * rdev)3973c6f73aabSFrançois Tigeot static void si_set_clk_bypass_mode(struct radeon_device *rdev)
3974c6f73aabSFrançois Tigeot {
3975c6f73aabSFrançois Tigeot u32 tmp, i;
3976c6f73aabSFrançois Tigeot
3977c6f73aabSFrançois Tigeot tmp = RREG32(CG_SPLL_FUNC_CNTL);
3978c6f73aabSFrançois Tigeot tmp |= SPLL_BYPASS_EN;
3979c6f73aabSFrançois Tigeot WREG32(CG_SPLL_FUNC_CNTL, tmp);
3980c6f73aabSFrançois Tigeot
3981c6f73aabSFrançois Tigeot tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
3982c6f73aabSFrançois Tigeot tmp |= SPLL_CTLREQ_CHG;
3983c6f73aabSFrançois Tigeot WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
3984c6f73aabSFrançois Tigeot
3985c6f73aabSFrançois Tigeot for (i = 0; i < rdev->usec_timeout; i++) {
3986c6f73aabSFrançois Tigeot if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS)
3987c6f73aabSFrançois Tigeot break;
3988c6f73aabSFrançois Tigeot udelay(1);
3989c6f73aabSFrançois Tigeot }
3990c6f73aabSFrançois Tigeot
3991c6f73aabSFrançois Tigeot tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
3992c6f73aabSFrançois Tigeot tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE);
3993c6f73aabSFrançois Tigeot WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
3994c6f73aabSFrançois Tigeot
3995c6f73aabSFrançois Tigeot tmp = RREG32(MPLL_CNTL_MODE);
3996c6f73aabSFrançois Tigeot tmp &= ~MPLL_MCLK_SEL;
3997c6f73aabSFrançois Tigeot WREG32(MPLL_CNTL_MODE, tmp);
3998c6f73aabSFrançois Tigeot }
3999c6f73aabSFrançois Tigeot
si_spll_powerdown(struct radeon_device * rdev)4000c6f73aabSFrançois Tigeot static void si_spll_powerdown(struct radeon_device *rdev)
4001c6f73aabSFrançois Tigeot {
4002c6f73aabSFrançois Tigeot u32 tmp;
4003c6f73aabSFrançois Tigeot
4004c6f73aabSFrançois Tigeot tmp = RREG32(SPLL_CNTL_MODE);
4005c6f73aabSFrançois Tigeot tmp |= SPLL_SW_DIR_CONTROL;
4006c6f73aabSFrançois Tigeot WREG32(SPLL_CNTL_MODE, tmp);
4007c6f73aabSFrançois Tigeot
4008c6f73aabSFrançois Tigeot tmp = RREG32(CG_SPLL_FUNC_CNTL);
4009c6f73aabSFrançois Tigeot tmp |= SPLL_RESET;
4010c6f73aabSFrançois Tigeot WREG32(CG_SPLL_FUNC_CNTL, tmp);
4011c6f73aabSFrançois Tigeot
4012c6f73aabSFrançois Tigeot tmp = RREG32(CG_SPLL_FUNC_CNTL);
4013c6f73aabSFrançois Tigeot tmp |= SPLL_SLEEP;
4014c6f73aabSFrançois Tigeot WREG32(CG_SPLL_FUNC_CNTL, tmp);
4015c6f73aabSFrançois Tigeot
4016c6f73aabSFrançois Tigeot tmp = RREG32(SPLL_CNTL_MODE);
4017c6f73aabSFrançois Tigeot tmp &= ~SPLL_SW_DIR_CONTROL;
4018c6f73aabSFrançois Tigeot WREG32(SPLL_CNTL_MODE, tmp);
4019c6f73aabSFrançois Tigeot }
4020c6f73aabSFrançois Tigeot
si_gpu_pci_config_reset(struct radeon_device * rdev)4021c6f73aabSFrançois Tigeot static void si_gpu_pci_config_reset(struct radeon_device *rdev)
4022c6f73aabSFrançois Tigeot {
4023c6f73aabSFrançois Tigeot struct evergreen_mc_save save;
4024c6f73aabSFrançois Tigeot u32 tmp, i;
4025c6f73aabSFrançois Tigeot
4026c6f73aabSFrançois Tigeot dev_info(rdev->dev, "GPU pci config reset\n");
4027c6f73aabSFrançois Tigeot
4028c6f73aabSFrançois Tigeot /* disable dpm? */
4029c6f73aabSFrançois Tigeot
4030c6f73aabSFrançois Tigeot /* disable cg/pg */
4031c6f73aabSFrançois Tigeot si_fini_pg(rdev);
4032c6f73aabSFrançois Tigeot si_fini_cg(rdev);
4033c6f73aabSFrançois Tigeot
4034c6f73aabSFrançois Tigeot /* Disable CP parsing/prefetching */
4035c6f73aabSFrançois Tigeot WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
4036c6f73aabSFrançois Tigeot /* dma0 */
4037c6f73aabSFrançois Tigeot tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
4038c6f73aabSFrançois Tigeot tmp &= ~DMA_RB_ENABLE;
4039c6f73aabSFrançois Tigeot WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
4040c6f73aabSFrançois Tigeot /* dma1 */
4041c6f73aabSFrançois Tigeot tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
4042c6f73aabSFrançois Tigeot tmp &= ~DMA_RB_ENABLE;
4043c6f73aabSFrançois Tigeot WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
4044c6f73aabSFrançois Tigeot /* XXX other engines? */
4045c6f73aabSFrançois Tigeot
4046c6f73aabSFrançois Tigeot /* halt the rlc, disable cp internal ints */
4047c6f73aabSFrançois Tigeot si_rlc_stop(rdev);
4048c6f73aabSFrançois Tigeot
4049c6f73aabSFrançois Tigeot udelay(50);
4050c6f73aabSFrançois Tigeot
4051c6f73aabSFrançois Tigeot /* disable mem access */
4052c6f73aabSFrançois Tigeot evergreen_mc_stop(rdev, &save);
4053c6f73aabSFrançois Tigeot if (evergreen_mc_wait_for_idle(rdev)) {
4054c6f73aabSFrançois Tigeot dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
4055c6f73aabSFrançois Tigeot }
4056c6f73aabSFrançois Tigeot
4057c6f73aabSFrançois Tigeot /* set mclk/sclk to bypass */
4058c6f73aabSFrançois Tigeot si_set_clk_bypass_mode(rdev);
4059c6f73aabSFrançois Tigeot /* powerdown spll */
4060c6f73aabSFrançois Tigeot si_spll_powerdown(rdev);
4061c6f73aabSFrançois Tigeot /* disable BM */
4062c59a5c48SFrançois Tigeot pci_clear_master(rdev->pdev);
4063c6f73aabSFrançois Tigeot /* reset */
4064c6f73aabSFrançois Tigeot radeon_pci_config_reset(rdev);
4065c6f73aabSFrançois Tigeot /* wait for asic to come out of reset */
4066c6f73aabSFrançois Tigeot for (i = 0; i < rdev->usec_timeout; i++) {
4067c6f73aabSFrançois Tigeot if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
4068c6f73aabSFrançois Tigeot break;
4069c6f73aabSFrançois Tigeot udelay(1);
4070c6f73aabSFrançois Tigeot }
4071c6f73aabSFrançois Tigeot }
4072c6f73aabSFrançois Tigeot
si_asic_reset(struct radeon_device * rdev,bool hard)4073d78d3a22SFrançois Tigeot int si_asic_reset(struct radeon_device *rdev, bool hard)
4074926deccbSFrançois Tigeot {
4075b403bed8SMichael Neumann u32 reset_mask;
4076b403bed8SMichael Neumann
4077d78d3a22SFrançois Tigeot if (hard) {
4078d78d3a22SFrançois Tigeot si_gpu_pci_config_reset(rdev);
4079d78d3a22SFrançois Tigeot return 0;
4080d78d3a22SFrançois Tigeot }
4081d78d3a22SFrançois Tigeot
4082b403bed8SMichael Neumann reset_mask = si_gpu_check_soft_reset(rdev);
4083b403bed8SMichael Neumann
4084b403bed8SMichael Neumann if (reset_mask)
4085b403bed8SMichael Neumann r600_set_bios_scratch_engine_hung(rdev, true);
4086b403bed8SMichael Neumann
4087c6f73aabSFrançois Tigeot /* try soft reset */
4088b403bed8SMichael Neumann si_gpu_soft_reset(rdev, reset_mask);
4089b403bed8SMichael Neumann
4090b403bed8SMichael Neumann reset_mask = si_gpu_check_soft_reset(rdev);
4091b403bed8SMichael Neumann
4092c6f73aabSFrançois Tigeot /* try pci config reset */
4093c6f73aabSFrançois Tigeot if (reset_mask && radeon_hard_reset)
4094c6f73aabSFrançois Tigeot si_gpu_pci_config_reset(rdev);
4095c6f73aabSFrançois Tigeot
4096c6f73aabSFrançois Tigeot reset_mask = si_gpu_check_soft_reset(rdev);
4097c6f73aabSFrançois Tigeot
4098b403bed8SMichael Neumann if (!reset_mask)
4099b403bed8SMichael Neumann r600_set_bios_scratch_engine_hung(rdev, false);
4100b403bed8SMichael Neumann
4101b403bed8SMichael Neumann return 0;
4102b403bed8SMichael Neumann }
4103b403bed8SMichael Neumann
4104b403bed8SMichael Neumann /**
4105b403bed8SMichael Neumann * si_gfx_is_lockup - Check if the GFX engine is locked up
4106b403bed8SMichael Neumann *
4107b403bed8SMichael Neumann * @rdev: radeon_device pointer
4108b403bed8SMichael Neumann * @ring: radeon_ring structure holding ring information
4109b403bed8SMichael Neumann *
4110b403bed8SMichael Neumann * Check if the GFX engine is locked up.
4111b403bed8SMichael Neumann * Returns true if the engine appears to be locked up, false if not.
4112b403bed8SMichael Neumann */
si_gfx_is_lockup(struct radeon_device * rdev,struct radeon_ring * ring)4113b403bed8SMichael Neumann bool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
4114b403bed8SMichael Neumann {
4115b403bed8SMichael Neumann u32 reset_mask = si_gpu_check_soft_reset(rdev);
4116b403bed8SMichael Neumann
4117b403bed8SMichael Neumann if (!(reset_mask & (RADEON_RESET_GFX |
4118926deccbSFrançois Tigeot RADEON_RESET_COMPUTE |
4119b403bed8SMichael Neumann RADEON_RESET_CP))) {
4120c6f73aabSFrançois Tigeot radeon_ring_lockup_update(rdev, ring);
4121b403bed8SMichael Neumann return false;
4122b403bed8SMichael Neumann }
4123b403bed8SMichael Neumann return radeon_ring_test_lockup(rdev, ring);
4124b403bed8SMichael Neumann }
4125b403bed8SMichael Neumann
4126926deccbSFrançois Tigeot /* MC */
si_mc_program(struct radeon_device * rdev)4127926deccbSFrançois Tigeot static void si_mc_program(struct radeon_device *rdev)
4128926deccbSFrançois Tigeot {
4129926deccbSFrançois Tigeot struct evergreen_mc_save save;
4130926deccbSFrançois Tigeot u32 tmp;
4131926deccbSFrançois Tigeot int i, j;
4132926deccbSFrançois Tigeot
4133926deccbSFrançois Tigeot /* Initialize HDP */
4134926deccbSFrançois Tigeot for (i = 0, j = 0; i < 32; i++, j += 0x18) {
4135926deccbSFrançois Tigeot WREG32((0x2c14 + j), 0x00000000);
4136926deccbSFrançois Tigeot WREG32((0x2c18 + j), 0x00000000);
4137926deccbSFrançois Tigeot WREG32((0x2c1c + j), 0x00000000);
4138926deccbSFrançois Tigeot WREG32((0x2c20 + j), 0x00000000);
4139926deccbSFrançois Tigeot WREG32((0x2c24 + j), 0x00000000);
4140926deccbSFrançois Tigeot }
4141926deccbSFrançois Tigeot WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
4142926deccbSFrançois Tigeot
4143926deccbSFrançois Tigeot evergreen_mc_stop(rdev, &save);
4144926deccbSFrançois Tigeot if (radeon_mc_wait_for_idle(rdev)) {
4145926deccbSFrançois Tigeot dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
4146926deccbSFrançois Tigeot }
4147f43cf1b1SMichael Neumann if (!ASIC_IS_NODCE(rdev))
4148926deccbSFrançois Tigeot /* Lockout access through VGA aperture*/
4149926deccbSFrançois Tigeot WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
4150926deccbSFrançois Tigeot /* Update configuration */
4151926deccbSFrançois Tigeot WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
4152926deccbSFrançois Tigeot rdev->mc.vram_start >> 12);
4153926deccbSFrançois Tigeot WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
4154926deccbSFrançois Tigeot rdev->mc.vram_end >> 12);
4155926deccbSFrançois Tigeot WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
4156926deccbSFrançois Tigeot rdev->vram_scratch.gpu_addr >> 12);
4157926deccbSFrançois Tigeot tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
4158926deccbSFrançois Tigeot tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
4159926deccbSFrançois Tigeot WREG32(MC_VM_FB_LOCATION, tmp);
4160926deccbSFrançois Tigeot /* XXX double check these! */
4161926deccbSFrançois Tigeot WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
4162926deccbSFrançois Tigeot WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
4163926deccbSFrançois Tigeot WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
4164926deccbSFrançois Tigeot WREG32(MC_VM_AGP_BASE, 0);
4165926deccbSFrançois Tigeot WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
4166926deccbSFrançois Tigeot WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
4167926deccbSFrançois Tigeot if (radeon_mc_wait_for_idle(rdev)) {
4168926deccbSFrançois Tigeot dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
4169926deccbSFrançois Tigeot }
4170926deccbSFrançois Tigeot evergreen_mc_resume(rdev, &save);
4171f43cf1b1SMichael Neumann if (!ASIC_IS_NODCE(rdev)) {
4172926deccbSFrançois Tigeot /* we need to own VRAM, so turn off the VGA renderer here
4173926deccbSFrançois Tigeot * to stop it overwriting our objects */
4174926deccbSFrançois Tigeot rv515_vga_render_disable(rdev);
4175926deccbSFrançois Tigeot }
4176926deccbSFrançois Tigeot }
4177926deccbSFrançois Tigeot
si_vram_gtt_location(struct radeon_device * rdev,struct radeon_mc * mc)417857e252bfSMichael Neumann void si_vram_gtt_location(struct radeon_device *rdev,
4179926deccbSFrançois Tigeot struct radeon_mc *mc)
4180926deccbSFrançois Tigeot {
4181926deccbSFrançois Tigeot if (mc->mc_vram_size > 0xFFC0000000ULL) {
4182926deccbSFrançois Tigeot /* leave room for at least 1024M GTT */
4183926deccbSFrançois Tigeot dev_warn(rdev->dev, "limiting VRAM\n");
4184926deccbSFrançois Tigeot mc->real_vram_size = 0xFFC0000000ULL;
4185926deccbSFrançois Tigeot mc->mc_vram_size = 0xFFC0000000ULL;
4186926deccbSFrançois Tigeot }
4187f43cf1b1SMichael Neumann radeon_vram_location(rdev, &rdev->mc, 0);
4188926deccbSFrançois Tigeot rdev->mc.gtt_base_align = 0;
4189f43cf1b1SMichael Neumann radeon_gtt_location(rdev, mc);
4190926deccbSFrançois Tigeot }
4191926deccbSFrançois Tigeot
si_mc_init(struct radeon_device * rdev)4192926deccbSFrançois Tigeot static int si_mc_init(struct radeon_device *rdev)
4193926deccbSFrançois Tigeot {
4194926deccbSFrançois Tigeot u32 tmp;
4195926deccbSFrançois Tigeot int chansize, numchan;
4196926deccbSFrançois Tigeot
4197926deccbSFrançois Tigeot /* Get VRAM informations */
4198926deccbSFrançois Tigeot rdev->mc.vram_is_ddr = true;
4199926deccbSFrançois Tigeot tmp = RREG32(MC_ARB_RAMCFG);
4200926deccbSFrançois Tigeot if (tmp & CHANSIZE_OVERRIDE) {
4201926deccbSFrançois Tigeot chansize = 16;
4202926deccbSFrançois Tigeot } else if (tmp & CHANSIZE_MASK) {
4203926deccbSFrançois Tigeot chansize = 64;
4204926deccbSFrançois Tigeot } else {
4205926deccbSFrançois Tigeot chansize = 32;
4206926deccbSFrançois Tigeot }
4207926deccbSFrançois Tigeot tmp = RREG32(MC_SHARED_CHMAP);
4208926deccbSFrançois Tigeot switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
4209926deccbSFrançois Tigeot case 0:
4210926deccbSFrançois Tigeot default:
4211926deccbSFrançois Tigeot numchan = 1;
4212926deccbSFrançois Tigeot break;
4213926deccbSFrançois Tigeot case 1:
4214926deccbSFrançois Tigeot numchan = 2;
4215926deccbSFrançois Tigeot break;
4216926deccbSFrançois Tigeot case 2:
4217926deccbSFrançois Tigeot numchan = 4;
4218926deccbSFrançois Tigeot break;
4219926deccbSFrançois Tigeot case 3:
4220926deccbSFrançois Tigeot numchan = 8;
4221926deccbSFrançois Tigeot break;
4222926deccbSFrançois Tigeot case 4:
4223926deccbSFrançois Tigeot numchan = 3;
4224926deccbSFrançois Tigeot break;
4225926deccbSFrançois Tigeot case 5:
4226926deccbSFrançois Tigeot numchan = 6;
4227926deccbSFrançois Tigeot break;
4228926deccbSFrançois Tigeot case 6:
4229926deccbSFrançois Tigeot numchan = 10;
4230926deccbSFrançois Tigeot break;
4231926deccbSFrançois Tigeot case 7:
4232926deccbSFrançois Tigeot numchan = 12;
4233926deccbSFrançois Tigeot break;
4234926deccbSFrançois Tigeot case 8:
4235926deccbSFrançois Tigeot numchan = 16;
4236926deccbSFrançois Tigeot break;
4237926deccbSFrançois Tigeot }
4238926deccbSFrançois Tigeot rdev->mc.vram_width = numchan * chansize;
4239926deccbSFrançois Tigeot /* Could aper size report 0 ? */
42404a26d795SImre Vadasz rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
42414a26d795SImre Vadasz rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
4242926deccbSFrançois Tigeot /* size in MB on si */
4243c6f73aabSFrançois Tigeot tmp = RREG32(CONFIG_MEMSIZE);
4244c6f73aabSFrançois Tigeot /* some boards may have garbage in the upper 16 bits */
4245c6f73aabSFrançois Tigeot if (tmp & 0xffff0000) {
4246c6f73aabSFrançois Tigeot DRM_INFO("Probable bad vram size: 0x%08x\n", tmp);
4247c6f73aabSFrançois Tigeot if (tmp & 0xffff)
4248c6f73aabSFrançois Tigeot tmp &= 0xffff;
4249c6f73aabSFrançois Tigeot }
4250c6f73aabSFrançois Tigeot rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL;
4251c6f73aabSFrançois Tigeot rdev->mc.real_vram_size = rdev->mc.mc_vram_size;
4252926deccbSFrançois Tigeot rdev->mc.visible_vram_size = rdev->mc.aper_size;
4253926deccbSFrançois Tigeot si_vram_gtt_location(rdev, &rdev->mc);
4254926deccbSFrançois Tigeot radeon_update_bandwidth_info(rdev);
4255926deccbSFrançois Tigeot
4256926deccbSFrançois Tigeot return 0;
4257926deccbSFrançois Tigeot }
4258926deccbSFrançois Tigeot
4259926deccbSFrançois Tigeot /*
4260926deccbSFrançois Tigeot * GART
4261926deccbSFrançois Tigeot */
si_pcie_gart_tlb_flush(struct radeon_device * rdev)4262926deccbSFrançois Tigeot void si_pcie_gart_tlb_flush(struct radeon_device *rdev)
4263926deccbSFrançois Tigeot {
4264926deccbSFrançois Tigeot /* flush hdp cache */
4265926deccbSFrançois Tigeot WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
4266926deccbSFrançois Tigeot
4267926deccbSFrançois Tigeot /* bits 0-15 are the VM contexts0-15 */
4268926deccbSFrançois Tigeot WREG32(VM_INVALIDATE_REQUEST, 1);
4269926deccbSFrançois Tigeot }
4270926deccbSFrançois Tigeot
si_pcie_gart_enable(struct radeon_device * rdev)4271926deccbSFrançois Tigeot static int si_pcie_gart_enable(struct radeon_device *rdev)
4272926deccbSFrançois Tigeot {
4273926deccbSFrançois Tigeot int r, i;
4274926deccbSFrançois Tigeot
4275926deccbSFrançois Tigeot if (rdev->gart.robj == NULL) {
4276926deccbSFrançois Tigeot dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
4277926deccbSFrançois Tigeot return -EINVAL;
4278926deccbSFrançois Tigeot }
4279926deccbSFrançois Tigeot r = radeon_gart_table_vram_pin(rdev);
4280926deccbSFrançois Tigeot if (r)
4281926deccbSFrançois Tigeot return r;
4282926deccbSFrançois Tigeot /* Setup TLB control */
4283926deccbSFrançois Tigeot WREG32(MC_VM_MX_L1_TLB_CNTL,
4284926deccbSFrançois Tigeot (0xA << 7) |
4285926deccbSFrançois Tigeot ENABLE_L1_TLB |
4286c6f73aabSFrançois Tigeot ENABLE_L1_FRAGMENT_PROCESSING |
4287926deccbSFrançois Tigeot SYSTEM_ACCESS_MODE_NOT_IN_SYS |
4288926deccbSFrançois Tigeot ENABLE_ADVANCED_DRIVER_MODEL |
4289926deccbSFrançois Tigeot SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
4290926deccbSFrançois Tigeot /* Setup L2 cache */
4291926deccbSFrançois Tigeot WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
4292c6f73aabSFrançois Tigeot ENABLE_L2_FRAGMENT_PROCESSING |
4293926deccbSFrançois Tigeot ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
4294926deccbSFrançois Tigeot ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
4295926deccbSFrançois Tigeot EFFECTIVE_L2_QUEUE_SIZE(7) |
4296926deccbSFrançois Tigeot CONTEXT1_IDENTITY_ACCESS_MODE(1));
4297926deccbSFrançois Tigeot WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
4298926deccbSFrançois Tigeot WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
4299c6f73aabSFrançois Tigeot BANK_SELECT(4) |
4300c6f73aabSFrançois Tigeot L2_CACHE_BIGK_FRAGMENT_SIZE(4));
4301926deccbSFrançois Tigeot /* setup context0 */
4302926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
4303926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
4304926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
4305926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
4306926deccbSFrançois Tigeot (u32)(rdev->dummy_page.addr >> 12));
4307926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL2, 0);
4308926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
4309926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_DEFAULT));
4310926deccbSFrançois Tigeot
4311926deccbSFrançois Tigeot WREG32(0x15D4, 0);
4312926deccbSFrançois Tigeot WREG32(0x15D8, 0);
4313926deccbSFrançois Tigeot WREG32(0x15DC, 0);
4314926deccbSFrançois Tigeot
4315926deccbSFrançois Tigeot /* empty context1-15 */
4316926deccbSFrançois Tigeot /* set vm size, must be a multiple of 4 */
4317926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
4318c59a5c48SFrançois Tigeot WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
4319926deccbSFrançois Tigeot /* Assign the pt base to something valid for now; the pts used for
4320926deccbSFrançois Tigeot * the VMs are determined by the application and setup and assigned
4321926deccbSFrançois Tigeot * on the fly in the vm part of radeon_gart.c
4322926deccbSFrançois Tigeot */
4323926deccbSFrançois Tigeot for (i = 1; i < 16; i++) {
4324926deccbSFrançois Tigeot if (i < 8)
4325926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
4326c6f73aabSFrançois Tigeot rdev->vm_manager.saved_table_addr[i]);
4327926deccbSFrançois Tigeot else
4328926deccbSFrançois Tigeot WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
4329c6f73aabSFrançois Tigeot rdev->vm_manager.saved_table_addr[i]);
4330926deccbSFrançois Tigeot }
4331926deccbSFrançois Tigeot
4332926deccbSFrançois Tigeot /* enable context1-15 */
4333926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
4334926deccbSFrançois Tigeot (u32)(rdev->dummy_page.addr >> 12));
4335926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL2, 4);
4336926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
4337c6f73aabSFrançois Tigeot PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
4338926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4339926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
4340926deccbSFrançois Tigeot DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4341926deccbSFrançois Tigeot DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
4342926deccbSFrançois Tigeot PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
4343926deccbSFrançois Tigeot PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
4344926deccbSFrançois Tigeot VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
4345926deccbSFrançois Tigeot VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
4346926deccbSFrançois Tigeot READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
4347926deccbSFrançois Tigeot READ_PROTECTION_FAULT_ENABLE_DEFAULT |
4348926deccbSFrançois Tigeot WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4349926deccbSFrançois Tigeot WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
4350926deccbSFrançois Tigeot
4351926deccbSFrançois Tigeot si_pcie_gart_tlb_flush(rdev);
4352926deccbSFrançois Tigeot DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
4353926deccbSFrançois Tigeot (unsigned)(rdev->mc.gtt_size >> 20),
4354926deccbSFrançois Tigeot (unsigned long long)rdev->gart.table_addr);
4355926deccbSFrançois Tigeot rdev->gart.ready = true;
4356926deccbSFrançois Tigeot return 0;
4357926deccbSFrançois Tigeot }
4358926deccbSFrançois Tigeot
si_pcie_gart_disable(struct radeon_device * rdev)4359926deccbSFrançois Tigeot static void si_pcie_gart_disable(struct radeon_device *rdev)
4360926deccbSFrançois Tigeot {
4361c6f73aabSFrançois Tigeot unsigned i;
4362c6f73aabSFrançois Tigeot
4363c6f73aabSFrançois Tigeot for (i = 1; i < 16; ++i) {
4364c6f73aabSFrançois Tigeot uint32_t reg;
4365c6f73aabSFrançois Tigeot if (i < 8)
4366c6f73aabSFrançois Tigeot reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2);
4367c6f73aabSFrançois Tigeot else
4368c6f73aabSFrançois Tigeot reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2);
4369c6f73aabSFrançois Tigeot rdev->vm_manager.saved_table_addr[i] = RREG32(reg);
4370c6f73aabSFrançois Tigeot }
4371c6f73aabSFrançois Tigeot
4372926deccbSFrançois Tigeot /* Disable all tables */
4373926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL, 0);
4374926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL, 0);
4375926deccbSFrançois Tigeot /* Setup TLB control */
4376926deccbSFrançois Tigeot WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS |
4377926deccbSFrançois Tigeot SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
4378926deccbSFrançois Tigeot /* Setup L2 cache */
4379926deccbSFrançois Tigeot WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
4380926deccbSFrançois Tigeot ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
4381926deccbSFrançois Tigeot EFFECTIVE_L2_QUEUE_SIZE(7) |
4382926deccbSFrançois Tigeot CONTEXT1_IDENTITY_ACCESS_MODE(1));
4383926deccbSFrançois Tigeot WREG32(VM_L2_CNTL2, 0);
4384926deccbSFrançois Tigeot WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
4385926deccbSFrançois Tigeot L2_CACHE_BIGK_FRAGMENT_SIZE(0));
4386926deccbSFrançois Tigeot radeon_gart_table_vram_unpin(rdev);
4387926deccbSFrançois Tigeot }
4388926deccbSFrançois Tigeot
si_pcie_gart_fini(struct radeon_device * rdev)4389926deccbSFrançois Tigeot static void si_pcie_gart_fini(struct radeon_device *rdev)
4390926deccbSFrançois Tigeot {
4391926deccbSFrançois Tigeot si_pcie_gart_disable(rdev);
4392926deccbSFrançois Tigeot radeon_gart_table_vram_free(rdev);
4393926deccbSFrançois Tigeot radeon_gart_fini(rdev);
4394926deccbSFrançois Tigeot }
4395926deccbSFrançois Tigeot
4396926deccbSFrançois Tigeot /* vm parser */
si_vm_reg_valid(u32 reg)4397926deccbSFrançois Tigeot static bool si_vm_reg_valid(u32 reg)
4398926deccbSFrançois Tigeot {
4399926deccbSFrançois Tigeot /* context regs are fine */
4400926deccbSFrançois Tigeot if (reg >= 0x28000)
4401926deccbSFrançois Tigeot return true;
4402926deccbSFrançois Tigeot
4403d78d3a22SFrançois Tigeot /* shader regs are also fine */
4404d78d3a22SFrançois Tigeot if (reg >= 0xB000 && reg < 0xC000)
4405d78d3a22SFrançois Tigeot return true;
4406d78d3a22SFrançois Tigeot
4407926deccbSFrançois Tigeot /* check config regs */
4408926deccbSFrançois Tigeot switch (reg) {
4409926deccbSFrançois Tigeot case GRBM_GFX_INDEX:
4410926deccbSFrançois Tigeot case CP_STRMOUT_CNTL:
4411926deccbSFrançois Tigeot case VGT_VTX_VECT_EJECT_REG:
4412926deccbSFrançois Tigeot case VGT_CACHE_INVALIDATION:
4413926deccbSFrançois Tigeot case VGT_ESGS_RING_SIZE:
4414926deccbSFrançois Tigeot case VGT_GSVS_RING_SIZE:
4415926deccbSFrançois Tigeot case VGT_GS_VERTEX_REUSE:
4416926deccbSFrançois Tigeot case VGT_PRIMITIVE_TYPE:
4417926deccbSFrançois Tigeot case VGT_INDEX_TYPE:
4418926deccbSFrançois Tigeot case VGT_NUM_INDICES:
4419926deccbSFrançois Tigeot case VGT_NUM_INSTANCES:
4420926deccbSFrançois Tigeot case VGT_TF_RING_SIZE:
4421926deccbSFrançois Tigeot case VGT_HS_OFFCHIP_PARAM:
4422926deccbSFrançois Tigeot case VGT_TF_MEMORY_BASE:
4423926deccbSFrançois Tigeot case PA_CL_ENHANCE:
4424926deccbSFrançois Tigeot case PA_SU_LINE_STIPPLE_VALUE:
4425926deccbSFrançois Tigeot case PA_SC_LINE_STIPPLE_STATE:
4426926deccbSFrançois Tigeot case PA_SC_ENHANCE:
4427926deccbSFrançois Tigeot case SQC_CACHES:
4428926deccbSFrançois Tigeot case SPI_STATIC_THREAD_MGMT_1:
4429926deccbSFrançois Tigeot case SPI_STATIC_THREAD_MGMT_2:
4430926deccbSFrançois Tigeot case SPI_STATIC_THREAD_MGMT_3:
4431926deccbSFrançois Tigeot case SPI_PS_MAX_WAVE_ID:
4432926deccbSFrançois Tigeot case SPI_CONFIG_CNTL:
4433926deccbSFrançois Tigeot case SPI_CONFIG_CNTL_1:
4434926deccbSFrançois Tigeot case TA_CNTL_AUX:
44351dedbd3bSFrançois Tigeot case TA_CS_BC_BASE_ADDR:
4436926deccbSFrançois Tigeot return true;
4437926deccbSFrançois Tigeot default:
4438926deccbSFrançois Tigeot DRM_ERROR("Invalid register 0x%x in CS\n", reg);
4439926deccbSFrançois Tigeot return false;
4440926deccbSFrançois Tigeot }
4441926deccbSFrançois Tigeot }
4442926deccbSFrançois Tigeot
si_vm_packet3_ce_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4443926deccbSFrançois Tigeot static int si_vm_packet3_ce_check(struct radeon_device *rdev,
4444926deccbSFrançois Tigeot u32 *ib, struct radeon_cs_packet *pkt)
4445926deccbSFrançois Tigeot {
4446926deccbSFrançois Tigeot switch (pkt->opcode) {
4447926deccbSFrançois Tigeot case PACKET3_NOP:
4448926deccbSFrançois Tigeot case PACKET3_SET_BASE:
4449926deccbSFrançois Tigeot case PACKET3_SET_CE_DE_COUNTERS:
4450926deccbSFrançois Tigeot case PACKET3_LOAD_CONST_RAM:
4451926deccbSFrançois Tigeot case PACKET3_WRITE_CONST_RAM:
4452926deccbSFrançois Tigeot case PACKET3_WRITE_CONST_RAM_OFFSET:
4453926deccbSFrançois Tigeot case PACKET3_DUMP_CONST_RAM:
4454926deccbSFrançois Tigeot case PACKET3_INCREMENT_CE_COUNTER:
4455926deccbSFrançois Tigeot case PACKET3_WAIT_ON_DE_COUNTER:
4456926deccbSFrançois Tigeot case PACKET3_CE_WRITE:
4457926deccbSFrançois Tigeot break;
4458926deccbSFrançois Tigeot default:
4459926deccbSFrançois Tigeot DRM_ERROR("Invalid CE packet3: 0x%x\n", pkt->opcode);
4460926deccbSFrançois Tigeot return -EINVAL;
4461926deccbSFrançois Tigeot }
4462926deccbSFrançois Tigeot return 0;
4463926deccbSFrançois Tigeot }
4464926deccbSFrançois Tigeot
si_vm_packet3_cp_dma_check(u32 * ib,u32 idx)44654cd92098Szrj static int si_vm_packet3_cp_dma_check(u32 *ib, u32 idx)
44664cd92098Szrj {
44674cd92098Szrj u32 start_reg, reg, i;
44684cd92098Szrj u32 command = ib[idx + 4];
44694cd92098Szrj u32 info = ib[idx + 1];
44704cd92098Szrj u32 idx_value = ib[idx];
44714cd92098Szrj if (command & PACKET3_CP_DMA_CMD_SAS) {
44724cd92098Szrj /* src address space is register */
44734cd92098Szrj if (((info & 0x60000000) >> 29) == 0) {
44744cd92098Szrj start_reg = idx_value << 2;
44754cd92098Szrj if (command & PACKET3_CP_DMA_CMD_SAIC) {
44764cd92098Szrj reg = start_reg;
44774cd92098Szrj if (!si_vm_reg_valid(reg)) {
44784cd92098Szrj DRM_ERROR("CP DMA Bad SRC register\n");
44794cd92098Szrj return -EINVAL;
44804cd92098Szrj }
44814cd92098Szrj } else {
44824cd92098Szrj for (i = 0; i < (command & 0x1fffff); i++) {
44834cd92098Szrj reg = start_reg + (4 * i);
44844cd92098Szrj if (!si_vm_reg_valid(reg)) {
44854cd92098Szrj DRM_ERROR("CP DMA Bad SRC register\n");
44864cd92098Szrj return -EINVAL;
44874cd92098Szrj }
44884cd92098Szrj }
44894cd92098Szrj }
44904cd92098Szrj }
44914cd92098Szrj }
44924cd92098Szrj if (command & PACKET3_CP_DMA_CMD_DAS) {
44934cd92098Szrj /* dst address space is register */
44944cd92098Szrj if (((info & 0x00300000) >> 20) == 0) {
44954cd92098Szrj start_reg = ib[idx + 2];
44964cd92098Szrj if (command & PACKET3_CP_DMA_CMD_DAIC) {
44974cd92098Szrj reg = start_reg;
44984cd92098Szrj if (!si_vm_reg_valid(reg)) {
44994cd92098Szrj DRM_ERROR("CP DMA Bad DST register\n");
45004cd92098Szrj return -EINVAL;
45014cd92098Szrj }
45024cd92098Szrj } else {
45034cd92098Szrj for (i = 0; i < (command & 0x1fffff); i++) {
45044cd92098Szrj reg = start_reg + (4 * i);
45054cd92098Szrj if (!si_vm_reg_valid(reg)) {
45064cd92098Szrj DRM_ERROR("CP DMA Bad DST register\n");
45074cd92098Szrj return -EINVAL;
45084cd92098Szrj }
45094cd92098Szrj }
45104cd92098Szrj }
45114cd92098Szrj }
45124cd92098Szrj }
45134cd92098Szrj return 0;
45144cd92098Szrj }
45154cd92098Szrj
si_vm_packet3_gfx_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4516926deccbSFrançois Tigeot static int si_vm_packet3_gfx_check(struct radeon_device *rdev,
4517926deccbSFrançois Tigeot u32 *ib, struct radeon_cs_packet *pkt)
4518926deccbSFrançois Tigeot {
45194cd92098Szrj int r;
4520926deccbSFrançois Tigeot u32 idx = pkt->idx + 1;
4521926deccbSFrançois Tigeot u32 idx_value = ib[idx];
4522926deccbSFrançois Tigeot u32 start_reg, end_reg, reg, i;
4523926deccbSFrançois Tigeot
4524926deccbSFrançois Tigeot switch (pkt->opcode) {
4525926deccbSFrançois Tigeot case PACKET3_NOP:
4526926deccbSFrançois Tigeot case PACKET3_SET_BASE:
4527926deccbSFrançois Tigeot case PACKET3_CLEAR_STATE:
4528926deccbSFrançois Tigeot case PACKET3_INDEX_BUFFER_SIZE:
4529926deccbSFrançois Tigeot case PACKET3_DISPATCH_DIRECT:
4530926deccbSFrançois Tigeot case PACKET3_DISPATCH_INDIRECT:
4531926deccbSFrançois Tigeot case PACKET3_ALLOC_GDS:
4532926deccbSFrançois Tigeot case PACKET3_WRITE_GDS_RAM:
4533926deccbSFrançois Tigeot case PACKET3_ATOMIC_GDS:
4534926deccbSFrançois Tigeot case PACKET3_ATOMIC:
4535926deccbSFrançois Tigeot case PACKET3_OCCLUSION_QUERY:
4536926deccbSFrançois Tigeot case PACKET3_SET_PREDICATION:
4537926deccbSFrançois Tigeot case PACKET3_COND_EXEC:
4538926deccbSFrançois Tigeot case PACKET3_PRED_EXEC:
4539926deccbSFrançois Tigeot case PACKET3_DRAW_INDIRECT:
4540926deccbSFrançois Tigeot case PACKET3_DRAW_INDEX_INDIRECT:
4541926deccbSFrançois Tigeot case PACKET3_INDEX_BASE:
4542926deccbSFrançois Tigeot case PACKET3_DRAW_INDEX_2:
4543926deccbSFrançois Tigeot case PACKET3_CONTEXT_CONTROL:
4544926deccbSFrançois Tigeot case PACKET3_INDEX_TYPE:
4545926deccbSFrançois Tigeot case PACKET3_DRAW_INDIRECT_MULTI:
4546926deccbSFrançois Tigeot case PACKET3_DRAW_INDEX_AUTO:
4547926deccbSFrançois Tigeot case PACKET3_DRAW_INDEX_IMMD:
4548926deccbSFrançois Tigeot case PACKET3_NUM_INSTANCES:
4549926deccbSFrançois Tigeot case PACKET3_DRAW_INDEX_MULTI_AUTO:
4550926deccbSFrançois Tigeot case PACKET3_STRMOUT_BUFFER_UPDATE:
4551926deccbSFrançois Tigeot case PACKET3_DRAW_INDEX_OFFSET_2:
4552926deccbSFrançois Tigeot case PACKET3_DRAW_INDEX_MULTI_ELEMENT:
4553926deccbSFrançois Tigeot case PACKET3_DRAW_INDEX_INDIRECT_MULTI:
4554926deccbSFrançois Tigeot case PACKET3_MPEG_INDEX:
4555926deccbSFrançois Tigeot case PACKET3_WAIT_REG_MEM:
4556926deccbSFrançois Tigeot case PACKET3_MEM_WRITE:
4557926deccbSFrançois Tigeot case PACKET3_PFP_SYNC_ME:
4558926deccbSFrançois Tigeot case PACKET3_SURFACE_SYNC:
4559926deccbSFrançois Tigeot case PACKET3_EVENT_WRITE:
4560926deccbSFrançois Tigeot case PACKET3_EVENT_WRITE_EOP:
4561926deccbSFrançois Tigeot case PACKET3_EVENT_WRITE_EOS:
4562926deccbSFrançois Tigeot case PACKET3_SET_CONTEXT_REG:
4563926deccbSFrançois Tigeot case PACKET3_SET_CONTEXT_REG_INDIRECT:
4564926deccbSFrançois Tigeot case PACKET3_SET_SH_REG:
4565926deccbSFrançois Tigeot case PACKET3_SET_SH_REG_OFFSET:
4566926deccbSFrançois Tigeot case PACKET3_INCREMENT_DE_COUNTER:
4567926deccbSFrançois Tigeot case PACKET3_WAIT_ON_CE_COUNTER:
4568926deccbSFrançois Tigeot case PACKET3_WAIT_ON_AVAIL_BUFFER:
4569926deccbSFrançois Tigeot case PACKET3_ME_WRITE:
4570926deccbSFrançois Tigeot break;
4571926deccbSFrançois Tigeot case PACKET3_COPY_DATA:
4572926deccbSFrançois Tigeot if ((idx_value & 0xf00) == 0) {
4573926deccbSFrançois Tigeot reg = ib[idx + 3] * 4;
4574926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4575926deccbSFrançois Tigeot return -EINVAL;
4576926deccbSFrançois Tigeot }
4577926deccbSFrançois Tigeot break;
4578926deccbSFrançois Tigeot case PACKET3_WRITE_DATA:
4579926deccbSFrançois Tigeot if ((idx_value & 0xf00) == 0) {
4580926deccbSFrançois Tigeot start_reg = ib[idx + 1] * 4;
4581926deccbSFrançois Tigeot if (idx_value & 0x10000) {
4582926deccbSFrançois Tigeot if (!si_vm_reg_valid(start_reg))
4583926deccbSFrançois Tigeot return -EINVAL;
4584926deccbSFrançois Tigeot } else {
4585926deccbSFrançois Tigeot for (i = 0; i < (pkt->count - 2); i++) {
4586926deccbSFrançois Tigeot reg = start_reg + (4 * i);
4587926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4588926deccbSFrançois Tigeot return -EINVAL;
4589926deccbSFrançois Tigeot }
4590926deccbSFrançois Tigeot }
4591926deccbSFrançois Tigeot }
4592926deccbSFrançois Tigeot break;
4593926deccbSFrançois Tigeot case PACKET3_COND_WRITE:
4594926deccbSFrançois Tigeot if (idx_value & 0x100) {
4595926deccbSFrançois Tigeot reg = ib[idx + 5] * 4;
4596926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4597926deccbSFrançois Tigeot return -EINVAL;
4598926deccbSFrançois Tigeot }
4599926deccbSFrançois Tigeot break;
4600926deccbSFrançois Tigeot case PACKET3_COPY_DW:
4601926deccbSFrançois Tigeot if (idx_value & 0x2) {
4602926deccbSFrançois Tigeot reg = ib[idx + 3] * 4;
4603926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4604926deccbSFrançois Tigeot return -EINVAL;
4605926deccbSFrançois Tigeot }
4606926deccbSFrançois Tigeot break;
4607926deccbSFrançois Tigeot case PACKET3_SET_CONFIG_REG:
4608926deccbSFrançois Tigeot start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
4609926deccbSFrançois Tigeot end_reg = 4 * pkt->count + start_reg - 4;
4610926deccbSFrançois Tigeot if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
4611926deccbSFrançois Tigeot (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
4612926deccbSFrançois Tigeot (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
4613926deccbSFrançois Tigeot DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
4614926deccbSFrançois Tigeot return -EINVAL;
4615926deccbSFrançois Tigeot }
4616926deccbSFrançois Tigeot for (i = 0; i < pkt->count; i++) {
4617926deccbSFrançois Tigeot reg = start_reg + (4 * i);
4618926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4619926deccbSFrançois Tigeot return -EINVAL;
4620926deccbSFrançois Tigeot }
4621926deccbSFrançois Tigeot break;
4622926deccbSFrançois Tigeot case PACKET3_CP_DMA:
46234cd92098Szrj r = si_vm_packet3_cp_dma_check(ib, idx);
46244cd92098Szrj if (r)
46254cd92098Szrj return r;
4626926deccbSFrançois Tigeot break;
4627926deccbSFrançois Tigeot default:
4628926deccbSFrançois Tigeot DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode);
4629926deccbSFrançois Tigeot return -EINVAL;
4630926deccbSFrançois Tigeot }
4631926deccbSFrançois Tigeot return 0;
4632926deccbSFrançois Tigeot }
4633926deccbSFrançois Tigeot
si_vm_packet3_compute_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4634926deccbSFrançois Tigeot static int si_vm_packet3_compute_check(struct radeon_device *rdev,
4635926deccbSFrançois Tigeot u32 *ib, struct radeon_cs_packet *pkt)
4636926deccbSFrançois Tigeot {
46374cd92098Szrj int r;
4638926deccbSFrançois Tigeot u32 idx = pkt->idx + 1;
4639926deccbSFrançois Tigeot u32 idx_value = ib[idx];
4640926deccbSFrançois Tigeot u32 start_reg, reg, i;
4641926deccbSFrançois Tigeot
4642926deccbSFrançois Tigeot switch (pkt->opcode) {
4643926deccbSFrançois Tigeot case PACKET3_NOP:
4644926deccbSFrançois Tigeot case PACKET3_SET_BASE:
4645926deccbSFrançois Tigeot case PACKET3_CLEAR_STATE:
4646926deccbSFrançois Tigeot case PACKET3_DISPATCH_DIRECT:
4647926deccbSFrançois Tigeot case PACKET3_DISPATCH_INDIRECT:
4648926deccbSFrançois Tigeot case PACKET3_ALLOC_GDS:
4649926deccbSFrançois Tigeot case PACKET3_WRITE_GDS_RAM:
4650926deccbSFrançois Tigeot case PACKET3_ATOMIC_GDS:
4651926deccbSFrançois Tigeot case PACKET3_ATOMIC:
4652926deccbSFrançois Tigeot case PACKET3_OCCLUSION_QUERY:
4653926deccbSFrançois Tigeot case PACKET3_SET_PREDICATION:
4654926deccbSFrançois Tigeot case PACKET3_COND_EXEC:
4655926deccbSFrançois Tigeot case PACKET3_PRED_EXEC:
4656926deccbSFrançois Tigeot case PACKET3_CONTEXT_CONTROL:
4657926deccbSFrançois Tigeot case PACKET3_STRMOUT_BUFFER_UPDATE:
4658926deccbSFrançois Tigeot case PACKET3_WAIT_REG_MEM:
4659926deccbSFrançois Tigeot case PACKET3_MEM_WRITE:
4660926deccbSFrançois Tigeot case PACKET3_PFP_SYNC_ME:
4661926deccbSFrançois Tigeot case PACKET3_SURFACE_SYNC:
4662926deccbSFrançois Tigeot case PACKET3_EVENT_WRITE:
4663926deccbSFrançois Tigeot case PACKET3_EVENT_WRITE_EOP:
4664926deccbSFrançois Tigeot case PACKET3_EVENT_WRITE_EOS:
4665926deccbSFrançois Tigeot case PACKET3_SET_CONTEXT_REG:
4666926deccbSFrançois Tigeot case PACKET3_SET_CONTEXT_REG_INDIRECT:
4667926deccbSFrançois Tigeot case PACKET3_SET_SH_REG:
4668926deccbSFrançois Tigeot case PACKET3_SET_SH_REG_OFFSET:
4669926deccbSFrançois Tigeot case PACKET3_INCREMENT_DE_COUNTER:
4670926deccbSFrançois Tigeot case PACKET3_WAIT_ON_CE_COUNTER:
4671926deccbSFrançois Tigeot case PACKET3_WAIT_ON_AVAIL_BUFFER:
4672926deccbSFrançois Tigeot case PACKET3_ME_WRITE:
4673926deccbSFrançois Tigeot break;
4674926deccbSFrançois Tigeot case PACKET3_COPY_DATA:
4675926deccbSFrançois Tigeot if ((idx_value & 0xf00) == 0) {
4676926deccbSFrançois Tigeot reg = ib[idx + 3] * 4;
4677926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4678926deccbSFrançois Tigeot return -EINVAL;
4679926deccbSFrançois Tigeot }
4680926deccbSFrançois Tigeot break;
4681926deccbSFrançois Tigeot case PACKET3_WRITE_DATA:
4682926deccbSFrançois Tigeot if ((idx_value & 0xf00) == 0) {
4683926deccbSFrançois Tigeot start_reg = ib[idx + 1] * 4;
4684926deccbSFrançois Tigeot if (idx_value & 0x10000) {
4685926deccbSFrançois Tigeot if (!si_vm_reg_valid(start_reg))
4686926deccbSFrançois Tigeot return -EINVAL;
4687926deccbSFrançois Tigeot } else {
4688926deccbSFrançois Tigeot for (i = 0; i < (pkt->count - 2); i++) {
4689926deccbSFrançois Tigeot reg = start_reg + (4 * i);
4690926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4691926deccbSFrançois Tigeot return -EINVAL;
4692926deccbSFrançois Tigeot }
4693926deccbSFrançois Tigeot }
4694926deccbSFrançois Tigeot }
4695926deccbSFrançois Tigeot break;
4696926deccbSFrançois Tigeot case PACKET3_COND_WRITE:
4697926deccbSFrançois Tigeot if (idx_value & 0x100) {
4698926deccbSFrançois Tigeot reg = ib[idx + 5] * 4;
4699926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4700926deccbSFrançois Tigeot return -EINVAL;
4701926deccbSFrançois Tigeot }
4702926deccbSFrançois Tigeot break;
4703926deccbSFrançois Tigeot case PACKET3_COPY_DW:
4704926deccbSFrançois Tigeot if (idx_value & 0x2) {
4705926deccbSFrançois Tigeot reg = ib[idx + 3] * 4;
4706926deccbSFrançois Tigeot if (!si_vm_reg_valid(reg))
4707926deccbSFrançois Tigeot return -EINVAL;
4708926deccbSFrançois Tigeot }
4709926deccbSFrançois Tigeot break;
47104cd92098Szrj case PACKET3_CP_DMA:
47114cd92098Szrj r = si_vm_packet3_cp_dma_check(ib, idx);
47124cd92098Szrj if (r)
47134cd92098Szrj return r;
47144cd92098Szrj break;
4715926deccbSFrançois Tigeot default:
4716926deccbSFrançois Tigeot DRM_ERROR("Invalid Compute packet3: 0x%x\n", pkt->opcode);
4717926deccbSFrançois Tigeot return -EINVAL;
4718926deccbSFrançois Tigeot }
4719926deccbSFrançois Tigeot return 0;
4720926deccbSFrançois Tigeot }
4721926deccbSFrançois Tigeot
si_ib_parse(struct radeon_device * rdev,struct radeon_ib * ib)4722926deccbSFrançois Tigeot int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
4723926deccbSFrançois Tigeot {
4724926deccbSFrançois Tigeot int ret = 0;
4725591d5043SFrançois Tigeot u32 idx = 0, i;
4726926deccbSFrançois Tigeot struct radeon_cs_packet pkt;
4727926deccbSFrançois Tigeot
4728926deccbSFrançois Tigeot do {
4729926deccbSFrançois Tigeot pkt.idx = idx;
4730b403bed8SMichael Neumann pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]);
4731b403bed8SMichael Neumann pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]);
4732926deccbSFrançois Tigeot pkt.one_reg_wr = 0;
4733926deccbSFrançois Tigeot switch (pkt.type) {
4734b403bed8SMichael Neumann case RADEON_PACKET_TYPE0:
4735926deccbSFrançois Tigeot dev_err(rdev->dev, "Packet0 not allowed!\n");
4736926deccbSFrançois Tigeot ret = -EINVAL;
4737926deccbSFrançois Tigeot break;
4738b403bed8SMichael Neumann case RADEON_PACKET_TYPE2:
4739926deccbSFrançois Tigeot idx += 1;
4740926deccbSFrançois Tigeot break;
4741b403bed8SMichael Neumann case RADEON_PACKET_TYPE3:
4742b403bed8SMichael Neumann pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]);
4743926deccbSFrançois Tigeot if (ib->is_const_ib)
4744926deccbSFrançois Tigeot ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt);
4745926deccbSFrançois Tigeot else {
4746926deccbSFrançois Tigeot switch (ib->ring) {
4747926deccbSFrançois Tigeot case RADEON_RING_TYPE_GFX_INDEX:
4748926deccbSFrançois Tigeot ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt);
4749926deccbSFrançois Tigeot break;
4750926deccbSFrançois Tigeot case CAYMAN_RING_TYPE_CP1_INDEX:
4751926deccbSFrançois Tigeot case CAYMAN_RING_TYPE_CP2_INDEX:
4752926deccbSFrançois Tigeot ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt);
4753926deccbSFrançois Tigeot break;
4754926deccbSFrançois Tigeot default:
4755926deccbSFrançois Tigeot dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->ring);
4756926deccbSFrançois Tigeot ret = -EINVAL;
4757926deccbSFrançois Tigeot break;
4758926deccbSFrançois Tigeot }
4759926deccbSFrançois Tigeot }
4760926deccbSFrançois Tigeot idx += pkt.count + 2;
4761926deccbSFrançois Tigeot break;
4762926deccbSFrançois Tigeot default:
4763926deccbSFrançois Tigeot dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type);
4764926deccbSFrançois Tigeot ret = -EINVAL;
4765926deccbSFrançois Tigeot break;
4766926deccbSFrançois Tigeot }
4767c59a5c48SFrançois Tigeot if (ret) {
4768c59a5c48SFrançois Tigeot for (i = 0; i < ib->length_dw; i++) {
4769c59a5c48SFrançois Tigeot if (i == idx)
4770c59a5c48SFrançois Tigeot printk("\t0x%08x <---\n", ib->ptr[i]);
4771c59a5c48SFrançois Tigeot else
4772c59a5c48SFrançois Tigeot printk("\t0x%08x\n", ib->ptr[i]);
4773c59a5c48SFrançois Tigeot }
4774926deccbSFrançois Tigeot break;
4775c59a5c48SFrançois Tigeot }
4776926deccbSFrançois Tigeot } while (idx < ib->length_dw);
4777926deccbSFrançois Tigeot
4778926deccbSFrançois Tigeot return ret;
4779926deccbSFrançois Tigeot }
4780926deccbSFrançois Tigeot
4781926deccbSFrançois Tigeot /*
4782926deccbSFrançois Tigeot * vm
4783926deccbSFrançois Tigeot */
si_vm_init(struct radeon_device * rdev)4784926deccbSFrançois Tigeot int si_vm_init(struct radeon_device *rdev)
4785926deccbSFrançois Tigeot {
4786926deccbSFrançois Tigeot /* number of VMs */
4787926deccbSFrançois Tigeot rdev->vm_manager.nvm = 16;
4788926deccbSFrançois Tigeot /* base offset of vram pages */
4789926deccbSFrançois Tigeot rdev->vm_manager.vram_base_offset = 0;
4790926deccbSFrançois Tigeot
4791926deccbSFrançois Tigeot return 0;
4792926deccbSFrançois Tigeot }
4793926deccbSFrançois Tigeot
si_vm_fini(struct radeon_device * rdev)4794926deccbSFrançois Tigeot void si_vm_fini(struct radeon_device *rdev)
4795926deccbSFrançois Tigeot {
4796926deccbSFrançois Tigeot }
4797926deccbSFrançois Tigeot
4798926deccbSFrançois Tigeot /**
479957e252bfSMichael Neumann * si_vm_decode_fault - print human readable fault info
480057e252bfSMichael Neumann *
480157e252bfSMichael Neumann * @rdev: radeon_device pointer
480257e252bfSMichael Neumann * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
480357e252bfSMichael Neumann * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
480457e252bfSMichael Neumann *
480557e252bfSMichael Neumann * Print human readable fault information (SI).
480657e252bfSMichael Neumann */
si_vm_decode_fault(struct radeon_device * rdev,u32 status,u32 addr)480757e252bfSMichael Neumann static void si_vm_decode_fault(struct radeon_device *rdev,
480857e252bfSMichael Neumann u32 status, u32 addr)
480957e252bfSMichael Neumann {
481057e252bfSMichael Neumann u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
481157e252bfSMichael Neumann u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
481257e252bfSMichael Neumann u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
481357e252bfSMichael Neumann char *block;
481457e252bfSMichael Neumann
481557e252bfSMichael Neumann if (rdev->family == CHIP_TAHITI) {
481657e252bfSMichael Neumann switch (mc_id) {
481757e252bfSMichael Neumann case 160:
481857e252bfSMichael Neumann case 144:
481957e252bfSMichael Neumann case 96:
482057e252bfSMichael Neumann case 80:
482157e252bfSMichael Neumann case 224:
482257e252bfSMichael Neumann case 208:
482357e252bfSMichael Neumann case 32:
482457e252bfSMichael Neumann case 16:
482557e252bfSMichael Neumann block = "CB";
482657e252bfSMichael Neumann break;
482757e252bfSMichael Neumann case 161:
482857e252bfSMichael Neumann case 145:
482957e252bfSMichael Neumann case 97:
483057e252bfSMichael Neumann case 81:
483157e252bfSMichael Neumann case 225:
483257e252bfSMichael Neumann case 209:
483357e252bfSMichael Neumann case 33:
483457e252bfSMichael Neumann case 17:
483557e252bfSMichael Neumann block = "CB_FMASK";
483657e252bfSMichael Neumann break;
483757e252bfSMichael Neumann case 162:
483857e252bfSMichael Neumann case 146:
483957e252bfSMichael Neumann case 98:
484057e252bfSMichael Neumann case 82:
484157e252bfSMichael Neumann case 226:
484257e252bfSMichael Neumann case 210:
484357e252bfSMichael Neumann case 34:
484457e252bfSMichael Neumann case 18:
484557e252bfSMichael Neumann block = "CB_CMASK";
484657e252bfSMichael Neumann break;
484757e252bfSMichael Neumann case 163:
484857e252bfSMichael Neumann case 147:
484957e252bfSMichael Neumann case 99:
485057e252bfSMichael Neumann case 83:
485157e252bfSMichael Neumann case 227:
485257e252bfSMichael Neumann case 211:
485357e252bfSMichael Neumann case 35:
485457e252bfSMichael Neumann case 19:
485557e252bfSMichael Neumann block = "CB_IMMED";
485657e252bfSMichael Neumann break;
485757e252bfSMichael Neumann case 164:
485857e252bfSMichael Neumann case 148:
485957e252bfSMichael Neumann case 100:
486057e252bfSMichael Neumann case 84:
486157e252bfSMichael Neumann case 228:
486257e252bfSMichael Neumann case 212:
486357e252bfSMichael Neumann case 36:
486457e252bfSMichael Neumann case 20:
486557e252bfSMichael Neumann block = "DB";
486657e252bfSMichael Neumann break;
486757e252bfSMichael Neumann case 165:
486857e252bfSMichael Neumann case 149:
486957e252bfSMichael Neumann case 101:
487057e252bfSMichael Neumann case 85:
487157e252bfSMichael Neumann case 229:
487257e252bfSMichael Neumann case 213:
487357e252bfSMichael Neumann case 37:
487457e252bfSMichael Neumann case 21:
487557e252bfSMichael Neumann block = "DB_HTILE";
487657e252bfSMichael Neumann break;
487757e252bfSMichael Neumann case 167:
487857e252bfSMichael Neumann case 151:
487957e252bfSMichael Neumann case 103:
488057e252bfSMichael Neumann case 87:
488157e252bfSMichael Neumann case 231:
488257e252bfSMichael Neumann case 215:
488357e252bfSMichael Neumann case 39:
488457e252bfSMichael Neumann case 23:
488557e252bfSMichael Neumann block = "DB_STEN";
488657e252bfSMichael Neumann break;
488757e252bfSMichael Neumann case 72:
488857e252bfSMichael Neumann case 68:
488957e252bfSMichael Neumann case 64:
489057e252bfSMichael Neumann case 8:
489157e252bfSMichael Neumann case 4:
489257e252bfSMichael Neumann case 0:
489357e252bfSMichael Neumann case 136:
489457e252bfSMichael Neumann case 132:
489557e252bfSMichael Neumann case 128:
489657e252bfSMichael Neumann case 200:
489757e252bfSMichael Neumann case 196:
489857e252bfSMichael Neumann case 192:
489957e252bfSMichael Neumann block = "TC";
490057e252bfSMichael Neumann break;
490157e252bfSMichael Neumann case 112:
490257e252bfSMichael Neumann case 48:
490357e252bfSMichael Neumann block = "CP";
490457e252bfSMichael Neumann break;
490557e252bfSMichael Neumann case 49:
490657e252bfSMichael Neumann case 177:
490757e252bfSMichael Neumann case 50:
490857e252bfSMichael Neumann case 178:
490957e252bfSMichael Neumann block = "SH";
491057e252bfSMichael Neumann break;
491157e252bfSMichael Neumann case 53:
491257e252bfSMichael Neumann case 190:
491357e252bfSMichael Neumann block = "VGT";
491457e252bfSMichael Neumann break;
491557e252bfSMichael Neumann case 117:
491657e252bfSMichael Neumann block = "IH";
491757e252bfSMichael Neumann break;
491857e252bfSMichael Neumann case 51:
491957e252bfSMichael Neumann case 115:
492057e252bfSMichael Neumann block = "RLC";
492157e252bfSMichael Neumann break;
492257e252bfSMichael Neumann case 119:
492357e252bfSMichael Neumann case 183:
492457e252bfSMichael Neumann block = "DMA0";
492557e252bfSMichael Neumann break;
492657e252bfSMichael Neumann case 61:
492757e252bfSMichael Neumann block = "DMA1";
492857e252bfSMichael Neumann break;
492957e252bfSMichael Neumann case 248:
493057e252bfSMichael Neumann case 120:
493157e252bfSMichael Neumann block = "HDP";
493257e252bfSMichael Neumann break;
493357e252bfSMichael Neumann default:
493457e252bfSMichael Neumann block = "unknown";
493557e252bfSMichael Neumann break;
493657e252bfSMichael Neumann }
493757e252bfSMichael Neumann } else {
493857e252bfSMichael Neumann switch (mc_id) {
493957e252bfSMichael Neumann case 32:
494057e252bfSMichael Neumann case 16:
494157e252bfSMichael Neumann case 96:
494257e252bfSMichael Neumann case 80:
494357e252bfSMichael Neumann case 160:
494457e252bfSMichael Neumann case 144:
494557e252bfSMichael Neumann case 224:
494657e252bfSMichael Neumann case 208:
494757e252bfSMichael Neumann block = "CB";
494857e252bfSMichael Neumann break;
494957e252bfSMichael Neumann case 33:
495057e252bfSMichael Neumann case 17:
495157e252bfSMichael Neumann case 97:
495257e252bfSMichael Neumann case 81:
495357e252bfSMichael Neumann case 161:
495457e252bfSMichael Neumann case 145:
495557e252bfSMichael Neumann case 225:
495657e252bfSMichael Neumann case 209:
495757e252bfSMichael Neumann block = "CB_FMASK";
495857e252bfSMichael Neumann break;
495957e252bfSMichael Neumann case 34:
496057e252bfSMichael Neumann case 18:
496157e252bfSMichael Neumann case 98:
496257e252bfSMichael Neumann case 82:
496357e252bfSMichael Neumann case 162:
496457e252bfSMichael Neumann case 146:
496557e252bfSMichael Neumann case 226:
496657e252bfSMichael Neumann case 210:
496757e252bfSMichael Neumann block = "CB_CMASK";
496857e252bfSMichael Neumann break;
496957e252bfSMichael Neumann case 35:
497057e252bfSMichael Neumann case 19:
497157e252bfSMichael Neumann case 99:
497257e252bfSMichael Neumann case 83:
497357e252bfSMichael Neumann case 163:
497457e252bfSMichael Neumann case 147:
497557e252bfSMichael Neumann case 227:
497657e252bfSMichael Neumann case 211:
497757e252bfSMichael Neumann block = "CB_IMMED";
497857e252bfSMichael Neumann break;
497957e252bfSMichael Neumann case 36:
498057e252bfSMichael Neumann case 20:
498157e252bfSMichael Neumann case 100:
498257e252bfSMichael Neumann case 84:
498357e252bfSMichael Neumann case 164:
498457e252bfSMichael Neumann case 148:
498557e252bfSMichael Neumann case 228:
498657e252bfSMichael Neumann case 212:
498757e252bfSMichael Neumann block = "DB";
498857e252bfSMichael Neumann break;
498957e252bfSMichael Neumann case 37:
499057e252bfSMichael Neumann case 21:
499157e252bfSMichael Neumann case 101:
499257e252bfSMichael Neumann case 85:
499357e252bfSMichael Neumann case 165:
499457e252bfSMichael Neumann case 149:
499557e252bfSMichael Neumann case 229:
499657e252bfSMichael Neumann case 213:
499757e252bfSMichael Neumann block = "DB_HTILE";
499857e252bfSMichael Neumann break;
499957e252bfSMichael Neumann case 39:
500057e252bfSMichael Neumann case 23:
500157e252bfSMichael Neumann case 103:
500257e252bfSMichael Neumann case 87:
500357e252bfSMichael Neumann case 167:
500457e252bfSMichael Neumann case 151:
500557e252bfSMichael Neumann case 231:
500657e252bfSMichael Neumann case 215:
500757e252bfSMichael Neumann block = "DB_STEN";
500857e252bfSMichael Neumann break;
500957e252bfSMichael Neumann case 72:
501057e252bfSMichael Neumann case 68:
501157e252bfSMichael Neumann case 8:
501257e252bfSMichael Neumann case 4:
501357e252bfSMichael Neumann case 136:
501457e252bfSMichael Neumann case 132:
501557e252bfSMichael Neumann case 200:
501657e252bfSMichael Neumann case 196:
501757e252bfSMichael Neumann block = "TC";
501857e252bfSMichael Neumann break;
501957e252bfSMichael Neumann case 112:
502057e252bfSMichael Neumann case 48:
502157e252bfSMichael Neumann block = "CP";
502257e252bfSMichael Neumann break;
502357e252bfSMichael Neumann case 49:
502457e252bfSMichael Neumann case 177:
502557e252bfSMichael Neumann case 50:
502657e252bfSMichael Neumann case 178:
502757e252bfSMichael Neumann block = "SH";
502857e252bfSMichael Neumann break;
502957e252bfSMichael Neumann case 53:
503057e252bfSMichael Neumann block = "VGT";
503157e252bfSMichael Neumann break;
503257e252bfSMichael Neumann case 117:
503357e252bfSMichael Neumann block = "IH";
503457e252bfSMichael Neumann break;
503557e252bfSMichael Neumann case 51:
503657e252bfSMichael Neumann case 115:
503757e252bfSMichael Neumann block = "RLC";
503857e252bfSMichael Neumann break;
503957e252bfSMichael Neumann case 119:
504057e252bfSMichael Neumann case 183:
504157e252bfSMichael Neumann block = "DMA0";
504257e252bfSMichael Neumann break;
504357e252bfSMichael Neumann case 61:
504457e252bfSMichael Neumann block = "DMA1";
504557e252bfSMichael Neumann break;
504657e252bfSMichael Neumann case 248:
504757e252bfSMichael Neumann case 120:
504857e252bfSMichael Neumann block = "HDP";
504957e252bfSMichael Neumann break;
505057e252bfSMichael Neumann default:
505157e252bfSMichael Neumann block = "unknown";
505257e252bfSMichael Neumann break;
505357e252bfSMichael Neumann }
505457e252bfSMichael Neumann }
505557e252bfSMichael Neumann
505657e252bfSMichael Neumann printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
505757e252bfSMichael Neumann protections, vmid, addr,
505857e252bfSMichael Neumann (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
505957e252bfSMichael Neumann block, mc_id);
506057e252bfSMichael Neumann }
506157e252bfSMichael Neumann
si_vm_flush(struct radeon_device * rdev,struct radeon_ring * ring,unsigned vm_id,uint64_t pd_addr)50627dcf36dcSFrançois Tigeot void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
50637dcf36dcSFrançois Tigeot unsigned vm_id, uint64_t pd_addr)
5064926deccbSFrançois Tigeot {
5065926deccbSFrançois Tigeot /* write new base address */
5066926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5067c6f73aabSFrançois Tigeot radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5068926deccbSFrançois Tigeot WRITE_DATA_DST_SEL(0)));
5069926deccbSFrançois Tigeot
50707dcf36dcSFrançois Tigeot if (vm_id < 8) {
5071926deccbSFrançois Tigeot radeon_ring_write(ring,
50727dcf36dcSFrançois Tigeot (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2);
5073926deccbSFrançois Tigeot } else {
5074926deccbSFrançois Tigeot radeon_ring_write(ring,
50757dcf36dcSFrançois Tigeot (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2);
5076926deccbSFrançois Tigeot }
5077926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
50787dcf36dcSFrançois Tigeot radeon_ring_write(ring, pd_addr >> 12);
5079926deccbSFrançois Tigeot
5080926deccbSFrançois Tigeot /* flush hdp cache */
5081926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5082c6f73aabSFrançois Tigeot radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5083926deccbSFrançois Tigeot WRITE_DATA_DST_SEL(0)));
5084926deccbSFrançois Tigeot radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
5085926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
5086926deccbSFrançois Tigeot radeon_ring_write(ring, 0x1);
5087926deccbSFrançois Tigeot
5088926deccbSFrançois Tigeot /* bits 0-15 are the VM contexts0-15 */
5089926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5090c6f73aabSFrançois Tigeot radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5091926deccbSFrançois Tigeot WRITE_DATA_DST_SEL(0)));
5092926deccbSFrançois Tigeot radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
5093926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
50947dcf36dcSFrançois Tigeot radeon_ring_write(ring, 1 << vm_id);
50957dcf36dcSFrançois Tigeot
50967dcf36dcSFrançois Tigeot /* wait for the invalidate to complete */
50977dcf36dcSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
50987dcf36dcSFrançois Tigeot radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */
50997dcf36dcSFrançois Tigeot WAIT_REG_MEM_ENGINE(0))); /* me */
51007dcf36dcSFrançois Tigeot radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
51017dcf36dcSFrançois Tigeot radeon_ring_write(ring, 0);
51027dcf36dcSFrançois Tigeot radeon_ring_write(ring, 0); /* ref */
51037dcf36dcSFrançois Tigeot radeon_ring_write(ring, 0); /* mask */
51047dcf36dcSFrançois Tigeot radeon_ring_write(ring, 0x20); /* poll interval */
5105926deccbSFrançois Tigeot
5106926deccbSFrançois Tigeot /* sync PFP to ME, otherwise we might get invalid PFP reads */
5107926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
5108926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0);
5109926deccbSFrançois Tigeot }
5110926deccbSFrançois Tigeot
5111926deccbSFrançois Tigeot /*
511257e252bfSMichael Neumann * Power and clock gating
511357e252bfSMichael Neumann */
si_wait_for_rlc_serdes(struct radeon_device * rdev)511457e252bfSMichael Neumann static void si_wait_for_rlc_serdes(struct radeon_device *rdev)
511557e252bfSMichael Neumann {
511657e252bfSMichael Neumann int i;
511757e252bfSMichael Neumann
511857e252bfSMichael Neumann for (i = 0; i < rdev->usec_timeout; i++) {
511957e252bfSMichael Neumann if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0)
512057e252bfSMichael Neumann break;
5121c4ef309bSzrj udelay(1);
512257e252bfSMichael Neumann }
512357e252bfSMichael Neumann
512457e252bfSMichael Neumann for (i = 0; i < rdev->usec_timeout; i++) {
512557e252bfSMichael Neumann if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0)
512657e252bfSMichael Neumann break;
5127c4ef309bSzrj udelay(1);
512857e252bfSMichael Neumann }
512957e252bfSMichael Neumann }
513057e252bfSMichael Neumann
si_enable_gui_idle_interrupt(struct radeon_device * rdev,bool enable)513157e252bfSMichael Neumann static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
513257e252bfSMichael Neumann bool enable)
513357e252bfSMichael Neumann {
513457e252bfSMichael Neumann u32 tmp = RREG32(CP_INT_CNTL_RING0);
513557e252bfSMichael Neumann u32 mask;
513657e252bfSMichael Neumann int i;
513757e252bfSMichael Neumann
513857e252bfSMichael Neumann if (enable)
513957e252bfSMichael Neumann tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
514057e252bfSMichael Neumann else
514157e252bfSMichael Neumann tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
514257e252bfSMichael Neumann WREG32(CP_INT_CNTL_RING0, tmp);
514357e252bfSMichael Neumann
514457e252bfSMichael Neumann if (!enable) {
514557e252bfSMichael Neumann /* read a gfx register */
514657e252bfSMichael Neumann tmp = RREG32(DB_DEPTH_INFO);
514757e252bfSMichael Neumann
514857e252bfSMichael Neumann mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS;
514957e252bfSMichael Neumann for (i = 0; i < rdev->usec_timeout; i++) {
515057e252bfSMichael Neumann if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS))
515157e252bfSMichael Neumann break;
5152c4ef309bSzrj udelay(1);
515357e252bfSMichael Neumann }
515457e252bfSMichael Neumann }
515557e252bfSMichael Neumann }
515657e252bfSMichael Neumann
si_set_uvd_dcm(struct radeon_device * rdev,bool sw_mode)515757e252bfSMichael Neumann static void si_set_uvd_dcm(struct radeon_device *rdev,
515857e252bfSMichael Neumann bool sw_mode)
515957e252bfSMichael Neumann {
516057e252bfSMichael Neumann u32 tmp, tmp2;
516157e252bfSMichael Neumann
516257e252bfSMichael Neumann tmp = RREG32(UVD_CGC_CTRL);
516357e252bfSMichael Neumann tmp &= ~(CLK_OD_MASK | CG_DT_MASK);
516457e252bfSMichael Neumann tmp |= DCM | CG_DT(1) | CLK_OD(4);
516557e252bfSMichael Neumann
516657e252bfSMichael Neumann if (sw_mode) {
516757e252bfSMichael Neumann tmp &= ~0x7ffff800;
516857e252bfSMichael Neumann tmp2 = DYN_OR_EN | DYN_RR_EN | G_DIV_ID(7);
516957e252bfSMichael Neumann } else {
517057e252bfSMichael Neumann tmp |= 0x7ffff800;
517157e252bfSMichael Neumann tmp2 = 0;
517257e252bfSMichael Neumann }
517357e252bfSMichael Neumann
517457e252bfSMichael Neumann WREG32(UVD_CGC_CTRL, tmp);
517557e252bfSMichael Neumann WREG32_UVD_CTX(UVD_CGC_CTRL2, tmp2);
517657e252bfSMichael Neumann }
517757e252bfSMichael Neumann
si_init_uvd_internal_cg(struct radeon_device * rdev)51784cd92098Szrj void si_init_uvd_internal_cg(struct radeon_device *rdev)
517957e252bfSMichael Neumann {
518057e252bfSMichael Neumann bool hw_mode = true;
518157e252bfSMichael Neumann
518257e252bfSMichael Neumann if (hw_mode) {
518357e252bfSMichael Neumann si_set_uvd_dcm(rdev, false);
518457e252bfSMichael Neumann } else {
518557e252bfSMichael Neumann u32 tmp = RREG32(UVD_CGC_CTRL);
518657e252bfSMichael Neumann tmp &= ~DCM;
518757e252bfSMichael Neumann WREG32(UVD_CGC_CTRL, tmp);
518857e252bfSMichael Neumann }
518957e252bfSMichael Neumann }
519057e252bfSMichael Neumann
si_halt_rlc(struct radeon_device * rdev)519157e252bfSMichael Neumann static u32 si_halt_rlc(struct radeon_device *rdev)
519257e252bfSMichael Neumann {
519357e252bfSMichael Neumann u32 data, orig;
519457e252bfSMichael Neumann
519557e252bfSMichael Neumann orig = data = RREG32(RLC_CNTL);
519657e252bfSMichael Neumann
519757e252bfSMichael Neumann if (data & RLC_ENABLE) {
519857e252bfSMichael Neumann data &= ~RLC_ENABLE;
519957e252bfSMichael Neumann WREG32(RLC_CNTL, data);
520057e252bfSMichael Neumann
520157e252bfSMichael Neumann si_wait_for_rlc_serdes(rdev);
520257e252bfSMichael Neumann }
520357e252bfSMichael Neumann
520457e252bfSMichael Neumann return orig;
520557e252bfSMichael Neumann }
520657e252bfSMichael Neumann
si_update_rlc(struct radeon_device * rdev,u32 rlc)520757e252bfSMichael Neumann static void si_update_rlc(struct radeon_device *rdev, u32 rlc)
520857e252bfSMichael Neumann {
520957e252bfSMichael Neumann u32 tmp;
521057e252bfSMichael Neumann
521157e252bfSMichael Neumann tmp = RREG32(RLC_CNTL);
521257e252bfSMichael Neumann if (tmp != rlc)
521357e252bfSMichael Neumann WREG32(RLC_CNTL, rlc);
521457e252bfSMichael Neumann }
521557e252bfSMichael Neumann
si_enable_dma_pg(struct radeon_device * rdev,bool enable)521657e252bfSMichael Neumann static void si_enable_dma_pg(struct radeon_device *rdev, bool enable)
521757e252bfSMichael Neumann {
521857e252bfSMichael Neumann u32 data, orig;
521957e252bfSMichael Neumann
522057e252bfSMichael Neumann orig = data = RREG32(DMA_PG);
52214cd92098Szrj if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA))
522257e252bfSMichael Neumann data |= PG_CNTL_ENABLE;
522357e252bfSMichael Neumann else
522457e252bfSMichael Neumann data &= ~PG_CNTL_ENABLE;
522557e252bfSMichael Neumann if (orig != data)
522657e252bfSMichael Neumann WREG32(DMA_PG, data);
522757e252bfSMichael Neumann }
522857e252bfSMichael Neumann
si_init_dma_pg(struct radeon_device * rdev)522957e252bfSMichael Neumann static void si_init_dma_pg(struct radeon_device *rdev)
523057e252bfSMichael Neumann {
523157e252bfSMichael Neumann u32 tmp;
523257e252bfSMichael Neumann
523357e252bfSMichael Neumann WREG32(DMA_PGFSM_WRITE, 0x00002000);
523457e252bfSMichael Neumann WREG32(DMA_PGFSM_CONFIG, 0x100010ff);
523557e252bfSMichael Neumann
523657e252bfSMichael Neumann for (tmp = 0; tmp < 5; tmp++)
523757e252bfSMichael Neumann WREG32(DMA_PGFSM_WRITE, 0);
523857e252bfSMichael Neumann }
523957e252bfSMichael Neumann
si_enable_gfx_cgpg(struct radeon_device * rdev,bool enable)524057e252bfSMichael Neumann static void si_enable_gfx_cgpg(struct radeon_device *rdev,
524157e252bfSMichael Neumann bool enable)
524257e252bfSMichael Neumann {
524357e252bfSMichael Neumann u32 tmp;
524457e252bfSMichael Neumann
52454cd92098Szrj if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG)) {
524657e252bfSMichael Neumann tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10);
524757e252bfSMichael Neumann WREG32(RLC_TTOP_D, tmp);
524857e252bfSMichael Neumann
524957e252bfSMichael Neumann tmp = RREG32(RLC_PG_CNTL);
525057e252bfSMichael Neumann tmp |= GFX_PG_ENABLE;
525157e252bfSMichael Neumann WREG32(RLC_PG_CNTL, tmp);
525257e252bfSMichael Neumann
525357e252bfSMichael Neumann tmp = RREG32(RLC_AUTO_PG_CTRL);
525457e252bfSMichael Neumann tmp |= AUTO_PG_EN;
525557e252bfSMichael Neumann WREG32(RLC_AUTO_PG_CTRL, tmp);
525657e252bfSMichael Neumann } else {
525757e252bfSMichael Neumann tmp = RREG32(RLC_AUTO_PG_CTRL);
525857e252bfSMichael Neumann tmp &= ~AUTO_PG_EN;
525957e252bfSMichael Neumann WREG32(RLC_AUTO_PG_CTRL, tmp);
526057e252bfSMichael Neumann
526157e252bfSMichael Neumann tmp = RREG32(DB_RENDER_CONTROL);
526257e252bfSMichael Neumann }
526357e252bfSMichael Neumann }
526457e252bfSMichael Neumann
si_init_gfx_cgpg(struct radeon_device * rdev)526557e252bfSMichael Neumann static void si_init_gfx_cgpg(struct radeon_device *rdev)
526657e252bfSMichael Neumann {
526757e252bfSMichael Neumann u32 tmp;
526857e252bfSMichael Neumann
526957e252bfSMichael Neumann WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
527057e252bfSMichael Neumann
527157e252bfSMichael Neumann tmp = RREG32(RLC_PG_CNTL);
527257e252bfSMichael Neumann tmp |= GFX_PG_SRC;
527357e252bfSMichael Neumann WREG32(RLC_PG_CNTL, tmp);
527457e252bfSMichael Neumann
527557e252bfSMichael Neumann WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
527657e252bfSMichael Neumann
527757e252bfSMichael Neumann tmp = RREG32(RLC_AUTO_PG_CTRL);
527857e252bfSMichael Neumann
527957e252bfSMichael Neumann tmp &= ~GRBM_REG_SGIT_MASK;
528057e252bfSMichael Neumann tmp |= GRBM_REG_SGIT(0x700);
528157e252bfSMichael Neumann tmp &= ~PG_AFTER_GRBM_REG_ST_MASK;
528257e252bfSMichael Neumann WREG32(RLC_AUTO_PG_CTRL, tmp);
528357e252bfSMichael Neumann }
528457e252bfSMichael Neumann
si_get_cu_active_bitmap(struct radeon_device * rdev,u32 se,u32 sh)528557e252bfSMichael Neumann static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh)
528657e252bfSMichael Neumann {
528757e252bfSMichael Neumann u32 mask = 0, tmp, tmp1;
528857e252bfSMichael Neumann int i;
528957e252bfSMichael Neumann
529057e252bfSMichael Neumann si_select_se_sh(rdev, se, sh);
529157e252bfSMichael Neumann tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
529257e252bfSMichael Neumann tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG);
529357e252bfSMichael Neumann si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
529457e252bfSMichael Neumann
529557e252bfSMichael Neumann tmp &= 0xffff0000;
529657e252bfSMichael Neumann
529757e252bfSMichael Neumann tmp |= tmp1;
529857e252bfSMichael Neumann tmp >>= 16;
529957e252bfSMichael Neumann
530057e252bfSMichael Neumann for (i = 0; i < rdev->config.si.max_cu_per_sh; i ++) {
530157e252bfSMichael Neumann mask <<= 1;
530257e252bfSMichael Neumann mask |= 1;
530357e252bfSMichael Neumann }
530457e252bfSMichael Neumann
530557e252bfSMichael Neumann return (~tmp) & mask;
530657e252bfSMichael Neumann }
530757e252bfSMichael Neumann
si_init_ao_cu_mask(struct radeon_device * rdev)530857e252bfSMichael Neumann static void si_init_ao_cu_mask(struct radeon_device *rdev)
530957e252bfSMichael Neumann {
531057e252bfSMichael Neumann u32 i, j, k, active_cu_number = 0;
531157e252bfSMichael Neumann u32 mask, counter, cu_bitmap;
531257e252bfSMichael Neumann u32 tmp = 0;
531357e252bfSMichael Neumann
531457e252bfSMichael Neumann for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
531557e252bfSMichael Neumann for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
531657e252bfSMichael Neumann mask = 1;
531757e252bfSMichael Neumann cu_bitmap = 0;
531857e252bfSMichael Neumann counter = 0;
531957e252bfSMichael Neumann for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) {
532057e252bfSMichael Neumann if (si_get_cu_active_bitmap(rdev, i, j) & mask) {
532157e252bfSMichael Neumann if (counter < 2)
532257e252bfSMichael Neumann cu_bitmap |= mask;
532357e252bfSMichael Neumann counter++;
532457e252bfSMichael Neumann }
532557e252bfSMichael Neumann mask <<= 1;
532657e252bfSMichael Neumann }
532757e252bfSMichael Neumann
532857e252bfSMichael Neumann active_cu_number += counter;
532957e252bfSMichael Neumann tmp |= (cu_bitmap << (i * 16 + j * 8));
533057e252bfSMichael Neumann }
533157e252bfSMichael Neumann }
533257e252bfSMichael Neumann
533357e252bfSMichael Neumann WREG32(RLC_PG_AO_CU_MASK, tmp);
533457e252bfSMichael Neumann
533557e252bfSMichael Neumann tmp = RREG32(RLC_MAX_PG_CU);
533657e252bfSMichael Neumann tmp &= ~MAX_PU_CU_MASK;
533757e252bfSMichael Neumann tmp |= MAX_PU_CU(active_cu_number);
533857e252bfSMichael Neumann WREG32(RLC_MAX_PG_CU, tmp);
533957e252bfSMichael Neumann }
534057e252bfSMichael Neumann
si_enable_cgcg(struct radeon_device * rdev,bool enable)534157e252bfSMichael Neumann static void si_enable_cgcg(struct radeon_device *rdev,
534257e252bfSMichael Neumann bool enable)
534357e252bfSMichael Neumann {
534457e252bfSMichael Neumann u32 data, orig, tmp;
534557e252bfSMichael Neumann
534657e252bfSMichael Neumann orig = data = RREG32(RLC_CGCG_CGLS_CTRL);
534757e252bfSMichael Neumann
53484cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)) {
53494cd92098Szrj si_enable_gui_idle_interrupt(rdev, true);
535057e252bfSMichael Neumann
535157e252bfSMichael Neumann WREG32(RLC_GCPM_GENERAL_3, 0x00000080);
535257e252bfSMichael Neumann
535357e252bfSMichael Neumann tmp = si_halt_rlc(rdev);
535457e252bfSMichael Neumann
535557e252bfSMichael Neumann WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
535657e252bfSMichael Neumann WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
535757e252bfSMichael Neumann WREG32(RLC_SERDES_WR_CTRL, 0x00b000ff);
535857e252bfSMichael Neumann
535957e252bfSMichael Neumann si_wait_for_rlc_serdes(rdev);
536057e252bfSMichael Neumann
536157e252bfSMichael Neumann si_update_rlc(rdev, tmp);
536257e252bfSMichael Neumann
536357e252bfSMichael Neumann WREG32(RLC_SERDES_WR_CTRL, 0x007000ff);
536457e252bfSMichael Neumann
536557e252bfSMichael Neumann data |= CGCG_EN | CGLS_EN;
536657e252bfSMichael Neumann } else {
53674cd92098Szrj si_enable_gui_idle_interrupt(rdev, false);
53684cd92098Szrj
536957e252bfSMichael Neumann RREG32(CB_CGTT_SCLK_CTRL);
537057e252bfSMichael Neumann RREG32(CB_CGTT_SCLK_CTRL);
537157e252bfSMichael Neumann RREG32(CB_CGTT_SCLK_CTRL);
537257e252bfSMichael Neumann RREG32(CB_CGTT_SCLK_CTRL);
537357e252bfSMichael Neumann
537457e252bfSMichael Neumann data &= ~(CGCG_EN | CGLS_EN);
537557e252bfSMichael Neumann }
537657e252bfSMichael Neumann
537757e252bfSMichael Neumann if (orig != data)
537857e252bfSMichael Neumann WREG32(RLC_CGCG_CGLS_CTRL, data);
537957e252bfSMichael Neumann }
538057e252bfSMichael Neumann
si_enable_mgcg(struct radeon_device * rdev,bool enable)538157e252bfSMichael Neumann static void si_enable_mgcg(struct radeon_device *rdev,
538257e252bfSMichael Neumann bool enable)
538357e252bfSMichael Neumann {
538457e252bfSMichael Neumann u32 data, orig, tmp = 0;
538557e252bfSMichael Neumann
53864cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)) {
538757e252bfSMichael Neumann orig = data = RREG32(CGTS_SM_CTRL_REG);
538857e252bfSMichael Neumann data = 0x96940200;
538957e252bfSMichael Neumann if (orig != data)
539057e252bfSMichael Neumann WREG32(CGTS_SM_CTRL_REG, data);
539157e252bfSMichael Neumann
53924cd92098Szrj if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CP_LS) {
539357e252bfSMichael Neumann orig = data = RREG32(CP_MEM_SLP_CNTL);
539457e252bfSMichael Neumann data |= CP_MEM_LS_EN;
539557e252bfSMichael Neumann if (orig != data)
539657e252bfSMichael Neumann WREG32(CP_MEM_SLP_CNTL, data);
53974cd92098Szrj }
539857e252bfSMichael Neumann
539957e252bfSMichael Neumann orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
540057e252bfSMichael Neumann data &= 0xffffffc0;
540157e252bfSMichael Neumann if (orig != data)
540257e252bfSMichael Neumann WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
540357e252bfSMichael Neumann
540457e252bfSMichael Neumann tmp = si_halt_rlc(rdev);
540557e252bfSMichael Neumann
540657e252bfSMichael Neumann WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
540757e252bfSMichael Neumann WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
540857e252bfSMichael Neumann WREG32(RLC_SERDES_WR_CTRL, 0x00d000ff);
540957e252bfSMichael Neumann
541057e252bfSMichael Neumann si_update_rlc(rdev, tmp);
541157e252bfSMichael Neumann } else {
541257e252bfSMichael Neumann orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
541357e252bfSMichael Neumann data |= 0x00000003;
541457e252bfSMichael Neumann if (orig != data)
541557e252bfSMichael Neumann WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
541657e252bfSMichael Neumann
541757e252bfSMichael Neumann data = RREG32(CP_MEM_SLP_CNTL);
541857e252bfSMichael Neumann if (data & CP_MEM_LS_EN) {
541957e252bfSMichael Neumann data &= ~CP_MEM_LS_EN;
542057e252bfSMichael Neumann WREG32(CP_MEM_SLP_CNTL, data);
542157e252bfSMichael Neumann }
542257e252bfSMichael Neumann orig = data = RREG32(CGTS_SM_CTRL_REG);
542357e252bfSMichael Neumann data |= LS_OVERRIDE | OVERRIDE;
542457e252bfSMichael Neumann if (orig != data)
542557e252bfSMichael Neumann WREG32(CGTS_SM_CTRL_REG, data);
542657e252bfSMichael Neumann
542757e252bfSMichael Neumann tmp = si_halt_rlc(rdev);
542857e252bfSMichael Neumann
542957e252bfSMichael Neumann WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
543057e252bfSMichael Neumann WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
543157e252bfSMichael Neumann WREG32(RLC_SERDES_WR_CTRL, 0x00e000ff);
543257e252bfSMichael Neumann
543357e252bfSMichael Neumann si_update_rlc(rdev, tmp);
543457e252bfSMichael Neumann }
543557e252bfSMichael Neumann }
543657e252bfSMichael Neumann
si_enable_uvd_mgcg(struct radeon_device * rdev,bool enable)543757e252bfSMichael Neumann static void si_enable_uvd_mgcg(struct radeon_device *rdev,
543857e252bfSMichael Neumann bool enable)
543957e252bfSMichael Neumann {
544057e252bfSMichael Neumann u32 orig, data, tmp;
544157e252bfSMichael Neumann
54424cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)) {
544357e252bfSMichael Neumann tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
544457e252bfSMichael Neumann tmp |= 0x3fff;
544557e252bfSMichael Neumann WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
544657e252bfSMichael Neumann
544757e252bfSMichael Neumann orig = data = RREG32(UVD_CGC_CTRL);
544857e252bfSMichael Neumann data |= DCM;
544957e252bfSMichael Neumann if (orig != data)
545057e252bfSMichael Neumann WREG32(UVD_CGC_CTRL, data);
545157e252bfSMichael Neumann
545257e252bfSMichael Neumann WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0);
545357e252bfSMichael Neumann WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0);
545457e252bfSMichael Neumann } else {
545557e252bfSMichael Neumann tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
545657e252bfSMichael Neumann tmp &= ~0x3fff;
545757e252bfSMichael Neumann WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
545857e252bfSMichael Neumann
545957e252bfSMichael Neumann orig = data = RREG32(UVD_CGC_CTRL);
546057e252bfSMichael Neumann data &= ~DCM;
546157e252bfSMichael Neumann if (orig != data)
546257e252bfSMichael Neumann WREG32(UVD_CGC_CTRL, data);
546357e252bfSMichael Neumann
546457e252bfSMichael Neumann WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0xffffffff);
546557e252bfSMichael Neumann WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0xffffffff);
546657e252bfSMichael Neumann }
546757e252bfSMichael Neumann }
546857e252bfSMichael Neumann
546957e252bfSMichael Neumann static const u32 mc_cg_registers[] =
547057e252bfSMichael Neumann {
547157e252bfSMichael Neumann MC_HUB_MISC_HUB_CG,
547257e252bfSMichael Neumann MC_HUB_MISC_SIP_CG,
547357e252bfSMichael Neumann MC_HUB_MISC_VM_CG,
547457e252bfSMichael Neumann MC_XPB_CLK_GAT,
547557e252bfSMichael Neumann ATC_MISC_CG,
547657e252bfSMichael Neumann MC_CITF_MISC_WR_CG,
547757e252bfSMichael Neumann MC_CITF_MISC_RD_CG,
547857e252bfSMichael Neumann MC_CITF_MISC_VM_CG,
547957e252bfSMichael Neumann VM_L2_CG,
548057e252bfSMichael Neumann };
548157e252bfSMichael Neumann
si_enable_mc_ls(struct radeon_device * rdev,bool enable)548257e252bfSMichael Neumann static void si_enable_mc_ls(struct radeon_device *rdev,
548357e252bfSMichael Neumann bool enable)
548457e252bfSMichael Neumann {
548557e252bfSMichael Neumann int i;
548657e252bfSMichael Neumann u32 orig, data;
548757e252bfSMichael Neumann
548857e252bfSMichael Neumann for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
548957e252bfSMichael Neumann orig = data = RREG32(mc_cg_registers[i]);
54904cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS))
549157e252bfSMichael Neumann data |= MC_LS_ENABLE;
549257e252bfSMichael Neumann else
549357e252bfSMichael Neumann data &= ~MC_LS_ENABLE;
549457e252bfSMichael Neumann if (data != orig)
549557e252bfSMichael Neumann WREG32(mc_cg_registers[i], data);
549657e252bfSMichael Neumann }
549757e252bfSMichael Neumann }
549857e252bfSMichael Neumann
si_enable_mc_mgcg(struct radeon_device * rdev,bool enable)54994cd92098Szrj static void si_enable_mc_mgcg(struct radeon_device *rdev,
55004cd92098Szrj bool enable)
55014cd92098Szrj {
55024cd92098Szrj int i;
55034cd92098Szrj u32 orig, data;
55044cd92098Szrj
55054cd92098Szrj for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
55064cd92098Szrj orig = data = RREG32(mc_cg_registers[i]);
55074cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_MGCG))
55084cd92098Szrj data |= MC_CG_ENABLE;
55094cd92098Szrj else
55104cd92098Szrj data &= ~MC_CG_ENABLE;
55114cd92098Szrj if (data != orig)
55124cd92098Szrj WREG32(mc_cg_registers[i], data);
55134cd92098Szrj }
55144cd92098Szrj }
55154cd92098Szrj
si_enable_dma_mgcg(struct radeon_device * rdev,bool enable)55164cd92098Szrj static void si_enable_dma_mgcg(struct radeon_device *rdev,
55174cd92098Szrj bool enable)
55184cd92098Szrj {
55194cd92098Szrj u32 orig, data, offset;
55204cd92098Szrj int i;
55214cd92098Szrj
55224cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_MGCG)) {
55234cd92098Szrj for (i = 0; i < 2; i++) {
55244cd92098Szrj if (i == 0)
55254cd92098Szrj offset = DMA0_REGISTER_OFFSET;
55264cd92098Szrj else
55274cd92098Szrj offset = DMA1_REGISTER_OFFSET;
55284cd92098Szrj orig = data = RREG32(DMA_POWER_CNTL + offset);
55294cd92098Szrj data &= ~MEM_POWER_OVERRIDE;
55304cd92098Szrj if (data != orig)
55314cd92098Szrj WREG32(DMA_POWER_CNTL + offset, data);
55324cd92098Szrj WREG32(DMA_CLK_CTRL + offset, 0x00000100);
55334cd92098Szrj }
55344cd92098Szrj } else {
55354cd92098Szrj for (i = 0; i < 2; i++) {
55364cd92098Szrj if (i == 0)
55374cd92098Szrj offset = DMA0_REGISTER_OFFSET;
55384cd92098Szrj else
55394cd92098Szrj offset = DMA1_REGISTER_OFFSET;
55404cd92098Szrj orig = data = RREG32(DMA_POWER_CNTL + offset);
55414cd92098Szrj data |= MEM_POWER_OVERRIDE;
55424cd92098Szrj if (data != orig)
55434cd92098Szrj WREG32(DMA_POWER_CNTL + offset, data);
55444cd92098Szrj
55454cd92098Szrj orig = data = RREG32(DMA_CLK_CTRL + offset);
55464cd92098Szrj data = 0xff000000;
55474cd92098Szrj if (data != orig)
55484cd92098Szrj WREG32(DMA_CLK_CTRL + offset, data);
55494cd92098Szrj }
55504cd92098Szrj }
55514cd92098Szrj }
55524cd92098Szrj
si_enable_bif_mgls(struct radeon_device * rdev,bool enable)55534cd92098Szrj static void si_enable_bif_mgls(struct radeon_device *rdev,
55544cd92098Szrj bool enable)
55554cd92098Szrj {
55564cd92098Szrj u32 orig, data;
55574cd92098Szrj
55584cd92098Szrj orig = data = RREG32_PCIE(PCIE_CNTL2);
55594cd92098Szrj
55604cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_BIF_LS))
55614cd92098Szrj data |= SLV_MEM_LS_EN | MST_MEM_LS_EN |
55624cd92098Szrj REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN;
55634cd92098Szrj else
55644cd92098Szrj data &= ~(SLV_MEM_LS_EN | MST_MEM_LS_EN |
55654cd92098Szrj REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN);
55664cd92098Szrj
55674cd92098Szrj if (orig != data)
55684cd92098Szrj WREG32_PCIE(PCIE_CNTL2, data);
55694cd92098Szrj }
55704cd92098Szrj
si_enable_hdp_mgcg(struct radeon_device * rdev,bool enable)55714cd92098Szrj static void si_enable_hdp_mgcg(struct radeon_device *rdev,
55724cd92098Szrj bool enable)
55734cd92098Szrj {
55744cd92098Szrj u32 orig, data;
55754cd92098Szrj
55764cd92098Szrj orig = data = RREG32(HDP_HOST_PATH_CNTL);
55774cd92098Szrj
55784cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_MGCG))
55794cd92098Szrj data &= ~CLOCK_GATING_DIS;
55804cd92098Szrj else
55814cd92098Szrj data |= CLOCK_GATING_DIS;
55824cd92098Szrj
55834cd92098Szrj if (orig != data)
55844cd92098Szrj WREG32(HDP_HOST_PATH_CNTL, data);
55854cd92098Szrj }
55864cd92098Szrj
si_enable_hdp_ls(struct radeon_device * rdev,bool enable)55874cd92098Szrj static void si_enable_hdp_ls(struct radeon_device *rdev,
55884cd92098Szrj bool enable)
55894cd92098Szrj {
55904cd92098Szrj u32 orig, data;
55914cd92098Szrj
55924cd92098Szrj orig = data = RREG32(HDP_MEM_POWER_LS);
55934cd92098Szrj
55944cd92098Szrj if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_LS))
55954cd92098Szrj data |= HDP_LS_ENABLE;
55964cd92098Szrj else
55974cd92098Szrj data &= ~HDP_LS_ENABLE;
55984cd92098Szrj
55994cd92098Szrj if (orig != data)
56004cd92098Szrj WREG32(HDP_MEM_POWER_LS, data);
56014cd92098Szrj }
56024cd92098Szrj
si_update_cg(struct radeon_device * rdev,u32 block,bool enable)5603c6f73aabSFrançois Tigeot static void si_update_cg(struct radeon_device *rdev,
56044cd92098Szrj u32 block, bool enable)
56054cd92098Szrj {
56064cd92098Szrj if (block & RADEON_CG_BLOCK_GFX) {
56074cd92098Szrj si_enable_gui_idle_interrupt(rdev, false);
56084cd92098Szrj /* order matters! */
56094cd92098Szrj if (enable) {
56104cd92098Szrj si_enable_mgcg(rdev, true);
56114cd92098Szrj si_enable_cgcg(rdev, true);
56124cd92098Szrj } else {
56134cd92098Szrj si_enable_cgcg(rdev, false);
56144cd92098Szrj si_enable_mgcg(rdev, false);
56154cd92098Szrj }
56164cd92098Szrj si_enable_gui_idle_interrupt(rdev, true);
56174cd92098Szrj }
56184cd92098Szrj
56194cd92098Szrj if (block & RADEON_CG_BLOCK_MC) {
56204cd92098Szrj si_enable_mc_mgcg(rdev, enable);
56214cd92098Szrj si_enable_mc_ls(rdev, enable);
56224cd92098Szrj }
56234cd92098Szrj
56244cd92098Szrj if (block & RADEON_CG_BLOCK_SDMA) {
56254cd92098Szrj si_enable_dma_mgcg(rdev, enable);
56264cd92098Szrj }
56274cd92098Szrj
56284cd92098Szrj if (block & RADEON_CG_BLOCK_BIF) {
56294cd92098Szrj si_enable_bif_mgls(rdev, enable);
56304cd92098Szrj }
56314cd92098Szrj
56324cd92098Szrj if (block & RADEON_CG_BLOCK_UVD) {
56334cd92098Szrj if (rdev->has_uvd) {
56344cd92098Szrj si_enable_uvd_mgcg(rdev, enable);
56354cd92098Szrj }
56364cd92098Szrj }
56374cd92098Szrj
56384cd92098Szrj if (block & RADEON_CG_BLOCK_HDP) {
56394cd92098Szrj si_enable_hdp_mgcg(rdev, enable);
56404cd92098Szrj si_enable_hdp_ls(rdev, enable);
56414cd92098Szrj }
56424cd92098Szrj }
564357e252bfSMichael Neumann
si_init_cg(struct radeon_device * rdev)564457e252bfSMichael Neumann static void si_init_cg(struct radeon_device *rdev)
564557e252bfSMichael Neumann {
56464cd92098Szrj si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
56474cd92098Szrj RADEON_CG_BLOCK_MC |
56484cd92098Szrj RADEON_CG_BLOCK_SDMA |
56494cd92098Szrj RADEON_CG_BLOCK_BIF |
56504cd92098Szrj RADEON_CG_BLOCK_HDP), true);
565157e252bfSMichael Neumann if (rdev->has_uvd) {
56524cd92098Szrj si_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
565357e252bfSMichael Neumann si_init_uvd_internal_cg(rdev);
565457e252bfSMichael Neumann }
565557e252bfSMichael Neumann }
565657e252bfSMichael Neumann
si_fini_cg(struct radeon_device * rdev)565757e252bfSMichael Neumann static void si_fini_cg(struct radeon_device *rdev)
565857e252bfSMichael Neumann {
56594cd92098Szrj if (rdev->has_uvd) {
56604cd92098Szrj si_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
56614cd92098Szrj }
56624cd92098Szrj si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
56634cd92098Szrj RADEON_CG_BLOCK_MC |
56644cd92098Szrj RADEON_CG_BLOCK_SDMA |
56654cd92098Szrj RADEON_CG_BLOCK_BIF |
56664cd92098Szrj RADEON_CG_BLOCK_HDP), false);
56674cd92098Szrj }
56684cd92098Szrj
si_get_csb_size(struct radeon_device * rdev)56694cd92098Szrj u32 si_get_csb_size(struct radeon_device *rdev)
56704cd92098Szrj {
56714cd92098Szrj u32 count = 0;
56724cd92098Szrj const struct cs_section_def *sect = NULL;
56734cd92098Szrj const struct cs_extent_def *ext = NULL;
56744cd92098Szrj
56754cd92098Szrj if (rdev->rlc.cs_data == NULL)
56764cd92098Szrj return 0;
56774cd92098Szrj
56784cd92098Szrj /* begin clear state */
56794cd92098Szrj count += 2;
56804cd92098Szrj /* context control state */
56814cd92098Szrj count += 3;
56824cd92098Szrj
56834cd92098Szrj for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
56844cd92098Szrj for (ext = sect->section; ext->extent != NULL; ++ext) {
56854cd92098Szrj if (sect->id == SECT_CONTEXT)
56864cd92098Szrj count += 2 + ext->reg_count;
56874cd92098Szrj else
56884cd92098Szrj return 0;
56894cd92098Szrj }
56904cd92098Szrj }
56914cd92098Szrj /* pa_sc_raster_config */
56924cd92098Szrj count += 3;
56934cd92098Szrj /* end clear state */
56944cd92098Szrj count += 2;
56954cd92098Szrj /* clear state */
56964cd92098Szrj count += 2;
56974cd92098Szrj
56984cd92098Szrj return count;
56994cd92098Szrj }
57004cd92098Szrj
si_get_csb_buffer(struct radeon_device * rdev,volatile u32 * buffer)57014cd92098Szrj void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)
57024cd92098Szrj {
57034cd92098Szrj u32 count = 0, i;
57044cd92098Szrj const struct cs_section_def *sect = NULL;
57054cd92098Szrj const struct cs_extent_def *ext = NULL;
57064cd92098Szrj
57074cd92098Szrj if (rdev->rlc.cs_data == NULL)
57084cd92098Szrj return;
57094cd92098Szrj if (buffer == NULL)
57104cd92098Szrj return;
57114cd92098Szrj
5712c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
5713c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
57144cd92098Szrj
5715c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1));
5716c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(0x80000000);
5717c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(0x80000000);
57184cd92098Szrj
57194cd92098Szrj for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
57204cd92098Szrj for (ext = sect->section; ext->extent != NULL; ++ext) {
57214cd92098Szrj if (sect->id == SECT_CONTEXT) {
5722c6f73aabSFrançois Tigeot buffer[count++] =
5723c6f73aabSFrançois Tigeot cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count));
5724c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000);
57254cd92098Szrj for (i = 0; i < ext->reg_count; i++)
5726c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(ext->extent[i]);
57274cd92098Szrj } else {
57284cd92098Szrj return;
57294cd92098Szrj }
57304cd92098Szrj }
57314cd92098Szrj }
57324cd92098Szrj
5733c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1));
5734c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
57354cd92098Szrj switch (rdev->family) {
57364cd92098Szrj case CHIP_TAHITI:
57374cd92098Szrj case CHIP_PITCAIRN:
5738c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(0x2a00126a);
57394cd92098Szrj break;
57404cd92098Szrj case CHIP_VERDE:
5741c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(0x0000124a);
57424cd92098Szrj break;
57434cd92098Szrj case CHIP_OLAND:
5744c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(0x00000082);
57454cd92098Szrj break;
57464cd92098Szrj case CHIP_HAINAN:
5747c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(0x00000000);
57484cd92098Szrj break;
57494cd92098Szrj default:
5750c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(0x00000000);
57514cd92098Szrj break;
57524cd92098Szrj }
57534cd92098Szrj
5754c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
5755c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
57564cd92098Szrj
5757c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0));
5758c6f73aabSFrançois Tigeot buffer[count++] = cpu_to_le32(0);
575957e252bfSMichael Neumann }
576057e252bfSMichael Neumann
si_init_pg(struct radeon_device * rdev)576157e252bfSMichael Neumann static void si_init_pg(struct radeon_device *rdev)
576257e252bfSMichael Neumann {
57634cd92098Szrj if (rdev->pg_flags) {
57644cd92098Szrj if (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA) {
576557e252bfSMichael Neumann si_init_dma_pg(rdev);
57664cd92098Szrj }
57674cd92098Szrj si_init_ao_cu_mask(rdev);
57684cd92098Szrj if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) {
576957e252bfSMichael Neumann si_init_gfx_cgpg(rdev);
5770c6f73aabSFrançois Tigeot } else {
5771c6f73aabSFrançois Tigeot WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
5772c6f73aabSFrançois Tigeot WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
57734cd92098Szrj }
57744cd92098Szrj si_enable_dma_pg(rdev, true);
577557e252bfSMichael Neumann si_enable_gfx_cgpg(rdev, true);
577657e252bfSMichael Neumann } else {
577757e252bfSMichael Neumann WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
577857e252bfSMichael Neumann WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
577957e252bfSMichael Neumann }
578057e252bfSMichael Neumann }
578157e252bfSMichael Neumann
si_fini_pg(struct radeon_device * rdev)578257e252bfSMichael Neumann static void si_fini_pg(struct radeon_device *rdev)
578357e252bfSMichael Neumann {
57844cd92098Szrj if (rdev->pg_flags) {
578557e252bfSMichael Neumann si_enable_dma_pg(rdev, false);
578657e252bfSMichael Neumann si_enable_gfx_cgpg(rdev, false);
578757e252bfSMichael Neumann }
578857e252bfSMichael Neumann }
578957e252bfSMichael Neumann
579057e252bfSMichael Neumann /*
5791926deccbSFrançois Tigeot * RLC
5792926deccbSFrançois Tigeot */
si_rlc_reset(struct radeon_device * rdev)57934cd92098Szrj void si_rlc_reset(struct radeon_device *rdev)
579457e252bfSMichael Neumann {
579557e252bfSMichael Neumann u32 tmp = RREG32(GRBM_SOFT_RESET);
579657e252bfSMichael Neumann
579757e252bfSMichael Neumann tmp |= SOFT_RESET_RLC;
579857e252bfSMichael Neumann WREG32(GRBM_SOFT_RESET, tmp);
5799c4ef309bSzrj udelay(50);
580057e252bfSMichael Neumann tmp &= ~SOFT_RESET_RLC;
580157e252bfSMichael Neumann WREG32(GRBM_SOFT_RESET, tmp);
5802c4ef309bSzrj udelay(50);
580357e252bfSMichael Neumann }
580457e252bfSMichael Neumann
si_rlc_stop(struct radeon_device * rdev)5805926deccbSFrançois Tigeot static void si_rlc_stop(struct radeon_device *rdev)
5806926deccbSFrançois Tigeot {
5807926deccbSFrançois Tigeot WREG32(RLC_CNTL, 0);
580857e252bfSMichael Neumann
580957e252bfSMichael Neumann si_enable_gui_idle_interrupt(rdev, false);
581057e252bfSMichael Neumann
581157e252bfSMichael Neumann si_wait_for_rlc_serdes(rdev);
5812926deccbSFrançois Tigeot }
5813926deccbSFrançois Tigeot
si_rlc_start(struct radeon_device * rdev)5814926deccbSFrançois Tigeot static void si_rlc_start(struct radeon_device *rdev)
5815926deccbSFrançois Tigeot {
5816926deccbSFrançois Tigeot WREG32(RLC_CNTL, RLC_ENABLE);
581757e252bfSMichael Neumann
581857e252bfSMichael Neumann si_enable_gui_idle_interrupt(rdev, true);
581957e252bfSMichael Neumann
5820c4ef309bSzrj udelay(50);
582157e252bfSMichael Neumann }
582257e252bfSMichael Neumann
si_lbpw_supported(struct radeon_device * rdev)582357e252bfSMichael Neumann static bool si_lbpw_supported(struct radeon_device *rdev)
582457e252bfSMichael Neumann {
582557e252bfSMichael Neumann u32 tmp;
582657e252bfSMichael Neumann
582757e252bfSMichael Neumann /* Enable LBPW only for DDR3 */
582857e252bfSMichael Neumann tmp = RREG32(MC_SEQ_MISC0);
582957e252bfSMichael Neumann if ((tmp & 0xF0000000) == 0xB0000000)
583057e252bfSMichael Neumann return true;
583157e252bfSMichael Neumann return false;
583257e252bfSMichael Neumann }
583357e252bfSMichael Neumann
si_enable_lbpw(struct radeon_device * rdev,bool enable)583457e252bfSMichael Neumann static void si_enable_lbpw(struct radeon_device *rdev, bool enable)
583557e252bfSMichael Neumann {
583657e252bfSMichael Neumann u32 tmp;
583757e252bfSMichael Neumann
583857e252bfSMichael Neumann tmp = RREG32(RLC_LB_CNTL);
583957e252bfSMichael Neumann if (enable)
584057e252bfSMichael Neumann tmp |= LOAD_BALANCE_ENABLE;
584157e252bfSMichael Neumann else
584257e252bfSMichael Neumann tmp &= ~LOAD_BALANCE_ENABLE;
584357e252bfSMichael Neumann WREG32(RLC_LB_CNTL, tmp);
584457e252bfSMichael Neumann
584557e252bfSMichael Neumann if (!enable) {
584657e252bfSMichael Neumann si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
584757e252bfSMichael Neumann WREG32(SPI_LB_CU_MASK, 0x00ff);
584857e252bfSMichael Neumann }
5849926deccbSFrançois Tigeot }
5850926deccbSFrançois Tigeot
si_rlc_resume(struct radeon_device * rdev)5851926deccbSFrançois Tigeot static int si_rlc_resume(struct radeon_device *rdev)
5852926deccbSFrançois Tigeot {
5853926deccbSFrançois Tigeot u32 i;
5854926deccbSFrançois Tigeot
5855926deccbSFrançois Tigeot if (!rdev->rlc_fw)
5856926deccbSFrançois Tigeot return -EINVAL;
5857926deccbSFrançois Tigeot
5858926deccbSFrançois Tigeot si_rlc_stop(rdev);
5859926deccbSFrançois Tigeot
586057e252bfSMichael Neumann si_rlc_reset(rdev);
586157e252bfSMichael Neumann
586257e252bfSMichael Neumann si_init_pg(rdev);
586357e252bfSMichael Neumann
586457e252bfSMichael Neumann si_init_cg(rdev);
586557e252bfSMichael Neumann
5866926deccbSFrançois Tigeot WREG32(RLC_RL_BASE, 0);
5867926deccbSFrançois Tigeot WREG32(RLC_RL_SIZE, 0);
5868926deccbSFrançois Tigeot WREG32(RLC_LB_CNTL, 0);
5869926deccbSFrançois Tigeot WREG32(RLC_LB_CNTR_MAX, 0xffffffff);
5870926deccbSFrançois Tigeot WREG32(RLC_LB_CNTR_INIT, 0);
587157e252bfSMichael Neumann WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff);
5872926deccbSFrançois Tigeot
5873926deccbSFrançois Tigeot WREG32(RLC_MC_CNTL, 0);
5874926deccbSFrançois Tigeot WREG32(RLC_UCODE_CNTL, 0);
5875926deccbSFrançois Tigeot
5876cb754608SImre Vadász if (rdev->new_fw) {
5877cb754608SImre Vadász const struct rlc_firmware_header_v1_0 *hdr =
5878cb754608SImre Vadász (const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data;
5879cb754608SImre Vadász u32 fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
5880cb754608SImre Vadász const __le32 *fw_data = (const __le32 *)
5881c59a5c48SFrançois Tigeot (rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
5882cb754608SImre Vadász
5883cb754608SImre Vadász radeon_ucode_print_rlc_hdr(&hdr->header);
5884cb754608SImre Vadász
5885cb754608SImre Vadász for (i = 0; i < fw_size; i++) {
5886cb754608SImre Vadász WREG32(RLC_UCODE_ADDR, i);
5887cb754608SImre Vadász WREG32(RLC_UCODE_DATA, le32_to_cpup(fw_data++));
5888cb754608SImre Vadász }
5889cb754608SImre Vadász } else {
5890cb754608SImre Vadász const __be32 *fw_data =
5891cb754608SImre Vadász (const __be32 *)rdev->rlc_fw->data;
5892926deccbSFrançois Tigeot for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
5893926deccbSFrançois Tigeot WREG32(RLC_UCODE_ADDR, i);
5894926deccbSFrançois Tigeot WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
5895926deccbSFrançois Tigeot }
5896cb754608SImre Vadász }
5897926deccbSFrançois Tigeot WREG32(RLC_UCODE_ADDR, 0);
5898926deccbSFrançois Tigeot
589957e252bfSMichael Neumann si_enable_lbpw(rdev, si_lbpw_supported(rdev));
590057e252bfSMichael Neumann
5901926deccbSFrançois Tigeot si_rlc_start(rdev);
5902926deccbSFrançois Tigeot
5903926deccbSFrançois Tigeot return 0;
5904926deccbSFrançois Tigeot }
5905926deccbSFrançois Tigeot
si_enable_interrupts(struct radeon_device * rdev)5906926deccbSFrançois Tigeot static void si_enable_interrupts(struct radeon_device *rdev)
5907926deccbSFrançois Tigeot {
5908926deccbSFrançois Tigeot u32 ih_cntl = RREG32(IH_CNTL);
5909926deccbSFrançois Tigeot u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
5910926deccbSFrançois Tigeot
5911926deccbSFrançois Tigeot ih_cntl |= ENABLE_INTR;
5912926deccbSFrançois Tigeot ih_rb_cntl |= IH_RB_ENABLE;
5913926deccbSFrançois Tigeot WREG32(IH_CNTL, ih_cntl);
5914926deccbSFrançois Tigeot WREG32(IH_RB_CNTL, ih_rb_cntl);
5915926deccbSFrançois Tigeot rdev->ih.enabled = true;
5916926deccbSFrançois Tigeot }
5917926deccbSFrançois Tigeot
si_disable_interrupts(struct radeon_device * rdev)5918926deccbSFrançois Tigeot static void si_disable_interrupts(struct radeon_device *rdev)
5919926deccbSFrançois Tigeot {
5920926deccbSFrançois Tigeot u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
5921926deccbSFrançois Tigeot u32 ih_cntl = RREG32(IH_CNTL);
5922926deccbSFrançois Tigeot
5923926deccbSFrançois Tigeot ih_rb_cntl &= ~IH_RB_ENABLE;
5924926deccbSFrançois Tigeot ih_cntl &= ~ENABLE_INTR;
5925926deccbSFrançois Tigeot WREG32(IH_RB_CNTL, ih_rb_cntl);
5926926deccbSFrançois Tigeot WREG32(IH_CNTL, ih_cntl);
5927926deccbSFrançois Tigeot /* set rptr, wptr to 0 */
5928926deccbSFrançois Tigeot WREG32(IH_RB_RPTR, 0);
5929926deccbSFrançois Tigeot WREG32(IH_RB_WPTR, 0);
5930926deccbSFrançois Tigeot rdev->ih.enabled = false;
5931926deccbSFrançois Tigeot rdev->ih.rptr = 0;
5932926deccbSFrançois Tigeot }
5933926deccbSFrançois Tigeot
si_disable_interrupt_state(struct radeon_device * rdev)5934926deccbSFrançois Tigeot static void si_disable_interrupt_state(struct radeon_device *rdev)
5935926deccbSFrançois Tigeot {
5936*3f2dd94aSFrançois Tigeot int i;
5937926deccbSFrançois Tigeot u32 tmp;
5938926deccbSFrançois Tigeot
59394cd92098Szrj tmp = RREG32(CP_INT_CNTL_RING0) &
59404cd92098Szrj (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
59414cd92098Szrj WREG32(CP_INT_CNTL_RING0, tmp);
5942926deccbSFrançois Tigeot WREG32(CP_INT_CNTL_RING1, 0);
5943926deccbSFrançois Tigeot WREG32(CP_INT_CNTL_RING2, 0);
5944926deccbSFrançois Tigeot tmp = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
5945926deccbSFrançois Tigeot WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, tmp);
5946926deccbSFrançois Tigeot tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
5947926deccbSFrançois Tigeot WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp);
5948926deccbSFrançois Tigeot WREG32(GRBM_INT_CNTL, 0);
5949c59a5c48SFrançois Tigeot WREG32(SRBM_INT_CNTL, 0);
5950*3f2dd94aSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i++)
5951*3f2dd94aSFrançois Tigeot WREG32(INT_MASK + crtc_offsets[i], 0);
5952*3f2dd94aSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i++)
5953*3f2dd94aSFrançois Tigeot WREG32(GRPH_INT_CONTROL + crtc_offsets[i], 0);
5954926deccbSFrançois Tigeot
5955f43cf1b1SMichael Neumann if (!ASIC_IS_NODCE(rdev)) {
5956c6f73aabSFrançois Tigeot WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
5957926deccbSFrançois Tigeot
5958*3f2dd94aSFrançois Tigeot for (i = 0; i < 6; i++)
5959*3f2dd94aSFrançois Tigeot WREG32_AND(DC_HPDx_INT_CONTROL(i),
5960*3f2dd94aSFrançois Tigeot DC_HPDx_INT_POLARITY);
5961f43cf1b1SMichael Neumann }
5962926deccbSFrançois Tigeot }
5963926deccbSFrançois Tigeot
si_irq_init(struct radeon_device * rdev)5964926deccbSFrançois Tigeot static int si_irq_init(struct radeon_device *rdev)
5965926deccbSFrançois Tigeot {
5966926deccbSFrançois Tigeot int ret = 0;
5967926deccbSFrançois Tigeot int rb_bufsz;
5968926deccbSFrançois Tigeot u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
5969926deccbSFrançois Tigeot
5970926deccbSFrançois Tigeot /* allocate ring */
5971926deccbSFrançois Tigeot ret = r600_ih_ring_alloc(rdev);
5972926deccbSFrançois Tigeot if (ret)
5973926deccbSFrançois Tigeot return ret;
5974926deccbSFrançois Tigeot
5975926deccbSFrançois Tigeot /* disable irqs */
5976926deccbSFrançois Tigeot si_disable_interrupts(rdev);
5977926deccbSFrançois Tigeot
5978926deccbSFrançois Tigeot /* init rlc */
5979926deccbSFrançois Tigeot ret = si_rlc_resume(rdev);
5980926deccbSFrançois Tigeot if (ret) {
5981926deccbSFrançois Tigeot r600_ih_ring_fini(rdev);
5982926deccbSFrançois Tigeot return ret;
5983926deccbSFrançois Tigeot }
5984926deccbSFrançois Tigeot
5985926deccbSFrançois Tigeot /* setup interrupt control */
5986926deccbSFrançois Tigeot /* set dummy read address to ring address */
5987926deccbSFrançois Tigeot WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
5988926deccbSFrançois Tigeot interrupt_cntl = RREG32(INTERRUPT_CNTL);
5989926deccbSFrançois Tigeot /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
5990926deccbSFrançois Tigeot * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
5991926deccbSFrançois Tigeot */
5992926deccbSFrançois Tigeot interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
5993926deccbSFrançois Tigeot /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
5994926deccbSFrançois Tigeot interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
5995926deccbSFrançois Tigeot WREG32(INTERRUPT_CNTL, interrupt_cntl);
5996926deccbSFrançois Tigeot
5997926deccbSFrançois Tigeot WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
59984cd92098Szrj rb_bufsz = order_base_2(rdev->ih.ring_size / 4);
5999926deccbSFrançois Tigeot
6000926deccbSFrançois Tigeot ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
6001926deccbSFrançois Tigeot IH_WPTR_OVERFLOW_CLEAR |
6002926deccbSFrançois Tigeot (rb_bufsz << 1));
6003926deccbSFrançois Tigeot
6004926deccbSFrançois Tigeot if (rdev->wb.enabled)
6005926deccbSFrançois Tigeot ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;
6006926deccbSFrançois Tigeot
6007926deccbSFrançois Tigeot /* set the writeback address whether it's enabled or not */
6008926deccbSFrançois Tigeot WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC);
6009926deccbSFrançois Tigeot WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF);
6010926deccbSFrançois Tigeot
6011926deccbSFrançois Tigeot WREG32(IH_RB_CNTL, ih_rb_cntl);
6012926deccbSFrançois Tigeot
6013926deccbSFrançois Tigeot /* set rptr, wptr to 0 */
6014926deccbSFrançois Tigeot WREG32(IH_RB_RPTR, 0);
6015926deccbSFrançois Tigeot WREG32(IH_RB_WPTR, 0);
6016926deccbSFrançois Tigeot
6017926deccbSFrançois Tigeot /* Default settings for IH_CNTL (disabled at first) */
6018926deccbSFrançois Tigeot ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0);
6019926deccbSFrançois Tigeot /* RPTR_REARM only works if msi's are enabled */
6020926deccbSFrançois Tigeot if (rdev->msi_enabled)
6021926deccbSFrançois Tigeot ih_cntl |= RPTR_REARM;
6022926deccbSFrançois Tigeot WREG32(IH_CNTL, ih_cntl);
6023926deccbSFrançois Tigeot
6024926deccbSFrançois Tigeot /* force the active interrupt state to all disabled */
6025926deccbSFrançois Tigeot si_disable_interrupt_state(rdev);
6026926deccbSFrançois Tigeot
6027c59a5c48SFrançois Tigeot pci_set_master(rdev->pdev);
6028926deccbSFrançois Tigeot
6029926deccbSFrançois Tigeot /* enable irqs */
6030926deccbSFrançois Tigeot si_enable_interrupts(rdev);
6031926deccbSFrançois Tigeot
6032926deccbSFrançois Tigeot return ret;
6033926deccbSFrançois Tigeot }
6034926deccbSFrançois Tigeot
6035*3f2dd94aSFrançois Tigeot /* The order we write back each register here is important */
si_irq_set(struct radeon_device * rdev)6036926deccbSFrançois Tigeot int si_irq_set(struct radeon_device *rdev)
6037926deccbSFrançois Tigeot {
6038*3f2dd94aSFrançois Tigeot int i;
60394cd92098Szrj u32 cp_int_cntl;
6040926deccbSFrançois Tigeot u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
6041926deccbSFrançois Tigeot u32 grbm_int_cntl = 0;
6042926deccbSFrançois Tigeot u32 dma_cntl, dma_cntl1;
604357e252bfSMichael Neumann u32 thermal_int = 0;
6044926deccbSFrançois Tigeot
6045926deccbSFrançois Tigeot if (!rdev->irq.installed) {
6046c4ef309bSzrj WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
6047926deccbSFrançois Tigeot return -EINVAL;
6048926deccbSFrançois Tigeot }
6049926deccbSFrançois Tigeot /* don't enable anything if the ih is disabled */
6050926deccbSFrançois Tigeot if (!rdev->ih.enabled) {
6051926deccbSFrançois Tigeot si_disable_interrupts(rdev);
6052926deccbSFrançois Tigeot /* force the active interrupt state to all disabled */
6053926deccbSFrançois Tigeot si_disable_interrupt_state(rdev);
6054926deccbSFrançois Tigeot return 0;
6055926deccbSFrançois Tigeot }
6056926deccbSFrançois Tigeot
60574cd92098Szrj cp_int_cntl = RREG32(CP_INT_CNTL_RING0) &
60584cd92098Szrj (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
60594cd92098Szrj
6060926deccbSFrançois Tigeot dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
6061926deccbSFrançois Tigeot dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
6062926deccbSFrançois Tigeot
606357e252bfSMichael Neumann thermal_int = RREG32(CG_THERMAL_INT) &
606457e252bfSMichael Neumann ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
606557e252bfSMichael Neumann
6066926deccbSFrançois Tigeot /* enable CP interrupts on all rings */
6067926deccbSFrançois Tigeot if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
6068926deccbSFrançois Tigeot DRM_DEBUG("si_irq_set: sw int gfx\n");
6069926deccbSFrançois Tigeot cp_int_cntl |= TIME_STAMP_INT_ENABLE;
6070926deccbSFrançois Tigeot }
6071926deccbSFrançois Tigeot if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
6072926deccbSFrançois Tigeot DRM_DEBUG("si_irq_set: sw int cp1\n");
6073926deccbSFrançois Tigeot cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
6074926deccbSFrançois Tigeot }
6075926deccbSFrançois Tigeot if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
6076926deccbSFrançois Tigeot DRM_DEBUG("si_irq_set: sw int cp2\n");
6077926deccbSFrançois Tigeot cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
6078926deccbSFrançois Tigeot }
6079926deccbSFrançois Tigeot if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
6080926deccbSFrançois Tigeot DRM_DEBUG("si_irq_set: sw int dma\n");
6081926deccbSFrançois Tigeot dma_cntl |= TRAP_ENABLE;
6082926deccbSFrançois Tigeot }
6083926deccbSFrançois Tigeot
6084926deccbSFrançois Tigeot if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
6085926deccbSFrançois Tigeot DRM_DEBUG("si_irq_set: sw int dma1\n");
6086926deccbSFrançois Tigeot dma_cntl1 |= TRAP_ENABLE;
6087926deccbSFrançois Tigeot }
6088926deccbSFrançois Tigeot
6089926deccbSFrançois Tigeot WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
6090926deccbSFrançois Tigeot WREG32(CP_INT_CNTL_RING1, cp_int_cntl1);
6091926deccbSFrançois Tigeot WREG32(CP_INT_CNTL_RING2, cp_int_cntl2);
6092926deccbSFrançois Tigeot
6093926deccbSFrançois Tigeot WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, dma_cntl);
6094926deccbSFrançois Tigeot WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, dma_cntl1);
6095926deccbSFrançois Tigeot
6096926deccbSFrançois Tigeot WREG32(GRBM_INT_CNTL, grbm_int_cntl);
6097926deccbSFrançois Tigeot
609857e252bfSMichael Neumann if (rdev->irq.dpm_thermal) {
609957e252bfSMichael Neumann DRM_DEBUG("dpm thermal\n");
610057e252bfSMichael Neumann thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
610157e252bfSMichael Neumann }
610257e252bfSMichael Neumann
6103*3f2dd94aSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i++) {
6104*3f2dd94aSFrançois Tigeot radeon_irq_kms_set_irq_n_enabled(
6105*3f2dd94aSFrançois Tigeot rdev, INT_MASK + crtc_offsets[i], VBLANK_INT_MASK,
6106*3f2dd94aSFrançois Tigeot rdev->irq.crtc_vblank_int[i] ||
6107*3f2dd94aSFrançois Tigeot atomic_read(&rdev->irq.pflip[i]), "vblank", i);
6108926deccbSFrançois Tigeot }
6109926deccbSFrançois Tigeot
6110*3f2dd94aSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i++)
6111*3f2dd94aSFrançois Tigeot WREG32(GRPH_INT_CONTROL + crtc_offsets[i], GRPH_PFLIP_INT_MASK);
6112926deccbSFrançois Tigeot
6113f43cf1b1SMichael Neumann if (!ASIC_IS_NODCE(rdev)) {
6114*3f2dd94aSFrançois Tigeot for (i = 0; i < 6; i++) {
6115*3f2dd94aSFrançois Tigeot radeon_irq_kms_set_irq_n_enabled(
6116*3f2dd94aSFrançois Tigeot rdev, DC_HPDx_INT_CONTROL(i),
6117*3f2dd94aSFrançois Tigeot DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN,
6118*3f2dd94aSFrançois Tigeot rdev->irq.hpd[i], "HPD", i);
6119*3f2dd94aSFrançois Tigeot }
6120f43cf1b1SMichael Neumann }
6121926deccbSFrançois Tigeot
612257e252bfSMichael Neumann WREG32(CG_THERMAL_INT, thermal_int);
612357e252bfSMichael Neumann
61247dcf36dcSFrançois Tigeot /* posting read */
61257dcf36dcSFrançois Tigeot RREG32(SRBM_STATUS);
61267dcf36dcSFrançois Tigeot
6127926deccbSFrançois Tigeot return 0;
6128926deccbSFrançois Tigeot }
6129926deccbSFrançois Tigeot
6130*3f2dd94aSFrançois Tigeot /* The order we write back each register here is important */
si_irq_ack(struct radeon_device * rdev)6131926deccbSFrançois Tigeot static inline void si_irq_ack(struct radeon_device *rdev)
6132926deccbSFrançois Tigeot {
6133*3f2dd94aSFrançois Tigeot int i, j;
6134*3f2dd94aSFrançois Tigeot u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
6135*3f2dd94aSFrançois Tigeot u32 *grph_int = rdev->irq.stat_regs.evergreen.grph_int;
6136926deccbSFrançois Tigeot
6137f43cf1b1SMichael Neumann if (ASIC_IS_NODCE(rdev))
6138f43cf1b1SMichael Neumann return;
6139f43cf1b1SMichael Neumann
6140*3f2dd94aSFrançois Tigeot for (i = 0; i < 6; i++) {
6141*3f2dd94aSFrançois Tigeot disp_int[i] = RREG32(si_disp_int_status[i]);
6142*3f2dd94aSFrançois Tigeot if (i < rdev->num_crtc)
6143*3f2dd94aSFrançois Tigeot grph_int[i] = RREG32(GRPH_INT_STATUS + crtc_offsets[i]);
6144926deccbSFrançois Tigeot }
6145926deccbSFrançois Tigeot
6146*3f2dd94aSFrançois Tigeot /* We write back each interrupt register in pairs of two */
6147*3f2dd94aSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i += 2) {
6148*3f2dd94aSFrançois Tigeot for (j = i; j < (i + 2); j++) {
6149*3f2dd94aSFrançois Tigeot if (grph_int[j] & GRPH_PFLIP_INT_OCCURRED)
6150*3f2dd94aSFrançois Tigeot WREG32(GRPH_INT_STATUS + crtc_offsets[j],
6151*3f2dd94aSFrançois Tigeot GRPH_PFLIP_INT_CLEAR);
6152926deccbSFrançois Tigeot }
6153926deccbSFrançois Tigeot
6154*3f2dd94aSFrançois Tigeot for (j = i; j < (i + 2); j++) {
6155*3f2dd94aSFrançois Tigeot if (disp_int[j] & LB_D1_VBLANK_INTERRUPT)
6156*3f2dd94aSFrançois Tigeot WREG32(VBLANK_STATUS + crtc_offsets[j],
6157*3f2dd94aSFrançois Tigeot VBLANK_ACK);
6158*3f2dd94aSFrançois Tigeot if (disp_int[j] & LB_D1_VLINE_INTERRUPT)
6159*3f2dd94aSFrançois Tigeot WREG32(VLINE_STATUS + crtc_offsets[j],
6160*3f2dd94aSFrançois Tigeot VLINE_ACK);
6161*3f2dd94aSFrançois Tigeot }
6162926deccbSFrançois Tigeot }
6163926deccbSFrançois Tigeot
6164*3f2dd94aSFrançois Tigeot for (i = 0; i < 6; i++) {
6165*3f2dd94aSFrançois Tigeot if (disp_int[i] & DC_HPD1_INTERRUPT)
6166*3f2dd94aSFrançois Tigeot WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_ACK);
6167926deccbSFrançois Tigeot }
6168c59a5c48SFrançois Tigeot
6169*3f2dd94aSFrançois Tigeot for (i = 0; i < 6; i++) {
6170*3f2dd94aSFrançois Tigeot if (disp_int[i] & DC_HPD1_RX_INTERRUPT)
6171*3f2dd94aSFrançois Tigeot WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK);
6172c59a5c48SFrançois Tigeot }
6173926deccbSFrançois Tigeot }
6174926deccbSFrançois Tigeot
si_irq_disable(struct radeon_device * rdev)6175926deccbSFrançois Tigeot static void si_irq_disable(struct radeon_device *rdev)
6176926deccbSFrançois Tigeot {
6177926deccbSFrançois Tigeot si_disable_interrupts(rdev);
6178926deccbSFrançois Tigeot /* Wait and acknowledge irq */
6179c4ef309bSzrj mdelay(1);
6180926deccbSFrançois Tigeot si_irq_ack(rdev);
6181926deccbSFrançois Tigeot si_disable_interrupt_state(rdev);
6182926deccbSFrançois Tigeot }
6183926deccbSFrançois Tigeot
si_irq_suspend(struct radeon_device * rdev)6184926deccbSFrançois Tigeot static void si_irq_suspend(struct radeon_device *rdev)
6185926deccbSFrançois Tigeot {
6186926deccbSFrançois Tigeot si_irq_disable(rdev);
6187926deccbSFrançois Tigeot si_rlc_stop(rdev);
6188926deccbSFrançois Tigeot }
6189926deccbSFrançois Tigeot
si_irq_fini(struct radeon_device * rdev)6190926deccbSFrançois Tigeot static void si_irq_fini(struct radeon_device *rdev)
6191926deccbSFrançois Tigeot {
6192926deccbSFrançois Tigeot si_irq_suspend(rdev);
6193926deccbSFrançois Tigeot r600_ih_ring_fini(rdev);
6194926deccbSFrançois Tigeot }
6195926deccbSFrançois Tigeot
si_get_ih_wptr(struct radeon_device * rdev)6196926deccbSFrançois Tigeot static inline u32 si_get_ih_wptr(struct radeon_device *rdev)
6197926deccbSFrançois Tigeot {
6198926deccbSFrançois Tigeot u32 wptr, tmp;
6199926deccbSFrançois Tigeot
6200926deccbSFrançois Tigeot if (rdev->wb.enabled)
6201926deccbSFrançois Tigeot wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
6202926deccbSFrançois Tigeot else
6203926deccbSFrançois Tigeot wptr = RREG32(IH_RB_WPTR);
6204926deccbSFrançois Tigeot
6205926deccbSFrançois Tigeot if (wptr & RB_OVERFLOW) {
6206c6f73aabSFrançois Tigeot wptr &= ~RB_OVERFLOW;
6207926deccbSFrançois Tigeot /* When a ring buffer overflow happen start parsing interrupt
6208926deccbSFrançois Tigeot * from the last not overwritten vector (wptr + 16). Hopefully
6209926deccbSFrançois Tigeot * this should allow us to catchup.
6210926deccbSFrançois Tigeot */
6211c6f73aabSFrançois Tigeot dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
6212c6f73aabSFrançois Tigeot wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
6213926deccbSFrançois Tigeot rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
6214926deccbSFrançois Tigeot tmp = RREG32(IH_RB_CNTL);
6215926deccbSFrançois Tigeot tmp |= IH_WPTR_OVERFLOW_CLEAR;
6216926deccbSFrançois Tigeot WREG32(IH_RB_CNTL, tmp);
6217926deccbSFrançois Tigeot }
6218926deccbSFrançois Tigeot return (wptr & rdev->ih.ptr_mask);
6219926deccbSFrançois Tigeot }
6220926deccbSFrançois Tigeot
6221926deccbSFrançois Tigeot /* SI IV Ring
6222926deccbSFrançois Tigeot * Each IV ring entry is 128 bits:
6223926deccbSFrançois Tigeot * [7:0] - interrupt source id
6224926deccbSFrançois Tigeot * [31:8] - reserved
6225926deccbSFrançois Tigeot * [59:32] - interrupt source data
6226926deccbSFrançois Tigeot * [63:60] - reserved
6227926deccbSFrançois Tigeot * [71:64] - RINGID
6228926deccbSFrançois Tigeot * [79:72] - VMID
6229926deccbSFrançois Tigeot * [127:80] - reserved
6230926deccbSFrançois Tigeot */
si_irq_process(struct radeon_device * rdev)6231926deccbSFrançois Tigeot irqreturn_t si_irq_process(struct radeon_device *rdev)
6232926deccbSFrançois Tigeot {
6233*3f2dd94aSFrançois Tigeot u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
6234*3f2dd94aSFrançois Tigeot u32 crtc_idx, hpd_idx;
6235*3f2dd94aSFrançois Tigeot u32 mask;
6236926deccbSFrançois Tigeot u32 wptr;
6237926deccbSFrançois Tigeot u32 rptr;
6238926deccbSFrançois Tigeot u32 src_id, src_data, ring_id;
6239926deccbSFrançois Tigeot u32 ring_index;
6240926deccbSFrançois Tigeot bool queue_hotplug = false;
6241c59a5c48SFrançois Tigeot bool queue_dp = false;
624257e252bfSMichael Neumann bool queue_thermal = false;
624357e252bfSMichael Neumann u32 status, addr;
6244*3f2dd94aSFrançois Tigeot const char *event_name;
6245926deccbSFrançois Tigeot
6246926deccbSFrançois Tigeot if (!rdev->ih.enabled || rdev->shutdown)
6247926deccbSFrançois Tigeot return IRQ_NONE;
6248926deccbSFrançois Tigeot
6249926deccbSFrançois Tigeot wptr = si_get_ih_wptr(rdev);
6250926deccbSFrançois Tigeot
6251926deccbSFrançois Tigeot restart_ih:
6252926deccbSFrançois Tigeot /* is somebody else already processing irqs? */
6253926deccbSFrançois Tigeot if (atomic_xchg(&rdev->ih.lock, 1))
6254926deccbSFrançois Tigeot return IRQ_NONE;
6255926deccbSFrançois Tigeot
6256926deccbSFrançois Tigeot rptr = rdev->ih.rptr;
6257ee479021SImre Vadász DRM_DEBUG_VBLANK("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
6258926deccbSFrançois Tigeot
6259926deccbSFrançois Tigeot /* Order reading of wptr vs. reading of IH ring data */
6260c4ef309bSzrj rmb();
6261926deccbSFrançois Tigeot
6262926deccbSFrançois Tigeot /* display interrupts */
6263926deccbSFrançois Tigeot si_irq_ack(rdev);
6264926deccbSFrançois Tigeot
6265926deccbSFrançois Tigeot while (rptr != wptr) {
6266926deccbSFrançois Tigeot /* wptr/rptr are in bytes! */
6267926deccbSFrançois Tigeot ring_index = rptr / 4;
6268926deccbSFrançois Tigeot src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
6269926deccbSFrançois Tigeot src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
6270926deccbSFrançois Tigeot ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff;
6271926deccbSFrançois Tigeot
6272926deccbSFrançois Tigeot switch (src_id) {
6273926deccbSFrançois Tigeot case 1: /* D1 vblank/vline */
6274926deccbSFrançois Tigeot case 2: /* D2 vblank/vline */
6275926deccbSFrançois Tigeot case 3: /* D3 vblank/vline */
6276926deccbSFrançois Tigeot case 4: /* D4 vblank/vline */
6277926deccbSFrançois Tigeot case 5: /* D5 vblank/vline */
6278926deccbSFrançois Tigeot case 6: /* D6 vblank/vline */
6279*3f2dd94aSFrançois Tigeot crtc_idx = src_id - 1;
6280c59a5c48SFrançois Tigeot
6281*3f2dd94aSFrançois Tigeot if (src_data == 0) { /* vblank */
6282*3f2dd94aSFrançois Tigeot mask = LB_D1_VBLANK_INTERRUPT;
6283*3f2dd94aSFrançois Tigeot event_name = "vblank";
6284*3f2dd94aSFrançois Tigeot
6285*3f2dd94aSFrançois Tigeot if (rdev->irq.crtc_vblank_int[crtc_idx]) {
6286*3f2dd94aSFrançois Tigeot drm_handle_vblank(rdev->ddev, crtc_idx);
6287926deccbSFrançois Tigeot rdev->pm.vblank_sync = true;
6288c4ef309bSzrj wake_up(&rdev->irq.vblank_queue);
6289926deccbSFrançois Tigeot }
6290*3f2dd94aSFrançois Tigeot if (atomic_read(&rdev->irq.pflip[crtc_idx])) {
6291*3f2dd94aSFrançois Tigeot radeon_crtc_handle_vblank(rdev,
6292*3f2dd94aSFrançois Tigeot crtc_idx);
6293*3f2dd94aSFrançois Tigeot }
6294c59a5c48SFrançois Tigeot
6295*3f2dd94aSFrançois Tigeot } else if (src_data == 1) { /* vline */
6296*3f2dd94aSFrançois Tigeot mask = LB_D1_VLINE_INTERRUPT;
6297*3f2dd94aSFrançois Tigeot event_name = "vline";
6298*3f2dd94aSFrançois Tigeot } else {
6299*3f2dd94aSFrançois Tigeot DRM_DEBUG("Unhandled interrupt: %d %d\n",
6300*3f2dd94aSFrançois Tigeot src_id, src_data);
6301926deccbSFrançois Tigeot break;
6302926deccbSFrançois Tigeot }
6303*3f2dd94aSFrançois Tigeot
6304*3f2dd94aSFrançois Tigeot if (!(disp_int[crtc_idx] & mask)) {
6305*3f2dd94aSFrançois Tigeot DRM_DEBUG("IH: D%d %s - IH event w/o asserted irq bit?\n",
6306*3f2dd94aSFrançois Tigeot crtc_idx + 1, event_name);
6307*3f2dd94aSFrançois Tigeot }
6308*3f2dd94aSFrançois Tigeot
6309*3f2dd94aSFrançois Tigeot disp_int[crtc_idx] &= ~mask;
6310*3f2dd94aSFrançois Tigeot DRM_DEBUG("IH: D%d %s\n", crtc_idx + 1, event_name);
6311*3f2dd94aSFrançois Tigeot
6312926deccbSFrançois Tigeot break;
6313c6f73aabSFrançois Tigeot case 8: /* D1 page flip */
6314c6f73aabSFrançois Tigeot case 10: /* D2 page flip */
6315c6f73aabSFrançois Tigeot case 12: /* D3 page flip */
6316c6f73aabSFrançois Tigeot case 14: /* D4 page flip */
6317c6f73aabSFrançois Tigeot case 16: /* D5 page flip */
6318c6f73aabSFrançois Tigeot case 18: /* D6 page flip */
6319*3f2dd94aSFrançois Tigeot DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
6320c6f73aabSFrançois Tigeot if (radeon_use_pflipirq > 0)
6321c6f73aabSFrançois Tigeot radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
6322c6f73aabSFrançois Tigeot break;
6323926deccbSFrançois Tigeot case 42: /* HPD hotplug */
6324*3f2dd94aSFrançois Tigeot if (src_data <= 5) {
6325*3f2dd94aSFrançois Tigeot hpd_idx = src_data;
6326*3f2dd94aSFrançois Tigeot mask = DC_HPD1_INTERRUPT;
6327926deccbSFrançois Tigeot queue_hotplug = true;
6328*3f2dd94aSFrançois Tigeot event_name = "HPD";
6329c59a5c48SFrançois Tigeot
6330*3f2dd94aSFrançois Tigeot } else if (src_data <= 11) {
6331*3f2dd94aSFrançois Tigeot hpd_idx = src_data - 6;
6332*3f2dd94aSFrançois Tigeot mask = DC_HPD1_RX_INTERRUPT;
6333c59a5c48SFrançois Tigeot queue_dp = true;
6334*3f2dd94aSFrançois Tigeot event_name = "HPD_RX";
6335c59a5c48SFrançois Tigeot
6336*3f2dd94aSFrançois Tigeot } else {
6337*3f2dd94aSFrançois Tigeot DRM_DEBUG("Unhandled interrupt: %d %d\n",
6338*3f2dd94aSFrançois Tigeot src_id, src_data);
6339926deccbSFrançois Tigeot break;
6340926deccbSFrançois Tigeot }
6341*3f2dd94aSFrançois Tigeot
6342*3f2dd94aSFrançois Tigeot if (!(disp_int[hpd_idx] & mask))
6343*3f2dd94aSFrançois Tigeot DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
6344*3f2dd94aSFrançois Tigeot
6345*3f2dd94aSFrançois Tigeot disp_int[hpd_idx] &= ~mask;
6346*3f2dd94aSFrançois Tigeot DRM_DEBUG("IH: %s%d\n", event_name, hpd_idx + 1);
6347926deccbSFrançois Tigeot break;
6348c59a5c48SFrançois Tigeot case 96:
6349c59a5c48SFrançois Tigeot DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR));
6350c59a5c48SFrançois Tigeot WREG32(SRBM_INT_ACK, 0x1);
6351c59a5c48SFrançois Tigeot break;
6352c6f73aabSFrançois Tigeot case 124: /* UVD */
6353c6f73aabSFrançois Tigeot DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
6354c6f73aabSFrançois Tigeot radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
6355c6f73aabSFrançois Tigeot break;
6356926deccbSFrançois Tigeot case 146:
6357926deccbSFrançois Tigeot case 147:
635857e252bfSMichael Neumann addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
635957e252bfSMichael Neumann status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
6360c6f73aabSFrançois Tigeot /* reset addr and status */
6361c6f73aabSFrançois Tigeot WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
6362c6f73aabSFrançois Tigeot if (addr == 0x0 && status == 0x0)
6363c6f73aabSFrançois Tigeot break;
6364926deccbSFrançois Tigeot dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
6365926deccbSFrançois Tigeot dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
636657e252bfSMichael Neumann addr);
6367926deccbSFrançois Tigeot dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
636857e252bfSMichael Neumann status);
636957e252bfSMichael Neumann si_vm_decode_fault(rdev, status, addr);
6370926deccbSFrançois Tigeot break;
6371926deccbSFrançois Tigeot case 176: /* RINGID0 CP_INT */
6372926deccbSFrançois Tigeot radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
6373926deccbSFrançois Tigeot break;
6374926deccbSFrançois Tigeot case 177: /* RINGID1 CP_INT */
6375926deccbSFrançois Tigeot radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6376926deccbSFrançois Tigeot break;
6377926deccbSFrançois Tigeot case 178: /* RINGID2 CP_INT */
6378926deccbSFrançois Tigeot radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6379926deccbSFrançois Tigeot break;
6380926deccbSFrançois Tigeot case 181: /* CP EOP event */
6381926deccbSFrançois Tigeot DRM_DEBUG("IH: CP EOP\n");
6382926deccbSFrançois Tigeot switch (ring_id) {
6383926deccbSFrançois Tigeot case 0:
6384926deccbSFrançois Tigeot radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
6385926deccbSFrançois Tigeot break;
6386926deccbSFrançois Tigeot case 1:
6387926deccbSFrançois Tigeot radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6388926deccbSFrançois Tigeot break;
6389926deccbSFrançois Tigeot case 2:
6390926deccbSFrançois Tigeot radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6391926deccbSFrançois Tigeot break;
6392926deccbSFrançois Tigeot }
6393926deccbSFrançois Tigeot break;
6394926deccbSFrançois Tigeot case 224: /* DMA trap event */
6395926deccbSFrançois Tigeot DRM_DEBUG("IH: DMA trap\n");
6396926deccbSFrançois Tigeot radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
6397926deccbSFrançois Tigeot break;
639857e252bfSMichael Neumann case 230: /* thermal low to high */
639957e252bfSMichael Neumann DRM_DEBUG("IH: thermal low to high\n");
640057e252bfSMichael Neumann rdev->pm.dpm.thermal.high_to_low = false;
640157e252bfSMichael Neumann queue_thermal = true;
640257e252bfSMichael Neumann break;
640357e252bfSMichael Neumann case 231: /* thermal high to low */
640457e252bfSMichael Neumann DRM_DEBUG("IH: thermal high to low\n");
640557e252bfSMichael Neumann rdev->pm.dpm.thermal.high_to_low = true;
640657e252bfSMichael Neumann queue_thermal = true;
640757e252bfSMichael Neumann break;
6408926deccbSFrançois Tigeot case 233: /* GUI IDLE */
6409926deccbSFrançois Tigeot DRM_DEBUG("IH: GUI idle\n");
6410926deccbSFrançois Tigeot break;
6411926deccbSFrançois Tigeot case 244: /* DMA trap event */
6412926deccbSFrançois Tigeot DRM_DEBUG("IH: DMA1 trap\n");
6413926deccbSFrançois Tigeot radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
6414926deccbSFrançois Tigeot break;
6415926deccbSFrançois Tigeot default:
6416926deccbSFrançois Tigeot DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
6417926deccbSFrançois Tigeot break;
6418926deccbSFrançois Tigeot }
6419926deccbSFrançois Tigeot
6420926deccbSFrançois Tigeot /* wptr/rptr are in bytes! */
6421926deccbSFrançois Tigeot rptr += 16;
6422926deccbSFrançois Tigeot rptr &= rdev->ih.ptr_mask;
6423c6f73aabSFrançois Tigeot WREG32(IH_RB_RPTR, rptr);
6424926deccbSFrançois Tigeot }
6425c59a5c48SFrançois Tigeot if (queue_dp)
6426c59a5c48SFrançois Tigeot schedule_work(&rdev->dp_work);
6427926deccbSFrançois Tigeot if (queue_hotplug)
6428c59a5c48SFrançois Tigeot schedule_delayed_work(&rdev->hotplug_work, 0);
642957e252bfSMichael Neumann if (queue_thermal && rdev->pm.dpm_enabled)
64302c5cc6b9SFrançois Tigeot schedule_work(&rdev->pm.dpm.thermal.work);
6431926deccbSFrançois Tigeot rdev->ih.rptr = rptr;
6432926deccbSFrançois Tigeot atomic_set(&rdev->ih.lock, 0);
6433926deccbSFrançois Tigeot
6434926deccbSFrançois Tigeot /* make sure wptr hasn't changed while processing */
6435926deccbSFrançois Tigeot wptr = si_get_ih_wptr(rdev);
6436926deccbSFrançois Tigeot if (wptr != rptr)
6437926deccbSFrançois Tigeot goto restart_ih;
6438926deccbSFrançois Tigeot
6439926deccbSFrançois Tigeot return IRQ_HANDLED;
6440926deccbSFrançois Tigeot }
6441926deccbSFrançois Tigeot
6442926deccbSFrançois Tigeot /*
6443926deccbSFrançois Tigeot * startup/shutdown callbacks
6444926deccbSFrançois Tigeot */
si_uvd_init(struct radeon_device * rdev)6445d78d3a22SFrançois Tigeot static void si_uvd_init(struct radeon_device *rdev)
6446d78d3a22SFrançois Tigeot {
6447d78d3a22SFrançois Tigeot int r;
6448d78d3a22SFrançois Tigeot
6449d78d3a22SFrançois Tigeot if (!rdev->has_uvd)
6450d78d3a22SFrançois Tigeot return;
6451d78d3a22SFrançois Tigeot
6452d78d3a22SFrançois Tigeot r = radeon_uvd_init(rdev);
6453d78d3a22SFrançois Tigeot if (r) {
6454d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
6455d78d3a22SFrançois Tigeot /*
6456d78d3a22SFrançois Tigeot * At this point rdev->uvd.vcpu_bo is NULL which trickles down
6457d78d3a22SFrançois Tigeot * to early fails uvd_v2_2_resume() and thus nothing happens
6458d78d3a22SFrançois Tigeot * there. So it is pointless to try to go through that code
6459d78d3a22SFrançois Tigeot * hence why we disable uvd here.
6460d78d3a22SFrançois Tigeot */
6461d78d3a22SFrançois Tigeot rdev->has_uvd = 0;
6462d78d3a22SFrançois Tigeot return;
6463d78d3a22SFrançois Tigeot }
6464d78d3a22SFrançois Tigeot rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
6465d78d3a22SFrançois Tigeot r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
6466d78d3a22SFrançois Tigeot }
6467d78d3a22SFrançois Tigeot
si_uvd_start(struct radeon_device * rdev)6468d78d3a22SFrançois Tigeot static void si_uvd_start(struct radeon_device *rdev)
6469d78d3a22SFrançois Tigeot {
6470d78d3a22SFrançois Tigeot int r;
6471d78d3a22SFrançois Tigeot
6472d78d3a22SFrançois Tigeot if (!rdev->has_uvd)
6473d78d3a22SFrançois Tigeot return;
6474d78d3a22SFrançois Tigeot
6475d78d3a22SFrançois Tigeot r = uvd_v2_2_resume(rdev);
6476d78d3a22SFrançois Tigeot if (r) {
6477d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
6478d78d3a22SFrançois Tigeot goto error;
6479d78d3a22SFrançois Tigeot }
6480d78d3a22SFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
6481d78d3a22SFrançois Tigeot if (r) {
6482d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
6483d78d3a22SFrançois Tigeot goto error;
6484d78d3a22SFrançois Tigeot }
6485d78d3a22SFrançois Tigeot return;
6486d78d3a22SFrançois Tigeot
6487d78d3a22SFrançois Tigeot error:
6488d78d3a22SFrançois Tigeot rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
6489d78d3a22SFrançois Tigeot }
6490d78d3a22SFrançois Tigeot
si_uvd_resume(struct radeon_device * rdev)6491d78d3a22SFrançois Tigeot static void si_uvd_resume(struct radeon_device *rdev)
6492d78d3a22SFrançois Tigeot {
6493d78d3a22SFrançois Tigeot struct radeon_ring *ring;
6494d78d3a22SFrançois Tigeot int r;
6495d78d3a22SFrançois Tigeot
6496d78d3a22SFrançois Tigeot if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
6497d78d3a22SFrançois Tigeot return;
6498d78d3a22SFrançois Tigeot
6499d78d3a22SFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
65001dedbd3bSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
6501d78d3a22SFrançois Tigeot if (r) {
6502d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
6503d78d3a22SFrançois Tigeot return;
6504d78d3a22SFrançois Tigeot }
6505d78d3a22SFrançois Tigeot r = uvd_v1_0_init(rdev);
6506d78d3a22SFrançois Tigeot if (r) {
6507d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
6508d78d3a22SFrançois Tigeot return;
6509d78d3a22SFrançois Tigeot }
6510d78d3a22SFrançois Tigeot }
6511d78d3a22SFrançois Tigeot
si_vce_init(struct radeon_device * rdev)6512d78d3a22SFrançois Tigeot static void si_vce_init(struct radeon_device *rdev)
6513d78d3a22SFrançois Tigeot {
6514d78d3a22SFrançois Tigeot int r;
6515d78d3a22SFrançois Tigeot
6516d78d3a22SFrançois Tigeot if (!rdev->has_vce)
6517d78d3a22SFrançois Tigeot return;
6518d78d3a22SFrançois Tigeot
6519d78d3a22SFrançois Tigeot r = radeon_vce_init(rdev);
6520d78d3a22SFrançois Tigeot if (r) {
6521d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed VCE (%d) init.\n", r);
6522d78d3a22SFrançois Tigeot /*
6523d78d3a22SFrançois Tigeot * At this point rdev->vce.vcpu_bo is NULL which trickles down
6524d78d3a22SFrançois Tigeot * to early fails si_vce_start() and thus nothing happens
6525d78d3a22SFrançois Tigeot * there. So it is pointless to try to go through that code
6526d78d3a22SFrançois Tigeot * hence why we disable vce here.
6527d78d3a22SFrançois Tigeot */
6528d78d3a22SFrançois Tigeot rdev->has_vce = 0;
6529d78d3a22SFrançois Tigeot return;
6530d78d3a22SFrançois Tigeot }
6531d78d3a22SFrançois Tigeot rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL;
6532d78d3a22SFrançois Tigeot r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096);
6533d78d3a22SFrançois Tigeot rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL;
6534d78d3a22SFrançois Tigeot r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096);
6535d78d3a22SFrançois Tigeot }
6536d78d3a22SFrançois Tigeot
si_vce_start(struct radeon_device * rdev)6537d78d3a22SFrançois Tigeot static void si_vce_start(struct radeon_device *rdev)
6538d78d3a22SFrançois Tigeot {
6539d78d3a22SFrançois Tigeot int r;
6540d78d3a22SFrançois Tigeot
6541d78d3a22SFrançois Tigeot if (!rdev->has_vce)
6542d78d3a22SFrançois Tigeot return;
6543d78d3a22SFrançois Tigeot
6544d78d3a22SFrançois Tigeot r = radeon_vce_resume(rdev);
6545d78d3a22SFrançois Tigeot if (r) {
6546d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
6547d78d3a22SFrançois Tigeot goto error;
6548d78d3a22SFrançois Tigeot }
6549d78d3a22SFrançois Tigeot r = vce_v1_0_resume(rdev);
6550d78d3a22SFrançois Tigeot if (r) {
6551d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
6552d78d3a22SFrançois Tigeot goto error;
6553d78d3a22SFrançois Tigeot }
6554d78d3a22SFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
6555d78d3a22SFrançois Tigeot if (r) {
6556d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r);
6557d78d3a22SFrançois Tigeot goto error;
6558d78d3a22SFrançois Tigeot }
6559d78d3a22SFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
6560d78d3a22SFrançois Tigeot if (r) {
6561d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r);
6562d78d3a22SFrançois Tigeot goto error;
6563d78d3a22SFrançois Tigeot }
6564d78d3a22SFrançois Tigeot return;
6565d78d3a22SFrançois Tigeot
6566d78d3a22SFrançois Tigeot error:
6567d78d3a22SFrançois Tigeot rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
6568d78d3a22SFrançois Tigeot rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
6569d78d3a22SFrançois Tigeot }
6570d78d3a22SFrançois Tigeot
si_vce_resume(struct radeon_device * rdev)6571d78d3a22SFrançois Tigeot static void si_vce_resume(struct radeon_device *rdev)
6572d78d3a22SFrançois Tigeot {
6573d78d3a22SFrançois Tigeot struct radeon_ring *ring;
6574d78d3a22SFrançois Tigeot int r;
6575d78d3a22SFrançois Tigeot
6576d78d3a22SFrançois Tigeot if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size)
6577d78d3a22SFrançois Tigeot return;
6578d78d3a22SFrançois Tigeot
6579d78d3a22SFrançois Tigeot ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
6580d78d3a22SFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
6581d78d3a22SFrançois Tigeot if (r) {
6582d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
6583d78d3a22SFrançois Tigeot return;
6584d78d3a22SFrançois Tigeot }
6585d78d3a22SFrançois Tigeot ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
6586d78d3a22SFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
6587d78d3a22SFrançois Tigeot if (r) {
6588d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
6589d78d3a22SFrançois Tigeot return;
6590d78d3a22SFrançois Tigeot }
6591d78d3a22SFrançois Tigeot r = vce_v1_0_init(rdev);
6592d78d3a22SFrançois Tigeot if (r) {
6593d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE (%d).\n", r);
6594d78d3a22SFrançois Tigeot return;
6595d78d3a22SFrançois Tigeot }
6596d78d3a22SFrançois Tigeot }
6597d78d3a22SFrançois Tigeot
si_startup(struct radeon_device * rdev)6598926deccbSFrançois Tigeot static int si_startup(struct radeon_device *rdev)
6599926deccbSFrançois Tigeot {
6600926deccbSFrançois Tigeot struct radeon_ring *ring;
6601926deccbSFrançois Tigeot int r;
6602926deccbSFrançois Tigeot
660357e252bfSMichael Neumann /* enable pcie gen2/3 link */
660457e252bfSMichael Neumann si_pcie_gen3_enable(rdev);
660557e252bfSMichael Neumann /* enable aspm */
660657e252bfSMichael Neumann si_program_aspm(rdev);
660757e252bfSMichael Neumann
66084cd92098Szrj /* scratch needs to be initialized before MC */
66094cd92098Szrj r = r600_vram_scratch_init(rdev);
66104cd92098Szrj if (r)
66114cd92098Szrj return r;
66124cd92098Szrj
661357e252bfSMichael Neumann si_mc_program(rdev);
661457e252bfSMichael Neumann
6615c6f73aabSFrançois Tigeot if (!rdev->pm.dpm_enabled) {
6616926deccbSFrançois Tigeot r = si_mc_load_microcode(rdev);
6617926deccbSFrançois Tigeot if (r) {
6618926deccbSFrançois Tigeot DRM_ERROR("Failed to load MC firmware!\n");
6619926deccbSFrançois Tigeot return r;
6620926deccbSFrançois Tigeot }
6621c6f73aabSFrançois Tigeot }
6622926deccbSFrançois Tigeot
6623926deccbSFrançois Tigeot r = si_pcie_gart_enable(rdev);
6624926deccbSFrançois Tigeot if (r)
6625926deccbSFrançois Tigeot return r;
6626926deccbSFrançois Tigeot si_gpu_init(rdev);
6627926deccbSFrançois Tigeot
6628926deccbSFrançois Tigeot /* allocate rlc buffers */
66294cd92098Szrj if (rdev->family == CHIP_VERDE) {
66304cd92098Szrj rdev->rlc.reg_list = verde_rlc_save_restore_register_list;
66314cd92098Szrj rdev->rlc.reg_list_size =
66324cd92098Szrj (u32)ARRAY_SIZE(verde_rlc_save_restore_register_list);
66334cd92098Szrj }
66344cd92098Szrj rdev->rlc.cs_data = si_cs_data;
66354cd92098Szrj r = sumo_rlc_init(rdev);
6636926deccbSFrançois Tigeot if (r) {
6637926deccbSFrançois Tigeot DRM_ERROR("Failed to init rlc BOs!\n");
6638926deccbSFrançois Tigeot return r;
6639926deccbSFrançois Tigeot }
6640926deccbSFrançois Tigeot
6641926deccbSFrançois Tigeot /* allocate wb buffer */
6642926deccbSFrançois Tigeot r = radeon_wb_init(rdev);
6643926deccbSFrançois Tigeot if (r)
6644926deccbSFrançois Tigeot return r;
6645926deccbSFrançois Tigeot
6646926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
6647926deccbSFrançois Tigeot if (r) {
6648926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6649926deccbSFrançois Tigeot return r;
6650926deccbSFrançois Tigeot }
6651926deccbSFrançois Tigeot
6652926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6653926deccbSFrançois Tigeot if (r) {
6654926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6655926deccbSFrançois Tigeot return r;
6656926deccbSFrançois Tigeot }
6657926deccbSFrançois Tigeot
6658926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6659926deccbSFrançois Tigeot if (r) {
6660926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6661926deccbSFrançois Tigeot return r;
6662926deccbSFrançois Tigeot }
6663926deccbSFrançois Tigeot
6664926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
6665926deccbSFrançois Tigeot if (r) {
6666926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
6667926deccbSFrançois Tigeot return r;
6668926deccbSFrançois Tigeot }
6669926deccbSFrançois Tigeot
6670926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
6671926deccbSFrançois Tigeot if (r) {
6672926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
6673926deccbSFrançois Tigeot return r;
6674926deccbSFrançois Tigeot }
6675926deccbSFrançois Tigeot
6676d78d3a22SFrançois Tigeot si_uvd_start(rdev);
6677d78d3a22SFrançois Tigeot si_vce_start(rdev);
6678c59a5c48SFrançois Tigeot
6679926deccbSFrançois Tigeot /* Enable IRQ */
6680f43cf1b1SMichael Neumann if (!rdev->irq.installed) {
6681f43cf1b1SMichael Neumann r = radeon_irq_kms_init(rdev);
6682f43cf1b1SMichael Neumann if (r)
6683f43cf1b1SMichael Neumann return r;
6684f43cf1b1SMichael Neumann }
6685f43cf1b1SMichael Neumann
6686926deccbSFrançois Tigeot r = si_irq_init(rdev);
6687926deccbSFrançois Tigeot if (r) {
6688926deccbSFrançois Tigeot DRM_ERROR("radeon: IH init failed (%d).\n", r);
6689926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev);
6690926deccbSFrançois Tigeot return r;
6691926deccbSFrançois Tigeot }
6692926deccbSFrançois Tigeot si_irq_set(rdev);
6693926deccbSFrançois Tigeot
6694926deccbSFrançois Tigeot ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6695926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
66964cd92098Szrj RADEON_CP_PACKET2);
6697926deccbSFrançois Tigeot if (r)
6698926deccbSFrançois Tigeot return r;
6699926deccbSFrançois Tigeot
6700926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
6701926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
67024cd92098Szrj RADEON_CP_PACKET2);
6703926deccbSFrançois Tigeot if (r)
6704926deccbSFrançois Tigeot return r;
6705926deccbSFrançois Tigeot
6706926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
6707926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
67084cd92098Szrj RADEON_CP_PACKET2);
6709926deccbSFrançois Tigeot if (r)
6710926deccbSFrançois Tigeot return r;
6711926deccbSFrançois Tigeot
6712926deccbSFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
6713926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
67144cd92098Szrj DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
6715926deccbSFrançois Tigeot if (r)
6716926deccbSFrançois Tigeot return r;
6717926deccbSFrançois Tigeot
6718926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
6719926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
67204cd92098Szrj DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
6721926deccbSFrançois Tigeot if (r)
6722926deccbSFrançois Tigeot return r;
6723926deccbSFrançois Tigeot
6724926deccbSFrançois Tigeot r = si_cp_load_microcode(rdev);
6725926deccbSFrançois Tigeot if (r)
6726926deccbSFrançois Tigeot return r;
6727926deccbSFrançois Tigeot r = si_cp_resume(rdev);
6728926deccbSFrançois Tigeot if (r)
6729926deccbSFrançois Tigeot return r;
6730926deccbSFrançois Tigeot
6731926deccbSFrançois Tigeot r = cayman_dma_resume(rdev);
6732926deccbSFrançois Tigeot if (r)
6733926deccbSFrançois Tigeot return r;
6734926deccbSFrançois Tigeot
6735d78d3a22SFrançois Tigeot si_uvd_resume(rdev);
6736d78d3a22SFrançois Tigeot si_vce_resume(rdev);
6737c59a5c48SFrançois Tigeot
6738926deccbSFrançois Tigeot r = radeon_ib_pool_init(rdev);
6739926deccbSFrançois Tigeot if (r) {
6740926deccbSFrançois Tigeot dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
6741926deccbSFrançois Tigeot return r;
6742926deccbSFrançois Tigeot }
6743926deccbSFrançois Tigeot
6744926deccbSFrançois Tigeot r = radeon_vm_manager_init(rdev);
6745926deccbSFrançois Tigeot if (r) {
6746926deccbSFrançois Tigeot dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
6747926deccbSFrançois Tigeot return r;
6748926deccbSFrançois Tigeot }
6749926deccbSFrançois Tigeot
6750c59a5c48SFrançois Tigeot r = radeon_audio_init(rdev);
67514cd92098Szrj if (r)
67524cd92098Szrj return r;
67534cd92098Szrj
6754926deccbSFrançois Tigeot return 0;
6755926deccbSFrançois Tigeot }
6756926deccbSFrançois Tigeot
si_resume(struct radeon_device * rdev)6757926deccbSFrançois Tigeot int si_resume(struct radeon_device *rdev)
6758926deccbSFrançois Tigeot {
6759926deccbSFrançois Tigeot int r;
6760926deccbSFrançois Tigeot
6761926deccbSFrançois Tigeot /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
6762926deccbSFrançois Tigeot * posting will perform necessary task to bring back GPU into good
6763926deccbSFrançois Tigeot * shape.
6764926deccbSFrançois Tigeot */
6765926deccbSFrançois Tigeot /* post card */
6766926deccbSFrançois Tigeot atom_asic_init(rdev->mode_info.atom_context);
6767926deccbSFrançois Tigeot
6768f43cf1b1SMichael Neumann /* init golden registers */
6769f43cf1b1SMichael Neumann si_init_golden_registers(rdev);
6770f43cf1b1SMichael Neumann
6771c6f73aabSFrançois Tigeot if (rdev->pm.pm_method == PM_METHOD_DPM)
6772c6f73aabSFrançois Tigeot radeon_pm_resume(rdev);
6773c6f73aabSFrançois Tigeot
6774926deccbSFrançois Tigeot rdev->accel_working = true;
6775926deccbSFrançois Tigeot r = si_startup(rdev);
6776926deccbSFrançois Tigeot if (r) {
6777926deccbSFrançois Tigeot DRM_ERROR("si startup failed on resume\n");
6778926deccbSFrançois Tigeot rdev->accel_working = false;
6779926deccbSFrançois Tigeot return r;
6780926deccbSFrançois Tigeot }
6781926deccbSFrançois Tigeot
6782926deccbSFrançois Tigeot return r;
6783926deccbSFrançois Tigeot
6784926deccbSFrançois Tigeot }
6785926deccbSFrançois Tigeot
si_suspend(struct radeon_device * rdev)6786926deccbSFrançois Tigeot int si_suspend(struct radeon_device *rdev)
6787926deccbSFrançois Tigeot {
6788c6f73aabSFrançois Tigeot radeon_pm_suspend(rdev);
6789c59a5c48SFrançois Tigeot radeon_audio_fini(rdev);
6790b403bed8SMichael Neumann radeon_vm_manager_fini(rdev);
6791926deccbSFrançois Tigeot si_cp_enable(rdev, false);
6792926deccbSFrançois Tigeot cayman_dma_stop(rdev);
6793f43cf1b1SMichael Neumann if (rdev->has_uvd) {
67944cd92098Szrj uvd_v1_0_fini(rdev);
6795f43cf1b1SMichael Neumann radeon_uvd_suspend(rdev);
6796f43cf1b1SMichael Neumann }
6797d78d3a22SFrançois Tigeot if (rdev->has_vce)
6798d78d3a22SFrançois Tigeot radeon_vce_suspend(rdev);
67994cd92098Szrj si_fini_pg(rdev);
68004cd92098Szrj si_fini_cg(rdev);
6801926deccbSFrançois Tigeot si_irq_suspend(rdev);
6802926deccbSFrançois Tigeot radeon_wb_disable(rdev);
6803926deccbSFrançois Tigeot si_pcie_gart_disable(rdev);
6804926deccbSFrançois Tigeot return 0;
6805926deccbSFrançois Tigeot }
6806926deccbSFrançois Tigeot
6807926deccbSFrançois Tigeot /* Plan is to move initialization in that function and use
6808926deccbSFrançois Tigeot * helper function so that radeon_device_init pretty much
6809926deccbSFrançois Tigeot * do nothing more than calling asic specific function. This
6810926deccbSFrançois Tigeot * should also allow to remove a bunch of callback function
6811926deccbSFrançois Tigeot * like vram_info.
6812926deccbSFrançois Tigeot */
si_init(struct radeon_device * rdev)6813926deccbSFrançois Tigeot int si_init(struct radeon_device *rdev)
6814926deccbSFrançois Tigeot {
6815926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6816926deccbSFrançois Tigeot int r;
6817926deccbSFrançois Tigeot
6818926deccbSFrançois Tigeot /* Read BIOS */
6819926deccbSFrançois Tigeot if (!radeon_get_bios(rdev)) {
6820926deccbSFrançois Tigeot if (ASIC_IS_AVIVO(rdev))
6821926deccbSFrançois Tigeot return -EINVAL;
6822926deccbSFrançois Tigeot }
6823926deccbSFrançois Tigeot /* Must be an ATOMBIOS */
6824926deccbSFrançois Tigeot if (!rdev->is_atom_bios) {
6825926deccbSFrançois Tigeot dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
6826926deccbSFrançois Tigeot return -EINVAL;
6827926deccbSFrançois Tigeot }
6828926deccbSFrançois Tigeot r = radeon_atombios_init(rdev);
6829926deccbSFrançois Tigeot if (r)
6830926deccbSFrançois Tigeot return r;
6831926deccbSFrançois Tigeot
6832926deccbSFrançois Tigeot /* Post card if necessary */
6833926deccbSFrançois Tigeot if (!radeon_card_posted(rdev)) {
6834926deccbSFrançois Tigeot if (!rdev->bios) {
6835926deccbSFrançois Tigeot dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
6836926deccbSFrançois Tigeot return -EINVAL;
6837926deccbSFrançois Tigeot }
6838926deccbSFrançois Tigeot DRM_INFO("GPU not posted. posting now...\n");
6839926deccbSFrançois Tigeot atom_asic_init(rdev->mode_info.atom_context);
6840926deccbSFrançois Tigeot }
6841f43cf1b1SMichael Neumann /* init golden registers */
6842f43cf1b1SMichael Neumann si_init_golden_registers(rdev);
6843926deccbSFrançois Tigeot /* Initialize scratch registers */
6844926deccbSFrançois Tigeot si_scratch_init(rdev);
6845926deccbSFrançois Tigeot /* Initialize surface registers */
6846926deccbSFrançois Tigeot radeon_surface_init(rdev);
6847926deccbSFrançois Tigeot /* Initialize clocks */
6848926deccbSFrançois Tigeot radeon_get_clock_info(rdev->ddev);
6849926deccbSFrançois Tigeot
6850926deccbSFrançois Tigeot /* Fence driver */
6851926deccbSFrançois Tigeot r = radeon_fence_driver_init(rdev);
6852926deccbSFrançois Tigeot if (r)
6853926deccbSFrançois Tigeot return r;
6854926deccbSFrançois Tigeot
6855926deccbSFrançois Tigeot /* initialize memory controller */
6856926deccbSFrançois Tigeot r = si_mc_init(rdev);
6857926deccbSFrançois Tigeot if (r)
6858926deccbSFrançois Tigeot return r;
6859926deccbSFrançois Tigeot /* Memory manager */
6860926deccbSFrançois Tigeot r = radeon_bo_init(rdev);
6861926deccbSFrançois Tigeot if (r)
6862926deccbSFrançois Tigeot return r;
6863926deccbSFrançois Tigeot
6864c6f73aabSFrançois Tigeot if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
6865c6f73aabSFrançois Tigeot !rdev->rlc_fw || !rdev->mc_fw) {
6866c6f73aabSFrançois Tigeot r = si_init_microcode(rdev);
6867c6f73aabSFrançois Tigeot if (r) {
6868c6f73aabSFrançois Tigeot DRM_ERROR("Failed to load firmware!\n");
6869c6f73aabSFrançois Tigeot return r;
6870c6f73aabSFrançois Tigeot }
6871c6f73aabSFrançois Tigeot }
6872c6f73aabSFrançois Tigeot
6873c6f73aabSFrançois Tigeot /* Initialize power management */
6874c6f73aabSFrançois Tigeot radeon_pm_init(rdev);
6875c6f73aabSFrançois Tigeot
6876926deccbSFrançois Tigeot ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6877926deccbSFrançois Tigeot ring->ring_obj = NULL;
6878926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 1024 * 1024);
6879926deccbSFrançois Tigeot
6880926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
6881926deccbSFrançois Tigeot ring->ring_obj = NULL;
6882926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 1024 * 1024);
6883926deccbSFrançois Tigeot
6884926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
6885926deccbSFrançois Tigeot ring->ring_obj = NULL;
6886926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 1024 * 1024);
6887926deccbSFrançois Tigeot
6888926deccbSFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
6889926deccbSFrançois Tigeot ring->ring_obj = NULL;
6890926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 64 * 1024);
6891926deccbSFrançois Tigeot
6892926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
6893926deccbSFrançois Tigeot ring->ring_obj = NULL;
6894926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 64 * 1024);
6895926deccbSFrançois Tigeot
6896d78d3a22SFrançois Tigeot si_uvd_init(rdev);
6897d78d3a22SFrançois Tigeot si_vce_init(rdev);
6898c59a5c48SFrançois Tigeot
6899926deccbSFrançois Tigeot rdev->ih.ring_obj = NULL;
6900926deccbSFrançois Tigeot r600_ih_ring_init(rdev, 64 * 1024);
6901926deccbSFrançois Tigeot
6902926deccbSFrançois Tigeot r = r600_pcie_gart_init(rdev);
6903926deccbSFrançois Tigeot if (r)
6904926deccbSFrançois Tigeot return r;
6905926deccbSFrançois Tigeot
6906e8de9e94SFrançois Tigeot #ifdef __DragonFly__
6907e8de9e94SFrançois Tigeot /*
6908e8de9e94SFrançois Tigeot Some glx operations (xfce 4.14) hang on si hardware,
6909e8de9e94SFrançois Tigeot tell userland acceleration is not working properly
6910e8de9e94SFrançois Tigeot */
6911e8de9e94SFrançois Tigeot rdev->accel_working = false;
6912e6084b74SFrançois Tigeot DRM_ERROR("GPU acceleration disabled for now on DragonFly\n");
6913e8de9e94SFrançois Tigeot #else
6914926deccbSFrançois Tigeot rdev->accel_working = true;
6915e8de9e94SFrançois Tigeot #endif
6916926deccbSFrançois Tigeot r = si_startup(rdev);
6917926deccbSFrançois Tigeot if (r) {
6918926deccbSFrançois Tigeot dev_err(rdev->dev, "disabling GPU acceleration\n");
6919926deccbSFrançois Tigeot si_cp_fini(rdev);
6920926deccbSFrançois Tigeot cayman_dma_fini(rdev);
6921926deccbSFrançois Tigeot si_irq_fini(rdev);
69224cd92098Szrj sumo_rlc_fini(rdev);
6923926deccbSFrançois Tigeot radeon_wb_fini(rdev);
6924926deccbSFrançois Tigeot radeon_ib_pool_fini(rdev);
6925926deccbSFrançois Tigeot radeon_vm_manager_fini(rdev);
6926926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev);
6927926deccbSFrançois Tigeot si_pcie_gart_fini(rdev);
6928926deccbSFrançois Tigeot rdev->accel_working = false;
6929926deccbSFrançois Tigeot }
6930926deccbSFrançois Tigeot
6931926deccbSFrançois Tigeot /* Don't start up if the MC ucode is missing.
6932926deccbSFrançois Tigeot * The default clocks and voltages before the MC ucode
6933926deccbSFrançois Tigeot * is loaded are not suffient for advanced operations.
6934926deccbSFrançois Tigeot */
6935926deccbSFrançois Tigeot if (!rdev->mc_fw) {
6936926deccbSFrançois Tigeot DRM_ERROR("radeon: MC ucode required for NI+.\n");
6937926deccbSFrançois Tigeot return -EINVAL;
6938926deccbSFrançois Tigeot }
6939926deccbSFrançois Tigeot
6940926deccbSFrançois Tigeot return 0;
6941926deccbSFrançois Tigeot }
6942926deccbSFrançois Tigeot
si_fini(struct radeon_device * rdev)6943926deccbSFrançois Tigeot void si_fini(struct radeon_device *rdev)
6944926deccbSFrançois Tigeot {
6945c6f73aabSFrançois Tigeot radeon_pm_fini(rdev);
6946926deccbSFrançois Tigeot si_cp_fini(rdev);
6947926deccbSFrançois Tigeot cayman_dma_fini(rdev);
694857e252bfSMichael Neumann si_fini_pg(rdev);
69494cd92098Szrj si_fini_cg(rdev);
69504cd92098Szrj si_irq_fini(rdev);
69514cd92098Szrj sumo_rlc_fini(rdev);
6952926deccbSFrançois Tigeot radeon_wb_fini(rdev);
6953926deccbSFrançois Tigeot radeon_vm_manager_fini(rdev);
6954926deccbSFrançois Tigeot radeon_ib_pool_fini(rdev);
6955926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev);
695657e252bfSMichael Neumann if (rdev->has_uvd) {
69574cd92098Szrj uvd_v1_0_fini(rdev);
6958f43cf1b1SMichael Neumann radeon_uvd_fini(rdev);
695957e252bfSMichael Neumann }
6960d78d3a22SFrançois Tigeot if (rdev->has_vce)
6961d78d3a22SFrançois Tigeot radeon_vce_fini(rdev);
6962926deccbSFrançois Tigeot si_pcie_gart_fini(rdev);
6963926deccbSFrançois Tigeot r600_vram_scratch_fini(rdev);
6964926deccbSFrançois Tigeot radeon_gem_fini(rdev);
6965926deccbSFrançois Tigeot radeon_fence_driver_fini(rdev);
6966926deccbSFrançois Tigeot radeon_bo_fini(rdev);
6967926deccbSFrançois Tigeot radeon_atombios_fini(rdev);
6968c4ef309bSzrj kfree(rdev->bios);
6969926deccbSFrançois Tigeot rdev->bios = NULL;
6970926deccbSFrançois Tigeot }
6971926deccbSFrançois Tigeot
6972926deccbSFrançois Tigeot /**
6973b403bed8SMichael Neumann * si_get_gpu_clock_counter - return GPU clock counter snapshot
6974926deccbSFrançois Tigeot *
6975926deccbSFrançois Tigeot * @rdev: radeon_device pointer
6976926deccbSFrançois Tigeot *
6977926deccbSFrançois Tigeot * Fetches a GPU clock counter snapshot (SI).
6978926deccbSFrançois Tigeot * Returns the 64 bit clock counter snapshot.
6979926deccbSFrançois Tigeot */
si_get_gpu_clock_counter(struct radeon_device * rdev)6980b403bed8SMichael Neumann uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev)
6981926deccbSFrançois Tigeot {
6982926deccbSFrançois Tigeot uint64_t clock;
6983926deccbSFrançois Tigeot
6984fefad7a7SFrançois Tigeot mutex_lock(&rdev->gpu_clock_mutex);
6985926deccbSFrançois Tigeot WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
6986926deccbSFrançois Tigeot clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
6987926deccbSFrançois Tigeot ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
6988fefad7a7SFrançois Tigeot mutex_unlock(&rdev->gpu_clock_mutex);
6989926deccbSFrançois Tigeot return clock;
6990926deccbSFrançois Tigeot }
6991f43cf1b1SMichael Neumann
si_set_uvd_clocks(struct radeon_device * rdev,u32 vclk,u32 dclk)6992f43cf1b1SMichael Neumann int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
6993f43cf1b1SMichael Neumann {
6994f43cf1b1SMichael Neumann unsigned fb_div = 0, vclk_div = 0, dclk_div = 0;
6995f43cf1b1SMichael Neumann int r;
6996f43cf1b1SMichael Neumann
6997f43cf1b1SMichael Neumann /* bypass vclk and dclk with bclk */
6998f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL_2,
6999f43cf1b1SMichael Neumann VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
7000f43cf1b1SMichael Neumann ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
7001f43cf1b1SMichael Neumann
7002f43cf1b1SMichael Neumann /* put PLL in bypass mode */
7003f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
7004f43cf1b1SMichael Neumann
7005f43cf1b1SMichael Neumann if (!vclk || !dclk) {
70067dcf36dcSFrançois Tigeot /* keep the Bypass mode */
7007f43cf1b1SMichael Neumann return 0;
7008f43cf1b1SMichael Neumann }
7009f43cf1b1SMichael Neumann
7010f43cf1b1SMichael Neumann r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 125000, 250000,
7011f43cf1b1SMichael Neumann 16384, 0x03FFFFFF, 0, 128, 5,
7012f43cf1b1SMichael Neumann &fb_div, &vclk_div, &dclk_div);
7013f43cf1b1SMichael Neumann if (r)
7014f43cf1b1SMichael Neumann return r;
7015f43cf1b1SMichael Neumann
7016f43cf1b1SMichael Neumann /* set RESET_ANTI_MUX to 0 */
7017f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
7018f43cf1b1SMichael Neumann
7019f43cf1b1SMichael Neumann /* set VCO_MODE to 1 */
7020f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
7021f43cf1b1SMichael Neumann
70227dcf36dcSFrançois Tigeot /* disable sleep mode */
7023f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
7024f43cf1b1SMichael Neumann
7025f43cf1b1SMichael Neumann /* deassert UPLL_RESET */
7026f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
7027f43cf1b1SMichael Neumann
7028c4ef309bSzrj mdelay(1);
7029f43cf1b1SMichael Neumann
7030f43cf1b1SMichael Neumann r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
7031f43cf1b1SMichael Neumann if (r)
7032f43cf1b1SMichael Neumann return r;
7033f43cf1b1SMichael Neumann
7034f43cf1b1SMichael Neumann /* assert UPLL_RESET again */
7035f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
7036f43cf1b1SMichael Neumann
7037f43cf1b1SMichael Neumann /* disable spread spectrum. */
7038f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
7039f43cf1b1SMichael Neumann
7040f43cf1b1SMichael Neumann /* set feedback divider */
7041f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div), ~UPLL_FB_DIV_MASK);
7042f43cf1b1SMichael Neumann
7043f43cf1b1SMichael Neumann /* set ref divider to 0 */
7044f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK);
7045f43cf1b1SMichael Neumann
7046f43cf1b1SMichael Neumann if (fb_div < 307200)
7047f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9);
7048f43cf1b1SMichael Neumann else
7049f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9);
7050f43cf1b1SMichael Neumann
7051f43cf1b1SMichael Neumann /* set PDIV_A and PDIV_B */
7052f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL_2,
7053f43cf1b1SMichael Neumann UPLL_PDIV_A(vclk_div) | UPLL_PDIV_B(dclk_div),
7054f43cf1b1SMichael Neumann ~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK));
7055f43cf1b1SMichael Neumann
7056f43cf1b1SMichael Neumann /* give the PLL some time to settle */
7057c4ef309bSzrj mdelay(15);
7058f43cf1b1SMichael Neumann
7059f43cf1b1SMichael Neumann /* deassert PLL_RESET */
7060f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
7061f43cf1b1SMichael Neumann
7062c4ef309bSzrj mdelay(15);
7063f43cf1b1SMichael Neumann
7064f43cf1b1SMichael Neumann /* switch from bypass mode to normal mode */
7065f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
7066f43cf1b1SMichael Neumann
7067f43cf1b1SMichael Neumann r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
7068f43cf1b1SMichael Neumann if (r)
7069f43cf1b1SMichael Neumann return r;
7070f43cf1b1SMichael Neumann
7071f43cf1b1SMichael Neumann /* switch VCLK and DCLK selection */
7072f43cf1b1SMichael Neumann WREG32_P(CG_UPLL_FUNC_CNTL_2,
7073f43cf1b1SMichael Neumann VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
7074f43cf1b1SMichael Neumann ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
7075f43cf1b1SMichael Neumann
7076c4ef309bSzrj mdelay(100);
7077f43cf1b1SMichael Neumann
7078f43cf1b1SMichael Neumann return 0;
7079f43cf1b1SMichael Neumann }
708057e252bfSMichael Neumann
si_pcie_gen3_enable(struct radeon_device * rdev)708157e252bfSMichael Neumann static void si_pcie_gen3_enable(struct radeon_device *rdev)
708257e252bfSMichael Neumann {
70834cd92098Szrj struct pci_dev *root = rdev->pdev->bus->self;
708457e252bfSMichael Neumann int bridge_pos, gpu_pos;
708557e252bfSMichael Neumann u32 speed_cntl, mask, current_data_rate;
708657e252bfSMichael Neumann int ret, i;
708757e252bfSMichael Neumann u16 tmp16;
708857e252bfSMichael Neumann
7089c59a5c48SFrançois Tigeot #if 0
7090c59a5c48SFrançois Tigeot if (pci_is_root_bus(rdev->pdev->bus))
7091c59a5c48SFrançois Tigeot return;
7092c59a5c48SFrançois Tigeot #endif
7093c59a5c48SFrançois Tigeot
709457e252bfSMichael Neumann if (radeon_pcie_gen2 == 0)
709557e252bfSMichael Neumann return;
709657e252bfSMichael Neumann
709757e252bfSMichael Neumann if (rdev->flags & RADEON_IS_IGP)
709857e252bfSMichael Neumann return;
709957e252bfSMichael Neumann
710057e252bfSMichael Neumann if (!(rdev->flags & RADEON_IS_PCIE))
710157e252bfSMichael Neumann return;
710257e252bfSMichael Neumann
710357e252bfSMichael Neumann ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
710457e252bfSMichael Neumann if (ret != 0)
710557e252bfSMichael Neumann return;
710657e252bfSMichael Neumann
710757e252bfSMichael Neumann if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
710857e252bfSMichael Neumann return;
710957e252bfSMichael Neumann
711057e252bfSMichael Neumann speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
711157e252bfSMichael Neumann current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >>
711257e252bfSMichael Neumann LC_CURRENT_DATA_RATE_SHIFT;
711357e252bfSMichael Neumann if (mask & DRM_PCIE_SPEED_80) {
711457e252bfSMichael Neumann if (current_data_rate == 2) {
711557e252bfSMichael Neumann DRM_INFO("PCIE gen 3 link speeds already enabled\n");
711657e252bfSMichael Neumann return;
711757e252bfSMichael Neumann }
711857e252bfSMichael Neumann DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n");
711957e252bfSMichael Neumann } else if (mask & DRM_PCIE_SPEED_50) {
712057e252bfSMichael Neumann if (current_data_rate == 1) {
712157e252bfSMichael Neumann DRM_INFO("PCIE gen 2 link speeds already enabled\n");
712257e252bfSMichael Neumann return;
712357e252bfSMichael Neumann }
712457e252bfSMichael Neumann DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
712557e252bfSMichael Neumann }
712657e252bfSMichael Neumann
7127c59a5c48SFrançois Tigeot bridge_pos = pci_pcie_cap(root);
712857e252bfSMichael Neumann if (!bridge_pos)
712957e252bfSMichael Neumann return;
713057e252bfSMichael Neumann
7131c59a5c48SFrançois Tigeot gpu_pos = pci_pcie_cap(rdev->pdev);
713257e252bfSMichael Neumann if (!gpu_pos)
713357e252bfSMichael Neumann return;
713457e252bfSMichael Neumann
713557e252bfSMichael Neumann if (mask & DRM_PCIE_SPEED_80) {
713657e252bfSMichael Neumann /* re-try equalization if gen3 is not already enabled */
713757e252bfSMichael Neumann if (current_data_rate != 2) {
713857e252bfSMichael Neumann u16 bridge_cfg, gpu_cfg;
713957e252bfSMichael Neumann u16 bridge_cfg2, gpu_cfg2;
714057e252bfSMichael Neumann u32 max_lw, current_lw, tmp;
714157e252bfSMichael Neumann
7142c6f73aabSFrançois Tigeot pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg);
7143c6f73aabSFrançois Tigeot pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg);
714457e252bfSMichael Neumann
714557e252bfSMichael Neumann tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
7146c6f73aabSFrançois Tigeot pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16);
714757e252bfSMichael Neumann
714857e252bfSMichael Neumann tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
7149c6f73aabSFrançois Tigeot pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16);
715057e252bfSMichael Neumann
715157e252bfSMichael Neumann tmp = RREG32_PCIE(PCIE_LC_STATUS1);
715257e252bfSMichael Neumann max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
715357e252bfSMichael Neumann current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT;
715457e252bfSMichael Neumann
715557e252bfSMichael Neumann if (current_lw < max_lw) {
715657e252bfSMichael Neumann tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
715757e252bfSMichael Neumann if (tmp & LC_RENEGOTIATION_SUPPORT) {
715857e252bfSMichael Neumann tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS);
715957e252bfSMichael Neumann tmp |= (max_lw << LC_LINK_WIDTH_SHIFT);
716057e252bfSMichael Neumann tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW;
716157e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp);
716257e252bfSMichael Neumann }
716357e252bfSMichael Neumann }
716457e252bfSMichael Neumann
716557e252bfSMichael Neumann for (i = 0; i < 10; i++) {
716657e252bfSMichael Neumann /* check status */
7167c6f73aabSFrançois Tigeot pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_DEVSTA, &tmp16);
716857e252bfSMichael Neumann if (tmp16 & PCI_EXP_DEVSTA_TRPND)
716957e252bfSMichael Neumann break;
717057e252bfSMichael Neumann
7171c6f73aabSFrançois Tigeot pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg);
7172c6f73aabSFrançois Tigeot pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg);
717357e252bfSMichael Neumann
7174c6f73aabSFrançois Tigeot pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &bridge_cfg2);
7175c6f73aabSFrançois Tigeot pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &gpu_cfg2);
717657e252bfSMichael Neumann
717757e252bfSMichael Neumann tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
717857e252bfSMichael Neumann tmp |= LC_SET_QUIESCE;
717957e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
718057e252bfSMichael Neumann
718157e252bfSMichael Neumann tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
718257e252bfSMichael Neumann tmp |= LC_REDO_EQ;
718357e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
718457e252bfSMichael Neumann
7185c4ef309bSzrj mdelay(100);
718657e252bfSMichael Neumann
718757e252bfSMichael Neumann /* linkctl */
7188c6f73aabSFrançois Tigeot pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &tmp16);
718957e252bfSMichael Neumann tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
719057e252bfSMichael Neumann tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
7191c6f73aabSFrançois Tigeot pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16);
719257e252bfSMichael Neumann
7193c6f73aabSFrançois Tigeot pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &tmp16);
719457e252bfSMichael Neumann tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
719557e252bfSMichael Neumann tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
7196c6f73aabSFrançois Tigeot pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16);
719757e252bfSMichael Neumann
719857e252bfSMichael Neumann /* linkctl2 */
7199c6f73aabSFrançois Tigeot pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &tmp16);
720057e252bfSMichael Neumann tmp16 &= ~((1 << 4) | (7 << 9));
720157e252bfSMichael Neumann tmp16 |= (bridge_cfg2 & ((1 << 4) | (7 << 9)));
7202c6f73aabSFrançois Tigeot pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, tmp16);
720357e252bfSMichael Neumann
7204c6f73aabSFrançois Tigeot pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
720557e252bfSMichael Neumann tmp16 &= ~((1 << 4) | (7 << 9));
720657e252bfSMichael Neumann tmp16 |= (gpu_cfg2 & ((1 << 4) | (7 << 9)));
7207c6f73aabSFrançois Tigeot pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16);
720857e252bfSMichael Neumann
720957e252bfSMichael Neumann tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
721057e252bfSMichael Neumann tmp &= ~LC_SET_QUIESCE;
721157e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
721257e252bfSMichael Neumann }
721357e252bfSMichael Neumann }
721457e252bfSMichael Neumann }
721557e252bfSMichael Neumann
721657e252bfSMichael Neumann /* set the link speed */
721757e252bfSMichael Neumann speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE;
721857e252bfSMichael Neumann speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
721957e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
722057e252bfSMichael Neumann
7221c6f73aabSFrançois Tigeot pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
722257e252bfSMichael Neumann tmp16 &= ~0xf;
722357e252bfSMichael Neumann if (mask & DRM_PCIE_SPEED_80)
722457e252bfSMichael Neumann tmp16 |= 3; /* gen3 */
722557e252bfSMichael Neumann else if (mask & DRM_PCIE_SPEED_50)
722657e252bfSMichael Neumann tmp16 |= 2; /* gen2 */
722757e252bfSMichael Neumann else
722857e252bfSMichael Neumann tmp16 |= 1; /* gen1 */
7229c6f73aabSFrançois Tigeot pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16);
723057e252bfSMichael Neumann
723157e252bfSMichael Neumann speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
723257e252bfSMichael Neumann speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
723357e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
723457e252bfSMichael Neumann
723557e252bfSMichael Neumann for (i = 0; i < rdev->usec_timeout; i++) {
723657e252bfSMichael Neumann speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
723757e252bfSMichael Neumann if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0)
723857e252bfSMichael Neumann break;
7239c4ef309bSzrj udelay(1);
724057e252bfSMichael Neumann }
724157e252bfSMichael Neumann }
724257e252bfSMichael Neumann
si_program_aspm(struct radeon_device * rdev)724357e252bfSMichael Neumann static void si_program_aspm(struct radeon_device *rdev)
724457e252bfSMichael Neumann {
724557e252bfSMichael Neumann u32 data, orig;
724657e252bfSMichael Neumann bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
7247c59a5c48SFrançois Tigeot #if 0
724857e252bfSMichael Neumann bool disable_clkreq = false;
7249c59a5c48SFrançois Tigeot #endif
725057e252bfSMichael Neumann
725157e252bfSMichael Neumann if (radeon_aspm == 0)
725257e252bfSMichael Neumann return;
725357e252bfSMichael Neumann
725457e252bfSMichael Neumann if (!(rdev->flags & RADEON_IS_PCIE))
725557e252bfSMichael Neumann return;
725657e252bfSMichael Neumann
725757e252bfSMichael Neumann orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
725857e252bfSMichael Neumann data &= ~LC_XMIT_N_FTS_MASK;
725957e252bfSMichael Neumann data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN;
726057e252bfSMichael Neumann if (orig != data)
726157e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data);
726257e252bfSMichael Neumann
726357e252bfSMichael Neumann orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3);
726457e252bfSMichael Neumann data |= LC_GO_TO_RECOVERY;
726557e252bfSMichael Neumann if (orig != data)
726657e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_CNTL3, data);
726757e252bfSMichael Neumann
726857e252bfSMichael Neumann orig = data = RREG32_PCIE(PCIE_P_CNTL);
726957e252bfSMichael Neumann data |= P_IGNORE_EDB_ERR;
727057e252bfSMichael Neumann if (orig != data)
727157e252bfSMichael Neumann WREG32_PCIE(PCIE_P_CNTL, data);
727257e252bfSMichael Neumann
727357e252bfSMichael Neumann orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
727457e252bfSMichael Neumann data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
727557e252bfSMichael Neumann data |= LC_PMI_TO_L1_DIS;
727657e252bfSMichael Neumann if (!disable_l0s)
727757e252bfSMichael Neumann data |= LC_L0S_INACTIVITY(7);
727857e252bfSMichael Neumann
727957e252bfSMichael Neumann if (!disable_l1) {
728057e252bfSMichael Neumann data |= LC_L1_INACTIVITY(7);
728157e252bfSMichael Neumann data &= ~LC_PMI_TO_L1_DIS;
728257e252bfSMichael Neumann if (orig != data)
728357e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
728457e252bfSMichael Neumann
728557e252bfSMichael Neumann if (!disable_plloff_in_l1) {
728657e252bfSMichael Neumann bool clk_req_support;
728757e252bfSMichael Neumann
728857e252bfSMichael Neumann orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
728957e252bfSMichael Neumann data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
729057e252bfSMichael Neumann data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
729157e252bfSMichael Neumann if (orig != data)
729257e252bfSMichael Neumann WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
729357e252bfSMichael Neumann
729457e252bfSMichael Neumann orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
729557e252bfSMichael Neumann data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
729657e252bfSMichael Neumann data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
729757e252bfSMichael Neumann if (orig != data)
729857e252bfSMichael Neumann WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
729957e252bfSMichael Neumann
730057e252bfSMichael Neumann orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
730157e252bfSMichael Neumann data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
730257e252bfSMichael Neumann data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
730357e252bfSMichael Neumann if (orig != data)
730457e252bfSMichael Neumann WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
730557e252bfSMichael Neumann
730657e252bfSMichael Neumann orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
730757e252bfSMichael Neumann data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
730857e252bfSMichael Neumann data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
730957e252bfSMichael Neumann if (orig != data)
731057e252bfSMichael Neumann WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
731157e252bfSMichael Neumann
731257e252bfSMichael Neumann if ((rdev->family != CHIP_OLAND) && (rdev->family != CHIP_HAINAN)) {
731357e252bfSMichael Neumann orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
731457e252bfSMichael Neumann data &= ~PLL_RAMP_UP_TIME_0_MASK;
731557e252bfSMichael Neumann if (orig != data)
731657e252bfSMichael Neumann WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
731757e252bfSMichael Neumann
731857e252bfSMichael Neumann orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
731957e252bfSMichael Neumann data &= ~PLL_RAMP_UP_TIME_1_MASK;
732057e252bfSMichael Neumann if (orig != data)
732157e252bfSMichael Neumann WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
732257e252bfSMichael Neumann
732357e252bfSMichael Neumann orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2);
732457e252bfSMichael Neumann data &= ~PLL_RAMP_UP_TIME_2_MASK;
732557e252bfSMichael Neumann if (orig != data)
732657e252bfSMichael Neumann WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2, data);
732757e252bfSMichael Neumann
732857e252bfSMichael Neumann orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3);
732957e252bfSMichael Neumann data &= ~PLL_RAMP_UP_TIME_3_MASK;
733057e252bfSMichael Neumann if (orig != data)
733157e252bfSMichael Neumann WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3, data);
733257e252bfSMichael Neumann
733357e252bfSMichael Neumann orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
733457e252bfSMichael Neumann data &= ~PLL_RAMP_UP_TIME_0_MASK;
733557e252bfSMichael Neumann if (orig != data)
733657e252bfSMichael Neumann WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
733757e252bfSMichael Neumann
733857e252bfSMichael Neumann orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
733957e252bfSMichael Neumann data &= ~PLL_RAMP_UP_TIME_1_MASK;
734057e252bfSMichael Neumann if (orig != data)
734157e252bfSMichael Neumann WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
734257e252bfSMichael Neumann
734357e252bfSMichael Neumann orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2);
734457e252bfSMichael Neumann data &= ~PLL_RAMP_UP_TIME_2_MASK;
734557e252bfSMichael Neumann if (orig != data)
734657e252bfSMichael Neumann WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2, data);
734757e252bfSMichael Neumann
734857e252bfSMichael Neumann orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3);
734957e252bfSMichael Neumann data &= ~PLL_RAMP_UP_TIME_3_MASK;
735057e252bfSMichael Neumann if (orig != data)
735157e252bfSMichael Neumann WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3, data);
735257e252bfSMichael Neumann }
735357e252bfSMichael Neumann orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
735457e252bfSMichael Neumann data &= ~LC_DYN_LANES_PWR_STATE_MASK;
735557e252bfSMichael Neumann data |= LC_DYN_LANES_PWR_STATE(3);
735657e252bfSMichael Neumann if (orig != data)
735757e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
735857e252bfSMichael Neumann
735957e252bfSMichael Neumann orig = data = RREG32_PIF_PHY0(PB0_PIF_CNTL);
736057e252bfSMichael Neumann data &= ~LS2_EXIT_TIME_MASK;
736157e252bfSMichael Neumann if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
736257e252bfSMichael Neumann data |= LS2_EXIT_TIME(5);
736357e252bfSMichael Neumann if (orig != data)
736457e252bfSMichael Neumann WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
736557e252bfSMichael Neumann
736657e252bfSMichael Neumann orig = data = RREG32_PIF_PHY1(PB1_PIF_CNTL);
736757e252bfSMichael Neumann data &= ~LS2_EXIT_TIME_MASK;
736857e252bfSMichael Neumann if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
736957e252bfSMichael Neumann data |= LS2_EXIT_TIME(5);
737057e252bfSMichael Neumann if (orig != data)
737157e252bfSMichael Neumann WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
737257e252bfSMichael Neumann
73734cd92098Szrj #ifdef zMN_TODO
7374c59a5c48SFrançois Tigeot if (!disable_clkreq &&
7375c59a5c48SFrançois Tigeot !pci_is_root_bus(rdev->pdev->bus)) {
737657e252bfSMichael Neumann struct pci_dev *root = rdev->pdev->bus->self;
737757e252bfSMichael Neumann u32 lnkcap;
737857e252bfSMichael Neumann
737957e252bfSMichael Neumann clk_req_support = false;
738057e252bfSMichael Neumann pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
738157e252bfSMichael Neumann if (lnkcap & PCI_EXP_LNKCAP_CLKPM)
738257e252bfSMichael Neumann clk_req_support = true;
738357e252bfSMichael Neumann } else {
738457e252bfSMichael Neumann clk_req_support = false;
738557e252bfSMichael Neumann }
7386c59a5c48SFrançois Tigeot #else
7387c59a5c48SFrançois Tigeot clk_req_support = false;
7388c59a5c48SFrançois Tigeot #endif
738957e252bfSMichael Neumann
739057e252bfSMichael Neumann if (clk_req_support) {
739157e252bfSMichael Neumann orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2);
739257e252bfSMichael Neumann data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23;
739357e252bfSMichael Neumann if (orig != data)
739457e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_CNTL2, data);
739557e252bfSMichael Neumann
739657e252bfSMichael Neumann orig = data = RREG32(THM_CLK_CNTL);
739757e252bfSMichael Neumann data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK);
739857e252bfSMichael Neumann data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1);
739957e252bfSMichael Neumann if (orig != data)
740057e252bfSMichael Neumann WREG32(THM_CLK_CNTL, data);
740157e252bfSMichael Neumann
740257e252bfSMichael Neumann orig = data = RREG32(MISC_CLK_CNTL);
740357e252bfSMichael Neumann data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK);
740457e252bfSMichael Neumann data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1);
740557e252bfSMichael Neumann if (orig != data)
740657e252bfSMichael Neumann WREG32(MISC_CLK_CNTL, data);
740757e252bfSMichael Neumann
740857e252bfSMichael Neumann orig = data = RREG32(CG_CLKPIN_CNTL);
740957e252bfSMichael Neumann data &= ~BCLK_AS_XCLK;
741057e252bfSMichael Neumann if (orig != data)
741157e252bfSMichael Neumann WREG32(CG_CLKPIN_CNTL, data);
741257e252bfSMichael Neumann
741357e252bfSMichael Neumann orig = data = RREG32(CG_CLKPIN_CNTL_2);
741457e252bfSMichael Neumann data &= ~FORCE_BIF_REFCLK_EN;
741557e252bfSMichael Neumann if (orig != data)
741657e252bfSMichael Neumann WREG32(CG_CLKPIN_CNTL_2, data);
741757e252bfSMichael Neumann
741857e252bfSMichael Neumann orig = data = RREG32(MPLL_BYPASSCLK_SEL);
741957e252bfSMichael Neumann data &= ~MPLL_CLKOUT_SEL_MASK;
742057e252bfSMichael Neumann data |= MPLL_CLKOUT_SEL(4);
742157e252bfSMichael Neumann if (orig != data)
742257e252bfSMichael Neumann WREG32(MPLL_BYPASSCLK_SEL, data);
742357e252bfSMichael Neumann
742457e252bfSMichael Neumann orig = data = RREG32(SPLL_CNTL_MODE);
742557e252bfSMichael Neumann data &= ~SPLL_REFCLK_SEL_MASK;
742657e252bfSMichael Neumann if (orig != data)
742757e252bfSMichael Neumann WREG32(SPLL_CNTL_MODE, data);
742857e252bfSMichael Neumann }
742957e252bfSMichael Neumann }
743057e252bfSMichael Neumann } else {
743157e252bfSMichael Neumann if (orig != data)
743257e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
743357e252bfSMichael Neumann }
743457e252bfSMichael Neumann
743557e252bfSMichael Neumann orig = data = RREG32_PCIE(PCIE_CNTL2);
743657e252bfSMichael Neumann data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN;
743757e252bfSMichael Neumann if (orig != data)
743857e252bfSMichael Neumann WREG32_PCIE(PCIE_CNTL2, data);
743957e252bfSMichael Neumann
744057e252bfSMichael Neumann if (!disable_l0s) {
744157e252bfSMichael Neumann data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
744257e252bfSMichael Neumann if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) {
744357e252bfSMichael Neumann data = RREG32_PCIE(PCIE_LC_STATUS1);
744457e252bfSMichael Neumann if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) {
744557e252bfSMichael Neumann orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
744657e252bfSMichael Neumann data &= ~LC_L0S_INACTIVITY_MASK;
744757e252bfSMichael Neumann if (orig != data)
744857e252bfSMichael Neumann WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
744957e252bfSMichael Neumann }
745057e252bfSMichael Neumann }
745157e252bfSMichael Neumann }
745257e252bfSMichael Neumann }
7453c59a5c48SFrançois Tigeot
si_vce_send_vcepll_ctlreq(struct radeon_device * rdev)7454c59a5c48SFrançois Tigeot static int si_vce_send_vcepll_ctlreq(struct radeon_device *rdev)
7455c59a5c48SFrançois Tigeot {
7456c59a5c48SFrançois Tigeot unsigned i;
7457c59a5c48SFrançois Tigeot
7458c59a5c48SFrançois Tigeot /* make sure VCEPLL_CTLREQ is deasserted */
7459c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
7460c59a5c48SFrançois Tigeot
7461c59a5c48SFrançois Tigeot mdelay(10);
7462c59a5c48SFrançois Tigeot
7463c59a5c48SFrançois Tigeot /* assert UPLL_CTLREQ */
7464c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK);
7465c59a5c48SFrançois Tigeot
7466c59a5c48SFrançois Tigeot /* wait for CTLACK and CTLACK2 to get asserted */
7467c59a5c48SFrançois Tigeot for (i = 0; i < 100; ++i) {
7468c59a5c48SFrançois Tigeot uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK;
7469c59a5c48SFrançois Tigeot if ((RREG32_SMC(CG_VCEPLL_FUNC_CNTL) & mask) == mask)
7470c59a5c48SFrançois Tigeot break;
7471c59a5c48SFrançois Tigeot mdelay(10);
7472c59a5c48SFrançois Tigeot }
7473c59a5c48SFrançois Tigeot
7474c59a5c48SFrançois Tigeot /* deassert UPLL_CTLREQ */
7475c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
7476c59a5c48SFrançois Tigeot
7477c59a5c48SFrançois Tigeot if (i == 100) {
7478c59a5c48SFrançois Tigeot DRM_ERROR("Timeout setting UVD clocks!\n");
7479c59a5c48SFrançois Tigeot return -ETIMEDOUT;
7480c59a5c48SFrançois Tigeot }
7481c59a5c48SFrançois Tigeot
7482c59a5c48SFrançois Tigeot return 0;
7483c59a5c48SFrançois Tigeot }
7484c59a5c48SFrançois Tigeot
si_set_vce_clocks(struct radeon_device * rdev,u32 evclk,u32 ecclk)7485c59a5c48SFrançois Tigeot int si_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
7486c59a5c48SFrançois Tigeot {
7487c59a5c48SFrançois Tigeot unsigned fb_div = 0, evclk_div = 0, ecclk_div = 0;
7488c59a5c48SFrançois Tigeot int r;
7489c59a5c48SFrançois Tigeot
7490c59a5c48SFrançois Tigeot /* bypass evclk and ecclk with bclk */
7491c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7492c59a5c48SFrançois Tigeot EVCLK_SRC_SEL(1) | ECCLK_SRC_SEL(1),
7493c59a5c48SFrançois Tigeot ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK));
7494c59a5c48SFrançois Tigeot
7495c59a5c48SFrançois Tigeot /* put PLL in bypass mode */
7496c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_BYPASS_EN_MASK,
7497c59a5c48SFrançois Tigeot ~VCEPLL_BYPASS_EN_MASK);
7498c59a5c48SFrançois Tigeot
7499c59a5c48SFrançois Tigeot if (!evclk || !ecclk) {
7500c59a5c48SFrançois Tigeot /* keep the Bypass mode, put PLL to sleep */
7501c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK,
7502c59a5c48SFrançois Tigeot ~VCEPLL_SLEEP_MASK);
7503c59a5c48SFrançois Tigeot return 0;
7504c59a5c48SFrançois Tigeot }
7505c59a5c48SFrançois Tigeot
7506c59a5c48SFrançois Tigeot r = radeon_uvd_calc_upll_dividers(rdev, evclk, ecclk, 125000, 250000,
7507c59a5c48SFrançois Tigeot 16384, 0x03FFFFFF, 0, 128, 5,
7508c59a5c48SFrançois Tigeot &fb_div, &evclk_div, &ecclk_div);
7509c59a5c48SFrançois Tigeot if (r)
7510c59a5c48SFrançois Tigeot return r;
7511c59a5c48SFrançois Tigeot
7512c59a5c48SFrançois Tigeot /* set RESET_ANTI_MUX to 0 */
7513c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
7514c59a5c48SFrançois Tigeot
7515c59a5c48SFrançois Tigeot /* set VCO_MODE to 1 */
7516c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_VCO_MODE_MASK,
7517c59a5c48SFrançois Tigeot ~VCEPLL_VCO_MODE_MASK);
7518c59a5c48SFrançois Tigeot
7519c59a5c48SFrançois Tigeot /* toggle VCEPLL_SLEEP to 1 then back to 0 */
7520c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK,
7521c59a5c48SFrançois Tigeot ~VCEPLL_SLEEP_MASK);
7522c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_SLEEP_MASK);
7523c59a5c48SFrançois Tigeot
7524c59a5c48SFrançois Tigeot /* deassert VCEPLL_RESET */
7525c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK);
7526c59a5c48SFrançois Tigeot
7527c59a5c48SFrançois Tigeot mdelay(1);
7528c59a5c48SFrançois Tigeot
7529c59a5c48SFrançois Tigeot r = si_vce_send_vcepll_ctlreq(rdev);
7530c59a5c48SFrançois Tigeot if (r)
7531c59a5c48SFrançois Tigeot return r;
7532c59a5c48SFrançois Tigeot
7533c59a5c48SFrançois Tigeot /* assert VCEPLL_RESET again */
7534c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_RESET_MASK, ~VCEPLL_RESET_MASK);
7535c59a5c48SFrançois Tigeot
7536c59a5c48SFrançois Tigeot /* disable spread spectrum. */
7537c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
7538c59a5c48SFrançois Tigeot
7539c59a5c48SFrançois Tigeot /* set feedback divider */
7540c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_3, VCEPLL_FB_DIV(fb_div), ~VCEPLL_FB_DIV_MASK);
7541c59a5c48SFrançois Tigeot
7542c59a5c48SFrançois Tigeot /* set ref divider to 0 */
7543c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_REF_DIV_MASK);
7544c59a5c48SFrançois Tigeot
7545c59a5c48SFrançois Tigeot /* set PDIV_A and PDIV_B */
7546c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7547c59a5c48SFrançois Tigeot VCEPLL_PDIV_A(evclk_div) | VCEPLL_PDIV_B(ecclk_div),
7548c59a5c48SFrançois Tigeot ~(VCEPLL_PDIV_A_MASK | VCEPLL_PDIV_B_MASK));
7549c59a5c48SFrançois Tigeot
7550c59a5c48SFrançois Tigeot /* give the PLL some time to settle */
7551c59a5c48SFrançois Tigeot mdelay(15);
7552c59a5c48SFrançois Tigeot
7553c59a5c48SFrançois Tigeot /* deassert PLL_RESET */
7554c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK);
7555c59a5c48SFrançois Tigeot
7556c59a5c48SFrançois Tigeot mdelay(15);
7557c59a5c48SFrançois Tigeot
7558c59a5c48SFrançois Tigeot /* switch from bypass mode to normal mode */
7559c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_BYPASS_EN_MASK);
7560c59a5c48SFrançois Tigeot
7561c59a5c48SFrançois Tigeot r = si_vce_send_vcepll_ctlreq(rdev);
7562c59a5c48SFrançois Tigeot if (r)
7563c59a5c48SFrançois Tigeot return r;
7564c59a5c48SFrançois Tigeot
7565c59a5c48SFrançois Tigeot /* switch VCLK and DCLK selection */
7566c59a5c48SFrançois Tigeot WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7567c59a5c48SFrançois Tigeot EVCLK_SRC_SEL(16) | ECCLK_SRC_SEL(16),
7568c59a5c48SFrançois Tigeot ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK));
7569c59a5c48SFrançois Tigeot
7570c59a5c48SFrançois Tigeot mdelay(100);
7571c59a5c48SFrançois Tigeot
7572c59a5c48SFrançois Tigeot return 0;
7573c59a5c48SFrançois Tigeot }
7574