// SPDX-License-Identifier: MIT
/*
 * Copyright 2020 Noralf Trønnes
 */

#include <linux/backlight.h>
#include <linux/workqueue.h>

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_connector.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder.h>
#include <drm/drm_file.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/gud.h>

#include "gud_internal.h"

struct gud_connector {
	struct drm_connector connector;
	struct drm_encoder encoder;
	struct backlight_device *backlight;
	struct work_struct backlight_work;

	/* Supported properties */
	u16 *properties;
	unsigned int num_properties;

	/* Initial gadget tv state if applicable, applied on state reset */
	struct drm_tv_connector_state initial_tv_state;

	/*
	 * Initial gadget backlight brightness if applicable, applied on state reset.
	 * The value -ENODEV is used to signal no backlight.
	 */
	int initial_brightness;
};

static inline struct gud_connector *to_gud_connector(struct drm_connector *connector)
{
	return container_of(connector, struct gud_connector, connector);
}

static void gud_conn_err(struct drm_connector *connector, const char *msg, int ret)
{
	dev_err(connector->dev->dev, "%s: %s (ret=%d)\n", connector->name, msg, ret);
}

/*
 * Use a worker to avoid taking kms locks inside the backlight lock.
 * Other display drivers use backlight within their kms locks.
 * This avoids inconsistent locking rules, which would upset lockdep.
 */
static void gud_connector_backlight_update_status_work(struct work_struct *work)
{
	struct gud_connector *gconn = container_of(work, struct gud_connector, backlight_work);
	struct drm_connector *connector = &gconn->connector;
	struct drm_connector_state *connector_state;
	struct drm_device *drm = connector->dev;
	struct drm_modeset_acquire_ctx ctx;
	struct drm_atomic_state *state;
	int idx, ret;

	if (!drm_dev_enter(drm, &idx))
		return;

	state = drm_atomic_state_alloc(drm);
	if (!state) {
		ret = -ENOMEM;
		goto exit;
	}

	drm_modeset_acquire_init(&ctx, 0);
	state->acquire_ctx = &ctx;
retry:
	connector_state = drm_atomic_get_connector_state(state, connector);
	if (IS_ERR(connector_state)) {
		ret = PTR_ERR(connector_state);
		goto out;
	}

	/* Reuse tv.brightness to avoid having to subclass */
	connector_state->tv.brightness = gconn->backlight->props.brightness;

	ret = drm_atomic_commit(state);
out:
	if (ret == -EDEADLK) {
		drm_atomic_state_clear(state);
		drm_modeset_backoff(&ctx);
		goto retry;
	}

	drm_atomic_state_put(state);

	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
exit:
	drm_dev_exit(idx);

	if (ret)
		dev_err(drm->dev, "Failed to update backlight, err=%d\n", ret);
}

static int gud_connector_backlight_update_status(struct backlight_device *bd)
{
	struct drm_connector *connector = bl_get_data(bd);
	struct gud_connector *gconn = to_gud_connector(connector);

	/* The USB timeout is 5 seconds so use system_long_wq for worst case scenario */
	queue_work(system_long_wq, &gconn->backlight_work);

	return 0;
}

static const struct backlight_ops gud_connector_backlight_ops = {
	.update_status	= gud_connector_backlight_update_status,
};

static int gud_connector_backlight_register(struct gud_connector *gconn)
{
	struct drm_connector *connector = &gconn->connector;
	struct backlight_device *bd;
	const char *name;
	const struct backlight_properties props = {
		.type = BACKLIGHT_RAW,
		.scale = BACKLIGHT_SCALE_NON_LINEAR,
		.max_brightness = 100,
		.brightness = gconn->initial_brightness,
	};

	name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
			 connector->dev->primary->index, connector->name);
	if (!name)
		return -ENOMEM;

	bd = backlight_device_register(name, connector->kdev, connector,
				       &gud_connector_backlight_ops, &props);
	kfree(name);
	if (IS_ERR(bd))
		return PTR_ERR(bd);

	gconn->backlight = bd;

	return 0;
}

