Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dff03ed4 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/dp: add dp-mst sideband simulator"

parents 7eb847f4 48bc7e31
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
QTI Snapdragon Display Engine (SDE) DP-MST sideband message emulation driver

Required properties:
- compatible:		"qcom,dp-mst-sim"

Each child node represents a port at root branch, with properties:
- qcom,mode-h-active:      A u32 property defines the horizontal active size.
- qcom,mode-h-front-porch: A u32 property defines the horizontal front porch.
- qcom,mode-h-pulse-width: A u32 property defines the horizontal pulse.
- qcom,mode-h-back-porch:  A u32 property defines the horizontal back porch.
- qcom,mode-h-active-high: A boolean property if horizontal polarity is high.
- qcom,mode-v-active:      A u32 property defines the vertical active size.
- qcom,mode-v-front-porch: A u32 property defines the vertical front portch.
- qcom,mode-v-pulse-width: A u32 property defines the vertical pulse width.
- qcom,mode-v-back-porch:  A u32 property defines the vertical back porch.
- qcom,mode-v-active-high: A boolean property if vertical polarity is high.
- qcom,mode-refresh-rate:  A u32 property defines vertial refresh rate.
- qcom,mode-clock-in-khz:  A u32 property defines clock in kHz.

Example:

/ {
	...

	sde_dp_mst_sim: qcom,dp-mst-sim {
		compatible = "qcom,dp-mst-sim";

		port@0 {
			qcom,mode-h-active = <1920>;
			qcom,mode-h-front-porch = <88>;
			qcom,mode-h-pulse-width = <44>;
			qcom,mode-h-back-porch = <148>;
			qcom,mode-h-active-high;
			qcom,mode-v-active = <1080>;
			qcom,mode-v-front-porch = <4>;
			qcom,mode-v-pulse-width = <5>;
			qcom,mode-v-back-porch = <36>;
			qcom,mode-v-active-high;
			qcom,mode-refresh-rate = <60>;
			qcom,mode-clock-in-khz = <148500>;
		};

		port@1 {
			qcom,mode-h-active = <1920>;
			qcom,mode-h-front-porch = <88>;
			qcom,mode-h-pulse-width = <44>;
			qcom,mode-h-back-porch = <148>;
			qcom,mode-h-active-high;
			qcom,mode-v-active = <1080>;
			qcom,mode-v-front-porch = <4>;
			qcom,mode-v-pulse-width = <5>;
			qcom,mode-v-back-porch = <36>;
			qcom,mode-v-active-high;
			qcom,mode-refresh-rate = <60>;
			qcom,mode-clock-in-khz = <148500>;
		};
	};
};
+4 −0
Original line number Diff line number Diff line
@@ -22,7 +22,11 @@ msm_drm-y := \
	dp/dp_ctrl.o \
	dp/dp_audio.o \
	dp/dp_debug.o \
	dp/dp_mst_sim_helper.o \
	dp/dp_mst_sim.o \
	dp/dp_hpd.o \
	dp/dp_aux_bridge.o \
	dp/dp_bridge_hpd.o \
	dp/dp_gpio_hpd.o \
	dp/dp_lphw_hpd.o \
	dp/dp_display.o \
+31 −1
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ struct dp_aux_private {
	struct completion comp;
	struct drm_dp_aux drm_aux;

	struct msm_dp_aux_bridge *aux_bridge;
	bool bridge_in_transfer;

	bool cmd_busy;
	bool native;
	bool read;
@@ -635,6 +638,25 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *drm_aux,
	return ret;
}

static ssize_t dp_aux_bridge_transfer(struct drm_dp_aux *drm_aux,
		struct drm_dp_aux_msg *msg)
{
	struct dp_aux_private *aux = container_of(drm_aux,
			struct dp_aux_private, drm_aux);
	ssize_t size;

	if (aux->bridge_in_transfer) {
		size = dp_aux_transfer(drm_aux, msg);
	} else {
		aux->bridge_in_transfer = true;
		size = aux->aux_bridge->transfer(aux->aux_bridge,
				drm_aux, msg);
		aux->bridge_in_transfer = false;
	}

	return size;
}

static void dp_aux_reset_phy_config_indices(struct dp_aux_cfg *aux_cfg)
{
	int i = 0;
@@ -707,6 +729,10 @@ static int dp_aux_register(struct dp_aux *dp_aux)
		goto exit;
	}
	dp_aux->drm_aux = &aux->drm_aux;

	/* if bridge is defined, override transfer function */
	if (aux->aux_bridge && aux->aux_bridge->transfer)
		aux->drm_aux.transfer = dp_aux_bridge_transfer;
exit:
	return ret;
}
@@ -758,6 +784,8 @@ static void dp_aux_set_sim_mode(struct dp_aux *dp_aux, bool en,
	if (en) {
		atomic_set(&aux->aborted, 0);
		aux->drm_aux.transfer = dp_aux_transfer_debug;
	} else if (aux->aux_bridge && aux->aux_bridge->transfer) {
		aux->drm_aux.transfer = dp_aux_bridge_transfer;
	} else {
		aux->drm_aux.transfer = dp_aux_transfer;
	}
@@ -812,7 +840,8 @@ static int dp_aux_configure_aux_switch(struct dp_aux *dp_aux,
}

struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
		struct dp_parser *parser, struct device_node *aux_switch)
		struct dp_parser *parser, struct device_node *aux_switch,
		struct msm_dp_aux_bridge *aux_bridge)
{
	int rc = 0;
	struct dp_aux_private *aux;
@@ -841,6 +870,7 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
	aux->catalog = catalog;
	aux->cfg = parser->aux_cfg;
	aux->aux_switch_node = aux_switch;
	aux->aux_bridge = aux_bridge;
	dp_aux = &aux->dp_aux;
	aux->retry_cnt = 0;
	aux->dp_aux.reg = 0xFFFF;
+3 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

#include "dp_catalog.h"
#include "drm_dp_helper.h"
#include <soc/qcom/msm_dp_aux_bridge.h>

#define DP_STATE_NOTIFICATION_SENT          BIT(0)
#define DP_STATE_TRAIN_1_STARTED            BIT(1)
@@ -63,7 +64,8 @@ struct dp_aux {
};

struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
		struct dp_parser *parser, struct device_node *aux_switch);
		struct dp_parser *parser, struct device_node *aux_switch,
		struct msm_dp_aux_bridge *aux_bridge);
void dp_aux_put(struct dp_aux *aux);

#endif /*__DP_AUX_H_*/
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2019, The Linux Foundation. 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 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <soc/qcom/msm_dp_aux_bridge.h>

static DEFINE_MUTEX(dp_aux_bridge_lock);
static LIST_HEAD(du_aux_bridge_list);

int msm_dp_aux_add_bridge(struct msm_dp_aux_bridge *bridge)
{
	mutex_lock(&dp_aux_bridge_lock);
	list_add_tail(&bridge->head, &du_aux_bridge_list);
	mutex_unlock(&dp_aux_bridge_lock);

	return 0;
}

#ifdef CONFIG_OF
struct msm_dp_aux_bridge *of_msm_dp_aux_find_bridge(struct device_node *np)
{
	struct msm_dp_aux_bridge *bridge;

	mutex_lock(&dp_aux_bridge_lock);

	list_for_each_entry(bridge, &du_aux_bridge_list, head) {
		if (bridge->of_node == np) {
			mutex_unlock(&dp_aux_bridge_lock);
			return bridge;
		}
	}

	mutex_unlock(&dp_aux_bridge_lock);
	return NULL;
}
#endif
Loading