/* * $Id: map_funcs.c,v 1.10 2005/06/06 23:04:36 tpoynor Exp $ * * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS * is enabled. */ #include #include #include #include #include #include #include static map_word __xipram simple_map_read(struct map_info *map, unsigned long ofs) { return inline_map_read(map, ofs); } static void __xipram simple_map_write(struct map_info *map, const map_word datum, unsigned long ofs) { inline_map_write(map, datum, ofs); } static void __xipram simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { inline_map_copy_from(map, to, from, len); } static void __xipram simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) { inline_map_copy_to(map, to, from, len); } void simple_map_init(struct map_info *map) { BUG_ON(!map_bankwidth_supported(map->bankwidth)); map->read = simple_map_read; map->write = simple_map_write; map->copy_from = simple_map_copy_from; map->copy_to = simple_map_copy_to; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #ifdef CONFIG_MTD_PAGEDMAP /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static map_word __xipram paged_map_read(struct map_info *map, unsigned long addr) { struct gpio_controller *GPIO = (struct gpio_controller *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10); map_word result; unsigned int field, mask; mask = (1 << CONFIG_MTD_PAGED_BIT_A20) | (1 << CONFIG_MTD_PAGED_BIT_A21) | (1 << CONFIG_MTD_PAGED_BIT_A22) | (1 << CONFIG_MTD_PAGED_BIT_A23); field = addr / CONFIG_MTD_PAGEDMAP_LEN; field <<= CONFIG_MTD_PAGED_BIT_A20; GPIO->clr_data = ~field & mask; GPIO->set_data = field & mask; /*--- GPIO->clr_data = ---*/ /*--- (addr & (1 << 20) ? 0 : (1 << CONFIG_MTD_PAGED_BIT_A20)) | ---*/ /*--- (addr & (1 << 21) ? 0 : (1 << CONFIG_MTD_PAGED_BIT_A21)) | ---*/ /*--- (addr & (1 << 22) ? 0 : (1 << CONFIG_MTD_PAGED_BIT_A22)) | ---*/ /*--- (addr & (1 << 23) ? 0 : (1 << CONFIG_MTD_PAGED_BIT_A23)); ---*/ /*--- GPIO->set_data = ---*/ /*--- (addr & (1 << 20) ? (1 << CONFIG_MTD_PAGED_BIT_A20) : 0) | ---*/ /*--- (addr & (1 << 21) ? (1 << CONFIG_MTD_PAGED_BIT_A21) : 0) | ---*/ /*--- (addr & (1 << 22) ? (1 << CONFIG_MTD_PAGED_BIT_A22) : 0) | ---*/ /*--- (addr & (1 << 23) ? (1 << CONFIG_MTD_PAGED_BIT_A23) : 0); ---*/ result = inline_map_read(map, addr % CONFIG_MTD_PAGEDMAP_LEN); /*--- printk("[paged_map_read] 0x%lx from 0x%lx (0x%lx)\n", result.x[0], addr, addr % CONFIG_MTD_PAGEDMAP_LEN); ---*/ GPIO->clr_data = (1 << CONFIG_MTD_PAGED_BIT_A20) | (1 << CONFIG_MTD_PAGED_BIT_A21) | (1 << CONFIG_MTD_PAGED_BIT_A22) | (1 << CONFIG_MTD_PAGED_BIT_A23); return result; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void __xipram paged_map_write(struct map_info *map, const map_word datum, unsigned long addr) { struct gpio_controller *GPIO = (struct gpio_controller *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10); unsigned int field, mask; mask = (1 << CONFIG_MTD_PAGED_BIT_A20) | (1 << CONFIG_MTD_PAGED_BIT_A21) | (1 << CONFIG_MTD_PAGED_BIT_A22) | (1 << CONFIG_MTD_PAGED_BIT_A23); field = addr / CONFIG_MTD_PAGEDMAP_LEN; field <<= CONFIG_MTD_PAGED_BIT_A20; GPIO->clr_data = ~field & mask; GPIO->set_data = field & mask; /*--- GPIO->clr_data = ---*/ /*--- (addr & (1 << 20) ? 0 : (1 << CONFIG_MTD_PAGED_BIT_A20)) | ---*/ /*--- (addr & (1 << 21) ? 0 : (1 << CONFIG_MTD_PAGED_BIT_A21)) | ---*/ /*--- (addr & (1 << 22) ? 0 : (1 << CONFIG_MTD_PAGED_BIT_A22)) | ---*/ /*--- (addr & (1 << 23) ? 0 : (1 << CONFIG_MTD_PAGED_BIT_A23)); ---*/ /*--- GPIO->set_data = ---*/ /*--- (addr & (1 << 20) ? (1 << CONFIG_MTD_PAGED_BIT_A20) : 0) | ---*/ /*--- (addr & (1 << 21) ? (1 << CONFIG_MTD_PAGED_BIT_A21) : 0) | ---*/ /*--- (addr & (1 << 22) ? (1 << CONFIG_MTD_PAGED_BIT_A22) : 0) | ---*/ /*--- (addr & (1 << 23) ? (1 << CONFIG_MTD_PAGED_BIT_A23) : 0); ---*/ /*--- printk("[paged_map_write] 0x%lx to 0x%lx (0x%lx)\n", datum.x[0], addr, addr % CONFIG_MTD_PAGEDMAP_LEN); ---*/ inline_map_write(map, datum, addr % CONFIG_MTD_PAGEDMAP_LEN); GPIO->clr_data = (1 << CONFIG_MTD_PAGED_BIT_A20) | (1 << CONFIG_MTD_PAGED_BIT_A21) | (1 << CONFIG_MTD_PAGED_BIT_A22) | (1 << CONFIG_MTD_PAGED_BIT_A23); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void __xipram paged_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { unsigned long addr = (unsigned long)from % CONFIG_MTD_PAGEDMAP_LEN; struct gpio_controller *GPIO = (struct gpio_controller *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10); unsigned int field, mask; if(len == 0) return; mask = (1 << CONFIG_MTD_PAGED_BIT_A20) | (1 << CONFIG_MTD_PAGED_BIT_A21) | (1 << CONFIG_MTD_PAGED_BIT_A22) | (1 << CONFIG_MTD_PAGED_BIT_A23); field = from / CONFIG_MTD_PAGEDMAP_LEN; field <<= CONFIG_MTD_PAGED_BIT_A20; GPIO->clr_data = ~field & mask; GPIO->set_data = field & mask; /*--- printk("field 0x%x mask 0x%x\n", field, mask); ---*/ if(addr + len > CONFIG_MTD_PAGEDMAP_LEN) { unsigned int read_len = CONFIG_MTD_PAGEDMAP_LEN - addr; printk("[paged_map_copy_from] addr 0x%x len 0x%x read_len 0x%x\n", addr, len, read_len); inline_map_copy_from(map, to, addr, read_len); len -= read_len; from += read_len; to += read_len; addr = 0; field = from / CONFIG_MTD_PAGEDMAP_LEN; field <<= CONFIG_MTD_PAGED_BIT_A20; GPIO->clr_data = ~field & mask; GPIO->set_data = field & mask; } /*--- printk("[paged_map_copy_from] len %u from 0x%lx (0x%x MByte +0x%lx) to 0x%p\n", ---*/ /*--- len, from, (GPIO->out_data >> CONFIG_MTD_PAGED_BIT_A20) % 0x0F, from % CONFIG_MTD_PAGEDMAP_LEN, to); ---*/ inline_map_copy_from(map, to, addr, len); GPIO->clr_data = (1 << CONFIG_MTD_PAGED_BIT_A20) | (1 << CONFIG_MTD_PAGED_BIT_A21) | (1 << CONFIG_MTD_PAGED_BIT_A22) | (1 << CONFIG_MTD_PAGED_BIT_A23); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void __xipram paged_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) { unsigned long addr = (unsigned long)to % CONFIG_MTD_PAGEDMAP_LEN; struct gpio_controller *GPIO = (struct gpio_controller *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10); unsigned int field, mask; if(len == 0) return; mask = (1 << CONFIG_MTD_PAGED_BIT_A20) | (1 << CONFIG_MTD_PAGED_BIT_A21) | (1 << CONFIG_MTD_PAGED_BIT_A22) | (1 << CONFIG_MTD_PAGED_BIT_A23); field = to / CONFIG_MTD_PAGEDMAP_LEN; field <<= CONFIG_MTD_PAGED_BIT_A20; GPIO->clr_data = ~field & mask; GPIO->set_data = field & mask; /*--- printk("field 0x%x mask 0x%x\n", field, mask); ---*/ if(addr + len > CONFIG_MTD_PAGEDMAP_LEN) { unsigned int write_len = CONFIG_MTD_PAGEDMAP_LEN - addr; /*--- printk("[paged_map_copy_to] addr 0x%x len 0x%x write_len 0x%x\n", addr, len, write_len); ---*/ inline_map_copy_to(map, from, addr, write_len); len -= write_len; to += write_len; from += write_len; addr = 0; field = to / CONFIG_MTD_PAGEDMAP_LEN; field <<= CONFIG_MTD_PAGED_BIT_A20; GPIO->clr_data = ~field & mask; GPIO->set_data = field & mask; } /*--- printk("[paged_map_copy_to] len %u to 0x%lx (0x%x MByte +0x%lx) from 0x%p\n", ---*/ /*--- len, to, (GPIO->out_data >> CONFIG_MTD_PAGED_BIT_A20) % 0x0F, to % CONFIG_MTD_PAGEDMAP_LEN, from); ---*/ inline_map_copy_to(map, from, addr, len); GPIO->clr_data = (1 << CONFIG_MTD_PAGED_BIT_A20) | (1 << CONFIG_MTD_PAGED_BIT_A21) | (1 << CONFIG_MTD_PAGED_BIT_A22) | (1 << CONFIG_MTD_PAGED_BIT_A23); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void paged_map_init(struct map_info *map) { BUG_ON(!map_bankwidth_supported(map->bankwidth)); /*--- #ifdef CONFIG_ARCH_DAVINCI ---*/ /*--- davinci_gpio_ctrl(CONFIG_MTD_PAGED_BIT_A20, GPIO_PIN, GPIO_OUTPUT_PIN); ---*/ /*--- davinci_gpio_ctrl(CONFIG_MTD_PAGED_BIT_A21, GPIO_PIN, GPIO_OUTPUT_PIN); ---*/ /*--- davinci_gpio_ctrl(CONFIG_MTD_PAGED_BIT_A22, GPIO_PIN, GPIO_OUTPUT_PIN); ---*/ /*--- davinci_gpio_ctrl(CONFIG_MTD_PAGED_BIT_A23, GPIO_PIN, GPIO_OUTPUT_PIN); ---*/ /*--- #endif ---*/ /*--- #ifdef CONFIG_ARCH_DAVINCI ---*/ map->read = paged_map_read; map->write = paged_map_write; map->copy_from = paged_map_copy_from; map->copy_to = paged_map_copy_to; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void paged_map_exit(struct map_info *map) { return; } EXPORT_SYMBOL(paged_map_exit); EXPORT_SYMBOL(paged_map_init); #endif /*--- #ifdef CONFIG_MTD_PAGEDMAP ---*/ EXPORT_SYMBOL(simple_map_init); MODULE_LICENSE("GPL");