| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * NAND Flash Controller Device Driver |
|---|
| 3 | 4 | * Copyright (c) 2009 - 2010, Intel Corporation and its suppliers. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 7 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 12 | | - * more details. |
|---|
| 13 | 5 | */ |
|---|
| 14 | 6 | |
|---|
| 15 | 7 | #ifndef __DENALI_H__ |
|---|
| 16 | 8 | #define __DENALI_H__ |
|---|
| 17 | 9 | |
|---|
| 18 | | -#include <linux/bitops.h> |
|---|
| 10 | +#include <linux/bits.h> |
|---|
| 19 | 11 | #include <linux/completion.h> |
|---|
| 12 | +#include <linux/list.h> |
|---|
| 20 | 13 | #include <linux/mtd/rawnand.h> |
|---|
| 21 | 14 | #include <linux/spinlock_types.h> |
|---|
| 22 | 15 | #include <linux/types.h> |
|---|
| .. | .. |
|---|
| 298 | 291 | #define CHNL_ACTIVE__CHANNEL2 BIT(2) |
|---|
| 299 | 292 | #define CHNL_ACTIVE__CHANNEL3 BIT(3) |
|---|
| 300 | 293 | |
|---|
| 301 | | -struct denali_nand_info { |
|---|
| 302 | | - struct nand_chip nand; |
|---|
| 303 | | - unsigned long clk_rate; /* core clock rate */ |
|---|
| 304 | | - unsigned long clk_x_rate; /* bus interface clock rate */ |
|---|
| 305 | | - int active_bank; /* currently selected bank */ |
|---|
| 294 | +/** |
|---|
| 295 | + * struct denali_chip_sel - per-CS data of Denali NAND |
|---|
| 296 | + * |
|---|
| 297 | + * @bank: bank id of the controller this CS is connected to |
|---|
| 298 | + * @hwhr2_and_we_2_re: value of timing register HWHR2_AND_WE_2_RE |
|---|
| 299 | + * @tcwaw_and_addr_2_data: value of timing register TCWAW_AND_ADDR_2_DATA |
|---|
| 300 | + * @re_2_we: value of timing register RE_2_WE |
|---|
| 301 | + * @acc_clks: value of timing register ACC_CLKS |
|---|
| 302 | + * @rdwr_en_lo_cnt: value of timing register RDWR_EN_LO_CNT |
|---|
| 303 | + * @rdwr_en_hi_cnt: value of timing register RDWR_EN_HI_CNT |
|---|
| 304 | + * @cs_setup_cnt: value of timing register CS_SETUP_CNT |
|---|
| 305 | + * @re_2_re: value of timing register RE_2_RE |
|---|
| 306 | + */ |
|---|
| 307 | +struct denali_chip_sel { |
|---|
| 308 | + int bank; |
|---|
| 309 | + u32 hwhr2_and_we_2_re; |
|---|
| 310 | + u32 tcwaw_and_addr_2_data; |
|---|
| 311 | + u32 re_2_we; |
|---|
| 312 | + u32 acc_clks; |
|---|
| 313 | + u32 rdwr_en_lo_cnt; |
|---|
| 314 | + u32 rdwr_en_hi_cnt; |
|---|
| 315 | + u32 cs_setup_cnt; |
|---|
| 316 | + u32 re_2_re; |
|---|
| 317 | +}; |
|---|
| 318 | + |
|---|
| 319 | +/** |
|---|
| 320 | + * struct denali_chip - per-chip data of Denali NAND |
|---|
| 321 | + * |
|---|
| 322 | + * @chip: base NAND chip structure |
|---|
| 323 | + * @node: node to be used to associate this chip with the controller |
|---|
| 324 | + * @nsels: the number of CS lines of this chip |
|---|
| 325 | + * @sels: the array of per-cs data |
|---|
| 326 | + */ |
|---|
| 327 | +struct denali_chip { |
|---|
| 328 | + struct nand_chip chip; |
|---|
| 329 | + struct list_head node; |
|---|
| 330 | + unsigned int nsels; |
|---|
| 331 | + struct denali_chip_sel sels[]; |
|---|
| 332 | +}; |
|---|
| 333 | + |
|---|
| 334 | +/** |
|---|
| 335 | + * struct denali_controller - Denali NAND controller data |
|---|
| 336 | + * |
|---|
| 337 | + * @controller: base NAND controller structure |
|---|
| 338 | + * @dev: device |
|---|
| 339 | + * @chips: the list of chips attached to this controller |
|---|
| 340 | + * @clk_rate: frequency of core clock |
|---|
| 341 | + * @clk_x_rate: frequency of bus interface clock |
|---|
| 342 | + * @reg: base of Register Interface |
|---|
| 343 | + * @host: base of Host Data/Command interface |
|---|
| 344 | + * @complete: completion used to wait for interrupts |
|---|
| 345 | + * @irq: interrupt number |
|---|
| 346 | + * @irq_mask: interrupt bits the controller is waiting for |
|---|
| 347 | + * @irq_status: interrupt bits of events that have happened |
|---|
| 348 | + * @irq_lock: lock to protect @irq_mask and @irq_status |
|---|
| 349 | + * @dma_avail: set if DMA engine is available |
|---|
| 350 | + * @devs_per_cs: number of devices connected in parallel |
|---|
| 351 | + * @oob_skip_bytes: number of bytes in OOB skipped by the ECC engine |
|---|
| 352 | + * @active_bank: active bank id |
|---|
| 353 | + * @nbanks: the number of banks supported by this controller |
|---|
| 354 | + * @revision: IP revision |
|---|
| 355 | + * @caps: controller capabilities that cannot be detected run-time |
|---|
| 356 | + * @ecc_caps: ECC engine capabilities |
|---|
| 357 | + * @host_read: callback for read access of Host Data/Command Interface |
|---|
| 358 | + * @host_write: callback for write access of Host Data/Command Interface |
|---|
| 359 | + * @setup_dma: callback for setup of the Data DMA |
|---|
| 360 | + */ |
|---|
| 361 | +struct denali_controller { |
|---|
| 362 | + struct nand_controller controller; |
|---|
| 306 | 363 | struct device *dev; |
|---|
| 307 | | - void __iomem *reg; /* Register Interface */ |
|---|
| 308 | | - void __iomem *host; /* Host Data/Command Interface */ |
|---|
| 364 | + struct list_head chips; |
|---|
| 365 | + unsigned long clk_rate; |
|---|
| 366 | + unsigned long clk_x_rate; |
|---|
| 367 | + void __iomem *reg; |
|---|
| 368 | + void __iomem *host; |
|---|
| 309 | 369 | struct completion complete; |
|---|
| 310 | | - spinlock_t irq_lock; /* protect irq_mask and irq_status */ |
|---|
| 311 | | - u32 irq_mask; /* interrupts we are waiting for */ |
|---|
| 312 | | - u32 irq_status; /* interrupts that have happened */ |
|---|
| 313 | 370 | int irq; |
|---|
| 314 | | - void *buf; /* for syndrome layout conversion */ |
|---|
| 315 | | - dma_addr_t dma_addr; |
|---|
| 316 | | - int dma_avail; /* can support DMA? */ |
|---|
| 317 | | - int devs_per_cs; /* devices connected in parallel */ |
|---|
| 318 | | - int oob_skip_bytes; /* number of bytes reserved for BBM */ |
|---|
| 319 | | - int max_banks; |
|---|
| 320 | | - unsigned int revision; /* IP revision */ |
|---|
| 321 | | - unsigned int caps; /* IP capability (or quirk) */ |
|---|
| 371 | + u32 irq_mask; |
|---|
| 372 | + u32 irq_status; |
|---|
| 373 | + spinlock_t irq_lock; |
|---|
| 374 | + bool dma_avail; |
|---|
| 375 | + int devs_per_cs; |
|---|
| 376 | + int oob_skip_bytes; |
|---|
| 377 | + int active_bank; |
|---|
| 378 | + int nbanks; |
|---|
| 379 | + unsigned int revision; |
|---|
| 380 | + unsigned int caps; |
|---|
| 322 | 381 | const struct nand_ecc_caps *ecc_caps; |
|---|
| 323 | | - u32 (*host_read)(struct denali_nand_info *denali, u32 addr); |
|---|
| 324 | | - void (*host_write)(struct denali_nand_info *denali, u32 addr, u32 data); |
|---|
| 325 | | - void (*setup_dma)(struct denali_nand_info *denali, dma_addr_t dma_addr, |
|---|
| 326 | | - int page, int write); |
|---|
| 382 | + u32 (*host_read)(struct denali_controller *denali, u32 addr); |
|---|
| 383 | + void (*host_write)(struct denali_controller *denali, u32 addr, |
|---|
| 384 | + u32 data); |
|---|
| 385 | + void (*setup_dma)(struct denali_controller *denali, dma_addr_t dma_addr, |
|---|
| 386 | + int page, bool write); |
|---|
| 327 | 387 | }; |
|---|
| 328 | 388 | |
|---|
| 329 | 389 | #define DENALI_CAP_HW_ECC_FIXUP BIT(0) |
|---|
| 330 | 390 | #define DENALI_CAP_DMA_64BIT BIT(1) |
|---|
| 331 | 391 | |
|---|
| 332 | 392 | int denali_calc_ecc_bytes(int step_size, int strength); |
|---|
| 333 | | -int denali_init(struct denali_nand_info *denali); |
|---|
| 334 | | -void denali_remove(struct denali_nand_info *denali); |
|---|
| 393 | +int denali_chip_init(struct denali_controller *denali, |
|---|
| 394 | + struct denali_chip *dchip); |
|---|
| 395 | +int denali_init(struct denali_controller *denali); |
|---|
| 396 | +void denali_remove(struct denali_controller *denali); |
|---|
| 335 | 397 | |
|---|
| 336 | 398 | #endif /* __DENALI_H__ */ |
|---|