1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2017 Hisilicon Limited, All Rights Reserved.
4 * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
5 * Author: Zou Rongrong <zourongrong@huawei.com>
6 * Author: John Garry <john.garry@huawei.com>
9 #include <linux/acpi.h>
10 #include <linux/console.h>
11 #include <linux/delay.h>
13 #include <linux/logic_pio.h>
14 #include <linux/module.h>
16 #include <linux/of_address.h>
17 #include <linux/of_platform.h>
18 #include <linux/pci.h>
19 #include <linux/serial_8250.h>
20 #include <linux/slab.h>
22 #define DRV_NAME "hisi-lpc"
25 * Setting this bit means each IO operation will target a different port
26 * address; 0 means repeated IO operations will use the same port,
29 #define FG_INCRADDR_LPC 0x02
31 struct lpc_cycle_para
{
33 unsigned int csize
; /* data length of each operation */
37 spinlock_t cycle_lock
;
38 void __iomem
*membase
;
39 struct logic_pio_hwaddr
*io_host
;
42 /* The max IO cycle counts supported is four per operation at maximum */
43 #define LPC_MAX_DWIDTH 4
45 #define LPC_REG_STARTUP_SIGNAL 0x00
46 #define LPC_REG_STARTUP_SIGNAL_START BIT(0)
47 #define LPC_REG_OP_STATUS 0x04
48 #define LPC_REG_OP_STATUS_IDLE BIT(0)
49 #define LPC_REG_OP_STATUS_FINISHED BIT(1)
50 #define LPC_REG_OP_LEN 0x10 /* LPC cycles count per start */
51 #define LPC_REG_CMD 0x14
52 #define LPC_REG_CMD_OP BIT(0) /* 0: read, 1: write */
53 #define LPC_REG_CMD_SAMEADDR BIT(3)
54 #define LPC_REG_ADDR 0x20 /* target address */
55 #define LPC_REG_WDATA 0x24 /* write FIFO */
56 #define LPC_REG_RDATA 0x28 /* read FIFO */
58 /* The minimal nanosecond interval for each query on LPC cycle status */
59 #define LPC_NSEC_PERWAIT 100
62 * The maximum waiting time is about 128us. It is specific for stream I/O,
65 * The fastest IO cycle time is about 390ns, but the worst case will wait
66 * for extra 256 lpc clocks, so (256 + 13) * 30ns = 8 us. The maximum burst
67 * cycles is 16. So, the maximum waiting time is about 128us under worst
70 * Choose 1300 as the maximum.
72 #define LPC_MAX_WAITCNT 1300
74 /* About 10us. This is specific for single IO operations, such as inb */
75 #define LPC_PEROP_WAITCNT 100
77 static int wait_lpc_idle(unsigned char *mbase
, unsigned int waitcnt
)
82 status
= readl(mbase
+ LPC_REG_OP_STATUS
);
83 if (status
& LPC_REG_OP_STATUS_IDLE
)
84 return (status
& LPC_REG_OP_STATUS_FINISHED
) ? 0 : -EIO
;
85 ndelay(LPC_NSEC_PERWAIT
);
92 * hisi_lpc_target_in - trigger a series of LPC cycles for read operation
93 * @lpcdev: pointer to hisi lpc device
94 * @para: some parameters used to control the lpc I/O operations
95 * @addr: the lpc I/O target port address
96 * @buf: where the read back data is stored
97 * @opcnt: how many I/O operations required, i.e. data width
99 * Returns 0 on success, non-zero on fail.
101 static int hisi_lpc_target_in(struct hisi_lpc_dev
*lpcdev
,
102 struct lpc_cycle_para
*para
, unsigned long addr
,
103 unsigned char *buf
, unsigned long opcnt
)
105 unsigned int cmd_word
;
106 unsigned int waitcnt
;
110 if (!buf
|| !opcnt
|| !para
|| !para
->csize
|| !lpcdev
)
113 cmd_word
= 0; /* IO mode, Read */
114 waitcnt
= LPC_PEROP_WAITCNT
;
115 if (!(para
->opflags
& FG_INCRADDR_LPC
)) {
116 cmd_word
|= LPC_REG_CMD_SAMEADDR
;
117 waitcnt
= LPC_MAX_WAITCNT
;
120 /* whole operation must be atomic */
121 spin_lock_irqsave(&lpcdev
->cycle_lock
, flags
);
123 writel_relaxed(opcnt
, lpcdev
->membase
+ LPC_REG_OP_LEN
);
124 writel_relaxed(cmd_word
, lpcdev
->membase
+ LPC_REG_CMD
);
125 writel_relaxed(addr
, lpcdev
->membase
+ LPC_REG_ADDR
);
127 writel(LPC_REG_STARTUP_SIGNAL_START
,
128 lpcdev
->membase
+ LPC_REG_STARTUP_SIGNAL
);
130 /* whether the operation is finished */
131 ret
= wait_lpc_idle(lpcdev
->membase
, waitcnt
);
133 spin_unlock_irqrestore(&lpcdev
->cycle_lock
, flags
);
137 readsb(lpcdev
->membase
+ LPC_REG_RDATA
, buf
, opcnt
);
139 spin_unlock_irqrestore(&lpcdev
->cycle_lock
, flags
);
145 * hisi_lpc_target_out - trigger a series of LPC cycles for write operation
146 * @lpcdev: pointer to hisi lpc device
147 * @para: some parameters used to control the lpc I/O operations
148 * @addr: the lpc I/O target port address
149 * @buf: where the data to be written is stored
150 * @opcnt: how many I/O operations required, i.e. data width
152 * Returns 0 on success, non-zero on fail.
154 static int hisi_lpc_target_out(struct hisi_lpc_dev
*lpcdev
,
155 struct lpc_cycle_para
*para
, unsigned long addr
,
156 const unsigned char *buf
, unsigned long opcnt
)
158 unsigned int waitcnt
;
163 if (!buf
|| !opcnt
|| !para
|| !lpcdev
)
166 /* default is increasing address */
167 cmd_word
= LPC_REG_CMD_OP
; /* IO mode, write */
168 waitcnt
= LPC_PEROP_WAITCNT
;
169 if (!(para
->opflags
& FG_INCRADDR_LPC
)) {
170 cmd_word
|= LPC_REG_CMD_SAMEADDR
;
171 waitcnt
= LPC_MAX_WAITCNT
;
174 spin_lock_irqsave(&lpcdev
->cycle_lock
, flags
);
176 writel_relaxed(opcnt
, lpcdev
->membase
+ LPC_REG_OP_LEN
);
177 writel_relaxed(cmd_word
, lpcdev
->membase
+ LPC_REG_CMD
);
178 writel_relaxed(addr
, lpcdev
->membase
+ LPC_REG_ADDR
);
180 writesb(lpcdev
->membase
+ LPC_REG_WDATA
, buf
, opcnt
);
182 writel(LPC_REG_STARTUP_SIGNAL_START
,
183 lpcdev
->membase
+ LPC_REG_STARTUP_SIGNAL
);
185 /* whether the operation is finished */
186 ret
= wait_lpc_idle(lpcdev
->membase
, waitcnt
);
188 spin_unlock_irqrestore(&lpcdev
->cycle_lock
, flags
);
193 static unsigned long hisi_lpc_pio_to_addr(struct hisi_lpc_dev
*lpcdev
,
196 return pio
- lpcdev
->io_host
->io_start
+ lpcdev
->io_host
->hw_start
;
200 * hisi_lpc_comm_in - input the data in a single operation
201 * @hostdata: pointer to the device information relevant to LPC controller
202 * @pio: the target I/O port address
203 * @dwidth: the data length required to read from the target I/O port
205 * When success, data is returned. Otherwise, ~0 is returned.
207 static u32
hisi_lpc_comm_in(void *hostdata
, unsigned long pio
, size_t dwidth
)
209 struct hisi_lpc_dev
*lpcdev
= hostdata
;
210 struct lpc_cycle_para iopara
;
215 if (!lpcdev
|| !dwidth
|| dwidth
> LPC_MAX_DWIDTH
)
218 addr
= hisi_lpc_pio_to_addr(lpcdev
, pio
);
220 iopara
.opflags
= FG_INCRADDR_LPC
;
221 iopara
.csize
= dwidth
;
223 ret
= hisi_lpc_target_in(lpcdev
, &iopara
, addr
,
224 (unsigned char *)&rd_data
, dwidth
);
228 return le32_to_cpu(rd_data
);
232 * hisi_lpc_comm_out - output the data in a single operation
233 * @hostdata: pointer to the device information relevant to LPC controller
234 * @pio: the target I/O port address
235 * @val: a value to be output from caller, maximum is four bytes
236 * @dwidth: the data width required writing to the target I/O port
238 * This function corresponds to out(b,w,l) only.
240 static void hisi_lpc_comm_out(void *hostdata
, unsigned long pio
,
241 u32 val
, size_t dwidth
)
243 struct hisi_lpc_dev
*lpcdev
= hostdata
;
244 struct lpc_cycle_para iopara
;
245 const unsigned char *buf
;
248 if (!lpcdev
|| !dwidth
|| dwidth
> LPC_MAX_DWIDTH
)
251 val
= cpu_to_le32(val
);
253 buf
= (const unsigned char *)&val
;
254 addr
= hisi_lpc_pio_to_addr(lpcdev
, pio
);
256 iopara
.opflags
= FG_INCRADDR_LPC
;
257 iopara
.csize
= dwidth
;
259 hisi_lpc_target_out(lpcdev
, &iopara
, addr
, buf
, dwidth
);
263 * hisi_lpc_comm_ins - input the data in the buffer in multiple operations
264 * @hostdata: pointer to the device information relevant to LPC controller
265 * @pio: the target I/O port address
266 * @buffer: a buffer where read/input data bytes are stored
267 * @dwidth: the data width required writing to the target I/O port
268 * @count: how many data units whose length is dwidth will be read
270 * When success, the data read back is stored in buffer pointed by buffer.
271 * Returns 0 on success, -errno otherwise.
273 static u32
hisi_lpc_comm_ins(void *hostdata
, unsigned long pio
, void *buffer
,
274 size_t dwidth
, unsigned int count
)
276 struct hisi_lpc_dev
*lpcdev
= hostdata
;
277 unsigned char *buf
= buffer
;
278 struct lpc_cycle_para iopara
;
281 if (!lpcdev
|| !buf
|| !count
|| !dwidth
|| dwidth
> LPC_MAX_DWIDTH
)
286 iopara
.opflags
|= FG_INCRADDR_LPC
;
287 iopara
.csize
= dwidth
;
289 addr
= hisi_lpc_pio_to_addr(lpcdev
, pio
);
294 ret
= hisi_lpc_target_in(lpcdev
, &iopara
, addr
, buf
, dwidth
);
304 * hisi_lpc_comm_outs - output the data in the buffer in multiple operations
305 * @hostdata: pointer to the device information relevant to LPC controller
306 * @pio: the target I/O port address
307 * @buffer: a buffer where write/output data bytes are stored
308 * @dwidth: the data width required writing to the target I/O port
309 * @count: how many data units whose length is dwidth will be written
311 static void hisi_lpc_comm_outs(void *hostdata
, unsigned long pio
,
312 const void *buffer
, size_t dwidth
,
315 struct hisi_lpc_dev
*lpcdev
= hostdata
;
316 struct lpc_cycle_para iopara
;
317 const unsigned char *buf
= buffer
;
320 if (!lpcdev
|| !buf
|| !count
|| !dwidth
|| dwidth
> LPC_MAX_DWIDTH
)
325 iopara
.opflags
|= FG_INCRADDR_LPC
;
326 iopara
.csize
= dwidth
;
328 addr
= hisi_lpc_pio_to_addr(lpcdev
, pio
);
330 if (hisi_lpc_target_out(lpcdev
, &iopara
, addr
, buf
, dwidth
))
336 static const struct logic_pio_host_ops hisi_lpc_ops
= {
337 .in
= hisi_lpc_comm_in
,
338 .out
= hisi_lpc_comm_out
,
339 .ins
= hisi_lpc_comm_ins
,
340 .outs
= hisi_lpc_comm_outs
,
344 static int hisi_lpc_acpi_xlat_io_res(struct acpi_device
*adev
,
345 struct acpi_device
*host
,
346 struct resource
*res
)
348 unsigned long sys_port
;
349 resource_size_t len
= resource_size(res
);
351 sys_port
= logic_pio_trans_hwaddr(&host
->fwnode
, res
->start
, len
);
352 if (sys_port
== ~0UL)
355 res
->start
= sys_port
;
356 res
->end
= sys_port
+ len
;
362 * hisi_lpc_acpi_set_io_res - set the resources for a child
363 * @child: the device node to be updated the I/O resource
364 * @hostdev: the device node associated with host controller
365 * @res: double pointer to be set to the address of translated resources
366 * @num_res: pointer to variable to hold the number of translated resources
368 * Returns 0 when successful, and a negative value for failure.
370 * For a given host controller, each child device will have an associated
371 * host-relative address resource. This function will return the translated
372 * logical PIO addresses for each child devices resources.
374 static int hisi_lpc_acpi_set_io_res(struct device
*child
,
375 struct device
*hostdev
,
376 const struct resource
**res
, int *num_res
)
378 struct acpi_device
*adev
;
379 struct acpi_device
*host
;
380 struct resource_entry
*rentry
;
381 LIST_HEAD(resource_list
);
382 struct resource
*resources
;
386 if (!child
|| !hostdev
)
389 host
= to_acpi_device(hostdev
);
390 adev
= to_acpi_device(child
);
392 if (!adev
->status
.present
) {
393 dev_dbg(child
, "device is not present\n");
397 if (acpi_device_enumerated(adev
)) {
398 dev_dbg(child
, "has been enumerated\n");
403 * The following code segment to retrieve the resources is common to
404 * acpi_create_platform_device(), so consider a common helper function
407 count
= acpi_dev_get_resources(adev
, &resource_list
, NULL
, NULL
);
409 dev_dbg(child
, "failed to get resources\n");
410 return count
? count
: -EIO
;
413 resources
= devm_kcalloc(hostdev
, count
, sizeof(*resources
),
416 dev_warn(hostdev
, "could not allocate memory for %d resources\n",
418 acpi_dev_free_resource_list(&resource_list
);
422 list_for_each_entry(rentry
, &resource_list
, node
)
423 resources
[count
++] = *rentry
->res
;
425 acpi_dev_free_resource_list(&resource_list
);
427 /* translate the I/O resources */
428 for (i
= 0; i
< count
; i
++) {
431 if (!(resources
[i
].flags
& IORESOURCE_IO
))
433 ret
= hisi_lpc_acpi_xlat_io_res(adev
, host
, &resources
[i
]);
435 dev_err(child
, "translate IO range %pR failed (%d)\n",
446 static int hisi_lpc_acpi_remove_subdev(struct device
*dev
, void *unused
)
448 platform_device_unregister(to_platform_device(dev
));
452 struct hisi_lpc_acpi_cell
{
459 static void hisi_lpc_acpi_remove(struct device
*hostdev
)
461 struct acpi_device
*adev
= ACPI_COMPANION(hostdev
);
462 struct acpi_device
*child
;
464 device_for_each_child(hostdev
, NULL
, hisi_lpc_acpi_remove_subdev
);
466 list_for_each_entry(child
, &adev
->children
, node
)
467 acpi_device_clear_enumerated(child
);
471 * hisi_lpc_acpi_probe - probe children for ACPI FW
472 * @hostdev: LPC host device pointer
474 * Returns 0 when successful, and a negative value for failure.
476 * Create a platform device per child, fixing up the resources
477 * from bus addresses to Logical PIO addresses.
480 static int hisi_lpc_acpi_probe(struct device
*hostdev
)
482 struct acpi_device
*adev
= ACPI_COMPANION(hostdev
);
483 struct acpi_device
*child
;
486 /* Only consider the children of the host */
487 list_for_each_entry(child
, &adev
->children
, node
) {
488 const char *hid
= acpi_device_hid(child
);
489 const struct hisi_lpc_acpi_cell
*cell
;
490 struct platform_device
*pdev
;
491 const struct resource
*res
;
495 ret
= hisi_lpc_acpi_set_io_res(&child
->dev
, &adev
->dev
, &res
,
498 dev_warn(hostdev
, "set resource fail (%d)\n", ret
);
502 cell
= (struct hisi_lpc_acpi_cell
[]){
506 .name
= "hisi-lpc-ipmi",
508 /* 8250-compatible uart */
511 .name
= "serial8250",
512 .pdata
= (struct plat_serial8250_port
[]) {
514 .iobase
= res
->start
,
517 .flags
= UPF_BOOT_AUTOCONF
,
522 sizeof(struct plat_serial8250_port
),
527 for (; cell
&& cell
->name
; cell
++) {
528 if (!strcmp(cell
->hid
, hid
)) {
536 "could not find cell for child device (%s)\n",
542 pdev
= platform_device_alloc(cell
->name
, PLATFORM_DEVID_AUTO
);
548 pdev
->dev
.parent
= hostdev
;
549 ACPI_COMPANION_SET(&pdev
->dev
, child
);
551 ret
= platform_device_add_resources(pdev
, res
, num_res
);
555 ret
= platform_device_add_data(pdev
, cell
->pdata
,
560 ret
= platform_device_add(pdev
);
564 acpi_device_set_enumerated(child
);
570 hisi_lpc_acpi_remove(hostdev
);
574 static const struct acpi_device_id hisi_lpc_acpi_match
[] = {
579 static int hisi_lpc_acpi_probe(struct device
*dev
)
584 static void hisi_lpc_acpi_remove(struct device
*hostdev
)
587 #endif // CONFIG_ACPI
590 * hisi_lpc_probe - the probe callback function for hisi lpc host,
591 * will finish all the initialization.
592 * @pdev: the platform device corresponding to hisi lpc host
594 * Returns 0 on success, non-zero on fail.
596 static int hisi_lpc_probe(struct platform_device
*pdev
)
598 struct device
*dev
= &pdev
->dev
;
599 struct acpi_device
*acpi_device
= ACPI_COMPANION(dev
);
600 struct logic_pio_hwaddr
*range
;
601 struct hisi_lpc_dev
*lpcdev
;
602 resource_size_t io_end
;
603 struct resource
*res
;
606 lpcdev
= devm_kzalloc(dev
, sizeof(*lpcdev
), GFP_KERNEL
);
610 spin_lock_init(&lpcdev
->cycle_lock
);
612 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
613 lpcdev
->membase
= devm_ioremap_resource(dev
, res
);
614 if (IS_ERR(lpcdev
->membase
))
615 return PTR_ERR(lpcdev
->membase
);
617 range
= devm_kzalloc(dev
, sizeof(*range
), GFP_KERNEL
);
621 range
->fwnode
= dev
->fwnode
;
622 range
->flags
= LOGIC_PIO_INDIRECT
;
623 range
->size
= PIO_INDIRECT_SIZE
;
624 range
->hostdata
= lpcdev
;
625 range
->ops
= &hisi_lpc_ops
;
626 lpcdev
->io_host
= range
;
628 ret
= logic_pio_register_range(range
);
630 dev_err(dev
, "register IO range failed (%d)!\n", ret
);
634 /* register the LPC host PIO resources */
636 ret
= hisi_lpc_acpi_probe(dev
);
638 ret
= of_platform_populate(dev
->of_node
, NULL
, NULL
, dev
);
640 logic_pio_unregister_range(range
);
644 dev_set_drvdata(dev
, lpcdev
);
646 io_end
= lpcdev
->io_host
->io_start
+ lpcdev
->io_host
->size
;
647 dev_info(dev
, "registered range [%pa - %pa]\n",
648 &lpcdev
->io_host
->io_start
, &io_end
);
653 static int hisi_lpc_remove(struct platform_device
*pdev
)
655 struct device
*dev
= &pdev
->dev
;
656 struct acpi_device
*acpi_device
= ACPI_COMPANION(dev
);
657 struct hisi_lpc_dev
*lpcdev
= dev_get_drvdata(dev
);
658 struct logic_pio_hwaddr
*range
= lpcdev
->io_host
;
661 hisi_lpc_acpi_remove(dev
);
663 of_platform_depopulate(dev
);
665 logic_pio_unregister_range(range
);
670 static const struct of_device_id hisi_lpc_of_match
[] = {
671 { .compatible
= "hisilicon,hip06-lpc", },
672 { .compatible
= "hisilicon,hip07-lpc", },
676 static struct platform_driver hisi_lpc_driver
= {
679 .of_match_table
= hisi_lpc_of_match
,
680 .acpi_match_table
= ACPI_PTR(hisi_lpc_acpi_match
),
682 .probe
= hisi_lpc_probe
,
683 .remove
= hisi_lpc_remove
,
685 builtin_platform_driver(hisi_lpc_driver
);