/*
 * Copyright (c) 2022 Henrik Brix Andersen <henrik@brixandersen.dk>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT kvaser_pcican

#include "can_sja1000.h"

#include <zephyr/drivers/can.h>
#include <zephyr/drivers/pcie/pcie.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>

LOG_MODULE_REGISTER(can_kvaser_pci, CONFIG_CAN_LOG_LEVEL);

/* AMCC S5920 I/O BAR registers */
#define S5920_INTCSR_REG       0x38
#define S5920_INTCSR_ADDINT_EN BIT(13)
#define S5920_PTCR_REG	       0x60

/* Xilinx I/O BAR registers */
#define XLNX_VERINT_REG		0x07
#define XLNX_VERINT_VERSION_POS 4U

struct can_kvaser_pci_config {
	void (*irq_config_func)(const struct device *dev);
	struct pcie_dev *pcie;
};

struct can_kvaser_pci_data {
	io_port_t sja1000_base;
};

static uint8_t can_kvaser_pci_read_reg(const struct device *dev, uint8_t reg)
{
	struct can_sja1000_data *sja1000_data = dev->data;
	struct can_kvaser_pci_data *kvaser_data = sja1000_data->custom;
	io_port_t addr = kvaser_data->sja1000_base + reg;

	return sys_in8(addr);
}

static void can_kvaser_pci_write_reg(const struct device *dev, uint8_t reg, uint8_t val)
{
	struct can_sja1000_data *sja1000_data = dev->data;
	struct can_kvaser_pci_data *kvaser_data = sja1000_data->custom;
	io_port_t addr = kvaser_data->sja1000_base + reg;

	sys_out8(val, addr);
}

static int can_kvaser_pci_get_core_clock(const struct device *dev, uint32_t *rate)
{
	ARG_UNUSED(dev);

	/* The internal clock operates at half of the oscillator frequency */
	*rate = MHZ(16) / 2;

	return 0;
}

static int can_kvaser_pci_init(const struct device *dev)
{
	const struct can_sja1000_config *sja1000_config = dev->config;
	const struct can_kvaser_pci_config *kvaser_config = sja1000_config->custom;
	struct can_sja1000_data *sja1000_data = dev->data;
	struct can_kvaser_pci_data *kvaser_data = sja1000_data->custom;
	struct pcie_bar iobar;
	static io_port_t amcc_base;
	static io_port_t xlnx_base;
	uint32_t intcsr;
	int err;

	if (kvaser_config->pcie->bdf == PCIE_BDF_NONE) {
		LOG_ERR("failed to find PCIe device");
		return -ENODEV;
	}

	pcie_set_cmd(kvaser_config->pcie->bdf, PCIE_CONF_CMDSTAT_IO, true);

	/* AMCC S5920 registers */
	if (!pcie_probe_iobar(kvaser_config->pcie->bdf, 0, &iobar)) {
		LOG_ERR("failed to probe AMCC S5920 I/O BAR");
		return -ENODEV;
	}

	amcc_base = iobar.phys_addr;

	/* SJA1000 registers */
	if (!pcie_probe_iobar(kvaser_config->pcie->bdf, 1, &iobar)) {
		LOG_ERR("failed to probe SJA1000 I/O BAR");
		return -ENODEV;
	}

	kvaser_data->sja1000_base = iobar.phys_addr;

	/* Xilinx registers */
	if (!pcie_probe_iobar(kvaser_config->pcie->bdf, 2, &iobar)) {
		LOG_ERR("failed to probe Xilinx I/O BAR");
		return -ENODEV;
	}

	xlnx_base = iobar.phys_addr;
	LOG_DBG("Xilinx version: %d",
		sys_in8(xlnx_base + XLNX_VERINT_REG) >> XLNX_VERINT_VERSION_POS);

	/*
	 * Initialization sequence as per Kvaser PCIcan Hardware Reference Manual (UG 98048
	 * v3.0.0).
	 */

	/* AMCC S5920 PCI Pass-Thru Configuration Register (PTCR) */
	sys_out32(0x80808080UL, amcc_base + S5920_PTCR_REG);

	/* AMCC S5920 PCI Interrupt Control/Status Register (INTCSR) */
	intcsr = sys_in32(amcc_base + S5920_INTCSR_REG);
	intcsr |= S5920_INTCSR_ADDINT_EN;
	sys_out32(intcsr, amcc_base + S5920_INTCSR_REG);

	err = can_sja1000_init(dev);
	if (err != 0) {
		LOG_ERR("failed to initialize controller (err %d)", err);
		return err;
	}

	kvaser_config->irq_config_func(dev);

	return 0;
}

