brintos

brintos / linux-shallow public Read only

0
0
Text · 2.4 KiB · 1131ebe Raw
106 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2017 Broadcom4 */5 6/*7 * This driver provides reset support for Broadcom FlexRM ring manager8 * to VFIO platform.9 */10 11#include <linux/delay.h>12#include <linux/device.h>13#include <linux/init.h>14#include <linux/io.h>15#include <linux/kernel.h>16#include <linux/module.h>17 18#include "../vfio_platform_private.h"19 20/* FlexRM configuration */21#define RING_REGS_SIZE					0x1000022#define RING_VER_MAGIC					0x7630303123 24/* Per-Ring register offsets */25#define RING_VER					0x00026#define RING_CONTROL					0x03427#define RING_FLUSH_DONE					0x03828 29/* Register RING_CONTROL fields */30#define CONTROL_FLUSH_SHIFT				531 32/* Register RING_FLUSH_DONE fields */33#define FLUSH_DONE_MASK					0x134 35static int vfio_platform_bcmflexrm_shutdown(void __iomem *ring)36{37	unsigned int timeout;38 39	/* Disable/inactivate ring */40	writel_relaxed(0x0, ring + RING_CONTROL);41 42	/* Set ring flush state */43	timeout = 1000; /* timeout of 1s */44	writel_relaxed(BIT(CONTROL_FLUSH_SHIFT), ring + RING_CONTROL);45	do {46		if (readl_relaxed(ring + RING_FLUSH_DONE) &47		    FLUSH_DONE_MASK)48			break;49		mdelay(1);50	} while (--timeout);51	if (!timeout)52		return -ETIMEDOUT;53 54	/* Clear ring flush state */55	timeout = 1000; /* timeout of 1s */56	writel_relaxed(0x0, ring + RING_CONTROL);57	do {58		if (!(readl_relaxed(ring + RING_FLUSH_DONE) &59		      FLUSH_DONE_MASK))60			break;61		mdelay(1);62	} while (--timeout);63	if (!timeout)64		return -ETIMEDOUT;65 66	return 0;67}68 69static int vfio_platform_bcmflexrm_reset(struct vfio_platform_device *vdev)70{71	void __iomem *ring;72	int rc = 0, ret = 0, ring_num = 0;73	struct vfio_platform_region *reg = &vdev->regions[0];74 75	/* Map FlexRM ring registers if not mapped */76	if (!reg->ioaddr) {77		reg->ioaddr = ioremap(reg->addr, reg->size);78		if (!reg->ioaddr)79			return -ENOMEM;80	}81 82	/* Discover and shutdown each FlexRM ring */83	for (ring = reg->ioaddr;84	     ring < (reg->ioaddr + reg->size); ring += RING_REGS_SIZE) {85		if (readl_relaxed(ring + RING_VER) == RING_VER_MAGIC) {86			rc = vfio_platform_bcmflexrm_shutdown(ring);87			if (rc) {88				dev_warn(vdev->device,89					 "FlexRM ring%d shutdown error %d\n",90					 ring_num, rc);91				ret |= rc;92			}93			ring_num++;94		}95	}96 97	return ret;98}99 100module_vfio_reset_handler("brcm,iproc-flexrm-mbox",101			  vfio_platform_bcmflexrm_reset);102 103MODULE_LICENSE("GPL v2");104MODULE_AUTHOR("Anup Patel <anup.patel@broadcom.com>");105MODULE_DESCRIPTION("Reset support for Broadcom FlexRM VFIO platform device");106