Commit d6486813 authored by Dave Airlie's avatar Dave Airlie

Merge remote branch 'nouveau/for-airlied' of ../drm-nouveau-next into drm-core-next

* 'nouveau/for-airlied' of ../drm-nouveau-next: (77 commits)
  drm/nouveau: set TASK_(UN)INTERRUPTIBLE before schedule_timeout()
  drm/nv50: fix some not-error error messages
  drm/nouveau: introduce gpio engine
  drm/nv50: correct wait condition for instmem flush
  drm/nouveau: Fix TV-out detection on unposted cards lacking a usable DCB table.
  drm/nouveau: Get rid of the remaining VGA CRTC locking.
  drm/nouveau: Move display init to a new nouveau_engine.
  drm/nouveau: Put back the old 2-messages I2C slave test.
  drm/nouveau: Reset AGP before running the init scripts.
  drm/nv30: Init the PFB+0x3xx memory timing regs.
  drm/nouveau: disable hotplug detect around DP link training
  drm/nv50: add function to control GPIO IRQ reporting
  drm/nouveau: add nv_mask register accessor
  drm/nouveau: fix build without CONFIG_ACPI
  drm/nouveau: Reset CRTC owner to 0 before BIOS init.
  drm/nouveau: No need to lock/unlock the VGA CRTC regs all the time.
  drm/nouveau: Remove useless CRTC_OWNER logging.
  drm/nouveau: Add some generic I2C gadget detection code.
  drm/i2c/ch7006: Don't assume that the specified config points to static memory.
  drm/nv04-nv3x: Implement init-compute-mem.
  ...

Conflicts:
	drivers/gpu/drm/nouveau/nouveau_bios.c