static int gud_connector_detect(struct drm_connector *connector,
				struct drm_modeset_acquire_ctx *ctx, bool force)
{
	struct gud_device *gdrm = to_gud_device(connector->dev);
	int idx, ret;
	u8 status;

	if (!drm_dev_enter(connector->dev, &idx))
		return connector_status_disconnected;

	if (force) {
		ret = gud_usb_set(gdrm, GUD_REQ_SET_CONNECTOR_FORCE_DETECT,
				  connector->index, NULL, 0);
		if (ret) {
			ret = connector_status_unknown;
			goto exit;
		}
	}

	ret = gud_usb_get_u8(gdrm, GUD_REQ_GET_CONNECTOR_STATUS, connector->index, &status);
	if (ret) {
		ret = connector_status_unknown;
		goto exit;
	}

	switch (status & GUD_CONNECTOR_STATUS_CONNECTED_MASK) {
	case GUD_CONNECTOR_STATUS_DISCONNECTED:
		ret = connector_status_disconnected;
		break;
	case GUD_CONNECTOR_STATUS_CONNECTED:
		ret = connector_status_connected;
		break;
	default:
		ret = connector_status_unknown;
		break;
	}

	if (status & GUD_CONNECTOR_STATUS_CHANGED)
		connector->epoch_counter += 1;
exit:
	drm_dev_exit(idx);

	return ret;
}

struct gud_connector_get_edid_ctx {
	void *buf;
	size_t len;
	bool edid_override;
};

static int gud_connector_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
{
	struct gud_connector_get_edid_ctx *ctx = data;
	size_t start = block * EDID_LENGTH;

	ctx->edid_override = false;

	if (start + len > ctx->len)
		return -1;

	memcpy(buf, ctx->buf + start, len);

	return 0;
}

static int gud_connector_get_modes(struct drm_connector *connector)
{
	struct gud_device *gdrm = to_gud_device(connector->dev);
	struct gud_display_mode_req *reqmodes = NULL;
	struct gud_connector_get_edid_ctx edid_ctx;
	unsigned int i, num_modes = 0;
	struct edid *edid = NULL;
	int idx, ret;

	if (!drm_dev_enter(connector->dev, &idx))
		return 0;

	edid_ctx.edid_override = true;
	edid_ctx.buf = kmalloc(GUD_CONNECTOR_MAX_EDID_LEN, GFP_KERNEL);
	if (!edid_ctx.buf)
		goto out;

	ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTOR_EDID, connector->index,
			  edid_ctx.buf, GUD_CONNECTOR_MAX_EDID_LEN);
	if (ret > 0 && ret % EDID_LENGTH) {
		gud_conn_err(connector, "Invalid EDID size", ret);
	} else if (ret > 0) {
		edid_ctx.len = ret;
		edid = drm_do_get_edid(connector, gud_connector_get_edid_block, &edid_ctx);
	}

	kfree(edid_ctx.buf);
	drm_connector_update_edid_property(connector, edid);

	if (edid && edid_ctx.edid_override)
		goto out;

	reqmodes = kmalloc_array(GUD_CONNECTOR_MAX_NUM_MODES, sizeof(*reqmodes), GFP_KERNEL);
	if (!reqmodes)
		goto out;

	ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTOR_MODES, connector->index,
			  reqmodes, GUD_CONNECTOR_MAX_NUM_MODES * sizeof(*reqmodes));
	if (ret <= 0)
		goto out;
	if (ret % sizeof(*reqmodes)) {
		gud_conn_err(connector, "Invalid display mode array size", ret);
		goto out;
	}

	num_modes = ret / sizeof(*reqmodes);

	for (i = 0; i < num_modes; i++) {
		struct drm_display_mode *mode;

		mode = drm_mode_create(connector->dev);
		if (!mode) {
			num_modes = i;
			goto out;
		}

		gud_to_display_mode(mode, &reqmodes[i]);
		drm_mode_probed_add(connector, mode);
	}
