#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define UART16550_WRITE(x, z) UART_WRITE(x, z) extern unsigned int serial_inited; void ath_dispatch_wlan_intr(void) { do_IRQ(ATH_PCI_IRQ_DEV0); } void UartInit(void) { int freq, div; ath_sys_frequency(); freq = ath_uart_freq; MY_WRITE(0xb8040000, 0xcff); MY_WRITE(0xb8040008, 0x3b); /* Enable UART , SPI and Disable S26 UART */ MY_WRITE(0xb8040028, (ath_reg_rd(0xb8040028) | 0x48002)); MY_WRITE(0xb8040008, 0x2f); div = freq / (ATH_CONSOLE_BAUD * 16); /* set DIAB bit */ UART16550_WRITE(OFS_LINE_CONTROL, 0x80); /* set divisor */ UART16550_WRITE(OFS_DIVISOR_LSB, (div & 0xff)); UART16550_WRITE(OFS_DIVISOR_MSB, (div >> 8) & 0xff); // UART16550_WRITE(OFS_DIVISOR_LSB, 0x61); // UART16550_WRITE(OFS_DIVISOR_MSB, 0x03); /* clear DIAB bit */ UART16550_WRITE(OFS_LINE_CONTROL, 0x00); /* set data format */ UART16550_WRITE(OFS_DATA_FORMAT, 0x3); UART16550_WRITE(OFS_INTR_ENABLE, 0); serial_inited = 1; } void ath_sys_frequency(void) { #ifdef CONFIG_ATH_EMULATION ath_cpu_freq = 80000000; ath_ddr_freq = 80000000; ath_ahb_freq = 40000000; #else uint32_t pll, pll_div, ahb_div, ddr_div, freq, ref_div; if (ath_cpu_freq) return; ath_ref_freq= (40 * 1000000); pll = ath_reg_rd(ATH_PLL_CONFIG); pll_div = ((pll >> PLL_DIV_SHIFT) & PLL_DIV_MASK); ref_div = (pll >> REF_DIV_SHIFT) & REF_DIV_MASK; ddr_div = ((pll >> DDR_DIV_SHIFT) & DDR_DIV_MASK) + 1; ahb_div = (((pll >> AHB_DIV_SHIFT) & AHB_DIV_MASK) + 1) * 2; freq = pll_div * ref_div * 5000000; ath_cpu_freq = freq; ath_ddr_freq = freq / ddr_div; ath_ahb_freq = ath_cpu_freq / ahb_div; ath_uart_freq = ath_ahb_freq; #endif } /*--------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------*/ unsigned int ath_get_clock(enum _avm_clock_id id) { switch(id) { case avm_clock_id_cpu: return ath_cpu_freq; case avm_clock_id_peripheral: return ath_uart_freq; case avm_clock_id_ahb: return ath_ahb_freq; case avm_clock_id_ddr: return ath_ddr_freq; case avm_clock_id_ref: return ath_ref_freq; default: break; } return 0; } EXPORT_SYMBOL(ath_get_clock); #ifdef CONFIG_USB_OHCI_ATH /* * OHCI (USB full speed host controller) */ static struct resource ath_usb_ohci_resources[] = { [0] = { .start = ATH_USB_OHCI_BASE, .end = ATH_USB_OHCI_BASE + ATH_USB_WINDOW - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = ATH_CPU_IRQ_USB, .end = ATH_CPU_IRQ_USB, .flags = IORESOURCE_IRQ, }, }; /* * The dmamask must be set for OHCI to work */ static u64 ohci_dmamask = ~(u32) 0; static struct platform_device ath_usb_ohci_device = { .name = "ath-ohci", .id = 0, .dev = { .dma_mask = &ohci_dmamask, .coherent_dma_mask = 0xffffffff, }, .num_resources = ARRAY_SIZE(ath_usb_ohci_resources), .resource = ath_usb_ohci_resources, }; #endif /*--- #ifdef CONFIG_USB_OHCI_ATH ---*/ #ifdef CONFIG_USB_EHCI_AR9130 /* * EHCI (USB full speed host controller) */ static struct resource ath_usb_ehci_resources[] = { [0] = { .start = ATH_USB_EHCI_BASE, .end = ATH_USB_EHCI_BASE + ATH_USB_WINDOW - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = ATH_CPU_IRQ_USB, .end = ATH_CPU_IRQ_USB, .flags = IORESOURCE_IRQ, }, }; /* * The dmamask must be set for EHCI to work */ static u64 ehci_dmamask = ~(u32) 0; static struct platform_device ath_usb_ehci_device = { .name = "ath-ehci", .id = 0, .dev = { .dma_mask = &ehci_dmamask, .coherent_dma_mask = 0xffffffff, }, .num_resources = ARRAY_SIZE(ath_usb_ehci_resources), .resource = ath_usb_ehci_resources, }; #endif /*--- #ifdef CONFIG_USB_EHCI_AR9130 ---*/ #ifdef CONFIG_SERIAL_8250 static struct resource ath_uart_resources[] = { { .start = ATH_UART_BASE, .end = ATH_UART_BASE + 0x0fff, .flags = IORESOURCE_MEM, }, }; extern unsigned int ath_serial_in(int offset); extern void ath_serial_out(int offset, int value); unsigned int ath_plat_serial_in(struct uart_port *up, int offset) { return ath_serial_in(offset); } void ath_plat_serial_out(struct uart_port *up, int offset, int value) { ath_serial_out(offset, value); } static struct plat_serial8250_port ath_uart_data[] = { { .mapbase = (u32) KSEG1ADDR(ATH_UART_BASE), .membase = (void __iomem *)((u32) (KSEG1ADDR(ATH_UART_BASE))), .irq = ATH_MISC_IRQ_UART, .flags = (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST), .iotype = UPIO_MEM32, .regshift = 2, .uartclk = 0, /* ath_ahb_freq, */ }, {}, }; static struct platform_device ath_uart = { .name = "serial8250", .id = 0, .dev.platform_data = ath_uart_data, .num_resources = 1, .resource = ath_uart_resources }; #endif /*--- #ifdef CONFIG_SERIAL_8250 ---*/ #ifdef CONFIG_USB_SUPPORT static struct platform_device *ar7241_platform_devices[] __initdata = { #ifdef CONFIG_USB_EHCI_AR9130 &ath_usb_ehci_device #endif }; static struct platform_device *ar7240_platform_devices[] __initdata = { #ifdef CONFIG_USB_OHCI_ATH &ath_usb_ohci_device #endif }; #endif /*--- #ifdef CONFIG_USB_SUPPORT ---*/ #ifdef CONFIG_SERIAL_8250 static struct platform_device *ar724x_platform_devices[] __initdata = { &ath_uart }; #endif extern void ath_serial_setup(void); int ath_platform_init(void) { int ret = 0; #ifdef CONFIG_SERIAL_8250 ath_uart_data[0].uartclk = ath_ahb_freq; ret = platform_add_devices(ar724x_platform_devices, ARRAY_SIZE(ar724x_platform_devices)); printk("===== ath_platform_init: %d\n", ret); if (ret < 0) { printk("ath_platform_init: uart failed %d\n", ret); return ret; } #endif printk("[%s] init devices for '%s'\n", __FUNCTION__, CONFIG_ATH_SYS_TYPE); ath_reg_rmw_set(ATH_RESET, ATH_RESET_USB_PHY | ATH_RESET_USB_HOST | ATH_RESET_USB_PHY_ANALOG); #ifdef CONFIG_USB_SUPPORT if (is_ar7240()) { ret = platform_add_devices(ar7240_platform_devices, ARRAY_SIZE(ar7240_platform_devices)); } else { // 7241 and 7242 ret = platform_add_devices(ar7241_platform_devices, ARRAY_SIZE(ar7241_platform_devices)); } if (ret < 0) { printk("ath_platform_init: usb failed %d\n", ret); return ret; } #endif /*--- #ifdef CONFIG_USB_SUPPORT ---*/ return ret; } arch_initcall(ath_platform_init);