Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb75d97e authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau: implement devinit subdev, and new init table parser



v2:
- make sure not to execute display scripts unless resuming

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 70790f4f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -20,9 +20,12 @@ nouveau-y += core/core/subdev.o

nouveau-y += core/subdev/bios/base.o
nouveau-y += core/subdev/bios/bit.o
nouveau-y += core/subdev/bios/conn.o
nouveau-y += core/subdev/bios/dcb.o
nouveau-y += core/subdev/bios/dp.o
nouveau-y += core/subdev/bios/gpio.o
nouveau-y += core/subdev/bios/i2c.o
nouveau-y += core/subdev/bios/init.o
nouveau-y += core/subdev/bios/pll.o
nouveau-y += core/subdev/clock/nv04.o
nouveau-y += core/subdev/clock/nv40.o
@@ -40,6 +43,13 @@ nouveau-y += core/subdev/device/nv40.o
nouveau-y += core/subdev/device/nv50.o
nouveau-y += core/subdev/device/nvc0.o
nouveau-y += core/subdev/device/nve0.o
nouveau-y += core/subdev/devinit/base.o
nouveau-y += core/subdev/devinit/nv04.o
nouveau-y += core/subdev/devinit/nv05.o
nouveau-y += core/subdev/devinit/nv10.o
nouveau-y += core/subdev/devinit/nv1a.o
nouveau-y += core/subdev/devinit/nv20.o
nouveau-y += core/subdev/devinit/nv50.o
nouveau-y += core/subdev/fb/nv04.o
nouveau-y += core/subdev/fb/nv10.o
nouveau-y += core/subdev/fb/nv20.o
+27 −0
Original line number Diff line number Diff line
#ifndef __NVBIOS_CONN_H__
#define __NVBIOS_CONN_H__

enum dcb_connector_type {
	DCB_CONNECTOR_VGA = 0x00,
	DCB_CONNECTOR_TV_0 = 0x10,
	DCB_CONNECTOR_TV_1 = 0x11,
	DCB_CONNECTOR_TV_3 = 0x13,
	DCB_CONNECTOR_DVI_I = 0x30,
	DCB_CONNECTOR_DVI_D = 0x31,
	DCB_CONNECTOR_DMS59_0 = 0x38,
	DCB_CONNECTOR_DMS59_1 = 0x39,
	DCB_CONNECTOR_LVDS = 0x40,
	DCB_CONNECTOR_LVDS_SPWG = 0x41,
	DCB_CONNECTOR_DP = 0x46,
	DCB_CONNECTOR_eDP = 0x47,
	DCB_CONNECTOR_HDMI_0 = 0x60,
	DCB_CONNECTOR_HDMI_1 = 0x61,
	DCB_CONNECTOR_DMS59_DP0 = 0x64,
	DCB_CONNECTOR_DMS59_DP1 = 0x65,
	DCB_CONNECTOR_NONE = 0xff
};

u16 dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len);

#endif
+72 −1
Original line number Diff line number Diff line
#ifndef __NVBIOS_DCB_H__
#define __NVBIOS_DCB_H__

struct nouveau_bios;

enum dcb_output_type {
	DCB_OUTPUT_ANALOG	= 0x0,
	DCB_OUTPUT_TV		= 0x1,
	DCB_OUTPUT_TMDS		= 0x2,
	DCB_OUTPUT_LVDS		= 0x3,
	DCB_OUTPUT_DP		= 0x4,
	DCB_OUTPUT_DP		= 0x6,
	DCB_OUTPUT_EOL		= 0xe,
	DCB_OUTPUT_UNUSED	= 0xf,
	DCB_OUTPUT_ANY = -1,
};

struct dcb_output {
	int index;	/* may not be raw dcb index if merging has happened */
	enum dcb_output_type type;
	uint8_t i2c_index;
	uint8_t heads;
	uint8_t connector;
	uint8_t bus;
	uint8_t location;
	uint8_t or;
	bool duallink_possible;
	union {
		struct sor_conf {
			int link;
		} sorconf;
		struct {
			int maxfreq;
		} crtconf;
		struct {
			struct sor_conf sor;
			bool use_straps_for_mode;
			bool use_acpi_for_edid;
			bool use_power_scripts;
		} lvdsconf;
		struct {
			bool has_component_output;
		} tvconf;
		struct {
			struct sor_conf sor;
			int link_nr;
			int link_bw;
		} dpconf;
		struct {
			struct sor_conf sor;
			int slave_addr;
		} tmdsconf;
	};
	bool i2c_upper_default;
};

u16 dcb_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len);
@@ -16,4 +58,33 @@ u16 dcb_outp(struct nouveau_bios *, u8 idx, u8 *ver, u8 *len);
int dcb_outp_foreach(struct nouveau_bios *, void *data, int (*exec)
		     (struct nouveau_bios *, void *, int index, u16 entry));


/* BIT 'U'/'d' table encoder subtables have hashes matching them to
 * a particular set of encoders.
 *
 * This function returns true if a particular DCB entry matches.
 */
static inline bool
dcb_hash_match(struct dcb_output *dcb, u32 hash)
{
	if ((hash & 0x000000f0) != (dcb->location << 4))
		return false;
	if ((hash & 0x0000000f) != dcb->type)
		return false;
	if (!(hash & (dcb->or << 16)))
		return false;

	switch (dcb->type) {
	case DCB_OUTPUT_TMDS:
	case DCB_OUTPUT_LVDS:
	case DCB_OUTPUT_DP:
		if (hash & 0x00c00000) {
			if (!(hash & (dcb->sorconf.link << 22)))
				return false;
		}
	default:
		return true;
	}
}

#endif
+8 −0
Original line number Diff line number Diff line
#ifndef __NVBIOS_DP_H__
#define __NVBIOS_DP_H__

u16 dp_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 dp_outp(struct nouveau_bios *, u8 idx, u8 *ver, u8 *len);
u16 dp_outp_match(struct nouveau_bios *, struct dcb_output *, u8 *ver, u8 *len);

#endif
+21 −0
Original line number Diff line number Diff line
#ifndef __NVBIOS_INIT_H__
#define __NVBIOS_INIT_H__

struct nvbios_init {
	struct nouveau_subdev *subdev;
	struct nouveau_bios *bios;
	u16 offset;
	struct dcb_output *outp;
	int crtc;

	/* internal state used during parsing */
	u8 execute;
	u32 nested;
	u16 repeat;
	u16 repend;
};

int nvbios_exec(struct nvbios_init *);
int nvbios_init(struct nouveau_subdev *, bool execute);

#endif
Loading