/*
 * Copyright (c) 2020 Teslabs Engineering S.L.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/device.h>
#include <soc.h>

#include <zephyr/drivers/clock_control/stm32_clock_control.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/memc/memc_stm32.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(memc_stm32, CONFIG_MEMC_LOG_LEVEL);

#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_fmc)
#define DT_DRV_COMPAT st_stm32_fmc
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_fmc)
#define DT_DRV_COMPAT st_stm32h7_fmc
#else
#error "No compatible FMC devicetree node found"
#endif

/* This symbol takes the value 1 if one of the device instances */
/* is configured in dts with a domain clock */
#if STM32_DT_INST_DEV_DOMAIN_CLOCK_SUPPORT
#define STM32_FMC_DOMAIN_CLOCK_SUPPORT 1
#else
#define STM32_FMC_DOMAIN_CLOCK_SUPPORT 0
#endif

struct memc_stm32_config {
	uint32_t fmc;
	const struct stm32_pclken *pclken;
	size_t pclk_len;
	const struct pinctrl_dev_config *pcfg;
};

static int memc_stm32_init(const struct device *dev)
{
	const struct memc_stm32_config *config = dev->config;

	int r;
	const struct device *clk;

	/* configure pinmux */
	r = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
	if (r < 0) {
		LOG_ERR("FMC pinctrl setup failed (%d)", r);
		return r;
	}

	/* enable FMC peripheral clock */
	clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);

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

	r = clock_control_on(clk, (clock_control_subsys_t)&config->pclken[0]);
	if (r < 0) {
		LOG_ERR("Could not initialize FMC clock (%d)", r);
		return r;
	}

	if (IS_ENABLED(STM32_FMC_DOMAIN_CLOCK_SUPPORT) && (config->pclk_len > 1)) {
		/* Enable FMC clock source */
		r = clock_control_configure(clk, (clock_control_subsys_t)&config->pclken[1], NULL);
		if (r < 0) {
			LOG_ERR("Could not select FMC clock (%d)", r);
			return r;
		}
	}

#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_fmc)
#if (DT_ENUM_IDX(DT_DRV_INST(0), st_mem_swap) == 1)
	/* sdram-sram */
	MODIFY_REG(FMC_Bank1_R->BTCR[0], FMC_BCR1_BMAP, FMC_BCR1_BMAP_0);
#elif (DT_ENUM_IDX(DT_DRV_INST(0), st_mem_swap) == 2)
	/* sdramb2 */
	MODIFY_REG(FMC_Bank1_R->BTCR[0], FMC_BCR1_BMAP, FMC_BCR1_BMAP_1);
#endif
#endif

	return 0;
}

int memc_stm32_fmc_clock_rate(uint32_t *freq)
{
	const struct device *dev = DEVICE_DT_GET_ONE(DT_DRV_COMPAT);
	const struct memc_stm32_config *config = dev->config;

	if (IS_ENABLED(STM32_FMC_DOMAIN_CLOCK_SUPPORT) && (config->pclk_len > 1)) {
		if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
					   (clock_control_subsys_t)&config->pclken[1],
					   freq) < 0) {
			return -EIO;
		}
	} else {
		if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
					   (clock_control_subsys_t)&config->pclken[0],
					   freq) < 0) {
			return -EIO;
		}
	}

	return 0;
}

PINCTRL_DT_INST_DEFINE(0);

static const struct stm32_pclken pclken[] = STM32_DT_INST_CLOCKS(0);

static const struct memc_stm32_config config = {
	.fmc = DT_INST_REG_ADDR(0),
	.pclken = pclken,
	.pclk_len = DT_INST_NUM_CLOCKS(0),
	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
};

DEVICE_DT_INST_DEFINE(0, memc_stm32_init, NULL, NULL,
	      &config, POST_KERNEL, CONFIG_MEMC_INIT_PRIORITY, NULL);
