0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/err.h>
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/mtd/hyperbus.h>
0012 #include <linux/mtd/mtd.h>
0013 #include <linux/mux/consumer.h>
0014 #include <linux/of.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/types.h>
0017
0018 #include <memory/renesas-rpc-if.h>
0019
0020 struct rpcif_hyperbus {
0021 struct rpcif rpc;
0022 struct hyperbus_ctlr ctlr;
0023 struct hyperbus_device hbdev;
0024 };
0025
0026 static const struct rpcif_op rpcif_op_tmpl = {
0027 .cmd = {
0028 .buswidth = 8,
0029 .ddr = true,
0030 },
0031 .ocmd = {
0032 .buswidth = 8,
0033 .ddr = true,
0034 },
0035 .addr = {
0036 .nbytes = 1,
0037 .buswidth = 8,
0038 .ddr = true,
0039 },
0040 .data = {
0041 .buswidth = 8,
0042 .ddr = true,
0043 },
0044 };
0045
0046 static void rpcif_hb_prepare_read(struct rpcif *rpc, void *to,
0047 unsigned long from, ssize_t len)
0048 {
0049 struct rpcif_op op = rpcif_op_tmpl;
0050
0051 op.cmd.opcode = HYPERBUS_RW_READ | HYPERBUS_AS_MEM;
0052 op.addr.val = from >> 1;
0053 op.dummy.buswidth = 1;
0054 op.dummy.ncycles = 15;
0055 op.data.dir = RPCIF_DATA_IN;
0056 op.data.nbytes = len;
0057 op.data.buf.in = to;
0058
0059 rpcif_prepare(rpc, &op, NULL, NULL);
0060 }
0061
0062 static void rpcif_hb_prepare_write(struct rpcif *rpc, unsigned long to,
0063 void *from, ssize_t len)
0064 {
0065 struct rpcif_op op = rpcif_op_tmpl;
0066
0067 op.cmd.opcode = HYPERBUS_RW_WRITE | HYPERBUS_AS_MEM;
0068 op.addr.val = to >> 1;
0069 op.data.dir = RPCIF_DATA_OUT;
0070 op.data.nbytes = len;
0071 op.data.buf.out = from;
0072
0073 rpcif_prepare(rpc, &op, NULL, NULL);
0074 }
0075
0076 static u16 rpcif_hb_read16(struct hyperbus_device *hbdev, unsigned long addr)
0077 {
0078 struct rpcif_hyperbus *hyperbus =
0079 container_of(hbdev, struct rpcif_hyperbus, hbdev);
0080 map_word data;
0081
0082 rpcif_hb_prepare_read(&hyperbus->rpc, &data, addr, 2);
0083
0084 rpcif_manual_xfer(&hyperbus->rpc);
0085
0086 return data.x[0];
0087 }
0088
0089 static void rpcif_hb_write16(struct hyperbus_device *hbdev, unsigned long addr,
0090 u16 data)
0091 {
0092 struct rpcif_hyperbus *hyperbus =
0093 container_of(hbdev, struct rpcif_hyperbus, hbdev);
0094
0095 rpcif_hb_prepare_write(&hyperbus->rpc, addr, &data, 2);
0096
0097 rpcif_manual_xfer(&hyperbus->rpc);
0098 }
0099
0100 static void rpcif_hb_copy_from(struct hyperbus_device *hbdev, void *to,
0101 unsigned long from, ssize_t len)
0102 {
0103 struct rpcif_hyperbus *hyperbus =
0104 container_of(hbdev, struct rpcif_hyperbus, hbdev);
0105
0106 rpcif_hb_prepare_read(&hyperbus->rpc, to, from, len);
0107
0108 rpcif_dirmap_read(&hyperbus->rpc, from, len, to);
0109 }
0110
0111 static const struct hyperbus_ops rpcif_hb_ops = {
0112 .read16 = rpcif_hb_read16,
0113 .write16 = rpcif_hb_write16,
0114 .copy_from = rpcif_hb_copy_from,
0115 };
0116
0117 static int rpcif_hb_probe(struct platform_device *pdev)
0118 {
0119 struct device *dev = &pdev->dev;
0120 struct rpcif_hyperbus *hyperbus;
0121 int error;
0122
0123 hyperbus = devm_kzalloc(dev, sizeof(*hyperbus), GFP_KERNEL);
0124 if (!hyperbus)
0125 return -ENOMEM;
0126
0127 error = rpcif_sw_init(&hyperbus->rpc, pdev->dev.parent);
0128 if (error)
0129 return error;
0130
0131 platform_set_drvdata(pdev, hyperbus);
0132
0133 rpcif_enable_rpm(&hyperbus->rpc);
0134
0135 error = rpcif_hw_init(&hyperbus->rpc, true);
0136 if (error)
0137 goto out_disable_rpm;
0138
0139 hyperbus->hbdev.map.size = hyperbus->rpc.size;
0140 hyperbus->hbdev.map.virt = hyperbus->rpc.dirmap;
0141
0142 hyperbus->ctlr.dev = dev;
0143 hyperbus->ctlr.ops = &rpcif_hb_ops;
0144 hyperbus->hbdev.ctlr = &hyperbus->ctlr;
0145 hyperbus->hbdev.np = of_get_next_child(pdev->dev.parent->of_node, NULL);
0146 error = hyperbus_register_device(&hyperbus->hbdev);
0147 if (error)
0148 goto out_disable_rpm;
0149
0150 return 0;
0151
0152 out_disable_rpm:
0153 rpcif_disable_rpm(&hyperbus->rpc);
0154 return error;
0155 }
0156
0157 static int rpcif_hb_remove(struct platform_device *pdev)
0158 {
0159 struct rpcif_hyperbus *hyperbus = platform_get_drvdata(pdev);
0160
0161 hyperbus_unregister_device(&hyperbus->hbdev);
0162
0163 rpcif_disable_rpm(&hyperbus->rpc);
0164
0165 return 0;
0166 }
0167
0168 static struct platform_driver rpcif_platform_driver = {
0169 .probe = rpcif_hb_probe,
0170 .remove = rpcif_hb_remove,
0171 .driver = {
0172 .name = "rpc-if-hyperflash",
0173 },
0174 };
0175
0176 module_platform_driver(rpcif_platform_driver);
0177
0178 MODULE_DESCRIPTION("Renesas RPC-IF HyperFlash driver");
0179 MODULE_LICENSE("GPL v2");