⛏️ index : haiku.git

/*
 * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *		Axel DΓΆrfler, axeld@pinc-software.de
 *		Alexander von Gluck, kallisti5@unixzen.com
 */
#ifndef RADEON_HD_ACCELERANT_H
#define RADEON_HD_ACCELERANT_H


#include <ByteOrder.h>
#include <edid.h>

#include "atom.h"
#include "dp.h"
#include "encoder.h"
#include "mode.h"
#include "pll.h"
#include "radeon_hd.h"
#include "ringqueue.h"


#define MAX_DISPLAY 2
	// Maximum displays (more then two requires AtomBIOS)
#define MAX_GPIO_PINS   64
	// Maximum possible GPIO pins in gGPIOInfo

struct gpu_state {
	uint32 d1vgaControl;
	uint32 d2vgaControl;
	uint32 vgaRenderControl;
	uint32 vgaHdpControl;
	uint32 d1crtcControl;
	uint32 d2crtcControl;
};


struct fb_info {
	bool		valid;
	uint64		vramStart;
	uint64		vramEnd;
	uint64		vramSize;

	uint64		gartStart;
	uint64		gartEnd;
	uint64		gartSize;
	uint64		agpBase;
};


struct accelerant_info {
	vuint8*			regs;
	area_id			regs_area;

	radeon_shared_info* shared_info;
	area_id			shared_info_area;

	display_mode*	mode_list;		// cloned list of standard display modes
	area_id			mode_list_area;

	uint8*			rom;
	area_id			rom_area;

	edid1_info		edid_info;
	bool			has_edid;

	int				device;
	bool			is_clone;

	struct fb_info	fb;	// used for frame buffer info within MC

	volatile uint32	dpms_mode;		// current driver dpms mode

	uint32			maximumPixelClock;
	uint32			displayClockFrequency;
	uint32			dpExternalClock;

	uint32			lvdsSpreadSpectrumID;

	RingQueue*		ringQueue[RADEON_QUEUE_MAX]; // Ring buffer command processor
};


struct register_info {
	uint16	crtcOffset;
	uint16	vgaControl;
	uint16	grphEnable;
	uint16	grphControl;
	uint16	grphSwapControl;
	uint16	grphPrimarySurfaceAddr;
	uint16	grphSecondarySurfaceAddr;
	uint16	grphPrimarySurfaceAddrHigh;
	uint16	grphSecondarySurfaceAddrHigh;
	uint16	grphPitch;
	uint16	grphSurfaceOffsetX;
	uint16	grphSurfaceOffsetY;
	uint16	grphXStart;
	uint16	grphYStart;
	uint16	grphXEnd;
	uint16	grphYEnd;
	uint16	modeDesktopHeight;
	uint16	modeDataFormat;
	uint16	viewportStart;
	uint16	viewportSize;
};


typedef struct {
	bool	valid;

	uint32	hwPin;	// GPIO hardware pin on GPU
	uint32	hwReg;	// GPIO register
	uint32	hwMask;	// GPIO pin mask

	struct {
		bool valid;
		bool hwCapable;	// can do hw assisted i2c
		uint32 sclMaskReg;
		uint32 sdaMaskReg;
		uint32 sclMask;
		uint32 sdaMask;

		uint32 sclEnReg;
		uint32 sdaEnReg;
		uint32 sclEnMask;
		uint32 sdaEnMask;

		uint32 sclYReg;
		uint32 sdaYReg;
		uint32 sclYMask;
		uint32 sdaYMask;

		uint32 sclAReg;
		uint32 sdaAReg;
		uint32 sclAMask;
		uint32 sdaAMask;
	} i2c;
} gpio_info;


struct encoder_info {
	bool		valid;
	uint16		objectID;
	uint32		type;
	uint32		capabilities;
	uint32		linkEnumeration; // ex. linkb == GRAPH_OBJECT_ENUM_ID2
	bool		isExternal;
	bool		isDPBridge;
	struct pll_info	pll;
};


