Commit 77145f1c authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau: port remainder of drm code, and rip out compat layer



v2: Ben Skeggs <bskeggs@redhat.com>
- fill in nouveau_pm.dev to prevent oops
- fix ppc issues (build + OF shadow)
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 2094dd82
......@@ -145,47 +145,17 @@ nouveau-y += core/engine/software/nv50.o
nouveau-y += core/engine/software/nvc0.o
nouveau-y += core/engine/vp/nv84.o
# drm/compat - will go away
nouveau-y += nouveau_compat.o nouveau_revcompat.o
# drm/core
nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o
nouveau-y += nouveau_agp.o
nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.o
nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o
nouveau-y += nouveau_abi16.o
nouveau-y += nouveau_prime.o nouveau_abi16.o
nouveau-y += nv04_fence.o nv10_fence.o nv50_fence.o nv84_fence.o nvc0_fence.o
# drm/kms/common
nouveau-y += nouveau_fbcon.o
# drm/kms/nv04:nv50
nouveau-y += nv04_fbcon.o
# drm/kms/nv50:nvd9
nouveau-y += nv50_fbcon.o nvc0_fbcon.o
# drm/kms/nvd9-
# other random bits
nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
nouveau-$(CONFIG_ACPI) += nouveau_acpi.o
nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
##
## unported bits below
##
# drm/core
nouveau-y += nouveau_drv.o nouveau_state.o nouveau_irq.o
nouveau-y += nouveau_prime.o
# drm/kms/bios
nouveau-y += nouveau_bios.o
# drm/kms/common
nouveau-y += nouveau_display.o nouveau_connector.o
nouveau-y += nouveau_hdmi.o nouveau_dp.o
# drm/kms
nouveau-y += nouveau_bios.o nouveau_fbcon.o nouveau_display.o
nouveau-y += nouveau_connector.o nouveau_hdmi.o nouveau_dp.o
nouveau-y += nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o
# drm/kms/nv04:nv50
nouveau-y += nouveau_hw.o nouveau_calc.o
......@@ -202,4 +172,9 @@ nouveau-y += nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o
nouveau-y += nv04_pm.o nv40_pm.o nv50_pm.o nva3_pm.o nvc0_pm.o
nouveau-y += nouveau_mem.o
# other random bits
nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
nouveau-$(CONFIG_ACPI) += nouveau_acpi.o
nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
......@@ -20,8 +20,8 @@ void nouveau_timer_alarm(void *, u32 nsec, struct nouveau_alarm *);
nouveau_timer_wait_eq((o), NV_WAIT_DEFAULT, (a), (m), (v))
#define nv_wait_ne(o,a,m,v) \
nouveau_timer_wait_ne((o), NV_WAIT_DEFAULT, (a), (m), (v))
#define nv_wait_cb(o,a,m,v) \
nouveau_timer_wait_cb((o), NV_WAIT_DEFAULT, (a), (m), (v))
#define nv_wait_cb(o,c,d) \
nouveau_timer_wait_cb((o), NV_WAIT_DEFAULT, (c), (d))
struct nouveau_timer {
struct nouveau_subdev base;
......
......@@ -56,6 +56,31 @@ nvbios_findstr(const u8 *data, int size, const char *str, int len)
return 0;
}
#if defined(__powerpc__)
static void
nouveau_bios_shadow_of(struct nouveau_bios *bios)
{
struct pci_dev *pdev = nv_device(bios)->pdev;
struct device_node *dn;
const u32 *data;
int size, i;
dn = pci_device_to_OF_node(pdev);
if (!dn) {
nv_info(bios, "Unable to get the OF node\n");
return;
}
data = of_get_property(dn, "NVDA,BMP", &size);
if (data) {
bios->size = size;
bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data)
memcpy(bios->data, data, size);
}
}
#endif
static void
nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
{
......@@ -221,7 +246,7 @@ nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
}
struct methods {
const char desc[8];
const char desc[16];
void (*shadow)(struct nouveau_bios *);
const bool rw;
int score;
......@@ -233,6 +258,9 @@ static int
nouveau_bios_shadow(struct nouveau_bios *bios)
{
struct methods shadow_methods[] = {
#if defined(__powerpc__)
{ "OpenFirmware", nouveau_bios_shadow_of, true, 0, 0, NULL },
#endif
{ "PRAMIN", nouveau_bios_shadow_pramin, true, 0, 0, NULL },
{ "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL },
{ "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL },
......
......@@ -71,7 +71,7 @@ static const struct backlight_ops nv40_bl_ops = {
static int
nv40_backlight_init(struct drm_connector *connector)
{
struct nouveau_drm *drm = nouveau_newpriv(connector->dev);
struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct nouveau_device *device = nv_device(drm->device);
struct backlight_properties props;
struct backlight_device *bd;
......@@ -95,7 +95,7 @@ static int
nv50_get_intensity(struct backlight_device *bd)
{
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
struct nouveau_drm *drm = nouveau_newpriv(nv_encoder->base.base.dev);
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_device *device = nv_device(drm->device);
int or = nv_encoder->or;
u32 div = 1025;
......@@ -110,7 +110,7 @@ static int
nv50_set_intensity(struct backlight_device *bd)
{
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
struct nouveau_drm *drm = nouveau_newpriv(nv_encoder->base.base.dev);
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_device *device = nv_device(drm->device);
int or = nv_encoder->or;
u32 div = 1025;
......@@ -131,7 +131,7 @@ static int
nva3_get_intensity(struct backlight_device *bd)
{
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
struct nouveau_drm *drm = nouveau_newpriv(nv_encoder->base.base.dev);
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_device *device = nv_device(drm->device);
int or = nv_encoder->or;
u32 div, val;
......@@ -149,7 +149,7 @@ static int
nva3_set_intensity(struct backlight_device *bd)
{
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
struct nouveau_drm *drm = nouveau_newpriv(nv_encoder->base.base.dev);
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_device *device = nv_device(drm->device);
int or = nv_encoder->or;
u32 div, val;
......@@ -175,7 +175,7 @@ static const struct backlight_ops nva3_bl_ops = {
static int
nv50_backlight_init(struct drm_connector *connector)
{
struct nouveau_drm *drm = nouveau_newpriv(connector->dev);
struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct nouveau_device *device = nv_device(drm->device);
struct nouveau_encoder *nv_encoder;
struct backlight_properties props;
......@@ -216,7 +216,7 @@ nv50_backlight_init(struct drm_connector *connector)
int
nouveau_backlight_init(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_device *device = nv_device(drm->device);
struct drm_connector *connector;
......@@ -250,7 +250,7 @@ nouveau_backlight_init(struct drm_device *dev)
void
nouveau_backlight_exit(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
if (drm->backlight) {
backlight_device_unregister(drm->backlight);
......
This diff is collapsed.
......@@ -21,8 +21,8 @@
* DEALINGS IN THE SOFTWARE.
*/
#ifndef __NOUVEAU_BIOS_H__
#define __NOUVEAU_BIOS_H__
#ifndef __NOUVEAU_DISPBIOS_H__
#define __NOUVEAU_DISPBIOS_H__
#include "nvreg.h"
......@@ -38,8 +38,8 @@
#define ROM48(x) ({ u8 *p = &(x); (u64)ROM16(p[4]) << 32 | ROM32(p[0]); })
#define ROM64(x) le64_to_cpu(*(u64 *)&(x))
#define ROMPTR(d,x) ({ \
struct drm_nouveau_private *dev_priv = (d)->dev_private; \
ROM16(x) ? &dev_priv->vbios.data[ROM16(x)] : NULL; \
struct nouveau_drm *drm = nouveau_drm((d)); \
ROM16(x) ? &drm->vbios.data[ROM16(x)] : NULL; \
})
struct bit_entry {
......@@ -180,4 +180,21 @@ int olddcb_outp_foreach(struct drm_device *, void *data,
u8 *olddcb_conntab(struct drm_device *);
u8 *olddcb_conn(struct drm_device *, u8 idx);
int nouveau_bios_init(struct drm_device *);
void nouveau_bios_takedown(struct drm_device *dev);
int nouveau_run_vbios_init(struct drm_device *);
struct dcb_connector_table_entry *
nouveau_bios_connector_entry(struct drm_device *, int index);
int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk,
struct dcb_output *, int crtc);
bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *);
uint8_t *nouveau_bios_embedded_edid(struct drm_device *);
int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk,
bool *dl, bool *if_is_24bit);
int run_tmds_table(struct drm_device *, struct dcb_output *,
int head, int pxclk);
int call_lvds_script(struct drm_device *, struct dcb_output *, int head,
enum LVDS_script, int pxclk);
bool bios_encoder_match(struct dcb_output *, u32 hash);
#endif
......@@ -49,7 +49,7 @@ static void
nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg,
u32 addr, u32 size, u32 pitch, u32 flags)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
int i = reg - drm->tile.reg;
struct nouveau_fb *pfb = nouveau_fb(drm->device);
struct nouveau_fb_tile *tile = &pfb->tile.region[i];
......@@ -74,7 +74,7 @@ nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg,
static struct nouveau_drm_tile *
nv10_bo_get_tile_region(struct drm_device *dev, int i)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_drm_tile *tile = &drm->tile.reg[i];
spin_lock(&drm->tile.lock);
......@@ -93,7 +93,7 @@ static void
nv10_bo_put_tile_region(struct drm_device *dev, struct nouveau_drm_tile *tile,
struct nouveau_fence *fence)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
if (tile) {
spin_lock(&drm->tile.lock);
......@@ -112,7 +112,7 @@ static struct nouveau_drm_tile *
nv10_bo_set_tiling(struct drm_device *dev, u32 addr,
u32 size, u32 pitch, u32 flags)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_fb *pfb = nouveau_fb(drm->device);
struct nouveau_drm_tile *tile, *found = NULL;
int i;
......@@ -191,7 +191,7 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
struct sg_table *sg,
struct nouveau_bo **pnvbo)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_bo *nvbo;
size_t acc_size;
int ret;
......
......@@ -22,7 +22,8 @@
*/
#include "drmP.h"
#include "nouveau_drv.h"
#include "nouveau_drm.h"
#include "nouveau_reg.h"
#include "nouveau_hw.h"
/****************************************************************************\
......@@ -195,12 +196,13 @@ static void
nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
int *burst, int *lwm)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_device *device = nouveau_dev(dev);
struct nv_fifo_info fifo_data;
struct nv_sim_state sim_data;
int MClk = nouveau_hw_get_clock(dev, PLL_MEMORY);
int NVClk = nouveau_hw_get_clock(dev, PLL_CORE);
uint32_t cfg1 = nv_rd32(dev, NV04_PFB_CFG1);
uint32_t cfg1 = nv_rd32(device, NV04_PFB_CFG1);
sim_data.pclk_khz = VClk;
sim_data.mclk_khz = MClk;
......@@ -218,13 +220,13 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
sim_data.mem_latency = 3;
sim_data.mem_page_miss = 10;
} else {
sim_data.memory_type = nv_rd32(dev, NV04_PFB_CFG0) & 0x1;
sim_data.memory_width = (nv_rd32(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
sim_data.memory_type = nv_rd32(device, NV04_PFB_CFG0) & 0x1;
sim_data.memory_width = (nv_rd32(device, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
sim_data.mem_latency = cfg1 & 0xf;
sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
}
if (dev_priv->card_type == NV_04)
if (nv_device(drm->device)->card_type == NV_04)
nv04_calc_arb(&fifo_data, &sim_data);
else
nv10_calc_arb(&fifo_data, &sim_data);
......@@ -249,9 +251,9 @@ nv20_update_arb(int *burst, int *lwm)
void
nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_drm *drm = nouveau_drm(dev);
if (dev_priv->card_type < NV_20)
if (nv_device(drm->device)->card_type < NV_20)
nv04_update_arb(dev, vclk, bpp, burst, lwm);
else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ ||
(dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) {
......
#include "nouveau_drm.h"
#include "nouveau_chan.h"
#include "nouveau_compat.h"
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/init.h>
#include <subdev/bios/pll.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/bar.h>
#include <subdev/vm.h>
int
nvdrm_gart_init(struct drm_device *dev, u64 *base, u64 *size)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
if (drm->agp.stat == ENABLED) {
*base = drm->agp.base;
*size = drm->agp.base;
return 0;
}
return -ENODEV;
}
u8
_nv_rd08(struct drm_device *dev, u32 reg)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
return nv_ro08(drm->device, reg);
}
void
_nv_wr08(struct drm_device *dev, u32 reg, u8 val)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
nv_wo08(drm->device, reg, val);
}
u32
_nv_rd32(struct drm_device *dev, u32 reg)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
return nv_ro32(drm->device, reg);
}
void
_nv_wr32(struct drm_device *dev, u32 reg, u32 val)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
nv_wo32(drm->device, reg, val);
}
u32
_nv_mask(struct drm_device *dev, u32 reg, u32 mask, u32 val)
{
u32 tmp = _nv_rd32(dev, reg);
_nv_wr32(dev, reg, (tmp & ~mask) | val);
return tmp;
}
bool
_nv_bios(struct drm_device *dev, u8 **data, u32 *size)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_bios *bios = nouveau_bios(drm->device);
*data = bios->data;
*size = bios->size;
return true;
}
void
nouveau_gpio_reset(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
gpio->reset(gpio);
}
int
nouveau_gpio_find(struct drm_device *dev, int idx, u8 tag, u8 line,
struct dcb_gpio_func *func)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
return gpio->find(gpio, idx, tag, line, func);
}
bool
nouveau_gpio_func_valid(struct drm_device *dev, u8 tag)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
struct dcb_gpio_func func;
return gpio->find(gpio, 0, tag, 0xff, &func) == 0;
}
int
nouveau_gpio_func_set(struct drm_device *dev, u8 tag, int state)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
if (gpio && gpio->get)
return gpio->set(gpio, 0, tag, 0xff, state);
return -ENODEV;
}
int
nouveau_gpio_func_get(struct drm_device *dev, u8 tag)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
if (gpio && gpio->get)
return gpio->get(gpio, 0, tag, 0xff);
return -ENODEV;
}
int
nouveau_gpio_irq(struct drm_device *dev, int idx, u8 tag, u8 line, bool on)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
if (gpio && gpio->irq)
return gpio->irq(gpio, idx, tag, line, on);
return -ENODEV;
}
int
nouveau_gpio_isr_add(struct drm_device *dev, int idx, u8 tag, u8 line,
void (*exec)(void *, int state), void *data)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
if (gpio && gpio->isr_add)
return gpio->isr_add(gpio, idx, tag, line, exec, data);
return -ENODEV;
}
void
nouveau_gpio_isr_del(struct drm_device *dev, int idx, u8 tag, u8 line,
void (*exec)(void *, int state), void *data)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
if (gpio && gpio->isr_del)
gpio->isr_del(gpio, idx, tag, line, exec, data);
}
struct nouveau_i2c_port *
nouveau_i2c_find(struct drm_device *dev, u8 index)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
return i2c->find(i2c, index);
}
bool
nouveau_probe_i2c_addr(struct nouveau_i2c_port *port, int addr)
{
return nv_probe_i2c(port, addr);
}
struct i2c_adapter *
nouveau_i2c_adapter(struct nouveau_i2c_port *port)
{
return &port->adapter;
}
int
nouveau_i2c_identify(struct drm_device *dev, const char *what,
struct i2c_board_info *info,
bool (*match)(struct nouveau_i2c_port *,
struct i2c_board_info *),
int index)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
return i2c->identify(i2c, index, what, info, match);
}
int
auxch_rd(struct drm_device *dev, struct nouveau_i2c_port *port,
u32 addr, u8 *data, u8 size)
{
return nv_rdaux(port, addr, data, size);
}
int
auxch_wr(struct drm_device *dev, struct nouveau_i2c_port *port,
u32 addr, u8 *data, u8 size)
{
return nv_wraux(port, addr, data, size);
}
u32
get_pll_register(struct drm_device *dev, u32 type)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_bios *bios = nouveau_bios(drm->device);
struct nvbios_pll info;
if (nvbios_pll_parse(bios, type, &info))
return 0;
return info.reg;
}
int
get_pll_limits(struct drm_device *dev, u32 type, struct nvbios_pll *info)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_bios *bios = nouveau_bios(drm->device);
return nvbios_pll_parse(bios, type, info);
}
int
setPLL(struct drm_device *dev, u32 reg, u32 freq)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_clock *clk = nouveau_clock(drm->device);
int ret = -ENODEV;
if (clk->pll_set)
ret = clk->pll_set(clk, reg, freq);
return ret;
}
int
nouveau_calc_pll_mnp(struct drm_device *dev, struct nvbios_pll *info,
int freq, struct nouveau_pll_vals *pv)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_clock *clk = nouveau_clock(drm->device);
int ret = 0;
if (clk->pll_calc)
ret = clk->pll_calc(clk, info, freq, pv);
return ret;
}
int
nouveau_hw_setpll(struct drm_device *dev, u32 reg1,
struct nouveau_pll_vals *pv)
{
struct nouveau_drm *drm = nouveau_newpriv(dev);
struct nouveau_clock *clk = nouveau_clock(drm->device);
int ret = -ENODEV;
if (clk->pll_prog)
ret = clk->pll_prog(clk, reg1, pv);
return ret;
}
int nva3_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
int *N, int *fN, int *M, int *P);
int