initial commit

This commit is contained in:
eliboa 2020-06-24 20:30:39 +02:00
commit 014f7766c9
173 changed files with 57756 additions and 0 deletions

73
.gitignore vendored Normal file
View file

@ -0,0 +1,73 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe

31
TegraRcmGUI.pro Normal file
View file

@ -0,0 +1,31 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
tegrarcmgui.cpp
HEADERS += \
tegrarcmgui.h
FORMS += \
tegrarcmgui.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

1
ariane/ariane.cflags Normal file
View file

@ -0,0 +1 @@
-std=c17

2
ariane/ariane.config Normal file
View file

@ -0,0 +1,2 @@
// Add predefined macros for your project here. For example:
// #define THE_ANSWER 42

1
ariane/ariane.creator Normal file
View file

@ -0,0 +1 @@
[General]

1
ariane/ariane.cxxflags Normal file
View file

@ -0,0 +1 @@
-std=c++17

104
ariane/ariane.files Normal file
View file

@ -0,0 +1,104 @@
src/cbmem.c
src/cbmem.h
src/display/cfb_console.c
src/display/video_fb.h
src/display/video_font_large.h
src/display/video_font_small.h
src/fuse.c
src/fuse.h
src/hwinit/btn.c
src/hwinit/btn.h
src/hwinit/carveout.c
src/hwinit/carveout.h
src/hwinit/clock.c
src/hwinit/clock.h
src/hwinit/cluster.c
src/hwinit/cluster.h
src/hwinit/di.c
src/hwinit/di.h
src/hwinit/di.inl
src/hwinit/emc.h
src/hwinit/flow.h
src/hwinit/fuse.c
src/hwinit/fuse.h
src/hwinit/gpio.c
src/hwinit/gpio.h
src/hwinit/hwinit.c
src/hwinit/hwinit.h
src/hwinit/i2c.c
src/hwinit/i2c.h
src/hwinit/kfuse.c
src/hwinit/kfuse.h
src/hwinit/max77620.h
src/hwinit/max7762x.c
src/hwinit/max7762x.h
src/hwinit/mc.c
src/hwinit/mc.h
src/hwinit/mc_t210.h
src/hwinit/mmc.h
src/hwinit/mtc.c
src/hwinit/mtc.h
src/hwinit/pinmux.c
src/hwinit/pinmux.h
src/hwinit/pmc.h
src/hwinit/sd.h
src/hwinit/sdmmc.c
src/hwinit/sdmmc.h
src/hwinit/sdmmc_driver.c
src/hwinit/sdmmc_driver.h
src/hwinit/sdmmc_t210.h
src/hwinit/sdram.c
src/hwinit/sdram.h
src/hwinit/sdram_lp0.c
src/hwinit/sdram_lz4.inl
src/hwinit/sdram_param_t210.h
src/hwinit/t210.h
src/hwinit/timer.c
src/hwinit/timer.h
src/hwinit/tsec.c
src/hwinit/tsec.h
src/hwinit/types.h
src/hwinit/uart.c
src/hwinit/uart.h
src/hwinit/util.c
src/hwinit/util.h
src/lib/crc32.c
src/lib/crc32.h
src/lib/decomp.h
src/lib/diskio.c
src/lib/diskio.h
src/lib/ff.c
src/lib/ff.h
src/lib/ffconf.h
src/lib/ffsystem.c
src/lib/ffunicode.c
src/lib/heap.c
src/lib/heap.h
src/lib/integer.h
src/lib/lz.c
src/lib/lz.h
src/lib/lz4.c.inc
src/lib/lz4_wrapper.c
src/lib/lzma.c
src/lib/lzmadecode.c
src/lib/lzmadecode.h
src/lib/printk.c
src/lib/printk.h
src/lib/vsprintf.c
src/lib/vsprintf.h
src/main.c
src/minerva_tc/mtc/mtc.c
src/minerva_tc/mtc/mtc.h
src/minerva_tc/mtc/mtc_mc_emc_regs.h
src/minerva_tc/mtc/mtc_table.h
src/minerva_tc/mtc/types.h
src/panic_color.h
src/rcm_usb.c
src/rcm_usb.h
src/start.s
src/storage.c
src/storage.h
src/usb_command.h
src/usb_output.h
src/utils.c
src/utils.h

5
ariane/ariane.includes Normal file
View file

@ -0,0 +1,5 @@
src
src/display
src/hwinit
src/lib
src/minerva_tc/mtc

154
ariane/linker.ld Normal file
View file

@ -0,0 +1,154 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
/* Mostly copied from https://github.com/devkitPro/buildscripts/blob/master/dkarm-eabi/crtls/3dsx.ld */
SECTIONS
{
PROVIDE(__start__ = 0x40008000);
. = __start__;
. = ALIGN(32);
.text :
{
. = ALIGN(32);
/* .init */
KEEP( *(.text.start) )
KEEP( *(.init) )
. = ALIGN(4);
/* .text */
*(.text)
*(.text.*)
*(.glue_7)
*(.glue_7t)
*(.stub)
*(.gnu.warning)
*(.gnu.linkonce.t*)
. = ALIGN(4);
/* .fini */
KEEP( *(.fini) )
. = ALIGN(4);
}
.rodata :
{
*(.rodata)
*(.roda)
*(.rodata.*)
*all.rodata*(*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4);
}
.preinit_array ALIGN(4) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
}
.init_array ALIGN(4) :
{
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
}
.fini_array ALIGN(4) :
{
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
}
.ctors ALIGN(4) :
{
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors ALIGN(4) :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
__exidx_start = .;
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
__exidx_end = .;
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
. = ALIGN(4);
}
__bss_start__ = ALIGN(32);
.bss :
{
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b*)
*(COMMON)
. = ALIGN(8);
}
__bss_end__ = .;
__end__ = ABSOLUTE(.) ;
PROVIDE(__stack = 0x4003F000);
. = __stack;
/* ==================
==== Metadata ====
================== */
/* Discard sections that difficult post-processing */
/DISCARD/ : { *(.group .comment .note) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

7
ariane/linker.specs Normal file
View file

@ -0,0 +1,7 @@
%rename link old_link
*link:
%(old_link) -T linker.ld --nmagic --gc-sections
*startfile:
crti%O%s crtbegin%O%s

BIN
ariane/out/ariane.bin Normal file

Binary file not shown.

390
ariane/src/cbmem.c Normal file
View file

@ -0,0 +1,390 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2014 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "cbmem.h"
#include "hwinit/carveout.h"
#include "lib/printk.h"
#include <string.h>
#include <stdbool.h>
#if defined(__INT_MAX__) && __INT_MAX__ == 2147483647
typedef int ssize_t;
#else
typedef long ssize_t;
#endif
void *cbmem_top(void)
{
static uintptr_t addr;
if (addr == 0) {
uintptr_t begin_mib;
uintptr_t end_mib;
memory_in_range_below_4gb(&begin_mib, &end_mib);
/* Make sure we consume everything up to 4GIB. */
if (end_mib == 4096)
addr = ~(uint32_t)0;
else
addr = end_mib << 20;
}
return (void *)addr;
}
void cbmem_initialize_empty(void)
{
cbmem_initialize_empty_id_size(0, 0);
}
/*
* The struct imd is a handle for working with an in-memory directory.
*
* NOTE: Do not directly touch any fields within this structure. An imd pointer
* is meant to be opaque, but the fields are exposed for stack allocation.
*/
struct imdr {
uintptr_t limit;
void *r;
};
struct imd {
struct imdr lg;
struct imdr sm;
};
static const uint32_t IMD_ROOT_PTR_MAGIC = 0xc0389481;
static const uint32_t IMD_ENTRY_MAGIC = ~0xc0389481;
static const uint32_t SMALL_REGION_ID = CBMEM_ID_IMD_SMALL;
static const size_t LIMIT_ALIGN = 4096;
static void imdr_init(struct imdr *ir, void *upper_limit)
{
uintptr_t limit = (uintptr_t)upper_limit;
/* Upper limit is aligned down to 4KiB */
ir->limit = ALIGN_DOWN(limit, LIMIT_ALIGN);
ir->r = NULL;
}
/* Initialize imd handle. */
static void imd_handle_init(struct imd *imd, void *upper_limit)
{
imdr_init(&imd->lg, upper_limit);
imdr_init(&imd->sm, NULL);
}
/* In-memory data structures. */
struct imd_root_pointer {
uint32_t magic;
/* Relative to upper limit/offset. */
int32_t root_offset;
} __packed;
struct imd_entry {
uint32_t magic;
/* start is located relative to imd_root */
int32_t start_offset;
uint32_t size;
uint32_t id;
} __packed;
struct imd_root {
uint32_t max_entries;
uint32_t num_entries;
uint32_t flags;
uint32_t entry_align;
/* Used for fixing the size of an imd. Relative to the root. */
int32_t max_offset;
struct imd_entry entries[0];
} __packed;
#define IMD_FLAG_LOCKED 1
static void imd_entry_assign(struct imd_entry *e, uint32_t id,
ssize_t offset, size_t size)
{
e->magic = IMD_ENTRY_MAGIC;
e->start_offset = offset;
e->size = size;
e->id = id;
}
static void *relative_pointer(void *base, ssize_t offset)
{
intptr_t b = (intptr_t)base;
b += offset;
return (void *)b;
}
static struct imd_root *imdr_root(const struct imdr *imdr)
{
return imdr->r;
}
/*
* The root pointer is relative to the upper limit of the imd. i.e. It sits
* just below the upper limit.
*/
static struct imd_root_pointer *imdr_get_root_pointer(const struct imdr *imdr)
{
struct imd_root_pointer *rp;
rp = relative_pointer((void *)imdr->limit, -sizeof(*rp));
return rp;
}
static void imd_link_root(struct imd_root_pointer *rp, struct imd_root *r)
{
rp->magic = IMD_ROOT_PTR_MAGIC;
rp->root_offset = (int32_t)((intptr_t)r - (intptr_t)rp);
}
static struct imd_entry *root_last_entry(struct imd_root *r)
{
return &r->entries[r->num_entries - 1];
}
static size_t root_num_entries(size_t root_size)
{
size_t entries_size;
entries_size = root_size;
entries_size -= sizeof(struct imd_root_pointer);
entries_size -= sizeof(struct imd_root);
return entries_size / sizeof(struct imd_entry);
}
static size_t imd_root_data_left(struct imd_root *r)
{
struct imd_entry *last_entry;
last_entry = root_last_entry(r);
if (r->max_offset != 0)
return last_entry->start_offset - r->max_offset;
return ~(size_t)0;
}
static bool root_is_locked(const struct imd_root *r)
{
return !!(r->flags & IMD_FLAG_LOCKED);
}
static int imdr_create_empty(struct imdr *imdr, size_t root_size,
size_t entry_align)
{
struct imd_root_pointer *rp;
struct imd_root *r;
struct imd_entry *e;
ssize_t root_offset;
if (!imdr->limit)
return -1;
/* root_size and entry_align should be a power of 2. */
if (!IS_POWER_OF_2(root_size))
{
dbg_print("IMDR root_size not a power of 2, given %u\n", root_size);
while (1) {}
}
if (!IS_POWER_OF_2(entry_align))
{
dbg_print("IMDR entry_align not a power of 2, given %u\n", entry_align);
while (1) {}
}
if (!imdr->limit)
return -1;
/*
* root_size needs to be large enough to accommodate root pointer and
* root book keeping structure. The caller needs to ensure there's
* enough room for tracking individual allocations.
*/
if (root_size < (sizeof(*rp) + sizeof(*r)))
return -1;
/* For simplicity don't allow sizes or alignments to exceed LIMIT_ALIGN.
*/
if (root_size > LIMIT_ALIGN || entry_align > LIMIT_ALIGN)
return -1;
/* Additionally, don't handle an entry alignment > root_size. */
if (entry_align > root_size)
return -1;
rp = imdr_get_root_pointer(imdr);
root_offset = -(ssize_t)root_size;
/* Set root pointer. */
imdr->r = relative_pointer((void *)imdr->limit, root_offset);
r = imdr_root(imdr);
imd_link_root(rp, r);
memset(r, 0, sizeof(*r));
r->entry_align = entry_align;
/* Calculate size left for entries. */
r->max_entries = root_num_entries(root_size);
/* Fill in first entry covering the root region. */
r->num_entries = 1;
e = &r->entries[0];
imd_entry_assign(e, CBMEM_ID_IMD_ROOT, 0, root_size);
dbg_print("IMD: root @ %p %u entries.\n", r, r->max_entries);
return 0;
}
static int imdr_limit_size(struct imdr *imdr, size_t max_size)
{
struct imd_root *r;
ssize_t smax_size;
size_t root_size;
r = imdr_root(imdr);
if (r == NULL)
return -1;
root_size = imdr->limit - (uintptr_t)r;
if (max_size < root_size)
return -1;
/* Take into account the root size. */
smax_size = max_size - root_size;
smax_size = -smax_size;
r->max_offset = smax_size;
return 0;
}
static void *imdr_entry_at(const struct imdr *imdr, const struct imd_entry *e)
{
return relative_pointer(imdr_root(imdr), e->start_offset);
}
static struct imd_entry *imd_entry_add_to_root(struct imd_root *r, uint32_t id,
size_t size)
{
struct imd_entry *entry;
struct imd_entry *last_entry;
ssize_t e_offset;
size_t used_size;
if (r->num_entries == r->max_entries)
return NULL;
/* Determine total size taken up by entry. */
used_size = ALIGN_UP(size, r->entry_align);
/* See if size overflows imd total size. */
if (used_size > imd_root_data_left(r))
return NULL;
/*
* Determine if offset field overflows. All offsets should be lower
* than the previous one.
*/
last_entry = root_last_entry(r);
e_offset = last_entry->start_offset;
e_offset -= (ssize_t)used_size;
if (e_offset > last_entry->start_offset)
return NULL;
entry = root_last_entry(r) + 1;
r->num_entries++;
imd_entry_assign(entry, id, e_offset, size);
return entry;
}
static const struct imd_entry *imdr_entry_add(const struct imdr *imdr,
uint32_t id, size_t size)
{
struct imd_root *r;
r = imdr_root(imdr);
if (r == NULL)
return NULL;
if (root_is_locked(r))
return NULL;
return imd_entry_add_to_root(r, id, size);
}
static int imd_create_tiered_empty(struct imd *imd,
size_t lg_root_size, size_t lg_entry_align,
size_t sm_root_size, size_t sm_entry_align)
{
size_t sm_region_size;
const struct imd_entry *e;
struct imdr *imdr;
imdr = &imd->lg;
if (imdr_create_empty(imdr, lg_root_size, lg_entry_align) != 0)
return -1;
/* Calculate the size of the small region to request. */
sm_region_size = root_num_entries(sm_root_size) * sm_entry_align;
sm_region_size += sm_root_size;
sm_region_size = ALIGN_UP(sm_region_size, lg_entry_align);
/* Add a new entry to the large region to cover the root and entries. */
e = imdr_entry_add(imdr, SMALL_REGION_ID, sm_region_size);
if (e == NULL)
goto fail;
imd->sm.limit = (uintptr_t)imdr_entry_at(imdr, e);
imd->sm.limit += sm_region_size;
if (imdr_create_empty(&imd->sm, sm_root_size, sm_entry_align) != 0 ||
imdr_limit_size(&imd->sm, sm_region_size))
goto fail;
return 0;
fail:
imd_handle_init(imd, (void *)imdr->limit);
return -1;
}
void cbmem_initialize_empty_id_size(u32 id, u64 size)
{
struct imd *imd;
struct imd imd_backing;
imd = &imd_backing;
imd_handle_init(imd, cbmem_top());
dbg_print("CBMEM:\n");
if (imd_create_tiered_empty(imd, CBMEM_ROOT_MIN_SIZE, CBMEM_LG_ALIGN,
CBMEM_SM_ROOT_SIZE, CBMEM_SM_ALIGN)) {
dbg_print("failed.\n");
return;
}
/* Add the specified range first */
if (size)
dbg_print("CBMEM region can only be empty, while size of %llu specified!\n", size);
}

70
ariane/src/cbmem.h Normal file
View file

@ -0,0 +1,70 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009 coresystems GmbH
* Copyright (C) 2013 Google, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _CBMEM_H_
#define _CBMEM_H_
#include <stddef.h>
#include <stdint.h>
#include "hwinit/types.h"
#define CBMEM_FSP_HOB_PTR 0x614
struct cbmem_entry;
/*
* The dynamic cbmem infrastructure allows for growing cbmem dynamically as
* things are added. It requires an external function, cbmem_top(), to be
* implemented by the board or chipset to define the upper address where
* cbmem lives. This address is required to be a 32-bit address. Additionally,
* the address needs to be consistent in both romstage and ramstage. The
* dynamic cbmem infrastructure allocates new regions below the last allocated
* region. Regions are defined by a cbmem_entry struct that is opaque. Regions
* may be removed, but the last one added is the only that can be removed.
*/
#define DYN_CBMEM_ALIGN_SIZE (4096)
#define CBMEM_ROOT_SIZE DYN_CBMEM_ALIGN_SIZE
/* The root region is at least DYN_CBMEM_ALIGN_SIZE . */
#define CBMEM_ROOT_MIN_SIZE DYN_CBMEM_ALIGN_SIZE
#define CBMEM_LG_ALIGN CBMEM_ROOT_MIN_SIZE
/* Small allocation parameters. */
#define CBMEM_SM_ROOT_SIZE 1024
#define CBMEM_SM_ALIGN 32
/* Determine the size for CBMEM root and the small allocations */
static inline size_t cbmem_overhead_size(void)
{
return 2 * CBMEM_ROOT_MIN_SIZE;
}
#define CBMEM_ID_IMD_ROOT 0xff4017ff
#define CBMEM_ID_IMD_SMALL 0x53a11439
/* Initialize cbmem to be empty. */
void cbmem_initialize_empty(void);
void cbmem_initialize_empty_id_size(u32 id, u64 size);
/* Return the top address for dynamic cbmem. The address returned needs to
* be consistent across romstage and ramstage, and it is required to be
* below 4GiB.
* x86 boards or chipsets must return NULL before the cbmem backing store has
* been initialized. */
void *cbmem_top(void);
#endif /* _CBMEM_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,59 @@
/*
* (C) Copyright 1997-2002 ELTEC Elektronik AG
* Frank Gottschling <fgottschling@eltec.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _VIDEO_FB_H_
#define _VIDEO_FB_H_
#define CONSOLE_BG_COL 0x00
#define CONSOLE_FG_COL 0xa0
/* Try using the small font */
#define CONFIG_VIDEO_FONT_SMALL
/*
* Graphic Data Format (GDF) bits for VIDEO_DATA_FORMAT
*/
#define GDF__8BIT_INDEX 0
#define GDF_15BIT_555RGB 1
#define GDF_16BIT_565RGB 2
#define GDF_32BIT_X888RGB 3
#define GDF_24BIT_888RGB 4
#define GDF__8BIT_332RGB 5
#define CONFIG_VIDEO_FB_LITTLE_ENDIAN
#define CONFIG_VIDEO_VISIBLE_COLS 720
#define CONFIG_VIDEO_VISIBLE_ROWS 1280
#define CONFIG_VIDEO_COLS 768
#define CONFIG_VIDEO_PIXEL_SIZE 4
#define CONFIG_VIDEO_DATA_FORMAT GDF_32BIT_X888RGB /* BGR actually, but w/e */
int video_get_col(void);
int video_get_row(void);
void video_reposition(int row, int col);
void video_clear_line();
int video_init(void *fb);
int video_resume(void *fb, int row, int col);
void video_puts(const char *s);
#endif /*_VIDEO_FB_H_ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

236
ariane/src/fuse.c Normal file
View file

@ -0,0 +1,236 @@
#include <string.h>
#include "hwinit/hwinit.h"
#include "hwinit/clock.h"
#include "hwinit/timer.h"
#include "fuse.h"
/* Prototypes for internal commands. */
void fuse_make_regs_visible(void);
void fuse_enable_power(void);
void fuse_disable_power(void);
void fuse_wait_idle(void);
/* Initialize the FUSE driver */
void fuse_init(void)
{
/*
Already done by hwinit, except maybe fuse_secondary_private_key_disable (?)
fuse_make_regs_visible();
fuse_secondary_private_key_disable();
fuse_disable_programming();
*/
/* TODO: Overrides (iROM patches) and various reads happen here */
}
/* Make all fuse registers visible */
void fuse_make_regs_visible(void)
{
clock_enable_fuse(1);
}
/* Enable power to the fuse hardware array */
void fuse_enable_power(void)
{
FUSE_REGS->FUSE_PWR_GOOD_SW = 1;
usleep(1);
}
/* Disable power to the fuse hardware array */
void fuse_disable_power(void)
{
FUSE_REGS->FUSE_PWR_GOOD_SW = 0;
usleep(1);
}
/* Wait for the fuse driver to go idle */
void fuse_wait_idle(void)
{
uint32_t ctrl_val = 0;
/* Wait for STATE_IDLE */
while ((ctrl_val & (0xF0000)) != 0x40000)
{
usleep(1);
ctrl_val = FUSE_REGS->FUSE_CTRL;
}
}
/* Read a fuse from the hardware array */
uint32_t fuse_hw_read(uint32_t addr)
{
fuse_wait_idle();
/* Program the target address */
FUSE_REGS->FUSE_REG_ADDR = addr;
/* Enable read operation in control register */
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x1; /* Set FUSE_READ command */
FUSE_REGS->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
return FUSE_REGS->FUSE_REG_READ;
}
/* Write a fuse in the hardware array */
void fuse_hw_write(uint32_t value, uint32_t addr)
{
fuse_wait_idle();
/* Program the target address and value */
FUSE_REGS->FUSE_REG_ADDR = addr;
FUSE_REGS->FUSE_REG_WRITE = value;
/* Enable write operation in control register */
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
FUSE_REGS->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
}
/* Sense the fuse hardware array into the shadow cache */
void fuse_hw_sense(void)
{
fuse_wait_idle();
/* Enable sense operation in control register */
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
FUSE_REGS->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
}
/* Disables all fuse programming. */
void fuse_disable_programming(void) {
FUSE_REGS->FUSE_DIS_PGM = 1;
}
/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */
void fuse_secondary_private_key_disable(void) {
FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10;
}
/* Read the SKU info register from the shadow cache */
uint32_t fuse_get_sku_info(void)
{
return FUSE_CHIP_REGS->FUSE_SKU_INFO;
}
/* Read the bootrom patch version from a register in the shadow cache */
uint32_t fuse_get_bootrom_patch_version(void)
{
return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1;
}
/* Read a spare bit register from the shadow cache */
uint32_t fuse_get_spare_bit(uint32_t idx)
{
if (idx >= 32) {
return 0;
}
return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx];
}
/* Read a reserved ODM register from the shadow cache */
uint32_t fuse_get_reserved_odm(uint32_t idx)
{
if (idx >= 8) {
return 0;
}
return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx];
}
/* Derive the Device ID using values in the shadow cache */
uint64_t fuse_get_device_id(void) {
uint64_t device_id = 0;
uint64_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF;
uint64_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF;
uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F;
uint32_t lot_code = FUSE_CHIP_REGS->FUSE_LOT_CODE_0;
uint64_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
uint64_t derived_lot_code = 0;
for (unsigned int i = 0; i < 5; i++) {
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
}
derived_lot_code &= 0x03FFFFFF;
device_id |= y_coord << 0;
device_id |= x_coord << 9;
device_id |= wafer_id << 18;
device_id |= derived_lot_code << 24;
device_id |= fab_code << 50;
return device_id;
}
/* Get the DRAM ID using values in the shadow cache */
uint32_t fuse_get_dram_id(void) {
return (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
}
/* Derive the Hardware Type using values in the shadow cache */
uint32_t fuse_get_hardware_type(void) {
/* This function is very different between 4.x and < 4.x */
uint32_t hardware_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 2) & 1);
/* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) {
static const uint32_t types[] = {0,1,4,3};
hardware_type |= (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
hardware_type--;
return hardware_type > 3 ? 4 : types[hardware_type];
} else {*/
if (hardware_type >= 1) {
return hardware_type > 2 ? 3 : hardware_type - 1;
} else if ((FUSE_CHIP_REGS->FUSE_SPARE_BIT[9] & 1) == 0) {
return 0;
} else {
return 3;
}
// }
}
/* Derive the Retail Type using values in the shadow cache */
uint32_t fuse_get_retail_type(void) {
/* Retail type = IS_RETAIL | UNIT_TYPE */
uint32_t retail_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 4) | (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] & 3);
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
return 1;
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
return 0;
}
return 2; /* IS_RETAIL | DEV_UNIT */
}
/* Derive the 16-byte Hardware Info using values in the shadow cache, and copy to output buffer. */
void fuse_get_hardware_info(void *dst) {
uint32_t hw_info[0x4];
uint32_t unk_hw_fuse = FUSE_CHIP_REGS->_0x120 & 0x3F;
uint32_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF;
uint32_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF;
uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F;
uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_LOT_CODE_0;
uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
uint32_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_VENDOR_CODE & 0xF;
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
hw_info[3] = (uint32_t)(vendor_code);
memcpy(dst, hw_info, 0x10);
}

197
ariane/src/fuse.h Normal file
View file

@ -0,0 +1,197 @@
#ifndef FUSEE_FUSE_H
#define FUSEE_FUSE_H
#include <stdbool.h>
#include <stdint.h>
typedef struct {
uint32_t FUSE_CTRL;
uint32_t FUSE_REG_ADDR;
uint32_t FUSE_REG_READ;
uint32_t FUSE_REG_WRITE;
uint32_t FUSE_TIME_RD1;
uint32_t FUSE_TIME_RD2;
uint32_t FUSE_TIME_PGM1;
uint32_t FUSE_TIME_PGM2;
uint32_t FUSE_PRIV2INTFC;
uint32_t FUSE_FUSEBYPASS;
uint32_t FUSE_PRIVATEKEYDISABLE;
uint32_t FUSE_DIS_PGM;
uint32_t FUSE_WRITE_ACCESS;
uint32_t FUSE_PWR_GOOD_SW;
uint32_t _0x38[0x32];
} fuse_registers_t;
typedef struct {
uint32_t FUSE_PRODUCTION_MODE;
uint32_t _0x4;
uint32_t _0x8;
uint32_t _0xC;
uint32_t FUSE_SKU_INFO;
uint32_t FUSE_CPU_SPEEDO_0;
uint32_t FUSE_CPU_IDDQ;
uint32_t _0x1C;
uint32_t _0x20;
uint32_t _0x24;
uint32_t FUSE_FT_REV;
uint32_t FUSE_CPU_SPEEDO_1;
uint32_t FUSE_CPU_SPEEDO_2;
uint32_t FUSE_SOC_SPEEDO_0;
uint32_t FUSE_SOC_SPEEDO_1;
uint32_t FUSE_SOC_SPEEDO_2;
uint32_t FUSE_SOC_IDDQ;
uint32_t _0x44;
uint32_t FUSE_FA;
uint32_t _0x4C;
uint32_t _0x50;
uint32_t _0x54;
uint32_t _0x58;
uint32_t _0x5C;
uint32_t _0x60;
uint32_t FUSE_PUBLIC_KEY[0x8];
uint32_t FUSE_TSENSOR_1;
uint32_t FUSE_TSENSOR_2;
uint32_t _0x8C;
uint32_t FUSE_CP_REV;
uint32_t _0x94;
uint32_t FUSE_TSENSOR_0;
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
uint32_t FUSE_SECURITY_MODE;
uint32_t FUSE_PRIVATE_KEY[0x4];
uint32_t FUSE_DEVICE_KEY;
uint32_t _0xB8;
uint32_t _0xBC;
uint32_t FUSE_RESERVED_SW;
uint32_t FUSE_VP8_ENABLE;
uint32_t FUSE_RESERVED_ODM[0x8];
uint32_t _0xE8;
uint32_t _0xEC;
uint32_t FUSE_SKU_USB_CALIB;
uint32_t FUSE_SKU_DIRECT_CONFIG;
uint32_t _0xF8;
uint32_t _0xFC;
uint32_t FUSE_VENDOR_CODE;
uint32_t FUSE_FAB_CODE;
uint32_t FUSE_LOT_CODE_0;
uint32_t FUSE_LOT_CODE_1;
uint32_t FUSE_WAFER_ID;
uint32_t FUSE_X_COORDINATE;
uint32_t FUSE_Y_COORDINATE;
uint32_t _0x11C;
uint32_t _0x120;
uint32_t FUSE_SATA_CALIB;
uint32_t FUSE_GPU_IDDQ;
uint32_t FUSE_TSENSOR_3;
uint32_t _0x130;
uint32_t _0x134;
uint32_t _0x138;
uint32_t _0x13C;
uint32_t _0x140;
uint32_t _0x144;
uint32_t FUSE_OPT_SUBREVISION;
uint32_t _0x14C;
uint32_t _0x150;
uint32_t FUSE_TSENSOR_4;
uint32_t FUSE_TSENSOR_5;
uint32_t FUSE_TSENSOR_6;
uint32_t FUSE_TSENSOR_7;
uint32_t FUSE_OPT_PRIV_SEC_DIS;
uint32_t FUSE_PKC_DISABLE;
uint32_t _0x16C;
uint32_t _0x170;
uint32_t _0x174;
uint32_t _0x178;
uint32_t _0x17C;
uint32_t FUSE_TSENSOR_COMMON;
uint32_t _0x184;
uint32_t _0x188;
uint32_t _0x18C;
uint32_t _0x190;
uint32_t _0x194;
uint32_t _0x198;
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
uint32_t _0x1A0;
uint32_t _0x1A4;
uint32_t _0x1A8;
uint32_t _0x1AC;
uint32_t _0x1B0;
uint32_t _0x1B4;
uint32_t _0x1B8;
uint32_t _0x1BC;
uint32_t _0x1D0;
uint32_t FUSE_TSENSOR_8;
uint32_t _0x1D8;
uint32_t _0x1DC;
uint32_t _0x1E0;
uint32_t _0x1E4;
uint32_t _0x1E8;
uint32_t _0x1EC;
uint32_t _0x1F0;
uint32_t _0x1F4;
uint32_t _0x1F8;
uint32_t _0x1FC;
uint32_t _0x200;
uint32_t FUSE_RESERVED_CALIB;
uint32_t _0x208;
uint32_t _0x20C;
uint32_t _0x210;
uint32_t _0x214;
uint32_t _0x218;
uint32_t FUSE_TSENSOR_9;
uint32_t _0x220;
uint32_t _0x224;
uint32_t _0x228;
uint32_t _0x22C;
uint32_t _0x230;
uint32_t _0x234;
uint32_t _0x238;
uint32_t _0x23C;
uint32_t _0x240;
uint32_t _0x244;
uint32_t _0x248;
uint32_t _0x24C;
uint32_t FUSE_USB_CALIB_EXT;
uint32_t _0x254;
uint32_t _0x258;
uint32_t _0x25C;
uint32_t _0x260;
uint32_t _0x264;
uint32_t _0x268;
uint32_t _0x26C;
uint32_t _0x270;
uint32_t _0x274;
uint32_t _0x278;
uint32_t _0x27C;
uint32_t FUSE_SPARE_BIT[0x20];
} fuse_chip_registers_t;
static inline volatile fuse_registers_t *get_fuse_regs(void) {
return (volatile fuse_registers_t *)(0x7000F000 + 0x800);
}
static inline volatile fuse_chip_registers_t *get_fuse_chip_regs(void) {
return (volatile fuse_chip_registers_t *)(0x7000F000 + 0x900);
}
#define FUSE_REGS (get_fuse_regs())
#define FUSE_CHIP_REGS (get_fuse_chip_regs())
void fuse_init(void);
uint32_t fuse_hw_read(uint32_t addr);
void fuse_hw_write(uint32_t value, uint32_t addr);
void fuse_hw_sense(void);
void fuse_disable_programming(void);
void fuse_secondary_private_key_disable(void);
uint32_t fuse_get_sku_info(void);
uint32_t fuse_get_spare_bit(uint32_t idx);
uint32_t fuse_get_reserved_odm(uint32_t idx);
uint32_t fuse_get_bootrom_patch_version(void);
uint64_t fuse_get_device_id(void);
uint32_t fuse_get_dram_id(void);
uint32_t fuse_get_hardware_type(void);
uint32_t fuse_get_retail_type(void);
void fuse_get_hardware_info(void *dst);
#endif

75
ariane/src/hwinit/btn.c Normal file
View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "btn.h"
#include "gpio.h"
#include "pinmux.h"
#include "max7762x.h"
#include "max77620.h"
#include "timer.h"
u32 btn_read()
{
u32 res = 0;
if (!gpio_read(GPIO_BY_NAME(BUTTON_VOL_DOWN)))
res |= BTN_VOL_DOWN;
if (!gpio_read(GPIO_BY_NAME(BUTTON_VOL_UP)))
res |= BTN_VOL_UP;
if (max77620_recv_byte(MAX77620_REG_ONOFFSTAT) & 0x4)
res |= BTN_POWER;
return res;
}
u32 btn_wait()
{
u32 res = 0, btn = btn_read();
int pwr = 0;
//Power button down, raise a filter.
if (btn & BTN_POWER)
{
pwr = 1;
btn &= ~BTN_POWER;
}
do
{
res = btn_read();
//Power button up, remove filter.
if (!(res & BTN_POWER) && pwr)
pwr = 0;
else if (pwr) //Power button still down.
res &= ~BTN_POWER;
} while (btn == res);
return res;
}
u32 btn_wait_timeout(u32 time_ms)
{
u32 timeout = get_tmr_ms() + time_ms;
u32 res = btn_read();
u32 btn = res;
do
{
//Keep the new value until timeout is reached
if (btn == res)
res = btn_read();
} while (get_tmr_ms() < timeout);
return res;
}

30
ariane/src/hwinit/btn.h Normal file
View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _BTN_H_
#define _BTN_H_
#include "types.h"
#define BTN_POWER 0x1
#define BTN_VOL_DOWN 0x2
#define BTN_VOL_UP 0x4
u32 btn_read();
u32 btn_wait();
u32 btn_wait_timeout(u32 time_ms);
#endif

View file

@ -0,0 +1,381 @@
#include "carveout.h"
#include "t210.h"
#include "mc_t210.h"
#include "util.h"
#include "lib/printk.h"
static uintptr_t tz_base_mib = 0;
static const size_t tz_size_mib = TRUSTZONE_CARVEOUT_SIZE_MB;
/* returns total amount of DRAM (in MB) from memory controller registers */
int sdram_size_mb(void)
{
struct tegra_mc_regs *mc = (struct tegra_mc_regs *)MC_BASE;
static int total_size = 0;
if (total_size)
return total_size;
/*
* This obtains memory size from the External Memory Aperture
* Configuration register. Nvidia confirmed that it is safe to assume
* this value represents the total physical DRAM size.
*/
total_size = (mc->emem_cfg >> MC_EMEM_CFG_SIZE_MB_SHIFT) & MC_EMEM_CFG_SIZE_MB_MASK;
return total_size;
}
static void carveout_from_regs(uintptr_t *base_mib, size_t *size_mib,
uint32_t bom, uint32_t bom_hi, uint32_t size)
{
/* All size regs of carveouts are in MiB. */
if (size == 0)
return;
*size_mib = size;
bom >>= 20;
bom |= bom_hi << (32 - 20);
*base_mib = bom;
}
void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib)
{
*base_mib = 0;
*size_mib = 0;
struct tegra_mc_regs * const mc = (struct tegra_mc_regs *)MC_BASE;
size_t region_size_mb;
switch (id) {
case CARVEOUT_TZ:
*base_mib = tz_base_mib;
*size_mib = tz_size_mib;
break;
case CARVEOUT_SEC:
carveout_from_regs(base_mib, size_mib,
mc->sec_carveout_bom,
mc->sec_carveout_adr_hi,
mc->sec_carveout_size_mb);
break;
case CARVEOUT_MTS:
carveout_from_regs(base_mib, size_mib,
mc->mts_carveout_bom,
mc->mts_carveout_adr_hi,
mc->mts_carveout_size_mb);
break;
case CARVEOUT_VPR:
/*
* A 128MB VPR carveout is felt to be sufficient as per syseng.
* Set it up in vpr_region_init, below.
*/
carveout_from_regs(base_mib, size_mib,
mc->video_protect_bom,
mc->video_protect_bom_adr_hi,
mc->video_protect_size_mb);
break;
case CARVEOUT_GPU:
/* These carveout regs use 128KB granularity - convert to MB */
region_size_mb = DIV_ROUND_UP(mc->security_carveout2_size_128kb, 8);
/* BOM address set in gpu_region_init, below */
carveout_from_regs(base_mib, size_mib,
mc->security_carveout2_bom,
mc->security_carveout2_bom_hi,
region_size_mb);
break;
case CARVEOUT_NVDEC:
/* These carveout regs use 128KB granularity - convert to MB */
region_size_mb = DIV_ROUND_UP(mc->security_carveout1_size_128kb, 8);
/* BOM address set in nvdec_region_init, below */
carveout_from_regs(base_mib, size_mib,
mc->security_carveout1_bom,
mc->security_carveout1_bom_hi,
region_size_mb);
break;
case CARVEOUT_TSEC:
/* These carveout regs use 128KB granularity - convert to MB */
region_size_mb = DIV_ROUND_UP(mc->security_carveout4_size_128kb, 8);
/* BOM address set in tsec_region_init, below.
* Since the TSEC region consumes 2 carveouts, and is
* expected to be split evenly between the two, size_mib
* is doubled here.
*/
region_size_mb *= 2;
carveout_from_regs(base_mib, size_mib,
mc->security_carveout4_bom,
mc->security_carveout4_bom_hi,
region_size_mb);
break;
default:
break;
}
}
void print_carveouts(void)
{
#ifdef CARVEOUT_DEBUGGING
int i;
dbg_print("Carveout ranges:\n");
for (i = 0; i < CARVEOUT_NUM; i++) {
uintptr_t base, end;
size_t size;
carveout_range(i, &base, &size);
end = base + size;
if (end && base)
dbg_print("ID:%d [%lx - %lx)\n", i,
(unsigned long)base * 1024*1024,
(unsigned long)end * 1024*1024);
}
#endif
}
/*
* Memory Map is as follows
*
* ------------------------------ <-- Start of DRAM
* | |
* | Available DRAM |
* |____________________________|
* | |
* | CBMEM |
* |____________________________|
* | |
* | Other carveouts |
* | (with dynamic allocation) |
* |____________________________|
* | |
* | TZ carveout of size |
* | TRUSTZONE_CARVEOUT_SIZE_MB |
* |____________________________| <-- 0x100000000
* | |
* | Available DRAM |
* | |
* ------------------------------ <-- End of DRAM
*
*/
static void memory_in_range(uintptr_t *base_mib, uintptr_t *end_mib,
int ignore_carveout_id)
{
uintptr_t base;
uintptr_t end;
int i;
base = (uintptr_t)TEGRA_DRAM_START / (1024*1024);
end = base + sdram_size_mb();
#ifdef CARVEOUT_DEBUGGING
dbg_print("BASE: 0x%08x END: 0x%08x\n", base, end);
#endif
/* Requested limits out of range. */
if (*end_mib <= base || *base_mib >= end) {
*end_mib = *base_mib = 0;
return;
}
/* Clip region to passed in limits. */
if (*end_mib < end)
end = *end_mib;
if (*base_mib > base)
base = *base_mib;
for (i = 0; i < CARVEOUT_NUM; i++) {
uintptr_t carveout_base;
uintptr_t carveout_end;
size_t carveout_size;
if (i == ignore_carveout_id)
continue;
carveout_range(i, &carveout_base, &carveout_size);
if (carveout_size == 0)
continue;
carveout_end = carveout_base + carveout_size;
/* Bypass carveouts out of requested range. */
if (carveout_base >= end || carveout_end <= base)
continue;
/*
* This is crude, but the assumption is that carveouts live
* at the upper range of physical memory. Therefore, update
* the end address to be equal to the base of the carveout.
*/
end = carveout_base;
}
*base_mib = base;
*end_mib = end;
}
void memory_in_range_below_4gb(uintptr_t *base_mib, uintptr_t *end_mib)
{
*base_mib = 0;
*end_mib = 4096;
memory_in_range(base_mib, end_mib, CARVEOUT_NUM);
}
void memory_in_range_above_4gb(uintptr_t *base_mib, uintptr_t *end_mib)
{
*base_mib = 4096;
*end_mib = ~0UL;
memory_in_range(base_mib, end_mib, CARVEOUT_NUM);
}
void trustzone_region_init(void)
{
struct tegra_mc_regs * const mc = (void *)(uintptr_t)MC_BASE;
uintptr_t end = 4096;
/* Already has been initialized. */
if (tz_size_mib != 0 && tz_base_mib != 0)
return;
/*
* Get memory layout below 4GiB ignoring the TZ carveout because
* that's the one to initialize.
*/
tz_base_mib = end - tz_size_mib;
memory_in_range(&tz_base_mib, &end, CARVEOUT_TZ);
/*
* IMPORTANT!!!!!
* We need to ensure that trustzone region is located at the end of
* 32-bit address space. If any carveout is allocated space before
* trustzone_region_init is called, then this assert will ensure that
* the boot flow fails. If you are here because of this assert, please
* move your call to initialize carveout after trustzone_region_init in
* romstage and ramstage.
*/
if (end != 4096)
{
dbg_print("MC_CARVEOUT ERROR: end is %u instead of 4096!\n", end);
while (1) {}
}
/* AVP cannot set the TZ registers proper as it is always non-secure. */
if (running_on_bpmp())
{
#ifdef CARVEOUT_DEBUGGING
dbg_print("IN AVP CONTEXT, SKIPPIN, 0x%08x 0x%08x\n", (uint32_t)(tz_base_mib << 20), (uint32_t)(tz_size_mib));
#endif
return;
}
#ifdef CARVEOUT_DEBUGGING
else
dbg_print("NOT IN AVP CONTEXT, TZ: 0x%08x 0x%08x\n", (uint32_t)(tz_base_mib) << 20, (uint32_t)(tz_size_mib));
#endif
/* Set the carveout region. */
mc->security_cfg0 = tz_base_mib << 20;
mc->security_cfg1 = tz_size_mib;
/* Enable SMMU translations */
mc->smmu_config = MC_SMMU_CONFIG_ENABLE;
}
void gpu_region_init(void)
{
struct tegra_mc_regs * const mc = (void *)(uintptr_t)MC_BASE;
uintptr_t gpu_base_mib = 0, end = 4096;
size_t gpu_size_mib = GPU_CARVEOUT_SIZE_MB;
/* Get memory layout below 4GiB */
memory_in_range(&gpu_base_mib, &end, CARVEOUT_GPU);
gpu_base_mib = end - gpu_size_mib;
/* Set the carveout2 base address. Everything else has been set in the BCT cfg/inc */
mc->security_carveout2_bom = gpu_base_mib << 20;
mc->security_carveout2_bom_hi = 0;
/* Set the locked bit. This will lock out any other writes! */
mc->security_carveout2_cfg0 |= MC_SECURITY_CARVEOUT_LOCKED;
/* Set the carveout3 base to 0, unused */
mc->security_carveout3_bom = 0;
mc->security_carveout3_bom_hi = 0;
#ifdef CARVEOUT_DEBUGGING
dbg_print("GPU_REGION INIT: 0x%08x 0x%08x\n", (uint32_t)(gpu_base_mib << 20), (uint32_t)(gpu_size_mib));
#endif
/* Set the locked bit. This will lock out any other writes! */
//mc->security_carveout3_cfg0 = MC_SECURITY_CARVEOUT_LOCKED;
}
void nvdec_region_init(void)
{
struct tegra_mc_regs * const mc = (void *)(uintptr_t)MC_BASE;
uintptr_t nvdec_base_mib = 0, end = 4096;
size_t nvdec_size_mib = NVDEC_CARVEOUT_SIZE_MB;
/* Get memory layout below 4GiB */
memory_in_range(&nvdec_base_mib, &end, CARVEOUT_NVDEC);
nvdec_base_mib = end - nvdec_size_mib;
/* Set the carveout1 base address. Everything else has been set in the BCT cfg/inc */
mc->security_carveout1_bom = nvdec_base_mib << 20;
mc->security_carveout1_bom_hi = 0;
#ifdef CARVEOUT_DEBUGGING
dbg_print("NVDEC_REGION INIT: 0x%08x 0x%08x\n", (uint32_t)(nvdec_base_mib << 20), (uint32_t)(nvdec_size_mib));
#endif
/* Set the locked bit. This will lock out any other writes! */
//mc->security_carveout1_cfg0 |= MC_SECURITY_CARVEOUT_LOCKED;
}
void tsec_region_init(void)
{
struct tegra_mc_regs * const mc = (void *)(uintptr_t)MC_BASE;
uintptr_t tsec_base_mib = 0, end = 4096;
size_t tsec_size_mib = TSEC_CARVEOUT_SIZE_MB;
/* Get memory layout below 4GiB */
memory_in_range(&tsec_base_mib, &end, CARVEOUT_TSEC);
tsec_base_mib = end - tsec_size_mib;
/*
* Set the carveout4/5 base address. Everything else has been set in the BCT cfg/inc
* Note that the TSEC range is split evenly between the 2 carveouts (i.e. 1MB each)
*/
mc->security_carveout4_bom = tsec_base_mib << 20;
mc->security_carveout4_bom_hi = 0;
mc->security_carveout5_bom = (tsec_base_mib + (TSEC_CARVEOUT_SIZE_MB / 2)) << 20;
mc->security_carveout5_bom_hi = 0;
#ifdef CARVEOUT_DEBUGGING
dbg_print("TSEC_REGION INIT: 0x%08x 0x%08x\n", (uint32_t)(tsec_base_mib << 20), (uint32_t)(tsec_size_mib));
#endif
/* Set the locked bit. This will lock out any other writes! */
mc->security_carveout4_cfg0 |= MC_SECURITY_CARVEOUT_LOCKED;
mc->security_carveout5_cfg0 |= MC_SECURITY_CARVEOUT_LOCKED;
}
void vpr_region_init(void)
{
struct tegra_mc_regs * const mc = (void *)(uintptr_t)MC_BASE;
uintptr_t vpr_base_mib = 0, end = 4096;
size_t vpr_size_mib = VPR_CARVEOUT_SIZE_MB;
/* Get memory layout below 4GiB */
memory_in_range(&vpr_base_mib, &end, CARVEOUT_VPR);
vpr_base_mib = end - vpr_size_mib;
/* Set the carveout base address and size */
mc->video_protect_bom = vpr_base_mib << 20;
mc->video_protect_bom_adr_hi = 0;
mc->video_protect_size_mb = vpr_size_mib;
#ifdef CARVEOUT_DEBUGGING
dbg_print("VPR_REGION INIT: 0x%08x 0x%08x\n", (uint32_t)(vpr_base_mib << 20), (uint32_t)(vpr_size_mib));
#endif
/* Set the locked bit. This will lock out any other writes! */
//mc->video_protect_reg_ctrl = MC_VPR_WR_ACCESS_DISABLE;
}

View file

@ -0,0 +1,50 @@
#ifndef _CARVEOUT_H_
#define _CARVEOUT_H_
#include <stdint.h>
#include <stdlib.h>
#define GPU_CARVEOUT_SIZE_MB 1
#define NVDEC_CARVEOUT_SIZE_MB 1
#define TSEC_CARVEOUT_SIZE_MB 2
#define VPR_CARVEOUT_SIZE_MB 128
#define TRUSTZONE_CARVEOUT_SIZE_MB 0x14
#define TEGRA_DRAM_START 0x80000000
/* Return total size of DRAM memory configured on the platform. */
int sdram_size_mb(void);
/* Find memory below and above 4GiB boundary repsectively. All units 1MiB. */
void memory_in_range_below_4gb(uintptr_t *base_mib, uintptr_t *end_mib);
void memory_in_range_above_4gb(uintptr_t *base_mib, uintptr_t *end_mib);
enum {
CARVEOUT_TZ,
CARVEOUT_SEC,
CARVEOUT_MTS,
CARVEOUT_VPR,
CARVEOUT_GPU,
CARVEOUT_NVDEC,
CARVEOUT_TSEC,
CARVEOUT_NUM,
};
/* Provided the careout id, obtain the base and size in 1MiB units. */
void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib);
void print_carveouts(void);
/*
* There are complications accessing the Trust Zone carveout region. The
* AVP cannot access these registers and the CPU can't access this register
* as a non-secure access. When the page tables live in non-secure memory
* these registers cannot be accessed either. Thus, this function handles
* both the AVP case and non-secured access case by keeping global state.
*/
void trustzone_region_init(void);
void gpu_region_init(void);
void nvdec_region_init(void);
void tsec_region_init(void);
void vpr_region_init(void);
#endif

435
ariane/src/hwinit/clock.c Normal file
View file

@ -0,0 +1,435 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clock.h"
#include "t210.h"
#include "timer.h"
#include "sdmmc.h"
#include "flow.h"
static const clock_t _clock_uart[] = {
/* UART A */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, 6 , 0, 0 },
/* UART B */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, 7 , 0, 0 },
/* UART C */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, 23, 0, 0 },
/* UART D */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, 1 , 0, 0 },
/* UART E */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, 0, 2, 0, 0 }
};
static const clock_t _clock_i2c[] = {
/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 12, 6, 0 },
/* I2C2 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, 22, 6, 0 },
/* I2C3 */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, 3, 6, 0 },
/* I2C4 */ { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, 7, 6, 0 },
/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 15, 6, 0 },
/* I2C6 */ { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, 6 , 6, 0 },
};
static clock_t _clock_se = { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, 31, 0, 0 };
static clock_t _clock_host1x = { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, 28, 4, 3 };
static clock_t _clock_tsec = { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, 19, 0, 2 };
static clock_t _clock_sor_safe = { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, 0, 30, 0, 0 };
static clock_t _clock_sor0 = { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, 0, 22, 0, 0 }; //no CLK_RST_CONTROLLER_CLK_SOURCE_SOR0 on this one ?
static clock_t _clock_sor1 = { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, 23, 0, 2 };
static clock_t _clock_kfuse = { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, 0, 8, 0, 0 };
static clock_t _clock_cl_dvfs = { CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, 0, 27, 0, 0 };
static clock_t _clock_coresight = { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, 9, 0, 4};
void clock_enable(const clock_t *clk)
{
//Put clock into reset.
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);
//Disable.
CLOCK(clk->enable) &= ~(1 << clk->index);
//Configure clock source if required.
if (clk->source)
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
//Enable.
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index);
//Take clock off reset.
CLOCK(clk->reset) &= ~(1 << clk->index);
}
void clock_disable(const clock_t *clk)
{
//Put clock into reset.
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);
//Disable.
CLOCK(clk->enable) &= ~(1 << clk->index);
}
void clock_enable_fuse(u32 enable)
{
static const u32 FUSE_ENABLE_BIT = 1u << 28;
if (enable)
CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) |= FUSE_ENABLE_BIT;
else
CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) &= ~FUSE_ENABLE_BIT;
}
void clock_enable_uart(u32 idx)
{
clock_enable(&_clock_uart[idx]);
}
void clock_enable_i2c(u32 idx)
{
clock_enable(&_clock_i2c[idx]);
}
void clock_enable_se()
{
clock_enable(&_clock_se);
}
void clock_enable_host1x()
{
clock_enable(&_clock_host1x);
}
void clock_disable_host1x()
{
clock_disable(&_clock_host1x);
}
void clock_enable_tsec()
{
clock_enable(&_clock_tsec);
}
void clock_disable_tsec()
{
clock_disable(&_clock_tsec);
}
void clock_enable_sor_safe()
{
clock_enable(&_clock_sor_safe);
}
void clock_disable_sor_safe()
{
clock_disable(&_clock_sor_safe);
}
void clock_enable_sor0()
{
clock_enable(&_clock_sor0);
}
void clock_disable_sor0()
{
clock_disable(&_clock_sor0);
}
void clock_enable_sor1()
{
clock_enable(&_clock_sor1);
}
void clock_disable_sor1()
{
clock_disable(&_clock_sor1);
}
void clock_enable_kfuse()
{
//clock_enable(&_clock_kfuse);
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) |= CLK_H_KFUSE;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) &= ~CLK_H_KFUSE;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) |= CLK_H_KFUSE;
usleep(10);
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= ~CLK_H_KFUSE;
usleep(20);
}
void clock_disable_kfuse()
{
clock_disable(&_clock_kfuse);
}
void clock_enable_cl_dvfs()
{
clock_enable(&_clock_cl_dvfs);
}
void clock_enable_coresight()
{
clock_enable(&_clock_coresight);
}
static int _clock_sdmmc_is_reset(u32 id)
{
switch (id)
{
case SDMMC_1:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & CLK_L_SDMMC1;
case SDMMC_2:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & CLK_L_SDMMC2;
case SDMMC_3:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & CLK_U_SDMMC3;
case SDMMC_4:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & CLK_L_SDMMC4;
}
return 0;
}
static void _clock_sdmmc_set_reset(u32 id)
{
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = CLK_L_SDMMC1;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = CLK_L_SDMMC2;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = CLK_U_SDMMC3;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = CLK_L_SDMMC4;
}
}
static void _clock_sdmmc_clear_reset(u32 id)
{
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = CLK_L_SDMMC1;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = CLK_L_SDMMC2;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = CLK_U_SDMMC3;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = CLK_L_SDMMC4;
}
}
static int _clock_sdmmc_is_enabled(u32 id)
{
switch (id)
{
case SDMMC_1:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & CLK_L_SDMMC1;
case SDMMC_2:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & CLK_L_SDMMC2;
case SDMMC_3:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & CLK_U_SDMMC3;
case SDMMC_4:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & CLK_L_SDMMC4;
}
return 0;
}
static void _clock_sdmmc_set_enable(u32 id)
{
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = CLK_L_SDMMC1;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = CLK_L_SDMMC2;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = CLK_U_SDMMC3;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = CLK_L_SDMMC4;
}
}
static void _clock_sdmmc_clear_enable(u32 id)
{
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = CLK_L_SDMMC1;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = CLK_L_SDMMC2;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = CLK_U_SDMMC3;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = CLK_L_SDMMC4;
}
}
static u32 _clock_sdmmc_table[8] = { 0 };
static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
{
u32 divisor = 0;
u32 source = 0;
switch (val)
{
case 25000:
*pout = 24728;
divisor = 31;
break;
case 26000:
*pout = 25500;
divisor = 30;
break;
case 40800:
*pout = 40800;
divisor = 18;
break;
case 50000:
*pout = 48000;
divisor = 15;
break;
case 52000:
*pout = 51000;
divisor = 14;
break;
case 100000:
*pout = 90667;
divisor = 7;
break;
case 200000:
*pout = 163200;
divisor = 3;
break;
case 208000:
*pout = 204000;
divisor = 2;
break;
default:
return 0;
}
_clock_sdmmc_table[2 * id] = val;
_clock_sdmmc_table[2 * id + 1] = *pout;
switch (id)
{
case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = source | divisor;
break;
case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = source | divisor;
break;
case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = source | divisor;
break;
case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = source | divisor;
break;
}
return 1;
}
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val)
{
if (_clock_sdmmc_table[2 * id] == val)
{
*pout = _clock_sdmmc_table[2 * id + 1];
}
else
{
int is_enabled = _clock_sdmmc_is_enabled(id);
if (is_enabled)
_clock_sdmmc_clear_enable(id);
_clock_sdmmc_config_clock_source_inner(pout, id, val);
if (is_enabled)
_clock_sdmmc_set_enable(id);
_clock_sdmmc_is_reset(id);
}
}
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type)
{
switch (type)
{
case 0:
*pout = 26000;
*pdivisor = 66;
break;
case 1:
*pout = 26000;
*pdivisor = 1;
break;
case 2:
*pout = 52000;
*pdivisor = 1;
break;
case 3:
case 4:
case 11:
*pout = 200000;
*pdivisor = 1;
break;
case 5:
*pout = 25000;
*pdivisor = 64;
case 6:
case 8:
*pout = 25000;
*pdivisor = 1;
break;
case 7:
*pout = 50000;
*pdivisor = 1;
case 10:
*pout = 100000;
*pdivisor = 1;
case 13:
*pout = 40800;
*pdivisor = 1;
break;
case 14:
*pout = 200000;
*pdivisor = 2;
break;
}
}
int clock_sdmmc_is_not_reset_and_enabled(u32 id)
{
return !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);
}
void clock_sdmmc_enable(u32 id, u32 val)
{
u32 div = 0;
if (_clock_sdmmc_is_enabled(id))
_clock_sdmmc_clear_enable(id);
_clock_sdmmc_set_reset(id);
_clock_sdmmc_config_clock_source_inner(&div, id, val);
_clock_sdmmc_set_enable(id);
_clock_sdmmc_is_reset(id);
usleep((100000 + div - 1) / div);
_clock_sdmmc_clear_reset(id);
_clock_sdmmc_is_reset(id);
}
void clock_sdmmc_disable(u32 id)
{
_clock_sdmmc_set_reset(id);
_clock_sdmmc_clear_enable(id);
_clock_sdmmc_is_reset(id);
}
void clock_halt_bpmp(void)
{
static struct flow_ctlr *flow = (void *)FLOW_CTLR_BASE;
for (;;)
{
flow->halt_cop_events = FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ | FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT;
}
}

490
ariane/src/hwinit/clock.h Normal file
View file

@ -0,0 +1,490 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CLOCK_H_
#define _CLOCK_H_
#include "types.h"
/*! Clock registers. */
#define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4
#define CLK_RST_CONTROLLER_RST_DEVICES_H 0x8
#define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18
#define CLK_RST_CONTROLLER_CCLK_BURST_POLICY 0x20
#define CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER 0x24
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28
#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30
#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48
#define CLK_RST_CONTROLLER_OSC_CTRL 0x50
#define CLK_RST_CONTROLLER_PLLM_BASE 0x90
#define CLK_RST_CONTROLLER_PLLM_OUT 0x94
#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9c
#define CLK_RST_CONTROLLER_PLLD_BASE 0xD0
#define CLK_RST_CONTROLLER_PLLD_MISC1 0xD8
#define CLK_RST_CONTROLLER_PLLD_MISC 0xDC
#define CLK_RST_CONTROLLER_PLLX_BASE 0xE0
#define CLK_RST_CONTROLLER_PLLX_MISC 0xE4
#define CLK_RST_CONTROLLER_PLLE_BASE 0xE8
#define CLK_RST_CONTROLLER_PLLE_MISC 0xEC
#define CLK_RST_CONTROLLER_PLLE_SS_CNTL1 0xF0
#define CLK_RST_CONTROLLER_PLLE_SS_CNTL2 0xF4
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA 0xF8
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB 0xFC
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC 0x3A0
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE 0x554
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S2 0x100
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S3 0x104
#define CLK_RST_CONTROLLER_CLK_SOURCE_SPDIF_OUT 0x108
#define CLK_RST_CONTROLLER_CLK_SOURCE_SPDIF_IN 0x10C
#define CLK_RST_CONTROLLER_CLK_SOURCE_PWM 0x110
#define CLK_RST_CONTROLLER_CLK_SOURCE_SPI2 0x118
#define CLK_RST_CONTROLLER_CLK_SOURCE_SPI3 0x11C
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 0x124
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5 0x128
#define CLK_RST_CONTROLLER_CLK_SOURCE_SPI1 0x134
#define CLK_RST_CONTROLLER_CLK_SOURCE_DISP1 0x138
#define CLK_RST_CONTROLLER_CLK_SOURCE_DISP2 0x13C
#define CLK_RST_CONTROLLER_CLK_SOURCE_ISP 0x144
#define CLK_RST_CONTROLLER_CLK_SOURCE_VI 0x148
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 0x150
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 0x154
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 0x164
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA 0x178
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB 0x17C
#define CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X 0x180
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C2 0x198
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC 0x1A0
#define CLK_RST_CONTROLLER_CLK_SOURCE_VI_SENSOR 0x1A8
#define CLK_RST_CONTROLLER_CLK_SOURCE_SPI4 0x1B4
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 0x1B8
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 0x1BC
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTD 0x1C0
#define CLK_RST_CONTROLLER_CLK_SOURCE_OWR 0x1CC
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE 0x1D4
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S1 0x1D8
#define CLK_RST_CONTROLLER_CLK_SOURCE_DTV 0x1DC
#define CLK_RST_CONTROLLER_CLK_SOURCE_TSEC 0x1F4
#define CLK_RST_CONTROLLER_CLK_SPARE2 0x1FC
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X 0x280
#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284
#define CLK_RST_CONTROLLER_CLK_ENB_X_CLR 0x288
#define CLK_RST_CONTROLLER_RST_DEVICES_X 0x28C
#define CLK_RST_CONTROLLER_RST_DEV_X_SET 0x290
#define CLK_RST_CONTROLLER_RST_DEV_X_CLR 0x294
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_Y 0x298
#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET 0x29C
#define CLK_RST_CONTROLLER_CLK_ENB_Y_CLR 0x2A0
#define CLK_RST_CONTROLLER_RST_DEVICES_Y 0x2A4
#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2A8
#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2AC
#define CLK_RST_CONTROLLER_DFLL_BASE 0x2F4
#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304
#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308
#define CLK_RST_CONTROLLER_RST_DEV_H_CLR 0x30C
#define CLK_RST_CONTROLLER_RST_DEV_U_SET 0x310
#define CLK_RST_CONTROLLER_RST_DEV_U_CLR 0x314
#define CLK_RST_CONTROLLER_CLK_ENB_L_SET 0x320
#define CLK_RST_CONTROLLER_CLK_ENB_L_CLR 0x324
#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328
#define CLK_RST_CONTROLLER_CLK_ENB_H_CLR 0x32C
#define CLK_RST_CONTROLLER_CLK_ENB_U_SET 0x330
#define CLK_RST_CONTROLLER_CLK_ENB_U_CLR 0x334
#define CLK_RST_CONTROLLER_CCPLEX_PG_SM_OVRD 0x33C
#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340
#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358
#define CLK_RST_CONTROLLER_RST_DEVICES_W 0x35C
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_V 0x360
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W 0x364
#define CLK_RST_CONTROLLER_CCLKG_BURST_POLICY 0x368
#define CLK_RST_CONTROLLER_SUPER_CCLKG_DIVIDER 0x36C
#define CLK_RST_CONTROLLER_CCLKLP_BURST_POLICY 0x370
#define CLK_RST_CONTROLLER_SUPER_CCLKLP_DIVIDER 0x374
#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL 0x380
#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL1 0x384
#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 0x388
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
#define CLK_RST_CONTROLLER_CLK_SOURCE_TSENSOR 0x3B8
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S4 0x3BC
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S5 0x3C0
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 0x3C4
#define CLK_RST_CONTROLLER_CLK_SOURCE_AHUB 0x3D0
#define CLK_RST_CONTROLLER_CLK_SOURCE_HDA2CODEC_2X 0x3E4
#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON 0x3E8
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1 0x3EC
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2 0x3F0
#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH3 0x3F4
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C_SLOW 0x3FC
#define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400
#define CLK_RST_CONTROLLER_CLK_SOURCE_ISPB 0x404
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR0 0x414
#define CLK_RST_CONTROLLER_CLK_SOURCE_HDA 0x428
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
#define CLK_RST_CONTROLLER_RST_DEV_V_CLR 0x434
#define CLK_RST_CONTROLLER_RST_DEV_W_SET 0x438
#define CLK_RST_CONTROLLER_RST_DEV_W_CLR 0x43C
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440
#define CLK_RST_CONTROLLER_CLK_ENB_V_CLR 0x444
#define CLK_RST_CONTROLLER_CLK_ENB_W_SET 0x448
#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR 0x44C
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454
#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518
#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_HOST 0x600
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FALCON 0x604
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS 0x608
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV 0x60C
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS 0x610
#define CLK_RST_CONTROLLER_CLK_SOURCE_CILAB 0x614
#define CLK_RST_CONTROLLER_CLK_SOURCE_CILCD 0x618
#define CLK_RST_CONTROLLER_CLK_SOURCE_CILEF 0x61C
#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620
#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIB_LP 0x624
#define CLK_RST_CONTROLLER_CLK_SOURCE_ENTROPY 0x628
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF 0x62C
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC 0x630
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_LATENCY 0x640
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOC_THERM 0x644
#define CLK_RST_CONTROLLER_CLK_SOURCE_DMIC1 0x64C
#define CLK_RST_CONTROLLER_CLK_SOURCE_DMIC2 0x650
#define CLK_RST_CONTROLLER_CLK_SOURCE_VI_SENSOR2 0x658
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C
#define CLK_RST_CONTROLLER_CLK_SOURCE_MIPIBIF 0x660
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C
#define CLK_RST_CONTROLLER_CLK_SOURCE_VIC 0x678
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC 0x698
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG 0x69C
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0
#define CLK_RST_CONTROLLER_PLLA1_BASE 0x6A4
#define CLK_RST_CONTROLLER_PLLA1_MISC_0 0x6A8
#define CLK_RST_CONTROLLER_PLLA1_MISC_1 0x6AC
#define CLK_RST_CONTROLLER_PLLA1_MISC_2 0x6B0
#define CLK_RST_CONTROLLER_PLLA1_MISC_3 0x6B4
#define CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_DMIC3 0x6B8
#define CLK_RST_CONTROLLER_CLK_SOURCE_DMIC3 0x6BC
#define CLK_RST_CONTROLLER_CLK_SOURCE_APE 0x6C0
#define CLK_RST_CONTROLLER_CLK_SOURCE_QSPI 0x6C4
#define CLK_RST_CONTROLLER_CLK_SOURCE_VI_I2C 0x6C8
#define CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK 0x6CC
#define CLK_RST_CONTROLLER_CLK_SOURCE_PEX_SATA_USB_RX_BYP 0x6D0
#define CLK_RST_CONTROLLER_CLK_SOURCE_MAUD 0x6D4
#define CLK_RST_CONTROLLER_CLK_SOURCE_TSECB 0x6D8
#define CLK_RST_CONTROLLER_CLK_CPUG_MISC1 0x6DC
enum {
CLK_L_CPU = 0x1 << 0,
CLK_L_COP = 0x1 << 1,
CLK_L_TRIG_SYS = 0x1 << 2,
CLK_L_RTC = 0x1 << 4,
CLK_L_TMR = 0x1 << 5,
CLK_L_UARTA = 0x1 << 6,
CLK_L_UARTB = 0x1 << 7,
CLK_L_GPIO = 0x1 << 8,
CLK_L_SDMMC2 = 0x1 << 9,
CLK_L_SPDIF = 0x1 << 10,
CLK_L_I2S2 = 0x1 << 11,
CLK_L_I2C1 = 0x1 << 12,
CLK_L_NDFLASH = 0x1 << 13,
CLK_L_SDMMC1 = 0x1 << 14,
CLK_L_SDMMC4 = 0x1 << 15,
CLK_L_PWM = 0x1 << 17,
CLK_L_I2S3 = 0x1 << 18,
CLK_L_EPP = 0x1 << 19,
CLK_L_VI = 0x1 << 20,
CLK_L_2D = 0x1 << 21,
CLK_L_USBD = 0x1 << 22,
CLK_L_ISP = 0x1 << 23,
CLK_L_3D = 0x1 << 24,
CLK_L_DISP2 = 0x1 << 26,
CLK_L_DISP1 = 0x1 << 27,
CLK_L_HOST1X = 0x1 << 28,
CLK_L_VCP = 0x1 << 29,
CLK_L_I2S1 = 0x1 << 30,
CLK_L_CACHE2 = 0x1 << 31,
CLK_H_MEM = 0x1 << 0,
CLK_H_AHBDMA = 0x1 << 1,
CLK_H_APBDMA = 0x1 << 2,
CLK_H_KBC = 0x1 << 4,
CLK_H_STAT_MON = 0x1 << 5,
CLK_H_PMC = 0x1 << 6,
CLK_H_FUSE = 0x1 << 7,
CLK_H_KFUSE = 0x1 << 8,
CLK_H_SBC1 = 0x1 << 9,
CLK_H_SNOR = 0x1 << 10,
CLK_H_JTAG2TBC = 0x1 << 11,
CLK_H_SBC2 = 0x1 << 12,
CLK_H_SBC3 = 0x1 << 14,
CLK_H_I2C5 = 0x1 << 15,
CLK_H_DSI = 0x1 << 16,
CLK_H_HSI = 0x1 << 18,
CLK_H_HDMI = 0x1 << 19,
CLK_H_CSI = 0x1 << 20,
CLK_H_I2C2 = 0x1 << 22,
CLK_H_UARTC = 0x1 << 23,
CLK_H_MIPI_CAL = 0x1 << 24,
CLK_H_EMC = 0x1 << 25,
CLK_H_USB2 = 0x1 << 26,
CLK_H_USB3 = 0x1 << 27,
CLK_H_MPE = 0x1 << 28,
CLK_H_VDE = 0x1 << 29,
CLK_H_BSEA = 0x1 << 30,
CLK_H_BSEV = 0x1 << 31,
CLK_U_UARTD = 0x1 << 1,
CLK_U_UARTE = 0x1 << 2,
CLK_U_I2C3 = 0x1 << 3,
CLK_U_SBC4 = 0x1 << 4,
CLK_U_SDMMC3 = 0x1 << 5,
CLK_U_PCIE = 0x1 << 6,
CLK_U_OWR = 0x1 << 7,
CLK_U_AFI = 0x1 << 8,
CLK_U_CSITE = 0x1 << 9,
CLK_U_PCIEXCLK = 0x1 << 10,
CLK_U_AVPUCQ = 0x1 << 11,
CLK_U_TRACECLKIN = 0x1 << 13,
CLK_U_SOC_THERM = 0x1 << 14,
CLK_U_DTV = 0x1 << 15,
CLK_U_NAND_SPEED = 0x1 << 16,
CLK_U_I2C_SLOW = 0x1 << 17,
CLK_U_DSIB = 0x1 << 18,
CLK_U_TSEC = 0x1 << 19,
CLK_U_IRAMA = 0x1 << 20,
CLK_U_IRAMB = 0x1 << 21,
CLK_U_IRAMC = 0x1 << 22,
// Clock reset.
CLK_U_EMUCIF = 0x1 << 23,
// Clock enable.
CLK_U_IRAMD = 0x1 << 23,
CLK_U_CRAM2 = 0x2 << 24,
CLK_U_XUSB_HOST = 0x1 << 25,
CLK_U_MSENC = 0x1 << 27,
CLK_U_SUS_OUT = 0x1 << 28,
CLK_U_DEV2_OUT = 0x1 << 29,
CLK_U_DEV1_OUT = 0x1 << 30,
CLK_U_XUSB_DEV = 0x1 << 31,
CLK_V_CPUG = 0x1 << 0,
CLK_V_CPULP = 0x1 << 1,
CLK_V_3D2 = 0x1 << 2,
CLK_V_MSELECT = 0x1 << 3,
CLK_V_I2S4 = 0x1 << 5,
CLK_V_I2S5 = 0x1 << 6,
CLK_V_I2C4 = 0x1 << 7,
CLK_V_SBC5 = 0x1 << 8,
CLK_V_SBC6 = 0x1 << 9,
CLK_V_AHUB = 0x1 << 10,
CLK_V_APB2APE = 0x1 << 11,
CLK_V_HDA2CODEC_2X = 0x1 << 15,
CLK_V_ATOMICS = 0x1 << 16,
CLK_V_SPDIF_DOUBLER = 0x1 << 22,
CLK_V_ACTMON = 0x1 << 23,
CLK_V_EXTPERIPH1 = 0x1 << 24,
CLK_V_SATA = 0x1 << 28,
CLK_V_HDA = 0x1 << 29,
CLK_W_HDA2HDMICODEC = 0x1 << 0,
CLK_W_SATACOLD = 0x1 << 1,
CLK_W_PCIERX0 = 0x1 << 2,
CLK_W_PCIERX1 = 0x1 << 3,
CLK_W_PCIERX2 = 0x1 << 4,
CLK_W_PCIERX3 = 0x1 << 5,
CLK_W_PCIERX4 = 0x1 << 6,
CLK_W_PCIERX5 = 0x1 << 7,
CLK_W_CEC = 0x1 << 8,
CLK_W_PCIE2_IOBIST = 0x1 << 9,
CLK_W_EMC_IOBIST = 0x1 << 10,
CLK_W_SATA_IOBIST = 0x1 << 12,
CLK_W_MIPI_IOBIST = 0x1 << 13,
CLK_W_XUSB_PADCTL = 0x1 << 14,
CLK_W_XUSB = 0x1 << 15,
CLK_W_CILAB = 0x1 << 16,
CLK_W_CILCD = 0x1 << 17,
CLK_W_CILEF = 0x1 << 18,
CLK_W_DSIA_LP = 0x1 << 19,
CLK_W_DSIB_LP = 0x1 << 20,
CLK_W_ENTROPY = 0x1 << 21,
CLK_W_DVFS = 0x1 << 27,
CLK_W_XUSB_SS = 0x1 << 28,
CLK_W_EMC_LATENCY = 0x1 << 29,
CLK_W_MC1 = 0x1 << 30,
CLK_X_SPARE = 0x1 << 0,
CLK_X_DMIC1 = 0x1 << 1,
CLK_X_DMIC2 = 0x1 << 2,
CLK_X_ETR = 0x1 << 3,
CLK_X_CAM_MCLK = 0x1 << 4,
CLK_X_CAM_MCLK2 = 0x1 << 5,
CLK_X_I2C6 = 0x1 << 6,
CLK_X_MC_CAPA = 0x1 << 7,
CLK_X_MC_CBPA = 0x1 << 8,
CLK_X_MC_CPU = 0x1 << 9,
CLK_X_MC_BBC = 0x1 << 10,
CLK_X_VIM2_CLK = 0x1 << 11,
CLK_X_MIPIBIF = 0x1 << 13,
CLK_X_EMC_DLL = 0x1 << 14,
CLK_X_UART_FST_MIPI_CAL = 0x1 << 17,
CLK_X_VIC = 0x1 << 18,
CLK_X_DPAUX = 0x1 << 21,
CLK_X_SOR0 = 0x1 << 22,
CLK_X_SOR1 = 0x1 << 23,
CLK_X_GPU = 0x1 << 24,
CLK_X_DPGAPB = 0x1 << 25,
CLK_X_HPLL_ADSP = 0x1 << 26,
CLK_X_PLLP_ADSP = 0x1 << 27,
CLK_X_PLLA_ADSP = 0x1 << 28,
CLK_X_PLLG_REF = 0x1 << 29,
CLK_Y_SPARE1 = 0x1 << 0,
CLK_Y_SDMMC_LEGACY_TM = 0x1 << 1,
CLK_Y_NVDEC = 0x1 << 2,
CLK_Y_NVJPG = 0x1 << 3,
CLK_Y_AXIAP = 0x1 << 4,
CLK_Y_DMIC3 = 0x1 << 5,
CLK_Y_APE = 0x1 << 6,
CLK_Y_ADSP = 0x1 << 7,
CLK_Y_MC_CDPA = 0x1 << 8,
CLK_Y_MC_CCPA = 0x1 << 9,
CLK_Y_MAUD = 0x1 << 10,
CLK_Y_TSECB = 0x1 << 14,
CLK_Y_DPAUX1 = 0x1 << 15,
CLK_Y_VI_I2C = 0x1 << 16,
CLK_Y_HSIC_TRK = 0x1 << 17,
CLK_Y_USB2_TRK = 0x1 << 18,
CLK_Y_QSPI = 0x1 << 19,
CLK_Y_UARTAPE = 0x1 << 20,
CLK_Y_ADSPNEON = 0x1 << 26,
CLK_Y_NVENC = 0x1 << 27,
CLK_Y_IQC2 = 0x1 << 28,
CLK_Y_IQC1 = 0x1 << 29,
CLK_Y_SOR_SAFE = 0x1 << 30,
CLK_Y_PLLP_OUT_CPU = 0x1 << 31
};
/* PLLM specific registers */
#define PLLM_MISC1_SETUP_SHIFT 0
#define PLLM_MISC1_PD_LSHIFT_PH45_SHIFT 28
#define PLLM_MISC1_PD_LSHIFT_PH90_SHIFT 29
#define PLLM_MISC1_PD_LSHIFT_PH135_SHIFT 30
#define PLLM_MISC2_KCP_SHIFT 1
#define PLLM_MISC2_KVCO_SHIFT 0
#define PLLM_OUT1_RSTN_RESET_DISABLE (1 << 0)
#define PLLM_EN_LCKDET (1 << 4)
/* CLK_RST_CONTROLLER_PLL*_BASE_0 */
#define PLL_BASE_BYPASS (1U << 31)
#define PLL_BASE_ENABLE (1U << 30)
#define PLL_BASE_REF_DIS (1U << 29)
#define PLL_BASE_OVRRIDE (1U << 28)
#define PLL_BASE_LOCK (1U << 27)
#define PLLC_BASE_LOCK (1U << 26)
#define PLL_BASE_DIVP_SHIFT 20
#define PLL_BASE_DIVP_MASK (7U << PLL_BASE_DIVP_SHIFT)
#define PLL_BASE_DIVN_SHIFT 8
#define PLL_BASE_DIVN_MASK (0x3ffU << PLL_BASE_DIVN_SHIFT)
#define PLL_BASE_DIVM_SHIFT 0
#define PLL_BASE_DIVM_MASK (0x1f << PLL_BASE_DIVM_SHIFT)
/* SPECIAL CASE: PLLM, PLLC and PLLX use different-sized fields here */
#define PLLCX_BASE_DIVP_MASK (0xfU << PLL_BASE_DIVP_SHIFT)
#define PLLM_BASE_DIVP_MASK (0x1fU << PLL_BASE_DIVP_SHIFT)
#define PLLCMX_BASE_DIVN_MASK (0xffU << PLL_BASE_DIVN_SHIFT)
#define PLLCMX_BASE_DIVM_MASK (0xffU << PLL_BASE_DIVM_SHIFT)
#define PLLX_IDDQ_SHIFT 3
#define PLLX_IDDQ_MASK (1U << PLLX_IDDQ_SHIFT)
#define CLK_DIVISOR_MASK (0xffff)
#define CLK_SOURCE_SHIFT 29
#define CLK_SOURCE_MASK (0x7 << CLK_SOURCE_SHIFT)
#define CLK_SOURCE_EMC_MC_EMC_SAME_FREQ (1 << 16)
#define EMC_2X_CLK_SRC_SHIFT 29
#define PLLM_UD 4
/* PLL stabilization delay in usec */
#define CLOCK_PLL_STABLE_DELAY_US 300
#define IO_STABILIZATION_DELAY (2)
#define LOGIC_STABILIZATION_DELAY (2)
/* Bits to enable/reset modules */
#define CLK_ENB_CPU (1 << 0)
#define SWR_TRIG_SYS_RST (1 << 2)
#define SWR_CSITE_RST (1 << 9)
#define CLK_ENB_CSITE (1 << 9)
#define CLK_ENB_EMC_DLL (1 << 14)
/*! Generic clock descriptor. */
typedef struct _clock_t
{
u32 reset;
u32 enable;
u32 source;
u8 index;
u8 clk_src;
u8 clk_div;
} clock_t;
/*! Generic clock enable/disable. */
void clock_enable(const clock_t *clk);
void clock_disable(const clock_t *clk);
/*! Clock control for specific hardware portions. */
void clock_enable_fuse(u32 enable);
void clock_enable_uart(u32 idx);
void clock_enable_i2c(u32 idx);
void clock_enable_se();
void clock_enable_host1x();
void clock_disable_host1x();
void clock_enable_tsec();
void clock_disable_tsec();
void clock_enable_sor_safe();
void clock_disable_sor_safe();
void clock_enable_sor0();
void clock_disable_sor0();
void clock_enable_sor1();
void clock_disable_sor1();
void clock_enable_kfuse();
void clock_disable_kfuse();
void clock_enable_cl_dvfs();
void clock_enable_coresight();
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
void clock_sdmmc_enable(u32 id, u32 val);
void clock_sdmmc_disable(u32 id);
void clock_halt_bpmp(void);
#endif

143
ariane/src/hwinit/cluster.c Normal file
View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cluster.h"
#include "clock.h"
#include "timer.h"
#include "pmc.h"
#include "flow.h"
#include "t210.h"
#include "i2c.h"
#include "max7762x.h"
#include "max77620.h"
void _cluster_enable_power()
{
u8 tmp = max77620_recv_byte(MAX77620_REG_AME_GPIO);
max77620_send_byte(MAX77620_REG_AME_GPIO, tmp & 0xDF);
max77620_send_byte(MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH);
// Enable cores power.
max7762x_send_byte(MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG,
MAX77621_AD_ENABLE | MAX77621_NFSR_ENABLE | MAX77621_SNS_ENABLE); // 1-3.x: MAX77621_NFSR_ENABLE
max7762x_send_byte(MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,
MAX77621_T_JUNCTION_120 | MAX77621_WDTMR_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US| MAX77621_INDUCTOR_NOMINAL);
// 1-3.x: MAX77621_T_JUNCTION_120 | MAX77621_CKKADV_TRIP_DISABLE | MAX77621_INDUCTOR_NOMINAL
max7762x_send_byte(MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_ENABLE | 0x37);
max7762x_send_byte(MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVC_REG, MAX77621_VOUT_ENABLE | 0x37);
}
int _cluster_pmc_enable_partition(u32 part, u32 toggle, u32 enable)
{
//Check if the partition has already been turned on.
if (enable && (PMC(APBDEV_PMC_PWRGATE_STATUS) & part))
return 1;
u32 startTime = get_tmr_ms();
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
{
if (get_tmr_ms() - startTime >= 5) //only wait for 5ms
return 0;
}
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = toggle | (enable ? 0x100 : 0);
startTime = get_tmr_ms();
while ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part) == 0)
{
if (get_tmr_ms() - startTime >= 5) //only wait for 5ms
return 0;
}
return 1;
}
#define PLLX_VALUE_FROM_DIVS(DIVM, DIVN, DIVP) (((DIVP & 0x1F) << 20) | ((DIVN & 0xFF) << 8) | (DIVM & 0xFF))
void cluster_boot_cpu0(u32 entry)
{
struct flow_ctlr* const flow = (void *)FLOW_CTLR_BASE;
flow->bpmp_cluster_control &= ~(1u << 0); //Set ACTIVE_CLUSER to FAST.
_cluster_enable_power();
//final_freq = ((38.4MHz / DIVM) * DIVN) / (2^DIVP)
typedef struct freqEntry_s { u32 clkFreqHz; u32 pllxDividers; } freqEntry_t;
static const freqEntry_t frequencies[] =
{
{ 93600000, PLLX_VALUE_FROM_DIVS(2, 78, 4) }, //93.6MHz (bench: 6677351 us)
{ 187200000, PLLX_VALUE_FROM_DIVS(2, 78, 3) }, //187.2MHz (bench: 5341881 us)
{ 249600000, PLLX_VALUE_FROM_DIVS(3, 156, 3) }, //249.6MHz (bench: 4006410 us)
{ 499200000, PLLX_VALUE_FROM_DIVS(3, 156, 2) }, //499.2MHz (bench: 3004808 us)
{ 748800000, PLLX_VALUE_FROM_DIVS(2, 78, 1) }, //748.8MHz (bench: 2670940 us)
{ 998400000, PLLX_VALUE_FROM_DIVS(3, 156, 1) } //998.4MHz (bench: 2003206 us)
};
static const u32 pllxDividers = frequencies[0].pllxDividers;
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & (1u << 30)))
{
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= ~(1u << 3);
usleep(2);
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = (1u << 31) | pllxDividers;
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x00000000 | pllxDividers;
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) |= (1u << 18);
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = (1u << 30) | pllxDividers;
}
while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x8000000)) {}
//Configure MSELECT source and enable clock.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= CLK_V_MSELECT;
//Configure initial CPU clock frequency and enable clock.
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = CLK_V_CPUG;
clock_enable_coresight();
//CAR2PMC_CPU_ACK_WIDTH should be set to 0.
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
//Enable CPU rail.
_cluster_pmc_enable_partition(1, 0, 1);
//Enable cluster 0 non-CPU.
_cluster_pmc_enable_partition(0x8000, 15, 1);
//Enable CE0.
_cluster_pmc_enable_partition(0x4000, 14, 1);
//Request and wait for RAM repair.
flow->ram_repair = 1;
while (!(flow->ram_repair & 2)) {}
EXCP_VEC(0x100) = 0;
//Keep bootrom accessible after cluster boot
SB(SB_PIROM_START) = 96*1024;
//Set reset vector.
SB(SB_AA64_RESET_LOW) = entry | 1;
SB(SB_AA64_RESET_HIGH) = 0;
//Non-secure reset vector write disable.
SB(SB_CSR) = 2;
(void)SB(SB_CSR);
//Clear MSELECT reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= ~CLK_V_MSELECT;
//Clear NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
//Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x411F000F;
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CLUSTER_H_
#define _CLUSTER_H_
#include "types.h"
void cluster_boot_cpu0(u32 entry);
#endif

209
ariane/src/hwinit/di.c Normal file
View file

@ -0,0 +1,209 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "di.h"
#include "clock.h"
#include "gpio.h"
#include "pinmux.h"
#include "t210.h"
#include "timer.h"
#include "util.h"
#include "pmc.h"
#include "max7762x.h"
#include "max77620.h"
#include "di.inl"
static u32 _display_ver = 0;
static void _display_dsi_wait(u32 milliseconds, u32 off, u32 mask)
{
u32 end = get_tmr_ms() + milliseconds;
while (DSI(off) & mask) { if (get_tmr_ms() >= end) return; }
usleep(5);
}
void display_init()
{
//Power on.
max77620_regulator_set_voltage(REGULATOR_LDO0, 1200000); //1.2V
max77620_regulator_enable(REGULATOR_LDO0, 1);
max77620_send_byte(MAX77620_REG_GPIO7, 0x09);
//Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = CLK_H_DSI | CLK_H_MIPI_CAL;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLK_H_DSI | CLK_H_MIPI_CAL;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = CLK_L_DISP1 | CLK_L_HOST1X;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = CLK_L_DISP1 | CLK_L_HOST1X;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = CLK_X_UART_FST_MIPI_CAL;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 0xA;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = CLK_W_DSIA_LP;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 0xA;
//DPD idle.
PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;
PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;
//Config pins.
pinmux_set_config(PINMUX_GPIO_I0, pinmux_get_config(PINMUX_GPIO_I0) & (~PINMUX_TRISTATE));
pinmux_set_config(PINMUX_GPIO_I1, pinmux_get_config(PINMUX_GPIO_I1) & (~PINMUX_TRISTATE));
pinmux_set_config(PINMUX_LCD_BL_PWM_INDEX, pinmux_get_config(PINMUX_LCD_BL_PWM_INDEX) & (~PINMUX_TRISTATE));
pinmux_set_config(PINMUX_LCD_BL_EN_INDEX, pinmux_get_config(PINMUX_LCD_BL_EN_INDEX) & (~PINMUX_TRISTATE));
pinmux_set_config(PINMUX_LCD_RST_INDEX, pinmux_get_config(PINMUX_LCD_RST_INDEX) & (~PINMUX_TRISTATE));
gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); //Backlight +-5V.
gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); //Backlight +-5V.
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); //Backlight +5V enable.
msleep(10);
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); //Backlight -5V enable.
msleep(10);
gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); //Backlight PWM, Enable, Reset.
gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
gpio_write(GPIO_BY_NAME(LCD_BL_EN), GPIO_HIGH); //Backlight Enable enable.
//Config display interface and display.
MIPI_CAL(0x60) = 0;
exec_cfg((u32 *)CLOCK_BASE, _display_config_1, ARRAY_SIZE(_display_config_1));
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, ARRAY_SIZE(_display_config_2));
exec_cfg((u32 *)DSI_BASE, _display_config_3, ARRAY_SIZE(_display_config_3));
msleep(10);
gpio_write(GPIO_BY_NAME(LCD_RST), GPIO_HIGH); //Backlight Reset enable.
msleep(60);
DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204;
DSI(_DSIREG(DSI_WR_DATA)) = 0x337;
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
_display_dsi_wait(250, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
DSI(_DSIREG(DSI_WR_DATA)) = 0x406;
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
_display_dsi_wait(250, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
_display_dsi_wait(150, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
msleep(5);
_display_ver = DSI(_DSIREG(DSI_RD_DATA));
if (_display_ver == 0x10)
exec_cfg((u32 *)DSI_BASE, _display_config_4, ARRAY_SIZE(_display_config_4));
DSI(_DSIREG(DSI_WR_DATA)) = 0x1105;
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
msleep(180);
DSI(_DSIREG(DSI_WR_DATA)) = 0x2905;
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
msleep(20);
exec_cfg((u32 *)DSI_BASE, _display_config_5, ARRAY_SIZE(_display_config_5));
exec_cfg((u32 *)CLOCK_BASE, _display_config_6, ARRAY_SIZE(_display_config_6));
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4;
exec_cfg((u32 *)DSI_BASE, _display_config_7, ARRAY_SIZE(_display_config_7));
msleep(10);
exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, ARRAY_SIZE(_display_config_8));
exec_cfg((u32 *)DSI_BASE, _display_config_9, ARRAY_SIZE(_display_config_9));
exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, ARRAY_SIZE(_display_config_10));
msleep(10);
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, ARRAY_SIZE(_display_config_11));
}
void display_enable_backlight(u32 on)
{
gpio_write(GPIO_BY_NAME(LCD_BL_PWM), on ? GPIO_HIGH : GPIO_LOW); //Backlight PWM.
}
void display_end()
{
display_enable_backlight(0);
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 1;
DSI(_DSIREG(DSI_WR_DATA)) = 0x2805;
u32 end = HOST1X(0x30A4) + 5;
while (HOST1X(0x30A4) < end) {}
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, ARRAY_SIZE(_display_config_12));
exec_cfg((u32 *)DSI_BASE, _display_config_13, ARRAY_SIZE(_display_config_13));
msleep(10);
if (_display_ver == 0x10)
exec_cfg((u32 *)DSI_BASE, _display_config_14, ARRAY_SIZE(_display_config_14));
DSI(_DSIREG(DSI_WR_DATA)) = 0x1005;
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
msleep(50);
gpio_write(GPIO_BY_NAME(LCD_RST), GPIO_LOW); //Backlight Reset disable.
msleep(10);
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable.
msleep(10);
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable.
msleep(10);
//Disable clocks.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = CLK_H_DSI | CLK_H_MIPI_CAL;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = CLK_H_DSI | CLK_H_MIPI_CAL;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = CLK_L_DISP1 | CLK_L_HOST1X;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = CLK_L_DISP1 | CLK_L_HOST1X;
DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
gpio_config(GPIO_BY_NAME(LCD_BL_PWM), GPIO_MODE_SPIO); //Backlight PWM.
pinmux_set_config(PINMUX_LCD_BL_PWM_INDEX, pinmux_get_config(PINMUX_LCD_BL_PWM_INDEX) | PINMUX_TRISTATE);
pinmux_set_config(PINMUX_LCD_BL_PWM_INDEX, (pinmux_get_config(PINMUX_LCD_BL_PWM_INDEX) & (~PINMUX_FUNC_MASK)) | PINMUX_LCD_BL_PWM_FUNC_PWM0);
}
void display_color_screen(u32 color)
{
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
//Configure display to show single color.
DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
msleep(35);
display_enable_backlight(1);
}
u32 *display_init_framebuffer(u32 *fb)
{
//This configures the framebuffer @ 0xC0000000 with a resolution of 1280x720 (line stride 768).
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, ARRAY_SIZE(cfg_display_framebuffer));
msleep(35);
return (u32 *)0xC0000000;
}

352
ariane/src/hwinit/di.h Normal file
View file

@ -0,0 +1,352 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DI_H_
#define _DI_H_
#include "types.h"
/*! Display registers. */
#define _DIREG(reg) ((reg) * 4)
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
#define SYNCPT_CNTRL_NO_STALL (1 << 8)
#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
#define SYNCPT_VSYNC_ENABLE (1 << 8)
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
#define DC_CMD_DISPLAY_COMMAND 0x32
#define DISP_CTRL_MODE_STOP (0 << 5)
#define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5)
#define DISP_CTRL_MODE_MASK (3 << 5)
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
#define PW0_ENABLE (1 << 0)
#define PW1_ENABLE (1 << 2)
#define PW2_ENABLE (1 << 4)
#define PW3_ENABLE (1 << 6)
#define PW4_ENABLE (1 << 8)
#define PM0_ENABLE (1 << 16)
#define PM1_ENABLE (1 << 18)
#define DC_CMD_INT_MASK 0x38
#define DC_CMD_INT_ENABLE 0x39
#define DC_CMD_STATE_ACCESS 0x40
#define READ_MUX (1 << 0)
#define WRITE_MUX (1 << 2)
#define DC_CMD_STATE_CONTROL 0x41
#define GENERAL_ACT_REQ (1 << 0)
#define WIN_A_ACT_REQ (1 << 1)
#define WIN_B_ACT_REQ (1 << 2)
#define WIN_C_ACT_REQ (1 << 3)
#define CURSOR_ACT_REQ (1 << 7)
#define GENERAL_UPDATE (1 << 8)
#define WIN_A_UPDATE (1 << 9)
#define WIN_B_UPDATE (1 << 10)
#define WIN_C_UPDATE (1 << 11)
#define CURSOR_UPDATE (1 << 15)
#define NC_HOST_TRIG (1 << 24)
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
#define WINDOW_A_SELECT (1 << 4)
#define WINDOW_B_SELECT (1 << 5)
#define WINDOW_C_SELECT (1 << 6)
#define DC_CMD_REG_ACT_CONTROL 0x043
#define DC_COM_CRC_CONTROL 0x300
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
#define DC_COM_DSC_TOP_CTL 0x33E
#define DC_DISP_DISP_WIN_OPTIONS 0x402
#define HDMI_ENABLE (1 << 30)
#define DSI_ENABLE (1 << 29)
#define SOR1_TIMING_CYA (1 << 27)
#define SOR1_ENABLE (1 << 26)
#define SOR_ENABLE (1 << 25)
#define CURSOR_ENABLE (1 << 16)
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
#define DC_DISP_REF_TO_SYNC 0x406
#define DC_DISP_SYNC_WIDTH 0x407
#define DC_DISP_BACK_PORCH 0x408
#define DC_DISP_ACTIVE 0x409
#define DC_DISP_FRONT_PORCH 0x40A
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8)
#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8)
#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8)
#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8)
#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8)
#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8)
#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8)
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0)
#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0)
#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0)
#define DISP_DATA_FORMAT_DF2S (4 << 0)
#define DISP_DATA_FORMAT_DF3S (5 << 0)
#define DISP_DATA_FORMAT_DFSPI (6 << 0)
#define DISP_DATA_FORMAT_DF1P3C24B (7 << 0)
#define DISP_DATA_FORMAT_DF1P3C18B (8 << 0)
#define DISP_ALIGNMENT_MSB (0 << 8)
#define DISP_ALIGNMENT_LSB (1 << 8)
#define DISP_ORDER_RED_BLUE (0 << 9)
#define DISP_ORDER_BLUE_RED (1 << 9)
#define DC_DISP_DISP_COLOR_CONTROL 0x430
#define DITHER_CONTROL_MASK (3 << 8)
#define DITHER_CONTROL_DISABLE (0 << 8)
#define DITHER_CONTROL_ORDERED (2 << 8)
#define DITHER_CONTROL_ERRDIFF (3 << 8)
#define BASE_COLOR_SIZE_MASK (0xf << 0)
#define BASE_COLOR_SIZE_666 (0 << 0)
#define BASE_COLOR_SIZE_111 (1 << 0)
#define BASE_COLOR_SIZE_222 (2 << 0)
#define BASE_COLOR_SIZE_333 (3 << 0)
#define BASE_COLOR_SIZE_444 (4 << 0)
#define BASE_COLOR_SIZE_555 (5 << 0)
#define BASE_COLOR_SIZE_565 (6 << 0)
#define BASE_COLOR_SIZE_332 (7 << 0)
#define BASE_COLOR_SIZE_888 (8 << 0)
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
#define SC1_H_QUALIFIER_NONE (1 << 16)
#define SC0_H_QUALIFIER_NONE (1 << 0)
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
#define DE_SELECT_ACTIVE (1 << 0)
#define DE_SELECT_ACTIVE_IS (2 << 0)
#define DE_CONTROL_ONECLK (0 << 2)
#define DE_CONTROL_NORMAL (1 << 2)
#define DE_CONTROL_EARLY_EXT (2 << 2)
#define DE_CONTROL_EARLY (3 << 2)
#define DE_CONTROL_ACTIVE_BLANK (4 << 2)
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
#define DC_WIN_CSC_YOF 0x611
#define DC_WIN_CSC_KYRGB 0x612
#define DC_WIN_CSC_KUR 0x613
#define DC_WIN_CSC_KVR 0x614
#define DC_WIN_CSC_KUG 0x615
#define DC_WIN_CSC_KVG 0x616
#define DC_WIN_CSC_KUB 0x617
#define DC_WIN_CSC_KVB 0x618
#define DC_WIN_AD_WIN_OPTIONS 0xB80
#define DC_WIN_BD_WIN_OPTIONS 0xD80
#define DC_WIN_CD_WIN_OPTIONS 0xF80
//The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
#define DC_WIN_WIN_OPTIONS 0x700
#define H_DIRECTION (1 << 0)
#define V_DIRECTION (1 << 2)
#define COLOR_EXPAND (1 << 6)
#define CSC_ENABLE (1 << 18)
#define WIN_ENABLE (1 << 30)
#define DC_WIN_COLOR_DEPTH 0x703
#define WIN_COLOR_DEPTH_P1 0x0
#define WIN_COLOR_DEPTH_P2 0x1
#define WIN_COLOR_DEPTH_P4 0x2
#define WIN_COLOR_DEPTH_P8 0x3
#define WIN_COLOR_DEPTH_B4G4R4A4 0x4
#define WIN_COLOR_DEPTH_B5G5R5A 0x5
#define WIN_COLOR_DEPTH_B5G6R5 0x6
#define WIN_COLOR_DEPTH_AB5G5R5 0x7
#define WIN_COLOR_DEPTH_B8G8R8A8 0xC
#define WIN_COLOR_DEPTH_R8G8B8A8 0xD
#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE
#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF
#define WIN_COLOR_DEPTH_YCbCr422 0x10
#define WIN_COLOR_DEPTH_YUV422 0x11
#define WIN_COLOR_DEPTH_YCbCr420P 0x12
#define WIN_COLOR_DEPTH_YUV420P 0x13
#define WIN_COLOR_DEPTH_YCbCr422P 0x14
#define WIN_COLOR_DEPTH_YUV422P 0x15
#define WIN_COLOR_DEPTH_YCbCr422R 0x16
#define WIN_COLOR_DEPTH_YUV422R 0x17
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
#define WIN_COLOR_DEPTH_YUV422RA 0x19
#define DC_WIN_BUFFER_CONTROL 0x702
#define DC_WIN_POSITION 0x704
#define DC_WIN_SIZE 0x705
#define H_SIZE(x) (((x) & 0x1fff) << 0)
#define V_SIZE(x) (((x) & 0x1fff) << 16)
#define DC_WIN_PRESCALED_SIZE 0x706
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
#define DC_WIN_H_INITIAL_DDA 0x707
#define DC_WIN_V_INITIAL_DDA 0x708
#define DC_WIN_DDA_INC 0x709
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
#define DC_WIN_LINE_STRIDE 0x70A
#define DC_WIN_DV_CONTROL 0x70E
//The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER).
#define DC_WINBUF_START_ADDR 0x800
#define DC_WINBUF_ADDR_H_OFFSET 0x806
#define DC_WINBUF_ADDR_V_OFFSET 0x808
#define DC_WINBUF_SURFACE_KIND 0x80B
/*! Display serial interface registers. */
#define _DSIREG(reg) ((reg) * 4)
#define DSI_RD_DATA 0x9
#define DSI_WR_DATA 0xA
#define DSI_POWER_CONTROL 0xB
#define DSI_POWER_CONTROL_ENABLE 1
#define DSI_INT_ENABLE 0xC
#define DSI_INT_STATUS 0xD
#define DSI_INT_MASK 0xE
#define DSI_HOST_CONTROL 0xF
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
#define DSI_HOST_CONTROL_RAW (1 << 6)
#define DSI_HOST_CONTROL_HS (1 << 5)
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
#define DSI_HOST_CONTROL_CS (1 << 1)
#define DSI_HOST_CONTROL_ECC (1 << 0)
#define DSI_CONTROL 0x10
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
#define DSI_CONTROL_HOST_ENABLE (1 << 0)
#define DSI_SOL_DELAY 0x11
#define DSI_MAX_THRESHOLD 0x12
#define DSI_TRIGGER 0x13
#define DSI_TRIGGER_HOST (1 << 1)
#define DSI_TRIGGER_VIDEO (1 << 0)
#define DSI_TX_CRC 0x14
#define DSI_STATUS 0x15
#define DSI_INIT_SEQ_CONTROL 0x1A
#define DSI_INIT_SEQ_DATA_0 0x1B
#define DSI_INIT_SEQ_DATA_1 0x1C
#define DSI_INIT_SEQ_DATA_2 0x1D
#define DSI_INIT_SEQ_DATA_3 0x1E
#define DSI_PKT_SEQ_0_LO 0x23
#define DSI_PKT_SEQ_0_HI 0x24
#define DSI_PKT_SEQ_1_LO 0x25
#define DSI_PKT_SEQ_1_HI 0x26
#define DSI_PKT_SEQ_2_LO 0x27
#define DSI_PKT_SEQ_2_HI 0x28
#define DSI_PKT_SEQ_3_LO 0x29
#define DSI_PKT_SEQ_3_HI 0x2A
#define DSI_PKT_SEQ_4_LO 0x2B
#define DSI_PKT_SEQ_4_HI 0x2C
#define DSI_PKT_SEQ_5_LO 0x2D
#define DSI_PKT_SEQ_5_HI 0x2E
#define DSI_DCS_CMDS 0x33
#define DSI_PKT_LEN_0_1 0x34
#define DSI_PKT_LEN_2_3 0x35
#define DSI_PKT_LEN_4_5 0x36
#define DSI_PKT_LEN_6_7 0x37
#define DSI_PHY_TIMING_0 0x3C
#define DSI_PHY_TIMING_1 0x3D
#define DSI_PHY_TIMING_2 0x3E
#define DSI_BTA_TIMING 0x3F
#define DSI_TIMEOUT_0 0x44
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
#define DSI_TIMEOUT_1 0x45
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
#define DSI_TO_TALLY 0x46
#define DSI_PAD_CONTROL_0 0x4B
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
#define DSI_PAD_CONTROL_CD 0x4c
#define DSI_VIDEO_MODE_CONTROL 0x4E
#define DSI_PAD_CONTROL_1 0x4F
#define DSI_PAD_CONTROL_2 0x50
#define DSI_PAD_CONTROL_3 0x51
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
#define DSI_PAD_CONTROL_4 0x52
void display_init();
void display_end();
/*! Show one single color on the display. */
void display_color_screen(u32 color);
/*! Init display in full 1280x720 resolution (32bpp, line stride 768, framebuffer size = 1280*768*4 bytes). */
u32 *display_init_framebuffer();
/*! Enable or disable the backlight. Should only be called when the screen is completely set up, to avoid flickering. */
void display_enable_backlight(u32 on);
#endif

562
ariane/src/hwinit/di.inl Normal file
View file

@ -0,0 +1,562 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//Clock config.
static const cfg_op_t _display_config_1[4] = {
{0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1
{0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
{0x37, 0x2D0AAA} //CLK_RST_CONTROLLER_PLLD_MISC
};
//Display A config.
static const cfg_op_t _display_config_2[94] = {
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_REG_ACT_CONTROL, 0x54},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_DISP_DC_MCCIF_FIFOCTRL, 0},
{DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
{DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
{DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
{DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
{DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{0x4E4, 0},
{DC_COM_CRC_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_COMMAND, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
};
//DSI Init config.
static const cfg_op_t _display_config_3[60] = {
{DSI_WR_DATA, 0},
{DSI_INT_ENABLE, 0},
{DSI_INT_STATUS, 0},
{DSI_INT_MASK, 0},
{DSI_INIT_SEQ_DATA_0, 0},
{DSI_INIT_SEQ_DATA_1, 0},
{DSI_INIT_SEQ_DATA_2, 0},
{DSI_INIT_SEQ_DATA_3, 0},
{DSI_DCS_CMDS, 0},
{DSI_PKT_SEQ_0_LO, 0},
{DSI_PKT_SEQ_1_LO, 0},
{DSI_PKT_SEQ_2_LO, 0},
{DSI_PKT_SEQ_3_LO, 0},
{DSI_PKT_SEQ_4_LO, 0},
{DSI_PKT_SEQ_5_LO, 0},
{DSI_PKT_SEQ_0_HI, 0},
{DSI_PKT_SEQ_1_HI, 0},
{DSI_PKT_SEQ_2_HI, 0},
{DSI_PKT_SEQ_3_HI, 0},
{DSI_PKT_SEQ_4_HI, 0},
{DSI_PKT_SEQ_5_HI, 0},
{DSI_CONTROL, 0},
{DSI_PAD_CONTROL_CD, 0},
{DSI_SOL_DELAY, 0x18},
{DSI_MAX_THRESHOLD, 0x1E0},
{DSI_TRIGGER, 0},
{DSI_INIT_SEQ_CONTROL, 0},
{DSI_PKT_LEN_0_1, 0},
{DSI_PKT_LEN_2_3, 0},
{DSI_PKT_LEN_4_5, 0},
{DSI_PKT_LEN_6_7, 0},
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30109},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
{DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_POWER_CONTROL, 0},
{DSI_POWER_CONTROL, 0},
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30118},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_MAX_THRESHOLD, 0x40},
{DSI_TRIGGER, 0},
{DSI_TX_CRC, 0},
{DSI_INIT_SEQ_CONTROL, 0}
};
//DSI config (if ver == 0x10).
static const cfg_op_t _display_config_4[43] = {
{DSI_WR_DATA, 0x439},
{DSI_WR_DATA, 0x9483FFB9},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xBD15},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x1939},
{DSI_WR_DATA, 0xAAAAAAD8},
{DSI_WR_DATA, 0xAAAAAAEB},
{DSI_WR_DATA, 0xAAEBAAAA},
{DSI_WR_DATA, 0xAAAAAAAA},
{DSI_WR_DATA, 0xAAAAAAEB},
{DSI_WR_DATA, 0xAAEBAAAA},
{DSI_WR_DATA, 0xAA},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x1BD15},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2739},
{DSI_WR_DATA, 0xFFFFFFD8},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFF},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2BD15},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xF39},
{DSI_WR_DATA, 0xFFFFFFD8},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFF},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xBD15},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x6D915},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x439},
{DSI_WR_DATA, 0xB9},
{DSI_TRIGGER, DSI_TRIGGER_HOST}
};
//DSI config.
static const cfg_op_t _display_config_5[21] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30172},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
{DSI_PKT_SEQ_0_LO, 0x40000208},
{DSI_PKT_SEQ_2_LO, 0x40000308},
{DSI_PKT_SEQ_4_LO, 0x40000308},
{DSI_PKT_SEQ_1_LO, 0x40000308},
{DSI_PKT_SEQ_3_LO, 0x3F3B2B08},
{DSI_PKT_SEQ_3_HI, 0x2CC},
{DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
{DSI_PKT_SEQ_5_HI, 0x2CC},
{DSI_PKT_LEN_0_1, 0xCE0000},
{DSI_PKT_LEN_2_3, 0x87001A2},
{DSI_PKT_LEN_4_5, 0x190},
{DSI_PKT_LEN_6_7, 0x190},
{DSI_HOST_CONTROL, 0},
};
//Clock config.
static const cfg_op_t _display_config_6[3] = {
{0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
{0x37, 0x2DFC00} //CLK_RST_CONTROLLER_PLLD_MISC
};
//DSI config.
static const cfg_op_t _display_config_7[10] = {
{DSI_TRIGGER, 0},
{DSI_CONTROL, 0},
{DSI_SOL_DELAY, 6},
{DSI_MAX_THRESHOLD, 0x1E0},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
};
//MIPI CAL config.
static const cfg_op_t _display_config_8[6] = {
{0x18, 0},
{2, 0xF3F10000},
{0x16, 1},
{0x18, 0},
{0x18, 0x10010},
{0x17, 0x300}
};
//DSI config.
static const cfg_op_t _display_config_9[4] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PAD_CONTROL_2, 0},
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
{DSI_PAD_CONTROL_4, 0}
};
//MIPI CAL config.
static const cfg_op_t _display_config_10[16] = {
{0xE, 0x200200},
{0xF, 0x200200},
{0x19, 0x200002},
{0x1A, 0x200002},
{5, 0},
{6, 0},
{7, 0},
{8, 0},
{9, 0},
{0xA, 0},
{0x10, 0},
{0x11, 0},
{0x1A, 0},
{0x1C, 0},
{0x1D, 0},
{0, 0x2A000001}
};
//Display A config.
static const cfg_op_t _display_config_11[113] = {
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_DV_CONTROL, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
/* Setup default YUV colorspace conversion coefficients */
{DC_WIN_CSC_YOF, 0xF0},
{DC_WIN_CSC_KYRGB, 0x12A},
{DC_WIN_CSC_KUR, 0},
{DC_WIN_CSC_KVR, 0x198},
{DC_WIN_CSC_KUG, 0x39B},
{DC_WIN_CSC_KVG, 0x32F},
{DC_WIN_CSC_KUB, 0x204},
{DC_WIN_CSC_KVB, 0},
/* End of color coefficients */
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{0x4E4, 0},
{DC_COM_CRC_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{0x716, 0x10000FF},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_COMMAND, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_STATE_ACCESS, 0},
/* Set Display timings */
{DC_DISP_DISP_TIMING_OPTIONS, 0},
{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
{DC_DISP_SYNC_WIDTH, 0x10048},
{DC_DISP_BACK_PORCH, 0x90048},
{DC_DISP_ACTIVE, 0x50002D0},
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
/* End of Display timings */
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_DISP_DISP_CLOCK_CONTROL, 0},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
{DC_DISP_FRONT_PORCH, 0xA0088},
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_STATE_ACCESS, 0},
{DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
{DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
};
////Display A config.
static const cfg_op_t _display_config_12[17] = {
{DC_DISP_FRONT_PORCH, 0xA0088},
{DC_CMD_INT_MASK, 0},
{DC_CMD_STATE_ACCESS, 0},
{DC_CMD_INT_ENABLE, 0},
{DC_CMD_CONT_SYNCPT_VSYNC, 0},
{DC_CMD_DISPLAY_COMMAND, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
{DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_DISPLAY_POWER_CONTROL, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
};
//DSI config.
static const cfg_op_t _display_config_13[16] = {
{DSI_POWER_CONTROL, 0},
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30109},
{DSI_BTA_TIMING, 0x190A14},
{DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
{DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
{DSI_TO_TALLY, 0},
{DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
{DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_MAX_THRESHOLD, 0x40},
{DSI_TRIGGER, 0},
{DSI_TX_CRC, 0},
{DSI_INIT_SEQ_CONTROL, 0}
};
//DSI config (if ver == 0x10).
static const cfg_op_t _display_config_14[22] = {
{DSI_WR_DATA, 0x439},
{DSI_WR_DATA, 0x9483FFB9},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2139},
{DSI_WR_DATA, 0x191919D5},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xB39},
{DSI_WR_DATA, 0x4F0F41B1},
{DSI_WR_DATA, 0xF179A433},
{DSI_WR_DATA, 0x2D81},
{DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x439},
{DSI_WR_DATA, 0xB9},
{DSI_TRIGGER, DSI_TRIGGER_HOST}
};
//Display A config.
static const cfg_op_t cfg_display_one_color[8] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} //DISPLAY_CTRL_MODE: continuous display.
};
//Display A config.
static const cfg_op_t cfg_display_framebuffer[32] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_R8G8B8A8}, //T_A8B8G8R8
{DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.
{DC_WIN_LINE_STRIDE, 0x6000C00}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
{DC_WIN_BUFFER_CONTROL, 0},
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
{DC_WINBUF_START_ADDR, 0xC0000000}, //Framebuffer address.
{DC_WINBUF_ADDR_H_OFFSET, 0},
{DC_WINBUF_ADDR_V_OFFSET, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, //Enable window AD.
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
};

471
ariane/src/hwinit/emc.h Normal file
View file

@ -0,0 +1,471 @@
/*
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
* Copyright (C) 2014 Google Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __SOC_NVIDIA_TEGRA210_EMC_H__
#define __SOC_NVIDIA_TEGRA210_EMC_H__
#include <stddef.h>
#include <stdint.h>
#include "types.h"
enum {
EMC_PIN_RESET_MASK = 1 << 8,
EMC_PIN_RESET_ACTIVE = 0 << 8,
EMC_PIN_RESET_INACTIVE = 1 << 8,
EMC_PIN_DQM_MASK = 1 << 4,
EMC_PIN_DQM_NORMAL = 0 << 4,
EMC_PIN_DQM_INACTIVE = 1 << 4,
EMC_PIN_CKE_MASK = 1 << 0,
EMC_PIN_CKE_POWERDOWN = 0 << 0,
EMC_PIN_CKE_NORMAL = 1 << 0,
EMC_REF_CMD_MASK = 1 << 0,
EMC_REF_CMD_REFRESH = 1 << 0,
EMC_REF_NORMAL_MASK = 1 << 1,
EMC_REF_NORMAL_INIT = 0 << 1,
EMC_REF_NORMAL_ENABLED = 1 << 1,
EMC_REF_NUM_SHIFT = 8,
EMC_REF_NUM_MASK = 0xFF << EMC_REF_NUM_SHIFT,
EMC_REF_DEV_SELECTN_SHIFT = 30,
EMC_REF_DEV_SELECTN_MASK = 3 << EMC_REF_DEV_SELECTN_SHIFT,
EMC_REFCTRL_REF_VALID_MASK = 1 << 31,
EMC_REFCTRL_REF_VALID_DISABLED = 0 << 31,
EMC_REFCTRL_REF_VALID_ENABLED = 1 << 31,
EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE_MASK = 1 << 1,
EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1_MASK = 1 << 2,
EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2_MASK = 1 << 3,
EMC_NOP_CMD_SHIFT = 0,
EMC_NOP_CMD_MASK = 1 << EMC_NOP_CMD_SHIFT,
EMC_NOP_DEV_SELECTN_SHIFT = 30,
EMC_NOP_DEV_SELECTN_MASK = 3 << EMC_NOP_DEV_SELECTN_SHIFT,
EMC_TIMING_CONTROL_TIMING_UPDATE = 1,
EMC_PIN_GPIOEN_SHIFT = 16,
EMC_PIN_GPIO_SHIFT = 12,
EMC_PMACRO_BRICK_CTRL_RFU1_RESET_VAL = 0x1FFF1FFF,
AUTOCAL_MEASURE_STALL_ENABLE = 1 << 9,
WRITE_MUX_ACTIVE = 1 << 1,
CFG_ADR_EN_LOCKED = 1 << 1,
};
struct tegra_emc_regs {
vu32 intstatus; /* 0x0 */
vu32 intmask; /* 0x4 */
vu32 dbg; /* 0x8 */
vu32 cfg; /* 0xc */
vu32 adr_cfg; /* 0x10 */
vu32 rsvd_0x14[3]; /* 0x14-0x1C */
vu32 refctrl; /* 0x20 */
vu32 pin; /* 0x24 */
vu32 timing_control; /* 0x28 */
vu32 rc; /* 0x2c */
vu32 rfc; /* 0x30 */
vu32 ras; /* 0x34 */
vu32 rp; /* 0x38 */
vu32 r2w; /* 0x3c */
vu32 w2r; /* 0x40 */
vu32 r2p; /* 0x44 */
vu32 w2p; /* 0x48 */
vu32 rd_rcd; /* 0x4c */
vu32 wr_rcd; /* 0x50 */
vu32 rrd; /* 0x54 */
vu32 rext; /* 0x58 */
vu32 wdv; /* 0x5c */
vu32 quse; /* 0x60 */
vu32 qrst; /* 0x64 */
vu32 qsafe; /* 0x68 */
vu32 rdv; /* 0x6c */
vu32 refresh; /* 0x70 */
vu32 burst_refresh_num; /* 0x74 */
vu32 pdex2wr; /* 0x78 */
vu32 pdex2rd; /* 0x7c */
vu32 pchg2pden; /* 0x80 */
vu32 act2pden; /* 0x84 */
vu32 ar2pden; /* 0x88 */
vu32 rw2pden; /* 0x8c */
vu32 txsr; /* 0x90 */
vu32 tcke; /* 0x94 */
vu32 tfaw; /* 0x98 */
vu32 trpab; /* 0x9c */
vu32 tclkstable; /* 0xa0 */
vu32 tclkstop; /* 0xa4 */
vu32 trefbw; /* 0xa8 */
vu32 tppd; /* 0xac */
vu32 odt_write; /* 0xb0 */
vu32 pdex2mrr; /* 0xb4 */
vu32 wext; /* 0xb8 */
vu32 ctt; /* 0xbc */
vu32 rfc_slr; /* 0xc0 */
vu32 mrs_wait_cnt2; /* 0xc4 */
vu32 mrs_wait_cnt; /* 0xc8 */
vu32 mrs; /* 0xcc */
vu32 emrs; /* 0xd0 */
vu32 ref; /* 0xd4 */
vu32 pre; /* 0xd8 */
vu32 nop; /* 0xdc */
vu32 self_ref; /* 0xe0 */
vu32 dpd; /* 0xe4 */
vu32 mrw; /* 0xe8 */
vu32 mrr; /* 0xec */
vu32 cmdq; /* 0xf0 */
vu32 mc2emcq; /* 0xf4 */
vu32 xm2dqspadctrl3; /* 0xf8 */
vu32 rsvd_0xfc[1]; /* 0xfc */
vu32 fbio_spare; /* 0x100 */
vu32 fbio_cfg5; /* 0x104 */
vu32 fbio_wrptr_eq_2; /* 0x108 */
vu32 rsvd_0x10c[2]; /* 0x10c-0x110 */
vu32 fbio_cfg6; /* 0x114 */
vu32 pdex2cke; /* 0x118 */
vu32 cke2pden; /* 0x11C */
vu32 cfg_rsv; /* 0x120 */
vu32 acpd_control; /* 0x124 */
vu32 rsvd_0x128[1]; /* 0x128 */
vu32 emrs2; /* 0x12c */
vu32 emrs3; /* 0x130 */
vu32 mrw2; /* 0x134 */
vu32 mrw3; /* 0x138 */
vu32 mrw4; /* 0x13c */
vu32 clken_override; /* 0x140 */
vu32 r2r; /* 0x144 */
vu32 w2w; /* 0x148 */
vu32 einput; /* 0x14c */
vu32 einput_duration; /* 0x150 */
vu32 puterm_extra; /* 0x154 */
vu32 tckesr; /* 0x158 */
vu32 tpd; /* 0x15c */
vu32 rsvd_0x160[81]; /* 0x160-0x2A0 */
vu32 auto_cal_config; /* 0x2a4 */
vu32 auto_cal_interval; /* 0x2a8 */
vu32 auto_cal_status; /* 0x2ac */
vu32 req_ctrl; /* 0x2b0 */
vu32 status; /* 0x2b4 */
vu32 cfg_2; /* 0x2b8 */
vu32 cfg_dig_dll; /* 0x2bc */
vu32 cfg_dig_dll_period; /* 0x2c0 */
vu32 dig_dll_status; /* 0x2C4 */
vu32 cfg_dig_dll_1; /* 0x2C8 */
vu32 rdv_mask; /* 0x2cc */
vu32 wdv_mask; /* 0x2d0 */
vu32 rdv_early_mask; /* 0x2d4 */
vu32 rdv_early; /* 0x2d8 */
vu32 auto_cal_config8; /* 0x2DC */
vu32 zcal_interval; /* 0x2e0 */
vu32 zcal_wait_cnt; /* 0x2e4 */
vu32 zcal_mrw_cmd; /* 0x2e8 */
vu32 zq_cal; /* 0x2ec */
vu32 xm2cmdpadctrl; /* 0x2f0 */
vu32 xm2comppadctrl3; /* 0x2f4 */
vu32 auto_cal_vref_sel0; /* 0x2f8 */
vu32 xm2dqspadctrl2; /* 0x2fc */
vu32 auto_cal_vref_sel1; /* 0x300 */
vu32 xm2dqpadctrl2; /* 0x304 */
vu32 xm2clkpadctrl; /* 0x308 */
vu32 xm2comppadctrl; /* 0x30c */
vu32 fdpd_ctrl_dq; /* 0x310 */
vu32 fdpd_ctrl_cmd; /* 0x314 */
vu32 pmacro_cmd_brick_ctrl_fdpd; /* 0x318 */
vu32 pmacro_data_brick_ctrl_fdpd; /* 0x31c */
vu32 xm2dqspadctrl4; /* 0x320 */
vu32 scratch0; /* 0x324 */
vu32 rsvd_0x328[2]; /* 0x328-0x32C */
vu32 pmacro_brick_ctrl_rfu1; /* 0x330 */
vu32 pmacro_brick_ctrl_rfu2; /* 0x334 */
vu32 rsvd_0x338[18]; /* 0x338-0x37C */
vu32 cmd_mapping_cmd0_0; /* 0x380 */
vu32 cmd_mapping_cmd0_1; /* 0x384 */
vu32 cmd_mapping_cmd0_2; /* 0x388 */
vu32 cmd_mapping_cmd1_0; /* 0x38c */
vu32 cmd_mapping_cmd1_1; /* 0x390 */
vu32 cmd_mapping_cmd1_2; /* 0x394 */
vu32 cmd_mapping_cmd2_0; /* 0x398 */
vu32 cmd_mapping_cmd2_1; /* 0x39C */
vu32 cmd_mapping_cmd2_2; /* 0x3A0 */
vu32 cmd_mapping_cmd3_0; /* 0x3A4 */
vu32 cmd_mapping_cmd3_1; /* 0x3A8 */
vu32 cmd_mapping_cmd3_2; /* 0x3AC */
vu32 cmd_mapping_byte; /* 0x3B0 */
vu32 tr_timing_0; /* 0x3B4 */
vu32 tr_ctrl_0; /* 0x3B8 */
vu32 tr_ctrl_1; /* 0x3BC */
vu32 switch_back_ctrl; /* 0x3C0 */
vu32 tr_rdv; /* 0x3C4 */
vu32 stall_then_exe_before_clkchange; /* 0x3c8 */
vu32 stall_then_exe_after_clkchange; /* 0x3cc */
vu32 unstall_rw_after_clkchange; /* 0x3d0 */
vu32 auto_cal_clk_status; /* 0x3d4 */
vu32 sel_dpd_ctrl; /* 0x3d8 */
vu32 pre_refresh_req_cnt; /* 0x3dc */
vu32 dyn_self_ref_control; /* 0x3e0 */
vu32 txsrdll; /* 0x3e4 */
vu32 ccfifo_addr; /* 0x3e8 */
vu32 ccfifo_data; /* 0x3ec */
vu32 ccfifo_status; /* 0x3f0 */
vu32 cdb_cntl_1; /* 0x3f4 */
vu32 cdb_cntl_2; /* 0x3f8 */
vu32 xm2clkpadctrl2; /* 0x3fc */
vu32 swizzle_rank0_byte_cfg; /* 0x400 */
vu32 swizzle_rank0_byte0; /* 0x404 */
vu32 swizzle_rank0_byte1; /* 0x408 */
vu32 swizzle_rank0_byte2; /* 0x40c */
vu32 swizzle_rank0_byte3; /* 0x410 */
vu32 swizzle_rank1_byte_cfg; /* 0x414 */
vu32 swizzle_rank1_byte0; /* 0x418 */
vu32 swizzle_rank1_byte1; /* 0x41c */
vu32 swizzle_rank1_byte2; /* 0x420 */
vu32 swizzle_rank1_byte3; /* 0x424 */
vu32 issue_qrst; /* 0x428 */
vu32 rsvd_0x42C[5]; /* 0x42C-0x43C */
vu32 pmc_scratch1; /* 0x440 */
vu32 pmc_scratch2; /* 0x444 */
vu32 pmc_scratch3; /* 0x448 */
vu32 rsvd_0x44C[3]; /* 0x44C-0x454 */
vu32 auto_cal_config2; /* 0x458 */
vu32 auto_cal_config3; /* 0x45c */
vu32 auto_cal_status2; /* 0x460 */
vu32 auto_cal_channel; /* 0x464 */
vu32 ibdly; /* 0x468 */
vu32 obdly; /* 0x46c */
vu32 rsvd_0x470[3]; /* 0x470-0x478 */
vu32 dsr_vttgen_drv; /* 0x47c */
vu32 txdsrvttgen; /* 0x480 */
vu32 xm2cmdpadctrl4; /* 0x484 */
vu32 xm2cmdpadctrl5; /* 0x488 */
vu32 we_duration; /* 0x48C */
vu32 ws_duration; /* 0x490 */
vu32 wev; /* 0x494 */
vu32 wsv; /* 0x498 */
vu32 cfg_3; /* 0x49C */
vu32 mrw5; /* 0x4A0 */
vu32 mrw6; /* 0x4A4 */
vu32 mrw7; /* 0x4A8 */
vu32 mrw8; /* 0x4AC */
vu32 mrw9; /* 0x4B0 */
vu32 mrw10; /* 0x4B4 */
vu32 mrw11; /* 0x4B8 */
vu32 mrw12; /* 0x4BC */
vu32 mrw13; /* 0x4C0 */
vu32 mrw14; /* 0x4C4 */
vu32 rsvd_0x4c8[2]; /* 0x4C8-0x4CC */
vu32 mrw15; /* 0x4D0 */
vu32 cfg_sync; /* 0x4D4 */
vu32 fdpd_ctrl_cmd_no_ramp; /* 0x4D8 */
vu32 rsvd_0x4dc[1]; /* 0x4DC */
vu32 wdv_chk; /* 0x4E0 */
vu32 rsvd_0x4e4[28]; /* 0x4E4-0x550 */
vu32 cfg_pipe2; /* 0x554 */
vu32 cfg_pipe_clk; /* 0x558 */
vu32 cfg_pipe1; /* 0x55C */
vu32 cfg_pipe; /* 0x560 */
vu32 qpop; /* 0x564 */
vu32 quse_width; /* 0x568 */
vu32 puterm_width; /* 0x56c */
vu32 bgbias_ctl0; /* 0x570 */
vu32 auto_cal_config7; /* 0x574 */
vu32 xm2comppadctrl2; /* 0x578 */
vu32 comppadswctrl; /* 0x57C */
vu32 refctrl2; /* 0x580 */
vu32 fbio_cfg7; /* 0x584 */
vu32 data_brlshft_0; /* 0x588 */
vu32 data_brlshft_1; /* 0x58C */
vu32 rfcpb; /* 0x590 */
vu32 dqs_brlshft_0; /* 0x594 */
vu32 dqs_brlshft_1; /* 0x598 */
vu32 cmd_brlshft_0; /* 0x59C */
vu32 cmd_brlshft_1; /* 0x5A0 */
vu32 cmd_brlshft_2; /* 0x5A4 */
vu32 cmd_brlshft_3; /* 0x5A8 */
vu32 quse_brlshft_0; /* 0x5AC */
vu32 auto_cal_config4; /* 0x5B0 */
vu32 auto_cal_config5; /* 0x5B4 */
vu32 quse_brlshft_1; /* 0x5B8 */
vu32 quse_brlshft_2; /* 0x5BC */
vu32 ccdmw; /* 0x5C0 */
vu32 quse_brlshft_3; /* 0x5C4 */
vu32 fbio_cfg8; /* 0x5C8 */
vu32 auto_cal_config6; /* 0x5CC */
vu32 protobist_config_addr_1; /* 0x5D0 */
vu32 protobist_config_addr_2; /* 0x5D4 */
vu32 protobist_misc; /* 0x5D8 */
vu32 protobist_wdata_lower; /* 0x5DC */
vu32 protobist_wdata_upper; /* 0x5E0 */
vu32 dll_cfg0; /* 0x5E4 */
vu32 dll_cfg1; /* 0x5E8 */
vu32 protobist_rdata; /* 0x5EC */
vu32 config_sample_delay; /* 0x5F0 */
vu32 cfg_update; /* 0x5F4 */
vu32 rsvd_0x5f8[2]; /* 0x5F8-0x5FC */
vu32 pmacro_quse_ddll_rank0_0; /* 0x600 */
vu32 pmacro_quse_ddll_rank0_1; /* 0x604 */
vu32 pmacro_quse_ddll_rank0_2; /* 0x608 */
vu32 pmacro_quse_ddll_rank0_3; /* 0x60C */
vu32 pmacro_quse_ddll_rank0_4; /* 0x610 */
vu32 pmacro_quse_ddll_rank0_5; /* 0x614 */
vu32 rsvd_0x618[2]; /* 0x618-0x61C */
vu32 pmacro_quse_ddll_rank1_0; /* 0x620 */
vu32 pmacro_quse_ddll_rank1_1; /* 0x624 */
vu32 pmacro_quse_ddll_rank1_2; /* 0x628 */
vu32 pmacro_quse_ddll_rank1_3; /* 0x62C */
vu32 pmacro_quse_ddll_rank1_4; /* 0x630 */
vu32 pmacro_quse_ddll_rank1_5; /* 0x634 */
vu32 rsvd_0x638[2]; /* 0x638-0x63C */
vu32 pmacro_ob_ddll_long_dq_rank0_0; /* 0x640 */
vu32 pmacro_ob_ddll_long_dq_rank0_1; /* 0x644 */
vu32 pmacro_ob_ddll_long_dq_rank0_2; /* 0x648 */
vu32 pmacro_ob_ddll_long_dq_rank0_3; /* 0x64C */
vu32 pmacro_ob_ddll_long_dq_rank0_4; /* 0x650 */
vu32 pmacro_ob_ddll_long_dq_rank0_5; /* 0x654 */
vu32 rsvd_0x658[2]; /* 0x658-0x65C */
vu32 pmacro_ob_ddll_long_dq_rank1_0; /* 0x660 */
vu32 pmacro_ob_ddll_long_dq_rank1_1; /* 0x664 */
vu32 pmacro_ob_ddll_long_dq_rank1_2; /* 0x668 */
vu32 pmacro_ob_ddll_long_dq_rank1_3; /* 0x66C */
vu32 pmacro_ob_ddll_long_dq_rank1_4; /* 0x670 */
vu32 pmacro_ob_ddll_long_dq_rank1_5; /* 0x674 */
vu32 rsvd_0x678[2]; /* 0x678-0x67C */
vu32 pmacro_ob_ddll_long_dqs_rank0_0; /* 0x680 */
vu32 pmacro_ob_ddll_long_dqs_rank0_1; /* 0x684 */
vu32 pmacro_ob_ddll_long_dqs_rank0_2; /* 0x688 */
vu32 pmacro_ob_ddll_long_dqs_rank0_3; /* 0x68C */
vu32 pmacro_ob_ddll_long_dqs_rank0_4; /* 0x690 */
vu32 pmacro_ob_ddll_long_dqs_rank0_5; /* 0x694 */
vu32 rsvd_0x698[2]; /* 0x698-0x69C */
vu32 pmacro_ob_ddll_long_dqs_rank1_0; /* 0x6A0 */
vu32 pmacro_ob_ddll_long_dqs_rank1_1; /* 0x6A4 */
vu32 pmacro_ob_ddll_long_dqs_rank1_2; /* 0x6A8 */
vu32 pmacro_ob_ddll_long_dqs_rank1_3; /* 0x6AC */
vu32 pmacro_ob_ddll_long_dqs_rank1_4; /* 0x6B0 */
vu32 pmacro_ob_ddll_long_dqs_rank1_5; /* 0x6B4 */
vu32 rsvd_0x6B8[2]; /* 0x6B8-0x6BC */
vu32 pmacro_ib_ddll_long_dqs_rank0_0; /* 0x6C0 */
vu32 pmacro_ib_ddll_long_dqs_rank0_1; /* 0x6C4 */
vu32 pmacro_ib_ddll_long_dqs_rank0_2; /* 0x6C8 */
vu32 pmacro_ib_ddll_long_dqs_rank0_3; /* 0x6CC */
vu32 pmacro_ib_ddll_long_dqs_rank0_4; /* 0x6D0 */
vu32 pmacro_ib_ddll_long_dqs_rank0_5; /* 0x6D4 */
vu32 rsvd_0x6D8[2]; /* 0x6D8-0x6DC */
vu32 pmacro_ib_ddll_long_dqs_rank1_0; /* 0x6E0 */
vu32 pmacro_ib_ddll_long_dqs_rank1_1; /* 0x6E4 */
vu32 pmacro_ib_ddll_long_dqs_rank1_2; /* 0x6E8 */
vu32 pmacro_ib_ddll_long_dqs_rank1_3; /* 0x6EC */
vu32 pmacro_ib_ddll_long_dqs_rank1_4; /* 0x6F0 */
vu32 pmacro_ib_ddll_long_dqs_rank1_5; /* 0x6F4 */
vu32 rsvd_0x6F8[2]; /* 0x6F8-0x6FC */
vu32 pmacro_autocal_cfg0; /* 0x700 */
vu32 pmacro_autocal_cfg1; /* 0x704 */
vu32 pmacro_autocal_cfg2; /* 0x708 */
vu32 rsvd_0x70C[5]; /* 0x70C-0x71C */
vu32 pmacro_tx_pwrd_0; /* 0x720 */
vu32 pmacro_tx_pwrd_1; /* 0x724 */
vu32 pmacro_tx_pwrd_2; /* 0x728 */
vu32 pmacro_tx_pwrd_3; /* 0x72C */
vu32 pmacro_tx_pwrd_4; /* 0x730 */
vu32 pmacro_tx_pwrd_5; /* 0x734 */
vu32 rsvd_0x738[2]; /* 0x738-0x73C */
vu32 pmacro_tx_sel_clk_src_0; /* 0x740 */
vu32 pmacro_tx_sel_clk_src_1; /* 0x744 */
vu32 pmacro_tx_sel_clk_src_2; /* 0x748 */
vu32 pmacro_tx_sel_clk_src_3; /* 0x74C */
vu32 pmacro_tx_sel_clk_src_4; /* 0x750 */
vu32 pmacro_tx_sel_clk_src_5; /* 0x754 */
vu32 rsvd_0x758[2]; /* 0x758-0x75C */
vu32 pmacro_ddll_bypass; /* 0x760 */
vu32 rsvd_0x764[3]; /* 0x764-0x76C */
vu32 pmacro_ddll_pwrd_0; /* 0x770 */
vu32 pmacro_ddll_pwrd_1; /* 0x774 */
vu32 pmacro_ddll_pwrd_2; /* 0x778 */
vu32 rsvd_0x77C[1]; /* 0x77C */
vu32 pmacro_cmd_ctrl_0; /* 0x780 */
vu32 pmacro_cmd_ctrl_1; /* 0x784 */
vu32 pmacro_cmd_ctrl_2; /* 0x788 */
vu32 rsvd_0x78C[277]; /* 0x78C-0xBDC */
vu32 pmacro_ib_vref_dq_0; /* 0xBE0 */
vu32 pmacro_ib_vref_dq_1; /* 0xBE4 */
vu32 pmacro_ib_vref_dq_2; /* 0xBE8 */
vu32 rsvd_0xBEC[1]; /* 0xBEC */
vu32 pmacro_ib_vref_dqs_0; /* 0xBF0 */
vu32 pmacro_ib_vref_dqs_1; /* 0xBF4 */
vu32 pmacro_ib_vref_dqs_2; /* 0xBF8 */
vu32 rsvd_0xBFC[1]; /* 0xBFC */
vu32 pmacro_ddll_long_cmd_0; /* 0xC00 */
vu32 pmacro_ddll_long_cmd_1; /* 0xC04 */
vu32 pmacro_ddll_long_cmd_2; /* 0xC08 */
vu32 pmacro_ddll_long_cmd_3; /* 0xC0C */
vu32 pmacro_ddll_long_cmd_4; /* 0xC10 */
vu32 pmacro_ddll_long_cmd_5; /* 0xC14 */
vu32 rsvd_0xC18[2]; /* 0xC18-0xC1C */
vu32 pmacro_ddll_short_cmd_0; /* 0xC20 */
vu32 pmacro_ddll_short_cmd_1; /* 0xC24 */
vu32 pmacro_ddll_short_cmd_2; /* 0xC28 */
vu32 rsvd_0xC2C[2]; /* 0xC2C-0xC30 */
vu32 pmacro_vttgen_ctrl0; /* 0xC34 */
vu32 pmacro_vttgen_ctrl1; /* 0xC38 */
vu32 pmacro_bg_bias_ctrl_0; /* 0xC3C */
vu32 pmacro_pad_cfg_ctrl; /* 0xC40 */
vu32 pmacro_zctrl; /* 0xC44 */
vu32 pmacro_rx_term; /* 0xC48 */
vu32 pmacro_cmd_tx_drv; /* 0xC4C */
vu32 pmacro_cmd_pad_rx_ctrl; /* 0xC50 */
vu32 pmacro_data_pad_rx_ctrl; /* 0xC54 */
vu32 pmacro_cmd_rx_term_mode; /* 0xC58 */
vu32 pmacro_data_rx_term_mode; /* 0xC5C */
vu32 pmacro_cmd_pad_tx_ctrl; /* 0xC60 */
vu32 pmacro_data_pad_tx_ctrl; /* 0xC64 */
vu32 pmacro_common_pad_tx_ctrl; /* 0xC68 */
vu32 rsvd_0xC6C[1]; /* 0xC6C */
vu32 pmacro_dq_tx_drv; /* 0xC70 */
vu32 pmacro_ca_tx_drv; /* 0xC74 */
vu32 pmacro_autocal_cfg_common; /* 0xC78 */
vu32 rsvd_0xC7C[1]; /* 0xC7C */
vu32 pmacro_brick_mapping0; /* 0xC80 */
vu32 pmacro_brick_mapping1; /* 0xC84 */
vu32 pmacro_brick_mapping2; /* 0xC88 */
vu32 rsvd_0xC8C[25]; /* 0xC8C-0xCEC */
vu32 pmacro_vttgen_ctrl2; /* 0xCF0 */
vu32 pmacro_ib_rxrt; /* 0xCF4 */
vu32 pmacro_training_ctrl0; /* 0xCF8 */
vu32 pmacro_training_ctrl1; /* 0xCFC */
};
#endif /* __SOC_NVIDIA_TEGRA210_EMC_H__ */

98
ariane/src/hwinit/flow.h Normal file
View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef _TEGRA210_FLOW_H_
#define _TEGRA210_FLOW_H_
#include "types.h"
struct flow_ctlr {
vu32 halt_cpu_events; /* offset 0x00 */
vu32 halt_cop_events; /* offset 0x04 */
vu32 cpu_csr; /* offset 0x08 */
vu32 cop_csr; /* offset 0x0c */
vu32 xrq_events; /* offset 0x10 */
vu32 halt_cpu1_events; /* offset 0x14 */
vu32 cpu1_csr; /* offset 0x18 */
vu32 halt_cpu2_events; /* offset 0x1c */
vu32 cpu2_csr; /* offset 0x20 */
vu32 halt_cpu3_events; /* offset 0x24 */
vu32 cpu3_csr; /* offset 0x28 */
vu32 cluster_control; /* offset 0x2c */
vu32 halt_cop1_events; /* offset 0x30 */
vu32 halt_cop1_csr; /* offset 0x34 */
vu32 cpu_pwr_csr; /* offset 0x38 */
vu32 mpid; /* offset 0x3c */
vu32 ram_repair; /* offset 0x40 */
vu32 flow_dbg_sel; /* offset 0x44 */
vu32 flow_dbg_cnt0; /* offset 0x48 */
vu32 flow_dbg_cnt1; /* offset 0x4c */
vu32 flow_dbg_qual; /* offset 0x50 */
vu32 flow_ctlr_spare; /* offset 0x54 */
vu32 reserved; /* offset 0x58 */
vu32 fc_seq_intercept; /* offset 0x5c */
vu32 cc4_retention_control; /* offset 0x64 */
vu32 cc4_fc_status; /* offset 0x68 */
vu32 cc4_core0_ctrl; /* offset 0x6c */
vu32 cc4_core1_ctrl; /* offset 0x70 */
vu32 cc4_core2_ctrl; /* offset 0x74 */
vu32 cc4_core3_ctrl; /* offset 0x78 */
vu32 core0_idle_counter; /* offset 0x7c */
vu32 core1_idle_counter; /* offset 0x80 */
vu32 core2_idle_counter; /* offset 0x84 */
vu32 core3_idle_counter; /* offset 0x88 */
vu32 cc4_hvc_retry; /* offset 0x8c */
vu32 l2flush_timeout_cntr; /* offset 0x90 */
vu32 l2flush_control; /* offset 0x94 */
vu32 bpmp_cluster_control; /* offset 0x98 */
};
enum {
FLOW_MODE_SHIFT = 29,
FLOW_MODE_MASK = 0x7 << FLOW_MODE_SHIFT,
FLOW_MODE_NONE = 0 << FLOW_MODE_SHIFT,
FLOW_MODE_RUN_AND_INT = 1 << FLOW_MODE_SHIFT,
FLOW_MODE_WAITEVENT = 2 << FLOW_MODE_SHIFT,
FLOW_MODE_WAITEVENT_AND_INT = 3 << FLOW_MODE_SHIFT,
FLOW_MODE_STOP_UNTIL_IRQ = 4 << FLOW_MODE_SHIFT,
FLOW_MODE_STOP_UNTIL_IRQ_AND_INT = 5 << FLOW_MODE_SHIFT,
FLOW_MODE_STOP_UNTIL_EVENT_AND_IRQ = 6 << FLOW_MODE_SHIFT,
};
/* HALT_COP_EVENTS_0, 0x04 */
enum {
FLOW_EVENT_GIC_FIQ = 1 << 8,
FLOW_EVENT_GIC_IRQ = 1 << 9,
FLOW_EVENT_LIC_FIQ = 1 << 10,
FLOW_EVENT_LIC_IRQ = 1 << 11,
FLOW_EVENT_IBF = 1 << 12,
FLOW_EVENT_IBE = 1 << 13,
FLOW_EVENT_OBF = 1 << 14,
FLOW_EVENT_OBE = 1 << 15,
FLOW_EVENT_XRQ_A = 1 << 16,
FLOW_EVENT_XRQ_B = 1 << 17,
FLOW_EVENT_XRQ_C = 1 << 18,
FLOW_EVENT_XRQ_D = 1 << 19,
FLOW_EVENT_SMP30 = 1 << 20,
FLOW_EVENT_SMP31 = 1 << 21,
FLOW_EVENT_X_RDY = 1 << 22,
FLOW_EVENT_SEC = 1 << 23,
FLOW_EVENT_MSEC = 1 << 24,
FLOW_EVENT_USEC = 1 << 25,
FLOW_EVENT_X32K = 1 << 26,
FLOW_EVENT_SCLK = 1 << 27,
FLOW_EVENT_JTAG = 1 << 28
};
#endif /* _TEGRA210_FLOW_H_ */

28
ariane/src/hwinit/fuse.c Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fuse.h"
#include "t210.h"
void fuse_disable_program()
{
FUSE(FUSE_DISABLEREGPROGRAM) = 1;
}
u32 fuse_read_odm(u32 idx)
{
return FUSE(FUSE_RESERVED_ODMX(idx));
}

44
ariane/src/hwinit/fuse.h Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FUSE_H_
#define _FUSE_H_
#include "types.h"
/*! Fuse registers. */
#define FUSE_CTRL 0x0
#define FUSE_ADDR 0x4
#define FUSE_RDATA 0x8
#define FUSE_WDATA 0xC
#define FUSE_TIME_RD1 0x10
#define FUSE_TIME_RD2 0x14
#define FUSE_TIME_PGM1 0x18
#define FUSE_TIME_PGM2 0x1C
#define FUSE_PRIV2INTFC 0x20
#define FUSE_FUSEBYPASS 0x24
#define FUSE_PRIVATEKEYDISABLE 0x28
#define FUSE_DISABLEREGPROGRAM 0x2C
#define FUSE_WRITE_ACCESS_SW 0x30
#define FUSE_PWR_GOOD_SW 0x34
/*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
void fuse_disable_program();
u32 fuse_read_odm(u32 idx);
#endif

94
ariane/src/hwinit/gpio.c Normal file
View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gpio.h"
#include "t210.h"
static const u16 _gpio_cnf[31] = {
0x000, 0x004, 0x008, 0x00C,
0x100, 0x104, 0x108, 0x10C,
0x200, 0x204, 0x208, 0x20C,
0x300, 0x304, 0x308, 0x30C,
0x400, 0x404, 0x408, 0x40C,
0x500, 0x504, 0x508, 0x50C,
0x600, 0x604, 0x608, 0x60C,
0x700, 0x704, 0x708
};
static const u16 _gpio_oe[31] = {
0x010, 0x014, 0x018, 0x01C,
0x110, 0x114, 0x118, 0x11C,
0x210, 0x214, 0x218, 0x21C,
0x310, 0x314, 0x318, 0x31C,
0x410, 0x414, 0x418, 0x41C,
0x510, 0x514, 0x518, 0x51C,
0x610, 0x614, 0x618, 0x61C,
0x710, 0x714, 0x718
};
static const u16 _gpio_out[31] = {
0x020, 0x024, 0x028, 0x02C,
0x120, 0x124, 0x128, 0x12C,
0x220, 0x224, 0x228, 0x22C,
0x320, 0x324, 0x328, 0x32C,
0x420, 0x424, 0x428, 0x42C,
0x520, 0x524, 0x528, 0x52C,
0x620, 0x624, 0x628, 0x62C,
0x720, 0x724, 0x728
};
static const u16 _gpio_in[31] = {
0x030, 0x034, 0x038, 0x03C,
0x130, 0x134, 0x138, 0x13C,
0x230, 0x234, 0x238, 0x23C,
0x330, 0x334, 0x338, 0x33C,
0x430, 0x434, 0x438, 0x43C,
0x530, 0x534, 0x538, 0x53C,
0x630, 0x634, 0x638, 0x63C,
0x730, 0x734, 0x738
};
void gpio_config(u32 port, u32 pins, int mode)
{
if (mode)
GPIO(_gpio_cnf[port]) |= pins;
else
GPIO(_gpio_cnf[port]) &= ~pins;
(void)GPIO(_gpio_cnf[port]);
}
void gpio_output_enable(u32 port, u32 pins, int enable)
{
if (enable)
GPIO(_gpio_oe[port]) |= pins;
else
GPIO(_gpio_oe[port]) &= ~pins;
(void)GPIO(_gpio_oe[port]);
}
void gpio_write(u32 port, u32 pins, int high)
{
if (high)
GPIO(_gpio_out[port]) |= pins;
else
GPIO(_gpio_out[port]) &= ~pins;
(void)GPIO(_gpio_out[port]);
}
int gpio_read(u32 port, u32 pins)
{
return GPIO(_gpio_in[port]) & pins ? 1 : 0;
}

89
ariane/src/hwinit/gpio.h Normal file
View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#include "types.h"
#define GPIO_MODE_SPIO 0
#define GPIO_MODE_GPIO 1
#define GPIO_OUTPUT_DISABLE 0
#define GPIO_OUTPUT_ENABLE 1
#define GPIO_LOW 0
#define GPIO_HIGH 1
/*! GPIO pins (0-7 for each port). */
#define GPIO_PIN_0 (1 << 0)
#define GPIO_PIN_1 (1 << 1)
#define GPIO_PIN_2 (1 << 2)
#define GPIO_PIN_3 (1 << 3)
#define GPIO_PIN_4 (1 << 4)
#define GPIO_PIN_5 (1 << 5)
#define GPIO_PIN_6 (1 << 6)
#define GPIO_PIN_7 (1 << 7)
/*! GPIO ports (A-EE). */
#define GPIO_PORT_A 0
#define GPIO_PORT_B 1
#define GPIO_PORT_C 2
#define GPIO_PORT_D 3
#define GPIO_PORT_E 4
#define GPIO_PORT_F 5
#define GPIO_PORT_G 6
#define GPIO_PORT_H 7
#define GPIO_PORT_I 8
#define GPIO_PORT_J 9
#define GPIO_PORT_K 10
#define GPIO_PORT_L 11
#define GPIO_PORT_M 12
#define GPIO_PORT_N 13
#define GPIO_PORT_O 14
#define GPIO_PORT_P 15
#define GPIO_PORT_Q 16
#define GPIO_PORT_R 17
#define GPIO_PORT_S 18
#define GPIO_PORT_T 19
#define GPIO_PORT_U 20
#define GPIO_PORT_V 21
#define GPIO_PORT_W 22
#define GPIO_PORT_X 23
#define GPIO_PORT_Y 24
#define GPIO_PORT_Z 25
#define GPIO_PORT_AA 26
#define GPIO_PORT_BB 27
#define GPIO_PORT_CC 28
#define GPIO_PORT_DD 29
#define GPIO_PORT_EE 30
void gpio_config(u32 port, u32 pins, int mode);
void gpio_output_enable(u32 port, u32 pins, int enable);
void gpio_write(u32 port, u32 pins, int high);
int gpio_read(u32 port, u32 pins);
static inline u32 gpio_index_port(u32 index)
{
return index >> 3;
}
static inline u32 gpio_index_bitmask(u32 index)
{
return 1u << (index & 7);
}
#define GPIO_DECOMPOSE(x) gpio_index_port(x), gpio_index_bitmask(x)
#endif

278
ariane/src/hwinit/hwinit.c Normal file
View file

@ -0,0 +1,278 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clock.h"
#include "uart.h"
#include "i2c.h"
#include "sdram.h"
#include "di.h"
#include "mc.h"
#include "t210.h"
#include "pmc.h"
#include "gpio.h"
#include "pinmux.h"
#include "max77620.h"
#include "max7762x.h"
#include "fuse.h"
#include "timer.h"
#include "carveout.h"
#include <string.h>
void config_oscillators()
{
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4;
SYSCTR0(SYSCTR0_CNTFID0) = 19200000;
TMR(TMR_US_CFG_OFFS) = 0x45F;
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071;
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE;
PMC(APBDEV_PMC_OSC_EDPD_OVER) |= 0x400000;
PMC(APBDEV_PMC_CNTRL2) |= 0x1000;
PMC(APBDEV_PMC_SCRATCH188) = (PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF) | 0x2000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10;
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF;
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444;
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2;
}
void config_gpios()
{
pinmux_set_config(PINMUX_UART2_TX_INDEX, 0);
pinmux_set_config(PINMUX_UART3_TX_INDEX, 0);
pinmux_set_config(PINMUX_GPIO_PE6_INDEX, PINMUX_INPUT_ENABLE);
pinmux_set_config(PINMUX_GPIO_PH6_INDEX, PINMUX_INPUT_ENABLE);
gpio_config(GPIO_BY_NAME(UART2_TX), GPIO_MODE_GPIO);
gpio_config(GPIO_BY_NAME(UART3_TX), GPIO_MODE_GPIO);
gpio_config(GPIO_DECOMPOSE(GPIO_E6_INDEX), GPIO_MODE_GPIO);
gpio_config(GPIO_DECOMPOSE(GPIO_H6_INDEX), GPIO_MODE_GPIO);
gpio_output_enable(GPIO_BY_NAME(UART2_TX), GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_BY_NAME(UART3_TX), GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_DECOMPOSE(GPIO_E6_INDEX), GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_DECOMPOSE(GPIO_H6_INDEX), GPIO_OUTPUT_DISABLE);
pinmux_config_i2c(I2C_1);
pinmux_config_i2c(I2C_5);
//unused UART_A
PINMUX_SET_UNUSED_BY_NAME(UART1_RX);
PINMUX_SET_UNUSED_BY_NAME(UART1_TX);
PINMUX_SET_UNUSED_BY_NAME(UART1_CTS);
PINMUX_SET_UNUSED_BY_NAME(UART1_RTS);
//Configure volume up/down as inputs.
gpio_config(GPIO_BY_NAME(BUTTON_VOL_UP), GPIO_MODE_GPIO);
gpio_config(GPIO_BY_NAME(BUTTON_VOL_DOWN), GPIO_MODE_GPIO);
gpio_output_enable(GPIO_BY_NAME(BUTTON_VOL_UP), GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_BY_NAME(BUTTON_VOL_DOWN), GPIO_OUTPUT_DISABLE);
//Configure SD card detect pin
pinmux_set_config(PINMUX_GPIO_Z1, PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | PINMUX_GPIO_PZ1_FUNC_SDMMC1);
gpio_config(GPIO_DECOMPOSE(GPIO_Z1_INDEX), GPIO_MODE_GPIO);
gpio_output_enable(GPIO_DECOMPOSE(GPIO_Z1_INDEX), GPIO_OUTPUT_DISABLE);
APB_MISC(APB_MISC_GP_VGPIO_GPIO_MUX_SEL) = 0; //use GPIO for all SDMMC
//Configure SD power enable pin (powered off by default)
pinmux_set_config(PINMUX_DMIC3_CLK_INDEX, PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN | PINMUX_DMIC3_CLK_FUNC_I2S5A); //not sure about the altfunc here
gpio_config(GPIO_BY_NAME(DMIC3_CLK), GPIO_MODE_GPIO);
gpio_write(GPIO_BY_NAME(DMIC3_CLK), GPIO_LOW);
gpio_output_enable(GPIO_BY_NAME(DMIC3_CLK), GPIO_OUTPUT_ENABLE);
}
void config_pmc_scratch()
{
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF;
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE;
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= 0x10;
}
void mbist_workaround()
{
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000u;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = CLK_Y_APE;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = CLK_X_VIC;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = CLK_L_DISP1 | CLK_L_HOST1X;
usleep(2);
I2S(0x0A0) |= 0x400;
I2S(0x088) &= 0xFFFFFFFE;
I2S(0x1A0) |= 0x400;
I2S(0x188) &= 0xFFFFFFFE;
I2S(0x2A0) |= 0x400;
I2S(0x288) &= 0xFFFFFFFE;
I2S(0x3A0) |= 0x400;
I2S(0x388) &= 0xFFFFFFFE;
I2S(0x4A0) |= 0x400;
I2S(0x488) &= 0xFFFFFFFE;
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4;
VIC(0x8C) = 0xFFFFFFFF;
usleep(2);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = CLK_Y_APE;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = CLK_L_DISP1 | CLK_L_HOST1X;
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = CLK_X_VIC;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = CLK_H_PMC | CLK_H_FUSE;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = CLK_L_RTC | CLK_L_TMR | CLK_L_GPIO | CLK_L_USBD | CLK_L_CACHE2;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = CLK_U_CSITE | CLK_U_IRAMA | CLK_U_IRAMB | CLK_U_IRAMC | CLK_U_IRAMD | CLK_U_CRAM2;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = CLK_V_MSELECT | CLK_V_APB2APE | CLK_V_SPDIF_DOUBLER | 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = CLK_W_PCIERX0 | CLK_W_PCIERX1 | CLK_W_PCIERX2 | CLK_W_PCIERX3 | CLK_W_PCIERX4 | CLK_W_PCIERX5 | CLK_W_ENTROPY | CLK_W_MC1;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = CLK_X_MC_CAPA | CLK_X_MC_CBPA | CLK_X_MC_CPU | CLK_X_MC_BBC | CLK_X_GPU | CLK_X_DPGAPB | CLK_X_PLLG_REF;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = CLK_Y_MC_CDPA | CLK_Y_MC_CCPA;
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = 0;
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE) = 0;
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000;
}
void config_hw()
{
clock_enable_fuse(1);
// This memset needs to happen here, else TZRAM will behave weirdly later on.
memset((void *)TZRAM_BASE, 0, 0x10000);
PMC(APBDEV_PMC_CRYPTO_OP) = 0;
SE(0x010) = 0x1F;
// Clear the boot reason to avoid problems later
PMC(APBDEV_PMC_SCRATCH200) = 0x0;
PMC(0x1B4) = 0x0;
APB_MISC(0x08) = (APB_MISC(0x08) & 0xF0) | (7 << 10);
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
mbist_workaround();
clock_enable_se();
//Enable fuse clock.
clock_enable_fuse(1);
//Disable fuse programming.
fuse_disable_program();
mc_enable();
config_oscillators();
APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
config_gpios();
#ifdef DEBUG_UART_PORT
clock_enable_uart(DEBUG_UART_PORT);
uart_init(DEBUG_UART_PORT, 115200);
pinmux_config_uart(DEBUG_UART_PORT);
#endif
clock_enable_cl_dvfs();
clock_enable_i2c(I2C_1);
clock_enable_i2c(I2C_5);
// Clock TZRAM
clock_enable_se();
static const clock_t clock_unk = { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, 0, 30, 0, 0 };
clock_enable(&clock_unk);
i2c_init(I2C_1);
i2c_init(I2C_5);
max77620_send_byte(MAX77620_REG_CNFGBBC, 0x40);
max77620_send_byte(MAX77620_REG_ONOFFCNFG1, 0x78);
max77620_send_byte(MAX77620_REG_FPS_CFG0, 0x38);
max77620_send_byte(MAX77620_REG_FPS_CFG1, 0x3A);
max77620_send_byte(MAX77620_REG_FPS_CFG2, 0x38);
max77620_regulator_config_fps(REGULATOR_LDO4);
max77620_regulator_config_fps(REGULATOR_LDO8);
max77620_regulator_config_fps(REGULATOR_SD0);
max77620_regulator_config_fps(REGULATOR_SD1);
max77620_regulator_config_fps(REGULATOR_SD3);
max77620_regulator_set_voltage(REGULATOR_SD0, 1125000); //1.125V
//Set SDMMC1 IO clamps to default value before changing voltage
PMC(APBDEV_PMC_PWR_DET_VAL) |= (1 << 12);
//Start up the SDMMC1 IO voltage regulator
max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);
max77620_regulator_enable(REGULATOR_LDO2, 1);
//Remove isolation from SDMMC1 and core domain
PMC(APBDEV_PMC_NO_IOPOWER) &= ~(1 << 12);
// Fix CPU/GPU after a L4T warmboot.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power.
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVC_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power.
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US);
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power.
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_DVC_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power.
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US);
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG,
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
config_pmc_scratch();
//CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = (CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888) | 0x3333;
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // Set SCLK to PLLP_OUT (408MHz).
//mc_config_carveout();
{
const struct sdram_params* sdram_params = sdram_get_params();
sdram_init(sdram_params);
//TODO: test this with LP0 wakeup.
//sdram_lp0_save_params(sdram_params);
}
/*
* IMPORTANT:
* DO NOT INITIALIZE ANY CARVEOUT BEFORE TZ.
*
* Trust Zone needs to be initialized after the DRAM initialization
* because carveout registers are programmed during DRAM init.
* cbmem_initialize() is dependent on the Trust Zone region
* initialization because CBMEM lives right below the Trust Zone which
* needs to be properly identified.
*/
trustzone_region_init();
// Now do various other carveouts
gpu_region_init();
nvdec_region_init();
tsec_region_init();
vpr_region_init();
print_carveouts();
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _HWINIT_H_
#define _HWINIT_H_
void config_hw();
void mbist_workaround();
void config_pmc_scratch();
void config_gpios();
void config_oscillators();
#endif

132
ariane/src/hwinit/i2c.c Normal file
View file

@ -0,0 +1,132 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "i2c.h"
#include "timer.h"
static u32 i2c_addrs[] = { 0x7000C000, 0x7000C400, 0x7000C500, 0x7000C700, 0x7000D000, 0x7000D100 };
static void _i2c_wait(vu32 *base)
{
base[0x23] = 0x25;
for (u32 i = 0; i < 20; i++)
{
usleep(1);
if (!(base[0x23] & 1))
break;
}
}
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
{
if (size > 4)
return 0;
u32 tmp = 0;
memcpy(&tmp, buf, size);
vu32 *base = (vu32 *)i2c_addrs[idx];
base[1] = x << 1; //Set x (send mode).
base[3] = tmp; //Set value.
base[0] = (2 * size - 2) | 0x2800; //Set size and send mode.
_i2c_wait(base); //Kick transaction.
base[0] = (base[0] & 0xFFFFFDFF) | 0x200;
while (base[7] & 0x100)
;
if (base[7] << 28)
return 0;
return 1;
}
static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
{
if (size > 4)
return 0;
vu32 *base = (vu32 *)i2c_addrs[idx];
base[1] = (x << 1) | 1; //Set x (recv mode).
base[0] = (2 * size - 2) | 0x2840; //Set size and recv mode.
_i2c_wait(base); //Kick transaction.
base[0] = (base[0] & 0xFFFFFDFF) | 0x200;
while (base[7] & 0x100)
;
if (base[7] << 28)
return 0;
u32 tmp = base[3]; //Get value.
memcpy(buf, &tmp, size);
return 1;
}
void i2c_init(u32 idx)
{
vu32 *base = (vu32 *)i2c_addrs[idx];
base[0x1B] = 0x50001;
base[0x21] = 0x90003;
_i2c_wait(base);
for (u32 i = 0; i < 10; i++)
{
msleep(20);
if (base[0x1A] & 0x800)
break;
}
(void)base[0x22];
base[0x1A] = base[0x1A];
}
u32 i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
{
u8 tmp[4];
if (size > 3)
return 0;
tmp[0] = y;
memcpy(tmp + 1, buf, size);
return _i2c_send_pkt(idx, x, tmp, size + 1);
}
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
{
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
if (res)
res = _i2c_recv_pkt(idx, buf, size, x);
return res;
}
u32 i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
{
return i2c_send_buf_small(idx, x, y, &b, 1);
}
u8 i2c_recv_byte(u32 idx, u32 x, u32 y)
{
u8 tmp;
i2c_recv_buf_small(&tmp, 1, idx, x, y);
return tmp;
}

35
ariane/src/hwinit/i2c.h Normal file
View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _I2C_H_
#define _I2C_H_
#include "types.h"
#define I2C_1 0
#define I2C_2 1
#define I2C_3 2
#define I2C_4 3
#define I2C_5 4
#define I2C_6 5
void i2c_init(u32 idx);
u32 i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
u32 i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
#endif

42
ariane/src/hwinit/kfuse.c Normal file
View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "kfuse.h"
#include "clock.h"
#include "t210.h"
int kfuse_read(u32 *buf)
{
int res = 0;
clock_enable_kfuse();
while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
;
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
goto out;
KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC;
for (int i = 0; i < KFUSE_NUM_WORDS; i++)
buf[i] = KFUSE(KFUSE_KEYS);
res = 1;
out:;
clock_disable_kfuse();
return res;
}

41
ariane/src/hwinit/kfuse.h Normal file
View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _KFUSE_H_
#define _KFUSE_H_
#include "types.h"
#define KFUSE_STATE_SOFTRESET (1<<31)
#define KFUSE_STATE_STOP (1<<25)
#define KFUSE_STATE_RESTART (1<<24)
#define KFUSE_STATE_CRCPASS (1<<17)
#define KFUSE_STATE_DONE (1<<16)
#define KFUSE_STATE_ERRBLOCK_MASK 0x3F00
#define KFUSE_STATE_ERRBLOCK_SHIFT 8
#define KFUSE_STATE_CURBLOCK_MASK 0x3F
#define KFUSE_KEYADDR_AUTOINC (1<<16)
#define KFUSE_STATE 0x80
#define KFUSE_KEYADDR 0x88
#define KFUSE_KEYS 0x8C
#define KFUSE_NUM_WORDS 144
int kfuse_read(u32 *buf);
#endif

View file

@ -0,0 +1,328 @@
/*
* Defining registers address and its bit definitions of MAX77620 and MAX20024
*
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*/
#ifndef _MFD_MAX77620_H_
#define _MFD_MAX77620_H_
#define MAX77620_I2C_ADDR 0x3C
/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
#define MAX77620_REG_CNFGGLBL1 0x00
#define MAX77620_REG_CNFGGLBL2 0x01
#define MAX77620_REG_CNFGGLBL3 0x02
#define MAX77620_REG_CNFG1_32K 0x03
#define MAX77620_REG_CNFGBBC 0x04
#define MAX77620_REG_IRQTOP 0x05
#define MAX77620_REG_INTLBT 0x06
#define MAX77620_REG_IRQSD 0x07
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
#define MAX77620_REG_IRQ_LVL2_L8 0x09
#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
#define MAX77620_REG_ONOFFIRQ 0x0B
#define MAX77620_REG_NVERC 0x0C
#define MAX77620_REG_IRQTOPM 0x0D
#define MAX77620_REG_INTENLBT 0x0E
#define MAX77620_REG_IRQMASKSD 0x0F
#define MAX77620_REG_IRQ_MSK_L0_7 0x10
#define MAX77620_REG_IRQ_MSK_L8 0x11
#define MAX77620_REG_ONOFFIRQM 0x12
#define MAX77620_REG_STATLBT 0x13
#define MAX77620_REG_STATSD 0x14
#define MAX77620_REG_ONOFFSTAT 0x15
/* SD and LDO Registers */
#define MAX77620_REG_SD0 0x16
#define MAX77620_REG_SD1 0x17
#define MAX77620_REG_SD2 0x18
#define MAX77620_REG_SD3 0x19
#define MAX77620_REG_SD4 0x1A
#define MAX77620_REG_DVSSD0 0x1B
#define MAX77620_REG_DVSSD1 0x1C
#define MAX77620_REG_SD0_CFG 0x1D
#define MAX77620_REG_SD1_CFG 0x1E
#define MAX77620_REG_SD2_CFG 0x1F
#define MAX77620_REG_SD3_CFG 0x20
#define MAX77620_REG_SD4_CFG 0x21
#define MAX77620_REG_SD_CFG2 0x22
#define MAX77620_REG_LDO0_CFG 0x23
#define MAX77620_REG_LDO0_CFG2 0x24
#define MAX77620_REG_LDO1_CFG 0x25
#define MAX77620_REG_LDO1_CFG2 0x26
#define MAX77620_REG_LDO2_CFG 0x27
#define MAX77620_REG_LDO2_CFG2 0x28
#define MAX77620_REG_LDO3_CFG 0x29
#define MAX77620_REG_LDO3_CFG2 0x2A
#define MAX77620_REG_LDO4_CFG 0x2B
#define MAX77620_REG_LDO4_CFG2 0x2C
#define MAX77620_REG_LDO5_CFG 0x2D
#define MAX77620_REG_LDO5_CFG2 0x2E
#define MAX77620_REG_LDO6_CFG 0x2F
#define MAX77620_REG_LDO6_CFG2 0x30
#define MAX77620_REG_LDO7_CFG 0x31
#define MAX77620_REG_LDO7_CFG2 0x32
#define MAX77620_REG_LDO8_CFG 0x33
#define MAX77620_REG_LDO8_CFG2 0x34
#define MAX77620_REG_LDO_CFG3 0x35
#define MAX77620_LDO_SLEW_RATE_MASK 0x1
/* LDO Configuration 3 */
#define MAX77620_TRACK4_MASK (1 << 5)
#define MAX77620_TRACK4_SHIFT 5
/* Voltage */
#define MAX77620_SDX_VOLT_MASK 0xFF
#define MAX77620_SD0_VOLT_MASK 0x3F
#define MAX77620_SD1_VOLT_MASK 0x7F
#define MAX77620_LDO_VOLT_MASK 0x3F
#define MAX77620_REG_GPIO0 0x36
#define MAX77620_REG_GPIO1 0x37
#define MAX77620_REG_GPIO2 0x38
#define MAX77620_REG_GPIO3 0x39
#define MAX77620_REG_GPIO4 0x3A
#define MAX77620_REG_GPIO5 0x3B
#define MAX77620_REG_GPIO6 0x3C
#define MAX77620_REG_GPIO7 0x3D
#define MAX77620_REG_PUE_GPIO 0x3E
#define MAX77620_REG_PDE_GPIO 0x3F
#define MAX77620_REG_AME_GPIO 0x40
#define MAX77620_REG_ONOFFCNFG1 0x41
#define MAX77620_REG_ONOFFCNFG2 0x42
/* FPS Registers */
#define MAX77620_REG_FPS_CFG0 0x43
#define MAX77620_REG_FPS_CFG1 0x44
#define MAX77620_REG_FPS_CFG2 0x45
#define MAX77620_REG_FPS_LDO0 0x46
#define MAX77620_REG_FPS_LDO1 0x47
#define MAX77620_REG_FPS_LDO2 0x48
#define MAX77620_REG_FPS_LDO3 0x49
#define MAX77620_REG_FPS_LDO4 0x4A
#define MAX77620_REG_FPS_LDO5 0x4B
#define MAX77620_REG_FPS_LDO6 0x4C
#define MAX77620_REG_FPS_LDO7 0x4D
#define MAX77620_REG_FPS_LDO8 0x4E
#define MAX77620_REG_FPS_SD0 0x4F
#define MAX77620_REG_FPS_SD1 0x50
#define MAX77620_REG_FPS_SD2 0x51
#define MAX77620_REG_FPS_SD3 0x52
#define MAX77620_REG_FPS_SD4 0x53
#define MAX77620_REG_FPS_NONE 0
#define MAX77620_FPS_SRC_MASK 0xC0
#define MAX77620_FPS_SRC_SHIFT 6
#define MAX77620_FPS_PU_PERIOD_MASK 0x38
#define MAX77620_FPS_PU_PERIOD_SHIFT 3
#define MAX77620_FPS_PD_PERIOD_MASK 0x07
#define MAX77620_FPS_PD_PERIOD_SHIFT 0
#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
#define MAX77620_FPS_EN_SRC_MASK 0x06
#define MAX77620_FPS_EN_SRC_SHIFT 1
#define MAX77620_FPS_ENFPS_SW_MASK 0x01
#define MAX77620_FPS_ENFPS_SW 0x01
/* Minimum and maximum FPS period time (in microseconds) are
* different for MAX77620 and Max20024.
*/
#define MAX77620_FPS_PERIOD_MIN_US 40
#define MAX20024_FPS_PERIOD_MIN_US 20
#define MAX77620_FPS_PERIOD_MAX_US 2560
#define MAX20024_FPS_PERIOD_MAX_US 5120
#define MAX77620_REG_FPS_GPIO1 0x54
#define MAX77620_REG_FPS_GPIO2 0x55
#define MAX77620_REG_FPS_GPIO3 0x56
#define MAX77620_REG_FPS_RSO 0x57
#define MAX77620_REG_CID0 0x58
#define MAX77620_REG_CID1 0x59
#define MAX77620_REG_CID2 0x5A
#define MAX77620_REG_CID3 0x5B
#define MAX77620_REG_CID4 0x5C
#define MAX77620_REG_CID5 0x5D
#define MAX77620_REG_DVSSD4 0x5E
#define MAX20024_REG_MAX_ADD 0x70
#define MAX77620_CID_DIDM_MASK 0xF0
#define MAX77620_CID_DIDM_SHIFT 4
/* CNCG2SD */
#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1)
#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2)
/* Device Identification Metal */
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
/* Device Indentification OTP */
#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
/* SD CNFG1 */
#define MAX77620_SD_SR_MASK 0xC0
#define MAX77620_SD_SR_SHIFT 6
#define MAX77620_SD_POWER_MODE_MASK 0x30
#define MAX77620_SD_POWER_MODE_SHIFT 4
#define MAX77620_SD_CFG1_ADE_MASK (1 << 3)
#define MAX77620_SD_CFG1_ADE_DISABLE 0
#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3)
#define MAX77620_SD_FPWM_MASK 0x04
#define MAX77620_SD_FPWM_SHIFT 2
#define MAX77620_SD_FSRADE_MASK 0x01
#define MAX77620_SD_FSRADE_SHIFT 0
#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2)
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2)
#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1)
#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0)
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0)
/* LDO_CNFG2 */
#define MAX77620_LDO_POWER_MODE_MASK 0xC0
#define MAX77620_LDO_POWER_MODE_SHIFT 6
#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
#define MAX77620_LDO_CFG2_ADE_DISABLE 0
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
#define MAX77620_LDO_CFG2_SS_SLOW 0
#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7)
#define MAX77620_IRQ_TOP_SD_MASK (1 << 6)
#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5)
#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4)
#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3)
#define MAX77620_IRQ_TOP_32K_MASK (1 << 2)
#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1)
#define MAX77620_IRQ_LBM_MASK (1 << 3)
#define MAX77620_IRQ_TJALRM1_MASK (1 << 2)
#define MAX77620_IRQ_TJALRM2_MASK (1 << 1)
#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0)
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1)
#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2)
#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3)
#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4)
#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5)
#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6)
#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7)
#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2)
#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
#define MAX20024_ONOFFCNFG1_CLRSE 0x18
#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7)
#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6)
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5)
#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2)
#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0)
#define MAX77620_GLBLM_MASK (1 << 0)
#define MAX77620_WDTC_MASK 0x3
#define MAX77620_WDTOFFC (1 << 4)
#define MAX77620_WDTSLPC (1 << 3)
#define MAX77620_WDTEN (1 << 2)
#define MAX77620_TWD_MASK 0x3
#define MAX77620_TWD_2s 0x0
#define MAX77620_TWD_16s 0x1
#define MAX77620_TWD_64s 0x2
#define MAX77620_TWD_128s 0x3
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
#define MAX77620_CNFGGLBL1_LBDAC 0x0E
#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
/* CNFG BBC registers */
#define MAX77620_CNFGBBC_ENABLE (1 << 0)
#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)
#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
#define MAX77620_FPS_COUNT 3
/* Interrupts */
enum {
MAX77620_IRQ_TOP_GLBL, /* Low-Battery */
MAX77620_IRQ_TOP_SD, /* SD power fail */
MAX77620_IRQ_TOP_LDO, /* LDO power fail */
MAX77620_IRQ_TOP_GPIO, /* TOP GPIO internal int to MAX77620 */
MAX77620_IRQ_TOP_RTC, /* RTC */
MAX77620_IRQ_TOP_32K, /* 32kHz oscillator */
MAX77620_IRQ_TOP_ONOFF, /* ON/OFF oscillator */
MAX77620_IRQ_LBT_MBATLOW, /* Thermal alarm status, > 120C */
MAX77620_IRQ_LBT_TJALRM1, /* Thermal alarm status, > 120C */
MAX77620_IRQ_LBT_TJALRM2, /* Thermal alarm status, > 140C */
};
/* GPIOs */
enum {
MAX77620_GPIO0,
MAX77620_GPIO1,
MAX77620_GPIO2,
MAX77620_GPIO3,
MAX77620_GPIO4,
MAX77620_GPIO5,
MAX77620_GPIO6,
MAX77620_GPIO7,
MAX77620_GPIO_NR,
};
/* FPS Source */
enum max77620_fps_src {
MAX77620_FPS_SRC_0,
MAX77620_FPS_SRC_1,
MAX77620_FPS_SRC_2,
MAX77620_FPS_SRC_NONE,
MAX77620_FPS_SRC_DEF,
};
enum max77620_chip_id {
MAX77620,
MAX20024,
};
#endif /* _MFD_MAX77620_H_ */

View file

@ -0,0 +1,166 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "max7762x.h"
#include "max77620.h"
#include "i2c.h"
#include "timer.h"
#include "lib/printk.h"
#define REGULATOR_SD 0
#define REGULATOR_LDO 1
typedef struct _max77620_regulator_t
{
u8 type;
const char *name;
u8 reg_sd;
u32 mv_step;
u32 mv_min;
u32 mv_default;
u32 mv_max;
u8 volt_addr;
u8 cfg_addr;
u8 volt_mask;
u8 enable_mask;
u8 enable_shift;
u8 status_mask;
u8 fps_addr;
u8 fps_src;
u8 pd_period;
u8 pu_period;
} max77620_regulator_t;
static const max77620_regulator_t _pmic_regulators[] = {
{ REGULATOR_SD, "sd0", MAX77620_REG_SD0, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x80, MAX77620_REG_FPS_SD0, MAX77620_FPS_SRC_1, 7, 1 },
{ REGULATOR_SD, "sd1", MAX77620_REG_SD1, 12500, 600000, 1100000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x40, MAX77620_REG_FPS_SD1, MAX77620_FPS_SRC_0, 1, 5 },
{ REGULATOR_SD, "sd2", MAX77620_REG_SD2, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x20, MAX77620_REG_FPS_SD2, MAX77620_FPS_SRC_1, 5, 2 },
{ REGULATOR_SD, "sd3", MAX77620_REG_SD3, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x10, MAX77620_REG_FPS_SD3, MAX77620_FPS_SRC_0, 3, 3 },
{ REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO0, MAX77620_FPS_SRC_NONE, 7, 0 },
{ REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO1, MAX77620_FPS_SRC_NONE, 7, 0 },
{ REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO2, MAX77620_FPS_SRC_NONE, 7, 0 },
{ REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO3, MAX77620_FPS_SRC_NONE, 7, 0 },
{ REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO4, MAX77620_FPS_SRC_0, 7, 1 },
{ REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO5, MAX77620_FPS_SRC_NONE, 7, 0 },
{ REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO6, MAX77620_FPS_SRC_NONE, 7, 0 },
{ REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO7, MAX77620_FPS_SRC_1, 4, 3 },
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, MAX77620_FPS_SRC_NONE, 7, 0 }
};
u32 max77620_send_byte(u32 regAddr, u8 dataByte)
{
return i2c_send_byte(I2C_5, 0x3C, regAddr, dataByte);
}
u8 max77620_recv_byte(u32 regAddr)
{
return i2c_recv_byte(I2C_5, 0x3C, regAddr);
}
u32 max7762x_send_byte(u32 devAddr, u32 regAddr, u8 dataByte)
{
return i2c_send_byte(I2C_5, devAddr, regAddr, dataByte);
}
u8 max7762x_recv_byte(u32 devAddr, u32 regAddr)
{
return i2c_recv_byte(I2C_5, devAddr, regAddr);
}
int max77620_regulator_get_status(u32 id)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
if (reg->type == REGULATOR_SD)
return (max77620_recv_byte(MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1;
else
return (max77620_recv_byte(reg->cfg_addr) & 8) ? 1 : 0;
}
int max77620_regulator_config_fps(u32 id)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
max77620_send_byte(reg->fps_addr, (reg->fps_src << 6) | (reg->pu_period << 3) | (reg->pd_period));
return 1;
}
int max77620_regulator_set_voltage(u32 id, u32 mv)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
if (mv < reg->mv_min || mv > reg->mv_max)
{
dbg_print("max77620_regulator_set_voltage: wanted voltage %u for regulator %u outside bounds (min: %u max: %u), NOT SETTING!\n",
mv, id, reg->mv_min, reg->mv_max);
return 0;
}
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
u8 val = max77620_recv_byte(reg->volt_addr);
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
max77620_send_byte(reg->volt_addr, val);
usleep(1000);
return 1;
}
int max77620_regulator_enable(u32 id, int enable)
{
if (id > REGULATOR_MAX)
return 0;
const max77620_regulator_t *reg = &_pmic_regulators[id];
u32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;
u8 val = max77620_recv_byte(addr);
if (enable)
val = (val & ~reg->enable_mask) | ((3 << reg->enable_shift) & reg->enable_mask);
else
val &= ~reg->enable_mask;
max77620_send_byte(addr, val);
usleep(1000);
return 1;
}
void max77620_config_default()
{
for (u32 i = 1; i <= REGULATOR_MAX; i++)
{
max77620_recv_byte(MAX77620_REG_CID4);
max77620_regulator_config_fps(i);
max77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);
if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
max77620_regulator_enable(i, 1);
}
max77620_send_byte(MAX77620_REG_SD_CFG2, 4);
}
void max77620_low_battery_monitor_config()
{
i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_CNFGGLBL1, MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_LBHYST_N | MAX77620_CNFGGLBL1_LBDAC_N);
}

View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MAX7762X_H_
#define _MAX7762X_H_
#include "types.h"
/*
* Switch Power domains (max77620):
* Name | Usage | uV step | uV min | uV default | uV max | Init
*-------+---------------+---------+--------+------------+---------+------------------
* sd0 | core | 12500 | 600000 | 625000 | 1400000 | 1.125V (pkg1.1)
* sd1 | SDRAM | 12500 | 600000 | 1125000 | 1125000 | 1.1V (pkg1.1)
* sd2 | ldo{0-1, 7-8} | 12500 | 600000 | 1325000 | 1350000 | 1.325V (pcv)
* sd3 | 1.8V general | 12500 | 600000 | 1800000 | 1800000 |
* ldo0 | Display Panel | 25000 | 800000 | 1200000 | 1200000 | 1.2V (pkg1.1)
* ldo1 | XUSB | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
* ldo3 | | 50000 | 800000 | 3100000 | 3100000 |
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
* ldo5 | | 50000 | 800000 | 1800000 | 1800000 |
* ldo6 | | 50000 | 800000 | 2900000 | 2900000 |
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
*/
/*
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
* MAX77620_REG_GPIOx: 0x9 sets output and enable
*/
/*! MAX77620 partitions. */
#define REGULATOR_SD0 0
#define REGULATOR_SD1 1
#define REGULATOR_SD2 2
#define REGULATOR_SD3 3
#define REGULATOR_LDO0 4
#define REGULATOR_LDO1 5
#define REGULATOR_LDO2 6
#define REGULATOR_LDO3 7
#define REGULATOR_LDO4 8
#define REGULATOR_LDO5 9
#define REGULATOR_LDO6 10
#define REGULATOR_LDO7 11
#define REGULATOR_LDO8 12
#define REGULATOR_MAX 12
#define MAX77621_CPU_I2C_ADDR 0x1B
#define MAX77621_GPU_I2C_ADDR 0x1C
#define MAX77621_VOUT_REG 0
#define MAX77621_VOUT_DVC_REG 1
#define MAX77621_CONTROL1_REG 2
#define MAX77621_CONTROL2_REG 3
/* MAX77621_VOUT */
#define MAX77621_VOUT_ENABLE (1 << 7)
#define MAX77621_VOUT_MASK 0x7F
#define MAX77621_VOUT_0_95V 0x37
#define MAX77621_VOUT_1_09V 0x4F
/* MAX77621_VOUT_DVC_DVS */
#define MAX77621_DVS_VOUT_MASK 0x7F
/* MAX77621_CONTROL1 */
#define MAX77621_SNS_ENABLE (1 << 7)
#define MAX77621_FPWM_EN_M (1 << 6)
#define MAX77621_NFSR_ENABLE (1 << 5)
#define MAX77621_AD_ENABLE (1 << 4)
#define MAX77621_BIAS_ENABLE (1 << 3)
#define MAX77621_FREQSHIFT_9PER (1 << 2)
#define MAX77621_RAMP_12mV_PER_US 0x0
#define MAX77621_RAMP_25mV_PER_US 0x1
#define MAX77621_RAMP_50mV_PER_US 0x2
#define MAX77621_RAMP_200mV_PER_US 0x3
#define MAX77621_RAMP_MASK 0x3
/* MAX77621_CONTROL2 */
#define MAX77621_WDTMR_ENABLE (1 << 6)
#define MAX77621_DISCH_ENBABLE (1 << 5)
#define MAX77621_FT_ENABLE (1 << 4)
#define MAX77621_T_JUNCTION_120 (1 << 7)
#define MAX77621_CKKADV_TRIP_DISABLE 0xC
#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0
#define MAX77621_CKKADV_TRIP_150mV_PER_US 0x4
#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8
#define MAX77621_INDUCTOR_MIN_30_PER 0x0
#define MAX77621_INDUCTOR_NOMINAL 0x1
#define MAX77621_INDUCTOR_PLUS_30_PER 0x2
#define MAX77621_INDUCTOR_PLUS_60_PER 0x3
u32 max77620_send_byte(u32 regAddr, u8 dataByte);
u8 max77620_recv_byte(u32 y);
u32 max7762x_send_byte(u32 devAddr, u32 regAddr, u8 dataByte);
u8 max7762x_recv_byte(u32 devAddr, u32 y);
int max77620_regulator_get_status(u32 id);
int max77620_regulator_config_fps(u32 id);
int max77620_regulator_set_voltage(u32 id, u32 mv);
int max77620_regulator_enable(u32 id, int enable);
void max77620_config_default();
void max77620_low_battery_monitor_config();
#endif

149
ariane/src/hwinit/mc.c Normal file
View file

@ -0,0 +1,149 @@
#include "mc.h"
#include "t210.h"
#include "mc_t210.h"
#include "clock.h"
#include "timer.h"
void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock)
{
struct tegra_mc_regs* const mc = (void *)MC_BASE;
mc->sec_carveout_bom = bom;
mc->sec_carveout_size_mb = size1mb;
if (lock)
mc->sec_carveout_reg_ctrl |= 1;
}
void mc_config_carveout()
{
struct tegra_mc_regs * const mc = (void *)MC_BASE;
*(vu32 *)0x8005FFFC = 0xC0EDBBCC;
mc->video_protect_gpu_override_0 = 1;
mc->video_protect_gpu_override_1 = 0;
mc->video_protect_bom = 0;
mc->video_protect_size_mb = 0;
mc->video_protect_reg_ctrl = 1;
//Configure TSEC carveout @ 0x90000000, 1MB.
//mc_config_tsec_carveout(0x90000000, 1, 0);
mc_config_tsec_carveout(0, 0, 1);
mc->mts_carveout_bom = 0;
mc->mts_carveout_size_mb = 0;
mc->mts_carveout_adr_hi = 0;
mc->mts_carveout_reg_ctrl = 1;
mc->security_carveout1_bom = 0;
mc->security_carveout1_bom_hi = 0;
mc->security_carveout1_size_128kb = 0;
mc->security_carveout1_ca0 = 0;
mc->security_carveout1_ca1 = 0;
mc->security_carveout1_ca2 = 0;
mc->security_carveout1_ca3 = 0;
mc->security_carveout1_ca4 = 0;
mc->security_carveout1_cfia0 = 0;
mc->security_carveout1_cfia1 = 0;
mc->security_carveout1_cfia2 = 0;
mc->security_carveout1_cfia3 = 0;
mc->security_carveout1_cfia4 = 0;
mc->security_carveout1_cfg0 = 0x4000006;
mc->security_carveout2_bom = 0x80020000;
mc->security_carveout2_bom_hi = 0;
mc->security_carveout2_size_128kb = 2;
mc->security_carveout2_ca0 = 0;
mc->security_carveout2_ca1 = 0;
mc->security_carveout2_ca2 = 0x3000000;
mc->security_carveout2_ca3 = 0;
mc->security_carveout2_ca4 = 0x300;
mc->security_carveout2_cfia0 = 0;
mc->security_carveout2_cfia1 = 0;
mc->security_carveout2_cfia2 = 0;
mc->security_carveout2_cfia3 = 0;
mc->security_carveout2_cfia4 = 0;
mc->security_carveout2_cfg0 = 0x440167e;
mc->security_carveout3_bom = 0;
mc->security_carveout3_bom_hi = 0;
mc->security_carveout3_size_128kb = 0;
mc->security_carveout3_ca0 = 0;
mc->security_carveout3_ca1 = 0;
mc->security_carveout3_ca2 = 0x3000000;
mc->security_carveout3_ca3 = 0;
mc->security_carveout3_ca4 = 0x300;
mc->security_carveout3_cfia0 = 0;
mc->security_carveout3_cfia1 = 0;
mc->security_carveout3_cfia2 = 0;
mc->security_carveout3_cfia3 = 0;
mc->security_carveout3_cfia4 = 0;
mc->security_carveout3_cfg0 = 0x4401e7e;
mc->security_carveout4_bom = 0;
mc->security_carveout4_bom_hi = 0;
mc->security_carveout4_size_128kb = 0;
mc->security_carveout4_ca0 = 0;
mc->security_carveout4_ca1 = 0;
mc->security_carveout4_ca2 = 0;
mc->security_carveout4_ca3 = 0;
mc->security_carveout4_ca4 = 0;
mc->security_carveout4_cfia0 = 0;
mc->security_carveout4_cfia1 = 0;
mc->security_carveout4_cfia2 = 0;
mc->security_carveout4_cfia3 = 0;
mc->security_carveout4_cfia4 = 0;
mc->security_carveout4_cfg0 = 0x8f;
mc->security_carveout5_bom = 0;
mc->security_carveout5_bom_hi = 0;
mc->security_carveout5_size_128kb = 0;
mc->security_carveout5_ca0 = 0;
mc->security_carveout5_ca1 = 0;
mc->security_carveout5_ca2 = 0;
mc->security_carveout5_ca3 = 0;
mc->security_carveout5_ca4 = 0;
mc->security_carveout5_cfia0 = 0;
mc->security_carveout5_cfia1 = 0;
mc->security_carveout5_cfia2 = 0;
mc->security_carveout5_cfia3 = 0;
mc->security_carveout5_cfia4 = 0;
mc->security_carveout5_cfg0 = 0x8f;
}
static const u32 ARC_CLK_OVR_ON = 1u << 19;
void mc_enable_ahb_redirect()
{
struct tegra_mc_regs* const mc = (void *)MC_BASE;
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) |= ARC_CLK_OVR_ON;
//mc->iram_reg_ctrl &= ~(1);
mc->iram_bom = 0x40000000;
mc->iram_tom = 0x4003F000;
}
void mc_disable_ahb_redirect()
{
struct tegra_mc_regs* const mc = (void *)MC_BASE;
mc->iram_bom = 0xFFFFF000;
mc->iram_tom = 0;
//mc->iram_reg_ctrl |= 1; //Disable IRAM_CFG_WRITE_ACCESS (sticky).
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~ARC_CLK_OVR_ON;
}
void mc_enable()
{
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000;
//Enable EMC clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) |= CLK_H_EMC;
//Enable MEM clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) |= CLK_H_MEM;
//Enable EMC DLL clock.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) |= CLK_X_EMC_DLL;
//Clear EMC and MEM reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = CLK_H_MEM | CLK_H_EMC;
usleep(5);
mc_disable_ahb_redirect();
#ifdef CONFIG_ENABLE_AHB_REDIRECT
mc_enable_ahb_redirect();
#endif
}

12
ariane/src/hwinit/mc.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef _MC_H_
#define _MC_H_
#include "types.h"
void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock);
void mc_config_carveout();
void mc_enable_ahb_redirect();
void mc_disable_ahb_redirect();
void mc_enable();
#endif

226
ariane/src/hwinit/mc_t210.h Normal file
View file

@ -0,0 +1,226 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _MC_T210_H_
#define _MC_T210_H_
#include "types.h"
// Memory Controller registers we need/care about
struct tegra_mc_regs {
vu32 rsvd_0x0[4]; /* 0x00 */
vu32 smmu_config; /* 0x10 */
vu32 smmu_tlb_config; /* 0x14 */
vu32 smmu_ptc_config; /* 0x18 */
vu32 smmu_ptb_asid; /* 0x1c */
vu32 smmu_ptb_data; /* 0x20 */
vu32 rsvd_0x24[3]; /* 0x24 */
vu32 smmu_tlb_flush; /* 0x30 */
vu32 smmu_ptc_flush; /* 0x34 */
vu32 rsvd_0x38[6]; /* 0x38 */
vu32 emem_cfg; /* 0x50 */
vu32 emem_adr_cfg; /* 0x54 */
vu32 emem_adr_cfg_dev0; /* 0x58 */
vu32 emem_adr_cfg_dev1; /* 0x5c */
vu32 emem_adr_cfg_channel_mask; /* 0x60 */
vu32 emem_adr_cfg_bank_mask_0; /* 0x64 */
vu32 emem_adr_cfg_bank_mask_1; /* 0x68 */
vu32 emem_adr_cfg_bank_mask_2; /* 0x6c */
vu32 security_cfg0; /* 0x70 */
vu32 security_cfg1; /* 0x74 */
vu32 rsvd_0x78[6]; /* 0x78 */
vu32 emem_arb_cfg; /* 0x90 */
vu32 emem_arb_outstanding_req; /* 0x94 */
vu32 emem_arb_timing_rcd; /* 0x98 */
vu32 emem_arb_timing_rp; /* 0x9c */
vu32 emem_arb_timing_rc; /* 0xa0 */
vu32 emem_arb_timing_ras; /* 0xa4 */
vu32 emem_arb_timing_faw; /* 0xa8 */
vu32 emem_arb_timing_rrd; /* 0xac */
vu32 emem_arb_timing_rap2pre; /* 0xb0 */
vu32 emem_arb_timing_wap2pre; /* 0xb4 */
vu32 emem_arb_timing_r2r; /* 0xb8 */
vu32 emem_arb_timing_w2w; /* 0xbc */
vu32 emem_arb_timing_r2w; /* 0xc0 */
vu32 emem_arb_timing_w2r; /* 0xc4 */
vu32 emem_arb_misc2; /* 0xC8 */
vu32 rsvd_0xcc[1]; /* 0xCC */
vu32 emem_arb_da_turns; /* 0xd0 */
vu32 emem_arb_da_covers; /* 0xd4 */
vu32 emem_arb_misc0; /* 0xd8 */
vu32 emem_arb_misc1; /* 0xdc */
vu32 emem_arb_ring1_throttle; /* 0xe0 */
vu32 emem_arb_ring3_throttle; /* 0xe4 */
vu32 emem_arb_override; /* 0xe8 */
vu32 emem_arb_rsv; /* 0xec */
vu32 rsvd_0xf0[1]; /* 0xf0 */
vu32 clken_override; /* 0xf4 */
vu32 timing_control_dbg; /* 0xf8 */
vu32 timing_control; /* 0xfc */
vu32 stat_control; /* 0x100 */
vu32 rsvd_0x104[65]; /* 0x104 */
vu32 emem_arb_isochronous_0; /* 0x208 */
vu32 emem_arb_isochronous_1; /* 0x20c */
vu32 emem_arb_isochronous_2; /* 0x210 */
vu32 rsvd_0x214[38]; /* 0x214 */
vu32 dis_extra_snap_levels; /* 0x2ac */
vu32 rsvd_0x2b0[90]; /* 0x2b0 */
vu32 video_protect_vpr_override; /* 0x418 */
vu32 rsvd_0x41c[93]; /* 0x41c */
vu32 video_protect_vpr_override1; /* 0x590 */
vu32 rsvd_0x594[29]; /* 0x594 */
vu32 display_snap_ring; /* 0x608 */
vu32 rsvd_0x60c[15]; /* 0x60c */
vu32 video_protect_bom; /* 0x648 */
vu32 video_protect_size_mb; /* 0x64c */
vu32 video_protect_reg_ctrl; /* 0x650 */
vu32 rsvd_0x654[2]; /* 0x654 */
vu32 iram_bom; /* 0x65C */
vu32 iram_tom; /* 0x660 */
vu32 emem_cfg_access_ctrl; /* 0x664 */
vu32 rsvd_0x668[2]; /* 0x668 */
vu32 sec_carveout_bom; /* 0x670 */
vu32 sec_carveout_size_mb; /* 0x674 */
vu32 sec_carveout_reg_ctrl; /* 0x678 */
vu32 rsvd_0x67c[17]; /* 0x67C-0x6BC */
vu32 emem_arb_timing_rfcpb; /* 0x6C0 */
vu32 emem_arb_timing_ccdmw; /* 0x6C4 */
vu32 rsvd_0x6c8[10]; /* 0x6C8-0x6EC */
vu32 emem_arb_refpb_hp_ctrl; /* 0x6F0 */
vu32 emem_arb_refpb_bank_ctrl; /* 0x6F4 */
vu32 rsvd_0x6f8[155]; /* 0x6F8-0x960 */
vu32 iram_reg_ctrl; /* 0x964 */
vu32 emem_arb_override_1; /* 0x968 */
vu32 rsvd_0x96c[3]; /* 0x96c */
vu32 video_protect_bom_adr_hi; /* 0x978 */
vu32 rsvd_0x97c[2]; /* 0x97c */
vu32 video_protect_gpu_override_0; /* 0x984 */
vu32 video_protect_gpu_override_1; /* 0x988 */
vu32 rsvd_0x98c[5]; /* 0x98c */
vu32 mts_carveout_bom; /* 0x9a0 */
vu32 mts_carveout_size_mb; /* 0x9a4 */
vu32 mts_carveout_adr_hi; /* 0x9a8 */
vu32 mts_carveout_reg_ctrl; /* 0x9ac */
vu32 rsvd_0x9b0[4]; /* 0x9b0 */
vu32 emem_bank_swizzle_cfg0; /* 0x9c0 */
vu32 emem_bank_swizzle_cfg1; /* 0x9c4 */
vu32 emem_bank_swizzle_cfg2; /* 0x9c8 */
vu32 emem_bank_swizzle_cfg3; /* 0x9cc */
vu32 rsvd_0x9d0[1]; /* 0x9d0 */
vu32 sec_carveout_adr_hi; /* 0x9d4 */
vu32 rsvd_0x9d8; /* 0x9D8 */
vu32 da_config0; /* 0x9DC */
vu32 rsvd_0x9c0[138]; /* 0x9E0-0xc04 */
vu32 security_carveout1_cfg0; /* 0xc08 */
vu32 security_carveout1_bom; /* 0xc0c */
vu32 security_carveout1_bom_hi; /* 0xc10 */
vu32 security_carveout1_size_128kb; /* 0xc14 */
vu32 security_carveout1_ca0; /* 0xc18 */
vu32 security_carveout1_ca1; /* 0xc1c */
vu32 security_carveout1_ca2; /* 0xc20 */
vu32 security_carveout1_ca3; /* 0xc24 */
vu32 security_carveout1_ca4; /* 0xc28 */
vu32 security_carveout1_cfia0; /* 0xc2c */
vu32 security_carveout1_cfia1; /* 0xc30 */
vu32 security_carveout1_cfia2; /* 0xc34 */
vu32 security_carveout1_cfia3; /* 0xc38 */
vu32 security_carveout1_cfia4; /* 0xc3c */
vu32 rsvd_0xc40[6]; /* 0xc40-0xc54 */
vu32 security_carveout2_cfg0; /* 0xc58 */
vu32 security_carveout2_bom; /* 0xc5c */
vu32 security_carveout2_bom_hi; /* 0xc60 */
vu32 security_carveout2_size_128kb; /* 0xc64 */
vu32 security_carveout2_ca0; /* 0xc68 */
vu32 security_carveout2_ca1; /* 0xc6c */
vu32 security_carveout2_ca2; /* 0xc70 */
vu32 security_carveout2_ca3; /* 0xc74 */
vu32 security_carveout2_ca4; /* 0xc78 */
vu32 security_carveout2_cfia0; /* 0xc7c */
vu32 security_carveout2_cfia1; /* 0xc80 */
vu32 security_carveout2_cfia2; /* 0xc84 */
vu32 security_carveout2_cfia3; /* 0xc88 */
vu32 security_carveout2_cfia4; /* 0xc8c */
vu32 rsvd_0xc90[6]; /* 0xc90-0xca4 */
vu32 security_carveout3_cfg0; /* 0xca8 */
vu32 security_carveout3_bom; /* 0xcac */
vu32 security_carveout3_bom_hi; /* 0xcb0 */
vu32 security_carveout3_size_128kb; /* 0xcb4 */
vu32 security_carveout3_ca0; /* 0xcb8 */
vu32 security_carveout3_ca1; /* 0xcbc */
vu32 security_carveout3_ca2; /* 0xcc0 */
vu32 security_carveout3_ca3; /* 0xcc4 */
vu32 security_carveout3_ca4; /* 0xcc8 */
vu32 security_carveout3_cfia0; /* 0xccc */
vu32 security_carveout3_cfia1; /* 0xcd0 */
vu32 security_carveout3_cfia2; /* 0xcd4 */
vu32 security_carveout3_cfia3; /* 0xcd8 */
vu32 security_carveout3_cfia4; /* 0xcdc */
vu32 rsvd_0xce0[6]; /* 0xce0-0xcf4 */
vu32 security_carveout4_cfg0; /* 0xcf8 */
vu32 security_carveout4_bom; /* 0xcfc */
vu32 security_carveout4_bom_hi; /* 0xd00 */
vu32 security_carveout4_size_128kb; /* 0xd04 */
vu32 security_carveout4_ca0; /* 0xd08 */
vu32 security_carveout4_ca1; /* 0xd0c */
vu32 security_carveout4_ca2; /* 0xd10 */
vu32 security_carveout4_ca3; /* 0xd14 */
vu32 security_carveout4_ca4; /* 0xd18 */
vu32 security_carveout4_cfia0; /* 0xd1c */
vu32 security_carveout4_cfia1; /* 0xd20 */
vu32 security_carveout4_cfia2; /* 0xd24 */
vu32 security_carveout4_cfia3; /* 0xd28 */
vu32 security_carveout4_cfia4; /* 0xd2c */
vu32 rsvd_0xd30[6]; /* 0xd30-0xd44 */
vu32 security_carveout5_cfg0; /* 0xd48 */
vu32 security_carveout5_bom; /* 0xd4c */
vu32 security_carveout5_bom_hi; /* 0xd50 */
vu32 security_carveout5_size_128kb; /* 0xd54 */
vu32 security_carveout5_ca0; /* 0xd58 */
vu32 security_carveout5_ca1; /* 0xd5c */
vu32 security_carveout5_ca2; /* 0xd60 */
vu32 security_carveout5_ca3; /* 0xd64 */
vu32 security_carveout5_ca4; /* 0xd68 */
vu32 security_carveout5_cfia0; /* 0xd6c */
vu32 security_carveout5_cfia1; /* 0xd70 */
vu32 security_carveout5_cfia2; /* 0xd74 */
vu32 security_carveout5_cfia3; /* 0xd78 */
vu32 security_carveout5_cfia4; /* 0xd7c */
};
enum {
MC_SMMU_CONFIG_ENABLE = 1,
MC_EMEM_CFG_SIZE_MB_SHIFT = 0,
MC_EMEM_CFG_SIZE_MB_MASK = 0x3fff,
MC_EMEM_ARB_MISC0_MC_EMC_SAME_FREQ_SHIFT = 27,
MC_EMEM_ARB_MISC0_MC_EMC_SAME_FREQ_MASK = 1 << 27,
MC_EMEM_CFG_ACCESS_CTRL_WRITE_ACCESS_DISABLED = 1,
MC_TIMING_CONTROL_TIMING_UPDATE = 1,
};
#define MC_SECURITY_CARVEOUT_LOCKED (1 << 1)
#define MC_VPR_WR_ACCESS_DISABLE (1 << 0)
#define MC_VPR_ALLOW_TZ_WR_ACCESS_ENABLE (1 << 1)
#endif

432
ariane/src/hwinit/mmc.h Normal file
View file

@ -0,0 +1,432 @@
/*
* Header for MultiMediaCard (MMC)
*
* Copyright 2002 Hewlett-Packard Company
*
* Use consistent with the GNU GPL is permitted,
* provided that this copyright notice is
* preserved in its entirety in all copies and derived works.
*
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
* FITNESS FOR ANY PARTICULAR PURPOSE.
*
* Many thanks to Alessandro Rubini and Jonathan Corbet!
*
* Based strongly on code by:
*
* Author: Yong-iL Joh <tolkien@mizi.com>
*
* Author: Andrew Christian
* 15 May 2002
*/
#ifndef LINUX_MMC_MMC_H
#define LINUX_MMC_MMC_H
/* Standard MMC commands (4.1) type argument response */
/* class 1 */
#define MMC_GO_IDLE_STATE 0 /* bc */
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
#define MMC_BUS_TEST_R 14 /* adtc R1 */
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define MMC_BUS_TEST_W 19 /* adtc R1 */
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
/* class 2 */
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
/* class 4 */
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
#define MMC_PROGRAM_CID 26 /* adtc R1 */
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
/* class 6 */
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
/* class 5 */
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
#define MMC_ERASE 38 /* ac R1b */
/* class 9 */
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
/* class 7 */
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
/* class 8 */
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
/* class 11 */
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
/*
* MMC_SWITCH argument format:
*
* [31:26] Always 0
* [25:24] Access Mode
* [23:16] Location of target Byte in EXT_CSD
* [15:08] Value Byte
* [07:03] Always 0
* [02:00] Command Set
*/
/*
MMC status in R1, for native mode (SPI bits are different)
Type
e : error bit
s : status bit
r : detected and set for the actual command response
x : detected and set during command execution. the host must poll
the card by sending status command in order to read these bits.
Clear condition
a : according to the card state
b : always related to the previous command. Reception of
a valid command will clear it (with a delay of one command)
c : clear by read
*/
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
#define R1_CC_ERROR (1 << 20) /* erx, c */
#define R1_ERROR (1 << 19) /* erx, c */
#define R1_UNDERRUN (1 << 18) /* ex, c */
#define R1_OVERRUN (1 << 17) /* ex, c */
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
#define R1_ERASE_RESET (1 << 13) /* sr, c */
#define R1_STATUS(x) (x & 0xFFFFE000)
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
#define R1_STATE_IDLE 0
#define R1_STATE_READY 1
#define R1_STATE_IDENT 2
#define R1_STATE_STBY 3
#define R1_STATE_TRAN 4
#define R1_STATE_DATA 5
#define R1_STATE_RCV 6
#define R1_STATE_PRG 7
#define R1_STATE_DIS 8
/*
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
* R1 is the low order byte; R2 is the next highest byte, when present.
*/
#define R1_SPI_IDLE (1 << 0)
#define R1_SPI_ERASE_RESET (1 << 1)
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
#define R1_SPI_COM_CRC (1 << 3)
#define R1_SPI_ERASE_SEQ (1 << 4)
#define R1_SPI_ADDRESS (1 << 5)
#define R1_SPI_PARAMETER (1 << 6)
/* R1 bit 7 is always zero */
#define R2_SPI_CARD_LOCKED (1 << 8)
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
#define R2_SPI_ERROR (1 << 10)
#define R2_SPI_CC_ERROR (1 << 11)
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
#define R2_SPI_WP_VIOLATION (1 << 13)
#define R2_SPI_ERASE_PARAM (1 << 14)
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
/*
* OCR bits are mostly in host.h
*/
#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
/*
* Card Command Classes (CCC)
*/
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
/* (and for SPI, CMD58,59) */
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
/* (CMD11) */
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
/* (CMD16,17,18) */
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
/* (CMD20) */
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
/* (CMD16,24,25,26,27) */
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
/* (CMD32,33,34,35,36,37,38,39) */
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
/* (CMD28,29,30) */
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
/* (CMD16,CMD42) */
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
/* (CMD55,56,57,ACMD*) */
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
/* (CMD5,39,40,52,53) */
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
/* (CMD6,34,35,36,37,50) */
/* (11) Reserved */
/* (CMD?) */
/*
* CSD field definitions
*/
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
/*
* EXT_CSD fields
*/
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
#define EXT_CSD_FLUSH_CACHE 32 /* W */
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_HPI_MGMT 161 /* R/W */
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
#define EXT_CSD_BKOPS_EN 163 /* R/W */
#define EXT_CSD_BKOPS_START 164 /* W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
#define EXT_CSD_RPMB_MULT 168 /* RO */
#define EXT_CSD_FW_CONFIG 169 /* R/W */
#define EXT_CSD_BOOT_WP 173 /* R/W */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_PART_CONFIG 179 /* R/W */
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_POWER_CLASS 187 /* R/W */
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_MULT 226 /* RO */
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
#define EXT_CSD_TRIM_MULT 232 /* RO */
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
#define EXT_CSD_DEVICE_VERSION 262 /* RO, 2 bytes */
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
#define EXT_CSD_HPI_FEATURES 503 /* RO */
/*
* EXT_CSD field definitions
*/
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
#define EXT_CSD_CMD_SET_SECURE (1<<1)
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
EXT_CSD_CARD_TYPE_HS_52)
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
/* DDR mode @1.8V or 3V I/O */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
/* DDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
/* SDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
EXT_CSD_CARD_TYPE_HS200_1_2V)
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
EXT_CSD_CARD_TYPE_HS400_1_2V)
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
#define EXT_CSD_TIMING_HS 1 /* High speed */
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
#define EXT_CSD_SEC_ER_EN (1<<0)
#define EXT_CSD_SEC_BD_BLK_EN (1<<2)
#define EXT_CSD_SEC_GB_CL_EN (1<<4)
#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 only */
#define EXT_CSD_RST_N_EN_MASK 0x3
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
#define EXT_CSD_NO_POWER_NOTIFICATION 0
#define EXT_CSD_POWER_ON 1
#define EXT_CSD_POWER_OFF_SHORT 2
#define EXT_CSD_POWER_OFF_LONG 3
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
/*
* EXCEPTION_EVENT_STATUS field
*/
#define EXT_CSD_URGENT_BKOPS (1<<0)
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
#define EXT_CSD_PACKED_FAILURE (1<<3)
#define EXT_CSD_PACKED_GENERIC_ERROR (1<<0)
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
/*
* BKOPS status level
*/
#define EXT_CSD_BKOPS_LEVEL_2 0x2
/*
* BKOPS modes
*/
#define EXT_CSD_MANUAL_BKOPS_MASK 0x01
#define EXT_CSD_AUTO_BKOPS_MASK 0x02
/*
* Command Queue
*/
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
/*
* MMC_SWITCH access modes
*/
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
/*
* Erase/trim/discard
*/
#define MMC_ERASE_ARG 0x00000000
#define MMC_SECURE_ERASE_ARG 0x80000000
#define MMC_TRIM_ARG 0x00000001
#define MMC_DISCARD_ARG 0x00000003
#define MMC_SECURE_TRIM1_ARG 0x80000001
#define MMC_SECURE_TRIM2_ARG 0x80008000
#define MMC_SECURE_ARGS 0x80000000
#define MMC_TRIM_ARGS 0x00008001
#endif /* LINUX_MMC_MMC_H */

236
ariane/src/hwinit/mtc.c Normal file
View file

@ -0,0 +1,236 @@
#include "timer.h"
#include "sdram.h"
#include "lib/decomp.h"
#include "lib/crc32.h"
#include "lib/printk.h"
#include "lib/heap.h"
#include <string.h>
typedef int bool;
#define true 1
#define false 0
#include "minerva_tc/mtc/mtc.h"
#include "minerva_tc/mtc/mtc_mc_emc_regs.h"
extern size_t mtc_sdram_lzma_size;
extern const char mtc_sdram_lzma[];
static mtc_config_t _current_config = {0};
static u32 _current_table_crc = 0;
static bool _initialize_mtc_table()
{
const size_t mtc_tables_size = ulzman(mtc_sdram_lzma, mtc_sdram_lzma_size, NULL, 0);
if (mtc_tables_size > 0)
{
#ifdef MTC_DEBUGGING
printk("[MTC_LOAD] Decompressing %u -> %u bytes of MTC tables...\n", mtc_sdram_lzma_size, mtc_tables_size);
#endif
u8* decomp_buffer = malloc(mtc_tables_size);
#ifdef MTC_DEBUGGING
const u32 decomp_time_start = get_tmr_us();
#endif
const size_t mtc_decomp_size = ulzman(mtc_sdram_lzma, mtc_sdram_lzma_size, decomp_buffer, mtc_tables_size);
#ifdef MTC_DEBUGGING
const u32 decomp_time_end = get_tmr_us();
#endif
if (mtc_decomp_size != mtc_tables_size)
{
printk("[MTC_LOAD] Error during lzma decompression, got %u instead of %u bytes out!\n", mtc_decomp_size, mtc_tables_size);
free(decomp_buffer);
}
else
{
#ifdef MTC_DEBUGGING
printk("[MTC_LOAD] Decompression took %u us.\n", decomp_time_end - decomp_time_start);
#endif
u8 matchBuffer[0x40];
memcpy(matchBuffer, decomp_buffer, sizeof(matchBuffer));
const u8* matchStart = &decomp_buffer[sizeof(matchBuffer)];
const u8* matchEnd = &decomp_buffer[mtc_tables_size];
typedef struct
{
u32 start;
u32 len;
} ramEntry_t;
ramEntry_t entries[8];
memset(entries, 0, sizeof(entries));
#ifdef MTC_DEBUGGING
const u32 search_time_start = get_tmr_us();
#endif
u32 numEntries = 0;
while (matchStart < matchEnd)
{
if (memcmp(matchStart, matchBuffer, sizeof(matchBuffer)) == 0)
{
entries[numEntries].len = (matchStart - decomp_buffer) - entries[numEntries].start;
entries[++numEntries].start = (matchStart - decomp_buffer);
}
matchStart += sizeof(matchBuffer);
}
entries[numEntries].len = (matchEnd - decomp_buffer) - entries[numEntries].start;
numEntries++;
#ifdef MTC_DEBUGGING
const u32 search_time_end = get_tmr_us();
#endif
_current_config.sdram_id = get_sdram_id();
for (u32 i=0; i<numEntries; i++)
{
#ifdef MTC_DEBUGGING
printk("[MTC_LOAD] \tentry(%u): %08x %08x", i, entries[i].start, entries[i].len);
#endif
if (i == _current_config.sdram_id)
{
#ifdef MTC_DEBUGGING
printk(" <- CHOSEN");
#endif
_current_config.mtc_table = (void*)(0x80000000);
_current_config.table_entries = entries[i].len / sizeof(emc_table_t);
_current_config.emc_2X_clk_src_is_pllmb = false;
_current_config.fsp_for_src_freq = false;
_current_config.train_ram_patterns = true;
const size_t total_table_size = _current_config.table_entries * sizeof(emc_table_t);
memcpy(_current_config.mtc_table, &decomp_buffer[entries[i].start], total_table_size);
_current_table_crc = crc32b((unsigned char*)_current_config.mtc_table, total_table_size);
}
#ifdef MTC_DEBUGGING
printk("\n");
#endif
}
free(decomp_buffer);
#ifdef MTC_DEBUGGING
printk("[MTC_LOAD] Finding entries took %u us.\n", search_time_end - search_time_start);
#endif
return true;
}
}
return false;
}
int mtc_perform_memory_training(int targetFreq)
{
if (_current_config.mtc_table == NULL)
_initialize_mtc_table();
const emc_table_t* mtcTable = _current_config.mtc_table;
const u32 numEntries = _current_config.table_entries;
const size_t mtcTableSize = numEntries * sizeof(emc_table_t);
if (mtcTable == NULL || numEntries == 0)
return 0;
if (crc32b((unsigned char*)mtcTable, mtcTableSize) != _current_table_crc)
return 0;
const emc_table_t* currentTable = _current_config.current_emc_table;
if (currentTable == NULL)
{
u32 runningEntry;
const u32 currEmcClkSrc = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
for (runningEntry=0; runningEntry<numEntries; runningEntry++)
{
if (mtcTable[runningEntry].clk_src_emc == currEmcClkSrc)
break;
}
if (runningEntry >= numEntries)
{
printk("[MTC] failed to find currently running entry\n");
return 0;
}
currentTable = &mtcTable[runningEntry];
}
#ifdef MTC_DEBUGGING
printk("[MTC] currently using entry for %d kHz: %s\n", currentTable->rate_khz, currentTable->dvfs_ver);
#endif
#ifdef MTC_SEPARATE_TRAINING
for (u32 i=0; i<numEntries; i++)
{
if (&mtcTable[i] == currentTable)
continue;
_current_config.rate_from = currentTable->rate_khz;
_current_config.rate_to = mtcTable[i].rate_khz;
_current_config.train_mode = OP_TRAIN;
printk("[MTC] Training %d kHz -> %d kHz\n", _current_config.rate_from, _current_config.rate_to);
minerva_main(&_current_config);
}
#endif
const u32 wantedRateKhz = (targetFreq < 0) ? (-targetFreq) : targetFreq;
for (u32 nextTableIdx=(currentTable-mtcTable)+1; nextTableIdx<numEntries; nextTableIdx++)
{
const emc_table_t* nextTable = &mtcTable[nextTableIdx];
if (nextTable->rate_khz > wantedRateKhz)
break;
if (nextTable->periodic_training && targetFreq > 0)
break;
_current_config.rate_from = currentTable->rate_khz;
_current_config.rate_to = nextTable->rate_khz;
#ifdef MTC_SEPARATE_TRAINING
_current_config.train_mode = OP_SWITCH;
#else
_current_config.train_mode = OP_TRAIN_SWITCH;
#endif
printk("[MTC] Switching %d kHz -> %d kHz\n", _current_config.rate_from, _current_config.rate_to);
minerva_main(&_current_config);
if (_current_config.current_emc_table != NULL)
currentTable = _current_config.current_emc_table;
if (_current_config.current_emc_table != nextTable)
{
printk("[MTC] Failed to switch! Remaining on %d kHz\n", currentTable->rate_khz);
break;
}
}
int newClock = currentTable->rate_khz;
if (currentTable->periodic_training)
newClock = -newClock;
return newClock;
}
u32 mtc_redo_periodic_training(u32 lastPeriodicMs)
{
const emc_table_t* mtcTable = _current_config.mtc_table;
const u32 numEntries = _current_config.table_entries;
const size_t mtcTableSize = numEntries * sizeof(emc_table_t);
if (mtcTable == NULL || numEntries == 0)
return 0;
if (crc32b((unsigned char*)mtcTable, mtcTableSize) != _current_table_crc)
return 0;
const emc_table_t* currentTable = _current_config.current_emc_table;
if (currentTable == NULL)
return 0;
const u32 currTimeMs = get_tmr_ms();
if (currTimeMs < (lastPeriodicMs + EMC_PERIODIC_TRAIN_MS))
return lastPeriodicMs;
_current_config.rate_from = currentTable->rate_khz;
_current_config.rate_to = currentTable->rate_khz;
_current_config.train_mode = OP_PERIODIC_TRAIN;
minerva_main(&_current_config);
return currTimeMs;
}

10
ariane/src/hwinit/mtc.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef _HWINIT_MTC_H_
#define _HWINIT_MTC_H_
#include "types.h"
//negative targetFreq => periodic training is allowed as parameter, as return value periodic training is required
int mtc_perform_memory_training(int targetFreq);
//performs periodic training if the time interval since last one is greater than periodic training timeout
u32 mtc_redo_periodic_training(u32 lastPeriodicMs);
#endif

100
ariane/src/hwinit/pinmux.c Normal file
View file

@ -0,0 +1,100 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2013 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "pinmux.h"
#include "t210.h"
#include "gpio.h"
static volatile uint32_t *pinmux_regs = (void *)PINMUX_AUX_BASE;
void pinmux_set_config(int pin_index, uint32_t config)
{
pinmux_regs[pin_index] = config;
}
uint32_t pinmux_get_config(int pin_index)
{
return pinmux_regs[pin_index];
}
void pinmux_set_unused(int pin_index, int gpio_index, int has_gpio, int pulltype)
{
uint32_t reg = pinmux_get_config(pin_index);
reg &= ~PINMUX_INPUT_ENABLE;
reg |= PINMUX_TRISTATE;
reg &= ~PINMUX_PULL_MASK;
if (pulltype == POR_PU)
reg |= PINMUX_PULL_UP;
else if (pulltype == POR_PD)
reg |= PINMUX_PULL_DOWN;
pinmux_set_config(pin_index, reg);
if (has_gpio)
{
gpio_config(gpio_index_port(gpio_index), gpio_index_bitmask(gpio_index), GPIO_MODE_GPIO);
gpio_output_enable(gpio_index_port(gpio_index), gpio_index_bitmask(gpio_index), GPIO_OUTPUT_DISABLE);
}
}
void pinmux_config_i2c(int i2c_index)
{
static const int pinmux_i2c[] = {
PINMUX_GEN1_I2C_SDA_INDEX, PINMUX_GEN1_I2C_SCL_INDEX,
PINMUX_GEN2_I2C_SDA_INDEX, PINMUX_GEN2_I2C_SCL_INDEX,
PINMUX_GEN3_I2C_SDA_INDEX, PINMUX_GEN3_I2C_SCL_INDEX,
PINMUX_CAM_I2C_SDA_INDEX, PINMUX_CAM_I2C_SCL_INDEX,
PINMUX_PWR_I2C_SDA_INDEX, PINMUX_PWR_I2C_SCL_INDEX };
pinmux_set_config(pinmux_i2c[i2c_index*2+0], PINMUX_INPUT_ENABLE);
pinmux_set_config(pinmux_i2c[i2c_index*2+1], PINMUX_INPUT_ENABLE);
static const int gpio_i2c[] = {
PAD_TO_GPIO_GEN1_I2C_SDA, PAD_TO_GPIO_GEN1_I2C_SCL,
PAD_TO_GPIO_GEN2_I2C_SDA, PAD_TO_GPIO_GEN2_I2C_SCL,
PAD_TO_GPIO_GEN3_I2C_SDA, PAD_TO_GPIO_GEN3_I2C_SCL,
PAD_TO_GPIO_CAM_I2C_SDA, PAD_TO_GPIO_CAM_I2C_SCL,
PAD_TO_GPIO_PWR_I2C_SDA, PAD_TO_GPIO_PWR_I2C_SCL };
const int gpio_index_sda = gpio_i2c[i2c_index*2+0];
const int gpio_index_scl = gpio_i2c[i2c_index*2+1];
gpio_config(gpio_index_port(gpio_index_sda), gpio_index_bitmask(gpio_index_sda), GPIO_MODE_SPIO);
gpio_config(gpio_index_port(gpio_index_scl), gpio_index_bitmask(gpio_index_scl), GPIO_MODE_SPIO);
}
void pinmux_config_uart(int uart_index)
{
static const int pinmux_uart[] = {
PINMUX_UART1_TX_INDEX, PINMUX_UART1_RX_INDEX, PINMUX_UART1_RTS_INDEX, PINMUX_UART1_CTS_INDEX,
PINMUX_UART2_TX_INDEX, PINMUX_UART2_RX_INDEX, PINMUX_UART2_RTS_INDEX, PINMUX_UART2_CTS_INDEX,
PINMUX_UART3_TX_INDEX, PINMUX_UART3_RX_INDEX, PINMUX_UART3_RTS_INDEX, PINMUX_UART3_CTS_INDEX,
PINMUX_UART4_TX_INDEX, PINMUX_UART4_RX_INDEX, PINMUX_UART4_RTS_INDEX, PINMUX_UART4_CTS_INDEX };
pinmux_set_config(pinmux_uart[uart_index*4+0], PINMUX_PULL_UP);
pinmux_set_config(pinmux_uart[uart_index*4+1], PINMUX_INPUT_ENABLE | PINMUX_PULL_UP);
pinmux_set_config(pinmux_uart[uart_index*4+2], PINMUX_PULL_UP);
pinmux_set_config(pinmux_uart[uart_index*4+3], PINMUX_INPUT_ENABLE | PINMUX_PULL_UP);
static const int gpio_uart[] = {
PAD_TO_GPIO_UART1_TX, PAD_TO_GPIO_UART1_RX, PAD_TO_GPIO_UART1_RTS, PAD_TO_GPIO_UART1_CTS,
PAD_TO_GPIO_UART2_TX, PAD_TO_GPIO_UART2_RX, PAD_TO_GPIO_UART2_RTS, PAD_TO_GPIO_UART2_CTS,
PAD_TO_GPIO_UART3_TX, PAD_TO_GPIO_UART3_RX, PAD_TO_GPIO_UART3_RTS, PAD_TO_GPIO_UART3_CTS,
PAD_TO_GPIO_UART4_TX, PAD_TO_GPIO_UART4_RX, PAD_TO_GPIO_UART4_RTS, PAD_TO_GPIO_UART4_CTS };
for (int i=0; i<4; i++)
{
const int gpio_index = gpio_uart[uart_index*4+i];
gpio_config(gpio_index_port(gpio_index), gpio_index_bitmask(gpio_index), GPIO_MODE_SPIO);
}
}

297
ariane/src/hwinit/pinmux.h Normal file
View file

@ -0,0 +1,297 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2014 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __SOC_NVIDIA_TEGRA210_PINMUX_H__
#define __SOC_NVIDIA_TEGRA210_PINMUX_H__
#include <stdint.h>
void pinmux_set_config(int pin_index, uint32_t config);
uint32_t pinmux_get_config(int pin_index);
void pinmux_set_unused(int pin_index, int gpio_index, int has_gpio, int pulltype);
#define PINMUX_SET_UNUSED_BY_NAME(name) pinmux_set_unused(PINMUX_##name##_INDEX, PAD_TO_GPIO_##name, PAD_HAS_GPIO_##name, PAD_POR_PU_##name)
#define PINMUX_SET_UNUSED_BY_GPIO(gpio) pinmux_set_unused(PINMUX_GPIO_##gpio, GPIO_##gpio##_index, 1, GPIO_POR_PU_##gpio)
void pinmux_config_i2c(int i2c_index);
void pinmux_config_uart(int uart_index);
enum {
PINMUX_FUNC_MASK = 3 << 0,
PINMUX_PULL_MASK = 3 << 2,
PINMUX_PULL_NONE = 0 << 2,
PINMUX_PULL_DOWN = 1 << 2,
PINMUX_PULL_UP = 2 << 2,
PINMUX_TRISTATE = 1 << 4,
PINMUX_PARKED = 1 << 5,
PINMUX_INPUT_ENABLE = 1 << 6,
PINMUX_LOCK = 1 << 7,
PINMUX_LPDR = 1 << 8,
PINMUX_HSM = 1 << 9,
PINMUX_IO_HV = 1 << 10,
PINMUX_OPEN_DRAIN = 1 << 11,
PINMUX_SCHMT = 1 << 12,
PINMUX_DRIVE_1X = 0 << 13,
PINMUX_DRIVE_2X = 1 << 13,
PINMUX_DRIVE_3X = 2 << 13,
PINMUX_DRIVE_4X = 3 << 13,
};
/* GPIO index constants. */
#define GPIO_PORT_CONSTANTS(port) \
GPIO_##port##0_INDEX, GPIO_##port##1_INDEX, GPIO_##port##2_INDEX, \
GPIO_##port##3_INDEX, GPIO_##port##4_INDEX, GPIO_##port##5_INDEX, \
GPIO_##port##6_INDEX, GPIO_##port##7_INDEX
enum {
GPIO_PORT_CONSTANTS(A),
GPIO_PORT_CONSTANTS(B),
GPIO_PORT_CONSTANTS(C),
GPIO_PORT_CONSTANTS(D),
GPIO_PORT_CONSTANTS(E),
GPIO_PORT_CONSTANTS(F),
GPIO_PORT_CONSTANTS(G),
GPIO_PORT_CONSTANTS(H),
GPIO_PORT_CONSTANTS(I),
GPIO_PORT_CONSTANTS(J),
GPIO_PORT_CONSTANTS(K),
GPIO_PORT_CONSTANTS(L),
GPIO_PORT_CONSTANTS(M),
GPIO_PORT_CONSTANTS(N),
GPIO_PORT_CONSTANTS(O),
GPIO_PORT_CONSTANTS(P),
GPIO_PORT_CONSTANTS(Q),
GPIO_PORT_CONSTANTS(R),
GPIO_PORT_CONSTANTS(S),
GPIO_PORT_CONSTANTS(T),
GPIO_PORT_CONSTANTS(U),
GPIO_PORT_CONSTANTS(V),
GPIO_PORT_CONSTANTS(W),
GPIO_PORT_CONSTANTS(X),
GPIO_PORT_CONSTANTS(Y),
GPIO_PORT_CONSTANTS(Z),
GPIO_PORT_CONSTANTS(AA),
GPIO_PORT_CONSTANTS(BB),
GPIO_PORT_CONSTANTS(CC),
GPIO_PORT_CONSTANTS(DD),
GPIO_PORT_CONSTANTS(EE),
GPIO_PORT_CONSTANTS(FF),
GPIO_NONE_INDEX = 0,
};
#define PINMUX_CONSTANTS_GPIO(name, gpio) \
PINMUX_GPIO_##gpio = PINMUX_##name##_INDEX, \
GPIO_POR_PU_##gpio = PAD_POR_PU_##name
#define PINMUX_CONSTANTS(index, name, por_pu, gpio, has_gpio, \
func0, func1, func2, func3) \
PINMUX_##name##_INDEX = index, \
PINMUX_##name##_FUNC_##func0 = 0, \
PINMUX_##name##_FUNC_##func1 = 1, \
PINMUX_##name##_FUNC_##func2 = 2, \
PINMUX_##name##_FUNC_##func3 = 3, \
PAD_TO_GPIO_##name = GPIO_##gpio##_INDEX, \
PAD_HAS_GPIO_##name = has_gpio, \
PAD_POR_PU_##name = por_pu
#define PAD_GPIO(index, name, por_pu, gpio, func0, func1, func2, func3) \
PINMUX_CONSTANTS(index, name, por_pu, gpio, 1, \
func0, func1, func2, func3), \
PINMUX_CONSTANTS_GPIO(name, gpio)
#define PAD_NO_GPIO(index, name, por_pu, func0, func1, func2, func3) \
PINMUX_CONSTANTS(index, name, por_pu, NONE, 0, \
func0, func1, func2, func3)
enum {
/* Power-on-reset pull states. */
POR_PU = 2,
POR_PD = 1,
POR_NP = 0,
PAD_GPIO(0, SDMMC1_CLK, POR_PD, M0, SDMMC1, RES1, RES2, RES3),
PAD_GPIO(1, SDMMC1_CMD, POR_PU, M1, SDMMC1, RES1, RES2, RES3),
PAD_GPIO(2, SDMMC1_DAT3, POR_PU, M2, SDMMC1, RES1, RES2, RES3),
PAD_GPIO(3, SDMMC1_DAT2, POR_PU, M3, SDMMC1, RES1, RES2, RES3),
PAD_GPIO(4, SDMMC1_DAT1, POR_PU, M4, SDMMC1, RES1, RES2, RES3),
PAD_GPIO(5, SDMMC1_DAT0, POR_PU, M5, SDMMC1, RES1, RES2, RES3),
PAD_GPIO(6, SDMMC3_CLK, POR_PD, P0, SDMMC3, RES1, RES2, RES3),
PAD_GPIO(7, SDMMC3_CMD, POR_PU, P1, SDMMC3, RES1, RES2, RES3),
PAD_GPIO(8, SDMMC3_DAT0, POR_PU, P2, SDMMC3, RES1, RES2, RES3),
PAD_GPIO(9, SDMMC3_DAT1, POR_PU, P3, SDMMC3, RES1, RES2, RES3),
PAD_GPIO(10, SDMMC3_DAT2, POR_PU, P4, SDMMC3, RES1, RES2, RES3),
PAD_GPIO(11, SDMMC3_DAT3, POR_PU, P5, SDMMC3, RES1, RES2, RES3),
/* GPIO12 - unused */
/* GPIO13 - unused */
PAD_GPIO(14, PEX_L0_RST_N, POR_NP, A0, PE0, RES1, RES2, RES3),
PAD_GPIO(15, PEX_L0_CLKREQ_N, POR_NP, A1, PE0, RES1, RES2, RES3),
PAD_GPIO(16, PEX_WAKE_N, POR_NP, A2, PE, RES1, RES2, RES3),
PAD_GPIO(17, PEX_L1_RST_N, POR_NP, A3, PE1, RES1, RES2, RES3),
PAD_GPIO(18, PEX_L1_CLKREQ_N, POR_NP, A4, PE1, RES1, RES2, RES3),
PAD_GPIO(19, SATA_LED_ACTIVE, POR_NP, A5, SATA, RES1, RES2, RES3),
PAD_GPIO(20, SPI1_MOSI, POR_PD, C0, SPI1, RES1, RES2, RES3),
PAD_GPIO(21, SPI1_MISO, POR_PD, C1, SPI1, RES1, RES2, RES3),
PAD_GPIO(22, SPI1_SCK, POR_PD, C2, SPI1, RES1, RES2, RES3),
PAD_GPIO(23, SPI1_CS0, POR_PU, C3, SPI1, RES1, RES2, RES3),
PAD_GPIO(24, SPI1_CS1, POR_PU, C4, SPI1, RES1, RES2, RES3),
PAD_GPIO(25, SPI2_MOSI, POR_PD, B4, SPI2, DTV, RES2, RES3),
PAD_GPIO(26, SPI2_MISO, POR_PD, B5, SPI2, DTV, RES2, RES3),
PAD_GPIO(27, SPI2_SCK, POR_PD, B6, SPI2, DTV, RES2, RES3),
PAD_GPIO(28, SPI2_CS0, POR_PU, B7, SPI2, DTV, RES2, RES3),
PAD_GPIO(29, SPI2_CS1, POR_PU, DD0, SPI2, RES1, RES2, RES3),
PAD_GPIO(30, SPI4_MOSI, POR_PD, C7, SPI4, RES1, RES2, RES3),
PAD_GPIO(31, SPI4_MISO, POR_PD, D0, SPI4, RES1, RES2, RES3),
PAD_GPIO(32, SPI4_SCK, POR_PD, C5, SPI4, RES1, RES2, RES3),
PAD_GPIO(33, SPI4_CS0, POR_PU, C6, SPI4, RES1, RES2, RES3),
PAD_GPIO(34, QSPI_SCK, POR_PU, EE0, QSPI, RES1, RES2, RES3),
PAD_GPIO(35, QSPI_CS_N, POR_PU, EE1, QSPI, RES1, RES2, RES3),
PAD_GPIO(36, QSPI_IO0, POR_PU, EE2, QSPI, RES1, RES2, RES3),
PAD_GPIO(37, QSPI_IO1, POR_PU, EE3, QSPI, RES1, RES2, RES3),
PAD_GPIO(38, QSPI_IO2, POR_PU, EE4, QSPI, RES1, RES2, RES3),
PAD_GPIO(39, QSPI_IO3, POR_PU, EE5, QSPI, RES1, RES2, RES3),
/* GPIO40 - unused */
PAD_GPIO(41, DMIC1_CLK, POR_PD, E0, DMIC1, I2S3, RES2, RES3),
PAD_GPIO(42, DMIC1_DAT, POR_PD, E1, DMIC1, I2S3, RES2, RES3),
PAD_GPIO(43, DMIC2_CLK, POR_PD, E2, DMIC2, I2S3, RES2, RES3),
PAD_GPIO(44, DMIC2_DAT, POR_PD, E3, DMIC2, I2S3, RES2, RES3),
PAD_GPIO(45, DMIC3_CLK, POR_PD, E4, DMIC3, I2S5A, RES2, RES3),
PAD_GPIO(46, DMIC3_DAT, POR_PD, E5, DMIC3, I2S5A, RES2, RES3),
PAD_GPIO(47, GEN1_I2C_SDA, POR_NP, J0, I2C1, RES1, RES2, RES3),
PAD_GPIO(48, GEN1_I2C_SCL, POR_NP, J1, I2C1, RES1, RES2, RES3),
PAD_GPIO(49, GEN2_I2C_SCL, POR_NP, J2, I2C2, RES1, RES2, RES3),
PAD_GPIO(50, GEN2_I2C_SDA, POR_NP, J3, I2C2, RES1, RES2, RES3),
PAD_GPIO(51, GEN3_I2C_SCL, POR_NP, F0, I2C3, RES1, RES2, RES3),
PAD_GPIO(52, GEN3_I2C_SDA, POR_NP, F1, I2C3, RES1, RES2, RES3),
PAD_GPIO(53, CAM_I2C_SCL, POR_NP, S2, I2C3, I2CVI, RES2, RES3),
PAD_GPIO(54, CAM_I2C_SDA, POR_NP, S3, I2C3, I2CVI, RES2, RES3),
PAD_GPIO(55, PWR_I2C_SCL, POR_NP, Y3, I2CPMU, RES1, RES2, RES3),
PAD_GPIO(56, PWR_I2C_SDA, POR_NP, Y4, I2CPMU, RES1, RES2, RES3),
PAD_GPIO(57, UART1_TX, POR_PD, U0, UARTA, RES1, RES2, RES3),
PAD_GPIO(58, UART1_RX, POR_PD, U1, UARTA, RES1, RES2, RES3),
PAD_GPIO(59, UART1_RTS, POR_PD, U2, UARTA, RES1, RES2, RES3),
PAD_GPIO(60, UART1_CTS, POR_PD, U3, UARTA, RES1, RES2, RES3),
PAD_GPIO(61, UART2_TX, POR_PD, G0, UARTB, I2S4A, SPDIF, UART),
PAD_GPIO(62, UART2_RX, POR_PD, G1, UARTB, I2S4A, SPDIF, UART),
PAD_GPIO(63, UART2_RTS, POR_PD, G2, UARTB, I2S4A, RES2, UART),
PAD_GPIO(64, UART2_CTS, POR_PD, G3, UARTB, I2S4A, RES2, UART),
PAD_GPIO(65, UART3_TX, POR_PD, D1, UARTC, SPI4, RES2, RES3),
PAD_GPIO(66, UART3_RX, POR_PD, D2, UARTC, SPI4, RES2, RES3),
PAD_GPIO(67, UART3_RTS, POR_PD, D3, UARTC, SPI4, RES2, RES3),
PAD_GPIO(68, UART3_CTS, POR_PD, D4, UARTC, SPI4, RES2, RES3),
PAD_GPIO(69, UART4_TX, POR_PD, I4, UARTD, UART, RES2, RES3),
PAD_GPIO(70, UART4_RX, POR_PD, I5, UARTD, UART, RES2, RES3),
PAD_GPIO(71, UART4_RTS, POR_PD, I6, UARTD, UART, RES2, RES3),
PAD_GPIO(72, UART4_CTS, POR_PD, I7, UARTD, UART, RES2, RES3),
PAD_GPIO(73, DAP1_FS, POR_PD, B0, I2S1, RES1, RES2, RES3),
PAD_GPIO(74, DAP1_DIN, POR_PD, B1, I2S1, RES1, RES2, RES3),
PAD_GPIO(75, DAP1_DOUT, POR_PD, B2, I2S1, RES1, RES2, RES3),
PAD_GPIO(76, DAP1_SCLK, POR_PD, B3, I2S1, RES1, RES2, RES3),
PAD_GPIO(77, DAP2_FS, POR_PD, AA0, I2S2, RES1, RES2, RES3),
PAD_GPIO(78, DAP2_DIN, POR_PD, AA1, I2S2, RES1, RES2, RES3),
PAD_GPIO(79, DAP2_DOUT, POR_PD, AA2, I2S2, RES1, RES2, RES3),
PAD_GPIO(80, DAP2_SCLK, POR_PD, AA3, I2S2, RES1, RES2, RES3),
PAD_GPIO(81, DAP4_FS, POR_PD, J4, I2S4B, RES1, RES2, RES3),
PAD_GPIO(82, DAP4_DIN, POR_PD, J5, I2S4B, RES1, RES2, RES3),
PAD_GPIO(83, DAP4_DOUT, POR_PD, J6, I2S4B, RES1, RES2, RES3),
PAD_GPIO(84, DAP4_SCLK, POR_PD, J7, I2S4B, RES1, RES2, RES3),
PAD_GPIO(85, CAM1_MCLK, POR_PD, S0, EXTPERIPH3, RES1, RES2, RES3),
PAD_GPIO(86, CAM2_MCLK, POR_PD, S1, EXTPERIPH3, RES1, RES2, RES3),
PAD_NO_GPIO(87, JTAG_RTCK, POR_PU, JTAG, RES1, RES2, RES3),
PAD_NO_GPIO(88, CLK_32K_IN, POR_NP, CLK_32K_IN, RES1, RES2, RES3),
PAD_GPIO(89, CLK_32K_OUT, POR_PD, Y5, SOC, BLINK, RES2, RES3),
PAD_NO_GPIO(90, BATT_BCL, POR_NP, BCL, RES1, RES2, RES3),
PAD_NO_GPIO(91, CLK_REQ, POR_NP, CLK_REQ, RES1, RES2, RES3),
PAD_NO_GPIO(92, CPU_PWR_REQ, POR_NP, CPU, RES1, RES2, RES3),
PAD_NO_GPIO(93, PWR_INT_N, POR_NP, PMI, RES1, RES2, RES3),
PAD_NO_GPIO(94, SHUTDOWN, POR_NP, SHUTDOWN, RES1, RES2, RES3),
PAD_NO_GPIO(95, CORE_PWR_REQ, POR_NP, PWRON, RES1, RES2, RES3),
PAD_GPIO(96, AUD_MCLK, POR_PD, BB0, AUD, RES1, RES2, RES3),
PAD_GPIO(97, DVFS_PWM, POR_PD, BB1, RES0, CLDVFS, SPI3, RES3),
PAD_GPIO(98, DVFS_CLK, POR_PU, BB2, RES0, CLDVFS, SPI3, RES3),
PAD_GPIO(99, GPIO_X1_AUD, POR_PD, BB3, RES0, RES1, SPI3, RES3),
PAD_GPIO(100, GPIO_X3_AUD, POR_PU, BB4, RES0, RES1, SPI3, RES3),
PAD_NO_GPIO(101, GPIO_PCC7, POR_NP, RES0, RES1, RES2, RES3),
PAD_GPIO(102, HDMI_CEC, POR_NP, CC0, CEC, RES1, RES2, RES3),
PAD_GPIO(103, HDMI_INT_DP_HPD, POR_PD, CC1, DP, RES1, RES2, RES3),
PAD_GPIO(104, SPDIF_OUT, POR_PU, CC2, SPDIF, RES1, RES2, I2C3),
PAD_GPIO(105, SPDIF_IN, POR_PD, CC3, SPDIF, RES1, RES2, I2C3),
PAD_GPIO(106, USB_VBUS_EN0, POR_NP, CC4, USB, RES1, RES2, RES3),
PAD_GPIO(107, USB_VBUS_EN1, POR_NP, CC5, USB, RES1, RES2, RES3),
PAD_GPIO(108, DP_HPD0, POR_PD, CC6, DP, RES1, RES2, RES3),
PAD_GPIO(109, WIFI_EN, POR_PD, H0, RES0, RES1, RES2, RES3),
PAD_GPIO(110, WIFI_RST, POR_PD, H1, RES0, RES1, RES2, RES3),
PAD_GPIO(111, WIFI_WAKE_AP, POR_PD, H2, RES0, RES1, RES2, RES3),
PAD_GPIO(112, AP_WAKE_BT, POR_PD, H3, RES0, UARTB, SPDIF, RES3),
PAD_GPIO(113, BT_RST, POR_PD, H4, RES0, UARTB, SPDIF, RES3),
PAD_GPIO(114, BT_WAKE_AP, POR_PD, H5, RES0, RES1, RES2, RES3),
PAD_GPIO(115, AP_WAKE_NFC, POR_PD, H7, RES0, RES1, RES2, RES3),
PAD_GPIO(116, NFC_EN, POR_PD, I0, RES0, RES1, RES2, RES3),
PAD_GPIO(117, NFC_INT, POR_PD, I1, RES0, RES1, RES2, RES3),
PAD_GPIO(118, GPS_EN, POR_PD, I2, RES0, RES1, RES2, RES3),
PAD_GPIO(119, GPS_RST, POR_PD, I3, RES0, RES1, RES2, RES3),
PAD_GPIO(120, CAM_RST, POR_PD, S4, VGP1, RES1, RES2, RES3),
PAD_GPIO(121, CAM_AF_EN, POR_PD, S5, VIMCLK, VGP2, RES2, RES3),
PAD_GPIO(122, CAM_FLASH_EN, POR_PD, S6, VIMCLK, VGP3, RES2, RES3),
PAD_GPIO(123, CAM1_PWDN, POR_PD, S7, VGP4, RES1, RES2, RES3),
PAD_GPIO(124, CAM2_PWDN, POR_PD, T0, VGP5, RES1, RES2, RES3),
PAD_GPIO(125, CAM1_STROBE, POR_PD, T1, VGP6, RES1, RES2, RES3),
PAD_GPIO(126, LCD_TE, POR_PD, Y2, DISPLAYA, RES1, RES2, RES3),
PAD_GPIO(127, LCD_BL_PWM, POR_PD, V0, DISPLAYA, PWM0, SOR0, RES3),
PAD_GPIO(128, LCD_BL_EN, POR_PD, V1, RES0, RES1, RES2, RES3),
PAD_GPIO(129, LCD_RST, POR_PD, V2, RES0, RES1, RES2, RES3),
PAD_GPIO(130, LCD_GPIO1, POR_PD, V3, DISPLAYB, RES1, RES2, RES3),
PAD_GPIO(131, LCD_GPIO2, POR_PD, V4, DISPLAYB, PWM1, RES2, SOR1),
PAD_GPIO(132, AP_READY, POR_PD, V5, RES0, RES1, RES2, RES3),
PAD_GPIO(133, TOUCH_RST, POR_PD, V6, RES0, RES1, RES2, RES3),
PAD_GPIO(134, TOUCH_CLK, POR_PD, V7, TOUCH, RES1, RES2, RES3),
PAD_GPIO(135, MODEM_WAKE_AP, POR_PD, X0, RES0, RES1, RES2, RES3),
PAD_GPIO(136, TOUCH_INT, POR_PD, X1, RES0, RES1, RES2, RES3),
PAD_GPIO(137, MOTION_INT, POR_PD, X2, RES0, RES1, RES2, RES3),
PAD_GPIO(138, ALS_PROX_INT, POR_PD, X3, RES0, RES1, RES2, RES3),
PAD_GPIO(139, TEMP_ALERT, POR_PD, X4, RES0, RES1, RES2, RES3),
PAD_GPIO(140, BUTTON_POWER_ON, POR_PU, X5, RES0, RES1, RES2, RES3),
PAD_GPIO(141, BUTTON_VOL_UP, POR_PU, X6, RES0, RES1, RES2, RES3),
PAD_GPIO(142, BUTTON_VOL_DOWN, POR_PU, X7, RES0, RES1, RES2, RES3),
PAD_GPIO(143, BUTTON_SLIDE_SW, POR_PU, Y0, RES0, RES1, RES2, RES3),
PAD_GPIO(144, BUTTON_HOME, POR_PU, Y1, RES0, RES1, RES2, RES3),
PAD_NO_GPIO(145, GPIO_PA6, POR_NP, SATA, RES1, RES2, RES3),
PAD_NO_GPIO(146, GPIO_PE6, POR_PD, RES0, I2S5A, PWM2, RES3),
PAD_NO_GPIO(147, GPIO_PE7, POR_PD, RES0, I2S5A, PWM3, RES3),
PAD_NO_GPIO(148, GPIO_PH6, POR_PD, RES0, RES1, RES2, RES3),
PAD_GPIO(149, GPIO_PK0, POR_PD, K0, IQC0, I2S5B, RES2, RES3),
PAD_GPIO(150, GPIO_PK1, POR_PD, K1, IQC0, I2S5B, RES2, RES3),
PAD_GPIO(151, GPIO_PK2, POR_PD, K2, IQC0, I2S5B, RES2, RES3),
PAD_NO_GPIO(152, GPIO_PK3, POR_PD, IQC0, I2S5B, RES2, RES3),
PAD_NO_GPIO(153, GPIO_PK4, POR_PD, IQC1, RES1, RES2, RES3),
PAD_NO_GPIO(154, GPIO_PK5, POR_PD, IQC1, RES1, RES2, RES3),
PAD_NO_GPIO(155, GPIO_PK6, POR_PD, IQC1, RES1, RES2, RES3),
PAD_NO_GPIO(156, GPIO_PK7, POR_PD, IQC1, RES1, RES2, RES3),
PAD_NO_GPIO(157, GPIO_PL0, POR_PD, RES0, RES1, RES2, RES3),
PAD_NO_GPIO(158, GPIO_PL1, POR_PD, SOC, RES1, RES2, RES3),
PAD_NO_GPIO(159, GPIO_PZ0, POR_PD, VIMCLK2, RES1, RES2, RES3),
PAD_GPIO(160, GPIO_PZ1, POR_PD, Z1, VIMCLK2, SDMMC1, RES2, RES3),
PAD_NO_GPIO(161, GPIO_PZ2, POR_PD, SDMMC3, CCLA, RES2, RES3),
PAD_NO_GPIO(162, GPIO_PZ3, POR_PD, SDMMC3, RES1, RES2, RES3),
PAD_GPIO(163, GPIO_PZ4, POR_PD, Z4, SDMMC1, RES1, RES2, RES3),
PAD_NO_GPIO(164, GPIO_PZ5, POR_PD, SOC, RES1, RES2, RES3),
};
#define GPIO_BY_NAME(x) GPIO_DECOMPOSE(PAD_TO_GPIO_ ## x)
#endif /* __SOC_NVIDIA_TEGRA210_PINMUX_H__ */

719
ariane/src/hwinit/pmc.h Normal file
View file

@ -0,0 +1,719 @@
/*
* Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef _TEGRA210_PMC_H_
#define _TEGRA210_PMC_H_
#include "types.h"
enum {
POWER_PARTID_CRAIL = 0,
POWER_PARTID_TD = 1,
POWER_PARTID_VE = 2,
POWER_PARTID_PCX = 3,
POWER_PARTID_C0L2 = 5,
POWER_PARTID_MPE = 6,
POWER_PARTID_HEG = 7,
POWER_PARTID_SAX = 8,
POWER_PARTID_CE1 = 9,
POWER_PARTID_CE2 = 10,
POWER_PARTID_CE3 = 11,
POWER_PARTID_CELP = 12,
POWER_PARTID_CE0 = 14,
POWER_PARTID_C0NC = 15,
POWER_PARTID_C1NC = 16,
POWER_PARTID_SOR = 17,
POWER_PARTID_DIS = 18,
POWER_PARTID_DISB = 19,
POWER_PARTID_XUSBA = 20,
POWER_PARTID_XUSBB = 21,
POWER_PARTID_XUSBC = 22,
POWER_PARTID_VIC = 23,
POWER_PARTID_IRAM = 24,
POWER_PARTID_NVDEC = 25,
POWER_PARTID_NVJPG = 26,
POWER_PARTID_APE = 27,
POWER_PARTID_DFD = 28,
POWER_PARTID_VE2 = 29,
};
struct tegra_pmc_regs {
vu32 cntrl;
vu32 sec_disable;
vu32 pmc_swrst;
vu32 wake_mask;
vu32 wake_lvl;
vu32 wake_status;
vu32 sw_wake_status;
vu32 dpd_pads_oride;
vu32 dpd_sample;
vu32 dpd_enable;
vu32 pwrgate_timer_off;
vu32 clamp_status;
vu32 pwrgate_toggle;
vu32 remove_clamping_cmd;
vu32 pwrgate_status;
vu32 pwrgood_timer;
vu32 blink_timer;
vu32 no_iopower;
vu32 pwr_det;
vu32 pwr_det_latch;
vu32 scratch0;
vu32 scratch1;
vu32 scratch2;
vu32 scratch3;
vu32 scratch4;
vu32 scratch5;
vu32 scratch6;
vu32 scratch7;
vu32 scratch8;
vu32 scratch9;
vu32 scratch10;
vu32 scratch11;
vu32 scratch12;
vu32 scratch13;
vu32 scratch14;
vu32 scratch15;
vu32 scratch16;
vu32 scratch17;
vu32 scratch18;
vu32 scratch19;
vu32 odmdata;
vu32 scratch21;
vu32 scratch22;
vu32 scratch23;
vu32 secure_scratch0;
vu32 secure_scratch1;
vu32 secure_scratch2;
vu32 secure_scratch3;
vu32 secure_scratch4;
vu32 secure_scratch5;
vu32 cpupwrgood_timer;
vu32 cpupwroff_timer;
vu32 pg_mask;
vu32 pg_mask_1;
vu32 auto_wake_lvl;
vu32 auto_wake_lvl_mask;
vu32 wake_delay;
vu32 pwr_det_val;
vu32 ddr_pwr;
vu32 usb_debounce_del;
vu32 usb_a0;
vu32 crypto_op;
vu32 pllp_wb0_override;
vu32 scratch24;
vu32 scratch25;
vu32 scratch26;
vu32 scratch27;
vu32 scratch28;
vu32 scratch29;
vu32 scratch30;
vu32 scratch31;
vu32 scratch32;
vu32 scratch33;
vu32 scratch34;
vu32 scratch35;
vu32 scratch36;
vu32 scratch37;
vu32 scratch38;
vu32 scratch39;
vu32 scratch40;
vu32 scratch41;
vu32 scratch42;
vu32 bondout_mirror[3];
vu32 sys_33v_en;
vu32 bondout_mirror_access;
vu32 gate;
vu32 wake2_mask;
vu32 wake2_lvl;
vu32 wake2_status;
vu32 sw_wake2_status;
vu32 auto_wake2_lvl_mask;
vu32 pg_mask_2;
vu32 pg_mask_ce1;
vu32 pg_mask_ce2;
vu32 pg_mask_ce3;
vu32 pwrgate_timer_ce[7];
vu32 pcx_edpd_cntrl;
vu32 osc_edpd_over;
vu32 clk_out_cntrl;
vu32 sata_pwrgt;
vu32 sensor_ctrl;
vu32 rst_status;
vu32 io_dpd_req;
vu32 io_dpd_status;
vu32 io_dpd2_req;
vu32 io_dpd2_status;
vu32 sel_dpd_tim;
vu32 vddp_sel;
vu32 ddr_cfg;
vu32 e_no_vttgen;
u8 _rsv0[4];
vu32 pllm_wb0_override_freq;
vu32 test_pwrgate;
vu32 pwrgate_timer_mult;
vu32 dis_sel_dpd;
vu32 utmip_uhsic_triggers;
vu32 utmip_uhsic_saved_state;
vu32 utmip_pad_cfg;
vu32 utmip_term_pad_cfg;
vu32 utmip_uhsic_sleep_cfg;
vu32 utmip_uhsic_sleepwalk_cfg;
vu32 utmip_sleepwalk_p[3];
vu32 uhsic_sleepwalk_p0;
vu32 utmip_uhsic_status;
vu32 utmip_uhsic_fake;
vu32 bondout_mirror3[5 - 3];
vu32 secure_scratch6;
vu32 secure_scratch7;
vu32 scratch43;
vu32 scratch44;
vu32 scratch45;
vu32 scratch46;
vu32 scratch47;
vu32 scratch48;
vu32 scratch49;
vu32 scratch50;
vu32 scratch51;
vu32 scratch52;
vu32 scratch53;
vu32 scratch54;
vu32 scratch55;
vu32 scratch0_eco;
vu32 por_dpd_ctrl;
vu32 scratch2_eco;
vu32 utmip_uhsic_line_wakeup;
vu32 utmip_bias_master_cntrl;
vu32 utmip_master_config;
vu32 td_pwrgate_inter_part_timer;
vu32 utmip_uhsic2_triggers;
vu32 utmip_uhsic2_saved_state;
vu32 utmip_uhsic2_sleep_cfg;
vu32 utmip_uhsic2_sleepwalk_cfg;
vu32 uhsic2_sleepwalk_p1;
vu32 utmip_uhsic2_status;
vu32 utmip_uhsic2_fake;
vu32 utmip_uhsic2_line_wakeup;
vu32 utmip_master2_config;
vu32 utmip_uhsic_rpd_cfg;
vu32 pg_mask_ce0;
vu32 pg_mask3[5 - 3];
vu32 pllm_wb0_override2;
vu32 tsc_mult;
vu32 cpu_vsense_override;
vu32 glb_amap_cfg;
vu32 sticky_bits;
vu32 sec_disable2;
vu32 weak_bias;
vu32 reg_short;
vu32 pg_mask_andor;
u8 _rsv1[0x2c];
vu32 secure_scratch8; /* offset 0x300 */
vu32 secure_scratch9;
vu32 secure_scratch10;
vu32 secure_scratch11;
vu32 secure_scratch12;
vu32 secure_scratch13;
vu32 secure_scratch14;
vu32 secure_scratch15;
vu32 secure_scratch16;
vu32 secure_scratch17;
vu32 secure_scratch18;
vu32 secure_scratch19;
vu32 secure_scratch20;
vu32 secure_scratch21;
vu32 secure_scratch22;
vu32 secure_scratch23;
vu32 secure_scratch24;
vu32 secure_scratch25;
vu32 secure_scratch26;
vu32 secure_scratch27;
vu32 secure_scratch28;
vu32 secure_scratch29;
vu32 secure_scratch30;
vu32 secure_scratch31;
vu32 secure_scratch32;
vu32 secure_scratch33;
vu32 secure_scratch34;
vu32 secure_scratch35;
vu32 secure_scratch36;
vu32 secure_scratch37;
vu32 secure_scratch38;
vu32 secure_scratch39;
vu32 secure_scratch40;
vu32 secure_scratch41;
vu32 secure_scratch42;
vu32 secure_scratch43;
vu32 secure_scratch44;
vu32 secure_scratch45;
vu32 secure_scratch46;
vu32 secure_scratch47;
vu32 secure_scratch48;
vu32 secure_scratch49;
vu32 secure_scratch50;
vu32 secure_scratch51;
vu32 secure_scratch52;
vu32 secure_scratch53;
vu32 secure_scratch54;
vu32 secure_scratch55;
vu32 secure_scratch56;
vu32 secure_scratch57;
vu32 secure_scratch58;
vu32 secure_scratch59;
vu32 secure_scratch60;
vu32 secure_scratch61;
vu32 secure_scratch62;
vu32 secure_scratch63;
vu32 secure_scratch64;
vu32 secure_scratch65;
vu32 secure_scratch66;
vu32 secure_scratch67;
vu32 secure_scratch68;
vu32 secure_scratch69;
vu32 secure_scratch70;
vu32 secure_scratch71;
vu32 secure_scratch72;
vu32 secure_scratch73;
vu32 secure_scratch74;
vu32 secure_scratch75;
vu32 secure_scratch76;
vu32 secure_scratch77;
vu32 secure_scratch78;
vu32 secure_scratch79;
vu32 _rsv0x420[8];
vu32 cntrl2; /* 0x440 */
vu32 _rsv0x444[2];
vu32 event_counter; /* 0x44C */
vu32 fuse_control;
vu32 scratch1_eco;
vu32 _rsv0x458[1];
vu32 io_dpd3_req; /* 0x45C */
vu32 io_dpd3_status;
vu32 io_dpd4_req;
vu32 io_dpd4_status;
vu32 _rsv0x46C[30];
vu32 ddr_cntrl; /* 0x4E4 */
vu32 _rsv0x4E8[70];
vu32 scratch56; /* 0x600 */
vu32 scratch57;
vu32 scratch58;
vu32 scratch59;
vu32 scratch60;
vu32 scratch61;
vu32 scratch62;
vu32 scratch63;
vu32 scratch64;
vu32 scratch65;
vu32 scratch66;
vu32 scratch67;
vu32 scratch68;
vu32 scratch69;
vu32 scratch70;
vu32 scratch71;
vu32 scratch72;
vu32 scratch73;
vu32 scratch74;
vu32 scratch75;
vu32 scratch76;
vu32 scratch77;
vu32 scratch78;
vu32 scratch79;
vu32 scratch80;
vu32 scratch81;
vu32 scratch82;
vu32 scratch83;
vu32 scratch84;
vu32 scratch85;
vu32 scratch86;
vu32 scratch87;
vu32 scratch88;
vu32 scratch89;
vu32 scratch90;
vu32 scratch91;
vu32 scratch92;
vu32 scratch93;
vu32 scratch94;
vu32 scratch95;
vu32 scratch96;
vu32 scratch97;
vu32 scratch98;
vu32 scratch99;
vu32 scratch100;
vu32 scratch101;
vu32 scratch102;
vu32 scratch103;
vu32 scratch104;
vu32 scratch105;
vu32 scratch106;
vu32 scratch107;
vu32 scratch108;
vu32 scratch109;
vu32 scratch110;
vu32 scratch111;
vu32 scratch112;
vu32 scratch113;
vu32 scratch114;
vu32 scratch115;
vu32 scratch116;
vu32 scratch117;
vu32 scratch118;
vu32 scratch119;
vu32 scratch120; /* 0x700 */
vu32 scratch121;
vu32 scratch122;
vu32 scratch123;
vu32 scratch124;
vu32 scratch125;
vu32 scratch126;
vu32 scratch127;
vu32 scratch128;
vu32 scratch129;
vu32 scratch130;
vu32 scratch131;
vu32 scratch132;
vu32 scratch133;
vu32 scratch134;
vu32 scratch135;
vu32 scratch136;
vu32 scratch137;
vu32 scratch138;
vu32 scratch139;
vu32 scratch140;
vu32 scratch141;
vu32 scratch142;
vu32 scratch143;
vu32 scratch144;
vu32 scratch145;
vu32 scratch146;
vu32 scratch147;
vu32 scratch148;
vu32 scratch149;
vu32 scratch150;
vu32 scratch151;
vu32 scratch152;
vu32 scratch153;
vu32 scratch154;
vu32 scratch155;
vu32 scratch156;
vu32 scratch157;
vu32 scratch158;
vu32 scratch159;
vu32 scratch160;
vu32 scratch161;
vu32 scratch162;
vu32 scratch163;
vu32 scratch164;
vu32 scratch165;
vu32 scratch166;
vu32 scratch167;
vu32 scratch168;
vu32 scratch169;
vu32 scratch170;
vu32 scratch171;
vu32 scratch172;
vu32 scratch173;
vu32 scratch174;
vu32 scratch175;
vu32 scratch176;
vu32 scratch177;
vu32 scratch178;
vu32 scratch179;
vu32 scratch180;
vu32 scratch181;
vu32 scratch182;
vu32 scratch183;
vu32 scratch184;
vu32 scratch185;
vu32 scratch186;
vu32 scratch187;
vu32 scratch188;
vu32 scratch189;
vu32 scratch190;
vu32 scratch191;
vu32 scratch192;
vu32 scratch193;
vu32 scratch194;
vu32 scratch195;
vu32 scratch196;
vu32 scratch197;
vu32 scratch198;
vu32 scratch199;
vu32 scratch200;
vu32 scratch201;
vu32 scratch202;
vu32 scratch203;
vu32 scratch204;
vu32 scratch205;
vu32 scratch206;
vu32 scratch207;
vu32 scratch208;
vu32 scratch209;
vu32 scratch210;
vu32 scratch211;
vu32 scratch212;
vu32 scratch213;
vu32 scratch214;
vu32 scratch215;
vu32 scratch216;
vu32 scratch217;
vu32 scratch218;
vu32 scratch219;
vu32 scratch220;
vu32 scratch221;
vu32 scratch222;
vu32 scratch223;
vu32 scratch224;
vu32 scratch225;
vu32 scratch226;
vu32 scratch227;
vu32 scratch228;
vu32 scratch229;
vu32 scratch230;
vu32 scratch231;
vu32 scratch232;
vu32 scratch233;
vu32 scratch234;
vu32 scratch235;
vu32 scratch236;
vu32 scratch237;
vu32 scratch238;
vu32 scratch239;
vu32 scratch240;
vu32 scratch241;
vu32 scratch242;
vu32 scratch243;
vu32 scratch244;
vu32 scratch245;
vu32 scratch246;
vu32 scratch247;
vu32 scratch248;
vu32 scratch249;
vu32 scratch250;
vu32 scratch251;
vu32 scratch252;
vu32 scratch253;
vu32 scratch254;
vu32 scratch255;
vu32 scratch256;
vu32 scratch257;
vu32 scratch258;
vu32 scratch259;
vu32 scratch260;
vu32 scratch261;
vu32 scratch262;
vu32 scratch263;
vu32 scratch264;
vu32 scratch265;
vu32 scratch266;
vu32 scratch267;
vu32 scratch268;
vu32 scratch269;
vu32 scratch270;
vu32 scratch271;
vu32 scratch272;
vu32 scratch273;
vu32 scratch274;
vu32 scratch275;
vu32 scratch276;
vu32 scratch277;
vu32 scratch278;
vu32 scratch279;
vu32 scratch280;
vu32 scratch281;
vu32 scratch282;
vu32 scratch283;
vu32 scratch284;
vu32 scratch285;
vu32 scratch286;
vu32 scratch287;
vu32 scratch288;
vu32 scratch289;
vu32 scratch290;
vu32 scratch291;
vu32 scratch292;
vu32 scratch293;
vu32 scratch294;
vu32 scratch295;
vu32 scratch296;
vu32 scratch297;
vu32 scratch298;
vu32 scratch299; /* 0x9CC */
vu32 _rsv0x9D0[50];
vu32 secure_scratch80; /* 0xa98 */
vu32 secure_scratch81;
vu32 secure_scratch82;
vu32 secure_scratch83;
vu32 secure_scratch84;
vu32 secure_scratch85;
vu32 secure_scratch86;
vu32 secure_scratch87;
vu32 secure_scratch88;
vu32 secure_scratch89;
vu32 secure_scratch90;
vu32 secure_scratch91;
vu32 secure_scratch92;
vu32 secure_scratch93;
vu32 secure_scratch94;
vu32 secure_scratch95;
vu32 secure_scratch96;
vu32 secure_scratch97;
vu32 secure_scratch98;
vu32 secure_scratch99;
vu32 secure_scratch100;
vu32 secure_scratch101;
vu32 secure_scratch102;
vu32 secure_scratch103;
vu32 secure_scratch104;
vu32 secure_scratch105;
vu32 secure_scratch106;
vu32 secure_scratch107;
vu32 secure_scratch108;
vu32 secure_scratch109;
vu32 secure_scratch110;
vu32 secure_scratch111;
vu32 secure_scratch112;
vu32 secure_scratch113;
vu32 secure_scratch114;
vu32 secure_scratch115;
vu32 secure_scratch116;
vu32 secure_scratch117;
vu32 secure_scratch118;
vu32 secure_scratch119;
};
enum {
PMC_RST_STATUS_SOURCE_MASK = 0x7,
PMC_RST_STATUS_SOURCE_POR = 0x0,
PMC_RST_STATUS_SOURCE_WATCHDOG = 0x1,
PMC_RST_STATUS_SOURCE_SENSOR = 0x2,
PMC_RST_STATUS_SOURCE_SW_MAIN = 0x3,
PMC_RST_STATUS_SOURCE_LP0 = 0x4,
PMC_RST_STATUS_NUM_SOURCES = 0x5,
};
enum {
PMC_PWRGATE_TOGGLE_PARTID_MASK = 0x1f,
PMC_PWRGATE_TOGGLE_PARTID_SHIFT = 0,
PMC_PWRGATE_TOGGLE_START = 0x1 << 8
};
enum {
PMC_CNTRL_KBC_CLK_DIS = 0x1 << 0,
PMC_CNTRL_RTC_CLK_DIS = 0x1 << 1,
PMC_CNTRL_RTC_RST = 0x1 << 2,
PMC_CNTRL_KBC_RST = 0x1 << 3,
PMC_CNTRL_MAIN_RST = 0x1 << 4,
PMC_CNTRL_LATCHWAKE_EN = 0x1 << 5,
PMC_CNTRL_GLITCHDET_DIS = 0x1 << 6,
PMC_CNTRL_BLINK_EN = 0x1 << 7,
PMC_CNTRL_PWRREQ_POLARITY = 0x1 << 8,
PMC_CNTRL_PWRREQ_OE = 0x1 << 9,
PMC_CNTRL_SYSCLK_POLARITY = 0x1 << 10,
PMC_CNTRL_SYSCLK_OE = 0x1 << 11,
PMC_CNTRL_PWRGATE_DIS = 0x1 << 12,
PMC_CNTRL_AOINIT = 0x1 << 13,
PMC_CNTRL_SIDE_EFFECT_LP0 = 0x1 << 14,
PMC_CNTRL_CPUPWRREQ_POLARITY = 0x1 << 15,
PMC_CNTRL_CPUPWRREQ_OE = 0x1 << 16,
PMC_CNTRL_INTR_POLARITY = 0x1 << 17,
PMC_CNTRL_FUSE_OVERRIDE = 0x1 << 18,
PMC_CNTRL_CPUPWRGOOD_EN = 0x1 << 19,
PMC_CNTRL_CPUPWRGOOD_SEL_SHIFT = 20,
PMC_CNTRL_CPUPWRGOOD_SEL_MASK =
0x3 << PMC_CNTRL_CPUPWRGOOD_SEL_SHIFT
};
enum {
PMC_DDR_PWR_EMMC_MASK = 1 << 1,
PMC_DDR_PWR_VAL_MASK = 1 << 0,
};
enum {
PMC_DDR_CFG_PKG_MASK = 1 << 0,
PMC_DDR_CFG_IF_MASK = 1 << 1,
PMC_DDR_CFG_XM0_RESET_TRI_MASK = 1 << 12,
PMC_DDR_CFG_XM0_RESET_DPDIO_MASK = 1 << 13,
};
enum {
PMC_NO_IOPOWER_MEM_MASK = 1 << 7,
PMC_NO_IOPOWER_MEM_COMP_MASK = 1 << 16,
};
enum {
PMC_POR_DPD_CTRL_MEM0_ADDR0_CLK_SEL_DPD_MASK = 1 << 0,
PMC_POR_DPD_CTRL_MEM0_ADDR1_CLK_SEL_DPD_MASK = 1 << 1,
PMC_POR_DPD_CTRL_MEM0_HOLD_CKE_LOW_OVR_MASK = 1 << 31,
};
enum {
PMC_CNTRL2_HOLD_CKE_LOW_EN = 0x1 << 12
};
enum {
PMC_OSC_EDPD_OVER_XOFS_SHIFT = 1,
PMC_OSC_EDPD_OVER_XOFS_MASK =
0x3f << PMC_OSC_EDPD_OVER_XOFS_SHIFT
};
enum {
PMC_CMD_HOLD_LOW_BR00_11_MASK = 0x0007FF80,
DPD_OFF = 1 << 30,
DPD_ON = 2 << 30,
};
enum {
PMC_GPIO_RAIL_AO_SHIFT = 21,
PMC_GPIO_RAIL_AO_MASK = (1 << PMC_GPIO_RAIL_AO_SHIFT),
PMC_GPIO_RAIL_AO_DISABLE = (0 << PMC_GPIO_RAIL_AO_SHIFT),
PMC_GPIO_RAIL_AO_ENABLE = (1 << PMC_GPIO_RAIL_AO_SHIFT),
PMC_AUDIO_RAIL_AO_SHIFT = 18,
PMC_AUDIO_RAIL_AO_MASK = (1 << PMC_AUDIO_RAIL_AO_SHIFT),
PMC_AUDIO_RAIL_AO_DISABLE = (0 << PMC_AUDIO_RAIL_AO_SHIFT),
PMC_AUDIO_RAIL_AO_ENABLE = (1 << PMC_AUDIO_RAIL_AO_SHIFT),
PMC_SDMMC3_RAIL_AO_SHIFT = 13,
PMC_SDMMC3_RAIL_AO_MASK = (1 << PMC_SDMMC3_RAIL_AO_SHIFT),
PMC_SDMMC3_RAIL_AO_DISABLE = (0 << PMC_SDMMC3_RAIL_AO_SHIFT),
PMC_SDMMC3_RAIL_AO_ENABLE = (1 << PMC_SDMMC3_RAIL_AO_SHIFT),
};
/*! PMC registers. */
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
#define APBDEV_PMC_PWRGATE_STATUS 0x38
#define APBDEV_PMC_NO_IOPOWER 0x44
#define APBDEV_PMC_SCRATCH0 0x50
#define APBDEV_PMC_SCRATCH1 0x54
#define APBDEV_PMC_SCRATCH20 0xA0
#define APBDEV_PMC_PWR_DET_VAL 0xE4
#define APBDEV_PMC_DDR_PWR 0xE8
#define APBDEV_PMC_CRYPTO_OP 0xF4
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
#define APBDEV_PMC_VDDP_SEL 0x1CC
#define APBDEV_PMC_TSC_MULT 0x2B4
#define APBDEV_PMC_REG_SHORT 0x2CC
#define APBDEV_PMC_WEAK_BIAS 0x2C8
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
#define APBDEV_PMC_CNTRL2 0x440
#define APBDEV_PMC_IO_DPD4_REQ 0x464
#define APBDEV_PMC_DDR_CNTRL 0x4E4
#define APBDEV_PMC_SCRATCH188 0x810
#define APBDEV_PMC_SCRATCH190 0x818
#define APBDEV_PMC_SCRATCH200 0x840
#define APBDEV_PMC_SCRATCH49 0x244
#endif

124
ariane/src/hwinit/sd.h Normal file
View file

@ -0,0 +1,124 @@
/*
* include/linux/mmc/sd.h
*
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#ifndef LINUX_MMC_SD_H
#define LINUX_MMC_SD_H
/* SD commands type argument response */
/* class 0 */
/* This is basically the same command as for MMC with some quirks. */
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
/* class 10 */
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
/* class 5 */
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
/* Application commands */
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
#define SD_APP_SD_STATUS 13 /* adtc R1 */
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SET_CLR_CARD_DETECT 42
#define SD_APP_SEND_SCR 51 /* adtc R1 */
/* OCR bit definitions */
#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
#define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
/*
* SD_SWITCH argument format:
*
* [31] Check (0) or switch (1)
* [30:24] Reserved (0)
* [23:20] Function group 6
* [19:16] Function group 5
* [15:12] Function group 4
* [11:8] Function group 3
* [7:4] Function group 2
* [3:0] Function group 1
*/
/*
* SD_SEND_IF_COND argument format:
*
* [31:12] Reserved (0)
* [11:8] Host Voltage Supply Flags
* [7:0] Check Pattern (0xAA)
*/
/*
* SCR field definitions
*/
#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */
#define SD_SCR_BUS_WIDTH_1 (1<<0)
#define SD_SCR_BUS_WIDTH_4 (1<<2)
/*
* SD bus widths
*/
#define SD_BUS_WIDTH_1 0
#define SD_BUS_WIDTH_4 2
/*
* SD bus speeds
*/
#define UHS_SDR12_BUS_SPEED 0
#define HIGH_SPEED_BUS_SPEED 1
#define UHS_SDR25_BUS_SPEED 1
#define UHS_SDR50_BUS_SPEED 2
#define UHS_SDR104_BUS_SPEED 3
#define UHS_DDR50_BUS_SPEED 4
#define HS400_BUS_SPEED 5
#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED)
#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED)
#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED)
#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED)
#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED)
#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED)
#define SD_DRIVER_TYPE_B 0x01
#define SD_DRIVER_TYPE_A 0x02
#define SD_SET_CURRENT_LIMIT_200 0
#define SD_SET_CURRENT_LIMIT_400 1
#define SD_SET_CURRENT_LIMIT_600 2
#define SD_SET_CURRENT_LIMIT_800 3
/*
* SD_SWITCH mode
*/
#define SD_SWITCH_CHECK 0
#define SD_SWITCH_SET 1
/*
* SD_SWITCH function groups
*/
#define SD_SWITCH_GRP_ACCESS 0
/*
* SD_SWITCH access modes
*/
#define SD_SWITCH_ACCESS_DEF 0
#define SD_SWITCH_ACCESS_HS 1
#endif /* LINUX_MMC_SD_H */

1198
ariane/src/hwinit/sdmmc.c Normal file

File diff suppressed because it is too large Load diff

111
ariane/src/hwinit/sdmmc.h Normal file
View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SDMMC_H_
#define _SDMMC_H_
#include "types.h"
#include "sdmmc_driver.h"
typedef struct _mmc_cid
{
u32 manfid;
u8 prod_name[8];
u8 card_bga;
u8 prv;
u32 serial;
u16 oemid;
u16 year;
u8 hwrev;
u8 fwrev;
u8 month;
} mmc_cid_t;
typedef struct _mmc_csd
{
u8 structure;
u8 mmca_vsn;
u16 cmdclass;
u32 c_size;
u32 r2w_factor;
u32 max_dtr;
u32 erase_size; /* In sectors */
u32 read_blkbits;
u32 write_blkbits;
u32 capacity;
u8 write_protect;
u16 busspeed;
} mmc_csd_t;
typedef struct _mmc_ext_csd
{
u8 rev;
u32 sectors;
int bkops; /* background support bit */
int bkops_en; /* manual bkops enable bit */
u8 ext_struct; /* 194 */
u8 card_type; /* 196 */
u8 bkops_status; /* 246 */
u16 dev_version;
u8 boot_mult;
u8 rpmb_mult;
} mmc_ext_csd_t;
typedef struct _sd_scr
{
u8 sda_vsn;
u8 sda_spec3;
u8 bus_widths;
u8 cmds;
} sd_scr_t;
typedef struct _sd_ssr {
u8 bus_width;
u8 speed_class;
u8 uhs_grade;
u8 video_class;
u8 app_class;
} sd_ssr_t;
/*! SDMMC storage context. */
typedef struct _sdmmc_storage_t
{
sdmmc_t *sdmmc;
u32 rca;
int has_sector_access;
u32 sec_cnt;
int is_low_voltage;
u32 partition;
u8 raw_cid[0x10];
u8 raw_csd[0x10];
u8 raw_scr[8];
u8 raw_ssr[0x40];
mmc_cid_t cid;
mmc_csd_t csd;
mmc_ext_csd_t ext_csd;
sd_scr_t scr;
sd_ssr_t ssr;
} sdmmc_storage_t;
int sdmmc_storage_end(sdmmc_storage_t *storage, u32 powerOff);
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);
int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition);
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SDMMC_DRIVER_H_
#define _SDMMC_DRIVER_H_
#include "types.h"
#include "sdmmc_t210.h"
/*! SDMMC controller IDs. */
#define SDMMC_1 0
#define SDMMC_2 1
#define SDMMC_3 2
#define SDMMC_4 3
/*! SDMMC power types. */
#define SDMMC_POWER_OFF 0
#define SDMMC_POWER_1_8 1
#define SDMMC_POWER_3_3 2
/*! SDMMC bus widths. */
#define SDMMC_BUS_WIDTH_1 0
#define SDMMC_BUS_WIDTH_4 1
#define SDMMC_BUS_WIDTH_8 2
/*! SDMMC response types. */
#define SDMMC_RSP_TYPE_0 0
#define SDMMC_RSP_TYPE_1 1
#define SDMMC_RSP_TYPE_2 2
#define SDMMC_RSP_TYPE_3 3
#define SDMMC_RSP_TYPE_4 4
#define SDMMC_RSP_TYPE_5 5
/*! SDMMC mask interrupt status. */
#define SDMMC_MASKINT_MASKED 0
#define SDMMC_MASKINT_NOERROR -1
#define SDMMC_MASKINT_ERROR -2
/*! SDMMC host control 2 */
#define SDHCI_CTRL_UHS_MASK 0xFFF8
#define SDHCI_CTRL_VDD_330 0xFFF7
#define SDHCI_CTRL_VDD_180 8
#define SDHCI_CTRL_EXEC_TUNING 0x40
#define SDHCI_CTRL_TUNED_CLK 0x80
#define SDHCI_HOST_VERSION_4_EN 0x1000
#define SDHCI_ADDRESSING_64BIT_EN 0x2000
#define SDHCI_CTRL_PRESET_VAL_EN 0x8000
/*! SD bus speeds. */
#define UHS_SDR12_BUS_SPEED 0
#define HIGH_SPEED_BUS_SPEED 1
#define UHS_SDR25_BUS_SPEED 1
#define UHS_SDR50_BUS_SPEED 2
#define UHS_SDR104_BUS_SPEED 3
#define UHS_DDR50_BUS_SPEED 4
#define HS400_BUS_SPEED 5
/*! Helper for SWITCH command argument. */
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
/*! SDMMC controller context. */
typedef struct _sdmmc_t
{
t210_sdmmc_t *regs;
u32 id;
u32 divisor;
u32 clock_stopped;
int no_sd;
int sd_clock_enabled;
int venclkctl_set;
u32 venclkctl_tap;
u32 expected_rsp_type;
u32 dma_addr_next;
u32 rsp[4];
u32 rsp3;
} sdmmc_t;
/*! SDMMC command. */
typedef struct _sdmmc_cmd_t
{
u16 cmd;
u32 arg;
u32 rsp_type;
u32 check_busy;
} sdmmc_cmd_t;
/*! SDMMC request. */
typedef struct _sdmmc_req_t
{
void *buf;
u32 blksize;
u32 num_sectors;
int is_write;
int is_multi_block;
int is_auto_cmd12;
} sdmmc_req_t;
int sdmmc_get_voltage(sdmmc_t *sdmmc);
u32 sdmmc_get_bus_width(sdmmc_t *sdmmc);
void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width);
void sdmmc_get_venclkctl(sdmmc_t *sdmmc);
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);
void sdmmc_sd_clock_ctrl(sdmmc_t *sdmmc, int no_sd);
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);
int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd);
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int no_sd);
void sdmmc_end(sdmmc_t *sdmmc, u32 powerOff);
void sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy);
int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out);
int sdmmc_enable_low_voltage(sdmmc_t *sdmmc);
#endif

View file

@ -0,0 +1,132 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SDMMC_T210_H_
#define _SDMMC_T210_H_
#include "types.h"
#define TEGRA_MMC_PWRCTL_SD_BUS_POWER 0x1
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8 0xA
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0 0xC
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3 0xE
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_MASK 0xF1
#define TEGRA_MMC_HOSTCTL_1BIT 0x00
#define TEGRA_MMC_HOSTCTL_4BIT 0x02
#define TEGRA_MMC_HOSTCTL_8BIT 0x20
#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE 0x1
#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE 0x2
#define TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE 0x4
#define TEGRA_MMC_CLKCON_CLKGEN_SELECT 0x20
#define TEGRA_MMC_SWRST_SW_RESET_FOR_ALL 0x1
#define TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE 0x2
#define TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE 0x4
#define TEGRA_MMC_TRNMOD_DMA_ENABLE 0x1
#define TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE 0x2
#define TEGRA_MMC_TRNMOD_AUTO_CMD12 0x4
#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_WRITE 0x0
#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ 0x10
#define TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT 0x20
#define TEGRA_MMC_TRNMOD_CMD_CRC_CHECK 0x8
#define TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK 0x10
#define TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER 0x20
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_MASK 0x3
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE 0x0
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 0x1
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 0x2
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY 0x3
#define TEGRA_MMC_NORINTSTS_CMD_COMPLETE 0x1
#define TEGRA_MMC_NORINTSTS_XFER_COMPLETE 0x2
#define TEGRA_MMC_NORINTSTS_DMA_INTERRUPT 0x8
#define TEGRA_MMC_NORINTSTS_ERR_INTERRUPT 0x8000
#define TEGRA_MMC_NORINTSTS_CMD_TIMEOUT 0x10000
#define TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY 0x20
typedef struct _t210_sdmmc_t
{
vu32 sysad;
vu16 blksize;
vu16 blkcnt;
vu32 argument;
vu16 trnmod;
vu16 cmdreg;
vu32 rspreg0;
vu32 rspreg1;
vu32 rspreg2;
vu32 rspreg3;
vu32 bdata;
vu32 prnsts;
vu8 hostctl;
vu8 pwrcon;
vu8 blkgap;
vu8 wakcon;
vu16 clkcon;
vu8 timeoutcon;
vu8 swrst;
vu16 norintsts;
vu16 errintsts;
vu16 norintstsen;
vu16 errintstsen;
vu16 norintsigen;
vu16 errintsigen;
vu16 acmd12errsts;
vu16 hostctl2;
vu32 capareg;
vu32 capareg_1;
vu32 maxcurr;
vu8 res3[4];
vu16 setacmd12err;
vu16 setinterr;
vu8 admaerr;
vu8 res4[3];
vu32 admaaddr;
vu32 admaaddr_hi;
vu8 res5[156];
vu16 slotintstatus;
vu16 hcver;
vu32 venclkctl;
vu32 venspictl;
vu32 venspiintsts;
vu32 venceatactl;
vu32 venbootctl;
vu32 venbootacktout;
vu32 venbootdattout;
vu32 vendebouncecnt;
vu32 venmiscctl;
vu32 res6[34];
vu32 field_1AC;
vu32 field_1B0;
vu8 res7[8];
vu32 field_1BC;
vu32 field_1C0;
vu32 field_1C4;
vu8 field_1C8[24];
vu32 sdmemcmppadctl;
vu32 autocalcfg;
vu32 autocalintval;
vu32 autocalsts;
vu32 field_1F0;
} t210_sdmmc_t;
#endif

1113
ariane/src/hwinit/sdram.c Normal file

File diff suppressed because it is too large Load diff

28
ariane/src/hwinit/sdram.h Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SDRAM_H_
#define _SDRAM_H_
u32 get_sdram_id();
struct sdram_params;
void sdram_init(const struct sdram_params* params);
const struct sdram_params* sdram_get_params();
void sdram_lp0_save_params(const struct sdram_params* params);
void _sdram_config(const struct sdram_params *param);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,67 @@
static const u8 _dram_cfg_lz4[1023] =
{
0x04, 0x22, 0x4D, 0x18, 0x64, 0x40, 0xA7, 0xEC, 0x03, 0x00, 0x00, 0xFF, 0x00, 0x03, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x01, 0x00, 0x0E, 0xFC,
0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70, 0x01, 0x32, 0x54,
0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,
0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0,
0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, 0xD3, 0xA6, 0xA6, 0xAF, 0xB3,
0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x00, 0x3C, 0x00, 0x19, 0x1F,
0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, 0x01, 0x00, 0x00, 0x32, 0x64,
0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00,
0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C, 0x00, 0x10, 0x09, 0xC8, 0x00,
0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x57, 0x20,
0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02,
0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, 0x58, 0x00, 0x13, 0x02, 0x18,
0x00, 0x04, 0x64, 0x00, 0x04, 0xAA, 0x00, 0xB5, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x5C, 0x01, 0x03, 0x65, 0x00, 0x13, 0xC1, 0x54, 0x00, 0x17,
0x08, 0xCC, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x58, 0x00, 0x13, 0x27, 0x04, 0x00, 0x13,
0x05, 0x04, 0x00, 0x13, 0x04, 0xDC, 0x00, 0x08, 0x0C, 0x00, 0xA0, 0x1C, 0x03, 0x00, 0x00, 0x0D,
0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02,
0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C,
0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A,
0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0x12,
0xC5, 0x01, 0x2C, 0x00, 0xFF, 0xF0, 0x01, 0xB0, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08,
0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, 0x72,
0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14,
0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x6B, 0x02, 0x70, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00,
0x33, 0x72, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xD0, 0x01, 0x80,
0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, 0x00, 0x10, 0x04,
0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37,
0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F,
0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10, 0xBE, 0xBF, 0x00, 0x12, 0x0F,
0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x18,
0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x1F, 0x28, 0x02, 0x00, 0x0C,
0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00, 0x0C, 0x7A, 0x00, 0x05, 0x50,
0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x18, 0x00, 0x00, 0x28,
0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x58, 0x01, 0x03, 0x04,
0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03, 0x64, 0x03, 0x02, 0xA1, 0x01,
0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x78, 0x03, 0x04, 0x38, 0x00, 0x36, 0x8B, 0xFF, 0x07,
0xA0, 0x00, 0xF1, 0x00, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01,
0x34, 0x67, 0x25, 0x14, 0x00, 0xF0, 0x00, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23,
0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x14, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01,
0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x9C, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01,
0x00, 0x84, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x8A, 0x00, 0xB2, 0x08,
0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x61, 0x03, 0x0B, 0xA0, 0x04, 0x13,
0x37, 0x7A, 0x01, 0x12, 0x10, 0x95, 0x01, 0x31, 0x00, 0x11, 0x01, 0xC1, 0x02, 0x00, 0x1F, 0x00,
0x13, 0x0A, 0xB5, 0x04, 0x17, 0x10, 0x7F, 0x03, 0x05, 0x12, 0x00, 0x00, 0x10, 0x04, 0xCF, 0x81,
0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x34, 0x01, 0x05, 0x53, 0xFF,
0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01, 0x00, 0x01, 0x2C,
0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x60, 0x01, 0xB2, 0x08, 0x4C, 0x00,
0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE8, 0x02, 0x0C, 0x7C, 0x01, 0x04, 0x08, 0x00,
0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xF4, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03,
0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0xA4, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, 0xC8, 0x03,
0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xDC, 0x03, 0x68, 0x43, 0xC3, 0xBA,
0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, 0x00, 0x14,
0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x75, 0x0C, 0x00, 0x04, 0x58, 0x02, 0x01, 0x05,
0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7C, 0x16, 0x40, 0xAB, 0x05, 0x0F, 0x38, 0x00, 0x17,
0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x04, 0x0F, 0xF4, 0x02, 0x0A, 0x3F, 0x42, 0x24, 0x00, 0x38,
0x00, 0x23, 0x12, 0x2C, 0x38, 0x00, 0x2F, 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x74, 0x07, 0xF9,
0x1F, 0x0D, 0x74, 0x07, 0x4C, 0x03, 0x5F, 0x01, 0x1F, 0x80, 0x74, 0x07, 0xFF, 0xFF, 0xFF, 0x7D,
0x1F, 0x02, 0x74, 0x07, 0xB7, 0x1F, 0x05, 0x74, 0x07, 0xFF, 0x95, 0x0F, 0xE8, 0x0E, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x75, 0x0F, 0x74, 0x07, 0x95, 0x1F, 0x12, 0x74, 0x07, 0x18,
0x1F, 0x03, 0x74, 0x07, 0xFF, 0xFF, 0xB6, 0x13, 0x12, 0x04, 0x00, 0x0F, 0x74, 0x07, 0xFF, 0xFF,
0xAE, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x52, 0xE1, 0xE3
};

View file

@ -0,0 +1,971 @@
/*
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
* Copyright 2014 Google Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
/**
* Defines the SDRAM parameter structure.
*
* Note that PLLM is used by EMC. The field names are in camel case to ease
* directly converting BCT config files (*.cfg) into C structure.
*/
#ifndef __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
#define __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
#include <stddef.h>
#include <stdint.h>
enum {
/* Specifies the memory type to be undefined */
NvBootMemoryType_None = 0,
/* Specifies the memory type to be DDR SDRAM */
NvBootMemoryType_Ddr = 0,
/* Specifies the memory type to be LPDDR SDRAM */
NvBootMemoryType_LpDdr = 0,
/* Specifies the memory type to be DDR2 SDRAM */
NvBootMemoryType_Ddr2 = 0,
/* Specifies the memory type to be LPDDR2 SDRAM */
NvBootMemoryType_LpDdr2,
/* Specifies the memory type to be DDR3 SDRAM */
NvBootMemoryType_Ddr3,
/* Specifies the memory type to be LPDDR4 SDRAM */
NvBootMemoryType_LpDdr4,
NvBootMemoryType_Num,
/* Specifies an entry in the ram_code table that's not in use */
NvBootMemoryType_Unused = 0X7FFFFFF,
};
enum {
BOOT_ROM_PATCH_CONTROL_ENABLE_MASK = 0x1 << 31,
BOOT_ROM_PATCH_CONTROL_OFFSET_SHIFT = 0,
BOOT_ROM_PATCH_CONTROL_OFFSET_MASK = 0x7FFFFFFF << 0,
BOOT_ROM_PATCH_CONTROL_BASE_ADDRESS = 0x70000000,
EMC_ZCAL_WARM_COLD_BOOT_ENABLES_COLDBOOT_MASK = 1 << 0,
};
/**
* Defines the SDRAM parameter structure
*/
typedef struct sdram_params {
/* Specifies the type of memory device */
uint32_t MemoryType;
/* MC/EMC clock source configuration */
/* Specifies the M value for PllM */
uint32_t PllMInputDivider;
/* Specifies the N value for PllM */
uint32_t PllMFeedbackDivider;
/* Specifies the time to wait for PLLM to lock (in microseconds) */
uint32_t PllMStableTime;
/* Specifies misc. control bits */
uint32_t PllMSetupControl;
/* Specifies the P value for PLLM */
uint32_t PllMPostDivider;
/* Specifies value for Charge Pump Gain Control */
uint32_t PllMKCP;
/* Specifies VCO gain */
uint32_t PllMKVCO;
/* Spare BCT param */
uint32_t EmcBctSpare0;
/* Spare BCT param */
uint32_t EmcBctSpare1;
/* Spare BCT param */
uint32_t EmcBctSpare2;
/* Spare BCT param */
uint32_t EmcBctSpare3;
/* Spare BCT param */
uint32_t EmcBctSpare4;
/* Spare BCT param */
uint32_t EmcBctSpare5;
/* Spare BCT param */
uint32_t EmcBctSpare6;
/* Spare BCT param */
uint32_t EmcBctSpare7;
/* Spare BCT param */
uint32_t EmcBctSpare8;
/* Spare BCT param */
uint32_t EmcBctSpare9;
/* Spare BCT param */
uint32_t EmcBctSpare10;
/* Spare BCT param */
uint32_t EmcBctSpare11;
/* Spare BCT param */
uint32_t EmcBctSpare12;
/* Spare BCT param */
uint32_t EmcBctSpare13;
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
uint32_t EmcClockSource;
uint32_t EmcClockSourceDll;
/* Defines possible override for PLLLM_MISC2 */
uint32_t ClkRstControllerPllmMisc2Override;
/* enables override for PLLLM_MISC2 */
uint32_t ClkRstControllerPllmMisc2OverrideEnable;
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
uint32_t ClearClk2Mc1;
/* Auto-calibration of EMC pads */
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
uint32_t EmcAutoCalInterval;
/*
* Specifies the value for EMC_AUTO_CAL_CONFIG
* Note: Trigger bits are set by the SDRAM code.
*/
uint32_t EmcAutoCalConfig;
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
uint32_t EmcAutoCalConfig2;
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
uint32_t EmcAutoCalConfig3;
/* Specifies the values for EMC_AUTO_CAL_CONFIG4-8 */
uint32_t EmcAutoCalConfig4;
uint32_t EmcAutoCalConfig5;
uint32_t EmcAutoCalConfig6;
uint32_t EmcAutoCalConfig7;
uint32_t EmcAutoCalConfig8;
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
uint32_t EmcAutoCalVrefSel0;
uint32_t EmcAutoCalVrefSel1;
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
uint32_t EmcAutoCalChannel;
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
uint32_t EmcPmacroAutocalCfg0;
uint32_t EmcPmacroAutocalCfg1;
uint32_t EmcPmacroAutocalCfg2;
uint32_t EmcPmacroRxTerm;
uint32_t EmcPmacroDqTxDrv;
uint32_t EmcPmacroCaTxDrv;
uint32_t EmcPmacroCmdTxDrv;
uint32_t EmcPmacroAutocalCfgCommon;
uint32_t EmcPmacroZctrl;
/*
* Specifies the time for the calibration
* to stabilize (in microseconds)
*/
uint32_t EmcAutoCalWait;
uint32_t EmcXm2CompPadCtrl;
uint32_t EmcXm2CompPadCtrl2;
uint32_t EmcXm2CompPadCtrl3;
/*
* DRAM size information
* Specifies the value for EMC_ADR_CFG
*/
uint32_t EmcAdrCfg;
/*
* Specifies the time to wait after asserting pin
* CKE (in microseconds)
*/
uint32_t EmcPinProgramWait;
/* Specifies the extra delay before/after pin RESET/CKE command */
uint32_t EmcPinExtraWait;
uint32_t EmcPinGpioEn;
uint32_t EmcPinGpio;
/*
* Specifies the extra delay after the first writing
* of EMC_TIMING_CONTROL
*/
uint32_t EmcTimingControlWait;
/* Timing parameters required for the SDRAM */
/* Specifies the value for EMC_RC */
uint32_t EmcRc;
/* Specifies the value for EMC_RFC */
uint32_t EmcRfc;
/* Specifies the value for EMC_RFC_PB */
uint32_t EmcRfcPb;
/* Specifies the value for EMC_RFC_CTRL2 */
uint32_t EmcRefctrl2;
/* Specifies the value for EMC_RFC_SLR */
uint32_t EmcRfcSlr;
/* Specifies the value for EMC_RAS */
uint32_t EmcRas;
/* Specifies the value for EMC_RP */
uint32_t EmcRp;
/* Specifies the value for EMC_R2R */
uint32_t EmcR2r;
/* Specifies the value for EMC_W2W */
uint32_t EmcW2w;
/* Specifies the value for EMC_R2W */
uint32_t EmcR2w;
/* Specifies the value for EMC_W2R */
uint32_t EmcW2r;
/* Specifies the value for EMC_R2P */
uint32_t EmcR2p;
/* Specifies the value for EMC_W2P */
uint32_t EmcW2p;
uint32_t EmcTppd;
uint32_t EmcCcdmw;
/* Specifies the value for EMC_RD_RCD */
uint32_t EmcRdRcd;
/* Specifies the value for EMC_WR_RCD */
uint32_t EmcWrRcd;
/* Specifies the value for EMC_RRD */
uint32_t EmcRrd;
/* Specifies the value for EMC_REXT */
uint32_t EmcRext;
/* Specifies the value for EMC_WEXT */
uint32_t EmcWext;
/* Specifies the value for EMC_WDV */
uint32_t EmcWdv;
uint32_t EmcWdvChk;
uint32_t EmcWsv;
uint32_t EmcWev;
/* Specifies the value for EMC_WDV_MASK */
uint32_t EmcWdvMask;
uint32_t EmcWsDuration;
uint32_t EmcWeDuration;
/* Specifies the value for EMC_QUSE */
uint32_t EmcQUse;
/* Specifies the value for EMC_QUSE_WIDTH */
uint32_t EmcQuseWidth;
/* Specifies the value for EMC_IBDLY */
uint32_t EmcIbdly;
/* Specifies the value for EMC_OBDLY */
uint32_t EmcObdly;
/* Specifies the value for EMC_EINPUT */
uint32_t EmcEInput;
/* Specifies the value for EMC_EINPUT_DURATION */
uint32_t EmcEInputDuration;
/* Specifies the value for EMC_PUTERM_EXTRA */
uint32_t EmcPutermExtra;
/* Specifies the value for EMC_PUTERM_WIDTH */
uint32_t EmcPutermWidth;
/* Specifies the value for EMC_PUTERM_ADJ */
uint32_t EmcPutermAdj;
/* Specifies the value for EMC_QRST */
uint32_t EmcQRst;
/* Specifies the value for EMC_QSAFE */
uint32_t EmcQSafe;
/* Specifies the value for EMC_RDV */
uint32_t EmcRdv;
/* Specifies the value for EMC_RDV_MASK */
uint32_t EmcRdvMask;
/* Specifies the value for EMC_RDV_EARLY */
uint32_t EmcRdvEarly;
/* Specifies the value for EMC_RDV_EARLY_MASK */
uint32_t EmcRdvEarlyMask;
/* Specifies the value for EMC_QPOP */
uint32_t EmcQpop;
/* Specifies the value for EMC_REFRESH */
uint32_t EmcRefresh;
/* Specifies the value for EMC_BURST_REFRESH_NUM */
uint32_t EmcBurstRefreshNum;
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
uint32_t EmcPreRefreshReqCnt;
/* Specifies the value for EMC_PDEX2WR */
uint32_t EmcPdEx2Wr;
/* Specifies the value for EMC_PDEX2RD */
uint32_t EmcPdEx2Rd;
/* Specifies the value for EMC_PCHG2PDEN */
uint32_t EmcPChg2Pden;
/* Specifies the value for EMC_ACT2PDEN */
uint32_t EmcAct2Pden;
/* Specifies the value for EMC_AR2PDEN */
uint32_t EmcAr2Pden;
/* Specifies the value for EMC_RW2PDEN */
uint32_t EmcRw2Pden;
/* Specifies the value for EMC_CKE2PDEN */
uint32_t EmcCke2Pden;
/* Specifies the value for EMC_PDEX2CKE */
uint32_t EmcPdex2Cke;
/* Specifies the value for EMC_PDEX2MRR */
uint32_t EmcPdex2Mrr;
/* Specifies the value for EMC_TXSR */
uint32_t EmcTxsr;
/* Specifies the value for EMC_TXSRDLL */
uint32_t EmcTxsrDll;
/* Specifies the value for EMC_TCKE */
uint32_t EmcTcke;
/* Specifies the value for EMC_TCKESR */
uint32_t EmcTckesr;
/* Specifies the value for EMC_TPD */
uint32_t EmcTpd;
/* Specifies the value for EMC_TFAW */
uint32_t EmcTfaw;
/* Specifies the value for EMC_TRPAB */
uint32_t EmcTrpab;
/* Specifies the value for EMC_TCLKSTABLE */
uint32_t EmcTClkStable;
/* Specifies the value for EMC_TCLKSTOP */
uint32_t EmcTClkStop;
/* Specifies the value for EMC_TREFBW */
uint32_t EmcTRefBw;
/* FBIO configuration values */
/* Specifies the value for EMC_FBIO_CFG5 */
uint32_t EmcFbioCfg5;
/* Specifies the value for EMC_FBIO_CFG7 */
uint32_t EmcFbioCfg7;
/* Specifies the value for EMC_FBIO_CFG8 */
uint32_t EmcFbioCfg8;
/* Command mapping for CMD brick 0 */
uint32_t EmcCmdMappingCmd0_0;
uint32_t EmcCmdMappingCmd0_1;
uint32_t EmcCmdMappingCmd0_2;
uint32_t EmcCmdMappingCmd1_0;
uint32_t EmcCmdMappingCmd1_1;
uint32_t EmcCmdMappingCmd1_2;
uint32_t EmcCmdMappingCmd2_0;
uint32_t EmcCmdMappingCmd2_1;
uint32_t EmcCmdMappingCmd2_2;
uint32_t EmcCmdMappingCmd3_0;
uint32_t EmcCmdMappingCmd3_1;
uint32_t EmcCmdMappingCmd3_2;
uint32_t EmcCmdMappingByte;
/* Specifies the value for EMC_FBIO_SPARE */
uint32_t EmcFbioSpare;
/* Specifies the value for EMC_CFG_RSV */
uint32_t EmcCfgRsv;
/* MRS command values */
/* Specifies the value for EMC_MRS */
uint32_t EmcMrs;
/* Specifies the MP0 command to initialize mode registers */
uint32_t EmcEmrs;
/* Specifies the MP2 command to initialize mode registers */
uint32_t EmcEmrs2;
/* Specifies the MP3 command to initialize mode registers */
uint32_t EmcEmrs3;
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
uint32_t EmcMrw1;
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
uint32_t EmcMrw2;
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
uint32_t EmcMrw3;
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
uint32_t EmcMrw4;
/* Specifies the programming to LPDDR2 Mode Register 3? at cold boot */
uint32_t EmcMrw6;
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
uint32_t EmcMrw8;
/* Specifies the programming to LPDDR2 Mode Register 11? at cold boot */
uint32_t EmcMrw9;
/* Specifies the programming to LPDDR2 Mode Register 12 at cold boot */
uint32_t EmcMrw10;
/* Specifies the programming to LPDDR2 Mode Register 14 at cold boot */
uint32_t EmcMrw12;
/* Specifies the programming to LPDDR2 Mode Register 14? at cold boot */
uint32_t EmcMrw13;
/* Specifies the programming to LPDDR2 Mode Register 22 at cold boot */
uint32_t EmcMrw14;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at cold boot
*/
uint32_t EmcMrwExtra;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at warm boot
*/
uint32_t EmcWarmBootMrwExtra;
/*
* Specify the enable of extra Mode Register programming at
* warm boot
*/
uint32_t EmcWarmBootExtraModeRegWriteEnable;
/*
* Specify the enable of extra Mode Register programming at
* cold boot
*/
uint32_t EmcExtraModeRegWriteEnable;
/* Specifies the EMC_MRW reset command value */
uint32_t EmcMrwResetCommand;
/* Specifies the EMC Reset wait time (in microseconds) */
uint32_t EmcMrwResetNInitWait;
/* Specifies the value for EMC_MRS_WAIT_CNT */
uint32_t EmcMrsWaitCnt;
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
uint32_t EmcMrsWaitCnt2;
/* EMC miscellaneous configurations */
/* Specifies the value for EMC_CFG */
uint32_t EmcCfg;
/* Specifies the value for EMC_CFG_2 */
uint32_t EmcCfg2;
/* Specifies the pipe bypass controls */
uint32_t EmcCfgPipe;
uint32_t EmcCfgPipeClk;
uint32_t EmcFdpdCtrlCmdNoRamp;
uint32_t EmcCfgUpdate;
/* Specifies the value for EMC_DBG */
uint32_t EmcDbg;
uint32_t EmcDbgWriteMux;
/* Specifies the value for EMC_CMDQ */
uint32_t EmcCmdQ;
/* Specifies the value for EMC_MC2EMCQ */
uint32_t EmcMc2EmcQ;
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
uint32_t EmcDynSelfRefControl;
/* Specifies the value for MEM_INIT_DONE */
uint32_t AhbArbitrationXbarCtrlMemInitDone;
/* Specifies the value for EMC_CFG_DIG_DLL */
uint32_t EmcCfgDigDll;
uint32_t EmcCfgDigDll_1;
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
uint32_t EmcCfgDigDllPeriod;
/* Specifies the value of *DEV_SELECTN of various EMC registers */
uint32_t EmcDevSelect;
/* Specifies the value for EMC_SEL_DPD_CTRL */
uint32_t EmcSelDpdCtrl;
/* Pads trimmer delays */
uint32_t EmcFdpdCtrlDq;
uint32_t EmcFdpdCtrlCmd;
uint32_t EmcPmacroIbVrefDq_0;
uint32_t EmcPmacroIbVrefDq_1;
uint32_t EmcPmacroIbVrefDqs_0;
uint32_t EmcPmacroIbVrefDqs_1;
uint32_t EmcPmacroIbRxrt;
uint32_t EmcCfgPipe1;
uint32_t EmcCfgPipe2;
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
uint32_t EmcPmacroQuseDdllRank0_0;
uint32_t EmcPmacroQuseDdllRank0_1;
uint32_t EmcPmacroQuseDdllRank0_2;
uint32_t EmcPmacroQuseDdllRank0_3;
uint32_t EmcPmacroQuseDdllRank0_4;
uint32_t EmcPmacroQuseDdllRank0_5;
uint32_t EmcPmacroQuseDdllRank1_0;
uint32_t EmcPmacroQuseDdllRank1_1;
uint32_t EmcPmacroQuseDdllRank1_2;
uint32_t EmcPmacroQuseDdllRank1_3;
uint32_t EmcPmacroQuseDdllRank1_4;
uint32_t EmcPmacroQuseDdllRank1_5;
uint32_t EmcPmacroObDdllLongDqRank0_0;
uint32_t EmcPmacroObDdllLongDqRank0_1;
uint32_t EmcPmacroObDdllLongDqRank0_2;
uint32_t EmcPmacroObDdllLongDqRank0_3;
uint32_t EmcPmacroObDdllLongDqRank0_4;
uint32_t EmcPmacroObDdllLongDqRank0_5;
uint32_t EmcPmacroObDdllLongDqRank1_0;
uint32_t EmcPmacroObDdllLongDqRank1_1;
uint32_t EmcPmacroObDdllLongDqRank1_2;
uint32_t EmcPmacroObDdllLongDqRank1_3;
uint32_t EmcPmacroObDdllLongDqRank1_4;
uint32_t EmcPmacroObDdllLongDqRank1_5;
uint32_t EmcPmacroObDdllLongDqsRank0_0;
uint32_t EmcPmacroObDdllLongDqsRank0_1;
uint32_t EmcPmacroObDdllLongDqsRank0_2;
uint32_t EmcPmacroObDdllLongDqsRank0_3;
uint32_t EmcPmacroObDdllLongDqsRank0_4;
uint32_t EmcPmacroObDdllLongDqsRank0_5;
uint32_t EmcPmacroObDdllLongDqsRank1_0;
uint32_t EmcPmacroObDdllLongDqsRank1_1;
uint32_t EmcPmacroObDdllLongDqsRank1_2;
uint32_t EmcPmacroObDdllLongDqsRank1_3;
uint32_t EmcPmacroObDdllLongDqsRank1_4;
uint32_t EmcPmacroObDdllLongDqsRank1_5;
uint32_t EmcPmacroIbDdllLongDqsRank0_0;
uint32_t EmcPmacroIbDdllLongDqsRank0_1;
uint32_t EmcPmacroIbDdllLongDqsRank0_2;
uint32_t EmcPmacroIbDdllLongDqsRank0_3;
uint32_t EmcPmacroIbDdllLongDqsRank1_0;
uint32_t EmcPmacroIbDdllLongDqsRank1_1;
uint32_t EmcPmacroIbDdllLongDqsRank1_2;
uint32_t EmcPmacroIbDdllLongDqsRank1_3;
uint32_t EmcPmacroDdllLongCmd_0;
uint32_t EmcPmacroDdllLongCmd_1;
uint32_t EmcPmacroDdllLongCmd_2;
uint32_t EmcPmacroDdllLongCmd_3;
uint32_t EmcPmacroDdllLongCmd_4;
uint32_t EmcPmacroDdllShortCmd_0;
uint32_t EmcPmacroDdllShortCmd_1;
uint32_t EmcPmacroDdllShortCmd_2;
/*
* Specifies the delay after asserting CKE pin during a WarmBoot0
* sequence (in microseconds)
*/
uint32_t WarmBootWait;
/* Specifies the value for EMC_ODT_WRITE */
uint32_t EmcOdtWrite;
/* Periodic ZQ calibration */
/*
* Specifies the value for EMC_ZCAL_INTERVAL
* Value 0 disables ZQ calibration
*/
uint32_t EmcZcalInterval;
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
uint32_t EmcZcalWaitCnt;
/* Specifies the value for EMC_ZCAL_MRW_CMD */
uint32_t EmcZcalMrwCmd;
/* DRAM initialization sequence flow control */
/* Specifies the MRS command value for resetting DLL */
uint32_t EmcMrsResetDll;
/* Specifies the command for ZQ initialization of device 0 */
uint32_t EmcZcalInitDev0;
/* Specifies the command for ZQ initialization of device 1 */
uint32_t EmcZcalInitDev1;
/*
* Specifies the wait time after programming a ZQ initialization
* command (in microseconds)
*/
uint32_t EmcZcalInitWait;
/*
* Specifies the enable for ZQ calibration at cold boot [bit 0]
* and warm boot [bit 1]
*/
uint32_t EmcZcalWarmColdBootEnables;
/*
* Specifies the MRW command to LPDDR2 for ZQ calibration
* on warmboot
*/
/* Is issued to both devices separately */
uint32_t EmcMrwLpddr2ZcalWarmBoot;
/*
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
* Is issued to both devices separately
*/
uint32_t EmcZqCalDdr3WarmBoot;
uint32_t EmcZqCalLpDdr4WarmBoot;
/*
* Specifies the wait time for ZQ calibration on warmboot
* (in microseconds)
*/
uint32_t EmcZcalWarmBootWait;
/*
* Specifies the enable for DRAM Mode Register programming
* at warm boot
*/
uint32_t EmcMrsWarmBootEnable;
/*
* Specifies the wait time after sending an MRS DLL reset command
* in microseconds)
*/
uint32_t EmcMrsResetDllWait;
/* Specifies the extra MRS command to initialize mode registers */
uint32_t EmcMrsExtra;
/* Specifies the extra MRS command at warm boot */
uint32_t EmcWarmBootMrsExtra;
/* Specifies the EMRS command to enable the DDR2 DLL */
uint32_t EmcEmrsDdr2DllEnable;
/* Specifies the MRS command to reset the DDR2 DLL */
uint32_t EmcMrsDdr2DllReset;
/* Specifies the EMRS command to set OCD calibration */
uint32_t EmcEmrsDdr2OcdCalib;
/*
* Specifies the wait between initializing DDR and setting OCD
* calibration (in microseconds)
*/
uint32_t EmcDdr2Wait;
/* Specifies the value for EMC_CLKEN_OVERRIDE */
uint32_t EmcClkenOverride;
/*
* Specifies LOG2 of the extra refresh numbers after booting
* Program 0 to disable
*/
uint32_t EmcExtraRefreshNum;
/* Specifies the master override for all EMC clocks */
uint32_t EmcClkenOverrideAllWarmBoot;
/* Specifies the master override for all MC clocks */
uint32_t McClkenOverrideAllWarmBoot;
/* Specifies digital dll period, choosing between 4 to 64 ms */
uint32_t EmcCfgDigDllPeriodWarmBoot;
/* Pad controls */
/* Specifies the value for PMC_VDDP_SEL */
uint32_t PmcVddpSel;
/* Specifies the wait time after programming PMC_VDDP_SEL */
uint32_t PmcVddpSelWait;
/* Specifies the value for PMC_DDR_PWR */
uint32_t PmcDdrPwr;
/* Specifies the value for PMC_DDR_CFG */
uint32_t PmcDdrCfg;
/* Specifies the value for PMC_IO_DPD3_REQ */
uint32_t PmcIoDpd3Req;
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
uint32_t PmcIoDpd3ReqWait;
uint32_t PmcIoDpd4ReqWait;
/* Specifies the value for PMC_REG_SHORT */
uint32_t PmcRegShort;
/* Specifies the value for PMC_NO_IOPOWER */
uint32_t PmcNoIoPower;
uint32_t PmcDdrCntrlWait;
uint32_t PmcDdrCntrl;
/* Specifies the value for EMC_ACPD_CONTROL */
uint32_t EmcAcpdControl;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE_CFG */
uint32_t EmcSwizzleRank0ByteCfg;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
uint32_t EmcSwizzleRank0Byte0;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
uint32_t EmcSwizzleRank0Byte1;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
uint32_t EmcSwizzleRank0Byte2;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
uint32_t EmcSwizzleRank0Byte3;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE_CFG */
uint32_t EmcSwizzleRank1ByteCfg;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
uint32_t EmcSwizzleRank1Byte0;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
uint32_t EmcSwizzleRank1Byte1;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
uint32_t EmcSwizzleRank1Byte2;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
uint32_t EmcSwizzleRank1Byte3;
/* Specifies the value for EMC_TXDSRVTTGEN */
uint32_t EmcTxdsrvttgen;
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
uint32_t EmcDataBrlshft0;
uint32_t EmcDataBrlshft1;
uint32_t EmcDqsBrlshft0;
uint32_t EmcDqsBrlshft1;
uint32_t EmcCmdBrlshft0;
uint32_t EmcCmdBrlshft1;
uint32_t EmcCmdBrlshft2;
uint32_t EmcCmdBrlshft3;
uint32_t EmcQuseBrlshft0;
uint32_t EmcQuseBrlshft1;
uint32_t EmcQuseBrlshft2;
uint32_t EmcQuseBrlshft3;
uint32_t EmcDllCfg0;
uint32_t EmcDllCfg1;
uint32_t EmcPmcScratch1;
uint32_t EmcPmcScratch2;
uint32_t EmcPmcScratch3;
uint32_t EmcPmacroPadCfgCtrl;
uint32_t EmcPmacroVttgenCtrl0;
uint32_t EmcPmacroVttgenCtrl1;
uint32_t EmcPmacroVttgenCtrl2;
uint32_t EmcPmacroBrickCtrlRfu1;
uint32_t EmcPmacroCmdBrickCtrlFdpd;
uint32_t EmcPmacroBrickCtrlRfu2;
uint32_t EmcPmacroDataBrickCtrlFdpd;
uint32_t EmcPmacroBgBiasCtrl0;
uint32_t EmcPmacroDataPadRxCtrl;
uint32_t EmcPmacroCmdPadRxCtrl;
uint32_t EmcPmacroDataRxTermMode;
uint32_t EmcPmacroCmdRxTermMode;
uint32_t EmcPmacroDataPadTxCtrl;
uint32_t EmcPmacroCommonPadTxCtrl;
uint32_t EmcPmacroCmdPadTxCtrl;
uint32_t EmcCfg3;
uint32_t EmcPmacroTxPwrd0;
uint32_t EmcPmacroTxPwrd1;
uint32_t EmcPmacroTxPwrd2;
uint32_t EmcPmacroTxPwrd3;
uint32_t EmcPmacroTxPwrd4;
uint32_t EmcPmacroTxPwrd5;
uint32_t EmcConfigSampleDelay;
uint32_t EmcPmacroBrickMapping0;
uint32_t EmcPmacroBrickMapping1;
uint32_t EmcPmacroBrickMapping2;
uint32_t EmcPmacroTxSelClkSrc0;
uint32_t EmcPmacroTxSelClkSrc1;
uint32_t EmcPmacroTxSelClkSrc2;
uint32_t EmcPmacroTxSelClkSrc3;
uint32_t EmcPmacroTxSelClkSrc4;
uint32_t EmcPmacroTxSelClkSrc5;
uint32_t EmcPmacroDdllBypass;
uint32_t EmcPmacroDdllPwrd0;
uint32_t EmcPmacroDdllPwrd1;
uint32_t EmcPmacroDdllPwrd2;
uint32_t EmcPmacroCmdCtrl0;
uint32_t EmcPmacroCmdCtrl1;
uint32_t EmcPmacroCmdCtrl2;
/* DRAM size information */
/* Specifies the value for MC_EMEM_ADR_CFG */
uint32_t McEmemAdrCfg;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
uint32_t McEmemAdrCfgDev0;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
uint32_t McEmemAdrCfgDev1;
uint32_t McEmemAdrCfgChannelMask;
/* Specifies the value for MC_EMEM_BANK_SWIZZLECfg0 */
uint32_t McEmemAdrCfgBankMask0;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
uint32_t McEmemAdrCfgBankMask1;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
uint32_t McEmemAdrCfgBankMask2;
/*
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
uint32_t McEmemCfg;
/* MC arbitration configuration */
/* Specifies the value for MC_EMEM_ARB_CFG */
uint32_t McEmemArbCfg;
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
uint32_t McEmemArbOutstandingReq;
uint32_t McEmemArbRefpbHpCtrl;
uint32_t McEmemArbRefpbBankCtrl;
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
uint32_t McEmemArbTimingRcd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
uint32_t McEmemArbTimingRp;
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
uint32_t McEmemArbTimingRc;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
uint32_t McEmemArbTimingRas;
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
uint32_t McEmemArbTimingFaw;
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
uint32_t McEmemArbTimingRrd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
uint32_t McEmemArbTimingRap2Pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
uint32_t McEmemArbTimingWap2Pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
uint32_t McEmemArbTimingR2R;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
uint32_t McEmemArbTimingW2W;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
uint32_t McEmemArbTimingR2W;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
uint32_t McEmemArbTimingW2R;
uint32_t McEmemArbTimingRFCPB;
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
uint32_t McEmemArbDaTurns;
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
uint32_t McEmemArbDaCovers;
/* Specifies the value for MC_EMEM_ARB_MISC0 */
uint32_t McEmemArbMisc0;
/* Specifies the value for MC_EMEM_ARB_MISC1 */
uint32_t McEmemArbMisc1;
uint32_t McEmemArbMisc2;
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
uint32_t McEmemArbRing1Throttle;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
uint32_t McEmemArbOverride;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
uint32_t McEmemArbOverride1;
/* Specifies the value for MC_EMEM_ARB_RSV */
uint32_t McEmemArbRsv;
uint32_t McDaCfg0;
uint32_t McEmemArbTimingCcdmw;
/* Specifies the value for MC_CLKEN_OVERRIDE */
uint32_t McClkenOverride;
/* Specifies the value for MC_STAT_CONTROL */
uint32_t McStatControl;
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
uint32_t McVideoProtectBom;
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
uint32_t McVideoProtectBomAdrHi;
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
uint32_t McVideoProtectSizeMb;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
uint32_t McVideoProtectVprOverride;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
uint32_t McVideoProtectVprOverride1;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
uint32_t McVideoProtectGpuOverride0;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
uint32_t McVideoProtectGpuOverride1;
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
uint32_t McSecCarveoutBom;
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
uint32_t McSecCarveoutAdrHi;
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
uint32_t McSecCarveoutSizeMb;
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.
VIDEO_PROTECT_WRITEAccess */
uint32_t McVideoProtectWriteAccess;
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.
SEC_CARVEOUT_WRITEAccess */
uint32_t McSecCarveoutProtectWriteAccess;
/* Write-Protect Regions (WPR) */
uint32_t McGeneralizedCarveout1Bom;
uint32_t McGeneralizedCarveout1BomHi;
uint32_t McGeneralizedCarveout1Size128kb;
uint32_t McGeneralizedCarveout1Access0;
uint32_t McGeneralizedCarveout1Access1;
uint32_t McGeneralizedCarveout1Access2;
uint32_t McGeneralizedCarveout1Access3;
uint32_t McGeneralizedCarveout1Access4;
uint32_t McGeneralizedCarveout1ForceInternalAccess0;
uint32_t McGeneralizedCarveout1ForceInternalAccess1;
uint32_t McGeneralizedCarveout1ForceInternalAccess2;
uint32_t McGeneralizedCarveout1ForceInternalAccess3;
uint32_t McGeneralizedCarveout1ForceInternalAccess4;
uint32_t McGeneralizedCarveout1Cfg0;
uint32_t McGeneralizedCarveout2Bom;
uint32_t McGeneralizedCarveout2BomHi;
uint32_t McGeneralizedCarveout2Size128kb;
uint32_t McGeneralizedCarveout2Access0;
uint32_t McGeneralizedCarveout2Access1;
uint32_t McGeneralizedCarveout2Access2;
uint32_t McGeneralizedCarveout2Access3;
uint32_t McGeneralizedCarveout2Access4;
uint32_t McGeneralizedCarveout2ForceInternalAccess0;
uint32_t McGeneralizedCarveout2ForceInternalAccess1;
uint32_t McGeneralizedCarveout2ForceInternalAccess2;
uint32_t McGeneralizedCarveout2ForceInternalAccess3;
uint32_t McGeneralizedCarveout2ForceInternalAccess4;
uint32_t McGeneralizedCarveout2Cfg0;
uint32_t McGeneralizedCarveout3Bom;
uint32_t McGeneralizedCarveout3BomHi;
uint32_t McGeneralizedCarveout3Size128kb;
uint32_t McGeneralizedCarveout3Access0;
uint32_t McGeneralizedCarveout3Access1;
uint32_t McGeneralizedCarveout3Access2;
uint32_t McGeneralizedCarveout3Access3;
uint32_t McGeneralizedCarveout3Access4;
uint32_t McGeneralizedCarveout3ForceInternalAccess0;
uint32_t McGeneralizedCarveout3ForceInternalAccess1;
uint32_t McGeneralizedCarveout3ForceInternalAccess2;
uint32_t McGeneralizedCarveout3ForceInternalAccess3;
uint32_t McGeneralizedCarveout3ForceInternalAccess4;
uint32_t McGeneralizedCarveout3Cfg0;
uint32_t McGeneralizedCarveout4Bom;
uint32_t McGeneralizedCarveout4BomHi;
uint32_t McGeneralizedCarveout4Size128kb;
uint32_t McGeneralizedCarveout4Access0;
uint32_t McGeneralizedCarveout4Access1;
uint32_t McGeneralizedCarveout4Access2;
uint32_t McGeneralizedCarveout4Access3;
uint32_t McGeneralizedCarveout4Access4;
uint32_t McGeneralizedCarveout4ForceInternalAccess0;
uint32_t McGeneralizedCarveout4ForceInternalAccess1;
uint32_t McGeneralizedCarveout4ForceInternalAccess2;
uint32_t McGeneralizedCarveout4ForceInternalAccess3;
uint32_t McGeneralizedCarveout4ForceInternalAccess4;
uint32_t McGeneralizedCarveout4Cfg0;
uint32_t McGeneralizedCarveout5Bom;
uint32_t McGeneralizedCarveout5BomHi;
uint32_t McGeneralizedCarveout5Size128kb;
uint32_t McGeneralizedCarveout5Access0;
uint32_t McGeneralizedCarveout5Access1;
uint32_t McGeneralizedCarveout5Access2;
uint32_t McGeneralizedCarveout5Access3;
uint32_t McGeneralizedCarveout5Access4;
uint32_t McGeneralizedCarveout5ForceInternalAccess0;
uint32_t McGeneralizedCarveout5ForceInternalAccess1;
uint32_t McGeneralizedCarveout5ForceInternalAccess2;
uint32_t McGeneralizedCarveout5ForceInternalAccess3;
uint32_t McGeneralizedCarveout5ForceInternalAccess4;
uint32_t McGeneralizedCarveout5Cfg0;
/* Specifies enable for CA training */
uint32_t EmcCaTrainingEnable;
/* Set if bit 6 select is greater than bit 7 select; uses aremc.
spec packet SWIZZLE_BIT6_GT_BIT7 */
uint32_t SwizzleRankByteEncode;
/* Specifies enable and offset for patched boot ROM write */
uint32_t BootRomPatchControl;
/* Specifies data for patched boot ROM write */
uint32_t BootRomPatchData;
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
uint32_t McMtsCarveoutBom;
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
uint32_t McMtsCarveoutAdrHi;
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
uint32_t McMtsCarveoutSizeMb;
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
uint32_t McMtsCarveoutRegCtrl;
/* End */
} sdram_params_t;
#endif

118
ariane/src/hwinit/t210.h Normal file
View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _T210_H_
#define _T210_H_
#include "types.h"
#define HOST1X_BASE 0x50000000
#define DISPLAY_A_BASE 0x54200000
#define DSI_BASE 0x54300000
#define VIC_BASE 0x54340000
#define TSEC_BASE 0x54500000
#define SOR1_BASE 0x54580000
#define PG_UP_BASE 0x60000000
#define TMR_BASE 0x60005000
#define CLOCK_BASE 0x60006000
#define FLOW_CTLR_BASE 0x60007000
#define SYSREG_BASE 0x6000C000
#define SB_BASE (SYSREG_BASE + 0x200)
#define GPIO_BASE 0x6000D000
#define GPIO_1_BASE (GPIO_BASE)
#define GPIO_2_BASE (GPIO_BASE + 0x100)
#define GPIO_3_BASE (GPIO_BASE + 0x200)
#define GPIO_4_BASE (GPIO_BASE + 0x300)
#define GPIO_5_BASE (GPIO_BASE + 0x400)
#define GPIO_6_BASE (GPIO_BASE + 0x500)
#define GPIO_7_BASE (GPIO_BASE + 0x600)
#define GPIO_8_BASE (GPIO_BASE + 0x700)
#define EXCP_VEC_BASE 0x6000F000
#define APB_MISC_BASE 0x70000000
#define PINMUX_AUX_BASE 0x70003000
#define UART_BASE 0x70006000
#define RTC_BASE 0x7000E000
#define PMC_BASE 0x7000E400
#define SYSCTR0_BASE 0x7000F000
#define FUSE_BASE 0x7000F800
#define KFUSE_BASE 0x7000FC00
#define SE_BASE 0x70012000
#define MC_BASE 0x70019000
#define EMC_BASE 0x7001B000
#define MIPI_CAL_BASE 0x700E3000
#define I2S_BASE 0x702D1000
#define TZRAM_BASE 0x7C010000
#define _REG(base, off) *(vu32 *)((base) + (off))
#define HOST1X(off) _REG(HOST1X_BASE, off)
#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)
#define DSI(off) _REG(DSI_BASE, off)
#define VIC(off) _REG(VIC_BASE, off)
#define TSEC(off) _REG(TSEC_BASE, off)
#define SOR1(off) _REG(SOR1_BASE, off)
#define TMR(off) _REG(TMR_BASE, off)
#define CLOCK(off) _REG(CLOCK_BASE, off)
#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)
#define SYSREG(off) _REG(SYSREG_BASE, off)
#define SB(off) _REG(SB_BASE, off)
#define GPIO(off) _REG(GPIO_BASE, off)
#define GPIO_1(off) _REG(GPIO_1_BASE, off)
#define GPIO_2(off) _REG(GPIO_2_BASE, off)
#define GPIO_3(off) _REG(GPIO_3_BASE, off)
#define GPIO_4(off) _REG(GPIO_4_BASE, off)
#define GPIO_5(off) _REG(GPIO_5_BASE, off)
#define GPIO_6(off) _REG(GPIO_6_BASE, off)
#define GPIO_7(off) _REG(GPIO_7_BASE, off)
#define GPIO_8(off) _REG(GPIO_8_BASE, off)
#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)
#define APB_MISC(off) _REG(APB_MISC_BASE, off)
#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off)
#define RTC(off) _REG(RTC_BASE, off)
#define PMC(off) _REG(PMC_BASE, off)
#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)
#define FUSE(off) _REG(FUSE_BASE, off)
#define KFUSE(off) _REG(KFUSE_BASE, off)
#define SE(off) _REG(SE_BASE, off)
#define MC(off) _REG(MC_BASE, off)
#define EMC(off) _REG(EMC_BASE, off)
#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)
#define I2S(off) _REG(I2S_BASE, off)
/*! Misc registers. */
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
/*! System registers. */
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
#define AHB_AHB_SPARE_REG 0x110
/*! APB MISC registers. */
#define APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL 0x8D4
#define APB_MISC_GP_SDMMC3_CLK_LPBK_CONTROL 0x8D8
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
#define APB_MISC_GP_VGPIO_GPIO_MUX_SEL 0xB74
/*! Secure boot registers. */
#define SB_CSR 0x0
#define SB_PIROM_START 0x4
#define SB_AA64_RESET_LOW 0x30
#define SB_AA64_RESET_HIGH 0x34
/*! SYSCTR0 registers. */
#define SYSCTR0_CNTFID0 0x20
#endif

49
ariane/src/hwinit/timer.c Normal file
View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "timer.h"
#include "t210.h"
u32 get_tmr_s()
{
return RTC(RTC_SECONDS);
}
u32 get_tmr_ms()
{
//reading RTC_MILLI_SECONDS updates RTC_SHADOW_SECONDS value to match
u32 millis = RTC(RTC_MILLI_SECONDS);
u32 seconds = RTC(RTC_SHADOW_SECONDS);
return (millis | (seconds << 10));
}
u32 get_tmr_us()
{
return TMR(TMR_US_OFFS);
}
void msleep(u32 milliseconds)
{
u32 start = RTC(RTC_MILLI_SECONDS) | (RTC(RTC_SHADOW_SECONDS) << 10);
while (((RTC(RTC_MILLI_SECONDS) | (RTC(RTC_SHADOW_SECONDS) << 10)) - start) <= milliseconds) {}
}
void usleep(u32 microseconds)
{
u32 start = TMR(TMR_US_OFFS);
while ((TMR(TMR_US_OFFS) - start) <= microseconds) {}
}

36
ariane/src/hwinit/timer.h Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#include "types.h"
#define TMR_US_OFFS 0x10
#define TMR_US_CFG_OFFS 0x14
#define RTC_SECONDS 0x8
#define RTC_SHADOW_SECONDS 0xC
#define RTC_MILLI_SECONDS 0x10
u32 get_tmr_s();
u32 get_tmr_ms();
u32 get_tmr_us();
void msleep(u32 milliseconds);
void usleep(u32 microseconds);
#endif

165
ariane/src/hwinit/tsec.c Normal file
View file

@ -0,0 +1,165 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "tsec.h"
#include "clock.h"
#include "t210.h"
#include "timer.h"
static int _tsec_dma_wait_idle()
{
u32 timeout = get_tmr_ms() + 10000;
while (!(TSEC(0x1118) & 2))
if (get_tmr_ms() > timeout)
return 0;
return 1;
}
static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offset)
{
u32 cmd;
if (not_imem)
cmd = 0x600; // DMA 0x100 bytes
else
cmd = 0x10; // dma imem
TSEC(0x1114) = i_offset; // tsec_dmatrfmoffs_r
TSEC(0x111C) = pa_offset; // tsec_dmatrffboffs_r
TSEC(0x1118) = cmd; // tsec_dmatrfcmd_r
return _tsec_dma_wait_idle();
}
int tsec_query(u32 carveout, u8 *dst, u32 rev)
{
int res = 0;
//Enable clocks.
clock_enable_host1x();
clock_enable_tsec();
clock_enable_sor_safe();
clock_enable_sor0();
clock_enable_sor1();
clock_enable_kfuse();
//Configure Falcon.
TSEC(0x110C) = 0; // tsec_dmactl_r
TSEC(0x1010) = 0xFFF2; // tsec_irqmset_r
TSEC(0x101C) = 0xFFF0; // tsec_irqdest_r
TSEC(0x1048) = 3; // tsec_itfen_r
if (!_tsec_dma_wait_idle())
{
res = -1;
goto out;
}
//Load firmware.
#ifdef TEST_TSEC_RESET
static const u32 bit5_CPU_STOPPED = 1u << 5;
static const u32 bit4_CPU_HALTED = 1u << 4;
static const u32 bit3_HARD_RESET = 1u << 3;
static const u32 bit2_SOFT_RESET = 1u << 2;
static const u32 bit1_START_CPU = 1u << 1;
static const u32 bit0_IINVAL = 1u << 0;
u32 cpuState = TSEC(0x1100);
printk("TSEC CPU STATE: STOPPED: %02x HALTED: %02x HRESET: %02x SRESET: %02x START: %02x IINVAL: %02x\n",
(cpuState & bit5_CPU_STOPPED) ? 1 : 0,
(cpuState & bit4_CPU_HALTED) ? 1 : 0,
(cpuState & bit3_HARD_RESET) ? 1 : 0,
(cpuState & bit2_SOFT_RESET) ? 1 : 0,
(cpuState & bit1_START_CPU) ? 1 : 0,
(cpuState & bit0_IINVAL) ? 1 : 0);
cpuState |= bit3_HARD_RESET;
TSEC(0x1100) = cpuState;
while (cpuState & bit3_HARD_RESET)
{
cpuState = TSEC(0x1100);
printk("TSEC CPU STATE: STOPPED: %02x HALTED: %02x HRESET: %02x SRESET: %02x START: %02x IINVAL: %02x\n",
(cpuState & bit5_CPU_STOPPED) ? 1 : 0,
(cpuState & bit4_CPU_HALTED) ? 1 : 0,
(cpuState & bit3_HARD_RESET) ? 1 : 0,
(cpuState & bit2_SOFT_RESET) ? 1 : 0,
(cpuState & bit1_START_CPU) ? 1 : 0,
(cpuState & bit0_IINVAL) ? 1 : 0);
}
#endif
TSEC(0x1110) = carveout >> 8;// tsec_dmatrfbase_r
for (u32 addr = 0; addr < 0xF00; addr += 0x100)
{
if (!_tsec_dma_pa_to_internal_100(0, addr, addr))
{
res = -2;
goto out;
}
}
//Execute firmware.
HOST1X(0x3300) = 0x34C2E1DA;
TSEC(0x1044) = 0;
TSEC(0x1040) = rev;
TSEC(0x1104) = 0; // tsec_bootvec_r
TSEC(0x1100) = 2; // tsec_cpuctl_r
if (!_tsec_dma_wait_idle())
{
res = -3;
goto out;
}
u32 timeout = get_tmr_ms() + 2000;
while (!TSEC(0x1044))
{
if (get_tmr_ms() > timeout)
{
res = -4;
goto out;
}
}
if (TSEC(0x1044) != 0xB0B0B0B0)
{
res = -5;
goto out;
}
//Fetch result.
HOST1X(0x3300) = 0;
u32 buf[4];
buf[0] = SOR1(0x1E8);
buf[1] = SOR1(0x21C);
buf[2] = SOR1(0x208);
buf[3] = SOR1(0x20C);
SOR1(0x1E8) = 0;
SOR1(0x21C) = 0;
SOR1(0x208) = 0;
SOR1(0x20C) = 0;
memcpy(dst, &buf, 0x10);
out:;
//Disable clocks.
clock_disable_kfuse();
clock_disable_sor1();
clock_disable_sor0();
clock_disable_sor_safe();
clock_disable_tsec();
clock_disable_host1x();
return res;
}

24
ariane/src/hwinit/tsec.h Normal file
View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TSEC_H_
#define _TSEC_H_
#include "types.h"
int tsec_query(u32 carveout, u8 *dst, u32 rev);
#endif

54
ariane/src/hwinit/types.h Normal file
View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TYPES_H_
#define _TYPES_H_
#define NULL ((void *)0)
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define ALIGN_UP(x,a) ALIGN((x),(a))
#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL))
#define IS_ALIGNED(x,a) (((x) & ((typeof(x))(a)-1UL)) == 0)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ABS(a) (((a) < 0) ? (-(a)) : (a))
#define CEIL_DIV(a, b) (((a) + (b) - 1) / (b))
#define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)
#define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y))
#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m)
#define CONTAINER_OF(mp, t, mn) ((t *)((u32)mp - OFFSET_OF(t, mn)))
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
typedef char s8;
typedef short s16;
typedef int s32;
typedef long long int s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long int u64;
typedef volatile unsigned char vu8;
typedef volatile unsigned short vu16;
typedef volatile unsigned int vu32;
#endif

94
ariane/src/hwinit/uart.c Normal file
View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "uart.h"
#include "t210.h"
#include "timer.h"
/* UART A, B, C, D and E. */
static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
void uart_init(u32 idx, u32 baud)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
//Set baud rate.
u32 rate = (8 * baud + 408000000) / (16 * baud);
uart->UART_LCR = 0x80; //Enable DLAB.
uart->UART_THR_DLAB = (u8)rate; //Divisor latch LSB.
uart->UART_IER_DLAB = (u8)(rate >> 8); //Divisor latch MSB.
uart->UART_LCR = 0; //Diable DLAB.
//Setup UART in fifo mode.
uart->UART_IER_DLAB = 0;
uart->UART_IIR_FCR = 7; //Enable and clear TX and RX FIFOs.
(void)uart->UART_LSR;
usleep(3 * ((baud + 999999) / baud));
uart->UART_LCR = 3; //Set word length 8.
uart->UART_MCR = 0;
uart->UART_MSR = 0;
uart->UART_IRDA_CSR = 0;
uart->UART_RX_FIFO_CFG = 1;
uart->UART_MIE = 0;
uart->UART_ASR = 0;
}
void uart_wait_idle(u32 idx, u32 which)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
while (!(uart->UART_VENDOR_STATUS & which)) {}
}
void uart_send(u32 idx, u8 *buf, u32 len)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
for (u32 i = 0; i != len; i++)
{
while (uart->UART_LSR & UART_TX_FIFO_FULL) {}
uart->UART_THR_DLAB = buf[i];
};
}
void uart_print(u32 idx, const char* buf, u32 len)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
for (u32 i = 0; i != len; i++)
{
while (uart->UART_LSR & UART_TX_FIFO_FULL) {}
if (buf[i] == '\n')
{
uart->UART_THR_DLAB = '\r';
while (uart->UART_LSR & UART_TX_FIFO_FULL) {}
}
uart->UART_THR_DLAB = buf[i];
};
}
u32 uart_has_bytes(u32 idx)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
return (uart->UART_LSR & UART_RX_FIFO_EMPTY) == 0;
}
u8 uart_recv(u32 idx)
{
uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
while (uart->UART_LSR & UART_RX_FIFO_EMPTY) {}
return uart->UART_THR_DLAB;
}

59
ariane/src/hwinit/uart.h Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _UART_H_
#define _UART_H_
#include "types.h"
#define UART_A 0
#define UART_B 1
#define UART_C 2
#define UART_D 3
#define BAUD_115200 115200
#define UART_TX_IDLE 0x00000001
#define UART_RX_IDLE 0x00000002
#define UART_TX_FIFO_FULL 0x100
#define UART_RX_FIFO_EMPTY 0x200
typedef struct _uart_t
{
/* 0x00 */ vu32 UART_THR_DLAB;
/* 0x04 */ vu32 UART_IER_DLAB;
/* 0x08 */ vu32 UART_IIR_FCR;
/* 0x0C */ vu32 UART_LCR;
/* 0x10 */ vu32 UART_MCR;
/* 0x14 */ vu32 UART_LSR;
/* 0x18 */ vu32 UART_MSR;
/* 0x1C */ vu32 UART_SPR;
/* 0x20 */ vu32 UART_IRDA_CSR;
/* 0x24 */ vu32 UART_RX_FIFO_CFG;
/* 0x28 */ vu32 UART_MIE;
/* 0x2C */ vu32 UART_VENDOR_STATUS;
/* 0x30 */ u8 _pad_30[0xC];
/* 0x3C */ vu32 UART_ASR;
} uart_t;
void uart_init(u32 idx, u32 baud);
void uart_wait_idle(u32 idx, u32 which);
void uart_send(u32 idx, u8 *buf, u32 len);
void uart_print(u32 idx, const char* buf, u32 len);
u32 uart_has_bytes(u32 idx);
u8 uart_recv(u32 idx);
#endif

41
ariane/src/hwinit/util.c Normal file
View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "util.h"
#include "t210.h"
#include "max7762x.h"
#include "max77620.h"
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
{
for(u32 i = 0; i < num_ops; i++)
base[ops[i].off] = ops[i].val;
}
int running_on_bpmp(void)
{
static const u32 avp_id = 0xaaaaaaaa;
static volatile u32* uptag_ptr = (void *)PG_UP_BASE;
return (*uptag_ptr) == avp_id;
}
void shutdown_using_pmic()
{
u8 regVal = max77620_recv_byte(MAX77620_REG_ONOFFCNFG1);
regVal |= MAX77620_ONOFFCNFG1_PWR_OFF;
max77620_send_byte(MAX77620_REG_ONOFFCNFG1, regVal);
}

32
ariane/src/hwinit/util.h Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _UTIL_H_
#define _UTIL_H_
#include "types.h"
typedef struct _cfg_op_t
{
u32 off;
u32 val;
} cfg_op_t;
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
int running_on_bpmp(void);
void shutdown_using_pmic(void);
#endif

28
ariane/src/lib/crc32.c Normal file
View file

@ -0,0 +1,28 @@
#include "crc32.h"
/* This is the basic CRC-32 calculation with some optimization but no
table lookup. The the byte reversal is avoided by shifting the crc reg
right instead of left and by using a reversed 32-bit word to represent
the polynomial.
When compiled to Cyclops with GCC, this function executes in 8 + 72n
instructions, where n is the number of bytes in the input message. It
should be doable in 4 + 61n instructions.
If the inner loop is strung out (approx. 5*8 = 40 instructions),
it would take about 6 + 46n instructions. */
unsigned int crc32b(unsigned char* message, unsigned int msgLen)
{
unsigned int byte, crc, mask;
crc = 0xFFFFFFFF;
for (unsigned int i=0; i<msgLen; i++)
{
byte = message[i]; // Get next byte.
crc = crc ^ byte;
for (int j = 7; j >= 0; j--) // Do eight times.
{
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}

6
ariane/src/lib/crc32.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef _CRC32_H_
#define _CRC32_H_
unsigned int crc32b(unsigned char* message, unsigned int msgLen);
#endif

35
ariane/src/lib/decomp.h Normal file
View file

@ -0,0 +1,35 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2016 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _DECOMP_H_
#define _DECOMP_H_
#include <stddef.h>
/* Decompresses an LZ4F image (multiple LZ4 blocks with frame header) from src
* to dst, ensuring that it doesn't read more than srcn bytes and doesn't write
* more than dstn. Buffer sizes must stay below 2GB. Can decompress files loaded
* to the end of a buffer in-place, as long as buffer is larger than the final
* output size. (Usually just a few bytes, but may be up to (8 + dstn/255) in
* worst case. Will reliably return an error if buffer was too small.)
* Returns amount of decompressed bytes, or 0 on error.
*/
size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn);
/* Defined in src/lib/lzma.c. Returns decompressed size or 0 on error. */
size_t ulzman(const void *src, size_t srcn, void *dst, size_t dstn);
int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize);
#endif /* _DECOMP_H_ */

55
ariane/src/lib/diskio.c Normal file
View file

@ -0,0 +1,55 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include <string.h>
#include "diskio.h" /* FatFs lower layer API */
#include "storage.h"
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return 0;
}
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return 0;
}
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
return sdmmc_storage_read(get_storage_for_index(pdrv), sector, count, buff) ? RES_OK : RES_ERROR;
}
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
return sdmmc_storage_write(get_storage_for_index(pdrv), sector, count, (void *)buff) ? RES_OK : RES_ERROR;
}
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
return RES_OK;
}

80
ariane/src/lib/diskio.h Normal file
View file

@ -0,0 +1,80 @@
/*-----------------------------------------------------------------------/
/ Low level disk interface modlue include file (C)ChaN, 2014 /
/-----------------------------------------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#ifdef __cplusplus
}
#endif
#endif

6659
ariane/src/lib/ff.c Normal file

File diff suppressed because it is too large Load diff

376
ariane/src/lib/ff.h Normal file
View file

@ -0,0 +1,376 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.13b /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2018, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/
/----------------------------------------------------------------------------*/
#ifndef FF_DEFINED
#define FF_DEFINED 63463 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if FF_DEFINED != FFCONF_DEF
#error Wrong configuration file (ffconf.h).
#endif
/* Definitions of volume management */
#if FF_MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#endif
#if FF_STR_VOLUME_ID
#ifndef FF_VOLUME_STRS
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
#endif
#endif
/* Type of path name strings on FatFs API */
#ifndef _INC_TCHAR
#define _INC_TCHAR
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
typedef WCHAR TCHAR;
#define _T(x) L ## x
#define _TEXT(x) L ## x
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
typedef char TCHAR;
#define _T(x) u8 ## x
#define _TEXT(x) u8 ## x
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
typedef DWORD TCHAR;
#define _T(x) U ## x
#define _TEXT(x) U ## x
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
#error Wrong FF_LFN_UNICODE setting
#else /* ANSI/OEM code in SBCS/DBCS */
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
#endif
/* Type of file size variables */
#if FF_FS_EXFAT
typedef QWORD FSIZE_t;
#else
typedef DWORD FSIZE_t;
#endif
/* Filesystem object structure (FATFS) */
typedef struct {
BYTE fs_type; /* Filesystem type (0:N/A) */
BYTE pdrv; /* Physical drive number */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* Volume mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
#if FF_MAX_SS != FF_MIN_SS
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
#endif
#if FF_USE_LFN
WCHAR* lfnbuf; /* LFN working buffer */
#endif
#if FF_FS_EXFAT
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
#endif
#if FF_FS_REENTRANT
FF_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !FF_FS_READONLY
DWORD last_clst; /* Last allocated cluster */
DWORD free_clst; /* Number of free clusters */
#endif
#if FF_FS_RPATH
DWORD cdir; /* Current directory start cluster (0:root) */
#if FF_FS_EXFAT
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
#endif
#endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */
DWORD volbase; /* Volume base sector */
DWORD fatbase; /* FAT base sector */
DWORD dirbase; /* Root directory base sector/cluster */
DWORD database; /* Data base sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;
/* Object ID and allocation information (FFOBJID) */
typedef struct {
FATFS* fs; /* Pointer to the hosting volume of this object */
WORD id; /* Hosting volume mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if FF_FS_EXFAT
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
#endif
#if FF_FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
} FFOBJID;
/* File object structure (FIL) */
typedef struct {
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
#if !FF_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
#endif
#if FF_USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !FF_FS_TINY
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
/* Directory object structure (DIR) */
typedef struct {
FFOBJID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if FF_USE_LFN
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif
#if FF_USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
/* File information structure (FILINFO) */
typedef struct {
FSIZE_t fsize; /* File size */
WORD fdate; /* Modified date */
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if FF_USE_LFN
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
#else
TCHAR fname[12 + 1]; /* File name */
#endif
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
FRESULT f_setcp (WORD cp); /* Set current code page */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->obj.objsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#define f_rmdir(path) f_unlink(path)
#define f_unmount(path) f_mount(0, path, 0)
#ifndef EOF
#define EOF (-1)
#endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* RTC function */
#if !FF_FS_READONLY && !FF_FS_NORTC
DWORD get_fattime (void);
#endif
/* LFN support functions */
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
#endif
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
/* Sync functions */
#if FF_FS_REENTRANT
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01
#define FA_WRITE 0x02
#define FA_OPEN_EXISTING 0x00
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA_OPEN_APPEND 0x30
/* Fast seek controls (2nd argument of f_lseek) */
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
/* Format options (2nd argument of f_mkfs) */
#define FM_FAT 0x01
#define FM_FAT32 0x02
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
/* Filesystem type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_EXFAT 4
/* File attribute bits for directory entry (FILINFO.fattrib) */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#ifdef __cplusplus
}
#endif
#endif /* FF_DEFINED */

289
ariane/src/lib/ffconf.h Normal file
View file

@ -0,0 +1,289 @@
/*---------------------------------------------------------------------------/
/ FatFs - Configuration file
/---------------------------------------------------------------------------*/
#define FFCONF_DEF 63463 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_READONLY 0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define FF_FS_MINIMIZE 0
/* This option defines minimization level to remove some basic API functions.
/
/ 0: Basic functions are fully enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define FF_USE_STRFUNC 2
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define FF_USE_FIND 0
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define FF_USE_MKFS 0
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define FF_USE_FASTSEEK 0
/* This option switches fast seek function. (0:Disable or 1:Enable) */
#define FF_USE_EXPAND 0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define FF_USE_CHMOD 0
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
#define FF_USE_LABEL 0
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define FF_USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define FF_CODE_PAGE 850
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect code page setting can cause a file open failure.
/
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
/ 0 - Include all code pages above and configured by f_setcp()
*/
#define FF_USE_LFN 2
#define FF_MAX_LFN 255
/* The FF_USE_LFN switches the support for LFN (long file name).
/
/ 0: Disable LFN. FF_MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
/ specification.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree() in ffsystem.c, need to be added to the project. */
#define FF_LFN_UNICODE 0
/* This option switches the character encoding on the API when LFN is enabled.
/
/ 0: ANSI/OEM in current CP (TCHAR = char)
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
/ 2: Unicode in UTF-8 (TCHAR = char)
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
/
/ Also behavior of string I/O functions will be affected by this option.
/ When LFN is not enabled, this option has no effect. */
#define FF_LFN_BUF 255
#define FF_SFN_BUF 12
/* This set of options defines size of file name members in the FILINFO structure
/ which is used to read out directory items. These values should be suffcient for
/ the file names to read. The maximum possible length of the read file name depends
/ on character encoding. When LFN is not enabled, these options have no effect. */
#define FF_STRF_ENCODE 0
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
/ This option selects assumption of character encoding ON THE FILE to be
/ read/written via those functions.
/
/ 0: ANSI/OEM in current CP
/ 1: Unicode in UTF-16LE
/ 2: Unicode in UTF-16BE
/ 3: Unicode in UTF-8
*/
#define FF_FS_RPATH 0
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 2
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "sd"
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
/ not defined, a user defined volume string table needs to be defined as:
/
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
*/
#define FF_MULTI_PARTITION 0
/* This option switches support for multiple volumes on the physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this function is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define FF_MIN_SS 512
#define FF_MAX_SS 512
/* This set of options configures the range of sector size to be supported. (512,
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
/ for variable sector size mode and disk_ioctl() function needs to implement
/ GET_SECTOR_SIZE command. */
#define FF_USE_TRIM 0
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define FF_FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
#define FF_FS_EXFAT 1
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
/ To enable exFAT, also LFN needs to be enabled.
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define FF_FS_NORTC 1
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2018
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
#define FF_FS_LOCK 0
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define FF_FS_REENTRANT 0
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t HANDLE
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/* #include <windows.h> // O/S definitions */
/*--- End of configuration options ---*/

35
ariane/src/lib/ffsystem.c Normal file
View file

@ -0,0 +1,35 @@
/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */
/* (C) ChaN, 2017 */
/*------------------------------------------------------------------------*/
#include "ff.h"
#include "heap.h"
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free (nothing to do for null) */
)
{
free(mblock); /* Free the memory block with POSIX API */
}
#endif

627
ariane/src/lib/ffunicode.c Normal file
View file

@ -0,0 +1,627 @@
/*------------------------------------------------------------------------*/
/* Unicode handling functions for FatFs R0.13a */
/*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .const section when the /
/ FatFs is configured for LFN with DBCS. If the system has any Unicode /
/ utilitiy for the code conversion, this module should be modified to use /
/ that function to avoid silly memory consumption. /
/-------------------------------------------------------------------------*/
/*
/ Copyright (C) 2017, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
*/
#include "ff.h"
#if FF_USE_LFN /* This module is blanked when non-LFN configuration */
#if FF_DEFINED != 63463 /* Revision ID */
#error Wrong include file (ff.h).
#endif
#define MERGE2(a, b) a ## b
#define CVTBL(tbl, cp) MERGE2(tbl, cp)
/*------------------------------------------------------------------------*/
/* Code Conversion Tables */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0
static const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0
static const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0
static const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0
static const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0
static const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0
static const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0
static const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0
static const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0
static const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0
static const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0
static const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0
static const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0
static const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0
static const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
};
#endif
#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0
static const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0
static const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
};
#endif
#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0
static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
};
#endif
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for static code page configuration */
/* SBCS fixed code page */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */
)
{
WCHAR c = 0;
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
if (uni < 0x80) { /* ASCII? */
c = (WCHAR)uni;
} else { /* Non-ASCII */
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
for (c = 0; c < 0x80 && uni != p[c]; c++) ;
c = (c + 0x80) & 0xFF;
}
}
return c;
}
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
WCHAR oem, /* OEM code to be converted */
WORD cp /* Code page for the conversion */
)
{
WCHAR c = 0;
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
if (oem < 0x80) { /* ASCII? */
c = oem;
} else { /* Extended char */
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
if (oem < 0x100) c = p[oem - 0x80];
}
}
return c;
}
#endif
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for static code page configuration */
/* DBCS fixed code page */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE >= 900
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
WCHAR c = 0, uc;
UINT i = 0, n, li, hi;
if (uni < 0x80) { /* ASCII? */
c = (WCHAR)uni;
} else { /* Non-ASCII */
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
uc = (WCHAR)uni;
p = CVTBL(uni2oem, FF_CODE_PAGE);
hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
li = 0;
for (n = 16; n; n--) {
i = li + (hi - li) / 2;
if (uc == p[i * 2]) break;
if (uc > p[i * 2]) {
li = i;
} else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
}
}
return c;
}
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
WCHAR oem, /* OEM code to be converted */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
WCHAR c = 0;
UINT i = 0, n, li, hi;
if (oem < 0x80) { /* ASCII? */
c = oem;
} else { /* Extended char */
if (cp == FF_CODE_PAGE) { /* Is it valid code page? */
p = CVTBL(oem2uni, FF_CODE_PAGE);
hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;
li = 0;
for (n = 16; n; n--) {
i = li + (hi - li) / 2;
if (oem == p[i * 2]) break;
if (oem > p[i * 2]) {
li = i;
} else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
}
}
return c;
}
#endif
/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions for dynamic code page configuration */
/*------------------------------------------------------------------------*/
#if FF_CODE_PAGE == 0
static const WORD cp_code[] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 0};
static const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
DWORD uni, /* UTF-16 encoded character to be converted */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
WCHAR c = 0, uc;
UINT i, n, li, hi;
if (uni < 0x80) { /* ASCII? */
c = (WCHAR)uni;
} else { /* Non-ASCII */
if (uni < 0x10000) { /* Is it in BMP? */
uc = (WCHAR)uni;
p = 0;
if (cp < 900) { /* SBCS */
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get conversion table */
p = cp_table[i];
if (p) { /* Is it valid code page ? */
for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */
c = (c + 0x80) & 0xFF;
}
} else { /* DBCS */
switch (cp) { /* Get conversion table */
case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;
case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;
case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;
case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;
}
if (p) { /* Is it valid code page? */
li = 0;
for (n = 16; n; n--) { /* Find OEM code */
i = li + (hi - li) / 2;
if (uc == p[i * 2]) break;
if (uc > p[i * 2]) {
li = i;
} else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
}
}
}
}
return c;
}
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */
WORD cp /* Code page for the conversion */
)
{
const WCHAR *p;
WCHAR c = 0;
UINT i, n, li, hi;
if (oem < 0x80) { /* ASCII? */
c = oem;
} else { /* Extended char */
p = 0;
if (cp < 900) { /* SBCS */
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */
p = cp_table[i];
if (p) { /* Is it a valid CP ? */
if (oem < 0x100) c = p[oem - 0x80];
}
} else { /* DBCS */
switch (cp) {
case 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break;
case 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break;
case 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break;
case 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break;
}
if (p) {
li = 0;
for (n = 16; n; n--) {
i = li + (hi - li) / 2;
if (oem == p[i * 2]) break;
if (oem > p[i * 2]) {
li = i;
} else {
hi = i;
}
}
if (n != 0) c = p[i * 2 + 1];
}
}
}
return c;
}
#endif
/*------------------------------------------------------------------------*/
/* Unicode up-case conversion */
/*------------------------------------------------------------------------*/
DWORD ff_wtoupper ( /* Returns up-converted code point */
DWORD uni /* Unicode code point to be up-converted */
)
{
const WORD *p;
WORD uc, bc, nc, cmd;
static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */
/* Basic Latin */
0x0061,0x031A,
/* Latin-1 Supplement */
0x00E0,0x0317,
0x00F8,0x0307,
0x00FF,0x0001,0x0178,
/* Latin Extended-A */
0x0100,0x0130,
0x0132,0x0106,
0x0139,0x0110,
0x014A,0x012E,
0x0179,0x0106,
/* Latin Extended-B */
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
0x01CD,0x0110,
0x01DD,0x0001,0x018E,
0x01DE,0x0112,
0x01F3,0x0003,0x01F1,0x01F4,0x01F4,
0x01F8,0x0128,
0x0222,0x0112,
0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241,
0x0246,0x010A,
/* IPA Extensions */
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
/* Greek, Coptic */
0x037B,0x0003,0x03FD,0x03FE,0x03FF,
0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A,
0x03B1,0x0311,
0x03C2,0x0002,0x03A3,0x03A3,
0x03C4,0x0308,
0x03CC,0x0003,0x038C,0x038E,0x038F,
0x03D8,0x0118,
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
/* Cyrillic */
0x0430,0x0320,
0x0450,0x0710,
0x0460,0x0122,
0x048A,0x0136,
0x04C1,0x010E,
0x04CF,0x0001,0x04C0,
0x04D0,0x0144,
/* Armenian */
0x0561,0x0426,
0x0000 /* EOT */
};
static const WORD cvt2[] = { /* Compressed up conversion table for U+1000 - U+FFFF */
/* Phonetic Extensions */
0x1D7D,0x0001,0x2C63,
/* Latin Extended Additional */
0x1E00,0x0196,
0x1EA0,0x015A,
/* Greek Extended */
0x1F00,0x0608,
0x1F10,0x0606,
0x1F20,0x0608,
0x1F30,0x0608,
0x1F40,0x0606,
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F,
0x1F60,0x0608,
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
0x1F80,0x0608,
0x1F90,0x0608,
0x1FA0,0x0608,
0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
0x1FCC,0x0001,0x1FC3,
0x1FD0,0x0602,
0x1FE0,0x0602,
0x1FE5,0x0001,0x1FEC,
0x1FF3,0x0001,0x1FFC,
/* Letterlike Symbols */
0x214E,0x0001,0x2132,
/* Number forms */
0x2170,0x0210,
0x2184,0x0001,0x2183,
/* Enclosed Alphanumerics */
0x24D0,0x051A,
0x2C30,0x042F,
/* Latin Extended-C */
0x2C60,0x0102,
0x2C67,0x0106, 0x2C75,0x0102,
/* Coptic */
0x2C80,0x0164,
/* Georgian Supplement */
0x2D00,0x0826,
/* Full-width */
0xFF41,0x031A,
0x0000 /* EOT */
};
if (uni < 0x10000) { /* Is it in BMP? */
uc = (WORD)uni;
p = uc < 0x1000 ? cvt1 : cvt2;
for (;;) {
bc = *p++; /* Get the block base */
if (bc == 0 || uc < bc) break; /* Not matched? */
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
if (uc < bc + nc) { /* In the block? */
switch (cmd) {
case 0: uc = p[uc - bc]; break; /* Table conversion */
case 1: uc -= (uc - bc) & 1; break; /* Case pairs */
case 2: uc -= 16; break; /* Shift -16 */
case 3: uc -= 32; break; /* Shift -32 */
case 4: uc -= 48; break; /* Shift -48 */
case 5: uc -= 26; break; /* Shift -26 */
case 6: uc += 8; break; /* Shift +8 */
case 7: uc -= 80; break; /* Shift -80 */
case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */
}
break;
}
if (cmd == 0) p += nc; /* Skip table if needed */
}
uni = uc;
}
return uni;
}
#endif /* #if FF_USE_LFN */

136
ariane/src/lib/heap.c Normal file
View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "heap.h"
typedef struct _hnode
{
int used;
u32 size;
struct _hnode *prev;
struct _hnode *next;
} hnode_t;
typedef struct _heap
{
u32 start;
hnode_t *first;
} heap_t;
static void _heap_create(heap_t *heap, u32 start)
{
heap->start = start;
heap->first = NULL;
}
static u32 _heap_alloc(heap_t *heap, u32 size)
{
hnode_t *node, *new;
int search = 1;
size = ALIGN(size, 0x10);
if (!heap->first)
{
node = (hnode_t *)heap->start;
node->used = 1;
node->size = size;
node->prev = NULL;
node->next = NULL;
heap->first = node;
return (u32)node + sizeof(hnode_t);
}
node = heap->first;
while (search)
{
if (!node->used && size + sizeof(hnode_t) < node->size)
{
new = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
new->size = node->size - sizeof(hnode_t) - size;
node->size = size;
node->used = 1;
new->used = 0;
new->next = node->next;
new->prev = node;
node->next = new;
return (u32)node + sizeof(hnode_t);
}
if (node->next)
node = node->next;
else
search = 0;
}
new = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
new->used = 1;
new->size = size;
new->prev = node;
new->next = NULL;
node->next = new;
return (u32)new + sizeof(hnode_t);
}
static void _heap_free(heap_t *heap, u32 addr)
{
hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t));
node->used = 0;
node = heap->first;
while (node)
{
if (!node->used)
{
if (node->prev && !node->prev->used)
{
node->prev->size += node->size + sizeof(hnode_t);
node->prev->next = node->next;
if (node->next)
node->next->prev = node->prev;
}
}
node = node->next;
}
}
static heap_t _heap;
void heap_init(u32 base)
{
_heap_create(&_heap, base);
}
void *malloc(u32 size)
{
return (void *)_heap_alloc(&_heap, size);
}
void *calloc(u32 num, u32 size)
{
void *res = (void *)_heap_alloc(&_heap, num * size);
memset(res, 0, num * size);
return res;
}
void free(void *buf)
{
if (buf != NULL)
_heap_free(&_heap, (u32)buf);
}

27
ariane/src/lib/heap.h Normal file
View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _HEAP_H_
#define _HEAP_H_
#include "hwinit/types.h"
void heap_init(u32 base);
void *malloc(u32 size);
void *calloc(u32 num, u32 size);
void free(void *buf);
#endif

38
ariane/src/lib/integer.h Normal file
View file

@ -0,0 +1,38 @@
/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/
#ifndef FF_INTEGER
#define FF_INTEGER
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>
typedef unsigned __int64 QWORD;
#else /* Embedded platform */
/* These types MUST be 16-bit or 32-bit */
typedef int INT;
typedef unsigned int UINT;
/* This type MUST be 8-bit */
typedef unsigned char BYTE;
/* These types MUST be 16-bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;
#endif
#endif

179
ariane/src/lib/lz.c Normal file
View file

@ -0,0 +1,179 @@
/*************************************************************************
* Name: lz.c
* Author: Marcus Geelnard
* Description: LZ77 coder/decoder implementation.
* Reentrant: Yes
*
* The LZ77 compression scheme is a substitutional compression scheme
* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in
* its design, and uses no fancy bit level compression.
*
* This is my first attempt at an implementation of a LZ77 code/decoder.
*
* The principle of the LZ77 compression algorithm is to store repeated
* occurrences of strings as references to previous occurrences of the same
* string. The point is that the reference consumes less space than the
* string itself, provided that the string is long enough (in this
* implementation, the string has to be at least 4 bytes long, since the
* minimum coded reference is 3 bytes long). Also note that the term
* "string" refers to any kind of byte sequence (it does not have to be
* an ASCII string, for instance).
*
* The coder uses a brute force approach to finding string matches in the
* history buffer (or "sliding window", if you wish), which is very, very
* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),
* depending on the input data.
*
* There is also a faster implementation that uses a large working buffer
* in which a "jump table" is stored, which is used to quickly find
* possible string matches (see the source code for LZ_CompressFast() for
* more information). The faster method is an order of magnitude faster,
* but still quite slow compared to other compression methods.
*
* The upside is that decompression is very fast, and the compression ratio
* is often very good.
*
* The reference to a string is coded as a (length,offset) pair, where the
* length indicates the length of the string, and the offset gives the
* offset from the current data position. To distinguish between string
* references and literal strings (uncompressed bytes), a string reference
* is preceded by a marker byte, which is chosen as the least common byte
* symbol in the input data stream (this marker byte is stored in the
* output stream as the first byte).
*
* Occurrences of the marker byte in the stream are encoded as the marker
* byte followed by a zero byte, which means that occurrences of the marker
* byte have to be coded with two bytes.
*
* The lengths and offsets are coded in a variable length fashion, allowing
* values of any magnitude (up to 4294967295 in this implementation).
*
* With this compression scheme, the worst case compression result is
* (257/256)*insize + 1.
*
*-------------------------------------------------------------------------
* Copyright (c) 2003-2006 Marcus Geelnard
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Marcus Geelnard
* marcus.geelnard at home.se
*************************************************************************/
/*************************************************************************
* INTERNAL FUNCTIONS *
*************************************************************************/
/*************************************************************************
* _LZ_ReadVarSize() - Read unsigned integer with variable number of
* bytes depending on value.
*************************************************************************/
static int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )
{
unsigned int y, b, num_bytes;
/* Read complete value (stop when byte contains zero in 8:th bit) */
y = 0;
num_bytes = 0;
do
{
b = (unsigned int) (*buf ++);
y = (y << 7) | (b & 0x0000007f);
++ num_bytes;
}
while( b & 0x00000080 );
/* Store value in x */
*x = y;
/* Return number of bytes read */
return num_bytes;
}
/*************************************************************************
* PUBLIC FUNCTIONS *
*************************************************************************/
/*************************************************************************
* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.
* in - Input (compressed) buffer.
* out - Output (uncompressed) buffer. This buffer must be large
* enough to hold the uncompressed data.
* insize - Number of input bytes.
*************************************************************************/
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
unsigned int insize )
{
unsigned char marker, symbol;
unsigned int i, inpos, outpos, length, offset;
/* Do we have anything to uncompress? */
if( insize < 1 )
{
return;
}
/* Get marker symbol from input stream */
marker = in[ 0 ];
inpos = 1;
/* Main decompression loop */
outpos = 0;
do
{
symbol = in[ inpos ++ ];
if( symbol == marker )
{
/* We had a marker byte */
if( in[ inpos ] == 0 )
{
/* It was a single occurrence of the marker byte */
out[ outpos ++ ] = marker;
++ inpos;
}
else
{
/* Extract true length and offset */
inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );
inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );
/* Copy corresponding data from history window */
for( i = 0; i < length; ++ i )
{
out[ outpos ] = out[ outpos - offset ];
++ outpos;
}
}
}
else
{
/* No marker, plain copy */
out[ outpos ++ ] = symbol;
}
}
while( inpos < insize );
}

52
ariane/src/lib/lz.h Normal file
View file

@ -0,0 +1,52 @@
/*************************************************************************
* Name: lz.h
* Author: Marcus Geelnard
* Description: LZ77 coder/decoder interface.
* Reentrant: Yes
*-------------------------------------------------------------------------
* Copyright (c) 2003-2006 Marcus Geelnard
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Marcus Geelnard
* marcus.geelnard at home.se
*************************************************************************/
#ifndef _lz_h_
#define _lz_h_
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* Function prototypes
*************************************************************************/
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
unsigned int insize );
#ifdef __cplusplus
}
#endif
#endif /* _lz_h_ */

280
ariane/src/lib/lz4.c.inc Normal file
View file

@ -0,0 +1,280 @@
/*
LZ4 - Fast LZ compression algorithm
Copyright (C) 2011-2015, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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 COPYRIGHT HOLDERS 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 COPYRIGHT
OWNER 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.
You can contact the author at :
- LZ4 source repository : https://github.com/Cyan4973/lz4
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
*/
/**************************************
* Reading and writing into memory
**************************************/
/* customized variant of memcpy, which can overwrite up to 7 bytes beyond dstEnd */
static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
{
BYTE* d = (BYTE*)dstPtr;
const BYTE* s = (const BYTE*)srcPtr;
BYTE* const e = (BYTE*)dstEnd;
#if 0
const size_t l2 = 8 - (((size_t)d) & (sizeof(void*)-1));
LZ4_copy8(d,s); if (d>e-9) return;
d+=l2; s+=l2;
#endif /* join to align */
do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e);
}
/**************************************
* Common Constants
**************************************/
#define MINMATCH 4
#define WILDCOPYLENGTH 8
#define LASTLITERALS 5
#define MFLIMIT (WILDCOPYLENGTH+MINMATCH)
static const int LZ4_minLength = (MFLIMIT+1);
#define KB *(1 <<10)
#define MB *(1 <<20)
#define GB *(1U<<30)
#define MAXD_LOG 16
#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
#define ML_BITS 4
#define ML_MASK ((1U<<ML_BITS)-1)
#define RUN_BITS (8-ML_BITS)
#define RUN_MASK ((1U<<RUN_BITS)-1)
/**************************************
* Local Structures and types
**************************************/
typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
typedef enum { full = 0, partial = 1 } earlyEnd_directive;
/*******************************
* Decompression functions
*******************************/
/*
* This generic decompression function cover all use cases.
* It shall be instantiated several times, using different sets of directives
* Note that it is essential this generic function is really inlined,
* in order to remove useless branches during compilation optimization.
*/
FORCE_INLINE int LZ4_decompress_generic(
const char* const source,
char* const dest,
int inputSize,
int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */
int endOnInput, /* endOnOutputSize, endOnInputSize */
int partialDecoding, /* full, partial */
int targetOutputSize, /* only used if partialDecoding==partial */
int dict, /* noDict, withPrefix64k, usingExtDict */
const BYTE* const lowPrefix, /* == dest if dict == noDict */
const BYTE* const dictStart, /* only if dict==usingExtDict */
const size_t dictSize /* note : = 0 if noDict */
)
{
/* Local Variables */
const BYTE* ip = (const BYTE*) source;
const BYTE* const iend = ip + inputSize;
BYTE* op = (BYTE*) dest;
BYTE* const oend = op + outputSize;
BYTE* cpy;
BYTE* oexit = op + targetOutputSize;
const BYTE* const lowLimit = lowPrefix - dictSize;
const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
const unsigned dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4};
const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
const int safeDecode = (endOnInput==endOnInputSize);
const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
const int inPlaceDecode = ((ip >= op) && (ip < oend));
/* Special cases */
if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */
if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */
if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
/* Main Loop */
while (1)
{
unsigned token;
size_t length;
const BYTE* match;
size_t offset;
if (unlikely((inPlaceDecode) && (op + WILDCOPYLENGTH > ip))) goto _output_error; /* output stream ran over input stream */
/* get literal length */
token = *ip++;
if ((length=(token>>ML_BITS)) == RUN_MASK)
{
unsigned s;
do
{
s = *ip++;
length += s;
}
while ( likely(endOnInput ? ip<iend-RUN_MASK : 1) && (s==255) );
if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error; /* overflow detection */
if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error; /* overflow detection */
}
/* copy literals */
cpy = op+length;
if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
|| ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)))
{
if (partialDecoding)
{
if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */
if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */
}
else
{
if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */
if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */
}
memmove(op, ip, length);
ip += length;
op += length;
break; /* Necessarily EOF, due to parsing restrictions */
}
LZ4_wildCopy(op, ip, cpy);
ip += length; op = cpy;
/* get offset */
offset = LZ4_readLE16(ip); ip+=2;
match = op - offset;
if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside buffers */
/* get matchlength */
length = token & ML_MASK;
if (length == ML_MASK)
{
unsigned s;
do
{
if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error;
s = *ip++;
length += s;
} while (s==255);
if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */
}
length += MINMATCH;
/* check external dictionary */
if ((dict==usingExtDict) && (match < lowPrefix))
{
if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */
if (length <= (size_t)(lowPrefix-match))
{
/* match can be copied as a single segment from external dictionary */
match = dictEnd - (lowPrefix-match);
memmove(op, match, length); op += length;
}
else
{
/* match encompass external dictionary and current block */
size_t copySize = (size_t)(lowPrefix-match);
memcpy(op, dictEnd - copySize, copySize);
op += copySize;
copySize = length - copySize;
if (copySize > (size_t)(op-lowPrefix)) /* overlap copy */
{
BYTE* const endOfMatch = op + copySize;
const BYTE* copyFrom = lowPrefix;
while (op < endOfMatch) *op++ = *copyFrom++;
}
else
{
memcpy(op, lowPrefix, copySize);
op += copySize;
}
}
continue;
}
/* copy match within block */
cpy = op + length;
if (unlikely(offset<8))
{
const int dec64 = dec64table[offset];
op[0] = match[0];
op[1] = match[1];
op[2] = match[2];
op[3] = match[3];
match += dec32table[offset];
memcpy(op+4, match, 4);
match -= dec64;
} else { LZ4_copy8(op, match); match+=8; }
op += 8;
if (unlikely(cpy>oend-12))
{
BYTE* const oCopyLimit = oend-(WILDCOPYLENGTH-1);
if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */
if (op < oCopyLimit)
{
LZ4_wildCopy(op, match, oCopyLimit);
match += oCopyLimit - op;
op = oCopyLimit;
}
while (op<cpy) *op++ = *match++;
}
else
LZ4_wildCopy(op, match, cpy);
op=cpy; /* correction */
}
/* end of decoding */
if (endOnInput)
return (int) (((char*)op)-dest); /* Nb of output bytes decoded */
else
return (int) (((const char*)ip)-source); /* Nb of input bytes read */
/* Overflow error detected */
_output_error:
return (int) (-(((const char*)ip)-source))-1;
}

View file

@ -0,0 +1,208 @@
/*
* Copyright 2015-2016 Google Inc.
*
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* 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 <stdint.h>
#include <string.h>
#include "hwinit/types.h"
static inline uint16_t read_le16(const void *src)
{
const uint8_t *s = src;
return (((uint16_t)s[1]) << 8) | (((uint16_t)s[0]) << 0);
}
static inline uint32_t read_le32(const void *src)
{
const uint8_t *s = src;
return (((uint32_t)s[3]) << 24) | (((uint32_t)s[2]) << 16) |
(((uint32_t)s[1]) << 8) | (((uint32_t)s[0]) << 0);
}
/* LZ4 comes with its own supposedly portable memory access functions, but they
* seem to be very inefficient in practice (at least on ARM64). Since coreboot
* knows about endinaness and allows some basic assumptions (such as unaligned
* access support), we can easily write the ones we need ourselves. */
static uint16_t LZ4_readLE16(const void *src)
{
return read_le16(src);
}
static void LZ4_copy8(void *dst, const void *src)
{
/* ARM32 needs to be a special snowflake to prevent GCC from coalescing the
* access into LDRD/STRD (which don't support unaligned accesses). */
#ifdef __arm__ /* ARMv < 6 doesn't support unaligned accesses at all. */
int i;
for (i = 0; i < 8; i++)
((uint8_t *)dst)[i] = ((uint8_t *)src)[i];
#elif defined(__riscv)
/* RISC-V implementations may trap on any unaligned access. */
int i;
for (i = 0; i < 8; i++)
((uint8_t *)dst)[i] = ((uint8_t *)src)[i];
#else
*(uint64_t *)dst = *(const uint64_t *)src;
#endif
}
typedef uint8_t BYTE;
typedef uint16_t U16;
typedef uint32_t U32;
typedef int32_t S32;
typedef uint64_t U64;
#define FORCE_INLINE static inline __attribute__((always_inline))
#define likely(expr) __builtin_expect((expr) != 0, 1)
#define unlikely(expr) __builtin_expect((expr) != 0, 0)
/* Unaltered (just removed unrelated code) from github.com/Cyan4973/lz4/dev. */
#include "lz4.c.inc" /* #include for inlining, do not link! */
int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize)
{
return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize,
endOnInputSize, 0, 0, noDict,
(BYTE*)dest, NULL, 0);
}
#define LZ4F_MAGICNUMBER 0x184D2204
struct lz4_frame_header {
uint32_t magic;
union {
uint8_t flags;
struct {
uint8_t reserved0 : 2;
uint8_t has_content_checksum : 1;
uint8_t has_content_size : 1;
uint8_t has_block_checksum : 1;
uint8_t independent_blocks : 1;
uint8_t version : 2;
};
};
union {
uint8_t block_descriptor;
struct {
uint8_t reserved1 : 4;
uint8_t max_block_size : 3;
uint8_t reserved2 : 1;
};
};
/* + uint64_t content_size iff has_content_size is set */
/* + uint8_t header_checksum */
} __packed;
struct lz4_block_header {
union {
uint32_t raw;
struct {
uint32_t size : 31;
uint32_t not_compressed : 1;
};
};
/* + size bytes of data */
/* + uint32_t block_checksum iff has_block_checksum is set */
} __packed;
size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn)
{
const void *in = src;
void *out = dst;
size_t out_size = 0;
int has_block_checksum;
{ /* With in-place decompression the header may become invalid later. */
const struct lz4_frame_header *h = in;
if (srcn < sizeof(*h) + sizeof(uint64_t) + sizeof(uint8_t))
return 0; /* input overrun */
/* We assume there's always only a single, standard frame. */
if (read_le32(&h->magic) != LZ4F_MAGICNUMBER || h->version != 1)
return 0; /* unknown format */
if (h->reserved0 || h->reserved1 || h->reserved2)
return 0; /* reserved must be zero */
if (!h->independent_blocks)
return 0; /* we don't support block dependency */
has_block_checksum = h->has_block_checksum;
in += sizeof(*h);
if (h->has_content_size)
{
const size_t content_size = read_le32(in);
if (content_size > dstn)
return content_size;
in += sizeof(uint64_t);
}
in += sizeof(uint8_t);
}
while (1) {
struct lz4_block_header b = { { .raw = read_le32(in) } };
in += sizeof(struct lz4_block_header);
if ((size_t)(in - src) + b.size > srcn)
break; /* input overrun */
if (!b.size) {
out_size = out - dst;
break; /* decompression successful */
}
if (b.not_compressed) {
size_t size = MIN((uintptr_t)b.size, (uintptr_t)dst
+ dstn - (uintptr_t)out);
memcpy(out, in, size);
if (size < b.size)
break; /* output overrun */
out += size;
} else {
/* constant folding essential, do not touch params! */
int ret = LZ4_decompress_generic(in, out, b.size,
dst + dstn - out, endOnInputSize,
full, 0, noDict, out, NULL, 0);
if (ret < 0)
break; /* decompression error */
out += ret;
}
in += b.size;
if (has_block_checksum)
in += sizeof(uint32_t);
}
return out_size;
}

59
ariane/src/lib/lzma.c Normal file
View file

@ -0,0 +1,59 @@
/*
* coreboot interface to memory-saving variant of LZMA decoder
*
* Copyright (C) 2006 Carl-Daniel Hailfinger
* Released under the GNU GPL v2 or later
*
* Parts of this file are based on C/7zip/Compress/LZMA_C/LzmaTest.c from the
* LZMA SDK 4.42, which is written and distributed to public domain by Igor
* Pavlov.
*
*/
#include "printk.h"
#include <string.h>
#include "lzmadecode.h"
size_t ulzman(const void *src, size_t srcn, void *dst, size_t dstn)
{
unsigned char properties[LZMA_PROPERTIES_SIZE];
const int data_offset = LZMA_PROPERTIES_SIZE + 8;
UInt32 outSize;
SizeT inProcessed;
SizeT outProcessed;
int res;
CLzmaDecoderState state;
SizeT mallocneeds;
unsigned char scratchpad[15980];
const unsigned char *cp;
memcpy(properties, src, LZMA_PROPERTIES_SIZE);
/* The outSize in LZMA stream is a 64bit integer stored in little-endian
* (ref: lzma.cc@LZMACompress: put_64). To prevent accessing by
* unaligned memory address and to load in correct endianness, read each
* byte and re-construct. */
cp = src + LZMA_PROPERTIES_SIZE;
outSize = cp[3] << 24 | cp[2] << 16 | cp[1] << 8 | cp[0];
if (LzmaDecodeProperties(&state.Properties, properties,
LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) {
printk("lzma: Incorrect stream properties.\n");
return 0;
}
mallocneeds = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (mallocneeds > sizeof(scratchpad)) {
printk("lzma: Decoder scratchpad too small, needs %u bytes!\n", (UInt32)mallocneeds);
return 0;
}
if (outSize > dstn)
return outSize;
state.Probs = (CProb *)scratchpad;
res = LzmaDecode(&state, src + data_offset, srcn - data_offset,
&inProcessed, dst, outSize, &outProcessed);
if (res != 0) {
printk("lzma: Decoding error = %d\n", res);
return 0;
}
return outProcessed;
}

431
ariane/src/lib/lzmadecode.c Normal file
View file

@ -0,0 +1,431 @@
/*
LzmaDecode.c
LZMA Decoder (optimized for Speed version)
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this Code, expressly permits you to
statically or dynamically link your Code (or bind by name) to the
interfaces of this file without subjecting your linked Code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "lzmadecode.h"
#include <stdint.h>
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
/* Use 32-bit reads whenever possible to avoid bad flash performance. Fall back
* to byte reads for last 4 bytes since RC_TEST returns an error when BufferLim
* is *reached* (not surpassed!), meaning we can't allow that to happen while
* there are still bytes to decode from the algorithm's point of view. */
#define RC_READ_BYTE \
(look_ahead_ptr < 4 ? look_ahead.raw[look_ahead_ptr++] \
: ((((uintptr_t) Buffer & 3) \
|| ((SizeT) (BufferLim - Buffer) <= 4)) ? (*Buffer++) \
: ((look_ahead.dw = *(UInt32 *)Buffer), (Buffer += 4), \
(look_ahead_ptr = 1), look_ahead.raw[0])))
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
{ \
int i; \
\
for (i = 0; i < 5; i++) { \
RC_TEST; \
Code = (Code << 8) | RC_READ_BYTE; \
} \
}
#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
#define RC_INIT(buffer, bufferSize) Buffer = buffer; \
BufferLim = buffer + bufferSize; RC_INIT2
#define RC_NORMALIZE \
if (Range < kTopValue) { \
RC_TEST; \
Range <<= 8; \
Code = (Code << 8) | RC_READ_BYTE; \
}
#define IfBit0(p) \
RC_NORMALIZE; \
bound = (Range >> kNumBitModelTotalBits) * *(p); \
if (Code < bound)
#define UpdateBit0(p) \
Range = bound; \
*(p) += (kBitModelTotal - *(p)) >> kNumMoveBits
#define UpdateBit1(p) \
Range -= bound; \
Code -= bound; \
*(p) -= (*(p)) >> kNumMoveBits
#define RC_GET_BIT2(p, mi, A0, A1) \
IfBit0(p) { \
UpdateBit0(p); \
mi <<= 1; \
A0; \
} else { \
UpdateBit1(p); \
mi = (mi + mi) + 1; \
A1; \
}
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ;, ;)
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
{ \
int i = numLevels; \
\
res = 1; \
do { \
CProb *cp = probs + res; \
RC_GET_BIT(cp, res) \
} while (--i != 0); \
res -= (1 << numLevels); \
}
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
int LzmaDecodeProperties(CLzmaProperties *propsRes,
const unsigned char *propsData, int size)
{
unsigned char prop0;
if (size < LZMA_PROPERTIES_SIZE)
return LZMA_RESULT_DATA_ERROR;
prop0 = propsData[0];
if (prop0 >= (9 * 5 * 5))
return LZMA_RESULT_DATA_ERROR;
{
for (propsRes->pb = 0; prop0 >= (9 * 5);
propsRes->pb++, prop0 -= (9 * 5))
;
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9)
;
propsRes->lc = prop0;
/*
* unsigned char remainder = (unsigned char)(prop0 / 9);
* propsRes->lc = prop0 % 9;
* propsRes->pb = remainder / 5;
* propsRes->lp = remainder % 5;
*/
}
return LZMA_RESULT_OK;
}
#define kLzmaStreamWasFinishedId (-1)
int LzmaDecode(CLzmaDecoderState *vs,
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
{
CProb *p = vs->Probs;
SizeT nowPos = 0;
Byte previousByte = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
int state = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
int len = 0;
const Byte *Buffer;
const Byte *BufferLim;
int look_ahead_ptr = 4;
union {
Byte raw[4];
UInt32 dw;
} look_ahead;
UInt32 Range;
UInt32 Code;
*inSizeProcessed = 0;
*outSizeProcessed = 0;
{
UInt32 i;
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc
+ vs->Properties.lp));
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
}
RC_INIT(inStream, inSize);
while (nowPos < outSize) {
CProb *prob;
UInt32 bound;
int posState = (int)((nowPos)&posStateMask);
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
IfBit0(prob) {
int symbol = 1;
UpdateBit0(prob);
prob = p + Literal + (LZMA_LIT_SIZE *
((((nowPos) & literalPosMask) << lc)
+ (previousByte >> (8 - lc))));
if (state >= kNumLitStates) {
int matchByte;
matchByte = outStream[nowPos - rep0];
do {
int bit;
CProb *probLit;
matchByte <<= 1;
bit = (matchByte & 0x100);
probLit = prob + 0x100 + bit + symbol;
RC_GET_BIT2(probLit, symbol,
if (bit != 0)
break,
if (bit == 0)
break)
} while (symbol < 0x100);
}
while (symbol < 0x100) {
CProb *probLit = prob + symbol;
RC_GET_BIT(probLit, symbol)
}
previousByte = (Byte)symbol;
outStream[nowPos++] = previousByte;
if (state < 4)
state = 0;
else if (state < 10)
state -= 3;
else
state -= 6;
} else {
UpdateBit1(prob);
prob = p + IsRep + state;
IfBit0(prob) {
UpdateBit0(prob);
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < kNumLitStates ? 0 : 3;
prob = p + LenCoder;
} else {
UpdateBit1(prob);
prob = p + IsRepG0 + state;
IfBit0(prob) {
UpdateBit0(prob);
prob = p + IsRep0Long
+ (state << kNumPosBitsMax)
+ posState;
IfBit0(prob) {
UpdateBit0(prob);
if (nowPos == 0)
return LZMA_RESULT_DATA_ERROR;
state = state < kNumLitStates
? 9 : 11;
previousByte = outStream[nowPos
- rep0];
outStream[nowPos++] =
previousByte;
continue;
} else
{
UpdateBit1(prob);
}
} else {
UInt32 distance;
UpdateBit1(prob);
prob = p + IsRepG1 + state;
IfBit0(prob) {
UpdateBit0(prob);
distance = rep1;
} else {
UpdateBit1(prob);
prob = p + IsRepG2 + state;
IfBit0(prob) {
UpdateBit0(prob);
distance = rep2;
} else {
UpdateBit1(prob);
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = p + RepLenCoder;
}
{
int numBits, offset;
CProb *probLen = prob + LenChoice;
IfBit0(probLen) {
UpdateBit0(probLen);
probLen = prob + LenLow
+ (posState << kLenNumLowBits);
offset = 0;
numBits = kLenNumLowBits;
} else {
UpdateBit1(probLen);
probLen = prob + LenChoice2;
IfBit0(probLen) {
UpdateBit0(probLen);
probLen = prob + LenMid
+ (posState <<
kLenNumMidBits);
offset = kLenNumLowSymbols;
numBits = kLenNumMidBits;
} else {
UpdateBit1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols
+ kLenNumMidSymbols;
numBits = kLenNumHighBits;
}
}
RangeDecoderBitTreeDecode(probLen, numBits,
len);
len += offset;
}
if (state < 4) {
int posSlot;
state += kNumLitStates;
prob = p + PosSlot +
((len < kNumLenToPosStates ? len :
kNumLenToPosStates - 1) <<
kNumPosSlotBits);
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits,
posSlot);
if (posSlot >= kStartPosModelIndex) {
int numDirectBits = ((posSlot >> 1)
- 1);
rep0 = (2 | ((UInt32)posSlot & 1));
if (posSlot < kEndPosModelIndex) {
rep0 <<= numDirectBits;
prob = p + SpecPos + rep0
- posSlot - 1;
} else {
numDirectBits -= kNumAlignBits;
do {
RC_NORMALIZE
Range >>= 1;
rep0 <<= 1;
if (Code >= Range) {
Code -= Range;
rep0 |= 1;
}
} while (--numDirectBits != 0);
prob = p + Align;
rep0 <<= kNumAlignBits;
numDirectBits = kNumAlignBits;
}
{
int i = 1;
int mi = 1;
do {
CProb *prob3 = prob
+ mi;
RC_GET_BIT2(prob3, mi,
;, rep0 |= i);
i <<= 1;
} while (--numDirectBits != 0);
}
} else
rep0 = posSlot;
if (++rep0 == (UInt32)(0)) {
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
if (rep0 > nowPos)
return LZMA_RESULT_DATA_ERROR;
do {
previousByte = outStream[nowPos - rep0];
len--;
outStream[nowPos++] = previousByte;
} while (len != 0 && nowPos < outSize);
}
}
RC_NORMALIZE;
*inSizeProcessed = (SizeT)(Buffer - inStream);
*outSizeProcessed = nowPos;
return LZMA_RESULT_OK;
}

View file

@ -0,0 +1,65 @@
/*
LzmaDecode.h
LZMA Decoder interface
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#ifndef __LZMADECODE_H
#define __LZMADECODE_H
typedef unsigned char Byte;
typedef unsigned short UInt16;
typedef unsigned int UInt32;
typedef UInt32 SizeT;
#define CProb UInt16
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LZMA_PROPERTIES_SIZE 5
typedef struct _CLzmaProperties {
int lc;
int lp;
int pb;
} CLzmaProperties;
int LzmaDecodeProperties(CLzmaProperties *propsRes,
const unsigned char *propsData, int size);
#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE \
<< ((Properties)->lc + (Properties)->lp)))
#define kLzmaNeedInitId (-2)
typedef struct _CLzmaDecoderState {
CLzmaProperties Properties;
CProb *Probs;
} CLzmaDecoderState;
int LzmaDecode(CLzmaDecoderState *vs,
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
#endif

62
ariane/src/lib/printk.c Normal file
View file

@ -0,0 +1,62 @@
/**
* Kernel print functions.
*/
#include "printk.h"
#include "vsprintf.h"
#include "../display/video_fb.h"
#ifdef DEBUG_UART_PORT
#include "../hwinit/uart.h"
#endif
/**
* Temporary stand-in main printk.
*
* TODO: This should print via UART, console framebuffer, and to a ring for
* consumption by Horizon
*/
void printk(char *fmt, ...)
{
va_list list;
va_start(list, fmt);
vprintk(fmt, list);
va_end(list);
}
void vprintk(char *fmt, va_list args)
{
char buf[512];
vsnprintf(buf, sizeof(buf), fmt, args);
video_puts(buf);
}
void dbg_print(char *fmt, ...)
{
va_list list;
va_start(list, fmt);
dbg_vprint(fmt, list);
va_end(list);
}
void dbg_vprint(char *fmt, va_list args)
{
char buf[512];
int numChars = vsnprintf(buf, sizeof(buf), fmt, args);
#ifdef DEBUG_UART_PORT
uart_print(DEBUG_UART_PORT, buf, numChars);
#else
(void)numChars;
video_puts(buf);
#endif
}
int snprintfk(char *buf, unsigned int bufSize, const char* fmt, ...)
{
va_list list;
va_start(list, fmt);
int outVal = vsnprintf(buf, bufSize, fmt, list);
va_end(list);
return outVal;
}

12
ariane/src/lib/printk.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef __PRINTK_H__
#define __PRINTK_H__
#include <stdarg.h>
void printk(char *fmt, ...);
void vprintk(char *fmt, va_list args);
void dbg_print(char* fmt, ...);
void dbg_vprint(char* fmt, va_list args);
int snprintfk(char *buf, unsigned int bufSize, const char* fmt, ...);
#endif

1676
ariane/src/lib/vsprintf.c Normal file

File diff suppressed because it is too large Load diff

28
ariane/src/lib/vsprintf.h Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2011 Andrei Warkentin <andrey.warkentin@gmail.com>
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <stdarg.h>
#include <stdlib.h>
#ifndef VSPRINTF_H
#define VSPRINTF_H
struct va_format {
const char *fmt;
va_list *va;
};
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base);
int sprintf(char *buf, const char *fmt, ...);
int scnprintf(char *buf, size_t size, const char *fmt, ...);
int snprintf(char *buf, size_t size, const char *fmt, ...);
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
int sscanf(const char *buf, const char *fmt, ...);
#endif /* VSPRINTF_H */

782
ariane/src/main.c Normal file
View file

@ -0,0 +1,782 @@
#include "utils.h"
#include "lib/printk.h"
#include "lib/heap.h"
#include "display/video_fb.h"
#include "hwinit/btn.h"
#include "hwinit/hwinit.h"
#include "hwinit/di.h"
#include "hwinit/mc.h"
#include "hwinit/mtc.h"
#include "hwinit/t210.h"
#include "hwinit/sdmmc.h"
#include "hwinit/timer.h"
#include "hwinit/cluster.h"
#include "hwinit/clock.h"
#include "hwinit/max77620.h"
#include "hwinit/max7762x.h"
#include "hwinit/util.h"
#include "hwinit/i2c.h"
#include "hwinit/pmc.h"
#include "hwinit/uart.h"
#include "hwinit/fuse.h"
#include "hwinit/pinmux.h"
#include "hwinit/sdram.h"
#include "hwinit/carveout.h"
#include "rcm_usb.h"
#include "usb_output.h"
#include "storage.h"
#include "lib/ff.h"
#include "lib/decomp.h"
#include "cbmem.h"
#include <alloca.h>
#include <strings.h>
#include "usb_command.h"
#define XVERSION 3
#define IPL_HEAP_START 0x84000000
#define IPL_HEAP_SZ 0x20000000 // 512MB.
#define IPL_STACK_TOP 0x83100000
#define IPL_LOAD_ADDR 0x40008000
extern void pivot_stack(u32 stack_top);
static int initialize_mount(FATFS* outFS, u8 devNum)
{
sdmmc_t* currCont = get_controller_for_index(devNum);
sdmmc_storage_t* currStor = get_storage_for_index(devNum);
if (currCont == NULL || currStor == NULL)
{
printk("get_controller_for_index(%d) OR get_storage_for_index(%d) failed\n", devNum, devNum);
return 0;
}
if (currStor->sdmmc != NULL)
return 1; //already initialized
if (devNum == 0) //maybe support more ?
{
if (sdmmc_storage_init_sd(currStor, currCont, SDMMC_1, SDMMC_BUS_WIDTH_4, 11) && f_mount(outFS, "", 1) == FR_OK)
return 1;
else
{
if (currStor->sdmmc != NULL)
sdmmc_storage_end(currStor, 0);
memset(currCont, 0, sizeof(sdmmc_t));
memset(currStor, 0, sizeof(sdmmc_storage_t));
}
}
if (devNum == 1)
{
if (sdmmc_storage_init_mmc(currStor, currCont, SDMMC_4, SDMMC_BUS_WIDTH_8, 4) == 1)
{
printk("sdmmc_storage_init_mmc succeeded\n");
if (sdmmc_storage_set_mmc_partition(currStor, 1)) // BOOT0
return 1;
printk("sdmmc_storage_set_mmc_partition failed\n");
}
printk("sdmmc_storage_init_mmc 2 failed\n");
if (currStor->sdmmc != NULL)
sdmmc_storage_end(currStor, 0);
memset(currCont, 0, sizeof(sdmmc_t));
memset(currStor, 0, sizeof(sdmmc_storage_t));
}
return 0;
}
static void deinitialize_storage(u32 devNum)
{
if (devNum == 0)
f_unmount("");
sdmmc_storage_t* currStor = get_storage_for_index((u8)devNum);
if (currStor != NULL && currStor->sdmmc != NULL)
{
if (!sdmmc_storage_end(currStor, 1))
dbg_print("sdmmc_storage_end for storage idx %u FAILED!\n", devNum);
else
memset(currStor, 0, sizeof(sdmmc_storage_t));
}
}
static void deinitialize_storages()
{
for (u32 i=0; i<FF_VOLUMES; i++)
{
deinitialize_storage(i);
}
}
#define USB_EP_BULK_IN_BUF_ADDR 0xFF000000
#define USB_EP_BULK_OUT_BUF_ADDR 0xFF800000
u8* usb_write_buff = (u8*)USB_EP_BULK_IN_BUF_ADDR;
u8* usb_read_buff = (u8*)USB_EP_BULK_OUT_BUF_ADDR;
static UC_CommandType usb_command_read()
{
memset(usb_read_buff, 0, 4096);
unsigned int bytesTransferred = 0;
if (!rcm_usb_device_read_ep1_out_sync(usb_read_buff, USB_BUFFER_LENGTH, &bytesTransferred))
{
if (bytesTransferred > 2)
{
UC_Header* uc = (UC_Header*)usb_read_buff;
if (uc->signature == COMMAND || uc->signature == EXEC_COMMAND)
{
printk("Received command from USB host\n");
return uc->command;
}
}
}
return NONE;
}
// This is a safe and unused DRAM region for our payloads.
#define RELOC_META_OFF 0x7C
#define PATCHED_RELOC_SZ 0x94
#define PATCHED_RELOC_STACK 0x40007000
#define PATCHED_RELOC_ENTRY 0x40010000
#define EXT_PAYLOAD_ADDR 0xC0000000
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
#define COREBOOT_END_ADDR 0xD0000000
#define CBFS_DRAM_EN_ADDR 0x4003e000
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
#define EMC_SCRATCH0 0x324
#define EMC_HEKA_UPD (1 << 30)
static void *coreboot_addr;
typedef struct __attribute__((__packed__)) _reloc_meta_t
{
u32 start;
u32 stack;
u32 end;
u32 ep;
} reloc_meta_t;
void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
{
memcpy((u8 *)payload_src, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);
volatile reloc_meta_t *relocator = (reloc_meta_t *)(payload_src + RELOC_META_OFF);
relocator->start = payload_dst - ALIGN(PATCHED_RELOC_SZ, 0x10);
relocator->stack = PATCHED_RELOC_STACK;
relocator->end = payload_dst + payload_size;
relocator->ep = payload_dst;
}
FRESULT f_write_buffer(FIL* fp, const void* buffer, u32 length, u32 *bytesWritten)
{
int block_size = 4096;
int btw = 0;
*bytesWritten = 0;
FRESULT res;
while(btw < length)
{
char b[block_size];
memcpy(b, buffer + btw, block_size);
unsigned int bytesWrite = 0;
int bs = btw + block_size > length ? length - btw : block_size;
printk("Prepare to write %db to file\n", bs);
res = f_write(fp, b, bs, &bytesWrite);
if (res != FR_OK)
{
printk("Res = %d\n", res);
*bytesWritten = btw;
return res;
}
if (!(bytesWrite > 0))
{
printk("ERROR 2 bytesWrite = 0\n");
return 20;
}
btw += bytesWrite;
printk("%d bytesWriten\n", bytesWrite);
}
*bytesWritten = btw;
return res;
}
void send_response(const void* in_buffer, u32 size)
{
u32 new_size = size + sizeof(u16), bytes = 0;
if (new_size > RESPONSE_MAX_SIZE)
return;
u16 signature = RESPONSE;
memcpy(&usb_write_buff[0], (u8*)&signature, sizeof(u16));
memcpy(&usb_write_buff[sizeof(u16)], in_buffer, size);
rcm_usb_device_write_ep1_in_sync(&usb_write_buff[0], new_size, &bytes);
}
bool recv_bin_packet(u32 *bytesReceived)
{
//printk("Preparing to receive packet\n");
memset(&usb_read_buff[0], 0, sizeof(UC_BlockHeader));
*bytesReceived = 0;
u32 bytesTransferred = 0;
if(rcm_usb_device_read_ep1_out_sync(usb_read_buff, USB_BUFFER_LENGTH, &bytesTransferred) && !bytesTransferred)
{
printk("Failed to receive packet\n");
return false;
}
UC_BlockHeader *bh = (UC_BlockHeader*)&usb_read_buff[0];
if (bh->signature != BIN_PACKET)
{
printk("Error, did not receive a bin packet from usb pipe\n");
return false;
}
//memcpy(&[buffer[0], &usb_read_buff[sizeof(UC_BlockHeader)]], bh->block_size);
// Send bloc size in response
send_response((const void*)&bh->block_size, sizeof(bh->block_size));
*bytesReceived = bh->block_size;
//printk("Received a packet %db\n", bh->block_size);
return true;
}
void on_WriteSDFileCommand()
{
UC_SDIO* uc = (UC_SDIO*)usb_read_buff;
printk("Received a WRITE_SD_FILE for path : %s (%uMB)\n", uc->path, uc->file_size / 1024 / 1024);
printk("file_size = %u, bytescount = %u\n", uc->file_size, 0);
//printk("file_size = %u, bytescount = %u\n", uc->file_size, 0);
//printk("Size of UC_SDIO = %ld, sign=%ld, command=%ld, path=%ld, filesize=%ld\n", sizeof(*uc), sizeof(uc->signature), sizeof(uc->command), sizeof(uc->path), sizeof(uc->file_size));
bool lz4compress = uc->is_lz4_compressed;
FIL fp;
FRESULT res;
f_unlink(uc->path);
res = f_open (&fp, uc->path, FA_WRITE | FA_CREATE_ALWAYS);
if (res == FR_OK)
{
u32* bytesCount = malloc(sizeof(u32));
u32* bytesTotal = malloc(sizeof(u32));
u32* begin_time = malloc(sizeof(u32));
*bytesCount = 0;
*bytesTotal = uc->file_size;
*begin_time = get_tmr_s();
int numTries = 0;
numTries = 0;
char *path = malloc(256);
memcpy(path, uc->path, 256);
u8* buf32 = malloc(64);
int *buf32_s = malloc(sizeof(int));
*buf32_s = 0;
int *pre_pct = malloc(sizeof(int));
*pre_pct = -1;
while (*bytesCount < *bytesTotal)
{
u32 bytesTransferred = 0;
if (!recv_bin_packet(&bytesTransferred))
break;
//printk("Preparing to write file block\n");
// Write (uncompressed bin)
u32 bytesWrite = 0;
if (f_write(&fp, &usb_read_buff[32], bytesTransferred, &bytesWrite) != FR_OK)
{
printk("Failed to write tmp_buffer\n");
break;
}
if (!(bytesWrite > 0))
{
printk("ERROR bytesWrite = 0\n");
break;
}
*bytesCount += bytesWrite;
//printk("File block written (total %u\n", *bytesCount);
int pct = (u64)(*bytesCount) * 100 / *bytesTotal;
if (pct != *pre_pct || *bytesCount >= *bytesTotal)
{
printk("\rDownloading %s - %d%% (%d MB) ", path, pct, *bytesCount / 1024 / 1024 );
*pre_pct = pct;
}
/*
//printk("Prepare to receive file\n");
if(rcm_usb_device_read_ep1_out_sync(usb_read_buff, USB_BUFFER_LENGTH, &bytesTransferred))
{
printk("Failed to receive file at off. %u \n", *bytesCount);
numTries++;
continue;
}
if (bytesTransferred)
{
unsigned int bytesWrite = 0;
UC_BlockHeader *bh = (UC_BlockHeader*)&usb_read_buff[0];
if (bh->signature != BIN_PACKET)
{
printk("Error, did not receive a bin packet from usb pipe");
break;
}
if (lz4compress)
{
int bfs = bh->block_full_size;
int bs = bh->block_size;
//printk("Received a compress packet. block_size %d, block_full_size %d, max_size %d\n\n", bh->block_size, bh->block_full_size, 1024*1024);
u8 *lz4_buffer = malloc(1024*1024);
memset(lz4_buffer, 0, 1024*1024);
int len = LZ4_decompress_safe((char*)&usb_read_buff[32], (char*)lz4_buffer, bs, 1024*1024);
if (len <= 0)
{
printk("Error decomp, len is %d", len);
break;
}
if (len != bfs)
{
printk("Error decomp size %d != bfs %d\n", len, bfs);
break;
} //else printk("LZ4 decompress done (%db)\n", len);
int align_val = 32;
// Push back 32b align buffer
if(*buf32_s && len < (1024*1024) - *buf32_s)
{
//printk("Push back 32b align buffer\n");
memcpy(&lz4_buffer[len], &buf32[0], *buf32_s);
len += *buf32_s;
*buf32_s = 0;
}
// Save 32b align buffer
if (len % align_val)
{
//printk("Save 32b align buffer\n");
*buf32_s = len - ((len / align_val) * align_val);
memcpy(&buf32[0], &lz4_buffer[len - *buf32_s], *buf32_s);
len -= *buf32_s;
}
if (len % align_val)
{
printk("Buffer is not 32b aligned\n");
break;
}
// Write
bytesWrite = 0;
if (f_write(&fp, lz4_buffer, len, &bytesWrite) != FR_OK)
{
printk("Failed to write tmp_buffer\n");
break;
}
if (!(bytesWrite > 0))
{
printk("ERROR bytesWrite = 0\n");
break;
}
*bytesCount += bytesWrite;
free(lz4_buffer);
bytesWrite = 0;
if (lz4compress && *bytesCount + *buf32_s > *bytesTotal && *buf32_s && f_write_buffer(&fp, buf32, *buf32_s > 32 ? 64 : 32, &bytesWrite) != FR_OK)
{
printk("Failed to write tmp_buffer\n");
break;
}
*bytesCount += bytesWrite;
}
else
{
// Write (uncompressed bin)
bytesWrite = 0;
if (f_write(&fp, &usb_read_buff[32], bh->block_size, &bytesWrite) != FR_OK)
{
printk("Failed to write tmp_buffer\n");
break;
}
if (!(bytesWrite > 0))
{
printk("ERROR bytesWrite = 0\n");
break;
}
*bytesCount += bytesWrite;
}
int pct = (u64)(*bytesCount) * 100 / *bytesTotal;
if (pct != *pre_pct || *bytesCount >= *bytesTotal)
{
printk("\rDownloading %s - %d%% (%d MB) ", path, pct, *bytesCount / 1024 / 1024 );
*pre_pct = pct;
}
}
else
{
printk("Failed to receive file at off. %u \n", *bytesCount);
break;
}
*/
}
printk("\nBytes received. %u (%u seconds)\n", *bytesCount, (get_tmr_s() - *begin_time));
f_close(&fp);
free(bytesCount); free(bytesTotal); free(begin_time);
free(path); free(buf32); free(buf32_s); free(pre_pct);
}
else
{
printk("Failed to open file. Err %d\n", res);
}
}
void on_PushPayloadCommand()
{
printk("Received a push payload command\n");
video_clear_line();
UC_EXEC* uc = (UC_EXEC*)usb_read_buff;
if (uc->command != PUSH_PAYLOAD)
{
printk("Wrong PUSH_PAYLOAD command\n");
video_clear_line();
return;
}
void *buf = (void *)RCM_PAYLOAD_ADDR;
u32 size = uc->bin_size;
u32 bytesCount = 0;
printk("Preparing to receive payload, size = %u\n", size);
video_clear_line();
while (bytesCount < size)
{
u32 bytesTransferred = 0;
if (!recv_bin_packet(&bytesTransferred))
{
printk("Failed to receive file at off. %u \n", bytesCount);
break;
}
memcpy(buf + bytesCount, &usb_read_buff[sizeof(UC_BlockHeader)], bytesTransferred);
bytesCount += bytesTransferred;
}
if (bytesCount != size)
return;
/*
uint32_t mrt_time = 2;
uint8_t reg_val = mrt_time - 2;
//bit 3..5 is the value we want to set
reg_val &= 0x7;
reg_val <<= 3;
reg_val |= 0x40; //always set normally
max77620_send_byte(MAX77620_REG_ONOFFCNFG1, reg_val);
*/
printk("Payload received and copied in RAM\n");
video_clear_line();
deinitialize_storages();
msleep(200);
//mc_disable_ahb_redirect();
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
//reconfig_hw_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
//printk("Launch payload\n");
display_end();
void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR;
(*ext_payload_ptr)();
printk("Failed to launch payload\n");
clock_halt_bpmp();
return;
}
void on_RebootRCMCommand()
{
deinitialize_storages();
mc_disable_ahb_redirect();
display_end();
bool confirm = true;
send_response((const void*)&confirm, sizeof(bool)); // Notify caller
msleep(10);
// Reboot to RCM
PMC(APBDEV_PMC_SCRATCH0) = (1 << 1);
PMC(0x0) |= PMC_CNTRL_MAIN_RST;
while (true)
clock_halt_bpmp();
}
bool get_autoRCM_state(bool *state)
{
if(!initialize_mount(NULL, 1))
{
printk("Failed to mount EMMC BOOT0\n");
return false;
}
bool bct_state[4];
bool autoRcmOn[4] = {false, false, false, false};
sdmmc_storage_t* currStor = get_storage_for_index(1);
for (int i = 0; i < 4; i++)
{
u8 buff[0x200];
memset(buff, 0, 0x200);
if (!sdmmc_storage_read(currStor, (0x200 + (0x4000 * i)) / 0x200, 1, &buff[0]))
{
printk("Error reading BCT %d from BOOT0.\n", i);
deinitialize_storage(1);
return false;
}
if (buff[0x10] == 0xF7) bct_state[i] = true;
else bct_state[i] = false;
}
if (!memcmp(autoRcmOn, bct_state, 4))
*state = true;
else
*state = false;
deinitialize_storage(1);
return true;
}
bool set_autoRCM_state(bool autoRCM)
{
if(!initialize_mount(NULL, 1))
{
printk("Failed to mount EMMC BOOT0\n");
return false;
}
sdmmc_storage_t* currStor = get_storage_for_index(1);
for (int i = 0; i < 4; i++)
{
u8 buff[0x200];
memset(buff, 0, 0x200);
if (!sdmmc_storage_read(currStor, (0x200 + (0x4000 * i)) / 0x200, 1, &buff[0]))
{
printk("Error reading BCT %d from BOOT0.\n", i);
deinitialize_storage(1);
return false;
}
if (!autoRCM)
buff[0x10] = 0xF7;
else
{
u8 randomXor = 0;
do randomXor = (unsigned)get_tmr_ms() & 0xFF;
while (!randomXor);
buff[0x10] ^= randomXor;
}
if (!sdmmc_storage_write(currStor, (0x200 + (0x4000 * i)) / 0x200, 1, &buff[0]))
{
printk("Error writing BCT %d from BOOT0.\n", i);
deinitialize_storage(1);
return false;
}
}
deinitialize_storage(1);
return true;
}
void on_getDeviceInfoCommand(FATFS *fs)
{
// Init a device info struct
UC_DeviceInfo di;
di.signature = DEVINFO;
// AutoRCM
get_autoRCM_state(&di.autoRCM);
// Burnt fuses
di.burnt_fuses = 0;
for (u32 i = 0; i < 32; i++)
{
if ((fuse_read_odm(7) >> i) & 1)
di.burnt_fuses++;
}
// Battery
int value = 0;
i2c_recv_buf_small((u8 *)&value, 2, I2C_1, 0x36, 0x06);
di.battery_capacity = value >> 8;
// FS info
if (fs == NULL || fs->fs_type == 0)
{
di.sdmmc_initialized = false;
di.cfw_sxos = false;
di.cfw_ams = false;
di.cbl_hekate = false;
}
else
{
di.sdmmc_initialized = true;
di.emmc_fs_type = fs->fs_type;
di.emmc_fs_cl_size = fs->csize;
di.emmc_fs_last_cl = fs->n_fatent - 2;
printk("di.emmc_fs_last_cl = %lu\n", emmc_fs_last_cl);
FATFS *ffs;
f_getfree("", &di.emmc_fs_free_cl, &ffs);
printk("di.emmc_fs_free_cl = %lu\n", di.emmc_fs_free_cl);
FILINFO fno;
di.cfw_sxos = (f_stat("boot.dat", &fno) == FR_OK);
di.cbl_hekate = (f_stat("bootloader/hekate_ipl.ini", &fno) == FR_OK);
di.cfw_ams = (f_stat("BCT.ini", &fno) == FR_OK)
|| (f_stat("atmosphere/BCT.ini", &fno) == FR_OK)
|| (f_stat("atmosphere/config/BCT.ini", &fno) == FR_OK);
/*
* ToDo:
* - emunand detection
* - fw detection (sys + emu)
* - get Nintendo device ID
* - check for ipatched switch
*/
}
u32 bytes;
rcm_usb_device_write_ep1_in_sync((u8*)&di, sizeof(UC_DeviceInfo), &bytes);
}
int main(void)
{
u32* lfb_base;
config_hw();
// Pivot the stack so we have enough space.
pivot_stack(IPL_STACK_TOP);
//Tegra/Horizon configuration goes to 0x80000000+, package2 goes to 0xA9800000, we place our heap in between.
heap_init(IPL_HEAP_START);
//heap_init(0x90020000);
// Train DRAM and switch to max frequency.
//minerva_init();
display_enable_backlight(false);
display_init();
// Set up the display, and register it as a printk provider.
lfb_base = display_init_framebuffer();
video_init(lfb_base);
//Init the CBFS memory store in case we are booting coreboot
cbmem_initialize_empty();
mc_enable_ahb_redirect();
/* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */
display_enable_backlight(true);
if (!rcm_usb_device_ready()) //somehow usb isn't initialized
printk("ERROR RCM USB not initialized, press the power button to turn off the system.\n");
//u8 *holdingBuffer = (void*)malloc(USB_BUFFER_LENGTH*2);
//usbBuffer = (void*)ALIGN_UP((u32)&holdingBuffer[0], USB_BUFFER_LENGTH);
printk("ARIANE\n");
FATFS fs;
memset(&fs, 0, sizeof(FATFS));
if(!initialize_mount(&fs, 0))
{
printk("Failed to initialise SD Card\n");
memset(&fs, 0, sizeof(FATFS));
}
// AutoRCM
bool autoRCM;
if (get_autoRCM_state(&autoRCM))
printk("autoRCM state : %s\n", autoRCM ? "ON" : "OFF");
// Fuses
u32 burntFuses = 0;
for (u32 i = 0; i < 32; i++)
{
if ((fuse_read_odm(7) >> i) & 1)
burntFuses++;
}
printk("Burnt Fuses : %u\n", burntFuses);
// Battery
int value = 0;
i2c_recv_buf_small((u8 *)&value, 2, I2C_1, 0x36, 0x06);
printk("Battery: %3d%\n", value >> 8);
static const char READY_NOTICE[] = "READY.\n";
unsigned int bytesTransferred = 0;
while(1)
{
if (btn_read() == BTN_POWER)
{
printk("EXIT\n");
goto progend;
}
/*
* ToDo
* -> Detect USB unplug
*/
// Dispatcher
switch (usb_command_read())
{
case GET_STATUS :
rcm_ready_notice();
break;
case WRITE_SD_FILE :
on_WriteSDFileCommand();
break;
case PUSH_PAYLOAD :
on_PushPayloadCommand();
break;
case REBOOT_RCM :
on_RebootRCMCommand();
break;
case GET_DEVICE_INFO:
on_getDeviceInfoCommand(&fs);
break;
}
}
progend_user:
printk("Press POWER button to exit\n");
while(1) { if (btn_read() == BTN_POWER) goto progend;}
progend:
// Tell the PMIC to turn everything off
shutdown_using_pmic();
/* Do nothing for now */
return 0;
}

Some files were not shown because too many files have changed in this diff Show more