summaryrefslogtreecommitdiff
path: root/kms++util/src
AgeCommit message (Collapse)Author
2017-10-03Rework framebuffer classesTomi Valkeinen
Drop (I)MappedFramebuffer, as it doesn't really provide any value, and have most of the methods be present in IFramebuffer with default exception throwing implementation. This gives us simpler way to use the framebuffers, as almost always we can just use a pointer to IFramebuffer.
2017-06-05testpat: fix the location of second diagonal lineTomi Valkeinen
2017-05-31Add different YCbCr encodings.Jyri Sarha
2017-05-18testpat: white box in top left cornerTomi Valkeinen
2017-05-18draw_char: use black bg for yuvTomi Valkeinen
2017-05-17draw_rect: support yuv modesTomi Valkeinen
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
2017-03-30resmgr: fix reserve_plane()Tomi Valkeinen
reserve_plane() had inverted check, and looked for any plane type but the one that was requested. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
2017-03-24resmgr: add sanity checksTomi Valkeinen
Add sanity checks to reserve_* methods, and return null if the give connector/crtc is null. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
2017-03-20ResourceManager: reserve_generic_plane() for either primary or overlayJyri Sarha
2017-02-10use reserve_connector from ResourceManagerTomi Valkeinen
2017-02-10fix race issue in threaded test pattern drawTomi Valkeinen
2016-08-15Merge branch 'master' of git://github.com/jsarha/kmsxxTomi Valkeinen
2016-08-15Fix byte order of 24-bit formats.Jyri Sarha
2016-08-15Add missing BGR color formats to draw_test_pattern_part().Jyri Sarha
2016-08-12ExtCPUFramebuffer: add size and offset paramsTomi Valkeinen
Add size and offset params to ExtCPUFramebuffer, so that we can fix fbtestpat's test pattern size on larger virtual fbdevs.
2016-08-11Add BGR888 (BG24) and BGR565 (BG16) pixelformats.Jyri Sarha
Note colorbar does not support 24 bit modes (RGB888 or BGR888) yet.
2016-06-22Add missing <system_error> includesTomi Valkeinen
Missing <system_error> breaks compliation on gcc 4.9. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
2016-06-16kmsutils: add VideoDeviceTomi Valkeinen
2016-06-16add ResourceManagerTomi Valkeinen
2016-06-16Support RGB888Tomi Valkeinen
2016-06-15draw_text: support YUV modesTomi Valkeinen
2016-06-11kms++util: split to subdirsTomi Valkeinen
href='#n285'>285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
/*
 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
 * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
 *
 * 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, sub license,
 * 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 (including the
 * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
 */
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <asm/io.h>
#include <linux/pci.h>

#include "via_ds.h"
extern unsigned int VIA_DEBUG;

set_t *via_setInit(void)
{
	int i;
	set_t *set;
	set = (set_t *) DRM(alloc) (sizeof(set_t), DRM_MEM_DRIVER);
	for (i = 0; i < SET_SIZE; i++) {
		set->list[i].free_next = i + 1;
		set->list[i].alloc_next = -1;
	}
	set->list[SET_SIZE - 1].free_next = -1;
	set->free = 0;
	set->alloc = -1;
	set->trace = -1;
	return set;
}

int via_setAdd(set_t * set, ITEM_TYPE item)
{
	int free = set->free;
	if (free != -1) {
		set->list[free].val = item;
		set->free = set->list[free].free_next;
	} else {
		return 0;
	}
	set->list[free].alloc_next = set->alloc;
	set->alloc = free;
	set->list[free].free_next = -1;
	return 1;
}

int via_setDel(set_t * set, ITEM_TYPE item)
{
	int alloc = set->alloc;
	int prev = -1;

	while (alloc != -1) {
		if (set->list[alloc].val == item) {
			if (prev != -1)
				set->list[prev].alloc_next =
				    set->list[alloc].alloc_next;
			else
				set->alloc = set->list[alloc].alloc_next;
			break;
		}
		prev = alloc;
		alloc = set->list[alloc].alloc_next;
	}

	if (alloc == -1)
		return 0;

	set->list[alloc].free_next = set->free;
	set->free = alloc;
	set->list[alloc].alloc_next = -1;

	return 1;
}

/* setFirst -> setAdd -> setNext is wrong */

int via_setFirst(set_t * set, ITEM_TYPE * item)
{
	if (set->alloc == -1)
		return 0;

	*item = set->list[set->alloc].val;
	set->trace = set->list[set->alloc].alloc_next;

	return 1;
}

int via_setNext(set_t * set, ITEM_TYPE * item)
{
	if (set->trace == -1)
		return 0;

	*item = set->list[set->trace].val;
	set->trace = set->list[set->trace].alloc_next;

	return 1;
}

int via_setDestroy(set_t * set)
{
	DRM(free) (set, sizeof(set_t), DRM_MEM_DRIVER);

	return 1;
}

#define ISFREE(bptr) ((bptr)->free)

#define PRINTF(fmt, arg...) do{}while(0)
#define fprintf(fmt, arg...) do{}while(0)

void via_mmDumpMemInfo(memHeap_t * heap)
{
	TMemBlock *p;

	PRINTF("Memory heap %p:\n", heap);

	if (heap == 0)
		PRINTF("  heap == 0\n");
	else {
		p = (TMemBlock *) heap;

		while (p) {
			PRINTF("  Offset:%08x, Size:%08x, %c%c\n", p->ofs,
			       p->size, p->free ? '.' : 'U',
			       p->reserved ? 'R' : '.');
			p = p->next;
		}
	}

	PRINTF("End of memory blocks\n");
}

