You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'drm-radeon-sitn-support' of git://people.freedesktop.org/~airlied/linux
Pull radeon southern islands / trinity support from Dave Airlie: "This is support from AMD for their newest GPU and APUs. The products called RadeonHD 7xxx, and the Trinity APU series. This did come in a bit late, due to some over-complicated AMD internal review process, which from the outside seems unnecessary once the company has decided it wants to support open source. However as I said previously I'd rather not put the people who've got this hw for 3 months now being forced to use fglrx on it if there is open code. Its pretty well self contained and just plugs into the driver in various places." * 'drm-radeon-sitn-support' of git://people.freedesktop.org/~airlied/linux: (48 commits) drm/radeon/kms: update duallink checks for DCE6 drm/radeon/kms: add trinity pci ids drm/radeon/kms: add radeon_asic struct for trinity drm/radeon/kms: add support for ucode loading on trinity (v2) drm/radeon/kms/vm: set vram base offset properly for TN drm/radeon/kms: Update evergreen functions for trinity drm/radeon/kms: cayman gpu init updates for trinity drm/radeon/kms: Add checks for TN in the DP bridge code drm/radeon/kms/DCE6.1: ss is not supported on the internal pplls drm/radeon/kms: disable PPLL0 on DCE6.1 when not in use drm/radeon/kms: Adjust pll picker for DCE6.1 drm/radeon/kms: DCE6.1 disp eng pll updates drm/radeon/kms: DCE6.1 watermark updates for TN drm/radeon/kms: no support for internal thermal sensor on TN yet drm/radeon/kms: add trinity (TN) chip family drm/radeon/kms: Add SI pci ids drm/radeon: Update radeon_info_ioctl for SI. (v2) drm/radeon/kms: add radeon_asic struct for SI drm/radeon/kms: add support for compute rings in CS ioctl on SI drm/radeon/kms: fill in startup/shutdown callbacks for SI ...
This commit is contained in:
@@ -71,7 +71,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
|
||||
r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
|
||||
evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
|
||||
radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \
|
||||
radeon_semaphore.o radeon_sa.o atombios_i2c.o
|
||||
radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o si_blit_shaders.o
|
||||
|
||||
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
|
||||
radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA 0x1F
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 0x20
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 0x21
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_VCE 0x24
|
||||
|
||||
#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF
|
||||
|
||||
@@ -387,6 +388,10 @@
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_VCE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_VCE << OBJECT_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Connector Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
|
||||
+1048
-61
File diff suppressed because it is too large
Load Diff
@@ -231,6 +231,22 @@ static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_powergate_crtc(struct drm_crtc *crtc, int state)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
|
||||
ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
args.ucDispPipeId = radeon_crtc->crtc_id;
|
||||
args.ucEnable = state;
|
||||
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
@@ -242,8 +258,11 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
radeon_crtc->enabled = true;
|
||||
/* adjust pm to dpms changes BEFORE enabling crtcs */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
/* disable crtc pair power gating before programming */
|
||||
if (ASIC_IS_DCE6(rdev))
|
||||
atombios_powergate_crtc(crtc, ATOM_DISABLE);
|
||||
atombios_enable_crtc(crtc, ATOM_ENABLE);
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
|
||||
atombios_blank_crtc(crtc, ATOM_DISABLE);
|
||||
drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
|
||||
@@ -255,10 +274,29 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
|
||||
if (radeon_crtc->enabled)
|
||||
atombios_blank_crtc(crtc, ATOM_ENABLE);
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
|
||||
atombios_enable_crtc(crtc, ATOM_DISABLE);
|
||||
radeon_crtc->enabled = false;
|
||||
/* power gating is per-pair */
|
||||
if (ASIC_IS_DCE6(rdev)) {
|
||||
struct drm_crtc *other_crtc;
|
||||
struct radeon_crtc *other_radeon_crtc;
|
||||
list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) {
|
||||
other_radeon_crtc = to_radeon_crtc(other_crtc);
|
||||
if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) ||
|
||||
((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) ||
|
||||
((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) ||
|
||||
((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) ||
|
||||
((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) ||
|
||||
((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) {
|
||||
/* if both crtcs in the pair are off, enable power gating */
|
||||
if (other_radeon_crtc->enabled == false)
|
||||
atombios_powergate_crtc(crtc, ATOM_ENABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* adjust pm to dpms changes AFTER disabling crtcs */
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
break;
|
||||
@@ -436,7 +474,7 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev,
|
||||
return;
|
||||
}
|
||||
args.v3.ucEnable = enable;
|
||||
if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK))
|
||||
if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE61(rdev))
|
||||
args.v3.ucEnable = ATOM_DISABLE;
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
|
||||
@@ -699,7 +737,7 @@ union set_pixel_clock {
|
||||
/* on DCE5, make sure the voltage is high enough to support the
|
||||
* required disp clk.
|
||||
*/
|
||||
static void atombios_crtc_set_dcpll(struct radeon_device *rdev,
|
||||
static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev,
|
||||
u32 dispclk)
|
||||
{
|
||||
u8 frev, crev;
|
||||
@@ -729,7 +767,12 @@ static void atombios_crtc_set_dcpll(struct radeon_device *rdev,
|
||||
* SetPixelClock provides the dividers
|
||||
*/
|
||||
args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
|
||||
args.v6.ucPpll = ATOM_DCPLL;
|
||||
if (ASIC_IS_DCE61(rdev))
|
||||
args.v6.ucPpll = ATOM_EXT_PLL1;
|
||||
else if (ASIC_IS_DCE6(rdev))
|
||||
args.v6.ucPpll = ATOM_PPLL0;
|
||||
else
|
||||
args.v6.ucPpll = ATOM_DCPLL;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d %d\n", frev, crev);
|
||||
@@ -1444,7 +1487,36 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
struct drm_crtc *test_crtc;
|
||||
uint32_t pll_in_use = 0;
|
||||
|
||||
if (ASIC_IS_DCE4(rdev)) {
|
||||
if (ASIC_IS_DCE61(rdev)) {
|
||||
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
|
||||
struct radeon_encoder *test_radeon_encoder =
|
||||
to_radeon_encoder(test_encoder);
|
||||
struct radeon_encoder_atom_dig *dig =
|
||||
test_radeon_encoder->enc_priv;
|
||||
|
||||
if ((test_radeon_encoder->encoder_id ==
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
|
||||
(dig->linkb == false)) /* UNIPHY A uses PPLL2 */
|
||||
return ATOM_PPLL2;
|
||||
}
|
||||
}
|
||||
/* UNIPHY B/C/D/E/F */
|
||||
list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct radeon_crtc *radeon_test_crtc;
|
||||
|
||||
if (crtc == test_crtc)
|
||||
continue;
|
||||
|
||||
radeon_test_crtc = to_radeon_crtc(test_crtc);
|
||||
if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
|
||||
(radeon_test_crtc->pll_id == ATOM_PPLL1))
|
||||
pll_in_use |= (1 << radeon_test_crtc->pll_id);
|
||||
}
|
||||
if (!(pll_in_use & 4))
|
||||
return ATOM_PPLL0;
|
||||
return ATOM_PPLL1;
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
|
||||
/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
|
||||
@@ -1483,10 +1555,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
|
||||
}
|
||||
|
||||
void radeon_atom_dcpll_init(struct radeon_device *rdev)
|
||||
void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
|
||||
{
|
||||
/* always set DCPLL */
|
||||
if (ASIC_IS_DCE4(rdev)) {
|
||||
if (ASIC_IS_DCE6(rdev))
|
||||
atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
|
||||
else if (ASIC_IS_DCE4(rdev)) {
|
||||
struct radeon_atom_ss ss;
|
||||
bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
|
||||
ASIC_INTERNAL_SS_ON_DCPLL,
|
||||
@@ -1494,7 +1568,7 @@ void radeon_atom_dcpll_init(struct radeon_device *rdev)
|
||||
if (ss_enabled)
|
||||
atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss);
|
||||
/* XXX: DCE5, make sure voltage, dispclk is high enough */
|
||||
atombios_crtc_set_dcpll(rdev, rdev->clock.default_dispclk);
|
||||
atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
|
||||
if (ss_enabled)
|
||||
atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss);
|
||||
}
|
||||
@@ -1572,6 +1646,8 @@ static void atombios_crtc_commit(struct drm_crtc *crtc)
|
||||
static void atombios_crtc_disable(struct drm_crtc *crtc)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_atom_ss ss;
|
||||
|
||||
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||
@@ -1583,6 +1659,12 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
|
||||
atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
|
||||
0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
|
||||
break;
|
||||
case ATOM_PPLL0:
|
||||
/* disable the ppll */
|
||||
if (ASIC_IS_DCE61(rdev))
|
||||
atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
|
||||
0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -63,12 +63,12 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
base = (unsigned char *)rdev->mode_info.atom_context->scratch;
|
||||
base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
|
||||
|
||||
memcpy(base, send, send_bytes);
|
||||
|
||||
args.v1.lpAuxRequest = 0;
|
||||
args.v1.lpDataOut = 16;
|
||||
args.v1.lpAuxRequest = 0 + 4;
|
||||
args.v1.lpDataOut = 16 + 4;
|
||||
args.v1.ucDataOutLen = 0;
|
||||
args.v1.ucChannelID = chan->rec.i2c_id;
|
||||
args.v1.ucDelay = delay / 10;
|
||||
|
||||
@@ -479,7 +479,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
|
||||
* - 2 DIG encoder blocks.
|
||||
* DIG1/2 can drive UNIPHY0/1/2 link A or link B
|
||||
*
|
||||
* DCE 4.0/5.0
|
||||
* DCE 4.0/5.0/6.0
|
||||
* - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
|
||||
* Supports up to 6 digital outputs
|
||||
* - 6 DIG encoder blocks.
|
||||
@@ -495,7 +495,11 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
|
||||
* - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
|
||||
* Supports up to 6 digital outputs
|
||||
* - 2 DIG encoder blocks.
|
||||
* llano
|
||||
* DIG1/2 can drive UNIPHY0/1/2 link A or link B
|
||||
* ontario
|
||||
* DIG1 drives UNIPHY0/1/2 link A
|
||||
* DIG2 drives UNIPHY0/1/2 link B
|
||||
*
|
||||
* Routing
|
||||
* crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
|
||||
@@ -703,6 +707,7 @@ union dig_transmitter_control {
|
||||
DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
|
||||
DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;
|
||||
DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4;
|
||||
DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5;
|
||||
};
|
||||
|
||||
void
|
||||
@@ -723,6 +728,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
||||
int connector_object_id = 0;
|
||||
int igp_lane_info = 0;
|
||||
int dig_encoder = dig->dig_encoder;
|
||||
int hpd_id = RADEON_HPD_NONE;
|
||||
|
||||
if (action == ATOM_TRANSMITTER_ACTION_INIT) {
|
||||
connector = radeon_get_connector_for_encoder_init(encoder);
|
||||
@@ -738,6 +744,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
||||
struct radeon_connector_atom_dig *dig_connector =
|
||||
radeon_connector->con_priv;
|
||||
|
||||
hpd_id = radeon_connector->hpd.hpd;
|
||||
dp_clock = dig_connector->dp_clock;
|
||||
dp_lane_count = dig_connector->dp_lane_count;
|
||||
connector_object_id =
|
||||
@@ -1003,6 +1010,60 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
||||
args.v4.acConfig.fDualLinkConnector = 1;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
args.v5.ucAction = action;
|
||||
if (is_dp)
|
||||
args.v5.usSymClock = cpu_to_le16(dp_clock / 10);
|
||||
else
|
||||
args.v5.usSymClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
||||
|
||||
switch (radeon_encoder->encoder_id) {
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||
if (dig->linkb)
|
||||
args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYB;
|
||||
else
|
||||
args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYA;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||
if (dig->linkb)
|
||||
args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYD;
|
||||
else
|
||||
args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYC;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||
if (dig->linkb)
|
||||
args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYF;
|
||||
else
|
||||
args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYE;
|
||||
break;
|
||||
}
|
||||
if (is_dp)
|
||||
args.v5.ucLaneNum = dp_lane_count;
|
||||
else if (radeon_encoder->pixel_clock > 165000)
|
||||
args.v5.ucLaneNum = 8;
|
||||
else
|
||||
args.v5.ucLaneNum = 4;
|
||||
args.v5.ucConnObjId = connector_object_id;
|
||||
args.v5.ucDigMode = atombios_get_encoder_mode(encoder);
|
||||
|
||||
if (is_dp && rdev->clock.dp_extclk)
|
||||
args.v5.asConfig.ucPhyClkSrcId = ENCODER_REFCLK_SRC_EXTCLK;
|
||||
else
|
||||
args.v5.asConfig.ucPhyClkSrcId = pll_id;
|
||||
|
||||
if (is_dp)
|
||||
args.v5.asConfig.ucCoherentMode = 1; /* DP requires coherent */
|
||||
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
||||
if (dig->coherent_mode)
|
||||
args.v5.asConfig.ucCoherentMode = 1;
|
||||
}
|
||||
if (hpd_id == RADEON_HPD_NONE)
|
||||
args.v5.asConfig.ucHPDSel = 0;
|
||||
else
|
||||
args.v5.asConfig.ucHPDSel = hpd_id + 1;
|
||||
args.v5.ucDigEncoderSel = 1 << dig_encoder;
|
||||
args.v5.ucDPLaneSet = lane_set;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
|
||||
break;
|
||||
@@ -1377,7 +1438,7 @@ radeon_atom_encoder_dpms_ext(struct drm_encoder *encoder,
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
default:
|
||||
if (ASIC_IS_DCE41(rdev)) {
|
||||
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) {
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT);
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
@@ -1388,7 +1449,7 @@ radeon_atom_encoder_dpms_ext(struct drm_encoder *encoder,
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
if (ASIC_IS_DCE41(rdev)) {
|
||||
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) {
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING);
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
@@ -1761,7 +1822,7 @@ radeon_atom_encoder_init(struct radeon_device *rdev)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ext_encoder && ASIC_IS_DCE41(rdev))
|
||||
if (ext_encoder && (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)))
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
|
||||
}
|
||||
@@ -1850,7 +1911,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
|
||||
}
|
||||
|
||||
if (ext_encoder) {
|
||||
if (ASIC_IS_DCE41(rdev))
|
||||
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
|
||||
else
|
||||
|
||||
@@ -581,7 +581,7 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev)
|
||||
u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp = RREG32(MC_SHARED_CHMAP);
|
||||
|
||||
@@ -1328,7 +1328,10 @@ void evergreen_mc_program(struct radeon_device *rdev)
|
||||
rdev->mc.vram_end >> 12);
|
||||
}
|
||||
WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
/* llano/ontario only */
|
||||
if ((rdev->family == CHIP_PALM) ||
|
||||
(rdev->family == CHIP_SUMO) ||
|
||||
(rdev->family == CHIP_SUMO2)) {
|
||||
tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF;
|
||||
tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24;
|
||||
tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20;
|
||||
@@ -1972,7 +1975,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
||||
|
||||
|
||||
mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
if ((rdev->family == CHIP_PALM) ||
|
||||
(rdev->family == CHIP_SUMO) ||
|
||||
(rdev->family == CHIP_SUMO2))
|
||||
mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG);
|
||||
else
|
||||
mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
|
||||
@@ -2362,7 +2367,9 @@ int evergreen_mc_init(struct radeon_device *rdev)
|
||||
|
||||
/* Get VRAM informations */
|
||||
rdev->mc.vram_is_ddr = true;
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
if ((rdev->family == CHIP_PALM) ||
|
||||
(rdev->family == CHIP_SUMO) ||
|
||||
(rdev->family == CHIP_SUMO2))
|
||||
tmp = RREG32(FUS_MC_ARB_RAMCFG);
|
||||
else
|
||||
tmp = RREG32(MC_ARB_RAMCFG);
|
||||
@@ -2394,12 +2401,14 @@ int evergreen_mc_init(struct radeon_device *rdev)
|
||||
rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
|
||||
rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
|
||||
/* Setup GPU memory space */
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
if ((rdev->family == CHIP_PALM) ||
|
||||
(rdev->family == CHIP_SUMO) ||
|
||||
(rdev->family == CHIP_SUMO2)) {
|
||||
/* size in bytes on fusion */
|
||||
rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
} else {
|
||||
/* size in MB on evergreen */
|
||||
/* size in MB on evergreen/cayman/tn */
|
||||
rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
|
||||
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
|
||||
}
|
||||
@@ -2557,7 +2566,9 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev)
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
||||
}
|
||||
|
||||
WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
|
||||
/* only one DAC on DCE6 */
|
||||
if (!ASIC_IS_DCE6(rdev))
|
||||
WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
|
||||
WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
|
||||
|
||||
tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
|
||||
|
||||
@@ -226,7 +226,7 @@ set_scissors(struct radeon_device *rdev, int x1, int y1,
|
||||
x1 = 1;
|
||||
if (y2 == 0)
|
||||
y1 = 1;
|
||||
if (rdev->family == CHIP_CAYMAN) {
|
||||
if (rdev->family >= CHIP_CAYMAN) {
|
||||
if ((x2 == 1) && (y2 == 1))
|
||||
x2 = 2;
|
||||
}
|
||||
|
||||
+118
-23
@@ -42,6 +42,8 @@ extern void evergreen_irq_suspend(struct radeon_device *rdev);
|
||||
extern int evergreen_mc_init(struct radeon_device *rdev);
|
||||
extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
|
||||
extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
|
||||
extern void si_rlc_fini(struct radeon_device *rdev);
|
||||
extern int si_rlc_init(struct radeon_device *rdev);
|
||||
|
||||
#define EVERGREEN_PFP_UCODE_SIZE 1120
|
||||
#define EVERGREEN_PM4_UCODE_SIZE 1376
|
||||
@@ -53,6 +55,8 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
|
||||
#define CAYMAN_RLC_UCODE_SIZE 1024
|
||||
#define CAYMAN_MC_UCODE_SIZE 6037
|
||||
|
||||
#define ARUBA_RLC_UCODE_SIZE 1536
|
||||
|
||||
/* Firmware Names */
|
||||
MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
|
||||
MODULE_FIRMWARE("radeon/BARTS_me.bin");
|
||||
@@ -68,6 +72,9 @@ MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
|
||||
MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
|
||||
MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
|
||||
MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
|
||||
MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
|
||||
MODULE_FIRMWARE("radeon/ARUBA_me.bin");
|
||||
MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
|
||||
|
||||
#define BTC_IO_MC_REGS_SIZE 29
|
||||
|
||||
@@ -326,6 +333,15 @@ int ni_init_microcode(struct radeon_device *rdev)
|
||||
rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
|
||||
mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
|
||||
break;
|
||||
case CHIP_ARUBA:
|
||||
chip_name = "ARUBA";
|
||||
rlc_chip_name = "ARUBA";
|
||||
/* pfp/me same size as CAYMAN */
|
||||
pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
|
||||
me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
|
||||
rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
|
||||
mc_req_size = 0;
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
|
||||
@@ -365,15 +381,18 @@ int ni_init_microcode(struct radeon_device *rdev)
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
|
||||
err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
if (rdev->mc_fw->size != mc_req_size) {
|
||||
printk(KERN_ERR
|
||||
"ni_mc: Bogus length %zu in firmware \"%s\"\n",
|
||||
rdev->mc_fw->size, fw_name);
|
||||
err = -EINVAL;
|
||||
/* no MC ucode on TN */
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
|
||||
err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
if (rdev->mc_fw->size != mc_req_size) {
|
||||
printk(KERN_ERR
|
||||
"ni_mc: Bogus length %zu in firmware \"%s\"\n",
|
||||
rdev->mc_fw->size, fw_name);
|
||||
err = -EINVAL;
|
||||
}
|
||||
}
|
||||
out:
|
||||
platform_device_unregister(pdev);
|
||||
@@ -478,6 +497,7 @@ static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
|
||||
memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * CAYMAN_MAX_PIPES);
|
||||
switch (rdev->family) {
|
||||
case CHIP_CAYMAN:
|
||||
case CHIP_ARUBA:
|
||||
force_no_swizzle = true;
|
||||
break;
|
||||
default:
|
||||
@@ -610,7 +630,6 @@ static void cayman_gpu_init(struct radeon_device *rdev)
|
||||
|
||||
switch (rdev->family) {
|
||||
case CHIP_CAYMAN:
|
||||
default:
|
||||
rdev->config.cayman.max_shader_engines = 2;
|
||||
rdev->config.cayman.max_pipes_per_simd = 4;
|
||||
rdev->config.cayman.max_tile_pipes = 8;
|
||||
@@ -632,6 +651,43 @@ static void cayman_gpu_init(struct radeon_device *rdev)
|
||||
rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
|
||||
rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
|
||||
break;
|
||||
case CHIP_ARUBA:
|
||||
default:
|
||||
rdev->config.cayman.max_shader_engines = 1;
|
||||
rdev->config.cayman.max_pipes_per_simd = 4;
|
||||
rdev->config.cayman.max_tile_pipes = 2;
|
||||
if ((rdev->pdev->device == 0x9900) ||
|
||||
(rdev->pdev->device == 0x9901)) {
|
||||
rdev->config.cayman.max_simds_per_se = 6;
|
||||
rdev->config.cayman.max_backends_per_se = 2;
|
||||
} else if ((rdev->pdev->device == 0x9903) ||
|
||||
(rdev->pdev->device == 0x9904)) {
|
||||
rdev->config.cayman.max_simds_per_se = 4;
|
||||
rdev->config.cayman.max_backends_per_se = 2;
|
||||
} else if ((rdev->pdev->device == 0x9990) ||
|
||||
(rdev->pdev->device == 0x9991)) {
|
||||
rdev->config.cayman.max_simds_per_se = 3;
|
||||
rdev->config.cayman.max_backends_per_se = 1;
|
||||
} else {
|
||||
rdev->config.cayman.max_simds_per_se = 2;
|
||||
rdev->config.cayman.max_backends_per_se = 1;
|
||||
}
|
||||
rdev->config.cayman.max_texture_channel_caches = 2;
|
||||
rdev->config.cayman.max_gprs = 256;
|
||||
rdev->config.cayman.max_threads = 256;
|
||||
rdev->config.cayman.max_gs_threads = 32;
|
||||
rdev->config.cayman.max_stack_entries = 512;
|
||||
rdev->config.cayman.sx_num_of_sets = 8;
|
||||
rdev->config.cayman.sx_max_export_size = 256;
|
||||
rdev->config.cayman.sx_max_export_pos_size = 64;
|
||||
rdev->config.cayman.sx_max_export_smx_size = 192;
|
||||
rdev->config.cayman.max_hw_contexts = 8;
|
||||
rdev->config.cayman.sq_num_cf_insts = 2;
|
||||
|
||||
rdev->config.cayman.sc_prim_fifo_size = 0x40;
|
||||
rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
|
||||
rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Initialize HDP */
|
||||
@@ -652,7 +708,9 @@ static void cayman_gpu_init(struct radeon_device *rdev)
|
||||
|
||||
cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE);
|
||||
cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG);
|
||||
cgts_tcc_disable = 0xff000000;
|
||||
cgts_tcc_disable = 0xffff0000;
|
||||
for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
|
||||
cgts_tcc_disable &= ~(1 << (16 + i));
|
||||
gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE);
|
||||
gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG);
|
||||
cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE);
|
||||
@@ -804,8 +862,13 @@ static void cayman_gpu_init(struct radeon_device *rdev)
|
||||
rdev->config.cayman.tile_config |= (3 << 0);
|
||||
break;
|
||||
}
|
||||
rdev->config.cayman.tile_config |=
|
||||
((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
|
||||
|
||||
/* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
rdev->config.evergreen.tile_config |= 1 << 4;
|
||||
else
|
||||
rdev->config.cayman.tile_config |=
|
||||
((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
|
||||
rdev->config.cayman.tile_config |=
|
||||
((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
|
||||
rdev->config.cayman.tile_config |=
|
||||
@@ -1440,18 +1503,29 @@ static int cayman_startup(struct radeon_device *rdev)
|
||||
/* enable pcie gen2 link */
|
||||
evergreen_pcie_gen2_enable(rdev);
|
||||
|
||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
|
||||
r = ni_init_microcode(rdev);
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
||||
r = ni_init_microcode(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to load firmware!\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
|
||||
r = ni_init_microcode(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to load firmware!\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = ni_mc_load_microcode(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to load firmware!\n");
|
||||
DRM_ERROR("Failed to load MC firmware!\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
r = ni_mc_load_microcode(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to load MC firmware!\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = r600_vram_scratch_init(rdev);
|
||||
if (r)
|
||||
@@ -1470,6 +1544,15 @@ static int cayman_startup(struct radeon_device *rdev)
|
||||
dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
|
||||
}
|
||||
|
||||
/* allocate rlc buffers */
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
r = si_rlc_init(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to init rlc BOs!\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate wb buffer */
|
||||
r = radeon_wb_init(rdev);
|
||||
if (r)
|
||||
@@ -1654,6 +1737,8 @@ int cayman_init(struct radeon_device *rdev)
|
||||
dev_err(rdev->dev, "disabling GPU acceleration\n");
|
||||
cayman_cp_fini(rdev);
|
||||
r600_irq_fini(rdev);
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
si_rlc_fini(rdev);
|
||||
radeon_wb_fini(rdev);
|
||||
r100_ib_fini(rdev);
|
||||
radeon_vm_manager_fini(rdev);
|
||||
@@ -1665,8 +1750,11 @@ int cayman_init(struct radeon_device *rdev)
|
||||
/* Don't start up if the MC ucode is missing.
|
||||
* The default clocks and voltages before the MC ucode
|
||||
* is loaded are not suffient for advanced operations.
|
||||
*
|
||||
* We can skip this check for TN, because there is no MC
|
||||
* ucode.
|
||||
*/
|
||||
if (!rdev->mc_fw) {
|
||||
if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
|
||||
DRM_ERROR("radeon: MC ucode required for NI+.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1679,6 +1767,8 @@ void cayman_fini(struct radeon_device *rdev)
|
||||
r600_blit_fini(rdev);
|
||||
cayman_cp_fini(rdev);
|
||||
r600_irq_fini(rdev);
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
si_rlc_fini(rdev);
|
||||
radeon_wb_fini(rdev);
|
||||
radeon_vm_manager_fini(rdev);
|
||||
r100_ib_fini(rdev);
|
||||
@@ -1702,7 +1792,12 @@ int cayman_vm_init(struct radeon_device *rdev)
|
||||
/* number of VMs */
|
||||
rdev->vm_manager.nvm = 8;
|
||||
/* base offset of vram pages */
|
||||
rdev->vm_manager.vram_base_offset = 0;
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
|
||||
tmp <<= 22;
|
||||
rdev->vm_manager.vram_base_offset = tmp;
|
||||
} else
|
||||
rdev->vm_manager.vram_base_offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3)
|
||||
#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5)
|
||||
#define ENABLE_ADVANCED_DRIVER_MODEL (1 << 6)
|
||||
#define FUS_MC_VM_FB_OFFSET 0x2068
|
||||
|
||||
#define MC_SHARED_BLACKOUT_CNTL 0x20ac
|
||||
#define MC_ARB_RAMCFG 0x2760
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#define EVERGREEN_PM4_UCODE_SIZE 1376
|
||||
#define EVERGREEN_RLC_UCODE_SIZE 768
|
||||
#define CAYMAN_RLC_UCODE_SIZE 1024
|
||||
#define ARUBA_RLC_UCODE_SIZE 1536
|
||||
|
||||
/* Firmware Names */
|
||||
MODULE_FIRMWARE("radeon/R600_pfp.bin");
|
||||
@@ -2778,7 +2779,7 @@ void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
|
||||
rdev->ih.rptr = 0;
|
||||
}
|
||||
|
||||
static int r600_ih_ring_alloc(struct radeon_device *rdev)
|
||||
int r600_ih_ring_alloc(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -2814,7 +2815,7 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void r600_ih_ring_fini(struct radeon_device *rdev)
|
||||
void r600_ih_ring_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
if (rdev->ih.ring_obj) {
|
||||
@@ -2861,10 +2862,17 @@ static int r600_rlc_init(struct radeon_device *rdev)
|
||||
|
||||
r600_rlc_stop(rdev);
|
||||
|
||||
WREG32(RLC_HB_BASE, 0);
|
||||
WREG32(RLC_HB_CNTL, 0);
|
||||
WREG32(RLC_HB_RPTR, 0);
|
||||
WREG32(RLC_HB_WPTR, 0);
|
||||
|
||||
if (rdev->family == CHIP_ARUBA) {
|
||||
WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
|
||||
WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
|
||||
}
|
||||
if (rdev->family <= CHIP_CAYMAN) {
|
||||
WREG32(RLC_HB_BASE, 0);
|
||||
WREG32(RLC_HB_RPTR, 0);
|
||||
WREG32(RLC_HB_WPTR, 0);
|
||||
}
|
||||
if (rdev->family <= CHIP_CAICOS) {
|
||||
WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
|
||||
WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
|
||||
@@ -2873,7 +2881,12 @@ static int r600_rlc_init(struct radeon_device *rdev)
|
||||
WREG32(RLC_UCODE_CNTL, 0);
|
||||
|
||||
fw_data = (const __be32 *)rdev->rlc_fw->data;
|
||||
if (rdev->family >= CHIP_CAYMAN) {
|
||||
if (rdev->family >= CHIP_ARUBA) {
|
||||
for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
} else if (rdev->family >= CHIP_CAYMAN) {
|
||||
for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
|
||||
@@ -593,6 +593,10 @@
|
||||
#define RLC_UCODE_ADDR 0x3f2c
|
||||
#define RLC_UCODE_DATA 0x3f30
|
||||
|
||||
/* new for TN */
|
||||
#define TN_RLC_SAVE_AND_RESTORE_BASE 0x3f10
|
||||
#define TN_RLC_CLEAR_STATE_RESTORE_BASE 0x3f20
|
||||
|
||||
#define SRBM_SOFT_RESET 0xe60
|
||||
# define SOFT_RESET_RLC (1 << 13)
|
||||
|
||||
|
||||
@@ -236,12 +236,12 @@ void radeon_pm_resume(struct radeon_device *rdev);
|
||||
void radeon_combios_get_power_modes(struct radeon_device *rdev);
|
||||
void radeon_atombios_get_power_modes(struct radeon_device *rdev);
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type);
|
||||
int radeon_atom_get_max_vddc(struct radeon_device *rdev, u16 *voltage);
|
||||
void rs690_pm_info(struct radeon_device *rdev);
|
||||
extern int rv6xx_get_temp(struct radeon_device *rdev);
|
||||
extern int rv770_get_temp(struct radeon_device *rdev);
|
||||
extern int evergreen_get_temp(struct radeon_device *rdev);
|
||||
extern int sumo_get_temp(struct radeon_device *rdev);
|
||||
extern int si_get_temp(struct radeon_device *rdev);
|
||||
extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
|
||||
unsigned *bankh, unsigned *mtaspect,
|
||||
unsigned *tile_split);
|
||||
@@ -632,6 +632,7 @@ struct radeon_ib {
|
||||
uint32_t *ptr;
|
||||
struct radeon_fence *fence;
|
||||
unsigned vm_id;
|
||||
bool is_const_ib;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -771,6 +772,18 @@ struct r600_blit {
|
||||
|
||||
void r600_blit_suspend(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* SI RLC stuff
|
||||
*/
|
||||
struct si_rlc {
|
||||
/* for power gating */
|
||||
struct radeon_bo *save_restore_obj;
|
||||
uint64_t save_restore_gpu_addr;
|
||||
/* for clear state */
|
||||
struct radeon_bo *clear_state_obj;
|
||||
uint64_t clear_state_gpu_addr;
|
||||
};
|
||||
|
||||
int radeon_ib_get(struct radeon_device *rdev, int ring,
|
||||
struct radeon_ib **ib, unsigned size);
|
||||
void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib);
|
||||
@@ -836,7 +849,9 @@ struct radeon_cs_parser {
|
||||
int chunk_ib_idx;
|
||||
int chunk_relocs_idx;
|
||||
int chunk_flags_idx;
|
||||
int chunk_const_ib_idx;
|
||||
struct radeon_ib *ib;
|
||||
struct radeon_ib *const_ib;
|
||||
void *track;
|
||||
unsigned family;
|
||||
int parser_error;
|
||||
@@ -978,6 +993,7 @@ enum radeon_int_thermal_type {
|
||||
THERMAL_TYPE_EVERGREEN,
|
||||
THERMAL_TYPE_SUMO,
|
||||
THERMAL_TYPE_NI,
|
||||
THERMAL_TYPE_SI,
|
||||
};
|
||||
|
||||
struct radeon_voltage {
|
||||
@@ -1369,6 +1385,37 @@ struct cayman_asic {
|
||||
struct r100_gpu_lockup lockup;
|
||||
};
|
||||
|
||||
struct si_asic {
|
||||
unsigned max_shader_engines;
|
||||
unsigned max_pipes_per_simd;
|
||||
unsigned max_tile_pipes;
|
||||
unsigned max_simds_per_se;
|
||||
unsigned max_backends_per_se;
|
||||
unsigned max_texture_channel_caches;
|
||||
unsigned max_gprs;
|
||||
unsigned max_gs_threads;
|
||||
unsigned max_hw_contexts;
|
||||
unsigned sc_prim_fifo_size_frontend;
|
||||
unsigned sc_prim_fifo_size_backend;
|
||||
unsigned sc_hiz_tile_fifo_size;
|
||||
unsigned sc_earlyz_tile_fifo_size;
|
||||
|
||||
unsigned num_shader_engines;
|
||||
unsigned num_tile_pipes;
|
||||
unsigned num_backends_per_se;
|
||||
unsigned backend_disable_mask_per_asic;
|
||||
unsigned backend_map;
|
||||
unsigned num_texture_channel_caches;
|
||||
unsigned mem_max_burst_length_bytes;
|
||||
unsigned mem_row_size_in_kb;
|
||||
unsigned shader_engine_tile_size;
|
||||
unsigned num_gpus;
|
||||
unsigned multi_gpu_tile_size;
|
||||
|
||||
unsigned tile_config;
|
||||
struct r100_gpu_lockup lockup;
|
||||
};
|
||||
|
||||
union radeon_asic_config {
|
||||
struct r300_asic r300;
|
||||
struct r100_asic r100;
|
||||
@@ -1376,6 +1423,7 @@ union radeon_asic_config {
|
||||
struct rv770_asic rv770;
|
||||
struct evergreen_asic evergreen;
|
||||
struct cayman_asic cayman;
|
||||
struct si_asic si;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1491,10 +1539,12 @@ struct radeon_device {
|
||||
const struct firmware *pfp_fw; /* r6/700 PFP firmware */
|
||||
const struct firmware *rlc_fw; /* r6/700 RLC firmware */
|
||||
const struct firmware *mc_fw; /* NI MC firmware */
|
||||
const struct firmware *ce_fw; /* SI CE firmware */
|
||||
struct r600_blit r600_blit;
|
||||
struct r600_vram_scratch vram_scratch;
|
||||
int msi_enabled; /* msi enabled */
|
||||
struct r600_ih ih; /* r6/700 interrupt ring */
|
||||
struct si_rlc rlc;
|
||||
struct work_struct hotplug_work;
|
||||
int num_crtc; /* number of crtcs */
|
||||
struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */
|
||||
@@ -1638,6 +1688,9 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
|
||||
#define ASIC_IS_DCE41(rdev) ((rdev->family >= CHIP_PALM) && \
|
||||
(rdev->flags & RADEON_IS_IGP))
|
||||
#define ASIC_IS_DCE5(rdev) ((rdev->family >= CHIP_BARTS))
|
||||
#define ASIC_IS_DCE6(rdev) ((rdev->family >= CHIP_ARUBA))
|
||||
#define ASIC_IS_DCE61(rdev) ((rdev->family >= CHIP_ARUBA) && \
|
||||
(rdev->flags & RADEON_IS_IGP))
|
||||
|
||||
/*
|
||||
* BIOS helpers.
|
||||
|
||||
@@ -1408,6 +1408,200 @@ static struct radeon_asic cayman_asic = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct radeon_asic trinity_asic = {
|
||||
.init = &cayman_init,
|
||||
.fini = &cayman_fini,
|
||||
.suspend = &cayman_suspend,
|
||||
.resume = &cayman_resume,
|
||||
.gpu_is_lockup = &cayman_gpu_is_lockup,
|
||||
.asic_reset = &cayman_asic_reset,
|
||||
.vga_set_state = &r600_vga_set_state,
|
||||
.ioctl_wait_idle = r600_ioctl_wait_idle,
|
||||
.gui_idle = &r600_gui_idle,
|
||||
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
|
||||
.gart = {
|
||||
.tlb_flush = &cayman_pcie_gart_tlb_flush,
|
||||
.set_page = &rs600_gart_set_page,
|
||||
},
|
||||
.ring = {
|
||||
[RADEON_RING_TYPE_GFX_INDEX] = {
|
||||
.ib_execute = &cayman_ring_ib_execute,
|
||||
.ib_parse = &evergreen_ib_parse,
|
||||
.emit_fence = &cayman_fence_ring_emit,
|
||||
.emit_semaphore = &r600_semaphore_ring_emit,
|
||||
.cs_parse = &evergreen_cs_parse,
|
||||
.ring_test = &r600_ring_test,
|
||||
.ib_test = &r600_ib_test,
|
||||
},
|
||||
[CAYMAN_RING_TYPE_CP1_INDEX] = {
|
||||
.ib_execute = &cayman_ring_ib_execute,
|
||||
.ib_parse = &evergreen_ib_parse,
|
||||
.emit_fence = &cayman_fence_ring_emit,
|
||||
.emit_semaphore = &r600_semaphore_ring_emit,
|
||||
.cs_parse = &evergreen_cs_parse,
|
||||
.ring_test = &r600_ring_test,
|
||||
.ib_test = &r600_ib_test,
|
||||
},
|
||||
[CAYMAN_RING_TYPE_CP2_INDEX] = {
|
||||
.ib_execute = &cayman_ring_ib_execute,
|
||||
.ib_parse = &evergreen_ib_parse,
|
||||
.emit_fence = &cayman_fence_ring_emit,
|
||||
.emit_semaphore = &r600_semaphore_ring_emit,
|
||||
.cs_parse = &evergreen_cs_parse,
|
||||
.ring_test = &r600_ring_test,
|
||||
.ib_test = &r600_ib_test,
|
||||
}
|
||||
},
|
||||
.irq = {
|
||||
.set = &evergreen_irq_set,
|
||||
.process = &evergreen_irq_process,
|
||||
},
|
||||
.display = {
|
||||
.bandwidth_update = &dce6_bandwidth_update,
|
||||
.get_vblank_counter = &evergreen_get_vblank_counter,
|
||||
.wait_for_vblank = &dce4_wait_for_vblank,
|
||||
},
|
||||
.copy = {
|
||||
.blit = &r600_copy_blit,
|
||||
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
.dma = NULL,
|
||||
.dma_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
.copy = &r600_copy_blit,
|
||||
.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
},
|
||||
.surface = {
|
||||
.set_reg = r600_set_surface_reg,
|
||||
.clear_reg = r600_clear_surface_reg,
|
||||
},
|
||||
.hpd = {
|
||||
.init = &evergreen_hpd_init,
|
||||
.fini = &evergreen_hpd_fini,
|
||||
.sense = &evergreen_hpd_sense,
|
||||
.set_polarity = &evergreen_hpd_set_polarity,
|
||||
},
|
||||
.pm = {
|
||||
.misc = &evergreen_pm_misc,
|
||||
.prepare = &evergreen_pm_prepare,
|
||||
.finish = &evergreen_pm_finish,
|
||||
.init_profile = &sumo_pm_init_profile,
|
||||
.get_dynpm_state = &r600_pm_get_dynpm_state,
|
||||
.get_engine_clock = &radeon_atom_get_engine_clock,
|
||||
.set_engine_clock = &radeon_atom_set_engine_clock,
|
||||
.get_memory_clock = NULL,
|
||||
.set_memory_clock = NULL,
|
||||
.get_pcie_lanes = NULL,
|
||||
.set_pcie_lanes = NULL,
|
||||
.set_clock_gating = NULL,
|
||||
},
|
||||
.pflip = {
|
||||
.pre_page_flip = &evergreen_pre_page_flip,
|
||||
.page_flip = &evergreen_page_flip,
|
||||
.post_page_flip = &evergreen_post_page_flip,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct radeon_vm_funcs si_vm_funcs = {
|
||||
.init = &si_vm_init,
|
||||
.fini = &si_vm_fini,
|
||||
.bind = &si_vm_bind,
|
||||
.unbind = &si_vm_unbind,
|
||||
.tlb_flush = &si_vm_tlb_flush,
|
||||
.page_flags = &cayman_vm_page_flags,
|
||||
.set_page = &cayman_vm_set_page,
|
||||
};
|
||||
|
||||
static struct radeon_asic si_asic = {
|
||||
.init = &si_init,
|
||||
.fini = &si_fini,
|
||||
.suspend = &si_suspend,
|
||||
.resume = &si_resume,
|
||||
.gpu_is_lockup = &si_gpu_is_lockup,
|
||||
.asic_reset = &si_asic_reset,
|
||||
.vga_set_state = &r600_vga_set_state,
|
||||
.ioctl_wait_idle = r600_ioctl_wait_idle,
|
||||
.gui_idle = &r600_gui_idle,
|
||||
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
|
||||
.gart = {
|
||||
.tlb_flush = &si_pcie_gart_tlb_flush,
|
||||
.set_page = &rs600_gart_set_page,
|
||||
},
|
||||
.ring = {
|
||||
[RADEON_RING_TYPE_GFX_INDEX] = {
|
||||
.ib_execute = &si_ring_ib_execute,
|
||||
.ib_parse = &si_ib_parse,
|
||||
.emit_fence = &si_fence_ring_emit,
|
||||
.emit_semaphore = &r600_semaphore_ring_emit,
|
||||
.cs_parse = NULL,
|
||||
.ring_test = &r600_ring_test,
|
||||
.ib_test = &r600_ib_test,
|
||||
},
|
||||
[CAYMAN_RING_TYPE_CP1_INDEX] = {
|
||||
.ib_execute = &si_ring_ib_execute,
|
||||
.ib_parse = &si_ib_parse,
|
||||
.emit_fence = &si_fence_ring_emit,
|
||||
.emit_semaphore = &r600_semaphore_ring_emit,
|
||||
.cs_parse = NULL,
|
||||
.ring_test = &r600_ring_test,
|
||||
.ib_test = &r600_ib_test,
|
||||
},
|
||||
[CAYMAN_RING_TYPE_CP2_INDEX] = {
|
||||
.ib_execute = &si_ring_ib_execute,
|
||||
.ib_parse = &si_ib_parse,
|
||||
.emit_fence = &si_fence_ring_emit,
|
||||
.emit_semaphore = &r600_semaphore_ring_emit,
|
||||
.cs_parse = NULL,
|
||||
.ring_test = &r600_ring_test,
|
||||
.ib_test = &r600_ib_test,
|
||||
}
|
||||
},
|
||||
.irq = {
|
||||
.set = &si_irq_set,
|
||||
.process = &si_irq_process,
|
||||
},
|
||||
.display = {
|
||||
.bandwidth_update = &dce6_bandwidth_update,
|
||||
.get_vblank_counter = &evergreen_get_vblank_counter,
|
||||
.wait_for_vblank = &dce4_wait_for_vblank,
|
||||
},
|
||||
.copy = {
|
||||
.blit = NULL,
|
||||
.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
.dma = NULL,
|
||||
.dma_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
.copy = NULL,
|
||||
.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
|
||||
},
|
||||
.surface = {
|
||||
.set_reg = r600_set_surface_reg,
|
||||
.clear_reg = r600_clear_surface_reg,
|
||||
},
|
||||
.hpd = {
|
||||
.init = &evergreen_hpd_init,
|
||||
.fini = &evergreen_hpd_fini,
|
||||
.sense = &evergreen_hpd_sense,
|
||||
.set_polarity = &evergreen_hpd_set_polarity,
|
||||
},
|
||||
.pm = {
|
||||
.misc = &evergreen_pm_misc,
|
||||
.prepare = &evergreen_pm_prepare,
|
||||
.finish = &evergreen_pm_finish,
|
||||
.init_profile = &sumo_pm_init_profile,
|
||||
.get_dynpm_state = &r600_pm_get_dynpm_state,
|
||||
.get_engine_clock = &radeon_atom_get_engine_clock,
|
||||
.set_engine_clock = &radeon_atom_set_engine_clock,
|
||||
.get_memory_clock = &radeon_atom_get_memory_clock,
|
||||
.set_memory_clock = &radeon_atom_set_memory_clock,
|
||||
.get_pcie_lanes = NULL,
|
||||
.set_pcie_lanes = NULL,
|
||||
.set_clock_gating = NULL,
|
||||
},
|
||||
.pflip = {
|
||||
.pre_page_flip = &evergreen_pre_page_flip,
|
||||
.page_flip = &evergreen_page_flip,
|
||||
.post_page_flip = &evergreen_post_page_flip,
|
||||
},
|
||||
};
|
||||
|
||||
int radeon_asic_init(struct radeon_device *rdev)
|
||||
{
|
||||
radeon_register_accessor_init(rdev);
|
||||
@@ -1525,6 +1719,20 @@ int radeon_asic_init(struct radeon_device *rdev)
|
||||
rdev->num_crtc = 6;
|
||||
rdev->vm_manager.funcs = &cayman_vm_funcs;
|
||||
break;
|
||||
case CHIP_ARUBA:
|
||||
rdev->asic = &trinity_asic;
|
||||
/* set num crtcs */
|
||||
rdev->num_crtc = 4;
|
||||
rdev->vm_manager.funcs = &cayman_vm_funcs;
|
||||
break;
|
||||
case CHIP_TAHITI:
|
||||
case CHIP_PITCAIRN:
|
||||
case CHIP_VERDE:
|
||||
rdev->asic = &si_asic;
|
||||
/* set num crtcs */
|
||||
rdev->num_crtc = 6;
|
||||
rdev->vm_manager.funcs = &si_vm_funcs;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: not supported yet */
|
||||
return -EINVAL;
|
||||
|
||||
@@ -461,4 +461,29 @@ void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm,
|
||||
unsigned pfn, uint64_t addr, uint32_t flags);
|
||||
int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
|
||||
|
||||
/* DCE6 - SI */
|
||||
void dce6_bandwidth_update(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* si
|
||||
*/
|
||||
void si_fence_ring_emit(struct radeon_device *rdev,
|
||||
struct radeon_fence *fence);
|
||||
void si_pcie_gart_tlb_flush(struct radeon_device *rdev);
|
||||
int si_init(struct radeon_device *rdev);
|
||||
void si_fini(struct radeon_device *rdev);
|
||||
int si_suspend(struct radeon_device *rdev);
|
||||
int si_resume(struct radeon_device *rdev);
|
||||
bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp);
|
||||
int si_asic_reset(struct radeon_device *rdev);
|
||||
void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
|
||||
int si_irq_set(struct radeon_device *rdev);
|
||||
int si_irq_process(struct radeon_device *rdev);
|
||||
int si_vm_init(struct radeon_device *rdev);
|
||||
void si_vm_fini(struct radeon_device *rdev);
|
||||
int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id);
|
||||
void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
|
||||
void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm);
|
||||
int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,6 +56,10 @@ extern void
|
||||
radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
|
||||
uint32_t supported_device);
|
||||
|
||||
/* local */
|
||||
static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
|
||||
u16 voltage_id, u16 *voltage);
|
||||
|
||||
union atom_supported_devices {
|
||||
struct _ATOM_SUPPORTED_DEVICES_INFO info;
|
||||
struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;
|
||||
@@ -253,7 +257,9 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device
|
||||
|
||||
memset(&hpd, 0, sizeof(struct radeon_hpd));
|
||||
|
||||
if (ASIC_IS_DCE4(rdev))
|
||||
if (ASIC_IS_DCE6(rdev))
|
||||
reg = SI_DC_GPIO_HPD_A;
|
||||
else if (ASIC_IS_DCE4(rdev))
|
||||
reg = EVERGREEN_DC_GPIO_HPD_A;
|
||||
else
|
||||
reg = AVIVO_DC_GPIO_HPD_A;
|
||||
@@ -1888,6 +1894,8 @@ static const char *pp_lib_thermal_controller_names[] = {
|
||||
"emc2103",
|
||||
"Sumo",
|
||||
"Northern Islands",
|
||||
"Southern Islands",
|
||||
"lm96163",
|
||||
};
|
||||
|
||||
union power_info {
|
||||
@@ -1904,6 +1912,7 @@ union pplib_clock_info {
|
||||
struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
|
||||
struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
|
||||
struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
|
||||
struct _ATOM_PPLIB_SI_CLOCK_INFO si;
|
||||
};
|
||||
|
||||
union pplib_power_state {
|
||||
@@ -2161,6 +2170,11 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
|
||||
(controller->ucFanParameters &
|
||||
ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
|
||||
rdev->pm.int_thermal_type = THERMAL_TYPE_NI;
|
||||
} else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) {
|
||||
DRM_INFO("Internal thermal controller %s fan control\n",
|
||||
(controller->ucFanParameters &
|
||||
ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
|
||||
rdev->pm.int_thermal_type = THERMAL_TYPE_SI;
|
||||
} else if ((controller->ucType ==
|
||||
ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) ||
|
||||
(controller->ucType ==
|
||||
@@ -2281,6 +2295,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
|
||||
union pplib_clock_info *clock_info)
|
||||
{
|
||||
u32 sclk, mclk;
|
||||
u16 vddc;
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
if (rdev->family >= CHIP_PALM) {
|
||||
@@ -2292,6 +2307,19 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
|
||||
sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
}
|
||||
} else if (ASIC_IS_DCE6(rdev)) {
|
||||
sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
|
||||
sclk |= clock_info->si.ucEngineClockHigh << 16;
|
||||
mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
|
||||
mclk |= clock_info->si.ucMemoryClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
|
||||
VOLTAGE_SW;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
|
||||
le16_to_cpu(clock_info->si.usVDDC);
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
|
||||
le16_to_cpu(clock_info->si.usVDDCI);
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
|
||||
sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
|
||||
@@ -2319,11 +2347,18 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
|
||||
}
|
||||
|
||||
/* patch up vddc if necessary */
|
||||
if (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage == 0xff01) {
|
||||
u16 vddc;
|
||||
|
||||
if (radeon_atom_get_max_vddc(rdev, &vddc) == 0)
|
||||
switch (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage) {
|
||||
case ATOM_VIRTUAL_VOLTAGE_ID0:
|
||||
case ATOM_VIRTUAL_VOLTAGE_ID1:
|
||||
case ATOM_VIRTUAL_VOLTAGE_ID2:
|
||||
case ATOM_VIRTUAL_VOLTAGE_ID3:
|
||||
if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC,
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage,
|
||||
&vddc) == 0)
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
@@ -2433,9 +2468,9 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
|
||||
int i, j, non_clock_array_index, clock_array_index;
|
||||
int state_index = 0, mode_index = 0;
|
||||
union pplib_clock_info *clock_info;
|
||||
struct StateArray *state_array;
|
||||
struct ClockInfoArray *clock_info_array;
|
||||
struct NonClockInfoArray *non_clock_info_array;
|
||||
struct _StateArray *state_array;
|
||||
struct _ClockInfoArray *clock_info_array;
|
||||
struct _NonClockInfoArray *non_clock_info_array;
|
||||
bool valid;
|
||||
union power_info *power_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
|
||||
@@ -2448,13 +2483,13 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
|
||||
power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
|
||||
state_array = (struct StateArray *)
|
||||
state_array = (struct _StateArray *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
le16_to_cpu(power_info->pplib.usStateArrayOffset));
|
||||
clock_info_array = (struct ClockInfoArray *)
|
||||
clock_info_array = (struct _ClockInfoArray *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
|
||||
non_clock_info_array = (struct NonClockInfoArray *)
|
||||
non_clock_info_array = (struct _NonClockInfoArray *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
|
||||
rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
|
||||
@@ -2481,7 +2516,7 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
|
||||
if (clock_array_index >= clock_info_array->ucNumEntries)
|
||||
continue;
|
||||
clock_info = (union pplib_clock_info *)
|
||||
&clock_info_array->clockInfo[clock_array_index];
|
||||
&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
|
||||
valid = radeon_atombios_parse_pplib_clock_info(rdev,
|
||||
state_index, mode_index,
|
||||
clock_info);
|
||||
@@ -2638,6 +2673,7 @@ union set_voltage {
|
||||
struct _SET_VOLTAGE_PS_ALLOCATION alloc;
|
||||
struct _SET_VOLTAGE_PARAMETERS v1;
|
||||
struct _SET_VOLTAGE_PARAMETERS_V2 v2;
|
||||
struct _SET_VOLTAGE_PARAMETERS_V1_3 v3;
|
||||
};
|
||||
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type)
|
||||
@@ -2664,6 +2700,11 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v
|
||||
args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;
|
||||
args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
|
||||
break;
|
||||
case 3:
|
||||
args.v3.ucVoltageType = voltage_type;
|
||||
args.v3.ucVoltageMode = ATOM_SET_VOLTAGE;
|
||||
args.v3.usVoltageLevel = cpu_to_le16(voltage_level);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
|
||||
return;
|
||||
@@ -2672,8 +2713,8 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
int radeon_atom_get_max_vddc(struct radeon_device *rdev,
|
||||
u16 *voltage)
|
||||
static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
|
||||
u16 voltage_id, u16 *voltage)
|
||||
{
|
||||
union set_voltage args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
|
||||
@@ -2694,6 +2735,15 @@ int radeon_atom_get_max_vddc(struct radeon_device *rdev,
|
||||
|
||||
*voltage = le16_to_cpu(args.v2.usVoltageLevel);
|
||||
break;
|
||||
case 3:
|
||||
args.v3.ucVoltageType = voltage_type;
|
||||
args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL;
|
||||
args.v3.usVoltageLevel = cpu_to_le16(voltage_id);
|
||||
|
||||
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
|
||||
*voltage = le16_to_cpu(args.v3.usVoltageLevel);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1085,7 +1085,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
|
||||
(radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
|
||||
return MODE_OK;
|
||||
else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) {
|
||||
if (0) {
|
||||
if (ASIC_IS_DCE6(rdev)) {
|
||||
/* HDMI 1.3+ supports max clock of 340 Mhz */
|
||||
if (mode->clock > 340000)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
@@ -103,8 +103,13 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
|
||||
p->ring = RADEON_RING_TYPE_GFX_INDEX;
|
||||
break;
|
||||
case RADEON_CS_RING_COMPUTE:
|
||||
/* for now */
|
||||
p->ring = RADEON_RING_TYPE_GFX_INDEX;
|
||||
if (p->rdev->family >= CHIP_TAHITI) {
|
||||
if (p->priority > 0)
|
||||
p->ring = CAYMAN_RING_TYPE_CP1_INDEX;
|
||||
else
|
||||
p->ring = CAYMAN_RING_TYPE_CP2_INDEX;
|
||||
} else
|
||||
p->ring = RADEON_RING_TYPE_GFX_INDEX;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -170,6 +175,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
|
||||
p->chunk_ib_idx = -1;
|
||||
p->chunk_relocs_idx = -1;
|
||||
p->chunk_flags_idx = -1;
|
||||
p->chunk_const_ib_idx = -1;
|
||||
p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL);
|
||||
if (p->chunks_array == NULL) {
|
||||
return -ENOMEM;
|
||||
@@ -208,6 +214,12 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
|
||||
if (p->chunks[i].length_dw == 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) {
|
||||
p->chunk_const_ib_idx = i;
|
||||
/* zero length CONST IB isn't useful */
|
||||
if (p->chunks[i].length_dw == 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) {
|
||||
p->chunk_flags_idx = i;
|
||||
/* zero length flags aren't useful */
|
||||
@@ -246,6 +258,13 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* we only support VM on SI+ */
|
||||
if ((p->rdev->family >= CHIP_TAHITI) &&
|
||||
((p->cs_flags & RADEON_CS_USE_VM) == 0)) {
|
||||
DRM_ERROR("VM required on SI+!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (radeon_cs_get_ring(p, ring, priority))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -389,6 +408,32 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
|
||||
if ((parser->cs_flags & RADEON_CS_USE_VM) == 0)
|
||||
return 0;
|
||||
|
||||
if ((rdev->family >= CHIP_TAHITI) &&
|
||||
(parser->chunk_const_ib_idx != -1)) {
|
||||
ib_chunk = &parser->chunks[parser->chunk_const_ib_idx];
|
||||
if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
|
||||
DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = radeon_ib_get(rdev, parser->ring, &parser->const_ib,
|
||||
ib_chunk->length_dw * 4);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to get const ib !\n");
|
||||
return r;
|
||||
}
|
||||
parser->const_ib->is_const_ib = true;
|
||||
parser->const_ib->length_dw = ib_chunk->length_dw;
|
||||
/* Copy the packet into the IB */
|
||||
if (DRM_COPY_FROM_USER(parser->const_ib->ptr, ib_chunk->user_ptr,
|
||||
ib_chunk->length_dw * 4)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
r = radeon_ring_ib_parse(rdev, parser->ring, parser->const_ib);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
ib_chunk = &parser->chunks[parser->chunk_ib_idx];
|
||||
if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) {
|
||||
DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw);
|
||||
@@ -424,11 +469,25 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to synchronize rings !\n");
|
||||
}
|
||||
|
||||
if ((rdev->family >= CHIP_TAHITI) &&
|
||||
(parser->chunk_const_ib_idx != -1)) {
|
||||
parser->const_ib->vm_id = vm->id;
|
||||
/* ib pool is bind at 0 in virtual address space to gpu_addr is the
|
||||
* offset inside the pool bo
|
||||
*/
|
||||
parser->const_ib->gpu_addr = parser->const_ib->sa_bo.offset;
|
||||
r = radeon_ib_schedule(rdev, parser->const_ib);
|
||||
if (r)
|
||||
goto out;
|
||||
}
|
||||
|
||||
parser->ib->vm_id = vm->id;
|
||||
/* ib pool is bind at 0 in virtual address space to gpu_addr is the
|
||||
* offset inside the pool bo
|
||||
*/
|
||||
parser->ib->gpu_addr = parser->ib->sa_bo.offset;
|
||||
parser->ib->is_const_ib = false;
|
||||
r = radeon_ib_schedule(rdev, parser->ib);
|
||||
out:
|
||||
if (!r) {
|
||||
|
||||
@@ -89,6 +89,10 @@ static const char radeon_family_name[][16] = {
|
||||
"TURKS",
|
||||
"CAICOS",
|
||||
"CAYMAN",
|
||||
"ARUBA",
|
||||
"TAHITI",
|
||||
"PITCAIRN",
|
||||
"VERDE",
|
||||
"LAST",
|
||||
};
|
||||
|
||||
@@ -964,7 +968,7 @@ int radeon_resume_kms(struct drm_device *dev)
|
||||
/* init dig PHYs, disp eng pll */
|
||||
if (rdev->is_atom_bios) {
|
||||
radeon_atom_encoder_init(rdev);
|
||||
radeon_atom_dcpll_init(rdev);
|
||||
radeon_atom_disp_eng_pll_init(rdev);
|
||||
}
|
||||
/* reset hpd state */
|
||||
radeon_hpd_init(rdev);
|
||||
|
||||
@@ -1296,7 +1296,7 @@ int radeon_modeset_init(struct radeon_device *rdev)
|
||||
/* init dig PHYs, disp eng pll */
|
||||
if (rdev->is_atom_bios) {
|
||||
radeon_atom_encoder_init(rdev);
|
||||
radeon_atom_dcpll_init(rdev);
|
||||
radeon_atom_disp_eng_pll_init(rdev);
|
||||
}
|
||||
|
||||
/* initialize hpd */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user