out:
	if (!num_modes)
		num_modes = drm_add_edid_modes(connector, edid);

	kfree(reqmodes);
	kfree(edid);
	drm_dev_exit(idx);

	return num_modes;
}

static int gud_connector_atomic_check(struct drm_connector *connector,
				      struct drm_atomic_state *state)
{
	struct drm_connector_state *new_state;
	struct drm_crtc_state *new_crtc_state;
	struct drm_connector_state *old_state;

	new_state = drm_atomic_get_new_connector_state(state, connector);
	if (!new_state->crtc)
		return 0;

	old_state = drm_atomic_get_old_connector_state(state, connector);
	new_crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);

	if (old_state->tv.margins.left != new_state->tv.margins.left ||
	    old_state->tv.margins.right != new_state->tv.margins.right ||
	    old_state->tv.margins.top != new_state->tv.margins.top ||
	    old_state->tv.margins.bottom != new_state->tv.margins.bottom ||
	    old_state->tv.mode != new_state->tv.mode ||
	    old_state->tv.brightness != new_state->tv.brightness ||
	    old_state->tv.contrast != new_state->tv.contrast ||
	    old_state->tv.flicker_reduction != new_state->tv.flicker_reduction ||
	    old_state->tv.overscan != new_state->tv.overscan ||
	    old_state->tv.saturation != new_state->tv.saturation ||
	    old_state->tv.hue != new_state->tv.hue)
		new_crtc_state->connectors_changed = true;

	return 0;
}

static const struct drm_connector_helper_funcs gud_connector_helper_funcs = {
	.detect_ctx = gud_connector_detect,
	.get_modes = gud_connector_get_modes,
	.atomic_check = gud_connector_atomic_check,
};

static int gud_connector_late_register(struct drm_connector *connector)
{
	struct gud_connector *gconn = to_gud_connector(connector);

	if (gconn->initial_brightness < 0)
		return 0;

	return gud_connector_backlight_register(gconn);
}

static void gud_connector_early_unregister(struct drm_connector *connector)
{
	struct gud_connector *gconn = to_gud_connector(connector);

	backlight_device_unregister(gconn->backlight);
	cancel_work_sync(&gconn->backlight_work);
}

static void gud_connector_destroy(struct drm_connector *connector)
{
	struct gud_connector *gconn = to_gud_connector(connector);

	drm_connector_cleanup(connector);
	kfree(gconn->properties);
	kfree(gconn);
}

static void gud_connector_reset(struct drm_connector *connector)
{
	struct gud_connector *gconn = to_gud_connector(connector);

	drm_atomic_helper_connector_reset(connector);
	connector->state->tv = gconn->initial_tv_state;
	/* Set margins from command line */
	drm_atomic_helper_connector_tv_reset(connector);
	if (gconn->initial_brightness >= 0)
		connector->state->tv.brightness = gconn->initial_brightness;
}