const struct can_driver_api can_kvaser_pci_driver_api = {
	.get_capabilities = can_sja1000_get_capabilities,
	.start = can_sja1000_start,
	.stop = can_sja1000_stop,
	.set_mode = can_sja1000_set_mode,
	.set_timing = can_sja1000_set_timing,
	.send = can_sja1000_send,
	.add_rx_filter = can_sja1000_add_rx_filter,
	.remove_rx_filter = can_sja1000_remove_rx_filter,
	.get_state = can_sja1000_get_state,
	.set_state_change_callback = can_sja1000_set_state_change_callback,
	.get_core_clock = can_kvaser_pci_get_core_clock,
	.get_max_filters = can_sja1000_get_max_filters,
	.get_max_bitrate = can_sja1000_get_max_bitrate,
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
	.recover = can_sja1000_recover,
#endif /* !CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
	.timing_min = CAN_SJA1000_TIMING_MIN_INITIALIZER,
	.timing_max = CAN_SJA1000_TIMING_MAX_INITIALIZER,
};

#define CAN_KVASER_PCI_OCR                                                                         \
	(CAN_SJA1000_OCR_OCMODE_NORMAL | CAN_SJA1000_OCR_OCTN0 | CAN_SJA1000_OCR_OCTP0 |           \
	 CAN_SJA1000_OCR_OCTN1 | CAN_SJA1000_OCR_OCTP1)

#define CAN_KVASER_PCI_CDR (CAN_SJA1000_CDR_CD_DIV2 | CAN_SJA1000_CDR_CLOCK_OFF)

#define CAN_KVASER_PCI_INIT(inst)                                                                  \
	static void can_kvaser_pci_config_func_##inst(const struct device *dev);                   \
	DEVICE_PCIE_INST_DECLARE(inst);                                                            \
                                                                                                   \
	static const struct can_kvaser_pci_config can_kvaser_pci_config_##inst = {                 \
		DEVICE_PCIE_INST_INIT(inst, pcie),                                                 \
		.irq_config_func = can_kvaser_pci_config_func_##inst                               \
	};                                                                                         \
                                                                                                   \
	static const struct can_sja1000_config can_sja1000_config_##inst =                         \
		CAN_SJA1000_DT_CONFIG_INST_GET(inst, &can_kvaser_pci_config_##inst,                \
					       can_kvaser_pci_read_reg, can_kvaser_pci_write_reg,  \
					       CAN_KVASER_PCI_OCR, CAN_KVASER_PCI_CDR);            \
                                                                                                   \
	static struct can_kvaser_pci_data can_kvaser_pci_data_##inst;                              \
                                                                                                   \
	static struct can_sja1000_data can_sja1000_data_##inst =                                   \
		CAN_SJA1000_DATA_INITIALIZER(&can_kvaser_pci_data_##inst);                         \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(inst, can_kvaser_pci_init, NULL, &can_sja1000_data_##inst,           \
			      &can_sja1000_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY,   \
			      &can_kvaser_pci_driver_api);                                         \
                                                                                                   \
	static void can_kvaser_pci_config_func_##inst(const struct device *dev)                    \
	{                                                                                          \
		IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), can_sja1000_isr,      \
			    DEVICE_DT_INST_GET(inst), DT_INST_IRQ(inst, sense));                   \
		irq_enable(DT_INST_IRQN(inst));                                                    \
	}

DT_INST_FOREACH_STATUS_OKAY(CAN_KVASER_PCI_INIT)
