int serial_init(void) { u32 rdata; u32 baudRateDivisor, clock_step; u32 fcEnable = 0; u32 ahb_freq, ddr_freq, cpu_freq; ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq); /* GPIO Configuration */ ar7240_reg_wr(AR7240_GPIO_OE, 0xcff); rdata = ar7240_reg_rd(AR7240_GPIO_OUT); rdata |= 0x400; // GPIO 10 (UART_SOUT) must output 1 ar7240_reg_wr(AR7240_GPIO_OUT, rdata); rdata = ar7240_reg_rd(AR7240_GPIO_FUNC); /* GPIO_FUN, bit1/UART_EN, bit2/UART_RTS_CTS_EN, bit15(disable_s26_uart) */ rdata |= (0x3 << 1) | (0x1 << 15); ar7240_reg_wr(AR7240_GPIO_FUNC, rdata); /* Get reference clock rate, then set baud rate to 115200 */ // TODO: check the following code rdata = ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS); rdata &= HORNET_BOOTSTRAP_SEL_25M_40M_MASK; if (rdata) { baudRateDivisor = (40000000 / (16 * 115200)) - 1; // 40 MHz clock is taken as UART clock } else { baudRateDivisor = (25000000 / (16 * 115200)) - 1; // 25 MHz clock is taken as UART clock } clock_step = 8192; rdata = UARTCLOCK_UARTCLOCKSCALE_SET(baudRateDivisor) | UARTCLOCK_UARTCLOCKSTEP_SET(clock_step); uart_reg_write(UARTCLOCK_ADDRESS, rdata); /* Config Uart Controller */ /* No interrupt */ rdata = UARTCS_UARTDMAEN_SET(0) | UARTCS_UARTHOSTINTEN_SET(0) | UARTCS_UARTHOSTINT_SET(0) | UARTCS_UARTSERIATXREADY_SET(0) | UARTCS_UARTTXREADYORIDE_SET(~fcEnable) | UARTCS_UARTRXREADYORIDE_SET(~fcEnable) | UARTCS_UARTHOSTINTEN_SET(0); /* is_dte == 1 */ rdata = rdata | UARTCS_UARTINTERFACEMODE_SET(2); if (fcEnable) { rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(2); } /* invert_fc ==0 (Inverted Flow Control) */ //rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(3); /* parityEnable == 0 */ //rdata = rdata | UARTCS_UARTPARITYMODE_SET(2); -->Parity Odd //rdata = rdata | UARTCS_UARTPARITYMODE_SET(3); -->Parity Even uart_reg_write(UARTCS_ADDRESS, rdata); return 0; }
void ag7240_mii_setup(ag7240_mac_t *mac) { u32 mgmt_cfg_val; u32 cpu_freq,ddr_freq,ahb_freq; u32 check_cnt,revid_val; if ((ar7240_reg_rd(WASP_BOOTSTRAP_REG) & WASP_REF_CLK_25) == 0) { #ifndef CFG_DUAL_PHY_SUPPORT ar7240_reg_wr(AR934X_SWITCH_CLOCK_SPARE, 0x271); #endif } else { ar7240_reg_wr(AR934X_SWITCH_CLOCK_SPARE, 0x570); } #if defined(CONFIG_AR7242_S16_PHY) || defined(CONFIG_ATHRS17_PHY) if (is_wasp() && mac->mac_unit == 0) { #ifdef CONFIG_AR7242_S16_PHY printf("WASP ----> S16 PHY *\n"); #else printf("WASP ----> S17 PHY *\n"); #endif mgmt_cfg_val = 4; if(mac->mac_unit == 0) ar7240_reg_wr(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0); udelay(1000); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); return; } #endif #ifdef CFG_ATHRS27_PHY if (is_wasp()) { printf("WASP ----> S27 PHY \n"); mgmt_cfg_val = 2; ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); return; } #endif #ifdef CONFIG_F2E_PHY if (is_wasp()) { printf("WASP ----> F2 PHY *\n"); ar7240_reg_wr(AG7240_ETH_CFG, (AG7240_ETH_CFG_RMII_MASTER_MODE | AG7240_ETH_CFG_RMII_GE0 | AG7240_ETH_CFG_RMII_HISPD_GE0)); mgmt_cfg_val = 6; ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); return; } #endif #if defined(CONFIG_F1E_PHY) || defined(CONFIG_VIR_PHY) if (is_wasp()) { #ifdef CONFIG_VIR_PHY printf("WASP ----> VIR PHY *\n"); #else printf("WASP ----> F1 PHY *\n"); #endif if(mac->mac_unit == 0) ar7240_reg_wr(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0); mgmt_cfg_val = 6; ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); return; } #endif if ((ar7240_reg_rd(AR7240_REV_ID) & AR7240_REV_ID_MASK) == AR7240_REV_1_2) { mgmt_cfg_val = 0x2; if (mac->mac_unit == 0) { ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); } } else { ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq); switch (ahb_freq/1000000) { case 150: mgmt_cfg_val = 0x7; break; case 175: mgmt_cfg_val = 0x5; break; case 200: mgmt_cfg_val = 0x4; break; case 210: mgmt_cfg_val = 0x9; break; case 220: mgmt_cfg_val = 0x9; break; default: mgmt_cfg_val = 0x7; } if ((is_ar7241() || is_ar7242())) { /* External MII mode */ if (mac->mac_unit == 0 && is_ar7242()) { mgmt_cfg_val = 0x6; ar7240_reg_rmw_set(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); } /* Virian */ mgmt_cfg_val = 0x4; ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); printf("Virian MDC CFG Value ==> %x\n",mgmt_cfg_val); } else if(is_ar933x()) { //GE0 receives Rx/Tx clock, and use S26 phy ar7240_reg_rmw_set(AG7240_ETH_CFG, AG7240_ETH_CFG_MII_GE0_SLAVE); mgmt_cfg_val = 0xF; if (mac->mac_unit == 1) { check_cnt = 0; while (check_cnt++ < 10) { ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); #ifdef CFG_ATHRS26_PHY if(athrs26_mdc_check() == 0) break; #endif } if(check_cnt == 11) printf("%s: MDC check failed\n", __func__); } } else { /* Python 1.0 & 1.1 */ if (mac->mac_unit == 0) { check_cnt = 0; while (check_cnt++ < 10) { ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); #ifdef CFG_ATHRS26_PHY if(athrs26_mdc_check() == 0) break; #endif } if(check_cnt == 11) printf("%s: MDC check failed\n", __func__); } } } }
void ag7240_mii_setup(ag7240_mac_t *mac) { u32 mgmt_cfg_val; u32 cpu_freq,ddr_freq,ahb_freq; u32 check_cnt,revid_val; #ifdef CFG_ATHRS27_PHY if (is_wasp()) { printf("WASP ----> S27 PHY \n"); mgmt_cfg_val = 2; ar7240_reg_wr(0xb8050024, 0x271); // 25MHz ref clock //ar7240_reg_wr(0xb8050024, 0x570); // 40MHz ref clock ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); return; } #endif #ifdef CONFIG_AR7242_S16_PHY if (is_wasp()) { printf("WASP ----> S16 PHY *\n"); mgmt_cfg_val = 4; if(mac->mac_unit == 0) ar7240_reg_wr(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0); ar7240_reg_rmw_clear(AG7240_ETH_SWITCH_CLK_SPARE, (1 << 6)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); return; } #endif #ifdef CONFIG_F1E_PHY if (is_wasp()) { printf("WASP ----> F1 PHY *\n"); mgmt_cfg_val = 6; if(mac->mac_unit == 0) ar7240_reg_wr(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); return; } #endif if ((ar7240_reg_rd(AR7240_REV_ID) & AR7240_REV_ID_MASK) == AR7240_REV_1_2) { mgmt_cfg_val = 0x2; if (mac->mac_unit == 0) { ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); } } else { ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq); switch (ahb_freq/1000000) { case 150: mgmt_cfg_val = 0x7; break; case 175: mgmt_cfg_val = 0x5; break; case 200: mgmt_cfg_val = 0x4; break; case 210: mgmt_cfg_val = 0x9; break; case 220: mgmt_cfg_val = 0x9; break; default: mgmt_cfg_val = 0x7; } if ((is_ar7241() || is_ar7242())) { /* External MII mode */ if (mac->mac_unit == 0 && is_ar7242()) { mgmt_cfg_val = 0x6; ar7240_reg_rmw_set(AG7240_ETH_CFG, AG7240_ETH_CFG_RGMII_GE0); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); } /* Virian */ mgmt_cfg_val = 0x4; ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(ag7240_macs[1], AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); printf("Virian MDC CFG Value ==> %x\n",mgmt_cfg_val); } else if(is_ar933x()){ //GE0 receives Rx/Tx clock, and use S26 phy ar7240_reg_rmw_set(AG7240_ETH_CFG, AG7240_ETH_CFG_MII_GE0_SLAVE); mgmt_cfg_val = 0xF; if (mac->mac_unit == 1) { check_cnt = 0; while (check_cnt++ < 10) { ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); #ifdef CFG_ATHRS26_PHY if(athrs26_mdc_check() == 0) break; #endif } if(check_cnt == 11) printf("%s: MDC check failed\n", __func__); } } else { /* Python 1.0 & 1.1 */ if (mac->mac_unit == 0) { check_cnt = 0; while (check_cnt++ < 10) { ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val | (1 << 31)); ag7240_reg_wr(mac, AG7240_MAC_MII_MGMT_CFG, mgmt_cfg_val); #ifdef CFG_ATHRS26_PHY if(athrs26_mdc_check() == 0) break; #endif } if(check_cnt == 11) printf("%s: MDC check failed\n", __func__); } } } }
/* * Set and store PLL configuration in FLASH */ int do_set_clocks(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){ unsigned int cpu_pll_config_flash, cpu_clock_control_flash, spi_control_flash, reg; unsigned int ahb_freq, ddr_freq, cpu_freq, spi_freq; unsigned int *data_pointer; int i, index, profiles_count; char buf[128]; profiles_count = sizeof(oc_profiles) / sizeof(ar9331_clock_profile); // print all available profiles and current settings if(argc == 1){ // read clocks ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq); // calculate SPI clock (we need to set bit 0 to 1 in SPI_FUNC_SELECT to access SPI registers) ar7240_reg_wr(AR7240_SPI_FS, 0x01); spi_freq = ahb_freq / (((ar7240_reg_rd(AR7240_SPI_CLOCK) & 0x3F) + 1) * 2); ar7240_reg_wr(AR7240_SPI_FS, 0x0); // make MHz from Hz cpu_freq /= 1000000; ddr_freq /= 1000000; ahb_freq /= 1000000; spi_freq /= 1000000; printf("Current clocks (approximated):\n- CPU: %3d MHz\n", cpu_freq); printf("- RAM: %3d MHz\n", ddr_freq); printf("- AHB: %3d MHz\n", ahb_freq); printf("- SPI: %3d MHz\n", spi_freq); // reference clock if(ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS) & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){ puts("- REF: 40 MHz\n\n"); } else { puts("- REF: 25 MHz\n\n"); } // do we have PLL_MAGIC in FLASH? reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET); // read all register values stored in FLASH cpu_pll_config_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 4); cpu_clock_control_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 8); spi_control_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 12); printf("Available PLL and clocks configurations: %d\n\n", profiles_count); puts(" | CPU | RAM | AHB | SPI | [ ]\n ---------------------------------\n"); for(i = 0; i < profiles_count; i++){ printf("%4d. |%4d |%4d |%4d |%4d | ", i + 1, oc_profiles[i].cpu_clock, oc_profiles[i].ram_clock, oc_profiles[i].ahb_clock, oc_profiles[i].spi_clock); if(reg == PLL_IN_FLASH_MAGIC && oc_profiles[i].cpu_pll_config == cpu_pll_config_flash && oc_profiles[i].cpu_clk_control == cpu_clock_control_flash && oc_profiles[i].spi_control == spi_control_flash){ puts("[*]\n"); } else { puts("[ ]\n"); } } puts("\n[*] = currently selected profile (stored in FLASH).\nAll clocks in MHz, run 'setclk X' to choose one.\n\n"); puts("** Notice:\n you should always make a backup of your device\n entire FLASH content before making any changes\n\n"); return(0); } else { // selected index index = simple_strtoul(argv[1], NULL, 10); if(index > profiles_count || index < 1){ printf("## Error: selected index should be in range 1..%d!\n", profiles_count); return(1); } printf("You have selected profile: %d.\n\n", index); // array is zero-based indexing index--; // backup entire block in which we store PLL/CLK settings data_pointer = (unsigned int *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS; if(!data_pointer){ puts("## Error: couldn't allocate RAM for data block backup!\n"); return(1); } memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET), PLL_IN_FLASH_DATA_BLOCK_LENGTH); // save PLL_IN_FLASH_MAGIC and PLL/clocks registers values data_pointer = (unsigned int *)(WEBFAILSAFE_UPLOAD_RAM_ADDRESS + PLL_IN_FLASH_MAGIC_OFFSET); *data_pointer = PLL_IN_FLASH_MAGIC; data_pointer++; *data_pointer = oc_profiles[index].cpu_pll_config; data_pointer++; *data_pointer = oc_profiles[index].cpu_clk_control; data_pointer++; *data_pointer = oc_profiles[index].spi_control; // erase FLASH, copy data from RAM sprintf(buf, "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX", CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET, PLL_IN_FLASH_DATA_BLOCK_LENGTH, WEBFAILSAFE_UPLOAD_RAM_ADDRESS, CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET, PLL_IN_FLASH_DATA_BLOCK_LENGTH); printf("Executing: %s\n\n", buf); return(run_command(buf, 0)); } }