static const struct drm_connector_funcs gud_connector_funcs = {
	.fill_modes = drm_helper_probe_single_connector_modes,
	.late_register = gud_connector_late_register,
	.early_unregister = gud_connector_early_unregister,
	.destroy = gud_connector_destroy,
	.reset = gud_connector_reset,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

/*
 * The tv.mode property is shared among the connectors and its enum names are
 * driver specific. This means that if more than one connector uses tv.mode,
 * the enum names has to be the same.
 */
static int gud_connector_add_tv_mode(struct gud_device *gdrm, struct drm_connector *connector)
{
	size_t buf_len = GUD_CONNECTOR_TV_MODE_MAX_NUM * GUD_CONNECTOR_TV_MODE_NAME_LEN;
	const char *modes[GUD_CONNECTOR_TV_MODE_MAX_NUM];
	unsigned int i, num_modes;
	char *buf;
	int ret;

	buf = kmalloc(buf_len, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTOR_TV_MODE_VALUES,
			  connector->index, buf, buf_len);
	if (ret < 0)
		goto free;
	if (!ret || ret % GUD_CONNECTOR_TV_MODE_NAME_LEN) {
		ret = -EIO;
		goto free;
	}

	num_modes = ret / GUD_CONNECTOR_TV_MODE_NAME_LEN;
	for (i = 0; i < num_modes; i++)
		modes[i] = &buf[i * GUD_CONNECTOR_TV_MODE_NAME_LEN];

	ret = drm_mode_create_tv_properties(connector->dev, num_modes, modes);
free:
	kfree(buf);
	if (ret < 0)
		gud_conn_err(connector, "Failed to add TV modes", ret);

	return ret;
}

static struct drm_property *
gud_connector_property_lookup(struct drm_connector *connector, u16 prop)
{
	struct drm_mode_config *config = &connector->dev->mode_config;

	switch (prop) {
	case GUD_PROPERTY_TV_LEFT_MARGIN:
		return config->tv_left_margin_property;
	case GUD_PROPERTY_TV_RIGHT_MARGIN:
		return config->tv_right_margin_property;
	case GUD_PROPERTY_TV_TOP_MARGIN:
		return config->tv_top_margin_property;
	case GUD_PROPERTY_TV_BOTTOM_MARGIN:
		return config->tv_bottom_margin_property;
	case GUD_PROPERTY_TV_MODE:
		return config->tv_mode_property;
	case GUD_PROPERTY_TV_BRIGHTNESS:
		return config->tv_brightness_property;
	case GUD_PROPERTY_TV_CONTRAST:
		return config->tv_contrast_property;
	case GUD_PROPERTY_TV_FLICKER_REDUCTION:
		return config->tv_flicker_reduction_property;
	case GUD_PROPERTY_TV_OVERSCAN:
		return config->tv_overscan_property;
	case GUD_PROPERTY_TV_SATURATION:
		return config->tv_saturation_property;
	case GUD_PROPERTY_TV_HUE:
		return config->tv_hue_property;
	default:
		return ERR_PTR(-EINVAL);
	}
}

static unsigned int *gud_connector_tv_state_val(u16 prop, struct drm_tv_connector_state *state)
{
	switch (prop) {
	case GUD_PROPERTY_TV_LEFT_MARGIN:
		return &state->margins.left;
	case GUD_PROPERTY_TV_RIGHT_MARGIN:
		return &state->margins.right;
	case GUD_PROPERTY_TV_TOP_MARGIN:
		return &state->margins.top;
	case GUD_PROPERTY_TV_BOTTOM_MARGIN:
		return &state->margins.bottom;
	case GUD_PROPERTY_TV_MODE:
		return &state->mode;
	case GUD_PROPERTY_TV_BRIGHTNESS:
		return &state->brightness;
	case GUD_PROPERTY_TV_CONTRAST:
		return &state->contrast;
	case GUD_PROPERTY_TV_FLICKER_REDUCTION:
		return &state->flicker_reduction;
	case GUD_PROPERTY_TV_OVERSCAN:
		return &state->overscan;
	case GUD_PROPERTY_TV_SATURATION:
		return &state->saturation;
	case GUD_PROPERTY_TV_HUE:
		return &state->hue;
	default:
		return ERR_PTR(-EINVAL);
	}
}

static int gud_connector_add_properties(struct gud_device *gdrm, struct gud_connector *gconn)
{
	struct drm_connector *connector = &gconn->connector;
	struct drm_device *drm = &gdrm->drm;
	struct gud_property_req *properties;
	unsigned int i, num_properties;
	int ret;

	properties = kcalloc(GUD_CONNECTOR_PROPERTIES_MAX_NUM, sizeof(*properties), GFP_KERNEL);
	if (!properties)
		return -ENOMEM;

	ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTOR_PROPERTIES, connector->index,
			  properties, GUD_CONNECTOR_PROPERTIES_MAX_NUM * sizeof(*properties));
	if (ret <= 0)
		goto out;
	if (ret % sizeof(*properties)) {
		ret = -EIO;
		goto out;
	}

	num_properties = ret / sizeof(*properties);
	ret = 0;

	gconn->properties = kcalloc(num_properties, sizeof(*gconn->properties), GFP_KERNEL);
	if (!gconn->properties) {
		ret = -ENOMEM;
		goto out;
	}

	for (i = 0; i < num_properties; i++) {
		u16 prop = le16_to_cpu(properties[i].prop);
		u64 val = le64_to_cpu(properties[i].val);
		struct drm_property *property;
		unsigned int *state_val;

		drm_dbg(drm, "property: %u = %llu(0x%llx)\n", prop, val, val);

		switch (prop) {
		case GUD_PROPERTY_TV_LEFT_MARGIN:
			fallthrough;
		case GUD_PROPERTY_TV_RIGHT_MARGIN:
			fallthrough;
		case GUD_PROPERTY_TV_TOP_MARGIN:
			fallthrough;
		case GUD_PROPERTY_TV_BOTTOM_MARGIN:
			ret = drm_mode_create_tv_margin_properties(drm);
			if (ret)
				goto out;
			break;
		case GUD_PROPERTY_TV_MODE:
			ret = gud_connector_add_tv_mode(gdrm, connector);
			if (ret)
				goto out;
			break;
		case GUD_PROPERTY_TV_BRIGHTNESS:
			fallthrough;
		case GUD_PROPERTY_TV_CONTRAST:
			fallthrough;
		case GUD_PROPERTY_TV_FLICKER_REDUCTION:
			fallthrough;
		case GUD_PROPERTY_TV_OVERSCAN:
			fallthrough;
		case GUD_PROPERTY_TV_SATURATION:
			fallthrough;
		case GUD_PROPERTY_TV_HUE:
			/* This is a no-op if already added. */
			ret = drm_mode_create_tv_properties(drm, 0, NULL);
			if (ret)
				goto out;
			break;
		case GUD_PROPERTY_BACKLIGHT_BRIGHTNESS:
			if (val > 100) {
				ret = -EINVAL;
				goto out;
			}
			gconn->initial_brightness = val;
			break;
		default:
			/* New ones might show up in future devices, skip those we don't know. */
			drm_dbg(drm, "Ignoring unknown property: %u\n", prop);
			continue;
		}

		gconn->properties[gconn->num_properties++] = prop;

		if (prop == GUD_PROPERTY_BACKLIGHT_BRIGHTNESS)
			continue; /* not a DRM property */

		property = gud_connector_property_lookup(connector, prop);
		if (WARN_ON(IS_ERR(property)))
			continue;

		state_val = gud_connector_tv_state_val(prop, &gconn->initial_tv_state);
		if (WARN_ON(IS_ERR(state_val)))
			continue;

		*state_val = val;
		drm_object_attach_property(&connector->base, property, 0);
	}
out:
	kfree(properties);

	return ret;
}