memHeap_t *via_mmInit(int ofs, int size)
{
	PMemBlock blocks;

	if (size <= 0)
		return 0;

	blocks =
	    (TMemBlock *) DRM(calloc) (1, sizeof(TMemBlock), DRM_MEM_DRIVER);

	if (blocks) {
		blocks->ofs = ofs;
		blocks->size = size;
		blocks->free = 1;
		return (memHeap_t *) blocks;
	} else
		return 0;
}

memHeap_t *via_mmAddRange(memHeap_t * heap, int ofs, int size)
{
	PMemBlock blocks;
	blocks =
	    (TMemBlock *) DRM(calloc) (2, sizeof(TMemBlock), DRM_MEM_DRIVER);

	if (blocks) {
		blocks[0].size = size;
		blocks[0].free = 1;
		blocks[0].ofs = ofs;
		blocks[0].next = &blocks[1];

		/* Discontinuity - stops JoinBlock from trying to join non-adjacent
		 * ranges.
		 */
		blocks[1].size = 0;
		blocks[1].free = 0;
		blocks[1].ofs = ofs + size;
		blocks[1].next = (PMemBlock) heap;
		return (memHeap_t *) blocks;
	} else
		return heap;
}

static TMemBlock *SliceBlock(TMemBlock * p,
			     int startofs, int size,
			     int reserved, int alignment)
{
	TMemBlock *newblock;

	/* break left */
	if (startofs > p->ofs) {
		newblock =
		    (TMemBlock *) DRM(calloc) (1, sizeof(TMemBlock),
					       DRM_MEM_DRIVER);
		newblock->ofs = startofs;
		newblock->size = p->size - (startofs - p->ofs);
		newblock->free = 1;
		newblock->next = p->next;
		p->size -= newblock->size;
		p->next = newblock;
		p = newblock;
	}

	/* break right */
	if (size < p->size) {
		newblock =
		    (TMemBlock *) DRM(calloc) (1, sizeof(TMemBlock),
					       DRM_MEM_DRIVER);
		newblock->ofs = startofs + size;
		newblock->size = p->size - size;
		newblock->free = 1;
		newblock->next = p->next;
		p->size = size;
		p->next = newblock;
	}

	/* p = middle block */
	p->align = alignment;
	p->free = 0;
	p->reserved = reserved;
	return p;
}

PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
			 int startSearch)
{
	int mask, startofs, endofs;
	TMemBlock *p;

	if (!heap || align2 < 0 || size <= 0)
		return NULL;

	mask = (1 << align2) - 1;
	startofs = 0;
	p = (TMemBlock *) heap;

	while (p) {
		if (ISFREE(p)) {
			startofs = (p->ofs + mask) & ~mask;

			if (startofs < startSearch)
				startofs = startSearch;

			endofs = startofs + size;

			if (endofs <= (p->ofs + p->size))
				break;
		}

		p = p->next;
	}

	if (!p)
		return NULL;

	p = SliceBlock(p, startofs, size, 0, mask + 1);
	p->heap = heap;

	return p;
}

static __inline__ int Join2Blocks(TMemBlock * p)
{
	if (p->free && p->next && p->next->free) {
		TMemBlock *q = p->next;
		p->size += q->size;
		p->next = q->next;
		DRM(free) (q, sizeof(TMemBlock), DRM_MEM_DRIVER);

		return 1;
	}

	return 0;
}

int via_mmFreeMem(PMemBlock b)
{
	TMemBlock *p, *prev;

	if (!b)
		return 0;

	if (!b->heap) {
		fprintf(stderr, "no heap\n");

		return -1;
	}

	p = b->heap;
	prev = NULL;

	while (p && p != b) {
		prev = p;
		p = p->next;
	}

	if (!p || p->free || p->reserved) {
		if (!p)
			fprintf(stderr, "block not found in heap\n");
		else if (p->free)
			fprintf(stderr, "block already free\n");
		else
			fprintf(stderr, "block is reserved\n");

		return -1;
	}

	p->free = 1;
	Join2Blocks(p);

	if (prev)
		Join2Blocks(prev);

	return 0;
}

int via_mmReserveMem(memHeap_t * heap, int offset, int size)
{
	int endofs;
	TMemBlock *p;

	if (!heap || size <= 0)
		return -1;
	endofs = offset + size;
	p = (TMemBlock *) heap;

	while (p && p->ofs <= offset) {
		if (ISFREE(p) && endofs <= (p->ofs + p->size)) {
			SliceBlock(p, offset, size, 1, 1);
			return 0;
		}
		p = p->next;
	}
	return -1;
}

int via_mmFreeReserved(memHeap_t * heap, int offset)
{
	TMemBlock *p, *prev;

	if (!heap)
		return -1;

	p = (TMemBlock *) heap;
	prev = NULL;

	while (p && p->ofs != offset) {
		prev = p;
		p = p->next;
	}

	if (!p || !p->reserved)
		return -1;
	p->free = 1;
	p->reserved = 0;
	Join2Blocks(p);

	if (prev)
		Join2Blocks(prev);

	return 0;
}

void via_mmDestroy(memHeap_t * heap)
{
	TMemBlock *p, *q;

	if (!heap)
		return;
	p = (TMemBlock *) heap;

	while (p) {
		q = p->next;
		DRM(free) (p, sizeof(TMemBlock), DRM_MEM_DRIVER);
		p = q;
	}
}