source: rtems/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c @ 098ad421

Last change on this file since 098ad421 was 098ad421, checked in by Alex White <alex.white@…>, on 12/19/22 at 03:07:11

bsps/xilinx-zynqmp: Add JFFS2 GQSPI NOR driver

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <string.h>
29
30#include <bsp/irq.h>
31#include <bsp/jffs2_xqspipsu.h>
32#include <rtems/jffs2.h>
33#include <rtems/libio.h>
34#include <xqspipsu-flash-helper.h>
35
36typedef struct {
37  rtems_jffs2_flash_control super;
38  XQspiPsu *qspipsu;
39} flash_control;
40
41/* From the N25Q512A datasheet */
42#define BLOCK_SIZE (64UL * 1024UL)
43#define FLASH_SIZE (1024UL * BLOCK_SIZE)
44#define FLASH_DEVICE_ID 0xbb20 /* Type: 0xbb, Capacity: 0x20 */
45
46static flash_control *get_flash_control( rtems_jffs2_flash_control *super )
47{
48  return (flash_control *) super;
49}
50
51static int do_read(
52  rtems_jffs2_flash_control *super,
53  uint32_t offset,
54  unsigned char *buffer,
55  size_t size_of_buffer
56)
57{
58  int Status;
59
60  flash_control *self = get_flash_control( super );
61  XQspiPsu *QspiPsuPtr = self->qspipsu;
62  u8* ReadBuffer = NULL;
63
64  Status = QspiPsu_NOR_Read(
65    QspiPsuPtr,
66    offset,
67    size_of_buffer,
68    &ReadBuffer
69  );
70  if ( Status != XST_SUCCESS ) {
71    return Status;
72  }
73
74  /*
75   * We have to copy since we can't be sure that buffer is properly aligned.
76   */
77  memcpy( buffer, ReadBuffer, size_of_buffer );
78
79  return 0;
80}
81
82static int do_write(
83  rtems_jffs2_flash_control *super,
84  uint32_t offset,
85  const unsigned char *buffer,
86  size_t size_of_buffer
87)
88{
89  int Status;
90
91  flash_control *self = get_flash_control( super );
92  XQspiPsu *QspiPsuPtr = self->qspipsu;
93
94  Status = QspiPsu_NOR_Write(
95    QspiPsuPtr,
96    offset,
97    size_of_buffer,
98    (unsigned char *) buffer
99  );
100  if ( Status != XST_SUCCESS ) {
101    return Status;
102  }
103
104  return 0;
105}
106
107static int do_erase(
108  rtems_jffs2_flash_control *super,
109  uint32_t offset
110)
111{
112  int Status;
113
114  flash_control *self = get_flash_control( super );
115  XQspiPsu *QspiPsuPtr = self->qspipsu;
116
117  Status = QspiPsu_NOR_Erase(
118    QspiPsuPtr,
119    offset,
120    BLOCK_SIZE
121  );
122  if ( Status != XST_SUCCESS ) {
123    return Status;
124  }
125
126  return 0;
127}
128
129static void do_destroy( rtems_jffs2_flash_control *super )
130{
131  flash_control *self = get_flash_control( super );
132
133  rtems_interrupt_handler_remove(
134    ZYNQMP_IRQ_QSPI,
135    (rtems_interrupt_handler) XQspiPsu_InterruptHandler,
136    self->qspipsu
137  );
138}
139
140static flash_control flash_instance = {
141  .super = {
142    .block_size        = BLOCK_SIZE,
143    .flash_size        = FLASH_SIZE,
144    .read              = do_read,
145    .write             = do_write,
146    .erase             = do_erase,
147    .destroy           = do_destroy,
148    .device_identifier = FLASH_DEVICE_ID
149  }
150};
151
152static rtems_jffs2_mount_data mount_data = {
153  .flash_control      = &flash_instance.super,
154  .compressor_control = NULL
155};
156
157int xilinx_zynqmp_nor_jffs2_initialize(
158  const char *mount_dir,
159  XQspiPsu *qspipsu_ptr
160)
161{
162  int rv = 0;
163
164  flash_instance.qspipsu = qspipsu_ptr;
165
166  rv = QspiPsu_NOR_Initialize(
167    flash_instance.qspipsu,
168    ZYNQMP_IRQ_QSPI
169  );
170  if ( rv != 0 ) {
171    return rv;
172  }
173
174  rv = mount(
175    NULL,
176    mount_dir,
177    RTEMS_FILESYSTEM_TYPE_JFFS2,
178    RTEMS_FILESYSTEM_READ_WRITE,
179    &mount_data
180  );
181  if ( rv != 0 ) {
182    return rv;
183  }
184
185  return 0;
186}
Note: See TracBrowser for help on using the repository browser.