int gud_connector_fill_properties(struct drm_connector_state *connector_state,
				  struct gud_property_req *properties)
{
	struct gud_connector *gconn = to_gud_connector(connector_state->connector);
	unsigned int i;

	for (i = 0; i < gconn->num_properties; i++) {
		u16 prop = gconn->properties[i];
		u64 val;

		if (prop == GUD_PROPERTY_BACKLIGHT_BRIGHTNESS) {
			val = connector_state->tv.brightness;
		} else {
			unsigned int *state_val;

			state_val = gud_connector_tv_state_val(prop, &connector_state->tv);
			if (WARN_ON_ONCE(IS_ERR(state_val)))
				return PTR_ERR(state_val);

			val = *state_val;
		}

		properties[i].prop = cpu_to_le16(prop);
		properties[i].val = cpu_to_le64(val);
	}

	return gconn->num_properties;
}

static int gud_connector_create(struct gud_device *gdrm, unsigned int index,
				struct gud_connector_descriptor_req *desc)
{
	struct drm_device *drm = &gdrm->drm;
	struct gud_connector *gconn;
	struct drm_connector *connector;
	struct drm_encoder *encoder;
	int ret, connector_type;
	u32 flags;

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

	INIT_WORK(&gconn->backlight_work, gud_connector_backlight_update_status_work);
	gconn->initial_brightness = -ENODEV;
	flags = le32_to_cpu(desc->flags);
	connector = &gconn->connector;

