xref: /plan9/sys/src/9/omap/devdss.c (revision 5efba40621eb0e8502497b8c98fd368f3bc4d354)
193631029SDavid du Colombier /*
293631029SDavid du Colombier  * omap35 display subsystem (dss) device interface to screen.c.
393631029SDavid du Colombier  * implements #v/vgactl
493631029SDavid du Colombier  */
593631029SDavid du Colombier #include "u.h"
693631029SDavid du Colombier #include "../port/lib.h"
793631029SDavid du Colombier #include "mem.h"
893631029SDavid du Colombier #include "dat.h"
993631029SDavid du Colombier #include "fns.h"
1093631029SDavid du Colombier #include "io.h"
1193631029SDavid du Colombier #include "ureg.h"
1293631029SDavid du Colombier #include "../port/error.h"
1393631029SDavid du Colombier 
1493631029SDavid du Colombier #define	Image	IMAGE
1593631029SDavid du Colombier #include <draw.h>
1693631029SDavid du Colombier #include <memdraw.h>
1793631029SDavid du Colombier #include <cursor.h>
1893631029SDavid du Colombier #include "screen.h"
1993631029SDavid du Colombier // #include "gamma.h"
2093631029SDavid du Colombier 
2193631029SDavid du Colombier enum {
2293631029SDavid du Colombier 	Qdir,
2393631029SDavid du Colombier 	Qdss,
2493631029SDavid du Colombier };
2593631029SDavid du Colombier 
2693631029SDavid du Colombier extern OScreen oscreen;
27*5efba406SDavid du Colombier extern Settings settings[];
2893631029SDavid du Colombier extern Omap3fb *framebuf;
2993631029SDavid du Colombier 
3093631029SDavid du Colombier static QLock dsslck;
3193631029SDavid du Colombier static Dirtab dsstab[] = {
3293631029SDavid du Colombier 	".",		{Qdir, 0, QTDIR},	0,	0555|DMDIR,
3393631029SDavid du Colombier 	"vgactl",	{Qdss, 0},		0,	0666,
3493631029SDavid du Colombier };
3593631029SDavid du Colombier 
3693631029SDavid du Colombier static Chan*
screenattach(char * spec)3793631029SDavid du Colombier screenattach(char *spec)
3893631029SDavid du Colombier {
3993631029SDavid du Colombier 	return devattach('v', spec);
4093631029SDavid du Colombier }
4193631029SDavid du Colombier 
4293631029SDavid du Colombier static Walkqid*
screenwalk(Chan * c,Chan * nc,char ** name,int nname)4393631029SDavid du Colombier screenwalk(Chan *c, Chan *nc, char **name, int nname)
4493631029SDavid du Colombier {
4593631029SDavid du Colombier 	return devwalk(c, nc, name, nname, dsstab, nelem(dsstab), devgen);
4693631029SDavid du Colombier }
4793631029SDavid du Colombier 
4893631029SDavid du Colombier static int
screenstat(Chan * c,uchar * dp,int n)4993631029SDavid du Colombier screenstat(Chan *c, uchar *dp, int n)
5093631029SDavid du Colombier {
5193631029SDavid du Colombier 	return devstat(c, dp, n, dsstab, nelem(dsstab), devgen);
5293631029SDavid du Colombier }
5393631029SDavid du Colombier 
5493631029SDavid du Colombier static Chan*
screenopen(Chan * c,int omode)5593631029SDavid du Colombier screenopen(Chan *c, int omode)
5693631029SDavid du Colombier {
5793631029SDavid du Colombier 	if ((ulong)c->qid.path == Qdss) {
5893631029SDavid du Colombier 		qlock(&dsslck);
5993631029SDavid du Colombier 		oscreen.open = 1;
6093631029SDavid du Colombier 		c->mode = openmode(omode);
6193631029SDavid du Colombier 		c->flag |= COPEN;
6293631029SDavid du Colombier 		c->offset = 0;
6393631029SDavid du Colombier 	}
6493631029SDavid du Colombier 	return c;
6593631029SDavid du Colombier }
6693631029SDavid du Colombier 
6793631029SDavid du Colombier static void
screenclose(Chan * c)6893631029SDavid du Colombier screenclose(Chan *c)
6993631029SDavid du Colombier {
7093631029SDavid du Colombier 	if ((c->qid.type & QTDIR) == 0 && c->flag & COPEN)
7193631029SDavid du Colombier 		if (c->qid.path == Qdss) {
7293631029SDavid du Colombier 			oscreen.open = 0;
7393631029SDavid du Colombier 			qunlock(&dsslck);
7493631029SDavid du Colombier 		}
7593631029SDavid du Colombier }
7693631029SDavid du Colombier 
7793631029SDavid du Colombier static ulong
getchans(char * p)7893631029SDavid du Colombier getchans(char *p)
7993631029SDavid du Colombier {
8093631029SDavid du Colombier 	if (strncmp("x24" , p, 3) == 0)
8193631029SDavid du Colombier 		return RGB24;		/* can't work yet, pixels are shorts */
8293631029SDavid du Colombier 	else if (strncmp("x16", p, 3) == 0)
8393631029SDavid du Colombier 		return RGB16;
8493631029SDavid du Colombier 	else
8593631029SDavid du Colombier 		return RGB16;
8693631029SDavid du Colombier }
8793631029SDavid du Colombier 
8893631029SDavid du Colombier static long
settingswrite(OScreen * scr,char * p)89*5efba406SDavid du Colombier settingswrite(OScreen *scr, char *p)
9093631029SDavid du Colombier {
9193631029SDavid du Colombier 	if (strncmp("800x600", p, 7) == 0) {
92634d7e5aSDavid du Colombier 		p += 7;
93*5efba406SDavid du Colombier 		scr->settings = &settings[Res800x600];
9493631029SDavid du Colombier 	} else if (strncmp("1024x768", p, 8) == 0) {
95634d7e5aSDavid du Colombier 		p += 8;
96*5efba406SDavid du Colombier 		scr->settings = &settings[Res1024x768];
9793631029SDavid du Colombier 	} else if (strncmp("1280x1024", p, 9) == 0) {
98634d7e5aSDavid du Colombier 		p += 9;
99*5efba406SDavid du Colombier 		scr->settings = &settings[Res1280x1024];
100634d7e5aSDavid du Colombier 	} else
10193631029SDavid du Colombier 		return -1;
102*5efba406SDavid du Colombier 	scr->settings->chan = getchans(p);
103634d7e5aSDavid du Colombier 	return 1;
10493631029SDavid du Colombier }
10593631029SDavid du Colombier 
10693631029SDavid du Colombier static long
screenread(Chan * c,void * a,long n,vlong off)10793631029SDavid du Colombier screenread(Chan *c, void *a, long n, vlong off)
10893631029SDavid du Colombier {
10993631029SDavid du Colombier 	int len, depth;
11093631029SDavid du Colombier 	char *p;
111*5efba406SDavid du Colombier 	Settings *set;
11293631029SDavid du Colombier 
11393631029SDavid du Colombier 	switch ((ulong)c->qid.path) {
11493631029SDavid du Colombier 	case Qdir:
115634d7e5aSDavid du Colombier 		return devdirread(c, a, n, dsstab, nelem(dsstab), devgen);
11693631029SDavid du Colombier 	case Qdss:
117*5efba406SDavid du Colombier 		set = oscreen.settings;
11893631029SDavid du Colombier 		p = malloc(READSTR);
11993631029SDavid du Colombier 		if(waserror()){
12093631029SDavid du Colombier 			free(p);
12193631029SDavid du Colombier 			nexterror();
12293631029SDavid du Colombier 		}
123*5efba406SDavid du Colombier 		if (set->chan == RGB16)
12493631029SDavid du Colombier 			depth = 16;
125*5efba406SDavid du Colombier 		else if (set->chan == RGB24)
12693631029SDavid du Colombier 			depth = 24;
12793631029SDavid du Colombier 		else
12893631029SDavid du Colombier 			depth = 0;
12993631029SDavid du Colombier 		len = snprint(p, READSTR, "size %dx%dx%d @ %d Hz\n"
130*5efba406SDavid du Colombier 			"addr %#p size %ud\n", set->wid, set->ht, depth,
131*5efba406SDavid du Colombier 			set->freq, framebuf, sizeof *framebuf);
13293631029SDavid du Colombier 		USED(len);
13393631029SDavid du Colombier 		n = readstr(off, a, n, p);
13493631029SDavid du Colombier 		poperror();
13593631029SDavid du Colombier 		free(p);
13693631029SDavid du Colombier 		return n;
13793631029SDavid du Colombier 	default:
13893631029SDavid du Colombier 		error(Egreg);
13993631029SDavid du Colombier 	}
14093631029SDavid du Colombier 	return 0;
14193631029SDavid du Colombier }
14293631029SDavid du Colombier 
14393631029SDavid du Colombier static long
screenwrite(Chan * c,void * a,long n,vlong off)14493631029SDavid du Colombier screenwrite(Chan *c, void *a, long n, vlong off)
14593631029SDavid du Colombier {
14693631029SDavid du Colombier 	switch ((ulong)c->qid.path) {
14793631029SDavid du Colombier 	case Qdss:
14893631029SDavid du Colombier 		if(off)
14993631029SDavid du Colombier 			error(Ebadarg);
15093631029SDavid du Colombier 		n = settingswrite(&oscreen, a);
151634d7e5aSDavid du Colombier 		if (n < 0)
152634d7e5aSDavid du Colombier 			error(Ebadctl);
15393631029SDavid du Colombier 		screeninit();
15493631029SDavid du Colombier 		return n;
15593631029SDavid du Colombier 	default:
15693631029SDavid du Colombier 		error(Egreg);
15793631029SDavid du Colombier 	}
15893631029SDavid du Colombier 	return 0;
15993631029SDavid du Colombier }
16093631029SDavid du Colombier 
16193631029SDavid du Colombier Dev dssdevtab = {
16293631029SDavid du Colombier 	L'v',
16393631029SDavid du Colombier 	"dss",
16493631029SDavid du Colombier 
16593631029SDavid du Colombier 	devreset,
16693631029SDavid du Colombier 	devinit,
16793631029SDavid du Colombier 	devshutdown,		// TODO add a shutdown to stop dma to monitor
16893631029SDavid du Colombier 	screenattach,
16993631029SDavid du Colombier 	screenwalk,
17093631029SDavid du Colombier 	screenstat,
17193631029SDavid du Colombier 	screenopen,
17293631029SDavid du Colombier 	devcreate,
17393631029SDavid du Colombier 	screenclose,
17493631029SDavid du Colombier 	screenread,
17593631029SDavid du Colombier 	devbread,
17693631029SDavid du Colombier 	screenwrite,
17793631029SDavid du Colombier 	devbwrite,
17893631029SDavid du Colombier 	devremove,
17993631029SDavid du Colombier 	devwstat,
18093631029SDavid du Colombier };
181