Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
nwert committed Mar 7, 2018
0 parents commit 6f6683e
Show file tree
Hide file tree
Showing 26 changed files with 4,159 additions and 0 deletions.
49 changes: 49 additions & 0 deletions hwinit/clock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "clock.h"
#include "t210.h"

static const clock_t _clock_uart[] = {
/* UART A */ { 4, 0x10, 0x178, 6, 0, 0 },
/* UART B */ { 4, 0x10, 0x17C, 7, 0, 0 },
/* UART C */ { 8, 0x14, 0x1A0, 0x17, 0, 0 },
/* UART D */ { 0 },
/* UART E */ { 0 }
};

static const clock_t _clock_i2c[] = {
/* I2C1 */ { 4, 0x10, 0x124, 0xC, 6, 0 },
/* I2C2 */ { 0 },
/* I2C3 */ { 0 },
/* I2C4 */ { 0 },
/* I2C5 */ { 8, 0x14, 0x128, 0xF, 6, 0 },
/* I2C6 */ { 0 }
};

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_enable_fuse(u32 enable)
{
CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF | ((enable & 1) << 28) & 0x10000000;
}

void clock_enable_uart(u32 idx)
{
clock_enable(&_clock_uart[idx]);
}

void clock_enable_i2c(u32 idx)
{
clock_enable(&_clock_i2c[idx]);
}
34 changes: 34 additions & 0 deletions hwinit/clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef _CLOCK_H_
#define _CLOCK_H_

#include "types.h"

/*! Clock registers. */
#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_CLK_SOURCE_EMC 0x19C
#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284
#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308
#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328
#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8

typedef struct _clock_t
{
u32 reset;
u32 enable;
u32 source;
u8 index;
u8 clk_src;
u8 clk_div;
} clock_t;

void clock_enable(const clock_t *clk);
void clock_enable_fuse(u32 enable);
void clock_enable_uart(u32 idx);
void clock_enable_i2c(u32 idx);

#endif
195 changes: 195 additions & 0 deletions hwinit/di.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#include "di.h"
#include "t210.h"
#include "util.h"
#include "i2c.h"

#include "di.inl"

static u32 _display_ver = 0;

static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
{
u32 end = TMR(0x10) + timeout;
while (TMR(0x10) < end && DSI(off) & mask)
;
sleep(5);
}

void display_init()
{
//Power on.
i2c_send_byte(I2C_5, 0x3C, 0x23, 0xD0);
i2c_send_byte(I2C_5, 0x3C, 0x3D, 0x09);

//Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.
CLOCK(0x30C) = 0x1010000;
CLOCK(0x328) = 0x1010000;
CLOCK(0x304) = 0x18000000;
CLOCK(0x320) = 0x18000000;
CLOCK(0x284) = 0x20000;
CLOCK(0x66C) = 0xA;
CLOCK(0x448) = 0x80000;
CLOCK(0x620) = 0xA;

//DPD idle.
PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;
PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;

//Config pins.
PINMUX_AUX(0x1D0) &= 0xFFFFFFEF;
PINMUX_AUX(0x1D4) &= 0xFFFFFFEF;
PINMUX_AUX(0x1FC) &= 0xFFFFFFEF;
PINMUX_AUX(0x200) &= 0xFFFFFFEF;
PINMUX_AUX(0x204) &= 0xFFFFFFEF;

GPIO_3(0x00) = GPIO_3(0x00) & 0xFFFFFFFC | 0x3;
GPIO_3(0x10) = GPIO_3(0x10) & 0xFFFFFFFC | 0x3;
GPIO_3(0x20) = GPIO_3(0x20) & 0xFFFFFFFE | 0x1;

sleep(10000u);

GPIO_3(0x20) = GPIO_3(0x20) & 0xFFFFFFFD | 0x2;

sleep(10000);

GPIO_6(0x04) = GPIO_6(0x04) & 0xFFFFFFF8 | 0x7;
GPIO_6(0x14) = GPIO_6(0x14) & 0xFFFFFFF8 | 0x7;
GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFD | 0x2;

//Config display interface and display.
MIPI_CAL(0x60) = 0;

exec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4);
exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94);
exec_cfg((u32 *)DSI_BASE, _display_config_3, 60);

sleep(10000);

GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFB | 0x4;

sleep(60000);

DSI(_DSIREG(DSI_DSI_BTA_TIMING)) = 0x50204;
DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x337;
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
_display_dsi_wait(250000, _DSIREG(DSI_DSI_TRIGGER), 3);

DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x406;
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
_display_dsi_wait(250000, _DSIREG(DSI_DSI_TRIGGER), 3);

