From 2e4cc1c5d4fabee86fc2985fac18f9a2023e39f8 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 26 May 2016 14:49:33 +0100 Subject: MIPS: Use CPHYSADDR to implement mips32 virt_to_phys Use CPHYSADDR to implement the virt_to_phys function for converting from a virtual to a physical address for MIPS32, much as is already done for MIPS64. This allows for virt_to_phys to work regardless of whether the address being translated is in kseg0 or kseg1, unlike the previous subtraction based approach which only worked for addresses in kseg0. This allows for drivers to provide an address to virt_to_phys without needing to manually ensure that kseg1 addresses are converted to equivalent kseg0 addresses first. This patch is equivalent to this Linux patch currently waiting to be reviewed & merged: https://patchwork.linux-mips.org/patch/12564/ Signed-off-by: Paul Burton diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 723a60a..5b86386 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -92,11 +92,8 @@ static inline unsigned long virt_to_phys(volatile const void *address) #ifdef CONFIG_64BIT if (addr < CKSEG0) return XPHYSADDR(addr); - - return CPHYSADDR(addr); -#else - return addr - PAGE_OFFSET + PHYS_OFFSET; #endif + return CPHYSADDR(addr); } /* -- cgit v0.10.2 From 4677d665a7cba420597dd46606735f86416ce552 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 26 May 2016 14:49:34 +0100 Subject: net: pcnet: Stop converting kseg1->kseg0 addresses Now that MIPS virt_to_phys can handle kseg1 addresses on MIPS32, stop manually converting addresses to their kseg0 equivalents in the pcnet driver. Signed-off-by: Paul Burton diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 16a7512..efa4afb 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -135,14 +135,11 @@ static void pcnet_halt (struct eth_device *dev); static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num); static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, - void *addr, bool uncached) + void *addr) { pci_dev_t devbusfn = (pci_dev_t)dev->priv; void *virt_addr = addr; - if (uncached) - virt_addr = (void *)CKSEG0ADDR(addr); - return pci_virt_to_mem(devbusfn, virt_addr); } @@ -361,7 +358,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - addr = pcnet_virt_to_mem(dev, (*lp->rx_buf)[i], false); + addr = pcnet_virt_to_mem(dev, (*lp->rx_buf)[i]); uc->rx_ring[i].base = cpu_to_le32(addr); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); @@ -393,9 +390,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) uc->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | RX_RING_LEN_BITS); - addr = pcnet_virt_to_mem(dev, uc->rx_ring, true); + addr = pcnet_virt_to_mem(dev, uc->rx_ring); uc->init_block.rx_ring = cpu_to_le32(addr); - addr = pcnet_virt_to_mem(dev, uc->tx_ring, true); + addr = pcnet_virt_to_mem(dev, uc->tx_ring); uc->init_block.tx_ring = cpu_to_le32(addr); PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", @@ -406,7 +403,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * Tell the controller where the Init Block is located. */ barrier(); - addr = pcnet_virt_to_mem(dev, &lp->uc->init_block, true); + addr = pcnet_virt_to_mem(dev, &lp->uc->init_block); pcnet_write_csr(dev, 1, addr & 0xffff); pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); @@ -464,7 +461,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) * Setup Tx ring. Caution: the write order is important here, * set the status with the "ownership" bits last. */ - addr = pcnet_virt_to_mem(dev, packet, false); + addr = pcnet_virt_to_mem(dev, packet); writew(-pkt_len, &entry->length); writel(0, &entry->misc); writel(addr, &entry->base); -- cgit v0.10.2 From 442d2e0149c4f3f2dadcf6ebc28b58d317fc5aa0 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 26 May 2016 14:49:35 +0100 Subject: net: pcnet: Make 64 bit safe Fix the pcnet driver to build safely on 64 bit platforms, in preparation for allowing MIPS64 builds for Malta boards. Signed-off-by: Paul Burton Acked-by: Joe Hershberger diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index efa4afb..d1fd4e4 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -137,7 +137,7 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num); static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, void *addr) { - pci_dev_t devbusfn = (pci_dev_t)dev->priv; + pci_dev_t devbusfn = (pci_dev_t)(unsigned long)dev->priv; void *virt_addr = addr; return pci_virt_to_mem(devbusfn, virt_addr); @@ -176,7 +176,7 @@ int pcnet_initialize(bd_t *bis) break; } memset(dev, 0, sizeof(*dev)); - dev->priv = (void *)devbusfn; + dev->priv = (void *)(unsigned long)devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); /* @@ -187,8 +187,8 @@ int pcnet_initialize(bd_t *bis) dev->iobase = pci_io_to_phys(devbusfn, dev->iobase); dev->iobase &= ~0xf; - PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ", - dev->name, devbusfn, dev->iobase); + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", + dev->name, devbusfn, (unsigned long)dev->iobase); command = PCI_COMMAND_IO | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); @@ -295,7 +295,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) { struct pcnet_uncached_priv *uc; int i, val; - u32 addr; + unsigned long addr; PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); @@ -333,16 +333,18 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10); + addr = (unsigned long)malloc(sizeof(pcnet_priv_t) + 0x10); addr = (addr + 0xf) & ~0xf; lp = (pcnet_priv_t *)addr; - addr = (u32)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->uc)); + addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, + sizeof(*lp->uc)); flush_dcache_range(addr, addr + sizeof(*lp->uc)); addr = UNCACHED_SDRAM(addr); lp->uc = (struct pcnet_uncached_priv *)addr; - addr = (u32)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->rx_buf)); + addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, + sizeof(*lp->rx_buf)); flush_dcache_range(addr, addr + sizeof(*lp->rx_buf)); lp->rx_buf = (void *)addr; } -- cgit v0.10.2 From bed1ca322da9b597aa59723a02a1dd647bf8bde4 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 26 May 2016 17:32:29 +0100 Subject: net: pcnet: Fix init on big endian 64 bit If dev->iobase is 64 bits wide then writing the value of the BAR into a pointer to iobase will not work on big endian systems, where the BAR value will incorrectly get written to the upper 32 bits of the 64 bit variable. Fix this by reading the BAR into a u32, matching the type expected by pci_read_config_dword. Signed-off-by: Paul Burton diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index d1fd4e4..1da9996 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -155,6 +155,7 @@ int pcnet_initialize(bd_t *bis) struct eth_device *dev; u16 command, status; int dev_nr = 0; + u32 bar; PCNET_DEBUG1("\npcnet_initialize...\n"); @@ -182,9 +183,8 @@ int pcnet_initialize(bd_t *bis) /* * Setup the PCI device. */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, - (unsigned int *)&dev->iobase); - dev->iobase = pci_io_to_phys(devbusfn, dev->iobase); + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &bar); + dev->iobase = pci_io_to_phys(devbusfn, bar); dev->iobase &= ~0xf; PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", -- cgit v0.10.2 From 0f832b9cdcbe8a024b53c585622d70129652d20b Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 26 May 2016 14:49:36 +0100 Subject: malta: Allow MIPS64 builds Both real Malta boards & emulators that mimic Malta (eg. QEMU) can support MIPS64 CPUs. Allow MIPS64 builds of U-Boot for such boards, which enables the user to make use of the whole 64 bit address space. Signed-off-by: Paul Burton diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 53363e3..abaeaf0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -33,6 +33,9 @@ config TARGET_MALTA select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 select SUPPORTS_CPU_MIPS32_R6 + select SUPPORTS_CPU_MIPS64_R1 + select SUPPORTS_CPU_MIPS64_R2 + select SUPPORTS_CPU_MIPS64_R6 select SWAP_IO_SPACE select MIPS_L1_CACHE_SHIFT_6 diff --git a/board/imgtec/malta/Kconfig b/board/imgtec/malta/Kconfig index 2bb8e8b..98eb4d1 100644 --- a/board/imgtec/malta/Kconfig +++ b/board/imgtec/malta/Kconfig @@ -10,6 +10,7 @@ config SYS_CONFIG_NAME default "malta" config SYS_TEXT_BASE - default 0xbe000000 + default 0xbe000000 if 32BIT + default 0xffffffffbe000000 if 64BIT endif diff --git a/board/imgtec/malta/lowlevel_init.S b/board/imgtec/malta/lowlevel_init.S index 534db1d..3d48cdc 100644 --- a/board/imgtec/malta/lowlevel_init.S +++ b/board/imgtec/malta/lowlevel_init.S @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -34,7 +35,7 @@ lowlevel_init: mtc0 t0, CP0_CONFIG, 2 /* detect the core card */ - li t0, KSEG1ADDR(MALTA_REVISION) + PTR_LI t0, CKSEG1ADDR(MALTA_REVISION) lw t0, 0(t0) srl t0, t0, MALTA_REVISION_CORID_SHF andi t0, t0, (MALTA_REVISION_CORID_MSK >> \ @@ -68,12 +69,12 @@ lowlevel_init: */ _gt64120: /* move GT64120 registers from 0x14000000 to 0x1be00000 */ - li t1, KSEG1ADDR(GT_DEF_BASE) + PTR_LI t1, CKSEG1ADDR(GT_DEF_BASE) li t0, CPU_TO_GT32(0xdf000000) sw t0, GT_ISD_OFS(t1) /* setup MEM-to-PCI0 mapping */ - li t1, KSEG1ADDR(MALTA_GT_BASE) + PTR_LI t1, CKSEG1ADDR(MALTA_GT_BASE) /* setup PCI0 io window to 0x18000000-0x181fffff */ li t0, CPU_TO_GT32(0xc0000000) @@ -100,7 +101,7 @@ _gt64120: */ _msc01: /* setup peripheral bus controller clock divide */ - li t0, KSEG1ADDR(MALTA_MSC01_PBC_BASE) + PTR_LI t0, CKSEG1ADDR(MALTA_MSC01_PBC_BASE) li t1, 0x1 << MSC01_PBC_CLKCFG_SHF sw t1, MSC01_PBC_CLKCFG_OFS(t0) @@ -122,7 +123,7 @@ _msc01: sw t1, MSC01_PBC_CS0CFG_OFS(t0) /* setup basic address decode */ - li t0, KSEG1ADDR(MALTA_MSC01_BIU_BASE) + PTR_LI t0, CKSEG1ADDR(MALTA_MSC01_BIU_BASE) li t1, 0x0 li t2, -CONFIG_SYS_MEM_SIZE sw t1, MSC01_BIU_MCBAS1L_OFS(t0) @@ -157,7 +158,7 @@ _msc01: sw t2, MSC01_BIU_IP3MSK2L_OFS(t0) /* setup PCI memory */ - li t0, KSEG1ADDR(MALTA_MSC01_PCI_BASE) + PTR_LI t0, CKSEG1ADDR(MALTA_MSC01_PCI_BASE) li t1, MALTA_MSC01_PCIMEM_BASE li t2, (-MALTA_MSC01_PCIMEM_SIZE) & MSC01_PCI_SC2PMMSKL_MSK_MSK li t3, MALTA_MSC01_PCIMEM_MAP diff --git a/include/configs/malta.h b/include/configs/malta.h index a369678..fc4baba 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -39,14 +39,18 @@ */ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE -#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ +#ifdef CONFIG_64BIT +# define CONFIG_SYS_SDRAM_BASE 0xffffffff80000000 +#else +# define CONFIG_SYS_SDRAM_BASE 0x80000000 +#endif #define CONFIG_SYS_MEM_SIZE (256 * 1024 * 1024) #define CONFIG_SYS_INIT_SP_OFFSET 0x400000 -#define CONFIG_SYS_LOAD_ADDR 0x81000000 -#define CONFIG_SYS_MEMTEST_START 0x80100000 -#define CONFIG_SYS_MEMTEST_END 0x80800000 +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x01000000) +#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x00100000) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x00800000) #define CONFIG_SYS_MALLOC_LEN (128 * 1024) #define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) @@ -69,7 +73,11 @@ /* * Flash configuration */ -#define CONFIG_SYS_FLASH_BASE 0xbe000000 +#ifdef CONFIG_64BIT +# define CONFIG_SYS_FLASH_BASE 0xffffffffbe000000 +#else +# define CONFIG_SYS_FLASH_BASE 0xbe000000 +#endif #define CONFIG_SYS_MAX_FLASH_BANKS 1 #define CONFIG_SYS_MAX_FLASH_SECT 128 #define CONFIG_SYS_FLASH_CFI -- cgit v0.10.2 From 07f5b966aa2a4fe3a9bed8e90103cb0fe83c8748 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Thu, 26 May 2016 15:28:38 +0200 Subject: MIPS: provide a default u-boot-spl.lds Provide a default linker script for SPL binaries. Start address and size of text section and BSS section are configurable. All sections are arranged in a way that only relevant sections are kept in the code section for maximum size reduction. All other sections are kept but moved outside the code section to help with debugging. Signed-off-by: Daniel Schwierzeck Acked-by: Marek Vasut diff --git a/arch/mips/config.mk b/arch/mips/config.mk index 609a998..dcd3460 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -65,7 +65,7 @@ else PF_ABICALLS := -mabicalls PF_PIC := -fpic PF_PIE := -pie -PF_OBJCOPY := -j .got -j .u_boot_list -j .rel.dyn -j .padding +PF_OBJCOPY := -j .got -j .rel.dyn -j .padding PF_OBJCOPY += -j .dtb.init.rodata endif @@ -74,4 +74,5 @@ PLATFORM_CPPFLAGS += -msoft-float PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_FINAL += --gc-sections $(PF_PIE) -OBJCOPYFLAGS += -j .text -j .rodata -j .data $(PF_OBJCOPY) +OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list +OBJCOPYFLAGS += $(PF_OBJCOPY) diff --git a/arch/mips/cpu/u-boot-spl.lds b/arch/mips/cpu/u-boot-spl.lds new file mode 100644 index 0000000..07004ea --- /dev/null +++ b/arch/mips/cpu/u-boot-spl.lds @@ -0,0 +1,90 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : { + *(.text*) + } > .spl_mem + + . = ALIGN(4); + .rodata : { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } > .spl_mem + + . = ALIGN(4); + .data : { + *(SORT_BY_ALIGNMENT(.data*)) + *(SORT_BY_ALIGNMENT(.sdata*)) + } > .spl_mem + +#ifdef CONFIG_SPL_DM + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } > .spl_mem +#endif + + . = ALIGN(4); + __image_copy_end = .; + + .bss (NOLOAD) : { + __bss_start = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + } > .bss_mem + + .rel.dyn (NOLOAD) : { + *(.rel.dyn) + } + + .dynsym : { + *(.dynsym) + } + + .dynbss : { + *(.dynbss) + } + + .dynstr : { + *(.dynstr) + } + + .dynamic : { + *(.dynamic) + } + + .plt : { + *(.plt) + } + + .interp : { + *(.interp) + } + + .gnu : { + *(.gnu*) + } + + .MIPS.stubs : { + *(.MIPS.stubs) + } + + .hash : { + *(.hash) + } +} -- cgit v0.10.2 From 5f9cc363ed9b68245cacc6408c793f150992f4d9 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Fri, 27 May 2016 15:39:39 +0200 Subject: MIPS: add tune for MIPS 34kc Add tune Kconfig option for MIPS 34kc. Signed-off-by: Daniel Schwierzeck diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index abaeaf0..a929452 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -228,6 +228,9 @@ config MIPS_TUNE_14KC config MIPS_TUNE_24KC bool +config MIPS_TUNE_34KC + bool + config MIPS_TUNE_74KC bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 0b5dbb6..efe7e44 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -34,6 +34,7 @@ arch-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,-mips64r6 tune-$(CONFIG_MIPS_TUNE_4KC) += -mtune=4kc tune-$(CONFIG_MIPS_TUNE_14KC) += -mtune=14kc tune-$(CONFIG_MIPS_TUNE_24KC) += -mtune=24kc +tune-$(CONFIG_MIPS_TUNE_34KC) += -mtune=34kc tune-$(CONFIG_MIPS_TUNE_74KC) += -mtune=74kc # Include default header files -- cgit v0.10.2 From e40095f63b4bc0edd747c7f104d3e54db61e7d3d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 24 May 2016 23:29:09 +0200 Subject: net: Add ag7xxx driver for Atheros MIPS Add ethernet driver for the AR933x and AR934x Atheros MIPS machines. The driver could be easily extended to other WiSoCs. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger Cc: Wills Wang [fixed Kconfig dependency] Signed-off-by: Daniel Schwierzeck diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 91b7690..c1cb689 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -46,6 +46,15 @@ menuconfig NETDEVICES if NETDEVICES +config AG7XXX + bool "Atheros AG7xxx Ethernet MAC support" + depends on DM_ETH && ARCH_ATH79 + select PHYLIB + help + This driver supports the Atheros AG7xxx Ethernet MAC. This MAC is + present in the Atheros AR7xxx, AR9xxx and QCA9xxx MIPS chips. + + config ALTERA_TSE bool "Altera Triple-Speed Ethernet MAC support" depends on DM_ETH diff --git a/drivers/net/Makefile b/drivers/net/Makefile index d5e4a97..5702592 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o obj-$(CONFIG_ALTERA_TSE) += altera_tse.o +obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o diff --git a/drivers/net/ag7xxx.c b/drivers/net/ag7xxx.c new file mode 100644 index 0000000..346f138 --- /dev/null +++ b/drivers/net/ag7xxx.c @@ -0,0 +1,980 @@ +/* + * Atheros AR71xx / AR9xxx GMAC driver + * + * Copyright (C) 2016 Marek Vasut + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +DECLARE_GLOBAL_DATA_PTR; + +enum ag7xxx_model { + AG7XXX_MODEL_AG933X, + AG7XXX_MODEL_AG934X, +}; + +#define AG7XXX_ETH_CFG1 0x00 +#define AG7XXX_ETH_CFG1_SOFT_RST BIT(31) +#define AG7XXX_ETH_CFG1_RX_RST BIT(19) +#define AG7XXX_ETH_CFG1_TX_RST BIT(18) +#define AG7XXX_ETH_CFG1_LOOPBACK BIT(8) +#define AG7XXX_ETH_CFG1_RX_EN BIT(2) +#define AG7XXX_ETH_CFG1_TX_EN BIT(0) + +#define AG7XXX_ETH_CFG2 0x04 +#define AG7XXX_ETH_CFG2_IF_1000 BIT(9) +#define AG7XXX_ETH_CFG2_IF_10_100 BIT(8) +#define AG7XXX_ETH_CFG2_IF_SPEED_MASK (3 << 8) +#define AG7XXX_ETH_CFG2_HUGE_FRAME_EN BIT(5) +#define AG7XXX_ETH_CFG2_LEN_CHECK BIT(4) +#define AG7XXX_ETH_CFG2_PAD_CRC_EN BIT(2) +#define AG7XXX_ETH_CFG2_FDX BIT(0) + +#define AG7XXX_ETH_MII_MGMT_CFG 0x20 +#define AG7XXX_ETH_MII_MGMT_CFG_RESET BIT(31) + +#define AG7XXX_ETH_MII_MGMT_CMD 0x24 +#define AG7XXX_ETH_MII_MGMT_CMD_READ 0x1 + +#define AG7XXX_ETH_MII_MGMT_ADDRESS 0x28 +#define AG7XXX_ETH_MII_MGMT_ADDRESS_SHIFT 8 + +#define AG7XXX_ETH_MII_MGMT_CTRL 0x2c + +#define AG7XXX_ETH_MII_MGMT_STATUS 0x30 + +#define AG7XXX_ETH_MII_MGMT_IND 0x34 +#define AG7XXX_ETH_MII_MGMT_IND_INVALID BIT(2) +#define AG7XXX_ETH_MII_MGMT_IND_BUSY BIT(0) + +#define AG7XXX_ETH_ADDR1 0x40 +#define AG7XXX_ETH_ADDR2 0x44 + +#define AG7XXX_ETH_FIFO_CFG_0 0x48 +#define AG7XXX_ETH_FIFO_CFG_1 0x4c +#define AG7XXX_ETH_FIFO_CFG_2 0x50 +#define AG7XXX_ETH_FIFO_CFG_3 0x54 +#define AG7XXX_ETH_FIFO_CFG_4 0x58 +#define AG7XXX_ETH_FIFO_CFG_5 0x5c + +#define AG7XXX_ETH_DMA_TX_CTRL 0x180 +#define AG7XXX_ETH_DMA_TX_CTRL_TXE BIT(0) + +#define AG7XXX_ETH_DMA_TX_DESC 0x184 + +#define AG7XXX_ETH_DMA_TX_STATUS 0x188 + +#define AG7XXX_ETH_DMA_RX_CTRL 0x18c +#define AG7XXX_ETH_DMA_RX_CTRL_RXE BIT(0) + +#define AG7XXX_ETH_DMA_RX_DESC 0x190 + +#define AG7XXX_ETH_DMA_RX_STATUS 0x194 + +/* Custom register at 0x18070000 */ +#define AG7XXX_GMAC_ETH_CFG 0x00 +#define AG7XXX_ETH_CFG_SW_PHY_ADDR_SWAP BIT(8) +#define AG7XXX_ETH_CFG_SW_PHY_SWAP BIT(7) +#define AG7XXX_ETH_CFG_SW_ONLY_MODE BIT(6) +#define AG7XXX_ETH_CFG_GE0_ERR_EN BIT(5) +#define AG7XXX_ETH_CFG_MII_GE0_SLAVE BIT(4) +#define AG7XXX_ETH_CFG_MII_GE0_MASTER BIT(3) +#define AG7XXX_ETH_CFG_GMII_GE0 BIT(2) +#define AG7XXX_ETH_CFG_MII_GE0 BIT(1) +#define AG7XXX_ETH_CFG_RGMII_GE0 BIT(0) + +#define CONFIG_TX_DESCR_NUM 8 +#define CONFIG_RX_DESCR_NUM 8 +#define CONFIG_ETH_BUFSIZE 2048 +#define TX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM) +#define RX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM) + +/* DMA descriptor. */ +struct ag7xxx_dma_desc { + u32 data_addr; +#define AG7XXX_DMADESC_IS_EMPTY BIT(31) +#define AG7XXX_DMADESC_FTPP_OVERRIDE_OFFSET 16 +#define AG7XXX_DMADESC_PKT_SIZE_OFFSET 0 +#define AG7XXX_DMADESC_PKT_SIZE_MASK 0xfff + u32 config; + u32 next_desc; + u32 _pad[5]; +}; + +struct ar7xxx_eth_priv { + struct ag7xxx_dma_desc tx_mac_descrtable[CONFIG_TX_DESCR_NUM]; + struct ag7xxx_dma_desc rx_mac_descrtable[CONFIG_RX_DESCR_NUM]; + char txbuffs[TX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN); + char rxbuffs[RX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN); + + void __iomem *regs; + void __iomem *phyregs; + + struct eth_device *dev; + struct phy_device *phydev; + struct mii_dev *bus; + + u32 interface; + u32 tx_currdescnum; + u32 rx_currdescnum; + enum ag7xxx_model model; +}; + +/* + * Switch and MDIO access + */ +static int ag7xxx_switch_read(struct mii_dev *bus, int addr, int reg, u16 *val) +{ + struct ar7xxx_eth_priv *priv = bus->priv; + void __iomem *regs = priv->phyregs; + int ret; + + writel(0x0, regs + AG7XXX_ETH_MII_MGMT_CMD); + writel((addr << AG7XXX_ETH_MII_MGMT_ADDRESS_SHIFT) | reg, + regs + AG7XXX_ETH_MII_MGMT_ADDRESS); + writel(AG7XXX_ETH_MII_MGMT_CMD_READ, + regs + AG7XXX_ETH_MII_MGMT_CMD); + + ret = wait_for_bit("ag7xxx", regs + AG7XXX_ETH_MII_MGMT_IND, + AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0); + if (ret) + return ret; + + *val = readl(regs + AG7XXX_ETH_MII_MGMT_STATUS) & 0xffff; + writel(0x0, regs + AG7XXX_ETH_MII_MGMT_CMD); + + return 0; +} + +static int ag7xxx_switch_write(struct mii_dev *bus, int addr, int reg, u16 val) +{ + struct ar7xxx_eth_priv *priv = bus->priv; + void __iomem *regs = priv->phyregs; + int ret; + + writel((addr << AG7XXX_ETH_MII_MGMT_ADDRESS_SHIFT) | reg, + regs + AG7XXX_ETH_MII_MGMT_ADDRESS); + writel(val, regs + AG7XXX_ETH_MII_MGMT_CTRL); + + ret = wait_for_bit("ag7xxx", regs + AG7XXX_ETH_MII_MGMT_IND, + AG7XXX_ETH_MII_MGMT_IND_BUSY, 0, 1000, 0); + + return ret; +} + +static int ag7xxx_switch_reg_read(struct mii_dev *bus, int reg, u32 *val) +{ + struct ar7xxx_eth_priv *priv = bus->priv; + u32 phy_addr; + u32 reg_addr; + u32 phy_temp; + u32 reg_temp; + u16 rv = 0; + int ret; + + if (priv->model == AG7XXX_MODEL_AG933X) { + phy_addr = 0x1f; + reg_addr = 0x10; + } else if (priv->model == AG7XXX_MODEL_AG934X) { + phy_addr = 0x18; + reg_addr = 0x00; + } else + return -EINVAL; + + ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9); + if (ret) + return ret; + + phy_temp = ((reg >> 6) & 0x7) | 0x10; + reg_temp = (reg >> 1) & 0x1e; + *val = 0; + + ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 0, &rv); + if (ret < 0) + return ret; + *val |= rv; + + ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 1, &rv); + if (ret < 0) + return ret; + *val |= (rv << 16); + + return 0; +} + +static int ag7xxx_switch_reg_write(struct mii_dev *bus, int reg, u32 val) +{ + struct ar7xxx_eth_priv *priv = bus->priv; + u32 phy_addr; + u32 reg_addr; + u32 phy_temp; + u32 reg_temp; + int ret; + + if (priv->model == AG7XXX_MODEL_AG933X) { + phy_addr = 0x1f; + reg_addr = 0x10; + } else if (priv->model == AG7XXX_MODEL_AG934X) { + phy_addr = 0x18; + reg_addr = 0x00; + } else + return -EINVAL; + + ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9); + if (ret) + return ret; + + phy_temp = ((reg >> 6) & 0x7) | 0x10; + reg_temp = (reg >> 1) & 0x1e; + + /* + * The switch on AR933x has some special register behavior, which + * expects particular write order of their nibbles: + * 0x40 ..... MSB first, LSB second + * 0x50 ..... MSB first, LSB second + * 0x98 ..... LSB first, MSB second + * others ... don't care + */ + if ((priv->model == AG7XXX_MODEL_AG933X) && (reg == 0x98)) { + ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 0, val & 0xffff); + if (ret < 0) + return ret; + + ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 1, val >> 16); + if (ret < 0) + return ret; + } else { + ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 1, val >> 16); + if (ret < 0) + return ret; + + ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 0, val & 0xffff); + if (ret < 0) + return ret; + } + + return 0; +} + +static u16 ag7xxx_mdio_rw(struct mii_dev *bus, int addr, int reg, u32 val) +{ + u32 data; + + /* Dummy read followed by PHY read/write command. */ + ag7xxx_switch_reg_read(bus, 0x98, &data); + data = val | (reg << 16) | (addr << 21) | BIT(30) | BIT(31); + ag7xxx_switch_reg_write(bus, 0x98, data); + + /* Wait for operation to finish */ + do { + ag7xxx_switch_reg_read(bus, 0x98, &data); + } while (data & BIT(31)); + + return data & 0xffff; +} + +static int ag7xxx_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) +{ + return ag7xxx_mdio_rw(bus, addr, reg, BIT(27)); +} + +static int ag7xxx_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 val) +{ + ag7xxx_mdio_rw(bus, addr, reg, val); + return 0; +} + +/* + * DMA ring handlers + */ +static void ag7xxx_dma_clean_tx(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + struct ag7xxx_dma_desc *curr, *next; + u32 start, end; + int i; + + for (i = 0; i < CONFIG_TX_DESCR_NUM; i++) { + curr = &priv->tx_mac_descrtable[i]; + next = &priv->tx_mac_descrtable[(i + 1) % CONFIG_TX_DESCR_NUM]; + + curr->data_addr = virt_to_phys(&priv->txbuffs[i * CONFIG_ETH_BUFSIZE]); + curr->config = AG7XXX_DMADESC_IS_EMPTY; + curr->next_desc = virt_to_phys(next); + } + + priv->tx_currdescnum = 0; + + /* Cache: Flush descriptors, don't care about buffers. */ + start = (u32)(&priv->tx_mac_descrtable[0]); + end = start + sizeof(priv->tx_mac_descrtable); + flush_dcache_range(start, end); +} + +static void ag7xxx_dma_clean_rx(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + struct ag7xxx_dma_desc *curr, *next; + u32 start, end; + int i; + + for (i = 0; i < CONFIG_RX_DESCR_NUM; i++) { + curr = &priv->rx_mac_descrtable[i]; + next = &priv->rx_mac_descrtable[(i + 1) % CONFIG_RX_DESCR_NUM]; + + curr->data_addr = virt_to_phys(&priv->rxbuffs[i * CONFIG_ETH_BUFSIZE]); + curr->config = AG7XXX_DMADESC_IS_EMPTY; + curr->next_desc = virt_to_phys(next); + } + + priv->rx_currdescnum = 0; + + /* Cache: Flush+Invalidate descriptors, Invalidate buffers. */ + start = (u32)(&priv->rx_mac_descrtable[0]); + end = start + sizeof(priv->rx_mac_descrtable); + flush_dcache_range(start, end); + invalidate_dcache_range(start, end); + + start = (u32)&priv->rxbuffs; + end = start + sizeof(priv->rxbuffs); + invalidate_dcache_range(start, end); +} + +/* + * Ethernet I/O + */ +static int ag7xxx_eth_send(struct udevice *dev, void *packet, int length) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + struct ag7xxx_dma_desc *curr; + u32 start, end; + + curr = &priv->tx_mac_descrtable[priv->tx_currdescnum]; + + /* Cache: Invalidate descriptor. */ + start = (u32)curr; + end = start + sizeof(*curr); + invalidate_dcache_range(start, end); + + if (!(curr->config & AG7XXX_DMADESC_IS_EMPTY)) { + printf("ag7xxx: Out of TX DMA descriptors!\n"); + return -EPERM; + } + + /* Copy the packet into the data buffer. */ + memcpy(phys_to_virt(curr->data_addr), packet, length); + curr->config = length & AG7XXX_DMADESC_PKT_SIZE_MASK; + + /* Cache: Flush descriptor, Flush buffer. */ + start = (u32)curr; + end = start + sizeof(*curr); + flush_dcache_range(start, end); + start = (u32)phys_to_virt(curr->data_addr); + end = start + length; + flush_dcache_range(start, end); + + /* Load the DMA descriptor and start TX DMA. */ + writel(AG7XXX_ETH_DMA_TX_CTRL_TXE, + priv->regs + AG7XXX_ETH_DMA_TX_CTRL); + + /* Switch to next TX descriptor. */ + priv->tx_currdescnum = (priv->tx_currdescnum + 1) % CONFIG_TX_DESCR_NUM; + + return 0; +} + +static int ag7xxx_eth_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + struct ag7xxx_dma_desc *curr; + u32 start, end, length; + + curr = &priv->rx_mac_descrtable[priv->rx_currdescnum]; + + /* Cache: Invalidate descriptor. */ + start = (u32)curr; + end = start + sizeof(*curr); + invalidate_dcache_range(start, end); + + /* No packets received. */ + if (curr->config & AG7XXX_DMADESC_IS_EMPTY) + return -EAGAIN; + + length = curr->config & AG7XXX_DMADESC_PKT_SIZE_MASK; + + /* Cache: Invalidate buffer. */ + start = (u32)phys_to_virt(curr->data_addr); + end = start + length; + invalidate_dcache_range(start, end); + + /* Receive one packet and return length. */ + *packetp = phys_to_virt(curr->data_addr); + return length; +} + +static int ag7xxx_eth_free_pkt(struct udevice *dev, uchar *packet, + int length) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + struct ag7xxx_dma_desc *curr; + u32 start, end; + + curr = &priv->rx_mac_descrtable[priv->rx_currdescnum]; + + curr->config = AG7XXX_DMADESC_IS_EMPTY; + + /* Cache: Flush descriptor. */ + start = (u32)curr; + end = start + sizeof(*curr); + flush_dcache_range(start, end); + + /* Switch to next RX descriptor. */ + priv->rx_currdescnum = (priv->rx_currdescnum + 1) % CONFIG_RX_DESCR_NUM; + + return 0; +} + +static int ag7xxx_eth_start(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + + /* FIXME: Check if link up */ + + /* Clear the DMA rings. */ + ag7xxx_dma_clean_tx(dev); + ag7xxx_dma_clean_rx(dev); + + /* Load DMA descriptors and start the RX DMA. */ + writel(virt_to_phys(&priv->tx_mac_descrtable[priv->tx_currdescnum]), + priv->regs + AG7XXX_ETH_DMA_TX_DESC); + writel(virt_to_phys(&priv->rx_mac_descrtable[priv->rx_currdescnum]), + priv->regs + AG7XXX_ETH_DMA_RX_DESC); + writel(AG7XXX_ETH_DMA_RX_CTRL_RXE, + priv->regs + AG7XXX_ETH_DMA_RX_CTRL); + + return 0; +} + +static void ag7xxx_eth_stop(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + + /* Stop the TX DMA. */ + writel(0, priv->regs + AG7XXX_ETH_DMA_TX_CTRL); + wait_for_bit("ag7xxx", priv->regs + AG7XXX_ETH_DMA_TX_CTRL, ~0, 0, + 1000, 0); + + /* Stop the RX DMA. */ + writel(0, priv->regs + AG7XXX_ETH_DMA_RX_CTRL); + wait_for_bit("ag7xxx", priv->regs + AG7XXX_ETH_DMA_RX_CTRL, ~0, 0, + 1000, 0); +} + +/* + * Hardware setup + */ +static int ag7xxx_eth_write_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + unsigned char *mac = pdata->enetaddr; + u32 macid_lo, macid_hi; + + macid_hi = mac[3] | (mac[2] << 8) | (mac[1] << 16) | (mac[0] << 24); + macid_lo = (mac[5] << 16) | (mac[4] << 24); + + writel(macid_lo, priv->regs + AG7XXX_ETH_ADDR1); + writel(macid_hi, priv->regs + AG7XXX_ETH_ADDR2); + + return 0; +} + +static void ag7xxx_hw_setup(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + u32 speed; + + setbits_be32(priv->regs + AG7XXX_ETH_CFG1, + AG7XXX_ETH_CFG1_RX_RST | AG7XXX_ETH_CFG1_TX_RST | + AG7XXX_ETH_CFG1_SOFT_RST); + + mdelay(10); + + writel(AG7XXX_ETH_CFG1_RX_EN | AG7XXX_ETH_CFG1_TX_EN, + priv->regs + AG7XXX_ETH_CFG1); + + if (priv->interface == PHY_INTERFACE_MODE_RMII) + speed = AG7XXX_ETH_CFG2_IF_10_100; + else + speed = AG7XXX_ETH_CFG2_IF_1000; + + clrsetbits_be32(priv->regs + AG7XXX_ETH_CFG2, + AG7XXX_ETH_CFG2_IF_SPEED_MASK, + speed | AG7XXX_ETH_CFG2_PAD_CRC_EN | + AG7XXX_ETH_CFG2_LEN_CHECK); + + writel(0xfff0000, priv->regs + AG7XXX_ETH_FIFO_CFG_1); + writel(0x1fff, priv->regs + AG7XXX_ETH_FIFO_CFG_2); + + writel(0x1f00, priv->regs + AG7XXX_ETH_FIFO_CFG_0); + setbits_be32(priv->regs + AG7XXX_ETH_FIFO_CFG_4, 0x3ffff); + writel(0x10ffff, priv->regs + AG7XXX_ETH_FIFO_CFG_1); + writel(0xaaa0555, priv->regs + AG7XXX_ETH_FIFO_CFG_2); + writel(0x7eccf, priv->regs + AG7XXX_ETH_FIFO_CFG_5); + writel(0x1f00140, priv->regs + AG7XXX_ETH_FIFO_CFG_3); +} + +static int ag7xxx_mii_get_div(void) +{ + ulong freq = get_bus_freq(0); + + switch (freq / 1000000) { + case 150: return 0x7; + case 175: return 0x5; + case 200: return 0x4; + case 210: return 0x9; + case 220: return 0x9; + default: return 0x7; + } +} + +static int ag7xxx_mii_setup(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int i, ret, div = ag7xxx_mii_get_div(); + u32 reg; + + if (priv->model == AG7XXX_MODEL_AG933X) { + /* Unit 0 is PHY-less on AR9331, see datasheet Figure 2-3 */ + if (priv->interface == PHY_INTERFACE_MODE_RMII) + return 0; + } + + if (priv->model == AG7XXX_MODEL_AG934X) { + writel(AG7XXX_ETH_MII_MGMT_CFG_RESET | 0x4, + priv->regs + AG7XXX_ETH_MII_MGMT_CFG); + writel(0x4, priv->regs + AG7XXX_ETH_MII_MGMT_CFG); + return 0; + } + + for (i = 0; i < 10; i++) { + writel(AG7XXX_ETH_MII_MGMT_CFG_RESET | div, + priv->regs + AG7XXX_ETH_MII_MGMT_CFG); + writel(div, priv->regs + AG7XXX_ETH_MII_MGMT_CFG); + + /* Check the switch */ + ret = ag7xxx_switch_reg_read(priv->bus, 0x10c, ®); + if (ret) + continue; + + if (reg != 0x18007fff) + continue; + + return 0; + } + + return -EINVAL; +} + +static int ag933x_phy_setup_wan(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + + /* Configure switch port 4 (GMAC0) */ + return ag7xxx_mdio_write(priv->bus, 4, 0, MII_BMCR, 0x9000); +} + +static int ag933x_phy_setup_lan(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int i, ret; + u32 reg; + + /* Reset the switch */ + ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); + if (ret) + return ret; + reg |= BIT(31); + ret = ag7xxx_switch_reg_write(priv->bus, 0, reg); + if (ret) + return ret; + + do { + ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); + if (ret) + return ret; + } while (reg & BIT(31)); + + /* Configure switch ports 0...3 (GMAC1) */ + for (i = 0; i < 4; i++) { + ret = ag7xxx_mdio_write(priv->bus, 0x4, 0, MII_BMCR, 0x9000); + if (ret) + return ret; + } + + /* Enable CPU port */ + ret = ag7xxx_switch_reg_write(priv->bus, 0x78, BIT(8)); + if (ret) + return ret; + + for (i = 0; i < 4; i++) { + ret = ag7xxx_switch_reg_write(priv->bus, i * 0x100, BIT(9)); + if (ret) + return ret; + } + + /* QM Control */ + ret = ag7xxx_switch_reg_write(priv->bus, 0x38, 0xc000050e); + if (ret) + return ret; + + /* Disable Atheros header */ + ret = ag7xxx_switch_reg_write(priv->bus, 0x104, 0x4004); + if (ret) + return ret; + + /* Tag priority mapping */ + ret = ag7xxx_switch_reg_write(priv->bus, 0x70, 0xfa50); + if (ret) + return ret; + + /* Enable ARP packets to the CPU */ + ret = ag7xxx_switch_reg_read(priv->bus, 0x5c, ®); + if (ret) + return ret; + reg |= 0x100000; + ret = ag7xxx_switch_reg_write(priv->bus, 0x5c, reg); + if (ret) + return ret; + + return 0; +} + +static int ag933x_phy_setup_reset_set(struct udevice *dev, int port) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int ret; + + ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_ADVERTISE, + ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | + ADVERTISE_PAUSE_ASYM); + if (ret) + return ret; + + if (priv->model == AG7XXX_MODEL_AG934X) { + ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_CTRL1000, + ADVERTISE_1000FULL); + if (ret) + return ret; + } + + return ag7xxx_mdio_write(priv->bus, port, 0, MII_BMCR, + BMCR_ANENABLE | BMCR_RESET); +} + +static int ag933x_phy_setup_reset_fin(struct udevice *dev, int port) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int ret; + + do { + ret = ag7xxx_mdio_read(priv->bus, port, 0, MII_BMCR); + if (ret < 0) + return ret; + mdelay(10); + } while (ret & BMCR_RESET); + + return 0; +} + +static int ag933x_phy_setup_common(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int i, ret, phymax; + + if (priv->model == AG7XXX_MODEL_AG933X) + phymax = 4; + else if (priv->model == AG7XXX_MODEL_AG934X) + phymax = 5; + else + return -EINVAL; + + if (priv->interface == PHY_INTERFACE_MODE_RMII) { + ret = ag933x_phy_setup_reset_set(dev, phymax); + if (ret) + return ret; + + ret = ag933x_phy_setup_reset_fin(dev, phymax); + if (ret) + return ret; + + /* Read out link status */ + ret = ag7xxx_mdio_read(priv->bus, phymax, 0, MII_MIPSCR); + if (ret < 0) + return ret; + + return 0; + } + + /* Switch ports */ + for (i = 0; i < phymax; i++) { + ret = ag933x_phy_setup_reset_set(dev, i); + if (ret) + return ret; + } + + for (i = 0; i < phymax; i++) { + ret = ag933x_phy_setup_reset_fin(dev, i); + if (ret) + return ret; + } + + for (i = 0; i < phymax; i++) { + /* Read out link status */ + ret = ag7xxx_mdio_read(priv->bus, i, 0, MII_MIPSCR); + if (ret < 0) + return ret; + } + + return 0; +} + +static int ag934x_phy_setup(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int i, ret; + u32 reg; + + ret = ag7xxx_switch_reg_write(priv->bus, 0x624, 0x7f7f7f7f); + if (ret) + return ret; + ret = ag7xxx_switch_reg_write(priv->bus, 0x10, 0x40000000); + if (ret) + return ret; + ret = ag7xxx_switch_reg_write(priv->bus, 0x4, 0x07600000); + if (ret) + return ret; + ret = ag7xxx_switch_reg_write(priv->bus, 0xc, 0x01000000); + if (ret) + return ret; + ret = ag7xxx_switch_reg_write(priv->bus, 0x7c, 0x0000007e); + if (ret) + return ret; + + /* AR8327/AR8328 v1.0 fixup */ + ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); + if (ret) + return ret; + if ((reg & 0xffff) == 0x1201) { + for (i = 0; i < 5; i++) { + ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1d, 0x0); + if (ret) + return ret; + ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1e, 0x02ea); + if (ret) + return ret; + ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1d, 0x3d); + if (ret) + return ret; + ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1e, 0x68a0); + if (ret) + return ret; + } + } + + ret = ag7xxx_switch_reg_read(priv->bus, 0x66c, ®); + if (ret) + return ret; + reg &= ~0x70000; + ret = ag7xxx_switch_reg_write(priv->bus, 0x66c, reg); + if (ret) + return ret; + + return 0; +} + +static int ag7xxx_mac_probe(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int ret; + + ag7xxx_hw_setup(dev); + ret = ag7xxx_mii_setup(dev); + if (ret) + return ret; + + ag7xxx_eth_write_hwaddr(dev); + + if (priv->model == AG7XXX_MODEL_AG933X) { + if (priv->interface == PHY_INTERFACE_MODE_RMII) + ret = ag933x_phy_setup_wan(dev); + else + ret = ag933x_phy_setup_lan(dev); + } else if (priv->model == AG7XXX_MODEL_AG934X) { + ret = ag934x_phy_setup(dev); + } else { + return -EINVAL; + } + + if (ret) + return ret; + + return ag933x_phy_setup_common(dev); +} + +static int ag7xxx_mdio_probe(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + struct mii_dev *bus = mdio_alloc(); + + if (!bus) + return -ENOMEM; + + bus->read = ag7xxx_mdio_read; + bus->write = ag7xxx_mdio_write; + snprintf(bus->name, sizeof(bus->name), dev->name); + + bus->priv = (void *)priv; + + return mdio_register(bus); +} + +static int ag7xxx_get_phy_iface_offset(struct udevice *dev) +{ + int offset; + + offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phy"); + if (offset <= 0) { + debug("%s: PHY OF node not found (ret=%i)\n", __func__, offset); + return -EINVAL; + } + + offset = fdt_parent_offset(gd->fdt_blob, offset); + if (offset <= 0) { + debug("%s: PHY OF node parent MDIO bus not found (ret=%i)\n", + __func__, offset); + return -EINVAL; + } + + offset = fdt_parent_offset(gd->fdt_blob, offset); + if (offset <= 0) { + debug("%s: PHY MDIO OF node parent MAC not found (ret=%i)\n", + __func__, offset); + return -EINVAL; + } + + return offset; +} + +static int ag7xxx_eth_probe(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + void __iomem *iobase, *phyiobase; + int ret, phyreg; + + /* Decoding of convoluted PHY wiring on Atheros MIPS. */ + ret = ag7xxx_get_phy_iface_offset(dev); + if (ret <= 0) + return ret; + phyreg = fdtdec_get_int(gd->fdt_blob, ret, "reg", -1); + + iobase = map_physmem(pdata->iobase, 0x200, MAP_NOCACHE); + phyiobase = map_physmem(phyreg, 0x200, MAP_NOCACHE); + + debug("%s, iobase=%p, phyiobase=%p, priv=%p\n", + __func__, iobase, phyiobase, priv); + priv->regs = iobase; + priv->phyregs = phyiobase; + priv->interface = pdata->phy_interface; + priv->model = dev_get_driver_data(dev); + + ret = ag7xxx_mdio_probe(dev); + if (ret) + return ret; + + priv->bus = miiphy_get_dev_by_name(dev->name); + + ret = ag7xxx_mac_probe(dev); + debug("%s, ret=%d\n", __func__, ret); + + return ret; +} + +static int ag7xxx_eth_remove(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + + free(priv->phydev); + mdio_unregister(priv->bus); + mdio_free(priv->bus); + + return 0; +} + +static const struct eth_ops ag7xxx_eth_ops = { + .start = ag7xxx_eth_start, + .send = ag7xxx_eth_send, + .recv = ag7xxx_eth_recv, + .free_pkt = ag7xxx_eth_free_pkt, + .stop = ag7xxx_eth_stop, + .write_hwaddr = ag7xxx_eth_write_hwaddr, +}; + +static int ag7xxx_eth_ofdata_to_platdata(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + const char *phy_mode; + int ret; + + pdata->iobase = dev_get_addr(dev); + pdata->phy_interface = -1; + + /* Decoding of convoluted PHY wiring on Atheros MIPS. */ + ret = ag7xxx_get_phy_iface_offset(dev); + if (ret <= 0) + return ret; + + phy_mode = fdt_getprop(gd->fdt_blob, ret, "phy-mode", NULL); + if (phy_mode) + pdata->phy_interface = phy_get_interface_by_name(phy_mode); + if (pdata->phy_interface == -1) { + debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); + return -EINVAL; + } + + return 0; +} + +static const struct udevice_id ag7xxx_eth_ids[] = { + { .compatible = "qca,ag933x-mac", .data = AG7XXX_MODEL_AG933X }, + { .compatible = "qca,ag934x-mac", .data = AG7XXX_MODEL_AG934X }, + { } +}; + +U_BOOT_DRIVER(eth_ag7xxx) = { + .name = "eth_ag7xxx", + .id = UCLASS_ETH, + .of_match = ag7xxx_eth_ids, + .ofdata_to_platdata = ag7xxx_eth_ofdata_to_platdata, + .probe = ag7xxx_eth_probe, + .remove = ag7xxx_eth_remove, + .ops = &ag7xxx_eth_ops, + .priv_auto_alloc_size = sizeof(struct ar7xxx_eth_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; -- cgit v0.10.2 From 83b0face8c710f719445f3c282c2ca6fad326bd7 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Fri, 27 May 2016 15:31:34 +0200 Subject: MIPS: remove dead code from asm/u-boot-mips.h Those wrappers for linker symbols were once used in the MIPS specific board.c implementation. Since the migration to generic board.c, those wrappers are dead code and can be removed. Signed-off-by: Daniel Schwierzeck diff --git a/arch/mips/include/asm/u-boot-mips.h b/arch/mips/include/asm/u-boot-mips.h index a5b2fc0..1f527bb 100644 --- a/arch/mips/include/asm/u-boot-mips.h +++ b/arch/mips/include/asm/u-boot-mips.h @@ -1,23 +1,8 @@ /* * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de */ -static inline unsigned long bss_start(void) -{ - extern char __bss_start[]; - return (unsigned long) &__bss_start; -} +#ifndef _U_BOOT_MIPS_H_ +#define _U_BOOT_MIPS_H_ -static inline unsigned long bss_end(void) -{ - extern ulong __bss_end; - return (unsigned long) &__bss_end; -} - -static inline unsigned long image_copy_end(void) -{ - extern char __image_copy_end[]; - return (unsigned long) &__image_copy_end; -} +#endif /* _U_BOOT_MIPS_H_ */ -- cgit v0.10.2 From ace3be4f15875d74344336b9754c14274f940969 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 27 May 2016 14:28:04 +0100 Subject: MIPS: Move cache sizes to Kconfig Move details of the L1 cache line sizes & total sizes into Kconfig, defaulting to 0. A new CONFIG_SYS_CACHE_SIZE_AUTO Kconfig entry is introduced to allow platforms to select auto-detection of cache sizes, and it defaults to being enabled if none of the cache sizes are set by the configuration (ie. sizes are all the default 0), and code is adjusted to #ifdef on that rather than on the definition of the sizes (which will always be defined even if 0). Signed-off-by: Paul Burton diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a929452..a79224e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -246,6 +246,34 @@ config SWAP_IO_SPACE config SYS_MIPS_CACHE_INIT_RAM_LOAD bool +config SYS_DCACHE_SIZE + int + default 0 + help + The total size of the L1 Dcache, if known at compile time. + +config SYS_ICACHE_SIZE + int + default 0 + help + The total size of the L1 ICache, if known at compile time. + +config SYS_CACHELINE_SIZE + int + default 0 + help + The size of L1 cache lines, if known at compile time. + +config SYS_CACHE_SIZE_AUTO + def_bool y if SYS_DCACHE_SIZE = 0 && SYS_ICACHE_SIZE = 0 && \ + SYS_CACHELINE_SIZE = 0 + help + Select this (or let it be auto-selected by not defining any cache + sizes) in order to allow U-Boot to automatically detect the sizes + of caches at runtime. This has a small cost in code size & runtime + so if you know the cache configuration for your system at compile + time it would be beneficial to configure it. + config MIPS_L1_CACHE_SHIFT_4 bool diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index 7482005..fbaafee 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -9,7 +9,7 @@ #include #include -#ifdef CONFIG_SYS_CACHELINE_SIZE +#ifndef CONFIG_SYS_CACHE_SIZE_AUTO static inline unsigned long icache_line_size(void) { diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index 08b7c3a..4bb9a17 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -99,14 +99,14 @@ * */ LEAF(mips_cache_reset) -#ifdef CONFIG_SYS_ICACHE_SIZE +#ifndef CONFIG_SYS_CACHE_SIZE_AUTO li t2, CONFIG_SYS_ICACHE_SIZE li t8, CONFIG_SYS_CACHELINE_SIZE #else l1_info t2, t8, MIPS_CONF1_IA_SHF #endif -#ifdef CONFIG_SYS_DCACHE_SIZE +#ifndef CONFIG_SYS_CACHE_SIZE_AUTO li t3, CONFIG_SYS_DCACHE_SIZE li t9, CONFIG_SYS_CACHELINE_SIZE #else @@ -116,7 +116,7 @@ LEAF(mips_cache_reset) #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* Determine the largest L1 cache size */ -#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE) +#ifndef CONFIG_SYS_CACHE_SIZE_AUTO #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE li v0, CONFIG_SYS_ICACHE_SIZE #else diff --git a/board/dbau1x00/Kconfig b/board/dbau1x00/Kconfig index 342ec59..1715a28 100644 --- a/board/dbau1x00/Kconfig +++ b/board/dbau1x00/Kconfig @@ -12,6 +12,15 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0xbfc00000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + menu "dbau1x00 board options" choice diff --git a/board/micronas/vct/Kconfig b/board/micronas/vct/Kconfig index 535a77b..5bb6f03 100644 --- a/board/micronas/vct/Kconfig +++ b/board/micronas/vct/Kconfig @@ -12,6 +12,15 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x87000000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + menu "vct board options" choice diff --git a/board/pb1x00/Kconfig b/board/pb1x00/Kconfig index 236a410..27b2ef0 100644 --- a/board/pb1x00/Kconfig +++ b/board/pb1x00/Kconfig @@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x83800000 +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + endif diff --git a/board/qca/ap121/Kconfig b/board/qca/ap121/Kconfig index c3ecc8f..f28ea1c 100644 --- a/board/qca/ap121/Kconfig +++ b/board/qca/ap121/Kconfig @@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x9f000000 +config SYS_DCACHE_SIZE + default 32768 + +config SYS_ICACHE_SIZE + default 65536 + +config SYS_CACHELINE_SIZE + default 32 + endif diff --git a/board/qca/ap143/Kconfig b/board/qca/ap143/Kconfig index 5ea5d6f..ff02236 100644 --- a/board/qca/ap143/Kconfig +++ b/board/qca/ap143/Kconfig @@ -12,4 +12,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0x9f000000 +config SYS_DCACHE_SIZE + default 32768 + +config SYS_ICACHE_SIZE + default 65536 + +config SYS_CACHELINE_SIZE + default 32 + endif diff --git a/board/qemu-mips/Kconfig b/board/qemu-mips/Kconfig index 3de1f44..66957e7 100644 --- a/board/qemu-mips/Kconfig +++ b/board/qemu-mips/Kconfig @@ -11,4 +11,13 @@ config SYS_TEXT_BASE default 0xbfc00000 if 32BIT default 0xffffffffbfc00000 if 64BIT +config SYS_DCACHE_SIZE + default 16384 + +config SYS_ICACHE_SIZE + default 16384 + +config SYS_CACHELINE_SIZE + default 32 + endif diff --git a/board/tplink/wdr4300/Kconfig b/board/tplink/wdr4300/Kconfig index 65785bd..ded7f9b 100644 --- a/board/tplink/wdr4300/Kconfig +++ b/board/tplink/wdr4300/Kconfig @@ -15,4 +15,13 @@ config SYS_CONFIG_NAME config SYS_TEXT_BASE default 0xa1000000 +config SYS_DCACHE_SIZE + default 32768 + +config SYS_ICACHE_SIZE + default 65536 + +config SYS_CACHELINE_SIZE + default 32 + endif diff --git a/include/configs/ap121.h b/include/configs/ap121.h index 6f69f31..f069d50 100644 --- a/include/configs/ap121.h +++ b/include/configs/ap121.h @@ -15,11 +15,6 @@ #define CONFIG_SYS_MHZ 200 #define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 - #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MALLOC_LEN 0x40000 diff --git a/include/configs/ap143.h b/include/configs/ap143.h index f907c02..e45f743 100644 --- a/include/configs/ap143.h +++ b/include/configs/ap143.h @@ -15,11 +15,6 @@ #define CONFIG_SYS_MHZ 325 #define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 - #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MALLOC_LEN 0x40000 diff --git a/include/configs/dbau1x00.h b/include/configs/dbau1x00.h index 68d9e36..68ff025 100644 --- a/include/configs/dbau1x00.h +++ b/include/configs/dbau1x00.h @@ -202,11 +202,4 @@ #define CONFIG_SYS_ATA_ALT_OFFSET 0x0100 #endif /* CONFIG_DBAU1550 */ -/*----------------------------------------------------------------------- - * Cache Configuration - */ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 - #endif /* __CONFIG_H */ diff --git a/include/configs/pb1x00.h b/include/configs/pb1x00.h index 869768a..b907419 100644 --- a/include/configs/pb1x00.h +++ b/include/configs/pb1x00.h @@ -144,12 +144,6 @@ #define CONFIG_SYS_ATA_ALT_OFFSET 0x0100 #endif -/*----------------------------------------------------------------------- - * Cache Configuration - */ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 /* * BOOTP options diff --git a/include/configs/qemu-mips.h b/include/configs/qemu-mips.h index 246ee01..f58fc4c 100644 --- a/include/configs/qemu-mips.h +++ b/include/configs/qemu-mips.h @@ -132,11 +132,4 @@ #define CONFIG_LZMA -/*----------------------------------------------------------------------- - * Cache Configuration - */ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 - #endif /* __CONFIG_H */ diff --git a/include/configs/qemu-mips64.h b/include/configs/qemu-mips64.h index 60a3a71..2190d16 100644 --- a/include/configs/qemu-mips64.h +++ b/include/configs/qemu-mips64.h @@ -132,11 +132,4 @@ #define CONFIG_LZMA -/*----------------------------------------------------------------------- - * Cache Configuration - */ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 - #endif /* __CONFIG_H */ diff --git a/include/configs/tplink_wdr4300.h b/include/configs/tplink_wdr4300.h index 09a69fe..6273711 100644 --- a/include/configs/tplink_wdr4300.h +++ b/include/configs/tplink_wdr4300.h @@ -15,11 +15,6 @@ #define CONFIG_SYS_MHZ 280 #define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) -/* Cache Configuration */ -#define CONFIG_SYS_DCACHE_SIZE 0x8000 -#define CONFIG_SYS_ICACHE_SIZE 0x10000 -#define CONFIG_SYS_CACHELINE_SIZE 32 - #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MALLOC_LEN 0x40000 diff --git a/include/configs/vct.h b/include/configs/vct.h index 68eb089..cc5e354 100644 --- a/include/configs/vct.h +++ b/include/configs/vct.h @@ -204,13 +204,6 @@ #endif /* CONFIG_VCT_ONENAND */ /* - * Cache Configuration - */ -#define CONFIG_SYS_DCACHE_SIZE 16384 -#define CONFIG_SYS_ICACHE_SIZE 16384 -#define CONFIG_SYS_CACHELINE_SIZE 32 - -/* * I2C/EEPROM */ #define CONFIG_SYS_I2C -- cgit v0.10.2 From 372286217f050bfd57695001d59f618c52822f40 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 27 May 2016 14:28:05 +0100 Subject: MIPS: Split I & D cache line size config Allow L1 Icache & L1 Dcache line size to be specified separately, since there's no architectural mandate that they be the same. The [id]cache_line_size functions are tidied up to take advantage of the fact that the Kconfig entries are always present to simply check them for zero rather than needing to #ifdef on their presence. Signed-off-by: Paul Burton [removed CONFIG_SYS_CACHELINE_SIZE in include/configs/pic32mzdask.h] Signed-off-by: Daniel Schwierzeck diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a79224e..5c30ae9 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -252,21 +252,27 @@ config SYS_DCACHE_SIZE help The total size of the L1 Dcache, if known at compile time. +config SYS_DCACHE_LINE_SIZE + hex + default 0 + help + The size of L1 Dcache lines, if known at compile time. + config SYS_ICACHE_SIZE int default 0 help The total size of the L1 ICache, if known at compile time. -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE int default 0 help - The size of L1 cache lines, if known at compile time. + The size of L1 Icache lines, if known at compile time. config SYS_CACHE_SIZE_AUTO def_bool y if SYS_DCACHE_SIZE = 0 && SYS_ICACHE_SIZE = 0 && \ - SYS_CACHELINE_SIZE = 0 + SYS_DCACHE_LINE_SIZE = 0 && SYS_ICACHE_LINE_SIZE = 0 help Select this (or let it be auto-selected by not defining any cache sizes) in order to allow U-Boot to automatically detect the sizes diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h index 806bd26..0cea581 100644 --- a/arch/mips/include/asm/cache.h +++ b/arch/mips/include/asm/cache.h @@ -12,4 +12,11 @@ #define ARCH_DMA_MINALIGN (L1_CACHE_BYTES) +/* + * CONFIG_SYS_CACHELINE_SIZE is still used in various drivers primarily for + * DMA buffer alignment. Satisfy those drivers by providing it as a synonym + * of ARCH_DMA_MINALIGN for now. + */ +#define CONFIG_SYS_CACHELINE_SIZE ARCH_DMA_MINALIGN + #endif /* __MIPS_CACHE_H__ */ diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index fbaafee..19a42ff 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -9,23 +9,13 @@ #include #include -#ifndef CONFIG_SYS_CACHE_SIZE_AUTO - static inline unsigned long icache_line_size(void) { - return CONFIG_SYS_CACHELINE_SIZE; -} - -static inline unsigned long dcache_line_size(void) -{ - return CONFIG_SYS_CACHELINE_SIZE; -} + unsigned long conf1, il; -#else /* !CONFIG_SYS_CACHELINE_SIZE */ + if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO)) + return CONFIG_SYS_ICACHE_LINE_SIZE; -static inline unsigned long icache_line_size(void) -{ - unsigned long conf1, il; conf1 = read_c0_config1(); il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHF; if (!il) @@ -36,6 +26,10 @@ static inline unsigned long icache_line_size(void) static inline unsigned long dcache_line_size(void) { unsigned long conf1, dl; + + if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO)) + return CONFIG_SYS_DCACHE_LINE_SIZE; + conf1 = read_c0_config1(); dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF; if (!dl) @@ -43,8 +37,6 @@ static inline unsigned long dcache_line_size(void) return 2 << dl; } -#endif /* !CONFIG_SYS_CACHELINE_SIZE */ - void flush_cache(ulong start_addr, ulong size) { unsigned long ilsize = icache_line_size(); diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index 4bb9a17..bc8ab27 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -101,14 +101,14 @@ LEAF(mips_cache_reset) #ifndef CONFIG_SYS_CACHE_SIZE_AUTO li t2, CONFIG_SYS_ICACHE_SIZE - li t8, CONFIG_SYS_CACHELINE_SIZE + li t8, CONFIG_SYS_ICACHE_LINE_SIZE #else l1_info t2, t8, MIPS_CONF1_IA_SHF #endif #ifndef CONFIG_SYS_CACHE_SIZE_AUTO li t3, CONFIG_SYS_DCACHE_SIZE - li t9, CONFIG_SYS_CACHELINE_SIZE + li t9, CONFIG_SYS_DCACHE_LINE_SIZE #else l1_info t3, t9, MIPS_CONF1_DA_SHF #endif diff --git a/board/dbau1x00/Kconfig b/board/dbau1x00/Kconfig index 1715a28..448176d 100644 --- a/board/dbau1x00/Kconfig +++ b/board/dbau1x00/Kconfig @@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 menu "dbau1x00 board options" diff --git a/board/micronas/vct/Kconfig b/board/micronas/vct/Kconfig index 5bb6f03..df7c029 100644 --- a/board/micronas/vct/Kconfig +++ b/board/micronas/vct/Kconfig @@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 menu "vct board options" diff --git a/board/pb1x00/Kconfig b/board/pb1x00/Kconfig index 27b2ef0..ef8905d 100644 --- a/board/pb1x00/Kconfig +++ b/board/pb1x00/Kconfig @@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif diff --git a/board/qca/ap121/Kconfig b/board/qca/ap121/Kconfig index f28ea1c..4fd6a71 100644 --- a/board/qca/ap121/Kconfig +++ b/board/qca/ap121/Kconfig @@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 32768 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 65536 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif diff --git a/board/qca/ap143/Kconfig b/board/qca/ap143/Kconfig index ff02236..74c632a 100644 --- a/board/qca/ap143/Kconfig +++ b/board/qca/ap143/Kconfig @@ -15,10 +15,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 32768 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 65536 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif diff --git a/board/qemu-mips/Kconfig b/board/qemu-mips/Kconfig index 66957e7..e696a12 100644 --- a/board/qemu-mips/Kconfig +++ b/board/qemu-mips/Kconfig @@ -14,10 +14,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 16384 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 16384 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif diff --git a/board/tplink/wdr4300/Kconfig b/board/tplink/wdr4300/Kconfig index ded7f9b..67a0228 100644 --- a/board/tplink/wdr4300/Kconfig +++ b/board/tplink/wdr4300/Kconfig @@ -18,10 +18,13 @@ config SYS_TEXT_BASE config SYS_DCACHE_SIZE default 32768 +config SYS_DCACHE_LINE_SIZE + default 32 + config SYS_ICACHE_SIZE default 65536 -config SYS_CACHELINE_SIZE +config SYS_ICACHE_LINE_SIZE default 32 endif diff --git a/include/configs/pic32mzdask.h b/include/configs/pic32mzdask.h index fb2e41f..319e3b5 100644 --- a/include/configs/pic32mzdask.h +++ b/include/configs/pic32mzdask.h @@ -100,7 +100,6 @@ * USB Configuration */ #define CONFIG_USB_MUSB_PIO_ONLY -#define CONFIG_SYS_CACHELINE_SIZE 16 /*----------------------------------------------------------------------- * File System Configuration -- cgit v0.10.2 From fb64cda579985e21610672eae44faf40eadd71ea Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 27 May 2016 14:28:06 +0100 Subject: MIPS: Abstract cache op loops with a macro The various cache maintenance routines perform a number of loops over cache lines. Rather than duplicate the code for performing such loops, abstract it out into a new cache_loop macro which performs an arbitrary number of cache ops on a range of addresses. This reduces duplication in the existing L1 cache maintenance code & will allow for not adding further duplication when introducing L2 cache support. Signed-off-by: Paul Burton diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index 19a42ff..5f520c0 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -37,82 +37,59 @@ static inline unsigned long dcache_line_size(void) return 2 << dl; } +#define cache_loop(start, end, lsize, ops...) do { \ + const void *addr = (const void *)(start & ~(lsize - 1)); \ + const void *aend = (const void *)((end - 1) & ~(lsize - 1)); \ + const unsigned int cache_ops[] = { ops }; \ + unsigned int i; \ + \ + for (; addr <= aend; addr += lsize) { \ + for (i = 0; i < ARRAY_SIZE(cache_ops); i++) \ + mips_cache(cache_ops[i], addr); \ + } \ +} while (0) + void flush_cache(ulong start_addr, ulong size) { unsigned long ilsize = icache_line_size(); unsigned long dlsize = dcache_line_size(); - const void *addr, *aend; /* aend will be miscalculated when size is zero, so we return here */ if (size == 0) return; - addr = (const void *)(start_addr & ~(dlsize - 1)); - aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1)); - if (ilsize == dlsize) { /* flush I-cache & D-cache simultaneously */ - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - mips_cache(HIT_INVALIDATE_I, addr); - if (addr == aend) - break; - addr += dlsize; - } + cache_loop(start_addr, start_addr + size, ilsize, + HIT_WRITEBACK_INV_D, HIT_INVALIDATE_I); return; } /* flush D-cache */ - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - if (addr == aend) - break; - addr += dlsize; - } + cache_loop(start_addr, start_addr + size, dlsize, HIT_WRITEBACK_INV_D); /* flush I-cache */ - addr = (const void *)(start_addr & ~(ilsize - 1)); - aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1)); - while (1) { - mips_cache(HIT_INVALIDATE_I, addr); - if (addr == aend) - break; - addr += ilsize; - } + cache_loop(start_addr, start_addr + size, ilsize, HIT_INVALIDATE_I); } void flush_dcache_range(ulong start_addr, ulong stop) { unsigned long lsize = dcache_line_size(); - const void *addr = (const void *)(start_addr & ~(lsize - 1)); - const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); /* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop) return; - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - if (addr == aend) - break; - addr += lsize; - } + cache_loop(start_addr, stop, lsize, HIT_WRITEBACK_INV_D); } void invalidate_dcache_range(ulong start_addr, ulong stop) { unsigned long lsize = dcache_line_size(); - const void *addr = (const void *)(start_addr & ~(lsize - 1)); - const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); /* aend will be miscalculated when size is zero, so we return here */ if (start_addr == stop) return; - while (1) { - mips_cache(HIT_INVALIDATE_D, addr); - if (addr == aend) - break; - addr += lsize; - } + cache_loop(start_addr, stop, lsize, HIT_INVALIDATE_I); } -- cgit v0.10.2 From d58de3157e3d04ebbf8e928cff9bfc2b3be22ad7 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Mon, 30 May 2016 13:00:21 +0200 Subject: MIPS: malta: add defconfigs for MIPS64 Add defconfigs for recently introduced MIPS64 support on Malta boards to get more build coverage for MIPS64. Signed-off-by: Daniel Schwierzeck diff --git a/configs/malta64_defconfig b/configs/malta64_defconfig new file mode 100644 index 0000000..7bef84c --- /dev/null +++ b/configs/malta64_defconfig @@ -0,0 +1,16 @@ +CONFIG_MIPS=y +CONFIG_TARGET_MALTA=y +CONFIG_CPU_MIPS64_R2=y +CONFIG_DEFAULT_DEVICE_TREE="mti,malta" +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="malta # " +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_DHCP=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y +CONFIG_OF_EMBED=y +CONFIG_SYS_NS16550=y +CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/malta64el_defconfig b/configs/malta64el_defconfig new file mode 100644 index 0000000..47ded9e --- /dev/null +++ b/configs/malta64el_defconfig @@ -0,0 +1,17 @@ +CONFIG_MIPS=y +CONFIG_TARGET_MALTA=y +CONFIG_SYS_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS64_R2=y +CONFIG_DEFAULT_DEVICE_TREE="mti,malta" +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="maltael # " +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_DHCP=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y +CONFIG_OF_EMBED=y +CONFIG_SYS_NS16550=y +CONFIG_USE_PRIVATE_LIBGCC=y -- cgit v0.10.2 From 375239174c6bc6a9966db333fa79f578154828f5 Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Mon, 30 May 2016 22:54:50 +0800 Subject: mips: ath79: Rename get_bootstrap into ath79_get_bootstrap Add a platform prefix for function name in order to make more readable, and move it into ath79.h Signed-off-by: Wills Wang Acked-by: Marek Vasut diff --git a/arch/mips/mach-ath79/ar933x/clk.c b/arch/mips/mach-ath79/ar933x/clk.c index 9fcd496..6d98efc 100644 --- a/arch/mips/mach-ath79/ar933x/clk.c +++ b/arch/mips/mach-ath79/ar933x/clk.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -17,7 +17,7 @@ static u32 ar933x_get_xtal(void) { u32 val; - val = get_bootstrap(); + val = ath79_get_bootstrap(); if (val & AR933X_BOOTSTRAP_REF_CLK_40) return 40000000; else diff --git a/arch/mips/mach-ath79/ar933x/ddr.c b/arch/mips/mach-ath79/ar933x/ddr.c index 7f20d34..2a25e23 100644 --- a/arch/mips/mach-ath79/ar933x/ddr.c +++ b/arch/mips/mach-ath79/ar933x/ddr.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -114,7 +114,7 @@ void ddr_init(void) writel(DDR_CONF_REG_VAL, regs + AR71XX_DDR_REG_CONFIG); writel(DDR_CONF2_REG_VAL, regs + AR71XX_DDR_REG_CONFIG2); - val = get_bootstrap(); + val = ath79_get_bootstrap(); if (val & AR933X_BOOTSTRAP_DDR2) { /* AHB maximum timeout */ writel(0xfffff, regs + AR933X_DDR_REG_TIMEOUT_MAX); diff --git a/arch/mips/mach-ath79/ar934x/clk.c b/arch/mips/mach-ath79/ar934x/clk.c index 9c65184..9b41d3d 100644 --- a/arch/mips/mach-ath79/ar934x/clk.c +++ b/arch/mips/mach-ath79/ar934x/clk.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -119,7 +119,7 @@ void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz) writel(0x03000000, srif_regs + 0x188); /* Undocumented reg :-) */ /* Test for 40MHz XTAL */ - reg = get_bootstrap(); + reg = ath79_get_bootstrap(); if (reg & AR934X_BOOTSTRAP_REF_CLK_40) { xtal_40 = 1; cpu_srif = 0x41c00000; @@ -214,7 +214,7 @@ static u32 ar934x_get_xtal(void) { u32 val; - val = get_bootstrap(); + val = ath79_get_bootstrap(); if (val & AR934X_BOOTSTRAP_REF_CLK_40) return 40000000; else diff --git a/arch/mips/mach-ath79/ar934x/ddr.c b/arch/mips/mach-ath79/ar934x/ddr.c index 4621d58..2ba1efa 100644 --- a/arch/mips/mach-ath79/ar934x/ddr.c +++ b/arch/mips/mach-ath79/ar934x/ddr.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -45,7 +45,7 @@ void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz) ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE, MAP_NOCACHE); - reg = get_bootstrap(); + reg = ath79_get_bootstrap(); if (reg & AR934X_BOOTSTRAP_SDRAM_DISABLED) { /* DDR */ if (reg & AR934X_BOOTSTRAP_DDR1) { /* DDR 1 */ memtype = AR934X_DDR1; diff --git a/arch/mips/mach-ath79/include/mach/ath79.h b/arch/mips/mach-ath79/include/mach/ath79.h index 17af082..582c028 100644 --- a/arch/mips/mach-ath79/include/mach/ath79.h +++ b/arch/mips/mach-ath79/include/mach/ath79.h @@ -140,6 +140,7 @@ static inline int soc_is_qca956x(void) return soc_is_tp9343() || soc_is_qca9561(); } +u32 ath79_get_bootstrap(void); int ath79_eth_reset(void); int ath79_usb_reset(void); diff --git a/arch/mips/mach-ath79/include/mach/reset.h b/arch/mips/mach-ath79/include/mach/reset.h deleted file mode 100644 index c383bfe..0000000 --- a/arch/mips/mach-ath79/include/mach/reset.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2015-2016 Wills Wang - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_MACH_RESET_H -#define __ASM_MACH_RESET_H - -#include - -u32 get_bootstrap(void); - -#endif /* __ASM_MACH_RESET_H */ diff --git a/arch/mips/mach-ath79/qca953x/clk.c b/arch/mips/mach-ath79/qca953x/clk.c index ef0a28e..533356c 100644 --- a/arch/mips/mach-ath79/qca953x/clk.c +++ b/arch/mips/mach-ath79/qca953x/clk.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -17,7 +17,7 @@ static u32 qca953x_get_xtal(void) { u32 val; - val = get_bootstrap(); + val = ath79_get_bootstrap(); if (val & QCA953X_BOOTSTRAP_REF_CLK_40) return 40000000; else diff --git a/arch/mips/mach-ath79/qca953x/ddr.c b/arch/mips/mach-ath79/qca953x/ddr.c index ac0130c..c6049d8 100644 --- a/arch/mips/mach-ath79/qca953x/ddr.c +++ b/arch/mips/mach-ath79/qca953x/ddr.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -226,7 +226,7 @@ void ddr_init(void) regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE, MAP_NOCACHE); - val = get_bootstrap(); + val = ath79_get_bootstrap(); if (val & QCA953X_BOOTSTRAP_DDR1) { writel(DDR_CTL_CONFIG_VAL, regs + QCA953X_DDR_REG_CTL_CONF); udelay(10); diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c index a88bcbc..33bf979 100644 --- a/arch/mips/mach-ath79/reset.c +++ b/arch/mips/mach-ath79/reset.c @@ -45,7 +45,7 @@ void _machine_restart(void) /* NOP */; } -u32 get_bootstrap(void) +u32 ath79_get_bootstrap(void) { void __iomem *base; u32 reg = 0; -- cgit v0.10.2 From 04583c686e61e6883158549603d60741ebf249fe Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Mon, 30 May 2016 22:54:51 +0800 Subject: mips: ath79: ap121: Enable ethernet This patch enable network function for ap121 board. Signed-off-by: Wills Wang Acked-by: Marek Vasut diff --git a/arch/mips/dts/ap121.dts b/arch/mips/dts/ap121.dts index e31f601..a934a58 100644 --- a/arch/mips/dts/ap121.dts +++ b/arch/mips/dts/ap121.dts @@ -41,3 +41,8 @@ reg = <0>; }; }; + +&gmac0 { + phy-mode = "rmii"; + status = "okay"; +}; diff --git a/arch/mips/dts/ar933x.dtsi b/arch/mips/dts/ar933x.dtsi index 00896b2..971f13e 100644 --- a/arch/mips/dts/ar933x.dtsi +++ b/arch/mips/dts/ar933x.dtsi @@ -75,7 +75,7 @@ }; gmac0: eth@0x19000000 { - compatible = "qca,ag7240-mac"; + compatible = "qca,ag933x-mac"; reg = <0x19000000 0x200>; phy = <&phy0>; phy-mode = "rmii"; @@ -92,7 +92,7 @@ }; gmac1: eth@0x1a000000 { - compatible = "qca,ag7240-mac"; + compatible = "qca,ag933x-mac"; reg = <0x1a000000 0x200>; phy = <&phy0>; phy-mode = "rgmii"; diff --git a/board/qca/ap121/ap121.c b/board/qca/ap121/ap121.c index d6c60fe..e245faa 100644 --- a/board/qca/ap121/ap121.c +++ b/board/qca/ap121/ap121.c @@ -10,6 +10,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -46,5 +47,6 @@ int board_early_init_f(void) debug_uart_init(); #endif ddr_init(); + ath79_eth_reset(); return 0; } diff --git a/configs/ap121_defconfig b/configs/ap121_defconfig index 7604e2e..91fa734 100644 --- a/configs/ap121_defconfig +++ b/configs/ap121_defconfig @@ -19,8 +19,13 @@ CONFIG_SYS_PROMPT="ap121 # " CONFIG_CMD_SF=y CONFIG_CMD_SPI=y # CONFIG_CMD_FPGA is not set -# CONFIG_CMD_NET is not set -# CONFIG_CMD_NFS is not set +CONFIG_CMD_NET=y +CONFIG_CMD_NFS=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_PING=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM_ETH=y +CONFIG_AG7XXX=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_ATMEL=y -- cgit v0.10.2 From ad5b48abfe7729d7e0eefcea8693d879af9915b7 Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Mon, 30 May 2016 22:54:52 +0800 Subject: mips: ath79: Use 8MB flash profile for mtd partition by default Change bootm flash address and mtd partition table for 8MB flash profile. Signed-off-by: Wills Wang diff --git a/include/configs/ap121.h b/include/configs/ap121.h index f069d50..b01031c 100644 --- a/include/configs/ap121.h +++ b/include/configs/ap121.h @@ -40,13 +40,13 @@ "rootfstype=squashfs" #define CONFIG_BOOTCOMMAND "sf probe;" \ "mtdparts default;" \ - "bootm 0x9f300000" + "bootm 0x9f650000" #define CONFIG_LZMA #define MTDIDS_DEFAULT "nor0=spi-flash.0" #define MTDPARTS_DEFAULT "mtdparts=spi-flash.0:" \ "256k(u-boot),64k(u-boot-env)," \ - "2752k(rootfs),896k(uImage)," \ + "6144k(rootfs),1600k(uImage)," \ "64k(NVRAM),64k(ART)" #define CONFIG_ENV_SPI_MAX_HZ 25000000 diff --git a/include/configs/ap143.h b/include/configs/ap143.h index e45f743..0fa73a7 100644 --- a/include/configs/ap143.h +++ b/include/configs/ap143.h @@ -44,14 +44,14 @@ "rootfstype=squashfs" #define CONFIG_BOOTCOMMAND "sf probe;" \ "mtdparts default;" \ - "bootm 0x9f300000" + "bootm 0x9f680000" #define CONFIG_LZMA #define MTDIDS_DEFAULT "nor0=spi-flash.0" #define MTDPARTS_DEFAULT "mtdparts=spi-flash.0:" \ "256k(u-boot),64k(u-boot-env)," \ - "2752k(rootfs),896k(uImage)," \ - "64k(NVRAM),64k(ART)" + "6336k(rootfs),1472k(uImage)," \ + "64k(ART)" #define CONFIG_ENV_SPI_MAX_HZ 25000000 #define CONFIG_ENV_IS_IN_SPI_FLASH -- cgit v0.10.2 From cdeb68e292358f9dedeaea167f6eba894c58823e Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Mon, 30 May 2016 22:54:53 +0800 Subject: mips: ath79: Add support for ungating USB and ethernet on qca953x Add code to ungate USB and ethernet controller on qca953x Signed-off-by: Wills Wang diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c index 33bf979..a5ee141 100644 --- a/arch/mips/mach-ath79/reset.c +++ b/arch/mips/mach-ath79/reset.c @@ -136,6 +136,23 @@ static int eth_init_ar934x(void) return 0; } +static int eth_init_qca953x(void) +{ + void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE, + MAP_NOCACHE); + const u32 mask = QCA953X_RESET_GE0_MAC | QCA953X_RESET_GE0_MDIO | + QCA953X_RESET_GE1_MAC | QCA953X_RESET_GE1_MDIO | + QCA953X_RESET_ETH_SWITCH_ANALOG | + QCA953X_RESET_ETH_SWITCH; + + setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + + return 0; +} + int ath79_eth_reset(void) { /* @@ -146,6 +163,8 @@ int ath79_eth_reset(void) return eth_init_ar933x(); if (soc_is_ar934x()) return eth_init_ar934x(); + if (soc_is_qca953x()) + return eth_init_qca953x(); return -EINVAL; } @@ -185,6 +204,35 @@ static int usb_reset_ar934x(void __iomem *reset_regs) return 0; } +static int usb_reset_qca953x(void __iomem *reset_regs) +{ + void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE, + MAP_NOCACHE); + + clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG, + 0xf00, 0x200); + mdelay(10); + + /* Ungate the USB block */ + setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USBSUS_OVERRIDE); + mdelay(1); + clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USB_PHY); + mdelay(1); + clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USB_PHY_ANALOG); + mdelay(1); + clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USB_HOST); + mdelay(1); + clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE, + QCA953X_RESET_USB_PHY_PLL_PWD_EXT); + mdelay(1); + + return 0; +} + int ath79_usb_reset(void) { void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE, @@ -204,6 +252,8 @@ int ath79_usb_reset(void) return usb_reset_ar933x(reset_regs); if (soc_is_ar934x()) return usb_reset_ar934x(reset_regs); + if (soc_is_qca953x()) + return usb_reset_qca953x(reset_regs); return -EINVAL; } -- cgit v0.10.2 From ca09e66b04cd2b80f95d5acc1cc7f61487034faf Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Mon, 30 May 2016 22:54:54 +0800 Subject: mips: ath79: Use AR933X_PLL_SWITCH_CLOCK_CONTROL_REG macro define Add AR933X_PLL_SWITCH_CLOCK_CONTROL_REG define for ar933x chip. Signed-off-by: Wills Wang diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h index dabcad0..7b48524 100644 --- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h +++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h @@ -331,6 +331,7 @@ #define AR933X_PLL_CPU_CONFIG_REG 0x00 #define AR933X_PLL_CLK_CTRL_REG 0x08 #define AR933X_PLL_DITHER_FRAC_REG 0x10 +#define AR933X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24 #define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10 #define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c index a5ee141..073a179 100644 --- a/arch/mips/mach-ath79/reset.c +++ b/arch/mips/mach-ath79/reset.c @@ -89,7 +89,7 @@ static int eth_init_ar933x(void) mdelay(10); /* Get Atheros S26 PHY out of reset. */ - clrsetbits_be32(pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG, + clrsetbits_be32(pregs + AR933X_PLL_SWITCH_CLOCK_CONTROL_REG, 0x1f, 0x10); mdelay(10); -- cgit v0.10.2 From f1b65c98b0a134ce92c38141b917fd3a210ee535 Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Mon, 30 May 2016 22:54:55 +0800 Subject: mips: ath79: ap143: Reset ethernet on boot This patch reset the ethernet controller for ap143 board Signed-off-by: Wills Wang diff --git a/board/qca/ap143/ap143.c b/board/qca/ap143/ap143.c index 1572472..e921ea5 100644 --- a/board/qca/ap143/ap143.c +++ b/board/qca/ap143/ap143.c @@ -10,6 +10,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -62,5 +63,6 @@ int board_early_init_f(void) debug_uart_init(); #endif ddr_init(); + ath79_eth_reset(); return 0; } -- cgit v0.10.2