parents 78276271 05991110
...@@ -33,7 +33,7 @@ static void ch7006_encoder_set_config(struct drm_encoder *encoder, ...@@ -33,7 +33,7 @@ static void ch7006_encoder_set_config(struct drm_encoder *encoder,
{ {
struct ch7006_priv *priv = to_ch7006_priv(encoder); struct ch7006_priv *priv = to_ch7006_priv(encoder);
priv->params = params; priv->params = *(struct ch7006_encoder_params *)params;
} }
static void ch7006_encoder_destroy(struct drm_encoder *encoder) static void ch7006_encoder_destroy(struct drm_encoder *encoder)
...@@ -114,7 +114,7 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder, ...@@ -114,7 +114,7 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder,
{ {
struct i2c_client *client = drm_i2c_encoder_get_client(encoder); struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
struct ch7006_priv *priv = to_ch7006_priv(encoder); struct ch7006_priv *priv = to_ch7006_priv(encoder);
struct ch7006_encoder_params *params = priv->params; struct ch7006_encoder_params *params = &priv->params;
struct ch7006_state *state = &priv->state; struct ch7006_state *state = &priv->state;
uint8_t *regs = state->regs; uint8_t *regs = state->regs;
struct ch7006_mode *mode = priv->mode; struct ch7006_mode *mode = priv->mode;
...@@ -428,6 +428,22 @@ static int ch7006_remove(struct i2c_client *client) ...@@ -428,6 +428,22 @@ static int ch7006_remove(struct i2c_client *client)
return 0; return 0;
} }
static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg)
{
ch7006_dbg(client, "\n");
return 0;
}
static int ch7006_resume(struct i2c_client *client)
{
ch7006_dbg(client, "\n");
ch7006_write(client, 0x3d, 0x0);
return 0;
}
static int ch7006_encoder_init(struct i2c_client *client, static int ch7006_encoder_init(struct i2c_client *client,
struct drm_device *dev, struct drm_device *dev,
struct drm_encoder_slave *encoder) struct drm_encoder_slave *encoder)
...@@ -487,6 +503,8 @@ static struct drm_i2c_encoder_driver ch7006_driver = { ...@@ -487,6 +503,8 @@ static struct drm_i2c_encoder_driver ch7006_driver = {
.i2c_driver = { .i2c_driver = {
.probe = ch7006_probe, .probe = ch7006_probe,
.remove = ch7006_remove, .remove = ch7006_remove,
.suspend = ch7006_suspend,
.resume = ch7006_resume,
.driver = { .driver = {
.name = "ch7006", .name = "ch7006",
......
...@@ -77,7 +77,7 @@ struct ch7006_state { ...@@ -77,7 +77,7 @@ struct ch7006_state {
}; };
struct ch7006_priv { struct ch7006_priv {
struct ch7006_encoder_params *params; struct ch7006_encoder_params params;
struct ch7006_mode *mode; struct ch7006_mode *mode;
struct ch7006_state state; struct ch7006_state state;
......
...@@ -9,10 +9,10 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ ...@@ -9,10 +9,10 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
nouveau_dp.o nouveau_grctx.o \ nouveau_dp.o \
nv04_timer.o \ nv04_timer.o \
nv04_mc.o nv40_mc.o nv50_mc.o \ nv04_mc.o nv40_mc.o nv50_mc.o \
nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \ nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o \
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
nv04_graph.o nv10_graph.o nv20_graph.o \ nv04_graph.o nv10_graph.o nv20_graph.o \
nv40_graph.o nv50_graph.o \ nv40_graph.o nv50_graph.o \
...@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ ...@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nv50_cursor.o nv50_display.o nv50_fbcon.o \ nv50_cursor.o nv50_display.o nv50_fbcon.o \
nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
nv17_gpio.o nv50_gpio.o \ nv10_gpio.o nv50_gpio.o \
nv50_calc.o nv50_calc.o
nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/video.h>
#include "drmP.h" #include "drmP.h"
#include "drm.h" #include "drm.h"
...@@ -11,6 +12,7 @@ ...@@ -11,6 +12,7 @@
#include "nouveau_drv.h" #include "nouveau_drv.h"
#include "nouveau_drm.h" #include "nouveau_drm.h"
#include "nv50_display.h" #include "nv50_display.h"
#include "nouveau_connector.h"
#include <linux/vga_switcheroo.h> #include <linux/vga_switcheroo.h>
...@@ -42,7 +44,7 @@ static const char nouveau_dsm_muid[] = { ...@@ -42,7 +44,7 @@ static const char nouveau_dsm_muid[] = {
0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
}; };
static int nouveau_dsm(acpi_handle handle, int func, int arg, int *result) static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
{ {
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_object_list input; struct acpi_object_list input;
...@@ -259,3 +261,37 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) ...@@ -259,3 +261,37 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
{ {
return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
} }
int
nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
{
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct acpi_device *acpidev;
acpi_handle handle;
int type, ret;
void *edid;
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_LVDS:
case DRM_MODE_CONNECTOR_eDP:
type = ACPI_VIDEO_DISPLAY_LCD;
break;
default:
return -EINVAL;
}
handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
if (!handle)
return -ENODEV;
ret = acpi_bus_get_device(handle, &acpidev);
if (ret)
return -ENODEV;
ret = acpi_video_get_edid(acpidev, type, -1, &edid);
if (ret < 0)
return ret;
nv_connector->edid = edid;
return 0;
}
This diff is collapsed.
...@@ -81,6 +81,7 @@ struct dcb_connector_table_entry { ...@@ -81,6 +81,7 @@ struct dcb_connector_table_entry {
enum dcb_connector_type type; enum dcb_connector_type type;
uint8_t index2; uint8_t index2;
uint8_t gpio_tag; uint8_t gpio_tag;
void *drm;
}; };
struct dcb_connector_table { struct dcb_connector_table {
...@@ -117,6 +118,7 @@ struct dcb_entry { ...@@ -117,6 +118,7 @@ struct dcb_entry {
struct { struct {
struct sor_conf sor; struct sor_conf sor;
bool use_straps_for_mode; bool use_straps_for_mode;
bool use_acpi_for_edid;
bool use_power_scripts; bool use_power_scripts;
} lvdsconf; } lvdsconf;
struct { struct {
...@@ -249,8 +251,6 @@ struct nvbios { ...@@ -249,8 +251,6 @@ struct nvbios {
struct { struct {
int crtchead; int crtchead;
/* these need remembering across suspend */
uint32_t saved_nv_pfb_cfg0;
} state; } state;
struct { struct {
......
...@@ -461,9 +461,9 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, ...@@ -461,9 +461,9 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
return ret; return ret;
ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL,
evict, no_wait_reserve, no_wait_gpu, new_mem); evict || (nvbo->channel &&
if (nvbo->channel && nvbo->channel != chan) nvbo->channel != chan),
ret = nouveau_fence_wait(fence, NULL, false, false); no_wait_reserve, no_wait_gpu, new_mem);
nouveau_fence_unref((void *)&fence); nouveau_fence_unref((void *)&fence);
return ret; return ret;
} }
...@@ -711,8 +711,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, ...@@ -711,8 +711,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
return ret; return ret;
/* Software copy if the card isn't up and running yet. */ /* Software copy if the card isn't up and running yet. */
if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || if (!dev_priv->channel) {
!dev_priv->channel) {
ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
goto out; goto out;
} }
......
...@@ -200,7 +200,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, ...@@ -200,7 +200,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
struct nv_sim_state sim_data; struct nv_sim_state sim_data;
int MClk = nouveau_hw_get_clock(dev, MPLL); int MClk = nouveau_hw_get_clock(dev, MPLL);
int NVClk = nouveau_hw_get_clock(dev, NVPLL); int NVClk = nouveau_hw_get_clock(dev, NVPLL);
uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1); uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1);
sim_data.pclk_khz = VClk; sim_data.pclk_khz = VClk;
sim_data.mclk_khz = MClk; sim_data.mclk_khz = MClk;
...@@ -218,7 +218,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, ...@@ -218,7 +218,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
sim_data.mem_latency = 3; sim_data.mem_latency = 3;
sim_data.mem_page_miss = 10; sim_data.mem_page_miss = 10;
} else { } else {
sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1; sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1;
sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
sim_data.mem_latency = cfg1 & 0xf; sim_data.mem_latency = cfg1 & 0xf;
sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1); sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
......
...@@ -258,9 +258,7 @@ nouveau_channel_free(struct nouveau_channel *chan) ...@@ -258,9 +258,7 @@ nouveau_channel_free(struct nouveau_channel *chan)
nouveau_debugfs_channel_fini(chan); nouveau_debugfs_channel_fini(chan);
/* Give outstanding push buffers a chance to complete */ /* Give outstanding push buffers a chance to complete */
spin_lock_irqsave(&chan->fence.lock, flags);
nouveau_fence_update(chan); nouveau_fence_update(chan);
spin_unlock_irqrestore(&chan->fence.lock, flags);
if (chan->fence.sequence != chan->fence.sequence_ack) { if (chan->fence.sequence != chan->fence.sequence_ack) {
struct nouveau_fence *fence = NULL; struct nouveau_fence *fence = NULL;
...@@ -369,8 +367,6 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, ...@@ -369,8 +367,6 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
struct nouveau_channel *chan; struct nouveau_channel *chan;
int ret; int ret;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
if (dev_priv->engine.graph.accel_blocked) if (dev_priv->engine.graph.accel_blocked)
return -ENODEV; return -ENODEV;
...@@ -419,7 +415,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, ...@@ -419,7 +415,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
struct drm_nouveau_channel_free *cfree = data; struct drm_nouveau_channel_free *cfree = data;
struct nouveau_channel *chan; struct nouveau_channel *chan;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan);
nouveau_channel_free(chan); nouveau_channel_free(chan);
......
This diff is collapsed.
...@@ -49,7 +49,10 @@ static inline struct nouveau_connector *nouveau_connector( ...@@ -49,7 +49,10 @@ static inline struct nouveau_connector *nouveau_connector(
return container_of(con, struct nouveau_connector, base); return container_of(con, struct nouveau_connector, base);
} }
int nouveau_connector_create(struct drm_device *, struct drm_connector *
struct dcb_connector_table_entry *); nouveau_connector_create(struct drm_device *, int index);
void
nouveau_connector_set_polling(struct drm_connector *);
#endif /* __NOUVEAU_CONNECTOR_H__ */ #endif /* __NOUVEAU_CONNECTOR_H__ */
...@@ -92,11 +92,9 @@ nouveau_dma_init(struct nouveau_channel *chan) ...@@ -92,11 +92,9 @@ nouveau_dma_init(struct nouveau_channel *chan)
return ret; return ret;
/* Map M2MF notifier object - fbcon. */ /* Map M2MF notifier object - fbcon. */
if (drm_core_check_feature(dev, DRIVER_MODESET)) { ret = nouveau_bo_map(chan->notifier_bo);
ret = nouveau_bo_map(chan->notifier_bo); if (ret)
if (ret) return ret;
return ret;
}
/* Insert NOPS for NOUVEAU_DMA_SKIPS */ /* Insert NOPS for NOUVEAU_DMA_SKIPS */
ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
......
...@@ -23,8 +23,10 @@ ...@@ -23,8 +23,10 @@
*/ */
#include "drmP.h" #include "drmP.h"
#include "nouveau_drv.h" #include "nouveau_drv.h"
#include "nouveau_i2c.h" #include "nouveau_i2c.h"
#include "nouveau_connector.h"
#include "nouveau_encoder.h" #include "nouveau_encoder.h"
static int static int
...@@ -270,13 +272,39 @@ bool ...@@ -270,13 +272,39 @@ bool
nouveau_dp_link_train(struct drm_encoder *encoder) nouveau_dp_link_train(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
uint8_t config[4]; struct nouveau_connector *nv_connector;
uint8_t status[3]; struct bit_displayport_encoder_table *dpe;
int dpe_headerlen;
uint8_t config[4], status[3];
bool cr_done, cr_max_vs, eq_done; bool cr_done, cr_max_vs, eq_done;
int ret = 0, i, tries, voltage; int ret = 0, i, tries, voltage;
NV_DEBUG_KMS(dev, "link training!!\n"); NV_DEBUG_KMS(dev, "link training!!\n");
nv_connector = nouveau_encoder_connector_get(nv_encoder);
if (!nv_connector)
return false;
dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
if (!dpe) {
NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or);
return false;
}
/* disable hotplug detect, this flips around on some panels during
* link training.
*/
pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false);
if (dpe->script0) {
NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
nv_encoder->dcb);
}
train: train:
cr_done = eq_done = false; cr_done = eq_done = false;
...@@ -403,6 +431,15 @@ nouveau_dp_link_train(struct drm_encoder *encoder) ...@@ -403,6 +431,15 @@ nouveau_dp_link_train(struct drm_encoder *encoder)
} }
} }
if (dpe->script1) {
NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
nv_encoder->dcb);
}
/* re-enable hotplug detect */
pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true);
return eq_done; return eq_done;
} }
......
...@@ -35,10 +35,6 @@ ...@@ -35,10 +35,6 @@
#include "drm_pciids.h" #include "drm_pciids.h"
MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)");
int nouveau_ctxfw = 0;
module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
MODULE_PARM_DESC(noagp, "Disable AGP"); MODULE_PARM_DESC(noagp, "Disable AGP");
int nouveau_noagp; int nouveau_noagp;
module_param_named(noagp, nouveau_noagp, int, 0400); module_param_named(noagp, nouveau_noagp, int, 0400);
...@@ -56,7 +52,7 @@ int nouveau_vram_pushbuf; ...@@ -56,7 +52,7 @@ int nouveau_vram_pushbuf;
module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM");
int nouveau_vram_notify = 1; int nouveau_vram_notify = 0;
module_param_named(vram_notify, nouveau_vram_notify, int, 0400); module_param_named(vram_notify, nouveau_vram_notify, int, 0400);
MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)");
...@@ -155,9 +151,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) ...@@ -155,9 +151,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
struct drm_crtc *crtc; struct drm_crtc *crtc;
int ret, i; int ret, i;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -ENODEV;
if (pm_state.event == PM_EVENT_PRETHAW) if (pm_state.event == PM_EVENT_PRETHAW)
return 0; return 0;
...@@ -257,9 +250,6 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -257,9 +250,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
struct drm_crtc *crtc; struct drm_crtc *crtc;
int ret, i; int ret, i;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -ENODEV;
nouveau_fbcon_save_disable_accel(dev); nouveau_fbcon_save_disable_accel(dev);
NV_INFO(dev, "We're back, enabling device...\n"); NV_INFO(dev, "We're back, enabling device...\n");
...@@ -269,6 +259,13 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -269,6 +259,13 @@ nouveau_pci_resume(struct pci_dev *pdev)
return -1; return -1;
pci_set_master(dev->pdev); pci_set_master(dev->pdev);
/* Make sure the AGP controller is in a consistent state */
if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
nouveau_mem_reset_agp(dev);
/* Make the CRTCs accessible */
engine->display.early_init(dev);
NV_INFO(dev, "POSTing device...\n"); NV_INFO(dev, "POSTing device...\n");
ret = nouveau_run_vbios_init(dev); ret = nouveau_run_vbios_init(dev);
if (ret) if (ret)
...@@ -323,7 +320,6 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -323,7 +320,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
int ret;
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
if (!ret) if (!ret)
...@@ -332,11 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -332,11 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
NV_ERROR(dev, "Could not pin/map cursor.\n"); NV_ERROR(dev, "Could not pin/map cursor.\n");
} }
if (dev_priv->card_type < NV_50) { engine->display.init(dev);
nv04_display_restore(dev);
NVLockVgaCrtcs(dev, false);
} else
nv50_display_init(dev);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
...@@ -371,7 +363,8 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -371,7 +363,8 @@ nouveau_pci_resume(struct pci_dev *pdev)
static struct drm_driver driver = { static struct drm_driver driver = {
.driver_features = .driver_features =
DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
DRIVER_MODESET,
.load = nouveau_load, .load = nouveau_load,
.firstopen = nouveau_firstopen, .firstopen = nouveau_firstopen,
.lastclose = nouveau_lastclose, .lastclose = nouveau_lastclose,
...@@ -438,16 +431,18 @@ static int __init nouveau_init(void) ...@@ -438,16 +431,18 @@ static int __init nouveau_init(void)
nouveau_modeset = 1; nouveau_modeset = 1;
} }
if (nouveau_modeset == 1) { if (!nouveau_modeset)
driver.driver_features |= DRIVER_MODESET; return 0;
nouveau_register_dsm_handler();
}
nouveau_register_dsm_handler();
return drm_init(&driver); return drm_init(&driver);
} }
static void __exit nouveau_exit(void) static void __exit nouveau_exit(void)
{ {
if (!nouveau_modeset)
return;
drm_exit(&driver); drm_exit(&driver);
nouveau_unregister_dsm_handler(); nouveau_unregister_dsm_handler();
} }
......
This diff is collapsed.
...@@ -38,13 +38,15 @@ struct nouveau_encoder { ...@@ -38,13 +38,15 @@ struct nouveau_encoder {
struct dcb_entry *dcb; struct dcb_entry *dcb;
int or; int or;
/* different to drm_encoder.crtc, this reflects what's
* actually programmed on the hw, not the proposed crtc */
struct drm_crtc *crtc;
struct drm_display_mode mode; struct drm_display_mode mode;
int last_dpms; int last_dpms;
struct nv04_output_reg restore; struct nv04_output_reg restore;
void (*disconnect)(struct nouveau_encoder *encoder);
union { union {
struct { struct {
int mc_unknown; int mc_unknown;
...@@ -71,8 +73,8 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc) ...@@ -71,8 +73,8 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
struct nouveau_connector * struct nouveau_connector *
nouveau_encoder_connector_get(struct nouveau_encoder *encoder); nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry); int nv50_sor_create(struct drm_connector *, struct dcb_entry *);
int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry); int nv50_dac_create(struct drm_connector *, struct dcb_entry *);
struct bit_displayport_encoder_table { struct bit_displayport_encoder_table {
uint32_t match; uint32_t match;
......
...@@ -333,7 +333,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev) ...@@ -333,7 +333,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev)
drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper); drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper);
} }
int static int
nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev) nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
{ {
struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb; struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb;
......
...@@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan) ...@@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan)
if (USE_REFCNT) if (USE_REFCNT)
sequence = nvchan_rd32(chan, 0x48); sequence = nvchan_rd32(chan, 0x48);
else else
sequence = chan->fence.last_sequence_irq; sequence = atomic_read(&chan->fence.last_sequence_irq);
if (chan->fence.sequence_ack == sequence) if (chan->fence.sequence_ack == sequence)
return; return;
chan->fence.sequence_ack = sequence; chan->fence.sequence_ack = sequence;
spin_lock(&chan->fence.lock);
list_for_each_safe(entry, tmp, &chan->fence.pending) { list_for_each_safe(entry, tmp, &chan->fence.pending) {
fence = list_entry(entry, struct nouveau_fence, entry); fence = list_entry(entry, struct nouveau_fence, entry);
...@@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan) ...@@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
if (sequence == chan->fence.sequence_ack) if (sequence == chan->fence.sequence_ack)
break; break;
} }
spin_unlock(&chan->fence.lock);
} }
int int
...@@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence) ...@@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence)
{ {
struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private; struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private;
struct nouveau_channel *chan = fence->channel; struct nouveau_channel *chan = fence->channel;
unsigned long flags;
int ret; int ret;
ret = RING_SPACE(chan, 2); ret = RING_SPACE(chan, 2);
...@@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) ...@@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
return ret; return ret;
if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) { if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) {
spin_lock_irqsave(&chan->fence.lock, flags);
nouveau_fence_update(chan); nouveau_fence_update(chan);
spin_unlock_irqrestore(&chan->fence.lock, flags);
BUG_ON(chan->fence.sequence == BUG_ON(chan->fence.sequence ==
chan->fence.sequence_ack - 1); chan->fence.sequence_ack - 1);
...@@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence) ...@@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
fence->sequence = ++chan->fence.sequence; fence->sequence = ++chan->fence.sequence;
kref_get(&fence->refcount); kref_get(&fence->refcount);
spin_lock_irqsave(&chan->fence.lock, flags); spin_lock(&chan->fence.lock);
list_add_tail(&fence->entry, &chan->fence.pending); list_add_tail(&fence->entry, &chan->fence.pending);
spin_unlock_irqrestore(&chan->fence.lock, flags); spin_unlock(&chan->fence.lock);
BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1); BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1);
OUT_RING(chan, fence->sequence); OUT_RING(chan, fence->sequence);
...@@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg) ...@@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg)
{ {
struct nouveau_fence *fence = nouveau_fence(sync_obj); struct nouveau_fence *fence = nouveau_fence(sync_obj);
struct nouveau_channel *chan = fence->channel; struct nouveau_channel *chan = fence->channel;
unsigned long flags;
if (fence->signalled) if (fence->signalled)
return true; return true;
spin_lock_irqsave(&chan->fence.lock, flags);
nouveau_fence_update(chan); nouveau_fence_update(chan);
spin_unlock_irqrestore(&chan->fence.lock, flags);
return fence->signalled; return fence->signalled;
} }
...@@ -190,8 +186,6 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) ...@@ -190,8 +186,6 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
unsigned long timeout = jiffies + (3 * DRM_HZ); unsigned long timeout = jiffies + (3 * DRM_HZ);
int ret = 0; int ret = 0;
__set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
while (1) { while (1) {
if (nouveau_fence_signalled(sync_obj, sync_arg)) if (nouveau_fence_signalled(sync_obj, sync_arg))
break; break;
...@@ -201,6 +195,8 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) ...@@ -201,6 +195,8 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
break; break;
} }
__set_current_state(intr ? TASK_INTERRUPTIBLE
: TASK_UNINTERRUPTIBLE);
if (lazy) if (lazy)
schedule_timeout(1); schedule_timeout(1);
...@@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg) ...@@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg)
return 0; return 0;
} }
void
nouveau_fence_handler(struct drm_device *dev, int channel)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_channel *chan = NULL;
if (channel >= 0 && channel < dev_priv->engine.fifo.channels)
chan = dev_priv->fifos[channel];
if (chan) {
spin_lock_irq(&chan->fence.lock);
nouveau_fence_update(chan);
spin_unlock_irq(&chan->fence.lock);
}
}
int int
nouveau_fence_init(struct nouveau_channel *chan) nouveau_fence_init(struct nouveau_channel *chan)
{ {
INIT_LIST_HEAD(&chan->fence.pending); INIT_LIST_HEAD(&chan->fence.pending);
spin_lock_init(&chan->fence.lock); spin_lock_init(&chan->fence.lock);
atomic_set(&chan->fence.last_sequence_irq, 0);
return 0; return 0;
} }
......
...@@ -137,8 +137,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, ...@@ -137,8 +137,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
uint32_t flags = 0; uint32_t flags = 0;
int ret = 0; int ret = 0;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
...@@ -577,10 +575,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, ...@@ -577,10 +575,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
struct drm_nouveau_gem_pushbuf_bo *bo; struct drm_nouveau_gem_pushbuf_bo *bo;
struct nouveau_channel *chan; struct nouveau_channel *chan;
struct validate_op op; struct validate_op op;
struct nouveau_fence *fence = 0; struct nouveau_fence *fence = NULL;
int i, j, ret = 0, do_reloc = 0; int i, j, ret = 0, do_reloc = 0;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
req->vram_available = dev_priv->fb_aper_free; req->vram_available = dev_priv->fb_aper_free;
...@@ -760,8 +757,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, ...@@ -760,8 +757,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT); bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
int ret = -EINVAL; int ret = -EINVAL;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
gem = drm_gem_object_lookup(dev, file_priv, req->handle); gem = drm_gem_object_lookup(dev, file_priv, req->handle);
if (!gem) if (!gem)
return ret; return ret;
...@@ -800,8 +795,6 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, ...@@ -800,8 +795,6 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data,
struct nouveau_bo *nvbo; struct nouveau_bo *nvbo;
int ret = -EINVAL; int ret = -EINVAL;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
gem = drm_gem_object_lookup(dev, file_priv, req->handle); gem = drm_gem_object_lookup(dev, file_priv, req->handle);
if (!gem) if (!gem)
return ret; return ret;
...@@ -827,8 +820,6 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data, ...@@ -827,8 +820,6 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data,
struct drm_gem_object *gem; struct drm_gem_object *gem;
int ret; int ret;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
gem = drm_gem_object_lookup(dev, file_priv, req->handle); gem = drm_gem_object_lookup(dev, file_priv, req->handle);
if (!gem) if (!gem)
return -EINVAL; return -EINVAL;
......
/*
* Copyright 2009 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include <linux/firmware.h>
#include <linux/slab.h>
#include "drmP.h"
#include "nouveau_drv.h"
struct nouveau_ctxprog {
uint32_t signature;
uint8_t version;
uint16_t length;
uint32_t data[];
} __attribute__ ((packed));
struct nouveau_ctxvals {
uint32_t signature;
uint8_t version;
uint32_t length;
struct {
uint32_t offset;
uint32_t value;
} data[];
} __attribute__ ((packed));
int
nouveau_grctx_prog_load(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
const int chipset = dev_priv->chipset;
const struct firmware *fw;
const struct nouveau_ctxprog *cp;
const struct nouveau_ctxvals *cv;
char name[32];
int ret, i;
if (pgraph->accel_blocked)
return -ENODEV;
if (!pgraph->ctxprog) {
sprintf(name, "nouveau/nv%02x.ctxprog", chipset);
ret = request_firmware(&fw, name, &dev->pdev->dev);
if (ret) {
NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
return ret;
}
pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!pgraph->ctxprog) {
NV_ERROR(dev, "OOM copying ctxprog\n");
release_firmware(fw);
return -ENOMEM;
}
cp = pgraph->ctxprog;
if (le32_to_cpu(cp->signature) != 0x5043564e ||
cp->version != 0 ||
le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
NV_ERROR(dev, "ctxprog invalid\n");
release_firmware(fw);
nouveau_grctx_fini(dev);
return -EINVAL;
}
release_firmware(fw);
}
if (!pgraph->ctxvals) {
sprintf(name, "nouveau/nv%02x.ctxvals", chipset);
ret = request_firmware(&fw, name, &dev->pdev->dev);
if (ret) {
NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
nouveau_grctx_fini(dev);
return ret;
}
pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!pgraph->ctxvals) {
NV_ERROR(dev, "OOM copying ctxvals\n");
release_firmware(fw);
nouveau_grctx_fini(dev);
return -ENOMEM;
}
cv = (void *)pgraph->ctxvals;
if (le32_to_cpu(cv->signature) != 0x5643564e ||
cv->version != 0 ||
le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
NV_ERROR(dev, "ctxvals invalid\n");
release_firmware(fw);
nouveau_grctx_fini(dev);
return -EINVAL;
}
release_firmware(fw);
}
cp = pgraph->ctxprog;
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
for (i = 0; i < le16_to_cpu(cp->length); i++)
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
le32_to_cpu(cp->data[i]));
return 0;
}
void
nouveau_grctx_fini(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
if (pgraph->ctxprog) {
kfree(pgraph->ctxprog);
pgraph->ctxprog = NULL;
}
if (pgraph->ctxvals) {
kfree(pgraph->ctxprog);
pgraph->ctxvals = NULL;
}
}
void
nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nouveau_ctxvals *cv = pgraph->ctxvals;
int i;
if (!cv)
return;
for (i = 0; i < le32_to_cpu(cv->length); i++)
nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
le32_to_cpu(cv->data[i].value));
}
...@@ -278,3 +278,45 @@ nouveau_i2c_find(struct drm_device *dev, int index) ...@@ -278,3 +278,45 @@ nouveau_i2c_find(struct drm_device *dev, int index)
return i2c->chan; return i2c->chan;
} }
bool
nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
{
uint8_t buf[] = { 0 };
struct i2c_msg msgs[] = {
{
.addr = addr,
.flags = 0,
.len = 1,
.buf = buf,
},
{
.addr = addr,
.flags = I2C_M_RD,
.len = 1,
.buf = buf,
}
};
return i2c_transfer(&i2c->adapter, msgs, 2) == 2;
}
int
nouveau_i2c_identify(struct drm_device *dev, const char *what,
struct i2c_board_info *info, int index)
{
struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
int i;
NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
for (i = 0; info[i].addr; i++) {
if (nouveau_probe_i2c_addr(i2c, info[i].addr)) {
NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
return i;
}
}
NV_DEBUG(dev, "No devices found.\n");
return -ENODEV;
}
...@@ -45,6 +45,9 @@ struct nouveau_i2c_chan { ...@@ -45,6 +45,9 @@ struct nouveau_i2c_chan {
int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index); int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index);
void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *); void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *);
struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index);
bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr);
int nouveau_i2c_identify(struct drm_device *dev, const char *what,
struct i2c_board_info *info, int index);
int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte, int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte,
uint8_t *read_byte); uint8_t *read_byte);
......
This diff is collapsed.
...@@ -55,7 +55,7 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) ...@@ -55,7 +55,7 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan)
if (ret) if (ret)
goto out_err; goto out_err;
ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size); ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size);
if (ret) if (ret)
goto out_err; goto out_err;
...@@ -80,7 +80,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan) ...@@ -80,7 +80,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
nouveau_bo_unpin(chan->notifier_bo); nouveau_bo_unpin(chan->notifier_bo);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
nouveau_mem_takedown(&chan->notifier_heap); drm_mm_takedown(&chan->notifier_heap);
} }
static void static void
...@@ -90,7 +90,7 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev, ...@@ -90,7 +90,7 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
NV_DEBUG(dev, "\n"); NV_DEBUG(dev, "\n");
if (gpuobj->priv) if (gpuobj->priv)
nouveau_mem_free_block(gpuobj->priv); drm_mm_put_block(gpuobj->priv);
} }
int int
...@@ -100,18 +100,13 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, ...@@ -100,18 +100,13 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *nobj = NULL; struct nouveau_gpuobj *nobj = NULL;
struct mem_block *mem; struct drm_mm_node *mem;
uint32_t offset; uint32_t offset;
int target, ret; int target, ret;
if (!chan->notifier_heap) { mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0);
NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n", if (mem)
chan->id); mem = drm_mm_get_block(mem, size, 0);
return -EINVAL;
}
mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0,
(struct drm_file *)-2, 0);
if (!mem) { if (!mem) {
NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);
return -ENOMEM; return -ENOMEM;
...@@ -144,17 +139,17 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, ...@@ -144,17 +139,17 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
mem->size, NV_DMA_ACCESS_RW, target, mem->size, NV_DMA_ACCESS_RW, target,
&nobj); &nobj);
if (ret) { if (ret) {
nouveau_mem_free_block(mem); drm_mm_put_block(mem);
NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret); NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret);
return ret; return ret;
} }
nobj->dtor = nouveau_notifier_gpuobj_dtor; nobj->dtor = nouveau_notifier_gpuobj_dtor;
nobj->priv = mem; nobj->priv = mem;
ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL); ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL);
if (ret) { if (ret) {
nouveau_gpuobj_del(dev, &nobj); nouveau_gpuobj_del(dev, &nobj);
nouveau_mem_free_block(mem); drm_mm_put_block(mem);
NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret); NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret);
return ret; return ret;
} }
...@@ -170,7 +165,7 @@ nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset) ...@@ -170,7 +165,7 @@ nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset)
return -EINVAL; return -EINVAL;
if (poffset) { if (poffset) {
struct mem_block *mem = nobj->priv; struct drm_mm_node *mem = nobj->priv;
if (*poffset >= mem->size) if (*poffset >= mem->size)
return false; return false;
...@@ -189,7 +184,6 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, ...@@ -189,7 +184,6 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data,
struct nouveau_channel *chan; struct nouveau_channel *chan;
int ret; int ret;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan);
ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset);
......
This diff is collapsed.
#define NV04_PFB_BOOT_0 0x00100000
# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003
# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000
# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001
# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002
# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003
# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004
# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028
# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000
# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008
# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010
# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018
# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020
# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028
# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100
# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000
#define NV04_PFB_DEBUG_0 0x00100080
# define NV04_PFB_DEBUG_0_PAGE_MODE 0x00000001
# define NV04_PFB_DEBUG_0_REFRESH_OFF 0x00000010
# define NV04_PFB_DEBUG_0_REFRESH_COUNTX64 0x00003f00
# define NV04_PFB_DEBUG_0_REFRESH_SLOW_CLK 0x00004000
# define NV04_PFB_DEBUG_0_SAFE_MODE 0x00008000
# define NV04_PFB_DEBUG_0_ALOM_ENABLE 0x00010000
# define NV04_PFB_DEBUG_0_CASOE 0x00100000
# define NV04_PFB_DEBUG_0_CKE_INVERT 0x10000000
# define NV04_PFB_DEBUG_0_REFINC 0x20000000
# define NV04_PFB_DEBUG_0_SAVE_POWER_OFF 0x40000000
#define NV04_PFB_CFG0 0x00100200
# define NV04_PFB_CFG0_SCRAMBLE 0x20000000
#define NV04_PFB_CFG1 0x00100204
#define NV04_PFB_FIFO_DATA 0x0010020c
# define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000
# define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20
#define NV10_PFB_REFCTRL 0x00100210
# define NV10_PFB_REFCTRL_VALID_1 (1 << 31)
#define NV04_PFB_PAD 0x0010021c
# define NV04_PFB_PAD_CKE_NORMAL (1 << 0)
#define NV10_PFB_TILE(i) (0x00100240 + (i*16))
#define NV10_PFB_TILE__SIZE 8
#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16))
#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16))
#define NV10_PFB_TSTATUS(i) (0x0010024c + (i*16))
#define NV04_PFB_REF 0x001002d0
# define NV04_PFB_REF_CMD_REFRESH (1 << 0)
#define NV04_PFB_PRE 0x001002d4
# define NV04_PFB_PRE_CMD_PRECHARGE (1 << 0)
#define NV10_PFB_CLOSE_PAGE2 0x0010033c
#define NV04_PFB_SCRAMBLE(i) (0x00100400 + 4 * (i))
#define NV40_PFB_TILE(i) (0x00100600 + (i*16))
#define NV40_PFB_TILE__SIZE_0 12
#define NV40_PFB_TILE__SIZE_1 15
#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16))
#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16))
#define NV40_PFB_TSTATUS(i) (0x0010060c + (i*16))
#define NV40_PFB_UNK_800 0x00100800
#define NV03_BOOT_0 0x00100000 #define NV_PEXTDEV_BOOT_0 0x00101000
# define NV03_BOOT_0_RAM_AMOUNT 0x00000003 #define NV_PEXTDEV_BOOT_0_RAMCFG 0x0000003c
# define NV03_BOOT_0_RAM_AMOUNT_8MB 0x00000000 # define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12)
# define NV03_BOOT_0_RAM_AMOUNT_2MB 0x00000001 #define NV_PEXTDEV_BOOT_3 0x0010100c
# define NV03_BOOT_0_RAM_AMOUNT_4MB 0x00000002
# define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM 0x00000003
# define NV04_BOOT_0_RAM_AMOUNT_32MB 0x00000000
# define NV04_BOOT_0_RAM_AMOUNT_4MB 0x00000001
# define NV04_BOOT_0_RAM_AMOUNT_8MB 0x00000002
# define NV04_BOOT_0_RAM_AMOUNT_16MB 0x00000003
#define NV04_FIFO_DATA 0x0010020c
# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000
# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20
#define NV_RAMIN 0x00700000 #define NV_RAMIN 0x00700000
...@@ -131,23 +176,6 @@ ...@@ -131,23 +176,6 @@
#define NV04_PTIMER_TIME_1 0x00009410 #define NV04_PTIMER_TIME_1 0x00009410
#define NV04_PTIMER_ALARM_0 0x00009420 #define NV04_PTIMER_ALARM_0 0x00009420
#define NV04_PFB_CFG0 0x00100200
#define NV04_PFB_CFG1 0x00100204
#define NV40_PFB_020C 0x0010020C
#define NV10_PFB_TILE(i) (0x00100240 + (i*16))
#define NV10_PFB_TILE__SIZE 8
#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16))
#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16))
#define NV10_PFB_TSTATUS(i) (0x0010024C + (i*16))
#define NV10_PFB_CLOSE_PAGE2 0x0010033C
#define NV40_PFB_TILE(i) (0x00100600 + (i*16))
#define NV40_PFB_TILE__SIZE_0 12
#define NV40_PFB_TILE__SIZE_1 15
#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16))
#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16))
#define NV40_PFB_TSTATUS(i) (0x0010060C + (i*16))
#define NV40_PFB_UNK_800 0x00100800
#define NV04_PGRAPH_DEBUG_0 0x00400080 #define NV04_PGRAPH_DEBUG_0 0x00400080
#define NV04_PGRAPH_DEBUG_1 0x00400084 #define NV04_PGRAPH_DEBUG_1 0x00400084
#define NV04_PGRAPH_DEBUG_2 0x00400088 #define NV04_PGRAPH_DEBUG_2 0x00400088
...@@ -814,6 +842,7 @@ ...@@ -814,6 +842,7 @@
#define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000
#define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff
#define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) #define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80)
#define NV50_SOR_DP_CTRL_ENABLED 0x00000001
#define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000
#define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 #define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000
#define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000 #define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000
......
...@@ -97,7 +97,6 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) ...@@ -97,7 +97,6 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start); NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start);
dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT); pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT);
nvbe->pte_start = pte; nvbe->pte_start = pte;
for (i = 0; i < nvbe->nr_pages; i++) { for (i = 0; i < nvbe->nr_pages; i++) {
...@@ -116,24 +115,11 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) ...@@ -116,24 +115,11 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
dma_offset += NV_CTXDMA_PAGE_SIZE; dma_offset += NV_CTXDMA_PAGE_SIZE;
} }
} }
dev_priv->engine.instmem.finish_access(nvbe->dev); dev_priv->engine.instmem.flush(nvbe->dev);
if (dev_priv->card_type == NV_50) { if (dev_priv->card_type == NV_50) {
nv_wr32(dev, 0x100c80, 0x00050001); nv50_vm_flush(dev, 5); /* PGRAPH */
if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { nv50_vm_flush(dev, 0); /* PFIFO */
NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
NV_ERROR(dev, "0x100c80 = 0x%08x\n",
nv_rd32(dev, 0x100c80));
return -EBUSY;
}
nv_wr32(dev, 0x100c80, 0x00000001);
if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
NV_ERROR(dev, "0x100c80 = 0x%08x\n",
nv_rd32(dev, 0x100c80));
return -EBUSY;
}
} }
nvbe->bound = true; nvbe->bound = true;
...@@ -154,7 +140,6 @@ nouveau_sgdma_unbind(struct ttm_backend *be) ...@@ -154,7 +140,6 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
if (!nvbe->bound) if (!nvbe->bound)
return 0; return 0;
dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
pte = nvbe->pte_start; pte = nvbe->pte_start;
for (i = 0; i < nvbe->nr_pages; i++) { for (i = 0; i < nvbe->nr_pages; i++) {
dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus; dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus;
...@@ -170,24 +155,11 @@ nouveau_sgdma_unbind(struct ttm_backend *be) ...@@ -170,24 +155,11 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
dma_offset += NV_CTXDMA_PAGE_SIZE; dma_offset += NV_CTXDMA_PAGE_SIZE;
} }
} }
dev_priv->engine.instmem.finish_access(nvbe->dev); dev_priv->engine.instmem.flush(nvbe->dev);
if (dev_priv->card_type == NV_50) { if (dev_priv->card_type == NV_50) {
nv_wr32(dev, 0x100c80, 0x00050001); nv50_vm_flush(dev, 5);
if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { nv50_vm_flush(dev, 0);
NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
NV_ERROR(dev, "0x100c80 = 0x%08x\n",
nv_rd32(dev, 0x100c80));
return -EBUSY;
}
nv_wr32(dev, 0x100c80, 0x00000001);
if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
NV_ERROR(dev, "0x100c80 = 0x%08x\n",
nv_rd32(dev, 0x100c80));
return -EBUSY;
}
} }
nvbe->bound = false; nvbe->bound = false;
...@@ -272,7 +244,6 @@ nouveau_sgdma_init(struct drm_device *dev) ...@@ -272,7 +244,6 @@ nouveau_sgdma_init(struct drm_device *dev)
pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0,
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
dev_priv->engine.instmem.prepare_access(dev, true);
if (dev_priv->card_type < NV_50) { if (dev_priv->card_type < NV_50) {
/* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
* confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE
...@@ -294,7 +265,7 @@ nouveau_sgdma_init(struct drm_device *dev) ...@@ -294,7 +265,7 @@ nouveau_sgdma_init(struct drm_device *dev)
nv_wo32(dev, gpuobj, (i+4)/4, 0); nv_wo32(dev, gpuobj, (i+4)/4, 0);
} }
} }
dev_priv->engine.instmem.finish_access(dev); dev_priv->engine.instmem.flush(dev);
dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; dev_priv->gart_info.type = NOUVEAU_GART_SGDMA;
dev_priv->gart_info.aper_base = 0; dev_priv->gart_info.aper_base = 0;
...@@ -325,14 +296,11 @@ nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page) ...@@ -325,14 +296,11 @@ nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
int pte; int pte;
pte = (offset >> NV_CTXDMA_PAGE_SHIFT); pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
if (dev_priv->card_type < NV_50) { if (dev_priv->card_type < NV_50) {
instmem->prepare_access(dev, false);
*page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK; *page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK;
instmem->finish_access(dev);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -157,6 +157,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -157,6 +157,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
{ {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_connector *connector;
unsigned char seq1 = 0, crtc17 = 0; unsigned char seq1 = 0, crtc17 = 0;
unsigned char crtc1A; unsigned char crtc1A;
...@@ -211,6 +212,10 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -211,6 +212,10 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
NVVgaSeqReset(dev, nv_crtc->index, false); NVVgaSeqReset(dev, nv_crtc->index, false);
NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A);
/* Update connector polling modes */
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
nouveau_connector_set_polling(connector);
} }
static bool static bool
......
...@@ -220,6 +220,7 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) ...@@ -220,6 +220,7 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio;
struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder);
uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput,
...@@ -251,22 +252,21 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) ...@@ -251,22 +252,21 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
} }
saved_gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); saved_gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1);
saved_gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); saved_gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0);
nv17_gpio_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); gpio->set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV);
nv17_gpio_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); gpio->set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV);
msleep(4); msleep(4);
saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
head = (saved_routput & 0x100) >> 8; head = (saved_routput & 0x100) >> 8;
#if 0
/* if there's a spare crtc, using it will minimise flicker for the case /* if there's a spare crtc, using it will minimise flicker */
* where the in-use crtc is in use by an off-chip tmds encoder */ if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0))
if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled)
head ^= 1; head ^= 1;
#endif
/* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
routput = (saved_routput & 0xfffffece) | head << 8; routput = (saved_routput & 0xfffffece) | head << 8;
...@@ -304,8 +304,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) ...@@ -304,8 +304,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); gpio->set(dev, DCB_GPIO_TVDAC1, saved_gpio1);
nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); gpio->set(dev, DCB_GPIO_TVDAC0, saved_gpio0);
return sample; return sample;
} }
...@@ -315,9 +315,12 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) ...@@ -315,9 +315,12 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
uint32_t sample = nv17_dac_sample_load(encoder);
if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { if (nv04_dac_in_use(encoder))
return connector_status_disconnected;
if (nv17_dac_sample_load(encoder) &
NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
NV_INFO(dev, "Load detected on output %c\n", NV_INFO(dev, "Load detected on output %c\n",
'@' + ffs(dcb->or)); '@' + ffs(dcb->or));
return connector_status_connected; return connector_status_connected;
...@@ -330,6 +333,9 @@ static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, ...@@ -330,6 +333,9 @@ static bool nv04_dac_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
if (nv04_dac_in_use(encoder))
return false;
return true; return true;
} }
...@@ -428,6 +434,17 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) ...@@ -428,6 +434,17 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
} }
} }
/* Check if the DAC corresponding to 'encoder' is being used by
* someone else. */
bool nv04_dac_in_use(struct drm_encoder *encoder)
{
struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
return nv_gf4_disp_arch(encoder->dev) &&
(dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index));
}
static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -501,11 +518,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = { ...@@ -501,11 +518,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = {
.destroy = nv04_dac_destroy, .destroy = nv04_dac_destroy,
}; };
int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) int
nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
{ {
const struct drm_encoder_helper_funcs *helper; const struct drm_encoder_helper_funcs *helper;
struct drm_encoder *encoder;
struct nouveau_encoder *nv_encoder = NULL; struct nouveau_encoder *nv_encoder = NULL;
struct drm_device *dev = connector->dev;
struct drm_encoder *encoder;
nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
if (!nv_encoder) if (!nv_encoder)
...@@ -527,5 +546,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) ...@@ -527,5 +546,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
encoder->possible_crtcs = entry->heads; encoder->possible_crtcs = entry->heads;
encoder->possible_clones = 0; encoder->possible_clones = 0;
drm_mode_connector_attach_encoder(connector, encoder);
return 0; return 0;
} }
...@@ -413,10 +413,6 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) ...@@ -413,10 +413,6 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
struct dcb_entry *dcbe = nv_encoder->dcb; struct dcb_entry *dcbe = nv_encoder->dcb;
int head = nouveau_crtc(encoder->crtc)->index; int head = nouveau_crtc(encoder->crtc)->index;
NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
if (dcbe->type == OUTPUT_TMDS) if (dcbe->type == OUTPUT_TMDS)
run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
else if (dcbe->type == OUTPUT_LVDS) else if (dcbe->type == OUTPUT_LVDS)
...@@ -584,11 +580,12 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = { ...@@ -584,11 +580,12 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = {
.destroy = nv04_dfp_destroy, .destroy = nv04_dfp_destroy,
}; };
int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) int
nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
{ {
const struct drm_encoder_helper_funcs *helper; const struct drm_encoder_helper_funcs *helper;
struct drm_encoder *encoder;
struct nouveau_encoder *nv_encoder = NULL; struct nouveau_encoder *nv_encoder = NULL;
struct drm_encoder *encoder;
int type; int type;
switch (entry->type) { switch (entry->type) {
...@@ -613,11 +610,12 @@ int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) ...@@ -613,11 +610,12 @@ int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
nv_encoder->dcb = entry; nv_encoder->dcb = entry;
nv_encoder->or = ffs(entry->or) - 1; nv_encoder->or = ffs(entry->or) - 1;
drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type); drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type);
drm_encoder_helper_add(encoder, helper); drm_encoder_helper_add(encoder, helper);
encoder->possible_crtcs = entry->heads; encoder->possible_crtcs = entry->heads;
encoder->possible_clones = 0; encoder->possible_clones = 0;
drm_mode_connector_attach_encoder(connector, encoder);
return 0; return 0;
} }
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
#include "nouveau_encoder.h" #include "nouveau_encoder.h"
#include "nouveau_connector.h" #include "nouveau_connector.h"
#define MULTIPLE_ENCODERS(e) (e & (e - 1))
static void static void
nv04_display_store_initial_head_owner(struct drm_device *dev) nv04_display_store_initial_head_owner(struct drm_device *dev)
{ {
...@@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
if (dev_priv->chipset != 0x11) { if (dev_priv->chipset != 0x11) {
dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44); dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
goto ownerknown; return;
} }
/* reading CR44 is broken on nv11, so we attempt to infer it */ /* reading CR44 is broken on nv11, so we attempt to infer it */
...@@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
bool tvA = false; bool tvA = false;
bool tvB = false; bool tvB = false;
NVLockVgaCrtcs(dev, false);
slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) & slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
0x80; 0x80;
if (slaved_on_B) if (slaved_on_B)
...@@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) & tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
MASK(NV_CIO_CRE_LCD_LCD_SELECT)); MASK(NV_CIO_CRE_LCD_LCD_SELECT));
NVLockVgaCrtcs(dev, true);
if (slaved_on_A && !tvA) if (slaved_on_A && !tvA)
dev_priv->crtc_owner = 0x0; dev_priv->crtc_owner = 0x0;
else if (slaved_on_B && !tvB) else if (slaved_on_B && !tvB)
...@@ -79,14 +73,40 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -79,14 +73,40 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
else else
dev_priv->crtc_owner = 0x0; dev_priv->crtc_owner = 0x0;
} }
}
int
nv04_display_early_init(struct drm_device *dev)
{
/* Make the I2C buses accessible. */
if (!nv_gf4_disp_arch(dev)) {
uint32_t pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
if (!(pmc_enable & 1))
nv_wr32(dev, NV03_PMC_ENABLE, pmc_enable | 1);
}
ownerknown: /* Unlock the VGA CRTCs. */
NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner); NVLockVgaCrtcs(dev, false);
/* Make sure the CRTCs aren't in slaved mode. */
if (nv_two_heads(dev)) {
nv04_display_store_initial_head_owner(dev);
NVSetOwner(dev, 0);
}
return 0;
}
void
nv04_display_late_takedown(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
if (nv_two_heads(dev))
NVSetOwner(dev, dev_priv->crtc_owner);
/* we need to ensure the heads are not tied henceforth, or reading any NVLockVgaCrtcs(dev, true);
* 8 bit reg on head B will fail
* setting a single arbitrary head solves that */
NVSetOwner(dev, 0);
} }
int int
...@@ -94,14 +114,13 @@ nv04_display_create(struct drm_device *dev) ...@@ -94,14 +114,13 @@ nv04_display_create(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct dcb_table *dcb = &dev_priv->vbios.dcb; struct dcb_table *dcb = &dev_priv->vbios.dcb;
struct drm_connector *connector, *ct;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_crtc *crtc; struct drm_crtc *crtc;
int i, ret; int i, ret;
NV_DEBUG_KMS(dev, "\n"); NV_DEBUG_KMS(dev, "\n");
if (nv_two_heads(dev))
nv04_display_store_initial_head_owner(dev);
nouveau_hw_save_vga_fonts(dev, 1); nouveau_hw_save_vga_fonts(dev, 1);
drm_mode_config_init(dev); drm_mode_config_init(dev);
...@@ -132,19 +151,23 @@ nv04_display_create(struct drm_device *dev) ...@@ -132,19 +151,23 @@ nv04_display_create(struct drm_device *dev)
for (i = 0; i < dcb->entries; i++) { for (i = 0; i < dcb->entries; i++) {
struct dcb_entry *dcbent = &dcb->entry[i]; struct dcb_entry *dcbent = &dcb->entry[i];
connector = nouveau_connector_create(dev, dcbent->connector);
if (IS_ERR(connector))
continue;
switch (dcbent->type) { switch (dcbent->type) {
case OUTPUT_ANALOG: case OUTPUT_ANALOG:
ret = nv04_dac_create(dev, dcbent); ret = nv04_dac_create(connector, dcbent);
break; break;
case OUTPUT_LVDS: case OUTPUT_LVDS:
case OUTPUT_TMDS: case OUTPUT_TMDS:
ret = nv04_dfp_create(dev, dcbent); ret = nv04_dfp_create(connector, dcbent);
break; break;
case OUTPUT_TV: case OUTPUT_TV:
if (dcbent->location == DCB_LOC_ON_CHIP) if (dcbent->location == DCB_LOC_ON_CHIP)
ret = nv17_tv_create(dev, dcbent); ret = nv17_tv_create(connector, dcbent);
else else
ret = nv04_tv_create(dev, dcbent); ret = nv04_tv_create(connector, dcbent);
break; break;
default: default:
NV_WARN(dev, "DCB type %d not known\n", dcbent->type); NV_WARN(dev, "DCB type %d not known\n", dcbent->type);
...@@ -155,12 +178,16 @@ nv04_display_create(struct drm_device *dev) ...@@ -155,12 +178,16 @@ nv04_display_create(struct drm_device *dev)
continue; continue;
} }
for (i = 0; i < dcb->connector.entries; i++) list_for_each_entry_safe(connector, ct,
nouveau_connector_create(dev, &dcb->connector.entry[i]); &dev->mode_config.connector_list, head) {
if (!connector->encoder_ids[0]) {
NV_WARN(dev, "%s has no encoders, removing\n",
drm_get_connector_name(connector));
connector->funcs->destroy(connector);
}
}
/* Save previous state */ /* Save previous state */
NVLockVgaCrtcs(dev, false);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
crtc->funcs->save(crtc); crtc->funcs->save(crtc);
...@@ -191,8 +218,6 @@ nv04_display_destroy(struct drm_device *dev) ...@@ -191,8 +218,6 @@ nv04_display_destroy(struct drm_device *dev)
} }
/* Restore state */ /* Restore state */
NVLockVgaCrtcs(dev, false);
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
struct drm_encoder_helper_funcs *func = encoder->helper_private; struct drm_encoder_helper_funcs *func = encoder->helper_private;
...@@ -207,15 +232,12 @@ nv04_display_destroy(struct drm_device *dev) ...@@ -207,15 +232,12 @@ nv04_display_destroy(struct drm_device *dev)
nouveau_hw_save_vga_fonts(dev, 0); nouveau_hw_save_vga_fonts(dev, 0);
} }
void int
nv04_display_restore(struct drm_device *dev) nv04_display_init(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_crtc *crtc; struct drm_crtc *crtc;
NVLockVgaCrtcs(dev, false);
/* meh.. modeset apparently doesn't setup all the regs and depends /* meh.. modeset apparently doesn't setup all the regs and depends
* on pre-existing state, for now load the state of the card *before* * on pre-existing state, for now load the state of the card *before*
* nouveau was loaded, and then do a modeset. * nouveau was loaded, and then do a modeset.
...@@ -233,12 +255,6 @@ nv04_display_restore(struct drm_device *dev) ...@@ -233,12 +255,6 @@ nv04_display_restore(struct drm_device *dev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
crtc->funcs->restore(crtc); crtc->funcs->restore(crtc);
if (nv_two_heads(dev)) { return 0;
NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n",
dev_priv->crtc_owner);
NVSetOwner(dev, dev_priv->crtc_owner);
}
NVLockVgaCrtcs(dev, true);
} }
...@@ -112,6 +112,12 @@ nv04_fifo_channel_id(struct drm_device *dev) ...@@ -112,6 +112,12 @@ nv04_fifo_channel_id(struct drm_device *dev)
NV03_PFIFO_CACHE1_PUSH1_CHID_MASK; NV03_PFIFO_CACHE1_PUSH1_CHID_MASK;
} }
#ifdef __BIG_ENDIAN
#define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN
#else
#define DMA_FETCH_ENDIANNESS 0
#endif
int int
nv04_fifo_create_context(struct nouveau_channel *chan) nv04_fifo_create_context(struct nouveau_channel *chan)
{ {
...@@ -131,18 +137,13 @@ nv04_fifo_create_context(struct nouveau_channel *chan) ...@@ -131,18 +137,13 @@ nv04_fifo_create_context(struct nouveau_channel *chan)
spin_lock_irqsave(&dev_priv->context_switch_lock, flags); spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
/* Setup initial state */ /* Setup initial state */
dev_priv->engine.instmem.prepare_access(dev, true);
RAMFC_WR(DMA_PUT, chan->pushbuf_base); RAMFC_WR(DMA_PUT, chan->pushbuf_base);
RAMFC_WR(DMA_GET, chan->pushbuf_base); RAMFC_WR(DMA_GET, chan->pushbuf_base);
RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4);
RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
#ifdef __BIG_ENDIAN DMA_FETCH_ENDIANNESS));
NV_PFIFO_CACHE1_BIG_ENDIAN |
#endif
0));
dev_priv->engine.instmem.finish_access(dev);
/* enable the fifo dma operation */ /* enable the fifo dma operation */
nv_wr32(dev, NV04_PFIFO_MODE, nv_wr32(dev, NV04_PFIFO_MODE,
...@@ -169,8 +170,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid) ...@@ -169,8 +170,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid)
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t fc = NV04_RAMFC(chid), tmp; uint32_t fc = NV04_RAMFC(chid), tmp;
dev_priv->engine.instmem.prepare_access(dev, false);
nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
tmp = nv_ri32(dev, fc + 8); tmp = nv_ri32(dev, fc + 8);
...@@ -181,8 +180,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid) ...@@ -181,8 +180,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid)
nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20)); nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20));
nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24)); nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24));
dev_priv->engine.instmem.finish_access(dev);
nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
} }
...@@ -223,7 +220,6 @@ nv04_fifo_unload_context(struct drm_device *dev) ...@@ -223,7 +220,6 @@ nv04_fifo_unload_context(struct drm_device *dev)
return -EINVAL; return -EINVAL;
} }
dev_priv->engine.instmem.prepare_access(dev, true);
RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16;
...@@ -233,7 +229,6 @@ nv04_fifo_unload_context(struct drm_device *dev) ...@@ -233,7 +229,6 @@ nv04_fifo_unload_context(struct drm_device *dev)
RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH));
RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
dev_priv->engine.instmem.finish_access(dev);
nv04_fifo_do_load_context(dev, pfifo->channels - 1); nv04_fifo_do_load_context(dev, pfifo->channels - 1);
nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
...@@ -297,6 +292,7 @@ nv04_fifo_init(struct drm_device *dev) ...@@ -297,6 +292,7 @@ nv04_fifo_init(struct drm_device *dev)
nv04_fifo_init_intr(dev); nv04_fifo_init_intr(dev);
pfifo->enable(dev); pfifo->enable(dev);
pfifo->reassign(dev, true);
for (i = 0; i < dev_priv->engine.fifo.channels; i++) { for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
if (dev_priv->fifos[i]) { if (dev_priv->fifos[i]) {
......
...@@ -342,7 +342,7 @@ static uint32_t nv04_graph_ctx_regs[] = { ...@@ -342,7 +342,7 @@ static uint32_t nv04_graph_ctx_regs[] = {
}; };
struct graph_state { struct graph_state {
int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
}; };
struct nouveau_channel * struct nouveau_channel *
...@@ -527,8 +527,7 @@ static int ...@@ -527,8 +527,7 @@ static int
nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass, nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass,
int mthd, uint32_t data) int mthd, uint32_t data)
{ {
chan->fence.last_sequence_irq = data; atomic_set(&chan->fence.last_sequence_irq, data);
nouveau_fence_handler(chan->dev, chan->id);
return 0; return 0;
} }
......
...@@ -49,10 +49,8 @@ nv04_instmem_determine_amount(struct drm_device *dev) ...@@ -49,10 +49,8 @@ nv04_instmem_determine_amount(struct drm_device *dev)
NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10); NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10);
/* Clear all of it, except the BIOS image that's in the first 64KiB */ /* Clear all of it, except the BIOS image that's in the first 64KiB */
dev_priv->engine.instmem.prepare_access(dev, true);
for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4) for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4)
nv_wi32(dev, i, 0x00000000); nv_wi32(dev, i, 0x00000000);
dev_priv->engine.instmem.finish_access(dev);
} }
static void static void
...@@ -106,7 +104,7 @@ int nv04_instmem_init(struct drm_device *dev) ...@@ -106,7 +104,7 @@ int nv04_instmem_init(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t offset; uint32_t offset;
int ret = 0; int ret;
nv04_instmem_determine_amount(dev); nv04_instmem_determine_amount(dev);
nv04_instmem_configure_fixed_tables(dev); nv04_instmem_configure_fixed_tables(dev);
...@@ -129,14 +127,14 @@ int nv04_instmem_init(struct drm_device *dev) ...@@ -129,14 +127,14 @@ int nv04_instmem_init(struct drm_device *dev)
offset = 0x40000; offset = 0x40000;
} }
ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, ret = drm_mm_init(&dev_priv->ramin_heap, offset,
offset, dev_priv->ramin_rsvd_vram - offset); dev_priv->ramin_rsvd_vram - offset);
if (ret) { if (ret) {
dev_priv->ramin_heap = NULL; NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret);
NV_ERROR(dev, "Failed to init RAMIN heap\n"); return ret;
} }
return ret; return 0;
} }
void void
...@@ -186,12 +184,7 @@ nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ...@@ -186,12 +184,7 @@ nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
} }
void void
nv04_instmem_prepare_access(struct drm_device *dev, bool write) nv04_instmem_flush(struct drm_device *dev)
{
}
void
nv04_instmem_finish_access(struct drm_device *dev)
{ {
} }
......
...@@ -11,6 +11,10 @@ nv04_mc_init(struct drm_device *dev) ...@@ -11,6 +11,10 @@ nv04_mc_init(struct drm_device *dev)
*/ */
nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
/* Disable PROM access. */
nv_wr32(dev, NV_PBUS_PCI_NV_20, NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
return 0; return 0;
} }
......
...@@ -34,69 +34,26 @@ ...@@ -34,69 +34,26 @@
#include "i2c/ch7006.h" #include "i2c/ch7006.h"
static struct { static struct i2c_board_info nv04_tv_encoder_info[] = {
struct i2c_board_info board_info;
struct drm_encoder_funcs funcs;
struct drm_encoder_helper_funcs hfuncs;
void *params;
} nv04_tv_encoder_info[] = {
{ {
.board_info = { I2C_BOARD_INFO("ch7006", 0x75) }, I2C_BOARD_INFO("ch7006", 0x75),
.params = &(struct ch7006_encoder_params) { .platform_data = &(struct ch7006_encoder_params) {
CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER,
0, 0, 0, 0, 0, 0,
CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED,
CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC
}, }
}, },
{ }
}; };
static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr)
{
struct i2c_msg msg = {
.addr = addr,
.len = 0,
};
return i2c_transfer(adapter, &msg, 1) == 1;
}
int nv04_tv_identify(struct drm_device *dev, int i2c_index) int nv04_tv_identify(struct drm_device *dev, int i2c_index)
{ {
struct nouveau_i2c_chan *i2c; return nouveau_i2c_identify(dev, "TV encoder",
bool was_locked; nv04_tv_encoder_info, i2c_index);
int i, ret;
NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index);
i2c = nouveau_i2c_find(dev, i2c_index);
if (!i2c)
return -ENODEV;
was_locked = NVLockVgaCrtcs(dev, false);
for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) {
if (probe_i2c_addr(&i2c->adapter,
nv04_tv_encoder_info[i].board_info.addr)) {
ret = i;
break;
}
}
if (i < ARRAY_SIZE(nv04_tv_encoder_info)) {
NV_TRACE(dev, "Detected TV encoder: %s\n",
nv04_tv_encoder_info[i].board_info.type);
} else {
NV_TRACE(dev, "No TV encoders found.\n");
i = -ENODEV;
}
NVLockVgaCrtcs(dev, was_locked);
return i;
} }
#define PLLSEL_TV_CRTC1_MASK \ #define PLLSEL_TV_CRTC1_MASK \
(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \
| NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1) | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1)
...@@ -214,30 +171,32 @@ static void nv04_tv_commit(struct drm_encoder *encoder) ...@@ -214,30 +171,32 @@ static void nv04_tv_commit(struct drm_encoder *encoder)
static void nv04_tv_destroy(struct drm_encoder *encoder) static void nv04_tv_destroy(struct drm_encoder *encoder)
{ {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
to_encoder_slave(encoder)->slave_funcs->destroy(encoder); to_encoder_slave(encoder)->slave_funcs->destroy(encoder);
drm_encoder_cleanup(encoder); drm_encoder_cleanup(encoder);
kfree(nv_encoder); kfree(encoder->helper_private);
kfree(nouveau_encoder(encoder));
} }
int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) static const struct drm_encoder_funcs nv04_tv_funcs = {
.destroy = nv04_tv_destroy,
};
int
nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
{ {
struct nouveau_encoder *nv_encoder; struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_device *dev = connector->dev;
struct i2c_adapter *adap; struct drm_encoder_helper_funcs *hfuncs;
struct drm_encoder_funcs *funcs = NULL; struct drm_encoder_slave_funcs *sfuncs;
struct drm_encoder_helper_funcs *hfuncs = NULL; struct nouveau_i2c_chan *i2c =
struct drm_encoder_slave_funcs *sfuncs = NULL; nouveau_i2c_find(dev, entry->i2c_index);
int i2c_index = entry->i2c_index;
int type, ret; int type, ret;
bool was_locked;
/* Ensure that we can talk to this encoder */ /* Ensure that we can talk to this encoder */
type = nv04_tv_identify(dev, i2c_index); type = nv04_tv_identify(dev, entry->i2c_index);
if (type < 0) if (type < 0)
return type; return type;
...@@ -246,41 +205,32 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) ...@@ -246,41 +205,32 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
if (!nv_encoder) if (!nv_encoder)
return -ENOMEM; return -ENOMEM;
hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL);
if (!hfuncs) {
ret = -ENOMEM;
goto fail_free;
}
/* Initialize the common members */ /* Initialize the common members */
encoder = to_drm_encoder(nv_encoder); encoder = to_drm_encoder(nv_encoder);
funcs = &nv04_tv_encoder_info[type].funcs; drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC);
hfuncs = &nv04_tv_encoder_info[type].hfuncs;
drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC);
drm_encoder_helper_add(encoder, hfuncs); drm_encoder_helper_add(encoder, hfuncs);
encoder->possible_crtcs = entry->heads; encoder->possible_crtcs = entry->heads;
encoder->possible_clones = 0; encoder->possible_clones = 0;
nv_encoder->dcb = entry; nv_encoder->dcb = entry;
nv_encoder->or = ffs(entry->or) - 1; nv_encoder->or = ffs(entry->or) - 1;
/* Run the slave-specific initialization */ /* Run the slave-specific initialization */
adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter; ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
&i2c->adapter, &nv04_tv_encoder_info[type]);
was_locked = NVLockVgaCrtcs(dev, false);
ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap,
&nv04_tv_encoder_info[type].board_info);
NVLockVgaCrtcs(dev, was_locked);
if (ret < 0) if (ret < 0)
goto fail; goto fail_cleanup;
/* Fill the function pointers */ /* Fill the function pointers */
sfuncs = to_encoder_slave(encoder)->slave_funcs; sfuncs = to_encoder_slave(encoder)->slave_funcs;
*funcs = (struct drm_encoder_funcs) {
.destroy = nv04_tv_destroy,
};
*hfuncs = (struct drm_encoder_helper_funcs) { *hfuncs = (struct drm_encoder_helper_funcs) {
.dpms = nv04_tv_dpms, .dpms = nv04_tv_dpms,
.save = sfuncs->save, .save = sfuncs->save,
...@@ -292,14 +242,17 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) ...@@ -292,14 +242,17 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
.detect = sfuncs->detect, .detect = sfuncs->detect,
}; };
/* Set the slave encoder configuration */ /* Attach it to the specified connector. */
sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params); sfuncs->set_config(encoder, nv04_tv_encoder_info[type].platform_data);
sfuncs->create_resources(encoder, connector);
drm_mode_connector_attach_encoder(connector, encoder);
return 0; return 0;
fail: fail_cleanup:
drm_encoder_cleanup(encoder); drm_encoder_cleanup(encoder);
kfree(hfuncs);
fail_free:
kfree(nv_encoder); kfree(nv_encoder);
return ret; return ret;
} }
...@@ -55,7 +55,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan) ...@@ -55,7 +55,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
/* Fill entries that are seen filled in dumps of nvidia driver just /* Fill entries that are seen filled in dumps of nvidia driver just
* after channel's is put into DMA mode * after channel's is put into DMA mode
*/ */
dev_priv->engine.instmem.prepare_access(dev, true);
nv_wi32(dev, fc + 0, chan->pushbuf_base); nv_wi32(dev, fc + 0, chan->pushbuf_base);
nv_wi32(dev, fc + 4, chan->pushbuf_base); nv_wi32(dev, fc + 4, chan->pushbuf_base);
nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
...@@ -66,7 +65,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan) ...@@ -66,7 +65,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
NV_PFIFO_CACHE1_BIG_ENDIAN | NV_PFIFO_CACHE1_BIG_ENDIAN |
#endif #endif
0); 0);
dev_priv->engine.instmem.finish_access(dev);
/* enable the fifo dma operation */ /* enable the fifo dma operation */
nv_wr32(dev, NV04_PFIFO_MODE, nv_wr32(dev, NV04_PFIFO_MODE,
...@@ -91,8 +89,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid) ...@@ -91,8 +89,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid)
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t fc = NV10_RAMFC(chid), tmp; uint32_t fc = NV10_RAMFC(chid), tmp;
dev_priv->engine.instmem.prepare_access(dev, false);
nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
...@@ -117,8 +113,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid) ...@@ -117,8 +113,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid)
nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48)); nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48));
out: out:
dev_priv->engine.instmem.finish_access(dev);
nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
} }
...@@ -155,8 +149,6 @@ nv10_fifo_unload_context(struct drm_device *dev) ...@@ -155,8 +149,6 @@ nv10_fifo_unload_context(struct drm_device *dev)
return 0; return 0;
fc = NV10_RAMFC(chid); fc = NV10_RAMFC(chid);
dev_priv->engine.instmem.prepare_access(dev, true);
nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
...@@ -179,8 +171,6 @@ nv10_fifo_unload_context(struct drm_device *dev) ...@@ -179,8 +171,6 @@ nv10_fifo_unload_context(struct drm_device *dev)
nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
out: out:
dev_priv->engine.instmem.finish_access(dev);
nv10_fifo_do_load_context(dev, pfifo->channels - 1); nv10_fifo_do_load_context(dev, pfifo->channels - 1);
nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
return 0; return 0;
......
...@@ -55,7 +55,7 @@ get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift, ...@@ -55,7 +55,7 @@ get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift,
} }
int int
nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
{ {
struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
uint32_t reg, shift, mask, value; uint32_t reg, shift, mask, value;
...@@ -72,7 +72,7 @@ nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) ...@@ -72,7 +72,7 @@ nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
} }
int int
nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
{ {
struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag);
uint32_t reg, shift, mask, value; uint32_t reg, shift, mask, value;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -48,7 +48,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan) ...@@ -48,7 +48,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
spin_lock_irqsave(&dev_priv->context_switch_lock, flags); spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
dev_priv->engine.instmem.prepare_access(dev, true);
nv_wi32(dev, fc + 0, chan->pushbuf_base); nv_wi32(dev, fc + 0, chan->pushbuf_base);
nv_wi32(dev, fc + 4, chan->pushbuf_base); nv_wi32(dev, fc + 4, chan->pushbuf_base);
nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
...@@ -61,7 +60,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan) ...@@ -61,7 +60,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
0x30000000 /* no idea.. */); 0x30000000 /* no idea.. */);
nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4); nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4);
nv_wi32(dev, fc + 60, 0x0001FFFF); nv_wi32(dev, fc + 60, 0x0001FFFF);
dev_priv->engine.instmem.finish_access(dev);
/* enable the fifo dma operation */ /* enable the fifo dma operation */
nv_wr32(dev, NV04_PFIFO_MODE, nv_wr32(dev, NV04_PFIFO_MODE,
...@@ -89,8 +87,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid) ...@@ -89,8 +87,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid)
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t fc = NV40_RAMFC(chid), tmp, tmp2; uint32_t fc = NV40_RAMFC(chid), tmp, tmp2;
dev_priv->engine.instmem.prepare_access(dev, false);
nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
...@@ -127,8 +123,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid) ...@@ -127,8 +123,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid)
nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76)); nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76));
nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80)); nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80));
dev_priv->engine.instmem.finish_access(dev);
nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
} }
...@@ -166,7 +160,6 @@ nv40_fifo_unload_context(struct drm_device *dev) ...@@ -166,7 +160,6 @@ nv40_fifo_unload_context(struct drm_device *dev)
return 0; return 0;
fc = NV40_RAMFC(chid); fc = NV40_RAMFC(chid);
dev_priv->engine.instmem.prepare_access(dev, true);
nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
...@@ -200,7 +193,6 @@ nv40_fifo_unload_context(struct drm_device *dev) ...@@ -200,7 +193,6 @@ nv40_fifo_unload_context(struct drm_device *dev)
tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16); tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16);
nv_wi32(dev, fc + 72, tmp); nv_wi32(dev, fc + 72, tmp);
#endif #endif
dev_priv->engine.instmem.finish_access(dev);
nv40_fifo_do_load_context(dev, pfifo->channels - 1); nv40_fifo_do_load_context(dev, pfifo->channels - 1);
nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
......
This diff is collapsed.
...@@ -19,7 +19,7 @@ nv40_mc_init(struct drm_device *dev) ...@@ -19,7 +19,7 @@ nv40_mc_init(struct drm_device *dev)
case 0x46: /* G72 */ case 0x46: /* G72 */
case 0x4e: case 0x4e:
case 0x4c: /* C51_G7X */ case 0x4c: /* C51_G7X */
tmp = nv_rd32(dev, NV40_PFB_020C); tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA);
nv_wr32(dev, NV40_PMC_1700, tmp); nv_wr32(dev, NV40_PMC_1700, tmp);
nv_wr32(dev, NV40_PMC_1704, 0); nv_wr32(dev, NV40_PMC_1704, 0);
nv_wr32(dev, NV40_PMC_1708, 0); nv_wr32(dev, NV40_PMC_1708, 0);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -38,9 +38,11 @@ ...@@ -38,9 +38,11 @@
void nv50_display_irq_handler(struct drm_device *dev); void nv50_display_irq_handler(struct drm_device *dev);
void nv50_display_irq_handler_bh(struct work_struct *work); void nv50_display_irq_handler_bh(struct work_struct *work);
void nv50_display_irq_hotplug_bh(struct work_struct *work); void nv50_display_irq_hotplug_bh(struct work_struct *work);
int nv50_display_init(struct drm_device *dev); int nv50_display_early_init(struct drm_device *dev);
void nv50_display_late_takedown(struct drm_device *dev);
int nv50_display_create(struct drm_device *dev); int nv50_display_create(struct drm_device *dev);
int nv50_display_destroy(struct drm_device *dev); int nv50_display_init(struct drm_device *dev);
void nv50_display_destroy(struct drm_device *dev);
int nv50_crtc_blank(struct nouveau_crtc *, bool blank); int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment