aboutsummaryrefslogtreecommitdiffstats
path: root/package/boot/uboot-rockchip/src/of-platdata/nanopi-r2c-rk3328/dt-plat.c
blob: e5b330c9d9756b02fd6e1ff33039da288314c1af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * DO NOT MODIFY
 *
 * Declares the U_BOOT_DRIVER() records and platform data.
 * This was generated by dtoc from a .dtb (device tree binary) file.
 */

/* Allow use of U_BOOT_DRVINFO() in this file */
#define DT_PLAT_C

#include <common.h>
#include <dm.h>
#include <dt-structs.h>

/*
 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
 *
 * idx  driver_info          driver
 * ---  -------------------- --------------------
 *   0: clock_controller_at_ff440000 rockchip_rk3328_cru
 *   1: dmc                  rockchip_rk3328_dmc
 *   2: mmc_at_ff500000      rockchip_rk3288_dw_mshc
 *   3: serial_at_ff130000   ns16550_serial
 *   4: syscon_at_ff100000   rockchip_rk3328_grf
 * ---  -------------------- --------------------
 */

/*
 * Node /clock-controller@ff440000 index 0
 * driver rockchip_rk3328_cru parent None
 */
static struct dtd_rockchip_rk3328_cru dtv_clock_controller_at_ff440000 = {
	.reg			= {0xff440000, 0x1000},
	.rockchip_grf		= 0x3a,
};
U_BOOT_DRVINFO(clock_controller_at_ff440000) = {
	.name		= "rockchip_rk3328_cru",
	.plat		= &dtv_clock_controller_at_ff440000,
	.plat_size	= sizeof(dtv_clock_controller_at_ff440000),
	.parent_idx	= -1,
};

/*
 * Node /dmc index 1
 * driver rockchip_rk3328_dmc parent None
 */
static struct dtd_rockchip_rk3328_dmc dtv_dmc = {
	.reg			= {0xff400000, 0x1000, 0xff780000, 0x3000, 0xff100000, 0x1000, 0xff440000, 0x1000,
		0xff720000, 0x1000, 0xff798000, 0x1000},
	.rockchip_sdram_params	= {0x1, 0xa, 0x2, 0x1, 0x0, 0x0, 0x11, 0x0,
		0x11, 0x0, 0x0, 0x94291288, 0x0, 0x27, 0x462, 0x15,
		0x242, 0xff, 0x14d, 0x0, 0x1, 0x0, 0x0, 0x0,
		0x43049010, 0x64, 0x28003b, 0xd0, 0x20053, 0xd4, 0x220000, 0xd8,
		0x100, 0xdc, 0x40000, 0xe0, 0x0, 0xe4, 0x110000, 0xe8,
		0x420, 0xec, 0x400, 0xf4, 0xf011f, 0x100, 0x9060b06, 0x104,
		0x20209, 0x108, 0x505040a, 0x10c, 0x40400c, 0x110, 0x5030206, 0x114,
		0x3030202, 0x120, 0x3030b03, 0x124, 0x20208, 0x180, 0x1000040, 0x184,
		0x0, 0x190, 0x7030003, 0x198, 0x5001100, 0x1a0, 0xc0400003, 0x240,
		0x6000604, 0x244, 0x201, 0x250, 0xf00, 0x490, 0x1, 0xffffffff,
		0xffffffff, 0xffffffff, 0xffffffff, 0x4, 0xc, 0x28, 0xa, 0x2c,
		0x0, 0x30, 0x9, 0xffffffff, 0xffffffff, 0x77, 0x88, 0x79,
		0x79, 0x87, 0x97, 0x87, 0x78, 0x77, 0x78, 0x87,
		0x88, 0x87, 0x87, 0x77, 0x78, 0x78, 0x78, 0x78,
		0x78, 0x78, 0x78, 0x78, 0x78, 0x69, 0x9, 0x77,
		0x78, 0x77, 0x78, 0x77, 0x78, 0x77, 0x78, 0x77,
		0x79, 0x9, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
		0x78, 0x78, 0x78, 0x69, 0x9, 0x77, 0x78, 0x77,
		0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x79, 0x9,
		0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
		0x78, 0x69, 0x9, 0x77, 0x78, 0x77, 0x78, 0x77,
		0x78, 0x77, 0x78, 0x77, 0x79, 0x9, 0x78, 0x78,
		0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x69,
		0x9, 0x77, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77,
		0x77, 0x77, 0x79, 0x9},
};
U_BOOT_DRVINFO(dmc) = {
	.name		= "rockchip_rk3328_dmc",
	.plat		= &dtv_dmc,
	.plat_size	= sizeof(dtv_dmc),
	.parent_idx	= -1,
};

