#ifndef __MACH_SAMA5D2_LL__ #define __MACH_SAMA5D2_LL__ #include <mach/sama5d2.h> #include <mach/at91_pmc_ll.h> #include <mach/iomux.h> #include <mach/debug_ll.h> #include <mach/early_udelay.h> #include <mach/ddramc.h> #include <common.h> void sama5d2_lowlevel_init(void); static inline void sama5d2_pmc_enable_periph_clock(int clk) { at91_pmc_sam9x5_enable_periph_clock(SAMA5D2_BASE_PMC, clk); } /* requires relocation */ static inline void sama5d2_udelay_init(unsigned int msc) { early_udelay_init(SAMA5D2_BASE_PMC, SAMA5D2_BASE_PITC, SAMA5D2_ID_PIT, msc, AT91_PMC_LL_SAMA5D2); } void sama5d2_ddr2_init(struct at91_ddramc_register *ddramc_reg_config); static inline int sama5d2_pmc_enable_generic_clock(unsigned int periph_id, unsigned int clk_source, unsigned int div) { return at91_pmc_enable_generic_clock(SAMA5D2_BASE_PMC, SAMA5D2_BASE_SFR, periph_id, clk_source, div, AT91_PMC_LL_SAMA5D2); } static inline int sama5d2_dbgu_setup_ll(unsigned dbgu_id, unsigned pin, unsigned periph, unsigned mck) { unsigned mask, bank, pio_id; void __iomem *dbgu_base, *pio_base; mask = pin_to_mask(pin); bank = pin_to_bank(pin); switch (dbgu_id) { case SAMA5D2_ID_UART0: dbgu_base = SAMA5D2_BASE_UART0; break; case SAMA5D2_ID_UART1: dbgu_base = SAMA5D2_BASE_UART1; break; case SAMA5D2_ID_UART2: dbgu_base = SAMA5D2_BASE_UART2; break; case SAMA5D2_ID_UART3: dbgu_base = SAMA5D2_BASE_UART3; break; case SAMA5D2_ID_UART4: dbgu_base = SAMA5D2_BASE_UART4; break; default: return -EINVAL; } pio_base = sama5d2_pio_map_bank(bank, &pio_id); if (!pio_base) return -EINVAL; sama5d2_pmc_enable_periph_clock(pio_id); at91_mux_pio4_set_periph(pio_base, mask, periph); sama5d2_pmc_enable_periph_clock(dbgu_id); at91_dbgu_setup_ll(dbgu_base, mck / 2, CONFIG_BAUDRATE); return 0; } struct sama5d2_uart_pinmux { void __iomem *base; u8 id, dtxd, periph; }; #define SAMA5D2_UART(idx, pio, periph) (struct sama5d2_uart_pinmux) { \ SAMA5D2_BASE_UART##idx, SAMA5D2_ID_UART##idx, \ AT91_PIN_##pio, AT91_MUX_PERIPH_##periph } static inline void __iomem *sama5d2_resetup_uart_console(unsigned mck) { struct sama5d2_uart_pinmux pinmux; /* Table 48-2 I/O Lines and 16.4.4 Boot Configuration Word */ switch (FIELD_GET(SAMA5D2_BOOTCFG_UART, sama5d2_bootcfg())) { case 0: /* UART_1_IOSET_1 */ pinmux = SAMA5D2_UART(1, PD3, A); break; case 1: /* UART_0_IOSET_1 */ pinmux = SAMA5D2_UART(0, PB27, C); break; case 2: /* UART_1_IOSET_2 */ pinmux = SAMA5D2_UART(1, PC8, E); break; case 3: /* UART_2_IOSET_1 */ pinmux = SAMA5D2_UART(2, PD5, B); break; case 4: /* UART_2_IOSET_2 */ pinmux = SAMA5D2_UART(2, PD24, A); break; case 5: /* UART_2_IOSET_3 */ pinmux = SAMA5D2_UART(2, PD20, C); break; case 6: /* UART_3_IOSET_1 */ pinmux = SAMA5D2_UART(3, PC13, D); break; case 7: /* UART_3_IOSET_2 */ pinmux = SAMA5D2_UART(3, PD0, C); break; case 8: /* UART_3_IOSET_3 */ pinmux = SAMA5D2_UART(3, PB12, C); break; case 9: /* UART_4_IOSET_1 */ pinmux = SAMA5D2_UART(4, PB4, A); break; default: return NULL; } sama5d2_dbgu_setup_ll(pinmux.id, pinmux.dtxd, pinmux.periph, mck); return pinmux.base; } #endif