/*
 * Driver for Synopsys DesignWare MAC
 *
 * Copyright (c) 2021 BayLibre SAS
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * STM32H7X specific glue.
 */


#define LOG_MODULE_NAME dwmac_plat
#define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

/* be compatible with the HAL-based driver here */
#define DT_DRV_COMPAT st_stm32_ethernet

#include <sys/types.h>
#include <zephyr/kernel.h>
#include <zephyr/net/ethernet.h>
#include <ethernet/eth.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
#include <zephyr/drivers/pinctrl.h>

#include "eth_dwmac_priv.h"

PINCTRL_DT_INST_DEFINE(0);
static const struct pinctrl_dev_config *eth0_pcfg =
	PINCTRL_DT_INST_DEV_CONFIG_GET(0);

static const struct stm32_pclken pclken = {
	.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, stmmaceth, bus),
	.enr = DT_INST_CLOCKS_CELL_BY_NAME(0, stmmaceth, bits),
};
static const struct stm32_pclken pclken_tx = {
	.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk_tx, bus),
	.enr = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk_tx, bits),
};
static const struct stm32_pclken pclken_rx = {
	.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk_rx, bus),
	.enr = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk_rx, bits),
};

int dwmac_bus_init(struct dwmac_priv *p)
{
	uint32_t reg_addr, reg_val;
	int ret;

	p->clock = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);

	if (!device_is_ready(p->clock)) {
		LOG_ERR("clock control device not ready");
		return -ENODEV;
	}

	ret  = clock_control_on(p->clock, (clock_control_subsys_t *)&pclken);
	ret |= clock_control_on(p->clock, (clock_control_subsys_t *)&pclken_tx);
	ret |= clock_control_on(p->clock, (clock_control_subsys_t *)&pclken_rx);
	if (ret) {
		LOG_ERR("Failed to enable ethernet clock");
		return -EIO;
	}

	ret = pinctrl_apply_state(eth0_pcfg, PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		LOG_ERR("Could not configure ethernet pins");
		return ret;
	}

	/* set SYSCFGEN in RCC_APB4ENR */
	reg_addr = DT_REG_ADDR(DT_INST(0, st_stm32h7_rcc)) + 0xf4;
	reg_val = sys_read32(reg_addr);
	sys_write32(reg_val | BIT(1), reg_addr);

	/* set RMII mode in SYSCFG_PMCR */
	reg_addr = 0x58000404;  /* no DT node? */
	reg_val = sys_read32(reg_addr);
	sys_write32(reg_val | 0x03800000, reg_addr);

	p->base_addr = DT_INST_REG_ADDR(0);
	return 0;
}

#if defined(CONFIG_NOCACHE_MEMORY)
#define __desc_mem __nocache __aligned(4)
#else
#error "missing memory attribute for descriptors"
#endif

/* Descriptor rings in uncached memory */
static struct dwmac_dma_desc dwmac_tx_descs[NB_TX_DESCS] __desc_mem;
static struct dwmac_dma_desc dwmac_rx_descs[NB_RX_DESCS] __desc_mem;

void dwmac_platform_init(struct dwmac_priv *p)
{
	p->tx_descs = dwmac_tx_descs;
	p->rx_descs = dwmac_rx_descs;

	/* basic configuration for this platform */
	REG_WRITE(MAC_CONF,
		  MAC_CONF_PS |
		  MAC_CONF_FES |
		  MAC_CONF_DM);
	REG_WRITE(DMA_SYSBUS_MODE,
		  DMA_SYSBUS_MODE_AAL |
		  DMA_SYSBUS_MODE_FB);

	/* set up IRQs (still masked for now) */
	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), dwmac_isr,
		    DEVICE_DT_INST_GET(0), 0);
	irq_enable(DT_INST_IRQN(0));

	/* create MAC address */
	gen_random_mac(p->mac_addr, 0x00, 0x80, 0xE1);
}

/* Our private device instance */
static struct dwmac_priv dwmac_instance;

ETH_NET_DEVICE_DT_INST_DEFINE(0,
			      dwmac_probe,
			      NULL,
			      &dwmac_instance,
			      NULL,
			      CONFIG_ETH_INIT_PRIORITY,
			      &dwmac_api,
			      NET_ETH_MTU);
