/* * (C) Copyright 2000-2011 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ */ /* Code taken from cmd_ide.c */ #include #include #include "ide.h" #ifdef CONFIG_IDE_8xx_DIRECT #include #include DECLARE_GLOBAL_DATA_PTR; /* Timings for IDE Interface * * SETUP / LENGTH / HOLD - cycles valid for 50 MHz clk * 70 165 30 PIO-Mode 0, [ns] * 4 9 2 [Cycles] * 50 125 20 PIO-Mode 1, [ns] * 3 7 2 [Cycles] * 30 100 15 PIO-Mode 2, [ns] * 2 6 1 [Cycles] * 30 80 10 PIO-Mode 3, [ns] * 2 5 1 [Cycles] * 25 70 10 PIO-Mode 4, [ns] * 2 4 1 [Cycles] */ static const pio_config_t pio_config_ns[IDE_MAX_PIO_MODE+1] = { /* Setup Length Hold */ { 70, 165, 30 }, /* PIO-Mode 0, [ns] */ { 50, 125, 20 }, /* PIO-Mode 1, [ns] */ { 30, 101, 15 }, /* PIO-Mode 2, [ns] */ { 30, 80, 10 }, /* PIO-Mode 3, [ns] */ { 25, 70, 10 }, /* PIO-Mode 4, [ns] */ }; static pio_config_t pio_config_clk[IDE_MAX_PIO_MODE+1]; #ifndef CONFIG_SYS_PIO_MODE #define CONFIG_SYS_PIO_MODE 0 /* use a relaxed default */ #endif static int pio_mode = CONFIG_SYS_PIO_MODE; /* Make clock cycles and always round up */ #define PCMCIA_MK_CLKS(t, T) (((t) * (T) + 999U) / 1000U) static void set_pcmcia_timing(int pmode) { volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); ulong timings; debug("Set timing for PIO Mode %d\n", pmode); timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold) | PCMCIA_SST(pio_config_clk[pmode].t_setup) | PCMCIA_SL(pio_config_clk[pmode].t_length); /* * IDE 0 */ pcmp->pcmc_pbr0 = CONFIG_SYS_PCMCIA_PBR0; #if (CONFIG_SYS_PCMCIA_POR0 != 0) pcmp->pcmc_por0 = CONFIG_SYS_PCMCIA_POR0 | timings; #else pcmp->pcmc_por0 = CONFIG_SYS_PCMCIA_POR0; #endif debug("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0); pcmp->pcmc_pbr1 = CONFIG_SYS_PCMCIA_PBR1; #if (CONFIG_SYS_PCMCIA_POR1 != 0) pcmp->pcmc_por1 = CONFIG_SYS_PCMCIA_POR1 | timings; #else pcmp->pcmc_por1 = CONFIG_SYS_PCMCIA_POR1; #endif debug("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1); pcmp->pcmc_pbr2 = CONFIG_SYS_PCMCIA_PBR2; #if (CONFIG_SYS_PCMCIA_POR2 != 0) pcmp->pcmc_por2 = CONFIG_SYS_PCMCIA_POR2 | timings; #else pcmp->pcmc_por2 = CONFIG_SYS_PCMCIA_POR2; #endif debug("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2); pcmp->pcmc_pbr3 = CONFIG_SYS_PCMCIA_PBR3; #if (CONFIG_SYS_PCMCIA_POR3 != 0) pcmp->pcmc_por3 = CONFIG_SYS_PCMCIA_POR3 | timings; #else pcmp->pcmc_por3 = CONFIG_SYS_PCMCIA_POR3; #endif debug("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3); /* * IDE 1 */ pcmp->pcmc_pbr4 = CONFIG_SYS_PCMCIA_PBR4; #if (CONFIG_SYS_PCMCIA_POR4 != 0) pcmp->pcmc_por4 = CONFIG_SYS_PCMCIA_POR4 | timings; #else pcmp->pcmc_por4 = CONFIG_SYS_PCMCIA_POR4; #endif debug("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4); pcmp->pcmc_pbr5 = CONFIG_SYS_PCMCIA_PBR5; #if (CONFIG_SYS_PCMCIA_POR5 != 0) pcmp->pcmc_por5 = CONFIG_SYS_PCMCIA_POR5 | timings; #else pcmp->pcmc_por5 = CONFIG_SYS_PCMCIA_POR5; #endif debug("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5); pcmp->pcmc_pbr6 = CONFIG_SYS_PCMCIA_PBR6; #if (CONFIG_SYS_PCMCIA_POR6 != 0) pcmp->pcmc_por6 = CONFIG_SYS_PCMCIA_POR6 | timings; #else pcmp->pcmc_por6 = CONFIG_SYS_PCMCIA_POR6; #endif debug("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6); pcmp->pcmc_pbr7 = CONFIG_SYS_PCMCIA_PBR7; #if (CONFIG_SYS_PCMCIA_POR7 != 0) pcmp->pcmc_por7 = CONFIG_SYS_PCMCIA_POR7 | timings; #else pcmp->pcmc_por7 = CONFIG_SYS_PCMCIA_POR7; #endif debug("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7); } int ide_preinit(void) { int i; /* Initialize PIO timing tables */ for (i = 0; i <= IDE_MAX_PIO_MODE; ++i) { pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup, gd->bus_clk); pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length, gd->bus_clk); pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold, gd->bus_clk); debug("PIO Mode %d: setup=%2d ns/%d clk" " len=%3d ns/%d clk" " hold=%2d ns/%d clk\n", i, pio_config_ns[i].t_setup, pio_config_clk[i].t_setup, pio_config_ns[i].t_length, pio_config_clk[i].t_length, pio_config_ns[i].t_hold, pio_config_clk[i].t_hold); } return 0; } int ide_init_postreset(void) { volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); /* PCMCIA / IDE initialization for common mem space */ pcmp->pcmc_pgcrb = 0; /* start in PIO mode 0 - most relaxed timings */ pio_mode = 0; set_pcmcia_timing(pio_mode); return 0; } #endif /* CONFIG_IDE_8xx_DIRECT */ #ifdef CONFIG_IDE_8xx_PCCARD int ide_preinit(void) { ide_devices_found = 0; /* initialize the PCMCIA IDE adapter card */ pcmcia_on(); if (!ide_devices_found) return 1; udelay(1000000);/* 1 s */ return 0; } #endif