• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hifmc100_spi_issi.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 #define SPI_NOR_ISSI_QE_SHIFT      6
24 #define SPI_NOR_ISSI_SRWD_MASK      (1 << 7)
25 #define SPI_NOR_ISSI_QE_MASK        (1 << SPI_NOR_ISSI_QE_SHIFT)
26 #define spi_nor_issi_get_qe(sr)        (((sr) & SPI_NOR_ISSI_QE_MASK) \
27 						>> SPI_NOR_ISSI_QE_SHIFT)
28 
spi_issi_set_cmd(struct hifmc_spi * spi)29 static void spi_issi_set_cmd(struct hifmc_spi *spi)
30 {
31 	unsigned int reg;
32 	struct hifmc_host *host = (struct hifmc_host *)spi->host;
33 
34 	reg = fmc_cmd_cmd1(SPI_CMD_WRSR);
35 	hifmc_write(host, FMC_CMD, reg);
36 	fmc_pr(QE_DBG, "\t|-Set CMD[%#x]%#x\n", FMC_CMD, reg);
37 
38 	reg = op_cfg_fm_cs(spi->chipselect) | OP_CFG_OEN_EN;
39 	hifmc_write(host, FMC_OP_CFG, reg);
40 	fmc_pr(QE_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
41 
42 	reg = fmc_data_num_cnt(SPI_NOR_SR_LEN);
43 	hifmc_write(host, FMC_DATA_NUM, reg);
44 	fmc_pr(QE_DBG, "\t|-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg);
45 
46 	reg = fmc_op_cmd1_en(ENABLE) |
47 		fmc_op_write_data_en(ENABLE) |
48 		FMC_OP_REG_OP_START;
49 	hifmc_write(host, FMC_OP, reg);
50 	fmc_pr(QE_DBG, "\t|-Set OP[%#x]%#x\n", FMC_OP, reg);
51 
52 	fmc_cmd_wait_cpu_finish(host);
53 }
54 
spi_issi_qe_enable(struct hifmc_spi * spi)55 static int spi_issi_qe_enable(struct hifmc_spi *spi)
56 {
57 	unsigned char config;
58 	unsigned char op;
59 
60 	const char *str[] = {"Disable", "Enable"};
61 	struct hifmc_host *host = (struct hifmc_host *)spi->host;
62 
63 	op = spi_is_quad(spi);
64 
65 	fmc_pr(QE_DBG, "\t*-Start SPI Nor %s Quad.\n", str[op]);
66 
67 	config = spi_general_get_flash_register(spi, SPI_CMD_RDSR);
68 	fmc_pr(QE_DBG, "\t|-Read Config Register[%#x]%#x\n", SPI_CMD_RDSR,
69 	       config);
70 	if (op == spi_nor_issi_get_qe(config)) {
71 		fmc_pr(QE_DBG, "\t* Quad was %sd, config:%#x\n", str[op],
72 		       config);
73 		return op;
74 	}
75 
76 	spi->driver->write_enable(spi);
77 
78 	config = spi_general_get_flash_register(spi, SPI_CMD_RDSR);
79 	config &= ~SPI_NOR_ISSI_SRWD_MASK;
80 
81 	if (op)
82 		config |= SPI_NOR_ISSI_QE_MASK;
83 	else
84 		config &= ~SPI_NOR_ISSI_QE_MASK;
85 	writeb(config, host->iobase);
86 	fmc_pr(QE_DBG, "\t|-Write IO[%p]%#x\n", host->iobase,
87 	       *(unsigned short *)host->iobase);
88 
89 	spi_issi_set_cmd(spi);
90 
91 	spi->driver->wait_ready(spi);
92 
93 	config = spi_general_get_flash_register(spi, SPI_CMD_RDSR);
94 	if (op == spi_nor_issi_get_qe(config)) {
95 		fmc_pr(QE_DBG, "\t|-%s Quad success, config: %#x\n", str[op],
96 		       config);
97 	} else {
98 		db_msg("Error: %s Quad failed! reg: %#x\n", str[op], config);
99 	}
100 
101 	fmc_pr(QE_DBG, "\t* End SPI Nor %s Quad.\n", str[op]);
102 
103 	return op;
104 }
105 
106