/*
*/
#include <sys/visual_io.h>
#if VIS_CONS_REV > 2
#include "efb.h"
/*
* Internal functions
*/
static int efb_map_dfb(drm_device_t *);
static void efb_termemu_display(efb_private_t *,
struct efb_vis_draw_data *);
static void efb_polled_conscursor(struct vis_polledio_arg *,
struct vis_conscursor *);
static void efb_polled_consdisplay(struct vis_polledio_arg *,
struct vis_consdisplay *);
static void efb_polled_conscopy(struct vis_polledio_arg *,
struct vis_conscopy *);
static int efb_invalidate_userctx(efb_private_t *);
static void efb_restore_kcmap(efb_private_t *);
static void efb_setup_cmap32(efb_private_t *);
static void efb_polled_check_power(efb_private_t *);
/*
* All functions called in polled I/O mode should not have lock
* ASSERT, for lock is not available in polled I/O mode. Each
* time polled routines (e.g. efb_polled_consdisplay) are called,
* efb_in_polledio is set and then PASSERT will just simply succeed.
*/
int volatile efb_in_polledio = 0;
static void efb_polledio_enter(void);
static void efb_polledio_exit(void);
int
{
};
else
0, 0x8000000, &fbMem,
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
extern int
{
int i;
return (EPERM);
}
/*
* Read the terminal emulator's change mode callback
* address out of the incoming structure
*/
return (EFAULT);
}
DRM_LOCK();
/*
* Allocate memory needed by the the kernel console
*/
}
(struct vis_polledio_arg *)efb_priv;
}
/*
* Determine which video stream the console will render on.
*/
switch (efb_priv->primary_stream) {
case 0: /* PROM version 1.10 or earlier uses 0 to mean stream 1 */
case 1:
break;
case 2:
break;
}
/*
* Extract the terminal emulator's video mode change notification
* callback information from the incoming struct
*/
/*
* Describe this driver's configuration for the caller.
*/
/* color_map ? */
/*
* Setup the standalone access (polled mode) entry points
* which are also passed back to the terminal emulator.
*/
/*
* Get our view of the console as scribbling pad of memory.
* (dumb framebuffer)
*/
DRM_UNLOCK();
return (ENOMEM);
}
/*
* Calculate the FULL length of a horizontal line of pixel
* memory including both the visible portion and the portion
* that extends past the visible boundary on the right.
* (The invisible section is where any rounding excess
* goes to accomodate to the 64 or 256 byte rounding
* requirements of certain device functional block
* components).
*/
else
/*
* Clear colormap update flags so we can do lazy loading
*/
for (i = 0; i < EFB_CMAP_ENTRIES; i++) {
efb_priv->cmap_flags[0][i] = 0;
}
/*
* TrueColor 24 _requires_ prepping the DAC properly, although it
* isn't documented in the Radeon PDF files (there is a reference
* in the Mach64 documents, however).
*/
DRM_UNLOCK();
/*
* Send framebuffer kernel console rendering parameters back to the
* terminal emulator
*/
return (EFAULT);
return (DDI_SUCCESS);
}
/*
* This calls back into the terminal emulator to inform it of
* a driver mode change.
*/
extern void
{
int surface_cntl;
int validated = 0;
int ntry = 0;
DRM_LOCK();
/* make sure we have the right stream */
* npixels;
} else {
* npixels;
}
ntry++;
} else {
validated = 1;
}
}
case 8:
break;
case 32:
break;
}
efb_priv->setting_videomode = 0;
if (surface_cntl &
/* 00rrggbb */
} else {
/* bbggrr00 */
}
DRM_UNLOCK();
DRM_LOCK();
DRM_UNLOCK();
&devinit);
}
}
extern int
{
return (EPERM);
DRM_LOCK();
sizeof (struct vis_polledio));
}
}
}
DRM_UNLOCK();
return (DDI_SUCCESS);
}
/*
* colormap manipulation entry points -------------------------------------
*
* For 8-bit a'lazy loading' scheme is used so that only restore cmap entries
* that have been flagged as in use by the terminal emulator. The highest
* ordered cmap entry that has been accessed since console's VIS_DEVINIT
* ioctl was invoked is tracked to optimize colormap restoration for speed.
*
* For 32-bit depth the DAC must be initialized for linear TrueColor 24 before
* the colors will work properly.
*/
/*
* Initialize the cmap for the current fb depth
*/
static void
{
int i;
for (i = 0; i < EFB_CMAP_ENTRIES; i++) {
}
}
/*
* This function is called to save a copy of the kernel terminal emulator's c
* color map when a VIS_PUTCMAP ioctl is issued to the driver.
*/
extern int
{
int stream;
int i;
return (EPERM);
}
return (DDI_SUCCESS);
}
/*
* Re-establish the kernel's 8-bit color map.
*/
static void
{
int i;
case 8:
}
}
break;
case 32:
/*
* This is a quick chance to see if we've set up the colormap
* properly. It is executed for each character so we want to
* keep it optimized. It seems to work. Worst case, some
* sort of sparse but more thorough checking could be done.
* This seems to work for the simple tradeoff between the
* X server's colormaps and the kernel terminal emulator's.
*/
break;
}
}
/*
* ioctl entry points -------------------------------------------------
*
* The ioctl interface tactics differ from the polled interface's.
* The console ioctls need to do context management (ie. unload user mappings,
* save user context, load kernel's context). However since the kernel's
* context isn't associated with memory mappings, the DDI won't prod us to
* re-establish the kernel's context if userland interrupts us. Therefore,
* we prevent interruption for the duration of any given rendering operation
* (ie. displaying character, scrolling one line, or displaying cursor),
* by holding the context lock.
*
* Each rendering operation depends on a particular static setup of the mach64
* draw engine state. Besides that, anything the kernel console rendering
* functions change in the draw engine state can be discarded, because they
* are re-initialized at each rendering operation. Therefore the static
* state is saved once when the kernel context is created, and then loaded,
* but not saved thereafter.
*
*/
extern int
{
return (EPERM);
return (EFAULT);
return (ENOMEM);
}
if (tmp)
}
image_size, flag))
return (EFAULT);
return (EINVAL);
}
DRM_LOCK();
/* Just return if videomode change is on-going */
if (efb_priv->setting_videomode) {
DRM_UNLOCK();
return (DDI_SUCCESS);
}
}
DRM_UNLOCK();
return (DDI_SUCCESS);
}
extern int
{
return (EPERM);
sizeof (struct vis_conscopy), flag))
return (EFAULT);
return (EINVAL);
}
DRM_LOCK();
/* Just return if videomode change is on-going */
if (efb_priv->setting_videomode) {
DRM_UNLOCK();
return (DDI_SUCCESS);
}
DRM_UNLOCK();
return (DDI_SUCCESS);
}
extern int
{
return (EPERM);
sizeof (struct vis_conscursor), flag))
return (EFAULT);
return (EINVAL);
}
DRM_LOCK();
/* Just return if videomode change is on-going */
if (efb_priv->setting_videomode) {
DRM_UNLOCK();
return (DDI_SUCCESS);
}
DRM_UNLOCK();
return (DDI_SUCCESS);
}
/*
* Polled I/O Entry Points. -----------------------------------------
*
* The tactics in these routines are based on the fact that we are
* -only- called in standalone mode. Therefore time is frozen
* for us. We sneak in restore the kernel's colormap, establish
* the kernel's draw engine context, render, and then replace the
* previous context -- no one the wiser for it.
*
* In polled I/O mode (also called standalone mode), the kernel isn't
* running, Only one CPU is enabled, system services are not running,
* and all access is single-threaded. The limitations of standalone
* mode are: (1) The driver cannot wait for interrupts, (2) The driver
* cannot use mutexes, (3) The driver cannot allocate memory.
*
* The advantage of polled I/O mode is, that because we don't have to
* worry about concurrent access to device state, we don't need to
* unload mappings and can perform a lighter form of graphics context
* switching, which doesn't require the use of mutexes.
*
*/
/*
* Setup for DFB rectangle BLIT on a "quiesced" system
*/
static void
struct vis_consdisplay *efb_cd)
{
}
/*
* Setup for DFB rectangle copy (vertical scroll) on
* a "quiesced: system.
*/
static void
struct vis_conscopy *efb_cpydata)
{
}
/*
* Setup for DFB inverting rectangle BLIT (cursor)
* on a "quiesced" system.
*
*/
static void
struct vis_conscursor *efb_cc)
{
}
/* ----------------------------------------------------------- */
/*
* Copy to DFB a rectangular image whose size, coordinates and pixels
* are defined in the draw struct. The proper pixel conversions
* are made based on the video mode depth. This operation is implemented
* in terms of memory copies.
*/
static void
{
void *pixp;
int r, c, y, x, h, w;
h = efb_draw->image_height;
w = efb_draw->image_width;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
case 32:
/* disp is 00rrggbb */
disp++;
/* Transform into DFB byte order */
break;
case 8: /* 8-bit color map index */
b = *disp++;
break;
}
}
}
}
/*
* for the current screen depth. Due to the difficulty of managing
* a cursor with the multitude of foreground/background text colors,
* and framebuffer depths with simple ALU operations, particularly
* in 8-bit psuedocolor mode, the cursor is always displayed along
* retains good legibility for all ANSI fg and bg combinations.
* in all depths.
*
* This approach requires saving the contents under the cursor so
* they can be restored when the cursor moves by re-blitting them
* onto the DFB, rather than using a heuristic.
*
* For the SHOW_CURSOR operation, the contents beneath the cursor
* are saved before displaying the monochrome overlay in anticipation
* of a HIDE_CURSOR operation over the same location, prior to moving
* the cursor to a new location.
*
* The HIDE_CURSOR function simply replaces the text saved under
* the cursor rectangle during the previous SHOW_CURSOR operation.
*
* This protocol necessitates tight cursor protocol agreement
* with the terminal emulator.
*
*/
static void
{
int x, y;
/*
*/
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
}
}
} else {
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
}
}
}
}
static void
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
}
}
} else {
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
}
}
}
}
static void
{
case 32:
break;
case 8:
break;
}
}
/*
* This function implements scrolling by copying a rectangular block of
* pixels upward on the Y-axis. The caller provides block copy parameters
* as a rectangle, defined by (s_col, s_row), (e_col, e_row) and target
* coords (t_col, t_row).
*
* This implementation uses the Radeon GUI engine to accomplish this faster
* than memory moves done from software. It is left to the caller to
* establish the kernel's graphic context prior to calling this function.
*/
static void
{
int i;
} else
} else
switch (depth) {
case 8:
break;
case 32:
}
/*
* Initialize GUI engine
*/
gmc_bpp |
regw(DST_LINE_START, 0);
regw(DST_LINE_END, 0);
/*
* Switch access mode to PIO
*/
for (i = 0;
i++) {
;
}
/*
* perform the copy
*/
}
/*
* This function invalidates the user's GUI context.
*
* It MUST NOT be called in standalone (polled I/O mode). Polled I/O
* operates within an incompatible set of constraints and liberties.
*
* If there is a user context currently active, this function tears
* down the user mappings and saves the user's context. The strategy
* is to make kernel operations uninterruptable from a user mapping,
*
* This routine exits HOLDING softc->softc_lock, WHICH THE *CALLER*
* MUST RELEASE. This makes each of the following console functions atomic,
* ie. Draw one character, scroll one line, render one cursor.
*
*/
static int
{
/*
* Make sure it's safe to do the context switch
*/
}
return (DDI_SUCCESS);
}
/*
* Validate the parameters for the data to be displayed on the
* console.
*
* 1. Verify beginning (X,Y) coords are in the displayed area of fb.
* 2. Verify that the character doesn't extend beyond displayed area.
*
* If characters exceed perimiter, clip if possible by adjusting
* size of characters. This allows the terminal emulator to clear
* the full screen or reverse video by writing characters all the way
* to the screen edge, merely clipping rather than rejecting all
* but the most egregious overlap.
*/
static int
{
return (EINVAL);
else
return (EINVAL);
}
else
return (EINVAL);
}
return (DDI_SUCCESS);
}
/*
* Validate the parameters for the data to be displayed on the
* console.
*
* 1. Verify beginning (X,Y) coords are in the displayed area of fb.
* 2. Verify that the character doesn't extend beyond displayed area.
*/
static int
{
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (DDI_SUCCESS);
}
/*
* Validate the parameters for the source and destination rectangles.
*/
static int
{
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (DDI_SUCCESS);
}
/*
* Since being in polled I/O mode, the kernel already has
* exclusive access to hardware, so we do not need to
* invalidate user context.
*/
static void
{
#if 0
}
} else {
}
#else
#endif
}
static void
efb_polledio_enter(void)
{
efb_in_polledio = 1;
}
static void
efb_polledio_exit(void)
{
efb_in_polledio = 0;
}
#endif /* VIS_CONS_REV */