Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "gma500 build fix + some regression fixes for nouveau/radeon" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/radeon: Only warn if the intra-domain offset actually exceeds the limit. drm/radeon/kms: add htile support to the cs checker v3 drm/radeon/kms/atom: force bpc to 8 for now drm/nouveau/i2c: fix thinko/regression on really old chipsets drm/nouveau: default to 8bpc for non-LVDS panels if EDID isn't useful drm/nouveau: fix thinko causing init to fail on cards without accel gma500: medfield: fix build without CONFIG_BACKLIGHT_CLASS_DEVICE
This commit is contained in:
commit
516e779770
15 changed files with 420 additions and 137 deletions
|
@ -244,7 +244,6 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
struct drm_encoder *encoder = connector->encoder;
|
struct drm_encoder *encoder = connector->encoder;
|
||||||
struct backlight_device *psb_bd;
|
|
||||||
|
|
||||||
if (!strcmp(property->name, "scaling mode") && encoder) {
|
if (!strcmp(property->name, "scaling mode") && encoder) {
|
||||||
struct psb_intel_crtc *psb_crtc =
|
struct psb_intel_crtc *psb_crtc =
|
||||||
|
@ -301,11 +300,15 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
|
||||||
value))
|
value))
|
||||||
goto set_prop_error;
|
goto set_prop_error;
|
||||||
else {
|
else {
|
||||||
|
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||||
|
struct backlight_device *psb_bd;
|
||||||
|
|
||||||
psb_bd = mdfld_get_backlight_device();
|
psb_bd = mdfld_get_backlight_device();
|
||||||
if (psb_bd) {
|
if (psb_bd) {
|
||||||
psb_bd->props.brightness = value;
|
psb_bd->props.brightness = value;
|
||||||
mdfld_set_brightness(psb_bd);
|
mdfld_set_brightness(psb_bd);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_prop_done:
|
set_prop_done:
|
||||||
|
|
|
@ -654,10 +654,13 @@ nouveau_connector_detect_depth(struct drm_connector *connector)
|
||||||
if (nv_connector->edid && connector->display_info.bpc)
|
if (nv_connector->edid && connector->display_info.bpc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* if not, we're out of options unless we're LVDS, default to 6bpc */
|
/* if not, we're out of options unless we're LVDS, default to 8bpc */
|
||||||
connector->display_info.bpc = 6;
|
if (nv_encoder->dcb->type != OUTPUT_LVDS) {
|
||||||
if (nv_encoder->dcb->type != OUTPUT_LVDS)
|
connector->display_info.bpc = 8;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connector->display_info.bpc = 6;
|
||||||
|
|
||||||
/* LVDS: panel straps */
|
/* LVDS: panel straps */
|
||||||
if (bios->fp_no_ddc) {
|
if (bios->fp_no_ddc) {
|
||||||
|
|
|
@ -315,8 +315,8 @@ nouveau_i2c_init(struct drm_device *dev)
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
struct nvbios *bios = &dev_priv->vbios;
|
struct nvbios *bios = &dev_priv->vbios;
|
||||||
struct nouveau_i2c_chan *port;
|
struct nouveau_i2c_chan *port;
|
||||||
|
u8 version = 0x00, entries, recordlen;
|
||||||
u8 *i2c, *entry, legacy[2][4] = {};
|
u8 *i2c, *entry, legacy[2][4] = {};
|
||||||
u8 version, entries, recordlen;
|
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&dev_priv->i2c_ports);
|
INIT_LIST_HEAD(&dev_priv->i2c_ports);
|
||||||
|
@ -346,12 +346,12 @@ nouveau_i2c_init(struct drm_device *dev)
|
||||||
if (i2c[7]) legacy[1][1] = i2c[7];
|
if (i2c[7]) legacy[1][1] = i2c[7];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i2c && version >= 0x30) {
|
if (version >= 0x30) {
|
||||||
entry = i2c[1] + i2c;
|
entry = i2c[1] + i2c;
|
||||||
entries = i2c[2];
|
entries = i2c[2];
|
||||||
recordlen = i2c[3];
|
recordlen = i2c[3];
|
||||||
} else
|
} else
|
||||||
if (i2c) {
|
if (version) {
|
||||||
entry = i2c;
|
entry = i2c;
|
||||||
entries = 16;
|
entries = 16;
|
||||||
recordlen = 4;
|
recordlen = 4;
|
||||||
|
|
|
@ -852,7 +852,7 @@ nouveau_card_init(struct drm_device *dev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_pm;
|
goto out_pm;
|
||||||
|
|
||||||
if (!dev_priv->noaccel) {
|
if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
|
||||||
ret = nouveau_card_channel_init(dev);
|
ret = nouveau_card_channel_init(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_fence;
|
goto out_fence;
|
||||||
|
|
|
@ -588,8 +588,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
||||||
if (encoder->crtc == crtc) {
|
if (encoder->crtc == crtc) {
|
||||||
radeon_encoder = to_radeon_encoder(encoder);
|
radeon_encoder = to_radeon_encoder(encoder);
|
||||||
connector = radeon_get_connector_for_encoder(encoder);
|
connector = radeon_get_connector_for_encoder(encoder);
|
||||||
if (connector && connector->display_info.bpc)
|
/* if (connector && connector->display_info.bpc)
|
||||||
bpc = connector->display_info.bpc;
|
bpc = connector->display_info.bpc; */
|
||||||
encoder_mode = atombios_get_encoder_mode(encoder);
|
encoder_mode = atombios_get_encoder_mode(encoder);
|
||||||
is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
|
is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
|
||||||
if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
|
if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
|
||||||
|
@ -965,7 +965,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
|
||||||
struct radeon_connector_atom_dig *dig_connector =
|
struct radeon_connector_atom_dig *dig_connector =
|
||||||
radeon_connector->con_priv;
|
radeon_connector->con_priv;
|
||||||
int dp_clock;
|
int dp_clock;
|
||||||
bpc = connector->display_info.bpc;
|
|
||||||
|
/* if (connector->display_info.bpc)
|
||||||
|
bpc = connector->display_info.bpc; */
|
||||||
|
|
||||||
switch (encoder_mode) {
|
switch (encoder_mode) {
|
||||||
case ATOM_ENCODER_MODE_DP_MST:
|
case ATOM_ENCODER_MODE_DP_MST:
|
||||||
|
|
|
@ -405,10 +405,13 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
|
||||||
/* get bpc from the EDID */
|
/* get bpc from the EDID */
|
||||||
static int convert_bpc_to_bpp(int bpc)
|
static int convert_bpc_to_bpp(int bpc)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (bpc == 0)
|
if (bpc == 0)
|
||||||
return 24;
|
return 24;
|
||||||
else
|
else
|
||||||
return bpc * 3;
|
return bpc * 3;
|
||||||
|
#endif
|
||||||
|
return 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the max pix clock supported by the link rate and lane num */
|
/* get the max pix clock supported by the link rate and lane num */
|
||||||
|
|
|
@ -541,7 +541,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
|
||||||
dp_clock = dig_connector->dp_clock;
|
dp_clock = dig_connector->dp_clock;
|
||||||
dp_lane_count = dig_connector->dp_lane_count;
|
dp_lane_count = dig_connector->dp_lane_count;
|
||||||
hpd_id = radeon_connector->hpd.hpd;
|
hpd_id = radeon_connector->hpd.hpd;
|
||||||
bpc = connector->display_info.bpc;
|
/* bpc = connector->display_info.bpc; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no dig encoder assigned */
|
/* no dig encoder assigned */
|
||||||
|
@ -1159,7 +1159,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
|
||||||
dp_lane_count = dig_connector->dp_lane_count;
|
dp_lane_count = dig_connector->dp_lane_count;
|
||||||
connector_object_id =
|
connector_object_id =
|
||||||
(radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
|
(radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
|
||||||
bpc = connector->display_info.bpc;
|
/* bpc = connector->display_info.bpc; */
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
|
@ -80,6 +80,9 @@ struct evergreen_cs_track {
|
||||||
bool cb_dirty;
|
bool cb_dirty;
|
||||||
bool db_dirty;
|
bool db_dirty;
|
||||||
bool streamout_dirty;
|
bool streamout_dirty;
|
||||||
|
u32 htile_offset;
|
||||||
|
u32 htile_surface;
|
||||||
|
struct radeon_bo *htile_bo;
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
|
static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
|
||||||
|
@ -144,6 +147,9 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
|
||||||
track->db_s_read_bo = NULL;
|
track->db_s_read_bo = NULL;
|
||||||
track->db_s_write_bo = NULL;
|
track->db_s_write_bo = NULL;
|
||||||
track->db_dirty = true;
|
track->db_dirty = true;
|
||||||
|
track->htile_bo = NULL;
|
||||||
|
track->htile_offset = 0xFFFFFFFF;
|
||||||
|
track->htile_surface = 0;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
track->vgt_strmout_size[i] = 0;
|
track->vgt_strmout_size[i] = 0;
|
||||||
|
@ -444,6 +450,62 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p,
|
||||||
|
unsigned nbx, unsigned nby)
|
||||||
|
{
|
||||||
|
struct evergreen_cs_track *track = p->track;
|
||||||
|
unsigned long size;
|
||||||
|
|
||||||
|
if (track->htile_bo == NULL) {
|
||||||
|
dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
|
||||||
|
__func__, __LINE__, track->db_z_info);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_028ABC_LINEAR(track->htile_surface)) {
|
||||||
|
/* pitch must be 16 htiles aligned == 16 * 8 pixel aligned */
|
||||||
|
nbx = round_up(nbx, 16 * 8);
|
||||||
|
/* height is npipes htiles aligned == npipes * 8 pixel aligned */
|
||||||
|
nby = round_up(nby, track->npipes * 8);
|
||||||
|
} else {
|
||||||
|
switch (track->npipes) {
|
||||||
|
case 8:
|
||||||
|
nbx = round_up(nbx, 64 * 8);
|
||||||
|
nby = round_up(nby, 64 * 8);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
nbx = round_up(nbx, 64 * 8);
|
||||||
|
nby = round_up(nby, 32 * 8);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
nbx = round_up(nbx, 32 * 8);
|
||||||
|
nby = round_up(nby, 32 * 8);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
nbx = round_up(nbx, 32 * 8);
|
||||||
|
nby = round_up(nby, 16 * 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
|
||||||
|
__func__, __LINE__, track->npipes);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* compute number of htile */
|
||||||
|
nbx = nbx / 8;
|
||||||
|
nby = nby / 8;
|
||||||
|
size = nbx * nby * 4;
|
||||||
|
size += track->htile_offset;
|
||||||
|
|
||||||
|
if (size > radeon_bo_size(track->htile_bo)) {
|
||||||
|
dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
|
||||||
|
__func__, __LINE__, radeon_bo_size(track->htile_bo),
|
||||||
|
size, nbx, nby);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
|
static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
|
||||||
{
|
{
|
||||||
struct evergreen_cs_track *track = p->track;
|
struct evergreen_cs_track *track = p->track;
|
||||||
|
@ -530,6 +592,14 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* hyperz */
|
||||||
|
if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
|
||||||
|
r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,6 +687,14 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* hyperz */
|
||||||
|
if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
|
||||||
|
r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +928,7 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
/* Check depth buffer */
|
/* Check depth buffer */
|
||||||
if (G_028800_Z_WRITE_ENABLE(track->db_depth_control)) {
|
if (G_028800_Z_ENABLE(track->db_depth_control)) {
|
||||||
r = evergreen_cs_track_validate_depth(p);
|
r = evergreen_cs_track_validate_depth(p);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
@ -1616,6 +1694,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||||
track->cb_color_bo[tmp] = reloc->robj;
|
track->cb_color_bo[tmp] = reloc->robj;
|
||||||
track->cb_dirty = true;
|
track->cb_dirty = true;
|
||||||
break;
|
break;
|
||||||
|
case DB_HTILE_DATA_BASE:
|
||||||
|
r = evergreen_cs_packet_next_reloc(p, &reloc);
|
||||||
|
if (r) {
|
||||||
|
dev_warn(p->dev, "bad SET_CONTEXT_REG "
|
||||||
|
"0x%04X\n", reg);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
track->htile_offset = radeon_get_ib_value(p, idx);
|
||||||
|
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||||
|
track->htile_bo = reloc->robj;
|
||||||
|
track->db_dirty = true;
|
||||||
|
break;
|
||||||
|
case DB_HTILE_SURFACE:
|
||||||
|
/* 8x8 only */
|
||||||
|
track->htile_surface = radeon_get_ib_value(p, idx);
|
||||||
|
track->db_dirty = true;
|
||||||
|
break;
|
||||||
case CB_IMMED0_BASE:
|
case CB_IMMED0_BASE:
|
||||||
case CB_IMMED1_BASE:
|
case CB_IMMED1_BASE:
|
||||||
case CB_IMMED2_BASE:
|
case CB_IMMED2_BASE:
|
||||||
|
@ -1628,7 +1723,6 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||||
case CB_IMMED9_BASE:
|
case CB_IMMED9_BASE:
|
||||||
case CB_IMMED10_BASE:
|
case CB_IMMED10_BASE:
|
||||||
case CB_IMMED11_BASE:
|
case CB_IMMED11_BASE:
|
||||||
case DB_HTILE_DATA_BASE:
|
|
||||||
case SQ_PGM_START_FS:
|
case SQ_PGM_START_FS:
|
||||||
case SQ_PGM_START_ES:
|
case SQ_PGM_START_ES:
|
||||||
case SQ_PGM_START_VS:
|
case SQ_PGM_START_VS:
|
||||||
|
|
|
@ -991,6 +991,14 @@
|
||||||
#define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
|
#define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
|
||||||
#define C_028008_SLICE_MAX 0xFF001FFF
|
#define C_028008_SLICE_MAX 0xFF001FFF
|
||||||
#define DB_HTILE_DATA_BASE 0x28014
|
#define DB_HTILE_DATA_BASE 0x28014
|
||||||
|
#define DB_HTILE_SURFACE 0x28abc
|
||||||
|
#define S_028ABC_HTILE_WIDTH(x) (((x) & 0x1) << 0)
|
||||||
|
#define G_028ABC_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
|
||||||
|
#define C_028ABC_HTILE_WIDTH 0xFFFFFFFE
|
||||||
|
#define S_028ABC_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
|
||||||
|
#define G_028ABC_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
|
||||||
|
#define C_028ABC_HTILE_HEIGHT 0xFFFFFFFD
|
||||||
|
#define G_028ABC_LINEAR(x) (((x) >> 2) & 0x1)
|
||||||
#define DB_Z_INFO 0x28040
|
#define DB_Z_INFO 0x28040
|
||||||
# define Z_ARRAY_MODE(x) ((x) << 4)
|
# define Z_ARRAY_MODE(x) ((x) << 4)
|
||||||
# define DB_TILE_SPLIT(x) (((x) & 0x7) << 8)
|
# define DB_TILE_SPLIT(x) (((x) & 0x7) << 8)
|
||||||
|
|
|
@ -78,6 +78,9 @@ struct r600_cs_track {
|
||||||
bool cb_dirty;
|
bool cb_dirty;
|
||||||
bool db_dirty;
|
bool db_dirty;
|
||||||
bool streamout_dirty;
|
bool streamout_dirty;
|
||||||
|
struct radeon_bo *htile_bo;
|
||||||
|
u64 htile_offset;
|
||||||
|
u32 htile_surface;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 }
|
#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 }
|
||||||
|
@ -321,6 +324,9 @@ static void r600_cs_track_init(struct r600_cs_track *track)
|
||||||
track->db_depth_size_idx = 0;
|
track->db_depth_size_idx = 0;
|
||||||
track->db_depth_control = 0xFFFFFFFF;
|
track->db_depth_control = 0xFFFFFFFF;
|
||||||
track->db_dirty = true;
|
track->db_dirty = true;
|
||||||
|
track->htile_bo = NULL;
|
||||||
|
track->htile_offset = 0xFFFFFFFF;
|
||||||
|
track->htile_surface = 0;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
track->vgt_strmout_size[i] = 0;
|
track->vgt_strmout_size[i] = 0;
|
||||||
|
@ -455,82 +461,23 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int r600_cs_track_check(struct radeon_cs_parser *p)
|
static int r600_cs_track_validate_db(struct radeon_cs_parser *p)
|
||||||
{
|
{
|
||||||
struct r600_cs_track *track = p->track;
|
struct r600_cs_track *track = p->track;
|
||||||
u32 tmp;
|
u32 nviews, bpe, ntiles, size, slice_tile_max, tmp;
|
||||||
int r, i;
|
u32 height_align, pitch_align, depth_align;
|
||||||
volatile u32 *ib = p->ib->ptr;
|
u32 pitch = 8192;
|
||||||
|
u32 height = 8192;
|
||||||
/* on legacy kernel we don't perform advanced check */
|
|
||||||
if (p->rdev == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* check streamout */
|
|
||||||
if (track->streamout_dirty && track->vgt_strmout_en) {
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (track->vgt_strmout_buffer_en & (1 << i)) {
|
|
||||||
if (track->vgt_strmout_bo[i]) {
|
|
||||||
u64 offset = (u64)track->vgt_strmout_bo_offset[i] +
|
|
||||||
(u64)track->vgt_strmout_size[i];
|
|
||||||
if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) {
|
|
||||||
DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n",
|
|
||||||
i, offset,
|
|
||||||
radeon_bo_size(track->vgt_strmout_bo[i]));
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dev_warn(p->dev, "No buffer for streamout %d\n", i);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
track->streamout_dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (track->sx_misc_kill_all_prims)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* check that we have a cb for each enabled target, we don't check
|
|
||||||
* shader_mask because it seems mesa isn't always setting it :(
|
|
||||||
*/
|
|
||||||
if (track->cb_dirty) {
|
|
||||||
tmp = track->cb_target_mask;
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if ((tmp >> (i * 4)) & 0xF) {
|
|
||||||
/* at least one component is enabled */
|
|
||||||
if (track->cb_color_bo[i] == NULL) {
|
|
||||||
dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
|
|
||||||
__func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
/* perform rewrite of CB_COLOR[0-7]_SIZE */
|
|
||||||
r = r600_cs_track_validate_cb(p, i);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
track->cb_dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (track->db_dirty) {
|
|
||||||
/* Check depth buffer */
|
|
||||||
if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
|
|
||||||
G_028800_Z_ENABLE(track->db_depth_control)) {
|
|
||||||
u32 nviews, bpe, ntiles, size, slice_tile_max;
|
|
||||||
u32 height, height_align, pitch, pitch_align, depth_align;
|
|
||||||
u64 base_offset, base_align;
|
u64 base_offset, base_align;
|
||||||
struct array_mode_checker array_check;
|
struct array_mode_checker array_check;
|
||||||
int array_mode;
|
int array_mode;
|
||||||
|
volatile u32 *ib = p->ib->ptr;
|
||||||
|
|
||||||
|
|
||||||
if (track->db_bo == NULL) {
|
if (track->db_bo == NULL) {
|
||||||
dev_warn(p->dev, "z/stencil with no depth buffer\n");
|
dev_warn(p->dev, "z/stencil with no depth buffer\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
|
|
||||||
dev_warn(p->dev, "this kernel doesn't support z/stencil htile\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
switch (G_028010_FORMAT(track->db_depth_info)) {
|
switch (G_028010_FORMAT(track->db_depth_info)) {
|
||||||
case V_028010_DEPTH_16:
|
case V_028010_DEPTH_16:
|
||||||
bpe = 2;
|
bpe = 2;
|
||||||
|
@ -612,7 +559,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (!IS_ALIGNED(base_offset, base_align)) {
|
if (!IS_ALIGNED(base_offset, base_align)) {
|
||||||
dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i,
|
dev_warn(p->dev, "%s offset 0x%llx, 0x%llx, %d not aligned\n", __func__,
|
||||||
base_offset, base_align, array_mode);
|
base_offset, base_align, array_mode);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -628,9 +575,202 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* hyperz */
|
||||||
|
if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
|
||||||
|
unsigned long size;
|
||||||
|
unsigned nbx, nby;
|
||||||
|
|
||||||
|
if (track->htile_bo == NULL) {
|
||||||
|
dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
|
||||||
|
__func__, __LINE__, track->db_depth_info);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
|
||||||
|
dev_warn(p->dev, "%s:%d htile can't be enabled with bogus db_depth_size 0x%08x\n",
|
||||||
|
__func__, __LINE__, track->db_depth_size);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbx = pitch;
|
||||||
|
nby = height;
|
||||||
|
if (G_028D24_LINEAR(track->htile_surface)) {
|
||||||
|
/* nbx must be 16 htiles aligned == 16 * 8 pixel aligned */
|
||||||
|
nbx = round_up(nbx, 16 * 8);
|
||||||
|
/* nby is npipes htiles aligned == npipes * 8 pixel aligned */
|
||||||
|
nby = round_up(nby, track->npipes * 8);
|
||||||
|
} else {
|
||||||
|
/* htile widht & nby (8 or 4) make 2 bits number */
|
||||||
|
tmp = track->htile_surface & 3;
|
||||||
|
/* align is htile align * 8, htile align vary according to
|
||||||
|
* number of pipe and tile width and nby
|
||||||
|
*/
|
||||||
|
switch (track->npipes) {
|
||||||
|
case 8:
|
||||||
|
switch (tmp) {
|
||||||
|
case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
|
||||||
|
nbx = round_up(nbx, 64 * 8);
|
||||||
|
nby = round_up(nby, 64 * 8);
|
||||||
|
break;
|
||||||
|
case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
|
||||||
|
case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
|
||||||
|
nbx = round_up(nbx, 64 * 8);
|
||||||
|
nby = round_up(nby, 32 * 8);
|
||||||
|
break;
|
||||||
|
case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
|
||||||
|
nbx = round_up(nbx, 32 * 8);
|
||||||
|
nby = round_up(nby, 32 * 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
switch (tmp) {
|
||||||
|
case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
|
||||||
|
nbx = round_up(nbx, 64 * 8);
|
||||||
|
nby = round_up(nby, 32 * 8);
|
||||||
|
break;
|
||||||
|
case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
|
||||||
|
case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
|
||||||
|
nbx = round_up(nbx, 32 * 8);
|
||||||
|
nby = round_up(nby, 32 * 8);
|
||||||
|
break;
|
||||||
|
case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
|
||||||
|
nbx = round_up(nbx, 32 * 8);
|
||||||
|
nby = round_up(nby, 16 * 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
switch (tmp) {
|
||||||
|
case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
|
||||||
|
nbx = round_up(nbx, 32 * 8);
|
||||||
|
nby = round_up(nby, 32 * 8);
|
||||||
|
break;
|
||||||
|
case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
|
||||||
|
case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
|
||||||
|
nbx = round_up(nbx, 32 * 8);
|
||||||
|
nby = round_up(nby, 16 * 8);
|
||||||
|
break;
|
||||||
|
case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
|
||||||
|
nbx = round_up(nbx, 16 * 8);
|
||||||
|
nby = round_up(nby, 16 * 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
switch (tmp) {
|
||||||
|
case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
|
||||||
|
nbx = round_up(nbx, 32 * 8);
|
||||||
|
nby = round_up(nby, 16 * 8);
|
||||||
|
break;
|
||||||
|
case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
|
||||||
|
case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
|
||||||
|
nbx = round_up(nbx, 16 * 8);
|
||||||
|
nby = round_up(nby, 16 * 8);
|
||||||
|
break;
|
||||||
|
case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
|
||||||
|
nbx = round_up(nbx, 16 * 8);
|
||||||
|
nby = round_up(nby, 8 * 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
|
||||||
|
__func__, __LINE__, track->npipes);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* compute number of htile */
|
||||||
|
nbx = G_028D24_HTILE_WIDTH(track->htile_surface) ? nbx / 8 : nbx / 4;
|
||||||
|
nby = G_028D24_HTILE_HEIGHT(track->htile_surface) ? nby / 8 : nby / 4;
|
||||||
|
size = nbx * nby * 4;
|
||||||
|
size += track->htile_offset;
|
||||||
|
|
||||||
|
if (size > radeon_bo_size(track->htile_bo)) {
|
||||||
|
dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
|
||||||
|
__func__, __LINE__, radeon_bo_size(track->htile_bo),
|
||||||
|
size, nbx, nby);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
track->db_dirty = false;
|
track->db_dirty = false;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int r600_cs_track_check(struct radeon_cs_parser *p)
|
||||||
|
{
|
||||||
|
struct r600_cs_track *track = p->track;
|
||||||
|
u32 tmp;
|
||||||
|
int r, i;
|
||||||
|
|
||||||
|
/* on legacy kernel we don't perform advanced check */
|
||||||
|
if (p->rdev == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check streamout */
|
||||||
|
if (track->streamout_dirty && track->vgt_strmout_en) {
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
if (track->vgt_strmout_buffer_en & (1 << i)) {
|
||||||
|
if (track->vgt_strmout_bo[i]) {
|
||||||
|
u64 offset = (u64)track->vgt_strmout_bo_offset[i] +
|
||||||
|
(u64)track->vgt_strmout_size[i];
|
||||||
|
if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) {
|
||||||
|
DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n",
|
||||||
|
i, offset,
|
||||||
|
radeon_bo_size(track->vgt_strmout_bo[i]));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dev_warn(p->dev, "No buffer for streamout %d\n", i);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
track->streamout_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track->sx_misc_kill_all_prims)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check that we have a cb for each enabled target, we don't check
|
||||||
|
* shader_mask because it seems mesa isn't always setting it :(
|
||||||
|
*/
|
||||||
|
if (track->cb_dirty) {
|
||||||
|
tmp = track->cb_target_mask;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if ((tmp >> (i * 4)) & 0xF) {
|
||||||
|
/* at least one component is enabled */
|
||||||
|
if (track->cb_color_bo[i] == NULL) {
|
||||||
|
dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
|
||||||
|
__func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
/* perform rewrite of CB_COLOR[0-7]_SIZE */
|
||||||
|
r = r600_cs_track_validate_cb(p, i);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
track->cb_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check depth buffer */
|
||||||
|
if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
|
||||||
|
G_028800_Z_ENABLE(track->db_depth_control))) {
|
||||||
|
r = r600_cs_track_validate_db(p);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,6 +1384,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||||
track->db_dirty = true;
|
track->db_dirty = true;
|
||||||
break;
|
break;
|
||||||
case DB_HTILE_DATA_BASE:
|
case DB_HTILE_DATA_BASE:
|
||||||
|
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||||
|
if (r) {
|
||||||
|
dev_warn(p->dev, "bad SET_CONTEXT_REG "
|
||||||
|
"0x%04X\n", reg);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
track->htile_offset = radeon_get_ib_value(p, idx) << 8;
|
||||||
|
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||||
|
track->htile_bo = reloc->robj;
|
||||||
|
track->db_dirty = true;
|
||||||
|
break;
|
||||||
|
case DB_HTILE_SURFACE:
|
||||||
|
track->htile_surface = radeon_get_ib_value(p, idx);
|
||||||
|
track->db_dirty = true;
|
||||||
|
break;
|
||||||
case SQ_PGM_START_FS:
|
case SQ_PGM_START_FS:
|
||||||
case SQ_PGM_START_ES:
|
case SQ_PGM_START_ES:
|
||||||
case SQ_PGM_START_VS:
|
case SQ_PGM_START_VS:
|
||||||
|
|
|
@ -195,6 +195,14 @@
|
||||||
#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31)
|
#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31)
|
||||||
#define DB_DEPTH_BASE 0x2800C
|
#define DB_DEPTH_BASE 0x2800C
|
||||||
#define DB_HTILE_DATA_BASE 0x28014
|
#define DB_HTILE_DATA_BASE 0x28014
|
||||||
|
#define DB_HTILE_SURFACE 0x28D24
|
||||||
|
#define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0)
|
||||||
|
#define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
|
||||||
|
#define C_028D24_HTILE_WIDTH 0xFFFFFFFE
|
||||||
|
#define S_028D24_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
|
||||||
|
#define G_028D24_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
|
||||||
|
#define C_028D24_HTILE_HEIGHT 0xFFFFFFFD
|
||||||
|
#define G_028D24_LINEAR(x) (((x) >> 2) & 0x1)
|
||||||
#define DB_WATERMARKS 0x9838
|
#define DB_WATERMARKS 0x9838
|
||||||
#define DEPTH_FREE(x) ((x) << 0)
|
#define DEPTH_FREE(x) ((x) << 0)
|
||||||
#define DEPTH_FLUSH(x) ((x) << 5)
|
#define DEPTH_FLUSH(x) ((x) << 5)
|
||||||
|
|
|
@ -233,7 +233,17 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
|
||||||
bo->pin_count++;
|
bo->pin_count++;
|
||||||
if (gpu_addr)
|
if (gpu_addr)
|
||||||
*gpu_addr = radeon_bo_gpu_offset(bo);
|
*gpu_addr = radeon_bo_gpu_offset(bo);
|
||||||
WARN_ON_ONCE(max_offset != 0);
|
|
||||||
|
if (max_offset != 0) {
|
||||||
|
u64 domain_start;
|
||||||
|
|
||||||
|
if (domain == RADEON_GEM_DOMAIN_VRAM)
|
||||||
|
domain_start = bo->rdev->mc.vram_start;
|
||||||
|
else
|
||||||
|
domain_start = bo->rdev->mc.gtt_start;
|
||||||
|
WARN_ON_ONCE((*gpu_addr - domain_start) > max_offset);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
radeon_ttm_placement_from_domain(bo, domain);
|
radeon_ttm_placement_from_domain(bo, domain);
|
||||||
|
|
|
@ -509,7 +509,6 @@ cayman 0x9400
|
||||||
0x00028AA8 IA_MULTI_VGT_PARAM
|
0x00028AA8 IA_MULTI_VGT_PARAM
|
||||||
0x00028AB4 VGT_REUSE_OFF
|
0x00028AB4 VGT_REUSE_OFF
|
||||||
0x00028AB8 VGT_VTX_CNT_EN
|
0x00028AB8 VGT_VTX_CNT_EN
|
||||||
0x00028ABC DB_HTILE_SURFACE
|
|
||||||
0x00028AC0 DB_SRESULTS_COMPARE_STATE0
|
0x00028AC0 DB_SRESULTS_COMPARE_STATE0
|
||||||
0x00028AC4 DB_SRESULTS_COMPARE_STATE1
|
0x00028AC4 DB_SRESULTS_COMPARE_STATE1
|
||||||
0x00028AC8 DB_PRELOAD_CONTROL
|
0x00028AC8 DB_PRELOAD_CONTROL
|
||||||
|
|
|
@ -519,7 +519,6 @@ evergreen 0x9400
|
||||||
0x00028AA4 VGT_INSTANCE_STEP_RATE_1
|
0x00028AA4 VGT_INSTANCE_STEP_RATE_1
|
||||||
0x00028AB4 VGT_REUSE_OFF
|
0x00028AB4 VGT_REUSE_OFF
|
||||||
0x00028AB8 VGT_VTX_CNT_EN
|
0x00028AB8 VGT_VTX_CNT_EN
|
||||||
0x00028ABC DB_HTILE_SURFACE
|
|
||||||
0x00028AC0 DB_SRESULTS_COMPARE_STATE0
|
0x00028AC0 DB_SRESULTS_COMPARE_STATE0
|
||||||
0x00028AC4 DB_SRESULTS_COMPARE_STATE1
|
0x00028AC4 DB_SRESULTS_COMPARE_STATE1
|
||||||
0x00028AC8 DB_PRELOAD_CONTROL
|
0x00028AC8 DB_PRELOAD_CONTROL
|
||||||
|
|
|
@ -713,7 +713,6 @@ r600 0x9400
|
||||||
0x0000A710 TD_VS_SAMPLER17_BORDER_RED
|
0x0000A710 TD_VS_SAMPLER17_BORDER_RED
|
||||||
0x00009508 TA_CNTL_AUX
|
0x00009508 TA_CNTL_AUX
|
||||||
0x0002802C DB_DEPTH_CLEAR
|
0x0002802C DB_DEPTH_CLEAR
|
||||||
0x00028D24 DB_HTILE_SURFACE
|
|
||||||
0x00028D34 DB_PREFETCH_LIMIT
|
0x00028D34 DB_PREFETCH_LIMIT
|
||||||
0x00028D30 DB_PRELOAD_CONTROL
|
0x00028D30 DB_PRELOAD_CONTROL
|
||||||
0x00028D0C DB_RENDER_CONTROL
|
0x00028D0C DB_RENDER_CONTROL
|
||||||
|
|
Loading…
Add table
Reference in a new issue