/*
 * Copyright (C) 2012 Avionic Design GmbH
 * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>

#include "drm.h"

struct host1x_drm_client {
	struct host1x_client *client;
	struct device_node *np;
	struct list_head list;
};

static int host1x_add_drm_client(struct host1x *host1x, struct device_node *np)
{
	struct host1x_drm_client *client;

	client = kzalloc(sizeof(*client), GFP_KERNEL);
	if (!client)
		return -ENOMEM;

	INIT_LIST_HEAD(&client->list);
	client->np = of_node_get(np);

	list_add_tail(&client->list, &host1x->drm_clients);

	return 0;
}

static int host1x_activate_drm_client(struct host1x *host1x,
				      struct host1x_drm_client *drm,
				      struct host1x_client *client)
{
	mutex_lock(&host1x->drm_clients_lock);
	list_del_init(&drm->list);
	list_add_tail(&drm->list, &host1x->drm_active);
	drm->client = client;
	mutex_unlock(&host1x->drm_clients_lock);

	return 0;
}

static int host1x_remove_drm_client(struct host1x *host1x,
				    struct host1x_drm_client *client)
{
	mutex_lock(&host1x->drm_clients_lock);
	list_del_init(&client->list);
	mutex_unlock(&host1x->drm_clients_lock);

	of_node_put(client->np);
	kfree(client);

	return 0;
}

static int host1x_parse_dt(struct host1x *host1x)
{
	static const char * const compat[] = {
		"nvidia,tegra20-dc",
		"nvidia,tegra20-hdmi",
	};
	unsigned int i;
	int err;

	for (i = 0; i < ARRAY_SIZE(compat); i++) {
		struct device_node *np;

		for_each_child_of_node(host1x->dev->of_node, np) {
			if (of_device_is_compatible(np, compat[i]) &&
			    of_device_is_available(np)) {
				err = host1x_add_drm_client(host1x, np);
				if (err < 0)
					return err;
			}
		}
	}

	return 0;
}

static int tegra_host1x_probe(struct platform_device *pdev)
{
	struct host1x *host1x;
	struct resource *regs;
	int err;

	host1x = devm_kzalloc(&pdev->dev, sizeof(*host1x), GFP_KERNEL);
	if (!host1x)
		return -ENOMEM;

	mutex_init(&host1x->drm_clients_lock);
	INIT_LIST_HEAD(&host1x->drm_clients);
	INIT_LIST_HEAD(&host1x->drm_active);
	mutex_init(&host1x->clients_lock);
	INIT_LIST_HEAD(&host1x->clients);
	host1x->dev = &pdev->dev;

	err = host1x_parse_dt(host1x);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to parse DT: %d\n", err);
		return err;
	}

	host1x->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(host1x->clk))
		return PTR_ERR(host1x->clk);

	err = clk_prepare_enable(host1x->clk);
	if (err < 0)
		return err;

	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!regs) {
		err = -ENXIO;
		goto err;
	}

	err = platform_get_irq(pdev, 0);
	if (err < 0)
		goto err;

	host1x->syncpt = err;

	err = platform_get_irq(pdev, 1);
	if (err < 0)
		goto err;

	host1x->irq = err;

	host1x->regs = devm_request_and_ioremap(&pdev->dev, regs);
	if (!host1x->regs) {
		err = -EADDRNOTAVAIL;
		goto err;
	}

	platform_set_drvdata(pdev, host1x);

	return 0;

err:
	clk_disable_unprepare(host1x->clk);
	return err;
}

static int tegra_host1x_remove(struct platform_device *pdev)
{
	struct host1x *host1x = platform_get_drvdata(pdev);

	clk_disable_unprepare(host1x->clk);

	return 0;
}

int host1x_drm_init(struct host1x *host1x, struct drm_device *drm)
{
	struct host1x_client *client;

	mutex_lock(&host1x->clients_lock);

	list_for_each_entry(client, &host1x->clients, list) {
		if (client->ops && client->ops->drm_init) {
			int err = client->ops->drm_init(client, drm);
			if (err < 0) {
				dev_err(host1x->dev,
					"DRM setup failed for %s: %d\n",
					dev_name(client->dev), err);
				return err;
			}
		}
	}

	mutex_unlock(&host1x->clients_lock);

	return 0;
}

int host1x_drm_exit(struct host1x *host1x)
{
	struct platform_device *pdev = to_platform_device(host1x->dev);
	struct host1x_client *client;

	if (!host1x->drm)
		return 0;

	mutex_lock(&host1x->clients_lock);

	list_for_each_entry_reverse(client, &host1x->clients, list) {
		if (client->ops && client->ops->drm_exit) {
			int err = client->ops->drm_exit(client);
			if (err < 0) {
				dev_err(host1x->dev,
					"DRM cleanup failed for %s: %d\n",
					dev_name(client->dev), err);
				return err;
			}
		}
	}

	mutex_unlock(&host1x->clients_lock);

	drm_platform_exit(&tegra_drm_driver, pdev);
	host1x->drm = NULL;

	return 0;
}

int host1x_register_client(struct host1x *host1x, struct host1x_client *client)
{
	struct host1x_drm_client *drm, *tmp;
	int err;

	mutex_lock(&host1x->clients_lock);
	list_add_tail(&client->list, &host1x->clients);
	mutex_unlock(&host1x->clients_lock);

	list_for_each_entry_safe(drm, tmp, &host1x->drm_clients, list)
		if (drm->np == client->dev->of_node)
			host1x_activate_drm_client(host1x, drm, client);

	if (list_empty(&host1x->drm_clients)) {
		struct platform_device *pdev = to_platform_device(host1x->dev);

		err = drm_platform_init(&tegra_drm_driver, pdev);
		if (err < 0) {
			dev_err(host1x->dev, "drm_platform_init(): %d\n", err);
			return err;
		}
	}

	return 0;
}

int host1x_unregister_client(struct host1x *host1x,
			     struct host1x_client *client)
{
	struct host1x_drm_client *drm, *tmp;
	int err;

	list_for_each_entry_safe(drm, tmp, &host1x->drm_active, list) {
		if (drm->client == client) {
			err = host1x_drm_exit(host1x);
			if (err < 0) {
				dev_err(host1x->dev, "host1x_drm_exit(): %d\n",
					err);
				return err;
			}

			host1x_remove_drm_client(host1x, drm);
			break;
		}
	}

	mutex_lock(&host1x->clients_lock);
	list_del_init(&client->list);
	mutex_unlock(&host1x->clients_lock);

	return 0;
}

static struct of_device_id tegra_host1x_of_match[] = {
	{ .compatible = "nvidia,tegra20-host1x", },
	{ },
};
MODULE_DEVICE_TABLE(of, tegra_host1x_of_match);

struct platform_driver tegra_host1x_driver = {
	.driver = {
		.name = "tegra-host1x",
		.owner = THIS_MODULE,
		.of_match_table = tegra_host1x_of_match,
	},
	.probe = tegra_host1x_probe,
	.remove = tegra_host1x_remove,
};

static int __init tegra_host1x_init(void)
{
	int err;

	err = platform_driver_register(&tegra_host1x_driver);
	if (err < 0)
		return err;

	err = platform_driver_register(&tegra_dc_driver);
	if (err < 0)
		goto unregister_host1x;

	err = platform_driver_register(&tegra_hdmi_driver);
	if (err < 0)
		goto unregister_dc;

	return 0;

unregister_dc:
	platform_driver_unregister(&tegra_dc_driver);
unregister_host1x:
	platform_driver_unregister(&tegra_host1x_driver);
	return err;
}
module_init(tegra_host1x_init);

static void __exit tegra_host1x_exit(void)
{
	platform_driver_unregister(&tegra_hdmi_driver);
	platform_driver_unregister(&tegra_dc_driver);
	platform_driver_unregister(&tegra_host1x_driver);
}
module_exit(tegra_host1x_exit);

MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
MODULE_DESCRIPTION("NVIDIA Tegra DRM driver");
MODULE_LICENSE("GPL");
