summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/app.lds144
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-jz4740.c104
-rw-r--r--firmware/target/mips/ingenic_jz47xx/boot.lds83
-rw-r--r--firmware/target/mips/ingenic_jz47xx/crt0.S54
-rw-r--r--firmware/target/mips/ingenic_jz47xx/debug-jz4740.c131
-rw-r--r--firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c15
-rw-r--r--firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c353
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h5
10 files changed, 539 insertions, 358 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/app.lds b/firmware/target/mips/ingenic_jz47xx/app.lds
new file mode 100644
index 0000000000..dd539b0d41
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/app.lds
@@ -0,0 +1,144 @@
1#include "config.h"
2#undef mips
3
4OUTPUT_FORMAT("elf32-littlemips")
5OUTPUT_ARCH(MIPS)
6ENTRY(_start)
7STARTUP(target/mips/ingenic_jz47xx/crt0.o)
8
9#ifdef DEBUG
10#define STUBOFFSET 0x10000
11#else
12#define STUBOFFSET 0
13#endif
14
15#define PLUGINSIZE PLUGIN_BUFFER_SIZE
16#define CODECSIZE CODEC_SIZE
17
18#define DRAMSIZE ((MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE)
19
20#define DRAMORIG 0x80004000
21#define IRAMORIG 0x80000000
22#define IRAMSIZE (16K-0x220)
23
24/* End of the audio buffer, where the codec buffer starts */
25#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
26
27/* Where the codec buffer ends, and the plugin buffer starts */
28#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
29
30MEMORY
31{
32 DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
33 IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
34}
35
36SECTIONS
37{
38 . = DRAMORIG;
39
40 .text :
41 {
42 loadaddress = .;
43 *(.init.text);
44 *(.text*);
45 } > DRAM
46
47 . = ALIGN(4);
48
49 .rodata :
50 {
51 *(.rodata); /* problems without this, dunno why */
52 *(.rodata*);
53 *(.rodata.str1.1);
54 *(.rodata.str1.4);
55 } > DRAM
56
57 . = ALIGN(4);
58
59 .data :
60 {
61 *(.data*);
62 *(.sdata*);
63 *(.rel.dyn);
64 } > DRAM
65
66 . = ALIGN(4);
67
68 .stack (NOLOAD):
69 {
70 *(.stack);
71 stackbegin = .;
72 . += 0x2000;
73 stackend = .;
74 } > DRAM
75
76 . = ALIGN(4);
77
78 .iram IRAMORIG:
79 {
80 _iramstart = .;
81 *(.vectors.1);
82 . = 0x100;
83 *(.vectors.2);
84 . = 0x180;
85 *(.vectors.3);
86 . = 0x200;
87 *(.vectors.4);
88 *(.vectors);
89
90 *(.icode);
91 *(.irodata);
92 *(.idata);
93 KEEP(*(.vectors))
94 *(.vectors);
95 _iramend = .;
96 } > IRAM AT> DRAM
97 _iramcopy = LOADADDR(.iram);
98
99 . = ALIGN(4);
100
101 .bss (NOLOAD):
102 {
103 _edata = .;
104 *(.sbss*);
105 *(.bss*);
106 *(COMMON);
107 *(.scommon*);
108 _end = .;
109 } > DRAM
110
111 . = ALIGN(4);
112
113 .ibss (NOLOAD) :
114 {
115 _iedata = .;
116 *(.ibss*);
117 _iend = .;
118 } > IRAM
119
120 .audiobuf ALIGN(4) :
121 {
122 audiobuffer = .;
123 } > DRAM
124
125 .audiobufend ENDAUDIOADDR:
126 {
127 audiobufend = .;
128 } > DRAM
129
130 .codec ENDAUDIOADDR:
131 {
132 codecbuf = .;
133 }
134
135 .plugin ENDADDR:
136 {
137 pluginbuf = .;
138 }
139
140 /DISCARD/ :
141 {
142 *(.eh_frame);
143 }
144}
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-jz4740.c
deleted file mode 100644
index 4c177d8ded..0000000000
--- a/firmware/target/mips/ingenic_jz47xx/ata-jz4740.c
+++ /dev/null
@@ -1,104 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Maurus Cuelenaere
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "ata.h"
24#include "ata-sd-target.h"
25#include "ata-nand-target.h"
26#include "panic.h"
27
28int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf)
29{
30 switch(drive)
31 {
32 case 0:
33 return nand_read_sectors(start, count, buf);
34 case 1:
35 return _sd_read_sectors(start, count, buf);
36 default:
37 panicf("ata_read_sectors: Drive %d unhandled!", drive);
38 return -1;
39 }
40}
41
42int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf)
43{
44 switch(drive)
45 {
46 case 0:
47 return nand_write_sectors(start, count, buf);
48 case 1:
49 return _sd_write_sectors(start, count, buf);
50 default:
51 panicf("ata_write_sectors: Drive %d unhandled!", drive);
52 return -1;
53 }
54}
55
56int ata_init(void)
57{
58 if(_sd_init() != 0)
59 return -1;
60 if(nand_init() != 0)
61 return -2;
62
63 return 0;
64}
65
66void ata_spindown(int seconds)
67{
68 /* null */
69 (void)seconds;
70}
71
72bool ata_disk_is_active(void)
73{
74 /* null */
75 return false;
76}
77
78void ata_sleep(void)
79{
80 /* null */
81}
82
83void ata_spin(void)
84{
85 /* null */
86}
87
88int ata_hard_reset(void)
89{
90 /* null */
91 return 0;
92}
93
94int ata_soft_reset(void)
95{
96 /* null */
97 return 0;
98}
99
100void ata_enable(bool on)
101{
102 /* null - flash controller is enabled/disabled as needed. */
103 (void)on;
104}
diff --git a/firmware/target/mips/ingenic_jz47xx/boot.lds b/firmware/target/mips/ingenic_jz47xx/boot.lds
index b6f3e169fb..40fd29cdd9 100644
--- a/firmware/target/mips/ingenic_jz47xx/boot.lds
+++ b/firmware/target/mips/ingenic_jz47xx/boot.lds
@@ -6,9 +6,9 @@ OUTPUT_ARCH(MIPS)
6ENTRY(_start) 6ENTRY(_start)
7STARTUP(target/mips/ingenic_jz47xx/crt0.o) 7STARTUP(target/mips/ingenic_jz47xx/crt0.o)
8 8
9#define DRAMSIZE (MEMORYSIZE * 0x100000) 9#define DRAMSIZE ((MEMORYSIZE-4) * 0x100000)
10 10
11#define DRAMORIG 0x80004000 11#define DRAMORIG 0x80404000
12#define IRAMORIG 0x80000000 12#define IRAMORIG 0x80000000
13#define IRAMSIZE 16K 13#define IRAMSIZE 16K
14 14
@@ -24,20 +24,9 @@ SECTIONS
24 24
25 .text : 25 .text :
26 { 26 {
27 loadaddress = .;
28 _loadaddress = .; 27 _loadaddress = .;
29 *(.init.text); 28 *(.init.text);
30 *(.text*); 29 *(.text*);
31 *(.glue_7);
32 *(.glue_7t);
33 *(.rel.dyn);
34 } > DRAM
35
36 .vectors :
37 {
38 _vectorsstart = .;
39 KEEP(*(.vectors))
40 *(.vectors);
41 } > DRAM 30 } > DRAM
42 31
43 . = ALIGN(4); 32 . = ALIGN(4);
@@ -48,71 +37,67 @@ SECTIONS
48 *(.rodata*); 37 *(.rodata*);
49 *(.rodata.str1.1); 38 *(.rodata.str1.1);
50 *(.rodata.str1.4); 39 *(.rodata.str1.4);
51 . = ALIGN(0x4);
52
53 /* Pseudo-allocate the copies of the data sections */
54 _datacopy = .;
55 } > DRAM 40 } > DRAM
41
42 . = ALIGN(4);
56 43
57 .data : 44 .data :
58 { 45 {
59 *(.icode);
60 *(.irodata);
61 *(.idata);
62 *(.data*); 46 *(.data*);
63 *(.sdata*); 47 *(.sdata*);
64 . = ALIGN(0x4); 48 *(.rel.dyn);
65 _dataend = . ;
66 } > DRAM 49 } > DRAM
67 50
68 _gp = ALIGN(16); 51 . = ALIGN(4);
69 .got : 52
53 .iram IRAMORIG:
70 { 54 {
71 *(.got*) 55 _iramstart = .;
72 } > DRAM 56 *(.vectors.1);
57 . = 0x100;
58 *(.vectors.2);
59 . = 0x180;
60 *(.vectors.3);
61 . = 0x200;
62 *(.vectors.4);
63 *(.vectors);
64
65 *(.icode);
66 *(.irodata);
67 *(.idata);
68 KEEP(*(.vectors*))
69 _iramend = .;
70 } > IRAM AT> DRAM
71 _iramcopy = LOADADDR(.iram);
73 72
74 . = ALIGN(4); 73 . = ALIGN(4);
75 74
76 .bss : 75 .bss (NOLOAD):
77 { 76 {
78 _edata = .; 77 _edata = .;
79 *(.sbss*); 78 *(.sbss*);
80 *(.bss*); 79 *(.bss*);
81 *(.ibss); 80 *(COMMON);
82 *(COMMON)
83 *(.scommon*); 81 *(.scommon*);
84 _end = .; 82 _end = .;
85 } > DRAM 83 } > DRAM
86 84
87 .iram IRAMORIG: 85 _bootend = .;
88 { 86
89 . = 0x220; /* Vectors take in 0x80000000 -> 0x80000220 */
90 _iramstart = .;
91 *(.icode)
92 *(.irodata)
93 *(.idata)
94 . = ALIGN(0x4);
95 _iramend = .;
96 } > IRAM AT> DRAM
97
98 _iramcopy = LOADADDR(.iram);
99
100 .ibss (NOLOAD) : 87 .ibss (NOLOAD) :
101 { 88 {
102 _iedata = .; 89 _iedata = .;
103 *(.ibss) 90 *(.ibss*)
104 . = ALIGN(0x4);
105 _iend = .; 91 _iend = .;
106 } > IRAM 92 } > IRAM
107 93
108 .stack : 94 . = ALIGN(4);
95
96 .stack (NOLOAD):
109 { 97 {
110 *(.stack) 98 *(.stack)
111 . = ALIGN(0x4);
112 _stackbegin = .;
113 stackbegin = .; 99 stackbegin = .;
114 . += 0x2000; 100 . += 0x2000;
115 _stackend = .;
116 stackend = .; 101 stackend = .;
117 } > IRAM 102 } > IRAM
118} 103}
diff --git a/firmware/target/mips/ingenic_jz47xx/crt0.S b/firmware/target/mips/ingenic_jz47xx/crt0.S
index 5cfd49141a..e619022fc8 100644
--- a/firmware/target/mips/ingenic_jz47xx/crt0.S
+++ b/firmware/target/mips/ingenic_jz47xx/crt0.S
@@ -52,6 +52,17 @@
52#ifdef BOOTLOADER 52#ifdef BOOTLOADER
53 .word 0 /* Unknown */ 53 .word 0 /* Unknown */
54 .word 0 /* Filesize */ 54 .word 0 /* Filesize */
55
56 /* Relocate bootloader */
57 la t0, (_loadaddress-0x400000)
58 la t1, _loadaddress
59 la t2, _bootend
60_relocate_loop:
61 lw t3, 0(t0)
62 sw t3, 0(t1)
63 addiu t1, 4
64 bne t1, t2, _relocate_loop
65 addiu t0, 4
55#endif 66#endif
56 67
57_start: 68_start:
@@ -119,7 +130,6 @@ _init_bss_loop:
119 bne t0, t1, _init_bss_loop 130 bne t0, t1, _init_bss_loop
120 addiu t0, 4 131 addiu t0, 4
121 132
122#ifndef BOOTLOADER
123 /* 133 /*
124 ---------------------------------------------------- 134 ----------------------------------------------------
125 clear IBSS section 135 clear IBSS section
@@ -146,7 +156,6 @@ _init_iram_loop:
146 addiu t1, 4 156 addiu t1, 4
147 bne t1, t2, _init_iram_loop 157 bne t1, t2, _init_iram_loop
148 addiu t0, 4 158 addiu t0, 4
149#endif
150 159
151 /* 160 /*
152 ---------------------------------------------------- 161 ----------------------------------------------------
@@ -167,23 +176,35 @@ _init_stack_loop:
167 nop 176 nop
168 177
169 178
170 .section .vectors, "ax", %progbits 179 /*
171 .extern real_exception_handler 180 * 0x0 - Simple TLB refill handler
172 .global except_common_entry 181 * 0x100 - Cache error handler
173 .type except_common_entry,@function 182 * 0x180 - Exception/Interrupt handler
174except_common_entry: 183 * 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE)
184 */
185
186
187 .section .vectors.1, "ax", %progbits
188 la k0, tlb_refill_handler
189 jr k0
190 nop
191
192 .section .vectors.2, "ax", %progbits
175 la k0, real_exception_handler 193 la k0, real_exception_handler
176 jr k0 194 jr k0
177 nop 195 nop
196
197 .section .vectors.3, "ax", %progbits
198 la k0, real_exception_handler
199 jr k0
178 nop 200 nop
179 nop
180 .fill 0x20
181 201
182 .extern _int 202 .section .vectors.4, "ax", %progbits
183 .extern _exception 203 la k0, real_exception_handler
184 .global real_exception_handler 204 jr k0
185 .type real_exception_handler,@function 205 nop
186 .set noreorder 206
207 .section .vectors, "ax", %progbits
187real_exception_handler: 208real_exception_handler:
188 addiu sp, -0x80 209 addiu sp, -0x80
189 sw ra, 0(sp) 210 sw ra, 0(sp)
@@ -241,8 +262,6 @@ real_exception_handler:
241 j _exception 262 j _exception
242 nop 263 nop
243 264
244 .global _int
245 .type _int,@function
246_int: 265_int:
247 jal intr_handler 266 jal intr_handler
248 nop 267 nop
@@ -298,9 +317,6 @@ _int:
298 eret # Exception Return 317 eret # Exception Return
299 nop 318 nop
300 319
301 .extern _exception_handler
302 .global _exception
303 .type _exception,@function
304_exception: 320_exception:
305 add a0, sp, $0 321 add a0, sp, $0
306 mfc0 a1, C0_CAUSE # C0_CAUSE of last exception 322 mfc0 a1, C0_CAUSE # C0_CAUSE of last exception
diff --git a/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c b/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c
new file mode 100644
index 0000000000..648d410cd6
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/debug-jz4740.c
@@ -0,0 +1,131 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Maurus Cuelenaere
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "jz4740.h"
24
25/*
26 * Clock Generation Module
27 */
28#define TO_MHZ(x) ((x)/1000000), ((x)%1000000)/10000
29#define TO_KHZ(x) ((x)/1000), ((x)%1000)/10
30
31static void display_clocks(void)
32{
33 unsigned int cppcr = REG_CPM_CPPCR; /* PLL Control Register */
34 unsigned int cpccr = REG_CPM_CPCCR; /* Clock Control Register */
35 unsigned int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
36 unsigned int od[4] = {1, 2, 2, 4};
37
38 printf("CPPCR : 0x%08x", cppcr);
39 printf("CPCCR : 0x%08x", cpccr);
40 printf("PLL : %s", (cppcr & CPM_CPPCR_PLLEN) ? "ON" : "OFF");
41 printf("m:n:o : %d:%d:%d",
42 __cpm_get_pllm() + 2,
43 __cpm_get_plln() + 2,
44 od[__cpm_get_pllod()]
45 );
46 printf("C:H:M:P : %d:%d:%d:%d",
47 div[__cpm_get_cdiv()],
48 div[__cpm_get_hdiv()],
49 div[__cpm_get_mdiv()],
50 div[__cpm_get_pdiv()]
51 );
52 printf("U:L:I:P:M : %d:%d:%d:%d:%d",
53 __cpm_get_udiv() + 1,
54 __cpm_get_ldiv() + 1,
55 __cpm_get_i2sdiv()+1,
56 __cpm_get_pixdiv()+1,
57 __cpm_get_mscdiv()+1
58 );
59 printf("PLL Freq: %3d.%02d MHz", TO_MHZ(__cpm_get_pllout()));
60 printf("CCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_cclk()));
61 printf("HCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_hclk()));
62 printf("MCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_mclk()));
63 printf("PCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_pclk()));
64 printf("LCDCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_lcdclk()));
65 printf("PIXCLK : %6d.%02d KHz", TO_KHZ(__cpm_get_pixclk()));
66 printf("I2SCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_i2sclk()));
67 printf("USBCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_usbclk()));
68 printf("MSCCLK : %3d.%02d MHz", TO_MHZ(__cpm_get_mscclk()));
69 printf("EXTALCLK: %3d.%02d MHz", TO_MHZ(__cpm_get_extalclk()));
70 printf("RTCCLK : %3d.%02d KHz", TO_KHZ(__cpm_get_rtcclk()));
71}
72
73static void display_enabled_clocks(void)
74{
75 unsigned long lcr = REG_CPM_LCR;
76 unsigned long clkgr = REG_CPM_CLKGR;
77
78 printf("Low Power Mode : %s",
79 ((lcr & CPM_LCR_LPM_MASK) == CPM_LCR_LPM_IDLE) ?
80 "IDLE" : (((lcr & CPM_LCR_LPM_MASK) == CPM_LCR_LPM_SLEEP) ? "SLEEP" : "HIBERNATE")
81 );
82
83 printf("Doze Mode : %s",
84 (lcr & CPM_LCR_DOZE_ON) ? "ON" : "OFF");
85 if (lcr & CPM_LCR_DOZE_ON)
86 printf(" duty : %d", (int)((lcr & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT));
87
88 printf("IPU : %s",
89 (clkgr & CPM_CLKGR_IPU) ? "stopped" : "running");
90 printf("DMAC : %s",
91 (clkgr & CPM_CLKGR_DMAC) ? "stopped" : "running");
92 printf("UHC : %s",
93 (clkgr & CPM_CLKGR_UHC) ? "stopped" : "running");
94 printf("UDC : %s",
95 (clkgr & CPM_CLKGR_UDC) ? "stopped" : "running");
96 printf("LCD : %s",
97 (clkgr & CPM_CLKGR_LCD) ? "stopped" : "running");
98 printf("CIM : %s",
99 (clkgr & CPM_CLKGR_CIM) ? "stopped" : "running");
100 printf("SADC : %s",
101 (clkgr & CPM_CLKGR_SADC) ? "stopped" : "running");
102 printf("MSC : %s",
103 (clkgr & CPM_CLKGR_MSC) ? "stopped" : "running");
104 printf("AIC1 : %s",
105 (clkgr & CPM_CLKGR_AIC1) ? "stopped" : "running");
106 printf("AIC2 : %s",
107 (clkgr & CPM_CLKGR_AIC2) ? "stopped" : "running");
108 printf("SSI : %s",
109 (clkgr & CPM_CLKGR_SSI) ? "stopped" : "running");
110 printf("I2C : %s",
111 (clkgr & CPM_CLKGR_I2C) ? "stopped" : "running");
112 printf("RTC : %s",
113 (clkgr & CPM_CLKGR_RTC) ? "stopped" : "running");
114 printf("TCU : %s",
115 (clkgr & CPM_CLKGR_TCU) ? "stopped" : "running");
116 printf("UART1 : %s",
117 (clkgr & CPM_CLKGR_UART1) ? "stopped" : "running");
118 printf("UART0 : %s",
119 (clkgr & CPM_CLKGR_UART0) ? "stopped" : "running");
120}
121
122bool __dbg_ports(void)
123{
124 return false;
125}
126
127bool __dbg_hw_info(void)
128{
129 return false;
130}
131
diff --git a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c
index 1fbf1fc19e..456542064c 100644
--- a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c
@@ -238,3 +238,7 @@ W_timeout:
238 __i2c_send_stop(); 238 __i2c_send_stop();
239 return -1; 239 return -1;
240} 240}
241
242void i2c_init(void)
243{
244}
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
index 317da8413e..071adbd63e 100644
--- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
@@ -69,6 +69,7 @@ bool lcd_enabled(void)
69/* Update a fraction of the display. */ 69/* Update a fraction of the display. */
70void lcd_update_rect(int x, int y, int width, int height) 70void lcd_update_rect(int x, int y, int width, int height)
71{ 71{
72x=0;y=0;width=LCD_WIDTH;height=LCD_HEIGHT;
72 mutex_lock(&lcd_mtx); 73 mutex_lock(&lcd_mtx);
73 74
74 __cpm_start_lcd(); 75 __cpm_start_lcd();
@@ -135,3 +136,17 @@ void lcd_update(void)
135 136
136 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 137 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
137} 138}
139
140void lcd_blit_yuv(unsigned char * const src[3],
141 int src_x, int src_y, int stride,
142 int x, int y, int width, int height)
143{
144 (void)src;
145 (void)src_x;
146 (void)src_y;
147 (void)stride;
148 (void)x;
149 (void)y;
150 (void)width;
151 (void)height;
152}
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
index c97ef13533..1ed36cd312 100644
--- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
@@ -142,6 +142,10 @@ void pcm_play_dma_pause(bool pause)
142 play_start_pcm(); 142 play_start_pcm();
143} 143}
144 144
145void audiohw_close(void)
146{
147}
148
145#ifdef HAVE_RECORDING 149#ifdef HAVE_RECORDING
146/* TODO */ 150/* TODO */
147void pcm_rec_dma_init(void) 151void pcm_rec_dma_init(void)
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index 052ea64495..c0f39a4933 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -397,7 +397,7 @@ void mdelay(unsigned int msec)
397} 397}
398 398
399/* Core-level interrupt masking */ 399/* Core-level interrupt masking */
400void cli(void) 400void clear_interrupts(void)
401{ 401{
402 register unsigned int t; 402 register unsigned int t;
403 t = read_c0_status(); 403 t = read_c0_status();
@@ -410,7 +410,7 @@ unsigned int mips_get_sr(void)
410 return read_c0_status(); 410 return read_c0_status();
411} 411}
412 412
413void sti(void) 413void store_interrupts(void)
414{ 414{
415 register unsigned int t; 415 register unsigned int t;
416 t = read_c0_status(); 416 t = read_c0_status();
@@ -525,13 +525,6 @@ void tlb_refill_handler(void)
525 panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr()); 525 panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr());
526} 526}
527 527
528static void tlb_call_refill(void)
529{
530 asm("la $8, tlb_refill_handler \n"
531 "jr $8 \n"
532 );
533}
534
535static int dma_count = 0; 528static int dma_count = 0;
536void dma_enable(void) 529void dma_enable(void)
537{ 530{
@@ -559,191 +552,178 @@ void dma_disable(void)
559 } 552 }
560} 553}
561 554
562static inline void pll_convert(unsigned int pllin, unsigned int *pll_cfcr, unsigned int *pll_plcr1) 555/* PLL output clock = EXTAL * NF / (NR * NO)
556 *
557 * NF = FD + 2, NR = RD + 2
558 * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
559 */
560static void pll_init(void) ICODE_ATTR;
561static void pll_init(void)
563{ 562{
564 register unsigned int cfcr, plcr1; 563 register unsigned int cfcr, plcr1;
564 int n2FR[33] = {
565 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
566 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
567 9
568 };
565 int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ 569 int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
566 int nf; 570 int nf, pllout2;
571
572 cfcr = CPM_CPCCR_CLKOEN |
573 CPM_CPCCR_PCS |
574 (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
575 (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
576 (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
577 (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
578 (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT) |
579 CPM_CPCCR_CE; /* Perform clock divisions immediately */
567 580
568 cfcr = CPM_CPCCR_CLKOEN | 581 pllout2 = (cfcr & CPM_CPCCR_PCS) ? CPU_FREQ : (CPU_FREQ / 2);
569 (div[0] << CPM_CPCCR_CDIV_BIT) |
570 (div[1] << CPM_CPCCR_HDIV_BIT) |
571 (div[2] << CPM_CPCCR_PDIV_BIT) |
572 (div[3] << CPM_CPCCR_MDIV_BIT) |
573 (div[4] << CPM_CPCCR_LDIV_BIT);
574 582
575 //nf = pllin * 2 / CFG_EXTAL; 583 /* Init USB Host clock, pllout2 must be n*48MHz */
576 nf = pllin * 2 / 375299969; 584 REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
585
586 nf = CPU_FREQ * 2 / CFG_EXTAL;
577 plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ 587 plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
578 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ 588 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
579 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ 589 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
580 (0xa << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ 590 (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
581 CPM_CPPCR_PLLEN; /* enable PLL */ 591 CPM_CPPCR_PLLEN; /* enable PLL */
582 592
583 /* init PLL */ 593 /* init PLL */
584 *pll_cfcr = cfcr; 594 REG_CPM_CPCCR = cfcr;
585 *pll_plcr1 = plcr1; 595 REG_CPM_CPPCR = plcr1;
586} 596}
587 597
588static inline void sdram_convert(unsigned int pllin, unsigned int *sdram_freq) 598// SDRAM paramters
589{ 599#define CFG_SDRAM_BW16 0 /* Data bus width: 0-32bit, 1-16bit */
590 register unsigned int ns, tmp; 600#define CFG_SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
591 601#define CFG_SDRAM_ROW 12 /* Row address: 11 to 13 */
592 ns = 1000000000 / pllin; 602#define CFG_SDRAM_COL 8 /* Column address: 8 to 12 */
593 tmp = 15625 / ns; 603#define CFG_SDRAM_CASL 2 /* CAS latency: 2 or 3 */
594 604
595 /* Set refresh registers */ 605// SDRAM Timings, unit: ns
606#define CFG_SDRAM_TRAS 45 /* RAS# Active Time */
607#define CFG_SDRAM_RCD 20 /* RAS# to CAS# Delay */
608#define CFG_SDRAM_TPC 20 /* RAS# Precharge Time */
609#define CFG_SDRAM_TRWL 7 /* Write Latency Time */
610#define CFG_SDRAM_TREF 7812 /* Refresh period: 8192 refresh cycles/64ms */
611
612/*
613 * Init SDRAM memory.
614 */
615static void sdram_init(void) ICODE_ATTR;
616static void sdram_init(void)
617{
618 register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
619
620 unsigned int cas_latency_sdmr[2] = {
621 EMC_SDMR_CAS_2,
622 EMC_SDMR_CAS_3,
623 };
624
625 unsigned int cas_latency_dmcr[2] = {
626 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
627 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
628 };
629
630 int div[] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 };
631
632 cpu_clk = CPU_FREQ;
633 mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
634
635 //REG_EMC_BCR = 0; /* Disable bus release */
636 REG_EMC_RTCSR = 0; /* Disable clock for counting */
637 REG_EMC_RTCOR = 0;
638 REG_EMC_RTCNT = 0;
639
640 /* Fault DMCR value for mode register setting */
641#define SDRAM_ROW0 11
642#define SDRAM_COL0 8
643#define SDRAM_BANK40 0
644
645 dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) |
646 ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) |
647 (SDRAM_BANK40 << EMC_DMCR_BA_BIT) |
648 (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) |
649 EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
650
651 /* Basic DMCR value */
652 dmcr = ((CFG_SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) |
653 ((CFG_SDRAM_COL - 8) << EMC_DMCR_CA_BIT) |
654 (CFG_SDRAM_BANK4 << EMC_DMCR_BA_BIT) |
655 (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) |
656 EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
657
658 /* SDRAM timimg */
659 ns = 1000000000 / mem_clk;
660 tmp = CFG_SDRAM_TRAS / ns;
661 if (tmp < 4)
662 tmp = 4;
663 if (tmp > 11)
664 tmp = 11;
665 dmcr |= ((tmp - 4) << EMC_DMCR_TRAS_BIT);
666 tmp = CFG_SDRAM_RCD / ns;
667 if (tmp > 3)
668 tmp = 3;
669 dmcr |= (tmp << EMC_DMCR_RCD_BIT);
670 tmp = CFG_SDRAM_TPC / ns;
671 if (tmp > 7)
672 tmp = 7;
673 dmcr |= (tmp << EMC_DMCR_TPC_BIT);
674 tmp = CFG_SDRAM_TRWL / ns;
675 if (tmp > 3)
676 tmp = 3;
677 dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
678 tmp = (CFG_SDRAM_TRAS + CFG_SDRAM_TPC) / ns;
679 if (tmp > 14)
680 tmp = 14;
681 dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
682
683 /* SDRAM mode value */
684 sdmode = EMC_SDMR_BT_SEQ |
685 EMC_SDMR_OM_NORMAL |
686 EMC_SDMR_BL_4 | cas_latency_sdmr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
687
688 /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
689 REG_EMC_DMCR = dmcr;
690 REG8(EMC_SDMR0 | sdmode) = 0;
691
692 /* Wait for precharge, > 200us */
693 tmp = (cpu_clk / 1000000) * 1000;
694 while (tmp--);
695
696 /* Stage 2. Enable auto-refresh */
697 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
698
699 tmp = CFG_SDRAM_TREF / ns;
596 tmp = tmp / 64 + 1; 700 tmp = tmp / 64 + 1;
597 701 if (tmp > 0xff)
598 if(tmp > 0xff)
599 tmp = 0xff; 702 tmp = 0xff;
600 703 REG_EMC_RTCOR = tmp;
601 *sdram_freq = tmp; 704 REG_EMC_RTCNT = 0;
602} 705 REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
603 706
604static inline void set_cpu_freq(unsigned int pllin, unsigned int div) 707 /* Wait for number of auto-refresh cycles */
605{ 708 tmp = (cpu_clk / 1000000) * 1000;
606 unsigned int sdram_freq; 709 while (tmp--);
607 unsigned int pll_cfcr, pll_plcr1;
608 int div_preq[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
609
610 if(pllin < 25000000 || pllin > 420000000)
611 panicf("PLL should be >25000000 and <420000000 !");
612
613 unsigned long t = read_c0_status();
614 write_c0_status(t & ~1);
615
616 pll_convert(pllin, &pll_cfcr, &pll_plcr1);
617 710
618 sdram_convert(pllin / div_preq[div], &sdram_freq); 711 /* Stage 3. Mode Register Set */
619 712 REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
620 REG_CPM_CPCCR &= ~CPM_CPCCR_CE; 713 REG8(EMC_SDMR0 | sdmode) = 0;
621
622 REG_CPM_CPCCR = pll_cfcr;
623 REG_CPM_CPPCR = pll_plcr1;
624
625 REG_EMC_RTCOR = sdram_freq;
626 REG_EMC_RTCNT = sdram_freq;
627
628 REG_CPM_CPCCR |= CPM_CPCCR_CE;
629
630 detect_clock();
631
632 write_c0_status(t);
633}
634 714
635static void OF_init_clocks(void) 715 /* Set back to basic DMCR value */
636{ 716 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
637 unsigned long t = read_c0_status();
638 write_c0_status(t & ~1);
639
640 unsigned int prog_entry = ((unsigned int)OF_init_clocks >> 5) << 5;
641 unsigned int i, prog_size = 1024;
642
643 for(i = prog_entry; i < prog_entry + prog_size; i += 32)
644 __asm__ __volatile__("cache 0x1c, 0x00(%0) \n"
645 :
646 : "r" (i)
647 );
648
649 /* disable PLL clock */
650 REG_CPM_CPPCR &= ~CPM_CPPCR_PLLEN;
651 REG_CPM_CPCCR |= CPM_CPCCR_CE;
652
653 unsigned long old_clocks = REG_CPM_CLKGR;
654 /*
655 REG_CPM_CLKGR = ~( CPM_CLKGR_UART0 | CPM_CLKGR_TCU |
656 CPM_CLKGR_RTC | CPM_CLKGR_SADC |
657 CPM_CLKGR_LCD );
658 */
659
660 unsigned long old_scr = REG_CPM_SCR;
661 REG_CPM_SCR &= ~CPM_SCR_OSC_ENABLE; /* O1SE: 12M oscillator is disabled in Sleep mode */
662
663 REG_EMC_DMCR |= (EMC_DMCR_RMODE | EMC_DMCR_RFSH); /* self refresh + refresh is performed */
664 REG_EMC_DMCR = (REG_EMC_DMCR & ~EMC_DMCR_RMODE) | 1; /* -> RMODE = auto refresh
665 -> CAS mode = 2 cycles */
666 __asm__ __volatile__("wait \n");
667
668 REG_CPM_CLKGR = old_clocks;
669 REG_CPM_SCR = old_scr;
670
671 for(i=0; i<90; i++);
672
673 set_cpu_freq(336000000, 1);
674
675 for(i=0; i<60; i++);
676
677 write_c0_status(t);
678}
679 717
680static void my_init_clocks(void) 718 /* everything is ok now */
681{
682 unsigned long t = read_c0_status();
683 write_c0_status(t & ~1);
684
685 unsigned int prog_entry = ((unsigned int)my_init_clocks / 32 - 1) * 32;
686 unsigned int i, prog_size = 1024;
687
688 for(i = prog_entry; i < prog_entry + prog_size; i += 32)
689 __asm__ __volatile__("cache 0x1c, 0x00(%0) \n"
690 :
691 : "r" (i)
692 );
693
694 unsigned int sdram_freq, plcr1, cfcr;
695
696 sdram_convert(336000000/3, &sdram_freq);
697
698 cfcr = CPM_CPCCR_CLKOEN |
699 (6 << CPM_CPCCR_UDIV_BIT) |
700 CPM_CPCCR_UCS |
701 CPM_CPCCR_PCS |
702 (0 << CPM_CPCCR_CDIV_BIT) |
703 (1 << CPM_CPCCR_HDIV_BIT) |
704 (1 << CPM_CPCCR_PDIV_BIT) |
705 (1 << CPM_CPCCR_MDIV_BIT) |
706 (1 << CPM_CPCCR_LDIV_BIT);
707
708 plcr1 = (54 << CPM_CPPCR_PLLM_BIT) | /* FD */
709 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
710 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
711 (0x20 << CPM_CPPCR_PLLST_BIT)| /* PLL stable time */
712 CPM_CPPCR_PLLEN; /* enable PLL */
713
714 REG_CPM_CPCCR &= ~CPM_CPCCR_CE;
715
716 REG_CPM_CPCCR = cfcr;
717 REG_CPM_CPPCR = plcr1;
718
719 REG_EMC_RTCOR = sdram_freq;
720 REG_EMC_RTCNT = sdram_freq;
721
722 REG_CPM_CPCCR |= CPM_CPCCR_CE;
723
724 REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | (11 << CPM_LPCDR_PIXDIV_BIT);
725
726 write_c0_status(t);
727} 719}
728 720
729extern int main(void); 721extern int main(void);
730extern void except_common_entry(void); 722void system_main(void) ICODE_ATTR;
731
732void system_main(void) 723void system_main(void)
733{ 724{
734 int i; 725 int i;
735 726
736 /*
737 * 0x0 - Simple TLB refill handler
738 * 0x100 - Cache error handler
739 * 0x180 - Exception/Interrupt handler
740 * 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE)
741 */
742 memcpy((void *)A_K0BASE, (void *)&tlb_call_refill, 0x20);
743 memcpy((void *)(A_K0BASE + 0x100), (void *)&except_common_entry, 0x20);
744 memcpy((void *)(A_K0BASE + 0x180), (void *)&except_common_entry, 0x20);
745 memcpy((void *)(A_K0BASE + 0x200), (void *)&except_common_entry, 0x20);
746
747 __dcache_writeback_all(); 727 __dcache_writeback_all();
748 __icache_invalidate_all(); 728 __icache_invalidate_all();
749 729
@@ -755,27 +735,22 @@ void system_main(void)
755 735
756 tlb_init(); 736 tlb_init();
757 737
738 //pll_init();
739 //sdram_init();
740
758 detect_clock(); 741 detect_clock();
759 742
760 /* Disable unneeded clocks, clocks are enabled when needed */ 743 /* Disable unneeded clocks, clocks are enabled when needed */
761 __cpm_stop_all(); 744 __cpm_stop_all();
762 __cpm_suspend_usbhost(); 745 __cpm_suspend_usbhost();
763 746
764#if 0
765 my_init_clocks();
766 //OF_init_clocks();
767 /*__cpm_stop_udc();
768 REG_CPM_CPCCR |= CPM_CPCCR_UCS;
769 REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | (3 << CPM_CPCCR_UDIV_BIT);
770 __cpm_start_udc();*/
771#endif
772
773 /* Enable interrupts at core level */ 747 /* Enable interrupts at core level */
774 sti(); 748 store_interrupts();
775 749
776 main(); /* Shouldn't return */ 750 main(); /* Shouldn't return */
777 751
778 while(1); 752 while(1)
753 core_idle();
779} 754}
780 755
781void system_reboot(void) 756void system_reboot(void)
@@ -812,3 +787,13 @@ void power_off(void)
812 787
813 while(1); 788 while(1);
814} 789}
790
791void system_init(void)
792{
793}
794
795int system_memory_guard(int newmode)
796{
797 (void)newmode;
798 return 0;
799}
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index 39782a3222..6b505d6178 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -87,6 +87,7 @@ static inline void restore_interrupt(int status)
87#define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff) 87#define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff)
88 88
89#define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000) 89#define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000)
90#define UNCACHED_ADDR(x) UNCACHED_ADDRESS((x))
90#define PHYSADDR(x) ((x) & 0x1fffffff) 91#define PHYSADDR(x) ((x) & 0x1fffffff)
91 92
92void __dcache_writeback_all(void); 93void __dcache_writeback_all(void);
@@ -95,8 +96,8 @@ void __icache_invalidate_all(void);
95void __flush_dcache_line(unsigned long addr); 96void __flush_dcache_line(unsigned long addr);
96void dma_cache_wback_inv(unsigned long addr, unsigned long size); 97void dma_cache_wback_inv(unsigned long addr, unsigned long size);
97void system_enable_irq(unsigned int irq); 98void system_enable_irq(unsigned int irq);
98void sti(void); 99void store_interrupts(void);
99void cli(void); 100void clear_interrupts(void);
100void udelay(unsigned int usec); 101void udelay(unsigned int usec);
101void mdelay(unsigned int msec); 102void mdelay(unsigned int msec);
102void power_off(void); 103void power_off(void);