xref: /linux/drivers/mtd/nand/raw/r852.h (revision cdd38c5f1ce4398ec58fec95904b75824daab7b5)
1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
267e054e9SMaxim Levitsky /*
367e054e9SMaxim Levitsky  * Copyright © 2009 - Maxim Levitsky
467e054e9SMaxim Levitsky  * driver for Ricoh xD readers
567e054e9SMaxim Levitsky  */
667e054e9SMaxim Levitsky 
767e054e9SMaxim Levitsky #include <linux/pci.h>
867e054e9SMaxim Levitsky #include <linux/completion.h>
967e054e9SMaxim Levitsky #include <linux/workqueue.h>
10d4092d76SBoris Brezillon #include <linux/mtd/rawnand.h>
1167e054e9SMaxim Levitsky #include <linux/spinlock.h>
1267e054e9SMaxim Levitsky 
1367e054e9SMaxim Levitsky 
1467e054e9SMaxim Levitsky /* nand interface + ecc
1567e054e9SMaxim Levitsky    byte write/read does one cycle on nand data lines.
1667e054e9SMaxim Levitsky    dword write/read does 4 cycles
1767e054e9SMaxim Levitsky    if R852_CTL_ECC_ACCESS is set in R852_CTL, then dword read reads
1867e054e9SMaxim Levitsky    results of ecc correction, if DMA read was done before.
1967e054e9SMaxim Levitsky    If write was done two dword reads read generated ecc checksums
2067e054e9SMaxim Levitsky */
2167e054e9SMaxim Levitsky #define	R852_DATALINE		0x00
2267e054e9SMaxim Levitsky 
2367e054e9SMaxim Levitsky /* control register */
2467e054e9SMaxim Levitsky #define R852_CTL		0x04
2567e054e9SMaxim Levitsky #define R852_CTL_COMMAND 	0x01	/* send command (#CLE)*/
2667e054e9SMaxim Levitsky #define R852_CTL_DATA		0x02	/* read/write data (#ALE)*/
2767e054e9SMaxim Levitsky #define R852_CTL_ON		0x04	/* only seem to controls the hd led, */
2867e054e9SMaxim Levitsky 					/* but has to be set on start...*/
2967e054e9SMaxim Levitsky #define R852_CTL_RESET		0x08	/* unknown, set only on start once*/
3067e054e9SMaxim Levitsky #define R852_CTL_CARDENABLE	0x10	/* probably (#CE) - always set*/
3167e054e9SMaxim Levitsky #define R852_CTL_ECC_ENABLE	0x20	/* enable ecc engine */
3267e054e9SMaxim Levitsky #define R852_CTL_ECC_ACCESS	0x40	/* read/write ecc via reg #0*/
3367e054e9SMaxim Levitsky #define R852_CTL_WRITE		0x80	/* set when performing writes (#WP) */
3467e054e9SMaxim Levitsky 
3567e054e9SMaxim Levitsky /* card detection status */
3667e054e9SMaxim Levitsky #define R852_CARD_STA		0x05
3767e054e9SMaxim Levitsky 
3867e054e9SMaxim Levitsky #define R852_CARD_STA_CD	0x01	/* state of #CD line, same as 0x04 */
3967e054e9SMaxim Levitsky #define R852_CARD_STA_RO	0x02	/* card is readonly */
4067e054e9SMaxim Levitsky #define R852_CARD_STA_PRESENT	0x04	/* card is present (#CD) */
4167e054e9SMaxim Levitsky #define R852_CARD_STA_ABSENT	0x08	/* card is absent */
4267e054e9SMaxim Levitsky #define R852_CARD_STA_BUSY	0x80	/* card is busy - (#R/B) */
4367e054e9SMaxim Levitsky 
4467e054e9SMaxim Levitsky /* card detection irq status & enable*/
4567e054e9SMaxim Levitsky #define R852_CARD_IRQ_STA	0x06	/* IRQ status */
4667e054e9SMaxim Levitsky #define R852_CARD_IRQ_ENABLE	0x07	/* IRQ enable */
4767e054e9SMaxim Levitsky 
4867e054e9SMaxim Levitsky #define R852_CARD_IRQ_CD	0x01	/* fire when #CD lights, same as 0x04*/
4967e054e9SMaxim Levitsky #define R852_CARD_IRQ_REMOVE	0x04	/* detect card removal */
5067e054e9SMaxim Levitsky #define R852_CARD_IRQ_INSERT	0x08	/* detect card insert */
5167e054e9SMaxim Levitsky #define R852_CARD_IRQ_UNK1	0x10	/* unknown */
5267e054e9SMaxim Levitsky #define R852_CARD_IRQ_GENABLE	0x80	/* general enable */
5367e054e9SMaxim Levitsky #define R852_CARD_IRQ_MASK	0x1D
5467e054e9SMaxim Levitsky 
5567e054e9SMaxim Levitsky 
5667e054e9SMaxim Levitsky 
5767e054e9SMaxim Levitsky /* hardware enable */
5867e054e9SMaxim Levitsky #define R852_HW			0x08
5967e054e9SMaxim Levitsky #define R852_HW_ENABLED		0x01	/* hw enabled */
6067e054e9SMaxim Levitsky #define R852_HW_UNKNOWN		0x80
6167e054e9SMaxim Levitsky 
6267e054e9SMaxim Levitsky 
6367e054e9SMaxim Levitsky /* dma capabilities */
6467e054e9SMaxim Levitsky #define R852_DMA_CAP		0x09
6567e054e9SMaxim Levitsky #define R852_SMBIT		0x20	/* if set with bit #6 or bit #7, then */
6667e054e9SMaxim Levitsky 					/* hw is smartmedia */
6767e054e9SMaxim Levitsky #define R852_DMA1		0x40	/* if set w/bit #7, dma is supported */
6867e054e9SMaxim Levitsky #define R852_DMA2		0x80	/* if set w/bit #6, dma is supported */
6967e054e9SMaxim Levitsky 
7067e054e9SMaxim Levitsky 
7167e054e9SMaxim Levitsky /* physical DMA address - 32 bit value*/
7267e054e9SMaxim Levitsky #define R852_DMA_ADDR		0x0C
7367e054e9SMaxim Levitsky 
7467e054e9SMaxim Levitsky 
7567e054e9SMaxim Levitsky /* dma settings */
7667e054e9SMaxim Levitsky #define R852_DMA_SETTINGS	0x10
7767e054e9SMaxim Levitsky #define R852_DMA_MEMORY		0x01	/* (memory <-> internal hw buffer) */
7867e054e9SMaxim Levitsky #define R852_DMA_READ		0x02	/* 0 = write, 1 = read */
7967e054e9SMaxim Levitsky #define R852_DMA_INTERNAL	0x04	/* (internal hw buffer <-> card) */
8067e054e9SMaxim Levitsky 
8167e054e9SMaxim Levitsky /* dma IRQ status */
8267e054e9SMaxim Levitsky #define R852_DMA_IRQ_STA		0x14
8367e054e9SMaxim Levitsky 
8467e054e9SMaxim Levitsky /* dma IRQ enable */
8567e054e9SMaxim Levitsky #define R852_DMA_IRQ_ENABLE	0x18
8667e054e9SMaxim Levitsky 
8767e054e9SMaxim Levitsky #define R852_DMA_IRQ_MEMORY	0x01	/* (memory <-> internal hw buffer) */
8867e054e9SMaxim Levitsky #define R852_DMA_IRQ_ERROR	0x02	/* error did happen */
8967e054e9SMaxim Levitsky #define R852_DMA_IRQ_INTERNAL	0x04	/* (internal hw buffer <-> card) */
9067e054e9SMaxim Levitsky #define R852_DMA_IRQ_MASK	0x07	/* mask of all IRQ bits */
9167e054e9SMaxim Levitsky 
9267e054e9SMaxim Levitsky 
9367e054e9SMaxim Levitsky /* ECC syndrome format - read from reg #0 will return two copies of these for
9467e054e9SMaxim Levitsky    each half of the page.
9567e054e9SMaxim Levitsky    first byte is error byte location, and second, bit location + flags */
9667e054e9SMaxim Levitsky #define R852_ECC_ERR_BIT_MSK	0x07	/* error bit location */
9767e054e9SMaxim Levitsky #define R852_ECC_CORRECT		0x10	/* no errors - (guessed) */
9867e054e9SMaxim Levitsky #define R852_ECC_CORRECTABLE	0x20	/* correctable error exist */
9967e054e9SMaxim Levitsky #define R852_ECC_FAIL		0x40	/* non correctable error detected */
10067e054e9SMaxim Levitsky 
10167e054e9SMaxim Levitsky #define R852_DMA_LEN		512
10267e054e9SMaxim Levitsky 
10367e054e9SMaxim Levitsky #define DMA_INTERNAL	0
10467e054e9SMaxim Levitsky #define DMA_MEMORY	1
10567e054e9SMaxim Levitsky 
10667e054e9SMaxim Levitsky struct r852_device {
107*7ef969a0SMiquel Raynal 	struct nand_controller		controller;
10867e054e9SMaxim Levitsky 	void __iomem *mmio;		/* mmio */
10967e054e9SMaxim Levitsky 	struct nand_chip *chip;		/* nand chip backpointer */
11067e054e9SMaxim Levitsky 	struct pci_dev *pci_dev;	/* pci backpointer */
11167e054e9SMaxim Levitsky 
11267e054e9SMaxim Levitsky 	/* dma area */
11367e054e9SMaxim Levitsky 	dma_addr_t phys_dma_addr;	/* bus address of buffer*/
11467e054e9SMaxim Levitsky 	struct completion dma_done;	/* data transfer done */
11567e054e9SMaxim Levitsky 
11667e054e9SMaxim Levitsky 	dma_addr_t phys_bounce_buffer;	/* bus address of bounce buffer */
11767e054e9SMaxim Levitsky 	uint8_t *bounce_buffer;		/* virtual address of bounce buffer */
11867e054e9SMaxim Levitsky 
11967e054e9SMaxim Levitsky 	int dma_dir;			/* 1 = read, 0 = write */
12067e054e9SMaxim Levitsky 	int dma_stage;			/* 0 - idle, 1 - first step,
12167e054e9SMaxim Levitsky 					   2 - second step */
12267e054e9SMaxim Levitsky 
12367e054e9SMaxim Levitsky 	int dma_state;			/* 0 = internal, 1 = memory */
12467e054e9SMaxim Levitsky 	int dma_error;			/* dma errors */
12567e054e9SMaxim Levitsky 	int dma_usable;			/* is it possible to use dma */
12667e054e9SMaxim Levitsky 
12767e054e9SMaxim Levitsky 	/* card status area */
12867e054e9SMaxim Levitsky 	struct delayed_work card_detect_work;
12967e054e9SMaxim Levitsky 	struct workqueue_struct *card_workqueue;
130ed8f0b23SColin Ian King 	int card_registered;		/* card registered with mtd */
13167e054e9SMaxim Levitsky 	int card_detected;		/* card detected in slot */
13267e054e9SMaxim Levitsky 	int card_unstable;		/* whenever the card is inserted,
13367e054e9SMaxim Levitsky 					   is not known yet */
13467e054e9SMaxim Levitsky 	int readonly;			/* card is readonly */
13567e054e9SMaxim Levitsky 	int sm;				/* Is card smartmedia */
13667e054e9SMaxim Levitsky 
13767e054e9SMaxim Levitsky 	/* interrupt handling */
13867e054e9SMaxim Levitsky 	spinlock_t irqlock;		/* IRQ protecting lock */
13967e054e9SMaxim Levitsky 	int irq;			/* irq num */
14067e054e9SMaxim Levitsky 	/* misc */
14167e054e9SMaxim Levitsky 	void *tmp_buffer;		/* temporary buffer */
14267e054e9SMaxim Levitsky 	uint8_t ctlreg;			/* cached contents of control reg */
14367e054e9SMaxim Levitsky };
14467e054e9SMaxim Levitsky 
14567e054e9SMaxim Levitsky #define dbg(format, ...) \
14667e054e9SMaxim Levitsky 	if (debug) \
14763fa37f0SShreeya Patel 		pr_debug(format "\n", ## __VA_ARGS__)
14867e054e9SMaxim Levitsky 
14967e054e9SMaxim Levitsky #define dbg_verbose(format, ...) \
15067e054e9SMaxim Levitsky 	if (debug > 1) \
15163fa37f0SShreeya Patel 		pr_debug(format "\n", ## __VA_ARGS__)
15267e054e9SMaxim Levitsky 
15367e054e9SMaxim Levitsky 
15467e054e9SMaxim Levitsky #define message(format, ...) \
15563fa37f0SShreeya Patel 	pr_info(format "\n", ## __VA_ARGS__)
156