Commit 70c0f263 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/bios: pull in basic vbios subdev, more to come later

v2: Ben Skeggs <bskeggs@redhat.com>
- use unaligned macros to access vbios image
- endianness fixes
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 586c55f6
...@@ -18,6 +18,8 @@ nouveau-y += core/core/printk.o ...@@ -18,6 +18,8 @@ nouveau-y += core/core/printk.o
nouveau-y += core/core/ramht.o nouveau-y += core/core/ramht.o
nouveau-y += core/core/subdev.o nouveau-y += core/core/subdev.o
nouveau-y += core/subdev/bios/base.o
nouveau-y += core/subdev/bios/bit.o
nouveau-y += core/subdev/device/base.o nouveau-y += core/subdev/device/base.o
nouveau-y += core/subdev/device/nv04.o nouveau-y += core/subdev/device/nv04.o
nouveau-y += core/subdev/device/nv10.o nouveau-y += core/subdev/device/nv10.o
......
#ifndef __NOUVEAU_BIOS_H__
#define __NOUVEAU_BIOS_H__
#include <core/subdev.h>
#include <core/device.h>
struct nouveau_bios {
struct nouveau_subdev base;
u32 size;
u8 *data;
u32 bmp_offset;
u32 bit_offset;
struct {
u8 major;
u8 chip;
u8 minor;
u8 micro;
} version;
};
static inline struct nouveau_bios *
nouveau_bios(void *obj)
{
return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VBIOS];
}
u8 nvbios_checksum(const u8 *data, int size);
u16 nvbios_findstr(const u8 *data, int size, const char *str, int len);
extern struct nouveau_oclass nouveau_bios_oclass;
#endif
#ifndef __NVBIOS_BIT_H__
#define __NVBIOS_BIT_H__
struct bit_entry {
u8 id;
u8 version;
u16 length;
u16 offset;
};
int bit_entry(struct nouveau_bios *, u8 id, struct bit_entry *);
#endif
#ifndef __NVBIOS_BMP_H__
#define __NVBIOS_BMP_H__
static inline u16
bmp_version(struct nouveau_bios *bios)
{
if (bios->bmp_offset) {
return nv_ro08(bios, bios->bmp_offset + 5) << 8 |
nv_ro08(bios, bios->bmp_offset + 6);
}
return 0x0000;
}
static inline u16
bmp_mem_init_table(struct nouveau_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nv_ro16(bios, bios->bmp_offset + 24);
return 0x0000;
}
static inline u16
bmp_sdr_seq_table(struct nouveau_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nv_ro16(bios, bios->bmp_offset + 26);
return 0x0000;
}
static inline u16
bmp_ddr_seq_table(struct nouveau_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nv_ro16(bios, bios->bmp_offset + 28);
return 0x0000;
}
#endif
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/unaligned.h>
static inline int static inline int
ffsll(u64 mask) ffsll(u64 mask)
{ {
......
This diff is collapsed.
/*
* Copyright 2012 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 "core/object.h"
#include "subdev/bios.h"
#include "subdev/bios/bit.h"
int
bit_entry(struct nouveau_bios *bios, u8 id, struct bit_entry *bit)
{
if (likely(bios->bit_offset)) {
u8 entries = nv_ro08(bios, bios->bit_offset + 10);
u32 entry = bios->bit_offset + 12;
while (entries--) {
if (nv_ro08(bios, entry + 0) == id) {
bit->id = nv_ro08(bios, entry + 0);
bit->version = nv_ro08(bios, entry + 1);
bit->length = nv_ro16(bios, entry + 2);
bit->offset = nv_ro16(bios, entry + 4);
return 0;
}
entry += nv_ro08(bios, bios->bit_offset + 9);
}
return -ENOENT;
}
return -EINVAL;
}
...@@ -23,14 +23,17 @@ ...@@ -23,14 +23,17 @@
*/ */
#include <subdev/device.h> #include <subdev/device.h>
#include <subdev/bios.h>
int int
nv04_identify(struct nouveau_device *device) nv04_identify(struct nouveau_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0x04: case 0x04:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x05: case 0x05:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
default: default:
nv_fatal(device, "unknown RIVA chipset\n"); nv_fatal(device, "unknown RIVA chipset\n");
......
...@@ -23,26 +23,35 @@ ...@@ -23,26 +23,35 @@
*/ */
#include <subdev/device.h> #include <subdev/device.h>
#include <subdev/bios.h>
int int
nv10_identify(struct nouveau_device *device) nv10_identify(struct nouveau_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0x10: case 0x10:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x15: case 0x15:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x16: case 0x16:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x1a: case 0x1a:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x11: case 0x11:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x17: case 0x17:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x1f: case 0x1f:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x18: case 0x18:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
default: default:
nv_fatal(device, "unknown Celsius chipset\n"); nv_fatal(device, "unknown Celsius chipset\n");
......
...@@ -23,18 +23,23 @@ ...@@ -23,18 +23,23 @@
*/ */
#include <subdev/device.h> #include <subdev/device.h>
#include <subdev/bios.h>
int int
nv20_identify(struct nouveau_device *device) nv20_identify(struct nouveau_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0x20: case 0x20:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x25: case 0x25:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x28: case 0x28:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x2a: case 0x2a:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
default: default:
nv_fatal(device, "unknown Kelvin chipset\n"); nv_fatal(device, "unknown Kelvin chipset\n");
......
...@@ -23,20 +23,26 @@ ...@@ -23,20 +23,26 @@
*/ */
#include <subdev/device.h> #include <subdev/device.h>
#include <subdev/bios.h>
int int
nv30_identify(struct nouveau_device *device) nv30_identify(struct nouveau_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0x30: case 0x30:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x35: case 0x35:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x31: case 0x31:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x36: case 0x36:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x34: case 0x34:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
default: default:
nv_fatal(device, "unknown Rankine chipset\n"); nv_fatal(device, "unknown Rankine chipset\n");
......
...@@ -23,42 +23,59 @@ ...@@ -23,42 +23,59 @@
*/ */
#include <subdev/device.h> #include <subdev/device.h>
#include <subdev/bios.h>
int int
nv40_identify(struct nouveau_device *device) nv40_identify(struct nouveau_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0x40: case 0x40:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x41: case 0x41:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x42: case 0x42:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x43: case 0x43:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x45: case 0x45:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x47: case 0x47:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x49: case 0x49:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x4b: case 0x4b:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x44: case 0x44:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x46: case 0x46:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x4a: case 0x4a:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x4c: case 0x4c:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x4e: case 0x4e:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x63: case 0x63:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x67: case 0x67:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x68: case 0x68:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
default: default:
nv_fatal(device, "unknown Curie chipset\n"); nv_fatal(device, "unknown Curie chipset\n");
......
...@@ -23,38 +23,53 @@ ...@@ -23,38 +23,53 @@
*/ */
#include <subdev/device.h> #include <subdev/device.h>
#include <subdev/bios.h>
int int
nv50_identify(struct nouveau_device *device) nv50_identify(struct nouveau_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0x50: case 0x50:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x84: case 0x84:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x86: case 0x86:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x92: case 0x92:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x94: case 0x94:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x96: case 0x96:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0x98: case 0x98:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xa0: case 0xa0:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xaa: case 0xaa:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xac: case 0xac:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xa3: case 0xa3:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xa5: case 0xa5:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xa8: case 0xa8:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xaf: case 0xaf:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
default: default:
nv_fatal(device, "unknown Tesla chipset\n"); nv_fatal(device, "unknown Tesla chipset\n");
......
...@@ -23,26 +23,35 @@ ...@@ -23,26 +23,35 @@
*/ */
#include <subdev/device.h> #include <subdev/device.h>
#include <subdev/bios.h>
int int
nvc0_identify(struct nouveau_device *device) nvc0_identify(struct nouveau_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0xc0: case 0xc0:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xc4: case 0xc4:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xc3: case 0xc3:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xce: case 0xce:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xcf: case 0xcf:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xc1: case 0xc1:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xc8: case 0xc8:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xd9: case 0xd9:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
default: default:
nv_fatal(device, "unknown Fermi chipset\n"); nv_fatal(device, "unknown Fermi chipset\n");
......
...@@ -23,14 +23,17 @@ ...@@ -23,14 +23,17 @@
*/ */
#include <subdev/device.h> #include <subdev/device.h>
#include <subdev/bios.h>
int int
nve0_identify(struct nouveau_device *device) nve0_identify(struct nouveau_device *device)
{ {
switch (device->chipset) { switch (device->chipset) {
case 0xe4: case 0xe4:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
case 0xe7: case 0xe7:
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
break; break;
default: default:
nv_fatal(device, "unknown Kepler chipset\n"); nv_fatal(device, "unknown Kepler chipset\n");
......
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