mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
Merge remote branch 'nouveau/for-airlied' into drm-next-stage
* nouveau/for-airlied: (25 commits) drm/nouveau: use ALIGN instead of open coding it drm/nouveau: report unknown connector state if lid closed drm/nouveau: support version 0x20 displayport tables drm/nouveau: Fix noaccel/nofbaccel option descriptions. drm/nv50: Implement ctxprog/state generation. drm/nouveau: use dcb connector types throughout the driver drm/nv50: enable hpd on any connector we know the gpio line for drm/nouveau: use dcb connector table for creating drm connectors drm/nouveau: construct a connector table for cards that lack a real one drm/nouveau: check for known dcb connector types drm/nouveau: parse dcb gpio/connector tables after encoders drm/nouveau: reorganise bios header, add dcb connector type enums drm/nouveau: merge nvbios and nouveau_bios_info drm/nouveau: merge parsed_dcb and bios_parsed_dcb into dcb_table drm/nouveau: rename parsed_dcb_gpio to dcb_gpio_table drm/nouveau: allow retrieval of vbios image from debugfs drm/nouveau: fix missing spin_unlock in failure path drm/nouveau: fix i2ctable bounds checking drm/nouveau: fix nouveau_i2c_find bounds checking drm/nouveau: fix pramdac_table range checking ... Conflicts: drivers/gpu/drm/nouveau/nouveau_gem.c
This commit is contained in:
@@ -16,7 +16,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
|
||||
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
|
||||
nv04_graph.o nv10_graph.o nv20_graph.o \
|
||||
nv40_graph.o nv50_graph.o \
|
||||
nv40_grctx.o \
|
||||
nv40_grctx.o nv50_grctx.o \
|
||||
nv04_instmem.o nv50_instmem.o \
|
||||
nv50_crtc.o nv50_dac.o nv50_sor.o \
|
||||
nv50_cursor.o nv50_display.o nv50_fbcon.o \
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,9 +34,67 @@
|
||||
|
||||
#define DCB_LOC_ON_CHIP 0
|
||||
|
||||
struct dcb_i2c_entry {
|
||||
uint8_t port_type;
|
||||
uint8_t read, write;
|
||||
struct nouveau_i2c_chan *chan;
|
||||
};
|
||||
|
||||
enum dcb_gpio_tag {
|
||||
DCB_GPIO_TVDAC0 = 0xc,
|
||||
DCB_GPIO_TVDAC1 = 0x2d,
|
||||
};
|
||||
|
||||
struct dcb_gpio_entry {
|
||||
enum dcb_gpio_tag tag;
|
||||
int line;
|
||||
bool invert;
|
||||
};
|
||||
|
||||
struct dcb_gpio_table {
|
||||
int entries;
|
||||
struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES];
|
||||
};
|
||||
|
||||
enum dcb_connector_type {
|
||||
DCB_CONNECTOR_VGA = 0x00,
|
||||
DCB_CONNECTOR_TV_0 = 0x10,
|
||||
DCB_CONNECTOR_TV_1 = 0x11,
|
||||
DCB_CONNECTOR_TV_3 = 0x13,
|
||||
DCB_CONNECTOR_DVI_I = 0x30,
|
||||
DCB_CONNECTOR_DVI_D = 0x31,
|
||||
DCB_CONNECTOR_LVDS = 0x40,
|
||||
DCB_CONNECTOR_DP = 0x46,
|
||||
DCB_CONNECTOR_eDP = 0x47,
|
||||
DCB_CONNECTOR_HDMI_0 = 0x60,
|
||||
DCB_CONNECTOR_HDMI_1 = 0x61,
|
||||
DCB_CONNECTOR_NONE = 0xff
|
||||
};
|
||||
|
||||
struct dcb_connector_table_entry {
|
||||
uint32_t entry;
|
||||
enum dcb_connector_type type;
|
||||
uint8_t index;
|
||||
uint8_t gpio_tag;
|
||||
};
|
||||
|
||||
struct dcb_connector_table {
|
||||
int entries;
|
||||
struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
|
||||
};
|
||||
|
||||
enum dcb_type {
|
||||
OUTPUT_ANALOG = 0,
|
||||
OUTPUT_TV = 1,
|
||||
OUTPUT_TMDS = 2,
|
||||
OUTPUT_LVDS = 3,
|
||||
OUTPUT_DP = 6,
|
||||
OUTPUT_ANY = -1
|
||||
};
|
||||
|
||||
struct dcb_entry {
|
||||
int index; /* may not be raw dcb index if merging has happened */
|
||||
uint8_t type;
|
||||
enum dcb_type type;
|
||||
uint8_t i2c_index;
|
||||
uint8_t heads;
|
||||
uint8_t connector;
|
||||
@@ -71,69 +129,22 @@ struct dcb_entry {
|
||||
bool i2c_upper_default;
|
||||
};
|
||||
|
||||
struct dcb_i2c_entry {
|
||||
uint8_t port_type;
|
||||
uint8_t read, write;
|
||||
struct nouveau_i2c_chan *chan;
|
||||
};
|
||||
|
||||
struct parsed_dcb {
|
||||
int entries;
|
||||
struct dcb_entry entry[DCB_MAX_NUM_ENTRIES];
|
||||
struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
|
||||
};
|
||||
|
||||
enum dcb_gpio_tag {
|
||||
DCB_GPIO_TVDAC0 = 0xc,
|
||||
DCB_GPIO_TVDAC1 = 0x2d,
|
||||
};
|
||||
|
||||
struct dcb_gpio_entry {
|
||||
enum dcb_gpio_tag tag;
|
||||
int line;
|
||||
bool invert;
|
||||
};
|
||||
|
||||
struct parsed_dcb_gpio {
|
||||
int entries;
|
||||
struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES];
|
||||
};
|
||||
|
||||
struct dcb_connector_table_entry {
|
||||
uint32_t entry;
|
||||
uint8_t type;
|
||||
uint8_t index;
|
||||
uint8_t gpio_tag;
|
||||
};
|
||||
|
||||
struct dcb_connector_table {
|
||||
int entries;
|
||||
struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES];
|
||||
};
|
||||
|
||||
struct bios_parsed_dcb {
|
||||
struct dcb_table {
|
||||
uint8_t version;
|
||||
|
||||
struct parsed_dcb dcb;
|
||||
int entries;
|
||||
struct dcb_entry entry[DCB_MAX_NUM_ENTRIES];
|
||||
|
||||
uint8_t *i2c_table;
|
||||
uint8_t i2c_default_indices;
|
||||
struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
|
||||
|
||||
uint16_t gpio_table_ptr;
|
||||
struct parsed_dcb_gpio gpio;
|
||||
struct dcb_gpio_table gpio;
|
||||
uint16_t connector_table_ptr;
|
||||
struct dcb_connector_table connector;
|
||||
};
|
||||
|
||||
enum nouveau_encoder_type {
|
||||
OUTPUT_ANALOG = 0,
|
||||
OUTPUT_TV = 1,
|
||||
OUTPUT_TMDS = 2,
|
||||
OUTPUT_LVDS = 3,
|
||||
OUTPUT_DP = 6,
|
||||
OUTPUT_ANY = -1
|
||||
};
|
||||
|
||||
enum nouveau_or {
|
||||
OUTPUT_A = (1 << 0),
|
||||
OUTPUT_B = (1 << 1),
|
||||
@@ -190,8 +201,8 @@ struct pll_lims {
|
||||
int refclk;
|
||||
};
|
||||
|
||||
struct nouveau_bios_info {
|
||||
struct parsed_dcb *dcb;
|
||||
struct nvbios {
|
||||
struct drm_device *dev;
|
||||
|
||||
uint8_t chip_version;
|
||||
|
||||
@@ -199,11 +210,6 @@ struct nouveau_bios_info {
|
||||
uint32_t tvdactestval;
|
||||
uint8_t digital_min_front_porch;
|
||||
bool fp_no_ddc;
|
||||
};
|
||||
|
||||
struct nvbios {
|
||||
struct drm_device *dev;
|
||||
struct nouveau_bios_info pub;
|
||||
|
||||
struct mutex lock;
|
||||
|
||||
@@ -234,7 +240,7 @@ struct nvbios {
|
||||
uint16_t some_script_ptr; /* BIT I + 14 */
|
||||
uint16_t init96_tbl_ptr; /* BIT I + 16 */
|
||||
|
||||
struct bios_parsed_dcb bdcb;
|
||||
struct dcb_table dcb;
|
||||
|
||||
struct {
|
||||
int crtchead;
|
||||
|
||||
@@ -274,7 +274,7 @@ getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
|
||||
* returns calculated clock
|
||||
*/
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
int cv = dev_priv->vbios->chip_version;
|
||||
int cv = dev_priv->vbios.chip_version;
|
||||
int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq;
|
||||
int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m;
|
||||
int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n;
|
||||
@@ -373,7 +373,7 @@ getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
|
||||
* returns calculated clock
|
||||
*/
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
int chip_version = dev_priv->vbios->chip_version;
|
||||
int chip_version = dev_priv->vbios.chip_version;
|
||||
int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq;
|
||||
int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq;
|
||||
int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq;
|
||||
|
||||
@@ -35,22 +35,27 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_bo *pb = chan->pushbuf_bo;
|
||||
struct nouveau_gpuobj *pushbuf = NULL;
|
||||
uint32_t start = pb->bo.mem.mm_node->start << PAGE_SHIFT;
|
||||
int ret;
|
||||
|
||||
if (dev_priv->card_type >= NV_50) {
|
||||
ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
|
||||
dev_priv->vm_end, NV_DMA_ACCESS_RO,
|
||||
NV_DMA_TARGET_AGP, &pushbuf);
|
||||
chan->pushbuf_base = pb->bo.offset;
|
||||
} else
|
||||
if (pb->bo.mem.mem_type == TTM_PL_TT) {
|
||||
ret = nouveau_gpuobj_gart_dma_new(chan, 0,
|
||||
dev_priv->gart_info.aper_size,
|
||||
NV_DMA_ACCESS_RO, &pushbuf,
|
||||
NULL);
|
||||
chan->pushbuf_base = start;
|
||||
chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
|
||||
} else
|
||||
if (dev_priv->card_type != NV_04) {
|
||||
ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
|
||||
dev_priv->fb_available_size,
|
||||
NV_DMA_ACCESS_RO,
|
||||
NV_DMA_TARGET_VIDMEM, &pushbuf);
|
||||
chan->pushbuf_base = start;
|
||||
chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
|
||||
} else {
|
||||
/* NV04 cmdbuf hack, from original ddx.. not sure of it's
|
||||
* exact reason for existing :) PCI access to cmdbuf in
|
||||
@@ -61,7 +66,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
|
||||
dev_priv->fb_available_size,
|
||||
NV_DMA_ACCESS_RO,
|
||||
NV_DMA_TARGET_PCI, &pushbuf);
|
||||
chan->pushbuf_base = start;
|
||||
chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf);
|
||||
@@ -275,9 +280,18 @@ nouveau_channel_free(struct nouveau_channel *chan)
|
||||
*/
|
||||
nouveau_fence_fini(chan);
|
||||
|
||||
/* Ensure the channel is no longer active on the GPU */
|
||||
/* This will prevent pfifo from switching channels. */
|
||||
pfifo->reassign(dev, false);
|
||||
|
||||
/* We want to give pgraph a chance to idle and get rid of all potential
|
||||
* errors. We need to do this before the lock, otherwise the irq handler
|
||||
* is unable to process them.
|
||||
*/
|
||||
if (pgraph->channel(dev) == chan)
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
|
||||
|
||||
pgraph->fifo_access(dev, false);
|
||||
if (pgraph->channel(dev) == chan)
|
||||
pgraph->unload_context(dev);
|
||||
@@ -293,6 +307,8 @@ nouveau_channel_free(struct nouveau_channel *chan)
|
||||
|
||||
pfifo->reassign(dev, true);
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
|
||||
|
||||
/* Release the channel's resources */
|
||||
nouveau_gpuobj_ref_del(dev, &chan->pushbuf);
|
||||
if (chan->pushbuf_bo) {
|
||||
@@ -369,6 +385,14 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
|
||||
return ret;
|
||||
init->channel = chan->id;
|
||||
|
||||
if (chan->dma.ib_max)
|
||||
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
|
||||
NOUVEAU_GEM_DOMAIN_GART;
|
||||
else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM)
|
||||
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
|
||||
else
|
||||
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
|
||||
|
||||
init->subchan[0].handle = NvM2MF;
|
||||
if (dev_priv->card_type < NV_50)
|
||||
init->subchan[0].grclass = 0x0039;
|
||||
@@ -408,7 +432,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
|
||||
***********************************/
|
||||
|
||||
struct drm_ioctl_desc nouveau_ioctls[] = {
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
|
||||
@@ -418,13 +441,9 @@ struct drm_ioctl_desc nouveau_ioctls[] = {
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL, nouveau_gem_ioctl_pushbuf_call, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PIN, nouveau_gem_ioctl_pin, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_UNPIN, nouveau_gem_ioctl_unpin, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL2, nouveau_gem_ioctl_pushbuf_call2, DRM_AUTH),
|
||||
};
|
||||
|
||||
int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
|
||||
|
||||
@@ -218,7 +218,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
|
||||
connector->interlace_allowed = true;
|
||||
}
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
|
||||
if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) {
|
||||
drm_connector_property_set_value(connector,
|
||||
dev->mode_config.dvi_i_subconnector_property,
|
||||
nv_encoder->dcb->type == OUTPUT_TMDS ?
|
||||
@@ -236,15 +236,17 @@ nouveau_connector_detect(struct drm_connector *connector)
|
||||
struct nouveau_i2c_chan *i2c;
|
||||
int type, flags;
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
|
||||
if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS)
|
||||
nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
|
||||
if (nv_encoder && nv_connector->native_mode) {
|
||||
unsigned status = connector_status_connected;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
if (!nouveau_ignorelid && !acpi_lid_open())
|
||||
return connector_status_disconnected;
|
||||
status = connector_status_unknown;
|
||||
#endif
|
||||
nouveau_connector_set_encoder(connector, nv_encoder);
|
||||
return connector_status_connected;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Cleanup the previous EDID block. */
|
||||
@@ -279,7 +281,7 @@ nouveau_connector_detect(struct drm_connector *connector)
|
||||
* same i2c channel so the value returned from ddc_detect
|
||||
* isn't necessarily correct.
|
||||
*/
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
|
||||
if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) {
|
||||
if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL)
|
||||
type = OUTPUT_TMDS;
|
||||
else
|
||||
@@ -321,11 +323,11 @@ detect_analog:
|
||||
static void
|
||||
nouveau_connector_force(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||
struct nouveau_encoder *nv_encoder;
|
||||
int type;
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
|
||||
if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) {
|
||||
if (connector->force == DRM_FORCE_ON_DIGITAL)
|
||||
type = OUTPUT_TMDS;
|
||||
else
|
||||
@@ -335,7 +337,7 @@ nouveau_connector_force(struct drm_connector *connector)
|
||||
|
||||
nv_encoder = find_encoder_by_type(connector, type);
|
||||
if (!nv_encoder) {
|
||||
NV_ERROR(dev, "can't find encoder to force %s on!\n",
|
||||
NV_ERROR(connector->dev, "can't find encoder to force %s on!\n",
|
||||
drm_get_connector_name(connector));
|
||||
connector->status = connector_status_disconnected;
|
||||
return;
|
||||
@@ -369,7 +371,7 @@ nouveau_connector_set_property(struct drm_connector *connector,
|
||||
}
|
||||
|
||||
/* LVDS always needs gpu scaling */
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
|
||||
if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS &&
|
||||
value == DRM_MODE_SCALE_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -535,7 +537,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
|
||||
/* If we're not LVDS, destroy the previous native mode, the attached
|
||||
* monitor could have changed.
|
||||
*/
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
|
||||
if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS &&
|
||||
nv_connector->native_mode) {
|
||||
drm_mode_destroy(dev, nv_connector->native_mode);
|
||||
nv_connector->native_mode = NULL;
|
||||
@@ -563,7 +565,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
|
||||
ret = get_slave_funcs(nv_encoder)->
|
||||
get_modes(to_drm_encoder(nv_encoder), connector);
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
|
||||
if (nv_encoder->dcb->type == OUTPUT_LVDS)
|
||||
ret += nouveau_connector_scaler_modes_add(connector);
|
||||
|
||||
return ret;
|
||||
@@ -613,6 +615,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
|
||||
|
||||
clock *= 3;
|
||||
break;
|
||||
default:
|
||||
BUG_ON(1);
|
||||
return MODE_BAD;
|
||||
}
|
||||
|
||||
if (clock < min_clock)
|
||||
@@ -680,7 +685,7 @@ nouveau_connector_create_lvds(struct drm_device *dev,
|
||||
/* Firstly try getting EDID over DDC, if allowed and I2C channel
|
||||
* is available.
|
||||
*/
|
||||
if (!dev_priv->VBIOS.pub.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
|
||||
if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
|
||||
i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
|
||||
|
||||
if (i2c) {
|
||||
@@ -695,7 +700,7 @@ nouveau_connector_create_lvds(struct drm_device *dev,
|
||||
*/
|
||||
if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) &&
|
||||
(nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
|
||||
dev_priv->VBIOS.pub.fp_no_ddc)) {
|
||||
dev_priv->vbios.fp_no_ddc)) {
|
||||
nv_connector->native_mode = drm_mode_duplicate(dev, &native);
|
||||
goto out;
|
||||
}
|
||||
@@ -704,7 +709,7 @@ nouveau_connector_create_lvds(struct drm_device *dev,
|
||||
* stored for the panel stored in them.
|
||||
*/
|
||||
if (!nv_connector->edid && !nv_connector->native_mode &&
|
||||
!dev_priv->VBIOS.pub.fp_no_ddc) {
|
||||
!dev_priv->vbios.fp_no_ddc) {
|
||||
struct edid *edid =
|
||||
(struct edid *)nouveau_bios_embedded_edid(dev);
|
||||
if (edid) {
|
||||
@@ -739,46 +744,66 @@ out:
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_connector_create(struct drm_device *dev, int index, int type)
|
||||
nouveau_connector_create(struct drm_device *dev,
|
||||
struct dcb_connector_table_entry *dcb)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_connector *nv_connector = NULL;
|
||||
struct drm_connector *connector;
|
||||
struct drm_encoder *encoder;
|
||||
int ret;
|
||||
int ret, type;
|
||||
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
switch (dcb->type) {
|
||||
case DCB_CONNECTOR_NONE:
|
||||
return 0;
|
||||
case DCB_CONNECTOR_VGA:
|
||||
NV_INFO(dev, "Detected a VGA connector\n");
|
||||
type = DRM_MODE_CONNECTOR_VGA;
|
||||
break;
|
||||
case DCB_CONNECTOR_TV_0:
|
||||
case DCB_CONNECTOR_TV_1:
|
||||
case DCB_CONNECTOR_TV_3:
|
||||
NV_INFO(dev, "Detected a TV connector\n");
|
||||
type = DRM_MODE_CONNECTOR_TV;
|
||||
break;
|
||||
case DCB_CONNECTOR_DVI_I:
|
||||
NV_INFO(dev, "Detected a DVI-I connector\n");
|
||||
type = DRM_MODE_CONNECTOR_DVII;
|
||||
break;
|
||||
case DCB_CONNECTOR_DVI_D:
|
||||
NV_INFO(dev, "Detected a DVI-D connector\n");
|
||||
type = DRM_MODE_CONNECTOR_DVID;
|
||||
break;
|
||||
case DCB_CONNECTOR_HDMI_0:
|
||||
case DCB_CONNECTOR_HDMI_1:
|
||||
NV_INFO(dev, "Detected a HDMI connector\n");
|
||||
type = DRM_MODE_CONNECTOR_HDMIA;
|
||||
break;
|
||||
case DCB_CONNECTOR_LVDS:
|
||||
NV_INFO(dev, "Detected a LVDS connector\n");
|
||||
type = DRM_MODE_CONNECTOR_LVDS;
|
||||
break;
|
||||
case DCB_CONNECTOR_DP:
|
||||
NV_INFO(dev, "Detected a DisplayPort connector\n");
|
||||
type = DRM_MODE_CONNECTOR_DisplayPort;
|
||||
break;
|
||||
case DCB_CONNECTOR_eDP:
|
||||
NV_INFO(dev, "Detected an eDP connector\n");
|
||||
type = DRM_MODE_CONNECTOR_eDP;
|
||||
break;
|
||||
default:
|
||||
NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
|
||||
if (!nv_connector)
|
||||
return -ENOMEM;
|
||||
nv_connector->dcb = nouveau_bios_connector_entry(dev, index);
|
||||
nv_connector->dcb = dcb;
|
||||
connector = &nv_connector->base;
|
||||
|
||||
switch (type) {
|
||||
case DRM_MODE_CONNECTOR_VGA:
|
||||
NV_INFO(dev, "Detected a VGA connector\n");
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DVID:
|
||||
NV_INFO(dev, "Detected a DVI-D connector\n");
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DVII:
|
||||
NV_INFO(dev, "Detected a DVI-I connector\n");
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
NV_INFO(dev, "Detected a LVDS connector\n");
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_TV:
|
||||
NV_INFO(dev, "Detected a TV connector\n");
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DisplayPort:
|
||||
NV_INFO(dev, "Detected a DisplayPort connector\n");
|
||||
break;
|
||||
default:
|
||||
NV_ERROR(dev, "Unknown connector, this is not good.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* defaults, will get overridden in detect() */
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
@@ -786,44 +811,11 @@ nouveau_connector_create(struct drm_device *dev, int index, int type)
|
||||
drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
|
||||
drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
|
||||
|
||||
/* Init DVI-I specific properties */
|
||||
if (type == DRM_MODE_CONNECTOR_DVII) {
|
||||
drm_mode_create_dvi_i_properties(dev);
|
||||
drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0);
|
||||
drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
|
||||
}
|
||||
|
||||
if (type != DRM_MODE_CONNECTOR_LVDS)
|
||||
nv_connector->use_dithering = false;
|
||||
|
||||
if (type == DRM_MODE_CONNECTOR_DVID ||
|
||||
type == DRM_MODE_CONNECTOR_DVII ||
|
||||
type == DRM_MODE_CONNECTOR_LVDS ||
|
||||
type == DRM_MODE_CONNECTOR_DisplayPort) {
|
||||
nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
|
||||
|
||||
drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property,
|
||||
nv_connector->scaling_mode);
|
||||
drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property,
|
||||
nv_connector->use_dithering ? DRM_MODE_DITHERING_ON
|
||||
: DRM_MODE_DITHERING_OFF);
|
||||
|
||||
} else {
|
||||
nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
|
||||
|
||||
if (type == DRM_MODE_CONNECTOR_VGA &&
|
||||
dev_priv->card_type >= NV_50) {
|
||||
drm_connector_attach_property(connector,
|
||||
dev->mode_config.scaling_mode_property,
|
||||
nv_connector->scaling_mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* attach encoders */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||
|
||||
if (nv_encoder->dcb->connector != index)
|
||||
if (nv_encoder->dcb->connector != dcb->index)
|
||||
continue;
|
||||
|
||||
if (get_slave_funcs(nv_encoder))
|
||||
@@ -832,9 +824,52 @@ nouveau_connector_create(struct drm_device *dev, int index, int type)
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
}
|
||||
|
||||
if (!connector->encoder_ids[0]) {
|
||||
NV_WARN(dev, " no encoders, ignoring\n");
|
||||
drm_connector_cleanup(connector);
|
||||
kfree(connector);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Init DVI-I specific properties */
|
||||
if (dcb->type == DCB_CONNECTOR_DVI_I) {
|
||||
drm_mode_create_dvi_i_properties(dev);
|
||||
drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0);
|
||||
drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
|
||||
}
|
||||
|
||||
if (dcb->type != DCB_CONNECTOR_LVDS)
|
||||
nv_connector->use_dithering = false;
|
||||
|
||||
switch (dcb->type) {
|
||||
case DCB_CONNECTOR_VGA:
|
||||
if (dev_priv->card_type >= NV_50) {
|
||||
drm_connector_attach_property(connector,
|
||||
dev->mode_config.scaling_mode_property,
|
||||
nv_connector->scaling_mode);
|
||||
}
|
||||
/* fall-through */
|
||||
case DCB_CONNECTOR_TV_0:
|
||||
case DCB_CONNECTOR_TV_1:
|
||||
case DCB_CONNECTOR_TV_3:
|
||||
nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
|
||||
break;
|
||||
default:
|
||||
nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
|
||||
|
||||
drm_connector_attach_property(connector,
|
||||
dev->mode_config.scaling_mode_property,
|
||||
nv_connector->scaling_mode);
|
||||
drm_connector_attach_property(connector,
|
||||
dev->mode_config.dithering_mode_property,
|
||||
nv_connector->use_dithering ?
|
||||
DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF);
|
||||
break;
|
||||
}
|
||||
|
||||
drm_sysfs_connector_add(connector);
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
|
||||
if (dcb->type == DCB_CONNECTOR_LVDS) {
|
||||
ret = nouveau_connector_create_lvds(dev, connector);
|
||||
if (ret) {
|
||||
connector->funcs->destroy(connector);
|
||||
|
||||
@@ -49,6 +49,7 @@ static inline struct nouveau_connector *nouveau_connector(
|
||||
return container_of(con, struct nouveau_connector, base);
|
||||
}
|
||||
|
||||
int nouveau_connector_create(struct drm_device *dev, int i2c_index, int type);
|
||||
int nouveau_connector_create(struct drm_device *,
|
||||
struct dcb_connector_table_entry *);
|
||||
|
||||
#endif /* __NOUVEAU_CONNECTOR_H__ */
|
||||
|
||||
@@ -47,12 +47,23 @@ nouveau_debugfs_channel_info(struct seq_file *m, void *data)
|
||||
seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2);
|
||||
seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2);
|
||||
seq_printf(m, " free: 0x%08x\n", chan->dma.free << 2);
|
||||
if (chan->dma.ib_max) {
|
||||
seq_printf(m, " ib max: 0x%08x\n", chan->dma.ib_max);
|
||||
seq_printf(m, " ib put: 0x%08x\n", chan->dma.ib_put);
|
||||
seq_printf(m, " ib free: 0x%08x\n", chan->dma.ib_free);
|
||||
}
|
||||
|
||||
seq_printf(m, "gpu fifo state:\n");
|
||||
seq_printf(m, " get: 0x%08x\n",
|
||||
nvchan_rd32(chan, chan->user_get));
|
||||
seq_printf(m, " put: 0x%08x\n",
|
||||
nvchan_rd32(chan, chan->user_put));
|
||||
if (chan->dma.ib_max) {
|
||||
seq_printf(m, " ib get: 0x%08x\n",
|
||||
nvchan_rd32(chan, 0x88));
|
||||
seq_printf(m, " ib put: 0x%08x\n",
|
||||
nvchan_rd32(chan, 0x8c));
|
||||
}
|
||||
|
||||
seq_printf(m, "last fence : %d\n", chan->fence.sequence);
|
||||
seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack);
|
||||
@@ -133,9 +144,22 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_debugfs_vbios_image(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dev_priv->vbios.length; i++)
|
||||
seq_printf(m, "%c", dev_priv->vbios.data[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_info_list nouveau_debugfs_list[] = {
|
||||
{ "chipset", nouveau_debugfs_chipset_info, 0, NULL },
|
||||
{ "memory", nouveau_debugfs_memory_info, 0, NULL },
|
||||
{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
|
||||
};
|
||||
#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
|
||||
|
||||
|
||||
@@ -32,7 +32,22 @@
|
||||
void
|
||||
nouveau_dma_pre_init(struct nouveau_channel *chan)
|
||||
{
|
||||
chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2;
|
||||
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
|
||||
struct nouveau_bo *pushbuf = chan->pushbuf_bo;
|
||||
|
||||
if (dev_priv->card_type == NV_50) {
|
||||
const int ib_size = pushbuf->bo.mem.size / 2;
|
||||
|
||||
chan->dma.ib_base = (pushbuf->bo.mem.size - ib_size) >> 2;
|
||||
chan->dma.ib_max = (ib_size / 8) - 1;
|
||||
chan->dma.ib_put = 0;
|
||||
chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put;
|
||||
|
||||
chan->dma.max = (pushbuf->bo.mem.size - ib_size) >> 2;
|
||||
} else {
|
||||
chan->dma.max = (pushbuf->bo.mem.size >> 2) - 2;
|
||||
}
|
||||
|
||||
chan->dma.put = 0;
|
||||
chan->dma.cur = chan->dma.put;
|
||||
chan->dma.free = chan->dma.max - chan->dma.cur;
|
||||
@@ -162,12 +177,101 @@ READ_GET(struct nouveau_channel *chan, uint32_t *prev_get, uint32_t *timeout)
|
||||
return (val - chan->pushbuf_base) >> 2;
|
||||
}
|
||||
|
||||
void
|
||||
nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
|
||||
int delta, int length)
|
||||
{
|
||||
struct nouveau_bo *pb = chan->pushbuf_bo;
|
||||
uint64_t offset = bo->bo.offset + delta;
|
||||
int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
|
||||
|
||||
BUG_ON(chan->dma.ib_free < 1);
|
||||
nouveau_bo_wr32(pb, ip++, lower_32_bits(offset));
|
||||
nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);
|
||||
|
||||
chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
|
||||
nvchan_wr32(chan, 0x8c, chan->dma.ib_put);
|
||||
chan->dma.ib_free--;
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_dma_push_wait(struct nouveau_channel *chan, int count)
|
||||
{
|
||||
uint32_t cnt = 0, prev_get = 0;
|
||||
|
||||
while (chan->dma.ib_free < count) {
|
||||
uint32_t get = nvchan_rd32(chan, 0x88);
|
||||
if (get != prev_get) {
|
||||
prev_get = get;
|
||||
cnt = 0;
|
||||
}
|
||||
|
||||
if ((++cnt & 0xff) == 0) {
|
||||
DRM_UDELAY(1);
|
||||
if (cnt > 100000)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
chan->dma.ib_free = get - chan->dma.ib_put;
|
||||
if (chan->dma.ib_free <= 0)
|
||||
chan->dma.ib_free += chan->dma.ib_max + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_dma_wait(struct nouveau_channel *chan, int slots, int count)
|
||||
{
|
||||
uint32_t cnt = 0, prev_get = 0;
|
||||
int ret;
|
||||
|
||||
ret = nv50_dma_push_wait(chan, slots + 1);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
while (chan->dma.free < count) {
|
||||
int get = READ_GET(chan, &prev_get, &cnt);
|
||||
if (unlikely(get < 0)) {
|
||||
if (get == -EINVAL)
|
||||
continue;
|
||||
|
||||
return get;
|
||||
}
|
||||
|
||||
if (get <= chan->dma.cur) {
|
||||
chan->dma.free = chan->dma.max - chan->dma.cur;
|
||||
if (chan->dma.free >= count)
|
||||
break;
|
||||
|
||||
FIRE_RING(chan);
|
||||
do {
|
||||
get = READ_GET(chan, &prev_get, &cnt);
|
||||
if (unlikely(get < 0)) {
|
||||
if (get == -EINVAL)
|
||||
continue;
|
||||
return get;
|
||||
}
|
||||
} while (get == 0);
|
||||
chan->dma.cur = 0;
|
||||
chan->dma.put = 0;
|
||||
}
|
||||
|
||||
chan->dma.free = get - chan->dma.cur - 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_dma_wait(struct nouveau_channel *chan, int size)
|
||||
nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size)
|
||||
{
|
||||
uint32_t prev_get = 0, cnt = 0;
|
||||
int get;
|
||||
|
||||
if (chan->dma.ib_max)
|
||||
return nv50_dma_wait(chan, slots, size);
|
||||
|
||||
while (chan->dma.free < size) {
|
||||
get = READ_GET(chan, &prev_get, &cnt);
|
||||
if (unlikely(get == -EBUSY))
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#define NOUVEAU_DMA_DEBUG 0
|
||||
#endif
|
||||
|
||||
void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
|
||||
int delta, int length);
|
||||
|
||||
/*
|
||||
* There's a hw race condition where you can't jump to your PUT offset,
|
||||
* to avoid this we jump to offset + SKIPS and fill the difference with
|
||||
@@ -96,13 +99,11 @@ enum {
|
||||
static __must_check inline int
|
||||
RING_SPACE(struct nouveau_channel *chan, int size)
|
||||
{
|
||||
if (chan->dma.free < size) {
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_dma_wait(chan, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
ret = nouveau_dma_wait(chan, 1, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
chan->dma.free -= size;
|
||||
return 0;
|
||||
@@ -146,7 +147,13 @@ FIRE_RING(struct nouveau_channel *chan)
|
||||
return;
|
||||
chan->accel_done = true;
|
||||
|
||||
WRITE_PUT(chan->dma.cur);
|
||||
if (chan->dma.ib_max) {
|
||||
nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2,
|
||||
(chan->dma.cur - chan->dma.put) << 2);
|
||||
} else {
|
||||
WRITE_PUT(chan->dma.cur);
|
||||
}
|
||||
|
||||
chan->dma.put = chan->dma.cur;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,11 +75,11 @@ MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status");
|
||||
int nouveau_ignorelid = 0;
|
||||
module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
|
||||
|
||||
MODULE_PARM_DESC(noagp, "Disable all acceleration");
|
||||
MODULE_PARM_DESC(noaccel, "Disable all acceleration");
|
||||
int nouveau_noaccel = 0;
|
||||
module_param_named(noaccel, nouveau_noaccel, int, 0400);
|
||||
|
||||
MODULE_PARM_DESC(noagp, "Disable fbcon acceleration");
|
||||
MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
|
||||
int nouveau_nofbaccel = 0;
|
||||
module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#define DRIVER_MAJOR 0
|
||||
#define DRIVER_MINOR 0
|
||||
#define DRIVER_PATCHLEVEL 15
|
||||
#define DRIVER_PATCHLEVEL 16
|
||||
|
||||
#define NOUVEAU_FAMILY 0x0000FFFF
|
||||
#define NOUVEAU_FLAGS 0xFFFF0000
|
||||
@@ -83,6 +83,7 @@ struct nouveau_bo {
|
||||
struct drm_file *reserved_by;
|
||||
struct list_head entry;
|
||||
int pbbo_index;
|
||||
bool validate_mapped;
|
||||
|
||||
struct nouveau_channel *channel;
|
||||
|
||||
@@ -239,6 +240,11 @@ struct nouveau_channel {
|
||||
int cur;
|
||||
int put;
|
||||
/* access via pushbuf_bo */
|
||||
|
||||
int ib_base;
|
||||
int ib_max;
|
||||
int ib_free;
|
||||
int ib_put;
|
||||
} dma;
|
||||
|
||||
uint32_t sw_subchannel[8];
|
||||
@@ -533,6 +539,9 @@ struct drm_nouveau_private {
|
||||
struct nouveau_engine engine;
|
||||
struct nouveau_channel *channel;
|
||||
|
||||
/* For PFIFO and PGRAPH. */
|
||||
spinlock_t context_switch_lock;
|
||||
|
||||
/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
|
||||
struct nouveau_gpuobj *ramht;
|
||||
uint32_t ramin_rsvd_vram;
|
||||
@@ -596,8 +605,7 @@ struct drm_nouveau_private {
|
||||
|
||||
struct list_head gpuobj_list;
|
||||
|
||||
struct nvbios VBIOS;
|
||||
struct nouveau_bios_info *vbios;
|
||||
struct nvbios vbios;
|
||||
|
||||
struct nv04_mode_state mode_reg;
|
||||
struct nv04_mode_state saved_reg;
|
||||
@@ -696,12 +704,6 @@ extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout,
|
||||
uint32_t reg, uint32_t mask, uint32_t val);
|
||||
extern bool nouveau_wait_for_idle(struct drm_device *);
|
||||
extern int nouveau_card_init(struct drm_device *);
|
||||
extern int nouveau_ioctl_card_init(struct drm_device *, void *data,
|
||||
struct drm_file *);
|
||||
extern int nouveau_ioctl_suspend(struct drm_device *, void *data,
|
||||
struct drm_file *);
|
||||
extern int nouveau_ioctl_resume(struct drm_device *, void *data,
|
||||
struct drm_file *);
|
||||
|
||||
/* nouveau_mem.c */
|
||||
extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start,
|
||||
@@ -845,7 +847,7 @@ nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
|
||||
/* nouveau_dma.c */
|
||||
extern void nouveau_dma_pre_init(struct nouveau_channel *);
|
||||
extern int nouveau_dma_init(struct nouveau_channel *);
|
||||
extern int nouveau_dma_wait(struct nouveau_channel *, int size);
|
||||
extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
|
||||
|
||||
/* nouveau_acpi.c */
|
||||
#ifdef CONFIG_ACPI
|
||||
@@ -1027,6 +1029,7 @@ extern void nv50_graph_destroy_context(struct nouveau_channel *);
|
||||
extern int nv50_graph_load_context(struct nouveau_channel *);
|
||||
extern int nv50_graph_unload_context(struct drm_device *);
|
||||
extern void nv50_graph_context_switch(struct drm_device *);
|
||||
extern int nv50_grctx_init(struct nouveau_grctx *);
|
||||
|
||||
/* nouveau_grctx.c */
|
||||
extern int nouveau_grctx_prog_load(struct drm_device *);
|
||||
@@ -1152,16 +1155,6 @@ extern int nouveau_gem_ioctl_new(struct drm_device *, void *,
|
||||
struct drm_file *);
|
||||
extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *,
|
||||
struct drm_file *);
|
||||
extern int nouveau_gem_ioctl_pushbuf_call(struct drm_device *, void *,
|
||||
struct drm_file *);
|
||||
extern int nouveau_gem_ioctl_pushbuf_call2(struct drm_device *, void *,
|
||||
struct drm_file *);
|
||||
extern int nouveau_gem_ioctl_pin(struct drm_device *, void *,
|
||||
struct drm_file *);
|
||||
extern int nouveau_gem_ioctl_unpin(struct drm_device *, void *,
|
||||
struct drm_file *);
|
||||
extern int nouveau_gem_ioctl_tile(struct drm_device *, void *,
|
||||
struct drm_file *);
|
||||
extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *,
|
||||
struct drm_file *);
|
||||
extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -160,7 +160,7 @@ static void
|
||||
setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
int chip_version = dev_priv->vbios->chip_version;
|
||||
int chip_version = dev_priv->vbios.chip_version;
|
||||
uint32_t oldpll = NVReadRAMDAC(dev, 0, reg);
|
||||
int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
|
||||
uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
|
||||
@@ -216,7 +216,7 @@ setPLL_double_highregs(struct drm_device *dev, uint32_t reg1,
|
||||
struct nouveau_pll_vals *pv)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
int chip_version = dev_priv->vbios->chip_version;
|
||||
int chip_version = dev_priv->vbios.chip_version;
|
||||
bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
|
||||
uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70);
|
||||
uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1);
|
||||
@@ -374,7 +374,7 @@ nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1,
|
||||
struct nouveau_pll_vals *pv)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
int cv = dev_priv->vbios->chip_version;
|
||||
int cv = dev_priv->vbios.chip_version;
|
||||
|
||||
if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
|
||||
cv >= 0x40) {
|
||||
|
||||
@@ -254,16 +254,16 @@ struct nouveau_i2c_chan *
|
||||
nouveau_i2c_find(struct drm_device *dev, int index)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nvbios *bios = &dev_priv->VBIOS;
|
||||
struct nvbios *bios = &dev_priv->vbios;
|
||||
|
||||
if (index > DCB_MAX_NUM_I2C_ENTRIES)
|
||||
if (index >= DCB_MAX_NUM_I2C_ENTRIES)
|
||||
return NULL;
|
||||
|
||||
if (!bios->bdcb.dcb.i2c[index].chan) {
|
||||
if (nouveau_i2c_init(dev, &bios->bdcb.dcb.i2c[index], index))
|
||||
if (!bios->dcb.i2c[index].chan) {
|
||||
if (nouveau_i2c_init(dev, &bios->dcb.i2c[index], index))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bios->bdcb.dcb.i2c[index].chan;
|
||||
return bios->dcb.i2c[index].chan;
|
||||
}
|
||||
|
||||
|
||||
@@ -691,11 +691,14 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
|
||||
struct drm_device *dev = (struct drm_device *)arg;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
uint32_t status, fbdev_flags = 0;
|
||||
unsigned long flags;
|
||||
|
||||
status = nv_rd32(dev, NV03_PMC_INTR_0);
|
||||
if (!status)
|
||||
return IRQ_NONE;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
|
||||
|
||||
if (dev_priv->fbdev_info) {
|
||||
fbdev_flags = dev_priv->fbdev_info->flags;
|
||||
dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
|
||||
@@ -733,5 +736,7 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
|
||||
if (dev_priv->fbdev_info)
|
||||
dev_priv->fbdev_info->flags = fbdev_flags;
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -391,6 +391,7 @@ nouveau_card_init(struct drm_device *dev)
|
||||
goto out;
|
||||
engine = &dev_priv->engine;
|
||||
dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
|
||||
spin_lock_init(&dev_priv->context_switch_lock);
|
||||
|
||||
/* Parse BIOS tables / Run init tables if card not POSTed */
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
@@ -776,13 +777,6 @@ int nouveau_unload(struct drm_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_ioctl_card_init(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return nouveau_card_init(dev);
|
||||
}
|
||||
|
||||
int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
|
||||
@@ -230,13 +230,13 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
|
||||
if (dcb->type == OUTPUT_TV) {
|
||||
testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0);
|
||||
|
||||
if (dev_priv->vbios->tvdactestval)
|
||||
testval = dev_priv->vbios->tvdactestval;
|
||||
if (dev_priv->vbios.tvdactestval)
|
||||
testval = dev_priv->vbios.tvdactestval;
|
||||
} else {
|
||||
testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
|
||||
|
||||
if (dev_priv->vbios->dactestval)
|
||||
testval = dev_priv->vbios->dactestval;
|
||||
if (dev_priv->vbios.dactestval)
|
||||
testval = dev_priv->vbios.dactestval;
|
||||
}
|
||||
|
||||
saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
|
||||
|
||||
@@ -269,10 +269,10 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
|
||||
regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
|
||||
if (!nv_gf4_disp_arch(dev) ||
|
||||
(output_mode->hsync_start - output_mode->hdisplay) >=
|
||||
dev_priv->vbios->digital_min_front_porch)
|
||||
dev_priv->vbios.digital_min_front_porch)
|
||||
regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay;
|
||||
else
|
||||
regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios->digital_min_front_porch - 1;
|
||||
regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios.digital_min_front_porch - 1;
|
||||
regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1;
|
||||
regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
|
||||
regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew;
|
||||
|
||||
@@ -93,10 +93,9 @@ int
|
||||
nv04_display_create(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct parsed_dcb *dcb = dev_priv->vbios->dcb;
|
||||
struct dcb_table *dcb = &dev_priv->vbios.dcb;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_crtc *crtc;
|
||||
uint16_t connector[16] = { 0 };
|
||||
int i, ret;
|
||||
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
@@ -154,52 +153,10 @@ nv04_display_create(struct drm_device *dev)
|
||||
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
connector[dcbent->connector] |= (1 << dcbent->type);
|
||||
}
|
||||
|
||||
for (i = 0; i < dcb->entries; i++) {
|
||||
struct dcb_entry *dcbent = &dcb->entry[i];
|
||||
uint16_t encoders;
|
||||
int type;
|
||||
|
||||
encoders = connector[dcbent->connector];
|
||||
if (!(encoders & (1 << dcbent->type)))
|
||||
continue;
|
||||
connector[dcbent->connector] = 0;
|
||||
|
||||
switch (dcbent->type) {
|
||||
case OUTPUT_ANALOG:
|
||||
if (!MULTIPLE_ENCODERS(encoders))
|
||||
type = DRM_MODE_CONNECTOR_VGA;
|
||||
else
|
||||
type = DRM_MODE_CONNECTOR_DVII;
|
||||
break;
|
||||
case OUTPUT_TMDS:
|
||||
if (!MULTIPLE_ENCODERS(encoders))
|
||||
type = DRM_MODE_CONNECTOR_DVID;
|
||||
else
|
||||
type = DRM_MODE_CONNECTOR_DVII;
|
||||
break;
|
||||
case OUTPUT_LVDS:
|
||||
type = DRM_MODE_CONNECTOR_LVDS;
|
||||
#if 0
|
||||
/* don't create i2c adapter when lvds ddc not allowed */
|
||||
if (dcbent->lvdsconf.use_straps_for_mode ||
|
||||
dev_priv->vbios->fp_no_ddc)
|
||||
i2c_index = 0xf;
|
||||
#endif
|
||||
break;
|
||||
case OUTPUT_TV:
|
||||
type = DRM_MODE_CONNECTOR_TV;
|
||||
break;
|
||||
default:
|
||||
type = DRM_MODE_CONNECTOR_Unknown;
|
||||
continue;
|
||||
}
|
||||
|
||||
nouveau_connector_create(dev, dcbent->connector, type);
|
||||
}
|
||||
for (i = 0; i < dcb->connector.entries; i++)
|
||||
nouveau_connector_create(dev, &dcb->connector.entry[i]);
|
||||
|
||||
/* Save previous state */
|
||||
NVLockVgaCrtcs(dev, false);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user