1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2014-2016 Stefan Roese <sr@denx.de> 4 */ 5 6 #include <common.h> 7 #include <ahci.h> 8 #include <linux/mbus.h> 9 #include <asm/io.h> 10 #include <asm/pl310.h> 11 #include <asm/arch/cpu.h> 12 #include <asm/arch/soc.h> 13 #include <sdhci.h> 14 15 #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) 16 #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) 17 18 static struct mbus_win windows[] = { 19 /* SPI */ 20 { MBUS_SPI_BASE, MBUS_SPI_SIZE, 21 CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH }, 22 23 /* NOR */ 24 { MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE, 25 CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_BOOTROM }, 26 }; 27 28 void lowlevel_init(void) 29 { 30 /* 31 * Dummy implementation, we only need LOWLEVEL_INIT 32 * on Armada to configure CP15 in start.S / cpu_init_cp15() 33 */ 34 } 35 36 void reset_cpu(unsigned long ignored) 37 { 38 struct mvebu_system_registers *reg = 39 (struct mvebu_system_registers *)MVEBU_SYSTEM_REG_BASE; 40 41 writel(readl(®->rstoutn_mask) | 1, ®->rstoutn_mask); 42 writel(readl(®->sys_soft_rst) | 1, ®->sys_soft_rst); 43 while (1) 44 ; 45 } 46 47 int mvebu_soc_family(void) 48 { 49 u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; 50 51 switch (devid) { 52 case SOC_MV78230_ID: 53 case SOC_MV78260_ID: 54 case SOC_MV78460_ID: 55 return MVEBU_SOC_AXP; 56 57 case SOC_88F6720_ID: 58 return MVEBU_SOC_A375; 59 60 case SOC_88F6810_ID: 61 case SOC_88F6820_ID: 62 case SOC_88F6828_ID: 63 return MVEBU_SOC_A38X; 64 65 case SOC_98DX3236_ID: 66 case SOC_98DX3336_ID: 67 case SOC_98DX4251_ID: 68 return MVEBU_SOC_MSYS; 69 } 70 71 return MVEBU_SOC_UNKNOWN; 72 } 73 74 #if defined(CONFIG_DISPLAY_CPUINFO) 75 76 #if defined(CONFIG_ARMADA_375) 77 /* SAR frequency values for Armada 375 */ 78 static const struct sar_freq_modes sar_freq_tab[] = { 79 { 0, 0x0, 266, 133, 266 }, 80 { 1, 0x0, 333, 167, 167 }, 81 { 2, 0x0, 333, 167, 222 }, 82 { 3, 0x0, 333, 167, 333 }, 83 { 4, 0x0, 400, 200, 200 }, 84 { 5, 0x0, 400, 200, 267 }, 85 { 6, 0x0, 400, 200, 400 }, 86 { 7, 0x0, 500, 250, 250 }, 87 { 8, 0x0, 500, 250, 334 }, 88 { 9, 0x0, 500, 250, 500 }, 89 { 10, 0x0, 533, 267, 267 }, 90 { 11, 0x0, 533, 267, 356 }, 91 { 12, 0x0, 533, 267, 533 }, 92 { 13, 0x0, 600, 300, 300 }, 93 { 14, 0x0, 600, 300, 400 }, 94 { 15, 0x0, 600, 300, 600 }, 95 { 16, 0x0, 666, 333, 333 }, 96 { 17, 0x0, 666, 333, 444 }, 97 { 18, 0x0, 666, 333, 666 }, 98 { 19, 0x0, 800, 400, 267 }, 99 { 20, 0x0, 800, 400, 400 }, 100 { 21, 0x0, 800, 400, 534 }, 101 { 22, 0x0, 900, 450, 300 }, 102 { 23, 0x0, 900, 450, 450 }, 103 { 24, 0x0, 900, 450, 600 }, 104 { 25, 0x0, 1000, 500, 500 }, 105 { 26, 0x0, 1000, 500, 667 }, 106 { 27, 0x0, 1000, 333, 500 }, 107 { 28, 0x0, 400, 400, 400 }, 108 { 29, 0x0, 1100, 550, 550 }, 109 { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ 110 }; 111 #elif defined(CONFIG_ARMADA_38X) 112 /* SAR frequency values for Armada 38x */ 113 static const struct sar_freq_modes sar_freq_tab[] = { 114 { 0x0, 0x0, 666, 333, 333 }, 115 { 0x2, 0x0, 800, 400, 400 }, 116 { 0x4, 0x0, 1066, 533, 533 }, 117 { 0x6, 0x0, 1200, 600, 600 }, 118 { 0x8, 0x0, 1332, 666, 666 }, 119 { 0xc, 0x0, 1600, 800, 800 }, 120 { 0x10, 0x0, 1866, 933, 933 }, 121 { 0x13, 0x0, 2000, 1000, 933 }, 122 { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ 123 }; 124 #else 125 /* SAR frequency values for Armada XP */ 126 static const struct sar_freq_modes sar_freq_tab[] = { 127 { 0xa, 0x5, 800, 400, 400 }, 128 { 0x1, 0x5, 1066, 533, 533 }, 129 { 0x2, 0x5, 1200, 600, 600 }, 130 { 0x2, 0x9, 1200, 600, 400 }, 131 { 0x3, 0x5, 1333, 667, 667 }, 132 { 0x4, 0x5, 1500, 750, 750 }, 133 { 0x4, 0x9, 1500, 750, 500 }, 134 { 0xb, 0x9, 1600, 800, 533 }, 135 { 0xb, 0xa, 1600, 800, 640 }, 136 { 0xb, 0x5, 1600, 800, 800 }, 137 { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ 138 }; 139 #endif 140 141 void get_sar_freq(struct sar_freq_modes *sar_freq) 142 { 143 u32 val; 144 u32 freq; 145 int i; 146 147 #if defined(CONFIG_ARMADA_375) 148 val = readl(CONFIG_SAR2_REG); /* SAR - Sample At Reset */ 149 #else 150 val = readl(CONFIG_SAR_REG); /* SAR - Sample At Reset */ 151 #endif 152 freq = (val & SAR_CPU_FREQ_MASK) >> SAR_CPU_FREQ_OFFS; 153 #if defined(SAR2_CPU_FREQ_MASK) 154 /* 155 * Shift CPU0 clock frequency select bit from SAR2 register 156 * into correct position 157 */ 158 freq |= ((readl(CONFIG_SAR2_REG) & SAR2_CPU_FREQ_MASK) 159 >> SAR2_CPU_FREQ_OFFS) << 3; 160 #endif 161 for (i = 0; sar_freq_tab[i].val != 0xff; i++) { 162 if (sar_freq_tab[i].val == freq) { 163 #if defined(CONFIG_ARMADA_375) || defined(CONFIG_ARMADA_38X) 164 *sar_freq = sar_freq_tab[i]; 165 return; 166 #else 167 int k; 168 u8 ffc; 169 170 ffc = (val & SAR_FFC_FREQ_MASK) >> 171 SAR_FFC_FREQ_OFFS; 172 for (k = i; sar_freq_tab[k].ffc != 0xff; k++) { 173 if (sar_freq_tab[k].ffc == ffc) { 174 *sar_freq = sar_freq_tab[k]; 175 return; 176 } 177 } 178 i = k; 179 #endif 180 } 181 } 182 183 /* SAR value not found, return 0 for frequencies */ 184 *sar_freq = sar_freq_tab[i - 1]; 185 } 186 187 int print_cpuinfo(void) 188 { 189 u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; 190 u8 revid = readl(MVEBU_REG_PCIE_REVID) & 0xff; 191 struct sar_freq_modes sar_freq; 192 193 puts("SoC: "); 194 195 switch (devid) { 196 case SOC_MV78230_ID: 197 puts("MV78230-"); 198 break; 199 case SOC_MV78260_ID: 200 puts("MV78260-"); 201 break; 202 case SOC_MV78460_ID: 203 puts("MV78460-"); 204 break; 205 case SOC_88F6720_ID: 206 puts("MV88F6720-"); 207 break; 208 case SOC_88F6810_ID: 209 puts("MV88F6810-"); 210 break; 211 case SOC_88F6820_ID: 212 puts("MV88F6820-"); 213 break; 214 case SOC_88F6828_ID: 215 puts("MV88F6828-"); 216 break; 217 case SOC_98DX3236_ID: 218 puts("98DX3236-"); 219 break; 220 case SOC_98DX3336_ID: 221 puts("98DX3336-"); 222 break; 223 case SOC_98DX4251_ID: 224 puts("98DX4251-"); 225 break; 226 default: 227 puts("Unknown-"); 228 break; 229 } 230 231 if (mvebu_soc_family() == MVEBU_SOC_AXP) { 232 switch (revid) { 233 case 1: 234 puts("A0"); 235 break; 236 case 2: 237 puts("B0"); 238 break; 239 default: 240 printf("?? (%x)", revid); 241 break; 242 } 243 } 244 245 if (mvebu_soc_family() == MVEBU_SOC_A375) { 246 switch (revid) { 247 case MV_88F67XX_A0_ID: 248 puts("A0"); 249 break; 250 default: 251 printf("?? (%x)", revid); 252 break; 253 } 254 } 255 256 if (mvebu_soc_family() == MVEBU_SOC_A38X) { 257 switch (revid) { 258 case MV_88F68XX_Z1_ID: 259 puts("Z1"); 260 break; 261 case MV_88F68XX_A0_ID: 262 puts("A0"); 263 break; 264 default: 265 printf("?? (%x)", revid); 266 break; 267 } 268 } 269 270 get_sar_freq(&sar_freq); 271 printf(" at %d MHz\n", sar_freq.p_clk); 272 273 return 0; 274 } 275 #endif /* CONFIG_DISPLAY_CPUINFO */ 276 277 /* 278 * This function initialize Controller DRAM Fastpath windows. 279 * It takes the CS size information from the 0x1500 scratch registers 280 * and sets the correct windows sizes and base addresses accordingly. 281 * 282 * These values are set in the scratch registers by the Marvell 283 * DDR3 training code, which is executed by the BootROM before the 284 * main payload (U-Boot) is executed. This training code is currently 285 * only available in the Marvell U-Boot version. It needs to be 286 * ported to mainline U-Boot SPL at some point. 287 */ 288 static void update_sdram_window_sizes(void) 289 { 290 u64 base = 0; 291 u32 size, temp; 292 int i; 293 294 for (i = 0; i < SDRAM_MAX_CS; i++) { 295 size = readl((MVEBU_SDRAM_SCRATCH + (i * 8))) & SDRAM_ADDR_MASK; 296 if (size != 0) { 297 size |= ~(SDRAM_ADDR_MASK); 298 299 /* Set Base Address */ 300 temp = (base & 0xFF000000ll) | ((base >> 32) & 0xF); 301 writel(temp, MVEBU_SDRAM_BASE + DDR_BASE_CS_OFF(i)); 302 303 /* 304 * Check if out of max window size and resize 305 * the window 306 */ 307 temp = (readl(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)) & 308 ~(SDRAM_ADDR_MASK)) | 1; 309 temp |= (size & SDRAM_ADDR_MASK); 310 writel(temp, MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)); 311 312 base += ((u64)size + 1); 313 } else { 314 /* 315 * Disable window if not used, otherwise this 316 * leads to overlapping enabled windows with 317 * pretty strange results 318 */ 319 clrbits_le32(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i), 1); 320 } 321 } 322 } 323 324 void mmu_disable(void) 325 { 326 asm volatile( 327 "mrc p15, 0, r0, c1, c0, 0\n" 328 "bic r0, #1\n" 329 "mcr p15, 0, r0, c1, c0, 0\n"); 330 } 331 332 #ifdef CONFIG_ARCH_CPU_INIT 333 static void set_cbar(u32 addr) 334 { 335 asm("mcr p15, 4, %0, c15, c0" : : "r" (addr)); 336 } 337 338 #define MV_USB_PHY_BASE (MVEBU_AXP_USB_BASE + 0x800) 339 #define MV_USB_PHY_PLL_REG(reg) (MV_USB_PHY_BASE | (((reg) & 0xF) << 2)) 340 #define MV_USB_X3_BASE(addr) (MVEBU_AXP_USB_BASE | BIT(11) | \ 341 (((addr) & 0xF) << 6)) 342 #define MV_USB_X3_PHY_CHANNEL(dev, reg) (MV_USB_X3_BASE((dev) + 1) | \ 343 (((reg) & 0xF) << 2)) 344 345 static void setup_usb_phys(void) 346 { 347 int dev; 348 349 /* 350 * USB PLL init 351 */ 352 353 /* Setup PLL frequency */ 354 /* USB REF frequency = 25 MHz */ 355 clrsetbits_le32(MV_USB_PHY_PLL_REG(1), 0x3ff, 0x605); 356 357 /* Power up PLL and PHY channel */ 358 setbits_le32(MV_USB_PHY_PLL_REG(2), BIT(9)); 359 360 /* Assert VCOCAL_START */ 361 setbits_le32(MV_USB_PHY_PLL_REG(1), BIT(21)); 362 363 mdelay(1); 364 365 /* 366 * USB PHY init (change from defaults) specific for 40nm (78X30 78X60) 367 */ 368 369 for (dev = 0; dev < 3; dev++) { 370 setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 3), BIT(15)); 371 372 /* Assert REG_RCAL_START in channel REG 1 */ 373 setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12)); 374 udelay(40); 375 clrbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12)); 376 } 377 } 378 379 /* 380 * This function is not called from the SPL U-Boot version 381 */ 382 int arch_cpu_init(void) 383 { 384 struct pl310_regs *const pl310 = 385 (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 386 387 /* 388 * Only with disabled MMU its possible to switch the base 389 * register address on Armada 38x. Without this the SDRAM 390 * located at >= 0x4000.0000 is also not accessible, as its 391 * still locked to cache. 392 */ 393 mmu_disable(); 394 395 /* Linux expects the internal registers to be at 0xf1000000 */ 396 writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG); 397 set_cbar(SOC_REGS_PHY_BASE + 0xC000); 398 399 /* 400 * From this stage on, the SoC detection is working. As we have 401 * configured the internal register base to the value used 402 * in the macros / defines in the U-Boot header (soc.h). 403 */ 404 405 if (mvebu_soc_family() == MVEBU_SOC_A38X) { 406 /* 407 * To fully release / unlock this area from cache, we need 408 * to flush all caches and disable the L2 cache. 409 */ 410 icache_disable(); 411 dcache_disable(); 412 clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 413 } 414 415 /* 416 * We need to call mvebu_mbus_probe() before calling 417 * update_sdram_window_sizes() as it disables all previously 418 * configured mbus windows and then configures them as 419 * required for U-Boot. Calling update_sdram_window_sizes() 420 * without this configuration will not work, as the internal 421 * registers can't be accessed reliably because of potenial 422 * double mapping. 423 * After updating the SDRAM access windows we need to call 424 * mvebu_mbus_probe() again, as this now correctly configures 425 * the SDRAM areas that are later used by the MVEBU drivers 426 * (e.g. USB, NETA). 427 */ 428 429 /* 430 * First disable all windows 431 */ 432 mvebu_mbus_probe(NULL, 0); 433 434 if (mvebu_soc_family() == MVEBU_SOC_AXP) { 435 /* 436 * Now the SDRAM access windows can be reconfigured using 437 * the information in the SDRAM scratch pad registers 438 */ 439 update_sdram_window_sizes(); 440 } 441 442 /* 443 * Finally the mbus windows can be configured with the 444 * updated SDRAM sizes 445 */ 446 mvebu_mbus_probe(windows, ARRAY_SIZE(windows)); 447 448 if (mvebu_soc_family() == MVEBU_SOC_AXP) { 449 /* Enable GBE0, GBE1, LCD and NFC PUP */ 450 clrsetbits_le32(ARMADA_XP_PUP_ENABLE, 0, 451 GE0_PUP_EN | GE1_PUP_EN | LCD_PUP_EN | 452 NAND_PUP_EN | SPI_PUP_EN); 453 454 /* Configure USB PLL and PHYs on AXP */ 455 setup_usb_phys(); 456 } 457 458 /* Enable NAND and NAND arbiter */ 459 clrsetbits_le32(MVEBU_SOC_DEV_MUX_REG, 0, NAND_EN | NAND_ARBITER_EN); 460 461 /* Disable MBUS error propagation */ 462 clrsetbits_le32(SOC_COHERENCY_FABRIC_CTRL_REG, MBUS_ERR_PROP_EN, 0); 463 464 return 0; 465 } 466 #endif /* CONFIG_ARCH_CPU_INIT */ 467 468 u32 mvebu_get_nand_clock(void) 469 { 470 u32 reg; 471 472 if (mvebu_soc_family() == MVEBU_SOC_A38X) 473 reg = MVEBU_DFX_DIV_CLK_CTRL(1); 474 else 475 reg = MVEBU_CORE_DIV_CLK_CTRL(1); 476 477 return CONFIG_SYS_MVEBU_PLL_CLOCK / 478 ((readl(reg) & 479 NAND_ECC_DIVCKL_RATIO_MASK) >> NAND_ECC_DIVCKL_RATIO_OFFS); 480 } 481 482 /* 483 * SOC specific misc init 484 */ 485 #if defined(CONFIG_ARCH_MISC_INIT) 486 int arch_misc_init(void) 487 { 488 /* Nothing yet, perhaps we need something here later */ 489 return 0; 490 } 491 #endif /* CONFIG_ARCH_MISC_INIT */ 492 493 #ifdef CONFIG_MMC_SDHCI_MV 494 int board_mmc_init(bd_t *bis) 495 { 496 mv_sdh_init(MVEBU_SDIO_BASE, 0, 0, 497 SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD); 498 499 return 0; 500 } 501 #endif 502 503 #ifdef CONFIG_SCSI_AHCI_PLAT 504 #define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0 505 #define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4 506 507 #define AHCI_WINDOW_CTRL(win) (0x60 + ((win) << 4)) 508 #define AHCI_WINDOW_BASE(win) (0x64 + ((win) << 4)) 509 #define AHCI_WINDOW_SIZE(win) (0x68 + ((win) << 4)) 510 511 static void ahci_mvebu_mbus_config(void __iomem *base) 512 { 513 const struct mbus_dram_target_info *dram; 514 int i; 515 516 dram = mvebu_mbus_dram_info(); 517 518 for (i = 0; i < 4; i++) { 519 writel(0, base + AHCI_WINDOW_CTRL(i)); 520 writel(0, base + AHCI_WINDOW_BASE(i)); 521 writel(0, base + AHCI_WINDOW_SIZE(i)); 522 } 523 524 for (i = 0; i < dram->num_cs; i++) { 525 const struct mbus_dram_window *cs = dram->cs + i; 526 527 writel((cs->mbus_attr << 8) | 528 (dram->mbus_dram_target_id << 4) | 1, 529 base + AHCI_WINDOW_CTRL(i)); 530 writel(cs->base >> 16, base + AHCI_WINDOW_BASE(i)); 531 writel(((cs->size - 1) & 0xffff0000), 532 base + AHCI_WINDOW_SIZE(i)); 533 } 534 } 535 536 static void ahci_mvebu_regret_option(void __iomem *base) 537 { 538 /* 539 * Enable the regret bit to allow the SATA unit to regret a 540 * request that didn't receive an acknowlegde and avoid a 541 * deadlock 542 */ 543 writel(0x4, base + AHCI_VENDOR_SPECIFIC_0_ADDR); 544 writel(0x80, base + AHCI_VENDOR_SPECIFIC_0_DATA); 545 } 546 547 void scsi_init(void) 548 { 549 printf("MVEBU SATA INIT\n"); 550 ahci_mvebu_mbus_config((void __iomem *)MVEBU_SATA0_BASE); 551 ahci_mvebu_regret_option((void __iomem *)MVEBU_SATA0_BASE); 552 ahci_init((void __iomem *)MVEBU_SATA0_BASE); 553 } 554 #endif 555 556 #ifdef CONFIG_USB_XHCI_MVEBU 557 #define USB3_MAX_WINDOWS 4 558 #define USB3_WIN_CTRL(w) (0x0 + ((w) * 8)) 559 #define USB3_WIN_BASE(w) (0x4 + ((w) * 8)) 560 561 static void xhci_mvebu_mbus_config(void __iomem *base, 562 const struct mbus_dram_target_info *dram) 563 { 564 int i; 565 566 for (i = 0; i < USB3_MAX_WINDOWS; i++) { 567 writel(0, base + USB3_WIN_CTRL(i)); 568 writel(0, base + USB3_WIN_BASE(i)); 569 } 570 571 for (i = 0; i < dram->num_cs; i++) { 572 const struct mbus_dram_window *cs = dram->cs + i; 573 574 /* Write size, attributes and target id to control register */ 575 writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | 576 (dram->mbus_dram_target_id << 4) | 1, 577 base + USB3_WIN_CTRL(i)); 578 579 /* Write base address to base register */ 580 writel((cs->base & 0xffff0000), base + USB3_WIN_BASE(i)); 581 } 582 } 583 584 int board_xhci_enable(fdt_addr_t base) 585 { 586 const struct mbus_dram_target_info *dram; 587 588 printf("MVEBU XHCI INIT controller @ 0x%lx\n", base); 589 590 dram = mvebu_mbus_dram_info(); 591 xhci_mvebu_mbus_config((void __iomem *)base, dram); 592 593 return 0; 594 } 595 #endif 596 597 void enable_caches(void) 598 { 599 /* Avoid problem with e.g. neta ethernet driver */ 600 invalidate_dcache_all(); 601 602 /* 603 * Armada 375 still has some problems with d-cache enabled in the 604 * ethernet driver (mvpp2). So lets keep the d-cache disabled 605 * until this is solved. 606 */ 607 if (mvebu_soc_family() != MVEBU_SOC_A375) { 608 /* Enable D-cache. I-cache is already enabled in start.S */ 609 dcache_enable(); 610 } 611 } 612 613 void v7_outer_cache_enable(void) 614 { 615 if (mvebu_soc_family() == MVEBU_SOC_AXP) { 616 struct pl310_regs *const pl310 = 617 (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 618 u32 u; 619 620 /* The L2 cache is already disabled at this point */ 621 622 /* 623 * For Aurora cache in no outer mode, enable via the CP15 624 * coprocessor broadcasting of cache commands to L2. 625 */ 626 asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u)); 627 u |= BIT(8); /* Set the FW bit */ 628 asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u)); 629 630 isb(); 631 632 /* Enable the L2 cache */ 633 setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 634 } 635 } 636 637 void v7_outer_cache_disable(void) 638 { 639 struct pl310_regs *const pl310 = 640 (struct pl310_regs *)CONFIG_SYS_PL310_BASE; 641 642 clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 643 } 644