/*
 * Node /mmc@ff500000 index 2
 * driver rockchip_rk3288_dw_mshc parent None
 */
static struct dtd_rockchip_rk3288_dw_mshc dtv_mmc_at_ff500000 = {
	.bus_width		= 0x4,
	.cap_sd_highspeed	= true,
	.clocks			= {
			{0, {317}},
			{0, {33}},
			{0, {74}},
			{0, {78}},},
	.disable_wp		= true,
	.fifo_depth		= 0x100,
	.interrupts		= {0x0, 0xc, 0x4},
	.max_frequency		= 0x8f0d180,
	.pinctrl_0		= {0x47, 0x48, 0x49, 0x4a},
	.pinctrl_names		= "default",
	.reg			= {0xff500000, 0x4000},
	.sd_uhs_sdr104		= true,
	.sd_uhs_sdr12		= true,
	.sd_uhs_sdr25		= true,
	.sd_uhs_sdr50		= true,
	.u_boot_spl_fifo_mode	= true,
	.vmmc_supply		= 0x4b,
	.vqmmc_supply		= 0x1e,
};
U_BOOT_DRVINFO(mmc_at_ff500000) = {
	.name		= "rockchip_rk3288_dw_mshc",
	.plat		= &dtv_mmc_at_ff500000,
	.plat_size	= sizeof(dtv_mmc_at_ff500000),
	.parent_idx	= -1,
};

/*
 * Node /serial@ff130000 index 3
 * driver ns16550_serial parent None
 */
static struct dtd_ns16550_serial dtv_serial_at_ff130000 = {
	.clock_frequency	= 0x16e3600,
	.clocks			= {
			{0, {40}},
			{0, {212}},},
	.dma_names		= {"tx", "rx"},
	.dmas			= {0x10, 0x6, 0x10, 0x7},
	.interrupts		= {0x0, 0x39, 0x4},
	.pinctrl_0		= 0x26,
	.pinctrl_names		= "default",
	.reg			= {0xff130000, 0x100},
	.reg_io_width		= 0x4,
	.reg_shift		= 0x2,
};
U_BOOT_DRVINFO(serial_at_ff130000) = {
	.name		= "ns16550_serial",
	.plat		= &dtv_serial_at_ff130000,
	.plat_size	= sizeof(dtv_serial_at_ff130000),
	.parent_idx	= -1,
};

/*
 * Node /syscon@ff100000 index 4
 * driver rockchip_rk3328_grf parent None
 */
