• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hifmc100_spi_micron.c
3  *
4  * The Flash Memory Controller v100 Device Driver for hisilicon
5  *
6  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 /*****************************************************************************/
24 #define SPI_CMD_FIRST_RESET_4ADDR  0x66
25 #define SPI_CMD_SECOND_RESET_4ADDR 0x99
26 
27 #define SPI_CMD_FLAG_SR_MICRON  0x70  /* READ FLAG STATUS REGISTER */
28 #define SPI_CMD_RD_RDCR_MICRON  0xB5  /* READ NONVOLATILE CONFIGURATION
29                                          REGISTER */
30 #define SPI_CMD_WR_RDCR_MICRON  0xB1 /* WRITE NONVOLATILE CONFIGURATION
31                                          REGISTER */
32 #define SPI_NOR_ADS_MASK    0x1
33 #define spi_nor_get_4byte_by_flag_sr(sr)     ((sr) & SPI_NOR_ADS_MASK)
34 
35 #define spi_nor_ads_set_4byte(cr)        ((cr) & (~SPI_NOR_ADS_MASK))
36 #define spi_nor_ads_get_4byte(cr)        ((cr) & SPI_NOR_ADS_MASK)
37 /****************************************************************************/
spi_micron_entry_4addr(struct hifmc_spi * spi,int enable)38 static int spi_micron_entry_4addr(struct hifmc_spi *spi, int enable)
39 {
40 	unsigned char status;
41 	unsigned int reg;
42 	const char *str[] = {"Disable", "Enable"};
43 	struct hifmc_host *host = (struct hifmc_host *)spi->host;
44 
45 	fmc_pr(AC_DBG, "\t* Start SPI Nor %s 4-byte mode.\n",
46 	       str[enable]);
47 
48 	if (spi->addrcycle != SPI_NOR_4BYTE_ADDR_LEN) {
49 		fmc_pr(AC_DBG, "\t* Not support 4B mode.\n");
50 		return 0;
51 	}
52 
53 	status = spi_general_get_flash_register(spi, SPI_CMD_FLAG_SR_MICRON);
54 	fmc_pr(AC_DBG, "\t Read flag status register[%#x]:%#x\n",
55 	       SPI_CMD_FLAG_SR_MICRON, status);
56 	if (spi_nor_get_4byte_by_flag_sr(status) == enable) {
57 		fmc_pr(AC_DBG, "\t* 4-byte was %sd, reg:%#x\n", str[enable],
58 		       status);
59 		return 0;
60 	}
61 
62 	spi->driver->write_enable(spi);
63 
64 	if (enable)
65 		reg = SPI_CMD_EN4B;
66 	else
67 		reg = SPI_CMD_EX4B;
68 	hifmc_write(host, FMC_CMD, fmc_cmd_cmd1(reg));
69 	fmc_pr(AC_DBG, "\t  Set CMD[%#x]%#x\n", FMC_CMD, reg);
70 
71 	reg = op_cfg_fm_cs(spi->chipselect) | OP_CFG_OEN_EN;
72 	hifmc_write(host, FMC_OP_CFG, reg);
73 	fmc_pr(AC_DBG, "\t  Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
74 
75 	reg = fmc_op_cmd1_en(ENABLE) | FMC_OP_REG_OP_START;
76 	hifmc_write(host, FMC_OP, reg);
77 	fmc_pr(AC_DBG, "\t  Set OP[%#x]%#x\n", FMC_OP, reg);
78 
79 	fmc_cmd_wait_cpu_finish(host);
80 
81 	spi->driver->wait_ready(spi);
82 
83 	status = spi_general_get_flash_register(spi,
84 						SPI_CMD_FLAG_SR_MICRON);
85 	fmc_pr(AC_DBG, "\t Read flag status register[%#x]:%#x\n",
86 	       SPI_CMD_FLAG_SR_MICRON, status);
87 	if (spi_nor_get_4byte_by_flag_sr(status) != enable) {
88 		db_msg("Error: %s 4-byte failed! SR3:%#x\n",
89 		       str[enable], status);
90 		return status;
91 	}
92 
93 	fmc_pr(AC_DBG, "\t  %s 4-byte success, SR3:%#x\n", str[enable], status);
94 	fmc_pr(AC_DBG, "\t* End SPI Nor flash %s 4-byte mode.\n", str[enable]);
95 
96 	return 0;
97 }
98