Merge ^/head r295601 through r295844.
This commit is contained in:
commit
9893f787ec
@ -1090,7 +1090,7 @@ distrib-dirs distribution: .MAKE .PHONY
|
||||
.if make(distribution)
|
||||
${_+_}cd ${.CURDIR}; ${CROSSENV} PATH=${TMPPATH} \
|
||||
${MAKE} -f Makefile.inc1 ${IMAKE_INSTALL} \
|
||||
METALOG=${METALOG} installconfig
|
||||
METALOG=${METALOG} MK_TESTS=no installconfig
|
||||
.endif
|
||||
|
||||
#
|
||||
|
@ -24,7 +24,18 @@ test: ${PROG} gen
|
||||
LC_ALL=en_US.US-ASCII hexdump -C | \
|
||||
diff -I FreeBSD - ${.CURDIR}/ref.${conv}
|
||||
.endfor
|
||||
@rm -f gen
|
||||
@${ECHO} "testing sparse file (obs zeroes)"
|
||||
@./gen 189284 | ./dd ibs=16 obs=8 conv=sparse of=obs_zeroes 2> /dev/null
|
||||
@hexdump -C obs_zeroes | diff -I FreeBSD - ${.CURDIR}/ref.obs_zeroes
|
||||
|
||||
@${ECHO} "testing spase file (all zeroes)"
|
||||
@./dd if=/dev/zero of=1M_zeroes bs=1048576 count=1 2> /dev/null
|
||||
@./dd if=1M_zeroes of=1M_zeroes.1 bs=1048576 conv=sparse 2> /dev/null
|
||||
@./dd if=1M_zeroes of=1M_zeroes.2 bs=1048576 2> /dev/null
|
||||
@diff 1M_zeroes 1M_zeroes.1
|
||||
@diff 1M_zeroes 1M_zeroes.2
|
||||
|
||||
@rm -f gen 1M_zeroes* obs_zeroes
|
||||
|
||||
.if ${MK_TESTS} != "no"
|
||||
SUBDIR+= tests
|
||||
|
36
bin/dd/dd.c
36
bin/dd/dd.c
@ -77,7 +77,6 @@ STAT st; /* statistics */
|
||||
void (*cfunc)(void); /* conversion function */
|
||||
uintmax_t cpy_cnt; /* # of blocks to copy */
|
||||
static off_t pending = 0; /* pending seek if sparse */
|
||||
static off_t last_sp = 0; /* size of last added sparse block */
|
||||
u_int ddflags = 0; /* conversion options */
|
||||
size_t cbsz; /* conversion block size */
|
||||
uintmax_t files_cnt = 1; /* # of files to copy */
|
||||
@ -409,6 +408,15 @@ dd_close(void)
|
||||
}
|
||||
if (out.dbcnt || pending)
|
||||
dd_out(1);
|
||||
|
||||
/*
|
||||
* If the file ends with a hole, ftruncate it to extend its size
|
||||
* up to the end of the hole (without having to write any data).
|
||||
*/
|
||||
if (out.seek_offset > 0 && (out.flags & ISTRUNC)) {
|
||||
if (ftruncate(out.fd, out.seek_offset) == -1)
|
||||
err(1, "truncating %s", out.name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -457,29 +465,27 @@ dd_out(int force)
|
||||
}
|
||||
if (sparse && !force) {
|
||||
pending += cnt;
|
||||
last_sp = cnt;
|
||||
nw = cnt;
|
||||
} else {
|
||||
if (pending != 0) {
|
||||
/* If forced to write, and we have no
|
||||
* data left, we need to write the last
|
||||
* sparse block explicitly.
|
||||
/*
|
||||
* Seek past hole. Note that we need to record the
|
||||
* reached offset, because we might have no more data
|
||||
* to write, in which case we'll need to call
|
||||
* ftruncate to extend the file size.
|
||||
*/
|
||||
if (force && cnt == 0) {
|
||||
pending -= last_sp;
|
||||
assert(outp == out.db);
|
||||
memset(outp, 0, cnt);
|
||||
}
|
||||
if (lseek(out.fd, pending, SEEK_CUR) ==
|
||||
-1)
|
||||
out.seek_offset = lseek(out.fd, pending, SEEK_CUR);
|
||||
if (out.seek_offset == -1)
|
||||
err(2, "%s: seek error creating sparse file",
|
||||
out.name);
|
||||
pending = last_sp = 0;
|
||||
pending = 0;
|
||||
}
|
||||
if (cnt)
|
||||
if (cnt) {
|
||||
nw = write(out.fd, outp, cnt);
|
||||
else
|
||||
out.seek_offset = 0;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (nw <= 0) {
|
||||
|
@ -54,6 +54,7 @@ typedef struct {
|
||||
const char *name; /* name */
|
||||
int fd; /* file descriptor */
|
||||
off_t offset; /* # of blocks to skip */
|
||||
off_t seek_offset; /* offset of last seek past output hole */
|
||||
} IO;
|
||||
|
||||
typedef struct {
|
||||
|
13
bin/dd/gen.c
13
bin/dd/gen.c
@ -5,13 +5,20 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main(int argc __unused, char **argv __unused)
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
putchar(i);
|
||||
if (argc > 1 && !strcmp(argv[1], "189284")) {
|
||||
fputs("ABCDEFGH", stdout);
|
||||
for (i = 0; i < 8; i++)
|
||||
putchar(0);
|
||||
} else {
|
||||
for (i = 0; i < 256; i++)
|
||||
putchar(i);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
3
bin/dd/ref.obs_zeroes
Normal file
3
bin/dd/ref.obs_zeroes
Normal file
@ -0,0 +1,3 @@
|
||||
$FreeBSD$
|
||||
00000000 41 42 43 44 45 46 47 48 00 00 00 00 00 00 00 00 |ABCDEFGH........|
|
||||
00000010
|
@ -195,8 +195,7 @@ preadfd(void)
|
||||
int
|
||||
preadbuffer(void)
|
||||
{
|
||||
char *p, *q;
|
||||
int more;
|
||||
char *p, *q, *r, *end;
|
||||
char savec;
|
||||
|
||||
while (parsefile->strpush) {
|
||||
@ -224,34 +223,31 @@ preadbuffer(void)
|
||||
}
|
||||
}
|
||||
|
||||
q = p = parsefile->buf + (parsenextc - parsefile->buf);
|
||||
|
||||
/* delete nul characters */
|
||||
for (more = 1; more;) {
|
||||
switch (*p) {
|
||||
case '\0':
|
||||
p++; /* Skip nul */
|
||||
goto check;
|
||||
|
||||
case '\n':
|
||||
parsenleft = q - parsenextc;
|
||||
more = 0; /* Stop processing here */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*q++ = *p++;
|
||||
check:
|
||||
if (--parselleft <= 0) {
|
||||
parsenleft = q - parsenextc - 1;
|
||||
if (parsenleft < 0)
|
||||
goto again;
|
||||
*q = '\0';
|
||||
more = 0;
|
||||
p = parsefile->buf + (parsenextc - parsefile->buf);
|
||||
end = p + parselleft;
|
||||
*end = '\0';
|
||||
q = strchrnul(p, '\n');
|
||||
if (q != end && *q == '\0') {
|
||||
/* delete nul characters */
|
||||
for (r = q; q != end; q++) {
|
||||
if (*q != '\0')
|
||||
*r++ = *q;
|
||||
}
|
||||
parselleft -= end - r;
|
||||
if (parselleft == 0)
|
||||
goto again;
|
||||
end = p + parselleft;
|
||||
*end = '\0';
|
||||
q = strchrnul(p, '\n');
|
||||
}
|
||||
if (q == end) {
|
||||
parsenleft = parselleft;
|
||||
parselleft = 0;
|
||||
} else /* *q == '\n' */ {
|
||||
parsenleft = q - parsenextc + 1;
|
||||
parselleft -= parsenleft;
|
||||
}
|
||||
parsenleft--;
|
||||
|
||||
savec = *q;
|
||||
*q = '\0';
|
||||
|
@ -10,6 +10,4 @@ TESTS_SUBDIRS+= parameters
|
||||
TESTS_SUBDIRS+= parser
|
||||
TESTS_SUBDIRS+= set-e
|
||||
|
||||
SUBDIR_PARALLEL=
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
@ -25,6 +25,8 @@ FILES+= alias15.0 alias15.0.stdout
|
||||
FILES+= and-pipe-not.0
|
||||
FILES+= case1.0
|
||||
FILES+= case2.0
|
||||
FILES+= comment1.0
|
||||
FILES+= comment2.42
|
||||
FILES+= dollar-quote1.0
|
||||
FILES+= dollar-quote2.0
|
||||
FILES+= dollar-quote3.0
|
||||
@ -71,6 +73,7 @@ FILES+= line-cont10.0
|
||||
FILES+= line-cont11.0
|
||||
FILES+= no-space1.0
|
||||
FILES+= no-space2.0
|
||||
FILES+= nul1.0
|
||||
FILES+= only-redir1.0
|
||||
FILES+= only-redir2.0
|
||||
FILES+= only-redir3.0
|
||||
|
3
bin/sh/tests/parser/comment1.0
Normal file
3
bin/sh/tests/parser/comment1.0
Normal file
@ -0,0 +1,3 @@
|
||||
# $FreeBSD$
|
||||
|
||||
${SH} -c '#'
|
4
bin/sh/tests/parser/comment2.42
Normal file
4
bin/sh/tests/parser/comment2.42
Normal file
@ -0,0 +1,4 @@
|
||||
# $FreeBSD$
|
||||
|
||||
${SH} -c '#
|
||||
exit 42'
|
12
bin/sh/tests/parser/nul1.0
Normal file
12
bin/sh/tests/parser/nul1.0
Normal file
@ -0,0 +1,12 @@
|
||||
# $FreeBSD$
|
||||
# Although POSIX does not specify the effect of NUL bytes in scripts,
|
||||
# we ignore them.
|
||||
|
||||
{
|
||||
printf 'v=%03000d\0%02000d' 7 2
|
||||
dd if=/dev/zero bs=1000 count=1 status=none
|
||||
printf '1 w=%03000d%02000d1\0\n' 7 2
|
||||
printf '\0l\0v\0=\0$\0{\0#\0v\0}\n'
|
||||
printf '\0l\0w\0=\0\0$\0{\0#\0w}\0\0\0\n'
|
||||
printf '[ "$lv.$lw.$v" = "5001.5001.$w" ]\n'
|
||||
} | ${SH}
|
@ -1713,7 +1713,7 @@ zfs_do_get(int argc, char **argv)
|
||||
default:
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid column name "
|
||||
"'%s'\n"), value);
|
||||
"'%s'\n"), suboptarg);
|
||||
usage(B_FALSE);
|
||||
}
|
||||
}
|
||||
@ -1750,7 +1750,7 @@ zfs_do_get(int argc, char **argv)
|
||||
default:
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid source "
|
||||
"'%s'\n"), value);
|
||||
"'%s'\n"), suboptarg);
|
||||
usage(B_FALSE);
|
||||
}
|
||||
}
|
||||
@ -1786,7 +1786,7 @@ zfs_do_get(int argc, char **argv)
|
||||
default:
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid type '%s'\n"),
|
||||
value);
|
||||
suboptarg);
|
||||
usage(B_FALSE);
|
||||
}
|
||||
}
|
||||
@ -3156,7 +3156,7 @@ zfs_do_list(int argc, char **argv)
|
||||
default:
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid type '%s'\n"),
|
||||
value);
|
||||
suboptarg);
|
||||
usage(B_FALSE);
|
||||
}
|
||||
}
|
||||
|
@ -5431,7 +5431,7 @@ zpool_do_get(int argc, char **argv)
|
||||
default:
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid column name "
|
||||
"'%s'\n"), value);
|
||||
"'%s'\n"), suboptarg);
|
||||
usage(B_FALSE);
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,4 @@ TESTS_SUBDIRS+= aggs \
|
||||
.PATH: ${.CURDIR:H:H:H:H:H}/tests
|
||||
KYUAFILE= YES
|
||||
|
||||
SUBDIR_PARALLEL=
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
@ -641,6 +641,18 @@ create_file(struct elfcopy *ecp, const char *src, const char *dst)
|
||||
* ELF object before processing.
|
||||
*/
|
||||
if (ecp->itf != ETF_ELF) {
|
||||
/*
|
||||
* If the output object is not an ELF file, choose an arbitrary
|
||||
* ELF format for the intermediate file. srec, ihex and binary
|
||||
* formats are independent of class, endianness and machine
|
||||
* type so these choices do not affect the output.
|
||||
*/
|
||||
if (ecp->otf != ETF_ELF) {
|
||||
if (ecp->oec == ELFCLASSNONE)
|
||||
ecp->oec = ELFCLASS64;
|
||||
if (ecp->oed == ELFDATANONE)
|
||||
ecp->oed = ELFDATA2LSB;
|
||||
}
|
||||
create_tempfile(&elftemp, &efd);
|
||||
if ((ecp->eout = elf_begin(efd, ELF_C_WRITE, NULL)) == NULL)
|
||||
errx(EXIT_FAILURE, "elf_begin() failed: %s",
|
||||
|
@ -16,7 +16,7 @@
|
||||
.R
|
||||
..
|
||||
.de Id
|
||||
.ND \\$4
|
||||
.ND 1 June 1995
|
||||
..
|
||||
.Id $FreeBSD$
|
||||
.RP
|
||||
|
@ -36,8 +36,10 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_types.h>
|
||||
#include <sys/signal.h>
|
||||
#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
|
||||
#include <machine/ucontext.h>
|
||||
#include <sys/_ucontext.h>
|
||||
#endif
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
/*
|
||||
|
15
lib/clang/libllvmdebuginfodwarf/Makefile.depend
Normal file
15
lib/clang/libllvmdebuginfodwarf/Makefile.depend
Normal file
@ -0,0 +1,15 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/libc++ \
|
||||
lib/msun \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
15
lib/clang/libllvmdebuginfopdb/Makefile.depend
Normal file
15
lib/clang/libllvmdebuginfopdb/Makefile.depend
Normal file
@ -0,0 +1,15 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/libc++ \
|
||||
lib/msun \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
18
lib/clang/libllvmlibdriver/Makefile.depend
Normal file
18
lib/clang/libllvmlibdriver/Makefile.depend
Normal file
@ -0,0 +1,18 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/libc++ \
|
||||
lib/msun \
|
||||
usr.bin/clang/tblgen.host \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
LibDriver.o: Options.inc.h
|
||||
LibDriver.po: Options.inc.h
|
||||
.endif
|
18
lib/clang/libllvmlto/Makefile.depend
Normal file
18
lib/clang/libllvmlto/Makefile.depend
Normal file
@ -0,0 +1,18 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/libc++ \
|
||||
lib/msun \
|
||||
usr.bin/clang/tblgen.host \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
LTOCodeGenerator.o: Intrinsics.inc.h
|
||||
LTOCodeGenerator.po: Intrinsics.inc.h
|
||||
.endif
|
15
lib/clang/libllvmmirparser/Makefile.depend
Normal file
15
lib/clang/libllvmmirparser/Makefile.depend
Normal file
@ -0,0 +1,15 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/libc++ \
|
||||
lib/msun \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
15
lib/clang/libllvmorcjit/Makefile.depend
Normal file
15
lib/clang/libllvmorcjit/Makefile.depend
Normal file
@ -0,0 +1,15 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/libc++ \
|
||||
lib/msun \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
18
lib/clang/libllvmpasses/Makefile.depend
Normal file
18
lib/clang/libllvmpasses/Makefile.depend
Normal file
@ -0,0 +1,18 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/libc++ \
|
||||
lib/msun \
|
||||
usr.bin/clang/tblgen.host \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
PassBuilder.o: Intrinsics.inc.h
|
||||
PassBuilder.po: Intrinsics.inc.h
|
||||
.endif
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)directory.3 8.1 (Berkeley) 6/4/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 6, 2015
|
||||
.Dd February 19, 2016
|
||||
.Dt DIRECTORY 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -46,7 +46,6 @@
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In dirent.h
|
||||
.Ft DIR *
|
||||
.Fn opendir "const char *filename"
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 19, 1994
|
||||
.Dd February 15, 2016
|
||||
.Dt FGETLN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -97,6 +97,9 @@ These changes are lost as soon as the pointer becomes invalid.
|
||||
The argument
|
||||
.Fa stream
|
||||
is not a stream open for reading.
|
||||
.It Bq Er ENOMEM
|
||||
The internal line buffer could not be expanded due to lack of available memory,
|
||||
or because it would need to expand beyond INT_MAX in size.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
|
@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94";
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -61,6 +63,10 @@ __slbexpand(FILE *fp, size_t newsize)
|
||||
#endif
|
||||
if (fp->_lb._size >= newsize)
|
||||
return (0);
|
||||
if (newsize > INT_MAX) {
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
if ((p = realloc(fp->_lb._base, newsize)) == NULL)
|
||||
return (-1);
|
||||
fp->_lb._base = p;
|
||||
@ -152,13 +158,14 @@ fgetln(FILE *fp, size_t *lenp)
|
||||
}
|
||||
*lenp = len;
|
||||
#ifdef notdef
|
||||
fp->_lb._base[len] = 0;
|
||||
fp->_lb._base[len] = '\0';
|
||||
#endif
|
||||
FUNLOCKFILE(fp);
|
||||
return ((char *)fp->_lb._base);
|
||||
|
||||
error:
|
||||
*lenp = 0; /* ??? */
|
||||
fp->_flags |= __SERR;
|
||||
FUNLOCKFILE(fp);
|
||||
return (NULL); /* ??? */
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ static char sccsid[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93";
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "un-namespace.h"
|
||||
@ -62,5 +63,7 @@ fputs(const char * __restrict s, FILE * __restrict fp)
|
||||
ORIENT(fp, -1);
|
||||
retval = __sfvwrite(fp, &uio);
|
||||
FUNLOCKFILE(fp);
|
||||
if (retval == 0)
|
||||
return (iov.iov_len > INT_MAX ? INT_MAX : iov.iov_len);
|
||||
return (retval);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)lseek.2 8.3 (Berkeley) 4/19/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 26, 2012
|
||||
.Dd February 18, 2016
|
||||
.Dt LSEEK 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -131,8 +131,14 @@ Applications can use
|
||||
.Dv SEEK_HOLE
|
||||
to optimise their behavior for ranges of zeros, but must not depend on it to
|
||||
find all such ranges in a file.
|
||||
Each file is presented as having a zero-size virtual hole at the very
|
||||
end of the file.
|
||||
The existence of a hole at the end of every data region allows for easy
|
||||
programming and implies that a virtual hole exists at the end of the file.
|
||||
programming and also provides compatibility to the original implementation
|
||||
in Solaris.
|
||||
It also causes the current file size (i.e., end-of-file offset) to be returned
|
||||
to indicate that there are no more holes past the supplied
|
||||
.Fa offset .
|
||||
Applications should use
|
||||
.Fn fpathconf _PC_MIN_HOLE_SIZE
|
||||
or
|
||||
@ -176,9 +182,11 @@ be negative for a non-character special file.
|
||||
For
|
||||
.Dv SEEK_DATA ,
|
||||
there are no more data regions past the supplied offset.
|
||||
For
|
||||
.Dv SEEK_HOLE ,
|
||||
there are no more holes past the supplied offset.
|
||||
Due to existence of the hole at the end of the file, for
|
||||
.Dv SEEK_HOLE
|
||||
this error is only returned when the
|
||||
.Fa offset
|
||||
already points to the end-of-file position.
|
||||
.It Bq Er EOVERFLOW
|
||||
The resulting file offset would be a value which cannot be represented
|
||||
correctly in an object of type
|
||||
|
@ -22,6 +22,8 @@ TESTS_SUBDIRS+= termios
|
||||
TESTS_SUBDIRS+= tls
|
||||
TESTS_SUBDIRS+= ttyio
|
||||
|
||||
SUBDIR_DEPEND_tls= tls_dso
|
||||
|
||||
.if ${MK_LOCALES} != "no"
|
||||
TESTS_SUBDIRS+= locale
|
||||
.endif
|
||||
|
@ -20,7 +20,7 @@ CLEANFILES+= h_nonexec
|
||||
.include "../../Makefile.netbsd-tests"
|
||||
|
||||
h_zero:
|
||||
dd if=/dev/zero of=h_zero bs=1k count=2
|
||||
dd if=/dev/zero of=h_zero bs=1k count=2 status=none
|
||||
chmod a+x h_zero
|
||||
|
||||
CLEANFILES+= h_zero
|
||||
|
@ -78,6 +78,6 @@ truncate_test_FILESGRP= wheel
|
||||
|
||||
CLEANFILES= truncate_test.root_owned
|
||||
truncate_test.root_owned:
|
||||
dd if=/dev/null bs=1 count=1 of=${.TARGET}
|
||||
dd if=/dev/null bs=1 count=1 of=${.TARGET} status=none
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
@ -183,7 +183,7 @@ _arm_initvtop(kvm_t *kd)
|
||||
#define l1pte_section_p(pde) (((pde) & ARM_L1_TYPE_MASK) == ARM_L1_TYPE_S)
|
||||
#define l1pte_valid(pde) ((pde) != 0)
|
||||
#define l2pte_valid(pte) ((pte) != 0)
|
||||
#define l2pte_index(v) (((v) & ARM_L2_ADDR_BITS) >> ARM_L2_S_SHIFT)
|
||||
#define l2pte_index(v) (((v) & ARM_L1_S_OFFSET) >> ARM_L2_S_SHIFT)
|
||||
|
||||
|
||||
static int
|
||||
|
@ -29,10 +29,6 @@
|
||||
#ifndef __KVM_ARM_H__
|
||||
#define __KVM_ARM_H__
|
||||
|
||||
#ifdef __arm__
|
||||
#include <machine/pte.h>
|
||||
#endif
|
||||
|
||||
typedef uint32_t arm_physaddr_t;
|
||||
typedef uint32_t arm_pd_entry_t;
|
||||
typedef uint32_t arm_pt_entry_t;
|
||||
@ -72,11 +68,15 @@ typedef uint32_t arm_pt_entry_t;
|
||||
#define ARM_L2_TYPE_T 0x03 /* Tiny Page - 1k - not used */
|
||||
#define ARM_L2_TYPE_MASK 0x03
|
||||
|
||||
#define ARM_L2_ADDR_BITS 0x000ff000 /* L2 PTE address bits */
|
||||
|
||||
#ifdef __arm__
|
||||
#include <machine/acle-compat.h>
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
#include <machine/pte-v6.h>
|
||||
#else
|
||||
#include <machine/pte-v4.h>
|
||||
#endif
|
||||
|
||||
_Static_assert(PAGE_SHIFT == ARM_PAGE_SHIFT, "PAGE_SHIFT mismatch");
|
||||
_Static_assert(PAGE_SIZE == ARM_PAGE_SIZE, "PAGE_SIZE mismatch");
|
||||
_Static_assert(PAGE_MASK == ARM_PAGE_MASK, "PAGE_MASK mismatch");
|
||||
@ -106,7 +106,6 @@ _Static_assert(L2_TYPE_S == ARM_L2_TYPE_S, "L2_TYPE_S mismatch");
|
||||
_Static_assert(L2_TYPE_T == ARM_L2_TYPE_T, "L2_TYPE_T mismatch");
|
||||
#endif
|
||||
_Static_assert(L2_TYPE_MASK == ARM_L2_TYPE_MASK, "L2_TYPE_MASK mismatch");
|
||||
_Static_assert(L2_ADDR_BITS == ARM_L2_ADDR_BITS, "L2_ADDR_BITS mismatch");
|
||||
#endif
|
||||
|
||||
int _arm_native(kvm_t *);
|
||||
|
13
lib/libpe/Makefile.depend
Normal file
13
lib/libpe/Makefile.depend
Normal file
@ -0,0 +1,13 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
include \
|
||||
include/xlocale \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
@ -10,6 +10,7 @@ SUBDIR= ${_atf} \
|
||||
${_dma} \
|
||||
getty \
|
||||
${_mail.local} \
|
||||
${_makewhatis.local} \
|
||||
${_mknetid} \
|
||||
${_pppoed} \
|
||||
revnetgroup \
|
||||
@ -88,6 +89,10 @@ _mail.local= mail.local
|
||||
_smrsh= smrsh
|
||||
.endif
|
||||
|
||||
.if ${MK_MAN_UTILS} != "no"
|
||||
_makewhatis.local= makewhatis.local
|
||||
.endif
|
||||
|
||||
.if ${MK_TALK} != "no"
|
||||
SUBDIR+= talkd
|
||||
.endif
|
||||
|
9
libexec/makewhatis.local/Makefile
Normal file
9
libexec/makewhatis.local/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SCRIPTS= makewhatis.local.sh
|
||||
MAN= makewhatis.local.8
|
||||
SCRIPTSDIR= ${LIBEXECDIR}
|
||||
LINKS= ${SCRIPTSDIR}/makewhatis.local ${SCRIPTSDIR}/catman.local
|
||||
MLINKS= makewhatis.local.8 catman.local.8
|
||||
|
||||
.include <bsd.prog.mk>
|
11
libexec/makewhatis.local/Makefile.depend
Normal file
11
libexec/makewhatis.local/Makefile.depend
Normal file
@ -0,0 +1,11 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
83
libexec/makewhatis.local/makewhatis.local.8
Normal file
83
libexec/makewhatis.local/makewhatis.local.8
Normal file
@ -0,0 +1,83 @@
|
||||
.\" Copyright (c) April 1996 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd April 26, 1996
|
||||
.Dt MAKEWHATIS.LOCAL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm makewhatis.local , catman.local
|
||||
.Nd start makewhatis or catman for local file systems
|
||||
.Sh SYNOPSIS
|
||||
.Nm /usr/libexec/makewhatis.local
|
||||
.Op options
|
||||
.Ar directories ...
|
||||
.Nm /usr/libexec/catman.local
|
||||
.Op options
|
||||
.Ar directories ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility starts
|
||||
.Xr makewhatis 1
|
||||
only for file systems physically mounted on the system
|
||||
where the
|
||||
.Nm
|
||||
is being executed.
|
||||
Running makewhatis
|
||||
by
|
||||
.Pa periodic weekly
|
||||
for rw nfs-mounted /usr may kill
|
||||
your NFS server -- all NFS clients start makewhatis at the same time!
|
||||
So use this wrapper for
|
||||
.Xr cron 8
|
||||
instead of calling makewhatis directly.
|
||||
The
|
||||
.Nm catman.local
|
||||
utility is using for same purposes as
|
||||
.Nm
|
||||
but for
|
||||
.Xr catman 1 .
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/periodic/weekly/320.whatis.XXX -compact
|
||||
.It Pa /etc/periodic/weekly/320.whatis
|
||||
run
|
||||
.Nm
|
||||
every week
|
||||
.It Pa /etc/periodic/weekly/330.catman
|
||||
run
|
||||
.Nm catman.local
|
||||
every week
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr catman 1 ,
|
||||
.Xr find 1 ,
|
||||
.Xr makewhatis 1 ,
|
||||
.Xr cron 8 ,
|
||||
.Xr periodic 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility appeared in
|
||||
.Fx 2.2 .
|
58
libexec/makewhatis.local/makewhatis.local.sh
Normal file
58
libexec/makewhatis.local/makewhatis.local.sh
Normal file
@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) April 1996 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# makewhatis.local - start makewhatis(1) only for file systems
|
||||
# physically mounted on the system
|
||||
#
|
||||
# Running makewhatis from /etc/periodic/weekly/320.whatis for rw nfs-mounted
|
||||
# /usr may kill your NFS server -- all clients start makewhatis at the same
|
||||
# time! So use this wrapper instead calling makewhatis directly.
|
||||
#
|
||||
# PS: this wrapper works also for catman(1)
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
PATH=/bin:/usr/bin:$PATH; export PATH
|
||||
opt= dirs= localdirs=
|
||||
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-*) opt="$opt $arg";;
|
||||
*) dirs="$dirs $arg";;
|
||||
esac
|
||||
done
|
||||
|
||||
dirs=`echo $dirs | sed 's/:/ /g'`
|
||||
case X"$dirs" in X) echo "usage: $0 [options] directories ..."; exit 1;; esac
|
||||
|
||||
localdirs=`find -H $dirs -fstype local -type d -prune -print`
|
||||
|
||||
case X"$localdirs" in
|
||||
X) echo "$0: no local-mounted manual directories found: $dirs"
|
||||
exit 1;;
|
||||
*) exec `basename $0 .local` $opt $localdirs;;
|
||||
esac
|
@ -4,6 +4,7 @@
|
||||
|
||||
SUBDIR+= libpythagoras target
|
||||
|
||||
SUBDIR_DEPEND_target= libpythagoras
|
||||
ATF_TESTS_C= ld_library_pathfds
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
@ -144,11 +144,12 @@ ifclonecreate(int s, void *arg)
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get a different name back than we put in, print it.
|
||||
* If we get a different name back than we put in, update record and
|
||||
* indicate it should be printed later.
|
||||
*/
|
||||
if (strncmp(name, ifr.ifr_name, sizeof(name)) != 0) {
|
||||
strlcpy(name, ifr.ifr_name, sizeof(name));
|
||||
printf("%s\n", name);
|
||||
printifname = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ int clearaddr;
|
||||
int newaddr = 1;
|
||||
int verbose;
|
||||
int noload;
|
||||
int printifname = 0;
|
||||
|
||||
int supmedia = 0;
|
||||
int printkeys = 0; /* Print keying material for interfaces. */
|
||||
@ -108,6 +109,8 @@ static struct afswtch *af_getbyname(const char *name);
|
||||
static struct afswtch *af_getbyfamily(int af);
|
||||
static void af_other_status(int);
|
||||
|
||||
void printifnamemaybe(void);
|
||||
|
||||
static struct option *opts = NULL;
|
||||
|
||||
struct ifa_order_elt {
|
||||
@ -297,6 +300,12 @@ sortifaddrs(struct ifaddrs *list,
|
||||
return (result);
|
||||
}
|
||||
|
||||
void printifnamemaybe()
|
||||
{
|
||||
if (printifname)
|
||||
printf("%s\n", name);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@ -314,6 +323,12 @@ main(int argc, char *argv[])
|
||||
size_t iflen;
|
||||
|
||||
all = downonly = uponly = namesonly = noload = verbose = 0;
|
||||
|
||||
/*
|
||||
* Ensure we print interface name when expected to,
|
||||
* even if we terminate early due to error.
|
||||
*/
|
||||
atexit(printifnamemaybe);
|
||||
|
||||
/* Parse leading line options */
|
||||
strlcpy(options, "adklmnuv", sizeof(options));
|
||||
@ -1011,6 +1026,8 @@ setifname(const char *val, int dummy __unused, int s,
|
||||
const struct afswtch *afp)
|
||||
{
|
||||
char *newname;
|
||||
|
||||
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||
|
||||
newname = strdup(val);
|
||||
if (newname == NULL)
|
||||
@ -1020,6 +1037,7 @@ setifname(const char *val, int dummy __unused, int s,
|
||||
free(newname);
|
||||
err(1, "ioctl SIOCSIFNAME (set name)");
|
||||
}
|
||||
printifname = 1;
|
||||
strlcpy(name, newname, sizeof(name));
|
||||
free(newname);
|
||||
}
|
||||
@ -1031,6 +1049,8 @@ setifdescr(const char *val, int dummy __unused, int s,
|
||||
{
|
||||
char *newdescr;
|
||||
|
||||
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||
|
||||
ifr.ifr_buffer.length = strlen(val) + 1;
|
||||
if (ifr.ifr_buffer.length == 1) {
|
||||
ifr.ifr_buffer.buffer = newdescr = NULL;
|
||||
|
@ -133,6 +133,7 @@ extern int supmedia;
|
||||
extern int printkeys;
|
||||
extern int newaddr;
|
||||
extern int verbose;
|
||||
extern int printifname;
|
||||
|
||||
void setifcap(const char *, int value, int s, const struct afswtch *);
|
||||
|
||||
|
@ -8,6 +8,7 @@ DIRDEPS = \
|
||||
lib/${CSU_DIR} \
|
||||
lib/libc \
|
||||
lib/libcompiler_rt \
|
||||
lib/libutil \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
@ -6,6 +6,7 @@ DIRDEPS = \
|
||||
gnu/lib/libgcc \
|
||||
include \
|
||||
include/arpa \
|
||||
include/gssapi \
|
||||
include/xlocale \
|
||||
lib/${CSU_DIR} \
|
||||
lib/libc \
|
||||
|
@ -1,3 +1,4 @@
|
||||
.\" Copyright (c) 2006, Ceri Davies <ceri@FreeBSD.org>
|
||||
.\" Copyright (c) 2014, Luiz Otavio O Souza <loos@FreeBSD.org>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
@ -100,8 +101,18 @@ Consumers:
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Maxim Sobolev Aq Mt sobomax@FreeBSD.org
|
||||
and
|
||||
.An Aleksandr Rybalko Aq Mt ray@FreeBSD.org .
|
||||
.An Max Khon Aq Mt fjoe@FreeBSD.org
|
||||
as
|
||||
.Xr geom_uzip 4 .
|
||||
.An Aleksandr Rybalko Aq Mt ray@FreeBSD.org
|
||||
copied it over as
|
||||
.Nm
|
||||
and added LZMA functionality .
|
||||
This manual page was written by
|
||||
.An Luiz Otavio O Souza Aq Mt loos@FreeBSD.org .
|
||||
.An Ceri Davies Aq Mt ceri@FreeBSD.org
|
||||
for the
|
||||
.Xr geom_uzip 4 ,
|
||||
and modified by
|
||||
.An Luiz Otavio O Souza Aq Mt loos@FreeBSD.org
|
||||
to match
|
||||
.Nm .
|
||||
|
@ -31,7 +31,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 8, 2010
|
||||
.Dd February 18, 2016
|
||||
.Dt MAILER.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -101,9 +101,10 @@ mailq /usr/libexec/sendmail/sendmail
|
||||
newaliases /usr/libexec/sendmail/sendmail
|
||||
.Ed
|
||||
.Pp
|
||||
This example shows how to invoke a sendmail-workalike like
|
||||
Using
|
||||
.Nm Postfix
|
||||
in place of
|
||||
(from ports)
|
||||
to replace
|
||||
.Xr sendmail 8 :
|
||||
.Bd -literal -offset indent
|
||||
# Emulate sendmail using postfix
|
||||
@ -113,12 +114,10 @@ mailq /usr/local/sbin/sendmail
|
||||
newaliases /usr/local/sbin/sendmail
|
||||
.Ed
|
||||
.Pp
|
||||
This example shows
|
||||
how to invoke
|
||||
a sendmail-workalike with
|
||||
Using
|
||||
.Nm Exim
|
||||
(from ports)
|
||||
in place of
|
||||
to replace
|
||||
.Xr sendmail 8 :
|
||||
.Bd -literal -offset indent
|
||||
# Emulate sendmail using exim
|
||||
@ -129,24 +128,40 @@ newaliases /usr/bin/true
|
||||
rmail /usr/local/sbin/exim -i -oee
|
||||
.Ed
|
||||
.Pp
|
||||
This example shows the use of the
|
||||
Using
|
||||
.Nm mini_sendmail
|
||||
package from ports in place of
|
||||
.Xr sendmail 8 .
|
||||
Note the use of additional arguments.
|
||||
(from ports)
|
||||
to replace
|
||||
.Xr sendmail 8 :
|
||||
.Bd -literal -offset indent
|
||||
# Send outgoing mail to a smart relay using mini_sendmail
|
||||
sendmail /usr/local/bin/mini_sendmail -srelayhost
|
||||
send-mail /usr/local/bin/mini_sendmail -srelayhost
|
||||
.Ed
|
||||
.Pp
|
||||
Using
|
||||
.Xr dma 8
|
||||
to replace
|
||||
.Xr sendmail 8 :
|
||||
.Bd -literal -offset indent
|
||||
# Execute dma instead of sendmail
|
||||
sendmail /usr/libexec/dma
|
||||
send-mail /usr/libexec/dma
|
||||
mailq /usr/libexec/dma
|
||||
newaliases /usr/libexec/dma
|
||||
rmail /usr/libexec/dma
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr mail 1 ,
|
||||
.Xr mailq 1 ,
|
||||
.Xr newaliases 1 ,
|
||||
.Xr dma 8 ,
|
||||
.Xr mailwrapper 8 ,
|
||||
.Xr sendmail 8
|
||||
.Pp
|
||||
.Xr postfix 1 Pq Pa ports/mail/postfix ,
|
||||
.Xr dma 8 Pq Pa ports/mail/dma ,
|
||||
.Xr exim 8 Pq Pa ports/mail/exim ,
|
||||
.Xr mini_sendmail 8 Pq Pa ports/mail/mini_sendmail
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
|
@ -175,6 +175,7 @@ nork [label="Norikatsu Shigemura\nnork@FreeBSD.org\n2002/04/01"]
|
||||
novel [label="Roman Bogorodskiy\nnovel@FreeBSD.org\n2005/03/07"]
|
||||
nox [label="Juergen Lock\nnox@FreeBSD.org\n2006/12/22"]
|
||||
obrien [label="David E. O'Brien\nobrien@FreeBSD.org\n1996/10/29"]
|
||||
olivier [label="Olivier Cochard-Labbe\nolivier@FreeBSD.org\n2016/02/02"]
|
||||
olivierd [label="Olivier Duchateau\nolivierd@FreeBSD.org\n2012/05/29"]
|
||||
osa [label="Sergey A. Osokin\nosa@FreeBSD.org\n2003/06/04"]
|
||||
pat [label="Patrick Li\npat@FreeBSD.org\n2001/11/14"]
|
||||
@ -400,6 +401,7 @@ itetcu -> sylvio
|
||||
|
||||
jadawin -> bapt
|
||||
jadawin -> flo
|
||||
jadawin -> olivier
|
||||
jadawin -> riggs
|
||||
jadawin -> sbz
|
||||
jadawin -> wen
|
||||
|
@ -5,6 +5,11 @@
|
||||
#
|
||||
# +++ variables +++
|
||||
#
|
||||
# CLEANDEPENDDIRS Additional directories to remove for the cleandepend
|
||||
# target.
|
||||
#
|
||||
# CLEANDEPENDFILES Additional files to remove for the cleandepend target.
|
||||
#
|
||||
# CTAGS A tags file generation program [gtags]
|
||||
#
|
||||
# CTAGSFLAGS Options for ctags(1) [not set]
|
||||
@ -27,7 +32,8 @@
|
||||
# +++ targets +++
|
||||
#
|
||||
# cleandepend:
|
||||
# Remove depend and tags file
|
||||
# remove ${CLEANDEPENDFILES}; remove ${CLEANDEPENDDIRS} and all
|
||||
# contents.
|
||||
#
|
||||
# depend:
|
||||
# Make the dependencies for the source files, and store
|
||||
@ -59,7 +65,7 @@ DEPENDFILE?= .depend
|
||||
.if ${MK_DIRDEPS_BUILD} == "no"
|
||||
.MAKE.DEPENDFILE= ${DEPENDFILE}
|
||||
.endif
|
||||
DEPENDFILES= ${DEPENDFILE}
|
||||
CLEANDEPENDFILES= ${DEPENDFILE} ${DEPENDFILE}.*
|
||||
|
||||
# Keep `tags' here, before SRCS are mangled below for `depend'.
|
||||
.if !target(tags) && defined(SRCS) && !defined(NO_TAGS)
|
||||
@ -75,6 +81,16 @@ tags: ${SRCS}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# Skip reading .depend when not needed to speed up tree-walks
|
||||
# and simple lookups.
|
||||
.if !empty(.MAKEFLAGS:M-V${_V_READ_DEPEND}) || make(obj) || make(clean*) || \
|
||||
make(install*)
|
||||
_SKIP_READ_DEPEND= 1
|
||||
.if ${MK_DIRDEPS_BUILD} == "no"
|
||||
.MAKE.DEPENDFILE= /dev/null
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if defined(SRCS)
|
||||
CLEANFILES?=
|
||||
|
||||
@ -156,7 +172,6 @@ ${_D}.po: ${_DSRC} ${POBJS:S/^${_D}.po$//}
|
||||
|
||||
.if ${MK_FAST_DEPEND} == "yes" && \
|
||||
(${.MAKE.MODE:Mmeta} == "" || ${.MAKE.MODE:Mnofilemon} != "")
|
||||
DEPENDFILES+= ${DEPENDFILE}.*
|
||||
DEPEND_MP?= -MP
|
||||
# Handle OBJS=../somefile.o hacks. Just replace '/' rather than use :T to
|
||||
# avoid collisions.
|
||||
@ -176,7 +191,7 @@ DEPENDSRCS= ${SRCS:M*.[cSC]} ${SRCS:M*.cxx} ${SRCS:M*.cpp} ${SRCS:M*.cc}
|
||||
DEPENDOBJS+= ${DEPENDSRCS:R:S,$,.o,}
|
||||
.endif
|
||||
DEPENDFILES_OBJS= ${DEPENDOBJS:O:u:${DEPEND_FILTER}:C/^/${DEPENDFILE}./}
|
||||
.if ${.MAKEFLAGS:M-V} == ""
|
||||
.if !defined(_SKIP_READ_DEPEND)
|
||||
.for __depend_obj in ${DEPENDFILES_OBJS}
|
||||
.sinclude "${__depend_obj}"
|
||||
.endfor
|
||||
@ -205,14 +220,6 @@ depend: beforedepend ${DEPENDFILE} afterdepend
|
||||
# This could be simpler with bmake :tW but needs to support fmake for MFC.
|
||||
_CFLAGS_INCLUDES= ${CFLAGS:Q:S/\\ /,/g:C/-include,/-include%/g:C/,/ /g:M-include*:C/%/ /g}
|
||||
_CXXFLAGS_INCLUDES= ${CXXFLAGS:Q:S/\\ /,/g:C/-include,/-include%/g:C/,/ /g:M-include*:C/%/ /g}
|
||||
# XXX: Temporary hack to workaround .depend files not tracking -include
|
||||
_hdrincludes=${_CFLAGS_INCLUDES:M*.h} ${_CXXFLAGS_INCLUDES:M*.h}
|
||||
.for _hdr in ${_hdrincludes:O:u}
|
||||
.if exists(${_hdr})
|
||||
${OBJS} ${POBJS} ${SOBJS}: ${_hdr}
|
||||
.endif
|
||||
.endfor
|
||||
.undef _hdrincludes
|
||||
|
||||
# Different types of sources are compiled with slightly different flags.
|
||||
# Split up the sources, and filter out headers and non-applicable flags.
|
||||
@ -261,16 +268,20 @@ afterdepend:
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${CTAGS:T} == "gtags"
|
||||
CLEANDEPENDFILES+= GPATH GRTAGS GSYMS GTAGS
|
||||
.if defined(HTML)
|
||||
CLEANDEPENDDIRS+= HTML
|
||||
.endif
|
||||
.else
|
||||
CLEANDEPENDFILES+= tags
|
||||
.endif
|
||||
.if !target(cleandepend)
|
||||
cleandepend:
|
||||
.if defined(SRCS)
|
||||
.if ${CTAGS:T} == "gtags"
|
||||
rm -f ${DEPENDFILES} GPATH GRTAGS GSYMS GTAGS
|
||||
.if defined(HTML)
|
||||
rm -rf HTML
|
||||
.endif
|
||||
.else
|
||||
rm -f ${DEPENDFILES} tags
|
||||
rm -f ${CLEANDEPENDFILES}
|
||||
.if !empty(CLEANDEPENDDIRS)
|
||||
rm -rf ${CLEANDEPENDDIRS}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
@ -15,6 +15,10 @@ __<bsd.init.mk>__:
|
||||
.endif
|
||||
.include <bsd.own.mk>
|
||||
.MAIN: all
|
||||
beforebuild: .PHONY .NOTMAIN
|
||||
.if !defined(_SKIP_BUILD)
|
||||
all: beforebuild .WAIT
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL:U1} == 0 && ${BUILD_AT_LEVEL0:Uyes:tl} == "no" && !make(clean*)
|
||||
# this tells lib.mk and prog.mk to not actually build anything
|
||||
|
@ -128,11 +128,6 @@ PO_FLAG=-pg
|
||||
-c ${.IMPSRC} -o ${.TARGET}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
.if !defined(_SKIP_BUILD)
|
||||
all: beforebuild .WAIT
|
||||
beforebuild: objwarn
|
||||
.endif
|
||||
|
||||
_LIBDIR:=${LIBDIR}
|
||||
_SHLIBDIR:=${SHLIBDIR}
|
||||
|
||||
|
@ -89,6 +89,7 @@ objwarn:
|
||||
canonical ${CANONICALOBJDIR}"
|
||||
.endif
|
||||
.endif
|
||||
beforebuild: objwarn
|
||||
|
||||
.if !defined(NO_OBJ)
|
||||
.if !target(obj)
|
||||
|
@ -148,8 +148,7 @@ MAN1= ${MAN}
|
||||
.if defined(_SKIP_BUILD)
|
||||
all:
|
||||
.else
|
||||
all: beforebuild .WAIT ${PROG} ${SCRIPTS}
|
||||
beforebuild: objwarn
|
||||
all: ${PROG} ${SCRIPTS}
|
||||
.if ${MK_MAN} != "no"
|
||||
all: _manpages
|
||||
.endif
|
||||
|
@ -89,6 +89,7 @@ ${__stage}install:
|
||||
install: beforeinstall realinstall afterinstall
|
||||
.ORDER: beforeinstall realinstall afterinstall
|
||||
.endif
|
||||
.ORDER: all install
|
||||
|
||||
# SUBDIR recursing may be disabled for MK_DIRDEPS_BUILD
|
||||
.if !target(_SUBDIR)
|
||||
|
@ -68,6 +68,7 @@ _TESTS=
|
||||
SUBDIR+= ${ts}
|
||||
.endif
|
||||
.endfor
|
||||
SUBDIR_PARALLEL= t
|
||||
.endif
|
||||
|
||||
# it is rare for test cases to have man pages
|
||||
|
@ -204,6 +204,7 @@ CSU_DIR := ${CSU_DIR.${MACHINE_ARCH}}
|
||||
.if !empty(TIME_STAMP)
|
||||
TRACER= ${TIME_STAMP} ${:U}
|
||||
.endif
|
||||
WITH_META_STATS= t
|
||||
|
||||
# toolchains can be a pain - especially bootstrappping them
|
||||
.if ${MACHINE} == "host"
|
||||
|
@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/rman.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/gpio.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
@ -49,7 +48,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/ahci/ahci.h>
|
||||
#include <arm/allwinner/a10_clk.h>
|
||||
#include "gpio_if.h"
|
||||
|
||||
/*
|
||||
* Allwinner a1x/a2x/a8x SATA attachment. This is just the AHCI register
|
||||
@ -119,9 +117,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define AHCI_P0PHYCR 0x0078
|
||||
#define AHCI_P0PHYSR 0x007C
|
||||
|
||||
/* Kludge for CUBIEBOARD (and Banana PI too) */
|
||||
#define GPIO_AHCI_PWR 40
|
||||
|
||||
static void inline
|
||||
ahci_set(struct resource *m, bus_size_t off, uint32_t set)
|
||||
{
|
||||
@ -298,7 +293,6 @@ ahci_a10_probe(device_t dev)
|
||||
static int
|
||||
ahci_a10_attach(device_t dev)
|
||||
{
|
||||
device_t gpio;
|
||||
int error;
|
||||
struct ahci_controller *ctlr;
|
||||
|
||||
@ -316,19 +310,6 @@ ahci_a10_attach(device_t dev)
|
||||
/* Turn on the PLL for SATA */
|
||||
a10_clk_ahci_activate();
|
||||
|
||||
/* Apply power to the drive, if any */
|
||||
gpio = devclass_get_device(devclass_find("gpio"), 0);
|
||||
if (gpio == NULL) {
|
||||
device_printf(dev,
|
||||
"GPIO device not yet present (SATA won't work).\n");
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
|
||||
ctlr->r_mem);
|
||||
return (ENXIO);
|
||||
}
|
||||
GPIO_PIN_SETFLAGS(gpio, GPIO_AHCI_PWR, GPIO_PIN_OUTPUT);
|
||||
GPIO_PIN_SET(gpio, GPIO_AHCI_PWR, GPIO_PIN_HIGH);
|
||||
DELAY(10000);
|
||||
|
||||
/* Reset controller */
|
||||
if ((error = ahci_a10_ctlr_reset(dev)) != 0) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
|
||||
|
@ -400,6 +400,29 @@ a10_clk_mmc_cfg(int devid, int freq)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
a10_clk_i2c_activate(int devid)
|
||||
{
|
||||
struct a10_ccm_softc *sc;
|
||||
uint32_t reg_value;
|
||||
|
||||
sc = a10_ccm_sc;
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
a10_clk_pll6_enable();
|
||||
|
||||
/* Gating APB clock for I2C/TWI */
|
||||
reg_value = ccm_read_4(sc, CCM_APB1_GATING);
|
||||
if (devid == 4)
|
||||
reg_value |= CCM_APB1_GATING_TWI << 15;
|
||||
else
|
||||
reg_value |= CCM_APB1_GATING_TWI << devid;
|
||||
ccm_write_4(sc, CCM_APB1_GATING, reg_value);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
a10_clk_dmac_activate(void)
|
||||
{
|
||||
|
@ -121,6 +121,9 @@
|
||||
/* AHB_GATING_REG1 */
|
||||
#define CCM_AHB_GATING_GMAC (1 << 17)
|
||||
|
||||
/* APB1_GATING_REG */
|
||||
#define CCM_APB1_GATING_TWI (1 << 0)
|
||||
|
||||
#define CCM_USB_PHY (1 << 8)
|
||||
#define CCM_USB0_RESET (1 << 0)
|
||||
#define CCM_USB1_RESET (1 << 1)
|
||||
@ -166,6 +169,7 @@ int a10_clk_gmac_activate(phandle_t);
|
||||
int a10_clk_ahci_activate(void);
|
||||
int a10_clk_mmc_activate(int);
|
||||
int a10_clk_mmc_cfg(int, int);
|
||||
int a10_clk_i2c_activate(int);
|
||||
int a10_clk_dmac_activate(void);
|
||||
int a10_clk_codec_activate(unsigned int);
|
||||
|
||||
|
850
sys/arm/allwinner/a10_codec.c
Normal file
850
sys/arm/allwinner/a10_codec.c
Normal file
@ -0,0 +1,850 @@
|
||||
/*-
|
||||
* Copyright (c) 2014-2016 Jared D. McNeill <jmcneill@invisible.ca>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Allwinner A10/A20 Audio Codec
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/gpio.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/sound/pcm/sound.h>
|
||||
#include <dev/sound/chip.h>
|
||||
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <arm/allwinner/a10_clk.h>
|
||||
|
||||
#include "sunxi_dma_if.h"
|
||||
#include "mixer_if.h"
|
||||
#include "gpio_if.h"
|
||||
|
||||
#define TX_TRIG_LEVEL 0xf
|
||||
#define RX_TRIG_LEVEL 0x7
|
||||
#define DRQ_CLR_CNT 0x3
|
||||
|
||||
#define AC_DAC_DPC 0x00
|
||||
#define DAC_DPC_EN_DA 0x80000000
|
||||
#define AC_DAC_FIFOC 0x04
|
||||
#define DAC_FIFOC_FS_SHIFT 29
|
||||
#define DAC_FIFOC_FS_MASK (7U << DAC_FIFOC_FS_SHIFT)
|
||||
#define DAC_FS_48KHZ 0
|
||||
#define DAC_FS_32KHZ 1
|
||||
#define DAC_FS_24KHZ 2
|
||||
#define DAC_FS_16KHZ 3
|
||||
#define DAC_FS_12KHZ 4
|
||||
#define DAC_FS_8KHZ 5
|
||||
#define DAC_FS_192KHZ 6
|
||||
#define DAC_FS_96KHZ 7
|
||||
#define DAC_FIFOC_FIFO_MODE_SHIFT 24
|
||||
#define DAC_FIFOC_FIFO_MODE_MASK (3U << DAC_FIFOC_FIFO_MODE_SHIFT)
|
||||
#define FIFO_MODE_24_31_8 0
|
||||
#define FIFO_MODE_16_31_16 0
|
||||
#define FIFO_MODE_16_15_0 1
|
||||
#define DAC_FIFOC_DRQ_CLR_CNT_SHIFT 21
|
||||
#define DAC_FIFOC_DRQ_CLR_CNT_MASK (3U << DAC_FIFOC_DRQ_CLR_CNT_SHIFT)
|
||||
#define DAC_FIFOC_TX_TRIG_LEVEL_SHIFT 8
|
||||
#define DAC_FIFOC_TX_TRIG_LEVEL_MASK (0x7f << DAC_FIFOC_TX_TRIG_LEVEL_SHIFT)
|
||||
#define DAC_FIFOC_MONO_EN (1U << 6)
|
||||
#define DAC_FIFOC_TX_BITS (1U << 5)
|
||||
#define DAC_FIFOC_DRQ_EN (1U << 4)
|
||||
#define DAC_FIFOC_FIFO_FLUSH (1U << 0)
|
||||
#define AC_DAC_FIFOS 0x08
|
||||
#define AC_DAC_TXDATA 0x0c
|
||||
#define AC_DAC_ACTL 0x10
|
||||
#define DAC_ACTL_DACAREN (1U << 31)
|
||||
#define DAC_ACTL_DACALEN (1U << 30)
|
||||
#define DAC_ACTL_MIXEN (1U << 29)
|
||||
#define DAC_ACTL_DACPAS (1U << 8)
|
||||
#define DAC_ACTL_PAMUTE (1U << 6)
|
||||
#define DAC_ACTL_PAVOL_SHIFT 0
|
||||
#define DAC_ACTL_PAVOL_MASK (0x3f << DAC_ACTL_PAVOL_SHIFT)
|
||||
#define AC_ADC_FIFOC 0x1c
|
||||
#define ADC_FIFOC_FS_SHIFT 29
|
||||
#define ADC_FIFOC_FS_MASK (7U << ADC_FIFOC_FS_SHIFT)
|
||||
#define ADC_FS_48KHZ 0
|
||||
#define ADC_FIFOC_EN_AD (1U << 28)
|
||||
#define ADC_FIFOC_RX_FIFO_MODE (1U << 24)
|
||||
#define ADC_FIFOC_RX_TRIG_LEVEL_SHIFT 8
|
||||
#define ADC_FIFOC_RX_TRIG_LEVEL_MASK (0x1f << ADC_FIFOC_RX_TRIG_LEVEL_SHIFT)
|
||||
#define ADC_FIFOC_MONO_EN (1U << 7)
|
||||
#define ADC_FIFOC_RX_BITS (1U << 6)
|
||||
#define ADC_FIFOC_DRQ_EN (1U << 4)
|
||||
#define ADC_FIFOC_FIFO_FLUSH (1U << 1)
|
||||
#define AC_ADC_FIFOS 0x20
|
||||
#define AC_ADC_RXDATA 0x24
|
||||
#define AC_ADC_ACTL 0x28
|
||||
#define ADC_ACTL_ADCREN (1U << 31)
|
||||
#define ADC_ACTL_ADCLEN (1U << 30)
|
||||
#define ADC_ACTL_PREG1EN (1U << 29)
|
||||
#define ADC_ACTL_PREG2EN (1U << 28)
|
||||
#define ADC_ACTL_VMICEN (1U << 27)
|
||||
#define ADC_ACTL_ADCG_SHIFT 20
|
||||
#define ADC_ACTL_ADCG_MASK (7U << ADC_ACTL_ADCG_SHIFT)
|
||||
#define ADC_ACTL_ADCIS_SHIFT 17
|
||||
#define ADC_ACTL_ADCIS_MASK (7U << ADC_ACTL_ADCIS_SHIFT)
|
||||
#define ADC_IS_LINEIN 0
|
||||
#define ADC_IS_FMIN 1
|
||||
#define ADC_IS_MIC1 2
|
||||
#define ADC_IS_MIC2 3
|
||||
#define ADC_IS_MIC1_L_MIC2_R 4
|
||||
#define ADC_IS_MIC1_LR_MIC2_LR 5
|
||||
#define ADC_IS_OMIX 6
|
||||
#define ADC_IS_LINEIN_L_MIC1_R 7
|
||||
#define ADC_ACTL_LNRDF (1U << 16)
|
||||
#define ADC_ACTL_LNPREG_SHIFT 13
|
||||
#define ADC_ACTL_LNPREG_MASK (7U << ADC_ACTL_LNPREG_SHIFT)
|
||||
#define ADC_ACTL_PA_EN (1U << 4)
|
||||
#define ADC_ACTL_DDE (1U << 3)
|
||||
#define AC_DAC_CNT 0x30
|
||||
#define AC_ADC_CNT 0x34
|
||||
|
||||
static uint32_t a10codec_fmt[] = {
|
||||
SND_FORMAT(AFMT_S16_LE, 1, 0),
|
||||
SND_FORMAT(AFMT_S16_LE, 2, 0),
|
||||
0
|
||||
};
|
||||
|
||||
static struct pcmchan_caps a10codec_pcaps = { 8000, 192000, a10codec_fmt, 0 };
|
||||
static struct pcmchan_caps a10codec_rcaps = { 8000, 48000, a10codec_fmt, 0 };
|
||||
|
||||
struct a10codec_info;
|
||||
|
||||
struct a10codec_chinfo {
|
||||
struct snd_dbuf *buffer;
|
||||
struct pcm_channel *channel;
|
||||
struct a10codec_info *parent;
|
||||
bus_dmamap_t dmamap;
|
||||
void *dmaaddr;
|
||||
bus_addr_t physaddr;
|
||||
bus_size_t fifo;
|
||||
device_t dmac;
|
||||
void *dmachan;
|
||||
|
||||
int dir;
|
||||
int run;
|
||||
uint32_t pos;
|
||||
uint32_t format;
|
||||
uint32_t blocksize;
|
||||
uint32_t speed;
|
||||
};
|
||||
|
||||
struct a10codec_info {
|
||||
device_t dev;
|
||||
struct resource *res[2];
|
||||
struct mtx *lock;
|
||||
bus_dma_tag_t dmat;
|
||||
unsigned dmasize;
|
||||
void *ih;
|
||||
|
||||
unsigned drqtype_codec;
|
||||
unsigned drqtype_sdram;
|
||||
|
||||
struct a10codec_chinfo play;
|
||||
struct a10codec_chinfo rec;
|
||||
};
|
||||
|
||||
static struct resource_spec a10codec_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE },
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
#define CODEC_READ(sc, reg) bus_read_4((sc)->res[0], (reg))
|
||||
#define CODEC_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
|
||||
|
||||
/*
|
||||
* Mixer interface
|
||||
*/
|
||||
|
||||
static int
|
||||
a10codec_mixer_init(struct snd_mixer *m)
|
||||
{
|
||||
struct a10codec_info *sc = mix_getdevinfo(m);
|
||||
pcell_t prop[4];
|
||||
phandle_t node;
|
||||
device_t gpio;
|
||||
uint32_t val;
|
||||
ssize_t len;
|
||||
int pin;
|
||||
|
||||
mix_setdevs(m, SOUND_MASK_VOLUME | SOUND_MASK_LINE | SOUND_MASK_RECLEV);
|
||||
mix_setrecdevs(m, SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC);
|
||||
|
||||
/* Unmute input source to PA */
|
||||
val = CODEC_READ(sc, AC_DAC_ACTL);
|
||||
val |= DAC_ACTL_PAMUTE;
|
||||
CODEC_WRITE(sc, AC_DAC_ACTL, val);
|
||||
|
||||
/* Enable PA */
|
||||
val = CODEC_READ(sc, AC_ADC_ACTL);
|
||||
val |= ADC_ACTL_PA_EN;
|
||||
CODEC_WRITE(sc, AC_ADC_ACTL, val);
|
||||
|
||||
/* Unmute PA */
|
||||
node = ofw_bus_get_node(sc->dev);
|
||||
len = OF_getencprop(node, "allwinner,pa-gpios", prop, sizeof(prop));
|
||||
if (len > 0 && (len / sizeof(prop[0])) == 4) {
|
||||
gpio = OF_device_from_xref(prop[0]);
|
||||
if (gpio != NULL) {
|
||||
pin = prop[1] * 32 + prop[2];
|
||||
GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT);
|
||||
GPIO_PIN_SET(gpio, pin, GPIO_PIN_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct a10codec_mixer {
|
||||
unsigned reg;
|
||||
unsigned mask;
|
||||
unsigned shift;
|
||||
} a10codec_mixers[SOUND_MIXER_NRDEVICES] = {
|
||||
[SOUND_MIXER_VOLUME] = { AC_DAC_ACTL, DAC_ACTL_PAVOL_MASK,
|
||||
DAC_ACTL_PAVOL_SHIFT },
|
||||
[SOUND_MIXER_LINE] = { AC_ADC_ACTL, ADC_ACTL_LNPREG_MASK,
|
||||
ADC_ACTL_LNPREG_SHIFT },
|
||||
[SOUND_MIXER_RECLEV] = { AC_ADC_ACTL, ADC_ACTL_ADCG_MASK,
|
||||
ADC_ACTL_ADCG_SHIFT },
|
||||
};
|
||||
|
||||
static int
|
||||
a10codec_mixer_set(struct snd_mixer *m, unsigned dev, unsigned left,
|
||||
unsigned right)
|
||||
{
|
||||
struct a10codec_info *sc = mix_getdevinfo(m);
|
||||
uint32_t val;
|
||||
unsigned nvol, max;
|
||||
|
||||
max = a10codec_mixers[dev].mask >> a10codec_mixers[dev].shift;
|
||||
nvol = (left * max) / 100;
|
||||
|
||||
val = CODEC_READ(sc, a10codec_mixers[dev].reg);
|
||||
val &= ~a10codec_mixers[dev].mask;
|
||||
val |= (nvol << a10codec_mixers[dev].shift);
|
||||
CODEC_WRITE(sc, a10codec_mixers[dev].reg, val);
|
||||
|
||||
left = right = (left * 100) / max;
|
||||
return (left | (right << 8));
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
a10codec_mixer_setrecsrc(struct snd_mixer *m, uint32_t src)
|
||||
{
|
||||
struct a10codec_info *sc = mix_getdevinfo(m);
|
||||
uint32_t val;
|
||||
|
||||
val = CODEC_READ(sc, AC_ADC_ACTL);
|
||||
|
||||
switch (src) {
|
||||
case SOUND_MASK_LINE: /* line-in */
|
||||
val &= ~ADC_ACTL_ADCIS_MASK;
|
||||
val |= (ADC_IS_LINEIN << ADC_ACTL_ADCIS_SHIFT);
|
||||
break;
|
||||
case SOUND_MASK_MIC: /* MIC1 */
|
||||
val &= ~ADC_ACTL_ADCIS_MASK;
|
||||
val |= (ADC_IS_MIC1 << ADC_ACTL_ADCIS_SHIFT);
|
||||
break;
|
||||
case SOUND_MASK_LINE1: /* MIC2 */
|
||||
val &= ~ADC_ACTL_ADCIS_MASK;
|
||||
val |= (ADC_IS_MIC2 << ADC_ACTL_ADCIS_SHIFT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CODEC_WRITE(sc, AC_ADC_ACTL, val);
|
||||
|
||||
switch ((val & ADC_ACTL_ADCIS_MASK) >> ADC_ACTL_ADCIS_SHIFT) {
|
||||
case ADC_IS_LINEIN:
|
||||
return (SOUND_MASK_LINE);
|
||||
case ADC_IS_MIC1:
|
||||
return (SOUND_MASK_MIC);
|
||||
case ADC_IS_MIC2:
|
||||
return (SOUND_MASK_LINE1);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
static kobj_method_t a10codec_mixer_methods[] = {
|
||||
KOBJMETHOD(mixer_init, a10codec_mixer_init),
|
||||
KOBJMETHOD(mixer_set, a10codec_mixer_set),
|
||||
KOBJMETHOD(mixer_setrecsrc, a10codec_mixer_setrecsrc),
|
||||
KOBJMETHOD_END
|
||||
};
|
||||
MIXER_DECLARE(a10codec_mixer);
|
||||
|
||||
|
||||
/*
|
||||
* Channel interface
|
||||
*/
|
||||
|
||||
static void
|
||||
a10codec_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||
{
|
||||
struct a10codec_chinfo *ch = arg;
|
||||
|
||||
if (error != 0)
|
||||
return;
|
||||
|
||||
ch->physaddr = segs[0].ds_addr;
|
||||
}
|
||||
|
||||
static void
|
||||
a10codec_transfer(struct a10codec_chinfo *ch)
|
||||
{
|
||||
bus_addr_t src, dst;
|
||||
int error;
|
||||
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
src = ch->physaddr + ch->pos;
|
||||
dst = ch->fifo;
|
||||
} else {
|
||||
src = ch->fifo;
|
||||
dst = ch->physaddr + ch->pos;
|
||||
}
|
||||
|
||||
error = SUNXI_DMA_TRANSFER(ch->dmac, ch->dmachan, src, dst,
|
||||
ch->blocksize);
|
||||
if (error) {
|
||||
ch->run = 0;
|
||||
device_printf(ch->parent->dev, "DMA transfer failed: %d\n",
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
a10codec_dmaconfig(struct a10codec_chinfo *ch)
|
||||
{
|
||||
struct a10codec_info *sc = ch->parent;
|
||||
struct sunxi_dma_config conf;
|
||||
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
conf.src_width = conf.dst_width = 16;
|
||||
conf.src_burst_len = conf.dst_burst_len = 4;
|
||||
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
conf.dst_noincr = true;
|
||||
conf.src_drqtype = sc->drqtype_sdram;
|
||||
conf.dst_drqtype = sc->drqtype_codec;
|
||||
} else {
|
||||
conf.src_noincr = true;
|
||||
conf.src_drqtype = sc->drqtype_codec;
|
||||
conf.dst_drqtype = sc->drqtype_sdram;
|
||||
}
|
||||
|
||||
SUNXI_DMA_SET_CONFIG(ch->dmac, ch->dmachan, &conf);
|
||||
}
|
||||
|
||||
static void
|
||||
a10codec_dmaintr(void *priv)
|
||||
{
|
||||
struct a10codec_chinfo *ch = priv;
|
||||
unsigned bufsize;
|
||||
|
||||
bufsize = sndbuf_getsize(ch->buffer);
|
||||
|
||||
ch->pos += ch->blocksize;
|
||||
if (ch->pos >= bufsize)
|
||||
ch->pos -= bufsize;
|
||||
|
||||
if (ch->run) {
|
||||
chn_intr(ch->channel);
|
||||
a10codec_transfer(ch);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
a10codec_fs(struct a10codec_chinfo *ch)
|
||||
{
|
||||
switch (ch->speed) {
|
||||
case 48000:
|
||||
return (DAC_FS_48KHZ);
|
||||
case 24000:
|
||||
return (DAC_FS_24KHZ);
|
||||
case 12000:
|
||||
return (DAC_FS_12KHZ);
|
||||
case 192000:
|
||||
return (DAC_FS_192KHZ);
|
||||
case 32000:
|
||||
return (DAC_FS_32KHZ);
|
||||
case 16000:
|
||||
return (DAC_FS_16KHZ);
|
||||
case 8000:
|
||||
return (DAC_FS_8KHZ);
|
||||
case 96000:
|
||||
return (DAC_FS_96KHZ);
|
||||
default:
|
||||
return (DAC_FS_48KHZ);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
a10codec_start(struct a10codec_chinfo *ch)
|
||||
{
|
||||
struct a10codec_info *sc = ch->parent;
|
||||
uint32_t val;
|
||||
|
||||
ch->pos = 0;
|
||||
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
/* Flush DAC FIFO */
|
||||
CODEC_WRITE(sc, AC_DAC_FIFOC, DAC_FIFOC_FIFO_FLUSH);
|
||||
|
||||
/* Clear DAC FIFO status */
|
||||
CODEC_WRITE(sc, AC_DAC_FIFOS, CODEC_READ(sc, AC_DAC_FIFOS));
|
||||
|
||||
/* Enable DAC analog left/right channels and output mixer */
|
||||
val = CODEC_READ(sc, AC_DAC_ACTL);
|
||||
val |= DAC_ACTL_DACAREN;
|
||||
val |= DAC_ACTL_DACALEN;
|
||||
val |= DAC_ACTL_DACPAS;
|
||||
CODEC_WRITE(sc, AC_DAC_ACTL, val);
|
||||
|
||||
/* Configure DAC DMA channel */
|
||||
a10codec_dmaconfig(ch);
|
||||
|
||||
/* Configure DAC FIFO */
|
||||
CODEC_WRITE(sc, AC_DAC_FIFOC,
|
||||
(AFMT_CHANNEL(ch->format) == 1 ? DAC_FIFOC_MONO_EN : 0) |
|
||||
(a10codec_fs(ch) << DAC_FIFOC_FS_SHIFT) |
|
||||
(FIFO_MODE_16_15_0 << DAC_FIFOC_FIFO_MODE_SHIFT) |
|
||||
(DRQ_CLR_CNT << DAC_FIFOC_DRQ_CLR_CNT_SHIFT) |
|
||||
(TX_TRIG_LEVEL << DAC_FIFOC_TX_TRIG_LEVEL_SHIFT));
|
||||
|
||||
/* Enable DAC DRQ */
|
||||
val = CODEC_READ(sc, AC_DAC_FIFOC);
|
||||
val |= DAC_FIFOC_DRQ_EN;
|
||||
CODEC_WRITE(sc, AC_DAC_FIFOC, val);
|
||||
} else {
|
||||
/* Flush ADC FIFO */
|
||||
CODEC_WRITE(sc, AC_ADC_FIFOC, ADC_FIFOC_FIFO_FLUSH);
|
||||
|
||||
/* Clear ADC FIFO status */
|
||||
CODEC_WRITE(sc, AC_ADC_FIFOS, CODEC_READ(sc, AC_ADC_FIFOS));
|
||||
|
||||
/* Enable ADC analog left/right channels, MIC1 preamp,
|
||||
* and VMIC pin voltage
|
||||
*/
|
||||
val = CODEC_READ(sc, AC_ADC_ACTL);
|
||||
val |= ADC_ACTL_ADCREN;
|
||||
val |= ADC_ACTL_ADCLEN;
|
||||
val |= ADC_ACTL_PREG1EN;
|
||||
val |= ADC_ACTL_VMICEN;
|
||||
CODEC_WRITE(sc, AC_ADC_ACTL, val);
|
||||
|
||||
/* Configure ADC DMA channel */
|
||||
a10codec_dmaconfig(ch);
|
||||
|
||||
/* Configure ADC FIFO */
|
||||
CODEC_WRITE(sc, AC_ADC_FIFOC,
|
||||
ADC_FIFOC_EN_AD |
|
||||
ADC_FIFOC_RX_FIFO_MODE |
|
||||
(AFMT_CHANNEL(ch->format) == 1 ? ADC_FIFOC_MONO_EN : 0) |
|
||||
(a10codec_fs(ch) << ADC_FIFOC_FS_SHIFT) |
|
||||
(RX_TRIG_LEVEL << ADC_FIFOC_RX_TRIG_LEVEL_SHIFT));
|
||||
|
||||
/* Enable ADC DRQ */
|
||||
val = CODEC_READ(sc, AC_ADC_FIFOC);
|
||||
val |= ADC_FIFOC_DRQ_EN;
|
||||
CODEC_WRITE(sc, AC_ADC_FIFOC, val);
|
||||
}
|
||||
|
||||
/* Start DMA transfer */
|
||||
a10codec_transfer(ch);
|
||||
}
|
||||
|
||||
static void
|
||||
a10codec_stop(struct a10codec_chinfo *ch)
|
||||
{
|
||||
struct a10codec_info *sc = ch->parent;
|
||||
uint32_t val;
|
||||
|
||||
/* Disable DMA channel */
|
||||
SUNXI_DMA_HALT(ch->dmac, ch->dmachan);
|
||||
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
/* Disable DAC analog left/right channels and output mixer */
|
||||
val = CODEC_READ(sc, AC_DAC_ACTL);
|
||||
val &= ~DAC_ACTL_DACAREN;
|
||||
val &= ~DAC_ACTL_DACALEN;
|
||||
val &= ~DAC_ACTL_DACPAS;
|
||||
CODEC_WRITE(sc, AC_DAC_ACTL, val);
|
||||
|
||||
/* Disable DAC DRQ */
|
||||
CODEC_WRITE(sc, AC_DAC_FIFOC, 0);
|
||||
} else {
|
||||
/* Disable ADC analog left/right channels, MIC1 preamp,
|
||||
* and VMIC pin voltage
|
||||
*/
|
||||
val = CODEC_READ(sc, AC_ADC_ACTL);
|
||||
val &= ~ADC_ACTL_ADCREN;
|
||||
val &= ~ADC_ACTL_ADCLEN;
|
||||
val &= ~ADC_ACTL_PREG1EN;
|
||||
val &= ~ADC_ACTL_VMICEN;
|
||||
CODEC_WRITE(sc, AC_ADC_ACTL, val);
|
||||
|
||||
/* Disable ADC DRQ */
|
||||
CODEC_WRITE(sc, AC_ADC_FIFOC, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
a10codec_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
|
||||
struct pcm_channel *c, int dir)
|
||||
{
|
||||
struct a10codec_info *sc = devinfo;
|
||||
struct a10codec_chinfo *ch = dir == PCMDIR_PLAY ? &sc->play : &sc->rec;
|
||||
int error;
|
||||
|
||||
ch->parent = sc;
|
||||
ch->channel = c;
|
||||
ch->buffer = b;
|
||||
ch->dir = dir;
|
||||
ch->fifo = rman_get_start(sc->res[0]) +
|
||||
(dir == PCMDIR_REC ? AC_ADC_RXDATA : AC_DAC_TXDATA);
|
||||
|
||||
ch->dmac = devclass_get_device(devclass_find("a10dmac"), 0);
|
||||
if (ch->dmac == NULL) {
|
||||
device_printf(sc->dev, "cannot find DMA controller\n");
|
||||
return (NULL);
|
||||
}
|
||||
ch->dmachan = SUNXI_DMA_ALLOC(ch->dmac, false, a10codec_dmaintr, ch);
|
||||
if (ch->dmachan == NULL) {
|
||||
device_printf(sc->dev, "cannot allocate DMA channel\n");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
error = bus_dmamem_alloc(sc->dmat, &ch->dmaaddr,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &ch->dmamap);
|
||||
if (error != 0) {
|
||||
device_printf(sc->dev, "cannot allocate channel buffer\n");
|
||||
return (NULL);
|
||||
}
|
||||
error = bus_dmamap_load(sc->dmat, ch->dmamap, ch->dmaaddr,
|
||||
sc->dmasize, a10codec_dmamap_cb, ch, BUS_DMA_NOWAIT);
|
||||
if (error != 0) {
|
||||
device_printf(sc->dev, "cannot load DMA map\n");
|
||||
return (NULL);
|
||||
}
|
||||
memset(ch->dmaaddr, 0, sc->dmasize);
|
||||
|
||||
if (sndbuf_setup(ch->buffer, ch->dmaaddr, sc->dmasize) != 0) {
|
||||
device_printf(sc->dev, "cannot setup sndbuf\n");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
static int
|
||||
a10codec_chan_free(kobj_t obj, void *data)
|
||||
{
|
||||
struct a10codec_chinfo *ch = data;
|
||||
struct a10codec_info *sc = ch->parent;
|
||||
|
||||
SUNXI_DMA_FREE(ch->dmac, ch->dmachan);
|
||||
bus_dmamap_unload(sc->dmat, ch->dmamap);
|
||||
bus_dmamem_free(sc->dmat, ch->dmaaddr, ch->dmamap);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
a10codec_chan_setformat(kobj_t obj, void *data, uint32_t format)
|
||||
{
|
||||
struct a10codec_chinfo *ch = data;
|
||||
|
||||
ch->format = format;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
a10codec_chan_setspeed(kobj_t obj, void *data, uint32_t speed)
|
||||
{
|
||||
struct a10codec_chinfo *ch = data;
|
||||
|
||||
/*
|
||||
* The codec supports full duplex operation but both DAC and ADC
|
||||
* use the same source clock (PLL2). Limit the available speeds to
|
||||
* those supported by a 24576000 Hz input.
|
||||
*/
|
||||
switch (speed) {
|
||||
case 8000:
|
||||
case 12000:
|
||||
case 16000:
|
||||
case 24000:
|
||||
case 32000:
|
||||
case 48000:
|
||||
ch->speed = speed;
|
||||
break;
|
||||
case 96000:
|
||||
case 192000:
|
||||
/* 96 KHz / 192 KHz mode only supported for playback */
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
ch->speed = speed;
|
||||
} else {
|
||||
ch->speed = 48000;
|
||||
}
|
||||
break;
|
||||
case 44100:
|
||||
ch->speed = 48000;
|
||||
break;
|
||||
case 22050:
|
||||
ch->speed = 24000;
|
||||
break;
|
||||
case 11025:
|
||||
ch->speed = 12000;
|
||||
break;
|
||||
default:
|
||||
ch->speed = 48000;
|
||||
break;
|
||||
}
|
||||
|
||||
return (ch->speed);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
a10codec_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
|
||||
{
|
||||
struct a10codec_chinfo *ch = data;
|
||||
|
||||
ch->blocksize = blocksize & ~3;
|
||||
|
||||
return (ch->blocksize);
|
||||
}
|
||||
|
||||
static int
|
||||
a10codec_chan_trigger(kobj_t obj, void *data, int go)
|
||||
{
|
||||
struct a10codec_chinfo *ch = data;
|
||||
struct a10codec_info *sc = ch->parent;
|
||||
|
||||
if (!PCMTRIG_COMMON(go))
|
||||
return (0);
|
||||
|
||||
snd_mtxlock(sc->lock);
|
||||
switch (go) {
|
||||
case PCMTRIG_START:
|
||||
ch->run = 1;
|
||||
a10codec_start(ch);
|
||||
break;
|
||||
case PCMTRIG_STOP:
|
||||
case PCMTRIG_ABORT:
|
||||
ch->run = 0;
|
||||
a10codec_stop(ch);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
snd_mtxunlock(sc->lock);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
a10codec_chan_getptr(kobj_t obj, void *data)
|
||||
{
|
||||
struct a10codec_chinfo *ch = data;
|
||||
|
||||
return (ch->pos);
|
||||
}
|
||||
|
||||
static struct pcmchan_caps *
|
||||
a10codec_chan_getcaps(kobj_t obj, void *data)
|
||||
{
|
||||
struct a10codec_chinfo *ch = data;
|
||||
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
return (&a10codec_pcaps);
|
||||
} else {
|
||||
return (&a10codec_rcaps);
|
||||
}
|
||||
}
|
||||
|
||||
static kobj_method_t a10codec_chan_methods[] = {
|
||||
KOBJMETHOD(channel_init, a10codec_chan_init),
|
||||
KOBJMETHOD(channel_free, a10codec_chan_free),
|
||||
KOBJMETHOD(channel_setformat, a10codec_chan_setformat),
|
||||
KOBJMETHOD(channel_setspeed, a10codec_chan_setspeed),
|
||||
KOBJMETHOD(channel_setblocksize, a10codec_chan_setblocksize),
|
||||
KOBJMETHOD(channel_trigger, a10codec_chan_trigger),
|
||||
KOBJMETHOD(channel_getptr, a10codec_chan_getptr),
|
||||
KOBJMETHOD(channel_getcaps, a10codec_chan_getcaps),
|
||||
KOBJMETHOD_END
|
||||
};
|
||||
CHANNEL_DECLARE(a10codec_chan);
|
||||
|
||||
|
||||
/*
|
||||
* Device interface
|
||||
*/
|
||||
|
||||
static int
|
||||
a10codec_probe(device_t dev)
|
||||
{
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "allwinner,sun7i-a20-codec"))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "Allwinner Audio Codec");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
a10codec_attach(device_t dev)
|
||||
{
|
||||
struct a10codec_info *sc;
|
||||
char status[SND_STATUSLEN];
|
||||
uint32_t val;
|
||||
int error;
|
||||
|
||||
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
sc->dev = dev;
|
||||
sc->lock = snd_mtxcreate(device_get_nameunit(dev), "a10codec softc");
|
||||
|
||||
if (bus_alloc_resources(dev, a10codec_spec, sc->res)) {
|
||||
device_printf(dev, "cannot allocate resources for device\n");
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* XXX DRQ types should come from FDT, but how? */
|
||||
if (ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-codec") ||
|
||||
ofw_bus_is_compatible(dev, "allwinner,sun7i-a20-codec")) {
|
||||
sc->drqtype_codec = 19;
|
||||
sc->drqtype_sdram = 22;
|
||||
} else {
|
||||
device_printf(dev, "DRQ types not known for this SoC\n");
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->dmasize = 131072;
|
||||
error = bus_dma_tag_create(
|
||||
bus_get_dma_tag(dev),
|
||||
4, sc->dmasize, /* alignment, boundary */
|
||||
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
sc->dmasize, 1, /* maxsize, nsegs */
|
||||
sc->dmasize, 0, /* maxsegsize, flags */
|
||||
NULL, NULL, /* lockfunc, lockarg */
|
||||
&sc->dmat);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "cannot create DMA tag\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Activate audio codec clock. According to the A10 and A20 user
|
||||
* manuals, Audio_pll can be either 24.576MHz or 22.5792MHz. Most
|
||||
* audio sampling rates require an 24.576MHz input clock with the
|
||||
* exception of 44.1kHz, 22.05kHz, and 11.025kHz. Unfortunately,
|
||||
* both capture and playback use the same clock source so to
|
||||
* safely support independent full duplex operation, we use a fixed
|
||||
* 24.576MHz clock source and don't advertise native support for
|
||||
* the three sampling rates that require a 22.5792MHz input.
|
||||
*/
|
||||
a10_clk_codec_activate(24576000);
|
||||
|
||||
/* Enable DAC */
|
||||
val = CODEC_READ(sc, AC_DAC_DPC);
|
||||
val |= DAC_DPC_EN_DA;
|
||||
CODEC_WRITE(sc, AC_DAC_DPC, val);
|
||||
|
||||
#ifdef notdef
|
||||
error = snd_setup_intr(dev, sc->irq, INTR_MPSAFE, a10codec_intr, sc,
|
||||
&sc->ih);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "could not setup interrupt handler\n");
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mixer_init(dev, &a10codec_mixer_class, sc)) {
|
||||
device_printf(dev, "mixer_init failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
|
||||
|
||||
if (pcm_register(dev, sc, 1, 1)) {
|
||||
device_printf(dev, "pcm_register failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pcm_addchan(dev, PCMDIR_PLAY, &a10codec_chan_class, sc);
|
||||
pcm_addchan(dev, PCMDIR_REC, &a10codec_chan_class, sc);
|
||||
|
||||
snprintf(status, SND_STATUSLEN, "at %s", ofw_bus_get_name(dev));
|
||||
pcm_setstatus(dev, status);
|
||||
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
bus_release_resources(dev, a10codec_spec, sc->res);
|
||||
snd_mtxfree(sc->lock);
|
||||
free(sc, M_DEVBUF);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static device_method_t a10codec_pcm_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, a10codec_probe),
|
||||
DEVMETHOD(device_attach, a10codec_attach),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t a10codec_pcm_driver = {
|
||||
"pcm",
|
||||
a10codec_pcm_methods,
|
||||
PCM_SOFTC_SIZE,
|
||||
};
|
||||
|
||||
DRIVER_MODULE(a10codec, simplebus, a10codec_pcm_driver, pcm_devclass, 0, 0);
|
||||
MODULE_DEPEND(a10codec, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
|
||||
MODULE_VERSION(a10codec, 1);
|
453
sys/arm/allwinner/a10_dmac.c
Normal file
453
sys/arm/allwinner/a10_dmac.c
Normal file
@ -0,0 +1,453 @@
|
||||
/*-
|
||||
* Copyright (c) 2014-2016 Jared D. McNeill <jmcneill@invisible.ca>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Allwinner A10/A20 DMA controller
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <arm/allwinner/a10_dmac.h>
|
||||
#include <arm/allwinner/a10_clk.h>
|
||||
|
||||
#include "sunxi_dma_if.h"
|
||||
|
||||
#define NDMA_CHANNELS 8
|
||||
#define DDMA_CHANNELS 8
|
||||
|
||||
enum a10dmac_type {
|
||||
CH_NDMA,
|
||||
CH_DDMA
|
||||
};
|
||||
|
||||
struct a10dmac_softc;
|
||||
|
||||
struct a10dmac_channel {
|
||||
struct a10dmac_softc * ch_sc;
|
||||
uint8_t ch_index;
|
||||
enum a10dmac_type ch_type;
|
||||
void (*ch_callback)(void *);
|
||||
void * ch_callbackarg;
|
||||
uint32_t ch_regoff;
|
||||
};
|
||||
|
||||
struct a10dmac_softc {
|
||||
struct resource * sc_res[2];
|
||||
struct mtx sc_mtx;
|
||||
void * sc_ih;
|
||||
|
||||
struct a10dmac_channel sc_ndma_channels[NDMA_CHANNELS];
|
||||
struct a10dmac_channel sc_ddma_channels[DDMA_CHANNELS];
|
||||
};
|
||||
|
||||
static struct resource_spec a10dmac_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE },
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
#define DMA_READ(sc, reg) bus_read_4((sc)->sc_res[0], (reg))
|
||||
#define DMA_WRITE(sc, reg, val) bus_write_4((sc)->sc_res[0], (reg), (val))
|
||||
#define DMACH_READ(ch, reg) \
|
||||
DMA_READ((ch)->ch_sc, (reg) + (ch)->ch_regoff)
|
||||
#define DMACH_WRITE(ch, reg, val) \
|
||||
DMA_WRITE((ch)->ch_sc, (reg) + (ch)->ch_regoff, (val))
|
||||
|
||||
static void a10dmac_intr(void *);
|
||||
|
||||
static int
|
||||
a10dmac_probe(device_t dev)
|
||||
{
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-dma"))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "Allwinner DMA controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
a10dmac_attach(device_t dev)
|
||||
{
|
||||
struct a10dmac_softc *sc;
|
||||
unsigned int index;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if (bus_alloc_resources(dev, a10dmac_spec, sc->sc_res)) {
|
||||
device_printf(dev, "cannot allocate resources for device\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
mtx_init(&sc->sc_mtx, "a10 dmac", NULL, MTX_SPIN);
|
||||
|
||||
/* Activate DMA controller clock */
|
||||
a10_clk_dmac_activate();
|
||||
|
||||
/* Disable all interrupts and clear pending status */
|
||||
DMA_WRITE(sc, AWIN_DMA_IRQ_EN_REG, 0);
|
||||
DMA_WRITE(sc, AWIN_DMA_IRQ_PEND_STA_REG, ~0);
|
||||
|
||||
/* Initialize channels */
|
||||
for (index = 0; index < NDMA_CHANNELS; index++) {
|
||||
sc->sc_ndma_channels[index].ch_sc = sc;
|
||||
sc->sc_ndma_channels[index].ch_index = index;
|
||||
sc->sc_ndma_channels[index].ch_type = CH_NDMA;
|
||||
sc->sc_ndma_channels[index].ch_callback = NULL;
|
||||
sc->sc_ndma_channels[index].ch_callbackarg = NULL;
|
||||
sc->sc_ndma_channels[index].ch_regoff = AWIN_NDMA_REG(index);
|
||||
DMACH_WRITE(&sc->sc_ndma_channels[index], AWIN_NDMA_CTL_REG, 0);
|
||||
}
|
||||
for (index = 0; index < DDMA_CHANNELS; index++) {
|
||||
sc->sc_ddma_channels[index].ch_sc = sc;
|
||||
sc->sc_ddma_channels[index].ch_index = index;
|
||||
sc->sc_ddma_channels[index].ch_type = CH_DDMA;
|
||||
sc->sc_ddma_channels[index].ch_callback = NULL;
|
||||
sc->sc_ddma_channels[index].ch_callbackarg = NULL;
|
||||
sc->sc_ddma_channels[index].ch_regoff = AWIN_DDMA_REG(index);
|
||||
DMACH_WRITE(&sc->sc_ddma_channels[index], AWIN_DDMA_CTL_REG, 0);
|
||||
}
|
||||
|
||||
error = bus_setup_intr(dev, sc->sc_res[1], INTR_MPSAFE | INTR_TYPE_MISC,
|
||||
NULL, a10dmac_intr, sc, &sc->sc_ih);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "could not setup interrupt handler\n");
|
||||
bus_release_resources(dev, a10dmac_spec, sc->sc_res);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
a10dmac_intr(void *priv)
|
||||
{
|
||||
struct a10dmac_softc *sc = priv;
|
||||
uint32_t sta, bit, mask;
|
||||
uint8_t index;
|
||||
|
||||
sta = DMA_READ(sc, AWIN_DMA_IRQ_PEND_STA_REG);
|
||||
DMA_WRITE(sc, AWIN_DMA_IRQ_PEND_STA_REG, sta);
|
||||
|
||||
while ((bit = ffs(sta & AWIN_DMA_IRQ_END_MASK)) != 0) {
|
||||
mask = (1U << (bit - 1));
|
||||
sta &= ~mask;
|
||||
/*
|
||||
* Map status bit to channel number. The status register is
|
||||
* encoded with two bits of status per channel (lowest bit
|
||||
* is half transfer pending, highest bit is end transfer
|
||||
* pending). The 8 normal DMA channel status are in the lower
|
||||
* 16 bits and the 8 dedicated DMA channel status are in
|
||||
* the upper 16 bits. The output is a channel number from 0-7.
|
||||
*/
|
||||
index = ((bit - 1) / 2) & 7;
|
||||
if (mask & AWIN_DMA_IRQ_NDMA) {
|
||||
if (sc->sc_ndma_channels[index].ch_callback == NULL)
|
||||
continue;
|
||||
sc->sc_ndma_channels[index].ch_callback(
|
||||
sc->sc_ndma_channels[index].ch_callbackarg);
|
||||
} else {
|
||||
if (sc->sc_ddma_channels[index].ch_callback == NULL)
|
||||
continue;
|
||||
sc->sc_ddma_channels[index].ch_callback(
|
||||
sc->sc_ddma_channels[index].ch_callbackarg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
a10dmac_read_ctl(struct a10dmac_channel *ch)
|
||||
{
|
||||
if (ch->ch_type == CH_NDMA) {
|
||||
return (DMACH_READ(ch, AWIN_NDMA_CTL_REG));
|
||||
} else {
|
||||
return (DMACH_READ(ch, AWIN_DDMA_CTL_REG));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
a10dmac_write_ctl(struct a10dmac_channel *ch, uint32_t val)
|
||||
{
|
||||
if (ch->ch_type == CH_NDMA) {
|
||||
DMACH_WRITE(ch, AWIN_NDMA_CTL_REG, val);
|
||||
} else {
|
||||
DMACH_WRITE(ch, AWIN_DDMA_CTL_REG, val);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
a10dmac_set_config(device_t dev, void *priv, const struct sunxi_dma_config *cfg)
|
||||
{
|
||||
struct a10dmac_channel *ch = priv;
|
||||
uint32_t val;
|
||||
unsigned int dst_dw, dst_bl, dst_bs, dst_wc;
|
||||
unsigned int src_dw, src_bl, src_bs, src_wc;
|
||||
|
||||
switch (cfg->dst_width) {
|
||||
case 8:
|
||||
dst_dw = AWIN_DMA_CTL_DATA_WIDTH_8;
|
||||
break;
|
||||
case 16:
|
||||
dst_dw = AWIN_DMA_CTL_DATA_WIDTH_16;
|
||||
break;
|
||||
case 32:
|
||||
dst_dw = AWIN_DMA_CTL_DATA_WIDTH_32;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
switch (cfg->dst_burst_len) {
|
||||
case 1:
|
||||
dst_bl = AWIN_DMA_CTL_BURST_LEN_1;
|
||||
break;
|
||||
case 4:
|
||||
dst_bl = AWIN_DMA_CTL_BURST_LEN_4;
|
||||
break;
|
||||
case 8:
|
||||
dst_bl = AWIN_DMA_CTL_BURST_LEN_8;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
switch (cfg->src_width) {
|
||||
case 8:
|
||||
src_dw = AWIN_DMA_CTL_DATA_WIDTH_8;
|
||||
break;
|
||||
case 16:
|
||||
src_dw = AWIN_DMA_CTL_DATA_WIDTH_16;
|
||||
break;
|
||||
case 32:
|
||||
src_dw = AWIN_DMA_CTL_DATA_WIDTH_32;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
switch (cfg->src_burst_len) {
|
||||
case 1:
|
||||
src_bl = AWIN_DMA_CTL_BURST_LEN_1;
|
||||
break;
|
||||
case 4:
|
||||
src_bl = AWIN_DMA_CTL_BURST_LEN_4;
|
||||
break;
|
||||
case 8:
|
||||
src_bl = AWIN_DMA_CTL_BURST_LEN_8;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
val = (dst_dw << AWIN_DMA_CTL_DST_DATA_WIDTH_SHIFT) |
|
||||
(dst_bl << AWIN_DMA_CTL_DST_BURST_LEN_SHIFT) |
|
||||
(cfg->dst_drqtype << AWIN_DMA_CTL_DST_DRQ_TYPE_SHIFT) |
|
||||
(src_dw << AWIN_DMA_CTL_SRC_DATA_WIDTH_SHIFT) |
|
||||
(src_bl << AWIN_DMA_CTL_SRC_BURST_LEN_SHIFT) |
|
||||
(cfg->src_drqtype << AWIN_DMA_CTL_SRC_DRQ_TYPE_SHIFT);
|
||||
if (cfg->dst_noincr) {
|
||||
val |= AWIN_NDMA_CTL_DST_ADDR_NOINCR;
|
||||
}
|
||||
if (cfg->src_noincr) {
|
||||
val |= AWIN_NDMA_CTL_SRC_ADDR_NOINCR;
|
||||
}
|
||||
|
||||
if (ch->ch_type == CH_NDMA) {
|
||||
DMACH_WRITE(ch, AWIN_NDMA_CTL_REG, val);
|
||||
} else {
|
||||
DMACH_WRITE(ch, AWIN_DDMA_CTL_REG, val);
|
||||
|
||||
dst_bs = cfg->dst_blksize - 1;
|
||||
dst_wc = cfg->dst_wait_cyc - 1;
|
||||
src_bs = cfg->src_blksize - 1;
|
||||
src_wc = cfg->src_wait_cyc - 1;
|
||||
|
||||
DMACH_WRITE(ch, AWIN_DDMA_PARA_REG,
|
||||
(dst_bs << AWIN_DDMA_PARA_DST_DATA_BLK_SIZ_SHIFT) |
|
||||
(dst_wc << AWIN_DDMA_PARA_DST_WAIT_CYC_SHIFT) |
|
||||
(src_bs << AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ_SHIFT) |
|
||||
(src_wc << AWIN_DDMA_PARA_SRC_WAIT_CYC_SHIFT));
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void *
|
||||
a10dmac_alloc(device_t dev, bool dedicated, void (*cb)(void *), void *cbarg)
|
||||
{
|
||||
struct a10dmac_softc *sc = device_get_softc(dev);
|
||||
struct a10dmac_channel *ch_list;
|
||||
struct a10dmac_channel *ch = NULL;
|
||||
uint32_t irqen;
|
||||
uint8_t ch_count, index;
|
||||
|
||||
if (dedicated) {
|
||||
ch_list = sc->sc_ddma_channels;
|
||||
ch_count = DDMA_CHANNELS;
|
||||
} else {
|
||||
ch_list = sc->sc_ndma_channels;
|
||||
ch_count = NDMA_CHANNELS;
|
||||
}
|
||||
|
||||
mtx_lock_spin(&sc->sc_mtx);
|
||||
for (index = 0; index < ch_count; index++) {
|
||||
if (ch_list[index].ch_callback == NULL) {
|
||||
ch = &ch_list[index];
|
||||
ch->ch_callback = cb;
|
||||
ch->ch_callbackarg = cbarg;
|
||||
|
||||
irqen = DMA_READ(sc, AWIN_DMA_IRQ_EN_REG);
|
||||
if (ch->ch_type == CH_NDMA)
|
||||
irqen |= AWIN_DMA_IRQ_NDMA_END(index);
|
||||
else
|
||||
irqen |= AWIN_DMA_IRQ_DDMA_END(index);
|
||||
DMA_WRITE(sc, AWIN_DMA_IRQ_EN_REG, irqen);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
mtx_unlock_spin(&sc->sc_mtx);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
static void
|
||||
a10dmac_free(device_t dev, void *priv)
|
||||
{
|
||||
struct a10dmac_channel *ch = priv;
|
||||
struct a10dmac_softc *sc = ch->ch_sc;
|
||||
uint32_t irqen, sta, cfg;
|
||||
|
||||
mtx_lock_spin(&sc->sc_mtx);
|
||||
|
||||
irqen = DMA_READ(sc, AWIN_DMA_IRQ_EN_REG);
|
||||
cfg = a10dmac_read_ctl(ch);
|
||||
if (ch->ch_type == CH_NDMA) {
|
||||
sta = AWIN_DMA_IRQ_NDMA_END(ch->ch_index);
|
||||
cfg &= ~AWIN_NDMA_CTL_DMA_LOADING;
|
||||
} else {
|
||||
sta = AWIN_DMA_IRQ_DDMA_END(ch->ch_index);
|
||||
cfg &= ~AWIN_DDMA_CTL_DMA_LOADING;
|
||||
}
|
||||
irqen &= ~sta;
|
||||
a10dmac_write_ctl(ch, cfg);
|
||||
DMA_WRITE(sc, AWIN_DMA_IRQ_EN_REG, irqen);
|
||||
DMA_WRITE(sc, AWIN_DMA_IRQ_PEND_STA_REG, sta);
|
||||
|
||||
ch->ch_callback = NULL;
|
||||
ch->ch_callbackarg = NULL;
|
||||
|
||||
mtx_unlock_spin(&sc->sc_mtx);
|
||||
}
|
||||
|
||||
static int
|
||||
a10dmac_transfer(device_t dev, void *priv, bus_addr_t src, bus_addr_t dst,
|
||||
size_t nbytes)
|
||||
{
|
||||
struct a10dmac_channel *ch = priv;
|
||||
uint32_t cfg;
|
||||
|
||||
cfg = a10dmac_read_ctl(ch);
|
||||
if (ch->ch_type == CH_NDMA) {
|
||||
if (cfg & AWIN_NDMA_CTL_DMA_LOADING)
|
||||
return (EBUSY);
|
||||
|
||||
DMACH_WRITE(ch, AWIN_NDMA_SRC_ADDR_REG, src);
|
||||
DMACH_WRITE(ch, AWIN_NDMA_DEST_ADDR_REG, dst);
|
||||
DMACH_WRITE(ch, AWIN_NDMA_BC_REG, nbytes);
|
||||
|
||||
cfg |= AWIN_NDMA_CTL_DMA_LOADING;
|
||||
a10dmac_write_ctl(ch, cfg);
|
||||
} else {
|
||||
if (cfg & AWIN_DDMA_CTL_DMA_LOADING)
|
||||
return (EBUSY);
|
||||
|
||||
DMACH_WRITE(ch, AWIN_DDMA_SRC_START_ADDR_REG, src);
|
||||
DMACH_WRITE(ch, AWIN_DDMA_DEST_START_ADDR_REG, dst);
|
||||
DMACH_WRITE(ch, AWIN_DDMA_BC_REG, nbytes);
|
||||
|
||||
cfg |= AWIN_DDMA_CTL_DMA_LOADING;
|
||||
a10dmac_write_ctl(ch, cfg);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
a10dmac_halt(device_t dev, void *priv)
|
||||
{
|
||||
struct a10dmac_channel *ch = priv;
|
||||
uint32_t cfg;
|
||||
|
||||
cfg = a10dmac_read_ctl(ch);
|
||||
if (ch->ch_type == CH_NDMA) {
|
||||
cfg &= ~AWIN_NDMA_CTL_DMA_LOADING;
|
||||
} else {
|
||||
cfg &= ~AWIN_DDMA_CTL_DMA_LOADING;
|
||||
}
|
||||
a10dmac_write_ctl(ch, cfg);
|
||||
}
|
||||
|
||||
static device_method_t a10dmac_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, a10dmac_probe),
|
||||
DEVMETHOD(device_attach, a10dmac_attach),
|
||||
|
||||
/* sunxi DMA interface */
|
||||
DEVMETHOD(sunxi_dma_alloc, a10dmac_alloc),
|
||||
DEVMETHOD(sunxi_dma_free, a10dmac_free),
|
||||
DEVMETHOD(sunxi_dma_set_config, a10dmac_set_config),
|
||||
DEVMETHOD(sunxi_dma_transfer, a10dmac_transfer),
|
||||
DEVMETHOD(sunxi_dma_halt, a10dmac_halt),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t a10dmac_driver = {
|
||||
"a10dmac",
|
||||
a10dmac_methods,
|
||||
sizeof(struct a10dmac_softc)
|
||||
};
|
||||
|
||||
static devclass_t a10dmac_devclass;
|
||||
|
||||
DRIVER_MODULE(a10dmac, simplebus, a10dmac_driver, a10dmac_devclass, 0, 0);
|
158
sys/arm/allwinner/a10_dmac.h
Normal file
158
sys/arm/allwinner/a10_dmac.h
Normal file
@ -0,0 +1,158 @@
|
||||
/*-
|
||||
* Copyright (c) 2014-2016 Jared D. McNeill <jmcneill@invisible.ca>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _A10_DMAC_H_
|
||||
#define _A10_DMAC_H_
|
||||
|
||||
#define AWIN_DMA_IRQ_EN_REG 0x0000
|
||||
#define AWIN_DMA_IRQ_PEND_STA_REG 0x0004
|
||||
#define AWIN_NDMA_AUTO_GATE_REG 0x0008
|
||||
#define AWIN_NDMA_REG(n) (0x100+0x20*(n))
|
||||
#define AWIN_NDMA_CTL_REG 0x0000
|
||||
#define AWIN_NDMA_SRC_ADDR_REG 0x0004
|
||||
#define AWIN_NDMA_DEST_ADDR_REG 0x0008
|
||||
#define AWIN_NDMA_BC_REG 0x000c
|
||||
#define AWIN_DDMA_REG(n) (0x300+0x20*(n))
|
||||
#define AWIN_DDMA_CTL_REG 0x0000
|
||||
#define AWIN_DDMA_SRC_START_ADDR_REG 0x0004
|
||||
#define AWIN_DDMA_DEST_START_ADDR_REG 0x0008
|
||||
#define AWIN_DDMA_BC_REG 0x000c
|
||||
#define AWIN_DDMA_PARA_REG 0x0018
|
||||
#define AWIN_DMA_IRQ_END_MASK 0xaaaaaaaa
|
||||
#define AWIN_DMA_IRQ_HF_MASK 0x55555555
|
||||
#define AWIN_DMA_IRQ_DDMA 0xffff0000
|
||||
#define AWIN_DMA_IRQ_DDMA_END(n) (1U << (17+2*(n)))
|
||||
#define AWIN_DMA_IRQ_DDMA_HF(n) (1U << (16+2*(n)))
|
||||
#define AWIN_DMA_IRQ_NDMA 0x0000ffff
|
||||
#define AWIN_DMA_IRQ_NDMA_END(n) (1U << (1+2*(n)))
|
||||
#define AWIN_DMA_IRQ_NDMA_HF(n) (1U << (0+2*(n)))
|
||||
#define AWIN_NDMA_AUTO_GATING_DIS (1U << 16)
|
||||
#define AWIN_DMA_CTL_DST_DATA_WIDTH_SHIFT 25
|
||||
#define AWIN_DMA_CTL_DST_DATA_WIDTH_MASK (3U << AWIN_DMA_CTL_DST_DATA_WIDTH_SHIFT)
|
||||
#define AWIN_DMA_CTL_DATA_WIDTH_8 0
|
||||
#define AWIN_DMA_CTL_DATA_WIDTH_16 1
|
||||
#define AWIN_DMA_CTL_DATA_WIDTH_32 2
|
||||
#define AWIN_DMA_CTL_DST_BURST_LEN_SHIFT 23
|
||||
#define AWIN_DMA_CTL_DST_BURST_LEN_MASK (3 << AWIN_DMA_CTL_DST_BURST_LEN_SHIFT)
|
||||
#define AWIN_DMA_CTL_BURST_LEN_1 0
|
||||
#define AWIN_DMA_CTL_BURST_LEN_4 1
|
||||
#define AWIN_DMA_CTL_BURST_LEN_8 2
|
||||
#define AWIN_DMA_CTL_DST_DRQ_TYPE_SHIFT 16
|
||||
#define AWIN_DMA_CTL_DST_DRQ_TYPE_MASK (0x1f << AWIN_DMA_CTL_DST_DRQ_TYPE_SHIFT)
|
||||
#define AWIN_DMA_CTL_BC_REMAINING (1U << 15)
|
||||
#define AWIN_DMA_CTL_SRC_DATA_WIDTH_SHIFT 9
|
||||
#define AWIN_DMA_CTL_SRC_DATA_WIDTH_MASK (3U << AWIN_DMA_CTL_SRC_DATA_WIDTH_SHIFT)
|
||||
#define AWIN_DMA_CTL_SRC_BURST_LEN_SHIFT 7
|
||||
#define AWIN_DMA_CTL_SRC_BURST_LEN_MASK (3U << AWIN_DMA_CTL_SRC_BURST_LEN_SHIFT)
|
||||
#define AWIN_DMA_CTL_SRC_DRQ_TYPE_SHIFT 0
|
||||
#define AWIN_DMA_CTL_SRC_DRQ_TYPE_MASK (0x1f << AWIN_DMA_CTL_SRC_DRQ_TYPE_SHIFT)
|
||||
#define AWIN_NDMA_CTL_DMA_LOADING (1U << 31)
|
||||
#define AWIN_NDMA_CTL_DMA_CONTIN_MODE (1U << 30)
|
||||
#define AWIN_NDMA_CTL_WAIT_STATE_LOG2_SHIFT 27
|
||||
#define AWIN_NDMA_CTL_WAIT_STATE_LOG2_MASK (7U << AWIN_NDMA_CTL_WAIT_STATE_LOG2_SHIFT)
|
||||
#define AWIN_NDMA_CTL_DST_NON_SECURE (1U << 22)
|
||||
#define AWIN_NDMA_CTL_DST_ADDR_NOINCR (1U << 21)
|
||||
#define AWIN_NDMA_CTL_DRQ_IRO 0
|
||||
#define AWIN_NDMA_CTL_DRQ_IR1 1
|
||||
#define AWIN_NDMA_CTL_DRQ_SPDIF 2
|
||||
#define AWIN_NDMA_CTL_DRQ_IISO 3
|
||||
#define AWIN_NDMA_CTL_DRQ_IIS1 4
|
||||
#define AWIN_NDMA_CTL_DRQ_AC97 5
|
||||
#define AWIN_NDMA_CTL_DRQ_IIS2 6
|
||||
#define AWIN_NDMA_CTL_DRQ_UARTO 8
|
||||
#define AWIN_NDMA_CTL_DRQ_UART1 9
|
||||
#define AWIN_NDMA_CTL_DRQ_UART2 10
|
||||
#define AWIN_NDMA_CTL_DRQ_UART3 11
|
||||
#define AWIN_NDMA_CTL_DRQ_UART4 12
|
||||
#define AWIN_NDMA_CTL_DRQ_UART5 13
|
||||
#define AWIN_NDMA_CTL_DRQ_UART6 14
|
||||
#define AWIN_NDMA_CTL_DRQ_UART7 15
|
||||
#define AWIN_NDMA_CTL_DRQ_DDC 16
|
||||
#define AWIN_NDMA_CTL_DRQ_USB_EP1 17
|
||||
#define AWIN_NDMA_CTL_DRQ_CODEC 19
|
||||
#define AWIN_NDMA_CTL_DRQ_SRAM 21
|
||||
#define AWIN_NDMA_CTL_DRQ_SDRAM 22
|
||||
#define AWIN_NDMA_CTL_DRQ_TP_AD 23
|
||||
#define AWIN_NDMA_CTL_DRQ_SPI0 24
|
||||
#define AWIN_NDMA_CTL_DRQ_SPI1 25
|
||||
#define AWIN_NDMA_CTL_DRQ_SPI2 26
|
||||
#define AWIN_NDMA_CTL_DRQ_SPI3 27
|
||||
#define AWIN_NDMA_CTL_DRQ_USB_EP2 28
|
||||
#define AWIN_NDMA_CTL_DRQ_USB_EP3 29
|
||||
#define AWIN_NDMA_CTL_DRQ_USB_EP4 30
|
||||
#define AWIN_NDMA_CTL_DRQ_USB_EP5 31
|
||||
#define AWIN_NDMA_CTL_SRC_NON_SECURE (1U << 6)
|
||||
#define AWIN_NDMA_CTL_SRC_ADDR_NOINCR (1U << 5)
|
||||
#define AWIN_NDMA_BC_COUNT 0x0003ffff
|
||||
#define AWIN_DDMA_CTL_DMA_LOADING (1U << 31)
|
||||
#define AWIN_DDMA_CTL_BUSY (1U << 30)
|
||||
#define AWIN_DDMA_CTL_DMA_CONTIN_MODE (1U << 29)
|
||||
#define AWIN_DDMA_CTL_DST_NON_SECURE (1U << 28)
|
||||
#define AWIN_DDMA_CTL_DST_ADDR_MODE_SHIFT 21
|
||||
#define AWIN_DDMA_CTL_DST_ADDR_MODE_MASK (3U << AWIN_DDMA_CTL_DST_ADDR_MODE_SHIFT)
|
||||
#define AWIN_DDMA_CTL_DMA_ADDR_LINEAR 0
|
||||
#define AWIN_DDMA_CTL_DMA_ADDR_IO 1
|
||||
#define AWIN_DDMA_CTL_DMA_ADDR_HPAGE 2
|
||||
#define AWIN_DDMA_CTL_DMA_ADDR_VPAGE 3
|
||||
#define AWIN_DDMA_CTL_DST_DRQ_TYPE_SHIFT 16
|
||||
#define AWIN_DDMA_CTL_DST_DRQ_TYPE_MASK (0x1f << AWIN_DDMA_CTL_DST_DRQ_TYPE_SHIFT)
|
||||
#define AWIN_DDMA_CTL_DRQ_SRAM 0
|
||||
#define AWIN_DDMA_CTL_DRQ_SDRAM 1
|
||||
#define AWIN_DDMA_CTL_DRQ_NFC 3
|
||||
#define AWIN_DDMA_CTL_DRQ_USB0 4
|
||||
#define AWIN_DDMA_CTL_DRQ_EMAC_TX 6
|
||||
#define AWIN_DDMA_CTL_DRQ_EMAC_RX 7
|
||||
#define AWIN_DDMA_CTL_DRQ_SPI1_TX 8
|
||||
#define AWIN_DDMA_CTL_DRQ_SPI1_RX 9
|
||||
#define AWIN_DDMA_CTL_DRQ_SS_TX 10
|
||||
#define AWIN_DDMA_CTL_DRQ_SS_RX 11
|
||||
#define AWIN_DDMA_CTL_DRQ_TCON0 14
|
||||
#define AWIN_DDMA_CTL_DRQ_TCON1 15
|
||||
#define AWIN_DDMA_CTL_DRQ_MS_TX 23
|
||||
#define AWIN_DDMA_CTL_DRQ_MS_RX 23
|
||||
#define AWIN_DDMA_CTL_DRQ_HDMI_AUDIO 24
|
||||
#define AWIN_DDMA_CTL_DRQ_SPI0_TX 26
|
||||
#define AWIN_DDMA_CTL_DRQ_SPI0_RX 27
|
||||
#define AWIN_DDMA_CTL_DRQ_SPI2_TX 28
|
||||
#define AWIN_DDMA_CTL_DRQ_SPI2_RX 29
|
||||
#define AWIN_DDMA_CTL_DRQ_SPI3_TX 30
|
||||
#define AWIN_DDMA_CTL_DRQ_SPI3_RX 31
|
||||
#define AWIN_DDMA_CTL_SRC_NON_SECURE (1U << 12)
|
||||
#define AWIN_DDMA_CTL_SRC_ADDR_MODE_SHIFT 5
|
||||
#define AWIN_DDMA_CTL_SRC_ADDR_MODE_MASK (3U << AWIN_DDMA_CTL_SRC_ADDR_MODE_SHIFT)
|
||||
#define AWIN_DDMA_BC_COUNT 0x00003fff
|
||||
#define AWIN_DDMA_PARA_DST_DATA_BLK_SIZ_SHIFT 24
|
||||
#define AWIN_DDMA_PARA_DST_DATA_BLK_SIZ_MASK (0xff << AWIN_DDMA_PARA_DST_DATA_BLK_SIZ_SHIFT)
|
||||
#define AWIN_DDMA_PARA_DST_WAIT_CYC_SHIFT 16
|
||||
#define AWIN_DDMA_PARA_DST_WAIT_CYC_MASK (0xff << AWIN_DDMA_PARA_DST_WAIT_CYC_SHIFT)
|
||||
#define AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ_SHIFT 8
|
||||
#define AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ_MASK (0xff << AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ_SHIFT)
|
||||
#define AWIN_DDMA_PARA_SRC_WAIT_CYC_SHIFT 0
|
||||
#define AWIN_DDMA_PARA_SRC_WAIT_CYC_MASK (0xff << AWIN_DDMA_PARA_SRC_WAIT_CYC_SHIFT)
|
||||
|
||||
#endif /* !_A10_DMAC_H_ */
|
@ -47,12 +47,15 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/fdt/fdt_pinctrl.h>
|
||||
#include <dev/gpio/gpiobusvar.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <arm/allwinner/allwinner_machdep.h>
|
||||
#include <arm/allwinner/allwinner_pinctrl.h>
|
||||
|
||||
#include "gpio_if.h"
|
||||
#include "a10_gpio.h"
|
||||
|
||||
/*
|
||||
* A10 have 9 banks of gpio.
|
||||
@ -62,7 +65,6 @@ __FBSDID("$FreeBSD$");
|
||||
* PG0 - PG9 | PH0 - PH27 | PI0 - PI12
|
||||
*/
|
||||
|
||||
#define A10_GPIO_PINS 288
|
||||
#define A10_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
|
||||
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
|
||||
|
||||
@ -73,6 +75,9 @@ __FBSDID("$FreeBSD$");
|
||||
#define A10_GPIO_INPUT 0
|
||||
#define A10_GPIO_OUTPUT 1
|
||||
|
||||
#define AW_GPIO_DRV_MASK 0x3
|
||||
#define AW_GPIO_PUD_MASK 0x3
|
||||
|
||||
static struct ofw_compat_data compat_data[] = {
|
||||
{"allwinner,sun4i-a10-pinctrl", 1},
|
||||
{"allwinner,sun7i-a20-pinctrl", 1},
|
||||
@ -88,8 +93,19 @@ struct a10_gpio_softc {
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
void * sc_intrhand;
|
||||
const struct allwinner_padconf * padconf;
|
||||
};
|
||||
|
||||
/* Defined in a10_padconf.c */
|
||||
#ifdef SOC_ALLWINNER_A10
|
||||
extern const struct allwinner_padconf a10_padconf;
|
||||
#endif
|
||||
|
||||
/* Defined in a20_padconf.c */
|
||||
#ifdef SOC_ALLWINNER_A20
|
||||
extern const struct allwinner_padconf a20_padconf;
|
||||
#endif
|
||||
|
||||
#define A10_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
|
||||
#define A10_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
|
||||
#define A10_GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
|
||||
@ -123,8 +139,10 @@ a10_gpio_get_function(struct a10_gpio_softc *sc, uint32_t pin)
|
||||
/* Must be called with lock held. */
|
||||
A10_GPIO_LOCK_ASSERT(sc);
|
||||
|
||||
bank = pin / 32;
|
||||
pin = pin % 32;
|
||||
if (pin > sc->padconf->npins)
|
||||
return (0);
|
||||
bank = sc->padconf->pins[pin].port;
|
||||
pin = sc->padconf->pins[pin].pin;
|
||||
offset = ((pin & 0x07) << 2);
|
||||
|
||||
func = A10_GPIO_READ(sc, A10_GPIO_GP_CFG(bank, pin >> 3));
|
||||
@ -146,8 +164,8 @@ a10_gpio_set_function(struct a10_gpio_softc *sc, uint32_t pin, uint32_t f)
|
||||
/* Must be called with lock held. */
|
||||
A10_GPIO_LOCK_ASSERT(sc);
|
||||
|
||||
bank = pin / 32;
|
||||
pin = pin % 32;
|
||||
bank = sc->padconf->pins[pin].port;
|
||||
pin = sc->padconf->pins[pin].pin;
|
||||
offset = ((pin & 0x07) << 2);
|
||||
|
||||
data = A10_GPIO_READ(sc, A10_GPIO_GP_CFG(bank, pin >> 3));
|
||||
@ -164,8 +182,8 @@ a10_gpio_get_pud(struct a10_gpio_softc *sc, uint32_t pin)
|
||||
/* Must be called with lock held. */
|
||||
A10_GPIO_LOCK_ASSERT(sc);
|
||||
|
||||
bank = pin / 32;
|
||||
pin = pin % 32;
|
||||
bank = sc->padconf->pins[pin].port;
|
||||
pin = sc->padconf->pins[pin].pin;
|
||||
offset = ((pin & 0x0f) << 1);
|
||||
|
||||
val = A10_GPIO_READ(sc, A10_GPIO_GP_PUL(bank, pin >> 4));
|
||||
@ -187,16 +205,34 @@ a10_gpio_set_pud(struct a10_gpio_softc *sc, uint32_t pin, uint32_t state)
|
||||
/* Must be called with lock held. */
|
||||
A10_GPIO_LOCK_ASSERT(sc);
|
||||
|
||||
bank = pin / 32;
|
||||
pin = pin % 32;
|
||||
bank = sc->padconf->pins[pin].port;
|
||||
pin = sc->padconf->pins[pin].pin;
|
||||
offset = ((pin & 0x0f) << 1);
|
||||
|
||||
val = A10_GPIO_READ(sc, A10_GPIO_GP_PUL(bank, pin >> 4));
|
||||
val &= ~(0x03 << offset);
|
||||
val &= ~(AW_GPIO_PUD_MASK << offset);
|
||||
val |= (state << offset);
|
||||
A10_GPIO_WRITE(sc, A10_GPIO_GP_PUL(bank, pin >> 4), val);
|
||||
}
|
||||
|
||||
static void
|
||||
a10_gpio_set_drv(struct a10_gpio_softc *sc, uint32_t pin, uint32_t drive)
|
||||
{
|
||||
uint32_t bank, offset, val;
|
||||
|
||||
/* Must be called with lock held. */
|
||||
A10_GPIO_LOCK_ASSERT(sc);
|
||||
|
||||
bank = sc->padconf->pins[pin].port;
|
||||
pin = sc->padconf->pins[pin].pin;
|
||||
offset = ((pin & 0x0f) << 1);
|
||||
|
||||
val = A10_GPIO_READ(sc, A10_GPIO_GP_DRV(bank, pin >> 4));
|
||||
val &= ~(AW_GPIO_DRV_MASK << offset);
|
||||
val |= (drive << offset);
|
||||
A10_GPIO_WRITE(sc, A10_GPIO_GP_DRV(bank, pin >> 4), val);
|
||||
}
|
||||
|
||||
static void
|
||||
a10_gpio_pin_configure(struct a10_gpio_softc *sc, uint32_t pin, uint32_t flags)
|
||||
{
|
||||
@ -218,7 +254,7 @@ a10_gpio_pin_configure(struct a10_gpio_softc *sc, uint32_t pin, uint32_t flags)
|
||||
a10_gpio_set_pud(sc, pin, A10_GPIO_PULLUP);
|
||||
else
|
||||
a10_gpio_set_pud(sc, pin, A10_GPIO_PULLDOWN);
|
||||
} else
|
||||
} else
|
||||
a10_gpio_set_pud(sc, pin, A10_GPIO_NONE);
|
||||
}
|
||||
|
||||
@ -235,16 +271,21 @@ a10_gpio_get_bus(device_t dev)
|
||||
static int
|
||||
a10_gpio_pin_max(device_t dev, int *maxpin)
|
||||
{
|
||||
struct a10_gpio_softc *sc;
|
||||
|
||||
*maxpin = A10_GPIO_PINS - 1;
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
*maxpin = sc->padconf->npins - 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
a10_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
|
||||
{
|
||||
struct a10_gpio_softc *sc;
|
||||
|
||||
if (pin >= A10_GPIO_PINS)
|
||||
sc = device_get_softc(dev);
|
||||
if (pin >= sc->padconf->npins)
|
||||
return (EINVAL);
|
||||
|
||||
*caps = A10_GPIO_DEFAULT_CAPS;
|
||||
@ -257,10 +298,10 @@ a10_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
|
||||
{
|
||||
struct a10_gpio_softc *sc;
|
||||
|
||||
if (pin >= A10_GPIO_PINS)
|
||||
sc = device_get_softc(dev);
|
||||
if (pin >= sc->padconf->npins)
|
||||
return (EINVAL);
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
A10_GPIO_LOCK(sc);
|
||||
*flags = a10_gpio_get_function(sc, pin);
|
||||
*flags |= a10_gpio_get_pud(sc, pin);
|
||||
@ -272,14 +313,14 @@ a10_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
|
||||
static int
|
||||
a10_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
|
||||
{
|
||||
uint32_t bank;
|
||||
struct a10_gpio_softc *sc;
|
||||
|
||||
if (pin >= A10_GPIO_PINS)
|
||||
sc = device_get_softc(dev);
|
||||
if (pin >= sc->padconf->npins)
|
||||
return (EINVAL);
|
||||
|
||||
bank = pin / 32;
|
||||
snprintf(name, GPIOMAXNAME - 1, "pin %d (P%c%d)",
|
||||
pin, bank + 'A', pin % 32);
|
||||
snprintf(name, GPIOMAXNAME - 1, "%s",
|
||||
sc->padconf->pins[pin].name);
|
||||
name[GPIOMAXNAME - 1] = '\0';
|
||||
|
||||
return (0);
|
||||
@ -290,10 +331,10 @@ a10_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
|
||||
{
|
||||
struct a10_gpio_softc *sc;
|
||||
|
||||
if (pin >= A10_GPIO_PINS)
|
||||
sc = device_get_softc(dev);
|
||||
if (pin > sc->padconf->npins)
|
||||
return (EINVAL);
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
A10_GPIO_LOCK(sc);
|
||||
a10_gpio_pin_configure(sc, pin, flags);
|
||||
A10_GPIO_UNLOCK(sc);
|
||||
@ -307,13 +348,13 @@ a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
|
||||
struct a10_gpio_softc *sc;
|
||||
uint32_t bank, data;
|
||||
|
||||
if (pin >= A10_GPIO_PINS)
|
||||
sc = device_get_softc(dev);
|
||||
if (pin > sc->padconf->npins)
|
||||
return (EINVAL);
|
||||
|
||||
bank = pin / 32;
|
||||
pin = pin % 32;
|
||||
bank = sc->padconf->pins[pin].port;
|
||||
pin = sc->padconf->pins[pin].pin;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
A10_GPIO_LOCK(sc);
|
||||
data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
|
||||
if (value)
|
||||
@ -332,13 +373,13 @@ a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
|
||||
struct a10_gpio_softc *sc;
|
||||
uint32_t bank, reg_data;
|
||||
|
||||
if (pin >= A10_GPIO_PINS)
|
||||
sc = device_get_softc(dev);
|
||||
if (pin > sc->padconf->npins)
|
||||
return (EINVAL);
|
||||
|
||||
bank = pin / 32;
|
||||
pin = pin % 32;
|
||||
bank = sc->padconf->pins[pin].port;
|
||||
pin = sc->padconf->pins[pin].pin;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
A10_GPIO_LOCK(sc);
|
||||
reg_data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
|
||||
A10_GPIO_UNLOCK(sc);
|
||||
@ -353,13 +394,13 @@ a10_gpio_pin_toggle(device_t dev, uint32_t pin)
|
||||
struct a10_gpio_softc *sc;
|
||||
uint32_t bank, data;
|
||||
|
||||
if (pin >= A10_GPIO_PINS)
|
||||
sc = device_get_softc(dev);
|
||||
if (pin > sc->padconf->npins)
|
||||
return (EINVAL);
|
||||
|
||||
bank = pin / 32;
|
||||
pin = pin % 32;
|
||||
bank = sc->padconf->pins[pin].port;
|
||||
pin = sc->padconf->pins[pin].pin;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
A10_GPIO_LOCK(sc);
|
||||
data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
|
||||
if (data & (1 << pin))
|
||||
@ -372,6 +413,92 @@ a10_gpio_pin_toggle(device_t dev, uint32_t pin)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
aw_find_pinnum_by_name(struct a10_gpio_softc *sc, const char *pinname)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sc->padconf->npins; i++)
|
||||
if (!strcmp(pinname, sc->padconf->pins[i].name))
|
||||
return i;
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
aw_find_pin_func(struct a10_gpio_softc *sc, int pin, const char *func)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AW_MAX_FUNC_BY_PIN; i++)
|
||||
if (sc->padconf->pins[pin].functions[i] &&
|
||||
!strcmp(func, sc->padconf->pins[pin].functions[i]))
|
||||
return (i);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
aw_fdt_configure_pins(device_t dev, phandle_t cfgxref)
|
||||
{
|
||||
struct a10_gpio_softc *sc;
|
||||
phandle_t node;
|
||||
const char **pinlist = NULL;
|
||||
char *pin_function = NULL;
|
||||
uint32_t pin_drive, pin_pull;
|
||||
int pins_nb, pin_num, pin_func, i, ret;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
node = OF_node_from_xref(cfgxref);
|
||||
ret = 0;
|
||||
|
||||
/* Getting all prop for configuring pins */
|
||||
pins_nb = ofw_bus_string_list_to_array(node, "allwinner,pins", &pinlist);
|
||||
if (pins_nb <= 0)
|
||||
return (ENOENT);
|
||||
if (OF_getprop_alloc(node, "allwinner,function",
|
||||
sizeof(*pin_function),
|
||||
(void **)&pin_function) == -1) {
|
||||
ret = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (OF_getencprop(node, "allwinner,drive",
|
||||
&pin_drive, sizeof(pin_drive)) == -1) {
|
||||
ret = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (OF_getencprop(node, "allwinner,pull",
|
||||
&pin_pull, sizeof(pin_pull)) == -1) {
|
||||
ret = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Configure each pin to the correct function, drive and pull */
|
||||
for (i = 0; i < pins_nb; i++) {
|
||||
pin_num = aw_find_pinnum_by_name(sc, pinlist[i]);
|
||||
if (pin_num == -1) {
|
||||
ret = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
pin_func = aw_find_pin_func(sc, pin_num, pin_function);
|
||||
if (pin_func == -1) {
|
||||
ret = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
A10_GPIO_LOCK(sc);
|
||||
a10_gpio_set_function(sc, pin_num, pin_func);
|
||||
a10_gpio_set_drv(sc, pin_num, pin_drive);
|
||||
a10_gpio_set_pud(sc, pin_num, pin_pull);
|
||||
A10_GPIO_UNLOCK(sc);
|
||||
}
|
||||
|
||||
out:
|
||||
free(pinlist, M_OFWPROP);
|
||||
free(pin_function, M_OFWPROP);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
a10_gpio_probe(device_t dev)
|
||||
{
|
||||
@ -382,7 +509,7 @@ a10_gpio_probe(device_t dev)
|
||||
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "Allwinner GPIO controller");
|
||||
device_set_desc(dev, "Allwinner GPIO/Pinmux controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
@ -428,6 +555,29 @@ a10_gpio_attach(device_t dev)
|
||||
if (sc->sc_busdev == NULL)
|
||||
goto fail;
|
||||
|
||||
|
||||
/* Use the right pin data for the current SoC */
|
||||
switch (allwinner_soc_type()) {
|
||||
#ifdef SOC_ALLWINNER_A10
|
||||
case ALLWINNERSOC_A10:
|
||||
sc->padconf = &a10_padconf;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SOC_ALLWINNER_A20
|
||||
case ALLWINNERSOC_A20:
|
||||
sc->padconf = &a20_padconf;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register as a pinctrl device
|
||||
*/
|
||||
fdt_pinctrl_register(dev, "allwinner,pins");
|
||||
fdt_pinctrl_configure_tree(dev);
|
||||
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
@ -459,9 +609,18 @@ static int
|
||||
a10_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
|
||||
pcell_t *gpios, uint32_t *pin, uint32_t *flags)
|
||||
{
|
||||
struct a10_gpio_softc *sc;
|
||||
int i;
|
||||
|
||||
sc = device_get_softc(bus);
|
||||
|
||||
/* The GPIO pins are mapped as: <gpio-phandle bank pin flags>. */
|
||||
*pin = gpios[0] * 32 + gpios[1];
|
||||
for (i = 0; i < sc->padconf->npins; i++)
|
||||
if (sc->padconf->pins[i].port == gpios[0] &&
|
||||
sc->padconf->pins[i].pin == gpios[1]) {
|
||||
*pin = i;
|
||||
break;
|
||||
}
|
||||
*flags = gpios[gcells - 1];
|
||||
|
||||
return (0);
|
||||
@ -488,6 +647,9 @@ static device_method_t a10_gpio_methods[] = {
|
||||
/* ofw_bus interface */
|
||||
DEVMETHOD(ofw_bus_get_node, a10_gpio_get_node),
|
||||
|
||||
/* fdt_pinctrl interface */
|
||||
DEVMETHOD(fdt_pinctrl_configure,aw_fdt_configure_pins),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
@ -501,22 +663,3 @@ static driver_t a10_gpio_driver = {
|
||||
|
||||
EARLY_DRIVER_MODULE(a10_gpio, simplebus, a10_gpio_driver, a10_gpio_devclass, 0, 0,
|
||||
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||
|
||||
|
||||
int
|
||||
a10_gpio_ethernet_activate(uint32_t func)
|
||||
{
|
||||
int i;
|
||||
struct a10_gpio_softc *sc = a10_gpio_sc;
|
||||
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/* Configure pin mux settings for MII. */
|
||||
A10_GPIO_LOCK(sc);
|
||||
for (i = 0; i <= 17; i++)
|
||||
a10_gpio_set_function(sc, i, func);
|
||||
A10_GPIO_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
227
sys/arm/allwinner/a10_padconf.c
Normal file
227
sys/arm/allwinner/a10_padconf.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Emmanuel Vadot <manu@bidouilliste.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arm/allwinner/allwinner_pinctrl.h>
|
||||
|
||||
const static struct allwinner_pins a10_pins[] = {
|
||||
{"PA0", 0, 0, {"gpio_in", "gpio_out", "emac", "spi1", "uart2", NULL, NULL, NULL}},
|
||||
{"PA1", 0, 1, {"gpio_in", "gpio_out", "emac", "spi1", "uart2", NULL, NULL, NULL}},
|
||||
{"PA2", 0, 2, {"gpio_in", "gpio_out", "emac", "spi1", "uart2", NULL, NULL, NULL}},
|
||||
{"PA3", 0, 3, {"gpio_in", "gpio_out", "emac", "spi1", "uart2", NULL, NULL, NULL}},
|
||||
{"PA4", 0, 4, {"gpio_in", "gpio_out", "emac", "spi1", NULL, NULL, NULL, NULL}},
|
||||
{"PA5", 0, 5, {"gpio_in", "gpio_out", "emac", "spi3", NULL, NULL, NULL, NULL}},
|
||||
{"PA6", 0, 6, {"gpio_in", "gpio_out", "emac", "spi3", NULL, NULL, NULL, NULL}},
|
||||
{"PA7", 0, 7, {"gpio_in", "gpio_out", "emac", "spi3", NULL, NULL, NULL, NULL}},
|
||||
{"PA8", 0, 8, {"gpio_in", "gpio_out", "emac", "spi3", NULL, NULL, NULL, NULL}},
|
||||
{"PA9", 0, 9, {"gpio_in", "gpio_out", "emac", "spi3", NULL, NULL, NULL, NULL}},
|
||||
{"PA10", 0, 10, {"gpio_in", "gpio_out", "emac", NULL, "uart1", NULL, NULL, NULL}},
|
||||
{"PA11", 0, 11, {"gpio_in", "gpio_out", "emac", NULL, "uart1", NULL, NULL, NULL}},
|
||||
{"PA12", 0, 12, {"gpio_in", "gpio_out", "emac", "uart6", "uart1", NULL, NULL, NULL}},
|
||||
{"PA13", 0, 13, {"gpio_in", "gpio_out", "emac", "uart6", "uart1", NULL, NULL, NULL}},
|
||||
{"PA14", 0, 14, {"gpio_in", "gpio_out", "emac", "uart7", "uart1", NULL, NULL, NULL}},
|
||||
{"PA15", 0, 15, {"gpio_in", "gpio_out", "emac", "uart7", "uart1", NULL, NULL, NULL}},
|
||||
{"PA16", 0, 16, {"gpio_in", "gpio_out", NULL, "can", "uart1", NULL, NULL, NULL}},
|
||||
{"PA17", 0, 17, {"gpio_in", "gpio_out", NULL, "can", "uart1", NULL, NULL, NULL}},
|
||||
|
||||
{"PB0", 1, 0, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB1", 1, 1, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB2", 1, 2, {"gpio_in", "gpio_out", "pwm", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB3", 1, 3, {"gpio_in", "gpio_out", "ir0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB4", 1, 4, {"gpio_in", "gpio_out", "ir0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB5", 1, 5, {"gpio_in", "gpio_out", "i2s", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB6", 1, 6, {"gpio_in", "gpio_out", "i2s", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB7", 1, 7, {"gpio_in", "gpio_out", "i2s", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB8", 1, 8, {"gpio_in", "gpio_out", "i2s", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB9", 1, 9, {"gpio_in", "gpio_out", "i2s", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB10", 1, 10, {"gpio_in", "gpio_out", "i2s", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB11", 1, 11, {"gpio_in", "gpio_out", "i2s", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB12", 1, 12, {"gpio_in", "gpio_out", "i2s", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB13", 1, 13, {"gpio_in", "gpio_out", "spi2", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB14", 1, 14, {"gpio_in", "gpio_out", "spi2", "jtag", NULL, NULL, NULL, NULL}},
|
||||
{"PB15", 1, 15, {"gpio_in", "gpio_out", "spi2", "jtag", NULL, NULL, NULL, NULL}},
|
||||
{"PB16", 1, 16, {"gpio_in", "gpio_out", "spi2", "jtag", NULL, NULL, NULL, NULL}},
|
||||
{"PB17", 1, 17, {"gpio_in", "gpio_out", "spi2", "jtag", NULL, NULL, NULL, NULL}},
|
||||
{"PB18", 1, 18, {"gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB19", 1, 19, {"gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB20", 1, 20, {"gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB21", 1, 21, {"gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB22", 1, 22, {"gpio_in", "gpio_out", "uart0", "ir1", NULL, NULL, NULL, NULL}},
|
||||
{"PB23", 1, 23, {"gpio_in", "gpio_out", "uart0", "ir1", NULL, NULL, NULL, NULL}},
|
||||
|
||||
{"PC0", 2, 0, {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
|
||||
{"PC1", 2, 1, {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
|
||||
{"PC2", 2, 2, {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
|
||||
{"PC3", 2, 3, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC4", 2, 4, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC5", 2, 5, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC6", 2, 6, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC7", 2, 7, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC8", 2, 8, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC9", 2, 9, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC10", 2, 10, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC11", 2, 11, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC12", 2, 12, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC13", 2, 13, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC14", 2, 14, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC15", 2, 15, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC16", 2, 16, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC17", 2, 17, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC18", 2, 18, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC19", 2, 19, {"gpio_in", "gpio_out", "nand", "spi2", NULL, NULL, NULL, NULL}},
|
||||
{"PC20", 2, 20, {"gpio_in", "gpio_out", "nand", "spi2", NULL, NULL, NULL, NULL}},
|
||||
{"PC21", 2, 21, {"gpio_in", "gpio_out", "nand", "spi2", NULL, NULL, NULL, NULL}},
|
||||
{"PC22", 2, 22, {"gpio_in", "gpio_out", "nand", "spi2", NULL, NULL, NULL, NULL}},
|
||||
{"PC23", 2, 23, {"gpio_in", "gpio_out", "spi0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC24", 2, 24, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
|
||||
|
||||
{"PD0", 3, 0, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD1", 3, 1, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD2", 3, 2, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD3", 3, 3, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD4", 3, 4, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD5", 3, 5, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD6", 3, 6, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD7", 3, 7, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD8", 3, 8, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD9", 3, 9, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD10", 3, 10, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD11", 3, 11, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD12", 3, 12, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD13", 3, 13, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD14", 3, 14, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD15", 3, 15, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD16", 3, 16, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD17", 3, 17, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD18", 3, 18, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD19", 3, 19, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
|
||||
{"PD20", 3, 20, {"gpio_in", "gpio_out", "lcd0", "csi1", NULL, NULL, NULL, NULL}},
|
||||
{"PD21", 3, 21, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD22", 3, 22, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD23", 3, 23, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD24", 3, 24, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD25", 3, 25, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD26", 3, 26, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD27", 3, 27, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
|
||||
{"PE0", 4, 0, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE1", 4, 1, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE2", 4, 2, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE3", 4, 3, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE4", 4, 4, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE5", 4, 5, {"gpio_in", "gpio_out", "ts0", "csi0", "sim", NULL, NULL, NULL}},
|
||||
{"PE6", 4, 6, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE7", 4, 7, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE8", 4, 8, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE9", 4, 9, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE10", 4, 10, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE11", 4, 11, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
|
||||
{"PF0", 5, 0, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
{"PF1", 5, 1, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
{"PF2", 5, 2, {"gpio_in", "gpio_out", "mmc0", NULL, "uart0", NULL, NULL, NULL}},
|
||||
{"PF3", 5, 3, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
{"PF4", 5, 4, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
{"PF5", 5, 5, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
|
||||
{"PG0", 6, 0, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", NULL, NULL, NULL}},
|
||||
{"PG1", 6, 1, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", NULL, NULL, NULL}},
|
||||
{"PG2", 6, 2, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", NULL, NULL, NULL}},
|
||||
{"PG3", 6, 3, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", NULL, NULL, NULL}},
|
||||
{"PG4", 6, 4, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", "csi0", NULL, NULL}},
|
||||
{"PG5", 6, 5, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", "csi0", NULL, NULL}},
|
||||
{"PG6", 6, 6, {"gpio_in", "gpio_out", "ts1", "csi1", "uart3", "csi0", NULL, NULL}},
|
||||
{"PG7", 6, 7, {"gpio_in", "gpio_out", "ts1", "csi1", "uart3", "csi0", NULL, NULL}},
|
||||
{"PG8", 6, 8, {"gpio_in", "gpio_out", "ts1", "csi1", "uart3", "csi0", NULL, NULL}},
|
||||
{"PG9", 6, 9, {"gpio_in", "gpio_out", "ts1", "csi1", "uart3", "csi0", NULL, NULL}},
|
||||
{"PG10", 6, 10, {"gpio_in", "gpio_out", "ts1", "csi1", "uart4", "csi0", NULL, NULL}},
|
||||
{"PG11", 6, 11, {"gpio_in", "gpio_out", "ts1", "csi1", "uart4", "csi0", NULL, NULL}},
|
||||
|
||||
{"PH0", 7, 0, {"gpio_in", "gpio_out", "lcd1", "pata", "uart3", NULL, "eint", "csi1"}},
|
||||
{"PH1", 7, 1, {"gpio_in", "gpio_out", "lcd1", "pata", "uart3", NULL, "eint", "csi1"}},
|
||||
{"PH2", 7, 2, {"gpio_in", "gpio_out", "lcd1", "pata", "uart3", NULL, "eint", "csi1"}},
|
||||
{"PH3", 7, 3, {"gpio_in", "gpio_out", "lcd1", "pata", "uart3", NULL, "eint", "csi1"}},
|
||||
{"PH4", 7, 4, {"gpio_in", "gpio_out", "lcd1", "pata", "uart4", NULL, "eint", "csi1"}},
|
||||
{"PH5", 7, 5, {"gpio_in", "gpio_out", "lcd1", "pata", "uart4", NULL, "eint", "csi1"}},
|
||||
{"PH6", 7, 6, {"gpio_in", "gpio_out", "lcd1", "pata", "uart5", "ms", "eint", "csi1"}},
|
||||
{"PH7", 7, 7, {"gpio_in", "gpio_out", "lcd1", "pata", "uart5", "ms", "eint", "csi1"}},
|
||||
{"PH8", 7, 8, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "ms", "eint", "csi1"}},
|
||||
{"PH9", 7, 9, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "ms", "eint", "csi1"}},
|
||||
{"PH10", 7, 10, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "ms", "eint", "csi1"}},
|
||||
{"PH11", 7, 11, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "ms", "eint", "csi1"}},
|
||||
{"PH12", 7, 12, {"gpio_in", "gpio_out", "lcd1", "pata", "ps2", NULL, "eint", "csi1"}},
|
||||
{"PH13", 7, 13, {"gpio_in", "gpio_out", "lcd1", "pata", "ps2", "sim", "eint", "csi1"}},
|
||||
{"PH14", 7, 14, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH15", 7, 15, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH16", 7, 16, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", NULL, "eint", "csi1"}},
|
||||
{"PH17", 7, 17, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH18", 7, 18, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH19", 7, 19, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH20", 7, 20, {"gpio_in", "gpio_out", "lcd1", "pata", "can", NULL, "eint", "csi1"}},
|
||||
{"PH21", 7, 21, {"gpio_in", "gpio_out", "lcd1", "pata", "can", NULL, "eint", "csi1"}},
|
||||
{"PH22", 7, 22, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH23", 7, 23, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH24", 7, 24, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH25", 7, 25, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH26", 7, 26, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH27", 7, 27, {"gpio_in", "gpio_out", "lcd1", "pata", "keypad", "mmc1", NULL, "csi1"}},
|
||||
|
||||
{"PI0", 8, 0, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI1", 8, 1, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI2", 8, 2, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI3", 8, 3, {"gpio_in", "gpio_out", "pwm", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI4", 8, 4, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI5", 8, 5, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI6", 8, 6, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI7", 8, 7, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI8", 8, 8, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI9", 8, 9, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI10", 8, 10, {"gpio_in", "gpio_out", "spi0", "uart5", NULL, NULL, "eint", NULL}},
|
||||
{"PI11", 8, 11, {"gpio_in", "gpio_out", "spi0", "uart5", NULL, NULL, "eint", NULL}},
|
||||
{"PI12", 8, 12, {"gpio_in", "gpio_out", "spi0", "uart6", NULL, NULL, "eint", NULL}},
|
||||
{"PI13", 8, 13, {"gpio_in", "gpio_out", "spi0", "uart6", NULL, NULL, "eint", NULL}},
|
||||
{"PI14", 8, 14, {"gpio_in", "gpio_out", "spi0", "ps2", "timer4", NULL, "eint", NULL}},
|
||||
{"PI15", 8, 15, {"gpio_in", "gpio_out", "spi1", "ps2", "timer5", NULL, "eint", NULL}},
|
||||
{"PI16", 8, 16, {"gpio_in", "gpio_out", "spi1", "uart2", NULL, NULL, "eint", NULL}},
|
||||
{"PI17", 8, 17, {"gpio_in", "gpio_out", "spi1", "uart2", NULL, NULL, "eint", NULL}},
|
||||
{"PI18", 8, 18, {"gpio_in", "gpio_out", "spi1", "uart2", NULL, NULL, "eint", NULL}},
|
||||
{"PI19", 8, 19, {"gpio_in", "gpio_out", "spi1", "uart2", NULL, NULL, "eint", NULL}},
|
||||
{"PI20", 8, 20, {"gpio_in", "gpio_out", "ps2", "uart7", "hdmi", NULL, NULL, NULL}},
|
||||
{"PI21", 8, 21, {"gpio_in", "gpio_out", "ps2", "uart7", "hdmi", NULL, NULL, NULL}},
|
||||
};
|
||||
|
||||
const struct allwinner_padconf a10_padconf = {
|
||||
.npins = sizeof(a10_pins) / sizeof(struct allwinner_pins),
|
||||
.pins = a10_pins,
|
||||
};
|
@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <arm/allwinner/a10_clk.h>
|
||||
#include <arm/allwinner/a10_gpio.h>
|
||||
|
||||
#include "if_dwc_if.h"
|
||||
|
||||
@ -63,8 +62,7 @@ a20_if_dwc_init(device_t dev)
|
||||
{
|
||||
|
||||
/* Activate GMAC clock and set the pin mux to rgmii. */
|
||||
if (a10_clk_gmac_activate(ofw_bus_get_node(dev)) != 0 ||
|
||||
a10_gpio_ethernet_activate(A10_GPIO_FUNC_RGMII)) {
|
||||
if (a10_clk_gmac_activate(ofw_bus_get_node(dev)) != 0) {
|
||||
device_printf(dev, "could not activate gmac module\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
227
sys/arm/allwinner/a20/a20_padconf.c
Normal file
227
sys/arm/allwinner/a20/a20_padconf.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Emmanuel Vadot <manu@bidouilliste.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arm/allwinner/allwinner_pinctrl.h>
|
||||
|
||||
const static struct allwinner_pins a20_pins[] = {
|
||||
{"PA0", 0, 0, {"gpio_in", "gpio_out", "emac", "spi1", "uart2", "gmac", NULL, NULL}},
|
||||
{"PA1", 0, 1, {"gpio_in", "gpio_out", "emac", "spi1", "uart2", "gmac", NULL, NULL}},
|
||||
{"PA2", 0, 2, {"gpio_in", "gpio_out", "emac", "spi1", "uart2", "gmac", NULL, NULL}},
|
||||
{"PA3", 0, 3, {"gpio_in", "gpio_out", "emac", "spi1", "uart2", "gmac", NULL, NULL}},
|
||||
{"PA4", 0, 4, {"gpio_in", "gpio_out", "emac", "spi1", NULL, "gmac", NULL, NULL}},
|
||||
{"PA5", 0, 5, {"gpio_in", "gpio_out", "emac", "spi3", NULL, "gmac", NULL, NULL}},
|
||||
{"PA6", 0, 6, {"gpio_in", "gpio_out", "emac", "spi3", NULL, "gmac", NULL, NULL}},
|
||||
{"PA7", 0, 7, {"gpio_in", "gpio_out", "emac", "spi3", NULL, "gmac", NULL, NULL}},
|
||||
{"PA8", 0, 8, {"gpio_in", "gpio_out", "emac", "spi3", NULL, "gmac", NULL, NULL}},
|
||||
{"PA9", 0, 9, {"gpio_in", "gpio_out", "emac", "spi3", NULL, "gmac", "i2c1", NULL}},
|
||||
{"PA10", 0, 10, {"gpio_in", "gpio_out", "emac", NULL, "uart1", "gmac", NULL, NULL}},
|
||||
{"PA11", 0, 11, {"gpio_in", "gpio_out", "emac", NULL, "uart1", "gmac", NULL, NULL}},
|
||||
{"PA12", 0, 12, {"gpio_in", "gpio_out", "emac", "uart6", "uart1", "gmac", NULL, NULL}},
|
||||
{"PA13", 0, 13, {"gpio_in", "gpio_out", "emac", "uart6", "uart1", "gmac", NULL, NULL}},
|
||||
{"PA14", 0, 14, {"gpio_in", "gpio_out", "emac", "uart7", "uart1", "gmac", "i2c1", NULL}},
|
||||
{"PA15", 0, 15, {"gpio_in", "gpio_out", "emac", "uart7", "uart1", "gmac", "i2c1", NULL}},
|
||||
{"PA16", 0, 16, {"gpio_in", "gpio_out", NULL, "can", "uart1", "gmac", "i2c1", NULL}},
|
||||
{"PA17", 0, 17, {"gpio_in", "gpio_out", NULL, "can", "uart1", "gmac", "i2c1", NULL}},
|
||||
|
||||
{"PB0", 1, 0, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB1", 1, 1, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB2", 1, 2, {"gpio_in", "gpio_out", "pwm", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB3", 1, 3, {"gpio_in", "gpio_out", "ir0", NULL, "spdif", NULL, NULL, NULL}},
|
||||
{"PB4", 1, 4, {"gpio_in", "gpio_out", "ir0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB5", 1, 5, {"gpio_in", "gpio_out", "i2s0", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB6", 1, 6, {"gpio_in", "gpio_out", "i2c0", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB7", 1, 7, {"gpio_in", "gpio_out", "i2c0", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB8", 1, 8, {"gpio_in", "gpio_out", "i2c0", "ac97", NULL, NULL, NULL, NULL}},
|
||||
{"PB9", 1, 9, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB10", 1, 10, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB11", 1, 11, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB12", 1, 12, {"gpio_in", "gpio_out", "i2c0", "ac97", "spdif", NULL, NULL, NULL}},
|
||||
{"PB13", 1, 13, {"gpio_in", "gpio_out", "spi2", NULL, "spdif", NULL, NULL, NULL}},
|
||||
{"PB14", 1, 14, {"gpio_in", "gpio_out", "spi2", "jtag", NULL, NULL, NULL, NULL}},
|
||||
{"PB15", 1, 15, {"gpio_in", "gpio_out", "spi2", "jtag", NULL, NULL, NULL, NULL}},
|
||||
{"PB16", 1, 16, {"gpio_in", "gpio_out", "spi2", "jtag", NULL, NULL, NULL, NULL}},
|
||||
{"PB17", 1, 17, {"gpio_in", "gpio_out", "spi2", "jtag", NULL, NULL, NULL, NULL}},
|
||||
{"PB18", 1, 18, {"gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB19", 1, 19, {"gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB20", 1, 20, {"gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB21", 1, 21, {"gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PB22", 1, 22, {"gpio_in", "gpio_out", "uart0", "ir1", NULL, NULL, NULL, NULL}},
|
||||
{"PB23", 1, 23, {"gpio_in", "gpio_out", "uart0", "ir1", NULL, NULL, NULL, NULL}},
|
||||
|
||||
{"PC0", 2, 0, {"gpio_in", "gpio_out", "nand0", "spi0", NULL, NULL, NULL, NULL}},
|
||||
{"PC1", 2, 1, {"gpio_in", "gpio_out", "nand0", "spi0", NULL, NULL, NULL, NULL}},
|
||||
{"PC2", 2, 2, {"gpio_in", "gpio_out", "nand0", "spi0", NULL, NULL, NULL, NULL}},
|
||||
{"PC3", 2, 3, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC4", 2, 4, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC5", 2, 5, {"gpio_in", "gpio_out", "nand0", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC6", 2, 6, {"gpio_in", "gpio_out", "nand0", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC7", 2, 7, {"gpio_in", "gpio_out", "nand0", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC8", 2, 8, {"gpio_in", "gpio_out", "nand0", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC9", 2, 9, {"gpio_in", "gpio_out", "nand0", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC10", 2, 10, {"gpio_in", "gpio_out", "nand0", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC11", 2, 11, {"gpio_in", "gpio_out", "nand0", "mmc2", NULL, NULL, NULL, NULL}},
|
||||
{"PC12", 2, 12, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC13", 2, 13, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC14", 2, 14, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC15", 2, 15, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC16", 2, 16, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC17", 2, 17, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC18", 2, 18, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PC19", 2, 19, {"gpio_in", "gpio_out", "nand0", "spi2", NULL, NULL, "eint", NULL}},
|
||||
{"PC20", 2, 20, {"gpio_in", "gpio_out", "nand0", "spi2", NULL, NULL, "eint", NULL}},
|
||||
{"PC21", 2, 21, {"gpio_in", "gpio_out", "nand0", "spi2", NULL, NULL, "eint", NULL}},
|
||||
{"PC22", 2, 22, {"gpio_in", "gpio_out", "nand0", "spi2", NULL, NULL, "eint", NULL}},
|
||||
{"PC23", 2, 23, {"gpio_in", "gpio_out", NULL, "spi0", NULL, NULL, NULL, NULL}},
|
||||
{"PC24", 2, 24, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
|
||||
|
||||
{"PD0", 3, 0, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD1", 3, 1, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD2", 3, 2, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD3", 3, 3, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD4", 3, 4, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD5", 3, 5, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD6", 3, 6, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD7", 3, 7, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD8", 3, 8, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD9", 3, 9, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD10", 3, 10, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD11", 3, 11, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD12", 3, 12, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD13", 3, 13, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD14", 3, 14, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD15", 3, 15, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD16", 3, 16, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD17", 3, 17, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD18", 3, 18, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD19", 3, 19, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
|
||||
{"PD20", 3, 20, {"gpio_in", "gpio_out", "lcd0", "csi1", NULL, NULL, NULL, NULL}},
|
||||
{"PD21", 3, 21, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD22", 3, 22, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD23", 3, 23, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD24", 3, 24, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD25", 3, 25, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD26", 3, 26, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
{"PD27", 3, 27, {"gpio_in", "gpio_out", "lcd0", "sim", NULL, NULL, NULL, NULL}},
|
||||
|
||||
{"PE0", 4, 0, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE1", 4, 1, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE2", 4, 2, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE3", 4, 3, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE4", 4, 4, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE5", 4, 5, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE6", 4, 6, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE7", 4, 7, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE8", 4, 8, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE9", 4, 9, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE10", 4, 10, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
{"PE11", 4, 11, {"gpio_in", "gpio_out", "ts0", "csi0", NULL, NULL, NULL, NULL}},
|
||||
|
||||
{"PF0", 5, 0, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
{"PF1", 5, 1, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
{"PF2", 5, 2, {"gpio_in", "gpio_out", "mmc0", NULL, "uart0", NULL, NULL, NULL}},
|
||||
{"PF3", 5, 3, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
{"PF4", 5, 4, {"gpio_in", "gpio_out", "mmc0", NULL, "uart0", NULL, NULL, NULL}},
|
||||
{"PF5", 5, 5, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
|
||||
|
||||
{"PG0", 6, 0, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", NULL, NULL, NULL}},
|
||||
{"PG1", 6, 1, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", NULL, NULL, NULL}},
|
||||
{"PG2", 6, 2, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", NULL, NULL, NULL}},
|
||||
{"PG3", 6, 3, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", NULL, NULL, NULL}},
|
||||
{"PG4", 6, 4, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", "csi0", NULL, NULL}},
|
||||
{"PG5", 6, 5, {"gpio_in", "gpio_out", "ts1", "csi1", "mmc1", "csi0", NULL, NULL}},
|
||||
{"PG6", 6, 6, {"gpio_in", "gpio_out", "ts1", "csi1", "uart3", "csi0", NULL, NULL}},
|
||||
{"PG7", 6, 7, {"gpio_in", "gpio_out", "ts1", "csi1", "uart3", "csi0", NULL, NULL}},
|
||||
{"PG8", 6, 8, {"gpio_in", "gpio_out", "ts1", "csi1", "uart3", "csi0", NULL, NULL}},
|
||||
{"PG9", 6, 9, {"gpio_in", "gpio_out", "ts1", "csi1", "uart3", "csi0", NULL, NULL}},
|
||||
{"PG10", 6, 10, {"gpio_in", "gpio_out", "ts1", "csi1", "uart4", "csi0", NULL, NULL}},
|
||||
{"PG11", 6, 11, {"gpio_in", "gpio_out", "ts1", "csi1", "uart4", "csi0", NULL, NULL}},
|
||||
|
||||
{"PH0", 7, 0, {"gpio_in", "gpio_out", "lcd1", NULL, "uart3", NULL, "eint", "csi1"}},
|
||||
{"PH1", 7, 1, {"gpio_in", "gpio_out", "lcd1", NULL, "uart3", NULL, "eint", "csi1"}},
|
||||
{"PH2", 7, 2, {"gpio_in", "gpio_out", "lcd1", NULL, "uart3", NULL, "eint", "csi1"}},
|
||||
{"PH3", 7, 3, {"gpio_in", "gpio_out", "lcd1", NULL, "uart3", NULL, "eint", "csi1"}},
|
||||
{"PH4", 7, 4, {"gpio_in", "gpio_out", "lcd1", NULL, "uart4", NULL, "eint", "csi1"}},
|
||||
{"PH5", 7, 5, {"gpio_in", "gpio_out", "lcd1", NULL, "uart4", NULL, "eint", "csi1"}},
|
||||
{"PH6", 7, 6, {"gpio_in", "gpio_out", "lcd1", NULL, "uart5", "ms", "eint", "csi1"}},
|
||||
{"PH7", 7, 7, {"gpio_in", "gpio_out", "lcd1", NULL, "uart5", "ms", "eint", "csi1"}},
|
||||
{"PH8", 7, 8, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "ms", "eint", "csi1"}},
|
||||
{"PH9", 7, 9, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "ms", "eint", "csi1"}},
|
||||
{"PH10", 7, 10, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "ms", "eint", "csi1"}},
|
||||
{"PH11", 7, 11, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "ms", "eint", "csi1"}},
|
||||
{"PH12", 7, 12, {"gpio_in", "gpio_out", "lcd1", NULL, "ps2", NULL, "eint", "csi1"}},
|
||||
{"PH13", 7, 13, {"gpio_in", "gpio_out", "lcd1", NULL, "ps2", "sim", "eint", "csi1"}},
|
||||
{"PH14", 7, 14, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH15", 7, 15, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH16", 7, 16, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH17", 7, 17, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH18", 7, 18, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH19", 7, 19, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "sim", "eint", "csi1"}},
|
||||
{"PH20", 7, 20, {"gpio_in", "gpio_out", "lcd1", NULL, "can", NULL, "eint", "csi1"}},
|
||||
{"PH21", 7, 21, {"gpio_in", "gpio_out", "lcd1", NULL, "can", NULL, "eint", "csi1"}},
|
||||
{"PH22", 7, 22, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH23", 7, 23, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH24", 7, 24, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH25", 7, 25, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH26", 7, 26, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "mmc1", NULL, "csi1"}},
|
||||
{"PH27", 7, 27, {"gpio_in", "gpio_out", "lcd1", NULL, "keypad", "mmc1", NULL, "csi1"}},
|
||||
|
||||
{"PI0", 8, 0, {"gpio_in", "gpio_out", NULL, "i2c3", NULL, NULL, NULL, NULL}},
|
||||
{"PI1", 8, 1, {"gpio_in", "gpio_out", NULL, "i2c3", NULL, NULL, NULL, NULL}},
|
||||
{"PI2", 8, 2, {"gpio_in", "gpio_out", NULL, "i2c4", NULL, NULL, NULL, NULL}},
|
||||
{"PI3", 8, 3, {"gpio_in", "gpio_out", "pwm", "i2c4", NULL, NULL, NULL, NULL}},
|
||||
{"PI4", 8, 4, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI5", 8, 5, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI6", 8, 6, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI7", 8, 7, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI8", 8, 8, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI9", 8, 9, {"gpio_in", "gpio_out", "mmc3", NULL, NULL, NULL, NULL, NULL}},
|
||||
{"PI10", 8, 10, {"gpio_in", "gpio_out", "spi0", "uart5", NULL, NULL, "eint", NULL}},
|
||||
{"PI11", 8, 11, {"gpio_in", "gpio_out", "spi0", "uart5", NULL, NULL, "eint", NULL}},
|
||||
{"PI12", 8, 12, {"gpio_in", "gpio_out", "spi0", "uart6", "clk_out_a", NULL, "eint", NULL}},
|
||||
{"PI13", 8, 13, {"gpio_in", "gpio_out", "spi0", "uart6", "clk_out_b", NULL, "eint", NULL}},
|
||||
{"PI14", 8, 14, {"gpio_in", "gpio_out", "spi0", "ps2", "timer4", NULL, "eint", NULL}},
|
||||
{"PI15", 8, 15, {"gpio_in", "gpio_out", "spi1", "ps2", "timer5", NULL, "eint", NULL}},
|
||||
{"PI16", 8, 16, {"gpio_in", "gpio_out", "spi1", "uart2", NULL, NULL, "eint", NULL}},
|
||||
{"PI17", 8, 17, {"gpio_in", "gpio_out", "spi1", "uart2", NULL, NULL, "eint", NULL}},
|
||||
{"PI18", 8, 18, {"gpio_in", "gpio_out", "spi1", "uart2", NULL, NULL, "eint", NULL}},
|
||||
{"PI19", 8, 19, {"gpio_in", "gpio_out", "spi1", "uart2", NULL, NULL, "eint", NULL}},
|
||||
{"PI20", 8, 20, {"gpio_in", "gpio_out", "ps2", "uart7", "hdmi", NULL, NULL, NULL}},
|
||||
{"PI21", 8, 21, {"gpio_in", "gpio_out", "ps2", "uart7", "hdmi", NULL, NULL, NULL}},
|
||||
};
|
||||
|
||||
const struct allwinner_padconf a20_padconf = {
|
||||
.npins = sizeof(a20_pins) / sizeof(struct allwinner_pins),
|
||||
.pins = a20_pins,
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
arm/allwinner/a20/a20_padconf.c standard
|
||||
arm/allwinner/a20/a20_mp.c optional smp
|
||||
arm/allwinner/a20/a20_if_dwc.c optional dwc
|
||||
|
@ -75,6 +75,23 @@ a20_attach(platform_t plat)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
a31_attach(platform_t plat)
|
||||
{
|
||||
soc_type = ALLWINNERSOC_A31;
|
||||
soc_family = ALLWINNERSOC_SUN6I;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
a31s_attach(platform_t plat)
|
||||
{
|
||||
soc_type = ALLWINNERSOC_A31S;
|
||||
soc_family = ALLWINNERSOC_SUN6I;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static vm_offset_t
|
||||
allwinner_lastaddr(platform_t plat)
|
||||
@ -138,6 +155,22 @@ static platform_method_t a20_methods[] = {
|
||||
PLATFORMMETHOD_END,
|
||||
};
|
||||
|
||||
static platform_method_t a31_methods[] = {
|
||||
PLATFORMMETHOD(platform_attach, a31_attach),
|
||||
PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr),
|
||||
PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init),
|
||||
|
||||
PLATFORMMETHOD_END,
|
||||
};
|
||||
|
||||
static platform_method_t a31s_methods[] = {
|
||||
PLATFORMMETHOD(platform_attach, a31s_attach),
|
||||
PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr),
|
||||
PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init),
|
||||
|
||||
PLATFORMMETHOD_END,
|
||||
};
|
||||
|
||||
u_int
|
||||
allwinner_soc_type(void)
|
||||
{
|
||||
@ -152,3 +185,5 @@ allwinner_soc_family(void)
|
||||
|
||||
FDT_PLATFORM_DEF(a10, "a10", 0, "allwinner,sun4i-a10");
|
||||
FDT_PLATFORM_DEF(a20, "a20", 0, "allwinner,sun7i-a20");
|
||||
FDT_PLATFORM_DEF(a31, "a31", 0, "allwinner,sun6i-a31");
|
||||
FDT_PLATFORM_DEF(a31s, "a31s", 0, "allwinner,sun6i-a31s");
|
||||
|
@ -34,9 +34,12 @@
|
||||
#define ALLWINNERSOC_A13 0x13000000
|
||||
#define ALLWINNERSOC_A10S 0x10000001
|
||||
#define ALLWINNERSOC_A20 0x20000000
|
||||
#define ALLWINNERSOC_A31 0x31000000
|
||||
#define ALLWINNERSOC_A31S 0x31000001
|
||||
|
||||
#define ALLWINNERSOC_SUN4I 0x40000000
|
||||
#define ALLWINNERSOC_SUN5I 0x50000000
|
||||
#define ALLWINNERSOC_SUN6I 0x60000000
|
||||
#define ALLWINNERSOC_SUN7I 0x70000000
|
||||
|
||||
u_int allwinner_soc_type(void);
|
||||
|
46
sys/arm/allwinner/allwinner_pinctrl.h
Normal file
46
sys/arm/allwinner/allwinner_pinctrl.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Emmanuel Vadot <manu@bidouilliste.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ALLWINNER_PINCTRL_H_
|
||||
#define _ALLWINNER_PINCTRL_H_
|
||||
|
||||
#define AW_MAX_FUNC_BY_PIN 8
|
||||
|
||||
struct allwinner_pins {
|
||||
const char *name;
|
||||
uint8_t port;
|
||||
uint8_t pin;
|
||||
const char *functions[8];
|
||||
};
|
||||
|
||||
struct allwinner_padconf {
|
||||
uint32_t npins;
|
||||
const struct allwinner_pins * pins;
|
||||
};
|
||||
|
||||
#endif /* _ALLWINNER_PINCTRL_H_ */
|
226
sys/arm/allwinner/axp209.c
Normal file
226
sys/arm/allwinner/axp209.c
Normal file
@ -0,0 +1,226 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Emmanuel Vadot <manu@bidouilliste.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
/*
|
||||
* X-Power AXP209 PMU for Allwinner SoCs
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include "iicbus_if.h"
|
||||
|
||||
/* Power State Register */
|
||||
#define AXP209_PSR 0x00
|
||||
#define AXP209_PSR_ACIN 0x80
|
||||
#define AXP209_PSR_ACIN_SHIFT 7
|
||||
#define AXP209_PSR_VBUS 0x20
|
||||
#define AXP209_PSR_VBUS_SHIFT 5
|
||||
|
||||
/* Shutdown and battery control */
|
||||
#define AXP209_SHUTBAT 0x32
|
||||
#define AXP209_SHUTBAT_SHUTDOWN 0x80
|
||||
|
||||
/* Temperature monitor */
|
||||
#define AXP209_TEMPMON 0x5e
|
||||
#define AXP209_TEMPMON_H(a) ((a) << 4)
|
||||
#define AXP209_TEMPMON_L(a) ((a) & 0xf)
|
||||
#define AXP209_TEMPMON_MIN 1447 /* -144.7C */
|
||||
|
||||
#define AXP209_0C_TO_K 2732
|
||||
|
||||
struct axp209_softc {
|
||||
uint32_t addr;
|
||||
struct intr_config_hook enum_hook;
|
||||
};
|
||||
|
||||
enum axp209_sensor {
|
||||
AXP209_TEMP
|
||||
};
|
||||
|
||||
static int
|
||||
axp209_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
|
||||
{
|
||||
struct axp209_softc *sc = device_get_softc(dev);
|
||||
struct iic_msg msg[2];
|
||||
|
||||
msg[0].slave = sc->addr;
|
||||
msg[0].flags = IIC_M_WR;
|
||||
msg[0].len = 1;
|
||||
msg[0].buf = ®
|
||||
|
||||
msg[1].slave = sc->addr;
|
||||
msg[1].flags = IIC_M_RD;
|
||||
msg[1].len = size;
|
||||
msg[1].buf = data;
|
||||
|
||||
return (iicbus_transfer(dev, msg, 2));
|
||||
}
|
||||
|
||||
static int
|
||||
axp209_write(device_t dev, uint8_t reg, uint8_t data)
|
||||
{
|
||||
uint8_t buffer[2];
|
||||
struct axp209_softc *sc = device_get_softc(dev);
|
||||
struct iic_msg msg;
|
||||
|
||||
buffer[0] = reg;
|
||||
buffer[1] = data;
|
||||
|
||||
msg.slave = sc->addr;
|
||||
msg.flags = IIC_M_WR;
|
||||
msg.len = 2;
|
||||
msg.buf = buffer;
|
||||
|
||||
return (iicbus_transfer(dev, &msg, 1));
|
||||
}
|
||||
|
||||
static int
|
||||
axp209_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
device_t dev = arg1;
|
||||
enum axp209_sensor sensor = arg2;
|
||||
uint8_t data[2];
|
||||
int val, error;
|
||||
|
||||
if (sensor != AXP209_TEMP)
|
||||
return (ENOENT);
|
||||
|
||||
error = axp209_read(dev, AXP209_TEMPMON, data, 2);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
/* Temperature is between -144.7C and 264.8C, step +0.1C */
|
||||
val = (AXP209_TEMPMON_H(data[0]) | AXP209_TEMPMON_L(data[1])) -
|
||||
AXP209_TEMPMON_MIN + AXP209_0C_TO_K;
|
||||
|
||||
return sysctl_handle_opaque(oidp, &val, sizeof(val), req);
|
||||
}
|
||||
|
||||
static void
|
||||
axp209_shutdown(void *devp, int howto)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
if (!(howto & RB_POWEROFF))
|
||||
return;
|
||||
dev = (device_t)devp;
|
||||
|
||||
if (bootverbose)
|
||||
device_printf(dev, "Shutdown AXP209\n");
|
||||
|
||||
axp209_write(dev, AXP209_SHUTBAT, AXP209_SHUTBAT_SHUTDOWN);
|
||||
}
|
||||
|
||||
static int
|
||||
axp209_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "x-powers,axp209"))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "X-Power AXP209 Power Management Unit");
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
axp209_attach(device_t dev)
|
||||
{
|
||||
struct axp209_softc *sc;
|
||||
const char *pwr_name[] = {"Battery", "AC", "USB", "AC and USB"};
|
||||
uint8_t data;
|
||||
uint8_t pwr_src;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
sc->addr = iicbus_get_addr(dev);
|
||||
|
||||
if (bootverbose) {
|
||||
/*
|
||||
* Read the Power State register.
|
||||
* Shift the AC presence into bit 0.
|
||||
* Shift the Battery presence into bit 1.
|
||||
*/
|
||||
axp209_read(dev, AXP209_PSR, &data, 1);
|
||||
pwr_src = ((data & AXP209_PSR_ACIN) >> AXP209_PSR_ACIN_SHIFT) |
|
||||
((data & AXP209_PSR_VBUS) >> (AXP209_PSR_VBUS_SHIFT - 1));
|
||||
|
||||
device_printf(dev, "AXP209 Powered by %s\n",
|
||||
pwr_name[pwr_src]);
|
||||
}
|
||||
|
||||
EVENTHANDLER_REGISTER(shutdown_final, axp209_shutdown, dev,
|
||||
SHUTDOWN_PRI_LAST);
|
||||
|
||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
||||
OID_AUTO, "temp",
|
||||
CTLTYPE_INT | CTLFLAG_RD,
|
||||
dev, AXP209_TEMP, axp209_sysctl, "IK", "Internal temperature");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t axp209_methods[] = {
|
||||
DEVMETHOD(device_probe, axp209_probe),
|
||||
DEVMETHOD(device_attach, axp209_attach),
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static driver_t axp209_driver = {
|
||||
"axp209_pmu",
|
||||
axp209_methods,
|
||||
sizeof(struct axp209_softc),
|
||||
};
|
||||
|
||||
static devclass_t axp209_devclass;
|
||||
|
||||
DRIVER_MODULE(axp209, iicbus, axp209_driver, axp209_devclass, 0, 0);
|
||||
MODULE_VERSION(axp209, 1);
|
||||
MODULE_DEPEND(axp209, iicbus, 1, 1, 1);
|
@ -1,4 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
arm/allwinner/a10_padconf.c standard
|
||||
arm/allwinner/aintc.c standard
|
||||
arm/allwinner/timer.c standard
|
||||
|
@ -3,7 +3,9 @@ kern/kern_clocksource.c standard
|
||||
|
||||
arm/allwinner/a10_ahci.c optional ahci
|
||||
arm/allwinner/a10_clk.c standard
|
||||
arm/allwinner/a10_codec.c optional sound
|
||||
arm/allwinner/a10_common.c standard
|
||||
arm/allwinner/a10_dmac.c standard
|
||||
arm/allwinner/a10_ehci.c optional ehci
|
||||
arm/allwinner/a10_gpio.c optional gpio
|
||||
arm/allwinner/a10_mmc.c optional mmc
|
||||
@ -11,5 +13,8 @@ arm/allwinner/a10_sramc.c standard
|
||||
arm/allwinner/a10_wdog.c standard
|
||||
arm/allwinner/a20/a20_cpu_cfg.c standard
|
||||
arm/allwinner/allwinner_machdep.c standard
|
||||
arm/allwinner/axp209.c optional axp209
|
||||
arm/allwinner/if_emac.c optional emac
|
||||
arm/allwinner/sunxi_dma_if.m standard
|
||||
dev/iicbus/twsi/a10_twsi.c optional twsi
|
||||
#arm/allwinner/console.c standard
|
||||
|
@ -84,7 +84,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "a10_clk.h"
|
||||
#include "a10_sramc.h"
|
||||
#include "a10_gpio.h"
|
||||
|
||||
struct emac_softc {
|
||||
struct ifnet *emac_ifp;
|
||||
@ -145,8 +144,6 @@ emac_sys_setup(void)
|
||||
|
||||
/* Activate EMAC clock. */
|
||||
a10_clk_emac_activate();
|
||||
/* Set the pin mux to EMAC (mii). */
|
||||
a10_gpio_ethernet_activate(A10_GPIO_FUNC_MII);
|
||||
/* Map sram. */
|
||||
a10_map_to_emac();
|
||||
}
|
||||
|
98
sys/arm/allwinner/sunxi_dma_if.m
Normal file
98
sys/arm/allwinner/sunxi_dma_if.m
Normal file
@ -0,0 +1,98 @@
|
||||
#-
|
||||
# Copyright (c) 2016 Jared D. McNeill <jmcneill@invisible.ca>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
#include <sys/bus.h>
|
||||
|
||||
INTERFACE sunxi_dma;
|
||||
|
||||
HEADER {
|
||||
#include <machine/bus.h>
|
||||
|
||||
struct sunxi_dma_config {
|
||||
unsigned int dst_width;
|
||||
unsigned int dst_burst_len;
|
||||
unsigned int dst_drqtype;
|
||||
bool dst_noincr;
|
||||
unsigned int dst_blksize; /* DDMA-only */
|
||||
unsigned int dst_wait_cyc; /* DDMA-only */
|
||||
unsigned int src_width;
|
||||
unsigned int src_burst_len;
|
||||
unsigned int src_drqtype;
|
||||
bool src_noincr;
|
||||
unsigned int src_blksize; /* DDMA-only */
|
||||
unsigned int src_wait_cyc; /* DDMA-only */
|
||||
};
|
||||
|
||||
typedef void (*sunxi_dma_callback)(void *);
|
||||
}
|
||||
|
||||
#
|
||||
# Allocate DMA channel
|
||||
#
|
||||
METHOD void * alloc {
|
||||
device_t dev;
|
||||
bool dedicated;
|
||||
sunxi_dma_callback callback;
|
||||
void *callback_arg;
|
||||
};
|
||||
|
||||
#
|
||||
# Free DMA channel
|
||||
#
|
||||
METHOD void free {
|
||||
device_t dev;
|
||||
void *dmachan;
|
||||
};
|
||||
|
||||
#
|
||||
# Set DMA channel configuration
|
||||
#
|
||||
METHOD int set_config {
|
||||
device_t dev;
|
||||
void *dmachan;
|
||||
const struct sunxi_dma_config *cfg;
|
||||
};
|
||||
|
||||
#
|
||||
# Start DMA channel transfer
|
||||
#
|
||||
METHOD int transfer {
|
||||
device_t dev;
|
||||
void *dmachan;
|
||||
bus_addr_t src;
|
||||
bus_addr_t dst;
|
||||
size_t nbytes;
|
||||
};
|
||||
|
||||
#
|
||||
# Halt DMA channel transfer
|
||||
#
|
||||
METHOD void halt {
|
||||
device_t dev;
|
||||
void *dmachan;
|
||||
};
|
@ -71,8 +71,8 @@ generic_bs_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
|
||||
|
||||
/*
|
||||
* We don't even examine the passed-in flags. For ARM, the CACHEABLE
|
||||
* flag doesn't make sense (we create PTE_DEVICE mappings), and the
|
||||
* LINEAR flag is just implied because we use kva_alloc(size).
|
||||
* flag doesn't make sense (we create VM_MEMATTR_DEVICE mappings), and
|
||||
* the LINEAR flag is just implied because we use kva_alloc(size).
|
||||
*/
|
||||
if ((va = pmap_mapdev(bpa, size)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
@ -52,7 +52,6 @@ static boolean_t devmap_bootstrap_done = false;
|
||||
|
||||
#if defined(__aarch64__)
|
||||
#define MAX_VADDR VM_MAX_KERNEL_ADDRESS
|
||||
#define PTE_DEVICE VM_MEMATTR_DEVICE
|
||||
#elif defined(__arm__)
|
||||
#define MAX_VADDR ARM_VECTORS_HIGH
|
||||
#endif
|
||||
@ -165,8 +164,6 @@ arm_devmap_add_entry(vm_paddr_t pa, vm_size_t sz)
|
||||
m->pd_va = akva_devmap_vaddr;
|
||||
m->pd_pa = pa;
|
||||
m->pd_size = sz;
|
||||
m->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
|
||||
m->pd_cache = PTE_DEVICE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -209,10 +206,10 @@ arm_devmap_bootstrap(vm_offset_t l1pt, const struct arm_devmap_entry *table)
|
||||
#if defined(__arm__)
|
||||
#if __ARM_ARCH >= 6
|
||||
pmap_preboot_map_attr(pd->pd_pa, pd->pd_va, pd->pd_size,
|
||||
pd->pd_prot, pd->pd_cache);
|
||||
VM_PROT_READ | VM_PROT_WRITE, VM_MEMATTR_DEVICE);
|
||||
#else
|
||||
pmap_map_chunk(l1pt, pd->pd_va, pd->pd_pa, pd->pd_size,
|
||||
pd->pd_prot, pd->pd_cache);
|
||||
VM_PROT_READ | VM_PROT_WRITE, PTE_DEVICE);
|
||||
#endif
|
||||
#elif defined(__aarch64__)
|
||||
pmap_kenter_device(pd->pd_va, pd->pd_size, pd->pd_pa);
|
||||
@ -270,7 +267,8 @@ arm_devmap_vtop(void * vpva, vm_size_t size)
|
||||
* range, otherwise it allocates kva space and maps the physical pages into it.
|
||||
*
|
||||
* This routine is intended to be used for mapping device memory, NOT real
|
||||
* memory; the mapping type is inherently PTE_DEVICE in pmap_kenter_device().
|
||||
* memory; the mapping type is inherently VM_MEMATTR_DEVICE in
|
||||
* pmap_kenter_device().
|
||||
*/
|
||||
void *
|
||||
pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
||||
|
@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/elf32.h>
|
||||
#include <sys/inflate.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/pte-v4.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/armreg.h>
|
||||
|
||||
|
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/acle-compat.h>
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/fiq.h>
|
||||
@ -73,13 +74,13 @@ fiq_installhandler(void *func, size_t size)
|
||||
{
|
||||
const uint32_t fiqvector = 7 * sizeof(uint32_t);
|
||||
|
||||
#if !defined(__ARM_FIQ_INDIRECT)
|
||||
#if __ARM_ARCH < 6 && !defined(__ARM_FIQ_INDIRECT)
|
||||
vector_page_setprot(VM_PROT_READ|VM_PROT_WRITE);
|
||||
#endif
|
||||
|
||||
memcpy((void *)(vector_page + fiqvector), func, size);
|
||||
|
||||
#if !defined(__ARM_FIQ_INDIRECT)
|
||||
#if __ARM_ARCH < 6 && !defined(__ARM_FIQ_INDIRECT)
|
||||
vector_page_setprot(VM_PROT_READ);
|
||||
#endif
|
||||
icache_sync((vm_offset_t) fiqvector, size);
|
||||
|
@ -129,7 +129,9 @@ ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
|
||||
#endif
|
||||
|
||||
ASSYM(PAGE_SIZE, PAGE_SIZE);
|
||||
#if __ARM_ARCH < 6
|
||||
ASSYM(PMAP_DOMAIN_KERNEL, PMAP_DOMAIN_KERNEL);
|
||||
#endif
|
||||
#ifdef PMAP_INCLUDE_PTE_SYNC
|
||||
ASSYM(PMAP_INCLUDE_PTE_SYNC, 1);
|
||||
#endif
|
||||
|
@ -363,6 +363,8 @@ arm_tmr_attach(device_t dev)
|
||||
if (node > 0) {
|
||||
error = OF_getencprop(node, "clock-frequency", &clock,
|
||||
sizeof(clock));
|
||||
if (error > 0)
|
||||
sc->clkfreq = clock;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <machine/asm.h>
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/cpuconf.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/pte-v4.h>
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/sysreg.h>
|
||||
#include <machine/cpuconf.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/pte-v6.h>
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
@ -280,7 +280,7 @@ ASENTRY_NP(init_mmu)
|
||||
mcr CP15_CONTEXTIDR(r0) /* Set ASID to 0 */
|
||||
|
||||
/* Set the Domain Access register */
|
||||
mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
|
||||
mov r0, #DOMAIN_CLIENT /* Only domain #0 is used */
|
||||
mcr CP15_DACR(r0)
|
||||
|
||||
/*
|
||||
|
@ -85,6 +85,7 @@ static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
|
||||
rman_res_t, rman_res_t, rman_res_t, u_int);
|
||||
static int nexus_activate_resource(device_t, device_t, int, int,
|
||||
struct resource *);
|
||||
static bus_space_tag_t nexus_get_bus_tag(device_t, device_t);
|
||||
#ifdef ARM_INTRNG
|
||||
#ifdef SMP
|
||||
static int nexus_bind_intr(device_t, device_t, struct resource *, int);
|
||||
@ -124,6 +125,7 @@ static device_method_t nexus_methods[] = {
|
||||
DEVMETHOD(bus_release_resource, nexus_release_resource),
|
||||
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
|
||||
DEVMETHOD(bus_get_bus_tag, nexus_get_bus_tag),
|
||||
#ifdef ARM_INTRNG
|
||||
DEVMETHOD(bus_describe_intr, nexus_describe_intr),
|
||||
#ifdef SMP
|
||||
@ -260,6 +262,17 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
|
||||
return (rman_release_resource(res));
|
||||
}
|
||||
|
||||
static bus_space_tag_t
|
||||
nexus_get_bus_tag(device_t bus __unused, device_t child __unused)
|
||||
{
|
||||
|
||||
#ifdef FDT
|
||||
return(fdtbus_bs_tag);
|
||||
#else
|
||||
return((void *)1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
|
||||
enum intr_polarity pol)
|
||||
|
@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
int
|
||||
OF_decode_addr(phandle_t dev, int regno, bus_space_tag_t *tag,
|
||||
bus_space_handle_t *handle)
|
||||
bus_space_handle_t *handle, bus_size_t *sz)
|
||||
{
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
@ -66,6 +66,10 @@ OF_decode_addr(phandle_t dev, int regno, bus_space_tag_t *tag,
|
||||
*tag = fdtbus_bs_tag;
|
||||
flags = 0;
|
||||
#endif
|
||||
|
||||
if (sz != NULL)
|
||||
*sz = size;
|
||||
|
||||
return (bus_space_map(*tag, addr, size, flags, handle));
|
||||
}
|
||||
|
||||
|
@ -2549,7 +2549,7 @@ pmap_remove_pages(pmap_t pmap)
|
||||
l2b = pmap_get_l2_bucket(pmap, pv->pv_va);
|
||||
KASSERT(l2b != NULL, ("No L2 bucket in pmap_remove_pages"));
|
||||
pt = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
|
||||
m = PHYS_TO_VM_PAGE(*pt & L2_ADDR_MASK);
|
||||
m = PHYS_TO_VM_PAGE(*pt & L2_S_FRAME);
|
||||
KASSERT((vm_offset_t)m >= KERNBASE, ("Trying to access non-existent page va %x pte %x", pv->pv_va, *pt));
|
||||
*pt = 0;
|
||||
PTE_SYNC(pt);
|
@ -1022,6 +1022,7 @@ pmap_preboot_map_attr(vm_paddr_t pa, vm_offset_t va, vm_size_t size,
|
||||
pt2_entry_t *pte2p;
|
||||
|
||||
l2_prot = prot & VM_PROT_WRITE ? PTE2_AP_KRW : PTE2_AP_KR;
|
||||
l2_prot |= (prot & VM_PROT_EXECUTE) ? PTE2_X : PTE2_NX;
|
||||
l2_attr = vm_memattr_to_pte2(attr);
|
||||
l1_prot = ATTR_TO_L1(l2_prot);
|
||||
l1_attr = ATTR_TO_L1(l2_attr);
|
||||
@ -1266,13 +1267,6 @@ pmap_kenter_prot_attr(vm_offset_t va, vm_paddr_t pa, uint32_t prot,
|
||||
pte2_store(pte2p, PTE2_KERN(pa, prot, attr));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int attr)
|
||||
{
|
||||
|
||||
pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, attr);
|
||||
}
|
||||
|
||||
PMAP_INLINE void
|
||||
pmap_kenter(vm_offset_t va, vm_paddr_t pa)
|
||||
{
|
||||
@ -6313,11 +6307,6 @@ pmap_fault(pmap_t pmap, vm_offset_t far, uint32_t fsr, int idx, bool usermode)
|
||||
return (KERN_FAILURE);
|
||||
}
|
||||
|
||||
/* !!!! REMOVE !!!! */
|
||||
void vector_page_setprot(int p)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(PMAP_DEBUG)
|
||||
/*
|
||||
* Reusing of KVA used in pmap_zero_page function !!!
|
||||
|
@ -98,17 +98,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
void swi_handler(struct trapframe *);
|
||||
|
||||
static __inline void
|
||||
call_trapsignal(struct thread *td, int sig, u_long code)
|
||||
{
|
||||
ksiginfo_t ksi;
|
||||
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = sig;
|
||||
ksi.ksi_code = (int)code;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
int
|
||||
cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ at91_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
return (NULL);
|
||||
if (rle->res)
|
||||
panic("Resource rid %d type %d already in use", *rid, type);
|
||||
if (start == 0UL && end == ~0UL) {
|
||||
if (RMAN_IS_DEFAULT_RANGE(start, end)) {
|
||||
start = rle->start;
|
||||
count = ulmax(count, rle->count);
|
||||
end = ulmax(rle->end, start + count - 1);
|
||||
|
@ -128,8 +128,6 @@ const struct arm_devmap_entry at91_devmap[] = {
|
||||
0xdff00000,
|
||||
0xfff00000,
|
||||
0x00100000,
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
/* There's a notion that we should do the rest of these lazily. */
|
||||
/*
|
||||
@ -152,16 +150,12 @@ const struct arm_devmap_entry at91_devmap[] = {
|
||||
AT91RM92_OHCI_VA_BASE,
|
||||
AT91RM92_OHCI_BASE,
|
||||
0x00100000,
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
{
|
||||
/* CompactFlash controller. Portion of EBI CS4 1MB */
|
||||
AT91RM92_CF_VA_BASE,
|
||||
AT91RM92_CF_BASE,
|
||||
0x00100000,
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
/*
|
||||
* The next two should be good for the 9260, 9261 and 9G20 since
|
||||
@ -172,16 +166,12 @@ const struct arm_devmap_entry at91_devmap[] = {
|
||||
AT91SAM9G20_OHCI_VA_BASE,
|
||||
AT91SAM9G20_OHCI_BASE,
|
||||
0x00100000,
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
{
|
||||
/* EBI CS3 256MB */
|
||||
AT91SAM9G20_NAND_VA_BASE,
|
||||
AT91SAM9G20_NAND_BASE,
|
||||
AT91SAM9G20_NAND_SIZE,
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
/*
|
||||
* The next should be good for the 9G45.
|
||||
@ -191,10 +181,8 @@ const struct arm_devmap_entry at91_devmap[] = {
|
||||
AT91SAM9G45_OHCI_VA_BASE,
|
||||
AT91SAM9G45_OHCI_BASE,
|
||||
0x00100000,
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
{ 0, 0, 0, 0, 0, }
|
||||
{ 0, 0, 0, }
|
||||
};
|
||||
|
||||
#ifdef LINUX_BOOT_ABI
|
||||
|
@ -280,7 +280,7 @@ pinctrl_alloc_resource(device_t bus, device_t child, int type, int *rid,
|
||||
* Request for the default allocation with a given rid: use resource
|
||||
* list stored in the local device info.
|
||||
*/
|
||||
if ((start == 0UL) && (end == ~0UL)) {
|
||||
if (RMAN_IS_DEFAULT_RANGE(start, end)) {
|
||||
if ((di = device_get_ivars(child)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
|
@ -104,6 +104,15 @@ __FBSDID("$FreeBSD$");
|
||||
/* relative offset from BCM_VC_DMA0_BASE (p.39) */
|
||||
#define BCM_DMA_CH(n) (0x100*(n))
|
||||
|
||||
/* channels used by GPU */
|
||||
#define BCM_DMA_CH_BULK 0
|
||||
#define BCM_DMA_CH_FAST1 2
|
||||
#define BCM_DMA_CH_FAST2 3
|
||||
|
||||
#define BCM_DMA_CH_GPU_MASK ((1 << BCM_DMA_CH_BULK) | \
|
||||
(1 << BCM_DMA_CH_FAST1) | \
|
||||
(1 << BCM_DMA_CH_FAST2))
|
||||
|
||||
/* DMA Control Block - 256bit aligned (p.40) */
|
||||
struct bcm_dma_cb {
|
||||
uint32_t info; /* Transfer Information */
|
||||
@ -143,6 +152,7 @@ struct bcm_dma_softc {
|
||||
};
|
||||
|
||||
static struct bcm_dma_softc *bcm_dma_sc = NULL;
|
||||
static uint32_t bcm_dma_channel_mask;
|
||||
|
||||
static void
|
||||
bcm_dmamap_cb(void *arg, bus_dma_segment_t *segs,
|
||||
@ -205,16 +215,32 @@ static int
|
||||
bcm_dma_init(device_t dev)
|
||||
{
|
||||
struct bcm_dma_softc *sc = device_get_softc(dev);
|
||||
uint32_t mask;
|
||||
uint32_t reg;
|
||||
struct bcm_dma_ch *ch;
|
||||
void *cb_virt;
|
||||
vm_paddr_t cb_phys;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
/* disable and clear interrupt status */
|
||||
bus_write_4(sc->sc_mem, BCM_DMA_ENABLE, 0);
|
||||
bus_write_4(sc->sc_mem, BCM_DMA_INT_STATUS, 0);
|
||||
/*
|
||||
* Only channels set in bcm_dma_channel_mask can be controlled by us.
|
||||
* The others are out of our control as well as the corresponding bits
|
||||
* in both BCM_DMA_ENABLE and BCM_DMA_INT_STATUS global registers. As
|
||||
* these registers are RW ones, there is no safe way how to write only
|
||||
* the bits which can be controlled by us.
|
||||
*
|
||||
* Fortunately, after reset, all channels are enabled in BCM_DMA_ENABLE
|
||||
* register and all statuses are cleared in BCM_DMA_INT_STATUS one.
|
||||
* Not touching these registers is a trade off between correct
|
||||
* initialization which does not count on anything and not messing up
|
||||
* something we have no control over.
|
||||
*/
|
||||
reg = bus_read_4(sc->sc_mem, BCM_DMA_ENABLE);
|
||||
if ((reg & bcm_dma_channel_mask) != bcm_dma_channel_mask)
|
||||
device_printf(dev, "channels are not enabled\n");
|
||||
reg = bus_read_4(sc->sc_mem, BCM_DMA_INT_STATUS);
|
||||
if ((reg & bcm_dma_channel_mask) != 0)
|
||||
device_printf(dev, "statuses are not cleared\n");
|
||||
|
||||
/* Allocate DMA chunks control blocks */
|
||||
/* p.40 of spec - control block should be 32-bit aligned */
|
||||
@ -227,7 +253,7 @@ bcm_dma_init(device_t dev)
|
||||
&sc->sc_dma_tag);
|
||||
|
||||
if (err) {
|
||||
device_printf(dev, "failed allocate DMA tag");
|
||||
device_printf(dev, "failed allocate DMA tag\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
@ -235,6 +261,13 @@ bcm_dma_init(device_t dev)
|
||||
for (i = 0; i < BCM_DMA_CH_MAX; i++) {
|
||||
ch = &sc->sc_dma_ch[i];
|
||||
|
||||
bzero(ch, sizeof(struct bcm_dma_ch));
|
||||
ch->ch = i;
|
||||
ch->flags = BCM_DMA_CH_UNMAP;
|
||||
|
||||
if ((bcm_dma_channel_mask & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
err = bus_dmamem_alloc(sc->sc_dma_tag, &cb_virt,
|
||||
BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
|
||||
&ch->dma_map);
|
||||
@ -263,33 +296,15 @@ bcm_dma_init(device_t dev)
|
||||
break;
|
||||
}
|
||||
|
||||
bzero(ch, sizeof(struct bcm_dma_ch));
|
||||
ch->ch = i;
|
||||
ch->cb = cb_virt;
|
||||
ch->vc_cb = cb_phys;
|
||||
ch->intr_func = NULL;
|
||||
ch->intr_arg = NULL;
|
||||
ch->flags = BCM_DMA_CH_UNMAP;
|
||||
|
||||
ch->flags = BCM_DMA_CH_FREE;
|
||||
ch->cb->info = INFO_WAIT_RESP;
|
||||
|
||||
/* reset DMA engine */
|
||||
bcm_dma_reset(dev, i);
|
||||
bus_write_4(sc->sc_mem, BCM_DMA_CS(i), CS_RESET);
|
||||
}
|
||||
|
||||
/* now use DMA2/DMA3 only */
|
||||
sc->sc_dma_ch[2].flags = BCM_DMA_CH_FREE;
|
||||
sc->sc_dma_ch[3].flags = BCM_DMA_CH_FREE;
|
||||
|
||||
/* enable DMAs */
|
||||
mask = 0;
|
||||
|
||||
for (i = 0; i < BCM_DMA_CH_MAX; i++)
|
||||
if (sc->sc_dma_ch[i].flags & BCM_DMA_CH_FREE)
|
||||
mask |= (1 << i);
|
||||
|
||||
bus_write_4(sc->sc_mem, BCM_DMA_ENABLE, mask);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -599,8 +614,11 @@ bcm_dma_intr(void *arg)
|
||||
/* my interrupt? */
|
||||
cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch->ch));
|
||||
|
||||
if (!(cs & (CS_INT | CS_ERR)))
|
||||
if (!(cs & (CS_INT | CS_ERR))) {
|
||||
device_printf(sc->sc_dev,
|
||||
"unexpected DMA intr CH=%d, CS=%x\n", ch->ch, cs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* running? */
|
||||
if (!(ch->flags & BCM_DMA_CH_USED)) {
|
||||
@ -651,6 +669,7 @@ static int
|
||||
bcm_dma_attach(device_t dev)
|
||||
{
|
||||
struct bcm_dma_softc *sc = device_get_softc(dev);
|
||||
phandle_t node;
|
||||
int rid, err = 0;
|
||||
int i;
|
||||
|
||||
@ -664,6 +683,19 @@ bcm_dma_attach(device_t dev)
|
||||
sc->sc_intrhand[i] = NULL;
|
||||
}
|
||||
|
||||
/* Get DMA channel mask. */
|
||||
node = ofw_bus_get_node(sc->sc_dev);
|
||||
if (OF_getencprop(node, "brcm,dma-channel-mask", &bcm_dma_channel_mask,
|
||||
sizeof(bcm_dma_channel_mask)) == -1 &&
|
||||
OF_getencprop(node, "broadcom,channels", &bcm_dma_channel_mask,
|
||||
sizeof(bcm_dma_channel_mask)) == -1) {
|
||||
device_printf(dev, "could not get channel mask property\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Mask out channels used by GPU. */
|
||||
bcm_dma_channel_mask &= ~BCM_DMA_CH_GPU_MASK;
|
||||
|
||||
/* DMA0 - DMA14 */
|
||||
rid = 0;
|
||||
sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
|
||||
@ -674,6 +706,9 @@ bcm_dma_attach(device_t dev)
|
||||
|
||||
/* IRQ DMA0 - DMA11 XXX NOT USE DMA12(spurious?) */
|
||||
for (rid = 0; rid < BCM_DMA_CH_MAX; rid++) {
|
||||
if ((bcm_dma_channel_mask & (1 << rid)) == 0)
|
||||
continue;
|
||||
|
||||
sc->sc_irq[rid] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
|
||||
RF_ACTIVE);
|
||||
if (sc->sc_irq[rid] == NULL) {
|
||||
|
@ -37,8 +37,6 @@
|
||||
/* request CH for any nubmer */
|
||||
#define BCM_DMA_CH_INVALID (-1)
|
||||
#define BCM_DMA_CH_ANY (-1)
|
||||
#define BCM_DMA_CH_FAST1 (2)
|
||||
#define BCM_DMA_CH_FAST2 (3)
|
||||
|
||||
/* Peripheral DREQ Signals (4.2.1.3) */
|
||||
#define BCM_DMA_DREQ_NONE 0
|
||||
|
@ -214,11 +214,7 @@ bcm_sdhci_attach(device_t dev)
|
||||
|
||||
sdhci_init_slot(dev, &sc->sc_slot, 0);
|
||||
|
||||
sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST1);
|
||||
if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
|
||||
sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST2);
|
||||
if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
|
||||
sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_ANY);
|
||||
sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_ANY);
|
||||
if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
|
||||
goto fail;
|
||||
|
||||
|
@ -425,7 +425,7 @@ econa_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
}
|
||||
if (rle->res)
|
||||
panic("Resource rid %d type %d already in use", *rid, type);
|
||||
if (start == 0UL && end == ~0UL) {
|
||||
if (RMAN_IS_DEFAULT_RANGE(start, end)) {
|
||||
start = rle->start;
|
||||
count = ulmax(count, rle->count);
|
||||
end = ulmax(rle->end, start + count - 1);
|
||||
|
@ -113,8 +113,6 @@ static const struct arm_devmap_entry econa_devmap[] = {
|
||||
ECONA_SDRAM_BASE, /*virtual*/
|
||||
ECONA_SDRAM_BASE, /*physical*/
|
||||
ECONA_SDRAM_SIZE, /*size*/
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
/*
|
||||
* Map the on-board devices VA == PA so that we can access them
|
||||
@ -128,8 +126,6 @@ static const struct arm_devmap_entry econa_devmap[] = {
|
||||
ECONA_IO_BASE, /*virtual*/
|
||||
ECONA_IO_BASE, /*physical*/
|
||||
ECONA_IO_SIZE, /*size*/
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
{
|
||||
/*
|
||||
@ -138,8 +134,6 @@ static const struct arm_devmap_entry econa_devmap[] = {
|
||||
ECONA_OHCI_VBASE, /*virtual*/
|
||||
ECONA_OHCI_PBASE, /*physical*/
|
||||
ECONA_USB_SIZE, /*size*/
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
{
|
||||
/*
|
||||
@ -148,15 +142,11 @@ static const struct arm_devmap_entry econa_devmap[] = {
|
||||
ECONA_CFI_VBASE, /*virtual*/
|
||||
ECONA_CFI_PBASE, /*physical*/
|
||||
ECONA_CFI_SIZE,
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
PTE_DEVICE,
|
||||
},
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
}
|
||||
};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user