/drivers/video/drm/radeon/atombios_crtc.c |
---|
1739,6 → 1739,7 |
static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) |
{ |
struct drm_device *dev = crtc->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct drm_crtc *test_crtc; |
struct radeon_crtc *test_radeon_crtc; |
1748,6 → 1749,10 |
test_radeon_crtc = to_radeon_crtc(test_crtc); |
if (test_radeon_crtc->encoder && |
ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) { |
/* PPLL2 is exclusive to UNIPHYA on DCE61 */ |
if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) && |
test_radeon_crtc->pll_id == ATOM_PPLL2) |
continue; |
/* for DP use the same PLL for all */ |
if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) |
return test_radeon_crtc->pll_id; |
1769,6 → 1774,7 |
{ |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
struct drm_device *dev = crtc->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct drm_crtc *test_crtc; |
struct radeon_crtc *test_radeon_crtc; |
u32 adjusted_clock, test_adjusted_clock; |
1784,6 → 1790,10 |
test_radeon_crtc = to_radeon_crtc(test_crtc); |
if (test_radeon_crtc->encoder && |
!ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) { |
/* PPLL2 is exclusive to UNIPHYA on DCE61 */ |
if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) && |
test_radeon_crtc->pll_id == ATOM_PPLL2) |
continue; |
/* check if we are already driving this connector with another crtc */ |
if (test_radeon_crtc->connector == radeon_crtc->connector) { |
/* if we are, return that pll */ |
/drivers/video/drm/radeon/atombios_dp.c |
---|
302,77 → 302,31 |
return bpc * 3; |
} |
/* get the max pix clock supported by the link rate and lane num */ |
static int dp_get_max_dp_pix_clock(int link_rate, |
int lane_num, |
int bpp) |
{ |
return (link_rate * lane_num * 8) / bpp; |
} |
/***** radeon specific DP functions *****/ |
int radeon_dp_get_max_link_rate(struct drm_connector *connector, |
const u8 dpcd[DP_DPCD_SIZE]) |
{ |
int max_link_rate; |
if (radeon_connector_is_dp12_capable(connector)) |
max_link_rate = min(drm_dp_max_link_rate(dpcd), 540000); |
else |
max_link_rate = min(drm_dp_max_link_rate(dpcd), 270000); |
return max_link_rate; |
} |
/* First get the min lane# when low rate is used according to pixel clock |
* (prefer low rate), second check max lane# supported by DP panel, |
* if the max lane# < low rate lane# then use max lane# instead. |
*/ |
static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, |
int radeon_dp_get_dp_link_config(struct drm_connector *connector, |
const u8 dpcd[DP_DPCD_SIZE], |
int pix_clock) |
unsigned pix_clock, |
unsigned *dp_lanes, unsigned *dp_rate) |
{ |
int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); |
int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd); |
int max_lane_num = drm_dp_max_lane_count(dpcd); |
int lane_num; |
int max_dp_pix_clock; |
static const unsigned link_rates[3] = { 162000, 270000, 540000 }; |
unsigned max_link_rate = drm_dp_max_link_rate(dpcd); |
unsigned max_lane_num = drm_dp_max_lane_count(dpcd); |
unsigned lane_num, i, max_pix_clock; |
for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) { |
max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp); |
if (pix_clock <= max_dp_pix_clock) |
break; |
for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { |
for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { |
max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; |
if (max_pix_clock >= pix_clock) { |
*dp_lanes = lane_num; |
*dp_rate = link_rates[i]; |
return 0; |
} |
return lane_num; |
} |
static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, |
const u8 dpcd[DP_DPCD_SIZE], |
int pix_clock) |
{ |
int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); |
int lane_num, max_pix_clock; |
if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
ENCODER_OBJECT_ID_NUTMEG) |
return 270000; |
lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); |
max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp); |
if (pix_clock <= max_pix_clock) |
return 162000; |
max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp); |
if (pix_clock <= max_pix_clock) |
return 270000; |
if (radeon_connector_is_dp12_capable(connector)) { |
max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); |
if (pix_clock <= max_pix_clock) |
return 540000; |
} |
return radeon_dp_get_max_link_rate(connector, dpcd); |
return -EINVAL; |
} |
static u8 radeon_dp_encoder_service(struct radeon_device *rdev, |
491,6 → 445,7 |
{ |
struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
struct radeon_connector_atom_dig *dig_connector; |
int ret; |
if (!radeon_connector->con_priv) |
return; |
498,10 → 453,14 |
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { |
dig_connector->dp_clock = |
radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); |
dig_connector->dp_lane_count = |
radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock); |
ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, |
mode->clock, |
&dig_connector->dp_lane_count, |
&dig_connector->dp_clock); |
if (ret) { |
dig_connector->dp_clock = 0; |
dig_connector->dp_lane_count = 0; |
} |
} |
} |
510,7 → 469,8 |
{ |
struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
struct radeon_connector_atom_dig *dig_connector; |
int dp_clock; |
unsigned dp_clock, dp_lanes; |
int ret; |
if ((mode->clock > 340000) && |
(!radeon_connector_is_dp12_capable(connector))) |
520,8 → 480,12 |
return MODE_CLOCK_HIGH; |
dig_connector = radeon_connector->con_priv; |
dp_clock = |
radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); |
ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, |
mode->clock, |
&dp_lanes, |
&dp_clock); |
if (ret) |
return MODE_CLOCK_HIGH; |
if ((dp_clock == 540000) && |
(!radeon_connector_is_dp12_capable(connector))) |
/drivers/video/drm/radeon/atombios_encoders.c |
---|
120,6 → 120,7 |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: |
if (dig->backlight_level == 0) |
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); |
else { |
310,6 → 311,10 |
&& (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
/* vertical FP must be at least 1 */ |
if (mode->crtc_vsync_start == mode->crtc_vdisplay) |
adjusted_mode->crtc_vsync_start++; |
/* get the native mode for scaling */ |
if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { |
radeon_panel_mode_fixup(encoder, adjusted_mode); |
892,8 → 897,6 |
else |
args.v1.ucLaneNum = 4; |
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) |
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
switch (radeon_encoder->encoder_id) { |
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; |
910,6 → 913,10 |
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; |
else |
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; |
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) |
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
break; |
case 2: |
case 3: |
/drivers/video/drm/radeon/evergreen.c |
---|
2608,10 → 2608,152 |
WREG32(VM_CONTEXT1_CNTL, 0); |
} |
static const unsigned ni_dig_offsets[] = |
{ |
NI_DIG0_REGISTER_OFFSET, |
NI_DIG1_REGISTER_OFFSET, |
NI_DIG2_REGISTER_OFFSET, |
NI_DIG3_REGISTER_OFFSET, |
NI_DIG4_REGISTER_OFFSET, |
NI_DIG5_REGISTER_OFFSET |
}; |
static const unsigned ni_tx_offsets[] = |
{ |
NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1, |
NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1, |
NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1, |
NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1, |
NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1, |
NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 |
}; |
static const unsigned evergreen_dp_offsets[] = |
{ |
EVERGREEN_DP0_REGISTER_OFFSET, |
EVERGREEN_DP1_REGISTER_OFFSET, |
EVERGREEN_DP2_REGISTER_OFFSET, |
EVERGREEN_DP3_REGISTER_OFFSET, |
EVERGREEN_DP4_REGISTER_OFFSET, |
EVERGREEN_DP5_REGISTER_OFFSET |
}; |
/* |
* Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc |
* We go from crtc to connector and it is not relible since it |
* should be an opposite direction .If crtc is enable then |
* find the dig_fe which selects this crtc and insure that it enable. |
* if such dig_fe is found then find dig_be which selects found dig_be and |
* insure that it enable and in DP_SST mode. |
* if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing |
* from dp symbols clocks . |
*/ |
static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev, |
unsigned crtc_id, unsigned *ret_dig_fe) |
{ |
unsigned i; |
unsigned dig_fe; |
unsigned dig_be; |
unsigned dig_en_be; |
unsigned uniphy_pll; |
unsigned digs_fe_selected; |
unsigned dig_be_mode; |
unsigned dig_fe_mask; |
bool is_enabled = false; |
bool found_crtc = false; |
/* loop through all running dig_fe to find selected crtc */ |
for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { |
dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]); |
if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON && |
crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) { |
/* found running pipe */ |
found_crtc = true; |
dig_fe_mask = 1 << i; |
dig_fe = i; |
break; |
} |
} |
if (found_crtc) { |
/* loop through all running dig_be to find selected dig_fe */ |
for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { |
dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]); |
/* if dig_fe_selected by dig_be? */ |
digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be); |
dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be); |
if (dig_fe_mask & digs_fe_selected && |
/* if dig_be in sst mode? */ |
dig_be_mode == NI_DIG_BE_DPSST) { |
dig_en_be = RREG32(NI_DIG_BE_EN_CNTL + |
ni_dig_offsets[i]); |
uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 + |
ni_tx_offsets[i]); |
/* dig_be enable and tx is running */ |
if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE && |
dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON && |
uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) { |
is_enabled = true; |
*ret_dig_fe = dig_fe; |
break; |
} |
} |
} |
} |
return is_enabled; |
} |
/* |
* Blank dig when in dp sst mode |
* Dig ignores crtc timing |
*/ |
static void evergreen_blank_dp_output(struct radeon_device *rdev, |
unsigned dig_fe) |
{ |
unsigned stream_ctrl; |
unsigned fifo_ctrl; |
unsigned counter = 0; |
if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) { |
DRM_ERROR("invalid dig_fe %d\n", dig_fe); |
return; |
} |
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + |
evergreen_dp_offsets[dig_fe]); |
if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) { |
DRM_ERROR("dig %d , should be enable\n", dig_fe); |
return; |
} |
stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE; |
WREG32(EVERGREEN_DP_VID_STREAM_CNTL + |
evergreen_dp_offsets[dig_fe], stream_ctrl); |
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + |
evergreen_dp_offsets[dig_fe]); |
while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) { |
msleep(1); |
counter++; |
stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + |
evergreen_dp_offsets[dig_fe]); |
} |
if (counter >= 32 ) |
DRM_ERROR("counter exceeds %d\n", counter); |
fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]); |
fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET; |
WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl); |
} |
void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
{ |
u32 crtc_enabled, tmp, frame_count, blackout; |
int i, j; |
unsigned dig_fe; |
if (!ASIC_IS_NODCE(rdev)) { |
save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
2651,7 → 2793,17 |
break; |
udelay(1); |
} |
/*we should disable dig if it drives dp sst*/ |
/*but we are in radeon_device_init and the topology is unknown*/ |
/*and it is available after radeon_modeset_init*/ |
/*the following method radeon_atom_encoder_dpms_dig*/ |
/*does the job if we initialize it properly*/ |
/*for now we do it this manually*/ |
/**/ |
if (ASIC_IS_DCE5(rdev) && |
evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe)) |
evergreen_blank_dp_output(rdev, dig_fe); |
/*we could remove 6 lines below*/ |
/* XXX this is a hack to avoid strange behavior with EFI on certain systems */ |
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); |
tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); |
/drivers/video/drm/radeon/evergreen_reg.h |
---|
250,8 → 250,43 |
/* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ |
#define EVERGREEN_HDMI_BASE 0x7030 |
/*DIG block*/ |
#define NI_DIG0_REGISTER_OFFSET (0x7000 - 0x7000) |
#define NI_DIG1_REGISTER_OFFSET (0x7C00 - 0x7000) |
#define NI_DIG2_REGISTER_OFFSET (0x10800 - 0x7000) |
#define NI_DIG3_REGISTER_OFFSET (0x11400 - 0x7000) |
#define NI_DIG4_REGISTER_OFFSET (0x12000 - 0x7000) |
#define NI_DIG5_REGISTER_OFFSET (0x12C00 - 0x7000) |
#define NI_DIG_FE_CNTL 0x7000 |
# define NI_DIG_FE_CNTL_SOURCE_SELECT(x) ((x) & 0x3) |
# define NI_DIG_FE_CNTL_SYMCLK_FE_ON (1<<24) |
#define NI_DIG_BE_CNTL 0x7140 |
# define NI_DIG_BE_CNTL_FE_SOURCE_SELECT(x) (((x) >> 8 ) & 0x3F) |
# define NI_DIG_FE_CNTL_MODE(x) (((x) >> 16) & 0x7 ) |
#define NI_DIG_BE_EN_CNTL 0x7144 |
# define NI_DIG_BE_EN_CNTL_ENABLE (1 << 0) |
# define NI_DIG_BE_EN_CNTL_SYMBCLK_ON (1 << 8) |
# define NI_DIG_BE_DPSST 0 |
/* Display Port block */ |
#define EVERGREEN_DP0_REGISTER_OFFSET (0x730C - 0x730C) |
#define EVERGREEN_DP1_REGISTER_OFFSET (0x7F0C - 0x730C) |
#define EVERGREEN_DP2_REGISTER_OFFSET (0x10B0C - 0x730C) |
#define EVERGREEN_DP3_REGISTER_OFFSET (0x1170C - 0x730C) |
#define EVERGREEN_DP4_REGISTER_OFFSET (0x1230C - 0x730C) |
#define EVERGREEN_DP5_REGISTER_OFFSET (0x12F0C - 0x730C) |
#define EVERGREEN_DP_VID_STREAM_CNTL 0x730C |
# define EVERGREEN_DP_VID_STREAM_CNTL_ENABLE (1 << 0) |
# define EVERGREEN_DP_VID_STREAM_STATUS (1 <<16) |
#define EVERGREEN_DP_STEER_FIFO 0x7310 |
# define EVERGREEN_DP_STEER_FIFO_RESET (1 << 0) |
#define EVERGREEN_DP_SEC_CNTL 0x7280 |
# define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) |
# define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) |
266,4 → 301,15 |
# define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) |
# define EVERGREEN_DP_SEC_SS_EN (1 << 28) |
/*DCIO_UNIPHY block*/ |
#define NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1 (0x6600 -0x6600) |
#define NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1 (0x6640 -0x6600) |
#define NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1 (0x6680 - 0x6600) |
#define NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1 (0x66C0 - 0x6600) |
#define NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1 (0x6700 - 0x6600) |
#define NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 (0x6740 - 0x6600) |
#define NI_DCIO_UNIPHY0_PLL_CONTROL1 0x6618 |
# define NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE (1 << 0) |
#endif |
/drivers/video/drm/radeon/main.c |
---|
5,7 → 5,7 |
#include "radeon.h" |
#include "bitmap.h" |
#define DRV_NAME "atikms v4.4.5-dbg1" |
#define DRV_NAME "atikms v4.4.30" |
void __init dmi_scan_machine(void); |
/drivers/video/drm/radeon/r600_dpm.c |
---|
156,7 → 156,7 |
struct drm_device *dev = rdev->ddev; |
struct drm_crtc *crtc; |
struct radeon_crtc *radeon_crtc; |
u32 line_time_us, vblank_lines; |
u32 vblank_in_pixels; |
u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ |
if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { |
163,12 → 163,13 |
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
radeon_crtc = to_radeon_crtc(crtc); |
if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { |
line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / |
radeon_crtc->hw_mode.clock; |
vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - |
vblank_in_pixels = |
radeon_crtc->hw_mode.crtc_htotal * |
(radeon_crtc->hw_mode.crtc_vblank_end - |
radeon_crtc->hw_mode.crtc_vdisplay + |
(radeon_crtc->v_border * 2); |
vblank_time_us = vblank_lines * line_time_us; |
(radeon_crtc->v_border * 2)); |
vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock; |
break; |
} |
} |
/drivers/video/drm/radeon/radeon.h |
---|
65,13 → 65,13 |
#include <linux/list.h> |
#include <linux/kref.h> |
#include <linux/interval_tree.h> |
#include <asm/div64.h> |
#include <linux/hashtable.h> |
#include <linux/fence.h> |
#include <ttm/ttm_bo_api.h> |
#include <ttm/ttm_bo_driver.h> |
#include <ttm/ttm_placement.h> |
//#include <ttm/ttm_module.h> |
#include <ttm/ttm_module.h> |
#include <ttm/ttm_execbuf_util.h> |
#include <linux/rwsem.h> |
/drivers/video/drm/radeon/radeon_atombios.c |
---|
1155,7 → 1155,7 |
le16_to_cpu(firmware_info->info.usReferenceClock); |
p1pll->reference_div = 0; |
if (crev < 2) |
if ((frev < 2) && (crev < 2)) |
p1pll->pll_out_min = |
le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); |
else |
1164,7 → 1164,7 |
p1pll->pll_out_max = |
le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); |
if (crev >= 4) { |
if (((frev < 2) && (crev >= 4)) || (frev >= 2)) { |
p1pll->lcd_pll_out_min = |
le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100; |
if (p1pll->lcd_pll_out_min == 0) |
/drivers/video/drm/radeon/radeon_connectors.c |
---|
1968,10 → 1968,12 |
rdev->mode_info.dither_property, |
RADEON_FMT_DITHER_DISABLE); |
if (radeon_audio != 0) |
if (radeon_audio != 0) { |
drm_object_attach_property(&radeon_connector->base.base, |
rdev->mode_info.audio_property, |
RADEON_AUDIO_AUTO); |
radeon_connector->audio = RADEON_AUDIO_AUTO; |
} |
if (ASIC_IS_DCE5(rdev)) |
drm_object_attach_property(&radeon_connector->base.base, |
rdev->mode_info.output_csc_property, |
2028,7 → 2030,6 |
RADEON_OUTPUT_CSC_BYPASS); |
/* no HPD on analog connectors */ |
radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
connector->interlace_allowed = true; |
connector->doublescan_allowed = true; |
break; |
2096,6 → 2097,7 |
drm_object_attach_property(&radeon_connector->base.base, |
rdev->mode_info.audio_property, |
RADEON_AUDIO_AUTO); |
radeon_connector->audio = RADEON_AUDIO_AUTO; |
} |
if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
radeon_connector->dac_load_detect = true; |
2151,6 → 2153,7 |
drm_object_attach_property(&radeon_connector->base.base, |
rdev->mode_info.audio_property, |
RADEON_AUDIO_AUTO); |
radeon_connector->audio = RADEON_AUDIO_AUTO; |
} |
if (ASIC_IS_DCE5(rdev)) |
drm_object_attach_property(&radeon_connector->base.base, |
2203,6 → 2206,7 |
drm_object_attach_property(&radeon_connector->base.base, |
rdev->mode_info.audio_property, |
RADEON_AUDIO_AUTO); |
radeon_connector->audio = RADEON_AUDIO_AUTO; |
} |
if (ASIC_IS_DCE5(rdev)) |
drm_object_attach_property(&radeon_connector->base.base, |
2275,8 → 2279,10 |
} |
if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { |
if (i2c_bus->valid) |
connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
if (i2c_bus->valid) { |
connector->polled = DRM_CONNECTOR_POLL_CONNECT | |
DRM_CONNECTOR_POLL_DISCONNECT; |
} |
} else |
connector->polled = DRM_CONNECTOR_POLL_HPD; |
2352,7 → 2358,6 |
1); |
/* no HPD on analog connectors */ |
radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
connector->interlace_allowed = true; |
connector->doublescan_allowed = true; |
break; |
2437,10 → 2442,13 |
} |
if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { |
if (i2c_bus->valid) |
connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
if (i2c_bus->valid) { |
connector->polled = DRM_CONNECTOR_POLL_CONNECT | |
DRM_CONNECTOR_POLL_DISCONNECT; |
} |
} else |
connector->polled = DRM_CONNECTOR_POLL_HPD; |
connector->display_info.subpixel_order = subpixel_order; |
drm_connector_register(connector); |
} |
/drivers/video/drm/radeon/radeon_device.c |
---|
35,7 → 35,6 |
#include "radeon.h" |
#include "atom.h" |
#include "bitmap.h" |
#include "display.h" |
825,6 → 824,8 |
return -ENOMEM; |
rdev->dummy_page.addr = pci_map_page(rdev->pdev, rdev->dummy_page.page, |
0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
rdev->dummy_page.entry = radeon_gart_get_page_entry(rdev->dummy_page.addr, |
RADEON_GART_PAGE_DUMMY); |
return 0; |
} |
1474,6 → 1475,8 |
return 0; |
} |
atomic_inc(&rdev->gpu_reset_counter); |
radeon_save_bios_scratch_regs(rdev); |
/* block TTM */ |
// resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
/drivers/video/drm/radeon/radeon_dp_auxch.c |
---|
105,7 → 105,7 |
tmp &= AUX_HPD_SEL(0x7); |
tmp |= AUX_HPD_SEL(chan->rec.hpd); |
tmp |= AUX_EN | AUX_LS_READ_EN; |
tmp |= AUX_EN | AUX_LS_READ_EN | AUX_HPD_DISCON(0x1); |
WREG32(AUX_CONTROL + aux_offset[instance], tmp); |
/drivers/video/drm/radeon/radeon_dp_mst.c |
---|
525,11 → 525,9 |
drm_mode_set_crtcinfo(adjusted_mode, 0); |
{ |
struct radeon_connector_atom_dig *dig_connector; |
dig_connector = mst_enc->connector->con_priv; |
dig_connector->dp_lane_count = drm_dp_max_lane_count(dig_connector->dpcd); |
dig_connector->dp_clock = radeon_dp_get_max_link_rate(&mst_enc->connector->base, |
dig_connector->dpcd); |
dig_connector->dp_clock = drm_dp_max_link_rate(dig_connector->dpcd); |
DRM_DEBUG_KMS("dig clock %p %d %d\n", dig_connector, |
dig_connector->dp_lane_count, dig_connector->dp_clock); |
} |
/drivers/video/drm/radeon/radeon_gart.c |
---|
29,17 → 29,6 |
#include <drm/radeon_drm.h> |
#include "radeon.h" |
#undef CONFIG_X86 |
void* pci_alloc_consistent(struct pci_dev *hwdev, size_t size, |
addr_t *dma_handle) |
{ |
size = (size + 0x7FFF) & ~0x7FFF; |
*dma_handle = AllocPages(size >> 12); |
return (void*)MapIoMem(*dma_handle, size, PG_SW+PG_NOCACHE); |
} |
/* |
* GART |
* The GART (Graphics Aperture Remapping Table) is an aperture |
/drivers/video/drm/radeon/radeon_mode.h |
---|
757,8 → 757,10 |
extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); |
extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, |
struct drm_connector *connector); |
int radeon_dp_get_max_link_rate(struct drm_connector *connector, |
const u8 *dpcd); |
extern int radeon_dp_get_dp_link_config(struct drm_connector *connector, |
const u8 *dpcd, |
unsigned pix_clock, |
unsigned *dp_lanes, unsigned *dp_rate); |
extern void radeon_dp_set_rx_power_state(struct drm_connector *connector, |
u8 power_state); |
extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector); |
/drivers/video/drm/radeon/radeon_pm.c |
---|
897,6 → 897,8 |
/* update display watermarks based on new power state */ |
radeon_bandwidth_update(rdev); |
/* update displays */ |
radeon_dpm_display_configuration_changed(rdev); |
/* wait for the rings to drain */ |
for (i = 0; i < RADEON_NUM_RINGS; i++) { |
913,9 → 915,6 |
radeon_dpm_post_set_power_state(rdev); |
/* update displays */ |
radeon_dpm_display_configuration_changed(rdev); |
rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; |
rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; |
rdev->pm.dpm.single_display = single_display; |
/drivers/video/drm/radeon/radeon_ttm.c |
---|
247,8 → 247,8 |
rdev = radeon_get_rdev(bo->bdev); |
ridx = radeon_copy_ring_index(rdev); |
old_start = old_mem->start << PAGE_SHIFT; |
new_start = new_mem->start << PAGE_SHIFT; |
old_start = (u64)old_mem->start << PAGE_SHIFT; |
new_start = (u64)new_mem->start << PAGE_SHIFT; |
switch (old_mem->mem_type) { |
case TTM_PL_VRAM: |
/drivers/video/drm/radeon/si_dpm.c |
---|
2926,9 → 2926,12 |
/* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ |
{ PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 }, |
{ PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 }, |
{ PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0x2015, 0, 120000 }, |
{ PCI_VENDOR_ID_ATI, 0x6810, 0x174b, 0xe271, 85000, 90000 }, |
{ PCI_VENDOR_ID_ATI, 0x6811, 0x1462, 0x2015, 0, 120000 }, |
{ PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 }, |
{ PCI_VENDOR_ID_ATI, 0x6811, 0x148c, 0x2015, 0, 120000 }, |
{ PCI_VENDOR_ID_ATI, 0x6810, 0x1682, 0x9275, 0, 120000 }, |
{ 0, 0, 0, 0 }, |
}; |
3008,6 → 3011,16 |
} |
++p; |
} |
/* limit mclk on all R7 370 parts for stability */ |
if (rdev->pdev->device == 0x6811 && |
rdev->pdev->revision == 0x81) |
max_mclk = 120000; |
/* limit sclk/mclk on Jet parts for stability */ |
if (rdev->pdev->device == 0x6665 && |
rdev->pdev->revision == 0xc3) { |
max_sclk = 75000; |
max_mclk = 80000; |
} |
if (rps->vce_active) { |
rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk; |
4099,7 → 4112,7 |
&rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) { |
si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table); |
table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] = |
table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] = |
cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low); |
si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay, |
/drivers/video/drm/radeon/sislands_smc.h |
---|
194,6 → 194,7 |
#define SISLANDS_SMC_VOLTAGEMASK_VDDC 0 |
#define SISLANDS_SMC_VOLTAGEMASK_MVDD 1 |
#define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2 |
#define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3 |
#define SISLANDS_SMC_VOLTAGEMASK_MAX 4 |
struct SISLANDS_SMC_VOLTAGEMASKTABLE |
/drivers/video/drm/radeon/utils.c |
---|
160,98 → 160,6 |
#define KMAP_MAX 256 |
static struct mutex kmap_mutex; |
static struct page* kmap_table[KMAP_MAX]; |
static int kmap_av; |
static int kmap_first; |
static void* kmap_base; |
int kmap_init() |
{ |
kmap_base = AllocKernelSpace(KMAP_MAX*4096); |
if(kmap_base == NULL) |
return -1; |
kmap_av = KMAP_MAX; |
MutexInit(&kmap_mutex); |
return 0; |
}; |
void *kmap(struct page *page) |
{ |
void *vaddr = NULL; |
int i; |
do |
{ |
MutexLock(&kmap_mutex); |
if(kmap_av != 0) |
{ |
for(i = kmap_first; i < KMAP_MAX; i++) |
{ |
if(kmap_table[i] == NULL) |
{ |
kmap_av--; |
kmap_first = i; |
kmap_table[i] = page; |
vaddr = kmap_base + (i<<12); |
MapPage(vaddr,(addr_t)page,3); |
break; |
}; |
}; |
}; |
MutexUnlock(&kmap_mutex); |
}while(vaddr == NULL); |
return vaddr; |
}; |
void *kmap_atomic(struct page *page) __attribute__ ((alias ("kmap"))); |
void kunmap(struct page *page) |
{ |
void *vaddr; |
int i; |
MutexLock(&kmap_mutex); |
for(i = 0; i < KMAP_MAX; i++) |
{ |
if(kmap_table[i] == page) |
{ |
kmap_av++; |
if(i < kmap_first) |
kmap_first = i; |
kmap_table[i] = NULL; |
vaddr = kmap_base + (i<<12); |
MapPage(vaddr,0,0); |
break; |
}; |
}; |
MutexUnlock(&kmap_mutex); |
}; |
void kunmap_atomic(void *vaddr) |
{ |
int i; |
MapPage(vaddr,0,0); |
i = (vaddr - kmap_base) >> 12; |
MutexLock(&kmap_mutex); |
kmap_av++; |
if(i < kmap_first) |
kmap_first = i; |
kmap_table[i] = NULL; |
MutexUnlock(&kmap_mutex); |
} |
void msleep(unsigned int msecs) |
{ |
msecs /= 10; |
891,3 → 799,13 |
KernelFree(addr); |
} |
int set_memory_uc(unsigned long addr, int numpages) |
{ |
return 0; |
}; |
int set_memory_wb(unsigned long addr, int numpages) |
{ |
return 0; |
}; |
/drivers/video/drm/ttm/ttm_bo.c |
---|
820,7 → 820,7 |
return ret; |
} |
static bool ttm_bo_mem_compat(struct ttm_placement *placement, |
bool ttm_bo_mem_compat(struct ttm_placement *placement, |
struct ttm_mem_reg *mem, |
uint32_t *new_flags) |
{ |
854,6 → 854,7 |
return false; |
} |
EXPORT_SYMBOL(ttm_bo_mem_compat); |
int ttm_bo_validate(struct ttm_buffer_object *bo, |
struct ttm_placement *placement, |