	drm_dbg(drm, "Connector: index=%u type=%u flags=0x%x\n", index, desc->connector_type, flags);

	switch (desc->connector_type) {
	case GUD_CONNECTOR_TYPE_PANEL:
		connector_type = DRM_MODE_CONNECTOR_USB;
		break;
	case GUD_CONNECTOR_TYPE_VGA:
		connector_type = DRM_MODE_CONNECTOR_VGA;
		break;
	case GUD_CONNECTOR_TYPE_DVI:
		connector_type = DRM_MODE_CONNECTOR_DVID;
		break;
	case GUD_CONNECTOR_TYPE_COMPOSITE:
		connector_type = DRM_MODE_CONNECTOR_Composite;
		break;
	case GUD_CONNECTOR_TYPE_SVIDEO:
		connector_type = DRM_MODE_CONNECTOR_SVIDEO;
		break;
	case GUD_CONNECTOR_TYPE_COMPONENT:
		connector_type = DRM_MODE_CONNECTOR_Component;
		break;
	case GUD_CONNECTOR_TYPE_DISPLAYPORT:
		connector_type = DRM_MODE_CONNECTOR_DisplayPort;
		break;
	case GUD_CONNECTOR_TYPE_HDMI:
		connector_type = DRM_MODE_CONNECTOR_HDMIA;
		break;
	default: /* future types */
		connector_type = DRM_MODE_CONNECTOR_USB;
		break;
	}

	drm_connector_helper_add(connector, &gud_connector_helper_funcs);
	ret = drm_connector_init(drm, connector, &gud_connector_funcs, connector_type);
	if (ret) {
		kfree(connector);
		return ret;
	}

	if (WARN_ON(connector->index != index))
		return -EINVAL;

	if (flags & GUD_CONNECTOR_FLAGS_POLL_STATUS)
		connector->polled = (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT);
	if (flags & GUD_CONNECTOR_FLAGS_INTERLACE)
		connector->interlace_allowed = true;
	if (flags & GUD_CONNECTOR_FLAGS_DOUBLESCAN)
		connector->doublescan_allowed = true;

	ret = gud_connector_add_properties(gdrm, gconn);
	if (ret) {
		gud_conn_err(connector, "Failed to add properties", ret);
		return ret;
	}

	/* The first connector is attached to the existing simple pipe encoder */
	if (!connector->index) {
		encoder = &gdrm->pipe.encoder;
	} else {
		encoder = &gconn->encoder;

		ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
		if (ret)
			return ret;

		encoder->possible_crtcs = 1;
	}

	return drm_connector_attach_encoder(connector, encoder);
}

int gud_get_connectors(struct gud_device *gdrm)
{
	struct gud_connector_descriptor_req *descs;
	unsigned int i, num_connectors;
	int ret;

	descs = kmalloc_array(GUD_CONNECTORS_MAX_NUM, sizeof(*descs), GFP_KERNEL);
	if (!descs)
		return -ENOMEM;

	ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTORS, 0,
			  descs, GUD_CONNECTORS_MAX_NUM * sizeof(*descs));
	if (ret < 0)
		goto free;
	if (!ret || ret % sizeof(*descs)) {
		ret = -EIO;
		goto free;
	}

	num_connectors = ret / sizeof(*descs);

	for (i = 0; i < num_connectors; i++) {
		ret = gud_connector_create(gdrm, i, &descs[i]);
		if (ret)
			goto free;
	}
free:
	kfree(descs);

	return ret;
}
