--- zzzz-none-000/linux-2.6.28.10/drivers/mtd/maps/map_funcs.c 2009-05-02 18:54:43.000000000 +0000 +++ puma5-6360-529/linux-2.6.28.10/drivers/mtd/maps/map_funcs.c 2009-12-04 15:28:09.000000000 +0000 @@ -9,6 +9,12 @@ #include #include +#ifdef CONFIG_MTD_PAGEDMAP +#include +/*--- #include ---*/ +#include +#endif /*--- #ifdef CONFIG_MTD_PAGEDMAP ---*/ + static map_word __xipram simple_map_read(struct map_info *map, unsigned long ofs) { return inline_map_read(map, ofs); @@ -39,5 +45,227 @@ 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");