ide-h8300.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * drivers/ide/ide-h8300.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * H8/300 generic IDE interface 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ide.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/config.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define bswap(d) \ 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds({ \ 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 r; \ 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __asm__("mov.b %w1,r1h\n\t" \ 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "mov.b %x1,r1l\n\t" \ 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "mov.w r1,%0" \ 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"=r"(r) \ 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"r"(d) \ 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"er1"); \ 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (r); \ 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}) 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mm_outw(u16 d, unsigned long a) 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __asm__("mov.b %w0,r2h\n\t" 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "mov.b %x0,r2l\n\t" 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "mov.w r2,@%1" 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"r"(d),"r"(a) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"er2"); 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u16 mm_inw(unsigned long a) 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u16 r __asm__("er0"); 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __asm__("mov.w @%1,r2\n\t" 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "mov.b r2l,%x0\n\t" 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "mov.b r2h,%w0" 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"=r"(r) 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"r"(a) 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"er2"); 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return r; 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mm_outsw(unsigned long addr, void *buf, u32 len) 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short *bp = (unsigned short *)buf; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; len > 0; len--, bp++) 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(volatile u16 *)addr = bswap(*bp); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mm_insw(unsigned long addr, void *buf, u32 len) 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short *bp = (unsigned short *)buf; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; len > 0; len--, bp++) 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *bp = bswap(*(volatile u16 *)addr); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define H8300_IDE_GAP (2) 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void hw_setup(hw_regs_t *hw) 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(hw, 0, sizeof(hw_regs_t)); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i <= IDE_STATUS_OFFSET; i++) 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw->io_ports[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw->io_ports[IDE_CONTROL_OFFSET] = CONFIG_H8300_IDE_ALT; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw->dma = NO_DMA; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw->chipset = ide_generic; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void hwif_setup(ide_hwif_t *hwif) 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default_hwif_iops(hwif); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->mmio = 2; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->OUTW = mm_outw; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->OUTSW = mm_outsw; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->INW = mm_inw; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->INSW = mm_insw; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->OUTL = NULL; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->INL = NULL; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->OUTSL = NULL; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->INSL = NULL; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init h8300_ide_init(void) 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw_regs_t hw; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ide_hwif_t *hwif; 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int idx; 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_busy; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) { 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_busy; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw_setup(&hw); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* register if */ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds idx = ide_register_hw(&hw, &hwif); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (idx == -1) { 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif_setup(hwif); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", idx); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_busy: 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n"); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 120