DSI(_DSIREG(DSI_HOST_DSI_CONTROL)) = 0x200B;
_display_dsi_wait(150000, _DSIREG(DSI_HOST_DSI_CONTROL), 8);

sleep(5000);

_display_ver = DSI(_DSIREG(DSI_DSI_RD_DATA));
if (_display_ver == 0x10)
exec_cfg((u32 *)DSI_BASE, _display_config_4, 43);

DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x1105;
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;

sleep(180000);

DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x2905;
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;

sleep(20000);

exec_cfg((u32 *)DSI_BASE, _display_config_5, 21);
exec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3);
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4;
exec_cfg((u32 *)DSI_BASE, _display_config_7, 10);

sleep(10000);

exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6);
exec_cfg((u32 *)DSI_BASE, _display_config_9, 4);
exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16);

sleep(10000);

exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113);
}

void display_end()
{
GPIO_6(0x24) &= 0xFFFFFFFE;
DSI(_DSIREG(DSI_DSI_VID_MODE_CONTROL)) = 1;
DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x2805;

u32 end = HOST1X(0x30A4) + 5;
while (HOST1X(0x30A4) < end)
;

DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = 5;
DSI(_DSIREG(DSI_DSI_VID_MODE_CONTROL)) = 0;

exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17);
exec_cfg((u32 *)DSI_BASE, _display_config_13, 16);

sleep(10000);

if (_display_ver == 0x10)
exec_cfg((u32 *)DSI_BASE, _display_config_14, 22);

DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x1005;
DSI(_DSIREG(DSI_DSI_TRIGGER)) = 2;

sleep(50000);

GPIO_6(0x24) &= 0xFFFFFFFB;

sleep(10000);

GPIO_3(0x20) &= 0xFFFFFFFD;

sleep(10000);

GPIO_3(0x20) = (GPIO_3(0x20) >> 1) << 1;

sleep(10000);

//Disable clocks.
CLOCK(0x308) = 0x1010000;
CLOCK(0x32C) = 0x1010000;
CLOCK(0x300) = 0x18000000;
CLOCK(0x324) = 0x18000000;

DSI(_DSIREG(DSI_PAD_CONTROL)) = 0x10F010F;
DSI(_DSIREG(DSI_DSI_POWER_CONTROL)) = 0;

GPIO_6(0x04) &= 0xFFFFFFFE;

PINMUX_AUX(0x1FC) = PINMUX_AUX(0x1FC) & 0xFFFFFFEF | 0x10;
PINMUX_AUX(0x1FC) = (PINMUX_AUX(0x1FC) >> 2) << 2 | 1;
}

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 | 1;

sleep(35000);

GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 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, 32);

sleep(35000);

GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 1;

return (u32 *)0xC0000000;
}
56 changes: 56 additions & 0 deletions hwinit/di.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifndef _DI_H_
#define _DI_H_

#include "types.h"

/*! Display registers. */
#define _DIREG(reg) ((reg) * 4)
#define DC_CMD_DISPLAY_COMMAND 0x32
#define DC_CMD_STATE_ACCESS 0x40
#define DC_CMD_STATE_CONTROL 0x41
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
#define DC_DISP_DISP_WIN_OPTIONS 0x402
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
#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_X_WIN_XD_WIN_OPTIONS 0x700
#define DC_X_WIN_XD_COLOR_DEPTH 0x703
#define DC_X_WIN_XD_POSITION 0x704
#define DC_X_WIN_XD_SIZE 0x705
#define DC_X_WIN_XD_PRESCALED_SIZE 0x706
#define DC_X_WIN_XD_H_INITIAL_DDA 0x707
#define DC_X_WIN_XD_V_INITIAL_DDA 0x708
#define DC_X_WIN_XD_DDA_INCREMENT 0x709
#define DC_X_WIN_XD_LINE_STRIDE 0x70A

//The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER).
#define DC_X_WINBUF_XD_START_ADDR 0x800
#define DC_X_WINBUF_XD_ADDR_H_OFFSET 0x806
#define DC_X_WINBUF_XD_ADDR_V_OFFSET 0x808
#define DC_X_WINBUF_XD_SURFACE_KIND 0x80B

/*! Display serial interface registers. */
#define _DSIREG(reg) ((reg) * 4)
#define DSI_DSI_RD_DATA 0x9
#define DSI_DSI_WR_DATA 0xA
#define DSI_DSI_POWER_CONTROL 0xB
#define DSI_HOST_DSI_CONTROL 0xF
#define DSI_DSI_TRIGGER 0x13
#define DSI_DSI_BTA_TIMING 0x3F
#define DSI_PAD_CONTROL 0x4B
#define DSI_DSI_VID_MODE_CONTROL 0x4E

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();

#endif
Loading

0 comments on commit 6f6683e

Please sign in to comment.