typedef struct {
	uint32		objectID;
	// i2c info
	uint16		i2cPinIndex; // id of gpio pin for i2c router
	uint32		i2cAddr;     // ?? hwPin??
	// i2c pin mux
	bool		ddcValid;
	uint8		ddcMuxType;
	uint8		ddcMuxControlPin;
	uint8		ddcMuxState;
	// clk / data pin mux
	bool		cdValid;
	uint8		cdMuxType;
	uint8		cdMuxControlPin;
	uint8		cdMuxState;
} router_info;


typedef struct {
	bool		valid;
	uint16		objectID;
	uint32		type;
	uint32		flags;
	uint32		lvdsFlags;
	uint16		i2cPinIndex; // id of gpio pin for i2c communications
	uint16		hpdPinIndex; // id of gpio pin for hotplug detection
	struct encoder_info encoder;
	struct encoder_info encoderExternal;
	dp_info		dpInfo;
	router_info	router;
} connector_info;


typedef struct {
	bool			attached;
	bool			powered;
	uint32			connectorIndex; // matches connector id in connector_info
	register_info*	regs;
	bool			foundRanges;
	uint32			vfreqMax;
	uint32			vfreqMin;
	uint32			hfreqMax;
	uint32			hfreqMin;
	edid1_info		edidData;
	display_mode	preferredMode;
	display_mode	currentMode;
} display_info;


// register MMIO modes
#define OUT 0x1	// Direct MMIO calls
#define CRT 0x2	// Crt controller calls
#define VGA 0x3 // Vga calls
#define PLL 0x4 // PLL calls
#define MC	0x5 // Memory controller calls


extern accelerant_info* gInfo;
extern atom_context* gAtomContext;
extern display_info* gDisplay[MAX_DISPLAY];
extern connector_info* gConnector[ATOM_MAX_SUPPORTED_DEVICE];
extern gpio_info* gGPIOInfo[MAX_GPIO_PINS];


// register access

inline uint32
_read32(uint32 offset)
{
	return *(volatile uint32*)(gInfo->regs + offset);
}


inline void
_write32(uint32 offset, uint32 value)
{
	*(volatile uint32 *)(gInfo->regs + offset) = value;
}


// AtomBIOS cail register calls (are *4... no clue why)
inline uint32
Read32Cail(uint32 offset)
{
	return _read32(offset * 4);
}


inline void
Write32Cail(uint32 offset, uint32 value)
{
	_write32(offset * 4, value);
}


inline uint32
Read32(uint32 subsystem, uint32 offset)
{
	switch (subsystem) {
		default:
		case OUT:
		case VGA:
		case CRT:
		case PLL:
			return _read32(offset);
		case MC:
			return _read32(offset);
	};
}


inline void
Write32(uint32 subsystem, uint32 offset, uint32 value)
{
	switch (subsystem) {
		default:
		case OUT:
		case VGA:
		case CRT:
		case PLL:
			_write32(offset, value);
			return;
		case MC:
			_write32(offset, value);
			return;
	};
}


inline void
Write32Mask(uint32 subsystem, uint32 offset, uint32 value, uint32 mask)
{
	uint32 temp;
	switch (subsystem) {
		default:
		case OUT:
		case VGA:
		case MC:
			temp = _read32(offset);
			break;
		case CRT:
			temp = _read32(offset);
			break;
		case PLL:
			temp = _read32(offset);
			//temp = _read32PLL(offset);
			break;
	};

	// only effect mask
	temp &= ~mask;
	temp |= value & mask;

	switch (subsystem) {
		default:
		case OUT:
		case VGA:
		case MC:
			_write32(offset, temp);
			return;
		case CRT:
			_write32(offset, temp);
			return;
		case PLL:
			_write32(offset, temp);
			//_write32PLL(offset, temp);
			return;
	};
}


#endif	/* RADEON_HD_ACCELERANT_H */