mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 03:58:17 +00:00 
			
		
		
		
	Adds support for NAND controllers found on OcteonTX or OcteonTX2 SoC platforms. Also includes driver to support Hardware ECC using BCH HW engine found on these platforms. Signed-off-by: Aaron Williams <awilliams@marvell.com> Signed-off-by: Suneel Garapati <sgarapati@marvell.com> Signed-off-by: Stefan Roese <sr@denx.de>
		
			
				
	
	
		
			132 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* SPDX-License-Identifier:    GPL-2.0
 | |
|  *
 | |
|  * Copyright (C) 2018 Marvell International Ltd.
 | |
|  */
 | |
| 
 | |
| #ifndef __OCTEONTX_BCH_H__
 | |
| #define __OCTEONTX_BCH_H__
 | |
| 
 | |
| #include "octeontx_bch_regs.h"
 | |
| 
 | |
| /* flags to indicate the features supported */
 | |
| #define BCH_FLAG_SRIOV_ENABLED		BIT(1)
 | |
| 
 | |
| /*
 | |
|  * BCH Registers map for 81xx
 | |
|  */
 | |
| 
 | |
| /* PF registers */
 | |
| #define BCH_CTL				0x0ull
 | |
| #define BCH_ERR_CFG			0x10ull
 | |
| #define BCH_BIST_RESULT			0x80ull
 | |
| #define BCH_ERR_INT			0x88ull
 | |
| #define BCH_ERR_INT_W1S			0x90ull
 | |
| #define BCH_ERR_INT_ENA_W1C		0xA0ull
 | |
| #define BCH_ERR_INT_ENA_W1S		0xA8ull
 | |
| 
 | |
| /* VF registers */
 | |
| #define BCH_VQX_CTL(z)			0x0ull
 | |
| #define BCH_VQX_CMD_BUF(z)		0x8ull
 | |
| #define BCH_VQX_CMD_PTR(z)		0x20ull
 | |
| #define BCH_VQX_DOORBELL(z)		0x800ull
 | |
| 
 | |
| #define BCHPF_DRIVER_NAME	"octeontx-bchpf"
 | |
| #define BCHVF_DRIVER_NAME	"octeontx-bchvf"
 | |
| 
 | |
| struct bch_device {
 | |
| 	struct list_head list;
 | |
| 	u8 max_vfs;
 | |
| 	u8 vfs_enabled;
 | |
| 	u8 vfs_in_use;
 | |
| 	u32 flags;
 | |
| 	void __iomem *reg_base;
 | |
| 	struct udevice *dev;
 | |
| };
 | |
| 
 | |
| struct bch_vf {
 | |
| 	u16 flags;
 | |
| 	u8 vfid;
 | |
| 	u8 node;
 | |
| 	u8 priority;
 | |
| 	struct udevice *dev;
 | |
| 	void __iomem *reg_base;
 | |
| };
 | |
| 
 | |
| struct buf_ptr {
 | |
| 	u8 *vptr;
 | |
| 	dma_addr_t dma_addr;
 | |
| 	u16 size;
 | |
| };
 | |
| 
 | |
| void *octeontx_bch_getv(void);
 | |
| void octeontx_bch_putv(void *token);
 | |
| void *octeontx_bch_getp(void);
 | |
| void octeontx_bch_putp(void *token);
 | |
| int octeontx_bch_wait(struct bch_vf *vf, union bch_resp *resp,
 | |
| 		      dma_addr_t handle);
 | |
| /**
 | |
|  * Given a data block calculate the ecc data and fill in the response
 | |
|  *
 | |
|  * @param[in] block	8-byte aligned pointer to data block to calculate ECC
 | |
|  * @param block_size	Size of block in bytes, must be a multiple of two.
 | |
|  * @param bch_level	Number of errors that must be corrected.  The number of
 | |
|  *			parity bytes is equal to ((15 * bch_level) + 7) / 8.
 | |
|  *			Must be 4, 8, 16, 24, 32, 40, 48, 56, 60 or 64.
 | |
|  * @param[out] ecc	8-byte aligned pointer to where ecc data should go
 | |
|  * @param[in] resp	pointer to where responses will be written.
 | |
|  *
 | |
|  * @return Zero on success, negative on failure.
 | |
|  */
 | |
| int octeontx_bch_encode(struct bch_vf *vf, dma_addr_t block, u16 block_size,
 | |
| 			u8 bch_level, dma_addr_t ecc, dma_addr_t resp);
 | |
| 
 | |
| /**
 | |
|  * Given a data block and ecc data correct the data block
 | |
|  *
 | |
|  * @param[in] block_ecc_in	8-byte aligned pointer to data block with ECC
 | |
|  *				data concatenated to the end to correct
 | |
|  * @param block_size		Size of block in bytes, must be a multiple of
 | |
|  *				two.
 | |
|  * @param bch_level		Number of errors that must be corrected.  The
 | |
|  *				number of parity bytes is equal to
 | |
|  *				((15 * bch_level) + 7) / 8.
 | |
|  *				Must be 4, 8, 16, 24, 32, 40, 48, 56, 60 or 64.
 | |
|  * @param[out] block_out	8-byte aligned pointer to corrected data buffer.
 | |
|  *				This should not be the same as block_ecc_in.
 | |
|  * @param[in] resp		pointer to where responses will be written.
 | |
|  *
 | |
|  * @return Zero on success, negative on failure.
 | |
|  */
 | |
| 
 | |
| int octeontx_bch_decode(struct bch_vf *vf, dma_addr_t block_ecc_in,
 | |
| 			u16 block_size, u8 bch_level,
 | |
| 			dma_addr_t block_out, dma_addr_t resp);
 | |
| 
 | |
| /**
 | |
|  * Ring the BCH doorbell telling it that new commands are
 | |
|  * available.
 | |
|  *
 | |
|  * @param num_commands	Number of new commands
 | |
|  * @param vf		virtual function handle
 | |
|  */
 | |
| static inline void octeontx_bch_write_doorbell(u64 num_commands,
 | |
| 					       struct bch_vf *vf)
 | |
| {
 | |
| 	u64 num_words = num_commands * sizeof(union bch_cmd) / sizeof(uint64_t);
 | |
| 
 | |
| 	writeq(num_words, vf->reg_base + BCH_VQX_DOORBELL(0));
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Since it's possible (and even likely) that the NAND device will be probed
 | |
|  * before the BCH device has been probed, we may need to defer the probing.
 | |
|  *
 | |
|  * In this case, the initial probe returns success but the actual probing
 | |
|  * is deferred until the BCH VF has been probed.
 | |
|  *
 | |
|  * @return	0 for success, otherwise error
 | |
|  */
 | |
| int octeontx_pci_nand_deferred_probe(void);
 | |
| 
 | |
| #endif /* __OCTEONTX_BCH_H__ */
 |