mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 14:04:27 -04:00
Merge tag 'drm-fixes-2025-04-26' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Dave Airlie:
"Weekly drm fixes, mostly amdgpu, with some exynos cleanups and a
couple of minor fixes, seems a bit quiet, but probably some lag from
Easter holidays.
amdgpu:
- P2P DMA fixes
- Display reset fixes
- DCN 3.5 fixes
- ACPI EDID fix
- LTTPR fix
- mode_valid() fix
exynos:
- fix spelling error
- remove redundant error handling in exynos_drm_vidi.c module
- marks struct decon_data as const in the exynos7_drm_decon driver
since it is only read
- Remove unnecessary checking in exynos_drm_drv.c module
meson:
- Fix VCLK calculation
panel:
- jd9365a: Fix reset polarity"
* tag 'drm-fixes-2025-04-26' of https://gitlab.freedesktop.org/drm/kernel:
drm/exynos: Fix spelling mistake "enqueu" -> "enqueue"
drm/exynos: exynos7_drm_decon: Consstify struct decon_data
drm/exynos: fixed a spelling error
drm/exynos/vidi: Remove redundant error handling in vidi_get_modes()
drm/exynos: Remove unnecessary checking
drm/amd/display: do not copy invalid CRTC timing info
drm/amd/display: Default IPS to RCG_IN_ACTIVE_IPS2_IN_OFF
drm/amd/display: Use 16ms AUX read interval for LTTPR with old sinks
drm/amd/display: Fix ACPI edid parsing on some Lenovo systems
drm/amdgpu: Allow P2P access through XGMI
drm/amd/display: Enable urgent latency adjustment on DCN35
drm/amd/display: Force full update in gpu reset
drm/amd/display: Fix gpu reset in multidisplay config
drm/amdgpu: Don't pin VRAM without DMABUF_MOVE_NOTIFY
drm/amdgpu: Use allowed_domains for pinning dmabufs
drm: panel: jd9365da: fix reset signal polarity in unprepare
drm/meson: use unsigned long long / Hz for frequency types
Revert "drm/meson: vclk: fix calculation of 59.94 fractional rates"
This commit is contained in:
@@ -43,6 +43,29 @@
|
||||
#include <linux/dma-fence-array.h>
|
||||
#include <linux/pci-p2pdma.h>
|
||||
|
||||
static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops;
|
||||
|
||||
/**
|
||||
* dma_buf_attach_adev - Helper to get adev of an attachment
|
||||
*
|
||||
* @attach: attachment
|
||||
*
|
||||
* Returns:
|
||||
* A struct amdgpu_device * if the attaching device is an amdgpu device or
|
||||
* partition, NULL otherwise.
|
||||
*/
|
||||
static struct amdgpu_device *dma_buf_attach_adev(struct dma_buf_attachment *attach)
|
||||
{
|
||||
if (attach->importer_ops == &amdgpu_dma_buf_attach_ops) {
|
||||
struct drm_gem_object *obj = attach->importer_priv;
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
|
||||
|
||||
return amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation
|
||||
*
|
||||
@@ -54,11 +77,13 @@
|
||||
static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
|
||||
struct dma_buf_attachment *attach)
|
||||
{
|
||||
struct amdgpu_device *attach_adev = dma_buf_attach_adev(attach);
|
||||
struct drm_gem_object *obj = dmabuf->priv;
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
|
||||
if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
|
||||
if (!amdgpu_dmabuf_is_xgmi_accessible(attach_adev, bo) &&
|
||||
pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
|
||||
attach->peer2peer = false;
|
||||
|
||||
amdgpu_vm_bo_update_shared(bo);
|
||||
@@ -77,22 +102,32 @@ static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach)
|
||||
{
|
||||
struct dma_buf *dmabuf = attach->dmabuf;
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(dmabuf->priv);
|
||||
u32 domains = bo->preferred_domains;
|
||||
u32 domains = bo->allowed_domains;
|
||||
|
||||
dma_resv_assert_held(dmabuf->resv);
|
||||
|
||||
/*
|
||||
* Try pinning into VRAM to allow P2P with RDMA NICs without ODP
|
||||
/* Try pinning into VRAM to allow P2P with RDMA NICs without ODP
|
||||
* support if all attachments can do P2P. If any attachment can't do
|
||||
* P2P just pin into GTT instead.
|
||||
*
|
||||
* To avoid with conflicting pinnings between GPUs and RDMA when move
|
||||
* notifiers are disabled, only allow pinning in VRAM when move
|
||||
* notiers are enabled.
|
||||
*/
|
||||
list_for_each_entry(attach, &dmabuf->attachments, node)
|
||||
if (!attach->peer2peer)
|
||||
domains &= ~AMDGPU_GEM_DOMAIN_VRAM;
|
||||
if (!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) {
|
||||
domains &= ~AMDGPU_GEM_DOMAIN_VRAM;
|
||||
} else {
|
||||
list_for_each_entry(attach, &dmabuf->attachments, node)
|
||||
if (!attach->peer2peer)
|
||||
domains &= ~AMDGPU_GEM_DOMAIN_VRAM;
|
||||
}
|
||||
|
||||
if (domains & AMDGPU_GEM_DOMAIN_VRAM)
|
||||
bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
||||
|
||||
if (WARN_ON(!domains))
|
||||
return -EINVAL;
|
||||
|
||||
return amdgpu_bo_pin(bo, domains);
|
||||
}
|
||||
|
||||
@@ -470,6 +505,9 @@ bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev,
|
||||
struct drm_gem_object *obj = &bo->tbo.base;
|
||||
struct drm_gem_object *gobj;
|
||||
|
||||
if (!adev)
|
||||
return false;
|
||||
|
||||
if (obj->import_attach) {
|
||||
struct dma_buf *dma_buf = obj->import_attach->dmabuf;
|
||||
|
||||
|
||||
@@ -1920,26 +1920,6 @@ static enum dmub_ips_disable_type dm_get_default_ips_mode(
|
||||
switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
|
||||
case IP_VERSION(3, 5, 0):
|
||||
case IP_VERSION(3, 6, 0):
|
||||
/*
|
||||
* On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to
|
||||
* cause a hard hang. A fix exists for newer PMFW.
|
||||
*
|
||||
* As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest
|
||||
* IPS state in all cases, except for s0ix and all displays off (DPMS),
|
||||
* where IPS2 is allowed.
|
||||
*
|
||||
* When checking pmfw version, use the major and minor only.
|
||||
*/
|
||||
if ((adev->pm.fw_version & 0x00FFFF00) < 0x005D6300)
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
else if (amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(11, 5, 0))
|
||||
/*
|
||||
* Other ASICs with DCN35 that have residency issues with
|
||||
* IPS2 in idle.
|
||||
* We want them to use IPS2 only in display off cases.
|
||||
*/
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
break;
|
||||
case IP_VERSION(3, 5, 1):
|
||||
ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
|
||||
break;
|
||||
@@ -3355,16 +3335,16 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
|
||||
for (k = 0; k < dc_state->stream_count; k++) {
|
||||
bundle->stream_update.stream = dc_state->streams[k];
|
||||
|
||||
for (m = 0; m < dc_state->stream_status->plane_count; m++) {
|
||||
for (m = 0; m < dc_state->stream_status[k].plane_count; m++) {
|
||||
bundle->surface_updates[m].surface =
|
||||
dc_state->stream_status->plane_states[m];
|
||||
dc_state->stream_status[k].plane_states[m];
|
||||
bundle->surface_updates[m].surface->force_full_update =
|
||||
true;
|
||||
}
|
||||
|
||||
update_planes_and_stream_adapter(dm->dc,
|
||||
UPDATE_TYPE_FULL,
|
||||
dc_state->stream_status->plane_count,
|
||||
dc_state->stream_status[k].plane_count,
|
||||
dc_state->streams[k],
|
||||
&bundle->stream_update,
|
||||
bundle->surface_updates);
|
||||
@@ -6521,12 +6501,12 @@ decide_crtc_timing_for_drm_display_mode(struct drm_display_mode *drm_mode,
|
||||
const struct drm_display_mode *native_mode,
|
||||
bool scale_enabled)
|
||||
{
|
||||
if (scale_enabled) {
|
||||
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
|
||||
} else if (native_mode->clock == drm_mode->clock &&
|
||||
native_mode->htotal == drm_mode->htotal &&
|
||||
native_mode->vtotal == drm_mode->vtotal) {
|
||||
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
|
||||
if (scale_enabled || (
|
||||
native_mode->clock == drm_mode->clock &&
|
||||
native_mode->htotal == drm_mode->htotal &&
|
||||
native_mode->vtotal == drm_mode->vtotal)) {
|
||||
if (native_mode->crtc_clock)
|
||||
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
|
||||
} else {
|
||||
/* no scaling nor amdgpu inserted, no need to patch */
|
||||
}
|
||||
@@ -11043,6 +11023,9 @@ static bool should_reset_plane(struct drm_atomic_state *state,
|
||||
state->allow_modeset)
|
||||
return true;
|
||||
|
||||
if (amdgpu_in_reset(adev) && state->allow_modeset)
|
||||
return true;
|
||||
|
||||
/* Exit early if we know that we're adding or removing the plane. */
|
||||
if (old_plane_state->crtc != new_plane_state->crtc)
|
||||
return true;
|
||||
|
||||
@@ -918,7 +918,7 @@ dm_helpers_probe_acpi_edid(void *data, u8 *buf, unsigned int block, size_t len)
|
||||
{
|
||||
struct drm_connector *connector = data;
|
||||
struct acpi_device *acpidev = ACPI_COMPANION(connector->dev->dev);
|
||||
unsigned char start = block * EDID_LENGTH;
|
||||
unsigned short start = block * EDID_LENGTH;
|
||||
struct edid *edid;
|
||||
int r;
|
||||
|
||||
|
||||
@@ -195,9 +195,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
|
||||
.dcn_downspread_percent = 0.5,
|
||||
.gpuvm_min_page_size_bytes = 4096,
|
||||
.hostvm_min_page_size_bytes = 4096,
|
||||
.do_urgent_latency_adjustment = 0,
|
||||
.do_urgent_latency_adjustment = 1,
|
||||
.urgent_latency_adjustment_fabric_clock_component_us = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
|
||||
};
|
||||
|
||||
void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)
|
||||
|
||||
@@ -35,6 +35,17 @@
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
||||
static void get_default_8b_10b_lttpr_aux_rd_interval(
|
||||
union training_aux_rd_interval *training_rd_interval)
|
||||
{
|
||||
/* LTTPR are required to program DPCD 0000Eh to 0x4 (16ms) upon AUX
|
||||
* read reply to this register. Since old sinks with DPCD rev 1.1
|
||||
* and earlier may not support this register, assume the mandatory
|
||||
* value is programmed by the LTTPR to avoid AUX timeout issues.
|
||||
*/
|
||||
training_rd_interval->raw = 0x4;
|
||||
}
|
||||
|
||||
static int32_t get_cr_training_aux_rd_interval(struct dc_link *link,
|
||||
const struct dc_link_settings *link_settings,
|
||||
enum lttpr_mode lttpr_mode)
|
||||
@@ -43,17 +54,22 @@ static int32_t get_cr_training_aux_rd_interval(struct dc_link *link,
|
||||
uint32_t wait_in_micro_secs = 100;
|
||||
|
||||
memset(&training_rd_interval, 0, sizeof(training_rd_interval));
|
||||
if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING &&
|
||||
link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
if (lttpr_mode != LTTPR_MODE_NON_TRANSPARENT)
|
||||
wait_in_micro_secs = 400;
|
||||
if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
|
||||
wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
|
||||
if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12)
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
else if (dp_is_lttpr_present(link))
|
||||
get_default_8b_10b_lttpr_aux_rd_interval(&training_rd_interval);
|
||||
|
||||
if (training_rd_interval.raw != 0) {
|
||||
if (lttpr_mode != LTTPR_MODE_NON_TRANSPARENT)
|
||||
wait_in_micro_secs = 400;
|
||||
if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
|
||||
wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
|
||||
}
|
||||
}
|
||||
return wait_in_micro_secs;
|
||||
}
|
||||
@@ -71,13 +87,15 @@ static uint32_t get_eq_training_aux_rd_interval(
|
||||
DP_128B132B_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
} else if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING &&
|
||||
link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
} else if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12)
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_TRAINING_AUX_RD_INTERVAL,
|
||||
(uint8_t *)&training_rd_interval,
|
||||
sizeof(training_rd_interval));
|
||||
else if (dp_is_lttpr_present(link))
|
||||
get_default_8b_10b_lttpr_aux_rd_interval(&training_rd_interval);
|
||||
}
|
||||
|
||||
switch (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL) {
|
||||
|
||||
@@ -43,13 +43,13 @@ struct decon_data {
|
||||
unsigned int wincon_burstlen_shift;
|
||||
};
|
||||
|
||||
static struct decon_data exynos7_decon_data = {
|
||||
static const struct decon_data exynos7_decon_data = {
|
||||
.vidw_buf_start_base = 0x80,
|
||||
.shadowcon_win_protect_shift = 10,
|
||||
.wincon_burstlen_shift = 11,
|
||||
};
|
||||
|
||||
static struct decon_data exynos7870_decon_data = {
|
||||
static const struct decon_data exynos7870_decon_data = {
|
||||
.vidw_buf_start_base = 0x880,
|
||||
.shadowcon_win_protect_shift = 8,
|
||||
.wincon_burstlen_shift = 10,
|
||||
|
||||
@@ -355,8 +355,7 @@ static void exynos_drm_platform_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct drm_device *drm = platform_get_drvdata(pdev);
|
||||
|
||||
if (drm)
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
}
|
||||
|
||||
static struct platform_driver exynos_drm_platform_driver = {
|
||||
|
||||
@@ -908,7 +908,7 @@ static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
|
||||
u32 buf_num;
|
||||
u32 cfg;
|
||||
|
||||
DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]enqueu[%d]\n", buf_id, enqueue);
|
||||
DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]enqueue[%d]\n", buf_id, enqueue);
|
||||
|
||||
spin_lock_irqsave(&ctx->lock, flags);
|
||||
|
||||
|
||||
@@ -731,7 +731,7 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
|
||||
/*
|
||||
* Setting dma-burst to 16Word causes permanent tearing for very small
|
||||
* buffers, e.g. cursor buffer. Burst Mode switching which based on
|
||||
* plane size is not recommended as plane size varies alot towards the
|
||||
* plane size is not recommended as plane size varies a lot towards the
|
||||
* end of the screen and rapid movement causes unstable DMA, but it is
|
||||
* still better to change dma-burst than displaying garbage.
|
||||
*/
|
||||
|
||||
@@ -312,9 +312,6 @@ static int vidi_get_modes(struct drm_connector *connector)
|
||||
else
|
||||
drm_edid = drm_edid_alloc(fake_edid_info, sizeof(fake_edid_info));
|
||||
|
||||
if (!drm_edid)
|
||||
return 0;
|
||||
|
||||
drm_edid_connector_update(connector, drm_edid);
|
||||
|
||||
count = drm_edid_connector_add_modes(connector);
|
||||
|
||||
@@ -169,7 +169,7 @@ static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = {
|
||||
/* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */
|
||||
{
|
||||
.limits = {
|
||||
.max_hdmi_phy_freq = 1650000,
|
||||
.max_hdmi_phy_freq = 1650000000,
|
||||
},
|
||||
.attrs = (const struct soc_device_attribute []) {
|
||||
{ .soc_id = "GXL (S805*)", },
|
||||
|
||||
@@ -37,7 +37,7 @@ struct meson_drm_match_data {
|
||||
};
|
||||
|
||||
struct meson_drm_soc_limits {
|
||||
unsigned int max_hdmi_phy_freq;
|
||||
unsigned long long max_hdmi_phy_freq;
|
||||
};
|
||||
|
||||
struct meson_drm {
|
||||
|
||||
@@ -70,12 +70,12 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi,
|
||||
{
|
||||
struct meson_drm *priv = encoder_hdmi->priv;
|
||||
int vic = drm_match_cea_mode(mode);
|
||||
unsigned int phy_freq;
|
||||
unsigned int vclk_freq;
|
||||
unsigned int venc_freq;
|
||||
unsigned int hdmi_freq;
|
||||
unsigned long long phy_freq;
|
||||
unsigned long long vclk_freq;
|
||||
unsigned long long venc_freq;
|
||||
unsigned long long hdmi_freq;
|
||||
|
||||
vclk_freq = mode->clock;
|
||||
vclk_freq = mode->clock * 1000;
|
||||
|
||||
/* For 420, pixel clock is half unlike venc clock */
|
||||
if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
|
||||
@@ -107,7 +107,8 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi,
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
venc_freq /= 2;
|
||||
|
||||
dev_dbg(priv->dev, "vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n",
|
||||
dev_dbg(priv->dev,
|
||||
"vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n",
|
||||
phy_freq, vclk_freq, venc_freq, hdmi_freq,
|
||||
priv->venc.hdmi_use_enci);
|
||||
|
||||
@@ -122,10 +123,11 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
|
||||
struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
|
||||
struct meson_drm *priv = encoder_hdmi->priv;
|
||||
bool is_hdmi2_sink = display_info->hdmi.scdc.supported;
|
||||
unsigned int phy_freq;
|
||||
unsigned int vclk_freq;
|
||||
unsigned int venc_freq;
|
||||
unsigned int hdmi_freq;
|
||||
unsigned long long clock = mode->clock * 1000;
|
||||
unsigned long long phy_freq;
|
||||
unsigned long long vclk_freq;
|
||||
unsigned long long venc_freq;
|
||||
unsigned long long hdmi_freq;
|
||||
int vic = drm_match_cea_mode(mode);
|
||||
enum drm_mode_status status;
|
||||
|
||||
@@ -144,12 +146,12 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
|
||||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
return meson_vclk_dmt_supported_freq(priv, mode->clock);
|
||||
return meson_vclk_dmt_supported_freq(priv, clock);
|
||||
/* Check against supported VIC modes */
|
||||
} else if (!meson_venc_hdmi_supported_vic(vic))
|
||||
return MODE_BAD;
|
||||
|
||||
vclk_freq = mode->clock;
|
||||
vclk_freq = clock;
|
||||
|
||||
/* For 420, pixel clock is half unlike venc clock */
|
||||
if (drm_mode_is_420_only(display_info, mode) ||
|
||||
@@ -179,7 +181,8 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
venc_freq /= 2;
|
||||
|
||||
dev_dbg(priv->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
|
||||
dev_dbg(priv->dev,
|
||||
"%s: vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz\n",
|
||||
__func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
|
||||
|
||||
return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq);
|
||||
|
||||
@@ -110,7 +110,10 @@
|
||||
#define HDMI_PLL_LOCK BIT(31)
|
||||
#define HDMI_PLL_LOCK_G12A (3 << 30)
|
||||
|
||||
#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001)
|
||||
#define PIXEL_FREQ_1000_1001(_freq) \
|
||||
DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL)
|
||||
#define PHY_FREQ_1000_1001(_freq) \
|
||||
(PIXEL_FREQ_1000_1001(DIV_ROUND_DOWN_ULL(_freq, 10ULL)) * 10)
|
||||
|
||||
/* VID PLL Dividers */
|
||||
enum {
|
||||
@@ -360,11 +363,11 @@ enum {
|
||||
};
|
||||
|
||||
struct meson_vclk_params {
|
||||
unsigned int pll_freq;
|
||||
unsigned int phy_freq;
|
||||
unsigned int vclk_freq;
|
||||
unsigned int venc_freq;
|
||||
unsigned int pixel_freq;
|
||||
unsigned long long pll_freq;
|
||||
unsigned long long phy_freq;
|
||||
unsigned long long vclk_freq;
|
||||
unsigned long long venc_freq;
|
||||
unsigned long long pixel_freq;
|
||||
unsigned int pll_od1;
|
||||
unsigned int pll_od2;
|
||||
unsigned int pll_od3;
|
||||
@@ -372,11 +375,11 @@ struct meson_vclk_params {
|
||||
unsigned int vclk_div;
|
||||
} params[] = {
|
||||
[MESON_VCLK_HDMI_ENCI_54000] = {
|
||||
.pll_freq = 4320000,
|
||||
.phy_freq = 270000,
|
||||
.vclk_freq = 54000,
|
||||
.venc_freq = 54000,
|
||||
.pixel_freq = 54000,
|
||||
.pll_freq = 4320000000,
|
||||
.phy_freq = 270000000,
|
||||
.vclk_freq = 54000000,
|
||||
.venc_freq = 54000000,
|
||||
.pixel_freq = 54000000,
|
||||
.pll_od1 = 4,
|
||||
.pll_od2 = 4,
|
||||
.pll_od3 = 1,
|
||||
@@ -384,11 +387,11 @@ struct meson_vclk_params {
|
||||
.vclk_div = 1,
|
||||
},
|
||||
[MESON_VCLK_HDMI_DDR_54000] = {
|
||||
.pll_freq = 4320000,
|
||||
.phy_freq = 270000,
|
||||
.vclk_freq = 54000,
|
||||
.venc_freq = 54000,
|
||||
.pixel_freq = 27000,
|
||||
.pll_freq = 4320000000,
|
||||
.phy_freq = 270000000,
|
||||
.vclk_freq = 54000000,
|
||||
.venc_freq = 54000000,
|
||||
.pixel_freq = 27000000,
|
||||
.pll_od1 = 4,
|
||||
.pll_od2 = 4,
|
||||
.pll_od3 = 1,
|
||||
@@ -396,11 +399,11 @@ struct meson_vclk_params {
|
||||
.vclk_div = 1,
|
||||
},
|
||||
[MESON_VCLK_HDMI_DDR_148500] = {
|
||||
.pll_freq = 2970000,
|
||||
.phy_freq = 742500,
|
||||
.vclk_freq = 148500,
|
||||
.venc_freq = 148500,
|
||||
.pixel_freq = 74250,
|
||||
.pll_freq = 2970000000,
|
||||
.phy_freq = 742500000,
|
||||
.vclk_freq = 148500000,
|
||||
.venc_freq = 148500000,
|
||||
.pixel_freq = 74250000,
|
||||
.pll_od1 = 4,
|
||||
.pll_od2 = 1,
|
||||
.pll_od3 = 1,
|
||||
@@ -408,11 +411,11 @@ struct meson_vclk_params {
|
||||
.vclk_div = 1,
|
||||
},
|
||||
[MESON_VCLK_HDMI_74250] = {
|
||||
.pll_freq = 2970000,
|
||||
.phy_freq = 742500,
|
||||
.vclk_freq = 74250,
|
||||
.venc_freq = 74250,
|
||||
.pixel_freq = 74250,
|
||||
.pll_freq = 2970000000,
|
||||
.phy_freq = 742500000,
|
||||
.vclk_freq = 74250000,
|
||||
.venc_freq = 74250000,
|
||||
.pixel_freq = 74250000,
|
||||
.pll_od1 = 2,
|
||||
.pll_od2 = 2,
|
||||
.pll_od3 = 2,
|
||||
@@ -420,11 +423,11 @@ struct meson_vclk_params {
|
||||
.vclk_div = 1,
|
||||
},
|
||||
[MESON_VCLK_HDMI_148500] = {
|
||||
.pll_freq = 2970000,
|
||||
.phy_freq = 1485000,
|
||||
.vclk_freq = 148500,
|
||||
.venc_freq = 148500,
|
||||
.pixel_freq = 148500,
|
||||
.pll_freq = 2970000000,
|
||||
.phy_freq = 1485000000,
|
||||
.vclk_freq = 148500000,
|
||||
.venc_freq = 148500000,
|
||||
.pixel_freq = 148500000,
|
||||
.pll_od1 = 1,
|
||||
.pll_od2 = 2,
|
||||
.pll_od3 = 2,
|
||||
@@ -432,11 +435,11 @@ struct meson_vclk_params {
|
||||
.vclk_div = 1,
|
||||
},
|
||||
[MESON_VCLK_HDMI_297000] = {
|
||||
.pll_freq = 5940000,
|
||||
.phy_freq = 2970000,
|
||||
.venc_freq = 297000,
|
||||
.vclk_freq = 297000,
|
||||
.pixel_freq = 297000,
|
||||
.pll_freq = 5940000000,
|
||||
.phy_freq = 2970000000,
|
||||
.venc_freq = 297000000,
|
||||
.vclk_freq = 297000000,
|
||||
.pixel_freq = 297000000,
|
||||
.pll_od1 = 2,
|
||||
.pll_od2 = 1,
|
||||
.pll_od3 = 1,
|
||||
@@ -444,11 +447,11 @@ struct meson_vclk_params {
|
||||
.vclk_div = 2,
|
||||
},
|
||||
[MESON_VCLK_HDMI_594000] = {
|
||||
.pll_freq = 5940000,
|
||||
.phy_freq = 5940000,
|
||||
.venc_freq = 594000,
|
||||
.vclk_freq = 594000,
|
||||
.pixel_freq = 594000,
|
||||
.pll_freq = 5940000000,
|
||||
.phy_freq = 5940000000,
|
||||
.venc_freq = 594000000,
|
||||
.vclk_freq = 594000000,
|
||||
.pixel_freq = 594000000,
|
||||
.pll_od1 = 1,
|
||||
.pll_od2 = 1,
|
||||
.pll_od3 = 2,
|
||||
@@ -456,11 +459,11 @@ struct meson_vclk_params {
|
||||
.vclk_div = 1,
|
||||
},
|
||||
[MESON_VCLK_HDMI_594000_YUV420] = {
|
||||
.pll_freq = 5940000,
|
||||
.phy_freq = 2970000,
|
||||
.venc_freq = 594000,
|
||||
.vclk_freq = 594000,
|
||||
.pixel_freq = 297000,
|
||||
.pll_freq = 5940000000,
|
||||
.phy_freq = 2970000000,
|
||||
.venc_freq = 594000000,
|
||||
.vclk_freq = 594000000,
|
||||
.pixel_freq = 297000000,
|
||||
.pll_od1 = 2,
|
||||
.pll_od2 = 1,
|
||||
.pll_od3 = 1,
|
||||
@@ -617,16 +620,16 @@ static void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
|
||||
3 << 20, pll_od_to_reg(od3) << 20);
|
||||
}
|
||||
|
||||
#define XTAL_FREQ 24000
|
||||
#define XTAL_FREQ (24 * 1000 * 1000)
|
||||
|
||||
static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
|
||||
unsigned int pll_freq)
|
||||
unsigned long long pll_freq)
|
||||
{
|
||||
/* The GXBB PLL has a /2 pre-multiplier */
|
||||
if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
|
||||
pll_freq /= 2;
|
||||
pll_freq = DIV_ROUND_DOWN_ULL(pll_freq, 2);
|
||||
|
||||
return pll_freq / XTAL_FREQ;
|
||||
return DIV_ROUND_DOWN_ULL(pll_freq, XTAL_FREQ);
|
||||
}
|
||||
|
||||
#define HDMI_FRAC_MAX_GXBB 4096
|
||||
@@ -635,12 +638,13 @@ static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
|
||||
|
||||
static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
|
||||
unsigned int m,
|
||||
unsigned int pll_freq)
|
||||
unsigned long long pll_freq)
|
||||
{
|
||||
unsigned int parent_freq = XTAL_FREQ;
|
||||
unsigned long long parent_freq = XTAL_FREQ;
|
||||
unsigned int frac_max = HDMI_FRAC_MAX_GXL;
|
||||
unsigned int frac_m;
|
||||
unsigned int frac;
|
||||
u32 remainder;
|
||||
|
||||
/* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
|
||||
if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
|
||||
@@ -652,11 +656,11 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
|
||||
frac_max = HDMI_FRAC_MAX_G12A;
|
||||
|
||||
/* We can have a perfect match !*/
|
||||
if (pll_freq / m == parent_freq &&
|
||||
pll_freq % m == 0)
|
||||
if (div_u64_rem(pll_freq, m, &remainder) == parent_freq &&
|
||||
remainder == 0)
|
||||
return 0;
|
||||
|
||||
frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
|
||||
frac = mul_u64_u64_div_u64(pll_freq, frac_max, parent_freq);
|
||||
frac_m = m * frac_max;
|
||||
if (frac_m > frac)
|
||||
return frac_max;
|
||||
@@ -666,7 +670,7 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
|
||||
}
|
||||
|
||||
static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
|
||||
unsigned int m,
|
||||
unsigned long long m,
|
||||
unsigned int frac)
|
||||
{
|
||||
if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
|
||||
@@ -694,7 +698,7 @@ static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
|
||||
}
|
||||
|
||||
static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
|
||||
unsigned int freq,
|
||||
unsigned long long freq,
|
||||
unsigned int *m,
|
||||
unsigned int *frac,
|
||||
unsigned int *od)
|
||||
@@ -706,7 +710,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
|
||||
continue;
|
||||
*frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
|
||||
|
||||
DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n",
|
||||
DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d\n",
|
||||
freq, *m, *frac, *od);
|
||||
|
||||
if (meson_hdmi_pll_validate_params(priv, *m, *frac))
|
||||
@@ -718,7 +722,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
|
||||
|
||||
/* pll_freq is the frequency after the OD dividers */
|
||||
enum drm_mode_status
|
||||
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq)
|
||||
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq)
|
||||
{
|
||||
unsigned int od, m, frac;
|
||||
|
||||
@@ -741,7 +745,7 @@ EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq);
|
||||
|
||||
/* pll_freq is the frequency after the OD dividers */
|
||||
static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
|
||||
unsigned int pll_freq)
|
||||
unsigned long long pll_freq)
|
||||
{
|
||||
unsigned int od, m, frac, od1, od2, od3;
|
||||
|
||||
@@ -756,7 +760,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
|
||||
od1 = od / od2;
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
|
||||
DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d/%d/%d\n",
|
||||
pll_freq, m, frac, od1, od2, od3);
|
||||
|
||||
meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
|
||||
@@ -764,17 +768,18 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
|
||||
return;
|
||||
}
|
||||
|
||||
DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n",
|
||||
DRM_ERROR("Fatal, unable to find parameters for PLL freq %lluHz\n",
|
||||
pll_freq);
|
||||
}
|
||||
|
||||
enum drm_mode_status
|
||||
meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
||||
unsigned int vclk_freq)
|
||||
meson_vclk_vic_supported_freq(struct meson_drm *priv,
|
||||
unsigned long long phy_freq,
|
||||
unsigned long long vclk_freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n",
|
||||
DRM_DEBUG_DRIVER("phy_freq = %lluHz vclk_freq = %lluHz\n",
|
||||
phy_freq, vclk_freq);
|
||||
|
||||
/* Check against soc revision/package limits */
|
||||
@@ -785,19 +790,19 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
||||
}
|
||||
|
||||
for (i = 0 ; params[i].pixel_freq ; ++i) {
|
||||
DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
|
||||
DRM_DEBUG_DRIVER("i = %d pixel_freq = %lluHz alt = %lluHz\n",
|
||||
i, params[i].pixel_freq,
|
||||
FREQ_1000_1001(params[i].pixel_freq));
|
||||
DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
|
||||
PIXEL_FREQ_1000_1001(params[i].pixel_freq));
|
||||
DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n",
|
||||
i, params[i].phy_freq,
|
||||
FREQ_1000_1001(params[i].phy_freq/1000)*1000);
|
||||
PHY_FREQ_1000_1001(params[i].phy_freq));
|
||||
/* Match strict frequency */
|
||||
if (phy_freq == params[i].phy_freq &&
|
||||
vclk_freq == params[i].vclk_freq)
|
||||
return MODE_OK;
|
||||
/* Match 1000/1001 variant */
|
||||
if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/1000)*1000) &&
|
||||
vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
|
||||
if (phy_freq == PHY_FREQ_1000_1001(params[i].phy_freq) &&
|
||||
vclk_freq == PIXEL_FREQ_1000_1001(params[i].vclk_freq))
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
@@ -805,8 +810,9 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq);
|
||||
|
||||
static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
||||
unsigned int od1, unsigned int od2, unsigned int od3,
|
||||
static void meson_vclk_set(struct meson_drm *priv,
|
||||
unsigned long long pll_base_freq, unsigned int od1,
|
||||
unsigned int od2, unsigned int od3,
|
||||
unsigned int vid_pll_div, unsigned int vclk_div,
|
||||
unsigned int hdmi_tx_div, unsigned int venc_div,
|
||||
bool hdmi_use_enci, bool vic_alternate_clock)
|
||||
@@ -826,15 +832,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
||||
meson_hdmi_pll_generic_set(priv, pll_base_freq);
|
||||
} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
|
||||
switch (pll_base_freq) {
|
||||
case 2970000:
|
||||
case 2970000000:
|
||||
m = 0x3d;
|
||||
frac = vic_alternate_clock ? 0xd02 : 0xe00;
|
||||
break;
|
||||
case 4320000:
|
||||
case 4320000000:
|
||||
m = vic_alternate_clock ? 0x59 : 0x5a;
|
||||
frac = vic_alternate_clock ? 0xe8f : 0;
|
||||
break;
|
||||
case 5940000:
|
||||
case 5940000000:
|
||||
m = 0x7b;
|
||||
frac = vic_alternate_clock ? 0xa05 : 0xc00;
|
||||
break;
|
||||
@@ -844,15 +850,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
||||
} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
|
||||
meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
|
||||
switch (pll_base_freq) {
|
||||
case 2970000:
|
||||
case 2970000000:
|
||||
m = 0x7b;
|
||||
frac = vic_alternate_clock ? 0x281 : 0x300;
|
||||
break;
|
||||
case 4320000:
|
||||
case 4320000000:
|
||||
m = vic_alternate_clock ? 0xb3 : 0xb4;
|
||||
frac = vic_alternate_clock ? 0x347 : 0;
|
||||
break;
|
||||
case 5940000:
|
||||
case 5940000000:
|
||||
m = 0xf7;
|
||||
frac = vic_alternate_clock ? 0x102 : 0x200;
|
||||
break;
|
||||
@@ -861,15 +867,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
||||
meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
|
||||
} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
|
||||
switch (pll_base_freq) {
|
||||
case 2970000:
|
||||
case 2970000000:
|
||||
m = 0x7b;
|
||||
frac = vic_alternate_clock ? 0x140b4 : 0x18000;
|
||||
break;
|
||||
case 4320000:
|
||||
case 4320000000:
|
||||
m = vic_alternate_clock ? 0xb3 : 0xb4;
|
||||
frac = vic_alternate_clock ? 0x1a3ee : 0;
|
||||
break;
|
||||
case 5940000:
|
||||
case 5940000000:
|
||||
m = 0xf7;
|
||||
frac = vic_alternate_clock ? 0x8148 : 0x10000;
|
||||
break;
|
||||
@@ -1025,14 +1031,14 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
||||
}
|
||||
|
||||
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||
unsigned int phy_freq, unsigned int vclk_freq,
|
||||
unsigned int venc_freq, unsigned int dac_freq,
|
||||
unsigned long long phy_freq, unsigned long long vclk_freq,
|
||||
unsigned long long venc_freq, unsigned long long dac_freq,
|
||||
bool hdmi_use_enci)
|
||||
{
|
||||
bool vic_alternate_clock = false;
|
||||
unsigned int freq;
|
||||
unsigned int hdmi_tx_div;
|
||||
unsigned int venc_div;
|
||||
unsigned long long freq;
|
||||
unsigned long long hdmi_tx_div;
|
||||
unsigned long long venc_div;
|
||||
|
||||
if (target == MESON_VCLK_TARGET_CVBS) {
|
||||
meson_venci_cvbs_clock_config(priv);
|
||||
@@ -1052,27 +1058,27 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||
return;
|
||||
}
|
||||
|
||||
hdmi_tx_div = vclk_freq / dac_freq;
|
||||
hdmi_tx_div = DIV_ROUND_DOWN_ULL(vclk_freq, dac_freq);
|
||||
|
||||
if (hdmi_tx_div == 0) {
|
||||
pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
|
||||
pr_err("Fatal Error, invalid HDMI-TX freq %lluHz\n",
|
||||
dac_freq);
|
||||
return;
|
||||
}
|
||||
|
||||
venc_div = vclk_freq / venc_freq;
|
||||
venc_div = DIV_ROUND_DOWN_ULL(vclk_freq, venc_freq);
|
||||
|
||||
if (venc_div == 0) {
|
||||
pr_err("Fatal Error, invalid HDMI venc freq %d\n",
|
||||
pr_err("Fatal Error, invalid HDMI venc freq %lluHz\n",
|
||||
venc_freq);
|
||||
return;
|
||||
}
|
||||
|
||||
for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
|
||||
if ((phy_freq == params[freq].phy_freq ||
|
||||
phy_freq == FREQ_1000_1001(params[freq].phy_freq/1000)*1000) &&
|
||||
phy_freq == PHY_FREQ_1000_1001(params[freq].phy_freq)) &&
|
||||
(vclk_freq == params[freq].vclk_freq ||
|
||||
vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
|
||||
vclk_freq == PIXEL_FREQ_1000_1001(params[freq].vclk_freq))) {
|
||||
if (vclk_freq != params[freq].vclk_freq)
|
||||
vic_alternate_clock = true;
|
||||
else
|
||||
@@ -1098,7 +1104,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||
}
|
||||
|
||||
if (!params[freq].pixel_freq) {
|
||||
pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq);
|
||||
pr_err("Fatal Error, invalid HDMI vclk freq %lluHz\n",
|
||||
vclk_freq);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,17 +20,18 @@ enum {
|
||||
};
|
||||
|
||||
/* 27MHz is the CVBS Pixel Clock */
|
||||
#define MESON_VCLK_CVBS 27000
|
||||
#define MESON_VCLK_CVBS (27 * 1000 * 1000)
|
||||
|
||||
enum drm_mode_status
|
||||
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq);
|
||||
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq);
|
||||
enum drm_mode_status
|
||||
meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
||||
unsigned int vclk_freq);
|
||||
meson_vclk_vic_supported_freq(struct meson_drm *priv,
|
||||
unsigned long long phy_freq,
|
||||
unsigned long long vclk_freq);
|
||||
|
||||
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
||||
unsigned int phy_freq, unsigned int vclk_freq,
|
||||
unsigned int venc_freq, unsigned int dac_freq,
|
||||
unsigned long long phy_freq, unsigned long long vclk_freq,
|
||||
unsigned long long venc_freq, unsigned long long dac_freq,
|
||||
bool hdmi_use_enci);
|
||||
|
||||
#endif /* __MESON_VCLK_H */
|
||||
|
||||
@@ -129,11 +129,11 @@ static int jadard_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct jadard *jadard = panel_to_jadard(panel);
|
||||
|
||||
gpiod_set_value(jadard->reset, 1);
|
||||
gpiod_set_value(jadard->reset, 0);
|
||||
msleep(120);
|
||||
|
||||
if (jadard->desc->reset_before_power_off_vcioo) {
|
||||
gpiod_set_value(jadard->reset, 0);
|
||||
gpiod_set_value(jadard->reset, 1);
|
||||
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user