// SPDX-License-Identifier: BSD-3-Clause
/*
 * Copyright (c) 2020, MIPI Alliance, Inc.
 *
 * Author: Nicolas Pitre <npitre@baylibre.com>
 */

#include <linux/bitfield.h>
#include <linux/bitmap.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/i3c/master.h>
#include <linux/io.h>

#include "hci.h"
#include "dat.h"


/*
 * Device Address Table Structure
 */

#define DAT_1_AUTOCMD_HDR_CODE		W1_MASK(58, 51)
#define DAT_1_AUTOCMD_MODE		W1_MASK(50, 48)
#define DAT_1_AUTOCMD_VALUE		W1_MASK(47, 40)
#define DAT_1_AUTOCMD_MASK		W1_MASK(39, 32)
/*	DAT_0_I2C_DEVICE		W0_BIT_(31) */
#define DAT_0_DEV_NACK_RETRY_CNT	W0_MASK(30, 29)
#define DAT_0_RING_ID			W0_MASK(28, 26)
#define DAT_0_DYNADDR_PARITY		W0_BIT_(23)
#define DAT_0_DYNAMIC_ADDRESS		W0_MASK(22, 16)
#define DAT_0_TS			W0_BIT_(15)
#define DAT_0_MR_REJECT			W0_BIT_(14)
/*	DAT_0_SIR_REJECT		W0_BIT_(13) */
/*	DAT_0_IBI_PAYLOAD		W0_BIT_(12) */
#define DAT_0_STATIC_ADDRESS		W0_MASK(6, 0)

#define dat_w0_read(i)		readl(hci->DAT_regs + (i) * 8)
#define dat_w1_read(i)		readl(hci->DAT_regs + (i) * 8 + 4)
#define dat_w0_write(i, v)	writel(v, hci->DAT_regs + (i) * 8)
#define dat_w1_write(i, v)	writel(v, hci->DAT_regs + (i) * 8 + 4)

static inline bool dynaddr_parity(unsigned int addr)
{
	addr |= 1 << 7;
	addr += addr >> 4;
	addr += addr >> 2;
	addr += addr >> 1;
	return (addr & 1);
}

static int hci_dat_v1_init(struct i3c_hci *hci)
{
	unsigned int dat_idx;

	if (!hci->DAT_regs) {
		dev_err(&hci->master.dev,
			"only DAT in register space is supported at the moment\n");
		return -EOPNOTSUPP;
	}
	if (hci->DAT_entry_size != 8) {
		dev_err(&hci->master.dev,
			"only 8-bytes DAT entries are supported at the moment\n");
		return -EOPNOTSUPP;
	}

	/* use a bitmap for faster free slot search */
	hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL);
	if (!hci->DAT_data)
		return -ENOMEM;

	/* clear them */
	for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) {
		dat_w0_write(dat_idx, 0);
		dat_w1_write(dat_idx, 0);
	}

	return 0;
}

static void hci_dat_v1_cleanup(struct i3c_hci *hci)
{
	bitmap_free(hci->DAT_data);
	hci->DAT_data = NULL;
}

static int hci_dat_v1_alloc_entry(struct i3c_hci *hci)
{
	unsigned int dat_idx;

	dat_idx = find_first_zero_bit(hci->DAT_data, hci->DAT_entries);
	if (dat_idx >= hci->DAT_entries)
		return -ENOENT;
	__set_bit(dat_idx, hci->DAT_data);

	/* default flags */
	dat_w0_write(dat_idx, DAT_0_SIR_REJECT | DAT_0_MR_REJECT);

	return dat_idx;
}

static void hci_dat_v1_free_entry(struct i3c_hci *hci, unsigned int dat_idx)
{
	dat_w0_write(dat_idx, 0);
	dat_w1_write(dat_idx, 0);
	__clear_bit(dat_idx, hci->DAT_data);
}

static void hci_dat_v1_set_dynamic_addr(struct i3c_hci *hci,
					unsigned int dat_idx, u8 address)
{
	u32 dat_w0;

	dat_w0 = dat_w0_read(dat_idx);
	dat_w0 &= ~(DAT_0_DYNAMIC_ADDRESS | DAT_0_DYNADDR_PARITY);
	dat_w0 |= FIELD_PREP(DAT_0_DYNAMIC_ADDRESS, address) |
		  (dynaddr_parity(address) ? DAT_0_DYNADDR_PARITY : 0);
	dat_w0_write(dat_idx, dat_w0);
}

static void hci_dat_v1_set_static_addr(struct i3c_hci *hci,
				       unsigned int dat_idx, u8 address)
{
	u32 dat_w0;

	dat_w0 = dat_w0_read(dat_idx);
	dat_w0 &= ~DAT_0_STATIC_ADDRESS;
	dat_w0 |= FIELD_PREP(DAT_0_STATIC_ADDRESS, address);
	dat_w0_write(dat_idx, dat_w0);
}

static void hci_dat_v1_set_flags(struct i3c_hci *hci, unsigned int dat_idx,
				 u32 w0_flags, u32 w1_flags)
{
	u32 dat_w0, dat_w1;

	dat_w0 = dat_w0_read(dat_idx);
	dat_w1 = dat_w1_read(dat_idx);
	dat_w0 |= w0_flags;
	dat_w1 |= w1_flags;
	dat_w0_write(dat_idx, dat_w0);
	dat_w1_write(dat_idx, dat_w1);
}

static void hci_dat_v1_clear_flags(struct i3c_hci *hci, unsigned int dat_idx,
				   u32 w0_flags, u32 w1_flags)
{
	u32 dat_w0, dat_w1;

	dat_w0 = dat_w0_read(dat_idx);
	dat_w1 = dat_w1_read(dat_idx);
	dat_w0 &= ~w0_flags;
	dat_w1 &= ~w1_flags;
	dat_w0_write(dat_idx, dat_w0);
	dat_w1_write(dat_idx, dat_w1);
}

static int hci_dat_v1_get_index(struct i3c_hci *hci, u8 dev_addr)
{
	unsigned int dat_idx;
	u32 dat_w0;

	for (dat_idx = find_first_bit(hci->DAT_data, hci->DAT_entries);
	     dat_idx < hci->DAT_entries;
	     dat_idx = find_next_bit(hci->DAT_data, hci->DAT_entries, dat_idx)) {
		dat_w0 = dat_w0_read(dat_idx);
		if (FIELD_GET(DAT_0_DYNAMIC_ADDRESS, dat_w0) == dev_addr)
			return dat_idx;
	}

	return -ENODEV;
}

const struct hci_dat_ops mipi_i3c_hci_dat_v1 = {
	.init			= hci_dat_v1_init,
	.cleanup		= hci_dat_v1_cleanup,
	.alloc_entry		= hci_dat_v1_alloc_entry,
	.free_entry		= hci_dat_v1_free_entry,
	.set_dynamic_addr	= hci_dat_v1_set_dynamic_addr,
	.set_static_addr	= hci_dat_v1_set_static_addr,
	.set_flags		= hci_dat_v1_set_flags,
	.clear_flags		= hci_dat_v1_clear_flags,
	.get_index		= hci_dat_v1_get_index,
};
