3 #include "l4/drivers-frst/lib_nand.h"
8 Gpmc::Gpmc(addr base_addr)
9 : _reg((Reg *)base_addr)
11 for (int i = 0; i < Num_cs; ++i)
13 /* Check if NAND type is set */
14 if (((_reg->cs[i].config1) & 0xc00) == 0x800)
16 //printf("found NAND chip\n");
22 // XXX just scan for one chip
25 // disable write protection
26 u32 config = _reg->config;
28 _reg->config = config;
31 _reg->irqstatus = 256;
32 _reg->irqenable = 256;
35 void Gpmc::add(Nand_chip *chip)
37 chip->add_options(Opt_no_padding | Opt_cacheprg | Opt_no_autoincr);
38 if ((_reg->cs[0].config1 & 0x3000) == 0x1000)
39 chip->add_options(Opt_buswidth_16);
45 Nand_chip *Gpmc::select(loff_t /*addr*/)
47 // XXX hack:we currently have only one chip
51 void Gpmc::wr_cmd(u8 c)
52 { *((volatile u8 *)&_reg->cs[0].nand_cmd) = c; }
54 void Gpmc::wr_adr(u8 a)
55 { *((volatile u8 *)&_reg->cs[0].nand_adr) = a; }
57 void Gpmc::wr_dat(u8 d)
58 { *((volatile u8 *)&_reg->cs[0].nand_dat) = d; }
61 { return (u8)(*((volatile u16 *)&_reg->cs[0].nand_dat)); }
63 void Gpmc::rd_dat(const u8 *buf, unsigned len)
68 for (unsigned i = 0; i < len; i++)
69 p[i] = *((volatile u16 *)&_reg->cs[0].nand_dat);
72 for (int i = 0; i < len; i+=4)
74 p[i] = *((volatile u16 *)&_reg->cs[0].nand_dat);
75 p[i+1] = *((volatile u16 *)&_reg->cs[0].nand_dat);
76 p[i+2] = *((volatile u16 *)&_reg->cs[0].nand_dat);
77 p[i+3] = *((volatile u16 *)&_reg->cs[0].nand_dat);
82 void Gpmc::wr_dat(const u8 *buf, unsigned len)
87 for (unsigned i = 0; i < len; i++)
88 *((volatile u16 *)&_reg->cs[0].nand_dat) = p[i];
91 int Gpmc::handle_irq()
94 u32 v = _reg->irqstatus;
95 u32 v2 = _reg->irqstatus;
98 ret = _chips[0]->handle_irq();
99 _reg->irqstatus = 256;
103 printf("spurious interrupt\n");
104 printf("irqstatus:%x %x\n", v, v2);
111 class Gpmc_drv : public Nand_drv
115 { arm_nand_register_driver(this); }
117 int probe(const char *configstr)
118 { return (strcmp(configstr, "GPMC")) ? 0 : 1; }
120 Nand_ctrl *create(addr base)
121 { return new Gpmc(base); }
124 static Gpmc_drv gpmc_drv;