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