static struct dtd_rockchip_rk3328_grf dtv_syscon_at_ff100000 = {
	.reg			= {0xff100000, 0x1000},
};
U_BOOT_DRVINFO(syscon_at_ff100000) = {
	.name		= "rockchip_rk3328_grf",
	.plat		= &dtv_syscon_at_ff100000,
	.plat_size	= sizeof(dtv_syscon_at_ff100000),
	.parent_idx	= -1,
};
an> ( v = RDWR_MPT_VIRT_START; v != RDWR_MPT_VIRT_END; v += 1 << L2_PAGETABLE_SHIFT ) { l3e = l4e_to_l3e(idle_pg_table[l4_table_offset(v)])[ l3_table_offset(v)]; if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) continue; l2e = l3e_to_l2e(l3e)[l2_table_offset(v)]; if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) continue; m2p_start_mfn = l2e_get_pfn(l2e); for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) { struct page_info *page = mfn_to_page(m2p_start_mfn + i); share_xen_page_with_privileged_guests(page, XENSHARE_readonly); } } } long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) { struct xen_machphys_mfn_list xmml; l3_pgentry_t l3e; l2_pgentry_t l2e; unsigned long mfn, v; unsigned int i; long rc = 0; switch ( op ) { case XENMEM_machphys_mfn_list: if ( copy_from_guest(&xmml, arg, 1) ) return -EFAULT; for ( i = 0, v = RDWR_MPT_VIRT_START; (i != xmml.max_extents) && (v != RDWR_MPT_VIRT_END); i++, v += 1 << 21 ) { l3e = l4e_to_l3e(idle_pg_table[l4_table_offset(v)])[ l3_table_offset(v)]; if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) break; l2e = l3e_to_l2e(l3e)[l2_table_offset(v)]; if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) break; mfn = l2e_get_pfn(l2e) + l1_table_offset(v); if ( copy_to_guest_offset(xmml.extent_start, i, &mfn, 1) ) return -EFAULT; } xmml.nr_extents = i; if ( copy_to_guest(arg, &xmml, 1) ) return -EFAULT; break; default: rc = -ENOSYS; break; } return rc; } long do_stack_switch(unsigned long ss, unsigned long esp) { fixup_guest_stack_selector(ss); current->arch.guest_context.kernel_ss = ss; current->arch.guest_context.kernel_sp = esp; return 0; } long do_set_segment_base(unsigned int which, unsigned long base) { struct vcpu *v = current; long ret = 0; switch ( which ) { case SEGBASE_FS: if ( wrmsr_safe(MSR_FS_BASE, base, base>>32) ) ret = -EFAULT; else v->arch.guest_context.fs_base = base; break; case SEGBASE_GS_USER: if ( wrmsr_safe(MSR_SHADOW_GS_BASE, base, base>>32) ) ret = -EFAULT; else v->arch.guest_context.gs_base_user = base; break; case SEGBASE_GS_KERNEL: if ( wrmsr_safe(MSR_GS_BASE, base, base>>32) ) ret = -EFAULT; else v->arch.guest_context.gs_base_kernel = base; break; case SEGBASE_GS_USER_SEL: __asm__ __volatile__ ( " swapgs \n" "1: movl %k0,%%gs \n" " "safe_swapgs" \n" ".section .fixup,\"ax\" \n" "2: xorl %k0,%k0 \n" " jmp 1b \n" ".previous \n" ".section __ex_table,\"a\"\n" " .align 8 \n" " .quad 1b,2b \n" ".previous " : : "r" (base&0xffff) ); break; default: ret = -EINVAL; break; } return ret; } /* Returns TRUE if given descriptor is valid for GDT or LDT. */ int check_descriptor(struct desc_struct *d) { u32 a = d->a, b = d->b; u16 cs; /* A not-present descriptor will always fault, so is safe. */ if ( !(b & _SEGMENT_P) ) goto good; /* Check and fix up the DPL. */ if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); /* All code and data segments are okay. No base/limit checking. */ if ( (b & _SEGMENT_S) ) goto good; /* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */ if ( (b & _SEGMENT_TYPE) == 0x000 ) goto good; /* Everything but a call gate is discarded here. */ if ( (b & _SEGMENT_TYPE) != 0xc00 ) goto bad; /* Validate and fix up the target code selector. */ cs = a >> 16; fixup_guest_code_selector(cs); if ( !guest_gate_selector_okay(cs) ) goto bad; a = d->a = (d->a & 0xffffU) | (cs << 16); /* Reserved bits must be zero. */ if ( (b & 0xe0) != 0 ) goto bad; good: return 1; bad: return 0; } /* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */