162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Cortina Systems Gemini SATA bridge add-on to Faraday FTIDE010
462306a36Sopenharmony_ci * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/init.h>
862306a36Sopenharmony_ci#include <linux/module.h>
962306a36Sopenharmony_ci#include <linux/platform_device.h>
1062306a36Sopenharmony_ci#include <linux/bitops.h>
1162306a36Sopenharmony_ci#include <linux/mfd/syscon.h>
1262306a36Sopenharmony_ci#include <linux/regmap.h>
1362306a36Sopenharmony_ci#include <linux/delay.h>
1462306a36Sopenharmony_ci#include <linux/reset.h>
1562306a36Sopenharmony_ci#include <linux/of.h>
1662306a36Sopenharmony_ci#include <linux/clk.h>
1762306a36Sopenharmony_ci#include <linux/io.h>
1862306a36Sopenharmony_ci#include <linux/pinctrl/consumer.h>
1962306a36Sopenharmony_ci#include "sata_gemini.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define DRV_NAME "gemini_sata_bridge"
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/**
2462306a36Sopenharmony_ci * struct sata_gemini - a state container for a Gemini SATA bridge
2562306a36Sopenharmony_ci * @dev: the containing device
2662306a36Sopenharmony_ci * @base: remapped I/O memory base
2762306a36Sopenharmony_ci * @muxmode: the current muxing mode
2862306a36Sopenharmony_ci * @ide_pins: if the device is using the plain IDE interface pins
2962306a36Sopenharmony_ci * @sata_bridge: if the device enables the SATA bridge
3062306a36Sopenharmony_ci * @sata0_reset: SATA0 reset handler
3162306a36Sopenharmony_ci * @sata1_reset: SATA1 reset handler
3262306a36Sopenharmony_ci * @sata0_pclk: SATA0 PCLK handler
3362306a36Sopenharmony_ci * @sata1_pclk: SATA1 PCLK handler
3462306a36Sopenharmony_ci */
3562306a36Sopenharmony_cistruct sata_gemini {
3662306a36Sopenharmony_ci	struct device *dev;
3762306a36Sopenharmony_ci	void __iomem *base;
3862306a36Sopenharmony_ci	enum gemini_muxmode muxmode;
3962306a36Sopenharmony_ci	bool ide_pins;
4062306a36Sopenharmony_ci	bool sata_bridge;
4162306a36Sopenharmony_ci	struct reset_control *sata0_reset;
4262306a36Sopenharmony_ci	struct reset_control *sata1_reset;
4362306a36Sopenharmony_ci	struct clk *sata0_pclk;
4462306a36Sopenharmony_ci	struct clk *sata1_pclk;
4562306a36Sopenharmony_ci};
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/* Miscellaneous Control Register */
4862306a36Sopenharmony_ci#define GEMINI_GLOBAL_MISC_CTRL		0x30
4962306a36Sopenharmony_ci/*
5062306a36Sopenharmony_ci * Values of IDE IOMUX bits in the misc control register
5162306a36Sopenharmony_ci *
5262306a36Sopenharmony_ci * Bits 26:24 are "IDE IO Select", which decides what SATA
5362306a36Sopenharmony_ci * adapters are connected to which of the two IDE/ATA
5462306a36Sopenharmony_ci * controllers in the Gemini. We can connect the two IDE blocks
5562306a36Sopenharmony_ci * to one SATA adapter each, both acting as master, or one IDE
5662306a36Sopenharmony_ci * blocks to two SATA adapters so the IDE block can act in a
5762306a36Sopenharmony_ci * master/slave configuration.
5862306a36Sopenharmony_ci *
5962306a36Sopenharmony_ci * We also bring out different blocks on the actual IDE
6062306a36Sopenharmony_ci * pins (not SATA pins) if (and only if) these are muxed in.
6162306a36Sopenharmony_ci *
6262306a36Sopenharmony_ci * 111-100 - Reserved
6362306a36Sopenharmony_ci * Mode 0: 000 - ata0 master <-> sata0
6462306a36Sopenharmony_ci *               ata1 master <-> sata1
6562306a36Sopenharmony_ci *               ata0 slave interface brought out on IDE pads
6662306a36Sopenharmony_ci * Mode 1: 001 - ata0 master <-> sata0
6762306a36Sopenharmony_ci *               ata1 master <-> sata1
6862306a36Sopenharmony_ci *               ata1 slave interface brought out on IDE pads
6962306a36Sopenharmony_ci * Mode 2: 010 - ata1 master <-> sata1
7062306a36Sopenharmony_ci *               ata1 slave  <-> sata0
7162306a36Sopenharmony_ci *               ata0 master and slave interfaces brought out
7262306a36Sopenharmony_ci *                    on IDE pads
7362306a36Sopenharmony_ci * Mode 3: 011 - ata0 master <-> sata0
7462306a36Sopenharmony_ci *               ata1 slave  <-> sata1
7562306a36Sopenharmony_ci *               ata1 master and slave interfaces brought out
7662306a36Sopenharmony_ci *                    on IDE pads
7762306a36Sopenharmony_ci */
7862306a36Sopenharmony_ci#define GEMINI_IDE_IOMUX_MASK			(7 << 24)
7962306a36Sopenharmony_ci#define GEMINI_IDE_IOMUX_MODE0			(0 << 24)
8062306a36Sopenharmony_ci#define GEMINI_IDE_IOMUX_MODE1			(1 << 24)
8162306a36Sopenharmony_ci#define GEMINI_IDE_IOMUX_MODE2			(2 << 24)
8262306a36Sopenharmony_ci#define GEMINI_IDE_IOMUX_MODE3			(3 << 24)
8362306a36Sopenharmony_ci#define GEMINI_IDE_IOMUX_SHIFT			(24)
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/*
8662306a36Sopenharmony_ci * Registers directly controlling the PATA<->SATA adapters
8762306a36Sopenharmony_ci */
8862306a36Sopenharmony_ci#define GEMINI_SATA_ID				0x00
8962306a36Sopenharmony_ci#define GEMINI_SATA_PHY_ID			0x04
9062306a36Sopenharmony_ci#define GEMINI_SATA0_STATUS			0x08
9162306a36Sopenharmony_ci#define GEMINI_SATA1_STATUS			0x0c
9262306a36Sopenharmony_ci#define GEMINI_SATA0_CTRL			0x18
9362306a36Sopenharmony_ci#define GEMINI_SATA1_CTRL			0x1c
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#define GEMINI_SATA_STATUS_BIST_DONE		BIT(5)
9662306a36Sopenharmony_ci#define GEMINI_SATA_STATUS_BIST_OK		BIT(4)
9762306a36Sopenharmony_ci#define GEMINI_SATA_STATUS_PHY_READY		BIT(0)
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_PHY_BIST_EN		BIT(14)
10062306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_PHY_FORCE_IDLE		BIT(13)
10162306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_PHY_FORCE_READY	BIT(12)
10262306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_PHY_AFE_LOOP_EN	BIT(10)
10362306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_PHY_DIG_LOOP_EN	BIT(9)
10462306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_HOTPLUG_DETECT_EN	BIT(4)
10562306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_ATAPI_EN		BIT(3)
10662306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_BUS_WITH_20		BIT(2)
10762306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_SLAVE_EN		BIT(1)
10862306a36Sopenharmony_ci#define GEMINI_SATA_CTRL_EN			BIT(0)
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/*
11162306a36Sopenharmony_ci * There is only ever one instance of this bridge on a system,
11262306a36Sopenharmony_ci * so create a singleton so that the FTIDE010 instances can grab
11362306a36Sopenharmony_ci * a reference to it.
11462306a36Sopenharmony_ci */
11562306a36Sopenharmony_cistatic struct sata_gemini *sg_singleton;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistruct sata_gemini *gemini_sata_bridge_get(void)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	if (sg_singleton)
12062306a36Sopenharmony_ci		return sg_singleton;
12162306a36Sopenharmony_ci	return ERR_PTR(-EPROBE_DEFER);
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ciEXPORT_SYMBOL(gemini_sata_bridge_get);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_cibool gemini_sata_bridge_enabled(struct sata_gemini *sg, bool is_ata1)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	if (!sg->sata_bridge)
12862306a36Sopenharmony_ci		return false;
12962306a36Sopenharmony_ci	/*
13062306a36Sopenharmony_ci	 * In muxmode 2 and 3 one of the ATA controllers is
13162306a36Sopenharmony_ci	 * actually not connected to any SATA bridge.
13262306a36Sopenharmony_ci	 */
13362306a36Sopenharmony_ci	if ((sg->muxmode == GEMINI_MUXMODE_2) &&
13462306a36Sopenharmony_ci	    !is_ata1)
13562306a36Sopenharmony_ci		return false;
13662306a36Sopenharmony_ci	if ((sg->muxmode == GEMINI_MUXMODE_3) &&
13762306a36Sopenharmony_ci	    is_ata1)
13862306a36Sopenharmony_ci		return false;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	return true;
14162306a36Sopenharmony_ci}
14262306a36Sopenharmony_ciEXPORT_SYMBOL(gemini_sata_bridge_enabled);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cienum gemini_muxmode gemini_sata_get_muxmode(struct sata_gemini *sg)
14562306a36Sopenharmony_ci{
14662306a36Sopenharmony_ci	return sg->muxmode;
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ciEXPORT_SYMBOL(gemini_sata_get_muxmode);
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic int gemini_sata_setup_bridge(struct sata_gemini *sg,
15162306a36Sopenharmony_ci				    unsigned int bridge)
15262306a36Sopenharmony_ci{
15362306a36Sopenharmony_ci	unsigned long timeout = jiffies + (HZ * 1);
15462306a36Sopenharmony_ci	bool bridge_online;
15562306a36Sopenharmony_ci	u32 val;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	if (bridge == 0) {
15862306a36Sopenharmony_ci		val = GEMINI_SATA_CTRL_HOTPLUG_DETECT_EN | GEMINI_SATA_CTRL_EN;
15962306a36Sopenharmony_ci		/* SATA0 slave mode is only used in muxmode 2 */
16062306a36Sopenharmony_ci		if (sg->muxmode == GEMINI_MUXMODE_2)
16162306a36Sopenharmony_ci			val |= GEMINI_SATA_CTRL_SLAVE_EN;
16262306a36Sopenharmony_ci		writel(val, sg->base + GEMINI_SATA0_CTRL);
16362306a36Sopenharmony_ci	} else {
16462306a36Sopenharmony_ci		val = GEMINI_SATA_CTRL_HOTPLUG_DETECT_EN | GEMINI_SATA_CTRL_EN;
16562306a36Sopenharmony_ci		/* SATA1 slave mode is only used in muxmode 3 */
16662306a36Sopenharmony_ci		if (sg->muxmode == GEMINI_MUXMODE_3)
16762306a36Sopenharmony_ci			val |= GEMINI_SATA_CTRL_SLAVE_EN;
16862306a36Sopenharmony_ci		writel(val, sg->base + GEMINI_SATA1_CTRL);
16962306a36Sopenharmony_ci	}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	/* Vendor code waits 10 ms here */
17262306a36Sopenharmony_ci	msleep(10);
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	/* Wait for PHY to become ready */
17562306a36Sopenharmony_ci	do {
17662306a36Sopenharmony_ci		msleep(100);
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci		if (bridge == 0)
17962306a36Sopenharmony_ci			val = readl(sg->base + GEMINI_SATA0_STATUS);
18062306a36Sopenharmony_ci		else
18162306a36Sopenharmony_ci			val = readl(sg->base + GEMINI_SATA1_STATUS);
18262306a36Sopenharmony_ci		if (val & GEMINI_SATA_STATUS_PHY_READY)
18362306a36Sopenharmony_ci			break;
18462306a36Sopenharmony_ci	} while (time_before(jiffies, timeout));
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	bridge_online = !!(val & GEMINI_SATA_STATUS_PHY_READY);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	dev_info(sg->dev, "SATA%d PHY %s\n", bridge,
18962306a36Sopenharmony_ci		 bridge_online ? "ready" : "not ready");
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	return bridge_online ? 0: -ENODEV;
19262306a36Sopenharmony_ci}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciint gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge)
19562306a36Sopenharmony_ci{
19662306a36Sopenharmony_ci	struct clk *pclk;
19762306a36Sopenharmony_ci	int ret;
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	if (bridge == 0)
20062306a36Sopenharmony_ci		pclk = sg->sata0_pclk;
20162306a36Sopenharmony_ci	else
20262306a36Sopenharmony_ci		pclk = sg->sata1_pclk;
20362306a36Sopenharmony_ci	clk_enable(pclk);
20462306a36Sopenharmony_ci	msleep(10);
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	/* Do not keep clocking a bridge that is not online */
20762306a36Sopenharmony_ci	ret = gemini_sata_setup_bridge(sg, bridge);
20862306a36Sopenharmony_ci	if (ret)
20962306a36Sopenharmony_ci		clk_disable(pclk);
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	return ret;
21262306a36Sopenharmony_ci}
21362306a36Sopenharmony_ciEXPORT_SYMBOL(gemini_sata_start_bridge);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_civoid gemini_sata_stop_bridge(struct sata_gemini *sg, unsigned int bridge)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	if (bridge == 0)
21862306a36Sopenharmony_ci		clk_disable(sg->sata0_pclk);
21962306a36Sopenharmony_ci	else if (bridge == 1)
22062306a36Sopenharmony_ci		clk_disable(sg->sata1_pclk);
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ciEXPORT_SYMBOL(gemini_sata_stop_bridge);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ciint gemini_sata_reset_bridge(struct sata_gemini *sg,
22562306a36Sopenharmony_ci			     unsigned int bridge)
22662306a36Sopenharmony_ci{
22762306a36Sopenharmony_ci	if (bridge == 0)
22862306a36Sopenharmony_ci		reset_control_reset(sg->sata0_reset);
22962306a36Sopenharmony_ci	else
23062306a36Sopenharmony_ci		reset_control_reset(sg->sata1_reset);
23162306a36Sopenharmony_ci	msleep(10);
23262306a36Sopenharmony_ci	return gemini_sata_setup_bridge(sg, bridge);
23362306a36Sopenharmony_ci}
23462306a36Sopenharmony_ciEXPORT_SYMBOL(gemini_sata_reset_bridge);
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistatic int gemini_sata_bridge_init(struct sata_gemini *sg)
23762306a36Sopenharmony_ci{
23862306a36Sopenharmony_ci	struct device *dev = sg->dev;
23962306a36Sopenharmony_ci	u32 sata_id, sata_phy_id;
24062306a36Sopenharmony_ci	int ret;
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	sg->sata0_pclk = devm_clk_get(dev, "SATA0_PCLK");
24362306a36Sopenharmony_ci	if (IS_ERR(sg->sata0_pclk)) {
24462306a36Sopenharmony_ci		dev_err(dev, "no SATA0 PCLK");
24562306a36Sopenharmony_ci		return -ENODEV;
24662306a36Sopenharmony_ci	}
24762306a36Sopenharmony_ci	sg->sata1_pclk = devm_clk_get(dev, "SATA1_PCLK");
24862306a36Sopenharmony_ci	if (IS_ERR(sg->sata1_pclk)) {
24962306a36Sopenharmony_ci		dev_err(dev, "no SATA1 PCLK");
25062306a36Sopenharmony_ci		return -ENODEV;
25162306a36Sopenharmony_ci	}
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	ret = clk_prepare_enable(sg->sata0_pclk);
25462306a36Sopenharmony_ci	if (ret) {
25562306a36Sopenharmony_ci		dev_err(dev, "failed to enable SATA0 PCLK\n");
25662306a36Sopenharmony_ci		return ret;
25762306a36Sopenharmony_ci	}
25862306a36Sopenharmony_ci	ret = clk_prepare_enable(sg->sata1_pclk);
25962306a36Sopenharmony_ci	if (ret) {
26062306a36Sopenharmony_ci		dev_err(dev, "failed to enable SATA1 PCLK\n");
26162306a36Sopenharmony_ci		clk_disable_unprepare(sg->sata0_pclk);
26262306a36Sopenharmony_ci		return ret;
26362306a36Sopenharmony_ci	}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	sg->sata0_reset = devm_reset_control_get_exclusive(dev, "sata0");
26662306a36Sopenharmony_ci	if (IS_ERR(sg->sata0_reset)) {
26762306a36Sopenharmony_ci		dev_err(dev, "no SATA0 reset controller\n");
26862306a36Sopenharmony_ci		clk_disable_unprepare(sg->sata1_pclk);
26962306a36Sopenharmony_ci		clk_disable_unprepare(sg->sata0_pclk);
27062306a36Sopenharmony_ci		return PTR_ERR(sg->sata0_reset);
27162306a36Sopenharmony_ci	}
27262306a36Sopenharmony_ci	sg->sata1_reset = devm_reset_control_get_exclusive(dev, "sata1");
27362306a36Sopenharmony_ci	if (IS_ERR(sg->sata1_reset)) {
27462306a36Sopenharmony_ci		dev_err(dev, "no SATA1 reset controller\n");
27562306a36Sopenharmony_ci		clk_disable_unprepare(sg->sata1_pclk);
27662306a36Sopenharmony_ci		clk_disable_unprepare(sg->sata0_pclk);
27762306a36Sopenharmony_ci		return PTR_ERR(sg->sata1_reset);
27862306a36Sopenharmony_ci	}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	sata_id = readl(sg->base + GEMINI_SATA_ID);
28162306a36Sopenharmony_ci	sata_phy_id = readl(sg->base + GEMINI_SATA_PHY_ID);
28262306a36Sopenharmony_ci	sg->sata_bridge = true;
28362306a36Sopenharmony_ci	clk_disable(sg->sata0_pclk);
28462306a36Sopenharmony_ci	clk_disable(sg->sata1_pclk);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	dev_info(dev, "SATA ID %08x, PHY ID: %08x\n", sata_id, sata_phy_id);
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	return 0;
28962306a36Sopenharmony_ci}
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_cistatic int gemini_setup_ide_pins(struct device *dev)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	struct pinctrl *p;
29462306a36Sopenharmony_ci	struct pinctrl_state *ide_state;
29562306a36Sopenharmony_ci	int ret;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	p = devm_pinctrl_get(dev);
29862306a36Sopenharmony_ci	if (IS_ERR(p))
29962306a36Sopenharmony_ci		return PTR_ERR(p);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	ide_state = pinctrl_lookup_state(p, "ide");
30262306a36Sopenharmony_ci	if (IS_ERR(ide_state))
30362306a36Sopenharmony_ci		return PTR_ERR(ide_state);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	ret = pinctrl_select_state(p, ide_state);
30662306a36Sopenharmony_ci	if (ret) {
30762306a36Sopenharmony_ci		dev_err(dev, "could not select IDE state\n");
30862306a36Sopenharmony_ci		return ret;
30962306a36Sopenharmony_ci	}
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	return 0;
31262306a36Sopenharmony_ci}
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_cistatic int gemini_sata_probe(struct platform_device *pdev)
31562306a36Sopenharmony_ci{
31662306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
31762306a36Sopenharmony_ci	struct device_node *np = dev->of_node;
31862306a36Sopenharmony_ci	struct sata_gemini *sg;
31962306a36Sopenharmony_ci	struct regmap *map;
32062306a36Sopenharmony_ci	enum gemini_muxmode muxmode;
32162306a36Sopenharmony_ci	u32 gmode;
32262306a36Sopenharmony_ci	u32 gmask;
32362306a36Sopenharmony_ci	int ret;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	sg = devm_kzalloc(dev, sizeof(*sg), GFP_KERNEL);
32662306a36Sopenharmony_ci	if (!sg)
32762306a36Sopenharmony_ci		return -ENOMEM;
32862306a36Sopenharmony_ci	sg->dev = dev;
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	sg->base = devm_platform_ioremap_resource(pdev, 0);
33162306a36Sopenharmony_ci	if (IS_ERR(sg->base))
33262306a36Sopenharmony_ci		return PTR_ERR(sg->base);
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	map = syscon_regmap_lookup_by_phandle(np, "syscon");
33562306a36Sopenharmony_ci	if (IS_ERR(map)) {
33662306a36Sopenharmony_ci		dev_err(dev, "no global syscon\n");
33762306a36Sopenharmony_ci		return PTR_ERR(map);
33862306a36Sopenharmony_ci	}
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	/* Set up the SATA bridge if need be */
34162306a36Sopenharmony_ci	if (of_property_read_bool(np, "cortina,gemini-enable-sata-bridge")) {
34262306a36Sopenharmony_ci		ret = gemini_sata_bridge_init(sg);
34362306a36Sopenharmony_ci		if (ret)
34462306a36Sopenharmony_ci			return ret;
34562306a36Sopenharmony_ci	}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	if (of_property_read_bool(np, "cortina,gemini-enable-ide-pins"))
34862306a36Sopenharmony_ci		sg->ide_pins = true;
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	if (!sg->sata_bridge && !sg->ide_pins) {
35162306a36Sopenharmony_ci		dev_err(dev, "neither SATA bridge or IDE output enabled\n");
35262306a36Sopenharmony_ci		ret = -EINVAL;
35362306a36Sopenharmony_ci		goto out_unprep_clk;
35462306a36Sopenharmony_ci	}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	ret = of_property_read_u32(np, "cortina,gemini-ata-muxmode", &muxmode);
35762306a36Sopenharmony_ci	if (ret) {
35862306a36Sopenharmony_ci		dev_err(dev, "could not parse ATA muxmode\n");
35962306a36Sopenharmony_ci		goto out_unprep_clk;
36062306a36Sopenharmony_ci	}
36162306a36Sopenharmony_ci	if (muxmode > GEMINI_MUXMODE_3) {
36262306a36Sopenharmony_ci		dev_err(dev, "illegal muxmode %d\n", muxmode);
36362306a36Sopenharmony_ci		ret = -EINVAL;
36462306a36Sopenharmony_ci		goto out_unprep_clk;
36562306a36Sopenharmony_ci	}
36662306a36Sopenharmony_ci	sg->muxmode = muxmode;
36762306a36Sopenharmony_ci	gmask = GEMINI_IDE_IOMUX_MASK;
36862306a36Sopenharmony_ci	gmode = (muxmode << GEMINI_IDE_IOMUX_SHIFT);
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, gmask, gmode);
37162306a36Sopenharmony_ci	if (ret) {
37262306a36Sopenharmony_ci		dev_err(dev, "unable to set up IDE muxing\n");
37362306a36Sopenharmony_ci		ret = -ENODEV;
37462306a36Sopenharmony_ci		goto out_unprep_clk;
37562306a36Sopenharmony_ci	}
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	/*
37862306a36Sopenharmony_ci	 * Route out the IDE pins if desired.
37962306a36Sopenharmony_ci	 * This is done by looking up a special pin control state called
38062306a36Sopenharmony_ci	 * "ide" that will route out the IDE pins.
38162306a36Sopenharmony_ci	 */
38262306a36Sopenharmony_ci	if (sg->ide_pins) {
38362306a36Sopenharmony_ci		ret = gemini_setup_ide_pins(dev);
38462306a36Sopenharmony_ci		if (ret)
38562306a36Sopenharmony_ci			return ret;
38662306a36Sopenharmony_ci	}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	dev_info(dev, "set up the Gemini IDE/SATA nexus\n");
38962306a36Sopenharmony_ci	platform_set_drvdata(pdev, sg);
39062306a36Sopenharmony_ci	sg_singleton = sg;
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	return 0;
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ciout_unprep_clk:
39562306a36Sopenharmony_ci	if (sg->sata_bridge) {
39662306a36Sopenharmony_ci		clk_unprepare(sg->sata1_pclk);
39762306a36Sopenharmony_ci		clk_unprepare(sg->sata0_pclk);
39862306a36Sopenharmony_ci	}
39962306a36Sopenharmony_ci	return ret;
40062306a36Sopenharmony_ci}
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_cistatic void gemini_sata_remove(struct platform_device *pdev)
40362306a36Sopenharmony_ci{
40462306a36Sopenharmony_ci	struct sata_gemini *sg = platform_get_drvdata(pdev);
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	if (sg->sata_bridge) {
40762306a36Sopenharmony_ci		clk_unprepare(sg->sata1_pclk);
40862306a36Sopenharmony_ci		clk_unprepare(sg->sata0_pclk);
40962306a36Sopenharmony_ci	}
41062306a36Sopenharmony_ci	sg_singleton = NULL;
41162306a36Sopenharmony_ci}
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_cistatic const struct of_device_id gemini_sata_of_match[] = {
41462306a36Sopenharmony_ci	{ .compatible = "cortina,gemini-sata-bridge", },
41562306a36Sopenharmony_ci	{ /* sentinel */ }
41662306a36Sopenharmony_ci};
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_cistatic struct platform_driver gemini_sata_driver = {
41962306a36Sopenharmony_ci	.driver = {
42062306a36Sopenharmony_ci		.name = DRV_NAME,
42162306a36Sopenharmony_ci		.of_match_table = gemini_sata_of_match,
42262306a36Sopenharmony_ci	},
42362306a36Sopenharmony_ci	.probe = gemini_sata_probe,
42462306a36Sopenharmony_ci	.remove_new = gemini_sata_remove,
42562306a36Sopenharmony_ci};
42662306a36Sopenharmony_cimodule_platform_driver(gemini_sata_driver);
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ciMODULE_DESCRIPTION("low level driver for Cortina Systems Gemini SATA bridge");
42962306a36Sopenharmony_ciMODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
43062306a36Sopenharmony_ciMODULE_LICENSE("GPL");
43162306a36Sopenharmony_ciMODULE_ALIAS("platform:" DRV_NAME);
432