1 From 4953294aa8f8b9023e6b5f7f39059706c72d916c Mon Sep 17 00:00:00 2001
2 From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
3 Date: Sun, 9 Dec 2012 17:54:56 +0100
4 Subject: MIPS: lantiq: add support for Lantiq XWAY ARX100 SoC family
6 Signed-off-by: Luka Perkov <luka@openwrt.org>
7 Signed-off-by: John Crispin <blogic@openwrt.org>
8 Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
11 +++ b/arch/mips/cpu/mips32/arx100/Makefile
14 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
16 +# SPDX-License-Identifier: GPL-2.0+
19 +include $(TOPDIR)/config.mk
21 +LIB = $(obj)lib$(SOC).o
23 +COBJS-y += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
24 +SOBJS-y += cgu_init.o mem_init.o
28 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
29 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
33 +$(LIB): $(obj).depend $(OBJS)
34 + $(call cmd_link_o_target, $(OBJS))
36 +#########################################################################
38 +# defines $(obj).depend target
39 +include $(SRCTREE)/rules.mk
41 +sinclude $(obj).depend
43 +#########################################################################
45 +++ b/arch/mips/cpu/mips32/arx100/cgu.c
48 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
49 + * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
51 + * SPDX-License-Identifier: GPL-2.0+
55 +#include <asm/arch/soc.h>
56 +#include <asm/lantiq/clk.h>
57 +#include <asm/lantiq/io.h>
59 +#define CGU_SYS_DDR_SEL (1 << 0)
60 +#define CGU_SYS_CPU_SEL (1 << 2)
61 +#define CGU_SYS_SYS_SHIFT 3
62 +#define CGU_SYS_SYS_MASK (0x3 << CGU_SYS_SYS_SHIFT)
63 +#define CGU_SYS_FPI_SEL (1 << 6)
64 +#define CGU_SYS_PPE_SEL (1 << 7)
66 +struct ltq_cgu_regs {
68 + __be32 pll0_cfg; /* PLL0 config */
69 + __be32 pll1_cfg; /* PLL1 config */
71 + __be32 sys; /* System clock */
72 + __be32 update; /* CGU update control */
73 + __be32 if_clk; /* Interface clock */
75 + __be32 smd; /* SDRAM Memory Control */
77 + __be32 ct1_sr; /* CT status 1 */
78 + __be32 ct_kval; /* CT K value */
79 + __be32 pcm_cr; /* PCM control */
82 +static struct ltq_cgu_regs *ltq_cgu_regs =
83 + (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
85 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
87 + return (ltq_readl(<q_cgu_regs->sys) & mask) >> shift;
90 +static unsigned long ltq_get_system_clock(void)
95 + sys_sel = ltq_cgu_sys_readl(CGU_SYS_SYS_MASK, CGU_SYS_SYS_SHIFT);
99 + clk = CLOCK_333_MHZ;
102 + clk = CLOCK_393_MHZ;
112 +unsigned long ltq_get_io_region_clock(void)
117 + ddr_sel = ltq_cgu_sys_readl(1, CGU_SYS_DDR_SEL);
120 + clk = ltq_get_system_clock() / 3;
122 + clk = ltq_get_system_clock() / 2;
127 +unsigned long ltq_get_cpu_clock(void)
132 + cpu_sel = ltq_cgu_sys_readl(1, CGU_SYS_CPU_SEL);
135 + clk = ltq_get_io_region_clock();
137 + clk = ltq_get_system_clock();
142 +unsigned long ltq_get_bus_clock(void)
147 + fpi_sel = ltq_cgu_sys_readl(1, CGU_SYS_FPI_SEL);
150 + clk = ltq_get_io_region_clock() / 2;
152 + clk = ltq_get_io_region_clock();
157 +++ b/arch/mips/cpu/mips32/arx100/cgu_init.S
160 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
161 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
163 + * SPDX-License-Identifier: GPL-2.0+
167 +#include <asm/asm.h>
168 +#include <asm/regdef.h>
169 +#include <asm/addrspace.h>
170 +#include <asm/arch/soc.h>
172 +/* CGU module register */
173 +#define CGU_PLL0_CFG 0x0004 /* PLL0 config */
174 +#define CGU_PLL1_CFG 0x0008 /* PLL1 config */
175 +#define CGU_SYS 0x0010 /* System clock */
176 +#define CGU_UPDATE 0x0014 /* Clock update control */
178 +/* Valid SYS.PPE_SEL values */
179 +#define CGU_SYS_PPESEL_SHIFT 7
180 +#define CGU_SYS_PPESEL_250_MHZ (0x1 << CGU_SYS_PPESEL_SHIFT)
182 +/* Valid SYS.SYS_SEL values */
183 +#define CGU_SYS_SYSSEL_SHIFT 3
184 +#define CGU_SYS_SYSSEL_PLL0_333_MHZ (0x0 << CGU_SYS_SYSSEL_SHIFT)
185 +#define CGU_SYS_SYSSEL_PLL1_393_MHZ (0x2 << CGU_SYS_SYSSEL_SHIFT)
187 +/* Valid SYS.CPU_SEL values */
188 +#define CGU_SYS_CPUSEL_SHIFT 2
189 +#define CGU_SYS_CPUSEL_EQUAL_SYSCLK (0x0 << CGU_SYS_CPUSEL_SHIFT)
190 +#define CGU_SYS_CPUSEL_EQUAL_DDRCLK (0x1 << CGU_SYS_CPUSEL_SHIFT)
192 +/* Valid SYS.DDR_SEL values */
193 +#define CGU_SYS_DDRSEL_HALF_SYSCLK 0x0
194 +#define CGU_SYS_DDRSEL_THIRD_SYSCLK 0x1
196 +#define CGU_UPDATE_UPD 0x1
198 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_393_DDR_197)
199 +#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ
200 +#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL1_393_MHZ
201 +#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_SYSCLK
202 +#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_HALF_SYSCLK
203 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_197_DDR_197)
204 +#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ
205 +#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL1_393_MHZ
206 +#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_DDRCLK
207 +#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_HALF_SYSCLK
208 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
209 +#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ
210 +#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL0_333_MHZ
211 +#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_SYSCLK
212 +#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_HALF_SYSCLK
213 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_167_DDR_167)
214 +#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ
215 +#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL0_333_MHZ
216 +#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_DDRCLK
217 +#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_HALF_SYSCLK
218 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_131_DDR_131)
219 +#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ
220 +#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL1_393_MHZ
221 +#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_DDRCLK
222 +#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_THIRD_SYSCLK
223 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
224 +#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ
225 +#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL0_333_MHZ
226 +#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_DDRCLK
227 +#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_THIRD_SYSCLK
229 +#error "Invalid system clock configuration!"
232 +/* Build register values */
233 +#define CGU_SYS_VALUE (CGU_SYS_PPESEL_CONFIG | \
234 + CGU_SYS_SYSSEL_CONFIG | \
235 + CGU_SYS_CPUSEL_CONFIG | \
236 + CGU_SYS_DDRSEL_CONFIG)
241 + /* Load current CGU register value */
242 + li t0, (LTQ_CGU_BASE | KSEG1)
245 + /* Load target CGU register values */
246 + li t2, CGU_SYS_VALUE
248 + /* Only update registers if values differ */
249 + beq t1, t2, finished
252 + /* Store target register values */
255 + /* Trigger CGU update */
256 + li t1, CGU_UPDATE_UPD
257 + sw t1, CGU_UPDATE(t0)
265 +++ b/arch/mips/cpu/mips32/arx100/chipid.c
268 + * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
270 + * SPDX-License-Identifier: GPL-2.0+
274 +#include <asm/lantiq/io.h>
275 +#include <asm/lantiq/chipid.h>
276 +#include <asm/arch/soc.h>
278 +#define LTQ_CHIPID_VERSION_SHIFT 28
279 +#define LTQ_CHIPID_VERSION_MASK (0xF << LTQ_CHIPID_VERSION_SHIFT)
280 +#define LTQ_CHIPID_PNUM_SHIFT 12
281 +#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
283 +struct ltq_chipid_regs {
284 + u32 manid; /* Manufacturer identification */
285 + u32 chipid; /* Chip identification */
288 +static struct ltq_chipid_regs *ltq_chipid_regs =
289 + (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
291 +unsigned int ltq_chip_version_get(void)
295 + chipid = ltq_readl(<q_chipid_regs->chipid);
297 + return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
300 +unsigned int ltq_chip_partnum_get(void)
304 + chipid = ltq_readl(<q_chipid_regs->chipid);
306 + return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
309 +const char *ltq_chip_partnum_str(void)
311 + enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
314 + case LTQ_SOC_ARX188:
316 + case LTQ_SOC_ARX186:
317 + case LTQ_SOC_ARX186_2:
319 + case LTQ_SOC_ARX182:
322 + printf("Unknown partnum: %x\n", partnum);
328 +++ b/arch/mips/cpu/mips32/arx100/config.mk
331 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
333 +# SPDX-License-Identifier: GPL-2.0+
336 +PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
337 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
339 +ifdef CONFIG_SPL_BUILD
340 +PF_ABICALLS := -mno-abicalls
343 +USE_PRIVATE_LIBGCC := yes
346 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
348 +ifndef CONFIG_SPL_BUILD
349 +ifdef CONFIG_SYS_BOOT_SFSPL
350 +ALL-y += $(obj)u-boot.ltq.sfspl
351 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
352 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
354 +ifdef CONFIG_SYS_BOOT_NORSPL
355 +ALL-y += $(obj)u-boot.ltq.norspl
356 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
357 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
361 +++ b/arch/mips/cpu/mips32/arx100/ebu.c
364 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
366 + * SPDX-License-Identifier: GPL-2.0+
370 +#include <asm/arch/soc.h>
371 +#include <asm/lantiq/io.h>
373 +#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
374 +#define EBU_ADDRSEL_REGEN (1 << 0)
376 +#define EBU_CON_WRDIS (1 << 31)
377 +#define EBU_CON_AGEN_DEMUX (0x0 << 24)
378 +#define EBU_CON_AGEN_MUX (0x2 << 24)
379 +#define EBU_CON_SETUP (1 << 22)
380 +#define EBU_CON_WAIT_DIS (0x0 << 20)
381 +#define EBU_CON_WAIT_ASYNC (0x1 << 20)
382 +#define EBU_CON_WAIT_SYNC (0x2 << 20)
383 +#define EBU_CON_WINV (1 << 19)
384 +#define EBU_CON_PW_8BIT (0x0 << 16)
385 +#define EBU_CON_PW_16BIT (0x1 << 16)
386 +#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
387 +#define EBU_CON_BCGEN_CS (0x0 << 12)
388 +#define EBU_CON_BCGEN_INTEL (0x1 << 12)
389 +#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
390 +#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
391 +#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
392 +#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
393 +#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
394 +#define EBU_CON_CMULT_1 0x0
395 +#define EBU_CON_CMULT_4 0x1
396 +#define EBU_CON_CMULT_8 0x2
397 +#define EBU_CON_CMULT_16 0x3
399 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
400 +#define ebu_region0_enable 1
402 +#define ebu_region0_enable 0
405 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
406 +#define ebu_region1_enable 1
408 +#define ebu_region1_enable 0
411 +struct ltq_ebu_regs {
429 +static struct ltq_ebu_regs *ltq_ebu_regs =
430 + (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
432 +void ltq_ebu_init(void)
434 + if (ebu_region0_enable) {
436 + * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
437 + * region control. This supports up to 32 MiB NOR flash in
440 + ltq_writel(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
441 + EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
443 + ltq_writel(<q_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
444 + EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
445 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
446 + EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
447 + EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
450 + ltq_clrbits(<q_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
452 + if (ebu_region1_enable) {
454 + * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
455 + * region control. This supports NAND flash in bank 1.
457 + ltq_writel(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
458 + EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
460 + ltq_writel(<q_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
461 + EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
462 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
463 + EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
464 + EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
467 + ltq_clrbits(<q_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
470 +void *flash_swap_addr(unsigned long addr)
472 + return (void *)(addr ^ 2);
475 +++ b/arch/mips/cpu/mips32/arx100/mem.c
478 + * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
480 + * SPDX-License-Identifier: GPL-2.0+
484 +#include <asm/arch/soc.h>
485 +#include <asm/lantiq/io.h>
487 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
489 +static inline u32 ltq_mc_dc_read(u32 index)
491 + return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
494 +phys_size_t initdram(int board_type)
496 + u32 col, row, dc04, dc19, dc20;
498 + dc04 = ltq_mc_dc_read(4);
499 + dc19 = ltq_mc_dc_read(19);
500 + dc20 = ltq_mc_dc_read(20);
502 + row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
503 + col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
505 + return (1 << (row + col)) * 4 * 2;
508 +++ b/arch/mips/cpu/mips32/arx100/mem_init.S
511 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
512 + * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
514 + * SPDX-License-Identifier: GPL-2.0+
518 +#include <asm/asm.h>
519 +#include <asm/regdef.h>
520 +#include <asm/addrspace.h>
521 +#include <asm/arch/soc.h>
523 +/* Must be configured in BOARDDIR */
524 +#include <ddr_settings.h>
526 +#define LTQ_MC_GEN_ERRCAUSE 0x0010
527 +#define LTQ_MC_GEN_ERRADDR 0x0020
528 +#define LTQ_MC_GEN_CON 0x0060
529 +#define LTQ_MC_GEN_STAT 0x0070
530 +#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0xD
531 +#define LTQ_MC_GEN_STAT_DLCK_PWRON 0xC
533 +#define LTQ_MC_DDR_DC03_MC_START 0x100
535 + /* Store given value in MC DDR CCRx register */
536 + .macro dc_sw num, val
538 + sw t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
542 + /* Load MC General and MC DDR module base */
543 + li t0, (LTQ_MC_GEN_BASE | KSEG1)
544 + li t1, (LTQ_MC_DDR_BASE | KSEG1)
546 + /* Clear access error log registers */
547 + sw zero, LTQ_MC_GEN_ERRCAUSE(t0)
548 + sw zero, LTQ_MC_GEN_ERRADDR(t0)
550 + /* Enable DDR and SRAM module in memory controller */
551 + li t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
552 + sw t2, LTQ_MC_GEN_CON(t0)
554 + /* Clear start bit of DDR memory controller */
555 + sw zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
557 + /* Init memory controller registers with values ddr_settings.h */
558 + dc_sw 0, MC_DC00_VALUE
559 + dc_sw 1, MC_DC01_VALUE
560 + dc_sw 2, MC_DC02_VALUE
561 + dc_sw 4, MC_DC04_VALUE
562 + dc_sw 5, MC_DC05_VALUE
563 + dc_sw 6, MC_DC06_VALUE
564 + dc_sw 7, MC_DC07_VALUE
565 + dc_sw 8, MC_DC08_VALUE
566 + dc_sw 9, MC_DC09_VALUE
568 + dc_sw 10, MC_DC10_VALUE
569 + dc_sw 11, MC_DC11_VALUE
570 + dc_sw 12, MC_DC12_VALUE
571 + dc_sw 13, MC_DC13_VALUE
572 + dc_sw 14, MC_DC14_VALUE
573 + dc_sw 15, MC_DC15_VALUE
574 + dc_sw 16, MC_DC16_VALUE
575 + dc_sw 17, MC_DC17_VALUE
576 + dc_sw 18, MC_DC18_VALUE
577 + dc_sw 19, MC_DC19_VALUE
579 + dc_sw 20, MC_DC20_VALUE
580 + dc_sw 21, MC_DC21_VALUE
581 + dc_sw 22, MC_DC22_VALUE
582 + dc_sw 23, MC_DC23_VALUE
583 + dc_sw 24, MC_DC24_VALUE
584 + dc_sw 25, MC_DC25_VALUE
585 + dc_sw 26, MC_DC26_VALUE
586 + dc_sw 27, MC_DC27_VALUE
587 + dc_sw 28, MC_DC28_VALUE
588 + dc_sw 29, MC_DC29_VALUE
590 + dc_sw 30, MC_DC30_VALUE
591 + dc_sw 31, MC_DC31_VALUE
592 + dc_sw 32, MC_DC32_VALUE
593 + dc_sw 33, MC_DC33_VALUE
594 + dc_sw 34, MC_DC34_VALUE
595 + dc_sw 35, MC_DC35_VALUE
596 + dc_sw 36, MC_DC36_VALUE
597 + dc_sw 37, MC_DC37_VALUE
598 + dc_sw 38, MC_DC38_VALUE
599 + dc_sw 39, MC_DC39_VALUE
601 + dc_sw 40, MC_DC40_VALUE
602 + dc_sw 41, MC_DC41_VALUE
603 + dc_sw 42, MC_DC42_VALUE
604 + dc_sw 43, MC_DC43_VALUE
605 + dc_sw 44, MC_DC44_VALUE
606 + dc_sw 45, MC_DC45_VALUE
607 + dc_sw 46, MC_DC46_VALUE
609 + /* Set start bit of DDR memory controller */
610 + li t2, LTQ_MC_DDR_DC03_MC_START
611 + sw t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
613 + /* Wait until DLL has locked and core is ready for data transfers */
615 + lw t2, LTQ_MC_GEN_STAT(t0)
616 + li t3, LTQ_MC_GEN_STAT_DLCK_PWRON
618 + bne t2, t3, wait_ready
625 +++ b/arch/mips/cpu/mips32/arx100/pmu.c
628 + * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
630 + * SPDX-License-Identifier: GPL-2.0+
634 +#include <asm/lantiq/io.h>
635 +#include <asm/lantiq/pm.h>
636 +#include <asm/arch/soc.h>
638 +#define LTQ_PMU_PWDCR_RESERVED 0xE00C200C
640 +#define LTQ_PMU_PWDCR_SWITCH (1 << 28)
641 +#define LTQ_PMU_PWDCR_USB1 (1 << 27)
642 +#define LTQ_PMU_PWDCR_USB1_PHY (1 << 26)
643 +#define LTQ_PMU_PWDCR_TDM (1 << 25)
644 +#define LTQ_PMU_PWDCR_DDR_MEM (1 << 24)
645 +#define LTQ_PMU_PWDCR_PPE_DP (1 << 23)
646 +#define LTQ_PMU_PWDCR_PPE_EMA (1 << 22)
647 +#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
648 +#define LTQ_PMU_PWDCR_DEU (1 << 20)
649 +#define LTQ_PMU_PWDCR_UART1 (1 << 17)
650 +#define LTQ_PMU_PWDCR_SDIO (1 << 16)
651 +#define LTQ_PMU_PWDCR_AHB (1 << 15)
652 +#define LTQ_PMU_PWDCR_FPI0 (1 << 14)
653 +#define LTQ_PMU_PWDCR_GPTC (1 << 12)
654 +#define LTQ_PMU_PWDCR_LEDC (1 << 11)
655 +#define LTQ_PMU_PWDCR_EBU (1 << 10)
656 +#define LTQ_PMU_PWDCR_DSL (1 << 9)
657 +#define LTQ_PMU_PWDCR_SPI (1 << 8)
658 +#define LTQ_PMU_PWDCR_UART0 (1 << 7)
659 +#define LTQ_PMU_PWDCR_USB (1 << 6)
660 +#define LTQ_PMU_PWDCR_DMA (1 << 5)
661 +#define LTQ_PMU_PWDCR_PCI (1 << 4)
662 +#define LTQ_PMU_PWDCR_FPI1 (1 << 1)
663 +#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0)
665 +struct ltq_pmu_regs {
671 +static struct ltq_pmu_regs *ltq_pmu_regs =
672 + (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
674 +u32 ltq_pm_map(enum ltq_pm_modules module)
680 + val = LTQ_PMU_PWDCR_DDR_MEM | LTQ_PMU_PWDCR_UART1 |
681 + LTQ_PMU_PWDCR_FPI0 | LTQ_PMU_PWDCR_LEDC |
685 + val = LTQ_PMU_PWDCR_DMA;
688 + val = LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DP |
689 + LTQ_PMU_PWDCR_PPE_EMA | LTQ_PMU_PWDCR_PPE_TC;
692 + val = LTQ_PMU_PWDCR_SPI;
702 +int ltq_pm_enable(enum ltq_pm_modules module)
704 + const unsigned long timeout = 1000;
705 + unsigned long timebase;
708 + val = ltq_pm_map(module);
709 + if (unlikely(!val))
712 + ltq_clrbits(<q_pmu_regs->pwdcr, val);
714 + timebase = get_timer(0);
717 + sr = ltq_readl(<q_pmu_regs->sr);
720 + } while (get_timer(timebase) < timeout);
725 +int ltq_pm_disable(enum ltq_pm_modules module)
729 + val = ltq_pm_map(module);
730 + if (unlikely(!val))
733 + ltq_setbits(<q_pmu_regs->pwdcr, val);
738 +void ltq_pmu_init(void)
742 + clr = ltq_pm_map(LTQ_PM_CORE);
743 + set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
745 + ltq_clrsetbits(<q_pmu_regs->pwdcr, clr, set);
748 +++ b/arch/mips/cpu/mips32/arx100/rcu.c
751 + * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
753 + * SPDX-License-Identifier: GPL-2.0+
757 +#include <asm/lantiq/io.h>
758 +#include <asm/lantiq/reset.h>
759 +#include <asm/lantiq/cpu.h>
760 +#include <asm/arch/soc.h>
762 +#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
763 +#define LTQ_RCU_RD_USB1 (1 << 28) /* USB1 MAC and PHY */
764 +#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */
765 +#define LTQ_RCU_RD_PPE_ATM_TC (1 << 22) /* PPE ATM TC */
766 +#define LTQ_RCU_RD_ETHSW (1 << 21) /* Ethernet switch */
767 +#define LTQ_RCU_RD_DSP_DEN (1 << 20) /* Enable DSP JTAG */
768 +#define LTQ_RCU_RD_TDM (1 << 19) /* TDM module interface */
769 +#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
770 +#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
771 +#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
772 +#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
773 +#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
774 +#define LTQ_RCU_RD_ARC_DFE (1 << 7) /* ARC/DFE core */
775 +#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
776 +#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
777 +#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
778 +#define LTQ_RCU_RD_CPU0 (1 << 1) /* CPU0 subsystem */
779 +#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
781 +#define LTQ_RCU_STAT_BOOT_SHIFT 17
782 +#define LTQ_RCU_STAT_BOOT_MASK (0xf << LTQ_RCU_STAT_BOOT_SHIFT)
784 +struct ltq_rcu_regs {
786 + __be32 req; /* Reset request */
787 + __be32 stat; /* Reset status */
788 + __be32 usb0_cfg; /* USB0 config */
790 + __be32 pci_rdy; /* PCI boot ready */
791 + __be32 ppe_conf; /* PPE config */
793 + __be32 usb1_cfg; /* USB1 config */
796 +static struct ltq_rcu_regs *ltq_rcu_regs =
797 + (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
799 +u32 ltq_reset_map(enum ltq_reset_modules module)
804 + case LTQ_RESET_CORE:
805 + case LTQ_RESET_SOFT:
806 + val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU0;
808 + case LTQ_RESET_DMA:
809 + val = LTQ_RCU_RD_DMA;
811 + case LTQ_RESET_ETH:
812 + val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
814 + case LTQ_RESET_HARD:
815 + val = LTQ_RCU_RD_HRST;
825 +int ltq_reset_activate(enum ltq_reset_modules module)
829 + val = ltq_reset_map(module);
830 + if (unlikely(!val))
833 + ltq_setbits(<q_rcu_regs->req, val);
838 +int ltq_reset_deactivate(enum ltq_reset_modules module)
842 + val = ltq_reset_map(module);
843 + if (unlikely(!val))
846 + ltq_clrbits(<q_rcu_regs->req, val);
851 +enum ltq_boot_select ltq_boot_select(void)
854 + unsigned int bootstrap;
856 + stat = ltq_readl(<q_rcu_regs->stat);
857 + bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
859 + switch (bootstrap) {
861 + return BOOT_NOR_NO_BOOTROM;
863 + return BOOT_RGMII0;
877 + return BOOT_UNKNOWN;
880 --- a/arch/mips/cpu/mips32/lantiq-common/cpu.c
881 +++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
882 @@ -20,6 +20,7 @@ static const char ltq_bootsel_strings[][
890 --- a/arch/mips/cpu/mips32/lantiq-common/start.S
891 +++ b/arch/mips/cpu/mips32/lantiq-common/start.S
893 #define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64)
896 +#ifdef CONFIG_SOC_XWAY_ARX100
897 +#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
898 +#define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64)
901 #ifdef CONFIG_SOC_XWAY_VRX200
902 #define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
903 #define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64)
905 +++ b/arch/mips/include/asm/arch-arx100/config.h
908 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
909 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
911 + * SPDX-License-Identifier: GPL-2.0+
913 + * Common board configuration for Lantiq XWAY ARX100 family
915 + * Use following defines in your board config to enable specific features
916 + * and drivers for this SoC:
918 + * CONFIG_LTQ_SUPPORT_UART
919 + * - support the Danube ASC/UART interface and console
921 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
922 + * - support a parallel NOR flash via the CFI interface in flash bank 0
924 + * CONFIG_LTQ_SUPPORT_ETHERNET
925 + * - support the Danube ETOP and MAC interface
927 + * CONFIG_LTQ_SUPPORT_SPI_FLASH
928 + * - support the Danube SPI interface and serial flash drivers
929 + * - specific SPI flash drivers must be configured separately
932 +#ifndef __ARX100_CONFIG_H__
933 +#define __ARX100_CONFIG_H__
935 +/* CPU and SoC type */
936 +#define CONFIG_SOC_LANTIQ
937 +#define CONFIG_SOC_XWAY_ARX100
939 +/* Cache configuration */
940 +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
941 +#define CONFIG_SYS_DCACHE_SIZE (16 * 1024)
942 +#define CONFIG_SYS_ICACHE_SIZE (32 * 1024)
943 +#define CONFIG_SYS_CACHELINE_SIZE 32
944 +#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
947 + * Supported clock modes
948 + * PLL0: rational PLL running at 500 MHz
949 + * PLL1: fractional PLL running at 393.219 MHz
951 +#define LTQ_CLK_CPU_393_DDR_197 0
952 +#define LTQ_CLK_CPU_197_DDR_197 1
953 +#define LTQ_CLK_CPU_333_DDR_167 2
954 +#define LTQ_CLK_CPU_167_DDR_167 3
955 +#define LTQ_CLK_CPU_131_DDR_131 4
956 +#define LTQ_CLK_CPU_111_DDR_111 5
959 +#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_333_DDR_167
960 +#define CONFIG_SYS_MIPS_TIMER_FREQ 166666667
961 +#define CONFIG_SYS_HZ 1000
964 +#define CONFIG_NR_DRAM_BANKS 1
965 +#define CONFIG_SYS_SDRAM_BASE 0x80000000
966 +#define CONFIG_SYS_SDRAM_BASE_UC 0xa0000000
967 +#define CONFIG_SYS_MEMTEST_START 0x81000000
968 +#define CONFIG_SYS_MEMTEST_END 0x82000000
969 +#define CONFIG_SYS_LOAD_ADDR 0x81000000
970 +#define CONFIG_SYS_INIT_SP_OFFSET (32 * 1024)
973 +#define CONFIG_SYS_SRAM_BASE 0xBE1A0000
974 +#define CONFIG_SYS_SRAM_SIZE 0x10000
976 +/* ASC/UART driver and console */
977 +#define CONFIG_LANTIQ_SERIAL
978 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
981 +#define CONFIG_LANTIQ_GPIO
982 +#define CONFIG_LTQ_GPIO_MAX_BANKS 3
983 +#define CONFIG_LTQ_HAS_GPIO_BANK3
986 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
987 +#define CONFIG_SYS_MAX_FLASH_BANKS 1
988 +#define CONFIG_SYS_MAX_FLASH_SECT 256
989 +#define CONFIG_SYS_FLASH_BASE 0xB0000000
990 +#define CONFIG_FLASH_16BIT
991 +#define CONFIG_SYS_FLASH_CFI
992 +#define CONFIG_FLASH_CFI_DRIVER
993 +#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
994 +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
995 +#define CONFIG_FLASH_SHOW_PROGRESS 50
996 +#define CONFIG_SYS_FLASH_PROTECTION
997 +#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
999 +#define CONFIG_CMD_FLASH
1001 +#define CONFIG_SYS_NO_FLASH
1002 +#endif /* CONFIG_NOR_FLASH */
1004 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
1005 +#define CONFIG_LANTIQ_SPI
1006 +#define CONFIG_SPI_FLASH
1008 +#define CONFIG_CMD_SF
1009 +#define CONFIG_CMD_SPI
1012 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
1013 +#define CONFIG_NAND_LANTIQ
1014 +#define CONFIG_SYS_MAX_NAND_DEVICE 1
1015 +#define CONFIG_SYS_NAND_BASE 0xB4000000
1017 +#define CONFIG_CMD_NAND
1020 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
1021 +#define CONFIG_LANTIQ_DMA
1022 +#define CONFIG_LANTIQ_ARX100_SWITCH
1024 +#define CONFIG_PHYLIB
1026 +#define CONFIG_UDP_CHECKSUM
1028 +#define CONFIG_CMD_MII
1029 +#define CONFIG_CMD_NET
1032 +#define CONFIG_SPL_MAX_SIZE (32 * 1024)
1033 +#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
1034 +#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
1035 +#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
1036 +#define CONFIG_SPL_STACK_BSS_IN_SRAM
1038 +#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
1039 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
1040 + CONFIG_SPL_MAX_SIZE + \
1041 + CONFIG_SPL_STACK_MAX_SIZE - 1)
1042 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
1043 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
1044 + CONFIG_SYS_INIT_SP_OFFSET)
1046 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
1047 + CONFIG_SYS_INIT_SP_OFFSET + \
1048 + CONFIG_SPL_STACK_MAX_SIZE - 1)
1049 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
1050 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
1051 + CONFIG_SPL_BSS_MAX_SIZE)
1054 +#if defined(CONFIG_SYS_BOOT_RAM)
1055 +#define CONFIG_SYS_TEXT_BASE 0xA0100000
1056 +#define CONFIG_SKIP_LOWLEVEL_INIT
1057 +#define CONFIG_SYS_DISABLE_CACHE
1060 +#if defined(CONFIG_SYS_BOOT_NOR)
1061 +#define CONFIG_SYS_TEXT_BASE 0xB0000000
1064 +#if defined(CONFIG_SYS_BOOT_SFSPL) || defined(CONFIG_SYS_BOOT_NANDSPL)
1065 +#define CONFIG_SYS_TEXT_BASE 0x80100000
1066 +#define CONFIG_SPL_TEXT_BASE 0xBE1A0000
1069 +#if defined(CONFIG_SYS_BOOT_NORSPL)
1070 +#define CONFIG_SYS_TEXT_BASE 0x80100000
1071 +#define CONFIG_SPL_TEXT_BASE 0xB0000000
1074 +#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
1075 +#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
1076 +#define CONFIG_XWAY_SWAP_BYTES
1079 +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
1081 +#endif /* __ARX100_CONFIG_H__ */
1083 +++ b/arch/mips/include/asm/arch-arx100/gpio.h
1086 + * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1088 + * SPDX-License-Identifier: GPL-2.0+
1091 +#ifndef __ARX100_GPIO_H__
1092 +#define __ARX100_GPIO_H__
1094 +#include <asm/lantiq/gpio.h>
1096 +#endif /* __ARX100_GPIO_H__ */
1098 +++ b/arch/mips/include/asm/arch-arx100/nand.h
1101 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1103 + * SPDX-License-Identifier: GPL-2.0+
1106 +#ifndef __VRX200_NAND_H__
1107 +#define __VRX200_NAND_H__
1110 +int ltq_nand_init(struct nand_chip *nand);
1112 +#endif /* __VRX200_NAND_H__ */
1114 +++ b/arch/mips/include/asm/arch-arx100/soc.h
1117 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
1118 + * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1120 + * SPDX-License-Identifier: GPL-2.0+
1123 +#ifndef __ARX100_SOC_H__
1124 +#define __ARX100_SOC_H__
1126 +#define LTQ_ASC0_BASE 0x1E100400
1127 +#define LTQ_SPI_BASE 0x1E100800
1128 +#define LTQ_GPIO_BASE 0x1E100B00
1129 +#define LTQ_SSIO_BASE 0x1E100BB0
1130 +#define LTQ_ASC1_BASE 0x1E100C00
1131 +#define LTQ_DMA_BASE 0x1E104100
1133 +#define LTQ_EBU_BASE 0x1E105300
1134 +#define LTQ_EBU_REGION0_BASE 0x10000000
1135 +#define LTQ_EBU_REGION1_BASE 0x14000000
1136 +#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0)
1138 +#define LTQ_PPE_BASE 0x1E180000
1139 +#define LTQ_SWITCH_BASE 0x1E108000
1141 +#define LTQ_PMU_BASE 0x1F102000
1142 +#define LTQ_CGU_BASE 0x1F103000
1143 +#define LTQ_MPS_BASE 0x1F107000
1144 +#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
1145 +#define LTQ_RCU_BASE 0x1F203000
1147 +#define LTQ_MC_GEN_BASE 0x1F800000
1148 +#define LTQ_MC_SDR_BASE 0x1F800200
1149 +#define LTQ_MC_DDR_BASE 0x1F801000
1150 +#define LTQ_MC_DDR_DC_OFFSET(x) (x * 0x10)
1152 +#endif /* __ARX100_SOC_H__ */
1153 --- a/arch/mips/include/asm/lantiq/chipid.h
1154 +++ b/arch/mips/include/asm/lantiq/chipid.h
1155 @@ -15,6 +15,10 @@ enum ltq_chip_partnum {
1156 LTQ_SOC_DANUBE = 0x0129,
1157 LTQ_SOC_DANUBE_S = 0x012B,
1158 LTQ_SOC_TWINPASS = 0x012D,
1159 + LTQ_SOC_ARX188 = 0x016C, /* ARX188 */
1160 + LTQ_SOC_ARX186 = 0x016D, /* ARX186 v1.1 */
1161 + LTQ_SOC_ARX186_2 = 0x016E, /* ARX186 v1.2 */
1162 + LTQ_SOC_ARX182 = 0x016F, /* ARX182 */
1163 LTQ_SOC_VRX288 = 0x01C0, /* VRX288 v1.1 */
1164 LTQ_SOC_VRX268 = 0x01C2, /* VRX268 v1.1 */
1165 LTQ_SOC_GRX288 = 0x01C9, /* GRX288 v1.1 */
1166 @@ -36,6 +40,38 @@ static inline int ltq_soc_is_danube(void
1172 +#ifdef CONFIG_SOC_XWAY_ARX100
1173 +static inline int ltq_soc_is_arx100(void)
1178 +static inline int ltq_soc_is_arx100_v1(void)
1180 + return ltq_chip_version_get() == 1;
1183 +static inline int ltq_soc_is_arx100_v2(void)
1185 + return ltq_chip_version_get() == 2;
1188 +static inline int ltq_soc_is_arx100(void)
1193 +static inline int ltq_soc_is_arx100_v1(void)
1198 +static inline int ltq_soc_is_arx100_v2(void)
1204 #ifdef CONFIG_SOC_XWAY_VRX200
1205 --- a/arch/mips/include/asm/lantiq/clk.h
1206 +++ b/arch/mips/include/asm/lantiq/clk.h
1207 @@ -13,9 +13,10 @@ enum ltq_clk {
1208 CLOCK_83_MHZ = 83333333,
1209 CLOCK_111_MHZ = 111111111,
1210 CLOCK_125_MHZ = 125000000,
1211 + CLOCK_131_MHZ = 131073000,
1212 CLOCK_133_MHZ = 133333333,
1213 CLOCK_166_MHZ = 166666667,
1214 - CLOCK_197_MHZ = 197000000,
1215 + CLOCK_197_MHZ = 196609500,
1216 CLOCK_333_MHZ = 333333333,
1217 CLOCK_393_MHZ = 393219000,
1218 CLOCK_500_MHZ = 500000000,
1219 --- a/arch/mips/include/asm/lantiq/cpu.h
1220 +++ b/arch/mips/include/asm/lantiq/cpu.h
1221 @@ -17,6 +17,7 @@ enum ltq_boot_select {